diff --git a/src/simulation/Simulation.cpp b/src/simulation/Simulation.cpp index 30f27acc4..47480df31 100644 --- a/src/simulation/Simulation.cpp +++ b/src/simulation/Simulation.cpp @@ -1095,8 +1095,12 @@ int Simulation::eval_move(int pt, int nx, int ny, unsigned *rr) const } break; case PT_PAPR: - // May allow PAPR to block particles when marked? Or would that be too contrived? - result = 2; + // BCOL can always pass through PAPR in order to color it + // Most elements are blocked by marked PAPR, except for certified "weird" elements where it's inverse + if ((pt == PT_BCOL) || ((parts[ID(r)].life >> 24) & 0x01 ^ (pt != PT_ANAR && pt != PT_BIZR && pt != PT_BIZRG))) + result = 2; + else + result = 0; break; default: // This should never happen diff --git a/src/simulation/SimulationData.cpp b/src/simulation/SimulationData.cpp index f7b3a86db..4a14c1d47 100644 --- a/src/simulation/SimulationData.cpp +++ b/src/simulation/SimulationData.cpp @@ -186,9 +186,9 @@ void SimulationData::init_can_move() if (elements[movingType].Properties & TYPE_PART) can_move[movingType][PT_SAWD] = 0; - // Let most non-solids pass through PAPR + // Let most non-solids pass through unmarked PAPR if (elements[movingType].Properties & (TYPE_GAS | TYPE_PART | TYPE_LIQUID) && (movingType != PT_FIRE && movingType != PT_SMKE)) - can_move[movingType][PT_PAPR] = 2; + can_move[movingType][PT_PAPR] = 3; } //a list of lots of things PHOT can move through // TODO: replace with property diff --git a/src/simulation/elements/ARAY.cpp b/src/simulation/elements/ARAY.cpp index e101e3aac..0968cc804 100644 --- a/src/simulation/elements/ARAY.cpp +++ b/src/simulation/elements/ARAY.cpp @@ -165,6 +165,30 @@ static int update(UPDATE_FUNC_ARGS) { parts[r].life = 10; } + } + else if (rt == PT_PAPR) + { + if (parts[r].tmp) + { + if (parts[r].tmp & 0x10) + { + // Read + if ((parts[r].life >> 24) & 0x1) + { + break; + } + } + else + { + // Write + parts[r].life = 0x11A2222; + } + } + else + { + // Enter writing state + parts[r].tmp = 0x0A; + } // this if prevents BRAY from stopping on certain materials } else if (rt != PT_INWR && (rt != PT_SPRK || parts[r].ctype != PT_INWR) && rt != PT_ARAY && rt != PT_WIFI && !(rt == PT_SWCH && parts[r].life >= 10)) @@ -189,7 +213,7 @@ static int update(UPDATE_FUNC_ARGS) parts[r].dcolour = 0xFF000000; //this if prevents red BRAY from stopping on certain materials } - else if (rt==PT_STOR || rt==PT_INWR || (rt==PT_SPRK && parts[r].ctype==PT_INWR) || rt==PT_ARAY || rt==PT_WIFI || rt==PT_FILT || (rt==PT_SWCH && parts[r].life>=10)) + else if (rt==PT_STOR || rt==PT_INWR || (rt==PT_SPRK && parts[r].ctype==PT_INWR) || rt==PT_ARAY || rt==PT_WIFI || rt==PT_FILT || (rt==PT_SWCH && parts[r].life>=10) || rt==PT_PAPR) { if (rt == PT_STOR) { @@ -201,6 +225,30 @@ static int update(UPDATE_FUNC_ARGS) isBlackDeco = (parts[r].dcolour==0xFF000000); parts[r].life = 2; } + else if (rt == PT_PAPR) + { + if (parts[r].tmp) + { + if (parts[r].tmp & 0x10) + { + // Read + if ((parts[r].life >> 24) & 0x1) + { + break; + } + } + else + { + // Write + parts[r].life = 0x0; + } + } + else + { + // Enter reading state + parts[r].tmp = 0x1A; + } + } docontinue = 1; } else diff --git a/src/simulation/elements/PAPR.cpp b/src/simulation/elements/PAPR.cpp index 1083418ee..e216b6876 100644 --- a/src/simulation/elements/PAPR.cpp +++ b/src/simulation/elements/PAPR.cpp @@ -8,7 +8,7 @@ static int graphics(GRAPHICS_FUNC_ARGS); // Additionally, it can be read and written to by ARAY. // Property usage: -// life: Written color value. If dcolour is not black, it gets copied here. 1 bit alpha +// life: Written color value. Uses same format as dcolour. // tmp: Temporary read/write state for ARAY interaction // tmp2: Singe level @@ -77,11 +77,55 @@ static int update(UPDATE_FUNC_ARGS) } } } + + // Get marked by BCOL + if (TYP(pmap[y][x]) == PT_BCOL) + { + parts[i].life = 0x122222A; + } + + // Get unmarked by SOAP + 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; + if (TYP(r) == PT_SOAP) + { + parts[i].life = 0; + } + } + } + } + + // Decrement tmp counter for laser reading/writing + if (parts[i].tmp & 0xF) + { + parts[i].tmp--; + } + else + { + parts[i].tmp = 0; + } return 0; } static int graphics(GRAPHICS_FUNC_ARGS) { + int ta = (cpart->life >> 24) & 0x01; + int tr = (cpart->life >> 16) & 0xFF; + int tg = (cpart->life >> 8) & 0xFF; + int tb = (cpart->life) & 0xFF; + if (ta) + { + *colr = tr; + *colg = tg; + *colb = tb; + } // Darken when burnt float maxtemp = std::max((float)cpart->tmp2, cpart->temp); if (maxtemp > 450)