|
| 1 | +#include "simulation/ElementCommon.h" |
| 2 | + |
| 3 | +static int update(UPDATE_FUNC_ARGS); |
| 4 | +static int graphics(GRAPHICS_FUNC_ARGS); |
| 5 | + |
| 6 | +void Element::Element_BASE() |
| 7 | +{ |
| 8 | + Identifier = "DEFAULT_PT_BASE"; |
| 9 | + Name = "BASE"; |
| 10 | + Colour = 0x90D5FF_rgb; |
| 11 | + MenuVisible = 1; |
| 12 | + MenuSection = SC_LIQUID; |
| 13 | + Enabled = 1; |
| 14 | + |
| 15 | + Advection = 0.5f; |
| 16 | + AirDrag = 0.01f * CFDS; |
| 17 | + AirLoss = 0.97f; |
| 18 | + Loss = 0.96f; |
| 19 | + Collision = 0.0f; |
| 20 | + Gravity = 0.08f; |
| 21 | + Diffusion = 0.00f; |
| 22 | + HotAir = 0.000f * CFDS; |
| 23 | + Falldown = 2; |
| 24 | + |
| 25 | + Flammable = 0; |
| 26 | + Explosive = 0; |
| 27 | + Meltable = 0; |
| 28 | + Hardness = 0; |
| 29 | + |
| 30 | + Weight = 16; |
| 31 | + |
| 32 | + HeatConduct = 31; |
| 33 | + Description = "Corrosive liquid. Rusts conductive solids, neutralizes acid."; |
| 34 | + |
| 35 | + Properties = TYPE_LIQUID|PROP_DEADLY; |
| 36 | + |
| 37 | + LowPressure = IPL; |
| 38 | + LowPressureTransition = NT; |
| 39 | + HighPressure = IPH; |
| 40 | + HighPressureTransition = NT; |
| 41 | + LowTemperature = ITL; |
| 42 | + LowTemperatureTransition = NT; |
| 43 | + HighTemperature = ITH; |
| 44 | + HighTemperatureTransition = NT; |
| 45 | + |
| 46 | + DefaultProperties.life = 75; |
| 47 | + |
| 48 | + Update = &update; |
| 49 | + Graphics = &graphics; |
| 50 | +} |
| 51 | + |
| 52 | +static int update(UPDATE_FUNC_ARGS) |
| 53 | +{ |
| 54 | + auto &sd = SimulationData::CRef(); |
| 55 | + auto &elements = sd.elements; |
| 56 | + |
| 57 | + //Reset spark effect |
| 58 | + parts[i].tmp = 0; |
| 59 | + |
| 60 | + if (parts[i].life < 1) |
| 61 | + parts[i].life = 1; |
| 62 | + |
| 63 | + if (parts[i].life > 100) |
| 64 | + parts[i].life = 100; |
| 65 | + |
| 66 | + float pres = sim->pv[y/CELL][x/CELL]; |
| 67 | + |
| 68 | + //Base evaporates into BOYL or increases concentration |
| 69 | + if (parts[i].life < 100 && pres < 10.0f && parts[i].temp > (120.0f + 273.15f)) |
| 70 | + { |
| 71 | + if (sim->rng.chance(parts[i].life+900, 1000)) |
| 72 | + parts[i].life++; |
| 73 | + else |
| 74 | + { |
| 75 | + sim->create_part(i, x, y, PT_BOYL); |
| 76 | + return 1; |
| 77 | + } |
| 78 | + } |
| 79 | + |
| 80 | + //Base's freezing point lowers with its concentration |
| 81 | + if (parts[i].temp < (273.15f - ((float)parts[i].life)/4.0f)) |
| 82 | + { |
| 83 | + //We don't save base's concentration, so ICEI(BASE) will unfreeze into life = 0 |
| 84 | + sim->part_change_type(i, x, y, PT_ICEI); |
| 85 | + parts[i].ctype = PT_BASE; |
| 86 | + parts[i].life = 0; |
| 87 | + return 1; |
| 88 | + } |
| 89 | + |
| 90 | + //Reactions |
| 91 | + for (auto rx = -1; rx <= 1; rx++) |
| 92 | + { |
| 93 | + for (auto ry = -1; ry <= 1; ry++) |
| 94 | + { |
| 95 | + if (rx || ry) |
| 96 | + { |
| 97 | + auto r = pmap[y+ry][x+rx]; |
| 98 | + if (!r) |
| 99 | + continue; |
| 100 | + int rt = TYP(r); |
| 101 | + |
| 102 | + if (rt != PT_BASE && rt != PT_SALT && rt != PT_SLTW && rt != PT_BOYL && rt != PT_MERC && |
| 103 | + rt != PT_BMTL && rt != PT_BRMT && rt != PT_SOAP && rt != PT_CLNE && rt != PT_PCLN) |
| 104 | + { |
| 105 | + //Base is diluted by water |
| 106 | + if (parts[i].life > 1 && (rt == PT_WATR || rt == PT_DSTW || rt == PT_CBNW)) |
| 107 | + { |
| 108 | + if (sim->rng.chance(1, 20)) |
| 109 | + { |
| 110 | + int saturh = parts[i].life/2; |
| 111 | + |
| 112 | + sim->part_change_type(ID(r), x+rx, y+ry, PT_BASE); |
| 113 | + parts[ID(r)].life = saturh; |
| 114 | + parts[ID(r)].temp += ((float)saturh)/10.0f; |
| 115 | + parts[i].life -= saturh; |
| 116 | + } |
| 117 | + } //Base neutralizes acid |
| 118 | + else if (rt == PT_ACID && parts[i].life >= parts[ID(r)].life) |
| 119 | + { |
| 120 | + sim->part_change_type(i, x, y, PT_SLTW); |
| 121 | + sim->part_change_type(ID(r), x+rx, y+ry, PT_SLTW); |
| 122 | + return 1; |
| 123 | + } //BASE + OIL = SOAP |
| 124 | + else if (parts[i].life >= 70 && rt == PT_OIL) |
| 125 | + { |
| 126 | + sim->part_change_type(i, x, y, PT_SOAP); |
| 127 | + parts[i].tmp = parts[i].tmp2 = parts[i].ctype = 0; |
| 128 | + sim->kill_part(ID(r)); |
| 129 | + return 1; |
| 130 | + } //BASE + GOO = GEL |
| 131 | + else if (parts[i].life > 1 && rt == PT_GOO) |
| 132 | + { |
| 133 | + sim->create_part(ID(r), x+rx, y+ry, PT_GEL); |
| 134 | + parts[i].life--; |
| 135 | + } //BASE + BCOL = GUNP |
| 136 | + else if (parts[i].life > 1 && rt == PT_BCOL) |
| 137 | + { |
| 138 | + sim->create_part(ID(r), x+rx, y+ry, PT_GUNP); |
| 139 | + parts[i].life--; |
| 140 | + } //BASE + Molten ROCK = MERC |
| 141 | + else if (rt == PT_LAVA && parts[ID(r)].ctype == PT_ROCK && pres >= 10.0f && sim->rng.chance(1, 1000)) |
| 142 | + { |
| 143 | + sim->part_change_type(i, x, y, PT_MERC); |
| 144 | + parts[i].life = 0; |
| 145 | + parts[i].tmp = 10; |
| 146 | + |
| 147 | + sim->kill_part(ID(r)); |
| 148 | + return 1; |
| 149 | + } //Base rusts conductive solids |
| 150 | + else if (parts[i].life >= 10 && |
| 151 | + (elements[rt].Properties & (TYPE_SOLID|PROP_CONDUCTS)) == (TYPE_SOLID|PROP_CONDUCTS) && sim->rng.chance(1, 10)) |
| 152 | + { |
| 153 | + sim->part_change_type(ID(r), x+rx, y+ry, PT_BMTL); |
| 154 | + parts[ID(r)].tmp = sim->rng.between(20, 29); |
| 155 | + parts[i].life--; |
| 156 | + //Draw a spark effect |
| 157 | + parts[i].tmp = 1; |
| 158 | + } //Base destroys a substance slower if acid destroys it faster |
| 159 | + else if (elements[rt].Hardness > 0 && elements[rt].Hardness < 50 && |
| 160 | + parts[i].life >= (2*elements[rt].Hardness) && sim->rng.chance(50-elements[rt].Hardness, 1000)) |
| 161 | + { |
| 162 | + sim->kill_part(ID(r)); |
| 163 | + parts[i].life -= 2; |
| 164 | + //Draw a spark |
| 165 | + parts[i].tmp = 1; |
| 166 | + } |
| 167 | + } |
| 168 | + } |
| 169 | + } |
| 170 | + } |
| 171 | + |
| 172 | + //Diffusion |
| 173 | + for (auto trade = 0; trade<2; trade++) |
| 174 | + { |
| 175 | + auto rx = sim->rng.between(-1, 1); |
| 176 | + auto ry = sim->rng.between(-1, 1); |
| 177 | + if (rx || ry) |
| 178 | + { |
| 179 | + auto r = pmap[y+ry][x+rx]; |
| 180 | + if (!r) |
| 181 | + continue; |
| 182 | + if (TYP(r) == PT_BASE && (parts[i].life > parts[ID(r)].life) && parts[i].life>1) |
| 183 | + { |
| 184 | + int temp = parts[i].life - parts[ID(r)].life; |
| 185 | + if (temp == 1) |
| 186 | + { |
| 187 | + parts[ID(r)].life++; |
| 188 | + parts[i].life--; |
| 189 | + } |
| 190 | + else if (temp>0) |
| 191 | + { |
| 192 | + parts[ID(r)].life += temp/2; |
| 193 | + parts[i].life -= temp/2; |
| 194 | + } |
| 195 | + } |
| 196 | + } |
| 197 | + } |
| 198 | + return 0; |
| 199 | +} |
| 200 | + |
| 201 | +static int graphics(GRAPHICS_FUNC_ARGS) |
| 202 | +{ |
| 203 | + int s = cpart->life; |
| 204 | + |
| 205 | + if (s < 25) |
| 206 | + { |
| 207 | + *colr = 0x33; |
| 208 | + *colg = 0x4C; |
| 209 | + *colb = 0xD8; |
| 210 | + } |
| 211 | + else if (s < 50) |
| 212 | + { |
| 213 | + *colr = 0x58; |
| 214 | + *colg = 0x83; |
| 215 | + *colb = 0xE8; |
| 216 | + } |
| 217 | + else if (s < 75) |
| 218 | + { |
| 219 | + *colr = 0x7D; |
| 220 | + *colg = 0xBA; |
| 221 | + *colb = 0xF7; |
| 222 | + } |
| 223 | + |
| 224 | + *pixel_mode |= PMODE_BLUR; |
| 225 | + |
| 226 | + if (cpart->tmp == 1) |
| 227 | + *pixel_mode |= PMODE_SPARK; |
| 228 | + |
| 229 | + return 0; |
| 230 | +} |
0 commit comments