piston retraction now checks pmap

This commit is contained in:
jacob1 2013-03-01 23:06:02 -05:00
parent a9f4b5fe34
commit cd18515e0a

View File

@ -148,20 +148,13 @@ int Element_PSTN::update(UPDATE_FUNC_ARGS)
if(pistonCount > armCount) if(pistonCount > armCount)
pistonCount = armCount; pistonCount = armCount;
if(armCount) { if(armCount) {
//Remove arm section
int lastPistonX = pistonEndX - nxi; //Go back to the very last piston arm particle
int lastPistonY = pistonEndY - nyi;
for(int j = 0; j < pistonCount; j++) {
sim->delete_part(lastPistonX+(nxi*-j), lastPistonY+(nyi*-j), 0);
}
MoveStack(sim, pistonEndX, pistonEndY, directionX, directionY, maxSize, pistonCount, true); MoveStack(sim, pistonEndX, pistonEndY, directionX, directionY, maxSize, pistonCount, true);
//newSpace = MoveStack(sim, pistonEndX, pistonEndY, directionX, directionY, maxSize, pistonCount, true);
movedPiston = true; movedPiston = true;
} }
} }
} }
if (movedPiston) if (movedPiston)
break; return 0;
} }
} }
@ -169,8 +162,8 @@ 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) //#TPT-Directive ElementHeader Element_PSTN static int CanMoveStack(Simulation * sim, int stackX, int stackY, int directionX, int directionY, int size, int amount, bool retract)
int Element_PSTN::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, bool retract)
{ {
int posX, posY, r, spaces = 0, currentPos = 0; int posX, posY, r, spaces = 0, currentPos = 0;
if (amount == 0) if (amount == 0)
@ -188,7 +181,7 @@ int Element_PSTN::CanMoveStack(Simulation * sim, int stackX, int stackY, int dir
if(spaces >= amount) if(spaces >= amount)
break; break;
} else { } else {
if(currentPos < size) if(currentPos < size && !retract)
tempParts[currentPos++] = r>>8; tempParts[currentPos++] = r>>8;
else else
return spaces; return spaces;
@ -207,62 +200,61 @@ 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 ret = amount;
int newY = !!directionX, newX = !!directionY; int newY = !!directionX, newX = !!directionY;
if (!retract) int realDirectionX = retract?-directionX:directionX;
{ int realDirectionY = retract?-directionY:directionY;
int maxRight = MAX_FRAME, maxLeft = MAX_FRAME;
//check if we can push all the FRME //check if we can push all the FRME
for(int c = 0; c < MAX_FRAME; c++) { for(int c = retract; c < MAX_FRAME; c++) {
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+directionX, posY+directionY, directionX, directionY, size, amount); int val = CanMoveStack(sim, posX+realDirectionX, posY+realDirectionY, realDirectionX, realDirectionY, size, amount, retract);
if(val < amount) if(val < amount)
amount = val; amount = val;
} else } else {
maxRight = c;
break; break;
} }
}
for(int c = 1; c < MAX_FRAME; c++) { for(int c = 1; c < MAX_FRAME; c++) {
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+directionX, posY+directionY, directionX, directionY, size, amount); int val = CanMoveStack(sim, posX+realDirectionX, posY+realDirectionY, realDirectionX, realDirectionY, size, amount, retract);
if(val < amount) if(val < amount)
amount = val; amount = val;
} else } else {
maxLeft = c;
break; 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 = 1; c < maxRight; c++) {
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) { MoveStack(sim, posX, posY, directionX, directionY, size, amount, retract, 1);
r = sim->pmap[posY][posX];
if((r&0xFF) == PT_FRME) {
int val = MoveStack(sim, posX, posY, directionX, directionY, size, amount, retract, 1);
if(c == 0)
ret = val;
} else
break;
} }
} for(int c = 1; c < maxLeft; c++) {
for(int c = 1; c < MAX_FRAME; c++) {
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) {
r = sim->pmap[posY][posX];
if((r&0xFF) == PT_FRME) {
MoveStack(sim, posX, posY, directionX, directionY, size, amount, retract, 1); MoveStack(sim, posX, posY, directionX, directionY, size, amount, retract, 1);
} else
break;
} }
}
return ret; //Remove arm section if retracting with FRME
if (retract)
for(int j = 1; j <= amount; j++)
sim->kill_part(sim->pmap[stackY+(directionY*-j)][stackX+(directionX*-j)]>>8);
return MoveStack(sim, stackX, stackY, directionX, directionY, size, amount, retract, 1);
} }
if(retract){ if(retract){
//Remove arm section if retracting without FRME
if (!callDepth)
for(int j = 1; j <= amount; j++)
sim->kill_part(sim->pmap[stackY+(directionY*-j)][stackX+(directionX*-j)]>>8);
bool foundEnd = false; bool foundEnd = false;
//Warning: retraction does not scan to see if it has space
for(posX = stackX, posY = stackY; currentPos < size; posX += directionX, posY += directionY) { for(posX = stackX, posY = stackY; currentPos < size; posX += directionX, posY += directionY) {
if (!(posX < XRES && posY < YRES && posX >= 0 && posY >= 0)) { if (!(posX < XRES && posY < YRES && posX >= 0 && posY >= 0)) {
break; break;
@ -289,7 +281,7 @@ 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, size, amount); currentPos = CanMoveStack(sim, stackX, stackY, directionX, directionY, size, amount, retract);
if(currentPos){ if(currentPos){
//Move particles //Move particles
int possibleMovement = 0; int possibleMovement = 0;