1
0
Fork 0

Feature: Show depot signs of removed depots. (based on patch by adf88, #6328, #5071)

pull/8480/head
J0anJosep 2023-05-10 21:52:47 +02:00
parent 6bdf50ca02
commit 63afc96d2a
10 changed files with 117 additions and 0 deletions

View File

@ -17,6 +17,7 @@
#include "vehiclelist.h" #include "vehiclelist.h"
#include "command_func.h" #include "command_func.h"
#include "vehicle_base.h" #include "vehicle_base.h"
#include "viewport_kdtree.h"
#include "safeguards.h" #include "safeguards.h"
@ -63,6 +64,10 @@ Depot::~Depot()
this->veh_type, this->owner, this->index).Pack()); this->veh_type, this->owner, this->index).Pack());
InvalidateWindowData(WC_SELECT_DEPOT, this->veh_type); InvalidateWindowData(WC_SELECT_DEPOT, this->veh_type);
/* The sign will now disappear. */
_viewport_sign_kdtree.Remove(ViewportSignKdtreeItem::MakeDepot(this->index));
this->sign.MarkDirty();
} }
/** /**
@ -77,6 +82,10 @@ void Depot::Reuse(TileIndex xy)
this->xy = xy; this->xy = xy;
this->ta.tile = xy; this->ta.tile = xy;
this->ta.h = this->ta.w = 1; this->ta.h = this->ta.w = 1;
/* Ensure the sign is not drawn */
_viewport_sign_kdtree.Remove(ViewportSignKdtreeItem::MakeDepot(this->index));
this->sign.MarkDirty();
} }
/** /**
@ -93,6 +102,10 @@ void Depot::Disuse()
{ {
/* Mark that the depot is demolished and start the countdown. */ /* Mark that the depot is demolished and start the countdown. */
this->delete_ctr = 8; this->delete_ctr = 8;
/* Update the sign, it will be visible from now. */
this->UpdateVirtCoord();
_viewport_sign_kdtree.Insert(ViewportSignKdtreeItem::MakeDepot(this->index));
} }
/** /**

View File

@ -11,6 +11,7 @@
#define DEPOT_BASE_H #define DEPOT_BASE_H
#include "depot_map.h" #include "depot_map.h"
#include "viewport_type.h"
#include "core/pool_type.hpp" #include "core/pool_type.hpp"
#include "timer/timer_game_calendar.h" #include "timer/timer_game_calendar.h"
#include "rail_type.h" #include "rail_type.h"
@ -33,6 +34,7 @@ struct Depot : DepotPool::PoolItem<&_depot_pool> {
VehicleType veh_type; ///< Vehicle type of the depot. VehicleType veh_type; ///< Vehicle type of the depot.
Owner owner; ///< Owner of the depot. Owner owner; ///< Owner of the depot.
uint8_t delete_ctr; ///< Delete counter. If greater than 0 then it is decremented until it reaches 0; the depot is then deleted. uint8_t delete_ctr; ///< Delete counter. If greater than 0 then it is decremented until it reaches 0; the depot is then deleted.
ViewportSign sign; ///< NOSAVE: Dimensions of sign
Station *station; ///< For aircraft, station associated with this hangar. Station *station; ///< For aircraft, station associated with this hangar.
union { union {
@ -87,6 +89,7 @@ struct Depot : DepotPool::PoolItem<&_depot_pool> {
void Reuse(TileIndex xy); void Reuse(TileIndex xy);
void Disuse(); void Disuse();
void UpdateVirtCoord();
/* Check we can add some tiles to this depot. */ /* Check we can add some tiles to this depot. */
CommandCost BeforeAddTiles(TileArea ta); CommandCost BeforeAddTiles(TileArea ta);

View File

