/* ACK-3D ( Animation Construction Kit 3D ) */ /* Door routines */ /* Author: Lary Myers */ #include #include #include #include #include #include #include #include #include #include #include "ack3d.h" #include "ackext.h" /**************************************************************************** ** Locate a door from its Map coordinate and return the index to the ** ** caller. ** ** ** ****************************************************************************/ int FindDoor(int MapPosn) { int index; for (index = 0; index < MAX_DOORS; index++) { if (MapPosn == Door[index].mPos || MapPosn == Door[index].mPos1) return(index); } return(-1); } /**************************************************************************** ** Find an empty slot for a door. If the door already occupies a slot and ** ** it is in a non-closed state then return error. ** ** ** ****************************************************************************/ int FindDoorSlot(int MapPosn) { int index; index = FindDoor(MapPosn); if (index >= 0 && Door[index].ColOffset) return(-1); for (index = 0; index < MAX_DOORS; index++) { if (Door[index].mPos == -1) return(index); } return(-1); } /**************************************************************************** ** Check all the doors to see what state they are in. If a door's column ** ** offset is non-zero then it is either opening or closing, so add in the ** ** speed of the door and check for fully open and fully closed conditions. ** ** ** ** ** ****************************************************************************/ void CheckDoors(int xPlayer,int yPlayer) { int i,MapPosn,mPos,mPos1; int column,mx,my,DeltaGrid; unsigned char mCode,mCode1; for (i = 0; i < MAX_DOORS; i++) { if (Door[i].ColOffset) { Door[i].ColOffset += Door[i].Speed; mPos = Door[i].mPos; mPos1 = Door[i].mPos1; /* Door is closing and is visible. Put old codes back to make non-passable */ if (Door[i].Speed < 0 && Door[i].ColOffset < 65) { MapPosn = (yPlayer & 0xFFC0) + (xPlayer >> 6); if (MapPosn == mPos || MapPosn == mPos1) { Door[i].ColOffset -= Door[i].Speed; continue; } if (Door[i].Type == DOOR_XCODE) { if (xObjGrid[mPos] || xObjGrid[mPos1]) { Door[i].ColOffset -= Door[i].Speed; continue; } xGrid[mPos] = Door[i].mCode; xGrid[mPos1] = Door[i].mCode1; } else { if (yObjGrid[mPos] || yObjGrid[mPos1]) { Door[i].ColOffset -= Door[i].Speed; continue; } yGrid[mPos] = Door[i].mCode; yGrid[mPos1] = Door[i].mCode1; } /* Door is close enough to fully closed to get rid of the door from the array */ if (Door[i].ColOffset < 3) { Door[i].ColOffset = 0; Door[i].mPos = -1; Door[i].mPos1 = -1; } } if (Door[i].ColOffset > 0xA0) Door[i].Speed = -Door[i].Speed; } } /* Now check for any action occuring in a secret door. This is currently */ /* setup to handle only one door at a time in the X and Y directions, but */ /* it should be fairly straightforward to use a list of doors, similiar */ /* to normal doors, to handle more than one. */ if (xSecretColumn) { if (xSecretColumn > 0) /* See if the door is to the right of us */ { mPos = xSecretmPos1; DeltaGrid = -1; xSecretColumn += DoorSpeed; } else { mPos = xSecretmPos; DeltaGrid = 0; xSecretColumn -= DoorSpeed; } my = mPos & 0xFFC0; mx = (mPos - my) << 6; if (abs(xSecretColumn) > GRID_SIZE) /* Beyond one grid square */ { mx += xSecretColumn; my = my + (mx >> 6); if (xGrid[my]) /* No further, an obstruction */ { xGrid[xSecretmPos] = 0; xGrid[xSecretmPos1] = 0; my += DeltaGrid; xGrid[my] = NonSecretCode; xGrid[my+1] = NonSecretCode; yGrid[my] = NonSecretCode; yGrid[my + GRID_WIDTH] = NonSecretCode; xSecretColumn = 0; } else { if (my != mPos) { xGrid[xSecretmPos] = 0; xGrid[xSecretmPos1] = 0; if (xSecretColumn > 0) { xSecretColumn -= 63; xGrid[my] = DOOR_SECRETCODE; xSecretmPos1 = my; my--; xGrid[my] = DOOR_SECRETCODE; xSecretmPos = my; } else { xSecretColumn += 63; xGrid[my] = DOOR_SECRETCODE; xGrid[my+1] = DOOR_SECRETCODE; xSecretmPos = my; xSecretmPos = my+1; } } } /* End if (xGrid[my]) ... else ... */ } /* End if (abs(xSecretColumn) > GRID_SIZE) */ } /* End if (xSecretColumn) */ /* Perform same process on a secret door that may be moving in the Y */ /* direction. The same door can move either way, depending on which */ /* angle the player struck it at. */ if (ySecretColumn) { if (ySecretColumn > 0) { mPos = ySecretmPos1; DeltaGrid = -GRID_WIDTH; ySecretColumn += DoorSpeed; } else { mPos = ySecretmPos; DeltaGrid = 0; ySecretColumn -= DoorSpeed; } my = mPos & 0xFFC0; mx = (mPos - my) << 6; if (abs(ySecretColumn) > GRID_SIZE) { my += ySecretColumn; my = (my & 0xFFC0) + (mx >> 6); if (yGrid[my]) { yGrid[ySecretmPos] = 0; yGrid[ySecretmPos1] = 0; my += DeltaGrid; xGrid[my] = NonSecretCode; xGrid[my+1] = NonSecretCode; yGrid[my] = NonSecretCode; yGrid[my + GRID_WIDTH] = NonSecretCode; ySecretColumn = 0; } else { if (my != mPos) { yGrid[ySecretmPos] = 0; yGrid[ySecretmPos1] = 0; if (ySecretColumn > 0) { ySecretColumn -= 63; yGrid[my] = DOOR_SECRETCODE; ySecretmPos1 = my; my -= GRID_WIDTH; yGrid[my] = DOOR_SECRETCODE; ySecretmPos = my; } else { ySecretColumn += 63; yGrid[my] = DOOR_SECRETCODE; yGrid[my+GRID_WIDTH] = DOOR_SECRETCODE; ySecretmPos = my; ySecretmPos = my+GRID_WIDTH; } } } } } }