X-Git-Url: http://4ch.mooo.com/gitweb/?p=16.git;a=blobdiff_plain;f=16%2Fkeen456%2FKEEN4-6%2FKEEN5%2FK5_ACT1.C;fp=16%2Fkeen456%2FKEEN4-6%2FKEEN5%2FK5_ACT1.C;h=0000000000000000000000000000000000000000;hp=9157bac9c14b329710e26608310d06e7756165fa;hb=a387b1ff6f02e2da93e870a330af886d1c8233da;hpb=7d1948e210bb7b58af0a0412e71f2a0a0a2010af diff --git a/16/keen456/KEEN4-6/KEEN5/K5_ACT1.C b/16/keen456/KEEN4-6/KEEN5/K5_ACT1.C deleted file mode 100755 index 9157bac9..00000000 --- a/16/keen456/KEEN4-6/KEEN5/K5_ACT1.C +++ /dev/null @@ -1,1524 +0,0 @@ -/* Reconstructed Commander Keen 4-6 Source Code - * Copyright (C) 2021 K1n9_Duk3 - * - * This file is loosely based on: - * Keen Dreams Source Code - * Copyright (C) 2014 Javier M. Chavez - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -/* -K5_ACT1.C -========= - -Contains the following actor types (in this order): - -- some shared routines -- Bonus Items -- Teleport and Fuse effects -- Platforms -- falling platforms -- static platforms -- Goplat platforms -- Volte Face -- sneaky platforms -- Turrets - -*/ - -#include "CK_DEF.H" - -/* -============================================================================= - - SHARED STUFF - -============================================================================= -*/ - -Sint16 pdirx[] = {0, 1, 0, -1, 1, 1, -1, -1}; -Sint16 pdiry[] = {-1, 0, 1, 0, -1, 1, 1, -1}; - -/* -=========================== -= -= CheckSpawnShot -= -=========================== -*/ - -Sint16 CheckSpawnShot(Uint16 x, Uint16 y, statetype *state) -{ - if (GetNewObj(true) == -1) - return -1; - new->x = x; - new->y = y; - new->obclass = mshotobj; - new->active = ac_removable; - NewState(new, state); - if (!CheckPosition(new)) - { - RemoveObj(new); - return -1; - } - return 0; -} - -/* -=========================== -= -= C_ClipSide -= -=========================== -*/ - -void C_ClipSide(objtype *ob, objtype *hit) -{ - if (hit->obclass == keenobj) - { - playerkludgeclipcancel = true; - ClipToSpriteSide(hit, ob); - playerkludgeclipcancel = false; - } -} - -/* -=========================== -= -= C_ClipTop -= -=========================== -*/ - -void C_ClipTop(objtype *ob, objtype *hit) -{ - if (hit->obclass == keenobj) - ClipToSpriteTop(hit, ob); -} - -/* -=========================== -= -= R_Land -= -=========================== -*/ - -void R_Land(objtype *ob) -{ - if (ob->hiteast || ob->hitwest) - ob->xspeed = 0; - - if (ob->hitsouth) - ob->yspeed = 0; - - if (ob->hitnorth) - { - ob->yspeed = 0; - if (ob->state->nextstate) - { - ChangeState(ob, ob->state->nextstate); - } - else - { - RemoveObj(ob); - return; - } - } - - RF_PlaceSprite(&ob->sprite, ob->x, ob->y, ob->shapenum, spritedraw, ob->priority); -} - -/* -=========================== -= -= R_Bounce -= -=========================== -*/ - -void R_Bounce(objtype *ob) -{ - Uint16 wall,absx,absy,angle,newangle; - Uint32 speed; - - - RF_PlaceSprite(&ob->sprite, ob->x, ob->y, ob->shapenum, spritedraw, ob->priority); - - if (ob->hiteast || ob->hitwest) - ob->xspeed = -ob->xspeed/2; - - if (ob->hitsouth) - { - ob->yspeed = -ob->yspeed/2; - return; - } - - wall = ob->hitnorth; - if (wall) - { - if (ob->yspeed < 0) - ob->yspeed = 0; - - absx = abs(ob->xspeed); - absy = ob->yspeed; - if (absx>absy) - { - if (absx>absy*2) // 22 degrees - { - angle = 0; - speed = absx*286; // x*sqrt(5)/2 - } - else // 45 degrees - { - angle = 1; - speed = absx*362; // x*sqrt(2) - } - } - else - { - if (absy>absx*2) // 90 degrees - { - angle = 3; - speed = absy*256; - } - else - { - angle = 2; // 67 degrees - speed = absy*286; // y*sqrt(5)/2 - } - } - if (ob->xspeed > 0) - angle = 7-angle; - - speed >>= 1; - newangle = bounceangle[ob->hitnorth][angle]; - switch (newangle) - { - case 0: - ob->xspeed = speed / 286; - ob->yspeed = -ob->xspeed / 2; - break; - case 1: - ob->xspeed = speed / 362; - ob->yspeed = -ob->xspeed; - break; - case 2: - ob->yspeed = -(speed / 286); - ob->xspeed = -ob->yspeed / 2; - break; - case 3: - - case 4: - ob->xspeed = 0; - ob->yspeed = -(speed / 256); - break; - case 5: - ob->yspeed = -(speed / 286); - ob->xspeed = ob->yspeed / 2; - break; - case 6: - ob->xspeed = ob->yspeed = -(speed / 362); - break; - case 7: - ob->xspeed = -(speed / 286); - ob->yspeed = ob->xspeed / 2; - break; - - case 8: - ob->xspeed = -(speed / 286); - ob->yspeed = -ob->xspeed / 2; - break; - case 9: - ob->xspeed = -(speed / 362); - ob->yspeed = -ob->xspeed; - break; - case 10: - ob->yspeed = speed / 286; - ob->xspeed = -ob->yspeed / 2; - break; - case 11: - - case 12: - ob->xspeed = 0; - ob->yspeed = -(speed / 256); - break; - case 13: - ob->yspeed = speed / 286; - ob->xspeed = ob->yspeed / 2; - break; - case 14: - ob->xspeed = speed / 362; - ob->yspeed = speed / 362; - break; - case 15: - ob->xspeed = speed / 286; - ob->yspeed = ob->xspeed / 2; - break; - } - - if (speed < 256*16) - { - ChangeState(ob, ob->state->nextstate); - } - } -} - -/* -============================================================================= - - BONUS ITEMS -temp1 = bonus type -temp2 = base shape number -temp3 = last animated shape number +1 - -============================================================================= -*/ - -statetype s_bonus1 = {0, 0, step, false, false, 20, 0, 0, T_Bonus, NULL, R_Draw, &s_bonus2}; -statetype s_bonus2 = {0, 0, step, false, false, 20, 0, 0, T_Bonus, NULL, R_Draw, &s_bonus1}; -statetype s_bonusfly1 = {0, 0, stepthink, false, false, 20, 0, 0, T_FlyBonus, NULL, R_Draw, &s_bonusfly2}; -statetype s_bonusfly2 = {0, 0, stepthink, false, false, 20, 0, 0, T_FlyBonus, NULL, R_Draw, &s_bonusfly1}; -statetype s_bonusrise = {0, 0, slide, false, false, 40, 0, 8, NULL, NULL, R_Draw, NULL}; -statetype s_splash1 = {VIVAPOOF1SPR, VIVAPOOF1SPR, step, false, false, 8, 0, 0, NULL, NULL, R_Draw, &s_splash2}; -statetype s_splash2 = {VIVAPOOF2SPR, VIVAPOOF2SPR, step, false, false, 8, 0, 0, NULL, NULL, R_Draw, &s_splash3}; -statetype s_splash3 = {VIVAPOOF3SPR, VIVAPOOF3SPR, step, false, false, 8, 0, 0, NULL, NULL, R_Draw, &s_splash4}; -statetype s_splash4 = {VIVAPOOF4SPR, VIVAPOOF4SPR, step, false, false, 8, 0, 0, NULL, NULL, R_Draw, NULL}; - -Uint16 bonusshape[] = { - REDGEM1SPR, YELLOWGEM1SPR, BLUEGEM1SPR, GREENGEM1SPR, - SUGAR1ASPR, SUGAR2ASPR, SUGAR3ASPR, - SUGAR4ASPR, SUGAR5ASPR, SUGAR6ASPR, - ONEUPASPR, STUNCLIP1SPR, DOORCARD1SPR -}; - -/* -=========================== -= -= SpawnBonus -= -=========================== -*/ - -void SpawnBonus(Uint16 tileX, Uint16 tileY, Uint16 type) -{ - GetNewObj(false); - new->needtoclip = cl_noclip; - new->priority = 2; - new->obclass = bonusobj; - new->x = CONVERT_TILE_TO_GLOBAL(tileX); - new->y = CONVERT_TILE_TO_GLOBAL(tileY); - new->ydir = -1; - new->temp1 = type; - new->temp2=new->shapenum = bonusshape[type]; - new->temp3 = new->temp2+2; - NewState(new, &s_bonus1); -} - -/* -=========================== -= -= SpawnSplash -= -=========================== -*/ - -void SpawnSplash(Uint16 tileX, Uint16 tileY) -{ - GetNewObj(true); - new->needtoclip = cl_noclip; - new->priority = 3; - new->obclass = inertobj; - new->x = CONVERT_TILE_TO_GLOBAL(tileX); - new->y = CONVERT_TILE_TO_GLOBAL(tileY); - NewState(new, &s_splash1); -} - -/* -=========================== -= -= T_Bonus -= -=========================== -*/ - -void T_Bonus(objtype *ob) -{ - if (++ob->shapenum == ob->temp3) - ob->shapenum = ob->temp2; -} - -/* -=========================== -= -= T_FlyBonus -= -=========================== -*/ - -void T_FlyBonus(objtype *ob) -{ - if (ob->hitnorth) - ob->state = &s_bonus1; - - if (++ob->shapenum == ob->temp3) - ob->shapenum = ob->temp2; - - DoGravity(ob); -} - -/* -============================================================================= - - TELEPORT EFFECTS - -============================================================================= -*/ - -statetype s_teleport1 = {TELEPORTSPARK1SPR, TELEPORTSPARK1SPR, step, false, false, 6, 0, 0, NULL, NULL, R_Draw, &s_teleport2}; -statetype s_teleport2 = {TELEPORTSPARK2SPR, TELEPORTSPARK2SPR, step, false, false, 6, 0, 0, NULL, NULL, R_Draw, &s_teleport1}; -statetype s_teleportzap1 = {TELEPORTZAP1SPR, TELEPORTZAP1SPR, step, false, false, 6, 0, 0, NULL, NULL, R_Draw, &s_teleportzap2}; -statetype s_teleportzap2 = {TELEPORTZAP2SPR, TELEPORTZAP2SPR, step, false, false, 6, 0, 0, NULL, NULL, R_Draw, &s_teleportzap1}; - -/* -=========================== -= -= SpawnTeleport -= -=========================== -*/ - -void SpawnTeleport(void) -{ - GetNewObj(true); - new->priority = 3; - new->needtoclip = cl_noclip; - new->obclass = teleporterobj; - new->x = CONVERT_TILE_TO_GLOBAL(player->tileleft) - 8*PIXGLOBAL; - new->y = CONVERT_TILE_TO_GLOBAL(player->tilebottom) - 5*TILEGLOBAL; - NewState(new, &s_teleport1); - - GetNewObj(true); - new->priority = 3; - new->needtoclip = cl_noclip; - new->obclass = teleporterobj; - new->x = CONVERT_TILE_TO_GLOBAL(player->tileleft); - new->y = CONVERT_TILE_TO_GLOBAL(player->tiletop) - 8*PIXGLOBAL; - NewState(new, &s_teleportzap1); - - SD_PlaySound(SND_TELEPORT); -} - -/* -============================================================================= - - FUSE FLASH - -============================================================================= -*/ - -statetype s_fuseflash1 = {FUSEFLASH1SPR, FUSEFLASH1SPR, step, false, false, 10, 0, 0, NULL, NULL, R_Draw, &s_fuseflash2}; -statetype s_fuseflash2 = {FUSEFLASH2SPR, FUSEFLASH2SPR, step, false, false, 20, 0, 0, NULL, NULL, R_Draw, &s_fuseflash3}; -statetype s_fuseflash3 = {FUSEFLASH3SPR, FUSEFLASH3SPR, step, false, false, 10, 0, 0, NULL, NULL, R_Draw, NULL}; - -/* -=========================== -= -= SpawnFuseFlash -= -=========================== -*/ - -void SpawnFuseFlash(Uint16 tileX, Uint16 tileY) -{ - GetNewObj(true); - new->priority = 3; - new->needtoclip = cl_noclip; - new->obclass = teleporterobj; - new->x = CONVERT_TILE_TO_GLOBAL(tileX-1); - new->y = CONVERT_TILE_TO_GLOBAL(tileY); - NewState(new, &s_fuseflash1); - SD_PlaySound(SND_BIGSPARK); -} - -/* -============================================================================= - - DEAD MACHINE - -============================================================================= -*/ - -statetype s_deadmachine = {-1, -1, step, false, false, 60, 0, 0, T_DeadMachine, NULL, R_Draw, NULL}; - -/* -=========================== -= -= SpawnDeadMachine -= -=========================== -*/ - -void SpawnDeadMachine(void) -{ - GetNewObj(false); - new->active = ac_allways; - new->needtoclip = cl_noclip; - NewState(new, &s_deadmachine); -} - -/* -=========================== -= -= T_DeadMachine -= -=========================== -*/ - -#pragma argsused -void T_DeadMachine(objtype *ob) -{ - if (mapon == 12) - { - playstate = ex_qedbroke; - } - else - { - playstate = ex_fusebroke; - } -} - -/* -============================================================================= - - PLATFORMS - -============================================================================= -*/ - -statetype s_platform = {PLATFORMSPR, PLATFORMSPR, think, false, false, 0, 0, 0, T_Platform, NULL, R_Draw, NULL}; -statetype s_slotplat1 = {SLOTPLAT1SPR, SLOTPLAT1SPR, stepthink, false, false, 0, 0, 0, T_Slotplat, NULL, R_Draw, &s_slotplat2}; -statetype s_slotplat2 = {SLOTPLAT2SPR, SLOTPLAT2SPR, stepthink, false, false, 0, 0, 0, T_Slotplat, NULL, R_Draw, &s_slotplat1}; -// BUG? the slotplat states have a tictime of 0, so they never transition to the next state - -/* -=========================== -= -= SpawnPlatform -= -=========================== -*/ - -void SpawnPlatform(Uint16 tileX, Uint16 tileY, Sint16 dir, Sint16 type) -{ - GetNewObj(false); - new->obclass = platformobj; - new->active = ac_allways; - new->priority = 0; - new->x = CONVERT_TILE_TO_GLOBAL(tileX); - new->y = CONVERT_TILE_TO_GLOBAL(tileY); - switch (dir) - { - case 0: - new->xdir = 0; - new->ydir = -1; - break; - case 1: - new->xdir = 1; - new->ydir = 0; - break; - case 2: - new->xdir = 0; - new->ydir = 1; - break; - case 3: - new->xdir = -1; - new->ydir = 0; - } - if (type) - { - new->x += 4*PIXGLOBAL; - new->y += 4*PIXGLOBAL; - NewState(new, &s_slotplat1); - } - else - { - NewState(new, &s_platform); - } -} - -/* -=========================== -= -= T_Platform -= -=========================== -*/ - -void T_Platform(objtype *ob) -{ - Uint16 newpos, newtile; - - // - // this code could be executed twice during the same frame because the - // object's animation/state changed during that frame, so don't update - // anything if we already have movement for the current frame i.e. the - // update code has already been executed this frame - // - if (!xtry && !ytry) - { - xtry = ob->xdir * 12 * tics; - ytry = ob->ydir * 12 * tics; - - if (ob->xdir == 1) - { - newpos = ob->right + xtry; - newtile = CONVERT_GLOBAL_TO_TILE(newpos); - if (ob->tileright != newtile) - { - if (*(mapsegs[2]+mapbwidthtable[ob->tiletop]/2 + newtile) == PLATFORMBLOCK) - { - ob->xdir = -1; - xtry = xtry - (newpos & 0xFF); - } - } - } - else if (ob->xdir == -1) - { - newpos = ob->left + xtry; - newtile = CONVERT_GLOBAL_TO_TILE(newpos); - if (ob->tileleft != newtile) - { - if (*(mapsegs[2]+mapbwidthtable[ob->tiletop]/2 + newtile) == PLATFORMBLOCK) - { - ob->xdir = 1; - xtry = xtry + (TILEGLOBAL - (newpos & 0xFF)); - } - } - } - else if (ob->ydir == 1) - { - newpos = ob->bottom + ytry; - newtile = CONVERT_GLOBAL_TO_TILE(newpos); - if (ob->tilebottom != newtile) - { - if (*(mapsegs[2]+mapbwidthtable[newtile]/2 + ob->tileleft) == PLATFORMBLOCK) - { - if (*(mapsegs[2]+mapbwidthtable[newtile-2]/2 + ob->tileleft) == PLATFORMBLOCK) - { - ytry = 0; - ob->needtoreact = true; - } - else - { - ob->ydir = -1; - ytry = ytry - (newpos & 0xFF); - } - } - } - } - else if (ob->ydir == -1) - { - newpos = ob->top + ytry; - newtile = CONVERT_GLOBAL_TO_TILE(newpos); - if (ob->tiletop != newtile) - { - if (*(mapsegs[2]+mapbwidthtable[newtile]/2 + ob->tileleft) == PLATFORMBLOCK) - { - if (*(mapsegs[2]+mapbwidthtable[newtile+2]/2 + ob->tileleft) == PLATFORMBLOCK) - { - ytry = 0; - ob->needtoreact = true; - } - else - { - ob->ydir = 1; - ytry = ytry + (TILEGLOBAL - (newpos & 0xFF)); - } - } - } - } - } -} - -/* -=========================== -= -= T_Slotplat -= -=========================== -*/ - -void T_Slotplat(objtype *ob) -{ - Uint16 newpos, newtile; - - // - // this code could be executed twice during the same frame because the - // object's animation/state changed during that frame, so don't update - // anything if we already have movement for the current frame i.e. the - // update code has already been executed this frame - // - if (!xtry && !ytry) - { - xtry = ob->xdir * 12 * tics; - ytry = ob->ydir * 12 * tics; - - if (ob->xdir == 1) - { - newpos = ob->right + xtry; - newtile = CONVERT_GLOBAL_TO_TILE(newpos); - if (ob->tileright != newtile) - { - if (*(mapsegs[2]+mapbwidthtable[ob->tiletop]/2 + newtile) == PLATFORMBLOCK) - { - ob->xdir = -1; - xtry = xtry - (newpos & 0xFF); - } - } - } - else if (ob->xdir == -1) - { - newpos = ob->left + xtry; - newtile = CONVERT_GLOBAL_TO_TILE(newpos); - if (ob->tileleft != newtile) - { - if (*(mapsegs[2]+mapbwidthtable[ob->tiletop]/2 + newtile) == PLATFORMBLOCK) - { - ob->xdir = 1; - xtry = xtry + (TILEGLOBAL - (newpos & 0xFF)); - } - } - } - else if (ob->ydir == 1) - { - newpos = ob->bottom + ytry; - newtile = CONVERT_GLOBAL_TO_TILE(newpos); - if (ob->tilebottom != newtile) - { - if (*(mapsegs[2]+mapbwidthtable[newtile]/2 + ob->tileleft + 1) == PLATFORMBLOCK) - { - if (*(mapsegs[2]+mapbwidthtable[newtile-2]/2 + ob->tileleft) == PLATFORMBLOCK) // BUG? '+ 1' is missing after 'tileleft' - { - ytry = 0; - ob->needtoreact = true; - } - else - { - ob->ydir = -1; - ytry = ytry - (newpos & 0xFF); - } - } - } - } - else if (ob->ydir == -1) - { - newpos = ob->top + ytry; - newtile = CONVERT_GLOBAL_TO_TILE(newpos); - if (ob->tiletop != newtile) - { - if (*(mapsegs[2]+mapbwidthtable[newtile]/2 + ob->tileleft + 1) == PLATFORMBLOCK) - { - if (*(mapsegs[2]+mapbwidthtable[newtile+2]/2 + ob->tileleft + 1) == PLATFORMBLOCK) - { - ytry = 0; - ob->needtoreact = true; - } - else - { - ob->ydir = 1; - ytry = ytry + (TILEGLOBAL - (newpos & 0xFF)); - } - } - } - } - } -} - -/* -============================================================================= - - DROPPING PLATFORM - -temp1 = initial y position - -============================================================================= -*/ - -statetype s_dropplatsit = {PLATFORMSPR, PLATFORMSPR, think, false, false, 0, 0, 0, T_DropPlatSit, NULL, R_Draw, NULL}; -statetype s_dropplatfall = {PLATFORMSPR, PLATFORMSPR, think, false, false, 0, 0, 0, T_DropPlatFall, NULL, R_Draw, NULL}; -statetype s_dropplatrise = {PLATFORMSPR, PLATFORMSPR, slidethink, false, false, 0, 0, -32, T_DropPlatRise, NULL, R_Draw, NULL}; - -/* -=========================== -= -= SpawnDropPlat -= -=========================== -*/ - -void SpawnDropPlat(Uint16 tileX, Uint16 tileY) -{ - GetNewObj(false); - new->obclass = platformobj; - new->active = ac_allways; - new->priority = 0; - new->x = CONVERT_TILE_TO_GLOBAL(tileX); - new->y=new->temp1 = CONVERT_TILE_TO_GLOBAL(tileY); - new->xdir = 0; - new->ydir = 1; - new->needtoclip = cl_noclip; - NewState(new, &s_dropplatsit); -} - -/* -=========================== -= -= T_DropPlatSit -= -=========================== -*/ - -void T_DropPlatSit(objtype *ob) -{ - if (gamestate.riding == ob) - { - ytry = tics << 4; //tics * 16; - ob->yspeed = 0; - if (ob->y + ytry - ob->temp1 >= 8*PIXGLOBAL) - ob->state = &s_dropplatfall; - } -} - -/* -=========================== -= -= T_DropPlatFall -= -=========================== -*/ - -void T_DropPlatFall(objtype *ob) -{ - Uint16 newpos, newtile; - - DoGravity(ob); - -#if 0 - // bugfix: don't skip a tile (this is present in Keen 4, but missing in 5 & 6) - if (ytry >= 15*PIXGLOBAL) - ytry = 15*PIXGLOBAL; -#endif - - newpos = ob->bottom + ytry; - newtile = CONVERT_GLOBAL_TO_TILE(newpos); - if (ob->tilebottom != newtile) - { - if (*(mapsegs[2]+mapbwidthtable[newtile]/2 + ob->tileleft) == PLATFORMBLOCK) - { - ytry = 0xFF - (ob->bottom & 0xFF); - if (gamestate.riding != ob) - ob->state = &s_dropplatrise; - } - } -} - -/* -=========================== -= -= T_DropPlatRise -= -=========================== -*/ - -void T_DropPlatRise(objtype *ob) -{ - if (gamestate.riding == ob) - { - ob->yspeed = 0; - ob->state = &s_dropplatfall; - } - else if (ob->y <= ob->temp1) - { - ytry = ob->temp1 - ob->y; - ob->state = &s_dropplatsit; - } -} - -/* -============================================================================= - - STATIC PLATFORM - -temp1 = initial y position (is set but never used) - -============================================================================= -*/ - -statetype s_statplat = {PLATFORMSPR, PLATFORMSPR, step, false, false, 32000, 0, 0, NULL, NULL, R_Draw, &s_statplat}; - -/* -=========================== -= -= SpawnStaticPlat -= -=========================== -*/ - -void SpawnStaticPlat(Uint16 tileX, Uint16 tileY) -{ - GetNewObj(false); - new->obclass = platformobj; - new->active = ac_yes; - new->priority = 0; - new->x = CONVERT_TILE_TO_GLOBAL(tileX); - new->y=new->temp1 = CONVERT_TILE_TO_GLOBAL(tileY); - new->xdir = 0; - new->ydir = 1; - new->needtoclip = cl_noclip; - NewState(new, &s_statplat); -} - -/* -============================================================================= - - GO PLATFORMS - -temp1 = direction -temp2 = countdown to next dir check - -============================================================================= -*/ - -statetype s_goplat = {PLATFORMSPR, PLATFORMSPR, think, false, false, 0, 0, 0, T_GoPlat, NULL, R_Draw, NULL}; -statetype s_slotgoplat1 = {SLOTPLAT1SPR, SLOTPLAT1SPR, stepthink, false, false, 0, 0, 0, T_GoSlotPlat, NULL, R_Draw, &s_slotgoplat2}; -statetype s_slotgoplat2 = {SLOTPLAT2SPR, SLOTPLAT2SPR, stepthink, false, false, 0, 0, 0, T_GoSlotPlat, NULL, R_Draw, &s_slotgoplat1}; -// BUG? the slotgoplat states have a tictime of 0, so they never transition to the next state - -/* -=========================== -= -= SpawnGoPlat -= -=========================== -*/ - -void SpawnGoPlat(Uint16 tileX, Uint16 tileY, Sint16 dir, Sint16 type) -{ - GetNewObj(false); - new->obclass = platformobj; - new->active = ac_allways; - new->priority = 0; - new->x = CONVERT_TILE_TO_GLOBAL(tileX); - new->y = CONVERT_TILE_TO_GLOBAL(tileY); - new->xdir = 0; - new->ydir = 1; - new->needtoclip = cl_noclip; - if (type) - { - new->x += 4*PIXGLOBAL; - new->y += 4*PIXGLOBAL; - NewState(new, &s_slotgoplat1); - } - else - { - NewState(new, &s_goplat); - } - *(mapsegs[2]+mapbwidthtable[tileY]/2 + tileX) = DIRARROWSTART + dir; - new->temp1 = dir; - new->temp2 = TILEGLOBAL; -} - -/* -=========================== -= -= T_GoPlat -= -=========================== -*/ - -void T_GoPlat(objtype *ob) -{ - Uint16 move; - Uint16 tx, ty; - Sint16 dir; - - // - // this code could be executed twice during the same frame because the - // object's animation/state changed during that frame, so don't update - // anything if we already have movement for the current frame i.e. the - // update code has already been executed this frame - // - if (!xtry && !ytry) - { - move = tics * 12; - if (ob->temp2 > move) - { - ob->temp2 = ob->temp2 - move; - - dir = pdirx[ob->temp1]; - if (dir == 1) - { - xtry = xtry + move; - } - else if (dir == -1) - { - xtry = xtry + -move; - } - - dir = pdiry[ob->temp1]; - if (dir == 1) - { - ytry = ytry + move; - } - else if (dir == -1) - { - ytry = ytry + -move; - } - } - else - { - dir = pdirx[ob->temp1]; - if (dir == 1) - { - xtry += ob->temp2; - } - else if (dir == -1) - { - xtry += -ob->temp2; - } - - dir = pdiry[ob->temp1]; - if (dir == 1) - { - ytry += ob->temp2; - } - else if (dir == -1) - { - ytry += -ob->temp2; - } - - tx = CONVERT_GLOBAL_TO_TILE(ob->x + xtry); - ty = CONVERT_GLOBAL_TO_TILE(ob->y + ytry); - ob->temp1 = *(mapsegs[2]+mapbwidthtable[ty]/2 + tx) - DIRARROWSTART; - if (ob->temp1 < arrow_North || ob->temp1 > arrow_None) - { - char error[60] = "Goplat moved to a bad spot: "; - char buf[5] = ""; - - strcat(error, itoa(ob->x, buf, 16)); - strcat(error, ","); - strcat(error, itoa(ob->y, buf, 16)); - Quit(error); - } - - move -= ob->temp2; - ob->temp2 = TILEGLOBAL - move; - - dir = pdirx[ob->temp1]; - if (dir == 1) - { - xtry = xtry + move; - } - else if (dir == -1) - { - xtry = xtry - move; - } - - dir = pdiry[ob->temp1]; - if (dir == 1) - { - ytry = ytry + move; - } - else if (dir == -1) - { - ytry = ytry - move; - } - } - } -} - -/* -=========================== -= -= T_GoSlotPlat -= -=========================== -*/ - -void T_GoSlotPlat(objtype *ob) -{ - Uint16 move; - Uint16 tx, ty; - Sint16 dir; - - // - // this code could be executed twice during the same frame because the - // object's animation/state changed during that frame, so don't update - // anything if we already have movement for the current frame i.e. the - // update code has already been executed this frame - // - if (!xtry && !ytry) - { - move = tics * 12; - if (ob->temp2 > move) - { - ob->temp2 = ob->temp2 - move; - - dir = pdirx[ob->temp1]; - if (dir == 1) - { - xtry = xtry + move; - } - else if (dir == -1) - { - xtry = xtry + -move; - } - - dir = pdiry[ob->temp1]; - if (dir == 1) - { - ytry = ytry + move; - } - else if (dir == -1) - { - ytry = ytry + -move; - } - } - else - { - dir = pdirx[ob->temp1]; - if (dir == 1) - { - xtry += ob->temp2; - } - else if (dir == -1) - { - xtry += -ob->temp2; - } - - dir = pdiry[ob->temp1]; - if (dir == 1) - { - ytry += ob->temp2; - } - else if (dir == -1) - { - ytry += -ob->temp2; - } - - tx = CONVERT_GLOBAL_TO_TILE(ob->x + xtry + 4*PIXGLOBAL); - ty = CONVERT_GLOBAL_TO_TILE(ob->y + ytry + 4*PIXGLOBAL); - ob->temp1 = *(mapsegs[2]+mapbwidthtable[ty]/2 + tx) - DIRARROWSTART; - if (ob->temp1 < arrow_North || ob->temp1 > arrow_None) - { - Quit("Goplat moved to a bad spot!"); - } - - move -= ob->temp2; - ob->temp2 = TILEGLOBAL - move; - - dir = pdirx[ob->temp1]; - if (dir == 1) - { - xtry = xtry + move; - } - else if (dir == -1) - { - xtry = xtry - move; - } - - dir = pdiry[ob->temp1]; - if (dir == 1) - { - ytry = ytry + move; - } - else if (dir == -1) - { - ytry = ytry - move; - } - } - } -} - -/* -============================================================================= - - VOLTEFACE - -temp1 = direction -temp2 = countdown to next dir check - -============================================================================= -*/ - -statetype s_volte1 = {VOLTEFACE1SPR, VOLTEFACE1SPR, stepthink, false, false, 6, 0, 0, T_Volte, C_Volte, R_Draw, &s_volte2}; -statetype s_volte2 = {VOLTEFACE2SPR, VOLTEFACE2SPR, stepthink, false, false, 6, 0, 0, T_Volte, C_Volte, R_Draw, &s_volte3}; -statetype s_volte3 = {VOLTEFACE3SPR, VOLTEFACE3SPR, stepthink, false, false, 6, 0, 0, T_Volte, C_Volte, R_Draw, &s_volte4}; -statetype s_volte4 = {VOLTEFACE4SPR, VOLTEFACE4SPR, stepthink, false, false, 6, 0, 0, T_Volte, C_Volte, R_Draw, &s_volte1}; -statetype s_voltestun = {VOLTEFACESTUNSPR, VOLTEFACESTUNSPR, step, false, false, 300, 0, 0, NULL, NULL, R_Draw, &s_volte1}; - -/* -=========================== -= -= SpawnVolte -= -=========================== -*/ - -void SpawnVolte(Uint16 tileX, Uint16 tileY) -{ - Uint16 dir; - Uint16 far *map; - - GetNewObj(false); - new->obclass = volteobj; - new->active = ac_allways; - new->priority = 2; - new->x = CONVERT_TILE_TO_GLOBAL(tileX); - new->y = CONVERT_TILE_TO_GLOBAL(tileY); - new->needtoclip = cl_noclip; - NewState(new, &s_volte1); - map = mapsegs[2] + mapbwidthtable[tileY]/2 + tileX; - if (map[-1] == DIRARROWSTART + arrow_East) - { - dir = arrow_East; - } - else if (map[1] == DIRARROWSTART + arrow_West) - { - dir = arrow_West; - } - else if (*(map-mapwidth) == DIRARROWSTART + arrow_South) - { - dir = arrow_South; - } - else if (*(map+mapwidth) == DIRARROWSTART + arrow_North) - { - dir = arrow_North; - } - map[0] = dir + DIRARROWSTART; - new->temp1 = dir; - new->temp2 = TILEGLOBAL; -} - -/* -=========================== -= -= T_Volte -= -=========================== -*/ - -void T_Volte(objtype *ob) -{ - Uint16 move; - Uint16 tx, ty; - Sint16 dir; - - // - // this code could be executed twice during the same frame because the - // object's animation/state changed during that frame, so don't update - // anything if we already have movement for the current frame i.e. the - // update code has already been executed this frame - // - if (!xtry && !ytry) - { - move = tics << 5; - if (ob->temp2 > move) - { - ob->temp2 = ob->temp2 - move; - - dir = pdirx[ob->temp1]; - if (dir == 1) - { - xtry = xtry + move; - } - else if (dir == -1) - { - xtry = xtry + -move; - } - - dir = pdiry[ob->temp1]; - if (dir == 1) - { - ytry = ytry + move; - } - else if (dir == -1) - { - ytry = ytry + -move; - } - } - else - { - dir = pdirx[ob->temp1]; - if (dir == 1) - { - xtry += ob->temp2; - } - else if (dir == -1) - { - xtry += -ob->temp2; - } - - dir = pdiry[ob->temp1]; - if (dir == 1) - { - ytry += ob->temp2; - } - else if (dir == -1) - { - ytry += -ob->temp2; - } - - tx = CONVERT_GLOBAL_TO_TILE(ob->x + xtry); - ty = CONVERT_GLOBAL_TO_TILE(ob->y + ytry); - ob->temp1 = *(mapsegs[2]+mapbwidthtable[ty]/2 + tx) - DIRARROWSTART; - if (ob->temp1 < arrow_North || ob->temp1 > arrow_None) - { - char error[60] = "Volte moved to a bad spot: "; - char buf[5] = ""; - - strcat(error, itoa(ob->x, buf, 16)); - strcat(error, ","); - strcat(error, itoa(ob->y, buf, 16)); - Quit(error); - } - - move -= ob->temp2; - ob->temp2 = TILEGLOBAL - move; - - dir = pdirx[ob->temp1]; - if (dir == 1) - { - xtry = xtry + move; - } - else if (dir == -1) - { - xtry = xtry - move; - } - - dir = pdiry[ob->temp1]; - if (dir == 1) - { - ytry = ytry + move; - } - else if (dir == -1) - { - ytry = ytry - move; - } - } - } -} - -/* -=========================== -= -= C_Volte -= -=========================== -*/ - -void C_Volte(objtype *ob, objtype *hit) -{ - if (hit->obclass == keenobj) - { - KillKeen(); - } - else if (hit->obclass == stunshotobj) - { - ExplodeShot(hit); - ChangeState(ob, &s_voltestun); - } -} - -/* -============================================================================= - - SNEAKY PLATFORM - -temp1 = initial x position (is set but never used) - -============================================================================= -*/ - -statetype s_sneakplatsit = {PLATFORMSPR, PLATFORMSPR, think, false, false, 0, 0, 0, T_SneakPlat, NULL, R_Draw, NULL}; -statetype s_sneakplatdodge = {PLATFORMSPR, PLATFORMSPR, slide, false, false, 48, 32, 0, NULL, NULL, R_Draw, &s_sneakplatreturn}; -statetype s_sneakplatreturn = {PLATFORMSPR, PLATFORMSPR, slide, false, false, 96, -16, 0, NULL, NULL, R_Draw, &s_sneakplatsit}; - -/* -=========================== -= -= SpawnSneakPlat -= -=========================== -*/ - -void SpawnSneakPlat(Uint16 tileX, Uint16 tileY) -{ - GetNewObj(false); - new->obclass = platformobj; - new->active = ac_allways; - new->priority = 0; - new->x=new->temp1 = CONVERT_TILE_TO_GLOBAL(tileX); - new->y = CONVERT_TILE_TO_GLOBAL(tileY); - new->xdir = 0; - new->ydir = 1; - new->needtoclip = cl_noclip; - NewState(new, &s_sneakplatsit); -} - -/* -=========================== -= -= T_SneakPlat -= -=========================== -*/ - -void T_SneakPlat(objtype *ob) -{ - Sint16 dist; - - if (player->state != &s_keenjump1) - return; - - if (player->xdir == 1) - { - dist = ob->left-player->right; - if (dist > 4*TILEGLOBAL || dist < 0) - return; - } - else - { - dist = player->left-ob->right; - if (dist > 4*TILEGLOBAL || dist < 0) - return; - } - dist = player->y - ob->y; - if (dist < -6*TILEGLOBAL || dist > 6*TILEGLOBAL) - return; - - ob->xdir = player->xdir; - ob->state = &s_sneakplatdodge; -} - -/* -============================================================================= - - CANNON - -temp1 = direction - -============================================================================= -*/ - -statetype s_cannon = {0, 0, step, false, false, 120, 0, 0, NULL, NULL, R_Draw, &s_cannonfire}; -statetype s_cannonfire = {0, 0, step, true, false, 1, 0, 0, T_Cannon, NULL, R_Draw, &s_cannon}; -statetype s_cshot1 = {LASER1SPR, LASER1SPR, stepthink, false, false, 8, 0, 0, T_Velocity, C_CShot, R_CShot, &s_cshot2}; -statetype s_cshot2 = {LASER2SPR, LASER2SPR, stepthink, false, false, 8, 0, 0, T_Velocity, C_CShot, R_CShot, &s_cshot3}; -statetype s_cshot3 = {LASER3SPR, LASER3SPR, stepthink, false, false, 8, 0, 0, T_Velocity, C_CShot, R_CShot, &s_cshot4}; -statetype s_cshot4 = {LASER4SPR, LASER4SPR, stepthink, false, false, 8, 0, 0, T_Velocity, C_CShot, R_CShot, &s_cshot1}; -statetype s_cshothit1 = {LASERHIT1SPR, LASERHIT1SPR, step, false, false, 10, 0, 0, NULL, NULL, R_Draw, &s_cshothit2}; -statetype s_cshothit2 = {LASERHIT2SPR, LASERHIT2SPR, step, false, false, 10, 0, 0, NULL, NULL, R_Draw, NULL}; - -/* -=========================== -= -= SpawnCannon -= -=========================== -*/ - -void SpawnCannon(Uint16 tileX, Uint16 tileY, Sint16 dir) -{ - GetNewObj(false); - new->obclass = cannonobj; - new->active = ac_yes; - new->tileright = new->tileleft = tileX; - new->tiletop = new->tilebottom = tileY; - new->x = new->left = new->right = CONVERT_TILE_TO_GLOBAL(tileX); - new->y = new->top = new->bottom = CONVERT_TILE_TO_GLOBAL(tileY); - new->temp1 = dir; - NewState(new, &s_cannon); -} - -/* -=========================== -= -= T_Cannon -= -=========================== -*/ - -void T_Cannon(objtype *ob) -{ - GetNewObj(true); - new->obclass = mshotobj; - new->active = ac_removable; - new->x = ob->x; - new->y = ob->y; - switch (ob->temp1) - { - case 0: - new->yspeed = -64; - break; - case 1: - new->xspeed = 64; - break; - case 2: - new->yspeed = 64; - break; - case 3: - new->xspeed = -64; - } - NewState(new, &s_cshot1); - SD_PlaySound(SND_ENEMYSHOT); -} - -/* -=========================== -= -= C_CShot -= -=========================== -*/ - -void C_CShot(objtype *ob, objtype *hit) -{ - if (hit->obclass == keenobj) - { - KillKeen(); - ChangeState(ob, &s_cshothit1); - } -} - -/* -=========================== -= -= R_CShot -= -=========================== -*/ - -void R_CShot(objtype *ob) -{ - if (ob->hitnorth || ob->hiteast || ob->hitsouth || ob->hitwest) - { - SD_PlaySound(SND_ENEMYSHOTEXPLODE); - ChangeState(ob, &s_cshothit1); - } - RF_PlaceSprite(&ob->sprite, ob->x, ob->y, ob->shapenum, spritedraw, ob->priority); -} \ No newline at end of file