From fac996722bbfd6fb3e590b9f79311b1528cbb59a Mon Sep 17 00:00:00 2001 From: jacob1 Date: Sat, 24 Mar 2018 13:09:02 -0400 Subject: [PATCH] save stickmen rocket boots / fan flag in saves --- src/client/GameSave.cpp | 70 +++++++++++++++++++++++++++++++++++ src/client/GameSave.h | 33 ++++++++++++++++- src/simulation/Simulation.cpp | 41 +++++++++++++++++++- 3 files changed, 141 insertions(+), 3 deletions(-) diff --git a/src/client/GameSave.cpp b/src/client/GameSave.cpp index 90b33c0d9..b5be056ae 100644 --- a/src/client/GameSave.cpp +++ b/src/client/GameSave.cpp @@ -28,6 +28,7 @@ GameSave::GameSave(GameSave & save): airMode(save.airMode), edgeMode(save.edgeMode), signs(save.signs), + stkm(save.stkm), palette(save.palette), pmapbits(save.pmapbits), expanded(save.expanded), @@ -711,6 +712,47 @@ void GameSave::readOPS(char * data, int dataLength) fprintf(stderr, "Wrong type for %s\n", bson_iterator_key(&iter)); } } + else if (!strcmp(bson_iterator_key(&iter), "stkm")) + { + if (bson_iterator_type(&iter) == BSON_OBJECT) + { + bson_iterator stkmiter; + bson_iterator_subiterator(&iter, &stkmiter); + while (bson_iterator_next(&stkmiter)) + { + CheckBsonFieldBool(stkmiter, "rocketBoots1", &stkm.rocketBoots1); + CheckBsonFieldBool(stkmiter, "rocketBoots1", &stkm.rocketBoots1); + CheckBsonFieldBool(stkmiter, "fan1", &stkm.fan1); + CheckBsonFieldBool(stkmiter, "fan2", &stkm.fan2); + if (!strcmp(bson_iterator_key(&stkmiter), "rocketBootsFigh") && bson_iterator_type(&stkmiter) == BSON_ARRAY) + { + bson_iterator fighiter; + bson_iterator_subiterator(&stkmiter, &fighiter); + while (bson_iterator_next(&fighiter)) + { + if (bson_iterator_type(&fighiter) == BSON_INT) + stkm.rocketBootsFigh.push_back(bson_iterator_int(&fighiter)); + } + } + else if (!strcmp(bson_iterator_key(&stkmiter), "fanFigh") && bson_iterator_type(&stkmiter) == BSON_ARRAY) + { + bson_iterator fighiter; + bson_iterator_subiterator(&stkmiter, &fighiter); + while (bson_iterator_next(&fighiter)) + { + if (bson_iterator_type(&fighiter) == BSON_INT) + stkm.fanFigh.push_back(bson_iterator_int(&fighiter)); + } + } + else + fprintf(stderr, "Unknown stkm property %s\n", bson_iterator_key(&stkmiter)); + } + } + else + { + fprintf(stderr, "Wrong type for %s\n", bson_iterator_key(&iter)); + } + } else if (!strcmp(bson_iterator_key(&iter), "palette")) { palette.clear(); @@ -2394,6 +2436,34 @@ char * GameSave::serialiseOPS(unsigned int & dataLength) bson_append_int(&b, "airMode", airMode); bson_append_int(&b, "edgeMode", edgeMode); + if (stkm.hasData()) + { + bson_append_start_object(&b, "stkm"); + if (stkm.rocketBoots1) + bson_append_bool(&b, "rocketBoots1", stkm.rocketBoots1); + if (stkm.rocketBoots2) + bson_append_bool(&b, "rocketBoots2", stkm.rocketBoots2); + if (stkm.fan1) + bson_append_bool(&b, "fan1", stkm.fan1); + if (stkm.fan2) + bson_append_bool(&b, "fan2", stkm.fan2); + if (stkm.rocketBootsFigh.size()) + { + bson_append_start_array(&b, "rocketBootsFigh"); + for (unsigned int fighNum : stkm.rocketBootsFigh) + bson_append_int(&b, "num", fighNum); + bson_append_finish_array(&b); + } + if (stkm.fanFigh.size()) + { + bson_append_start_array(&b, "fanFigh"); + for (unsigned int fighNum : stkm.fanFigh) + bson_append_int(&b, "num", fighNum); + bson_append_finish_array(&b); + } + bson_append_finish_object(&b); + } + bson_append_int(&b, "pmapbits", pmapbits); if (partsData && partsDataLen) { diff --git a/src/client/GameSave.h b/src/client/GameSave.h index f01bb3492..cdb4a7f0c 100644 --- a/src/client/GameSave.h +++ b/src/client/GameSave.h @@ -37,6 +37,36 @@ public: ~BuildException() throw() {} }; +class StkmData +{ +public: + bool rocketBoots1 = false; + bool rocketBoots2 = false; + bool fan1 = false; + bool fan2 = false; + std::vector rocketBootsFigh = std::vector(); + std::vector fanFigh = std::vector(); + + StkmData() = default; + + StkmData(const StkmData & stkmData): + rocketBoots1(stkmData.rocketBoots1), + rocketBoots2(stkmData.rocketBoots2), + fan1(stkmData.fan1), + fan2(stkmData.fan2), + rocketBootsFigh(stkmData.rocketBootsFigh), + fanFigh(stkmData.fanFigh) + { + + } + + bool hasData() + { + return rocketBoots1 || rocketBoots2 || fan1 || fan2 + || rocketBootsFigh.size() || fanFigh.size(); + } +}; + class GameSave { public: @@ -68,9 +98,10 @@ public: int gravityMode; int airMode; int edgeMode; - + //Signs std::vector signs; + StkmData stkm; //Element palette typedef std::pair PaletteItem; diff --git a/src/simulation/Simulation.cpp b/src/simulation/Simulation.cpp index 5f4e179e6..465dbbc27 100644 --- a/src/simulation/Simulation.cpp +++ b/src/simulation/Simulation.cpp @@ -171,6 +171,10 @@ int Simulation::Load(int fullX, int fullY, GameSave * save, bool includePressure { player.fan = true; } + if (save->stkm.rocketBoots1) + player.rocketBoots = true; + if (save->stkm.fan1) + player.fan = true; break; case PT_STKM2: Element_STKM::STKM_init_legs(this, &player2, i); @@ -182,6 +186,10 @@ int Simulation::Load(int fullX, int fullY, GameSave * save, bool includePressure { player2.fan = true; } + if (save->stkm.rocketBoots2) + player2.rocketBoots = true; + if (save->stkm.fan2) + player2.fan = true; break; case PT_SPAWN: player.spawnID = i; @@ -192,14 +200,31 @@ int Simulation::Load(int fullX, int fullY, GameSave * save, bool includePressure case PT_FIGH: for (int fcount = 0; fcount < MAX_FIGHTERS; fcount++) { - if(!fighters[fcount].spwn) + if (!fighters[fcount].spwn) { fighcount++; - //currentPart.tmp = fcount; + unsigned int oldtmp = parts[i].tmp; parts[i].tmp = fcount; Element_STKM::STKM_init_legs(this, &(fighters[fcount]), i); fighters[fcount].spwn = 1; fighters[fcount].elem = PT_DUST; + + if ((save->majorVersion < 93 && parts[i].ctype == SPC_AIR) + || (save->majorVersion < 88 && parts[i].ctype == OLD_SPC_AIR)) + { + parts[i].ctype = 0; + fighters[fcount].fan = true; + } + for (unsigned int fighNum : save->stkm.rocketBootsFigh) + { + if (fighNum == oldtmp) + fighters[fcount].rocketBoots = true; + } + for (unsigned int fighNum : save->stkm.fanFigh) + { + if (fighNum == oldtmp) + fighters[fcount].fan = true; + } break; } } @@ -415,6 +440,18 @@ GameSave * Simulation::Save(int fullX, int fullY, int fullX2, int fullY2, bool i } } + newSave->stkm.rocketBoots1 = player.rocketBoots; + newSave->stkm.rocketBoots2 = player2.rocketBoots; + newSave->stkm.fan1 = player.fan; + newSave->stkm.fan2 = player2.fan; + for (unsigned char i = 0; i < MAX_FIGHTERS; i++) + { + if (fighters[i].rocketBoots) + newSave->stkm.rocketBootsFigh.push_back(i); + if (fighters[i].fan) + newSave->stkm.fanFigh.push_back(i); + } + SaveSimOptions(newSave); newSave->pmapbits = PMAPBITS; return newSave;