Add savegame flag for station tile cache flags

Update flags as necessary on load and when reloading GRFs
pull/603/head
Jonathan G Rennison 8 months ago
parent b2a1ec96f1
commit df4c458c29

@ -51,6 +51,8 @@ extern TileIndex _aux_tileloop_tile;
extern void ClearAllSignalSpeedRestrictions();
extern void MakeNewgameSettingsLive();
extern uint64 _station_tile_cache_hash;
void InitializeSound();
void InitializeMusic();
void InitializeVehicles();
@ -137,6 +139,7 @@ void InitializeGame(uint size_x, uint size_y, bool reset_date, bool reset_settin
_game_load_time = 0;
_extra_aspects = 0;
_aspect_cfg_hash = 0;
_station_tile_cache_hash = 0;
InitGRFGlobalVars();
_loadgame_DBGL_data.clear();
if (reset_settings) MakeNewgameSettingsLive();

@ -24,9 +24,11 @@
#include "newgrf_animation_base.h"
#include "newgrf_class_func.h"
#include "newgrf_extension.h"
#include "core/checksum_func.hpp"
#include "safeguards.h"
uint64 _station_tile_cache_hash = 0;
template <typename Tspec, typename Tid, Tid Tmax>
/* static */ void NewGRFClass<Tspec, Tid, Tmax>::InsertDefaults()
@ -1089,3 +1091,42 @@ void DumpStationSpriteGroup(const StationSpec *statspec, BaseStation *st, DumpSp
}
}
}
void UpdateStationTileCacheFlags(bool force_update)
{
SimpleChecksum64 checksum;
for (uint i = 0; StationClass::IsClassIDValid((StationClassID)i); i++) {
StationClass *stclass = StationClass::Get((StationClassID)i);
checksum.Update(stclass->GetSpecCount());
for (uint j = 0; j < stclass->GetSpecCount(); j++) {
const StationSpec *statspec = stclass->GetSpec(j);
if (statspec == nullptr) continue;
checksum.Update(j);
checksum.Update(statspec->blocked);
checksum.Update(statspec->pylons);
checksum.Update(statspec->wires);
}
}
if (checksum.state != _station_tile_cache_hash || force_update) {
_station_tile_cache_hash = checksum.state;
for (TileIndex t = 0; t < MapSize(); t++) {
if (HasStationTileRail(t)) {
StationGfx gfx = GetStationGfx(t);
const StationSpec *statspec = GetStationSpec(t);
bool blocked = statspec != nullptr && HasBit(statspec->blocked, gfx);
/* Default stations do not draw pylons under roofs (gfx >= 4) */
bool pylons = statspec != nullptr ? HasBit(statspec->pylons, gfx) : gfx < 4;
bool wires = statspec == nullptr || !HasBit(statspec->wires, gfx);
SetStationTileBlocked(t, blocked);
SetStationTileHavePylons(t, pylons);
SetStationTileHaveWires(t, wires);
}
}
}
}

