From da4fe72154d5c8079b9c030fa1ac43003dfaca14 Mon Sep 17 00:00:00 2001 From: Saveliy Skresanov Date: Wed, 26 Feb 2025 23:01:35 +0700 Subject: [PATCH] Added BASE element. --- src/simulation/elements/BASE.cpp | 230 ++++++++++++++++++++++++++++ src/simulation/elements/DSTW.cpp | 12 ++ src/simulation/elements/NEUT.cpp | 4 + src/simulation/elements/VIRS.cpp | 2 +- src/simulation/elements/meson.build | 3 +- 5 files changed, 249 insertions(+), 2 deletions(-) create mode 100644 src/simulation/elements/BASE.cpp diff --git a/src/simulation/elements/BASE.cpp b/src/simulation/elements/BASE.cpp new file mode 100644 index 000000000..b98dd7afa --- /dev/null +++ b/src/simulation/elements/BASE.cpp @@ -0,0 +1,230 @@ +#include "simulation/ElementCommon.h" + +static int update(UPDATE_FUNC_ARGS); +static int graphics(GRAPHICS_FUNC_ARGS); + +void Element::Element_BASE() +{ + Identifier = "DEFAULT_PT_BASE"; + Name = "BASE"; + Colour = 0x90D5FF_rgb; + MenuVisible = 1; + MenuSection = SC_LIQUID; + Enabled = 1; + + Advection = 0.5f; + AirDrag = 0.01f * CFDS; + AirLoss = 0.97f; + Loss = 0.96f; + Collision = 0.0f; + Gravity = 0.08f; + Diffusion = 0.00f; + HotAir = 0.000f * CFDS; + Falldown = 2; + + Flammable = 0; + Explosive = 0; + Meltable = 0; + Hardness = 0; + + Weight = 16; + + HeatConduct = 31; + Description = "Corrosive liquid. Rusts conductive solids, neutralizes acid."; + + Properties = TYPE_LIQUID|PROP_DEADLY; + + LowPressure = IPL; + LowPressureTransition = NT; + HighPressure = IPH; + HighPressureTransition = NT; + LowTemperature = ITL; + LowTemperatureTransition = NT; + HighTemperature = ITH; + HighTemperatureTransition = NT; + + DefaultProperties.life = 75; + + Update = &update; + Graphics = &graphics; +} + +static int update(UPDATE_FUNC_ARGS) +{ + auto &sd = SimulationData::CRef(); + auto &elements = sd.elements; + + //Reset spark effect + parts[i].tmp = 0; + + if (parts[i].life < 1) + parts[i].life = 1; + + if (parts[i].life > 100) + parts[i].life = 100; + + float pres = sim->pv[y/CELL][x/CELL]; + + //Base evaporates into BOYL or increases concentration + if (parts[i].life < 100 && pres < 10.0f && parts[i].temp > (120.0f + 273.15f)) + { + if (sim->rng.chance(parts[i].life+900, 1000)) + parts[i].life++; + else + { + sim->create_part(i, x, y, PT_BOYL); + return 1; + } + } + + //Base's freezing point lowers with its concentration + if (parts[i].temp < (273.15f - ((float)parts[i].life)/4.0f)) + { + //We don't save base's concentration, so ICEI(BASE) will unfreeze into life = 0 + sim->part_change_type(i, x, y, PT_ICEI); + parts[i].ctype = PT_BASE; + parts[i].life = 0; + return 1; + } + + //Reactions + for (auto rx = -1; rx <= 1; rx++) + { + for (auto ry = -1; ry <= 1; ry++) + { + if (rx || ry) + { + auto r = pmap[y+ry][x+rx]; + if (!r) + continue; + int rt = TYP(r); + + if (rt != PT_BASE && rt != PT_SALT && rt != PT_SLTW && rt != PT_BOYL && rt != PT_MERC && + rt != PT_BMTL && rt != PT_BRMT && rt != PT_SOAP && rt != PT_CLNE && rt != PT_PCLN) + { + //Base is diluted by water + if (parts[i].life > 1 && (rt == PT_WATR || rt == PT_DSTW || rt == PT_CBNW)) + { + if (sim->rng.chance(1, 20)) + { + int saturh = parts[i].life/2; + + sim->part_change_type(ID(r), x+rx, y+ry, PT_BASE); + parts[ID(r)].life = saturh; + parts[ID(r)].temp += ((float)saturh)/10.0f; + parts[i].life -= saturh; + } + } //Base neutralizes acid + else if (rt == PT_ACID && parts[i].life >= parts[ID(r)].life) + { + sim->part_change_type(i, x, y, PT_SLTW); + sim->part_change_type(ID(r), x+rx, y+ry, PT_SLTW); + return 1; + } //BASE + OIL = SOAP + else if (parts[i].life >= 70 && rt == PT_OIL) + { + sim->part_change_type(i, x, y, PT_SOAP); + parts[i].tmp = parts[i].tmp2 = parts[i].ctype = 0; + sim->kill_part(ID(r)); + return 1; + } //BASE + GOO = GEL + else if (parts[i].life > 1 && rt == PT_GOO) + { + sim->create_part(ID(r), x+rx, y+ry, PT_GEL); + parts[i].life--; + } //BASE + BCOL = GUNP + else if (parts[i].life > 1 && rt == PT_BCOL) + { + sim->create_part(ID(r), x+rx, y+ry, PT_GUNP); + parts[i].life--; + } //BASE + Molten ROCK = MERC + else if (rt == PT_LAVA && parts[ID(r)].ctype == PT_ROCK && pres >= 10.0f && sim->rng.chance(1, 1000)) + { + sim->part_change_type(i, x, y, PT_MERC); + parts[i].life = 0; + parts[i].tmp = 10; + + sim->kill_part(ID(r)); + return 1; + } //Base rusts conductive solids + else if (parts[i].life >= 10 && + (elements[rt].Properties & (TYPE_SOLID|PROP_CONDUCTS)) == (TYPE_SOLID|PROP_CONDUCTS) && sim->rng.chance(1, 10)) + { + sim->part_change_type(ID(r), x+rx, y+ry, PT_BMTL); + parts[ID(r)].tmp = sim->rng.between(20, 29); + parts[i].life--; + //Draw a spark effect + parts[i].tmp = 1; + } //Base destroys a substance slower if acid destroys it faster + else if (elements[rt].Hardness > 0 && elements[rt].Hardness < 50 && + parts[i].life >= (2*elements[rt].Hardness) && sim->rng.chance(50-elements[rt].Hardness, 1000)) + { + sim->kill_part(ID(r)); + parts[i].life -= 2; + //Draw a spark + parts[i].tmp = 1; + } + } + } + } + } + + //Diffusion + for (auto trade = 0; trade<2; trade++) + { + auto rx = sim->rng.between(-1, 1); + auto ry = sim->rng.between(-1, 1); + if (rx || ry) + { + auto r = pmap[y+ry][x+rx]; + if (!r) + continue; + if (TYP(r) == PT_BASE && (parts[i].life > parts[ID(r)].life) && parts[i].life>1) + { + int temp = parts[i].life - parts[ID(r)].life; + if (temp == 1) + { + parts[ID(r)].life++; + parts[i].life--; + } + else if (temp>0) + { + parts[ID(r)].life += temp/2; + parts[i].life -= temp/2; + } + } + } + } + return 0; +} + +static int graphics(GRAPHICS_FUNC_ARGS) +{ + int s = cpart->life; + + if (s < 25) + { + *colr = 0x33; + *colg = 0x4C; + *colb = 0xD8; + } + else if (s < 50) + { + *colr = 0x58; + *colg = 0x83; + *colb = 0xE8; + } + else if (s < 75) + { + *colr = 0x7D; + *colg = 0xBA; + *colb = 0xF7; + } + + *pixel_mode |= PMODE_BLUR; + + if (cpart->tmp == 1) + *pixel_mode |= PMODE_SPARK; + + return 0; +} diff --git a/src/simulation/elements/DSTW.cpp b/src/simulation/elements/DSTW.cpp index 7d04bc3df..d0ca09c3e 100644 --- a/src/simulation/elements/DSTW.cpp +++ b/src/simulation/elements/DSTW.cpp @@ -95,6 +95,18 @@ static int update(UPDATE_FUNC_ARGS) return 1; } break; + case PT_SMKE: //DSTW + SMKE = BASE + if (parts[ID(r)].temp > (40 + 273.15f) && parts[ID(r)].temp < (60 + 273.15f) && + parts[i].temp > (40 + 273.15f) && parts[i].temp < (60 + 273.15f)) + { + if (sim->rng.chance(1, 100)) + { + sim->part_change_type(i,x,y,PT_BASE); + parts[i].life = 1; + sim->kill_part(ID(r)); + } + } + break; default: continue; } diff --git a/src/simulation/elements/NEUT.cpp b/src/simulation/elements/NEUT.cpp index 1e317961c..d6c08a429 100644 --- a/src/simulation/elements/NEUT.cpp +++ b/src/simulation/elements/NEUT.cpp @@ -191,6 +191,10 @@ static int update(UPDATE_FUNC_ARGS) return 1; } break; + case PT_BASE: + if (parts[ID(r)].temp > (50 + 273.15) && sim->rng.chance(1, 35)) + sim->create_part(ID(r), x+rx, y+ry, PT_LRBD); + break; default: break; } diff --git a/src/simulation/elements/VIRS.cpp b/src/simulation/elements/VIRS.cpp index 3940b77bd..4f2674140 100644 --- a/src/simulation/elements/VIRS.cpp +++ b/src/simulation/elements/VIRS.cpp @@ -114,7 +114,7 @@ int Element_VIRS_update(UPDATE_FUNC_ARGS) } } //transforms things into virus here - else if (TYP(r) != PT_VIRS && TYP(r) != PT_VRSS && TYP(r) != PT_VRSG && TYP(r) != PT_DMND) + else if (TYP(r) != PT_VIRS && TYP(r) != PT_VRSS && TYP(r) != PT_VRSG && TYP(r) != PT_DMND && TYP(r) != PT_BASE) { if (!(rndstore & 0x7)) { diff --git a/src/simulation/elements/meson.build b/src/simulation/elements/meson.build index 4f1dc9c64..ac6459d58 100644 --- a/src/simulation/elements/meson.build +++ b/src/simulation/elements/meson.build @@ -192,7 +192,8 @@ simulation_elem_names = [ 'ROCK', 'LITH', 'RSST', - 'RSSS' + 'RSSS', + 'BASE', ] simulation_elem_src = []