fix FRME breaking when partially blocked

This commit is contained in:
krawthekrow 2016-11-19 09:30:14 +08:00 committed by jacob1
parent 446d4412ea
commit c2642f35f8

View File

@ -45,6 +45,19 @@ Element_PSTN::Element_PSTN()
Graphics = &Element_PSTN::graphics; Graphics = &Element_PSTN::graphics;
} }
//#TPT-Directive ElementHeader Element_PSTN struct StackData
struct Element_PSTN::StackData
{
int pushed;
int spaces;
StackData(int pushed, int spaces):
pushed(pushed),
spaces(spaces)
{
}
};
//#TPT-Directive ElementHeader Element_PSTN static int tempParts[XRES] //#TPT-Directive ElementHeader Element_PSTN static int tempParts[XRES]
int Element_PSTN::tempParts[XRES]; int Element_PSTN::tempParts[XRES];
@ -175,12 +188,12 @@ 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 maxSize, int amount, bool retract, int block) //#TPT-Directive ElementHeader Element_PSTN static StackData CanMoveStack(Simulation * sim, int stackX, int stackY, int directionX, int directionY, int maxSize, int amount, bool retract, int block)
int Element_PSTN::CanMoveStack(Simulation * sim, int stackX, int stackY, int directionX, int directionY, int maxSize, int amount, bool retract, int block) Element_PSTN::StackData Element_PSTN::CanMoveStack(Simulation * sim, int stackX, int stackY, int directionX, int directionY, int maxSize, int amount, bool retract, int block)
{ {
int posX, posY, r, spaces = 0, currentPos = 0; int posX, posY, r, spaces = 0, currentPos = 0;
if (amount <= 0) if (amount <= 0)
return 0; return StackData(0, 0);
for (posX = stackX, posY = stackY; currentPos < maxSize + amount && currentPos < XRES-1; posX += directionX, posY += directionY) for (posX = stackX, posY = stackY; currentPos < maxSize + amount && currentPos < XRES-1; posX += directionX, posY += directionY)
{ {
if (!(posX < XRES && posY < YRES && posX >= 0 && posY >= 0)) if (!(posX < XRES && posY < YRES && posX >= 0 && posY >= 0))
@ -188,7 +201,7 @@ int Element_PSTN::CanMoveStack(Simulation * sim, int stackX, int stackY, int dir
r = sim->pmap[posY][posX]; r = sim->pmap[posY][posX];
if (sim->IsWallBlocking(posX, posY, 0) || (block && (r&0xFF) == block)) if (sim->IsWallBlocking(posX, posY, 0) || (block && (r&0xFF) == block))
return spaces; return StackData(currentPos - spaces, spaces);
if (!r) if (!r)
{ {
spaces++; spaces++;
@ -201,20 +214,17 @@ int Element_PSTN::CanMoveStack(Simulation * sim, int stackX, int stackY, int dir
if (currentPos - spaces < maxSize && (!retract || ((r&0xFF) == PT_FRME && posX == stackX && posY == stackY))) if (currentPos - spaces < maxSize && (!retract || ((r&0xFF) == PT_FRME && posX == stackX && posY == stackY)))
tempParts[currentPos++] = r>>8; tempParts[currentPos++] = r>>8;
else else
return currentPos; return StackData(currentPos - spaces, spaces);
} }
} }
if (spaces) return StackData(currentPos - spaces, 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 maxSize, int amount, bool retract, int block, bool sticky, int callDepth = 0) //#TPT-Directive ElementHeader Element_PSTN static int MoveStack(Simulation * sim, int stackX, int stackY, int directionX, int directionY, int maxSize, int amount, bool retract, int block, bool sticky, int callDepth = 0)
int Element_PSTN::MoveStack(Simulation * sim, int stackX, int stackY, int directionX, int directionY, int maxSize, int amount, bool retract, int block, bool sticky, int callDepth) int Element_PSTN::MoveStack(Simulation * sim, int stackX, int stackY, int directionX, int directionY, int maxSize, int amount, bool retract, int block, bool sticky, int callDepth)
{ {
bool foundParts = false; bool foundParts = false;
int posX, posY, r, spaces = 0, currentPos = 0; int posX, posY, r;
r = sim->pmap[stackY][stackX]; r = sim->pmap[stackY][stackX];
if(!callDepth && (r&0xFF) == PT_FRME) { if(!callDepth && (r&0xFF) == PT_FRME) {
int newY = !!directionX, newX = !!directionY; int newY = !!directionX, newX = !!directionY;
@ -227,9 +237,9 @@ int Element_PSTN::MoveStack(Simulation * sim, int stackX, int stackY, int direct
posY = stackY + (c*newY); posY = stackY + (c*newY);
posX = stackX + (c*newX); posX = stackX + (c*newX);
if (posX < XRES && posY < YRES && posX >= 0 && posY >= 0 && (sim->pmap[posY][posX]&0xFF) == PT_FRME) { if (posX < XRES && posY < YRES && posX >= 0 && posY >= 0 && (sim->pmap[posY][posX]&0xFF) == PT_FRME) {
int val = CanMoveStack(sim, posX, posY, realDirectionX, realDirectionY, maxSize, amount, retract, block); int spaces = CanMoveStack(sim, posX, posY, realDirectionX, realDirectionY, maxSize, amount, retract, block).spaces;
if(val < amount) if(spaces < amount)
amount = val; amount = spaces;
} else { } else {
maxRight = c; maxRight = c;
break; break;
@ -239,9 +249,9 @@ int Element_PSTN::MoveStack(Simulation * sim, int stackX, int stackY, int direct
posY = stackY - (c*newY); posY = stackY - (c*newY);
posX = stackX - (c*newX); posX = stackX - (c*newX);
if (posX < XRES && posY < YRES && posX >= 0 && posY >= 0 && (sim->pmap[posY][posX]&0xFF) == PT_FRME) { if (posX < XRES && posY < YRES && posX >= 0 && posY >= 0 && (sim->pmap[posY][posX]&0xFF) == PT_FRME) {
int val = CanMoveStack(sim, posX, posY, realDirectionX, realDirectionY, maxSize, amount, retract, block); int spaces = CanMoveStack(sim, posX, posY, realDirectionX, realDirectionY, maxSize, amount, retract, block).spaces;
if(val < amount) if(spaces < amount)
amount = val; amount = spaces;
} else { } else {
maxLeft = c; maxLeft = c;
break; break;
@ -272,6 +282,7 @@ int Element_PSTN::MoveStack(Simulation * sim, int stackX, int stackY, int direct
for(int j = 1; j <= amount; j++) for(int j = 1; j <= amount; j++)
sim->kill_part(sim->pmap[stackY+(directionY*-j)][stackX+(directionX*-j)]>>8); sim->kill_part(sim->pmap[stackY+(directionY*-j)][stackX+(directionX*-j)]>>8);
bool foundEnd = false; bool foundEnd = false;
int currentPos = 0;
for(posX = stackX, posY = stackY; currentPos < maxSize && currentPos < XRES-1; posX += directionX, posY += directionY) { for(posX = stackX, posY = stackY; currentPos < maxSize && currentPos < XRES-1; posX += directionX, posY += directionY) {
if (!(posX < XRES && posY < YRES && posX >= 0 && posY >= 0)) { if (!(posX < XRES && posY < YRES && posX >= 0 && posY >= 0)) {
break; break;
@ -300,7 +311,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 {
currentPos = CanMoveStack(sim, stackX, stackY, directionX, directionY, maxSize, amount, retract, block); StackData stackData = CanMoveStack(sim, stackX, stackY, directionX, directionY, maxSize, amount, retract, block);
int currentPos = stackData.pushed + stackData.spaces;
if(currentPos){ if(currentPos){
//Move particles //Move particles
int possibleMovement = 0; int possibleMovement = 0;
@ -321,8 +333,6 @@ int Element_PSTN::MoveStack(Simulation * sim, int stackX, int stackY, int direct
} }
return possibleMovement; return possibleMovement;
} }
if(!foundParts && spaces)
return spaces;
} }
return 0; return 0;
} }