Merge branch 'master' into 1.11

This commit is contained in:
dP
2021-03-24 23:07:53 +03:00
36 changed files with 2646 additions and 322 deletions

View File

@@ -57,7 +57,7 @@ void CcBuildAirport(const CommandCost &result, TileIndex tile, uint32 p1, uint32
*/
static void PlaceAirport(TileIndex tile)
{
if (_settings_client.gui.cm_use_improved_station_join) {
if (citymania::UseImprovedStationJoin()) {
citymania::PlaceAirport(tile);
return;
}
@@ -117,14 +117,14 @@ struct BuildAirToolbarWindow : Window {
{
switch (widget) {
case WID_AT_AIRPORT:
if (HandlePlacePushButton(this, WID_AT_AIRPORT, SPR_CURSOR_AIRPORT, HT_RECT)) {
if (HandlePlacePushButton(this, WID_AT_AIRPORT, SPR_CURSOR_AIRPORT, HT_RECT, CM_DDSP_BUILD_AIRPORT)) {
ShowBuildAirportPicker(this);
this->last_user_action = widget;
}
break;
case WID_AT_DEMOLISH:
HandlePlacePushButton(this, WID_AT_DEMOLISH, ANIMCURSOR_DEMOLISH, HT_RECT | HT_DIAGONAL);
HandlePlacePushButton(this, WID_AT_DEMOLISH, ANIMCURSOR_DEMOLISH, HT_RECT | HT_DIAGONAL, CM_DDSP_DEMOLISH);
this->last_user_action = widget;
break;

View File

@@ -3,6 +3,7 @@
#include "cm_export.hpp"
#include "../cargotype.h"
#include "../house.h"
#include "../gfx_func.h"
#include "../gfx_type.h"
#include "../engine_base.h"
@@ -139,6 +140,25 @@ public:
#define JKV(j, field) j.kv(#field, field)
void WriteHouseSpecInfo(JsonWriter &j) {
j.begin_list_with_key("house_specs");
for (uint i = 0; i < NUM_HOUSES; i++) {
const HouseSpec *hs = HouseSpec::Get(i);
j.begin_dict();
j.kv("min_year", hs->min_year);
j.kv("max_year", hs->max_year);
j.kv("population", hs->population);
j.kv("removal_cost", hs->removal_cost);
j.kv("name", hs->building_name);
j.kv("mail_generation", hs->mail_generation);
j.kv("flags", hs->building_flags);
j.kv("availability", hs->building_availability);
j.kv("enabled", hs->enabled);
j.end_dict();
}
j.end_list();
}
void WriteCargoSpecInfo(JsonWriter &j) {
j.begin_list_with_key("cargo_specs");
const CargoSpec *cs;
char buffer[128];
@@ -266,6 +286,7 @@ void WriteEngineInfo(JsonWriter &j) {
void ExportOpenttdData(const std::string &filename) {
data_export::JsonWriter j(filename);
data_export::WriteHouseSpecInfo(j);
data_export::WriteCargoSpecInfo(j);
data_export::WritePaletteInfo(j);
data_export::WriteEngineInfo(j);
}

View File

@@ -13,7 +13,9 @@
#include "../house.h"
#include "../industry.h"
#include "../landscape.h"
#include "../newgrf_airporttiles.h"
#include "../newgrf_railtype.h"
#include "../newgrf_roadtype.h"
#include "../newgrf_station.h"
#include "../town.h"
#include "../town_kdtree.h"
@@ -21,6 +23,8 @@
#include "../tilehighlight_type.h"
#include "../tilehighlight_func.h"
#include "../viewport_func.h"
// #include "../zoning.h"
#include "../table/airporttile_ids.h"
#include "../table/track_land.h"
#include <set>
@@ -38,8 +42,12 @@ extern const Station *_viewport_highlight_station;
extern TileHighlightData _thd;
extern bool IsInsideSelectedRectangle(int x, int y);
extern RailType _cur_railtype;
RoadBits FindRailsToConnect(TileIndex tile);
extern RoadType _cur_roadtype;
extern AirportClassID _selected_airport_class; ///< the currently visible airport class
extern int _selected_airport_index;
extern byte _selected_airport_layout;
extern DiagDirection _build_depot_direction; ///< Currently selected depot direction
extern DiagDirection _road_station_picker_orientation;
extern uint32 _realtime_tick;
extern void GetStationLayout(byte *layout, int numtracks, int plat_len, const StationSpec *statspec);
@@ -53,7 +61,6 @@ struct RailStationGUISettings {
};
extern RailStationGUISettings _railstation; ///< Settings of the station builder GUI
namespace citymania {
extern void (*DrawTileSelectionRect)(const TileInfo *ti, PaletteID pal);
@@ -75,7 +82,7 @@ extern const Station *_station_to_join;
extern const Station *_highlight_station_to_join;
extern TileArea _highlight_join_area;
std::set<std::pair<uint32, const Town*>, std::greater<std::pair<uint32, const Town*> > > _town_cache;
std::set<std::pair<uint32, const Town*>, std::greater<std::pair<uint32, const Town*>>> _town_cache;
// struct {
// int w;
// int h;
@@ -127,12 +134,31 @@ ObjectTileHighlight ObjectTileHighlight::make_rail_tunnel_head(SpriteID palette,
return oh;
}
ObjectTileHighlight ObjectTileHighlight::make_road_stop(SpriteID palette, RoadType roadtype, DiagDirection ddir, bool is_truck) {
auto oh = ObjectTileHighlight(Type::ROAD_STOP, palette);
oh.u.road.stop.roadtype = roadtype;
oh.u.road.stop.ddir = ddir;
oh.u.road.stop.is_truck = is_truck;
return oh;
}
ObjectTileHighlight ObjectTileHighlight::make_airport_tile(SpriteID palette, StationGfx gfx) {
auto oh = ObjectTileHighlight(Type::AIRPORT_TILE, palette);
oh.u.airport_tile.gfx = gfx;
return oh;
}
bool ObjectHighlight::operator==(const ObjectHighlight& oh) {
if (this->type != oh.type) return false;
return (this->tile == oh.tile
&& this->end_tile == oh.end_tile
&& this->axis == oh.axis
&& this->ddir == oh.ddir
&& this->roadtype == oh.roadtype
&& this->is_truck == oh.is_truck
&& this->airport_type == oh.airport_type
&& this->airport_layout == oh.airport_layout
&& this->blueprint == oh.blueprint);
// switch (this->type) {
// case Type::RAIL_DEPOT: return this->tile == oh.tile && this->ddir == oh.ddir;
@@ -161,6 +187,26 @@ ObjectHighlight ObjectHighlight::make_rail_station(TileIndex start_tile, TileInd
return oh;
}
ObjectHighlight ObjectHighlight::make_road_stop(TileIndex start_tile, TileIndex end_tile, RoadType roadtype, DiagDirection orientation, bool is_truck) {
auto oh = ObjectHighlight{ObjectHighlight::Type::ROAD_STOP};
oh.tile = start_tile;
oh.end_tile = end_tile;
oh.ddir = orientation;
oh.roadtype = roadtype;
oh.is_truck = is_truck;
return oh;
}
ObjectHighlight ObjectHighlight::make_airport(TileIndex start_tile, int airport_type, byte airport_layout) {
auto oh = ObjectHighlight{ObjectHighlight::Type::AIRPORT};
oh.tile = start_tile;
oh.airport_type = airport_type;
oh.airport_layout = airport_layout;
return oh;
}
// ObjectHighlight ObjectHighlight::make_blueprint(TileIndex tile, sp<Blueprint> blueprint) {
// auto oh = ObjectHighlight{ObjectHighlight::Type::BLUEPRINT};
// oh.tile = tile;
@@ -269,6 +315,41 @@ void ObjectHighlight::UpdateTiles() {
break;
}
case Type::ROAD_STOP: {
auto ta = OrthogonalTileArea(this->tile, this->end_tile);
auto palette = (CanBuild(
this->tile,
(uint32)(ta.w | ta.h << 8),
(this->is_truck ? 1 : 0) | (this->ddir >= DIAGDIR_END ? 2 : 0) | (((uint)this->ddir % 4) << 3) | (NEW_STATION << 16),
CMD_BUILD_ROAD_STOP
) ? PALETTE_TINT_WHITE : PALETTE_TINT_RED_DEEP);
TileIndex tile;
TILE_AREA_LOOP(tile, ta) {
this->tiles.insert(std::make_pair(tile, ObjectTileHighlight::make_road_stop(palette, this->roadtype, this->ddir, this->is_truck)));
}
break;
}
case Type::AIRPORT: {
auto palette = (CanBuild(
this->tile,
this->airport_type | ((uint)this->airport_layout << 8),
1 | (NEW_STATION << 16),
CMD_BUILD_AIRPORT
) ? PALETTE_TINT_WHITE : PALETTE_TINT_RED_DEEP);
const AirportSpec *as = AirportSpec::Get(this->airport_type);
if (!as->IsAvailable() || this->airport_layout >= as->num_table) break;
Direction rotation = as->rotation[this->airport_layout];
int w = as->size_x;
int h = as->size_y;
if (rotation == DIR_E || rotation == DIR_W) Swap(w, h);
TileArea airport_area = TileArea(this->tile, w, h);
for (AirportTileTableIterator iter(as->table[this->airport_layout], this->tile); iter != INVALID_TILE; ++iter) {
this->tiles.insert(std::make_pair(iter, ObjectTileHighlight::make_airport_tile(palette, iter.GetStationGfx())));
}
break;
}
// case Type::BLUEPRINT:
// if (this->blueprint && this->tile != INVALID_TILE)
// this->tiles = this->blueprint->GetTiles(this->tile);
@@ -397,6 +478,83 @@ void DrawTrainStationSprite(SpriteID palette, const TileInfo *ti, RailType railt
DrawRailTileSeq(ti, t, TO_INVALID, total_offset, 0, palette);
}
void DrawRoadStop(SpriteID palette, const TileInfo *ti, RoadType roadtype, DiagDirection orientation, bool is_truck) {
int32 total_offset = 0;
const RoadTypeInfo* rti = GetRoadTypeInfo(roadtype);
uint image = (uint)orientation;
if (image >= 4) {
/* Drive-through stop */
uint sprite_offset = 5 - image;
/* Road underlay takes precedence over tram */
if (rti->UsesOverlay()) {
SpriteID ground = GetCustomRoadSprite(rti, INVALID_TILE, ROTSG_GROUND);
DrawSprite(ground + sprite_offset, PAL_NONE, ti->x, ti->y);
SpriteID overlay = GetCustomRoadSprite(rti, INVALID_TILE, ROTSG_OVERLAY);
// if (overlay) DrawSprite(overlay + sprite_offset, PAL_NONE, x, y);
if (overlay) AddSortableSpriteToDraw(overlay + sprite_offset, palette, ti->x, ti->y, 1, 1, BB_HEIGHT_UNDER_BRIDGE, ti->z);
} else if (RoadTypeIsTram(roadtype)) {
// DrawSprite(SPR_TRAMWAY_TRAM + sprite_offset, PAL_NONE, x, y);
AddSortableSpriteToDraw(SPR_TRAMWAY_TRAM + sprite_offset, palette, ti->x, ti->y, 1, 1, BB_HEIGHT_UNDER_BRIDGE, ti->z);
}
} else {
/* Drive-in stop */
if (RoadTypeIsRoad(roadtype) && rti->UsesOverlay()) {
SpriteID ground = GetCustomRoadSprite(rti, INVALID_TILE, ROTSG_ROADSTOP);
// DrawSprite(, PAL_NONE, x, y);
AddSortableSpriteToDraw(ground + image, palette, ti->x, ti->y, 1, 1, BB_HEIGHT_UNDER_BRIDGE, ti->z);
}
}
const DrawTileSprites *t = GetStationTileLayout(is_truck ? STATION_TRUCK : STATION_BUS, image);
AddSortableSpriteToDraw(t->ground.sprite, palette, ti->x, ti->y, 1, 1, BB_HEIGHT_UNDER_BRIDGE, ti->z);
DrawRailTileSeq(ti, t, TO_INVALID, total_offset, 0, palette);
/* Draw road, tram catenary */
// DrawRoadCatenary(ti);
}
#include "../table/station_land.h"
void DrawAirportTile(SpriteID palette, const TileInfo *ti, StationGfx gfx) {
int32 total_offset = 0;
const DrawTileSprites *t = nullptr;
gfx = GetTranslatedAirportTileID(gfx);
if (gfx >= NEW_AIRPORTTILE_OFFSET) {
const AirportTileSpec *ats = AirportTileSpec::Get(gfx);
if (ats->grf_prop.spritegroup[0] != nullptr /* && DrawNewAirportTile(ti, Station::GetByTile(ti->tile), gfx, ats) */) {
return;
}
/* No sprite group (or no valid one) found, meaning no graphics associated.
* Use the substitute one instead */
assert(ats->grf_prop.subst_id != INVALID_AIRPORTTILE);
gfx = ats->grf_prop.subst_id;
}
switch (gfx) {
case APT_RADAR_GRASS_FENCE_SW:
t = &_station_display_datas_airport_radar_grass_fence_sw[GetAnimationFrame(ti->tile)];
break;
case APT_GRASS_FENCE_NE_FLAG:
t = &_station_display_datas_airport_flag_grass_fence_ne[GetAnimationFrame(ti->tile)];
break;
case APT_RADAR_FENCE_SW:
t = &_station_display_datas_airport_radar_fence_sw[GetAnimationFrame(ti->tile)];
break;
case APT_RADAR_FENCE_NE:
t = &_station_display_datas_airport_radar_fence_ne[GetAnimationFrame(ti->tile)];
break;
case APT_GRASS_FENCE_NE_FLAG_2:
t = &_station_display_datas_airport_flag_grass_fence_ne_2[GetAnimationFrame(ti->tile)];
break;
}
if (t == nullptr || t->seq == nullptr) t = GetStationTileLayout(STATION_AIRPORT, gfx);
if (t) {
AddSortableSpriteToDraw(t->ground.sprite, palette, ti->x, ti->y, 1, 1, BB_HEIGHT_UNDER_BRIDGE, ti->z);
DrawRailTileSeq(ti, t, TO_INVALID, total_offset, 0, palette);
}
}
enum SignalOffsets { // from rail_cmd.cpp
SIGNAL_TO_SOUTHWEST,
SIGNAL_TO_NORTHEAST,
@@ -548,6 +706,12 @@ void ObjectHighlight::Draw(const TileInfo *ti) {
case ObjectTileHighlight::Type::RAIL_TUNNEL_HEAD:
DrawTunnelHead(ti, _cur_railtype, oth.u.rail.tunnel_head.ddir);
break;
case ObjectTileHighlight::Type::ROAD_STOP:
DrawRoadStop(oth.palette, ti, oth.u.road.stop.roadtype, oth.u.road.stop.ddir, oth.u.road.stop.is_truck);
break;
case ObjectTileHighlight::Type::AIRPORT_TILE:
DrawAirportTile(oth.palette, ti, oth.u.airport_tile.gfx);
break;
default:
break;
}
@@ -883,13 +1047,16 @@ bool DrawTileSelection(const TileInfo *ti, const TileHighlightType &tht) {
// if (_thd.drawstyle == CM_HT_BLUEPRINT_PLACE) return true;
if ((_thd.drawstyle & HT_DRAG_MASK) == HT_RECT && _thd.outersize.x > 0) {
// if ((_thd.drawstyle & HT_DRAG_MASK) == HT_RECT && _thd.outersize.x > 0) {
if (_thd.select_proc == DDSP_BUILD_STATION || _thd.select_proc == DDSP_BUILD_BUSSTOP
|| _thd.select_proc == DDSP_BUILD_TRUCKSTOP || _thd.select_proc == CM_DDSP_BUILD_AIRPORT) {
// station selector, handled by DrawTileZoning
return true;
}
if ((_thd.drawstyle & HT_DRAG_MASK) == HT_RECT && IsInsideSelectedRectangle(ti->x, ti->y)
&& _cursor.sprite_seq[0].sprite == GetRailTypeInfo(_cur_railtype)->cursor.depot) {
if (_thd.select_proc == CM_DDSP_BUILD_RAIL_DEPOT) {
// if ((_thd.drawstyle & HT_DRAG_MASK) == HT_RECT && IsInsideSelectedRectangle(ti->x, ti->y)
// && _cursor.sprite_seq[0].sprite == GetRailTypeInfo(_cur_railtype)->cursor.depot) {
// DrawTileSelectionRect(ti, _thd.make_square_red ? PALETTE_SEL_TILE_RED : PAL_NONE);
// auto rti = GetRailTypeInfo(_cur_railtype);
@@ -905,47 +1072,6 @@ bool DrawTileSelection(const TileInfo *ti, const TileHighlightType &tht) {
return false;
}
// almost duplicate from road_gui.cpp
static DiagDirection TileFractCoordsToDiagDir(Point pt) {
auto x = pt.x & TILE_UNIT_MASK;
auto y = pt.y & TILE_UNIT_MASK;
bool diag = (x + y) < 16;
if (x < y) {
return diag ? DIAGDIR_NE : DIAGDIR_SE;
}
return diag ? DIAGDIR_NW : DIAGDIR_SW;
}
// FIXME duplicate from road_gui.cpp
static DiagDirection RoadBitsToDiagDir(RoadBits bits) {
if (bits < ROAD_SE) {
return bits == ROAD_NW ? DIAGDIR_NW : DIAGDIR_SW;
}
return bits == ROAD_SE ? DIAGDIR_SE : DIAGDIR_NE;
}
DiagDirection AutodetectRailObjectDirection(TileIndex tile, Point pt) {
RoadBits bits = FindRailsToConnect(tile);
// FIXME after this point repeats road autodetection
if (HasExactlyOneBit(bits)) return RoadBitsToDiagDir(bits);
if (bits == ROAD_NONE) bits = ROAD_ALL;
RoadBits frac_bits = DiagDirToRoadBits(TileFractCoordsToDiagDir(pt));
if (HasExactlyOneBit(frac_bits & bits)) {
return RoadBitsToDiagDir(frac_bits & bits);
}
frac_bits |= MirrorRoadBits(frac_bits);
if (HasExactlyOneBit(frac_bits & bits)) {
return RoadBitsToDiagDir(frac_bits & bits);
}
for (DiagDirection ddir = DIAGDIR_BEGIN; ddir < DIAGDIR_END; ddir++) {
if (DiagDirToRoadBits(ddir) & bits) {
return ddir;
}
}
NOT_REACHED();
}
TileIndex _autodetection_tile = INVALID_TILE;
DiagDirDiff _autodetection_rotation = DIAGDIRDIFF_SAME;
@@ -975,6 +1101,7 @@ void ResetRotateAutodetection() {
}
DiagDirection AddAutodetectionRotation(DiagDirection ddir) {
if (ddir >= DIAGDIR_END) return (DiagDirection)(((uint)ddir + (uint)GetAutodetectionRotation()) % 2 + DIAGDIR_END);
return ChangeDiagDir(ddir, GetAutodetectionRotation());
}
@@ -987,8 +1114,8 @@ HighLightStyle UpdateTileSelection(HighLightStyle new_drawstyle) {
// UpdateBlueprintTileSelection(pt, tile);
// new_drawstyle = CM_HT_BLUEPRINT_PLACE;
// } else
if ((_thd.place_mode & HT_DRAG_MASK) == HT_RECT &&
_cursor.sprite_seq[0].sprite == GetRailTypeInfo(_cur_railtype)->cursor.depot) {
if (_thd.make_square_red) {
} else if (_thd.select_proc == CM_DDSP_BUILD_RAIL_DEPOT) {
auto dir = _build_depot_direction;
if (pt.x != -1) {
if (dir >= DiagDirection::DIAGDIR_END) {
@@ -997,14 +1124,43 @@ HighLightStyle UpdateTileSelection(HighLightStyle new_drawstyle) {
_thd.cm_new = ObjectHighlight::make_rail_depot(tile, dir);
}
new_drawstyle = HT_RECT;
} else if (((_thd.place_mode & HT_DRAG_MASK) == HT_RECT || ((_thd.place_mode & HT_DRAG_MASK) == HT_SPECIAL && (_thd.next_drawstyle & HT_DRAG_MASK) == HT_RECT)) && _thd.new_outersize.x > 0 && !_thd.make_square_red) { // station
// } else if (((_thd.place_mode & HT_DRAG_MASK) == HT_RECT || ((_thd.place_mode & HT_DRAG_MASK) == HT_SPECIAL && (_thd.next_drawstyle & HT_DRAG_MASK) == HT_RECT)) && _thd.new_outersize.x > 0 && !_thd.make_square_red) { // station
} else if (_thd.select_proc == CM_DDSP_BUILD_AIRPORT) {
auto tile = TileXY(_thd.new_pos.x / TILE_SIZE, _thd.new_pos.y / TILE_SIZE);
const AirportSpec *as = AirportClass::Get(_selected_airport_class)->GetSpec(_selected_airport_index);
_thd.cm_new = ObjectHighlight::make_airport(tile, as->GetIndex(), _selected_airport_layout);
new_drawstyle = HT_RECT;
} else if (_thd.select_proc == DDSP_BUILD_STATION || _thd.select_proc == DDSP_BUILD_BUSSTOP
|| _thd.select_proc == DDSP_BUILD_TRUCKSTOP) { // station
if (_thd.size.x >= (int)TILE_SIZE && _thd.size.y >= (int)TILE_SIZE) {
auto start_tile = TileXY(_thd.new_pos.x / TILE_SIZE, _thd.new_pos.y / TILE_SIZE);
auto end_tile = TileXY(
std::min((_thd.new_pos.x + _thd.new_size.x) / TILE_SIZE, MapSizeX()) - 1,
std::min((_thd.new_pos.y + _thd.new_size.y) / TILE_SIZE, MapSizeY()) - 1
);
_thd.cm_new = ObjectHighlight::make_rail_station(start_tile, end_tile, _railstation.orientation);
if (_thd.select_proc == DDSP_BUILD_STATION)
_thd.cm_new = ObjectHighlight::make_rail_station(start_tile, end_tile, _railstation.orientation);
else if (_thd.select_proc == DDSP_BUILD_BUSSTOP || _thd.select_proc == DDSP_BUILD_TRUCKSTOP) {
auto ddir = _road_station_picker_orientation;
auto ta = TileArea(start_tile, end_tile);
if (pt.x != -1) {
if (ddir >= DIAGDIR_END && ddir < STATIONDIR_AUTO) {
// When placed on road autorotate anyway
if (ddir == STATIONDIR_X) {
if (!CheckDriveThroughRoadStopDirection(ta, ROAD_X))
ddir = STATIONDIR_Y;
} else {
if (!CheckDriveThroughRoadStopDirection(ta, ROAD_Y))
ddir = STATIONDIR_X;
}
} else if (ddir == STATIONDIR_AUTO) {
ddir = AddAutodetectionRotation(AutodetectRoadObjectDirection(start_tile, pt, _cur_roadtype));
} else if (ddir == STATIONDIR_AUTO_XY) {
ddir = AddAutodetectionRotation(AutodetectDriveThroughRoadStopDirection(ta, pt, _cur_roadtype));
}
}
_thd.cm_new = ObjectHighlight::make_road_stop(start_tile, end_tile, _cur_roadtype, ddir, _thd.select_proc == DDSP_BUILD_TRUCKSTOP);
}
}
new_drawstyle = HT_RECT;
}

View File

@@ -4,7 +4,9 @@
#include "../bridge.h"
#include "../direction_type.h"
#include "../map_func.h"
#include "../road_type.h"
#include "../signal_type.h"
#include "../station_map.h"
#include "../station_type.h"
#include "../tile_cmd.h"
#include "../tile_type.h"
@@ -27,6 +29,8 @@ public:
RAIL_SIGNAL,
RAIL_BRIDGE_HEAD,
RAIL_TUNNEL_HEAD,
ROAD_STOP,
AIRPORT_TILE,
END,
};
@@ -57,8 +61,19 @@ public:
DiagDirection ddir;
} tunnel_head;
} rail;
struct {
struct {
RoadType roadtype;
DiagDirection ddir;
bool is_truck;
} stop;
} road;
struct {
StationGfx gfx;
} airport_tile;
} u;
ObjectTileHighlight(Type type, SpriteID palette): type{type}, palette{palette} {}
static ObjectTileHighlight make_rail_depot(SpriteID palette, DiagDirection ddir);
static ObjectTileHighlight make_rail_track(SpriteID palette, Track track);
@@ -66,6 +81,9 @@ public:
static ObjectTileHighlight make_rail_signal(SpriteID palette, uint pos, SignalType type, SignalVariant variant);
static ObjectTileHighlight make_rail_bridge_head(SpriteID palette, DiagDirection ddir, BridgeType type);
static ObjectTileHighlight make_rail_tunnel_head(SpriteID palette, DiagDirection ddir);
static ObjectTileHighlight make_road_stop(SpriteID palette, RoadType roadtype, DiagDirection ddir, bool is_truck);
static ObjectTileHighlight make_airport_tile(SpriteID palette, StationGfx gfx);
};
class TileIndexDiffCCompare{
@@ -90,6 +108,7 @@ public:
RAIL_SIGNAL,
RAIL_BRIDGE,
RAIL_TUNNEL,
ROAD_STOP,
END,
};
Type type;
@@ -126,6 +145,12 @@ public:
TileIndexDiffC other_end;
} tunnel;
} rail;
struct {
struct {
DiagDirection ddir;
TileIndexDiffC other_end;
} stop;
} road;
} u;
Item(Type type, TileIndexDiffC tdiff)
: type{type}, tdiff{tdiff} {}
@@ -158,6 +183,8 @@ public:
NONE = 0,
RAIL_DEPOT = 1,
RAIL_STATION = 2,
ROAD_STOP = 3,
AIRPORT = 4,
// BLUEPRINT = 2,
};
@@ -166,6 +193,10 @@ public:
TileIndex end_tile = INVALID_TILE;
Axis axis = INVALID_AXIS;
DiagDirection ddir = INVALID_DIAGDIR;
RoadType roadtype = INVALID_ROADTYPE;
bool is_truck = false;
int airport_type = 0;
byte airport_layout = 0;
sp<Blueprint> blueprint = nullptr;
protected:
@@ -182,6 +213,8 @@ public:
static ObjectHighlight make_rail_depot(TileIndex tile, DiagDirection ddir);
static ObjectHighlight make_rail_station(TileIndex start_tile, TileIndex end_tile, Axis axis);
// static ObjectHighlight make_blueprint(TileIndex tile, sp<Blueprint> blueprint);
static ObjectHighlight make_road_stop(TileIndex start_tile, TileIndex end_tile, RoadType roadtype, DiagDirection orientation, bool is_truck);
static ObjectHighlight make_airport(TileIndex start_tile, int airport_type, byte airport_layout);
void Draw(const TileInfo *ti);
void MarkDirty();

View File

@@ -2,8 +2,8 @@
#include "cm_main.hpp"
#include "cm_hotkeys.hpp"
#include "cm_minimap.hpp"
#include "../smallmap_gui.h"
#include "../window_func.h"
#include "../safeguards.h"
@@ -22,7 +22,7 @@ void SwitchToMode(SwitchMode new_mode) {
}
void ToggleSmallMap() {
SmallMapWindow *w = dynamic_cast<SmallMapWindow*>(FindWindowById(WC_SMALLMAP, 0));
SmallMapWindow *w = dynamic_cast<citymania::SmallMapWindow*>(FindWindowById(WC_SMALLMAP, 0));
if (w == nullptr) ShowSmallMap();
delete w;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,8 +1,10 @@
#ifndef CM_MINIMAP_HPP
#define CM_MINIMAP_HPP
#include "../smallmap_gui.h"
#include "../core/endian_func.hpp"
namespace citymania {
#define MKCOLOUR(x) TO_LE32X(x)
@@ -35,6 +37,167 @@ static const uint32 _orange_map_heights[] = {
MKCOLOUR(0xC5C5C5C5),
};
void BuildLinkStatsLegend();
void BuildIndustriesLegend();
void ShowSmallMap();
void BuildLandLegend();
void BuildOwnerLegend();
/** Class managing the smallmap window. */
class SmallMapWindow : public Window {
protected:
/** Types of legends in the #WID_SM_LEGEND widget. */
enum SmallMapType {
SMT_CONTOUR,
SMT_VEHICLES,
SMT_INDUSTRY,
SMT_LINKSTATS,
SMT_ROUTES,
SMT_VEGETATION,
SMT_OWNER,
CM_SMT_IMBA,
};
/** Available kinds of zoomlevel changes. */
enum ZoomLevelChange {
ZLC_INITIALIZE, ///< Initialize zoom level.
ZLC_ZOOM_OUT, ///< Zoom out.
ZLC_ZOOM_IN, ///< Zoom in.
};
static SmallMapType map_type; ///< Currently displayed legends.
static bool show_towns; ///< Display town names in the smallmap.
static int max_heightlevel; ///< Currently used/cached maximum heightlevel.
static const uint LEGEND_BLOB_WIDTH = 8; ///< Width of the coloured blob in front of a line text in the #WID_SM_LEGEND widget.
static const uint INDUSTRY_MIN_NUMBER_OF_COLUMNS = 2; ///< Minimal number of columns in the #WID_SM_LEGEND widget for the #SMT_INDUSTRY legend.
static const uint FORCE_REFRESH_PERIOD = 930; ///< map is redrawn after that many milliseconds.
static const uint BLINK_PERIOD = 450; ///< highlight blinking interval in milliseconds.
uint min_number_of_columns; ///< Minimal number of columns in legends.
uint min_number_of_fixed_rows; ///< Minimal number of rows in the legends for the fixed layouts only (all except #SMT_INDUSTRY).
uint column_width; ///< Width of a column in the #WID_SM_LEGEND widget.
int32 scroll_x; ///< Horizontal world coordinate of the base tile left of the top-left corner of the smallmap display.
int32 scroll_y; ///< Vertical world coordinate of the base tile left of the top-left corner of the smallmap display.
int32 subscroll; ///< Number of pixels (0..3) between the right end of the base tile and the pixel at the top-left corner of the smallmap display.
int tile_zoom; ///< Zoom level. Bigger number means more zoom-out (further away).
int ui_zoom; ///< Zoom level. Bigger number means more zoom-out (further away).
int zoom; ///< Zoom level. Bigger number means more zoom-out (further away).
GUITimer refresh; ///< Refresh timer.
LinkGraphOverlay *overlay;
static void BreakIndustryChainLink();
Point SmallmapRemapCoords(int x, int y) const;
/**
* Draws vertical part of map indicator
* @param x X coord of left/right border of main viewport
* @param y Y coord of top border of main viewport
* @param y2 Y coord of bottom border of main viewport
*/
static inline void DrawVertMapIndicator(int x, int y, int y2)
{
GfxFillRect(x, y, x, y + 3, PC_VERY_LIGHT_YELLOW);
GfxFillRect(x, y2 - 3, x, y2, PC_VERY_LIGHT_YELLOW);
}
/**
* Draws horizontal part of map indicator
* @param x X coord of left border of main viewport
* @param x2 X coord of right border of main viewport
* @param y Y coord of top/bottom border of main viewport
*/
static inline void DrawHorizMapIndicator(int x, int x2, int y)
{
GfxFillRect(x, y, x + 3, y, PC_VERY_LIGHT_YELLOW);
GfxFillRect(x2 - 3, y, x2, y, PC_VERY_LIGHT_YELLOW);
}
/**
* Compute minimal required width of the legends.
* @return Minimally needed width for displaying the smallmap legends in pixels.
*/
inline uint GetMinLegendWidth() const
{
return WD_FRAMERECT_LEFT + this->min_number_of_columns * this->column_width;
}
/**
* Return number of columns that can be displayed in \a width pixels.
* @return Number of columns to display.
*/
inline uint GetNumberColumnsLegend(uint width) const
{
return width / this->column_width;
}
/**
* Compute height given a number of columns.
* @param num_columns Number of columns.
* @return Needed height for displaying the smallmap legends in pixels.
*/
inline uint GetLegendHeight(uint num_columns) const
{
return WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM +
this->GetNumberRowsLegend(num_columns) * FONT_HEIGHT_SMALL;
}
/**
* Get a bitmask for company links to be displayed. Usually this will be
* the _local_company. Spectators get to see all companies' links.
* @return Company mask.
*/
inline uint32 GetOverlayCompanyMask() const
{
return Company::IsValidID(_local_company) ? 1U << _local_company : 0xffffffff;
}
void RebuildColourIndexIfNecessary();
uint GetNumberRowsLegend(uint columns) const;
void SelectLegendItem(int click_pos, LegendAndColour *legend, int end_legend_item, int begin_legend_item = 0);
void SwitchMapType(SmallMapType map_type);
void SetNewScroll(int sx, int sy, int sub);
void DrawMapIndicators() const;
void DrawSmallMapColumn(void *dst, uint xc, uint yc, int pitch, int reps, int start_pos, int end_pos, int y, int end_y, Blitter *blitter) const;
void DrawVehicles(const DrawPixelInfo *dpi, Blitter *blitter) const;
void DrawTowns(const DrawPixelInfo *dpi) const;
void DrawSmallMap(DrawPixelInfo *dpi) const;
Point TileToPixel(int tx, int ty) const;
Point PixelToTile(int tx, int ty) const;
void SetZoomLevel(ZoomLevelChange change, const Point *zoom_pt);
void SetOverlayCargoMask();
void SetupWidgetData();
uint32 GetTileColours(const TileArea &ta) const;
int GetPositionOnLegend(Point pt);
public:
friend class NWidgetSmallmapDisplay;
SmallMapWindow(WindowDesc *desc, int window_number);
virtual ~SmallMapWindow();
void SmallMapCenterOnCurrentPos();
Point GetStationMiddle(const Station *st) const;
void SetStringParameters(int widget) const override;
void OnInit() override;
void OnPaint() override;
void DrawWidget(const Rect &r, int widget) const override;
void OnClick(Point pt, int widget, int click_count) override;
void OnInvalidateData(int data = 0, bool gui_scope = true) override;
bool OnRightClick(Point pt, int widget) override;
void OnMouseWheel(int wheel) override;
void OnRealtimeTick(uint delta_ms) override;
void OnScroll(Point delta) override;
void OnMouseOver(Point pt, int widget) override;
};
} // namespace citymania
#endif /* CITYMANIA_MINIMAP_HPP */

View File

@@ -35,11 +35,9 @@ extern TileHighlightData _thd;
extern void MarkCatchmentTilesDirty();
extern DiagDirection _road_station_picker_orientation;
extern bool CheckDriveThroughRoadStopDirection(TileArea area, RoadBits r);
extern DiagDirection AutodetectRoadObjectDirection(TileIndex tile);
extern DiagDirection AutodetectDriveThroughRoadStopDirection(TileArea area);
extern bool CheckClickOnViewportSign(const Viewport *vp, int x, int y, const ViewportSign *sign);
extern Rect ExpandRectWithViewportSignMargins(Rect r, ZoomLevel zoom);
extern RoadBits FindRailsToConnect(TileIndex tile);
extern ViewportSignKdtree _viewport_sign_kdtree;
extern AirportClassID _selected_airport_class;
extern int _selected_airport_index;
@@ -70,6 +68,10 @@ TileArea _highlight_join_area;
// _station_select.catchment = catchment;
// }
bool UseImprovedStationJoin() {
return _settings_client.gui.cm_use_improved_station_join && _settings_game.station.distant_join_stations;
}
void SetStationBiildingStatus(StationBuildingStatus status) {
_station_building_status = status;
};
@@ -221,33 +223,141 @@ void JoinAndBuild(CommandContainer cmdcont) {
DoCommandP(&cmdcont);
}
static DiagDirection TileFractCoordsToDiagDir(Point pt) {
auto x = pt.x & TILE_UNIT_MASK;
auto y = pt.y & TILE_UNIT_MASK;
bool diag = (x + y) < 16;
if (x < y) {
return diag ? DIAGDIR_NE : DIAGDIR_SE;
}
return diag ? DIAGDIR_NW : DIAGDIR_SW;
}
static DiagDirection RoadBitsToDiagDir(RoadBits bits) {
if (bits < ROAD_SE) {
return bits == ROAD_NW ? DIAGDIR_NW : DIAGDIR_SW;
}
return bits == ROAD_SE ? DIAGDIR_SE : DIAGDIR_NE;
}
DiagDirection AutodetectRailObjectDirection(TileIndex tile, Point pt) {
RoadBits bits = FindRailsToConnect(tile);
// FIXME after this point repeats road autodetection
if (HasExactlyOneBit(bits)) return RoadBitsToDiagDir(bits);
if (bits == ROAD_NONE) bits = ROAD_ALL;
RoadBits frac_bits = DiagDirToRoadBits(TileFractCoordsToDiagDir(pt));
if (HasExactlyOneBit(frac_bits & bits)) {
return RoadBitsToDiagDir(frac_bits & bits);
}
frac_bits |= MirrorRoadBits(frac_bits);
if (HasExactlyOneBit(frac_bits & bits)) {
return RoadBitsToDiagDir(frac_bits & bits);
}
for (DiagDirection ddir = DIAGDIR_BEGIN; ddir < DIAGDIR_END; ddir++) {
if (DiagDirToRoadBits(ddir) & bits) {
return ddir;
}
}
NOT_REACHED();
}
static RoadBits FindRoadsToConnect(TileIndex tile, RoadType roadtype) {
RoadBits bits = ROAD_NONE;
DiagDirection ddir;
auto cur_rtt = GetRoadTramType(roadtype);
// Prioritize roadbits that head in this direction
for (ddir = DIAGDIR_BEGIN; ddir < DIAGDIR_END; ddir++) {
TileIndex cur_tile = TileAddByDiagDir(tile, ddir);
if (GetAnyRoadBits(cur_tile, cur_rtt, true) &
DiagDirToRoadBits(ReverseDiagDir(ddir)))
{
bits |= DiagDirToRoadBits(ddir);
}
}
if (bits != ROAD_NONE) {
return bits;
}
// Try to connect to any road passing by
for (ddir = DIAGDIR_BEGIN; ddir < DIAGDIR_END; ddir++) {
TileIndex cur_tile = TileAddByDiagDir(tile, ddir);
if (GetTileType(cur_tile) == MP_ROAD && HasTileRoadType(cur_tile, cur_rtt) &&
(GetRoadTileType(cur_tile) == ROAD_TILE_NORMAL)) {
bits |= DiagDirToRoadBits(ddir);
}
}
return bits;
}
bool CheckDriveThroughRoadStopDirection(TileArea area, RoadBits r) {
TILE_AREA_LOOP(tile, area) {
if (GetTileType(tile) != MP_ROAD) continue;
if (GetRoadTileType(tile) != ROAD_TILE_NORMAL) continue;
if (GetAllRoadBits(tile) & ~r) return false;
}
return true;
}
/*
* Selects orientation for road object (depot, terminal station)
*/
DiagDirection AutodetectRoadObjectDirection(TileIndex tile, Point pt, RoadType roadtype) {
RoadBits bits = FindRoadsToConnect(tile, roadtype);
if (HasExactlyOneBit(bits)) {
return RoadBitsToDiagDir(bits);
}
if (bits == ROAD_NONE){
bits = ROAD_ALL;
}
RoadBits frac_bits = DiagDirToRoadBits(TileFractCoordsToDiagDir(pt));
if (HasExactlyOneBit(frac_bits & bits)) {
return RoadBitsToDiagDir(frac_bits & bits);
}
frac_bits |= MirrorRoadBits(frac_bits);
if (HasExactlyOneBit(frac_bits & bits)) {
return RoadBitsToDiagDir(frac_bits & bits);
}
for (DiagDirection ddir = DIAGDIR_BEGIN; ddir < DIAGDIR_END; ddir++) {
if (DiagDirToRoadBits(ddir) & bits) {
return ddir;
}
}
NOT_REACHED();
}
/*
* Automaticaly selects direction to use for road stop.
* @param area road stop area
* @return selected direction
*/
DiagDirection AutodetectDriveThroughRoadStopDirection(TileArea area, Point pt, RoadType roadtype) {
bool se_suits, ne_suits;
// Check which direction is available
// If both are not use SE, building will fail anyway
se_suits = CheckDriveThroughRoadStopDirection(area, ROAD_Y);
ne_suits = CheckDriveThroughRoadStopDirection(area, ROAD_X);
if (!ne_suits) return STATIONDIR_Y;
if (!se_suits) return STATIONDIR_X;
// Build station along the longer direction
if (area.w > area.h) return STATIONDIR_X;
if (area.w < area.h) return STATIONDIR_Y;
return DiagDirToAxis(AutodetectRoadObjectDirection(area.tile, pt, roadtype)) == AXIS_X ? STATIONDIR_X : STATIONDIR_Y;
}
void PlaceRoadStop(TileIndex start_tile, TileIndex end_tile, uint32 p2, uint32 cmd) {
uint8 ddir = _road_station_picker_orientation;
assert(_thd.cm.type == citymania::ObjectHighlight::Type::ROAD_STOP);
uint8 ddir = _thd.cm.ddir;
SB(p2, 16, 16, INVALID_STATION); // no station to join
TileArea ta(start_tile, end_tile);
if (CheckStationJoin(start_tile, end_tile)) return;
if (ddir >= DIAGDIR_END) {
if (ddir < DIAGDIR_END + 2) {
SetBit(p2, 1); // It's a drive-through stop.
ddir -= DIAGDIR_END; // Adjust picker result to actual direction.
// When placed on road autorotate anyway
if (ddir == DIAGDIR_SE) {
if (!CheckDriveThroughRoadStopDirection(ta, ROAD_Y))
ddir = DIAGDIR_NE;
} else {
if (!CheckDriveThroughRoadStopDirection(ta, ROAD_X))
ddir = DIAGDIR_SE;
}
}
else if (ddir == DIAGDIR_END + 2) {
ddir = AutodetectRoadObjectDirection(start_tile);
}
else if (ddir == DIAGDIR_END + 3) {
SetBit(p2, 1); // It's a drive-through stop.
ddir = AutodetectDriveThroughRoadStopDirection(ta);
}
if (ddir >= DIAGDIR_END) { // drive-through stops
SetBit(p2, 1);
ddir -= DIAGDIR_END;
}
p2 |= ddir << 3; // Set the DiagDirecion into p2 bits 3 and 4.

View File

@@ -3,11 +3,17 @@
#include "../core/geometry_type.hpp"
#include "../command_type.h"
#include "../road_type.h"
#include "../station_gui.h"
#include "../station_type.h"
namespace citymania {
const DiagDirection STATIONDIR_X = DIAGDIR_END;
const DiagDirection STATIONDIR_Y = (DiagDirection)((uint)DIAGDIR_END + 1);
const DiagDirection STATIONDIR_AUTO = (DiagDirection)((uint)DIAGDIR_END + 2);
const DiagDirection STATIONDIR_AUTO_XY = (DiagDirection)((uint)DIAGDIR_END + 3);
enum class StationBuildingStatus {
IMPOSSIBLE = 0,
QUERY = 1,
@@ -17,7 +23,7 @@ enum class StationBuildingStatus {
// void SetStationBiildingStatus(StationBuildingStatus status);
// void SetStationTileSelectSize(int w, int h, int catchment);
bool UseImprovedStationJoin();
void OnStationTileSetChange(const Station *station, bool adding, StationType type);
void OnStationPartBuilt(const Station *station, TileIndex tile, uint32 p1, uint32 p2);
void PlaceRoadStop(TileIndex start_tile, TileIndex end_tile, uint32 p2, uint32 cmd);
@@ -34,6 +40,11 @@ void AbortStationPlacement();
std::string GetStationCoverageProductionText(TileIndex tile, int w, int h, int rad, StationCoverageType sct);
bool CheckDriveThroughRoadStopDirection(TileArea area, RoadBits r);
DiagDirection AutodetectRoadObjectDirection(TileIndex tile, Point pt, RoadType roadtype);
DiagDirection AutodetectDriveThroughRoadStopDirection(TileArea area, Point pt, RoadType roadtype);
DiagDirection AutodetectRailObjectDirection(TileIndex tile, Point pt);
} // namespace citymania
#endif

View File

@@ -2639,7 +2639,7 @@ struct CompanyWindow : Window
this->RaiseButtons();
break;
}
SetObjectToPlaceWnd(SPR_CURSOR_HQ, PAL_NONE, HT_RECT, this);
SetObjectToPlaceWnd(SPR_CURSOR_HQ, PAL_NONE, HT_RECT, this, CM_DDSP_BUILD_HQ);
SetTileSelectSize(2, 2);
this->LowerWidget(WID_C_BUILD_HQ);
this->SetWidgetDirty(WID_C_BUILD_HQ);
@@ -2651,7 +2651,7 @@ struct CompanyWindow : Window
this->RaiseButtons();
break;
}
SetObjectToPlaceWnd(SPR_CURSOR_HQ, PAL_NONE, HT_RECT, this);
SetObjectToPlaceWnd(SPR_CURSOR_HQ, PAL_NONE, HT_RECT, this, CM_DDSP_BUILD_HQ);
SetTileSelectSize(2, 2);
this->LowerWidget(WID_C_RELOCATE_HQ);
this->SetWidgetDirty(WID_C_RELOCATE_HQ);

View File

@@ -541,7 +541,7 @@ struct DepotWindow : Window {
this->sel = INVALID_VEHICLE;
TrainDepotMoveVehicle(v, sel, gdvp.head);
} else if (v != nullptr) {
SetObjectToPlaceWnd(SPR_CURSOR_MOUSE, PAL_NONE, HT_DRAG, this);
SetObjectToPlaceWnd(SPR_CURSOR_MOUSE, PAL_NONE, HT_DRAG, this, CM_DDSP_DEPOT_MOVE);
SetMouseCursorVehicle(v, EIT_IN_DEPOT);
_cursor.vehchain = citymania::_fn_mod;
@@ -762,7 +762,7 @@ struct DepotWindow : Window {
SPR_CURSOR_CLONE_SHIP, SPR_CURSOR_CLONE_AIRPLANE
};
SetObjectToPlaceWnd(clone_icons[this->type], PAL_NONE, HT_VEHICLE, this);
SetObjectToPlaceWnd(clone_icons[this->type], PAL_NONE, HT_VEHICLE, this, CM_DDSP_DEPOT_CLONE);
} else {
ResetObjectToPlace();
}

View File

@@ -148,36 +148,36 @@ struct BuildDocksToolbarWindow : Window {
{
switch (widget) {
case WID_DT_CANAL: // Build canal button
HandlePlacePushButton(this, WID_DT_CANAL, SPR_CURSOR_CANAL, HT_RECT);
HandlePlacePushButton(this, WID_DT_CANAL, SPR_CURSOR_CANAL, HT_RECT, CM_DDSP_BUILD_CANNAL);
break;
case WID_DT_LOCK: // Build lock button
HandlePlacePushButton(this, WID_DT_LOCK, SPR_CURSOR_LOCK, HT_SPECIAL);
HandlePlacePushButton(this, WID_DT_LOCK, SPR_CURSOR_LOCK, HT_SPECIAL, CM_DDSP_BUILD_LOCK);
break;
case WID_DT_DEMOLISH: // Demolish aka dynamite button
HandlePlacePushButton(this, WID_DT_DEMOLISH, ANIMCURSOR_DEMOLISH, HT_RECT | HT_DIAGONAL);
HandlePlacePushButton(this, WID_DT_DEMOLISH, ANIMCURSOR_DEMOLISH, HT_RECT | HT_DIAGONAL, CM_DDSP_DEMOLISH);
break;
case WID_DT_DEPOT: // Build depot button
if (HandlePlacePushButton(this, WID_DT_DEPOT, SPR_CURSOR_SHIP_DEPOT, HT_RECT)) ShowBuildDocksDepotPicker(this);
if (HandlePlacePushButton(this, WID_DT_DEPOT, SPR_CURSOR_SHIP_DEPOT, HT_RECT, CM_DDSP_BUILD_SHIP_DEPOT)) ShowBuildDocksDepotPicker(this);
break;
case WID_DT_STATION: // Build station button
if (HandlePlacePushButton(this, WID_DT_STATION, SPR_CURSOR_DOCK, HT_SPECIAL)) ShowBuildDockStationPicker(this);
if (HandlePlacePushButton(this, WID_DT_STATION, SPR_CURSOR_DOCK, HT_SPECIAL, CM_DDSP_BUILD_DOCK)) ShowBuildDockStationPicker(this);
break;
case WID_DT_BUOY: // Build buoy button
HandlePlacePushButton(this, WID_DT_BUOY, SPR_CURSOR_BUOY, HT_RECT);
HandlePlacePushButton(this, WID_DT_BUOY, SPR_CURSOR_BUOY, HT_RECT, CM_DDSP_BUILD_BUOY);
break;
case WID_DT_RIVER: // Build river button (in scenario editor)
if (_game_mode != GM_EDITOR) return;
HandlePlacePushButton(this, WID_DT_RIVER, SPR_CURSOR_RIVER, HT_RECT);
HandlePlacePushButton(this, WID_DT_RIVER, SPR_CURSOR_RIVER, HT_RECT, CM_DDSP_BUILD_RIVER);
break;
case WID_DT_BUILD_AQUEDUCT: // Build aqueduct button
HandlePlacePushButton(this, WID_DT_BUILD_AQUEDUCT, SPR_CURSOR_AQUEDUCT, HT_SPECIAL);
HandlePlacePushButton(this, WID_DT_BUILD_AQUEDUCT, SPR_CURSOR_AQUEDUCT, HT_SPECIAL, CM_DDSP_BUILD_AQUEDUCT);
break;
default: return;
@@ -208,7 +208,7 @@ struct BuildDocksToolbarWindow : Window {
case WID_DT_STATION: { // Build station button
if (_settings_client.gui.cm_use_improved_station_join) {
if (citymania::UseImprovedStationJoin()) {
citymania::PlaceDock(tile);
break;
}

View File

@@ -360,7 +360,7 @@ public:
if (_game_mode != GM_MENU && !_networking && _game_mode != GM_EDITOR) {
DoCommandP(0, PM_PAUSED_SAVELOAD, 1, CMD_PAUSE);
}
SetObjectToPlace(SPR_CURSOR_ZZZ, PAL_NONE, HT_NONE, WC_MAIN_WINDOW, 0);
SetObjectToPlace(SPR_CURSOR_ZZZ, PAL_NONE, HT_NONE, WC_MAIN_WINDOW, 0, CM_DDSP_ZZZ);
this->OnInvalidateData(SLIWD_RESCAN_FILES);

View File

@@ -95,7 +95,7 @@ static void _GenerateWorld()
if (_settings_game.game_creation.generation_seed == GENERATE_NEW_SEED) _settings_game.game_creation.generation_seed = _settings_newgame.game_creation.generation_seed = InteractiveRandom();
_random.SetSeed(_settings_game.game_creation.generation_seed);
SetGeneratingWorldProgress(GWP_MAP_INIT, 2);
SetObjectToPlace(SPR_CURSOR_ZZZ, PAL_NONE, HT_NONE, WC_MAIN_WINDOW, 0);
SetObjectToPlace(SPR_CURSOR_ZZZ, PAL_NONE, HT_NONE, WC_MAIN_WINDOW, 0, CM_DDSP_ZZZ);
BasePersistentStorageArray::SwitchMode(PSM_ENTER_GAMELOOP);
@@ -292,7 +292,7 @@ void GenerateWorld(GenWorldMode mode, uint size_x, uint size_y, bool reset_setti
/* Create toolbars */
SetupColoursAndInitialWindow();
SetObjectToPlace(SPR_CURSOR_ZZZ, PAL_NONE, HT_NONE, WC_MAIN_WINDOW, 0);
SetObjectToPlace(SPR_CURSOR_ZZZ, PAL_NONE, HT_NONE, WC_MAIN_WINDOW, 0, CM_DDSP_ZZZ);
UnshowCriticalError();
DeleteAllNonVitalWindows();

View File

@@ -716,7 +716,7 @@ public:
this->group_sel = this->vli.index = this->groups[id_g]->index;
SetObjectToPlaceWnd(SPR_CURSOR_MOUSE, PAL_NONE, HT_DRAG, this);
SetObjectToPlaceWnd(SPR_CURSOR_MOUSE, PAL_NONE, HT_DRAG, this, CM_DDSP_GROUP);
this->vehgroups.ForceRebuild();
this->SetDirty();
@@ -755,11 +755,11 @@ public:
if (v) {
this->vehicle_sel = v->index;
if (_ctrl_pressed) {
if (citymania::_fn_mod) {
this->SelectGroup(v->group_id);
}
SetObjectToPlaceWnd(SPR_CURSOR_MOUSE, PAL_NONE, HT_DRAG, this);
SetObjectToPlaceWnd(SPR_CURSOR_MOUSE, PAL_NONE, HT_DRAG, this, CM_DDSP_GROUP);
SetMouseCursorVehicle(v, EIT_IN_LIST);
_cursor.vehchain = true;

View File

@@ -46,6 +46,7 @@
#include "citymania/cm_hotkeys.hpp"
#include "citymania/cm_highlight.hpp"
#include "citymania/cm_minimap.hpp"
#include "safeguards.h"
@@ -706,7 +707,7 @@ public:
DoCommandP(0, this->selected_type, InteractiveRandom(), CMD_BUILD_INDUSTRY | CMD_MSG(STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY));
this->HandleButtonClick(WID_DPI_FUND_WIDGET);
} else {
HandlePlacePushButton(this, WID_DPI_FUND_WIDGET, SPR_CURSOR_INDUSTRY, HT_RECT);
HandlePlacePushButton(this, WID_DPI_FUND_WIDGET, SPR_CURSOR_INDUSTRY, HT_RECT, CM_DDSP_FUND_INDUSTRY);
}
}
break;
@@ -3035,7 +3036,7 @@ struct IndustryCargoesWindow : public Window {
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP);
if (this->IsWidgetLowered(WID_IC_NOTIFY)) {
if (FindWindowByClass(WC_SMALLMAP) == nullptr) ShowSmallMap();
if (FindWindowByClass(WC_SMALLMAP) == nullptr) citymania::ShowSmallMap();
this->NotifySmallmap();
}
break;

View File

@@ -1475,7 +1475,7 @@ STR_CONFIG_SETTING_PERSISTENT_BUILDINGTOOLS_HELPTEXT :Keep the buildi
STR_CONFIG_SETTING_PERSISTENT_DEPOTTOOLS :Keep depot building tools active after usage: {STRING2}
STR_CONFIG_SETTING_PERSISTENT_DEPOTTOOLS_HELPTEXT :Keep the building tools for road, train and ship depots (reversible by placing with Ctrl).
STR_CM_CONFIG_SETTING_IMPROVED_STATION_JOIN :Use improved station joining controls: {STRING2}
STR_CM_CONFIG_SETTING_IMPROVED_STATION_JOIN_HELPTEXT :Use Ctrl-click on station tile to select or deselect station to join. If station has no tiles Ctrl-click its sign. Ctrl-click empty tile for a new station. Also recently built station is automatically selected as a station to join.
STR_CM_CONFIG_SETTING_IMPROVED_STATION_JOIN_HELPTEXT :Use Ctrl-click on station tile to select or deselect station to join. If station has no tiles Ctrl-click its sign. Ctrl-click empty tile for a new station. Also recently built station is automatically selected as a station to join. {RED}Does't work if joining stations not directly adjacent(distant join) is not allowed in settings.
STR_CONFIG_SETTING_EXPENSES_LAYOUT :Group expenses in company finance window: {STRING2}
STR_CONFIG_SETTING_EXPENSES_LAYOUT_HELPTEXT :Define the layout for the company expenses window
STR_CONFIG_SETTING_AUTO_REMOVE_SIGNALS :Automatically remove signals during rail construction: {STRING2}

View File

@@ -14,12 +14,14 @@
#include "../company_gui.h"
#include "../date_func.h"
#include "../viewport_func.h"
#include "../smallmap_gui.h"
// #include "../smallmap_gui.h"
#include "../core/geometry_func.hpp"
#include "../widgets/link_graph_legend_widget.h"
#include "table/strings.h"
#include "../citymania/cm_minimap.hpp"
#include "../safeguards.h"
/**
@@ -346,7 +348,7 @@ Point LinkGraphOverlay::GetStationMiddle(const Station *st) const
return GetViewportStationMiddle(this->window->viewport, st);
} else {
/* assume this is a smallmap */
return static_cast<const SmallMapWindow *>(this->window)->GetStationMiddle(st);
return static_cast<const citymania::SmallMapWindow *>(this->window)->GetStationMiddle(st);
}
}

View File

@@ -58,7 +58,7 @@
* @param mode Tile highlighting mode, e.g. drawing a rectangle or a dot on the ground
* @return true if the button is clicked, false if it's unclicked
*/
bool HandlePlacePushButton(Window *w, int widget, CursorID cursor, HighLightStyle mode)
bool HandlePlacePushButton(Window *w, int widget, CursorID cursor, HighLightStyle mode, ViewportDragDropSelectionProcess cm_process)
{
if (w->IsWidgetDisabled(widget)) return false;
@@ -70,7 +70,7 @@ bool HandlePlacePushButton(Window *w, int widget, CursorID cursor, HighLightStyl
return false;
}
SetObjectToPlace(cursor, PAL_NONE, mode, w->window_class, w->window_number);
SetObjectToPlace(cursor, PAL_NONE, mode, w->window_class, w->window_number, cm_process);
w->LowerWidget(widget);
return true;
}

View File

@@ -1011,7 +1011,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback {
this->InvalidateData();
if (click_count == 1) {
if (this->editable && this->active_sel != nullptr) SetObjectToPlaceWnd(SPR_CURSOR_MOUSE, PAL_NONE, HT_DRAG, this);
if (this->editable && this->active_sel != nullptr) SetObjectToPlaceWnd(SPR_CURSOR_MOUSE, PAL_NONE, HT_DRAG, this, CM_DDSP_NEWGRF_SELECT);
break;
}
/* With double click, continue */
@@ -1069,7 +1069,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback {
}
this->InvalidateData();
if (click_count == 1) {
if (this->editable && this->avail_sel != nullptr && !HasBit(this->avail_sel->flags, GCF_INVALID)) SetObjectToPlaceWnd(SPR_CURSOR_MOUSE, PAL_NONE, HT_DRAG, this);
if (this->editable && this->avail_sel != nullptr && !HasBit(this->avail_sel->flags, GCF_INVALID)) SetObjectToPlaceWnd(SPR_CURSOR_MOUSE, PAL_NONE, HT_DRAG, this, CM_DDSP_NEWGRF_SELECT);
break;
}
/* With double click, continue */

View File

@@ -450,7 +450,7 @@ public:
}
if (_selected_object_index != -1) {
SetObjectToPlaceWnd(SPR_CURSOR_TRANSMITTER, PAL_NONE, HT_RECT, this);
SetObjectToPlaceWnd(SPR_CURSOR_TRANSMITTER, PAL_NONE, HT_RECT, this, CM_DDSP_PLACE_OBJECT);
}
this->UpdateButtons(_selected_object_class, _selected_object_index, _selected_object_view);

View File

@@ -689,7 +689,7 @@ private:
HT_NONE, // OPOS_CONDITIONAL
HT_VEHICLE, // OPOS_SHARE
};
SetObjectToPlaceWnd(ANIMCURSOR_PICKSTATION, PAL_NONE, goto_place_style[type - 1], this);
SetObjectToPlaceWnd(ANIMCURSOR_PICKSTATION, PAL_NONE, goto_place_style[type - 1], this, CM_DDSP_PICK_STATION);
this->goto_type = type;
this->SetWidgetDirty(WID_O_GOTO);
}
@@ -1319,7 +1319,7 @@ public:
if (this->vehicle->owner == _local_company) {
/* Activate drag and drop */
SetObjectToPlaceWnd(SPR_CURSOR_MOUSE, PAL_NONE, HT_DRAG, this);
SetObjectToPlaceWnd(SPR_CURSOR_MOUSE, PAL_NONE, HT_DRAG, this, CM_DDSP_SELECT_ORDER);
}
}

View File

@@ -177,7 +177,7 @@ void CcRailDepot(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2
static void PlaceRail_Waypoint(TileIndex tile)
{
if (_remove_button_clicked) {
VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_REMOVE_STATION);
VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_BUILD_STATION);
return;
}
@@ -209,13 +209,13 @@ void CcStation(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2,
static void PlaceRail_Station(TileIndex tile)
{
if (_remove_button_clicked) {
VpStartPlaceSizing(tile, VPM_X_AND_Y_LIMITED, DDSP_REMOVE_STATION);
VpStartPlaceSizing(tile, VPM_X_AND_Y_LIMITED, DDSP_BUILD_STATION);
VpSetPlaceSizingLimit(-1);
} else if (_settings_client.gui.station_dragdrop) {
VpStartPlaceSizing(tile, VPM_X_AND_Y_LIMITED, DDSP_BUILD_STATION);
VpSetPlaceSizingLimit(_settings_game.station.station_spread);
} else {
if (_settings_client.gui.cm_use_improved_station_join) {
if (citymania::UseImprovedStationJoin()) {
citymania::PlaceRail_Station(tile);
return;
}
@@ -465,24 +465,6 @@ static void HandleAutoSignalPlacement()
CcPlaySound_CONSTRUCTION_RAIL);
}
// FIXME duplicate from road_gui.cpp
static DiagDirection TileFractCoordsToDiagDir() {
bool diag = (_tile_fract_coords.x + _tile_fract_coords.y) < 16;
if (_tile_fract_coords.x < _tile_fract_coords.y) {
return diag ? DIAGDIR_NE : DIAGDIR_SE;
}
return diag ? DIAGDIR_NW : DIAGDIR_SW;
}
// FIXME duplicate from road_gui.cpp
static DiagDirection RoadBitsToDiagDir(RoadBits bits) {
if (bits < ROAD_SE) {
return bits == ROAD_NW ? DIAGDIR_NW : DIAGDIR_SW;
}
return bits == ROAD_SE ? DIAGDIR_SE : DIAGDIR_NE;
}
RoadBits FindRailsToConnect(TileIndex tile) {
RoadBits directed = ROAD_NONE;
RoadBits passing = ROAD_NONE;
@@ -633,27 +615,27 @@ struct BuildRailToolbarWindow : Window {
switch (widget) {
case WID_RAT_BUILD_NS:
HandlePlacePushButton(this, WID_RAT_BUILD_NS, GetRailTypeInfo(_cur_railtype)->cursor.rail_ns, HT_LINE | HT_DIR_VL);
HandlePlacePushButton(this, WID_RAT_BUILD_NS, GetRailTypeInfo(_cur_railtype)->cursor.rail_ns, HT_LINE | HT_DIR_VL, DDSP_PLACE_RAIL);
this->last_user_action = widget;
break;
case WID_RAT_BUILD_X:
HandlePlacePushButton(this, WID_RAT_BUILD_X, GetRailTypeInfo(_cur_railtype)->cursor.rail_swne, HT_LINE | HT_DIR_X);
HandlePlacePushButton(this, WID_RAT_BUILD_X, GetRailTypeInfo(_cur_railtype)->cursor.rail_swne, HT_LINE | HT_DIR_X, DDSP_PLACE_RAIL);
this->last_user_action = widget;
break;
case WID_RAT_BUILD_EW:
HandlePlacePushButton(this, WID_RAT_BUILD_EW, GetRailTypeInfo(_cur_railtype)->cursor.rail_ew, HT_LINE | HT_DIR_HL);
HandlePlacePushButton(this, WID_RAT_BUILD_EW, GetRailTypeInfo(_cur_railtype)->cursor.rail_ew, HT_LINE | HT_DIR_HL, DDSP_PLACE_RAIL);
this->last_user_action = widget;
break;
case WID_RAT_BUILD_Y:
HandlePlacePushButton(this, WID_RAT_BUILD_Y, GetRailTypeInfo(_cur_railtype)->cursor.rail_nwse, HT_LINE | HT_DIR_Y);
HandlePlacePushButton(this, WID_RAT_BUILD_Y, GetRailTypeInfo(_cur_railtype)->cursor.rail_nwse, HT_LINE | HT_DIR_Y, DDSP_PLACE_RAIL);
this->last_user_action = widget;
break;
case WID_RAT_AUTORAIL:
HandlePlacePushButton(this, WID_RAT_AUTORAIL, GetRailTypeInfo(_cur_railtype)->cursor.autorail, HT_RAIL);
HandlePlacePushButton(this, WID_RAT_AUTORAIL, GetRailTypeInfo(_cur_railtype)->cursor.autorail, HT_RAIL, DDSP_PLACE_RAIL);
this->last_user_action = widget;
break;
@@ -680,7 +662,7 @@ struct BuildRailToolbarWindow : Window {
do_open = !was_open;
}
/* close/open the tool */
if (was_open != do_open) HandlePlacePushButton(this, WID_RAT_POLYRAIL, GetRailTypeInfo(railtype)->cursor.autorail, HT_RAIL | HT_POLY);
if (was_open != do_open) HandlePlacePushButton(this, WID_RAT_POLYRAIL, GetRailTypeInfo(railtype)->cursor.autorail, HT_RAIL | HT_POLY, DDSP_PLACE_RAIL);
/* set snapping mode */
if (do_open) SetRailSnapMode(do_snap ? RSM_SNAP_TO_RAIL : RSM_NO_SNAP);
@@ -690,12 +672,12 @@ struct BuildRailToolbarWindow : Window {
}
case WID_RAT_DEMOLISH:
HandlePlacePushButton(this, WID_RAT_DEMOLISH, ANIMCURSOR_DEMOLISH, HT_RECT | HT_DIAGONAL);
HandlePlacePushButton(this, WID_RAT_DEMOLISH, ANIMCURSOR_DEMOLISH, HT_RECT | HT_DIAGONAL, CM_DDSP_DEMOLISH);
this->last_user_action = widget;
break;
case WID_RAT_BUILD_DEPOT:
if (HandlePlacePushButton(this, WID_RAT_BUILD_DEPOT, GetRailTypeInfo(_cur_railtype)->cursor.depot, HT_RECT | (HighLightStyle)_build_depot_direction)) {
if (HandlePlacePushButton(this, WID_RAT_BUILD_DEPOT, GetRailTypeInfo(_cur_railtype)->cursor.depot, HT_RECT | (HighLightStyle)_build_depot_direction, CM_DDSP_BUILD_RAIL_DEPOT)) {
citymania::ResetRotateAutodetection();
ShowBuildTrainDepotPicker(this);
this->last_user_action = widget;
@@ -705,7 +687,7 @@ struct BuildRailToolbarWindow : Window {
case WID_RAT_BUILD_WAYPOINT:
this->last_user_action = widget;
_waypoint_count = StationClass::Get(STAT_CLASS_WAYP)->GetSpecCount();
if (HandlePlacePushButton(this, WID_RAT_BUILD_WAYPOINT, SPR_CURSOR_WAYPOINT, HT_RECT) && _waypoint_count > 1) {
if (HandlePlacePushButton(this, WID_RAT_BUILD_WAYPOINT, SPR_CURSOR_WAYPOINT, HT_RECT, CM_DDSP_BUILD_WAYPOINT) && _waypoint_count > 1) {
ShowBuildWaypointPicker(this);
}
break;
@@ -719,12 +701,12 @@ struct BuildRailToolbarWindow : Window {
if (was_open) ResetObjectToPlace();
if (!was_open || dragdrop != _settings_client.gui.station_dragdrop) {
_settings_client.gui.station_dragdrop = dragdrop;
if (HandlePlacePushButton(this, WID_RAT_BUILD_STATION, SPR_CURSOR_RAIL_STATION, HT_RECT))
if (HandlePlacePushButton(this, WID_RAT_BUILD_STATION, SPR_CURSOR_RAIL_STATION, HT_RECT, DDSP_BUILD_STATION))
ShowStationBuilder(this);
}
this->last_user_action = WID_RAT_BUILD_STATION;
} else { /* button */
if (HandlePlacePushButton(this, WID_RAT_BUILD_STATION, SPR_CURSOR_RAIL_STATION, HT_RECT)) {
if (HandlePlacePushButton(this, WID_RAT_BUILD_STATION, SPR_CURSOR_RAIL_STATION, HT_RECT, DDSP_BUILD_STATION)) {
ShowStationBuilder(this);
this->last_user_action = WID_RAT_BUILD_STATION;
}
@@ -734,7 +716,7 @@ struct BuildRailToolbarWindow : Window {
case WID_RAT_BUILD_SIGNALS: {
this->last_user_action = widget;
bool started = HandlePlacePushButton(this, WID_RAT_BUILD_SIGNALS, ANIMCURSOR_BUILDSIGNALS, HT_RECT);
bool started = HandlePlacePushButton(this, WID_RAT_BUILD_SIGNALS, ANIMCURSOR_BUILDSIGNALS, HT_RECT, DDSP_BUILD_SIGNALS);
if (started && _settings_client.gui.enable_signal_gui != citymania::_fn_mod) {
ShowSignalBuilder(this);
}
@@ -742,12 +724,12 @@ struct BuildRailToolbarWindow : Window {
}
case WID_RAT_BUILD_BRIDGE:
HandlePlacePushButton(this, WID_RAT_BUILD_BRIDGE, SPR_CURSOR_BRIDGE, HT_RECT);
HandlePlacePushButton(this, WID_RAT_BUILD_BRIDGE, SPR_CURSOR_BRIDGE, HT_RECT, CM_DDSP_BUILD_RAIL_BRIDGE);
this->last_user_action = widget;
break;
case WID_RAT_BUILD_TUNNEL:
HandlePlacePushButton(this, WID_RAT_BUILD_TUNNEL, GetRailTypeInfo(_cur_railtype)->cursor.tunnel, HT_SPECIAL);
HandlePlacePushButton(this, WID_RAT_BUILD_TUNNEL, GetRailTypeInfo(_cur_railtype)->cursor.tunnel, HT_SPECIAL, CM_DDSP_BUILD_RAIL_TUNNEL);
this->last_user_action = widget;
break;
@@ -756,7 +738,7 @@ struct BuildRailToolbarWindow : Window {
break;
case WID_RAT_CONVERT_RAIL:
HandlePlacePushButton(this, WID_RAT_CONVERT_RAIL, GetRailTypeInfo(_cur_railtype)->cursor.convert, HT_RECT | HT_DIAGONAL);
HandlePlacePushButton(this, WID_RAT_CONVERT_RAIL, GetRailTypeInfo(_cur_railtype)->cursor.convert, HT_RECT | HT_DIAGONAL, DDSP_CONVERT_RAIL);
this->last_user_action = widget;
break;
@@ -1081,7 +1063,7 @@ Window *ShowBuildRailToolbar(RailType railtype)
static void HandleStationPlacement(TileIndex start, TileIndex end)
{
if (_settings_client.gui.cm_use_improved_station_join) {
if (citymania::UseImprovedStationJoin()) {
citymania::HandleStationPlacement(start, end);
return;
}
@@ -1359,7 +1341,7 @@ public:
int rad = (_settings_game.station.modified_catchment) ? CA_TRAIN : CA_UNMODIFIED;
if (_settings_client.gui.cm_use_improved_station_join || _settings_client.gui.station_show_coverage)
if (citymania::UseImprovedStationJoin() || _settings_client.gui.station_show_coverage)
SetTileSelectBigSize(-rad, -rad, 2 * rad, 2 * rad);
for (uint bits = 0; bits < 7; bits++) {

View File

@@ -39,6 +39,7 @@
#include "table/strings.h"
#include "citymania/cm_highlight.hpp"
#include "citymania/cm_hotkeys.hpp"
#include "citymania/cm_station_gui.hpp"
@@ -67,7 +68,7 @@ DECLARE_ENUM_AS_BIT_SET(RoadFlags)
static RoadFlags _place_road_flag;
static RoadType _cur_roadtype;
/* CM static */ RoadType _cur_roadtype;
static DiagDirection _road_depot_orientation;
DiagDirection _road_station_picker_orientation;
@@ -176,107 +177,6 @@ void CcRoadStop(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2,
}
}
static RoadBits FindRoadsToConnect(TileIndex tile) {
RoadBits bits = ROAD_NONE;
DiagDirection ddir;
auto cur_rtt = GetRoadTramType(_cur_roadtype);
// Prioritize roadbits that head in this direction
for (ddir = DIAGDIR_BEGIN; ddir < DIAGDIR_END; ddir++) {
TileIndex cur_tile = TileAddByDiagDir(tile, ddir);
if (GetAnyRoadBits(cur_tile, cur_rtt, true) &
DiagDirToRoadBits(ReverseDiagDir(ddir)))
{
bits |= DiagDirToRoadBits(ddir);
}
}
if (bits != ROAD_NONE) {
return bits;
}
// Try to connect to any road passing by
for (ddir = DIAGDIR_BEGIN; ddir < DIAGDIR_END; ddir++) {
TileIndex cur_tile = TileAddByDiagDir(tile, ddir);
if (GetTileType(cur_tile) == MP_ROAD && HasTileRoadType(cur_tile, cur_rtt) &&
(GetRoadTileType(cur_tile) == ROAD_TILE_NORMAL)) {
bits |= DiagDirToRoadBits(ddir);
}
}
return bits;
}
static DiagDirection RoadBitsToDiagDir(RoadBits bits) {
if (bits < ROAD_SE) {
return bits == ROAD_NW ? DIAGDIR_NW : DIAGDIR_SW;
}
return bits == ROAD_SE ? DIAGDIR_SE : DIAGDIR_NE;
}
static DiagDirection TileFractCoordsToDiagDir() {
bool diag = (_tile_fract_coords.x + _tile_fract_coords.y) < 16;
if (_tile_fract_coords.x < _tile_fract_coords.y) {
return diag ? DIAGDIR_NE : DIAGDIR_SE;
}
return diag ? DIAGDIR_NW : DIAGDIR_SW;
}
/*
* Selects orientation for road object (depot, terminal station)
*/
DiagDirection AutodetectRoadObjectDirection(TileIndex tile) {
RoadBits bits = FindRoadsToConnect(tile);
if (HasExactlyOneBit(bits)) {
return RoadBitsToDiagDir(bits);
}
if (bits == ROAD_NONE){
bits = ROAD_ALL;
}
RoadBits frac_bits = DiagDirToRoadBits(TileFractCoordsToDiagDir());
if (HasExactlyOneBit(frac_bits & bits)) {
return RoadBitsToDiagDir(frac_bits & bits);
}
frac_bits |= MirrorRoadBits(frac_bits);
if (HasExactlyOneBit(frac_bits & bits)) {
return RoadBitsToDiagDir(frac_bits & bits);
}
for (DiagDirection ddir = DIAGDIR_BEGIN; ddir < DIAGDIR_END; ddir++) {
if (DiagDirToRoadBits(ddir) & bits) {
return ddir;
}
}
NOT_REACHED();
}
bool CheckDriveThroughRoadStopDirection(TileArea area, RoadBits r) {
TILE_AREA_LOOP(tile, area) {
if (GetTileType(tile) != MP_ROAD) continue;
if (GetRoadTileType(tile) != ROAD_TILE_NORMAL) continue;
if (GetAllRoadBits(tile) & ~r) return false;
}
return true;
}
/*
* Automaticaly selects direction to use for road stop.
* @param area road stop area
* @return selected direction
*/
DiagDirection AutodetectDriveThroughRoadStopDirection(TileArea area) {
bool se_suits, ne_suits;
// Check which direction is available
// If both are not use SE, building will fail anyway
se_suits = CheckDriveThroughRoadStopDirection(area, ROAD_Y);
ne_suits = CheckDriveThroughRoadStopDirection(area, ROAD_X);
if (!ne_suits) return DIAGDIR_SE;
if (!se_suits) return DIAGDIR_NE;
// Build station along the longer direction
if (area.w > area.h) return DIAGDIR_NE;
if (area.w < area.h) return DIAGDIR_SE;
return AutodetectRoadObjectDirection(area.tile);
}
/**
* Place a new road stop.
* @param start_tile First tile of the area.
@@ -289,35 +189,19 @@ DiagDirection AutodetectDriveThroughRoadStopDirection(TileArea area) {
*/
static void PlaceRoadStop(TileIndex start_tile, TileIndex end_tile, uint32 p2, uint32 cmd)
{
if (_settings_client.gui.cm_use_improved_station_join) {
if (citymania::UseImprovedStationJoin()) {
citymania::PlaceRoadStop(start_tile, end_tile, p2, cmd);
return;
}
uint8 ddir = _road_station_picker_orientation;
assert(_thd.cm.type == citymania::ObjectHighlight::Type::ROAD_STOP);
uint8 ddir = _thd.cm.ddir;
SB(p2, 16, 16, INVALID_STATION); // no station to join
TileArea ta(start_tile, end_tile);
if (ddir >= DIAGDIR_END) {
if (ddir < DIAGDIR_END + 2) {
SetBit(p2, 1); // It's a drive-through stop.
ddir -= DIAGDIR_END; // Adjust picker result to actual direction.
// When placed on road autorotate anyway
if (ddir == DIAGDIR_SE) {
if (!CheckDriveThroughRoadStopDirection(ta, ROAD_Y))
ddir = DIAGDIR_NE;
} else {
if (!CheckDriveThroughRoadStopDirection(ta, ROAD_X))
ddir = DIAGDIR_SE;
}
}
else if (ddir == DIAGDIR_END + 2) {
ddir = AutodetectRoadObjectDirection(start_tile);
}
else if (ddir == DIAGDIR_END + 3) {
SetBit(p2, 1); // It's a drive-through stop.
ddir = AutodetectDriveThroughRoadStopDirection(ta);
}
if (ddir >= DIAGDIR_END) { // drive-through stops
SetBit(p2, 1);
ddir -= DIAGDIR_END;
}
p2 |= ddir << 3; // Set the DiagDirecion into p2 bits 3 and 4.
@@ -332,7 +216,7 @@ static void PlaceRoadStop(TileIndex start_tile, TileIndex end_tile, uint32 p2, u
static void PlaceRoad_BusStation(TileIndex tile)
{
if (_remove_button_clicked) {
VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_REMOVE_BUSSTOP);
VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_BUILD_BUSSTOP);
} else {
if (_road_station_picker_orientation < DIAGDIR_END) { // Not a drive-through stop.
VpStartPlaceSizing(tile, (DiagDirToAxis(_road_station_picker_orientation) == AXIS_X) ? VPM_X_LIMITED : VPM_Y_LIMITED, DDSP_BUILD_BUSSTOP);
@@ -350,7 +234,7 @@ static void PlaceRoad_BusStation(TileIndex tile)
static void PlaceRoad_TruckStation(TileIndex tile)
{
if (_remove_button_clicked) {
VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_REMOVE_TRUCKSTOP);
VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_BUILD_TRUCKSTOP);
} else {
if (_road_station_picker_orientation < DIAGDIR_END) { // Not a drive-through stop.
VpStartPlaceSizing(tile, (DiagDirToAxis(_road_station_picker_orientation) == AXIS_X) ? VPM_X_LIMITED : VPM_Y_LIMITED, DDSP_BUILD_TRUCKSTOP);
@@ -567,41 +451,41 @@ struct BuildRoadToolbarWindow : Window {
_one_way_button_clicked = false;
switch (widget) {
case WID_ROT_ROAD_X:
HandlePlacePushButton(this, WID_ROT_ROAD_X, this->rti->cursor.road_nwse, HT_RECT);
HandlePlacePushButton(this, WID_ROT_ROAD_X, this->rti->cursor.road_nwse, HT_RECT, DDSP_PLACE_ROAD_X_DIR);
this->last_started_action = widget;
break;
case WID_ROT_ROAD_Y:
HandlePlacePushButton(this, WID_ROT_ROAD_Y, this->rti->cursor.road_swne, HT_RECT);
HandlePlacePushButton(this, WID_ROT_ROAD_Y, this->rti->cursor.road_swne, HT_RECT, DDSP_PLACE_ROAD_Y_DIR);
this->last_started_action = widget;
break;
case WID_ROT_AUTOROAD:
HandlePlacePushButton(this, WID_ROT_AUTOROAD, this->rti->cursor.autoroad, HT_RECT);
HandlePlacePushButton(this, WID_ROT_AUTOROAD, this->rti->cursor.autoroad, HT_RECT, DDSP_PLACE_AUTOROAD);
this->last_started_action = widget;
break;
case WID_ROT_DEMOLISH:
HandlePlacePushButton(this, WID_ROT_DEMOLISH, ANIMCURSOR_DEMOLISH, HT_RECT | HT_DIAGONAL);
HandlePlacePushButton(this, WID_ROT_DEMOLISH, ANIMCURSOR_DEMOLISH, HT_RECT | HT_DIAGONAL, CM_DDSP_DEMOLISH);
this->last_started_action = widget;
break;
case WID_ROT_DEPOT:
if (HandlePlacePushButton(this, WID_ROT_DEPOT, this->rti->cursor.depot, HT_RECT)) {
if (HandlePlacePushButton(this, WID_ROT_DEPOT, this->rti->cursor.depot, HT_RECT, CM_DDSP_BUILD_ROAD_DEPOT)) {
ShowRoadDepotPicker(this);
this->last_started_action = widget;
}
break;
case WID_ROT_BUS_STATION:
if (HandlePlacePushButton(this, WID_ROT_BUS_STATION, SPR_CURSOR_BUS_STATION, HT_RECT)) {
if (HandlePlacePushButton(this, WID_ROT_BUS_STATION, SPR_CURSOR_BUS_STATION, HT_RECT, DDSP_BUILD_BUSSTOP)) {
ShowRVStationPicker(this, ROADSTOP_BUS);
this->last_started_action = widget;
}
break;
case WID_ROT_TRUCK_STATION:
if (HandlePlacePushButton(this, WID_ROT_TRUCK_STATION, SPR_CURSOR_TRUCK_STATION, HT_RECT)) {
if (HandlePlacePushButton(this, WID_ROT_TRUCK_STATION, SPR_CURSOR_TRUCK_STATION, HT_RECT, DDSP_BUILD_TRUCKSTOP)) {
ShowRVStationPicker(this, ROADSTOP_TRUCK);
this->last_started_action = widget;
}
@@ -615,12 +499,12 @@ struct BuildRoadToolbarWindow : Window {
break;
case WID_ROT_BUILD_BRIDGE:
HandlePlacePushButton(this, WID_ROT_BUILD_BRIDGE, SPR_CURSOR_BRIDGE, HT_RECT);
HandlePlacePushButton(this, WID_ROT_BUILD_BRIDGE, SPR_CURSOR_BRIDGE, HT_RECT, CM_DDSP_BUILD_ROAD_BRIDGE);
this->last_started_action = widget;
break;
case WID_ROT_BUILD_TUNNEL:
HandlePlacePushButton(this, WID_ROT_BUILD_TUNNEL, this->rti->cursor.tunnel, HT_SPECIAL);
HandlePlacePushButton(this, WID_ROT_BUILD_TUNNEL, this->rti->cursor.tunnel, HT_SPECIAL, CM_DDSP_BUILD_ROAD_TUNNEL);
this->last_started_action = widget;
break;
@@ -634,7 +518,7 @@ struct BuildRoadToolbarWindow : Window {
break;
case WID_ROT_CONVERT_ROAD:
HandlePlacePushButton(this, WID_ROT_CONVERT_ROAD, this->rti->cursor.convert_road, HT_RECT);
HandlePlacePushButton(this, WID_ROT_CONVERT_ROAD, this->rti->cursor.convert_road, HT_RECT, DDSP_CONVERT_ROAD);
this->last_started_action = widget;
break;
@@ -683,7 +567,7 @@ struct BuildRoadToolbarWindow : Window {
case WID_ROT_DEPOT:
ddir = _road_depot_orientation;
if (ddir == DIAGDIR_NW + 1) {
ddir = AutodetectRoadObjectDirection(tile);
ddir = citymania::AutodetectRoadObjectDirection(tile, GetTileBelowCursor(), _cur_roadtype);
}
DoCommandP(tile, _cur_roadtype << 2 | ddir, 0,
CMD_BUILD_ROAD_DEPOT | CMD_MSG(this->rti->strings.err_depot), CcRoadDepot);
@@ -1247,6 +1131,13 @@ static void ShowRoadDepotPicker(Window *parent)
}
struct BuildRoadStationWindow : public PickerWindowBase {
/* CityMania code start */
public:
enum class Hotkey : int {
ROTATE,
};
/* CityMania code end */
BuildRoadStationWindow(WindowDesc *desc, Window *parent, RoadStopType rs) : PickerWindowBase(desc, parent)
{
this->CreateNestedTree();
@@ -1290,7 +1181,7 @@ struct BuildRoadStationWindow : public PickerWindowBase {
int rad = _settings_game.station.modified_catchment ? ((this->window_class == WC_BUS_STATION) ? CA_BUS : CA_TRUCK) : CA_UNMODIFIED;
SetTileSelectSize(1, 1);
if (_settings_client.gui.cm_use_improved_station_join || _settings_client.gui.station_show_coverage)
if (citymania::UseImprovedStationJoin() || _settings_client.gui.station_show_coverage)
SetTileSelectBigSize(-rad, -rad, 2 * rad, 2 * rad);
/* 'Accepts' and 'Supplies' texts. */
@@ -1383,6 +1274,39 @@ struct BuildRoadStationWindow : public PickerWindowBase {
{
CheckRedrawStationCoverage(this);
}
/* CityMania code start */
EventState OnHotkey(int hotkey) override
{
switch ((BuildRoadStationWindow::Hotkey)hotkey) {
/* Indicate to the OnClick that the action comes from a hotkey rather
* then from a click and that the CTRL state should be ignored. */
case BuildRoadStationWindow::Hotkey::ROTATE:
if (_road_station_picker_orientation < citymania::STATIONDIR_AUTO) {
this->RaiseWidget(_road_station_picker_orientation + WID_BROS_STATION_NE);
if (_road_station_picker_orientation < DIAGDIR_END) {
_road_station_picker_orientation = ChangeDiagDir(_road_station_picker_orientation, DIAGDIRDIFF_90RIGHT);
} else if (_road_station_picker_orientation == citymania::STATIONDIR_X) {
_road_station_picker_orientation = citymania::STATIONDIR_Y;
} else if (_road_station_picker_orientation == citymania::STATIONDIR_Y) {
_road_station_picker_orientation = citymania::STATIONDIR_X;
}
this->LowerWidget(_road_station_picker_orientation + WID_BROS_STATION_NE);
} else {
citymania::RotateAutodetection();
}
this->SetDirty();
return ES_HANDLED;
default:
NOT_REACHED();
}
return ES_NOT_HANDLED;
}
static HotkeyList hotkeys;
/* CityMania code end */
};
/** Widget definition of the build road station window */
@@ -1432,11 +1356,20 @@ static const NWidgetPart _nested_road_station_picker_widgets[] = {
EndContainer(),
};
/* CityMania code start */
static Hotkey _cm_road_station_pickerhotkeys[] = {
Hotkey(CM_WKC_MOUSE_MIDDLE, "rotate", (int)BuildRoadStationWindow::Hotkey::ROTATE),
HOTKEY_LIST_END
};
HotkeyList BuildRoadStationWindow::hotkeys("cm_build_road_station", _cm_road_station_pickerhotkeys);
/* CityMania code end */
static WindowDesc _road_station_picker_desc(
WDP_AUTO, nullptr, 0, 0,
WC_BUS_STATION, WC_BUILD_TOOLBAR,
WDF_CONSTRUCTION,
_nested_road_station_picker_widgets, lengthof(_nested_road_station_picker_widgets)
,&BuildRoadStationWindow::hotkeys // CityMania addition
);
/** Widget definition of the build tram station window */
@@ -1481,6 +1414,7 @@ static WindowDesc _tram_station_picker_desc(
WC_BUS_STATION, WC_BUILD_TOOLBAR,
WDF_CONSTRUCTION,
_nested_tram_station_picker_widgets, lengthof(_nested_tram_station_picker_widgets)
,&BuildRoadStationWindow::hotkeys // CityMania addition
);
static void ShowRVStationPicker(Window *parent, RoadStopType rs)

View File

@@ -170,6 +170,9 @@ static uint _company_to_list_pos[MAX_COMPANIES];
*/
void BuildIndustriesLegend()
{
citymania::BuildIndustriesLegend();
return;
uint j = 0;
/* Add each name */
@@ -200,6 +203,9 @@ void BuildIndustriesLegend()
*/
void BuildLinkStatsLegend()
{
citymania::BuildLinkStatsLegend();
return;
/* Clear the legend */
memset(_legend_linkstats, 0, sizeof(_legend_linkstats));
@@ -278,6 +284,9 @@ static SmallMapColourScheme _heightmap_schemes[] = {
*/
void BuildLandLegend()
{
citymania::BuildLandLegend();
return;
/* The smallmap window has never been initialized, so no need to change the legend. */
if (_heightmap_schemes[0].height_colours == nullptr) return;
@@ -329,6 +338,9 @@ void BuildLandLegend()
*/
void BuildOwnerLegend()
{
citymania::BuildOwnerLegend();
return;
_legend_land_owners[1].colour = _heightmap_schemes[_settings_client.gui.smallmap_land_colour].default_colour;
int i = NUM_NO_COMPANY_ENTRIES;
@@ -1890,6 +1902,9 @@ static const NWidgetPart _nested_smallmap_widgets[] = {
EndContainer(),
};
#if 0
CityMania has its own smallmap
static WindowDesc _smallmap_desc(
WDP_AUTO, "smallmap", 484, 314,
WC_SMALLMAP, WC_NONE,
@@ -1904,6 +1919,7 @@ void ShowSmallMap()
{
AllocateWindowDescFront<SmallMapWindow>(&_smallmap_desc, 0);
}
#endif
/**
* Scrolls the main window to given coordinates.
@@ -1923,8 +1939,9 @@ bool ScrollMainWindowTo(int x, int y, int z, bool instant)
if (res) return res;
SmallMapWindow *w = dynamic_cast<SmallMapWindow*>(FindWindowById(WC_SMALLMAP, 0));
citymania::SmallMapWindow *w = dynamic_cast<citymania::SmallMapWindow*>(FindWindowById(WC_SMALLMAP, 0));
if (w != nullptr) w->SmallMapCenterOnCurrentPos();
return res;
}

View File

@@ -23,7 +23,7 @@
void BuildLinkStatsLegend();
void BuildIndustriesLegend();
void ShowSmallMap();
// void ShowSmallMap(); CM
void BuildLandLegend();
void BuildOwnerLegend();

View File

@@ -154,7 +154,7 @@ static void FindStationsAroundSelection()
void CheckRedrawStationCoverage(const Window *w)
{
/* CityMania code begin */
if (_settings_client.gui.cm_use_improved_station_join) {
if (citymania::UseImprovedStationJoin()) {
if (citymania::CheckRedrawStationCoverage()) w->SetDirty();
return;
}

View File

@@ -577,7 +577,7 @@ protected:
this->active_button_id = INVALID_STORY_PAGE_ELEMENT;
} else {
CursorID cursor = TranslateStoryPageButtonCursor(StoryPageButtonData{ pe.referenced_id }.GetCursor());
SetObjectToPlaceWnd(cursor, PAL_NONE, HT_RECT, this);
SetObjectToPlaceWnd(cursor, PAL_NONE, HT_RECT, this, CM_DDSP_STORY_BUTTON);
this->active_button_id = pe.index;
}
this->SetWidgetDirty(WID_SB_PAGE_PANEL);
@@ -589,7 +589,7 @@ protected:
this->active_button_id = INVALID_STORY_PAGE_ELEMENT;
} else {
CursorID cursor = TranslateStoryPageButtonCursor(StoryPageButtonData{ pe.referenced_id }.GetCursor());
SetObjectToPlaceWnd(cursor, PAL_NONE, HT_VEHICLE, this);
SetObjectToPlaceWnd(cursor, PAL_NONE, HT_VEHICLE, this, CM_DDSP_STORY_BUTTON);
this->active_button_id = pe.index;
}
this->SetWidgetDirty(WID_SB_PAGE_PANEL);

View File

@@ -259,32 +259,32 @@ struct TerraformToolbarWindow : Window {
switch (widget) {
case WID_TT_LOWER_LAND: // Lower land button
HandlePlacePushButton(this, WID_TT_LOWER_LAND, ANIMCURSOR_LOWERLAND, HT_POINT | HT_DIAGONAL);
HandlePlacePushButton(this, WID_TT_LOWER_LAND, ANIMCURSOR_LOWERLAND, HT_POINT | HT_DIAGONAL, CM_DDSP_TERRAFORM);
this->last_user_action = widget;
break;
case WID_TT_RAISE_LAND: // Raise land button
HandlePlacePushButton(this, WID_TT_RAISE_LAND, ANIMCURSOR_RAISELAND, HT_POINT | HT_DIAGONAL);
HandlePlacePushButton(this, WID_TT_RAISE_LAND, ANIMCURSOR_RAISELAND, HT_POINT | HT_DIAGONAL, CM_DDSP_TERRAFORM);
this->last_user_action = widget;
break;
case WID_TT_LEVEL_LAND: // Level land button
HandlePlacePushButton(this, WID_TT_LEVEL_LAND, SPR_CURSOR_LEVEL_LAND, HT_POINT | HT_DIAGONAL);
HandlePlacePushButton(this, WID_TT_LEVEL_LAND, SPR_CURSOR_LEVEL_LAND, HT_POINT | HT_DIAGONAL, CM_DDSP_TERRAFORM);
this->last_user_action = widget;
break;
case WID_TT_DEMOLISH: // Demolish aka dynamite button
HandlePlacePushButton(this, WID_TT_DEMOLISH, ANIMCURSOR_DEMOLISH, HT_RECT | HT_DIAGONAL);
HandlePlacePushButton(this, WID_TT_DEMOLISH, ANIMCURSOR_DEMOLISH, HT_RECT | HT_DIAGONAL, CM_DDSP_DEMOLISH);
this->last_user_action = widget;
break;
case WID_TT_DEMOLISH_TREES: // Demolish aka dynamite button
HandlePlacePushButton(this, WID_TT_DEMOLISH_TREES, ANIMCURSOR_DEMOLISH, HT_RECT | HT_DIAGONAL);
HandlePlacePushButton(this, WID_TT_DEMOLISH_TREES, ANIMCURSOR_DEMOLISH, HT_RECT | HT_DIAGONAL, CM_DDSP_DEMOLISH_TREES);
this->last_user_action = widget;
break;
case WID_TT_BUY_LAND: // Buy land button
HandlePlacePushButton(this, WID_TT_BUY_LAND, SPR_CURSOR_BUY_LAND, HT_RECT);
HandlePlacePushButton(this, WID_TT_BUY_LAND, SPR_CURSOR_BUY_LAND, HT_RECT, CM_DDSP_BUY_LAND);
this->last_user_action = widget;
break;
@@ -293,7 +293,7 @@ struct TerraformToolbarWindow : Window {
break;
case WID_TT_PLACE_SIGN: // Place sign button
HandlePlacePushButton(this, WID_TT_PLACE_SIGN, SPR_CURSOR_SIGN, HT_RECT);
HandlePlacePushButton(this, WID_TT_PLACE_SIGN, SPR_CURSOR_SIGN, HT_RECT, CM_DDSP_PLACE_SIGN);
this->last_user_action = widget;
break;
@@ -670,32 +670,32 @@ struct ScenarioEditorLandscapeGenerationWindow : Window {
switch (widget) {
case WID_ETT_DEMOLISH: // Demolish aka dynamite button
HandlePlacePushButton(this, WID_ETT_DEMOLISH, ANIMCURSOR_DEMOLISH, HT_RECT | HT_DIAGONAL);
HandlePlacePushButton(this, WID_ETT_DEMOLISH, ANIMCURSOR_DEMOLISH, HT_RECT | HT_DIAGONAL, CM_DDSP_DEMOLISH);
this->last_user_action = widget;
break;
case WID_ETT_LOWER_LAND: // Lower land button
HandlePlacePushButton(this, WID_ETT_LOWER_LAND, ANIMCURSOR_LOWERLAND, HT_POINT);
HandlePlacePushButton(this, WID_ETT_LOWER_LAND, ANIMCURSOR_LOWERLAND, HT_POINT, CM_DDSP_TERRAFORM);
this->last_user_action = widget;
break;
case WID_ETT_RAISE_LAND: // Raise land button
HandlePlacePushButton(this, WID_ETT_RAISE_LAND, ANIMCURSOR_RAISELAND, HT_POINT);
HandlePlacePushButton(this, WID_ETT_RAISE_LAND, ANIMCURSOR_RAISELAND, HT_POINT, CM_DDSP_TERRAFORM);
this->last_user_action = widget;
break;
case WID_ETT_LEVEL_LAND: // Level land button
HandlePlacePushButton(this, WID_ETT_LEVEL_LAND, SPR_CURSOR_LEVEL_LAND, HT_POINT | HT_DIAGONAL);
HandlePlacePushButton(this, WID_ETT_LEVEL_LAND, SPR_CURSOR_LEVEL_LAND, HT_POINT | HT_DIAGONAL, CM_DDSP_TERRAFORM);
this->last_user_action = widget;
break;
case WID_ETT_PLACE_ROCKS: // Place rocks button
HandlePlacePushButton(this, WID_ETT_PLACE_ROCKS, SPR_CURSOR_ROCKY_AREA, HT_RECT);
HandlePlacePushButton(this, WID_ETT_PLACE_ROCKS, SPR_CURSOR_ROCKY_AREA, HT_RECT, CM_DDSP_TERRAFORM);
this->last_user_action = widget;
break;
case WID_ETT_PLACE_DESERT: // Place desert button (in tropical climate)
HandlePlacePushButton(this, WID_ETT_PLACE_DESERT, SPR_CURSOR_DESERT, HT_RECT);
HandlePlacePushButton(this, WID_ETT_PLACE_DESERT, SPR_CURSOR_DESERT, HT_RECT, CM_DDSP_TERRAFORM);
this->last_user_action = widget;
break;

View File

@@ -19,9 +19,9 @@
void PlaceProc_DemolishArea(TileIndex tile);
bool GUIPlaceProcDragXY(ViewportDragDropSelectionProcess proc, TileIndex start_tile, TileIndex end_tile);
bool HandlePlacePushButton(Window *w, int widget, CursorID cursor, HighLightStyle mode);
void SetObjectToPlaceWnd(CursorID icon, PaletteID pal, HighLightStyle mode, Window *w);
void SetObjectToPlace(CursorID icon, PaletteID pal, HighLightStyle mode, WindowClass window_class, WindowNumber window_num);
bool HandlePlacePushButton(Window *w, int widget, CursorID cursor, HighLightStyle mode, ViewportDragDropSelectionProcess cm_process);
void SetObjectToPlaceWnd(CursorID icon, PaletteID pal, HighLightStyle mode, Window *w, ViewportDragDropSelectionProcess cm_process);
void SetObjectToPlace(CursorID icon, PaletteID pal, HighLightStyle mode, WindowClass window_class, WindowNumber window_num, ViewportDragDropSelectionProcess cm_process);
void ResetObjectToPlace();
void VpSelectTilesWithMethod(int x, int y, ViewportPlaceMethod method);

View File

@@ -61,6 +61,7 @@
#include "citymania/cm_commands_gui.hpp"
#include "citymania/cm_locations.hpp"
#include "citymania/cm_main.hpp"
#include "citymania/cm_minimap.hpp"
#include "citymania/cm_watch_gui.hpp"
#include "citymania/cm_zoning.hpp"
@@ -267,7 +268,7 @@ static CallBackFunction SelectSignTool()
ResetObjectToPlace();
return CBF_NONE;
} else {
SetObjectToPlace(SPR_CURSOR_SIGN, PAL_NONE, HT_RECT, WC_MAIN_TOOLBAR, 0);
SetObjectToPlace(SPR_CURSOR_SIGN, PAL_NONE, HT_RECT, WC_MAIN_TOOLBAR, 0, CM_DDSP_PLACE_SIGN);
return CBF_PLACE_SIGN;
}
}
@@ -278,7 +279,7 @@ static CallBackFunction BuildCompanyHQ(){
ResetObjectToPlace();
return CBF_NONE;
} else {
SetObjectToPlace(SPR_CURSOR_HQ, PAL_NONE, HT_RECT, WC_MAIN_TOOLBAR, 0);
SetObjectToPlace(SPR_CURSOR_HQ, PAL_NONE, HT_RECT, WC_MAIN_TOOLBAR, 0, CM_DDSP_BUILD_HQ);
SetTileSelectSize(2, 2);
return CBF_BUILD_HQ;
}
@@ -517,7 +518,7 @@ static CallBackFunction ToolbarScenMapTownDir(Window *w)
static CallBackFunction MenuClickMap(int index)
{
switch (index) {
case MME_SHOW_SMALLMAP: ShowSmallMap(); break;
case MME_SHOW_SMALLMAP: citymania::ShowSmallMap(); break;
case MME_SHOW_EXTRAVIEWPORTS: ShowExtraViewportWindow(); break;
case MME_SHOW_LINKGRAPH: ShowLinkGraphLegend(); break;
case MME_SHOW_SIGNLISTS: ShowSignList(); break;
@@ -1116,7 +1117,7 @@ static CallBackFunction PlaceLandBlockInfo()
ResetObjectToPlace();
return CBF_NONE;
} else {
SetObjectToPlace(SPR_CURSOR_QUERY, PAL_NONE, HT_RECT, WC_MAIN_TOOLBAR, 0);
SetObjectToPlace(SPR_CURSOR_QUERY, PAL_NONE, HT_RECT, WC_MAIN_TOOLBAR, 0, CM_DDSP_LAND_INFO);
return CBF_PLACE_LANDINFO;
}
}
@@ -2140,7 +2141,7 @@ struct MainToolbarWindow : Window {
case MTHK_SETTINGS: ShowGameOptions(); break;
case MTHK_SAVEGAME: MenuClickSaveLoad(); break;
case MTHK_LOADGAME: ShowSaveLoadDialog(FT_SAVEGAME, SLO_LOAD); break;
case MTHK_SMALLMAP: ShowSmallMap(); break;
case MTHK_SMALLMAP: citymania::ShowSmallMap(); break;
case MTHK_TOWNDIRECTORY: ShowTownDirectory(); break;
case MTHK_SUBSIDIES: ShowSubsidiesList(); break;
case MTHK_STATIONS: ShowCompanyStations(_local_company); break;
@@ -2600,7 +2601,7 @@ struct ScenarioEditorToolbarWindow : Window {
case MTEHK_ZOOM_IN: ToolbarZoomInClick(this); break;
case MTEHK_ZOOM_OUT: ToolbarZoomOutClick(this); break;
case MTEHK_TERRAFORM: ShowEditorTerraformToolbar(); break;
case MTEHK_SMALLMAP: ShowSmallMap(); break;
case MTEHK_SMALLMAP: citymania::ShowSmallMap(); break;
case MTEHK_EXTRA_VIEWPORT: ShowExtraViewportWindowForTileUnderCursor(); break;
case CM_MTEHK_SMALLMAP_TOGGLE: citymania::ToggleSmallMap(); break;
default: return ES_NOT_HANDLED;

View File

@@ -1302,7 +1302,7 @@ public:
{
switch (widget) {
case WID_TF_NEW_TOWN:
HandlePlacePushButton(this, WID_TF_NEW_TOWN, SPR_CURSOR_TOWN, HT_RECT);
HandlePlacePushButton(this, WID_TF_NEW_TOWN, SPR_CURSOR_TOWN, HT_RECT, CM_DDSP_NEW_TOWN);
break;
case WID_TF_RANDOM_TOWN:

View File

@@ -102,7 +102,7 @@ class BuildTreesWindow : public Window
if (this->tree_to_plant >= 0) {
/* Activate placement */
if (_settings_client.sound.confirm) SndPlayFx(SND_15_BEEP);
SetObjectToPlace(SPR_CURSOR_TREE, PAL_NONE, HT_RECT, this->window_class, this->window_number);
SetObjectToPlace(SPR_CURSOR_TREE, PAL_NONE, HT_RECT, this->window_class, this->window_number, DDSP_PLANT_TREES);
this->tree_to_plant = current_tree; // SetObjectToPlace may call ResetObjectToPlace which may reset tree_to_plant to -1
} else {
/* Deactivate placement */

View File

@@ -1009,7 +1009,7 @@ struct RefitWindow : public Window {
this->SetSelectedVehicles(pt.x - nwi->pos_x);
this->SetWidgetDirty(WID_VR_VEHICLE_PANEL_DISPLAY);
if (!citymania::_fn_mod) {
SetObjectToPlaceWnd(SPR_CURSOR_MOUSE, PAL_NONE, HT_DRAG, this);
SetObjectToPlaceWnd(SPR_CURSOR_MOUSE, PAL_NONE, HT_DRAG, this, CM_DDSP_SELECT_REFIT);
} else {
/* The vehicle selection has changed. */
this->InvalidateData(2);

View File

@@ -3769,9 +3769,9 @@ EventState VpHandlePlaceSizingDrag()
* @param mode Mode to perform.
* @param w %Window requesting the mode change.
*/
void SetObjectToPlaceWnd(CursorID icon, PaletteID pal, HighLightStyle mode, Window *w)
void SetObjectToPlaceWnd(CursorID icon, PaletteID pal, HighLightStyle mode, Window *w, ViewportDragDropSelectionProcess cm_process)
{
SetObjectToPlace(icon, pal, mode, w->window_class, w->window_number);
SetObjectToPlace(icon, pal, mode, w->window_class, w->window_number, cm_process);
}
#include "table/animcursors.h"
@@ -3784,7 +3784,7 @@ void SetObjectToPlaceWnd(CursorID icon, PaletteID pal, HighLightStyle mode, Wind
* @param window_class %Window class of the window requesting the mode change.
* @param window_num Number of the window in its class requesting the mode change.
*/
void SetObjectToPlace(CursorID icon, PaletteID pal, HighLightStyle mode, WindowClass window_class, WindowNumber window_num)
void SetObjectToPlace(CursorID icon, PaletteID pal, HighLightStyle mode, WindowClass window_class, WindowNumber window_num, ViewportDragDropSelectionProcess cm_process)
{
if (_thd.window_class != WC_INVALID) {
/* Undo clicking on button and drag & drop */
@@ -3816,6 +3816,7 @@ void SetObjectToPlace(CursorID icon, PaletteID pal, HighLightStyle mode, WindowC
}
_thd.place_mode = mode;
_thd.select_proc = cm_process;
_thd.window_class = window_class;
_thd.window_number = window_num;
@@ -3834,7 +3835,7 @@ void SetObjectToPlace(CursorID icon, PaletteID pal, HighLightStyle mode, WindowC
/** Reset the cursor and mouse mode handling back to default (normal cursor, only clicking in windows). */
void ResetObjectToPlace()
{
SetObjectToPlace(SPR_CURSOR_MOUSE, PAL_NONE, HT_NONE, WC_MAIN_WINDOW, 0);
SetObjectToPlace(SPR_CURSOR_MOUSE, PAL_NONE, HT_NONE, WC_MAIN_WINDOW, 0, CM_DDSP_NONE);
}
Point GetViewportStationMiddle(const Viewport *vp, const Station *st)

View File

@@ -113,6 +113,7 @@ DECLARE_ENUM_AS_BIT_SET(ViewportPlaceMethod)
* you've selected it.
*/
enum ViewportDragDropSelectionProcess {
CM_DDSP_NONE, ///< CM Nothing is being built
DDSP_DEMOLISH_AREA, ///< Clear area
DDSP_DEMOLISH_TREES, ///< Clear trees
DDSP_RAISE_AND_LEVEL_AREA, ///< Raise / level area
@@ -142,6 +143,47 @@ enum ViewportDragDropSelectionProcess {
DDSP_REMOVE_BUSSTOP, ///< Road stop removal (buses)
DDSP_REMOVE_TRUCKSTOP, ///< Road stop removal (trucks)
DDSP_CONVERT_ROAD, ///< Road conversion
/* CityMania extras */
CM_DDSP_BUILD_HQ,
CM_DDSP_DEPOT_MOVE,
CM_DDSP_DEPOT_CLONE,
CM_DDSP_ZZZ,
CM_DDSP_STORY_BUTTON,
CM_DDSP_GROUP,
CM_DDSP_NEWGRF_SELECT,
CM_DDSP_PLACE_OBJECT,
CM_DDSP_PICK_STATION,
CM_DDSP_SELECT_ORDER,
CM_DDSP_PLACE_SIGN,
CM_DDSP_LAND_INFO,
CM_DDSP_SELECT_REFIT,
CM_DDSP_DEMOLISH,
CM_DDSP_BUILD_AIRPORT,
CM_DDSP_BUILD_CANNAL,
CM_DDSP_BUILD_LOCK,
CM_DDSP_BUILD_SHIP_DEPOT,
CM_DDSP_BUILD_DOCK,
CM_DDSP_BUILD_BUOY,
CM_DDSP_BUILD_RIVER,
CM_DDSP_BUILD_AQUEDUCT,
CM_DDSP_BUILD_RAIL_DEPOT,
CM_DDSP_FUND_INDUSTRY,
CM_DDSP_BUILD_WAYPOINT,
CM_DDSP_BUILD_RAIL_BRIDGE,
CM_DDSP_BUILD_RAIL_TUNNEL,
CM_DDSP_BUILD_ROAD_DEPOT,
CM_DDSP_BUILD_ROAD_BRIDGE,
CM_DDSP_BUILD_ROAD_TUNNEL,
CM_DDSP_DEMOLISH_TREES,
CM_DDSP_TERRAFORM,
CM_DDSP_BUY_LAND,
CM_DDSP_NEW_TOWN,
};