diff --git a/src/simulation/Simulation.cpp b/src/simulation/Simulation.cpp index e2d6b6a6e..bceba885f 100644 --- a/src/simulation/Simulation.cpp +++ b/src/simulation/Simulation.cpp @@ -3057,6 +3057,9 @@ int Simulation::create_part(int p, int x, int y, int tv) case PT_TSNS: parts[i].tmp2 = 2; break; + case PT_VINE: + parts[i].tmp = 1; + break; case PT_VIRS: case PT_VRSS: case PT_VRSG: diff --git a/src/simulation/elements/ACEL.cpp b/src/simulation/elements/ACEL.cpp index 15e1b896d..ae69fedf0 100644 --- a/src/simulation/elements/ACEL.cpp +++ b/src/simulation/elements/ACEL.cpp @@ -63,7 +63,7 @@ int Element_ACEL::update(UPDATE_FUNC_ARGS) parts[i].tmp = 0; for (rx=-1; rx<2; rx++) for (ry=-1; ry<2; ry++) - if (BOUNDS_CHECK && (rx || ry) && !(rx && ry)) + if (BOUNDS_CHECK && (!rx != !ry)) { r = pmap[y+ry][x+rx]; if(!r) diff --git a/src/simulation/elements/DRAY.cpp b/src/simulation/elements/DRAY.cpp index 96d8d8a8c..0a611fb9e 100644 --- a/src/simulation/elements/DRAY.cpp +++ b/src/simulation/elements/DRAY.cpp @@ -56,10 +56,10 @@ bool InBounds(int x, int y) int Element_DRAY::update(UPDATE_FUNC_ARGS) { int ctype = parts[i].ctype&0xFF, ctypeExtra = parts[i].ctype>>8, copyLength = parts[i].tmp, copySpaces = parts[i].tmp2; - if (copySpaces <= 0) - copySpaces = 0; - if (copyLength <= 0) - copyLength = 0; + if (copySpaces < 0) + copySpaces = parts[i].tmp2 = 0; + if (copyLength < 0) + copyLength = parts[i].tmp = 0; else copySpaces++; //strange hack if (!parts[i].life) // only fire when life is 0, but nothing sets the life right now diff --git a/src/simulation/elements/GOLD.cpp b/src/simulation/elements/GOLD.cpp index 655c1bdd8..7d550aadd 100644 --- a/src/simulation/elements/GOLD.cpp +++ b/src/simulation/elements/GOLD.cpp @@ -50,13 +50,15 @@ Element_GOLD::Element_GOLD() //#TPT-Directive ElementHeader Element_GOLD static int update(UPDATE_FUNC_ARGS) int Element_GOLD::update(UPDATE_FUNC_ARGS) { - int rx, ry, r, blocking = 0; + int rx, ry, r, rndstore, blocking = 0; static int checkCoordsX[] = { -4, 4, 0, 0 }; static int checkCoordsY[] = { 0, 0, -4, 4 }; //Find nearby rusted iron (BMTL with tmp 1+) for(int j = 0; j < 8; j++){ - rx = (rand()%9)-4; - ry = (rand()%9)-4; + rndstore = rand(); + rx = ((rndstore & 0xF) % 9)-4; + rndstore >>= 4; + ry = ((rndstore & 0xF) % 9)-4; if ((!rx != !ry) && BOUNDS_CHECK) { r = pmap[y+ry][x+rx]; if(!r) continue; @@ -73,7 +75,7 @@ int Element_GOLD::update(UPDATE_FUNC_ARGS) for(int j = 0; j < 4; j++){ rx = checkCoordsX[j]; ry = checkCoordsY[j]; - if ((!rx != !ry) && BOUNDS_CHECK) { + if (BOUNDS_CHECK) { r = pmap[y+ry][x+rx]; if(!r) continue; if((r&0xFF)==PT_SPRK && parts[r>>8].life && parts[r>>8].life<4) @@ -98,9 +100,12 @@ int Element_GOLD::update(UPDATE_FUNC_ARGS) //#TPT-Directive ElementHeader Element_GOLD static int graphics(GRAPHICS_FUNC_ARGS) int Element_GOLD::graphics(GRAPHICS_FUNC_ARGS) { - *colr += rand()%10-5; - *colg += rand()%10-5; - *colb += rand()%10-5; + int rndstore = rand(); + *colr += (rndstore & 0xF) % 10 - 5; + rndstore >>= 4; + *colg += (rndstore & 0xF) % 10 - 5; + rndstore >>= 4; + *colb += (rndstore & 0xF) % 10 - 5; return 0; } diff --git a/src/simulation/elements/PLNT.cpp b/src/simulation/elements/PLNT.cpp index 99890e6d8..4d23247fe 100644 --- a/src/simulation/elements/PLNT.cpp +++ b/src/simulation/elements/PLNT.cpp @@ -49,7 +49,7 @@ Element_PLNT::Element_PLNT() //#TPT-Directive ElementHeader Element_PLNT static int update(UPDATE_FUNC_ARGS) int Element_PLNT::update(UPDATE_FUNC_ARGS) { - int r, rx, ry, np; + int r, rx, ry, np, rndstore; for (rx=-1; rx<2; rx++) for (ry=-1; ry<2; ry++) if (BOUNDS_CHECK && (rx || ry)) @@ -81,11 +81,14 @@ int Element_PLNT::update(UPDATE_FUNC_ARGS) } break; case PT_WOOD: - if (surround_space && !(rand()%4) && (abs(rx+ry)<=2) && parts[i].tmp==1) + rndstore = rand(); + if (surround_space && !(rndstore%4) && parts[i].tmp==1) { - int nnx = rand()%3 -1; - int nny = rand()%3 -1; - if (x+rx+nnx>=0 && y+ry+nny>0 && x+rx+nnx>= 3; + int nnx = (rndstore%3) -1; + rndstore >>= 2; + int nny = (rndstore%3) -1; + if (nnx || nny) { if (pmap[y+ry+nny][x+rx+nnx]) continue; diff --git a/src/simulation/elements/PROT.cpp b/src/simulation/elements/PROT.cpp index 80d88784d..92eac996a 100644 --- a/src/simulation/elements/PROT.cpp +++ b/src/simulation/elements/PROT.cpp @@ -51,68 +51,71 @@ int Element_PROT::update(UPDATE_FUNC_ARGS) { sim->pv[y/CELL][x/CELL] -= .003f; int under = pmap[y][x]; - //set off explosives (only when hot because it wasn't as fun when it made an entire save explode) - if (parts[i].temp > 273.15f+500.0f && (sim->elements[under&0xFF].Flammable || sim->elements[under&0xFF].Explosive || (under&0xFF) == PT_BANG)) - { - sim->create_part(under>>8, x, y, PT_FIRE); - parts[under>>8].temp += restrict_flt(sim->elements[under&0xFF].Flammable*5, MIN_TEMP, MAX_TEMP); - sim->pv[y/CELL][x/CELL] += 1.00f; - } - //remove active sparks - else if ((under&0xFF) == PT_SPRK) + int utype = under & 0xFF; + switch (utype) { + case PT_SPRK: + //remove active sparks sim->part_change_type(under>>8, x, y, parts[under>>8].ctype); - parts[under>>8].life = 44+parts[under>>8].life; + parts[under>>8].life = 44 + parts[under>>8].life; parts[under>>8].ctype = 0; - } - else if ((under&0xFF) == PT_DEUT) - { - if ((-((int)sim->pv[y/CELL][x/CELL]-4)+(parts[under>>8].life/100)) > rand()%200) + break; + case PT_DEUT: + if ((-((int)sim->pv[y / CELL][x / CELL] - 4) + (parts[under>>8].life / 100)) > rand() % 200) { - DeutImplosion(sim, parts[under>>8].life, x, y, restrict_flt(parts[under>>8].temp + parts[under>>8].life*500, MIN_TEMP, MAX_TEMP), PT_PROT); + DeutImplosion(sim, parts[under>>8].life, x, y, restrict_flt(parts[under>>8].temp + parts[under>>8].life * 500, MIN_TEMP, MAX_TEMP), PT_PROT); sim->kill_part(under>>8); } - } - //prevent inactive sparkable elements from being sparked - else if ((sim->elements[under&0xFF].Properties&PROP_CONDUCTS) && parts[under>>8].life <= 4) - { - parts[under>>8].life = 40+parts[under>>8].life; - } - //Powered LCRY reaction: PROT->PHOT - else if ((under&0xFF) == PT_LCRY && parts[under>>8].life > 5 && !(rand()%10)) - { - sim->part_change_type(i, x, y, PT_PHOT); - parts[i].life *= 2; - parts[i].ctype = 0x3FFFFFFF; - } - else if ((under&0xFF) == PT_EXOT) + break; + case PT_LCRY: + //Powered LCRY reaction: PROT->PHOT + if (parts[under>>8].life > 5 && !(rand() % 10)) + { + sim->part_change_type(i, x, y, PT_PHOT); + parts[i].life *= 2; + parts[i].ctype = 0x3FFFFFFF; + } + break; + case PT_EXOT: parts[under>>8].ctype = PT_PROT; - + break; + case PT_WIFI: + float change; + if (parts[i].temp < 173.15f) change = -1000.0f; + else if (parts[i].temp < 273.15f) change = -100.0f; + else if (parts[i].temp > 473.15f) change = 1000.0f; + else if (parts[i].temp > 373.15f) change = 100.0f; + else change = 0.0f; + parts[under>>8].temp = restrict_flt(parts[under>>8].temp + change, MIN_TEMP, MAX_TEMP); + goto no_temp_change; + case PT_NONE: + //slowly kill if it's not inside an element + if (parts[i].life) + { + if (!--parts[i].life) + sim->kill_part(i); + } + goto no_temp_change; + default: + //set off explosives (only when hot because it wasn't as fun when it made an entire save explode) + if (parts[i].temp > 273.15f + 500.0f && (sim->elements[utype].Flammable || sim->elements[utype].Explosive || utype == PT_BANG)) + { + sim->create_part(under>>8, x, y, PT_FIRE); + parts[under>>8].temp += restrict_flt(sim->elements[utype].Flammable * 5, MIN_TEMP, MAX_TEMP); + sim->pv[y / CELL][x / CELL] += 1.00f; + } + //prevent inactive sparkable elements from being sparked + else if ((sim->elements[utype].Properties&PROP_CONDUCTS) && parts[under>>8].life <= 4) + { + parts[under>>8].life = 40 + parts[under>>8].life; + } + break; + } //make temp of other things closer to it's own temperature. This will change temp of things that don't conduct, and won't change the PROT's temperature - if (under) - { - //now changed so that PROT goes through portal, so only the WIFI part applies - if ((under&0xFF) == PT_WIFI/* || (under&0xFF) == PT_PRTI || (under&0xFF) == PT_PRTO*/) - { - float change; - if (parts[i].temp<173.15f) change = -1000.0f; - else if (parts[i].temp<273.15f) change = -100.0f; - else if (parts[i].temp>473.15f) change = 1000.0f; - else if (parts[i].temp>373.15f) change = 100.0f; - else change = 0.0f; - parts[under>>8].temp = restrict_flt(parts[under>>8].temp+change, MIN_TEMP, MAX_TEMP); - } - else - { - parts[under>>8].temp = restrict_flt(parts[under>>8].temp-(parts[under>>8].temp-parts[i].temp)/4.0f, MIN_TEMP, MAX_TEMP); - } - } - //else, slowly kill it if it's not inside an element - else if (parts[i].life) - { - if (!--parts[i].life) - sim->kill_part(i); - } + parts[under>>8].temp = restrict_flt(parts[under>>8].temp - (parts[under>>8].temp - parts[i].temp) / 4.0f, MIN_TEMP, MAX_TEMP); + +no_temp_change: + //if this proton has collided with another last frame, change it into a heavier element if (parts[i].tmp) diff --git a/src/simulation/elements/VIBR.cpp b/src/simulation/elements/VIBR.cpp index 1aeb957e4..ec7408dd4 100644 --- a/src/simulation/elements/VIBR.cpp +++ b/src/simulation/elements/VIBR.cpp @@ -48,7 +48,7 @@ Element_VIBR::Element_VIBR() //#TPT-Directive ElementHeader Element_VIBR static int update(UPDATE_FUNC_ARGS) int Element_VIBR::update(UPDATE_FUNC_ARGS) { - int r, rx, ry; + int r, rx, ry, random; int trade, transfer; if (!parts[i].life) //if not exploding { @@ -83,9 +83,9 @@ int Element_VIBR::update(UPDATE_FUNC_ARGS) { //Release sparks before explode if (parts[i].life < 300) { - int randstore = rand(); - rx = randstore%3-1; - ry = (randstore>>2)%3-1; + random = rand(); + rx = random%3-1; + ry = (random>>2)%3-1; r = pmap[y+ry][x+rx]; if ((r&0xFF) && (r&0xFF) != PT_BREC && (sim->elements[r&0xFF].Properties&PROP_CONDUCTS) && !parts[r>>8].life) { @@ -97,7 +97,7 @@ int Element_VIBR::update(UPDATE_FUNC_ARGS) { //Release all heat if (parts[i].life < 500) { - int random = rand(); + random = rand(); rx = random%7-3; ry = (random>>3)%7-3; if(BOUNDS_CHECK) @@ -115,18 +115,19 @@ int Element_VIBR::update(UPDATE_FUNC_ARGS) { { if (!parts[i].tmp2) { - int random = rand(), index; + int index; + random = rand(); sim->create_part(i, x, y, PT_EXOT); - parts[i].tmp2 = rand()%1000; index = sim->create_part(-3,x+((random>>4)&3)-1,y+((random>>6)&3)-1,PT_ELEC); if (index != -1) parts[index].temp = 7000; index = sim->create_part(-3,x+((random>>8)&3)-1,y+((random>>10)&3)-1,PT_PHOT); if (index != -1) parts[index].temp = 7000; - index = sim->create_part(-1,x+((random>>12)&3)-1,y+rand()%3-1,PT_BREC); + index = sim->create_part(-1,x+((random>>12)&3)-1,y+(random>>14)%3-1,PT_BREC); if (index != -1) parts[index].temp = 7000; + parts[i].tmp2 = (random>>16) % 1000; parts[i].temp=9000; sim->pv[y/CELL][x/CELL] += 50; @@ -146,8 +147,6 @@ int Element_VIBR::update(UPDATE_FUNC_ARGS) { if (BOUNDS_CHECK && (rx || ry)) { r = pmap[y+ry][x+rx]; - if (!r) - r = sim->photons[y+ry][x+rx]; if (!r) continue; if (parts[i].life) @@ -174,7 +173,8 @@ int Element_VIBR::update(UPDATE_FUNC_ARGS) { //Melts into EXOT if ((r&0xFF) == PT_EXOT && !(rand()%25)) { - sim->create_part(i, x, y, PT_EXOT); + sim->part_change_type(i, x, y, PT_EXOT); + return 0; } } //VIBR+ANAR=BVBR @@ -186,9 +186,12 @@ int Element_VIBR::update(UPDATE_FUNC_ARGS) { } for (trade = 0; trade < 9; trade++) { - int random = rand(); + if (!(trade%5)) + random = rand(); rx = random%7-3; - ry = (random>>3)%7-3; + random >>= 3; + ry = random%7-3; + random >>= 3; if (BOUNDS_CHECK && (rx || ry)) { r = pmap[y+ry][x+rx]; @@ -216,13 +219,16 @@ int Element_VIBR::graphics(GRAPHICS_FUNC_ARGS) { *colr = (int)(fabs(sin(exp((750.0f-cpart->life)/170)))*200.0f); if (cpart->tmp2) - *colg = (int)(fabs(sin(exp((750.0f-cpart->life)/170)))*200.0f); - else - *colg = 255; - if (cpart->tmp2) + { + *colg = *colr; *colb = 255; + } else - *colb = (int)(fabs(sin(exp((750.0f-cpart->life)/170)))*200.0f); + { + *colg = 255; + *colb = *colr; + } + *firea = 90; *firer = *colr; *fireg = *colg; diff --git a/src/simulation/elements/VINE.cpp b/src/simulation/elements/VINE.cpp index 398cce60d..551b6ae50 100644 --- a/src/simulation/elements/VINE.cpp +++ b/src/simulation/elements/VINE.cpp @@ -49,18 +49,21 @@ Element_VINE::Element_VINE() //#TPT-Directive ElementHeader Element_VINE static int update(UPDATE_FUNC_ARGS) int Element_VINE::update(UPDATE_FUNC_ARGS) { - int r, np, rx =(rand()%3)-1, ry=(rand()%3)-1; + int r, np, rx, ry, rndstore = rand(); + rx = (rndstore % 3) - 1; + rndstore >>= 2; + ry = (rndstore % 3) - 1; + rndstore >>= 2; if (BOUNDS_CHECK && (rx || ry)) { r = pmap[y+ry][x+rx]; - if (!(rand()%15)) - sim->part_change_type(i,x,y,PT_PLNT); + if (!(rndstore % 15)) + sim->part_change_type(i, x, y, PT_PLNT); else if (!r) { np = sim->create_part(-1,x+rx,y+ry,PT_VINE); if (np<0) return 0; parts[np].temp = parts[i].temp; - parts[i].tmp = 1; sim->part_change_type(i,x,y,PT_PLNT); } } diff --git a/src/simulation/elements/VIRS.cpp b/src/simulation/elements/VIRS.cpp index 2d1051cfe..cd0692281 100644 --- a/src/simulation/elements/VIRS.cpp +++ b/src/simulation/elements/VIRS.cpp @@ -54,7 +54,7 @@ int Element_VIRS::update(UPDATE_FUNC_ARGS) int r, rx, ry, rndstore = rand(); if (parts[i].pavg[0]) { - parts[i].pavg[0] -= (rndstore&0x1) ? 0:1; + parts[i].pavg[0] -= (rndstore & 0x1) ? 0:1; //has been cured, so change back into the original element if (!parts[i].pavg[0]) { @@ -62,32 +62,31 @@ int Element_VIRS::update(UPDATE_FUNC_ARGS) parts[i].tmp2 = 0; parts[i].pavg[0] = 0; parts[i].pavg[1] = 0; - return 0; } + return 0; + //cured virus is never in below code } //decrease pavg[1] so it slowly dies - if (parts[i].pavg[1] > 0) + if (parts[i].pavg[1]) { - if (((rndstore>>1)&0xD) < 1) + if (!(rndstore & 0x7)) { parts[i].pavg[1]--; - //if pavg[1] is now 0 and it's not in the process of being cured, kill it - if (!parts[i].pavg[1] && !parts[i].pavg[0]) + //if pavg[1] is now 0, kill it + if (!parts[i].pavg[1]) { sim->kill_part(i); return 1; } } + rndstore >>= 3; } - //none of the things in the below loop happen while virus is being cured - if (parts[i].pavg[0]) - return 0; - for (rx=-1; rx<2; rx++) { - //reset rndstore, one random can last through 3 locations and reduce rand() calling by up to 6x as much - rndstore = rand(); + //reset rndstore once, 1st rand has possible 3+15 bits max, this one has 30 max. + if (!rx) + rndstore = rand(); for (ry=-1; ry<2; ry++) { if (BOUNDS_CHECK && (rx || ry)) @@ -97,17 +96,16 @@ int Element_VIRS::update(UPDATE_FUNC_ARGS) continue; //spread "being cured" state - if (((r&0xFF) == PT_VIRS || (r&0xFF) == PT_VRSS || (r&0xFF) == PT_VRSG) && parts[r>>8].pavg[0]) + if (parts[r>>8].pavg[0] && ((r&0xFF) == PT_VIRS || (r&0xFF) == PT_VRSS || (r&0xFF) == PT_VRSG)) { - parts[i].pavg[0] = parts[r>>8].pavg[0] + (((rndstore&0x7)>>1) ? 2:1); - rndstore = rndstore >> 3; + parts[i].pavg[0] = parts[r>>8].pavg[0] + ((rndstore & 0x3) ? 2:1); return 0; } //soap cures virus else if ((r&0xFF) == PT_SOAP) { parts[i].pavg[0] += 10; - if (!((rndstore&0x7)>>1)) + if (!(rndstore & 0x3)) sim->kill_part(r>>8); return 0; } @@ -122,12 +120,16 @@ int Element_VIRS::update(UPDATE_FUNC_ARGS) //transforms things into virus here else if ((r&0xFF) != PT_VIRS && (r&0xFF) != PT_VRSS && (r&0xFF) != PT_VRSG && (r&0xFF) != PT_DMND) { - if (!((rndstore&0xF)>>1)) + if (!(rndstore & 0x7)) { + rndstore >>= 3; parts[r>>8].tmp2 = (r&0xFF); parts[r>>8].pavg[0] = 0; if (parts[i].pavg[1]) - parts[r>>8].pavg[1] = parts[i].pavg[1] + ((rndstore>>4) ? 1:0); + { + parts[r>>8].pavg[1] = parts[i].pavg[1] + ((rndstore & 0x3) % 3 ? 1 : 0); + rndstore >>= 2; + } else parts[r>>8].pavg[1] = 0; if (parts[r>>8].temp < 305.0f) @@ -137,7 +139,8 @@ int Element_VIRS::update(UPDATE_FUNC_ARGS) else sim->part_change_type(r>>8, x+rx, y+ry, PT_VIRS); } - rndstore = rndstore >> 5; + else + rndstore >>= 3; } //protons make VIRS last forever else if ((sim->photons[y+ry][x+rx]&0xFF) == PT_PROT)