Fix non-improved station joning
This commit is contained in:
@@ -188,9 +188,6 @@ struct TileZoning {
|
||||
static TileZoning *_mz = nullptr;
|
||||
static IndustryType _industry_forbidden_tiles = INVALID_INDUSTRYTYPE;
|
||||
|
||||
extern const Station *_station_to_join;
|
||||
extern const Station *_highlight_station_to_join;
|
||||
extern TileArea _highlight_join_area;
|
||||
extern bool _fn_mod;
|
||||
|
||||
std::set<std::pair<uint32, const Town*>, std::greater<std::pair<uint32, const Town*>>> _town_cache;
|
||||
@@ -1775,8 +1772,6 @@ static void SetStationSelectionHighlight(const TileInfo *ti, TileHighlight &th)
|
||||
bool draw_selection = ((_thd.drawstyle & HT_DRAG_MASK) == HT_RECT && _thd.outersize.x > 0);
|
||||
const Station *highlight_station = _viewport_highlight_station;
|
||||
|
||||
if (_highlight_station_to_join) highlight_station = _highlight_station_to_join;
|
||||
|
||||
if (draw_selection) {
|
||||
// const SpriteID pal[] = {SPR_PALETTE_ZONING_RED, SPR_PALETTE_ZONING_YELLOW, SPR_PALETTE_ZONING_LIGHT_BLUE, SPR_PALETTE_ZONING_GREEN};
|
||||
// auto color = pal[(int)_station_building_status];
|
||||
@@ -1819,20 +1814,6 @@ static void SetStationSelectionHighlight(const TileInfo *ti, TileHighlight &th)
|
||||
const SpriteID pal2[] = {PAL_NONE, CM_PALETTE_TINT_WHITE, CM_PALETTE_TINT_BLUE};
|
||||
th.ground_pal = th.structure_pal = pal2[b.second];
|
||||
}
|
||||
|
||||
if (_highlight_join_area.tile != INVALID_TILE) {
|
||||
auto b = CalcTileBorders(ti->tile, [](TileIndex t) {
|
||||
return _highlight_join_area.Contains(t) ? 1 : 0;
|
||||
});
|
||||
th.add_border(b.first, CM_SPR_PALETTE_ZONING_LIGHT_BLUE);
|
||||
if (b.second) {
|
||||
switch (th.ground_pal) {
|
||||
case CM_PALETTE_TINT_WHITE: th.ground_pal = th.structure_pal = CM_PALETTE_TINT_CYAN_WHITE; break;
|
||||
case CM_PALETTE_TINT_BLUE: break;
|
||||
default: th.ground_pal = th.structure_pal = CM_PALETTE_TINT_CYAN; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CalcCBAcceptanceBorders(TileHighlight &th, TileIndex tile, SpriteID border_pal, SpriteID ground_pal) {
|
||||
|
||||
@@ -37,10 +37,12 @@
|
||||
#include "generated/cm_gen_commands.hpp"
|
||||
|
||||
#include <cassert>
|
||||
#include <complex>
|
||||
#include <cstdio>
|
||||
#include <optional>
|
||||
#include <sstream>
|
||||
#include <unordered_set>
|
||||
#include <variant>
|
||||
|
||||
bool _remove_button_clicked; // replace vanilla static vars
|
||||
|
||||
@@ -83,13 +85,20 @@ extern byte _selected_airport_layout; ///< selected airport layout numb
|
||||
|
||||
namespace citymania {
|
||||
|
||||
const Station *_highlight_station_to_join = nullptr;
|
||||
TileArea _highlight_join_area;
|
||||
|
||||
bool UseImprovedStationJoin() {
|
||||
return _settings_client.gui.cm_use_improved_station_join && _settings_game.station.distant_join_stations && _settings_game.station.adjacent_stations;
|
||||
}
|
||||
|
||||
namespace StationAction {
|
||||
struct Create {};
|
||||
struct Join { StationID station; };
|
||||
struct Picker {};
|
||||
|
||||
using Mode = std::variant<Create, Join, Picker>;
|
||||
};
|
||||
|
||||
StationAction::Mode _station_action = StationAction::Create{};
|
||||
|
||||
static const int MAX_TILE_EXTENT_LEFT = ZOOM_LVL_BASE * TILE_PIXELS; ///< Maximum left extent of tile relative to north corner.
|
||||
static const int MAX_TILE_EXTENT_RIGHT = ZOOM_LVL_BASE * TILE_PIXELS; ///< Maximum right extent of tile relative to north corner.
|
||||
static const int MAX_TILE_EXTENT_TOP = ZOOM_LVL_BASE * MAX_BUILDING_PIXELS; ///< Maximum top extent of tile relative to north corner (not considering bridges).
|
||||
@@ -599,8 +608,8 @@ bool IsHighlightCoverageStation(const Station *station) {
|
||||
|
||||
void OnStationRemoved(const Station *station) {
|
||||
// if (_last_built_station == station) _last_built_station = nullptr;
|
||||
if (StationBuildTool::station_to_join == station->index) {
|
||||
StationBuildTool::station_to_join = INVALID_STATION;
|
||||
if (auto mode = std::get_if<StationAction::Join>(&_station_action); mode && mode->station == station->index) {
|
||||
_station_action = StationAction::Create{};
|
||||
UpdateActiveTool();
|
||||
}
|
||||
if (_selected_station == station->index) {
|
||||
@@ -753,15 +762,25 @@ void RemoveAction<Handler>::OnStationRemoved(const Station *) {}
|
||||
ToolGUIInfo PlacementAction::PrepareGUIInfo(std::optional<ObjectHighlight> ohl, up<Command> cmd, StationCoverageType sct, uint rad) {
|
||||
if (!cmd || !ohl.has_value()) return {};
|
||||
ohl.value().UpdateTiles();
|
||||
auto palette = CM_PALETTE_TINT_WHITE;
|
||||
auto area = ohl.value().GetArea();
|
||||
|
||||
auto cost = cmd->test();
|
||||
if (std::holds_alternative<StationAction::Picker>(_station_action)) {
|
||||
palette = CM_PALETTE_TINT_YELLOW;
|
||||
} else {
|
||||
palette = cost.Succeeded() ? CM_PALETTE_TINT_WHITE : CM_PALETTE_TINT_RED_DEEP;
|
||||
}
|
||||
|
||||
bool show_coverage = _settings_client.gui.station_show_coverage;
|
||||
|
||||
Station *to_join = nullptr;
|
||||
if (auto mode = std::get_if<StationAction::Join>(&_station_action))
|
||||
to_join = Station::GetIfValid(mode->station);
|
||||
auto hlmap = PrepareHighilightMap(
|
||||
UseImprovedStationJoin() ? Station::GetIfValid(StationBuildTool::station_to_join) : nullptr,
|
||||
to_join,
|
||||
ohl.value(),
|
||||
cost.Succeeded() ? CM_PALETTE_TINT_WHITE : CM_PALETTE_TINT_RED_DEEP,
|
||||
palette,
|
||||
true,
|
||||
show_coverage,
|
||||
rad
|
||||
@@ -771,14 +790,13 @@ ToolGUIInfo PlacementAction::PrepareGUIInfo(std::optional<ObjectHighlight> ohl,
|
||||
|
||||
BuildInfoOverlayData data;
|
||||
|
||||
if (StationBuildTool::station_to_join != INVALID_STATION) {
|
||||
SetDParam(0, StationBuildTool::station_to_join);
|
||||
if (auto mode = std::get_if<StationAction::Join>(&_station_action)) {
|
||||
SetDParam(0, mode->station);
|
||||
data.emplace_back(0, PAL_NONE, GetString(CM_STR_BULID_INFO_OVERLAY_JOIN_STATION));
|
||||
} else {
|
||||
data.emplace_back(0, PAL_NONE, GetString(CM_STR_BULID_INFO_OVERLAY_NEW_STATION));
|
||||
}
|
||||
|
||||
auto area = ohl.value().GetArea();
|
||||
if (area.has_value()) {
|
||||
// Add supplied cargo information
|
||||
// TODO can we use rad_area since we already have it?
|
||||
@@ -881,6 +899,57 @@ ToolGUIInfo PlacementAction::PrepareGUIInfo(std::optional<ObjectHighlight> ohl,
|
||||
template <ImplementsSizedPlacementHandler Handler>
|
||||
void SizedPlacementAction<Handler>::Update(Point, TileIndex tile) {
|
||||
this->cur_tile = tile;
|
||||
if (UseImprovedStationJoin()) return;
|
||||
|
||||
_station_action = StationAction::Create{};
|
||||
|
||||
auto area = this->GetArea();
|
||||
if (!area.has_value()) return;
|
||||
auto cmdptr = this->handler.GetCommand(tile, INVALID_STATION);
|
||||
auto cmd = dynamic_cast<cmd::BuildRailStation *>(cmdptr.get());
|
||||
if (cmd == nullptr) return;
|
||||
|
||||
if (!_settings_game.station.distant_join_stations && _fn_mod) return;
|
||||
|
||||
area->Expand(1);
|
||||
area->ClampToMap();
|
||||
StationID to_join = INVALID_STATION;
|
||||
bool ambigous_join = false;
|
||||
for (auto tile : area.value()) {
|
||||
if (IsTileType(tile, MP_STATION) && GetTileOwner(tile) == _local_company) {
|
||||
Station *st = Station::GetByTile(tile);
|
||||
if (st == nullptr || st->index == to_join) continue;
|
||||
if (to_join != INVALID_STATION) {
|
||||
to_join = INVALID_STATION;
|
||||
if (_settings_game.station.distant_join_stations)
|
||||
ambigous_join = true;
|
||||
break;
|
||||
}
|
||||
to_join = st->index;
|
||||
// TODO check for command to return multiple? but also check each to
|
||||
// see if they can be built
|
||||
// if (this->GetCommand(true, st->index)->test().Succeeded()) {
|
||||
// if (this->station_to_join != INVALID_STATION) {
|
||||
// this->station_to_join = INVALID_STATION;
|
||||
// this->palette = CM_PALETTE_TINT_YELLOW;
|
||||
// break;
|
||||
// } else this->station_to_join = st->index;
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
if (!_settings_game.station.distant_join_stations) return;
|
||||
|
||||
if (ambigous_join) _station_action = StationAction::Picker{};
|
||||
else if (to_join != INVALID_STATION) _station_action = StationAction::Join{to_join};
|
||||
else _station_action = StationAction::Create{};
|
||||
|
||||
// cmd->station_to_join = NEW_STATION;
|
||||
// cmd->adjacent = true;
|
||||
|
||||
// if (StationBuildTool::station_to_join == INVALID_STATION && !cmd->test().Succeeded()) {
|
||||
// StationBuildTool::ambigous_join = false;
|
||||
// }
|
||||
}
|
||||
|
||||
template <ImplementsSizedPlacementHandler Handler>
|
||||
@@ -967,12 +1036,11 @@ template <ImplementsStationSelectHandler Handler>
|
||||
void StationSelectAction<Handler>::HandleMouseRelease() {
|
||||
// TODO station sign click
|
||||
if (!IsValidTile(this->cur_tile)) return;
|
||||
this->selected_station = INVALID_STATION;
|
||||
_station_action = StationAction::Create{};
|
||||
if (IsTileType(this->cur_tile, MP_STATION)) {
|
||||
auto st = Station::GetByTile(this->cur_tile);
|
||||
if (st) this->selected_station = st->index;
|
||||
if (st) _station_action = StationAction::Join{st->index};
|
||||
}
|
||||
this->handler.SelectStationToJoin(this->selected_station);
|
||||
}
|
||||
|
||||
template <ImplementsStationSelectHandler Handler>
|
||||
@@ -993,13 +1061,11 @@ ToolGUIInfo StationSelectAction<Handler>::GetGUIInfo() {
|
||||
|
||||
template <ImplementsStationSelectHandler Handler>
|
||||
void StationSelectAction<Handler>::OnStationRemoved(const Station *station) {
|
||||
if (this->selected_station == station->index) this->selected_station = INVALID_STATION;
|
||||
// if (this->selected_station == station->index) this->selected_station = INVALID_STATION;
|
||||
}
|
||||
|
||||
// --- StationBuildTool ---
|
||||
|
||||
StationID StationBuildTool::station_to_join = INVALID_STATION;
|
||||
|
||||
TileArea GetCommandArea(const up<Command> &cmd) {
|
||||
if (auto rail_cmd = dynamic_cast<cmd::BuildRailStation *>(cmd.get())) {
|
||||
auto w = rail_cmd->numtracks;
|
||||
@@ -1014,6 +1080,7 @@ TileArea GetCommandArea(const up<Command> &cmd) {
|
||||
return {dock_cmd->tile, tile_to};
|
||||
} else if (auto airport_cmd = dynamic_cast<cmd::BuildAirport *>(cmd.get())) {
|
||||
const AirportSpec *as = AirportSpec::Get(airport_cmd->airport_type);
|
||||
if (as == nullptr) return {};
|
||||
return {airport_cmd->tile, as->size_x, as->size_y};
|
||||
}
|
||||
NOT_REACHED();
|
||||
@@ -1026,8 +1093,8 @@ StationBuildTool::StationBuildTool() {
|
||||
|
||||
template<typename Thandler, typename Tcallback, typename Targ>
|
||||
bool StationBuildTool::ExecuteBuildCommand(Thandler *handler, Tcallback callback, Targ arg) {
|
||||
if (UseImprovedStationJoin()) {
|
||||
auto cmd = handler->GetCommand(arg, StationBuildTool::station_to_join);
|
||||
if (auto mode = std::get_if<StationAction::Join>(&_station_action)) {
|
||||
auto cmd = handler->GetCommand(arg, mode->station);
|
||||
return cmd ? cmd->post(callback) : false;
|
||||
}
|
||||
|
||||
@@ -1073,6 +1140,14 @@ bool RailStationBuildTool::RemoveHandler::Execute(TileArea area) {
|
||||
return cmd->post(&CcPlaySound_CONSTRUCTION_RAIL);
|
||||
}
|
||||
|
||||
std::optional<TileArea> RailStationBuildTool::SizedPlacementHandler::GetArea(TileIndex tile) const {
|
||||
if (!IsValidTile(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};
|
||||
}
|
||||
|
||||
up<Command> RailStationBuildTool::SizedPlacementHandler::GetCommand(TileIndex tile, StationID to_join) {
|
||||
// TODO mostly same as DragNDropPlacement
|
||||
auto cmd = make_up<cmd::BuildRailStation>(
|
||||
@@ -1084,7 +1159,7 @@ up<Command> RailStationBuildTool::SizedPlacementHandler::GetCommand(TileIndex ti
|
||||
_railstation.station_class,
|
||||
_railstation.station_type,
|
||||
to_join,
|
||||
true
|
||||
_fn_mod
|
||||
);
|
||||
cmd->with_error(STR_ERROR_CAN_T_BUILD_RAILROAD_STATION);
|
||||
return cmd;
|
||||
@@ -1109,7 +1184,7 @@ up<Command> RailStationBuildTool::DragNDropPlacementHandler::GetCommand(TileArea
|
||||
_railstation.station_class,
|
||||
_railstation.station_type,
|
||||
to_join,
|
||||
true
|
||||
_fn_mod
|
||||
);
|
||||
cmd->with_error(STR_ERROR_CAN_T_BUILD_RAILROAD_STATION);
|
||||
return cmd;
|
||||
@@ -1217,7 +1292,7 @@ up<Command> RoadStopBuildTool::DragNDropPlacementHandler::GetCommand(TileArea ar
|
||||
_roadstop_gui_settings.roadstop_class,
|
||||
_roadstop_gui_settings.roadstop_type,
|
||||
to_join,
|
||||
true
|
||||
_fn_mod
|
||||
);
|
||||
|
||||
return res;
|
||||
@@ -1313,14 +1388,23 @@ bool DockBuildTool::RemoveHandler::Execute(TileArea area) {
|
||||
}
|
||||
|
||||
// SizedPlacementHandler
|
||||
|
||||
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};
|
||||
}
|
||||
|
||||
up<Command> DockBuildTool::SizedPlacementHandler::GetCommand(TileIndex tile, StationID to_join) {
|
||||
return make_up<cmd::BuildDock>(
|
||||
tile,
|
||||
to_join,
|
||||
true
|
||||
_fn_mod
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
bool DockBuildTool::SizedPlacementHandler::Execute(TileIndex tile) {
|
||||
return this->tool.ExecuteBuildCommand(this, &CcBuildDocks, tile);
|
||||
}
|
||||
@@ -1387,15 +1471,25 @@ bool AirportBuildTool::RemoveHandler::Execute(TileArea area) {
|
||||
}
|
||||
|
||||
// SizedPlacementHandler
|
||||
|
||||
std::optional<TileArea> AirportBuildTool::SizedPlacementHandler::GetArea(TileIndex tile) const {
|
||||
if (!IsValidTile(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};
|
||||
}
|
||||
|
||||
up<Command> AirportBuildTool::SizedPlacementHandler::GetCommand(TileIndex tile, StationID to_join) {
|
||||
byte airport_type = AirportClass::Get(_selected_airport_class)->GetSpec(_selected_airport_index)->GetIndex();
|
||||
auto as = AirportClass::Get(_selected_airport_class)->GetSpec(_selected_airport_index);
|
||||
if (as == nullptr) return nullptr;
|
||||
byte airport_type = as->GetIndex();
|
||||
byte layout = _selected_airport_layout;
|
||||
auto cmd = make_up<cmd::BuildAirport>(
|
||||
tile,
|
||||
airport_type,
|
||||
layout,
|
||||
to_join,
|
||||
true
|
||||
_fn_mod
|
||||
);
|
||||
cmd->with_error(STR_ERROR_CAN_T_BUILD_AIRPORT_HERE);
|
||||
return cmd;
|
||||
|
||||
@@ -95,7 +95,6 @@ public:
|
||||
class StationSelectHandler {
|
||||
public:
|
||||
virtual ~StationSelectHandler() = default;
|
||||
virtual void SelectStationToJoin(StationID station_id) = 0;
|
||||
};
|
||||
template<typename Handler>
|
||||
concept ImplementsStationSelectHandler = std::derived_from<Handler, StationSelectHandler>;
|
||||
@@ -105,7 +104,6 @@ class StationSelectAction : public Action {
|
||||
private:
|
||||
Handler handler;
|
||||
TileIndex cur_tile = INVALID_TILE;
|
||||
StationID selected_station = INVALID_STATION;
|
||||
public:
|
||||
StationSelectAction(const Handler &handler) : handler{handler} {}
|
||||
~StationSelectAction() override = default;
|
||||
@@ -131,6 +129,7 @@ public:
|
||||
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>;
|
||||
@@ -144,7 +143,7 @@ public:
|
||||
SizedPlacementAction(const Handler &handler) : handler{handler} {}
|
||||
~SizedPlacementAction() override = default;
|
||||
void Update(Point pt, TileIndex tile) override;
|
||||
std::optional<TileArea> GetArea() const override { return std::nullopt; };
|
||||
std::optional<TileArea> GetArea() const override { return this->handler.GetArea(this->cur_tile); }
|
||||
bool HandleMousePress() override;
|
||||
void HandleMouseRelease() override;
|
||||
ToolGUIInfo GetGUIInfo() override;
|
||||
@@ -182,19 +181,18 @@ public:
|
||||
|
||||
class StationBuildTool : public Tool {
|
||||
public:
|
||||
static StationID station_to_join;
|
||||
// static StationID station_to_join;
|
||||
// static bool ambigous_join;
|
||||
|
||||
class StationSelectHandler : public citymania::StationSelectHandler {
|
||||
public:
|
||||
StationBuildTool &tool;
|
||||
StationSelectHandler(StationBuildTool &tool) : tool(tool) {}
|
||||
~StationSelectHandler() {}
|
||||
void SelectStationToJoin(StationID station_id) override { this->tool.SelectStationToJoin(station_id); };
|
||||
};
|
||||
|
||||
StationBuildTool();
|
||||
~StationBuildTool() override = default;
|
||||
void SelectStationToJoin(StationID station_id) { StationBuildTool::station_to_join = station_id; };
|
||||
ToolGUIInfo GetGUIInfo() override {
|
||||
if (!this->action) return {};
|
||||
return this->action->GetGUIInfo();
|
||||
@@ -228,6 +226,7 @@ private:
|
||||
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;
|
||||
};
|
||||
|
||||
class DragNDropPlacementHandler: public citymania::DragNDropPlacementHandler {
|
||||
@@ -314,6 +313,7 @@ private:
|
||||
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;
|
||||
};
|
||||
|
||||
public:
|
||||
@@ -348,6 +348,7 @@ private:
|
||||
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;
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
@@ -3237,8 +3237,8 @@ static void CheckOverflow(int &test, int &other, int max, int mult)
|
||||
test = max;
|
||||
}
|
||||
|
||||
// static const uint X_DIRS = (1 << DIR_NE) | (1 << DIR_SW);
|
||||
// static const uint Y_DIRS = (1 << DIR_SE) | (1 << DIR_NW);
|
||||
static const uint X_DIRS = (1 << DIR_NE) | (1 << DIR_SW);
|
||||
static const uint Y_DIRS = (1 << DIR_SE) | (1 << DIR_NW);
|
||||
static const uint HORZ_DIRS = (1 << DIR_W) | (1 << DIR_E);
|
||||
// static const uint VERT_DIRS = (1 << DIR_N) | (1 << DIR_S);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user