mirror of
https://github.com/The-Powder-Toy/The-Powder-Toy.git
synced 2025-09-01 20:12:50 +02:00
fix PSTN bugs where FRME would still move even if all of it couldn't, fix PSTN going through walls, fix bug where the PSTN extention may not be created in some glitched cases
This commit is contained in:
@@ -1996,11 +1996,8 @@ void Simulation::clear_sim(void)
|
|||||||
SetEdgeMode(edgeMode);
|
SetEdgeMode(edgeMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Simulation::IsObsticle(int x, int y, int type)
|
bool Simulation::IsWallBlocking(int x, int y, int type)
|
||||||
{
|
{
|
||||||
if (pmap[y][x])// && (type != PT_SPRK || !(elements[pmap[y][x]&0xFF].Properties & PROP_CONDUCTS)))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (bmap[y/CELL][x/CELL])
|
if (bmap[y/CELL][x/CELL])
|
||||||
{
|
{
|
||||||
int wall = bmap[y/CELL][x/CELL];
|
int wall = bmap[y/CELL][x/CELL];
|
||||||
|
@@ -138,7 +138,7 @@ public:
|
|||||||
TPT_NO_INLINE int try_move(int i, int x, int y, int nx, int ny);
|
TPT_NO_INLINE int try_move(int i, int x, int y, int nx, int ny);
|
||||||
TPT_NO_INLINE int eval_move(int pt, int nx, int ny, unsigned *rr);
|
TPT_NO_INLINE int eval_move(int pt, int nx, int ny, unsigned *rr);
|
||||||
void init_can_move();
|
void init_can_move();
|
||||||
bool IsObsticle(int x, int y, int type);
|
bool IsWallBlocking(int x, int y, int type);
|
||||||
void create_cherenkov_photon(int pp);
|
void create_cherenkov_photon(int pp);
|
||||||
void create_gain_photon(int pp);
|
void create_gain_photon(int pp);
|
||||||
TPT_NO_INLINE void kill_part(int i);
|
TPT_NO_INLINE void kill_part(int i);
|
||||||
|
@@ -87,7 +87,7 @@ int Element_CRAY::update(UPDATE_FUNC_ARGS)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
r = pmap[y+nyi+nyy][x+nxi+nxx];
|
r = pmap[y+nyi+nyy][x+nxi+nxx];
|
||||||
if (!sim->IsObsticle(x+nxi+nxx, y+nyi+nyy, parts[i].ctype) || (parts[i].ctype == PT_SPRK && sim->elements[r&0xFF].Properties & PROP_CONDUCTS) && !destroy) { // create, also set color if it has passed through FILT
|
if (!sim->IsWallBlocking(x+nxi+nxx, y+nyi+nyy, parts[i].ctype) && (!sim->pmap[y+nyi+nyy][x+nxi+nxx] || (parts[i].ctype == PT_SPRK && !destroy))) { // create, also set color if it has passed through FILT
|
||||||
int nr;
|
int nr;
|
||||||
if (parts[i].ctype == PT_LIFE)
|
if (parts[i].ctype == PT_LIFE)
|
||||||
nr = sim->create_part(-1, x+nxi+nxx, y+nyi+nyy, parts[i].ctype|(parts[i].tmp2<<8));
|
nr = sim->create_part(-1, x+nxi+nxx, y+nyi+nyy, parts[i].ctype|(parts[i].tmp2<<8));
|
||||||
|
@@ -160,6 +160,37 @@ int Element_PSTN::update(UPDATE_FUNC_ARGS)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//#TPT-Directive ElementHeader Element_PSTN static int CanMoveStack(Simulation * sim, int stackX, int stackY, int directionX, int directionY, int size, int amount)
|
||||||
|
int Element_PSTN::CanMoveStack(Simulation * sim, int stackX, int stackY, int directionX, int directionY, int size, int amount)
|
||||||
|
{
|
||||||
|
int posX, posY, r, spaces = 0, currentPos = 0;
|
||||||
|
if (amount == 0)
|
||||||
|
return 0;
|
||||||
|
for(posX = stackX, posY = stackY; currentPos < size + amount; posX += directionX, posY += directionY) {
|
||||||
|
if (!(posX < XRES && posY < YRES && posX >= 0 && posY >= 0)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
r = sim->pmap[posY][posX];
|
||||||
|
if (sim->IsWallBlocking(posX, posY, 0)/* || (r&0xFF) == PT_INSL*/)
|
||||||
|
break;
|
||||||
|
if(!r) {
|
||||||
|
spaces++;
|
||||||
|
tempParts[currentPos++] = -1;
|
||||||
|
if(spaces >= amount)
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
if(currentPos < size)
|
||||||
|
tempParts[currentPos++] = r>>8;
|
||||||
|
else
|
||||||
|
return spaces;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (spaces)
|
||||||
|
return currentPos;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
//#TPT-Directive ElementHeader Element_PSTN static int MoveStack(Simulation * sim, int stackX, int stackY, int directionX, int directionY, int size, int amount, bool retract, int callDepth = 0)
|
//#TPT-Directive ElementHeader Element_PSTN static int MoveStack(Simulation * sim, int stackX, int stackY, int directionX, int directionY, int size, int amount, bool retract, int callDepth = 0)
|
||||||
int Element_PSTN::MoveStack(Simulation * sim, int stackX, int stackY, int directionX, int directionY, int size, int amount, bool retract, int callDepth)
|
int Element_PSTN::MoveStack(Simulation * sim, int stackX, int stackY, int directionX, int directionY, int size, int amount, bool retract, int callDepth)
|
||||||
{
|
{
|
||||||
@@ -167,8 +198,32 @@ int Element_PSTN::MoveStack(Simulation * sim, int stackX, int stackY, int direct
|
|||||||
int posX, posY, r, spaces = 0, currentPos = 0;
|
int posX, posY, r, spaces = 0, currentPos = 0;
|
||||||
r = sim->pmap[stackY][stackX];
|
r = sim->pmap[stackY][stackX];
|
||||||
if(!callDepth && (r&0xFF) == PT_FRME) {
|
if(!callDepth && (r&0xFF) == PT_FRME) {
|
||||||
int biggestMove = amount;
|
int ret = amount;
|
||||||
int newY = !!directionX, newX = !!directionY;
|
int newY = !!directionX, newX = !!directionY;
|
||||||
|
if (!retract)
|
||||||
|
{
|
||||||
|
//check if we can push all the FRME
|
||||||
|
for(int c = 0; c < MAX_FRAME; c++) {
|
||||||
|
posY = stackY + (c*newY);
|
||||||
|
posX = stackX + (c*newX);
|
||||||
|
if (posX < XRES && posY < YRES && posX >= 0 && posY >= 0 && (sim->pmap[posY][posX]&0xFF) == PT_FRME) {
|
||||||
|
int val = CanMoveStack(sim, posX+directionX, posY+directionY, directionX, directionY, size, amount);
|
||||||
|
if(val < amount)
|
||||||
|
amount = val;
|
||||||
|
} else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for(int c = 1; c < MAX_FRAME; c++) {
|
||||||
|
posY = stackY - (c*newY);
|
||||||
|
posX = stackX - (c*newX);
|
||||||
|
if (posX < XRES && posY < YRES && posX >= 0 && posY >= 0 && (sim->pmap[posY][posX]&0xFF) == PT_FRME) {
|
||||||
|
int val = CanMoveStack(sim, posX+directionX, posY+directionY, directionX, directionY, size, amount);
|
||||||
|
if(val < amount)
|
||||||
|
amount = val;
|
||||||
|
} else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
//If the piston is pushing frame, iterate out from the centre to the edge and push everything resting on frame
|
//If the piston is pushing frame, iterate out from the centre to the edge and push everything resting on frame
|
||||||
for(int c = 0; c < MAX_FRAME; c++) {
|
for(int c = 0; c < MAX_FRAME; c++) {
|
||||||
posY = stackY + (c*newY);
|
posY = stackY + (c*newY);
|
||||||
@@ -177,8 +232,8 @@ int Element_PSTN::MoveStack(Simulation * sim, int stackX, int stackY, int direct
|
|||||||
r = sim->pmap[posY][posX];
|
r = sim->pmap[posY][posX];
|
||||||
if((r&0xFF) == PT_FRME) {
|
if((r&0xFF) == PT_FRME) {
|
||||||
int val = MoveStack(sim, posX, posY, directionX, directionY, size, amount, retract, 1);
|
int val = MoveStack(sim, posX, posY, directionX, directionY, size, amount, retract, 1);
|
||||||
if(val < biggestMove)
|
if(c == 0)
|
||||||
biggestMove = val;
|
ret = val;
|
||||||
} else
|
} else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -189,14 +244,12 @@ int Element_PSTN::MoveStack(Simulation * sim, int stackX, int stackY, int direct
|
|||||||
if (posX < XRES && posY < YRES && posX >= 0 && posY >= 0) {
|
if (posX < XRES && posY < YRES && posX >= 0 && posY >= 0) {
|
||||||
r = sim->pmap[posY][posX];
|
r = sim->pmap[posY][posX];
|
||||||
if((r&0xFF) == PT_FRME) {
|
if((r&0xFF) == PT_FRME) {
|
||||||
int val = MoveStack(sim, posX, posY, directionX, directionY, size, amount, retract, 1);
|
MoveStack(sim, posX, posY, directionX, directionY, size, amount, retract, 1);
|
||||||
if(val < biggestMove)
|
|
||||||
biggestMove = val;
|
|
||||||
} else
|
} else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return biggestMove;
|
return ret;
|
||||||
}
|
}
|
||||||
if(retract){
|
if(retract){
|
||||||
bool foundEnd = false;
|
bool foundEnd = false;
|
||||||
@@ -227,25 +280,8 @@ int Element_PSTN::MoveStack(Simulation * sim, int stackX, int stackY, int direct
|
|||||||
if(!foundParts && foundEnd)
|
if(!foundParts && foundEnd)
|
||||||
return amount;
|
return amount;
|
||||||
} else {
|
} else {
|
||||||
for(posX = stackX, posY = stackY; currentPos < size + amount; posX += directionX, posY += directionY) {
|
currentPos = CanMoveStack(sim, stackX, stackY, directionX, directionY, size, amount);
|
||||||
if (!(posX < XRES && posY < YRES && posX >= 0 && posY >= 0)) {
|
if(currentPos){
|
||||||
break;
|
|
||||||
}
|
|
||||||
r = sim->pmap[posY][posX];
|
|
||||||
if(!r) {
|
|
||||||
spaces++;
|
|
||||||
tempParts[currentPos++] = -1;
|
|
||||||
if(spaces >= amount)
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
foundParts = true;
|
|
||||||
if(currentPos < size)
|
|
||||||
tempParts[currentPos++] = r>>8;
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(foundParts && spaces){
|
|
||||||
//Move particles
|
//Move particles
|
||||||
int possibleMovement = 0;
|
int possibleMovement = 0;
|
||||||
for(int j = currentPos-1; j >= 0; j--) {
|
for(int j = currentPos-1; j >= 0; j--) {
|
||||||
|
Reference in New Issue
Block a user