@ -17,6 +17,9 @@
#include "vehiclelist.h" #include "vehiclelist.h"
#include "window_func.h" #include "window_func.h"
#include "depot_cmd.h" #include "depot_cmd.h"
#include "strings_func.h"
#include "landscape.h"
#include "viewport_kdtree.h"
#include "timer/timer_game_tick.h" #include "timer/timer_game_tick.h"
#include "table/strings.h" #include "table/strings.h"
@ -60,6 +63,8 @@ CommandCost CmdRenameDepot(DoCommandFlag flags, DepotID depot_id, const std::str
} }
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
/* _viewport_sign_kdtree does not need to be updated, only in-use depots can be renamed */
if (reset) { if (reset) {
d->name.clear(); d->name.clear();
MakeDefaultName(d); MakeDefaultName(d);
@ -77,6 +82,27 @@ CommandCost CmdRenameDepot(DoCommandFlag flags, DepotID depot_id, const std::str
return CommandCost(); return CommandCost();
} }
/** Update the virtual coords needed to draw the depot sign. */
void Depot::UpdateVirtCoord()
{
Point pt = RemapCoords2(TileX(this->xy) * TILE_SIZE, TileY(this->xy) * TILE_SIZE);
pt.y -= 32 * ZOOM_BASE;
SetDParam(0, this->veh_type);
SetDParam(1, this->index);
this->sign.UpdatePosition(pt.x, pt.y, STR_VIEWPORT_DEPOT, STR_VIEWPORT_DEPOT_TINY);
SetWindowDirty(WC_VEHICLE_DEPOT, this->index);
}
/** Update the virtual coords needed to draw the depot sign for all depots. */
void UpdateAllDepotVirtCoords()
{
/* Only demolished depots have signs. */
for (Depot *d : Depot::Iterate()) if (!d->IsInUse()) d->UpdateVirtCoord();
}
/** /**
* Find a demolished depot close to a tile. * Find a demolished depot close to a tile.
* @param ta Tile area to search for. * @param ta Tile area to search for.

View File

@ -19,6 +19,7 @@ void ShowDepotWindow(DepotID depot_id);
void InitDepotWindowBlockSizes(); void InitDepotWindowBlockSizes();
void DeleteDepotHighlightOfVehicle(const Vehicle *v); void DeleteDepotHighlightOfVehicle(const Vehicle *v);
void UpdateAllDepotVirtCoords();
/** /**
* Find out if the slope of the tile is suitable to build a depot of given direction * Find out if the slope of the tile is suitable to build a depot of given direction

View File

@ -5848,6 +5848,9 @@ STR_VIEWPORT_STATION_TINY :{TINY_FONT}{STA
STR_VIEWPORT_WAYPOINT :{WAYPOINT} STR_VIEWPORT_WAYPOINT :{WAYPOINT}
STR_VIEWPORT_WAYPOINT_TINY :{TINY_FONT}{WAYPOINT} STR_VIEWPORT_WAYPOINT_TINY :{TINY_FONT}{WAYPOINT}
STR_VIEWPORT_DEPOT :{DEPOT}
STR_VIEWPORT_DEPOT_TINY :{TINY_FONT}{DEPOT}
# Simple strings to get specific types of data # Simple strings to get specific types of data
STR_COMPANY_NAME :{COMPANY} STR_COMPANY_NAME :{COMPANY}
STR_COMPANY_NAME_COMPANY_NUM :{COMPANY} {COMPANY_NUM} STR_COMPANY_NAME_COMPANY_NUM :{COMPANY} {COMPANY_NUM}

View File

@ -11,6 +11,7 @@
#include "../void_map.h" #include "../void_map.h"
#include "../signs_base.h" #include "../signs_base.h"
#include "../depot_base.h" #include "../depot_base.h"
#include "../depot_func.h"
#include "../fios.h" #include "../fios.h"
#include "../gamelog_internal.h" #include "../gamelog_internal.h"
#include "../network/network.h" #include "../network/network.h"
@ -222,6 +223,7 @@ static inline RailType UpdateRailType(RailType rt, RailType min)
void UpdateAllVirtCoords() void UpdateAllVirtCoords()
{ {
UpdateAllStationVirtCoords(); UpdateAllStationVirtCoords();
UpdateAllDepotVirtCoords();
UpdateAllSignVirtCoords(); UpdateAllSignVirtCoords();
UpdateAllTownVirtCoords(); UpdateAllTownVirtCoords();
UpdateAllTextEffectVirtCoords(); UpdateAllTextEffectVirtCoords();

View File

@ -755,6 +755,9 @@ void Airport::AddHangar()
*/ */
void Airport::RemoveHangar() void Airport::RemoveHangar()
{ {
if (this->hangar == nullptr) return;
/* TODO Check this. */
RemoveOrderFromAllVehicles(OT_GOTO_DEPOT, this->hangar->index); RemoveOrderFromAllVehicles(OT_GOTO_DEPOT, this->hangar->index);
for (Aircraft *a : Aircraft::Iterate()) { for (Aircraft *a : Aircraft::Iterate()) {
@ -764,6 +767,7 @@ void Airport::RemoveHangar()
a->current_order.MakeDummy(); a->current_order.MakeDummy();
} }
this->hangar->Disuse();
delete this->hangar; delete this->hangar;
this->hangar = nullptr; this->hangar = nullptr;
} }

View File

@ -44,6 +44,7 @@
#include "core/random_func.hpp" #include "core/random_func.hpp"
#include "core/backup_type.hpp" #include "core/backup_type.hpp"
#include "depot_base.h" #include "depot_base.h"
#include "depot_func.h"
#include "object_map.h" #include "object_map.h"
#include "object_base.h" #include "object_base.h"
#include "ai/ai.hpp" #include "ai/ai.hpp"
@ -2998,6 +2999,8 @@ CommandCost CmdRenameTown(DoCommandFlag flags, TownID town_id, const std::string
ClearAllStationCachedNames(); ClearAllStationCachedNames();
ClearAllIndustryCachedNames(); ClearAllIndustryCachedNames();
UpdateAllStationVirtCoords(); UpdateAllStationVirtCoords();
UpdateAllDepotVirtCoords();
RebuildViewportKdtree();
} }
return CommandCost(); return CommandCost();
} }

