From 275c141bf465d2d41f4c03b9592a59abb945a355 Mon Sep 17 00:00:00 2001 From: J0anJosep Date: Thu, 24 Dec 2020 01:02:59 +0100 Subject: [PATCH] Change: Adapt commands for buying and replacing ships in extended depots. --- src/autoreplace_cmd.cpp | 25 ++++++++++++++++++++++++ src/lang/english.txt | 1 + src/ship_cmd.cpp | 43 ++++++++++++++++++++++++++++++----------- 3 files changed, 58 insertions(+), 11 deletions(-) diff --git a/src/autoreplace_cmd.cpp b/src/autoreplace_cmd.cpp index 084ca8c838..ffcaf46710 100644 --- a/src/autoreplace_cmd.cpp +++ b/src/autoreplace_cmd.cpp @@ -20,6 +20,7 @@ #include "core/random_func.hpp" #include "vehiclelist.h" #include "road.h" +#include "ship.h" #include "ai/ai.hpp" #include "news_func.h" #include "strings_func.h" @@ -515,6 +516,25 @@ struct ReplaceChainItem { Vehicle *GetVehicle() const { return new_veh == nullptr ? old_veh : new_veh; } }; +/** + * When replacing a ship in an extended depot, copy the direction as well. + * @param old_ship The ship being replaced. + * @param new_ship The new ship that will replace the old one. + */ +void CopyShipStatusInExtendedDepot(const Ship *old_ship, Ship *new_ship) +{ + assert(IsExtendedDepotTile(old_ship->tile)); + assert(old_ship->tile == new_ship->tile); + + new_ship->x_pos = old_ship->x_pos; + new_ship->y_pos = old_ship->y_pos; + new_ship->z_pos = old_ship->z_pos; + new_ship->state = old_ship->state; + new_ship->direction = old_ship->direction; + new_ship->rotation = old_ship->rotation; + new_ship->GetImage(new_ship->direction, EIT_ON_MAP, &new_ship->sprite_cache.sprite_seq); +} + /** * Replace a whole vehicle chain * @param chain vehicle chain to let autoreplace/renew operator on @@ -712,6 +732,11 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon cost.AddCost(CopyHeadSpecificThings(old_head, new_head, flags)); if (cost.Succeeded()) { + /* Copy position and direction for ships in extended depots. */ + if (old_head->type == VEH_SHIP && IsExtendedDepotTile(old_head->tile)) { + CopyShipStatusInExtendedDepot(Ship::From(old_head), Ship::From(new_head)); + } + /* The new vehicle is constructed, now take over cargo */ if ((flags & DC_EXEC) != 0) { TransferCargo(old_head, new_head, true); diff --git a/src/lang/english.txt b/src/lang/english.txt index 08d2cc4f7c..60cd9351f3 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -5341,6 +5341,7 @@ STR_ERROR_TOO_MANY_VEHICLES_IN_GAME :{WHITE}Too many STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}Can't change servicing interval... STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... vehicle is destroyed +STR_ERROR_NO_FREE_DEPOT :{WHITE}... there is no free depot STR_ERROR_CAN_T_CLONE_VEHICLE_LIST :{WHITE}... not all vehicles are identical diff --git a/src/ship_cmd.cpp b/src/ship_cmd.cpp index 0f06765b4b..40c49152cf 100644 --- a/src/ship_cmd.cpp +++ b/src/ship_cmd.cpp @@ -36,6 +36,7 @@ #include "industry.h" #include "industry_map.h" #include "ship_cmd.h" +#include "command_func.h" #include "table/strings.h" @@ -957,10 +958,22 @@ void Ship::SetDestTile(TileIndex tile) */ CommandCost CmdBuildShip(DoCommandFlag flags, TileIndex tile, const Engine *e, Vehicle **ret) { - tile = GetShipDepotNorthTile(tile); + assert(IsShipDepotTile(tile)); + if (!(flags & DC_AUTOREPLACE)) { + std::vector *depot_tiles = &(Depot::GetByTile(tile)->depot_tiles); + tile = INVALID_TILE; + for (std::vector::iterator it = depot_tiles->begin(); it != depot_tiles->end(); ++it) { + if (CheckPlaceShipOnDepot(*it)) { + tile = *it; + break; + } + } + if (tile == INVALID_TILE) return_cmd_error(STR_ERROR_NO_FREE_DEPOT); + } + if (flags & DC_EXEC) { - int x; - int y; + bool is_extended_depot = IsExtendedDepot(tile); + TileIndexDiffC offset = TileIndexDiffCByDiagDir(ReverseDiagDir(GetShipDepotDirection(tile))); const ShipVehicleInfo *svi = &e->u.ship; @@ -969,14 +982,22 @@ CommandCost CmdBuildShip(DoCommandFlag flags, TileIndex tile, const Engine *e, V v->owner = _current_company; v->tile = tile; - x = TileX(tile) * TILE_SIZE + TILE_SIZE / 2; - y = TileY(tile) * TILE_SIZE + TILE_SIZE / 2; - v->x_pos = x; - v->y_pos = y; - v->z_pos = GetSlopePixelZ(x, y); + v->x_pos = TileX(tile) * TILE_SIZE + TILE_SIZE / 2 + offset.x * (TILE_SIZE / 2 - 1); + v->y_pos = TileY(tile) * TILE_SIZE + TILE_SIZE / 2 + offset.y * (TILE_SIZE / 2 - 1); + v->z_pos = GetSlopePixelZ(v->x_pos, v->y_pos); + v->state = TRACK_BIT_DEPOT; + if (is_extended_depot) { + v->state |= AxisToTrackBits(GetShipDepotAxis(tile)); + v->direction = AxisToDirection(GetShipDepotAxis(v->tile)); + SetDepotReservation(v->tile, DEPOT_RESERVATION_FULL_STOPPED_VEH); + } else { + v->vehstatus |= VS_HIDDEN; + } + + v->rotation = v->direction; v->UpdateDeltaXY(); - v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL; + v->vehstatus |= VS_STOPPED | VS_DEFPAL; v->spritenum = svi->image_index; v->cargo_type = e->GetDefaultCargoType(); @@ -992,8 +1013,6 @@ CommandCost CmdBuildShip(DoCommandFlag flags, TileIndex tile, const Engine *e, V v->reliability_spd_dec = e->reliability_spd_dec; v->max_age = e->GetLifeLengthInDays(); - v->state = TRACK_BIT_DEPOT; - v->SetServiceInterval(Company::Get(_current_company)->settings.vehicle.servint_ships); v->date_of_last_service = TimerGameEconomy::date; v->date_of_last_service_newgrf = TimerGameCalendar::date; @@ -1014,6 +1033,8 @@ CommandCost CmdBuildShip(DoCommandFlag flags, TileIndex tile, const Engine *e, V v->InvalidateNewGRFCacheOfChain(); v->UpdatePosition(); + + if (is_extended_depot) v->MarkDirty(); } return CommandCost();