Add object highlight types from blueprint branch
This commit is contained in:
@@ -1,10 +1,13 @@
|
||||
#include "../stdafx.h"
|
||||
|
||||
#include "cm_highlight.hpp"
|
||||
|
||||
#include "cm_blueprint.hpp"
|
||||
#include "cm_main.hpp"
|
||||
#include "cm_station_gui.hpp"
|
||||
|
||||
#include "../core/math_func.hpp"
|
||||
#include "../table/bridge_land.h"
|
||||
#include "../command_func.h"
|
||||
#include "../house.h"
|
||||
#include "../industry.h"
|
||||
@@ -72,27 +75,53 @@ const byte _tileh_to_sprite[32] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 17, 0, 15, 18, 0,
|
||||
};
|
||||
|
||||
|
||||
ObjectTileHighlight ObjectTileHighlight::make_depot(DiagDirection ddir) {
|
||||
ObjectTileHighlight ObjectTileHighlight::make_rail_depot(DiagDirection ddir) {
|
||||
auto oh = ObjectTileHighlight(Type::RAIL_DEPOT);
|
||||
oh.u.depot.ddir = ddir;
|
||||
oh.u.rail.depot.ddir = ddir;
|
||||
return oh;
|
||||
}
|
||||
|
||||
ObjectTileHighlight ObjectTileHighlight::make_rail(Track track) {
|
||||
ObjectTileHighlight ObjectTileHighlight::make_rail_track(Track track) {
|
||||
auto oh = ObjectTileHighlight(Type::RAIL_TRACK);
|
||||
oh.u.rail.track = track;
|
||||
return oh;
|
||||
}
|
||||
|
||||
ObjectTileHighlight ObjectTileHighlight::make_rail_station(Axis axis) {
|
||||
auto oh = ObjectTileHighlight(Type::RAIL_STATION);
|
||||
oh.u.rail.station.axis = axis;
|
||||
return oh;
|
||||
}
|
||||
|
||||
ObjectTileHighlight ObjectTileHighlight::make_rail_signal(uint pos, SignalType type, SignalVariant variant) {
|
||||
auto oh = ObjectTileHighlight(Type::RAIL_SIGNAL);
|
||||
oh.u.rail.signal.pos = pos;
|
||||
oh.u.rail.signal.type = type;
|
||||
oh.u.rail.signal.variant = variant;
|
||||
return oh;
|
||||
}
|
||||
|
||||
ObjectTileHighlight ObjectTileHighlight::make_rail_bridge_head(DiagDirection ddir, BridgeType type) {
|
||||
auto oh = ObjectTileHighlight(Type::RAIL_BRIDGE_HEAD);
|
||||
oh.u.rail.bridge_head.ddir = ddir;
|
||||
oh.u.rail.bridge_head.type = type;
|
||||
return oh;
|
||||
}
|
||||
|
||||
ObjectTileHighlight ObjectTileHighlight::make_rail_tunnel_head(DiagDirection ddir) {
|
||||
auto oh = ObjectTileHighlight(Type::RAIL_TUNNEL_HEAD);
|
||||
oh.u.rail.tunnel_head.ddir = ddir;
|
||||
return oh;
|
||||
}
|
||||
|
||||
bool ObjectHighlight::operator==(const ObjectHighlight& oh) {
|
||||
if (this->type != oh.type) return false;
|
||||
switch (this->type) {
|
||||
case Type::RAIL_DEPOT: return this->u.depot.tile == oh.u.depot.tile && this->u.depot.ddir == oh.u.depot.ddir;
|
||||
default: return true;
|
||||
}
|
||||
return true;
|
||||
return (this->tile == oh.tile && this->ddir == oh.ddir && this->blueprint == oh.blueprint);
|
||||
// switch (this->type) {
|
||||
// case Type::RAIL_DEPOT: return this->tile == oh.tile && this->ddir == oh.ddir;
|
||||
// default: return true;
|
||||
// }
|
||||
// return true;
|
||||
}
|
||||
|
||||
bool ObjectHighlight::operator!=(const ObjectHighlight& oh) {
|
||||
@@ -101,12 +130,19 @@ bool ObjectHighlight::operator!=(const ObjectHighlight& oh) {
|
||||
|
||||
|
||||
ObjectHighlight ObjectHighlight::make_depot(TileIndex tile, DiagDirection ddir) {
|
||||
auto oh = ObjectHighlight(ObjectHighlight::Type::RAIL_DEPOT);
|
||||
oh.u.depot.tile = tile;
|
||||
oh.u.depot.ddir = ddir;
|
||||
auto oh = ObjectHighlight{ObjectHighlight::Type::RAIL_DEPOT};
|
||||
oh.tile = tile;
|
||||
oh.ddir = ddir;
|
||||
return oh;
|
||||
}
|
||||
|
||||
// ObjectHighlight ObjectHighlight::make_blueprint(TileIndex tile, sp<Blueprint> blueprint) {
|
||||
// auto oh = ObjectHighlight{ObjectHighlight::Type::BLUEPRINT};
|
||||
// oh.tile = tile;
|
||||
// oh.blueprint = blueprint;
|
||||
// return oh;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Try to add an additional rail-track at the entrance of a depot
|
||||
* @param tile Tile to use for adding the rail-track
|
||||
@@ -119,7 +155,7 @@ void ObjectHighlight::PlaceExtraDepotRail(TileIndex tile, DiagDirection dir, Tra
|
||||
if (GetRailTileType(tile) != RAIL_TILE_NORMAL) return;
|
||||
if ((GetTrackBits(tile) & DiagdirReachesTracks(dir)) == 0) return;
|
||||
|
||||
this->tiles.insert(std::make_pair(tile, ObjectTileHighlight::make_rail(track)));
|
||||
this->tiles.insert(std::make_pair(tile, ObjectTileHighlight::make_rail_track(track)));
|
||||
}
|
||||
|
||||
/** Additional pieces of track to add at the entrance of a depot. */
|
||||
@@ -140,16 +176,20 @@ void ObjectHighlight::UpdateTiles() {
|
||||
this->tiles.clear();
|
||||
switch (this->type) {
|
||||
case Type::RAIL_DEPOT: {
|
||||
auto dir = this->u.depot.ddir;
|
||||
this->tiles.insert(std::make_pair(this->u.depot.tile, ObjectTileHighlight::make_depot(dir)));
|
||||
auto tile = this->u.depot.tile + TileOffsByDiagDir(dir);
|
||||
auto dir = this->ddir;
|
||||
this->tiles.insert(std::make_pair(this->tile, ObjectTileHighlight::make_rail_depot(dir)));
|
||||
auto tile = this->tile + TileOffsByDiagDir(dir);
|
||||
if (IsTileType(tile, MP_RAILWAY) && IsCompatibleRail(GetRailType(tile), _cur_railtype)) {
|
||||
PlaceExtraDepotRail(tile, _place_depot_extra_dir[dir], _place_depot_extra_track[dir]);
|
||||
PlaceExtraDepotRail(tile, _place_depot_extra_dir[dir + 4], _place_depot_extra_track[dir + 4]);
|
||||
PlaceExtraDepotRail(tile, _place_depot_extra_dir[dir + 8], _place_depot_extra_track[dir + 8]);
|
||||
this->PlaceExtraDepotRail(tile, _place_depot_extra_dir[dir], _place_depot_extra_track[dir]);
|
||||
this->PlaceExtraDepotRail(tile, _place_depot_extra_dir[dir + 4], _place_depot_extra_track[dir + 4]);
|
||||
this->PlaceExtraDepotRail(tile, _place_depot_extra_dir[dir + 8], _place_depot_extra_track[dir + 8]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
// case Type::BLUEPRINT:
|
||||
// if (this->blueprint && this->tile != INVALID_TILE)
|
||||
// this->tiles = this->blueprint->GetTiles(this->tile);
|
||||
// break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -195,24 +235,208 @@ void DrawTrainDepotSprite(const TileInfo *ti, RailType railtype, DiagDirection d
|
||||
DrawRailTileSeq(ti, dts, TO_INVALID, offset, 0, PALETTE_TINT_WHITE);
|
||||
}
|
||||
|
||||
void DrawTrainStationSprite(const TileInfo *ti, RailType railtype, Axis axis) {
|
||||
int32 total_offset = 0;
|
||||
PaletteID pal = COMPANY_SPRITE_COLOUR(_local_company);
|
||||
const DrawTileSprites *t = GetStationTileLayout(STATION_RAIL, (axis == AXIS_X ? 0 : 1));
|
||||
const RailtypeInfo *rti = nullptr;
|
||||
|
||||
if (railtype != INVALID_RAILTYPE) {
|
||||
rti = GetRailTypeInfo(railtype);
|
||||
total_offset = rti->GetRailtypeSpriteOffset();
|
||||
}
|
||||
|
||||
DrawAutorailSelection(ti, (axis == AXIS_X ? HT_DIR_X : HT_DIR_Y), PAL_NONE);
|
||||
|
||||
// if (roadtype != INVALID_ROADTYPE) {
|
||||
// const RoadTypeInfo* rti = GetRoadTypeInfo(roadtype);
|
||||
// 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, x, y);
|
||||
|
||||
// SpriteID overlay = GetCustomRoadSprite(rti, INVALID_TILE, ROTSG_OVERLAY);
|
||||
// if (overlay) DrawSprite(overlay + sprite_offset, PAL_NONE, x, y);
|
||||
// } else if (RoadTypeIsTram(roadtype)) {
|
||||
// DrawSprite(SPR_TRAMWAY_TRAM + sprite_offset, PAL_NONE, x, y);
|
||||
// }
|
||||
// } else {
|
||||
// /* Drive-in stop */
|
||||
// if (RoadTypeIsRoad(roadtype) && rti->UsesOverlay()) {
|
||||
// SpriteID ground = GetCustomRoadSprite(rti, INVALID_TILE, ROTSG_ROADSTOP);
|
||||
// DrawSprite(ground + image, PAL_NONE, x, y);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
/* Default waypoint has no railtype specific sprites */
|
||||
// DrawRailTileSeq(ti, t, TO_INVALID, (st == STATION_WAYPOINT ? 0 : total_offset), 0, PALETTE_TINT_WHITE);
|
||||
DrawRailTileSeq(ti, t, TO_INVALID, total_offset, 0, PALETTE_TINT_WHITE);
|
||||
}
|
||||
|
||||
enum SignalOffsets { // from rail_cmd.cpp
|
||||
SIGNAL_TO_SOUTHWEST,
|
||||
SIGNAL_TO_NORTHEAST,
|
||||
SIGNAL_TO_SOUTHEAST,
|
||||
SIGNAL_TO_NORTHWEST,
|
||||
SIGNAL_TO_EAST,
|
||||
SIGNAL_TO_WEST,
|
||||
SIGNAL_TO_SOUTH,
|
||||
SIGNAL_TO_NORTH,
|
||||
};
|
||||
|
||||
/**
|
||||
* copied from rail_cmd.cpp
|
||||
* Get surface height in point (x,y)
|
||||
* On tiles with halftile foundations move (x,y) to a safe point wrt. track
|
||||
*/
|
||||
static uint GetSaveSlopeZ(uint x, uint y, Track track)
|
||||
{
|
||||
switch (track) {
|
||||
case TRACK_UPPER: x &= ~0xF; y &= ~0xF; break;
|
||||
case TRACK_LOWER: x |= 0xF; y |= 0xF; break;
|
||||
case TRACK_LEFT: x |= 0xF; y &= ~0xF; break;
|
||||
case TRACK_RIGHT: x &= ~0xF; y |= 0xF; break;
|
||||
default: break;
|
||||
}
|
||||
return GetSlopePixelZ(x, y);
|
||||
}
|
||||
|
||||
void DrawSignal(const TileInfo *ti, RailType railtype, uint pos, SignalType type, SignalVariant variant) {
|
||||
// reference: DraawSingleSignal in rail_cmd.cpp
|
||||
bool side;
|
||||
switch (_settings_game.construction.train_signal_side) {
|
||||
case 0: side = false; break; // left
|
||||
case 2: side = true; break; // right
|
||||
default: side = _settings_game.vehicle.road_side != 0; break; // driving side
|
||||
}
|
||||
static const Point SignalPositions[2][12] = {
|
||||
{ // Signals on the left side
|
||||
/* LEFT LEFT RIGHT RIGHT UPPER UPPER */
|
||||
{ 8, 5}, {14, 1}, { 1, 14}, { 9, 11}, { 1, 0}, { 3, 10},
|
||||
/* LOWER LOWER X X Y Y */
|
||||
{11, 4}, {14, 14}, {11, 3}, { 4, 13}, { 3, 4}, {11, 13}
|
||||
}, { // Signals on the right side
|
||||
/* LEFT LEFT RIGHT RIGHT UPPER UPPER */
|
||||
{14, 1}, {12, 10}, { 4, 6}, { 1, 14}, {10, 4}, { 0, 1},
|
||||
/* LOWER LOWER X X Y Y */
|
||||
{14, 14}, { 5, 12}, {11, 13}, { 4, 3}, {13, 4}, { 3, 11}
|
||||
}
|
||||
};
|
||||
|
||||
uint x = TileX(ti->tile) * TILE_SIZE + SignalPositions[side][pos].x;
|
||||
uint y = TileY(ti->tile) * TILE_SIZE + SignalPositions[side][pos].y;
|
||||
|
||||
static const Track pos_track[] = {
|
||||
TRACK_LEFT, TRACK_LEFT, TRACK_RIGHT, TRACK_RIGHT,
|
||||
TRACK_UPPER, TRACK_UPPER, TRACK_LOWER, TRACK_LOWER,
|
||||
TRACK_X, TRACK_X, TRACK_Y, TRACK_Y,
|
||||
};
|
||||
static const SignalOffsets pos_offset[] = {
|
||||
SIGNAL_TO_NORTH, SIGNAL_TO_SOUTH, SIGNAL_TO_NORTH, SIGNAL_TO_SOUTH,
|
||||
SIGNAL_TO_WEST, SIGNAL_TO_EAST, SIGNAL_TO_WEST, SIGNAL_TO_EAST,
|
||||
SIGNAL_TO_SOUTHWEST, SIGNAL_TO_NORTHEAST, SIGNAL_TO_SOUTHEAST, SIGNAL_TO_NORTHWEST,
|
||||
};
|
||||
|
||||
auto track = pos_track[pos];
|
||||
auto image = pos_offset[pos];
|
||||
static const SignalState condition = SIGNAL_STATE_GREEN;
|
||||
|
||||
auto rti = GetRailTypeInfo(railtype);
|
||||
SpriteID sprite = GetCustomSignalSprite(rti, ti->tile, type, variant, condition);
|
||||
if (sprite != 0) {
|
||||
sprite += image;
|
||||
} else {
|
||||
/* Normal electric signals are stored in a different sprite block than all other signals. */
|
||||
sprite = (type == SIGTYPE_NORMAL && variant == SIG_ELECTRIC) ? SPR_ORIGINAL_SIGNALS_BASE : SPR_SIGNALS_BASE - 16;
|
||||
sprite += type * 16 + variant * 64 + image * 2 + condition + (type > SIGTYPE_LAST_NOPBS ? 64 : 0);
|
||||
}
|
||||
|
||||
AddSortableSpriteToDraw(sprite, PALETTE_TINT_WHITE, x, y, 1, 1, BB_HEIGHT_UNDER_BRIDGE, GetSaveSlopeZ(x, y, track));
|
||||
}
|
||||
|
||||
// copied from tunnelbridge_cmd.cpp
|
||||
static inline const PalSpriteID *GetBridgeSpriteTable(int index, BridgePieces table)
|
||||
{
|
||||
const BridgeSpec *bridge = GetBridgeSpec(index);
|
||||
assert(table < BRIDGE_PIECE_INVALID);
|
||||
if (bridge->sprite_table == nullptr || bridge->sprite_table[table] == nullptr) {
|
||||
return _bridge_sprite_table[index][table];
|
||||
} else {
|
||||
return bridge->sprite_table[table];
|
||||
}
|
||||
}
|
||||
|
||||
void DrawBridgeHead(const TileInfo *ti, RailType railtype, DiagDirection ddir, BridgeType type) {
|
||||
auto rti = GetRailTypeInfo(railtype);
|
||||
int base_offset = rti->bridge_offset;
|
||||
const PalSpriteID *psid;
|
||||
|
||||
/* HACK Wizardry to convert the bridge ramp direction into a sprite offset */
|
||||
base_offset += (6 - ddir) % 4;
|
||||
|
||||
/* Table number BRIDGE_PIECE_HEAD always refers to the bridge heads for any bridge type */
|
||||
if (ti->tileh == SLOPE_FLAT) base_offset += 4; // sloped bridge head
|
||||
psid = &GetBridgeSpriteTable(type, BRIDGE_PIECE_HEAD)[base_offset];
|
||||
|
||||
AddSortableSpriteToDraw(psid->sprite, PALETTE_TINT_WHITE, ti->x, ti->y, 16, 16, ti->tileh == SLOPE_FLAT ? 0 : 8, ti->z);
|
||||
// DrawAutorailSelection(ti, (ddir == DIAGDIR_SW || ddir == DIAGDIR_NE ? HT_DIR_X : HT_DIR_Y), PAL_NONE);
|
||||
}
|
||||
|
||||
void DrawTunnelHead(const TileInfo *ti, RailType railtype, DiagDirection ddir) {
|
||||
auto rti = GetRailTypeInfo(railtype);
|
||||
|
||||
SpriteID image;
|
||||
SpriteID railtype_overlay = 0;
|
||||
|
||||
image = rti->base_sprites.tunnel;
|
||||
if (rti->UsesOverlay()) {
|
||||
/* Check if the railtype has custom tunnel portals. */
|
||||
railtype_overlay = GetCustomRailSprite(rti, ti->tile, RTSG_TUNNEL_PORTAL);
|
||||
if (railtype_overlay != 0) image = SPR_RAILTYPE_TUNNEL_BASE; // Draw blank grass tunnel base.
|
||||
}
|
||||
|
||||
image += ddir * 2;
|
||||
AddSortableSpriteToDraw(image, PALETTE_TINT_WHITE, ti->x, ti->y, 16, 16, 0, ti->z);
|
||||
}
|
||||
|
||||
void ObjectHighlight::Draw(const TileInfo *ti) {
|
||||
this->UpdateTiles();
|
||||
auto range = this->tiles.equal_range(ti->tile);
|
||||
auto i=0;
|
||||
for (auto t = range.first; t != range.second; t++) {
|
||||
i++;
|
||||
auto &oth = t->second;
|
||||
switch (oth.type) {
|
||||
case ObjectTileHighlight::Type::RAIL_DEPOT:
|
||||
DrawTrainDepotSprite(ti, _cur_railtype, oth.u.depot.ddir);
|
||||
DrawTrainDepotSprite(ti, _cur_railtype, oth.u.rail.depot.ddir);
|
||||
break;
|
||||
case ObjectTileHighlight::Type::RAIL_TRACK: {
|
||||
auto hs = (HighLightStyle)oth.u.rail.track;
|
||||
DrawAutorailSelection(ti, hs, PAL_NONE);
|
||||
break;
|
||||
}
|
||||
case ObjectTileHighlight::Type::RAIL_STATION:
|
||||
DrawTrainStationSprite(ti, _cur_railtype, oth.u.rail.station.axis);
|
||||
break;
|
||||
case ObjectTileHighlight::Type::RAIL_SIGNAL:
|
||||
DrawSignal(ti, _cur_railtype, oth.u.rail.signal.pos, oth.u.rail.signal.type, oth.u.rail.signal.variant);
|
||||
break;
|
||||
case ObjectTileHighlight::Type::RAIL_BRIDGE_HEAD:
|
||||
DrawBridgeHead(ti, _cur_railtype, oth.u.rail.bridge_head.ddir, oth.u.rail.bridge_head.type);
|
||||
break;
|
||||
case ObjectTileHighlight::Type::RAIL_TUNNEL_HEAD:
|
||||
DrawTunnelHead(ti, _cur_railtype, oth.u.rail.tunnel_head.ddir);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
// fprintf(stderr, "TILEH DRAW %d %d %d\n", ti->tile, (int)i, (int)this->tiles.size());
|
||||
}
|
||||
|
||||
|
||||
@@ -526,6 +750,7 @@ TileHighlight GetTileHighlight(const TileInfo *ti) {
|
||||
}
|
||||
|
||||
SetStationSelectionHighlight(ti, th);
|
||||
// SetBlueprintHighlight(ti, th);
|
||||
|
||||
return th;
|
||||
}
|
||||
@@ -546,6 +771,8 @@ void DrawTileZoning(const TileInfo *ti, const TileHighlight &th) {
|
||||
bool DrawTileSelection(const TileInfo *ti, const TileHighlightType &tht) {
|
||||
_thd.cm.Draw(ti);
|
||||
|
||||
// if (_thd.drawstyle == CM_HT_BLUEPRINT_PLACE) return true;
|
||||
|
||||
if ((_thd.drawstyle & HT_DRAG_MASK) == HT_RECT && _thd.outersize.x > 0) {
|
||||
// station selector, handled by DrawTileZoning
|
||||
return true;
|
||||
@@ -643,11 +870,15 @@ DiagDirection AddAutodetectionRotation(DiagDirection ddir) {
|
||||
|
||||
HighLightStyle UpdateTileSelection(HighLightStyle new_drawstyle) {
|
||||
_thd.cm_new = ObjectHighlight(ObjectHighlight::Type::NONE);
|
||||
auto pt = GetTileBelowCursor();
|
||||
auto tile = (pt.x == -1 ? INVALID_TILE : TileVirtXY(pt.x, pt.y));
|
||||
// if (_thd.place_mode == CM_HT_BLUEPRINT_PLACE) {
|
||||
// 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) {
|
||||
auto dir = _build_depot_direction;
|
||||
auto pt = GetTileBelowCursor();
|
||||
auto tile = TileVirtXY(pt.x, pt.y);
|
||||
if (pt.x != -1) {
|
||||
if (dir >= DiagDirection::DIAGDIR_END) {
|
||||
dir = AddAutodetectionRotation(AutodetectRailObjectDirection(tile, pt));
|
||||
|
||||
@@ -1,36 +1,152 @@
|
||||
#ifndef CITYMANIA_HIGHLIGHT_TYPE_HPP
|
||||
#define CITYMANIA_HIGHLIGHT_TYPE_HPP
|
||||
|
||||
#include "../bridge.h"
|
||||
#include "../direction_type.h"
|
||||
#include "../map_func.h"
|
||||
#include "../signal_type.h"
|
||||
#include "../station_type.h"
|
||||
#include "../tile_cmd.h"
|
||||
#include "../tile_type.h"
|
||||
#include "../track_type.h"
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace citymania {
|
||||
|
||||
|
||||
class ObjectTileHighlight {
|
||||
public:
|
||||
enum class Type {
|
||||
RAIL_DEPOT = 0,
|
||||
RAIL_TRACK = 1,
|
||||
BEGIN = 0,
|
||||
RAIL_DEPOT = BEGIN,
|
||||
RAIL_TRACK,
|
||||
RAIL_STATION,
|
||||
RAIL_SIGNAL,
|
||||
RAIL_BRIDGE_HEAD,
|
||||
RAIL_TUNNEL_HEAD,
|
||||
END,
|
||||
};
|
||||
|
||||
Type type;
|
||||
union {
|
||||
struct {
|
||||
DiagDirection ddir;
|
||||
} depot;
|
||||
struct {
|
||||
struct {
|
||||
DiagDirection ddir;
|
||||
} depot;
|
||||
Track track;
|
||||
struct {
|
||||
Axis axis;
|
||||
} station;
|
||||
struct {
|
||||
uint pos;
|
||||
SignalType type;
|
||||
SignalVariant variant;
|
||||
} signal;
|
||||
struct {
|
||||
DiagDirection ddir;
|
||||
TileIndex other_end;
|
||||
BridgeType type;
|
||||
} bridge_head;
|
||||
struct {
|
||||
DiagDirection ddir;
|
||||
} tunnel_head;
|
||||
} rail;
|
||||
} u;
|
||||
|
||||
ObjectTileHighlight(Type type): type{type} {}
|
||||
static ObjectTileHighlight make_depot(DiagDirection ddir);
|
||||
static ObjectTileHighlight make_rail(Track track);
|
||||
static ObjectTileHighlight make_rail_depot(DiagDirection ddir);
|
||||
static ObjectTileHighlight make_rail_track(Track track);
|
||||
static ObjectTileHighlight make_rail_station(Axis axis);
|
||||
static ObjectTileHighlight make_rail_signal(uint pos, SignalType type, SignalVariant variant);
|
||||
static ObjectTileHighlight make_rail_bridge_head(DiagDirection ddir, BridgeType type);
|
||||
static ObjectTileHighlight make_rail_tunnel_head(DiagDirection ddir);
|
||||
};
|
||||
|
||||
class TileIndexDiffCCompare{
|
||||
public:
|
||||
bool operator()(const TileIndexDiffC &a, const TileIndexDiffC &b) {
|
||||
if (a.x < b.x) return true;
|
||||
if (a.x == b.x && a.y < b.y) return true;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
class Blueprint {
|
||||
public:
|
||||
class Item {
|
||||
public:
|
||||
enum class Type {
|
||||
BEGIN = 0,
|
||||
RAIL_DEPOT = BEGIN,
|
||||
RAIL_TRACK,
|
||||
RAIL_STATION,
|
||||
RAIL_STATION_PART,
|
||||
RAIL_SIGNAL,
|
||||
RAIL_BRIDGE,
|
||||
RAIL_TUNNEL,
|
||||
END,
|
||||
};
|
||||
Type type;
|
||||
TileIndexDiffC tdiff;
|
||||
union {
|
||||
struct {
|
||||
struct {
|
||||
DiagDirection ddir;
|
||||
} depot;
|
||||
struct {
|
||||
uint16 length;
|
||||
Trackdir start_dir;
|
||||
} track;
|
||||
struct {
|
||||
StationID id;
|
||||
bool has_part;
|
||||
} station;
|
||||
struct {
|
||||
Axis axis;
|
||||
StationID id;
|
||||
} station_part;
|
||||
struct {
|
||||
uint pos;
|
||||
SignalType type;
|
||||
SignalVariant variant;
|
||||
} signal;
|
||||
struct {
|
||||
DiagDirection ddir;
|
||||
TileIndexDiffC other_end;
|
||||
BridgeType type;
|
||||
} bridge;
|
||||
struct {
|
||||
DiagDirection ddir;
|
||||
TileIndexDiffC other_end;
|
||||
} tunnel;
|
||||
} rail;
|
||||
} u;
|
||||
Item(Type type, TileIndexDiffC tdiff)
|
||||
: type{type}, tdiff{tdiff} {}
|
||||
};
|
||||
|
||||
std::vector<Item> items;
|
||||
std::set<TileIndexDiffC, TileIndexDiffCCompare> tiles;
|
||||
|
||||
Blueprint() {}
|
||||
|
||||
void Clear() {
|
||||
this->items.clear();
|
||||
this->tiles.clear();
|
||||
}
|
||||
|
||||
void Add(Item item);
|
||||
|
||||
bool HasTile(TileIndexDiffC tdiff) {
|
||||
return (this->tiles.find(tdiff) != this->tiles.end());
|
||||
}
|
||||
|
||||
sp<Blueprint> Rotate();
|
||||
|
||||
std::multimap<TileIndex, ObjectTileHighlight> GetTiles(TileIndex tile);
|
||||
};
|
||||
|
||||
class ObjectHighlight {
|
||||
@@ -38,15 +154,13 @@ public:
|
||||
enum class Type {
|
||||
NONE = 0,
|
||||
RAIL_DEPOT = 1,
|
||||
// BLUEPRINT = 2,
|
||||
};
|
||||
|
||||
Type type;
|
||||
union {
|
||||
struct {
|
||||
TileIndex tile;
|
||||
DiagDirection ddir;
|
||||
} depot;
|
||||
} u;
|
||||
TileIndex tile = INVALID_TILE;
|
||||
DiagDirection ddir = INVALID_DIAGDIR;
|
||||
sp<Blueprint> blueprint = nullptr;
|
||||
|
||||
protected:
|
||||
bool tiles_updated = false;
|
||||
@@ -55,11 +169,12 @@ protected:
|
||||
void PlaceExtraDepotRail(TileIndex tile, DiagDirection dir, Track track);
|
||||
|
||||
public:
|
||||
ObjectHighlight(Type type = Type::NONE): type{type} { /* get rid of uninitualized warning */ this->u.depot.tile = INVALID_TILE; }
|
||||
ObjectHighlight(Type type = Type::NONE): type{type} {}
|
||||
bool operator==(const ObjectHighlight& oh);
|
||||
bool operator!=(const ObjectHighlight& oh);
|
||||
|
||||
static ObjectHighlight make_depot(TileIndex tile, DiagDirection ddir);
|
||||
// static ObjectHighlight make_blueprint(TileIndex tile, sp<Blueprint> blueprint);
|
||||
|
||||
void Draw(const TileInfo *ti);
|
||||
void MarkDirty();
|
||||
|
||||
@@ -825,7 +825,7 @@ struct BuildRailToolbarWindow : Window {
|
||||
ddir = _build_depot_direction;
|
||||
if (ddir == DIAGDIR_NW + 1) {
|
||||
assert(_thd.cm.type == citymania::ObjectHighlight::Type::RAIL_DEPOT);
|
||||
ddir = _thd.cm.u.depot.ddir;
|
||||
ddir = _thd.cm.ddir;
|
||||
}
|
||||
DoCommandP(tile, _cur_railtype, ddir,
|
||||
CMD_BUILD_TRAIN_DEPOT | CMD_MSG(STR_ERROR_CAN_T_BUILD_TRAIN_DEPOT),
|
||||
|
||||
Reference in New Issue
Block a user