View File

@ -66,6 +66,8 @@
#include "viewport_func.h" #include "viewport_func.h"
#include "station_base.h" #include "station_base.h"
#include "waypoint_base.h" #include "waypoint_base.h"
#include "depot_base.h"
#include "depot_func.h"
#include "town.h" #include "town.h"
#include "signs_base.h" #include "signs_base.h"
#include "signs_func.h" #include "signs_func.h"
@ -1366,12 +1368,14 @@ static void ViewportAddKdtreeSigns(DrawPixelInfo *dpi)
bool show_waypoints = HasBit(_display_opt, DO_SHOW_WAYPOINT_NAMES) && _game_mode != GM_MENU; bool show_waypoints = HasBit(_display_opt, DO_SHOW_WAYPOINT_NAMES) && _game_mode != GM_MENU;
bool show_towns = HasBit(_display_opt, DO_SHOW_TOWN_NAMES) && _game_mode != GM_MENU; bool show_towns = HasBit(_display_opt, DO_SHOW_TOWN_NAMES) && _game_mode != GM_MENU;
bool show_signs = HasBit(_display_opt, DO_SHOW_SIGNS) && !IsInvisibilitySet(TO_SIGNS); bool show_signs = HasBit(_display_opt, DO_SHOW_SIGNS) && !IsInvisibilitySet(TO_SIGNS);
bool show_depotsigns = _game_mode != GM_MENU;
bool show_competitors = HasBit(_display_opt, DO_SHOW_COMPETITOR_SIGNS); bool show_competitors = HasBit(_display_opt, DO_SHOW_COMPETITOR_SIGNS);
/* Collect all the items first and draw afterwards, to ensure layering */ /* Collect all the items first and draw afterwards, to ensure layering */
std::vector<const BaseStation *> stations; std::vector<const BaseStation *> stations;
std::vector<const Town *> towns; std::vector<const Town *> towns;
std::vector<const Sign *> signs; std::vector<const Sign *> signs;
std::vector<const Depot *> depots;
_viewport_sign_kdtree.FindContained(search_rect.left, search_rect.top, search_rect.right, search_rect.bottom, [&](const ViewportSignKdtreeItem & item) { _viewport_sign_kdtree.FindContained(search_rect.left, search_rect.top, search_rect.right, search_rect.bottom, [&](const ViewportSignKdtreeItem & item) {
switch (item.type) { switch (item.type) {
@ -1415,6 +1419,19 @@ static void ViewportAddKdtreeSigns(DrawPixelInfo *dpi)
break; break;
} }
case ViewportSignKdtreeItem::VKI_DEPOT: {
if (!show_depotsigns) break;
const Depot *depot = Depot::Get(item.id.depot);
/* Only show depot name after the depot is removed. */
if (depot->IsInUse()) break;
/* Don't draw if depot is owned by another company and competitor signs are hidden. */
if (!show_competitors && _local_company != depot->owner) break;
depots.push_back(depot);
break;
}
default: default:
NOT_REACHED(); NOT_REACHED();
} }
@ -1441,6 +1458,12 @@ static void ViewportAddKdtreeSigns(DrawPixelInfo *dpi)
(si->owner == OWNER_NONE) ? COLOUR_GREY : (si->owner == OWNER_DEITY ? INVALID_COLOUR : _company_colours[si->owner])); (si->owner == OWNER_NONE) ? COLOUR_GREY : (si->owner == OWNER_DEITY ? INVALID_COLOUR : _company_colours[si->owner]));
} }
for (const auto *d : depots) {
SetDParam(0, d->veh_type);
SetDParam(1, d->index);
ViewportAddString(dpi, ZOOM_LVL_OUT_4X, &d->sign, STR_VIEWPORT_DEPOT, STR_VIEWPORT_DEPOT_TINY, STR_NULL, COLOUR_GREY);
}
for (const auto *st : stations) { for (const auto *st : stations) {
SetDParam(0, st->index); SetDParam(0, st->index);
SetDParam(1, st->facilities); SetDParam(1, st->facilities);
@ -2237,6 +2260,7 @@ static bool CheckClickOnViewportSign(const Viewport *vp, int x, int y)
BaseStation *st = nullptr, *last_st = nullptr; BaseStation *st = nullptr, *last_st = nullptr;
Town *t = nullptr, *last_t = nullptr; Town *t = nullptr, *last_t = nullptr;
Sign *si = nullptr, *last_si = nullptr; Sign *si = nullptr, *last_si = nullptr;
Depot *dep = nullptr, *last_dep = nullptr;
/* See ViewportAddKdtreeSigns() for details on the search logic */ /* See ViewportAddKdtreeSigns() for details on the search logic */
_viewport_sign_kdtree.FindContained(search_rect.left, search_rect.top, search_rect.right, search_rect.bottom, [&](const ViewportSignKdtreeItem & item) { _viewport_sign_kdtree.FindContained(search_rect.left, search_rect.top, search_rect.right, search_rect.bottom, [&](const ViewportSignKdtreeItem & item) {
@ -2268,6 +2292,12 @@ static bool CheckClickOnViewportSign(const Viewport *vp, int x, int y)
if (CheckClickOnViewportSign(vp, x, y, &si->sign)) last_si = si; if (CheckClickOnViewportSign(vp, x, y, &si->sign)) last_si = si;
break; break;
case ViewportSignKdtreeItem::VKI_DEPOT:
dep = Depot::Get(item.id.depot);
if (!show_competitors && _local_company != st->owner && st->owner != OWNER_NONE) break;
if (CheckClickOnViewportSign(vp, x, y, &dep->sign)) last_dep = dep;
break;
default: default:
NOT_REACHED(); NOT_REACHED();
} }
@ -2287,6 +2317,9 @@ static bool CheckClickOnViewportSign(const Viewport *vp, int x, int y)
} else if (last_si != nullptr) { } else if (last_si != nullptr) {
HandleClickOnSign(last_si); HandleClickOnSign(last_si);
return true; return true;
} else if (last_dep != nullptr) {
ShowDepotWindow(last_dep->index);
return true;
} else { } else {
return false; return false;
} }
@ -2310,6 +2343,23 @@ ViewportSignKdtreeItem ViewportSignKdtreeItem::MakeStation(StationID id)
return item; return item;
} }
ViewportSignKdtreeItem ViewportSignKdtreeItem::MakeDepot(DepotID id)
{
ViewportSignKdtreeItem item;
item.type = VKI_DEPOT;
item.id.depot = id;
const Depot *depot = Depot::Get(id);
item.center = depot->sign.center;
item.top = depot->sign.top;
/* Assume the sign can be a candidate for drawing, so measure its width */
_viewport_sign_maxwidth = std::max<int>(_viewport_sign_maxwidth, depot->sign.width_normal);
return item;
}
ViewportSignKdtreeItem ViewportSignKdtreeItem::MakeWaypoint(StationID id) ViewportSignKdtreeItem ViewportSignKdtreeItem::MakeWaypoint(StationID id)
{ {
ViewportSignKdtreeItem item; ViewportSignKdtreeItem item;
@ -2385,6 +2435,11 @@ void RebuildViewportKdtree()
if (sign->sign.kdtree_valid) items.push_back(ViewportSignKdtreeItem::MakeSign(sign->index)); if (sign->sign.kdtree_valid) items.push_back(ViewportSignKdtreeItem::MakeSign(sign->index));
} }
for (const Depot *dep : Depot::Iterate()) {
if (dep->IsInUse()) continue;
items.push_back(ViewportSignKdtreeItem::MakeDepot(dep->index));
}
_viewport_sign_kdtree.Build(items.begin(), items.end()); _viewport_sign_kdtree.Build(items.begin(), items.end());
} }