@ -223,4 +223,6 @@ void TriggerStationAnimation(BaseStation *st, TileIndex tile, StationAnimationTr
void TriggerStationRandomisation(Station *st, TileIndex tile, StationRandomTrigger trigger, CargoID cargo_type = CT_INVALID);
void StationUpdateCachedTriggers(BaseStation *st);
void UpdateStationTileCacheFlags(bool force_update);
#endif /* NEWGRF_STATION_H */

@ -129,6 +129,7 @@ extern void RebuildTownCaches(bool cargo_update_required, bool old_map_position)
extern void ShowOSErrorBox(const char *buf, bool system);
extern void NORETURN DoOSAbort();
extern std::string _config_file;
extern uint64 _station_tile_cache_hash;
bool _save_config = false;
bool _request_newgrf_scan = false;
@ -515,6 +516,7 @@ static void ShutdownGame()
_game_load_time = 0;
_extra_aspects = 0;
_aspect_cfg_hash = 0;
_station_tile_cache_hash = 0;
InitGRFGlobalVars();
_loadgame_DBGL_data.clear();
_loadgame_DBGC_data.clear();

@ -3338,25 +3338,9 @@ bool AfterLoadGame()
_settings_game.script.settings_profile = IsInsideMM(_old_diff_level, SP_BEGIN, SP_END) ? _old_diff_level : (uint)SP_MEDIUM;
}
{
/* Station blocked, wires and pylon flags need to be stored in the map. This is effectively cached data, so no
* version check is necessary. This is done here as the SLV_182 check below needs the blocked status. */
for (TileIndex t = 0; t < map_size; t++) {
if (HasStationTileRail(t)) {
StationGfx gfx = GetStationGfx(t);
const StationSpec *statspec = GetStationSpec(t);
bool blocked = statspec != nullptr && HasBit(statspec->blocked, gfx);
/* Default stations do not draw pylons under roofs (gfx >= 4) */
bool pylons = statspec != nullptr ? HasBit(statspec->pylons, gfx) : gfx < 4;
bool wires = statspec == nullptr || !HasBit(statspec->wires, gfx);
SetStationTileBlocked(t, blocked);
SetStationTileHavePylons(t, pylons);
SetStationTileHaveWires(t, wires);
}
}
}
/* Station blocked, wires and pylon flags need to be stored in the map.
* This is done here as the SLV_182 check below needs the blocked status. */
UpdateStationTileCacheFlags(SlXvIsFeatureMissing(XSLFI_STATION_TILE_CACHE_FLAGS));
if (IsSavegameVersionBefore(SLV_182)) {
/* Aircraft acceleration variable was bonkers */
@ -4409,6 +4393,7 @@ void ReloadNewGRFData()
GroupStatistics::UpdateAfterLoad();
/* update station graphics */
AfterLoadStations();
UpdateStationTileCacheFlags(false);
RailType rail_type_translate_map[RAILTYPE_END];
for (RailType old_type = RAILTYPE_BEGIN; old_type != RAILTYPE_END; old_type++) {

@ -70,6 +70,8 @@ static void loadUV(const SlxiSubChunkInfo *info, uint32 length);
static uint32 saveUV(const SlxiSubChunkInfo *info, bool dry_run);
static void loadLC(const SlxiSubChunkInfo *info, uint32 length);
static uint32 saveLC(const SlxiSubChunkInfo *info, bool dry_run);
static void loadSTC(const SlxiSubChunkInfo *info, uint32 length);
static uint32 saveSTC(const SlxiSubChunkInfo *info, bool dry_run);
const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = {
{ XSLFI_VERSION_LABEL, XSCF_IGNORABLE_ALL, 1, 1, "version_label", saveVL, loadVL, nullptr },
@ -190,6 +192,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = {
{ XSLFI_LABEL_ORDERS, XSCF_NULL, 2, 2, "label_orders", nullptr, nullptr, nullptr },
{ XSLFI_VARIABLE_TICK_RATE, XSCF_IGNORABLE_ALL, 1, 1, "variable_tick_rate", nullptr, nullptr, nullptr },
{ XSLFI_ROAD_VEH_FLAGS, XSCF_NULL, 1, 1, "road_veh_flags", nullptr, nullptr, nullptr },
{ XSLFI_STATION_TILE_CACHE_FLAGS, XSCF_IGNORABLE_ALL, 1, 1, "station_tile_cache_flags", saveSTC, loadSTC, nullptr },
{ XSLFI_SCRIPT_INT64, XSCF_NULL, 1, 1, "script_int64", nullptr, nullptr, nullptr },
{ XSLFI_U64_TICK_COUNTER, XSCF_NULL, 1, 1, "u64_tick_counter", nullptr, nullptr, nullptr },
{ XSLFI_LINKGRAPH_TRAVEL_TIME, XSCF_NULL, 1, 1, "linkgraph_travel_time", nullptr, nullptr, nullptr },
@ -755,6 +758,24 @@ static uint32 saveLC(const SlxiSubChunkInfo *info, bool dry_run)
return 1;
}
static void loadSTC(const SlxiSubChunkInfo *info, uint32 length)
{
extern uint64 _station_tile_cache_hash;
if (length == 8) {
_station_tile_cache_hash = SlReadUint64();
} else {
DEBUG(sl, 1, "SLXI chunk: feature: '%s', version: %d, has data of wrong length: %u", info->name, _sl_xv_feature_versions[info->index], length);
ReadBuffer::GetCurrent()->SkipBytes(length);
}
}
static uint32 saveSTC(const SlxiSubChunkInfo *info, bool dry_run)
{
extern uint64 _station_tile_cache_hash;
if (!dry_run) SlWriteUint64(_station_tile_cache_hash);
return 8;
}
extern const ChunkHandler version_ext_chunk_handlers[] = {
{ 'SLXI', Save_SLXI, Load_SLXI, nullptr, Load_SLXI, CH_RIFF },
};

@ -141,6 +141,7 @@ enum SlXvFeatureIndex {
XSLFI_LABEL_ORDERS, ///< Label orders
XSLFI_VARIABLE_TICK_RATE, ///< Variable tick rate
XSLFI_ROAD_VEH_FLAGS, ///< Road vehicle flags
XSLFI_STATION_TILE_CACHE_FLAGS, ///< Station tile cache flags
XSLFI_SCRIPT_INT64, ///< See: SLV_SCRIPT_INT64
XSLFI_U64_TICK_COUNTER, ///< See: SLV_U64_TICK_COUNTER

Loading…
Cancel
Save