mirror of https://github.com/OpenTTD/OpenTTD
Feature: Try to reuse a removed depot when placing a new one. (based on patch by adf88, #6328, #7051)
parent
2ff99e2377
commit
6bdf50ca02
|
@ -65,6 +65,20 @@ Depot::~Depot()
|
||||||
InvalidateWindowData(WC_SELECT_DEPOT, this->veh_type);
|
InvalidateWindowData(WC_SELECT_DEPOT, this->veh_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancel deletion of this depot (reuse it).
|
||||||
|
* @param xy New location of the depot.
|
||||||
|
* @see Depot::IsInUse
|
||||||
|
* @see Depot::Disuse
|
||||||
|
*/
|
||||||
|
void Depot::Reuse(TileIndex xy)
|
||||||
|
{
|
||||||
|
this->delete_ctr = 0;
|
||||||
|
this->xy = xy;
|
||||||
|
this->ta.tile = xy;
|
||||||
|
this->ta.h = this->ta.w = 1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Schedule deletion of this depot.
|
* Schedule deletion of this depot.
|
||||||
*
|
*
|
||||||
|
@ -73,6 +87,7 @@ Depot::~Depot()
|
||||||
* placed again later without messing vehicle orders.
|
* placed again later without messing vehicle orders.
|
||||||
*
|
*
|
||||||
* @see Depot::IsInUse
|
* @see Depot::IsInUse
|
||||||
|
* @see Depot::Reuse
|
||||||
*/
|
*/
|
||||||
void Depot::Disuse()
|
void Depot::Disuse()
|
||||||
{
|
{
|
||||||
|
@ -112,13 +127,19 @@ CommandCost Depot::BeforeAddTiles(TileArea ta)
|
||||||
{
|
{
|
||||||
assert(ta.tile != INVALID_TILE);
|
assert(ta.tile != INVALID_TILE);
|
||||||
|
|
||||||
if (this->ta.tile != INVALID_TILE) {
|
if (this->ta.tile != INVALID_TILE && this->IsInUse()) {
|
||||||
/* Important when the old rect is completely inside the new rect, resp. the old one was empty. */
|
/* Important when the old rect is completely inside the new rect, resp. the old one was empty. */
|
||||||
ta.Add(this->ta.tile);
|
ta.Add(this->ta.tile);
|
||||||
ta.Add(TileAddXY(this->ta.tile, this->ta.w - 1, this->ta.h - 1));
|
ta.Add(TileAddXY(this->ta.tile, this->ta.w - 1, this->ta.h - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ta.w > _settings_game.depot.depot_spread) || (ta.h > _settings_game.depot.depot_spread)) {
|
/* A max depot spread of 1 for VEH_SHIP is a special case,
|
||||||
|
* as ship depots consist of two tiles. */
|
||||||
|
if (this->veh_type == VEH_SHIP && _settings_game.depot.depot_spread == 1) {
|
||||||
|
/* (ta.w, ta.h) must be equal to (1, 2) or (2, 1).
|
||||||
|
* This means that ta.w * ta.h must be equal to 2. */
|
||||||
|
if (ta.w * ta.h != 2) return_cmd_error(STR_ERROR_DEPOT_TOO_SPREAD_OUT);
|
||||||
|
} else if (std::max(ta.w, ta.h) > _settings_game.depot.depot_spread) {
|
||||||
return_cmd_error(STR_ERROR_DEPOT_TOO_SPREAD_OUT);
|
return_cmd_error(STR_ERROR_DEPOT_TOO_SPREAD_OUT);
|
||||||
}
|
}
|
||||||
return CommandCost();
|
return CommandCost();
|
||||||
|
@ -158,8 +179,13 @@ void Depot::AfterAddRemove(TileArea ta, bool adding)
|
||||||
} else {
|
} else {
|
||||||
assert(this->IsInUse());
|
assert(this->IsInUse());
|
||||||
this->Disuse();
|
this->Disuse();
|
||||||
|
TileIndex old_tile = this->xy;
|
||||||
|
this->RescanDepotTiles();
|
||||||
|
assert(this->depot_tiles.empty());
|
||||||
|
this->xy = old_tile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
InvalidateWindowData(WC_VEHICLE_DEPOT, this->index);
|
||||||
InvalidateWindowData(WC_SELECT_DEPOT, veh_type);
|
InvalidateWindowData(WC_SELECT_DEPOT, veh_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -78,12 +78,14 @@ struct Depot : DepotPool::PoolItem<&_depot_pool> {
|
||||||
* and the depot awaits to be deleted.
|
* and the depot awaits to be deleted.
|
||||||
* @return true iff still in use
|
* @return true iff still in use
|
||||||
* @see Depot::Disuse
|
* @see Depot::Disuse
|
||||||
|
* @see Depot::Reuse
|
||||||
*/
|
*/
|
||||||
inline bool IsInUse() const
|
inline bool IsInUse() const
|
||||||
{
|
{
|
||||||
return this->delete_ctr == 0;
|
return this->delete_ctr == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Reuse(TileIndex xy);
|
||||||
void Disuse();
|
void Disuse();
|
||||||
|
|
||||||
/* Check we can add some tiles to this depot. */
|
/* Check we can add some tiles to this depot. */
|
||||||
|
|
|
@ -77,6 +77,23 @@ CommandCost CmdRenameDepot(DoCommandFlag flags, DepotID depot_id, const std::str
|
||||||
return CommandCost();
|
return CommandCost();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find a demolished depot close to a tile.
|
||||||
|
* @param ta Tile area to search for.
|
||||||
|
* @param type Depot type.
|
||||||
|
* @param cid Previous owner of the depot.
|
||||||
|
* @return The index of a demolished nearby depot, or INVALID_DEPOT if none.
|
||||||
|
*/
|
||||||
|
DepotID FindDeletedDepotCloseTo(TileArea ta, VehicleType type, CompanyID cid)
|
||||||
|
{
|
||||||
|
for (Depot *depot : Depot::Iterate()) {
|
||||||
|
if (depot->IsInUse() || depot->veh_type != type || depot->owner != cid) continue;
|
||||||
|
if (ta.Contains(depot->xy)) return depot->index;
|
||||||
|
}
|
||||||
|
|
||||||
|
return INVALID_DEPOT;
|
||||||
|
}
|
||||||
|
|
||||||
void OnTick_Depot()
|
void OnTick_Depot()
|
||||||
{
|
{
|
||||||
if (_game_mode == GM_EDITOR) return;
|
if (_game_mode == GM_EDITOR) return;
|
||||||
|
@ -128,6 +145,12 @@ CommandCost FindJoiningDepot(TileArea ta, VehicleType veh_type, DepotID &join_to
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (closest_depot == INVALID_DEPOT) {
|
||||||
|
/* Check for close unused depots. */
|
||||||
|
check_area.Expand(7); // total distance of 8
|
||||||
|
closest_depot = FindDeletedDepotCloseTo(check_area, veh_type, _current_company);
|
||||||
|
}
|
||||||
|
|
||||||
if (closest_depot != INVALID_DEPOT) {
|
if (closest_depot != INVALID_DEPOT) {
|
||||||
assert(Depot::IsValidID(closest_depot));
|
assert(Depot::IsValidID(closest_depot));
|
||||||
depot = Depot::Get(closest_depot);
|
depot = Depot::Get(closest_depot);
|
||||||
|
@ -151,6 +174,7 @@ CommandCost FindJoiningDepot(TileArea ta, VehicleType veh_type, DepotID &join_to
|
||||||
depot = Depot::Get(join_to);
|
depot = Depot::Get(join_to);
|
||||||
assert(depot->owner == _current_company);
|
assert(depot->owner == _current_company);
|
||||||
assert(depot->veh_type == veh_type);
|
assert(depot->veh_type == veh_type);
|
||||||
|
if (!depot->IsInUse() && (flags & DC_EXEC)) depot->Reuse(ta.tile);
|
||||||
return depot->BeforeAddTiles(ta);
|
return depot->BeforeAddTiles(ta);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1249,6 +1249,15 @@ static const Depot *FindDepotsNearby(TileArea ta, VehicleType veh_type, bool dis
|
||||||
TileIndex tile = TileAddByDir(andd.search_area.tile, DIR_N);
|
TileIndex tile = TileAddByDir(andd.search_area.tile, DIR_N);
|
||||||
CircularTileSearch(&tile, max_dist, ta.w, ta.h, AddNearbyDepot, &andd);
|
CircularTileSearch(&tile, max_dist, ta.w, ta.h, AddNearbyDepot, &andd);
|
||||||
|
|
||||||
|
/* Add reusable depots. */
|
||||||
|
ta.Expand(8);
|
||||||
|
for (Depot *d : Depot::Iterate()) {
|
||||||
|
if (d->IsInUse()) continue;
|
||||||
|
if (d->veh_type != veh_type || d->owner != _current_company) continue;
|
||||||
|
if (!ta.Contains(d->xy)) continue;
|
||||||
|
_depots_nearby_list.push_back(d->index);
|
||||||
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue