mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-16 11:33:03 +01:00
Gamestate snapshots (#8819)
* Add initial interface. * Implement move operator in MemoryStream * Add pod array serialisation traits. * Add push_back with move semantics to CircularBuffer * Initial implementation of GameStateSnapshots * Add GameStateSnapshots to Context. * Add mp_desync console command. * Compare sprite data and fill change list. * Minor changes. * Proof of concept. * Calculate offset instead of using offsetof * Implement game state difference detection * Update mp_desync console command. * Fix identification of sprite remove/add. * Fix crash when only one peep in park when using mp_desync * Output state differences into user directory desync folder. * Add desync debugging as an option. * Add information to network status when a desync report was created. * Cast to proper type for %llu. * Update xcode project * Add more information to the diffed data. * Remove client-only relevant fields. * Cleanup. * Add better name output for misc sprites * Add srand0 and tick information to the output * Bump up network version * Cleanup * Set desync_debugging to false as default * Apply suggestions
This commit is contained in:
@@ -1549,6 +1549,66 @@ static int32_t cc_replay_normalise(InteractiveConsole& console, const arguments_
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t cc_mp_desync(InteractiveConsole& console, const arguments_t& argv)
|
||||
{
|
||||
int32_t desyncType = 0;
|
||||
if (argv.size() >= 1)
|
||||
{
|
||||
desyncType = atoi(argv[0].c_str());
|
||||
}
|
||||
|
||||
std::vector<rct_sprite*> peeps;
|
||||
std::vector<rct_sprite*> vehicles;
|
||||
|
||||
for (int i = 0; i < MAX_SPRITES; i++)
|
||||
{
|
||||
rct_sprite* sprite = get_sprite(i);
|
||||
if (sprite->generic.sprite_identifier == SPRITE_IDENTIFIER_NULL)
|
||||
continue;
|
||||
|
||||
if (sprite->generic.sprite_identifier == SPRITE_IDENTIFIER_PEEP)
|
||||
peeps.push_back(sprite);
|
||||
else if (sprite->generic.sprite_identifier == SPRITE_IDENTIFIER_VEHICLE)
|
||||
vehicles.push_back(sprite);
|
||||
}
|
||||
|
||||
switch (desyncType)
|
||||
{
|
||||
case 0: // Peep t-shirts.
|
||||
{
|
||||
if (peeps.empty())
|
||||
{
|
||||
console.WriteFormatLine("No peeps");
|
||||
}
|
||||
else
|
||||
{
|
||||
rct_sprite* sprite = peeps[0];
|
||||
if (peeps.size() > 1)
|
||||
sprite = peeps[util_rand() % peeps.size() - 1];
|
||||
sprite->peep.tshirt_colour = util_rand() & 0xFF;
|
||||
invalidate_sprite_0(sprite);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 1: // Remove random peep.
|
||||
{
|
||||
if (peeps.empty())
|
||||
{
|
||||
console.WriteFormatLine("No peep removed");
|
||||
}
|
||||
else
|
||||
{
|
||||
rct_sprite* sprite = peeps[0];
|
||||
if (peeps.size() > 1)
|
||||
sprite = peeps[util_rand() % peeps.size() - 1];
|
||||
sprite->AsPeep()->Remove();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4702) // unreachable code
|
||||
static int32_t cc_abort([[maybe_unused]] InteractiveConsole& console, [[maybe_unused]] const arguments_t& argv)
|
||||
@@ -1670,6 +1730,7 @@ static constexpr const console_command console_command_table[] = {
|
||||
{ "replay_start", cc_replay_start, "Starts a replay", "replay_start <name>"},
|
||||
{ "replay_stop", cc_replay_stop, "Stops the replay", "replay_stop"},
|
||||
{ "replay_normalise", cc_replay_normalise, "Normalises the replay to remove all gaps", "replay_normalise <input file> <output file>"},
|
||||
{ "mp_desync", cc_mp_desync, "Forces a multiplayer desync", "cc_mp_desync [desync_type, 0 = Random t-shirt color on random peep, 1 = Remove random peep ]"},
|
||||
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
Reference in New Issue
Block a user