Make a copy of particles before saving them and work off that

This is a minor refactor before the next commit; the significance of that commit would get lost in this noise otherwise.
This commit is contained in:
Tamás Bálint Misius 2025-01-15 19:00:14 +01:00
parent a7d73102d6
commit 2b0ee9392c
No known key found for this signature in database
GPG Key ID: 5B472A12F6ECA9F2

View File

@ -2200,33 +2200,34 @@ std::pair<bool, std::vector<char>> GameSave::serialiseOPS() const
//Store saved particle index+1 for this partsptr index (0 means not saved)
partsSaveIndex[i] = (partsCount++) + 1;
paletteSet.insert(particles[i].type);
auto part = particles[i];
paletteSet.insert(part.type);
for (auto index : possiblyCarriesType)
{
if (elements[particles[i].type].CarriesTypeIn & (1U << index))
if (elements[part.type].CarriesTypeIn & (1U << index))
{
auto *prop = reinterpret_cast<const int *>(reinterpret_cast<const char *>(&particles[i]) + properties[index].Offset);
auto *prop = reinterpret_cast<const int *>(reinterpret_cast<const char *>(&part) + properties[index].Offset);
paletteSet.insert(TYP(*prop));
}
}
//Type (required)
partsData[partsDataLen++] = particles[i].type;
partsData[partsDataLen++] = part.type;
//Location of the field descriptor
int fieldDesc3Loc = 0;
int fieldDescLoc = partsDataLen++;
partsDataLen++;
auto tmp3 = (unsigned int)(particles[i].tmp3);
auto tmp4 = (unsigned int)(particles[i].tmp4);
if ((tmp3 || tmp4) && (!PressureInTmp3(particles[i].type) || hasPressure))
auto tmp3 = (unsigned int)(part.tmp3);
auto tmp4 = (unsigned int)(part.tmp4);
if ((tmp3 || tmp4) && (!PressureInTmp3(part.type) || hasPressure))
{
fieldDesc |= 1 << 13;
// The tmp3 of PressureInTmp3 elements is okay to truncate because the loading code
// sign extends it anyway, expecting the value to not be higher in magnitude than
// 256 (max pressure value) * 64 (tmp3 multiplicative bias).
if (((tmp3 >> 16) || (tmp4 >> 16)) && !PressureInTmp3(particles[i].type))
if (((tmp3 >> 16) || (tmp4 >> 16)) && !PressureInTmp3(part.type))
{
fieldDesc |= 1 << 15;
fieldDesc |= 1 << 16;
@ -2235,24 +2236,24 @@ std::pair<bool, std::vector<char>> GameSave::serialiseOPS() const
}
// Extra type byte if necessary
if (particles[i].type & 0xFF00)
if (part.type & 0xFF00)
{
partsData[partsDataLen++] = particles[i].type >> 8;
partsData[partsDataLen++] = part.type >> 8;
fieldDesc |= 1 << 14;
RESTRICTVERSION(93, 0);
}
//Extra Temperature (2nd byte optional, 1st required), 1 to 2 bytes
//Store temperature as an offset of 21C(294.15K) or go into a 16byte int and store the whole thing
if(fabs(particles[i].temp-294.15f)<127)
if(fabs(part.temp-294.15f)<127)
{
tempTemp = int(floor(particles[i].temp-294.15f+0.5f));
tempTemp = int(floor(part.temp-294.15f+0.5f));
partsData[partsDataLen++] = tempTemp;
}
else
{
fieldDesc |= 1;
tempTemp = (int)(particles[i].temp+0.5f);
tempTemp = (int)(part.temp+0.5f);
partsData[partsDataLen++] = tempTemp;
partsData[partsDataLen++] = tempTemp >> 8;
}
@ -2263,9 +2264,9 @@ std::pair<bool, std::vector<char>> GameSave::serialiseOPS() const
}
//Life (optional), 1 to 2 bytes
if(particles[i].life)
if(part.life)
{
int life = particles[i].life;
int life = part.life;
if (life > 0xFFFF)
life = 0xFFFF;
else if (life < 0)
@ -2280,76 +2281,76 @@ std::pair<bool, std::vector<char>> GameSave::serialiseOPS() const
}
//Tmp (optional), 1, 2, or 4 bytes
if(particles[i].tmp)
if(part.tmp)
{
fieldDesc |= 1 << 3;
partsData[partsDataLen++] = particles[i].tmp;
if(particles[i].tmp & 0xFFFFFF00)
partsData[partsDataLen++] = part.tmp;
if(part.tmp & 0xFFFFFF00)
{
fieldDesc |= 1 << 4;
partsData[partsDataLen++] = particles[i].tmp >> 8;
if(particles[i].tmp & 0xFFFF0000)
partsData[partsDataLen++] = part.tmp >> 8;
if(part.tmp & 0xFFFF0000)
{
fieldDesc |= 1 << 12;
partsData[partsDataLen++] = (particles[i].tmp&0xFF000000)>>24;
partsData[partsDataLen++] = (particles[i].tmp&0x00FF0000)>>16;
partsData[partsDataLen++] = (part.tmp&0xFF000000)>>24;
partsData[partsDataLen++] = (part.tmp&0x00FF0000)>>16;
}
}
}
//Ctype (optional), 1 or 4 bytes
if(particles[i].ctype)
if(part.ctype)
{
fieldDesc |= 1 << 5;
partsData[partsDataLen++] = particles[i].ctype;
if(particles[i].ctype & 0xFFFFFF00)
partsData[partsDataLen++] = part.ctype;
if(part.ctype & 0xFFFFFF00)
{
fieldDesc |= 1 << 9;
partsData[partsDataLen++] = (particles[i].ctype&0xFF000000)>>24;
partsData[partsDataLen++] = (particles[i].ctype&0x00FF0000)>>16;
partsData[partsDataLen++] = (particles[i].ctype&0x0000FF00)>>8;
partsData[partsDataLen++] = (part.ctype&0xFF000000)>>24;
partsData[partsDataLen++] = (part.ctype&0x00FF0000)>>16;
partsData[partsDataLen++] = (part.ctype&0x0000FF00)>>8;
}
}
//Dcolour (optional), 4 bytes
if(particles[i].dcolour && (particles[i].dcolour & 0xFF000000 || particles[i].type == PT_LIFE))
if(part.dcolour && (part.dcolour & 0xFF000000 || part.type == PT_LIFE))
{
fieldDesc |= 1 << 6;
partsData[partsDataLen++] = (particles[i].dcolour&0xFF000000)>>24;
partsData[partsDataLen++] = (particles[i].dcolour&0x00FF0000)>>16;
partsData[partsDataLen++] = (particles[i].dcolour&0x0000FF00)>>8;
partsData[partsDataLen++] = (particles[i].dcolour&0x000000FF);
partsData[partsDataLen++] = (part.dcolour&0xFF000000)>>24;
partsData[partsDataLen++] = (part.dcolour&0x00FF0000)>>16;
partsData[partsDataLen++] = (part.dcolour&0x0000FF00)>>8;
partsData[partsDataLen++] = (part.dcolour&0x000000FF);
}
//VX (optional), 1 byte
if(fabs(particles[i].vx) > 0.001f)
if(fabs(part.vx) > 0.001f)
{
fieldDesc |= 1 << 7;
vTemp = (int)(particles[i].vx*16.0f+127.5f);
vTemp = (int)(part.vx*16.0f+127.5f);
if (vTemp<0) vTemp=0;
if (vTemp>255) vTemp=255;
partsData[partsDataLen++] = vTemp;
}
//VY (optional), 1 byte
if(fabs(particles[i].vy) > 0.001f)
if(fabs(part.vy) > 0.001f)
{
fieldDesc |= 1 << 8;
vTemp = (int)(particles[i].vy*16.0f+127.5f);
vTemp = (int)(part.vy*16.0f+127.5f);
if (vTemp<0) vTemp=0;
if (vTemp>255) vTemp=255;
partsData[partsDataLen++] = vTemp;
}
//Tmp2 (optional), 1 or 2 bytes
if(particles[i].tmp2)
if(part.tmp2)
{
fieldDesc |= 1 << 10;
partsData[partsDataLen++] = particles[i].tmp2;
if(particles[i].tmp2 & 0xFF00)
partsData[partsDataLen++] = part.tmp2;
if(part.tmp2 & 0xFF00)
{
fieldDesc |= 1 << 11;
partsData[partsDataLen++] = particles[i].tmp2 >> 8;
partsData[partsDataLen++] = part.tmp2 >> 8;
}
}
@ -2377,34 +2378,34 @@ std::pair<bool, std::vector<char>> GameSave::serialiseOPS() const
partsData[fieldDesc3Loc] = fieldDesc>>16;
}
if (particles[i].type == PT_SOAP)
if (part.type == PT_SOAP)
soapCount++;
if (particles[i].type == PT_RPEL && particles[i].ctype)
if (part.type == PT_RPEL && part.ctype)
{
RESTRICTVERSION(91, 4);
}
else if (particles[i].type == PT_NWHL && particles[i].tmp)
else if (part.type == PT_NWHL && part.tmp)
{
RESTRICTVERSION(91, 5);
}
if (particles[i].type == PT_HEAC || particles[i].type == PT_SAWD || particles[i].type == PT_POLO
|| particles[i].type == PT_RFRG || particles[i].type == PT_RFGL || particles[i].type == PT_LSNS)
if (part.type == PT_HEAC || part.type == PT_SAWD || part.type == PT_POLO
|| part.type == PT_RFRG || part.type == PT_RFGL || part.type == PT_LSNS)
{
RESTRICTVERSION(92, 0);
}
else if ((particles[i].type == PT_FRAY || particles[i].type == PT_INVIS) && particles[i].tmp)
else if ((part.type == PT_FRAY || part.type == PT_INVIS) && part.tmp)
{
RESTRICTVERSION(92, 0);
}
else if (particles[i].type == PT_PIPE || particles[i].type == PT_PPIP)
else if (part.type == PT_PIPE || part.type == PT_PPIP)
{
RESTRICTVERSION(93, 0);
}
if (particles[i].type == PT_TSNS || particles[i].type == PT_PSNS
|| particles[i].type == PT_HSWC || particles[i].type == PT_PUMP)
if (part.type == PT_TSNS || part.type == PT_PSNS
|| part.type == PT_HSWC || part.type == PT_PUMP)
{
if (particles[i].tmp == 1)
if (part.tmp == 1)
{
RESTRICTVERSION(93, 0);
}
@ -2413,9 +2414,9 @@ std::pair<bool, std::vector<char>> GameSave::serialiseOPS() const
{
for (auto index : possiblyCarriesType)
{
if (builtinElements[particles[i].type].CarriesTypeIn & (1U << index))
if (builtinElements[part.type].CarriesTypeIn & (1U << index))
{
auto *prop = reinterpret_cast<const int *>(reinterpret_cast<const char *>(&particles[i]) + properties[index].Offset);
auto *prop = reinterpret_cast<const int *>(reinterpret_cast<const char *>(&part) + properties[index].Offset);
if (TYP(*prop) > 0xFF)
{
RESTRICTVERSION(93, 0);
@ -2423,45 +2424,45 @@ std::pair<bool, std::vector<char>> GameSave::serialiseOPS() const
}
}
}
if (particles[i].type == PT_LDTC)
if (part.type == PT_LDTC)
{
RESTRICTVERSION(94, 0);
}
if (particles[i].type == PT_TSNS || particles[i].type == PT_PSNS)
if (part.type == PT_TSNS || part.type == PT_PSNS)
{
if (particles[i].tmp == 2)
if (part.tmp == 2)
{
RESTRICTVERSION(94, 0);
}
}
if (particles[i].type == PT_LSNS)
if (part.type == PT_LSNS)
{
if (particles[i].tmp >= 1 || particles[i].tmp <= 3)
if (part.tmp >= 1 || part.tmp <= 3)
{
RESTRICTVERSION(95, 0);
}
}
if (particles[i].type == PT_LIFE)
if (part.type == PT_LIFE)
{
RESTRICTVERSION(96, 0);
}
if (particles[i].type == PT_GLAS && particles[i].life > 0)
if (part.type == PT_GLAS && part.life > 0)
{
RESTRICTVERSION(97, 0);
}
if (PressureInTmp3(particles[i].type))
if (PressureInTmp3(part.type))
{
RESTRICTVERSION(97, 0);
}
if (particles[i].type == PT_CONV && particles[i].tmp2 != 0)
if (part.type == PT_CONV && part.tmp2 != 0)
{
RESTRICTVERSION(97, 0);
}
if (particles[i].type == PT_RSST || particles[i].type == PT_RSSS)
if (part.type == PT_RSST || part.type == PT_RSSS)
{
RESTRICTVERSION(98, 0);
}
if (particles[i].type == PT_ETRD && (particles[i].tmp || particles[i].tmp2))
if (part.type == PT_ETRD && (part.tmp || part.tmp2))
{
RESTRICTVERSION(98, 0);
}