View File

@ -22,12 +22,14 @@ struct ViewportSignKdtreeItem {
VKI_WAYPOINT, VKI_WAYPOINT,
VKI_TOWN, VKI_TOWN,
VKI_SIGN, VKI_SIGN,
VKI_DEPOT,
}; };
ItemType type; ItemType type;
union { union {
StationID station; StationID station;
TownID town; TownID town;
SignID sign; SignID sign;
DepotID depot;
} id; } id;
int32_t center; int32_t center;
int32_t top; int32_t top;
@ -43,6 +45,8 @@ struct ViewportSignKdtreeItem {
return this->id.town == other.id.town; return this->id.town == other.id.town;
case VKI_SIGN: case VKI_SIGN:
return this->id.sign == other.id.sign; return this->id.sign == other.id.sign;
case VKI_DEPOT:
return this->id.depot == other.id.depot;
default: default:
NOT_REACHED(); NOT_REACHED();
} }
@ -59,6 +63,8 @@ struct ViewportSignKdtreeItem {
return this->id.town < other.id.town; return this->id.town < other.id.town;
case VKI_SIGN: case VKI_SIGN:
return this->id.sign < other.id.sign; return this->id.sign < other.id.sign;
case VKI_DEPOT:
return this->id.depot < other.id.depot;
default: default:
NOT_REACHED(); NOT_REACHED();
} }
@ -68,6 +74,7 @@ struct ViewportSignKdtreeItem {
static ViewportSignKdtreeItem MakeWaypoint(StationID id); static ViewportSignKdtreeItem MakeWaypoint(StationID id);
static ViewportSignKdtreeItem MakeTown(TownID id); static ViewportSignKdtreeItem MakeTown(TownID id);
static ViewportSignKdtreeItem MakeSign(SignID id); static ViewportSignKdtreeItem MakeSign(SignID id);
static ViewportSignKdtreeItem MakeDepot(DepotID id);
}; };
inline int32_t Kdtree_ViewportSignXYFunc(const ViewportSignKdtreeItem &item, int dim) inline int32_t Kdtree_ViewportSignXYFunc(const ViewportSignKdtreeItem &item, int dim)