Simplify the code by removing station action handlers
This commit is contained in:
@@ -412,7 +412,7 @@ public:
|
||||
|
||||
class Tool {
|
||||
protected:
|
||||
up<Action> action = nullptr;
|
||||
sp<Action> action = nullptr;
|
||||
public:
|
||||
virtual ~Tool() = default;
|
||||
virtual void Update(Point pt, TileIndex tile) = 0;
|
||||
|
||||
@@ -712,52 +712,50 @@ ToolGUIInfo GetSelectedStationGUIInfo() {
|
||||
}
|
||||
|
||||
// --- Action base class ---
|
||||
|
||||
void Action::OnStationRemoved(const Station *) {}
|
||||
|
||||
// --- RemoveAction ---
|
||||
template <ImplementsRemoveHandler Handler>
|
||||
void RemoveAction<Handler>::Update(Point, TileIndex tile) {
|
||||
|
||||
void RemoveAction::Update(Point, TileIndex tile) {
|
||||
this->cur_tile = tile;
|
||||
}
|
||||
|
||||
template <ImplementsRemoveHandler Handler>
|
||||
bool RemoveAction<Handler>::HandleMousePress() {
|
||||
bool RemoveAction::HandleMousePress() {
|
||||
if (!IsValidTile(this->cur_tile)) return false;
|
||||
this->start_tile = this->cur_tile;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <ImplementsRemoveHandler Handler>
|
||||
void RemoveAction<Handler>::HandleMouseRelease() {
|
||||
void RemoveAction::HandleMouseRelease() {
|
||||
auto area = this->GetArea();
|
||||
if (!area.has_value()) return;
|
||||
this->handler->Execute(area.value());
|
||||
this->Execute(area.value());
|
||||
this->start_tile = INVALID_TILE;
|
||||
}
|
||||
|
||||
template <ImplementsRemoveHandler Handler>
|
||||
std::optional<TileArea> RemoveAction<Handler>::GetArea() const {
|
||||
std::optional<TileArea> RemoveAction::GetArea() const {
|
||||
if (!IsValidTile(this->cur_tile)) return std::nullopt;
|
||||
if (!IsValidTile(this->start_tile)) return TileArea{this->cur_tile, this->cur_tile};
|
||||
return TileArea{this->start_tile, this->cur_tile};
|
||||
}
|
||||
|
||||
template <ImplementsRemoveHandler Handler>
|
||||
ToolGUIInfo RemoveAction<Handler>::GetGUIInfo() {
|
||||
ToolGUIInfo RemoveAction::GetGUIInfo() {
|
||||
HighlightMap hlmap;
|
||||
BuildInfoOverlayData data;
|
||||
auto area = this->GetArea();
|
||||
CommandCost cost;
|
||||
if (area.has_value()) {
|
||||
hlmap.AddTileAreaWithBorder(area.value(), CM_PALETTE_TINT_RED_DEEP);
|
||||
auto cmd = this->handler->GetCommand(area.value());
|
||||
auto cmd = this->GetCommand(area.value());
|
||||
if (cmd) cost = cmd->test();
|
||||
}
|
||||
return {hlmap, data, cost};
|
||||
}
|
||||
|
||||
template <ImplementsRemoveHandler Handler>
|
||||
void RemoveAction<Handler>::OnStationRemoved(const Station *) {}
|
||||
void RemoveAction::OnStationRemoved(const Station *) {}
|
||||
|
||||
// --- PlacementAction ---
|
||||
|
||||
ToolGUIInfo PlacementAction::PrepareGUIInfo(std::optional<ObjectHighlight> ohl, up<Command> cmd, StationCoverageType sct, uint rad) {
|
||||
if (!cmd || !ohl.has_value()) return {};
|
||||
@@ -896,8 +894,8 @@ ToolGUIInfo PlacementAction::PrepareGUIInfo(std::optional<ObjectHighlight> ohl,
|
||||
}
|
||||
|
||||
// --- SizedPlacementAction ---
|
||||
template <ImplementsSizedPlacementHandler Handler>
|
||||
void SizedPlacementAction<Handler>::Update(Point, TileIndex tile) {
|
||||
|
||||
void SizedPlacementAction::Update(Point, TileIndex tile) {
|
||||
this->cur_tile = tile;
|
||||
if (UseImprovedStationJoin()) return;
|
||||
|
||||
@@ -905,7 +903,7 @@ void SizedPlacementAction<Handler>::Update(Point, TileIndex tile) {
|
||||
|
||||
auto area = this->GetArea();
|
||||
if (!area.has_value()) return;
|
||||
auto cmdptr = this->handler->GetCommand(tile, INVALID_STATION);
|
||||
auto cmdptr = this->GetCommand(tile, INVALID_STATION);
|
||||
auto cmd = dynamic_cast<cmd::BuildRailStation *>(cmdptr.get());
|
||||
if (cmd == nullptr) return;
|
||||
|
||||
@@ -952,88 +950,80 @@ void SizedPlacementAction<Handler>::Update(Point, TileIndex tile) {
|
||||
// }
|
||||
}
|
||||
|
||||
template <ImplementsSizedPlacementHandler Handler>
|
||||
bool SizedPlacementAction<Handler>::HandleMousePress() {
|
||||
bool SizedPlacementAction::HandleMousePress() {
|
||||
return IsValidTile(this->cur_tile);
|
||||
}
|
||||
|
||||
template <ImplementsSizedPlacementHandler Handler>
|
||||
void SizedPlacementAction<Handler>::HandleMouseRelease() {
|
||||
void SizedPlacementAction::HandleMouseRelease() {
|
||||
if (!IsValidTile(this->cur_tile)) return;
|
||||
this->handler->Execute(this->cur_tile);
|
||||
this->Execute(this->cur_tile);
|
||||
}
|
||||
|
||||
template <ImplementsSizedPlacementHandler Handler>
|
||||
ToolGUIInfo SizedPlacementAction<Handler>::GetGUIInfo() {
|
||||
ToolGUIInfo SizedPlacementAction::GetGUIInfo() {
|
||||
if (!IsValidTile(this->cur_tile)) return {};
|
||||
auto [sct, rad] = this->handler->GetCatchmentParams();
|
||||
auto [sct, rad] = this->GetCatchmentParams();
|
||||
return this->PrepareGUIInfo(
|
||||
this->handler->GetObjectHighlight(this->cur_tile),
|
||||
this->handler->GetCommand(this->cur_tile, INVALID_STATION),
|
||||
this->GetObjectHighlight(this->cur_tile),
|
||||
this->GetCommand(this->cur_tile, INVALID_STATION),
|
||||
sct,
|
||||
rad
|
||||
);
|
||||
}
|
||||
|
||||
template <ImplementsSizedPlacementHandler Handler>
|
||||
void SizedPlacementAction<Handler>::OnStationRemoved(const Station *) {}
|
||||
void SizedPlacementAction::OnStationRemoved(const Station *) {}
|
||||
|
||||
// --- DragNDropPlacementAction ---
|
||||
|
||||
template <ImplementsDragNDropPlacementHandler Handler>
|
||||
std::optional<TileArea> DragNDropPlacementAction<Handler>::GetArea() const {
|
||||
std::optional<TileArea> DragNDropPlacementAction::GetArea() const {
|
||||
// TODO separate common fuctions with RemoveAction into base class
|
||||
if (!IsValidTile(this->cur_tile)) return std::nullopt;
|
||||
if (!IsValidTile(this->start_tile)) return TileArea{this->cur_tile, this->cur_tile};
|
||||
return TileArea{this->start_tile, this->cur_tile};
|
||||
}
|
||||
|
||||
template <ImplementsDragNDropPlacementHandler Handler>
|
||||
void DragNDropPlacementAction<Handler>::Update(Point, TileIndex tile) {
|
||||
void DragNDropPlacementAction::Update(Point, TileIndex tile) {
|
||||
this->cur_tile = tile;
|
||||
}
|
||||
|
||||
template <ImplementsDragNDropPlacementHandler Handler>
|
||||
bool DragNDropPlacementAction<Handler>::HandleMousePress() {
|
||||
bool DragNDropPlacementAction::HandleMousePress() {
|
||||
if (!IsValidTile(this->cur_tile)) return false;
|
||||
this->start_tile = this->cur_tile;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <ImplementsDragNDropPlacementHandler Handler>
|
||||
void DragNDropPlacementAction<Handler>::HandleMouseRelease() {
|
||||
void DragNDropPlacementAction::HandleMouseRelease() {
|
||||
auto area = this->GetArea();
|
||||
if (!area.has_value()) return;
|
||||
this->handler->Execute(area.value());
|
||||
this->Execute(area.value());
|
||||
this->start_tile = INVALID_TILE;
|
||||
}
|
||||
|
||||
template <ImplementsDragNDropPlacementHandler Handler>
|
||||
ToolGUIInfo DragNDropPlacementAction<Handler>::GetGUIInfo() {
|
||||
ToolGUIInfo DragNDropPlacementAction::GetGUIInfo() {
|
||||
auto area = this->GetArea();
|
||||
if (!area.has_value()) return {};
|
||||
auto ohl = this->handler->GetObjectHighlight(area.value());
|
||||
auto [sct, rad] = this->handler->GetCatchmentParams();
|
||||
auto ohl = this->GetObjectHighlight(area.value());
|
||||
auto [sct, rad] = this->GetCatchmentParams();
|
||||
return this->PrepareGUIInfo(
|
||||
this->handler->GetObjectHighlight(area.value()),
|
||||
this->handler->GetCommand(area.value(), INVALID_STATION),
|
||||
this->GetObjectHighlight(area.value()),
|
||||
this->GetCommand(area.value(), INVALID_STATION),
|
||||
sct,
|
||||
rad
|
||||
);
|
||||
}
|
||||
|
||||
template <ImplementsDragNDropPlacementHandler Handler>
|
||||
void DragNDropPlacementAction<Handler>::OnStationRemoved(const Station *) {}
|
||||
void DragNDropPlacementAction::OnStationRemoved(const Station *) {}
|
||||
|
||||
// --- StationSelectAction ---
|
||||
template <ImplementsStationSelectHandler Handler>
|
||||
void StationSelectAction<Handler>::Update(Point, TileIndex tile) { this->cur_tile = tile; }
|
||||
|
||||
template <ImplementsStationSelectHandler Handler>
|
||||
bool StationSelectAction<Handler>::HandleMousePress() { return true; }
|
||||
void StationSelectAction::Update(Point, TileIndex tile) {
|
||||
this->cur_tile = tile;
|
||||
}
|
||||
|
||||
template <ImplementsStationSelectHandler Handler>
|
||||
void StationSelectAction<Handler>::HandleMouseRelease() {
|
||||
bool StationSelectAction::HandleMousePress() {
|
||||
return true;
|
||||
}
|
||||
|
||||
void StationSelectAction::HandleMouseRelease() {
|
||||
// TODO station sign click
|
||||
if (!IsValidTile(this->cur_tile)) return;
|
||||
_station_action = StationAction::Create{};
|
||||
@@ -1043,8 +1033,7 @@ void StationSelectAction<Handler>::HandleMouseRelease() {
|
||||
}
|
||||
}
|
||||
|
||||
template <ImplementsStationSelectHandler Handler>
|
||||
ToolGUIInfo StationSelectAction<Handler>::GetGUIInfo() {
|
||||
ToolGUIInfo StationSelectAction::GetGUIInfo() {
|
||||
if (!IsValidTile(this->cur_tile)) return {};
|
||||
HighlightMap hlmap;
|
||||
hlmap.Add(this->cur_tile, ObjectTileHighlight::make_border(CM_PALETTE_TINT_BLUE, ZoningBorder::FULL));
|
||||
@@ -1059,12 +1048,11 @@ ToolGUIInfo StationSelectAction<Handler>::GetGUIInfo() {
|
||||
return {hlmap, data, {}};
|
||||
}
|
||||
|
||||
template <ImplementsStationSelectHandler Handler>
|
||||
void StationSelectAction<Handler>::OnStationRemoved(const Station *station) {
|
||||
void StationSelectAction::OnStationRemoved(const Station *station) {
|
||||
// if (this->selected_station == station->index) this->selected_station = INVALID_STATION;
|
||||
}
|
||||
|
||||
// --- StationBuildTool ---
|
||||
// --- Misc functions ---
|
||||
|
||||
TileArea GetCommandArea(const up<Command> &cmd) {
|
||||
if (auto rail_cmd = dynamic_cast<cmd::BuildRailStation *>(cmd.get())) {
|
||||
@@ -1093,22 +1081,22 @@ StationBuildTool::StationBuildTool() {
|
||||
|
||||
extern void ShowSelectStationWindow(TileArea ta, StationPickerCmdProc&& proc);
|
||||
|
||||
template<typename Thandler, typename Tcallback, typename Targ>
|
||||
bool ExecuteBuildCommand(Thandler *handler, Tcallback callback, Targ arg) {
|
||||
template<typename Taction, typename Tcallback, typename Targ>
|
||||
bool ExecuteBuildCommand(Taction *action, Tcallback callback, Targ arg) {
|
||||
std::visit(Overload{
|
||||
[&](StationAction::Join &action) {
|
||||
Debug(misc, 0, "Join to {}", action.station);
|
||||
auto cmd = handler->GetCommand(arg, action.station);
|
||||
[&](StationAction::Join &a) {
|
||||
Debug(misc, 0, "Join to {}", a.station);
|
||||
auto cmd = action->GetCommand(arg, a.station);
|
||||
return cmd ? cmd->post(callback) : false;
|
||||
},
|
||||
[&](StationAction::Create &) {
|
||||
Debug(misc, 0, "Create new station");
|
||||
auto cmd = handler->GetCommand(arg, NEW_STATION);
|
||||
auto cmd = action->GetCommand(arg, NEW_STATION);
|
||||
return cmd ? cmd->post(callback) : false;
|
||||
},
|
||||
[&](StationAction::Picker &) {
|
||||
Debug(misc, 0, "Show picker");
|
||||
auto cmd = handler->GetCommand(arg, INVALID_STATION);
|
||||
auto cmd = action->GetCommand(arg, INVALID_STATION);
|
||||
auto proc = [cmd=sp<Command>{std::move(cmd)}, callback](bool test, StationID to_join) -> bool {
|
||||
if (!cmd) return false;
|
||||
auto station_cmd = dynamic_cast<StationBuildCommand *>(cmd.get());
|
||||
@@ -1122,7 +1110,7 @@ bool ExecuteBuildCommand(Thandler *handler, Tcallback callback, Targ arg) {
|
||||
}
|
||||
};
|
||||
|
||||
auto ohl = handler->GetObjectHighlight(arg);
|
||||
auto ohl = action->GetObjectHighlight(arg);
|
||||
if (!ohl.has_value()) return false;
|
||||
auto area = ohl->GetArea();
|
||||
if (!area.has_value()) return false;
|
||||
@@ -1136,9 +1124,9 @@ bool ExecuteBuildCommand(Thandler *handler, Tcallback callback, Targ arg) {
|
||||
}
|
||||
|
||||
|
||||
// --- RailStationBuildTool ---
|
||||
// --- RailStationBuildTool::RemoveAction ---
|
||||
|
||||
up<Command> RailStationBuildTool::RemoveHandler::GetCommand(TileArea area) {
|
||||
up<Command> RailStationBuildTool::RemoveAction::GetCommand(TileArea area) {
|
||||
auto cmd = make_up<cmd::RemoveFromRailStation>(
|
||||
area.tile,
|
||||
area.CMGetEndTile(),
|
||||
@@ -1148,20 +1136,23 @@ up<Command> RailStationBuildTool::RemoveHandler::GetCommand(TileArea area) {
|
||||
return cmd;
|
||||
}
|
||||
|
||||
bool RailStationBuildTool::RemoveHandler::Execute(TileArea area) {
|
||||
bool RailStationBuildTool::RemoveAction::Execute(TileArea area) {
|
||||
auto cmd = this->GetCommand(area);
|
||||
return cmd->post(&CcPlaySound_CONSTRUCTION_RAIL);
|
||||
}
|
||||
|
||||
std::optional<TileArea> RailStationBuildTool::SizedPlacementHandler::GetArea(TileIndex tile) const {
|
||||
if (!IsValidTile(tile)) return std::nullopt;
|
||||
|
||||
// --- RailStationBuildTool::SizedPlacementAction ---
|
||||
|
||||
std::optional<TileArea> RailStationBuildTool::SizedPlacementAction::GetArea() const {
|
||||
if (!IsValidTile(this->cur_tile)) return std::nullopt;
|
||||
auto w = _settings_client.gui.station_numtracks;
|
||||
auto h = _settings_client.gui.station_platlength;
|
||||
if (_railstation.orientation == AXIS_X) std::swap(w, h);
|
||||
return TileArea{tile, w, h};
|
||||
return TileArea{this->cur_tile, w, h};
|
||||
}
|
||||
|
||||
up<Command> RailStationBuildTool::SizedPlacementHandler::GetCommand(TileIndex tile, StationID to_join) {
|
||||
up<Command> RailStationBuildTool::SizedPlacementAction::GetCommand(TileIndex tile, StationID to_join) {
|
||||
// TODO mostly same as DragNDropPlacement
|
||||
auto cmd = make_up<cmd::BuildRailStation>(
|
||||
tile,
|
||||
@@ -1178,11 +1169,13 @@ up<Command> RailStationBuildTool::SizedPlacementHandler::GetCommand(TileIndex ti
|
||||
return cmd;
|
||||
}
|
||||
|
||||
bool RailStationBuildTool::SizedPlacementHandler::Execute(TileIndex tile) {
|
||||
bool RailStationBuildTool::SizedPlacementAction::Execute(TileIndex tile) {
|
||||
return ExecuteBuildCommand(this, &CcStation, tile);
|
||||
}
|
||||
|
||||
up<Command> RailStationBuildTool::DragNDropPlacementHandler::GetCommand(TileArea area, StationID to_join) {
|
||||
// --- RailStationBuildTool::DragNDropPlacementAction ---
|
||||
|
||||
up<Command> RailStationBuildTool::DragNDropPlacementAction::GetCommand(TileArea area, StationID to_join) {
|
||||
uint numtracks = area.w;
|
||||
uint platlength = area.h;
|
||||
|
||||
@@ -1203,20 +1196,27 @@ up<Command> RailStationBuildTool::DragNDropPlacementHandler::GetCommand(TileArea
|
||||
return cmd;
|
||||
}
|
||||
|
||||
bool RailStationBuildTool::DragNDropPlacementHandler::Execute(TileArea area) {
|
||||
bool RailStationBuildTool::DragNDropPlacementAction::Execute(TileArea area) {
|
||||
return ExecuteBuildCommand(this, &CcStation, area);
|
||||
}
|
||||
|
||||
std::optional<ObjectHighlight> RailStationBuildTool::DragNDropPlacementHandler::GetObjectHighlight(TileArea area) {
|
||||
return this->tool.GetStationObjectHighlight(area.tile, area.CMGetEndTile());
|
||||
std::optional<ObjectHighlight> RailStationBuildTool::DragNDropPlacementAction::GetObjectHighlight(TileArea area) {
|
||||
return ObjectHighlight::make_rail_station(area.tile, area.CMGetEndTile(), _railstation.orientation);
|
||||
}
|
||||
|
||||
std::optional<ObjectHighlight> RailStationBuildTool::SizedPlacementHandler::GetObjectHighlight(TileIndex tile) {
|
||||
return this->tool.GetStationObjectHighlight(tile, INVALID_TILE);
|
||||
std::optional<ObjectHighlight> RailStationBuildTool::SizedPlacementAction::GetObjectHighlight(TileIndex tile) {
|
||||
TileIndex end_tile;
|
||||
if (_railstation.orientation == AXIS_X)
|
||||
end_tile = TILE_ADDXY(tile, _settings_client.gui.station_platlength - 1, _settings_client.gui.station_numtracks - 1);
|
||||
else
|
||||
end_tile = TILE_ADDXY(tile, _settings_client.gui.station_numtracks - 1, _settings_client.gui.station_platlength - 1);
|
||||
return ObjectHighlight::make_rail_station(tile, end_tile, _railstation.orientation);
|
||||
}
|
||||
|
||||
// --- RailStationBuildTool implementation ---
|
||||
|
||||
RailStationBuildTool::RailStationBuildTool() : mode(Mode::SIZED) {
|
||||
this->action = make_up<SizedPlacementAction<SizedPlacementHandler>>(*this);
|
||||
this->action = make_sp<RailStationBuildTool::SizedPlacementAction>();
|
||||
}
|
||||
|
||||
void RailStationBuildTool::Update(Point pt, TileIndex tile) {
|
||||
@@ -1233,16 +1233,16 @@ void RailStationBuildTool::Update(Point pt, TileIndex tile) {
|
||||
if (new_mode != this->mode) {
|
||||
switch (new_mode) {
|
||||
case Mode::REMOVE:
|
||||
this->action = make_up<RemoveAction<RailStationBuildTool::RemoveHandler>>(*this);
|
||||
this->action = make_sp<RailStationBuildTool::RemoveAction>();
|
||||
break;
|
||||
case Mode::SELECT:
|
||||
this->action = make_up<StationSelectAction<StationBuildTool::StationSelectHandler>>(*this);
|
||||
this->action = make_sp<StationSelectAction>();
|
||||
break;
|
||||
case Mode::DRAGDROP:
|
||||
this->action = make_up<DragNDropPlacementAction<RailStationBuildTool::DragNDropPlacementHandler>>(*this);
|
||||
this->action = make_sp<RailStationBuildTool::DragNDropPlacementAction>();
|
||||
break;
|
||||
case Mode::SIZED:
|
||||
this->action = make_up<SizedPlacementAction<RailStationBuildTool::SizedPlacementHandler>>(*this);
|
||||
this->action = make_sp<RailStationBuildTool::SizedPlacementAction>();
|
||||
break;
|
||||
default:
|
||||
NOT_REACHED();
|
||||
@@ -1252,56 +1252,41 @@ void RailStationBuildTool::Update(Point pt, TileIndex tile) {
|
||||
this->action->Update(pt, tile);
|
||||
}
|
||||
|
||||
std::optional<ObjectHighlight> RailStationBuildTool::GetStationObjectHighlight(TileIndex start_tile, TileIndex end_tile) const {
|
||||
assert(IsValidTile(start_tile));
|
||||
assert(!IsValidTile(end_tile) || (TileX(start_tile) <= TileX(end_tile) && TileY(start_tile) <= TileY(end_tile)));
|
||||
if (!IsValidTile(end_tile)) {
|
||||
// Sized placement mode
|
||||
if (_railstation.orientation == AXIS_X)
|
||||
end_tile = TILE_ADDXY(start_tile, _settings_client.gui.station_platlength - 1, _settings_client.gui.station_numtracks - 1);
|
||||
else
|
||||
end_tile = TILE_ADDXY(start_tile, _settings_client.gui.station_numtracks - 1, _settings_client.gui.station_platlength - 1);
|
||||
} else {
|
||||
|
||||
}
|
||||
return ObjectHighlight::make_rail_station(start_tile, end_tile, _railstation.orientation);
|
||||
}
|
||||
|
||||
CursorID RailStationBuildTool::GetCursor() { return SPR_CURSOR_RAIL_STATION; }
|
||||
|
||||
// --- RoadStopBuildTool Handler Implementations ---
|
||||
// --- RoadStopBuildTool::RemoveAction ---
|
||||
|
||||
up<Command> RoadStopBuildTool::RemoveHandler::GetCommand(TileArea area) {
|
||||
up<Command> RoadStopBuildTool::RemoveAction::GetCommand(TileArea area) {
|
||||
auto cmd = make_up<cmd::RemoveRoadStop>(
|
||||
area.tile,
|
||||
area.w,
|
||||
area.h,
|
||||
this->tool.stop_type,
|
||||
this->stop_type,
|
||||
_fn_mod
|
||||
);
|
||||
auto rti = GetRoadTypeInfo(_cur_roadtype);
|
||||
cmd->with_error(rti->strings.err_remove_station[this->tool.stop_type]);
|
||||
cmd->with_error(rti->strings.err_remove_station[this->stop_type]);
|
||||
return cmd;
|
||||
}
|
||||
|
||||
bool RoadStopBuildTool::RemoveHandler::Execute(TileArea area) {
|
||||
bool RoadStopBuildTool::RemoveAction::Execute(TileArea area) {
|
||||
auto cmd = this->GetCommand(area);
|
||||
return cmd->post(&CcPlaySound_CONSTRUCTION_OTHER);
|
||||
}
|
||||
|
||||
up<Command> RoadStopBuildTool::DragNDropPlacementHandler::GetCommand(TileArea area, StationID to_join) {
|
||||
DiagDirection ddir = this->tool.ddir;
|
||||
bool drive_through = this->tool.ddir >= DIAGDIR_END;
|
||||
if (drive_through) ddir = static_cast<DiagDirection>(this->tool.ddir - DIAGDIR_END); // Adjust picker result to actual direction.
|
||||
up<Command> RoadStopBuildTool::DragNDropPlacementAction::GetCommand(TileArea area, StationID to_join) {
|
||||
DiagDirection ddir = this->ddir;
|
||||
bool drive_through = this->ddir >= DIAGDIR_END;
|
||||
if (drive_through) ddir = static_cast<DiagDirection>(this->ddir - DIAGDIR_END); // Adjust picker result to actual direction.
|
||||
|
||||
auto res = make_up<cmd::BuildRoadStop>(
|
||||
area.tile,
|
||||
area.w,
|
||||
area.h,
|
||||
this->tool.stop_type,
|
||||
this->stop_type,
|
||||
drive_through,
|
||||
ddir,
|
||||
_cur_roadtype,
|
||||
this->road_type,
|
||||
_roadstop_gui_settings.roadstop_class,
|
||||
_roadstop_gui_settings.roadstop_type,
|
||||
to_join,
|
||||
@@ -1311,27 +1296,52 @@ up<Command> RoadStopBuildTool::DragNDropPlacementHandler::GetCommand(TileArea ar
|
||||
return res;
|
||||
}
|
||||
|
||||
bool RoadStopBuildTool::DragNDropPlacementHandler::Execute(TileArea area) {
|
||||
bool RoadStopBuildTool::DragNDropPlacementAction::Execute(TileArea area) {
|
||||
return ExecuteBuildCommand(this, &CcRoadStop, area);
|
||||
}
|
||||
|
||||
std::optional<ObjectHighlight> RoadStopBuildTool::DragNDropPlacementHandler::GetObjectHighlight(TileArea area) {
|
||||
std::optional<ObjectHighlight> RoadStopBuildTool::DragNDropPlacementAction::GetObjectHighlight(TileArea area) {
|
||||
return ObjectHighlight::make_road_stop(
|
||||
area.tile,
|
||||
area.CMGetEndTile(),
|
||||
_cur_roadtype,
|
||||
this->tool.ddir,
|
||||
this->tool.stop_type == ROADSTOP_TRUCK,
|
||||
this->road_type,
|
||||
this->ddir,
|
||||
this->stop_type == ROADSTOP_TRUCK,
|
||||
_roadstop_gui_settings.roadstop_class,
|
||||
_roadstop_gui_settings.roadstop_type
|
||||
);
|
||||
}
|
||||
|
||||
// --- RoadStopBuildTool Implementation ---
|
||||
// --- RoadStopBuildTool implementation ---
|
||||
|
||||
RoadStopBuildTool::RoadStopBuildTool(RoadStopType stop_type) : mode(Mode::DRAGDROP), stop_type(stop_type)
|
||||
{
|
||||
this->action = make_up<DragNDropPlacementAction<RoadStopBuildTool::DragNDropPlacementHandler>>(*this);
|
||||
this->action = make_sp<RoadStopBuildTool::DragNDropPlacementAction>(_cur_roadtype, this->stop_type);
|
||||
}
|
||||
|
||||
void RoadStopBuildTool::DragNDropPlacementAction::Update(Point pt, TileIndex tile) {
|
||||
citymania::DragNDropPlacementAction::Update(pt, tile);
|
||||
this->ddir = DIAGDIR_NE;
|
||||
auto area = this->GetArea();
|
||||
if (pt.x != -1 && area.has_value()) {
|
||||
auto ddir = _roadstop_gui_settings.orientation;
|
||||
|
||||
if (ddir >= DIAGDIR_END && ddir < STATIONDIR_AUTO) {
|
||||
// When placed on road autorotate anyway
|
||||
if (ddir == STATIONDIR_X) {
|
||||
if (!CheckDriveThroughRoadStopDirection(area.value(), ROAD_X))
|
||||
ddir = STATIONDIR_Y;
|
||||
} else {
|
||||
if (!CheckDriveThroughRoadStopDirection(area.value(), ROAD_Y))
|
||||
ddir = STATIONDIR_X;
|
||||
}
|
||||
} else if (ddir == STATIONDIR_AUTO) {
|
||||
ddir = AddAutodetectionRotation(AutodetectRoadObjectDirection(tile, pt, this->road_type));
|
||||
} else if (ddir == STATIONDIR_AUTO_XY) {
|
||||
ddir = AddAutodetectionRotation(AutodetectDriveThroughRoadStopDirection(area.value(), pt, this->road_type));
|
||||
}
|
||||
this->ddir = ddir;
|
||||
}
|
||||
}
|
||||
|
||||
void RoadStopBuildTool::Update(Point pt, TileIndex tile) {
|
||||
@@ -1347,69 +1357,45 @@ void RoadStopBuildTool::Update(Point pt, TileIndex tile) {
|
||||
if (new_mode != this->mode) {
|
||||
switch (new_mode) {
|
||||
case Mode::REMOVE:
|
||||
this->action = make_up<RemoveAction<RoadStopBuildTool::RemoveHandler>>(*this);
|
||||
this->action = make_sp<RoadStopBuildTool::RemoveAction>(this->stop_type);
|
||||
break;
|
||||
case Mode::SELECT:
|
||||
this->action = make_up<StationSelectAction<StationBuildTool::StationSelectHandler>>(*this);
|
||||
this->action = make_sp<StationSelectAction>();
|
||||
break;
|
||||
case Mode::DRAGDROP:
|
||||
this->action = make_up<DragNDropPlacementAction<RoadStopBuildTool::DragNDropPlacementHandler>>(*this);
|
||||
this->action = make_sp<RoadStopBuildTool::DragNDropPlacementAction>(_cur_roadtype, this->stop_type);
|
||||
break;
|
||||
}
|
||||
this->mode = new_mode;
|
||||
}
|
||||
this->action->Update(pt, tile);
|
||||
|
||||
this->ddir = DIAGDIR_NE;
|
||||
auto area = this->action->GetArea();
|
||||
if (pt.x != -1 && this->mode == Mode::DRAGDROP && area.has_value()) {
|
||||
auto ddir = _roadstop_gui_settings.orientation;
|
||||
|
||||
if (ddir >= DIAGDIR_END && ddir < STATIONDIR_AUTO) {
|
||||
// When placed on road autorotate anyway
|
||||
if (ddir == STATIONDIR_X) {
|
||||
if (!CheckDriveThroughRoadStopDirection(area.value(), ROAD_X))
|
||||
ddir = STATIONDIR_Y;
|
||||
} else {
|
||||
if (!CheckDriveThroughRoadStopDirection(area.value(), ROAD_Y))
|
||||
ddir = STATIONDIR_X;
|
||||
}
|
||||
} else if (ddir == STATIONDIR_AUTO) {
|
||||
ddir = AddAutodetectionRotation(AutodetectRoadObjectDirection(tile, pt, _cur_roadtype));
|
||||
} else if (ddir == STATIONDIR_AUTO_XY) {
|
||||
ddir = AddAutodetectionRotation(AutodetectDriveThroughRoadStopDirection(area.value(), pt, _cur_roadtype));
|
||||
}
|
||||
this->ddir = ddir;
|
||||
}
|
||||
}
|
||||
|
||||
CursorID RoadStopBuildTool::GetCursor() {
|
||||
return this->stop_type == ROADSTOP_TRUCK ? SPR_CURSOR_TRUCK_STATION : SPR_CURSOR_BUS_STATION;
|
||||
}
|
||||
|
||||
// --- DockBuildTool Handler Implementations ---
|
||||
// --- DockBuildTool::RemoveAction ---
|
||||
|
||||
// RemoveHandler
|
||||
up<Command> DockBuildTool::RemoveHandler::GetCommand(TileArea area) {
|
||||
up<Command> DockBuildTool::RemoveAction::GetCommand(TileArea area) {
|
||||
// TODO: Implement dock removal command if available
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool DockBuildTool::RemoveHandler::Execute(TileArea area) {
|
||||
bool DockBuildTool::RemoveAction::Execute(TileArea area) {
|
||||
// TODO: Implement dock removal execution if available
|
||||
return false;
|
||||
}
|
||||
|
||||
// SizedPlacementHandler
|
||||
// --- DockBuildTool::SizedPlacementAction ---
|
||||
|
||||
std::optional<TileArea> DockBuildTool::SizedPlacementHandler::GetArea(TileIndex tile) const {
|
||||
if (!IsValidTile(tile)) return std::nullopt;
|
||||
DiagDirection dir = GetInclinedSlopeDirection(GetTileSlope(tile));
|
||||
TileIndex tile_to = (dir != INVALID_DIAGDIR ? TileAddByDiagDir(tile, ReverseDiagDir(dir)) : tile);
|
||||
return TileArea{tile, tile_to};
|
||||
std::optional<TileArea> DockBuildTool::SizedPlacementAction::GetArea() const {
|
||||
auto ddir = this->GetDirection(this->cur_tile);
|
||||
if (!ddir.has_value()) return std::nullopt;
|
||||
return TileArea{this->cur_tile, TileAddByDiagDir(this->cur_tile, *ddir)};
|
||||
}
|
||||
|
||||
up<Command> DockBuildTool::SizedPlacementHandler::GetCommand(TileIndex tile, StationID to_join) {
|
||||
up<Command> DockBuildTool::SizedPlacementAction::GetCommand(TileIndex tile, StationID to_join) {
|
||||
return make_up<cmd::BuildDock>(
|
||||
tile,
|
||||
to_join,
|
||||
@@ -1418,18 +1404,26 @@ up<Command> DockBuildTool::SizedPlacementHandler::GetCommand(TileIndex tile, Sta
|
||||
}
|
||||
|
||||
|
||||
bool DockBuildTool::SizedPlacementHandler::Execute(TileIndex tile) {
|
||||
bool DockBuildTool::SizedPlacementAction::Execute(TileIndex tile) {
|
||||
return ExecuteBuildCommand(this, &CcBuildDocks, tile);
|
||||
}
|
||||
|
||||
std::optional<ObjectHighlight> DockBuildTool::SizedPlacementHandler::GetObjectHighlight(TileIndex tile) {
|
||||
return ObjectHighlight::make_dock(tile, this->tool.ddir);
|
||||
std::optional<ObjectHighlight> DockBuildTool::SizedPlacementAction::GetObjectHighlight(TileIndex tile) {
|
||||
return ObjectHighlight::make_dock(tile, this->GetDirection(tile).value_or(DIAGDIR_SE));
|
||||
}
|
||||
|
||||
std::optional<DiagDirection> DockBuildTool::SizedPlacementAction::GetDirection(TileIndex tile) const {
|
||||
if (!IsValidTile(tile)) return std::nullopt;
|
||||
auto slope_dir = GetInclinedSlopeDirection(GetTileSlope(tile));
|
||||
if (slope_dir == INVALID_DIAGDIR) return std::nullopt;
|
||||
return ReverseDiagDir(slope_dir);
|
||||
};
|
||||
|
||||
|
||||
// --- DockBuildTool Implementation ---
|
||||
|
||||
DockBuildTool::DockBuildTool() : mode(Mode::SIZED) {
|
||||
this->action = make_up<SizedPlacementAction<DockBuildTool::SizedPlacementHandler>>(*this);
|
||||
this->action = make_sp<DockBuildTool::SizedPlacementAction>();
|
||||
}
|
||||
|
||||
void DockBuildTool::Update(Point pt, TileIndex tile) {
|
||||
@@ -1444,13 +1438,13 @@ void DockBuildTool::Update(Point pt, TileIndex tile) {
|
||||
if (new_mode != this->mode) {
|
||||
switch (new_mode) {
|
||||
case Mode::REMOVE:
|
||||
this->action = make_up<RemoveAction<DockBuildTool::RemoveHandler>>(*this);
|
||||
this->action = make_up<DockBuildTool::RemoveAction>();
|
||||
break;
|
||||
case Mode::SELECT:
|
||||
this->action = make_up<StationSelectAction<DockBuildTool::StationSelectHandler>>(*this);
|
||||
this->action = make_up<StationSelectAction>();
|
||||
break;
|
||||
case Mode::SIZED:
|
||||
this->action = make_up<SizedPlacementAction<DockBuildTool::SizedPlacementHandler>>(*this);
|
||||
this->action = make_up<DockBuildTool::SizedPlacementAction>();
|
||||
break;
|
||||
default:
|
||||
NOT_REACHED();
|
||||
@@ -1458,41 +1452,34 @@ void DockBuildTool::Update(Point pt, TileIndex tile) {
|
||||
this->mode = new_mode;
|
||||
}
|
||||
this->action->Update(pt, tile);
|
||||
this->ddir = DIAGDIR_SE;
|
||||
if (pt.x != -1 && this->mode == Mode::SIZED) {
|
||||
auto slope_dir = GetInclinedSlopeDirection(GetTileSlope(tile));
|
||||
if (slope_dir != INVALID_DIAGDIR)
|
||||
this->ddir = ReverseDiagDir(slope_dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CursorID DockBuildTool::GetCursor() {
|
||||
return SPR_CURSOR_DOCK;
|
||||
}
|
||||
|
||||
// --- AirportBuildTool Handler Implementations ---
|
||||
// --- AirportBuildTool::RemoveAction ---
|
||||
|
||||
// RemoveHandler
|
||||
up<Command> AirportBuildTool::RemoveHandler::GetCommand(TileArea area) {
|
||||
up<Command> AirportBuildTool::RemoveAction::GetCommand(TileArea area) {
|
||||
// TODO: Implement aiport removal command if available
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool AirportBuildTool::RemoveHandler::Execute(TileArea area) {
|
||||
bool AirportBuildTool::RemoveAction::Execute(TileArea area) {
|
||||
// TODO: Implement airport removal execution if available
|
||||
return false;
|
||||
}
|
||||
|
||||
// SizedPlacementHandler
|
||||
// --- AirportBuildTool::SizedPlacementAction ---
|
||||
|
||||
std::optional<TileArea> AirportBuildTool::SizedPlacementHandler::GetArea(TileIndex tile) const {
|
||||
if (!IsValidTile(tile)) return std::nullopt;
|
||||
std::optional<TileArea> AirportBuildTool::SizedPlacementAction::GetArea() const {
|
||||
if (!IsValidTile(this->cur_tile)) return std::nullopt;
|
||||
auto as = AirportClass::Get(_selected_airport_class)->GetSpec(_selected_airport_index);
|
||||
if (as == nullptr) return std::nullopt;
|
||||
return TileArea{tile, as->size_x, as->size_y};
|
||||
return TileArea{this->cur_tile, as->size_x, as->size_y};
|
||||
}
|
||||
|
||||
up<Command> AirportBuildTool::SizedPlacementHandler::GetCommand(TileIndex tile, StationID to_join) {
|
||||
up<Command> AirportBuildTool::SizedPlacementAction::GetCommand(TileIndex tile, StationID to_join) {
|
||||
auto as = AirportClass::Get(_selected_airport_class)->GetSpec(_selected_airport_index);
|
||||
if (as == nullptr) return nullptr;
|
||||
byte airport_type = as->GetIndex();
|
||||
@@ -1508,26 +1495,26 @@ up<Command> AirportBuildTool::SizedPlacementHandler::GetCommand(TileIndex tile,
|
||||
return cmd;
|
||||
}
|
||||
|
||||
bool AirportBuildTool::SizedPlacementHandler::Execute(TileIndex tile) {
|
||||
bool AirportBuildTool::SizedPlacementAction::Execute(TileIndex tile) {
|
||||
ExecuteBuildCommand(this, &CcBuildAirport, tile);
|
||||
}
|
||||
|
||||
std::optional<ObjectHighlight> AirportBuildTool::SizedPlacementHandler::GetObjectHighlight(TileIndex tile) {
|
||||
std::optional<ObjectHighlight> AirportBuildTool::SizedPlacementAction::GetObjectHighlight(TileIndex tile) {
|
||||
byte airport_type = AirportClass::Get(_selected_airport_class)->GetSpec(_selected_airport_index)->GetIndex();
|
||||
byte layout = _selected_airport_layout;
|
||||
return ObjectHighlight::make_airport(tile, airport_type, layout);
|
||||
}
|
||||
|
||||
std::pair<StationCoverageType, uint> AirportBuildTool::SizedPlacementHandler::GetCatchmentParams() {
|
||||
std::pair<StationCoverageType, uint> AirportBuildTool::SizedPlacementAction::GetCatchmentParams() {
|
||||
auto rad = AirportClass::Get(_selected_airport_class)->GetSpec(_selected_airport_index)->catchment;
|
||||
return {SCT_ALL, rad};
|
||||
}
|
||||
|
||||
|
||||
// --- AirportBuildTool Implementation ---
|
||||
// --- AirportBuildTool implementation ---
|
||||
|
||||
AirportBuildTool::AirportBuildTool() : mode(Mode::SIZED) {
|
||||
this->action = make_up<SizedPlacementAction<AirportBuildTool::SizedPlacementHandler>>(*this);
|
||||
this->action = make_sp<AirportBuildTool::SizedPlacementAction>();
|
||||
}
|
||||
|
||||
void AirportBuildTool::Update(Point pt, TileIndex tile) {
|
||||
@@ -1542,13 +1529,13 @@ void AirportBuildTool::Update(Point pt, TileIndex tile) {
|
||||
if (new_mode != this->mode) {
|
||||
switch (new_mode) {
|
||||
case Mode::REMOVE:
|
||||
this->action = make_up<RemoveAction<AirportBuildTool::RemoveHandler>>(*this);
|
||||
this->action = make_sp<AirportBuildTool::RemoveAction>();
|
||||
break;
|
||||
case Mode::SELECT:
|
||||
this->action = make_up<StationSelectAction<AirportBuildTool::StationSelectHandler>>(*this);
|
||||
this->action = make_sp<StationSelectAction>();
|
||||
break;
|
||||
case Mode::SIZED:
|
||||
this->action = make_up<SizedPlacementAction<AirportBuildTool::SizedPlacementHandler>>(*this);
|
||||
this->action = make_sp<AirportBuildTool::SizedPlacementAction>();
|
||||
break;
|
||||
default:
|
||||
NOT_REACHED();
|
||||
@@ -1562,17 +1549,4 @@ CursorID AirportBuildTool::GetCursor() {
|
||||
return SPR_CURSOR_AIRPORT;
|
||||
}
|
||||
|
||||
// --- Explicit template instantiations for handlers ---
|
||||
template class StationSelectAction<StationBuildTool::StationSelectHandler>;
|
||||
|
||||
template class DragNDropPlacementAction<RailStationBuildTool::DragNDropPlacementHandler>;
|
||||
template class RemoveAction<RailStationBuildTool::RemoveHandler>;
|
||||
template class SizedPlacementAction<RailStationBuildTool::SizedPlacementHandler>;
|
||||
|
||||
template class RemoveAction<RoadStopBuildTool::RemoveHandler>;
|
||||
template class DragNDropPlacementAction<RoadStopBuildTool::DragNDropPlacementHandler>;
|
||||
|
||||
template class RemoveAction<DockBuildTool::RemoveHandler>;
|
||||
template class SizedPlacementAction<DockBuildTool::SizedPlacementHandler>;
|
||||
|
||||
} // namespace citymania
|
||||
|
||||
@@ -63,25 +63,11 @@ struct OverlayParams {
|
||||
StationCoverageType coverage_type;
|
||||
};
|
||||
|
||||
// Remove action classes
|
||||
class RemoveHandler {
|
||||
public:
|
||||
virtual ~RemoveHandler() = default;
|
||||
virtual up<Command> GetCommand(TileArea area) = 0;
|
||||
virtual bool Execute(TileArea area) = 0;
|
||||
};
|
||||
template<typename Handler>
|
||||
concept ImplementsRemoveHandler = std::derived_from<Handler, RemoveHandler>;
|
||||
|
||||
template<ImplementsRemoveHandler Handler>
|
||||
class RemoveAction : public Action {
|
||||
private:
|
||||
sp<Handler> handler;
|
||||
protected:
|
||||
TileIndex start_tile = INVALID_TILE;
|
||||
TileIndex cur_tile = INVALID_TILE;
|
||||
public:
|
||||
template<typename T>
|
||||
RemoveAction(T &tool) { this->handler = make_sp<Handler>(tool); };
|
||||
~RemoveAction() override = default;
|
||||
void Update(Point pt, TileIndex tile) override;
|
||||
std::optional<TileArea> GetArea() const override;
|
||||
@@ -89,25 +75,14 @@ public:
|
||||
void HandleMouseRelease() override;
|
||||
ToolGUIInfo GetGUIInfo() override;
|
||||
void OnStationRemoved(const Station *) override;
|
||||
virtual up<Command> GetCommand(TileArea area) = 0;
|
||||
virtual bool Execute(TileArea area) = 0;
|
||||
};
|
||||
|
||||
|
||||
// StationSelect classes
|
||||
class StationSelectHandler {
|
||||
public:
|
||||
virtual ~StationSelectHandler() = default;
|
||||
};
|
||||
template<typename Handler>
|
||||
concept ImplementsStationSelectHandler = std::derived_from<Handler, StationSelectHandler>;
|
||||
|
||||
template<ImplementsStationSelectHandler Handler>
|
||||
class StationSelectAction : public Action {
|
||||
private:
|
||||
sp<Handler> handler;
|
||||
protected:
|
||||
TileIndex cur_tile = INVALID_TILE;
|
||||
public:
|
||||
template<typename T>
|
||||
StationSelectAction(T &tool) { this->handler = make_sp<Handler>(tool); };
|
||||
~StationSelectAction() override = default;
|
||||
void Update(Point pt, TileIndex tile) override;
|
||||
bool HandleMousePress() override;
|
||||
@@ -123,57 +98,27 @@ public:
|
||||
ToolGUIInfo PrepareGUIInfo(std::optional<ObjectHighlight> ohl, up<Command> cmd, StationCoverageType sct, uint rad);
|
||||
};
|
||||
|
||||
// SizedPlacement classes
|
||||
class SizedPlacementHandler {
|
||||
public:
|
||||
virtual ~SizedPlacementHandler() = default;
|
||||
virtual up<Command> GetCommand(TileIndex tile, StationID to_join) = 0;
|
||||
virtual bool Execute(TileIndex tile) = 0;
|
||||
virtual std::optional<ObjectHighlight> GetObjectHighlight(TileIndex tile) = 0;
|
||||
virtual std::pair<StationCoverageType, uint> GetCatchmentParams() = 0;
|
||||
virtual std::optional<TileArea> GetArea(TileIndex tile) const = 0;
|
||||
};
|
||||
template<typename Handler>
|
||||
concept ImplementsSizedPlacementHandler = std::derived_from<Handler, SizedPlacementHandler>;
|
||||
|
||||
template<ImplementsSizedPlacementHandler Handler>
|
||||
class SizedPlacementAction : public PlacementAction {
|
||||
private:
|
||||
sp<Handler> handler;
|
||||
protected:
|
||||
TileIndex cur_tile = INVALID_TILE;
|
||||
public:
|
||||
template<typename T>
|
||||
SizedPlacementAction(T &tool) { this->handler = make_sp<Handler>(tool); };
|
||||
~SizedPlacementAction() override = default;
|
||||
void Update(Point pt, TileIndex tile) override;
|
||||
std::optional<TileArea> GetArea() const override { return this->handler->GetArea(this->cur_tile); }
|
||||
bool HandleMousePress() override;
|
||||
void HandleMouseRelease() override;
|
||||
ToolGUIInfo GetGUIInfo() override;
|
||||
void OnStationRemoved(const Station *) override;
|
||||
};
|
||||
|
||||
// DragNDropPlacement classes
|
||||
class DragNDropPlacementHandler {
|
||||
public:
|
||||
virtual ~DragNDropPlacementHandler() = default;
|
||||
virtual up<Command> GetCommand(TileArea area, StationID to_join) = 0;
|
||||
virtual bool Execute(TileArea area) = 0;
|
||||
virtual std::optional<ObjectHighlight> GetObjectHighlight(TileArea area) = 0;
|
||||
virtual up<Command> GetCommand(TileIndex tile, StationID to_join) = 0;
|
||||
virtual bool Execute(TileIndex tile) = 0;
|
||||
virtual std::optional<ObjectHighlight> GetObjectHighlight(TileIndex tile) = 0;
|
||||
virtual std::pair<StationCoverageType, uint> GetCatchmentParams() = 0;
|
||||
};
|
||||
template<typename Handler>
|
||||
concept ImplementsDragNDropPlacementHandler = std::derived_from<Handler, DragNDropPlacementHandler>;
|
||||
|
||||
template<ImplementsDragNDropPlacementHandler Handler>
|
||||
class DragNDropPlacementAction : public PlacementAction {
|
||||
private:
|
||||
protected:
|
||||
TileIndex start_tile = INVALID_TILE;
|
||||
TileIndex cur_tile = INVALID_TILE;
|
||||
sp<Handler> handler;
|
||||
public:
|
||||
template<typename T>
|
||||
DragNDropPlacementAction(T &tool) { this->handler = make_sp<Handler>(tool); };
|
||||
~DragNDropPlacementAction() override = default;
|
||||
void Update(Point pt, TileIndex tile) override;
|
||||
std::optional<TileArea> GetArea() const override;
|
||||
@@ -181,20 +126,14 @@ public:
|
||||
void HandleMouseRelease() override;
|
||||
ToolGUIInfo GetGUIInfo() override;
|
||||
void OnStationRemoved(const Station *) override;
|
||||
virtual up<Command> GetCommand(TileArea area, StationID to_join) = 0;
|
||||
virtual bool Execute(TileArea area) = 0;
|
||||
virtual std::optional<ObjectHighlight> GetObjectHighlight(TileArea area) = 0;
|
||||
virtual std::pair<StationCoverageType, uint> GetCatchmentParams() = 0;
|
||||
};
|
||||
|
||||
class StationBuildTool : public Tool {
|
||||
public:
|
||||
// static StationID station_to_join;
|
||||
// static bool ambigous_join;
|
||||
|
||||
class StationSelectHandler : public citymania::StationSelectHandler {
|
||||
public:
|
||||
StationBuildTool &tool;
|
||||
StationSelectHandler(StationBuildTool &tool) : tool(tool) {}
|
||||
~StationSelectHandler() {}
|
||||
};
|
||||
|
||||
StationBuildTool();
|
||||
~StationBuildTool() override = default;
|
||||
ToolGUIInfo GetGUIInfo() override {
|
||||
@@ -210,42 +149,32 @@ protected:
|
||||
// RailStationBuildTool
|
||||
class RailStationBuildTool : public StationBuildTool {
|
||||
private:
|
||||
class RemoveHandler : public citymania::RemoveHandler {
|
||||
class RemoveAction : public citymania::RemoveAction {
|
||||
public:
|
||||
RailStationBuildTool &tool;
|
||||
// TODO storing tools in handlers isn't safe because of shared pointers
|
||||
RemoveHandler(RailStationBuildTool &tool) : tool(tool) {}
|
||||
~RemoveHandler() override = default;
|
||||
~RemoveAction() override = default;
|
||||
up<Command> GetCommand(TileArea area) override;
|
||||
bool Execute(TileArea area) override;
|
||||
};
|
||||
|
||||
class SizedPlacementHandler : public citymania::SizedPlacementHandler {
|
||||
class SizedPlacementAction : public citymania::SizedPlacementAction {
|
||||
public:
|
||||
RailStationBuildTool &tool;
|
||||
SizedPlacementHandler(RailStationBuildTool &tool) : tool(tool) {}
|
||||
~SizedPlacementHandler() override = default;
|
||||
~SizedPlacementAction() override = default;
|
||||
up<Command> GetCommand(TileIndex tile, StationID to_join) override;
|
||||
bool Execute(TileIndex tile) override;
|
||||
std::optional<ObjectHighlight> GetObjectHighlight(TileIndex tile) override;
|
||||
std::pair<StationCoverageType, uint> GetCatchmentParams() override { return {this->tool.GetCatchmentParams()}; };
|
||||
std::optional<TileArea> GetArea(TileIndex tile) const override;
|
||||
std::pair<StationCoverageType, uint> GetCatchmentParams() override { return {SCT_ALL, CA_TRAIN}; };
|
||||
std::optional<TileArea> GetArea() const override;
|
||||
};
|
||||
|
||||
class DragNDropPlacementHandler: public citymania::DragNDropPlacementHandler {
|
||||
class DragNDropPlacementAction: public citymania::DragNDropPlacementAction {
|
||||
public:
|
||||
RailStationBuildTool &tool;
|
||||
DragNDropPlacementHandler(RailStationBuildTool &tool) :tool{tool} {}
|
||||
~DragNDropPlacementHandler() override = default;
|
||||
~DragNDropPlacementAction() override = default;
|
||||
up<Command> GetCommand(TileArea area, StationID to_join) override;
|
||||
bool Execute(TileArea area) override;
|
||||
std::optional<ObjectHighlight> GetObjectHighlight(TileArea area) override;
|
||||
std::pair<StationCoverageType, uint> GetCatchmentParams() override { return {this->tool.GetCatchmentParams()}; };
|
||||
std::pair<StationCoverageType, uint> GetCatchmentParams() override { return {SCT_ALL, CA_TRAIN}; };
|
||||
};
|
||||
|
||||
std::optional<ObjectHighlight> GetStationObjectHighlight(TileIndex start_tile, TileIndex end_tile) const;
|
||||
std::pair<StationCoverageType, uint> GetCatchmentParams() { return {SCT_ALL, CA_TRAIN}; };
|
||||
|
||||
public:
|
||||
RailStationBuildTool();
|
||||
~RailStationBuildTool() override = default;
|
||||
@@ -259,30 +188,38 @@ private:
|
||||
// RoadStopBuildTool
|
||||
class RoadStopBuildTool : public StationBuildTool {
|
||||
private:
|
||||
class RemoveHandler : public citymania::RemoveHandler {
|
||||
class RemoveAction : public citymania::RemoveAction {
|
||||
public:
|
||||
RoadStopBuildTool &tool;
|
||||
RemoveHandler(RoadStopBuildTool &tool) : tool(tool) {}
|
||||
~RemoveHandler() override = default;
|
||||
RoadStopType stop_type;
|
||||
RemoveAction(RoadStopType stop_type) : stop_type{stop_type} {}
|
||||
~RemoveAction() override = default;
|
||||
up<Command> GetCommand(TileArea area) override;
|
||||
bool Execute(TileArea area) override;
|
||||
};
|
||||
|
||||
class DragNDropPlacementHandler: public citymania::DragNDropPlacementHandler {
|
||||
class DragNDropPlacementAction: public citymania::DragNDropPlacementAction {
|
||||
public:
|
||||
RoadStopBuildTool &tool;
|
||||
DragNDropPlacementHandler(RoadStopBuildTool &tool) :tool{tool} {}
|
||||
~DragNDropPlacementHandler() override = default;
|
||||
RoadType road_type;
|
||||
RoadStopType stop_type;
|
||||
DiagDirection ddir = DIAGDIR_NE;
|
||||
// RoadStopClassID spec_class;
|
||||
// uint16_t spec_index;
|
||||
|
||||
DragNDropPlacementAction(RoadType road_type, RoadStopType stop_type)
|
||||
:road_type{road_type}, stop_type{stop_type} {}
|
||||
// DragNDropPlacementHandler(DiagDirection ddir, RoadStopType stop_type, RoadStopClassID spec_class, uint16_t spec_index;)
|
||||
// :ddir{ddir}, stop_type{stop_type}, spec_class{spec_class}, spec_index{spec_index} {}
|
||||
~DragNDropPlacementAction() override = default;
|
||||
void Update(Point pt, TileIndex tile) override;
|
||||
up<Command> GetCommand(TileArea area, StationID to_join) override;
|
||||
bool Execute(TileArea area) override;
|
||||
std::optional<ObjectHighlight> GetObjectHighlight(TileArea area) override;
|
||||
std::pair<StationCoverageType, uint> GetCatchmentParams() override { return this->tool.GetCatchmentParams(); };
|
||||
std::pair<StationCoverageType, uint> GetCatchmentParams() override {
|
||||
if (this->stop_type == ROADSTOP_BUS) return {SCT_PASSENGERS_ONLY, CA_BUS};
|
||||
else return {SCT_NON_PASSENGERS_ONLY, CA_TRUCK};
|
||||
}
|
||||
};
|
||||
|
||||
std::pair<StationCoverageType, uint> GetCatchmentParams() {
|
||||
if (this->stop_type == ROADSTOP_BUS) return {SCT_PASSENGERS_ONLY, CA_BUS};
|
||||
else return {SCT_NON_PASSENGERS_ONLY, CA_TRUCK};
|
||||
};
|
||||
public:
|
||||
RoadStopBuildTool(RoadStopType stop_type);
|
||||
~RoadStopBuildTool() override = default;
|
||||
@@ -292,31 +229,27 @@ private:
|
||||
enum class Mode { REMOVE, SELECT, DRAGDROP };
|
||||
Mode mode;
|
||||
RoadStopType stop_type;
|
||||
DiagDirection ddir = DIAGDIR_NE;
|
||||
};
|
||||
|
||||
// --- DockBuildTool ---
|
||||
class DockBuildTool : public StationBuildTool {
|
||||
private:
|
||||
class RemoveHandler : public citymania::RemoveHandler {
|
||||
class RemoveAction : public citymania::RemoveAction {
|
||||
public:
|
||||
DockBuildTool &tool;
|
||||
RemoveHandler(DockBuildTool &tool) : tool(tool) {}
|
||||
~RemoveHandler() override = default;
|
||||
~RemoveAction() override = default;
|
||||
up<Command> GetCommand(TileArea area) override;
|
||||
bool Execute(TileArea area) override;
|
||||
};
|
||||
|
||||
class SizedPlacementHandler : public citymania::SizedPlacementHandler {
|
||||
class SizedPlacementAction : public citymania::SizedPlacementAction {
|
||||
public:
|
||||
DockBuildTool &tool;
|
||||
SizedPlacementHandler(DockBuildTool &tool) : tool(tool) {}
|
||||
~SizedPlacementHandler() override = default;
|
||||
~SizedPlacementAction() override = default;
|
||||
up<Command> GetCommand(TileIndex tile, StationID to_join) override;
|
||||
bool Execute(TileIndex tile) override;
|
||||
std::optional<ObjectHighlight> GetObjectHighlight(TileIndex tile) override;
|
||||
std::pair<StationCoverageType, uint> GetCatchmentParams() override { return {SCT_ALL, CA_DOCK}; };
|
||||
std::optional<TileArea> GetArea(TileIndex tile) const override;
|
||||
std::optional<TileArea> GetArea() const override;
|
||||
std::optional<DiagDirection> GetDirection(TileIndex tile) const;
|
||||
};
|
||||
|
||||
public:
|
||||
@@ -327,31 +260,26 @@ public:
|
||||
private:
|
||||
enum class Mode { REMOVE, SELECT, SIZED };
|
||||
Mode mode;
|
||||
DiagDirection ddir;
|
||||
};
|
||||
|
||||
// --- AirportBuildTool ---
|
||||
class AirportBuildTool : public StationBuildTool {
|
||||
private:
|
||||
class RemoveHandler : public citymania::RemoveHandler {
|
||||
class RemoveAction : public citymania::RemoveAction {
|
||||
public:
|
||||
AirportBuildTool &tool;
|
||||
RemoveHandler(AirportBuildTool &tool) : tool(tool) {}
|
||||
~RemoveHandler() override = default;
|
||||
~RemoveAction() override = default;
|
||||
up<Command> GetCommand(TileArea area) override;
|
||||
bool Execute(TileArea area) override;
|
||||
};
|
||||
|
||||
class SizedPlacementHandler : public citymania::SizedPlacementHandler {
|
||||
class SizedPlacementAction : public citymania::SizedPlacementAction {
|
||||
public:
|
||||
AirportBuildTool &tool;
|
||||
SizedPlacementHandler(AirportBuildTool &tool) : tool(tool) {}
|
||||
~SizedPlacementHandler() override = default;
|
||||
~SizedPlacementAction() override = default;
|
||||
up<Command> GetCommand(TileIndex tile, StationID to_join) override;
|
||||
bool Execute(TileIndex tile) override;
|
||||
std::optional<ObjectHighlight> GetObjectHighlight(TileIndex tile) override;
|
||||
std::pair<StationCoverageType, uint> GetCatchmentParams() override;
|
||||
std::optional<TileArea> GetArea(TileIndex tile) const override;
|
||||
std::optional<TileArea> GetArea() const override;
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
Reference in New Issue
Block a user