Add object highlight types from blueprint branch
This commit is contained in:
@@ -1,10 +1,13 @@
|
|||||||
#include "../stdafx.h"
|
#include "../stdafx.h"
|
||||||
|
|
||||||
#include "cm_highlight.hpp"
|
#include "cm_highlight.hpp"
|
||||||
|
|
||||||
|
#include "cm_blueprint.hpp"
|
||||||
#include "cm_main.hpp"
|
#include "cm_main.hpp"
|
||||||
#include "cm_station_gui.hpp"
|
#include "cm_station_gui.hpp"
|
||||||
|
|
||||||
#include "../core/math_func.hpp"
|
#include "../core/math_func.hpp"
|
||||||
|
#include "../table/bridge_land.h"
|
||||||
#include "../command_func.h"
|
#include "../command_func.h"
|
||||||
#include "../house.h"
|
#include "../house.h"
|
||||||
#include "../industry.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,
|
0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 17, 0, 15, 18, 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ObjectTileHighlight ObjectTileHighlight::make_rail_depot(DiagDirection ddir) {
|
||||||
ObjectTileHighlight ObjectTileHighlight::make_depot(DiagDirection ddir) {
|
|
||||||
auto oh = ObjectTileHighlight(Type::RAIL_DEPOT);
|
auto oh = ObjectTileHighlight(Type::RAIL_DEPOT);
|
||||||
oh.u.depot.ddir = ddir;
|
oh.u.rail.depot.ddir = ddir;
|
||||||
return oh;
|
return oh;
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectTileHighlight ObjectTileHighlight::make_rail(Track track) {
|
ObjectTileHighlight ObjectTileHighlight::make_rail_track(Track track) {
|
||||||
auto oh = ObjectTileHighlight(Type::RAIL_TRACK);
|
auto oh = ObjectTileHighlight(Type::RAIL_TRACK);
|
||||||
oh.u.rail.track = track;
|
oh.u.rail.track = track;
|
||||||
return oh;
|
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) {
|
bool ObjectHighlight::operator==(const ObjectHighlight& oh) {
|
||||||
if (this->type != oh.type) return false;
|
if (this->type != oh.type) return false;
|
||||||
switch (this->type) {
|
return (this->tile == oh.tile && this->ddir == oh.ddir && this->blueprint == oh.blueprint);
|
||||||
case Type::RAIL_DEPOT: return this->u.depot.tile == oh.u.depot.tile && this->u.depot.ddir == oh.u.depot.ddir;
|
// switch (this->type) {
|
||||||
default: return true;
|
// case Type::RAIL_DEPOT: return this->tile == oh.tile && this->ddir == oh.ddir;
|
||||||
}
|
// default: return true;
|
||||||
return true;
|
// }
|
||||||
|
// return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ObjectHighlight::operator!=(const ObjectHighlight& oh) {
|
bool ObjectHighlight::operator!=(const ObjectHighlight& oh) {
|
||||||
@@ -101,12 +130,19 @@ bool ObjectHighlight::operator!=(const ObjectHighlight& oh) {
|
|||||||
|
|
||||||
|
|
||||||
ObjectHighlight ObjectHighlight::make_depot(TileIndex tile, DiagDirection ddir) {
|
ObjectHighlight ObjectHighlight::make_depot(TileIndex tile, DiagDirection ddir) {
|
||||||
auto oh = ObjectHighlight(ObjectHighlight::Type::RAIL_DEPOT);
|
auto oh = ObjectHighlight{ObjectHighlight::Type::RAIL_DEPOT};
|
||||||
oh.u.depot.tile = tile;
|
oh.tile = tile;
|
||||||
oh.u.depot.ddir = ddir;
|
oh.ddir = ddir;
|
||||||
return oh;
|
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
|
* Try to add an additional rail-track at the entrance of a depot
|
||||||
* @param tile Tile to use for adding the rail-track
|
* @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 (GetRailTileType(tile) != RAIL_TILE_NORMAL) return;
|
||||||
if ((GetTrackBits(tile) & DiagdirReachesTracks(dir)) == 0) 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. */
|
/** Additional pieces of track to add at the entrance of a depot. */
|
||||||
@@ -140,16 +176,20 @@ void ObjectHighlight::UpdateTiles() {
|
|||||||
this->tiles.clear();
|
this->tiles.clear();
|
||||||
switch (this->type) {
|
switch (this->type) {
|
||||||
case Type::RAIL_DEPOT: {
|
case Type::RAIL_DEPOT: {
|
||||||
auto dir = this->u.depot.ddir;
|
auto dir = this->ddir;
|
||||||
this->tiles.insert(std::make_pair(this->u.depot.tile, ObjectTileHighlight::make_depot(dir)));
|
this->tiles.insert(std::make_pair(this->tile, ObjectTileHighlight::make_rail_depot(dir)));
|
||||||
auto tile = this->u.depot.tile + TileOffsByDiagDir(dir);
|
auto tile = this->tile + TileOffsByDiagDir(dir);
|
||||||
if (IsTileType(tile, MP_RAILWAY) && IsCompatibleRail(GetRailType(tile), _cur_railtype)) {
|
if (IsTileType(tile, MP_RAILWAY) && IsCompatibleRail(GetRailType(tile), _cur_railtype)) {
|
||||||
PlaceExtraDepotRail(tile, _place_depot_extra_dir[dir], _place_depot_extra_track[dir]);
|
this->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]);
|
this->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 + 8], _place_depot_extra_track[dir + 8]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
// case Type::BLUEPRINT:
|
||||||
|
// if (this->blueprint && this->tile != INVALID_TILE)
|
||||||
|
// this->tiles = this->blueprint->GetTiles(this->tile);
|
||||||
|
// break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -195,24 +235,208 @@ void DrawTrainDepotSprite(const TileInfo *ti, RailType railtype, DiagDirection d
|
|||||||
DrawRailTileSeq(ti, dts, TO_INVALID, offset, 0, PALETTE_TINT_WHITE);
|
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) {
|
void ObjectHighlight::Draw(const TileInfo *ti) {
|
||||||
this->UpdateTiles();
|
this->UpdateTiles();
|
||||||
auto range = this->tiles.equal_range(ti->tile);
|
auto range = this->tiles.equal_range(ti->tile);
|
||||||
|
auto i=0;
|
||||||
for (auto t = range.first; t != range.second; t++) {
|
for (auto t = range.first; t != range.second; t++) {
|
||||||
|
i++;
|
||||||
auto &oth = t->second;
|
auto &oth = t->second;
|
||||||
switch (oth.type) {
|
switch (oth.type) {
|
||||||
case ObjectTileHighlight::Type::RAIL_DEPOT:
|
case ObjectTileHighlight::Type::RAIL_DEPOT:
|
||||||
DrawTrainDepotSprite(ti, _cur_railtype, oth.u.depot.ddir);
|
DrawTrainDepotSprite(ti, _cur_railtype, oth.u.rail.depot.ddir);
|
||||||
break;
|
break;
|
||||||
case ObjectTileHighlight::Type::RAIL_TRACK: {
|
case ObjectTileHighlight::Type::RAIL_TRACK: {
|
||||||
auto hs = (HighLightStyle)oth.u.rail.track;
|
auto hs = (HighLightStyle)oth.u.rail.track;
|
||||||
DrawAutorailSelection(ti, hs, PAL_NONE);
|
DrawAutorailSelection(ti, hs, PAL_NONE);
|
||||||
break;
|
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:
|
default:
|
||||||
break;
|
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);
|
SetStationSelectionHighlight(ti, th);
|
||||||
|
// SetBlueprintHighlight(ti, th);
|
||||||
|
|
||||||
return th;
|
return th;
|
||||||
}
|
}
|
||||||
@@ -546,6 +771,8 @@ void DrawTileZoning(const TileInfo *ti, const TileHighlight &th) {
|
|||||||
bool DrawTileSelection(const TileInfo *ti, const TileHighlightType &tht) {
|
bool DrawTileSelection(const TileInfo *ti, const TileHighlightType &tht) {
|
||||||
_thd.cm.Draw(ti);
|
_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) {
|
if ((_thd.drawstyle & HT_DRAG_MASK) == HT_RECT && _thd.outersize.x > 0) {
|
||||||
// station selector, handled by DrawTileZoning
|
// station selector, handled by DrawTileZoning
|
||||||
return true;
|
return true;
|
||||||
@@ -643,11 +870,15 @@ DiagDirection AddAutodetectionRotation(DiagDirection ddir) {
|
|||||||
|
|
||||||
HighLightStyle UpdateTileSelection(HighLightStyle new_drawstyle) {
|
HighLightStyle UpdateTileSelection(HighLightStyle new_drawstyle) {
|
||||||
_thd.cm_new = ObjectHighlight(ObjectHighlight::Type::NONE);
|
_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 &&
|
if ((_thd.place_mode & HT_DRAG_MASK) == HT_RECT &&
|
||||||
_cursor.sprite_seq[0].sprite == GetRailTypeInfo(_cur_railtype)->cursor.depot) {
|
_cursor.sprite_seq[0].sprite == GetRailTypeInfo(_cur_railtype)->cursor.depot) {
|
||||||
auto dir = _build_depot_direction;
|
auto dir = _build_depot_direction;
|
||||||
auto pt = GetTileBelowCursor();
|
|
||||||
auto tile = TileVirtXY(pt.x, pt.y);
|
|
||||||
if (pt.x != -1) {
|
if (pt.x != -1) {
|
||||||
if (dir >= DiagDirection::DIAGDIR_END) {
|
if (dir >= DiagDirection::DIAGDIR_END) {
|
||||||
dir = AddAutodetectionRotation(AutodetectRailObjectDirection(tile, pt));
|
dir = AddAutodetectionRotation(AutodetectRailObjectDirection(tile, pt));
|
||||||
|
|||||||
@@ -1,36 +1,152 @@
|
|||||||
#ifndef CITYMANIA_HIGHLIGHT_TYPE_HPP
|
#ifndef CITYMANIA_HIGHLIGHT_TYPE_HPP
|
||||||
#define CITYMANIA_HIGHLIGHT_TYPE_HPP
|
#define CITYMANIA_HIGHLIGHT_TYPE_HPP
|
||||||
|
|
||||||
|
#include "../bridge.h"
|
||||||
#include "../direction_type.h"
|
#include "../direction_type.h"
|
||||||
|
#include "../map_func.h"
|
||||||
|
#include "../signal_type.h"
|
||||||
|
#include "../station_type.h"
|
||||||
#include "../tile_cmd.h"
|
#include "../tile_cmd.h"
|
||||||
#include "../tile_type.h"
|
#include "../tile_type.h"
|
||||||
#include "../track_type.h"
|
#include "../track_type.h"
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <set>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
namespace citymania {
|
namespace citymania {
|
||||||
|
|
||||||
|
|
||||||
class ObjectTileHighlight {
|
class ObjectTileHighlight {
|
||||||
public:
|
public:
|
||||||
enum class Type {
|
enum class Type {
|
||||||
RAIL_DEPOT = 0,
|
BEGIN = 0,
|
||||||
RAIL_TRACK = 1,
|
RAIL_DEPOT = BEGIN,
|
||||||
|
RAIL_TRACK,
|
||||||
|
RAIL_STATION,
|
||||||
|
RAIL_SIGNAL,
|
||||||
|
RAIL_BRIDGE_HEAD,
|
||||||
|
RAIL_TUNNEL_HEAD,
|
||||||
|
END,
|
||||||
};
|
};
|
||||||
|
|
||||||
Type type;
|
Type type;
|
||||||
union {
|
union {
|
||||||
struct {
|
struct {
|
||||||
DiagDirection ddir;
|
struct {
|
||||||
} depot;
|
DiagDirection ddir;
|
||||||
struct {
|
} depot;
|
||||||
Track track;
|
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;
|
} rail;
|
||||||
} u;
|
} u;
|
||||||
|
|
||||||
ObjectTileHighlight(Type type): type{type} {}
|
ObjectTileHighlight(Type type): type{type} {}
|
||||||
static ObjectTileHighlight make_depot(DiagDirection ddir);
|
static ObjectTileHighlight make_rail_depot(DiagDirection ddir);
|
||||||
static ObjectTileHighlight make_rail(Track track);
|
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 {
|
class ObjectHighlight {
|
||||||
@@ -38,15 +154,13 @@ public:
|
|||||||
enum class Type {
|
enum class Type {
|
||||||
NONE = 0,
|
NONE = 0,
|
||||||
RAIL_DEPOT = 1,
|
RAIL_DEPOT = 1,
|
||||||
|
// BLUEPRINT = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
Type type;
|
Type type;
|
||||||
union {
|
TileIndex tile = INVALID_TILE;
|
||||||
struct {
|
DiagDirection ddir = INVALID_DIAGDIR;
|
||||||
TileIndex tile;
|
sp<Blueprint> blueprint = nullptr;
|
||||||
DiagDirection ddir;
|
|
||||||
} depot;
|
|
||||||
} u;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool tiles_updated = false;
|
bool tiles_updated = false;
|
||||||
@@ -55,11 +169,12 @@ protected:
|
|||||||
void PlaceExtraDepotRail(TileIndex tile, DiagDirection dir, Track track);
|
void PlaceExtraDepotRail(TileIndex tile, DiagDirection dir, Track track);
|
||||||
|
|
||||||
public:
|
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);
|
||||||
bool operator!=(const ObjectHighlight& oh);
|
bool operator!=(const ObjectHighlight& oh);
|
||||||
|
|
||||||
static ObjectHighlight make_depot(TileIndex tile, DiagDirection ddir);
|
static ObjectHighlight make_depot(TileIndex tile, DiagDirection ddir);
|
||||||
|
// static ObjectHighlight make_blueprint(TileIndex tile, sp<Blueprint> blueprint);
|
||||||
|
|
||||||
void Draw(const TileInfo *ti);
|
void Draw(const TileInfo *ti);
|
||||||
void MarkDirty();
|
void MarkDirty();
|
||||||
|
|||||||
@@ -825,7 +825,7 @@ struct BuildRailToolbarWindow : Window {
|
|||||||
ddir = _build_depot_direction;
|
ddir = _build_depot_direction;
|
||||||
if (ddir == DIAGDIR_NW + 1) {
|
if (ddir == DIAGDIR_NW + 1) {
|
||||||
assert(_thd.cm.type == citymania::ObjectHighlight::Type::RAIL_DEPOT);
|
assert(_thd.cm.type == citymania::ObjectHighlight::Type::RAIL_DEPOT);
|
||||||
ddir = _thd.cm.u.depot.ddir;
|
ddir = _thd.cm.ddir;
|
||||||
}
|
}
|
||||||
DoCommandP(tile, _cur_railtype, ddir,
|
DoCommandP(tile, _cur_railtype, ddir,
|
||||||
CMD_BUILD_TRAIN_DEPOT | CMD_MSG(STR_ERROR_CAN_T_BUILD_TRAIN_DEPOT),
|
CMD_BUILD_TRAIN_DEPOT | CMD_MSG(STR_ERROR_CAN_T_BUILD_TRAIN_DEPOT),
|
||||||
|
|||||||
Reference in New Issue
Block a user