diff --git a/src/saveload/extended_ver_sl.cpp b/src/saveload/extended_ver_sl.cpp index 3c17267c68..4cd072185e 100644 --- a/src/saveload/extended_ver_sl.cpp +++ b/src/saveload/extended_ver_sl.cpp @@ -127,6 +127,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = { { XSLFI_DOCKING_CACHE_VER, XSCF_IGNORABLE_ALL, 1, 1, "docking_cache_ver", nullptr, nullptr, nullptr }, { XSLFI_EXTRA_CHEATS, XSCF_NULL, 1, 1, "extra_cheats", nullptr, nullptr, "CHTX" }, { XSLFI_TOWN_MULTI_BUILDING, XSCF_NULL, 1, 1, "town_multi_building", nullptr, nullptr, nullptr }, + { XSLFI_SHIP_LOST_COUNTER, XSCF_NULL, 1, 1, "ship_lost_counter", nullptr, nullptr, nullptr }, { XSLFI_NULL, XSCF_NULL, 0, 0, nullptr, nullptr, nullptr, nullptr },// This is the end marker }; diff --git a/src/saveload/extended_ver_sl.h b/src/saveload/extended_ver_sl.h index d273664bf0..6b25e67757 100644 --- a/src/saveload/extended_ver_sl.h +++ b/src/saveload/extended_ver_sl.h @@ -84,6 +84,7 @@ enum SlXvFeatureIndex { XSLFI_DOCKING_CACHE_VER, ///< Multiple docks - docking tile cache version XSLFI_EXTRA_CHEATS, ///< Extra cheats XSLFI_TOWN_MULTI_BUILDING, ///< Allow multiple stadium/church buildings in a single town + XSLFI_SHIP_LOST_COUNTER, ///< Ship lost counter XSLFI_RIFF_HEADER_60_BIT, ///< Size field in RIFF chunk header is 60 bit XSLFI_HEIGHT_8_BIT, ///< Map tile height is 8 bit instead of 4 bit, but savegame version may be before this became true in trunk diff --git a/src/saveload/vehicle_sl.cpp b/src/saveload/vehicle_sl.cpp index c3ec7e3aa5..2681a0d198 100644 --- a/src/saveload/vehicle_sl.cpp +++ b/src/saveload/vehicle_sl.cpp @@ -840,6 +840,7 @@ const SaveLoad *GetVehicleDescription(VehicleType vt) SLE_VAR(Ship, state, SLE_UINT8), SLE_CONDDEQUE(Ship, path, SLE_UINT8, SLV_SHIP_PATH_CACHE, SL_MAX_VERSION), SLE_CONDVAR(Ship, rotation, SLE_UINT8, SLV_SHIP_ROTATION, SL_MAX_VERSION), + SLE_CONDVAR_X(Ship, lost_count, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SHIP_LOST_COUNTER)), SLE_CONDNULL(16, SLV_2, SLV_144), // old reserved space diff --git a/src/ship.h b/src/ship.h index 30e0c1835e..b60044d4d3 100644 --- a/src/ship.h +++ b/src/ship.h @@ -31,6 +31,7 @@ struct Ship FINAL : public SpecializedVehicle { Direction rotation; ///< Visible direction. int16 rotation_x_pos; ///< NOSAVE: X Position before rotation. int16 rotation_y_pos; ///< NOSAVE: Y Position before rotation. + uint8 lost_count; ///< Count of number of failed pathfinder attempts /** We don't want GCC to zero our struct! It already is zeroed and has an index! */ Ship() : SpecializedVehicleBase() {} diff --git a/src/table/newgrf_debug_data.h b/src/table/newgrf_debug_data.h index 0f3a2ff3b9..42614b5b37 100644 --- a/src/table/newgrf_debug_data.h +++ b/src/table/newgrf_debug_data.h @@ -12,6 +12,7 @@ #include "../newgrf_roadtype.h" #include "../date_func.h" #include "../timetable.h" +#include "../ship.h" /* Helper for filling property tables */ #define NIP(prop, base, variable, type, name) { name, (ptrdiff_t)cpp_offsetof(base, variable), cpp_sizeof(base, variable), prop, type } @@ -149,6 +150,12 @@ class NIHVehicle : public NIHelper { t->wait_counter, t->reverse_distance, t->tunnel_bridge_signal_num, t->speed_restriction); print(buffer); } + if (v->type == VEH_SHIP) { + const Ship *s = Ship::From(v); + seprintf(buffer, lastof(buffer), " Lost counter: %u", + s->lost_count); + print(buffer); + } if (HasBit(v->vehicle_flags, VF_SEPARATION_ACTIVE)) { std::vector progress_array = PopulateSeparationState(v); diff --git a/src/vehicle.cpp b/src/vehicle.cpp index 69e35ed83c..da9440c510 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -885,16 +885,27 @@ void Vehicle::HandlePathfindingResult(bool path_found) /* Clear the flag as the PF's problem was solved. */ ClrBit(this->vehicle_flags, VF_PATHFINDER_LOST); + if (this->type == VEH_SHIP) { + Ship::From(this)->lost_count = 0; + } /* Delete the news item. */ DeleteVehicleNews(this->index, STR_NEWS_VEHICLE_IS_LOST); return; } - /* Were we already lost? */ - if (HasBit(this->vehicle_flags, VF_PATHFINDER_LOST)) return; + if (this->type == VEH_SHIP) { + SetBit(this->vehicle_flags, VF_PATHFINDER_LOST); + if (Ship::From(this)->lost_count == 255) return; + Ship::From(this)->lost_count++; + if (Ship::From(this)->lost_count != 16) return; + } else { + /* Were we already lost? */ + if (HasBit(this->vehicle_flags, VF_PATHFINDER_LOST)) return; + + /* It is first time the problem occurred, set the "lost" flag. */ + SetBit(this->vehicle_flags, VF_PATHFINDER_LOST); + } - /* It is first time the problem occurred, set the "lost" flag. */ - SetBit(this->vehicle_flags, VF_PATHFINDER_LOST); /* Notify user about the event. */ AI::NewEvent(this->owner, new ScriptEventVehicleLost(this->index)); if (_settings_client.gui.lost_vehicle_warn && this->owner == _local_company) {