Store signal style GRF to local map in savegame
Update existing signal style IDs as necessary
This commit is contained in:
@@ -120,6 +120,9 @@ void InitializeGame(uint size_x, uint size_y, bool reset_date, bool reset_settin
|
|||||||
ClearCargoPacketDeferredPayments();
|
ClearCargoPacketDeferredPayments();
|
||||||
PoolBase::Clean(PT_NORMAL);
|
PoolBase::Clean(PT_NORMAL);
|
||||||
|
|
||||||
|
extern void ClearNewSignalStyleMapping();
|
||||||
|
ClearNewSignalStyleMapping();
|
||||||
|
|
||||||
RebuildStationKdtree();
|
RebuildStationKdtree();
|
||||||
RebuildTownKdtree();
|
RebuildTownKdtree();
|
||||||
RebuildViewportKdtree();
|
RebuildViewportKdtree();
|
||||||
|
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
std::vector<const GRFFile *> _new_signals_grfs;
|
std::vector<const GRFFile *> _new_signals_grfs;
|
||||||
std::array<NewSignalStyle, MAX_NEW_SIGNAL_STYLES> _new_signal_styles;
|
std::array<NewSignalStyle, MAX_NEW_SIGNAL_STYLES> _new_signal_styles;
|
||||||
|
std::array<NewSignalStyleMapping, MAX_NEW_SIGNAL_STYLES> _new_signal_style_mapping;
|
||||||
uint _num_new_signal_styles = 0;
|
uint _num_new_signal_styles = 0;
|
||||||
|
|
||||||
/* virtual */ uint32 NewSignalsScopeResolver::GetRandomBits() const
|
/* virtual */ uint32 NewSignalsScopeResolver::GetRandomBits() const
|
||||||
|
@@ -47,6 +47,13 @@ struct NewSignalStyle {
|
|||||||
PalSpriteID signals[SIGTYPE_END][2][2];
|
PalSpriteID signals[SIGTYPE_END][2][2];
|
||||||
};
|
};
|
||||||
extern std::array<NewSignalStyle, MAX_NEW_SIGNAL_STYLES> _new_signal_styles;
|
extern std::array<NewSignalStyle, MAX_NEW_SIGNAL_STYLES> _new_signal_styles;
|
||||||
|
struct NewSignalStyleMapping {
|
||||||
|
uint32 grfid = 0;
|
||||||
|
uint8 grf_local_id = 0;
|
||||||
|
|
||||||
|
inline bool operator==(const NewSignalStyleMapping& o) const { return grfid == o.grfid && grf_local_id == o.grf_local_id; }
|
||||||
|
};
|
||||||
|
extern std::array<NewSignalStyleMapping, MAX_NEW_SIGNAL_STYLES> _new_signal_style_mapping;
|
||||||
extern uint _num_new_signal_styles;
|
extern uint _num_new_signal_styles;
|
||||||
|
|
||||||
/** Resolver for the new signals scope. */
|
/** Resolver for the new signals scope. */
|
||||||
|
@@ -447,6 +447,9 @@ static void ShutdownGame()
|
|||||||
FreeSignalPrograms();
|
FreeSignalPrograms();
|
||||||
FreeSignalDependencies();
|
FreeSignalDependencies();
|
||||||
|
|
||||||
|
extern void ClearNewSignalStyleMapping();
|
||||||
|
ClearNewSignalStyleMapping();
|
||||||
|
|
||||||
extern void ClearAllSignalSpeedRestrictions();
|
extern void ClearAllSignalSpeedRestrictions();
|
||||||
ClearAllSignalSpeedRestrictions();
|
ClearAllSignalSpeedRestrictions();
|
||||||
|
|
||||||
|
@@ -28,6 +28,7 @@ add_files(
|
|||||||
misc_sl.cpp
|
misc_sl.cpp
|
||||||
newgrf_sl.cpp
|
newgrf_sl.cpp
|
||||||
newgrf_sl.h
|
newgrf_sl.h
|
||||||
|
newsignals_sl.cpp
|
||||||
object_sl.cpp
|
object_sl.cpp
|
||||||
oldloader.cpp
|
oldloader.cpp
|
||||||
oldloader.h
|
oldloader.h
|
||||||
|
@@ -173,7 +173,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = {
|
|||||||
{ XSLFI_RV_ORDER_EXTRA_FLAGS, XSCF_IGNORABLE_UNKNOWN, 1, 1, "rv_order_extra_flags", nullptr, nullptr, nullptr },
|
{ XSLFI_RV_ORDER_EXTRA_FLAGS, XSCF_IGNORABLE_UNKNOWN, 1, 1, "rv_order_extra_flags", nullptr, nullptr, nullptr },
|
||||||
{ XSLFI_GRF_ROADSTOPS, XSCF_NULL, 1, 1, "grf_road_stops", nullptr, nullptr, nullptr },
|
{ XSLFI_GRF_ROADSTOPS, XSCF_NULL, 1, 1, "grf_road_stops", nullptr, nullptr, nullptr },
|
||||||
{ XSLFI_INDUSTRY_ANIM_MASK, XSCF_IGNORABLE_ALL, 1, 1, "industry_anim_mask", nullptr, nullptr, nullptr },
|
{ XSLFI_INDUSTRY_ANIM_MASK, XSCF_IGNORABLE_ALL, 1, 1, "industry_anim_mask", nullptr, nullptr, nullptr },
|
||||||
{ XSLFI_NEW_SIGNAL_STYLES, XSCF_NULL, 1, 1, "new_signal_styles", nullptr, nullptr, "XBST" },
|
{ XSLFI_NEW_SIGNAL_STYLES, XSCF_NULL, 2, 2, "new_signal_styles", nullptr, nullptr, "XBST,NSID" },
|
||||||
{ XSLFI_SCRIPT_INT64, XSCF_NULL, 1, 1, "script_int64", nullptr, nullptr, nullptr },
|
{ XSLFI_SCRIPT_INT64, XSCF_NULL, 1, 1, "script_int64", nullptr, nullptr, nullptr },
|
||||||
{ XSLFI_NULL, XSCF_NULL, 0, 0, nullptr, nullptr, nullptr, nullptr },// This is the end marker
|
{ XSLFI_NULL, XSCF_NULL, 0, 0, nullptr, nullptr, nullptr, nullptr },// This is the end marker
|
||||||
};
|
};
|
||||||
|
42
src/saveload/newsignals_sl.cpp
Normal file
42
src/saveload/newsignals_sl.cpp
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of OpenTTD.
|
||||||
|
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
||||||
|
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @file newsignals_sl.cpp Code handling saving and loading of new signals */
|
||||||
|
|
||||||
|
#include "../stdafx.h"
|
||||||
|
#include "../newgrf_newsignals.h"
|
||||||
|
|
||||||
|
#include "saveload.h"
|
||||||
|
|
||||||
|
#include "../safeguards.h"
|
||||||
|
|
||||||
|
static void Save_NSID()
|
||||||
|
{
|
||||||
|
SlSetLength(4 + (lengthof(_new_signal_style_mapping) * 5));
|
||||||
|
SlWriteUint32(lengthof(_new_signal_style_mapping));
|
||||||
|
for (const NewSignalStyleMapping &mapping : _new_signal_style_mapping) {
|
||||||
|
SlWriteUint32(mapping.grfid);
|
||||||
|
SlWriteByte(mapping.grf_local_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Load_NSID()
|
||||||
|
{
|
||||||
|
uint count = SlReadUint32();
|
||||||
|
for (uint i = 0; i < count; i++) {
|
||||||
|
NewSignalStyleMapping mapping;
|
||||||
|
mapping.grfid = SlReadUint32();
|
||||||
|
mapping.grf_local_id = SlReadByte();
|
||||||
|
if (i < lengthof(_new_signal_style_mapping)) _new_signal_style_mapping[i] = mapping;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const ChunkHandler new_signal_chunk_handlers[] = {
|
||||||
|
{ 'NSID', Save_NSID, Load_NSID, nullptr, nullptr, CH_RIFF },
|
||||||
|
};
|
||||||
|
|
||||||
|
extern const ChunkHandlerTable _new_signal_chunk_handlers(new_signal_chunk_handlers);
|
@@ -300,6 +300,7 @@ static const std::vector<ChunkHandler> &ChunkHandlers()
|
|||||||
extern const ChunkHandlerTable _bridge_signal_chunk_handlers;
|
extern const ChunkHandlerTable _bridge_signal_chunk_handlers;
|
||||||
extern const ChunkHandlerTable _tunnel_chunk_handlers;
|
extern const ChunkHandlerTable _tunnel_chunk_handlers;
|
||||||
extern const ChunkHandlerTable _train_speed_adaptation_chunk_handlers;
|
extern const ChunkHandlerTable _train_speed_adaptation_chunk_handlers;
|
||||||
|
extern const ChunkHandlerTable _new_signal_chunk_handlers;
|
||||||
extern const ChunkHandlerTable _debug_chunk_handlers;
|
extern const ChunkHandlerTable _debug_chunk_handlers;
|
||||||
|
|
||||||
/** List of all chunks in a savegame. */
|
/** List of all chunks in a savegame. */
|
||||||
@@ -346,6 +347,7 @@ static const std::vector<ChunkHandler> &ChunkHandlers()
|
|||||||
_bridge_signal_chunk_handlers,
|
_bridge_signal_chunk_handlers,
|
||||||
_tunnel_chunk_handlers,
|
_tunnel_chunk_handlers,
|
||||||
_train_speed_adaptation_chunk_handlers,
|
_train_speed_adaptation_chunk_handlers,
|
||||||
|
_new_signal_chunk_handlers,
|
||||||
_debug_chunk_handlers,
|
_debug_chunk_handlers,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -1503,6 +1503,79 @@ void UpdateAllSignalAspects()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClearNewSignalStyleMapping()
|
||||||
|
{
|
||||||
|
_new_signal_style_mapping.fill({});
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool RemapNewSignalStyles(const std::array<NewSignalStyleMapping, MAX_NEW_SIGNAL_STYLES> &new_mapping)
|
||||||
|
{
|
||||||
|
const std::array<NewSignalStyleMapping, MAX_NEW_SIGNAL_STYLES> old_mapping = _new_signal_style_mapping;
|
||||||
|
_new_signal_style_mapping = new_mapping;
|
||||||
|
|
||||||
|
uint8 remap_table[MAX_NEW_SIGNAL_STYLES + 1] = {};
|
||||||
|
remap_table[0] = 0;
|
||||||
|
|
||||||
|
uint8 next_free = _num_new_signal_styles;
|
||||||
|
|
||||||
|
bool do_remap = false;
|
||||||
|
for (uint i = 0; i < MAX_NEW_SIGNAL_STYLES; i++) {
|
||||||
|
if (old_mapping[i].grfid == 0) {
|
||||||
|
remap_table[i + 1] = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto find_target = [&]() {
|
||||||
|
for (uint j = 0; j < MAX_NEW_SIGNAL_STYLES; j++) {
|
||||||
|
if (old_mapping[i].grfid == _new_signal_style_mapping[j].grfid && old_mapping[i].grf_local_id == _new_signal_style_mapping[j].grf_local_id) {
|
||||||
|
remap_table[i + 1] = j + 1;
|
||||||
|
if (i != j) do_remap = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (next_free < MAX_NEW_SIGNAL_STYLES) {
|
||||||
|
remap_table[i + 1] = next_free + 1;
|
||||||
|
_new_signal_style_mapping[next_free].grfid = old_mapping[i].grfid;
|
||||||
|
_new_signal_style_mapping[next_free].grf_local_id = old_mapping[i].grf_local_id;
|
||||||
|
next_free++;
|
||||||
|
do_remap = true;
|
||||||
|
} else {
|
||||||
|
remap_table[i + 1] = 0;
|
||||||
|
do_remap = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
find_target();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (do_remap) {
|
||||||
|
const TileIndex map_size = MapSize();
|
||||||
|
for (TileIndex t = 0; t < map_size; t++) {
|
||||||
|
if (IsTileType(t, MP_RAILWAY) && HasSignals(t)) {
|
||||||
|
SetSignalStyle(t, TRACK_LOWER, remap_table[GetSignalStyle(t, TRACK_LOWER)]);
|
||||||
|
SetSignalStyle(t, TRACK_UPPER, remap_table[GetSignalStyle(t, TRACK_UPPER)]);
|
||||||
|
}
|
||||||
|
if (IsRailTunnelBridgeTile(t) && GetTunnelBridgeDirection(t) < DIAGDIR_SW) {
|
||||||
|
/* Only process west end of tunnel/bridge */
|
||||||
|
uint8 old_style = GetTunnelBridgeSignalStyle(t);
|
||||||
|
uint8 new_style = remap_table[old_style];
|
||||||
|
if (new_style != old_style) {
|
||||||
|
SetTunnelBridgeSignalStyle(t, GetOtherTunnelBridgeEnd(t), new_style);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return do_remap;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DetermineSignalStyleMapping(std::array<NewSignalStyleMapping, MAX_NEW_SIGNAL_STYLES> &mapping)
|
||||||
|
{
|
||||||
|
for (uint i = 0; i < _num_new_signal_styles; i++) {
|
||||||
|
mapping[i].grfid = _new_signal_styles[i].grffile->grfid;
|
||||||
|
mapping[i].grf_local_id = _new_signal_styles[i].grf_local_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static bool DetermineExtraAspectsVariable()
|
static bool DetermineExtraAspectsVariable()
|
||||||
{
|
{
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
@@ -1518,6 +1591,8 @@ static bool DetermineExtraAspectsVariable()
|
|||||||
for (const GRFFile *grf : _new_signals_grfs) {
|
for (const GRFFile *grf : _new_signals_grfs) {
|
||||||
new_extra_aspects = std::max<uint8>(new_extra_aspects, grf->new_signal_extra_aspects);
|
new_extra_aspects = std::max<uint8>(new_extra_aspects, grf->new_signal_extra_aspects);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (uint i = 0; i < _num_new_signal_styles; i++) {
|
for (uint i = 0; i < _num_new_signal_styles; i++) {
|
||||||
if (HasBit(_new_signal_styles[i].style_flags, NSSF_NO_ASPECT_INC)) {
|
if (HasBit(_new_signal_styles[i].style_flags, NSSF_NO_ASPECT_INC)) {
|
||||||
SetBit(_signal_style_masks.non_aspect_inc, i + 1);
|
SetBit(_signal_style_masks.non_aspect_inc, i + 1);
|
||||||
@@ -1542,7 +1617,6 @@ static bool DetermineExtraAspectsVariable()
|
|||||||
for (uint i = _num_new_signal_styles; i < MAX_NEW_SIGNAL_STYLES; i++) {
|
for (uint i = _num_new_signal_styles; i < MAX_NEW_SIGNAL_STYLES; i++) {
|
||||||
_new_signal_styles[i].lookahead_extra_aspects = new_extra_aspects;
|
_new_signal_styles[i].lookahead_extra_aspects = new_extra_aspects;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
_extra_aspects = new_extra_aspects;
|
_extra_aspects = new_extra_aspects;
|
||||||
|
|
||||||
@@ -1561,9 +1635,23 @@ static bool DetermineExtraAspectsVariable()
|
|||||||
|
|
||||||
void UpdateExtraAspectsVariable()
|
void UpdateExtraAspectsVariable()
|
||||||
{
|
{
|
||||||
bool changed = DetermineExtraAspectsVariable();
|
std::array<NewSignalStyleMapping, MAX_NEW_SIGNAL_STYLES> new_mapping;
|
||||||
|
DetermineSignalStyleMapping(new_mapping);
|
||||||
|
|
||||||
|
bool style_remap = false;
|
||||||
|
if (new_mapping != _new_signal_style_mapping) {
|
||||||
|
style_remap = RemapNewSignalStyles(new_mapping);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool style_change = DetermineExtraAspectsVariable();
|
||||||
|
|
||||||
|
if (style_remap || style_change) {
|
||||||
|
if (_networking && !_network_server) {
|
||||||
|
const char *msg = "Network client recalculating signal states and/or signal style mappings, this is likely to cause desyncs";
|
||||||
|
DEBUG(desync, 0, "%s", msg);
|
||||||
|
LogDesyncMsg(msg);
|
||||||
|
}
|
||||||
|
|
||||||
if (changed) {
|
|
||||||
UpdateAllSignalReserveThroughBits();
|
UpdateAllSignalReserveThroughBits();
|
||||||
if (_extra_aspects > 0) UpdateAllSignalAspects();
|
if (_extra_aspects > 0) UpdateAllSignalAspects();
|
||||||
UpdateAllBlockSignals();
|
UpdateAllBlockSignals();
|
||||||
@@ -1573,6 +1661,7 @@ void UpdateExtraAspectsVariable()
|
|||||||
|
|
||||||
void InitialiseExtraAspectsVariable()
|
void InitialiseExtraAspectsVariable()
|
||||||
{
|
{
|
||||||
|
DetermineSignalStyleMapping(_new_signal_style_mapping);
|
||||||
DetermineExtraAspectsVariable();
|
DetermineExtraAspectsVariable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user