diff --git a/src/client/GameSave.cpp b/src/client/GameSave.cpp index e6f36f510..470243a97 100644 --- a/src/client/GameSave.cpp +++ b/src/client/GameSave.cpp @@ -2280,17 +2280,17 @@ char * GameSave::serialiseOPS(unsigned int & dataLength) } if (PMAPBITS > 8) { - if (Simulation::TypeInCtype(particles[i].type) && particles[i].ctype > 0xFF) + if (TypeInCtype(particles[i].type, particles[i].ctype) && particles[i].ctype > 0xFF) { RESTRICTVERSION(93, 0); fromNewerVersion = true; // TODO: remove on 93.0 release } - else if (Simulation::TypeInTmp(particles[i].type) && particles[i].tmp > 0xFF) + else if (TypeInTmp(particles[i].type) && particles[i].tmp > 0xFF) { RESTRICTVERSION(93, 0); fromNewerVersion = true; // TODO: remove on 93.0 release } - else if (Simulation::TypeInTmp2(particles[i].type) && particles[i].tmp2 > 0xFF) + else if (TypeInTmp2(particles[i].type, particles[i].tmp2) && particles[i].tmp2 > 0xFF) { RESTRICTVERSION(93, 0); fromNewerVersion = true; // TODO: remove on 93.0 release @@ -2620,6 +2620,26 @@ void GameSave::Deallocate2DArray(T ***array, int blockHeight) } } +bool GameSave::TypeInCtype(int type, int ctype) +{ + return ctype >= 0 && ctype < PT_NUM && + (type == PT_CLNE || type == PT_PCLN || type == PT_BCLN || type == PT_PBCN || + type == PT_STOR || type == PT_CONV || type == PT_STKM || type == PT_STKM2 || + type == PT_FIGH || type == PT_LAVA || type == PT_SPRK || type == PT_PSTN || + type == PT_CRAY || type == PT_DTEC || type == PT_DRAY || type == PT_PIPE || + type == PT_PPIP); +} + +bool GameSave::TypeInTmp(int type) +{ + return type == PT_STOR; +} + +bool GameSave::TypeInTmp2(int type, int tmp2) +{ + return (type == PT_VIRS || type == PT_VRSG || type == PT_VRSS) && (tmp2 >= 0 && tmp2 < PT_NUM); +} + void GameSave::dealloc() { if (particles) diff --git a/src/client/GameSave.h b/src/client/GameSave.h index c8abac340..b619346ff 100644 --- a/src/client/GameSave.h +++ b/src/client/GameSave.h @@ -97,7 +97,11 @@ public: void Expand(); void Collapse(); bool Collapsed(); - + + static bool TypeInCtype(int type, int ctype); + static bool TypeInTmp(int type); + static bool TypeInTmp2(int type, int tmp2); + inline GameSave& operator << (Particle v) { if(particlesCount -#include +#include #ifdef _MSC_VER #include #else @@ -113,21 +113,21 @@ int Simulation::Load(int fullX, int fullY, GameSave * save, bool includePressure ctype = partMap[ctype]; tempPart.ctype = PMAP(extra, ctype); } - else if (tempPart.ctype > 0 && tempPart.ctype < PT_NUM && TypeInCtype(tempPart.type)) + else if (GameSave::TypeInCtype(tempPart.type, tempPart.ctype)) { tempPart.ctype = partMap[tempPart.ctype]; } // also stores extra bits past type (only STOR right now) - if (TypeInTmp(tempPart.type)) + if (GameSave::TypeInTmp(tempPart.type)) { int tmp = tempPart.tmp & pmapmask; int extra = tempPart.tmp >> save->pmapbits; + tmp = partMap[TYP(tmp)]; tempPart.tmp = PMAP(extra, tmp); } - if (TypeInTmp2(tempPart.type)) + if (GameSave::TypeInTmp2(tempPart.type, tempPart.tmp2)) { - if (tempPart.tmp2 > 0 && tempPart.tmp2 < PT_NUM) - tempPart.tmp2 = partMap[tempPart.tmp2]; + tempPart.tmp2 = partMap[tempPart.tmp2]; } //Replace existing @@ -266,25 +266,6 @@ int Simulation::Load(int fullX, int fullY, GameSave * save, bool includePressure return 0; } -bool Simulation::TypeInCtype(int el) -{ - return el == PT_CLNE || el == PT_PCLN || el == PT_BCLN || el == PT_PBCN || - el == PT_STOR || el == PT_CONV || el == PT_STKM || el == PT_STKM2 || - el == PT_FIGH || el == PT_LAVA || el == PT_SPRK || el == PT_PSTN || - el == PT_CRAY || el == PT_DTEC || el == PT_DRAY || el == PT_PIPE || - el == PT_PPIP; -} - -bool Simulation::TypeInTmp(int el) -{ - return el == PT_STOR; -} - -bool Simulation::TypeInTmp2(int el) -{ - return el == PT_VIRS || el == PT_VRSG || el == PT_VRSS; -} - GameSave * Simulation::Save(bool includePressure) { return Save(0, 0, XRES-1, YRES-1, includePressure); @@ -325,6 +306,7 @@ GameSave * Simulation::Save(int fullX, int fullY, int fullX2, int fullY2, bool i std::fill(elementCount, elementCount+PT_NUM, 0); // Map of soap particles loaded into this save, new ID -> old ID std::map soapList; + std::set paletteSet; for (int i = 0; i < NPART; i++) { int x, y; @@ -342,19 +324,23 @@ GameSave * Simulation::Save(int fullX, int fullY, int fullX2, int fullY2, bool i *newSave << tempPart; storedParts++; elementCount[tempPart.type]++; + + paletteSet.insert(tempPart.type); + if (GameSave::TypeInCtype(tempPart.type, tempPart.ctype)) + paletteSet.insert(tempPart.ctype); + if (GameSave::TypeInTmp(tempPart.type)) + paletteSet.insert(TYP(tempPart.tmp)); + if (GameSave::TypeInTmp2(tempPart.type, tempPart.tmp2)) + paletteSet.insert(tempPart.tmp2); } } } if (storedParts) { - for (int i = 0; i < PT_NUM; i++) - { - if (elements[i].Enabled && elementCount[i]) - { - newSave->palette.push_back(GameSave::PaletteItem(elements[i].Identifier, i)); - } - } + for (int ID : paletteSet) + newSave->palette.push_back(GameSave::PaletteItem(elements[ID].Identifier, ID)); + // fix SOAP links using soapList, a map of new particle ID -> old particle ID // loop through every new particle (saved into the save), and convert .tmp / .tmp2 for (std::map::iterator iter = soapList.begin(), end = soapList.end(); iter != end; ++iter) diff --git a/src/simulation/Simulation.h b/src/simulation/Simulation.h index a998beb5a..9652b97c9 100644 --- a/src/simulation/Simulation.h +++ b/src/simulation/Simulation.h @@ -216,12 +216,6 @@ public: return (x>=0 && y>=0 && x