Convert float pavg[2] to int tmp3, tmp4

Also add GameSave::PressureInTmp3 to check for elements with pressure memory and fix TUNG not sampling pressure on creation. This does not in itself fix #822 because tmp3 and tmp4 are still saved in 16 bits each, so full ctypes still don't fit in tmp3.
This commit is contained in:
Tamás Bálint Misius 2021-12-09 07:49:31 +01:00
parent 504fd21909
commit dbd971fb05
No known key found for this signature in database
GPG Key ID: 5B472A12F6ECA9F2
18 changed files with 111 additions and 142 deletions

View File

@ -1189,33 +1189,18 @@ void GameSave::readOPS(char * data, int dataLength)
} }
} }
//Read pavg //Read tmp3 and tmp4
if(fieldDescriptor & 0x2000) if(fieldDescriptor & 0x2000)
{ {
if (i+3 >= partsDataLen) if (i+3 >= partsDataLen)
throw ParseException(ParseException::Corrupt, "Ran past particle data buffer while loading pavg"); throw ParseException(ParseException::Corrupt, "Ran past particle data buffer while loading tmp3 and tmp4");
int pavg; unsigned int tmp34;
pavg = partsData[i++]; tmp34 = (unsigned int)partsData[i++];
pavg |= (((unsigned)partsData[i++]) << 8); tmp34 |= (unsigned int)partsData[i++] << 8;
particles[newIndex].pavg[0] = (float)pavg; particles[newIndex].tmp3 = tmp34;
pavg = partsData[i++]; tmp34 = (unsigned int)partsData[i++];
pavg |= (((unsigned)partsData[i++]) << 8); tmp34 |= (unsigned int)partsData[i++] << 8;
particles[newIndex].pavg[1] = (float)pavg; particles[newIndex].tmp4 = tmp34;
switch (particles[newIndex].type)
{
// List of elements that save pavg with a multiplicative bias of 2**6
// (or not at all if pressure is not saved).
// If you change this list, change it in Simulation::Load and GameSave::serialiseOPS too!
case PT_QRTZ:
case PT_GLAS:
case PT_TUNG:
if (particles[newIndex].pavg[0] >= 0x8000) particles[newIndex].pavg[0] -= 0x10000;
if (particles[newIndex].pavg[1] >= 0x8000) particles[newIndex].pavg[1] -= 0x10000;
particles[newIndex].pavg[0] /= 64;
particles[newIndex].pavg[1] /= 64;
break;
}
} }
//Particle specific parsing: //Particle specific parsing:
@ -2203,7 +2188,7 @@ char * GameSave::serialiseOPS(unsigned int & dataLength)
//Copy parts data //Copy parts data
/* Field descriptor format: /* Field descriptor format:
| 0 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | | 0 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| RESERVED | type[2] | pavg | tmp[3+4] | tmp2[2] | tmp2 | ctype[2] | vy | vx | decorations | ctype[1] | tmp[2] | tmp[1] | life[2] | life[1] | temp dbl len | | RESERVED | type[2] | tmp3 and tmp4 | tmp[3+4] | tmp2[2] | tmp2 | ctype[2] | vy | vx | decorations | ctype[1] | tmp[2] | tmp[1] | life[2] | life[1] | temp dbl len |
life[2] means a second byte (for a 16 bit field) if life[1] is present life[2] means a second byte (for a 16 bit field) if life[1] is present
last bit is reserved. If necessary, use it to signify that fieldDescriptor will have another byte last bit is reserved. If necessary, use it to signify that fieldDescriptor will have another byte
That way, if we ever need a 17th bit, we won't have to change the save format That way, if we ever need a 17th bit, we won't have to change the save format
@ -2355,36 +2340,16 @@ char * GameSave::serialiseOPS(unsigned int & dataLength)
} }
} }
//Pavg, 4 bytes //tmp3 and tmp4, 4 bytes
// save pavg if there's useful pavg to save if ((particles[i].tmp3 || particles[i].tmp4) && (!PressureInTmp3(particles[i].type) || hasPressure))
// and either we save pressure data too
// or the current particle is not one that cares about pressure
if (particles[i].pavg[0] || particles[i].pavg[1])
{ {
float pavg0 = particles[i].pavg[0]; auto tmp3 = (unsigned int)(particles[i].tmp3);
float pavg1 = particles[i].pavg[1]; auto tmp4 = (unsigned int)(particles[i].tmp4);
switch (particles[i].type) fieldDesc |= 1 << 13;
{ partsData[partsDataLen++] = tmp3 ;
// List of elements that save pavg with a multiplicative bias of 2**6 partsData[partsDataLen++] = tmp3 >> 8;
// (or not at all if pressure is not saved). partsData[partsDataLen++] = tmp4 ;
// If you change this list, change it in Simulation::Load and GameSave::readOPS too! partsData[partsDataLen++] = tmp4 >> 8;
case PT_QRTZ:
case PT_GLAS:
case PT_TUNG:
if (!hasPressure)
break;
pavg0 *= 64;
pavg1 *= 64;
// fallthrough!
default:
fieldDesc |= 1 << 13;
partsData[partsDataLen++] = (int)pavg0;
partsData[partsDataLen++] = ((int)pavg0)>>8;
partsData[partsDataLen++] = (int)pavg1;
partsData[partsDataLen++] = ((int)pavg1)>>8;
break;
}
} }
//Write the field descriptor //Write the field descriptor
@ -2855,6 +2820,11 @@ bool GameSave::TypeInTmp2(int type, int tmp2)
return (type == PT_VIRS || type == PT_VRSG || type == PT_VRSS) && (tmp2 >= 0 && tmp2 < PT_NUM); return (type == PT_VIRS || type == PT_VRSG || type == PT_VRSS) && (tmp2 >= 0 && tmp2 < PT_NUM);
} }
bool GameSave::PressureInTmp3(int type)
{
return type == PT_QRTZ || type == PT_GLAS || type == PT_TUNG;
}
void GameSave::dealloc() void GameSave::dealloc()
{ {
if (particles) if (particles)

View File

@ -133,6 +133,7 @@ public:
static bool TypeInCtype(int type, int ctype); static bool TypeInCtype(int type, int ctype);
static bool TypeInTmp(int type); static bool TypeInTmp(int type);
static bool TypeInTmp2(int type, int tmp2); static bool TypeInTmp2(int type, int tmp2);
static bool PressureInTmp3(int type);
GameSave& operator << (Particle &v); GameSave& operator << (Particle &v);
GameSave& operator << (sign &v); GameSave& operator << (sign &v);

View File

@ -783,9 +783,9 @@ void GameController::ResetAir()
sim->air->Clear(); sim->air->Clear();
for (int i = 0; i < NPART; i++) for (int i = 0; i < NPART; i++)
{ {
if (sim->parts[i].type == PT_QRTZ || sim->parts[i].type == PT_GLAS || sim->parts[i].type == PT_TUNG) if (GameSave::PressureInTmp3(sim->parts[i].type))
{ {
sim->parts[i].pavg[0] = sim->parts[i].pavg[1] = 0; sim->parts[i].tmp3 = 0;
} }
} }
} }

View File

@ -2149,13 +2149,13 @@ void GameView::OnDraw()
} }
else if ((type == PT_PIPE || type == PT_PPIP) && c->IsValidElement(ctype)) else if ((type == PT_PIPE || type == PT_PPIP) && c->IsValidElement(ctype))
{ {
if (ctype == PT_LAVA && c->IsValidElement((int)sample.particle.pavg[1])) if (ctype == PT_LAVA && c->IsValidElement(sample.particle.tmp4))
{ {
sampleInfo << c->ElementResolve(type, 0) << " with molten " << c->ElementResolve((int)sample.particle.pavg[1], -1); sampleInfo << c->ElementResolve(type, 0) << " with molten " << c->ElementResolve(sample.particle.tmp4, -1);
} }
else else
{ {
sampleInfo << c->ElementResolve(type, 0) << " with " << c->ElementResolve(ctype, (int)sample.particle.pavg[1]); sampleInfo << c->ElementResolve(type, 0) << " with " << c->ElementResolve(ctype, sample.particle.tmp4);
} }
} }
else if (type == PT_LIFE) else if (type == PT_LIFE)

View File

@ -94,15 +94,15 @@ int CommandInterface::GetPropertyOffset(ByteString key, FormatType & format)
offset = offsetof(Particle, dcolour); offset = offsetof(Particle, dcolour);
format = FormatInt; format = FormatInt;
} }
else if (!key.compare("pavg0")) else if (!key.compare("tmp3"))
{ {
offset = offsetof(Particle, pavg[0]); offset = offsetof(Particle, tmp3);
format = FormatFloat; format = FormatInt;
} }
else if (!key.compare("pavg1")) else if (!key.compare("tmp4"))
{ {
offset = offsetof(Particle, pavg[1]); offset = offsetof(Particle, tmp4);
format = FormatFloat; format = FormatInt;
} }
return offset; return offset;
} }

View File

@ -265,7 +265,7 @@ LuaScriptInterface::LuaScriptInterface(GameController * c, GameModel * m):
luaL_dostring (l, "ffi = require(\"ffi\")\n\ luaL_dostring (l, "ffi = require(\"ffi\")\n\
ffi.cdef[[\n\ ffi.cdef[[\n\
typedef struct { int type; int life, ctype; float x, y, vx, vy; float temp; float pavg[2]; int flags; int tmp; int tmp2; unsigned int dcolour; } particle;\n\ typedef struct { int type; int life, ctype; float x, y, vx, vy; float temp; int tmp3; int tmp4; int flags; int tmp; int tmp2; unsigned int dcolour; } particle;\n\
]]\n\ ]]\n\
tpt.parts = ffi.cast(\"particle *\", tpt.partsdata)\n\ tpt.parts = ffi.cast(\"particle *\", tpt.partsdata)\n\
ffi = nil\n\ ffi = nil\n\

View File

@ -15,9 +15,9 @@ std::vector<StructProperty> const &Particle::GetProperties()
{ "flags" , StructProperty::UInteger , (intptr_t)(offsetof(Particle, flags )) }, { "flags" , StructProperty::UInteger , (intptr_t)(offsetof(Particle, flags )) },
{ "tmp" , StructProperty::Integer , (intptr_t)(offsetof(Particle, tmp )) }, { "tmp" , StructProperty::Integer , (intptr_t)(offsetof(Particle, tmp )) },
{ "tmp2" , StructProperty::Integer , (intptr_t)(offsetof(Particle, tmp2 )) }, { "tmp2" , StructProperty::Integer , (intptr_t)(offsetof(Particle, tmp2 )) },
{ "tmp3" , StructProperty::Integer , (intptr_t)(offsetof(Particle, tmp3 )) },
{ "tmp4" , StructProperty::Integer , (intptr_t)(offsetof(Particle, tmp4 )) },
{ "dcolour", StructProperty::UInteger , (intptr_t)(offsetof(Particle, dcolour)) }, { "dcolour", StructProperty::UInteger , (intptr_t)(offsetof(Particle, dcolour)) },
{ "pavg0" , StructProperty::Float , (intptr_t)(offsetof(Particle, pavg[0])) },
{ "pavg1" , StructProperty::Float , (intptr_t)(offsetof(Particle, pavg[1])) },
}; };
return properties; return properties;
} }

View File

@ -11,7 +11,8 @@ struct Particle
int life, ctype; int life, ctype;
float x, y, vx, vy; float x, y, vx, vy;
float temp; float temp;
float pavg[2]; int tmp3;
int tmp4;
int flags; int flags;
int tmp; int tmp;
int tmp2; int tmp2;

View File

@ -306,19 +306,10 @@ int Simulation::Load(const GameSave * originalSave, bool includePressure, int fu
case PT_SOAP: case PT_SOAP:
soapList.insert(std::pair<unsigned int, unsigned int>(n, i)); soapList.insert(std::pair<unsigned int, unsigned int>(n, i));
break; break;
}
// List of elements that load pavg with a multiplicative bias of 2**6 if (GameSave::PressureInTmp3(parts[i].type) && !includePressure)
// (or not at all if pressure is not loaded). {
// If you change this list, change it in GameSave::serialiseOPS and GameSave::readOPS too! parts[i].tmp3 = 0;
case PT_QRTZ:
case PT_GLAS:
case PT_TUNG:
if (!includePressure)
{
parts[i].pavg[0] = 0;
parts[i].pavg[1] = 0;
}
break;
} }
} }
parts_lastActiveIndex = NPART-1; parts_lastActiveIndex = NPART-1;
@ -3375,7 +3366,8 @@ void Simulation::create_gain_photon(int pp)//photons from PHOT going through GLO
parts[i].vy = parts[pp].vy; parts[i].vy = parts[pp].vy;
parts[i].temp = parts[ID(pmap[ny][nx])].temp; parts[i].temp = parts[ID(pmap[ny][nx])].temp;
parts[i].tmp = 0; parts[i].tmp = 0;
parts[i].pavg[0] = parts[i].pavg[1] = 0.0f; parts[i].tmp3 = 0;
parts[i].tmp4 = 0;
photons[ny][nx] = PMAP(i, PT_PHOT); photons[ny][nx] = PMAP(i, PT_PHOT);
temp_bin = (int)((parts[i].temp-273.0f)*0.25f); temp_bin = (int)((parts[i].temp-273.0f)*0.25f);
@ -3413,7 +3405,8 @@ void Simulation::create_cherenkov_photon(int pp)//photons from NEUT going throug
parts[i].y = parts[pp].y; parts[i].y = parts[pp].y;
parts[i].temp = parts[ID(pmap[ny][nx])].temp; parts[i].temp = parts[ID(pmap[ny][nx])].temp;
parts[i].tmp = 0; parts[i].tmp = 0;
parts[i].pavg[0] = parts[i].pavg[1] = 0.0f; parts[i].tmp3 = 0;
parts[i].tmp4 = 0;
photons[ny][nx] = PMAP(i, PT_PHOT); photons[ny][nx] = PMAP(i, PT_PHOT);
if (lr) { if (lr) {
@ -4364,8 +4357,8 @@ killed:
parts[ID(r)].ctype = parts[i].type; parts[ID(r)].ctype = parts[i].type;
parts[ID(r)].temp = parts[i].temp; parts[ID(r)].temp = parts[i].temp;
parts[ID(r)].tmp2 = parts[i].life; parts[ID(r)].tmp2 = parts[i].life;
parts[ID(r)].pavg[0] = float(parts[i].tmp); parts[ID(r)].tmp3 = parts[i].tmp;
parts[ID(r)].pavg[1] = float(parts[i].ctype); parts[ID(r)].tmp4 = parts[i].ctype;
kill_part(i); kill_part(i);
continue; continue;
} }
@ -5382,20 +5375,20 @@ String Simulation::BasicParticleInfo(Particle const &sample_part) const
StringBuilder sampleInfo; StringBuilder sampleInfo;
int type = sample_part.type; int type = sample_part.type;
int ctype = sample_part.ctype; int ctype = sample_part.ctype;
int pavg1int = (int)sample_part.pavg[1]; int storedCtype = sample_part.tmp4;
if (type == PT_LAVA && IsElement(ctype)) if (type == PT_LAVA && IsElement(ctype))
{ {
sampleInfo << "Molten " << ElementResolve(ctype, -1); sampleInfo << "Molten " << ElementResolve(ctype, -1);
} }
else if ((type == PT_PIPE || type == PT_PPIP) && IsElement(ctype)) else if ((type == PT_PIPE || type == PT_PPIP) && IsElement(ctype))
{ {
if (ctype == PT_LAVA && IsElement(pavg1int)) if (ctype == PT_LAVA && IsElement(storedCtype))
{ {
sampleInfo << ElementResolve(type, -1) << " with molten " << ElementResolve(pavg1int, -1); sampleInfo << ElementResolve(type, -1) << " with molten " << ElementResolve(storedCtype, -1);
} }
else else
{ {
sampleInfo << ElementResolve(type, -1) << " with " << ElementResolve(ctype, pavg1int); sampleInfo << ElementResolve(type, -1) << " with " << ElementResolve(ctype, storedCtype);
} }
} }
else else

View File

@ -150,8 +150,8 @@ static int update(UPDATE_FUNC_ARGS)
{ {
parts[np].temp = parts[r].temp; parts[np].temp = parts[r].temp;
parts[np].life = parts[r].tmp2; parts[np].life = parts[r].tmp2;
parts[np].tmp = int(parts[r].pavg[0]); parts[np].tmp = parts[r].tmp3;
parts[np].ctype = int(parts[r].pavg[1]); parts[np].ctype = parts[r].tmp4;
parts[r].tmp = 0; parts[r].tmp = 0;
parts[r].life = 10; parts[r].life = 10;
break; break;

View File

@ -49,17 +49,17 @@ void Element::Element_GLAS()
static int update(UPDATE_FUNC_ARGS) static int update(UPDATE_FUNC_ARGS)
{ {
parts[i].pavg[0] = parts[i].pavg[1]; auto press = sim->pv[y/CELL][x/CELL] * 64;
parts[i].pavg[1] = sim->pv[y/CELL][x/CELL]; float diff = press - parts[i].tmp3;
float diff = parts[i].pavg[1] - parts[i].pavg[0]; if (diff > 16 || diff < -16)
if (diff > 0.25f || diff < -0.25f)
{ {
sim->part_change_type(i,x,y,PT_BGLA); sim->part_change_type(i,x,y,PT_BGLA);
} }
parts[i].tmp3 = press;
return 0; return 0;
} }
static void create(ELEMENT_CREATE_FUNC_ARGS) static void create(ELEMENT_CREATE_FUNC_ARGS)
{ {
sim->parts[i].pavg[1] = sim->pv[y/CELL][x/CELL]; sim->parts[i].tmp3 = sim->pv[y/CELL][x/CELL] * 64;
} }

View File

@ -355,10 +355,8 @@ int Element_PIPE_graphics(GRAPHICS_FUNC_ARGS)
tpart.type = t; tpart.type = t;
tpart.temp = cpart->temp; tpart.temp = cpart->temp;
tpart.life = cpart->tmp2; tpart.life = cpart->tmp2;
tpart.tmp = int(cpart->pavg[0]); tpart.tmp = cpart->tmp3;
tpart.ctype = int(cpart->pavg[1]); tpart.ctype = cpart->tmp4;
if (t == PT_PHOT && tpart.ctype == 0x40000000)
tpart.ctype = 0x3FFFFFFF;
*colr = PIXR(ren->sim->elements[t].Colour); *colr = PIXR(ren->sim->elements[t].Colour);
*colg = PIXG(ren->sim->elements[t].Colour); *colg = PIXG(ren->sim->elements[t].Colour);
@ -418,16 +416,14 @@ void Element_PIPE_transfer_pipe_to_part(Simulation * sim, Particle *pipe, Partic
} }
part->temp = pipe->temp; part->temp = pipe->temp;
part->life = pipe->tmp2; part->life = pipe->tmp2;
part->tmp = int(pipe->pavg[0]); part->tmp = pipe->tmp3;
part->ctype = int(pipe->pavg[1]); part->ctype = pipe->tmp4;
if (!(sim->elements[part->type].Properties & TYPE_ENERGY)) if (!(sim->elements[part->type].Properties & TYPE_ENERGY))
{ {
part->vx = 0.0f; part->vx = 0.0f;
part->vy = 0.0f; part->vy = 0.0f;
} }
else if (part->type == PT_PHOT && part->ctype == 0x40000000)
part->ctype = 0x3FFFFFFF;
part->tmp2 = 0; part->tmp2 = 0;
part->flags = 0; part->flags = 0;
part->dcolour = 0; part->dcolour = 0;
@ -438,8 +434,8 @@ static void transfer_part_to_pipe(Particle *part, Particle *pipe)
pipe->ctype = part->type; pipe->ctype = part->type;
pipe->temp = part->temp; pipe->temp = part->temp;
pipe->tmp2 = part->life; pipe->tmp2 = part->life;
pipe->pavg[0] = float(part->tmp); pipe->tmp3 = part->tmp;
pipe->pavg[1] = float(part->ctype); pipe->tmp4 = part->ctype;
} }
static void transfer_pipe_to_pipe(Particle *src, Particle *dest, bool STOR) static void transfer_pipe_to_pipe(Particle *src, Particle *dest, bool STOR)
@ -457,8 +453,8 @@ static void transfer_pipe_to_pipe(Particle *src, Particle *dest, bool STOR)
} }
dest->temp = src->temp; dest->temp = src->temp;
dest->tmp2 = src->tmp2; dest->tmp2 = src->tmp2;
dest->pavg[0] = src->pavg[0]; dest->tmp3 = src->tmp3;
dest->pavg[1] = src->pavg[1]; dest->tmp4 = src->tmp4;
} }
static void pushParticle(Simulation * sim, int i, int count, int original) static void pushParticle(Simulation * sim, int i, int count, int original)

View File

@ -54,13 +54,14 @@ int Element_QRTZ_update(UPDATE_FUNC_ARGS)
int r, tmp, trade, rx, ry, np, t = parts[i].type; int r, tmp, trade, rx, ry, np, t = parts[i].type;
if (t == PT_QRTZ) if (t == PT_QRTZ)
{ {
parts[i].pavg[0] = parts[i].pavg[1]; auto press = sim->pv[y/CELL][x/CELL] * 64;
parts[i].pavg[1] = sim->pv[y/CELL][x/CELL]; auto diffTolerance = parts[i].temp * 1.0666f;
if (parts[i].pavg[1]-parts[i].pavg[0] > 0.05*(parts[i].temp/3) || parts[i].pavg[1]-parts[i].pavg[0] < -0.05*(parts[i].temp/3)) if (press - parts[i].tmp3 > diffTolerance || press - parts[i].tmp3 < -diffTolerance)
{ {
sim->part_change_type(i,x,y,PT_PQRT); sim->part_change_type(i,x,y,PT_PQRT);
parts[i].life = 5; //timer before it can grow or diffuse again parts[i].life = 5; //timer before it can grow or diffuse again
} }
parts[i].tmp3 = press;
} }
if (parts[i].life>5) if (parts[i].life>5)
parts[i].life = 5; parts[i].life = 5;
@ -160,5 +161,5 @@ int Element_QRTZ_graphics(GRAPHICS_FUNC_ARGS)
static void create(ELEMENT_CREATE_FUNC_ARGS) static void create(ELEMENT_CREATE_FUNC_ARGS)
{ {
sim->parts[i].tmp2 = RNG::Ref().between(0, 10); sim->parts[i].tmp2 = RNG::Ref().between(0, 10);
sim->parts[i].pavg[1] = sim->pv[y/CELL][x/CELL]; sim->parts[i].tmp3 = sim->pv[y/CELL][x/CELL] * 64;
} }

View File

@ -71,8 +71,8 @@ static int update(UPDATE_FUNC_ARGS)
parts[i].tmp = parts[ID(r)].type; parts[i].tmp = parts[ID(r)].type;
parts[i].temp = parts[ID(r)].temp; parts[i].temp = parts[ID(r)].temp;
parts[i].tmp2 = parts[ID(r)].life; parts[i].tmp2 = parts[ID(r)].life;
parts[i].pavg[0] = float(parts[ID(r)].tmp); parts[i].tmp3 = parts[ID(r)].tmp;
parts[i].pavg[1] = float(parts[ID(r)].ctype); parts[i].tmp4 = parts[ID(r)].ctype;
sim->kill_part(ID(r)); sim->kill_part(ID(r));
} }
if(parts[i].tmp && TYP(r)==PT_SPRK && parts[ID(r)].ctype==PT_PSCN && parts[ID(r)].life>0 && parts[ID(r)].life<4) if(parts[i].tmp && TYP(r)==PT_SPRK && parts[ID(r)].ctype==PT_PSCN && parts[ID(r)].life>0 && parts[ID(r)].life<4)
@ -84,8 +84,8 @@ static int update(UPDATE_FUNC_ARGS)
{ {
parts[np].temp = parts[i].temp; parts[np].temp = parts[i].temp;
parts[np].life = parts[i].tmp2; parts[np].life = parts[i].tmp2;
parts[np].tmp = int(parts[i].pavg[0]); parts[np].tmp = parts[i].tmp3;
parts[np].ctype = int(parts[i].pavg[1]); parts[np].ctype = parts[i].tmp4;
parts[i].tmp = 0; parts[i].tmp = 0;
parts[i].life = 10; parts[i].life = 10;
break; break;

View File

@ -3,6 +3,7 @@
static int update(UPDATE_FUNC_ARGS); static int update(UPDATE_FUNC_ARGS);
static int graphics(GRAPHICS_FUNC_ARGS); static int graphics(GRAPHICS_FUNC_ARGS);
static void create(ELEMENT_CREATE_FUNC_ARGS);
void Element::Element_TUNG() void Element::Element_TUNG()
{ {
@ -46,6 +47,7 @@ void Element::Element_TUNG()
Update = &update; Update = &update;
Graphics = &graphics; Graphics = &graphics;
Create = &create;
} }
static int update(UPDATE_FUNC_ARGS) static int update(UPDATE_FUNC_ARGS)
@ -93,15 +95,15 @@ static int update(UPDATE_FUNC_ARGS)
parts[i].vy += RNG::Ref().between(-50, 50); parts[i].vy += RNG::Ref().between(-50, 50);
return 1; return 1;
} }
parts[i].pavg[0] = parts[i].pavg[1]; auto press = sim->pv[y/CELL][x/CELL] * 64;
parts[i].pavg[1] = sim->pv[y/CELL][x/CELL]; float diff = press - parts[i].tmp3;
float diff = parts[i].pavg[1] - parts[i].pavg[0]; if (diff > 32 || diff < -32)
if (diff > 0.50f || diff < -0.50f)
{ {
sim->part_change_type(i,x,y,PT_BRMT); sim->part_change_type(i,x,y,PT_BRMT);
parts[i].ctype = PT_TUNG; parts[i].ctype = PT_TUNG;
return 1; return 1;
} }
parts[i].tmp3 = press;
return 0; return 0;
} }
@ -127,3 +129,8 @@ static int graphics(GRAPHICS_FUNC_ARGS)
} }
return 0; return 0;
} }
static void create(ELEMENT_CREATE_FUNC_ARGS)
{
sim->parts[i].tmp3 = sim->pv[y/CELL][x/CELL] * 64;
}

View File

@ -44,7 +44,7 @@ void Element::Element_VIRS()
HighTemperature = 673.0f; HighTemperature = 673.0f;
HighTemperatureTransition = PT_VRSG; HighTemperatureTransition = PT_VRSG;
DefaultProperties.pavg[1] = 250; DefaultProperties.tmp4 = 250;
Update = &Element_VIRS_update; Update = &Element_VIRS_update;
Graphics = &graphics; Graphics = &graphics;
@ -52,27 +52,27 @@ void Element::Element_VIRS()
int Element_VIRS_update(UPDATE_FUNC_ARGS) int Element_VIRS_update(UPDATE_FUNC_ARGS)
{ {
//pavg[0] measures how many frames until it is cured (0 if still actively spreading and not being cured) //tmp3 measures how many frames until it is cured (0 if still actively spreading and not being cured)
//pavg[1] measures how many frames until it dies //tmp4 measures how many frames until it dies
int r, rx, ry, rndstore = RNG::Ref().gen(); int r, rx, ry, rndstore = RNG::Ref().gen();
if (parts[i].pavg[0]) if (parts[i].tmp3)
{ {
parts[i].pavg[0] -= (rndstore & 0x1) ? 0:1; parts[i].tmp3 -= (rndstore & 0x1) ? 0:1;
//has been cured, so change back into the original element //has been cured, so change back into the original element
if (!parts[i].pavg[0]) if (!parts[i].tmp3)
{ {
sim->part_change_type(i,x,y,parts[i].tmp2); sim->part_change_type(i,x,y,parts[i].tmp2);
parts[i].tmp2 = 0; parts[i].tmp2 = 0;
parts[i].pavg[0] = 0; parts[i].tmp3 = 0;
parts[i].pavg[1] = 0; parts[i].tmp4 = 0;
} }
return 0; return 0;
//cured virus is never in below code //cured virus is never in below code
} }
//decrease pavg[1] so it slowly dies //decrease tmp4 so it slowly dies
if (parts[i].pavg[1]) if (parts[i].tmp4)
{ {
if (!(rndstore & 0x7) && --parts[i].pavg[1] <= 0) if (!(rndstore & 0x7) && --parts[i].tmp4 <= 0)
{ {
sim->kill_part(i); sim->kill_part(i);
return 1; return 1;
@ -90,15 +90,15 @@ int Element_VIRS_update(UPDATE_FUNC_ARGS)
continue; continue;
//spread "being cured" state //spread "being cured" state
if (parts[ID(r)].pavg[0] && (TYP(r) == PT_VIRS || TYP(r) == PT_VRSS || TYP(r) == PT_VRSG)) if (parts[ID(r)].tmp3 && (TYP(r) == PT_VIRS || TYP(r) == PT_VRSS || TYP(r) == PT_VRSG))
{ {
parts[i].pavg[0] = parts[ID(r)].pavg[0] + ((rndstore & 0x3) ? 2:1); parts[i].tmp3 = parts[ID(r)].tmp3 + ((rndstore & 0x3) ? 2:1);
return 0; return 0;
} }
//soap cures virus //soap cures virus
else if (TYP(r) == PT_SOAP) else if (TYP(r) == PT_SOAP)
{ {
parts[i].pavg[0] += 10; parts[i].tmp3 += 10;
if (!(rndstore & 0x3)) if (!(rndstore & 0x3))
sim->kill_part(ID(r)); sim->kill_part(ID(r));
return 0; return 0;
@ -117,11 +117,11 @@ int Element_VIRS_update(UPDATE_FUNC_ARGS)
if (!(rndstore & 0x7)) if (!(rndstore & 0x7))
{ {
parts[ID(r)].tmp2 = TYP(r); parts[ID(r)].tmp2 = TYP(r);
parts[ID(r)].pavg[0] = 0; parts[ID(r)].tmp3 = 0;
if (parts[i].pavg[1]) if (parts[i].tmp4)
parts[ID(r)].pavg[1] = parts[i].pavg[1] + 1; parts[ID(r)].tmp4 = parts[i].tmp4 + 1;
else else
parts[ID(r)].pavg[1] = 0; parts[ID(r)].tmp4 = 0;
if (parts[ID(r)].temp < 305.0f) if (parts[ID(r)].temp < 305.0f)
sim->part_change_type(ID(r), x+rx, y+ry, PT_VRSS); sim->part_change_type(ID(r), x+rx, y+ry, PT_VRSS);
else if (parts[ID(r)].temp > 673.0f) else if (parts[ID(r)].temp > 673.0f)
@ -134,7 +134,7 @@ int Element_VIRS_update(UPDATE_FUNC_ARGS)
//protons make VIRS last forever //protons make VIRS last forever
else if (TYP(sim->photons[y+ry][x+rx]) == PT_PROT) else if (TYP(sim->photons[y+ry][x+rx]) == PT_PROT)
{ {
parts[i].pavg[1] = 0; parts[i].tmp4 = 0;
} }
} }
//reset rndstore only once, halfway through //reset rndstore only once, halfway through

View File

@ -44,7 +44,7 @@ void Element::Element_VRSG()
HighTemperature = ITH; HighTemperature = ITH;
HighTemperatureTransition = NT; HighTemperatureTransition = NT;
DefaultProperties.pavg[1] = 250; DefaultProperties.tmp4 = 250;
Update = &Element_VIRS_update; Update = &Element_VIRS_update;
Graphics = &graphics; Graphics = &graphics;

View File

@ -44,7 +44,7 @@ void Element::Element_VRSS()
HighTemperature = 305.0f; HighTemperature = 305.0f;
HighTemperatureTransition = PT_VIRS; HighTemperatureTransition = PT_VIRS;
DefaultProperties.pavg[1] = 250; DefaultProperties.tmp4 = 250;
Update = &Element_VIRS_update; Update = &Element_VIRS_update;
Graphics = &graphics; Graphics = &graphics;