From 9413a1f0b68544f1df229dc30a17fb335cba649d Mon Sep 17 00:00:00 2001 From: moonheart08 Date: Sun, 26 Jul 2020 04:45:50 -0500 Subject: [PATCH] Introduce element 187, SLCN. (#704) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add SLCN Co-authored-by: moonheart08 Co-authored-by: Tamás Bálint Misius --- src/simulation/ElementNumbers.h | 1 + src/simulation/elements/FIRE.cpp | 41 ++++++++- src/simulation/elements/SLCN.cpp | 141 +++++++++++++++++++++++++++++++ 3 files changed, 181 insertions(+), 2 deletions(-) create mode 100644 src/simulation/elements/SLCN.cpp diff --git a/src/simulation/ElementNumbers.h b/src/simulation/ElementNumbers.h index 5fe343a5d..7fa29efa5 100644 --- a/src/simulation/ElementNumbers.h +++ b/src/simulation/ElementNumbers.h @@ -195,5 +195,6 @@ ELEMENT_DEFINE(RFRG, 183); ELEMENT_DEFINE(RFGL, 184); ELEMENT_DEFINE(LSNS, 185); ELEMENT_DEFINE(LDTC, 186); +ELEMENT_DEFINE(SLCN, 187); #undef ELEMENT_DEFINE diff --git a/src/simulation/elements/FIRE.cpp b/src/simulation/elements/FIRE.cpp index 3e0dd50cb..b766f077f 100644 --- a/src/simulation/elements/FIRE.cpp +++ b/src/simulation/elements/FIRE.cpp @@ -121,17 +121,25 @@ int Element_FIRE_update(UPDATE_FUNC_ARGS) { if ((t==PT_FIRE || t==PT_PLSM)) { - if (parts[ID(r)].life>100 && RNG::Ref().chance(1, 500)) { + if (parts[ID(r)].life>100 && RNG::Ref().chance(1, 500)) + { parts[ID(r)].life = 99; } } else if (t==PT_LAVA) { - if (parts[i].ctype == PT_IRON && RNG::Ref().chance(1, 500)) { + if (parts[i].ctype == PT_IRON && RNG::Ref().chance(1, 500)) + { parts[i].ctype = PT_METL; sim->kill_part(ID(r)); continue; } + if ((parts[i].ctype == PT_STNE || parts[i].ctype == PT_NONE) && RNG::Ref().chance(1, 60)) + { + parts[i].ctype = PT_SLCN; + sim->kill_part(ID(r)); + continue; + } } } @@ -147,6 +155,35 @@ int Element_FIRE_update(UPDATE_FUNC_ARGS) parts[ID(r)].ctype = PT_CRMC; } } + else if (rt == PT_O2 && parts[i].ctype == PT_SLCN) + { + switch (RNG::Ref().between(0, 2)) + { + case 0: + parts[i].ctype = PT_SAND; + break; + + case 1: + parts[i].ctype = PT_CLST; + // avoid creating CRMC. + if (parts[i].temp >= sim->elements[PT_PQRT].HighTemperature * 3) + { + parts[i].ctype = PT_PQRT; + } + break; + + case 2: + parts[i].ctype = PT_STNE; + break; + } + sim->kill_part(ID(r)); + continue; + } + else if (rt == PT_LAVA && (parts[ID(r)].ctype == PT_METL || parts[ID(r)].ctype == PT_BMTL) && parts[i].ctype == PT_SLCN) + { + parts[i].ctype = PT_NSCN; + parts[ID(r)].ctype = PT_PSCN; + } else if (rt == PT_HEAC && parts[i].ctype == PT_HEAC) { if (parts[ID(r)].temp > sim->elements[PT_HEAC].HighTemperature) diff --git a/src/simulation/elements/SLCN.cpp b/src/simulation/elements/SLCN.cpp new file mode 100644 index 000000000..f9823229f --- /dev/null +++ b/src/simulation/elements/SLCN.cpp @@ -0,0 +1,141 @@ +#include "simulation/ElementCommon.h" + +static int update(UPDATE_FUNC_ARGS); +static int graphics(GRAPHICS_FUNC_ARGS); +static void create(ELEMENT_CREATE_FUNC_ARGS); + +void Element::Element_SLCN() +{ + Identifier = "DEFAULT_PT_SLCN"; + Name = "SLCN"; + Colour = PIXPACK(0xBCCDDF); + MenuVisible = 1; + MenuSection = SC_POWDERS; + Enabled = 1; + + Advection = 0.4f; + AirDrag = 0.04f * CFDS; + AirLoss = 0.94f; + Loss = 0.95f; + Collision = -0.1f; + Gravity = 0.27f; + Diffusion = 0.00f; + HotAir = 0.000f * CFDS; + Falldown = 1; + + Flammable = 0; + Explosive = 0; + Meltable = 0; + Hardness = 0; + + Weight = 90; + + HeatConduct = 100; + Description = "Powdered Silicon. A key element in multiple materials."; + + Properties = TYPE_PART | PROP_CONDUCTS | PROP_HOT_GLOW | PROP_LIFE_DEC; + + LowPressure = IPL; + LowPressureTransition = NT; + HighPressure = IPH; + HighPressureTransition = NT; + LowTemperature = ITL; + LowTemperatureTransition = NT; + HighTemperature = 3538.15f; + HighTemperatureTransition = PT_LAVA; + + Update = &update; + Graphics = &graphics; + Create = &create; +} + +static const int SLCN_COLOUR[16] = { + PIXPACK(0x5A6679), PIXPACK(0x6878A1), PIXPACK(0xABBFDD), PIXPACK(0x838490), + PIXPACK(0xBCCDDF), PIXPACK(0x82A0D2), PIXPACK(0x5B6680), PIXPACK(0x232C3B), + PIXPACK(0x485067), PIXPACK(0x8B9AB6), PIXPACK(0xADB1C1), PIXPACK(0xC3C6D1), + PIXPACK(0x8594AD), PIXPACK(0x262F47), PIXPACK(0xA9AEBC), PIXPACK(0xC2E1F7), +}; + +static void initSparkles(Particle &part) +{ + // bits 31-20: phase increment (randomised to a value between 1 and 9) + // bits 19-16: next colour index + // bits 15-12: current colour index + // bits 11-00: phase + part.tmp = RNG::Ref().between(0x100000, 0x9FFFFF); +} + +static int update(UPDATE_FUNC_ARGS) +{ + if (!parts[i].tmp) + { + initSparkles(parts[i]); + } + int phase = (parts[i].tmp & 0xFFF) + ((parts[i].tmp >> 20) & 0xFFF); + if (phase & 0x1000) + { + // discard current, current <- next, next <- random, wrap phase + parts[i].tmp = (parts[i].tmp & 0xFFF00000) | (phase & 0xFFF) | (RNG::Ref().between(0, 15) << 16) | ((parts[i].tmp >> 4) & 0xF000); + } + else + { + // update phase + parts[i].tmp = (parts[i].tmp & 0xFFFFF000) | phase; + } + + if (parts[i].life == 0 && parts[i].temp < 373.15f) + { + for (int j = 0; j < 4; j++) + { + static const int check_coords_x[] = { -4, 4, 0, 0 }; + static const int check_coords_y[] = { 0, 0, -4, 4 }; + int n = pmap[y + check_coords_y[j]][x + check_coords_x[j]]; + if (n && TYP(n) == PT_SPRK) + { + Particle &neighbour = parts[ID(n)]; + if (neighbour.life != 0 && neighbour.life < 4) + { + sim->part_change_type(i, x, y, PT_SPRK); + parts[i].life = 4; + parts[i].ctype = PT_SLCN; + } + } + } + } + + return 0; +} + +static int graphics(GRAPHICS_FUNC_ARGS) +{ + int curr_colour = SLCN_COLOUR[(cpart->tmp >> 12) & 15]; + if (cpart->tmp & 0x800) // mix with next colour if phase is at least halfway there + { + int next_colour = SLCN_COLOUR[(cpart->tmp >> 16) & 15]; + curr_colour = PIXRGB( + (PIXR(curr_colour) + PIXR(next_colour)) / 2, + (PIXG(curr_colour) + PIXG(next_colour)) / 2, + (PIXB(curr_colour) + PIXB(next_colour)) / 2 + ); + } + *colr = PIXR(curr_colour); + *colg = PIXG(curr_colour); + *colb = PIXB(curr_colour); + + int rnd = (cpart->tmp & 0xFFFF) * ((cpart->tmp >> 16) & 0xFFFF); + if (!(rnd % 887)) + { + *pixel_mode |= PMODE_FLARE | PMODE_GLOW; + } + if (!(rnd % 593)) + { + *pixel_mode |= PMODE_SPARK; + } + + return 0; +} + +static void create(ELEMENT_CREATE_FUNC_ARGS) +{ + initSparkles(sim->parts[i]); +}