X-Git-Url: http://4ch.mooo.com/gitweb/?p=16.git;a=blobdiff_plain;f=16%2Fkeen456%2FKEEN4-6%2FKEEN5%2FK5_ACT3.C;fp=16%2Fkeen456%2FKEEN4-6%2FKEEN5%2FK5_ACT3.C;h=0000000000000000000000000000000000000000;hp=a0fa9c78da821c6e6d7f61ed68c0c010b846ac7a;hb=a387b1ff6f02e2da93e870a330af886d1c8233da;hpb=7d1948e210bb7b58af0a0412e71f2a0a0a2010af diff --git a/16/keen456/KEEN4-6/KEEN5/K5_ACT3.C b/16/keen456/KEEN4-6/KEEN5/K5_ACT3.C deleted file mode 100755 index a0fa9c78..00000000 --- a/16/keen456/KEEN4-6/KEEN5/K5_ACT3.C +++ /dev/null @@ -1,2142 +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_ACT3.C -========= - -Contains the following actor types (in this order): - -- Shikadi Mine -- Robo Red -- Spirogrip -- Spindred -- Shikadi Master -- Shikadi -- Shockshund -- Sphereful -- Scottie -- QED - -*/ - -#include "CK_DEF.H" - -/* -============================================================================= - - SHIKADI MINE - -temp2 = x position of the "eye", in global units (relative to the mine sprite) -temp3 = y position of the "eye", in global units (relative to the mine sprite) -temp4 = sprite pointer for the "eye" - -============================================================================= -*/ - -static Uint16 dopposite[] = {2, 3, 0, 1, 6, 7, 4, 5, 8}; - -statetype s_mine = {SHIKADIMINESPR, SHIKADIMINESPR, think, false, false, 8, 0, 0, T_Mine, C_Solid, R_Mine, NULL}; -statetype s_minecenter = {SHIKADIMINESPR, SHIKADIMINESPR, think, false, false, 0, 0, 0, T_MineCenter, C_Solid, R_Mine, &s_mineshift}; -statetype s_mineshift = {SHIKADIMINESPR, SHIKADIMINESPR, think, false, false, 0, 0, 0, T_MineShift, C_Solid, R_Mine, &s_mine}; -statetype s_mineboom1 = {SHIKADIMINEPULSE1SPR, SHIKADIMINEPULSE1SPR, step, false, false, 10, 0, 0, NULL, C_Solid, R_Draw, &s_mineboom2}; -statetype s_mineboom2 = {SHIKADIMINEPULSE2SPR, SHIKADIMINEPULSE2SPR, step, false, false, 10, 0, 0, NULL, C_Solid, R_Draw, &s_mineboom3}; -statetype s_mineboom3 = {SHIKADIMINEPULSE1SPR, SHIKADIMINEPULSE1SPR, step, false, false, 10, 0, 0, NULL, C_Solid, R_Draw, &s_mineboom4}; -statetype s_mineboom4 = {SHIKADIMINEPULSE2SPR, SHIKADIMINEPULSE2SPR, step, false, false, 10, 0, 0, T_MineFrag, C_Solid, R_Draw, &s_mineboom5}; -statetype s_mineboom5 = {SHIKADIMINEBOOM1SPR, SHIKADIMINEBOOM1SPR, step, false, false, 20, 0, 0, NULL, C_Spindread, R_Draw, &s_mineboom6}; -statetype s_mineboom6 = {SHIKADIMINEBOOM2SPR, SHIKADIMINEBOOM2SPR, step, false, false, 20, 0, 0, NULL, C_Spindread, R_Draw, NULL}; -statetype s_minepiece = {SHIKADIMINEPIECESPR, SHIKADIMINEPIECESPR, think, false, false, 8, 0, 0, T_Projectile, C_MineFrag, R_Bounce, NULL}; - -/* -=========================== -= -= SpawnMine -= -=========================== -*/ - -void SpawnMine(Uint16 tileX, Uint16 tileY) -{ - Sint16 i; - - GetNewObj(false); - new->obclass = mineobj; - new->active = ac_yes; - new->needtoclip = cl_noclip; - new->x = CONVERT_TILE_TO_GLOBAL(tileX); - new->y = CONVERT_TILE_TO_GLOBAL(tileY) + -(31*PIXGLOBAL + 1); - new->temp2 = 16*PIXGLOBAL; - new->temp3 = 13*PIXGLOBAL; - NewState(new, &s_mineshift); - new->xspeed = TILEGLOBAL; - - for (i=0; i<=3; i++) - { - if (Walk(new, i)) - break; - } -} - -/* -=========================== -= -= MinePosCheck -= -=========================== -*/ - -boolean MinePosCheck(Uint16 tileX, Uint16 tileY) -{ - Uint16 far *map; - Uint16 x, y, tile; - - map = mapsegs[1] + mapbwidthtable[tileY]/2 + tileX; - for (y=0; y<2; y++) - { - for (x=0; x<3; x++) - { - tile = *(map + y*mapwidth + x); - if (tinf[tile+NORTHWALL] || tinf[tile+EASTWALL] || tinf[tile+SOUTHWALL] || tinf[tile+WESTWALL]) - return false; - } - } - return true; -} - -/* -=========================== -= -= Walk -= -=========================== -*/ - -boolean Walk(objtype *ob, Sint16 dir) -{ - Uint16 tileX, tileY; - - tileX = CONVERT_GLOBAL_TO_TILE(ob->x + xtry); - tileY = CONVERT_GLOBAL_TO_TILE(ob->y + ytry); - - switch (dir) - { - case 0: - if (MinePosCheck(tileX, tileY-1)) - { - ob->xdir = 0; - ob->ydir = -1; - return true; - } - return false; - case 1: - if (MinePosCheck(tileX+1, tileY)) - { - ob->xdir = 1; - ob->ydir = 0; - return true; - } - return false; - case 2: - if (MinePosCheck(tileX, tileY+1)) - { - ob->xdir = 0; - ob->ydir = 1; - return true; - } - return false; - case 3: - if (MinePosCheck(tileX-1, tileY)) - { - ob->xdir = -1; - ob->ydir = 0; - return true; - } - return false; - default: - Quit("Walk: Bad dir"); - } - return false; -} - -/* -=========================== -= -= ChaseThink -= -=========================== -*/ - -void ChaseThink(objtype *ob) -{ - Sint16 temp; - Sint16 xdist, ydist, ydir, xdir; - Sint16 olddir[2], oppdir; - - if (ob->xdir == 1) - { - olddir[0] = 1; - } - else if (ob->xdir == -1) - { - olddir[0] = 3; - } - else if (ob->ydir == -1) - { - olddir[0] = 0; - } - else if (ob->ydir == 1) - { - olddir[0] = 2; - } - oppdir = dopposite[olddir[0]]; - xdist = player->x - (ob->x + xtry); - ydist = player->y - (ob->y + ytry); - xdir = 8; - ydir = 8; - if (xdist > 0) - { - xdir = 1; - } - if (xdist < 0) - { - xdir = 3; - } - if (ydist > 0) - { - ydir = 2; - } - if (ydist < 0) - { - ydir = 0; - } - if (abs(ydist) > abs(xdist)) - { - temp = xdir; - xdir = ydir; - ydir = temp; - } - if (xdir == oppdir) - { - xdir = 8; - } - if (ydir == oppdir) - { - ydir = 8; - } - if (ydir != 8 && Walk(ob, ydir)) - { - return; - } - if (xdir != 8 && Walk(ob, xdir)) - { - return; - } - if (Walk(ob, olddir[0])) - { - return; - } - if (US_RndT() > 0x80) - { - for (temp=0; temp<=3; temp++) - { - if (temp != oppdir && Walk(ob, temp)) - return; - } - } - else - { - for (temp=3; temp>=0; temp--) - { - if (temp != oppdir && Walk(ob, temp)) - return; - } - } - Walk(ob, oppdir); -} - -/* -=========================== -= -= T_Mine -= -=========================== -*/ - -void T_Mine(objtype *ob) -{ - Sint16 oldxdir, oldydir; - Sint16 xdist, ydist; - Sint16 speed; - - xdist = ob->x - player->x; - ydist = ob->y - player->y; - if (xdist <= 2*TILEGLOBAL && xdist >= -5*TILEGLOBAL && ydist <= 3*TILEGLOBAL && ydist >= -5*PIXGLOBAL) - { - SD_PlaySound(SND_MINEEXPLODE); - ob->state = &s_mineboom1; - RF_RemoveSprite((void**)(&ob->temp4)); - } - else - { - speed = tics * 10; - if (ob->xspeed <= speed) - { - xtry = ob->xdir * ob->xspeed; - ytry = ob->ydir * ob->xspeed; // yes, this uses xspeed! - speed -= ob->xspeed; - oldxdir = ob->xdir; - oldydir = ob->ydir; - ChaseThink(ob); - ob->xspeed = TILEGLOBAL; - if (ob->xdir != oldxdir || ob->ydir != oldydir) - { - ob->state = &s_minecenter; - return; - } - } - ob->xspeed -= speed; - xtry += ob->xdir * speed; - ytry += ob->ydir * speed; - } -} - -/* -=========================== -= -= C_Solid -= -=========================== -*/ - -#pragma argsused -void C_Solid(objtype *ob, objtype *hit) -{ - if (hit->obclass == stunshotobj) - { - ExplodeShot(hit); - } -} - -/* -=========================== -= -= C_MineFrag -= -=========================== -*/ - -#pragma argsused -void C_MineFrag(objtype *ob, objtype *hit) -{ - if (hit->obclass == stunshotobj) - { - ExplodeShot(hit); - } - else if (hit->obclass == keenobj) - { - KillKeen(); - } - else if (hit->obclass == qedobj) - { - SpawnFuseFlash(hit->tileleft, hit->tiletop); - SpawnFuseFlash(hit->tileright, hit->tiletop); - SpawnFuseFlash(hit->tileleft, hit->tilebottom); - SpawnFuseFlash(hit->tileright, hit->tilebottom); - RF_MapToMap(0, 0, 16, 11, 4, 2); - RF_MapToMap(4, 0, 16, 13, 4, 2); - SpawnDeadMachine(); - RemoveObj(hit); - } -} - -/* -=========================== -= -= T_MineCenter -= -=========================== -*/ - -void T_MineCenter(objtype *ob) -{ - Sint16 px, py, xdist, ydist; - - xdist = ob->x - player->x; - ydist = ob->y - player->y; - - if (xdist <= 2*TILEGLOBAL && xdist >= -3*TILEGLOBAL && ydist <= 3*TILEGLOBAL && ydist >= -3*TILEGLOBAL) - { - //BUG? this doesn't play a sound - ob->state = &s_mineboom1; - RF_RemoveSprite((void**)&ob->temp4); - } - else - { - ob->needtoreact = true; - - px = 16*PIXGLOBAL; - py = 13*PIXGLOBAL; - - if (ob->temp2 < px) - { - ob->temp2 = ob->temp2 + tics*4; - if (ob->temp2 >= px) - { - ob->temp2 = px; - ob->state = ob->state->nextstate; - } - } - else if (ob->temp2 > px) - { - ob->temp2 = ob->temp2 - tics*4; - if (ob->temp2 <= px) - { - ob->temp2 = px; - ob->state = ob->state->nextstate; - } - } - if (ob->temp3 < py) - { - ob->temp3 = ob->temp3 + tics*4; - if (ob->temp3 >= py) - { - ob->temp3 = py; - ob->state = ob->state->nextstate; - } - } - else if (ob->temp3 > py) - { - ob->temp3 = ob->temp3 - tics*4; - if (ob->temp3 <= py) - { - ob->temp3 = py; - ob->state = ob->state->nextstate; - } - } - } -} - -/* -=========================== -= -= T_MineShift -= -=========================== -*/ - -void T_MineShift(objtype *ob) -{ - Sint16 px, py, xdist, ydist; - - xdist = ob->x - player->x; - ydist = ob->y - player->y; - - if (xdist <= 2*TILEGLOBAL && xdist >= -3*TILEGLOBAL && ydist <= 3*TILEGLOBAL && ydist >= -3*TILEGLOBAL) - { - //BUG? this doesn't play a sound - ob->state = &s_mineboom1; - RF_RemoveSprite((void**)&ob->temp4); - } - else - { - ob->needtoreact = true; - - switch (ob->xdir) - { - case -1: - px = 8*PIXGLOBAL; - break; - case 0: - px = 16*PIXGLOBAL; - break; - case 1: - px = 24*PIXGLOBAL; - } - switch (ob->ydir) - { - case -1: - py = 5*PIXGLOBAL; - break; - case 0: - py = 13*PIXGLOBAL; - break; - case 1: - py = 21*PIXGLOBAL; - } - - if (ob->temp2 < px) - { - ob->temp2 = ob->temp2 + tics*4; - if (ob->temp2 >= px) - { - ob->temp2 = px; - ob->state = ob->state->nextstate; - } - } - else if (ob->temp2 > px) - { - ob->temp2 = ob->temp2 - tics*4; - if (ob->temp2 <= px) - { - ob->temp2 = px; - ob->state = ob->state->nextstate; - } - } - if (ob->temp3 < py) - { - ob->temp3 = ob->temp3 + tics*4; - if (ob->temp3 >= py) - { - ob->temp3 = py; - ob->state = ob->state->nextstate; - } - } - else if (ob->temp3 > py) - { - ob->temp3 = ob->temp3 - tics*4; - if (ob->temp3 <= py) - { - ob->temp3 = py; - ob->state = ob->state->nextstate; - } - } - } -} - -/* -=========================== -= -= T_MineFrag -= -=========================== -*/ - -void T_MineFrag(objtype *ob) -{ - SD_PlaySound(SND_MINEEXPLODE); - - GetNewObj(true); - new->x = ob->x; - new->y = ob->y; - new->xspeed = -(US_RndT()>>3); - new->yspeed = -48; - NewState(new, &s_minepiece); - - GetNewObj(true); - new->x = ob->x + TILEGLOBAL; - new->y = ob->y; - new->xspeed = (US_RndT()>>3); - new->yspeed = -48; - NewState(new, &s_minepiece); - - GetNewObj(true); - new->x = ob->x; - new->y = ob->y; - new->xspeed = (US_RndT()>>4) + 40; - new->yspeed = -24; - NewState(new, &s_minepiece); - - GetNewObj(true); - new->x = ob->x + TILEGLOBAL; - new->y = ob->y; - new->xspeed = -40 - (US_RndT()>>4); - new->yspeed = -24; - NewState(new, &s_minepiece); - - GetNewObj(true); - new->x = ob->x; - new->y = ob->y; - new->xspeed = 24; - new->yspeed = 16; - NewState(new, &s_minepiece); - - GetNewObj(true); - new->x = ob->x + TILEGLOBAL; - new->y = ob->y; - new->xspeed = 24; - new->yspeed = 16; - NewState(new, &s_minepiece); -} - -/* -=========================== -= -= R_Mine -= -=========================== -*/ - -void R_Mine(objtype *ob) -{ - RF_PlaceSprite(&ob->sprite, ob->x, ob->y, ob->shapenum, spritedraw, ob->priority); - RF_PlaceSprite((void**)&ob->temp4, ob->x+ob->temp2, ob->y+ob->temp3, SHIKADIMINEEYESPR, spritedraw, 2); -} - -/* -============================================================================= - - ROBO RED - -temp1 = number of shots to fire - -============================================================================= -*/ - -statetype s_robored = {ROBOREDLSPR, ROBOREDRSPR, step, false, true, 6, 64, 0, T_RoboRed, C_RoboRed, R_Walk, &s_robored}; -statetype s_roboredfire0 = {ROBOREDLSPR, ROBOREDRSPR, step, true, true, 40, 0, 0, NULL, C_Spindread, R_Draw, &s_roboredfire1}; -statetype s_roboredfire1 = {ROBOREDLSPR, ROBOREDRSPR, step, true, true, 4, 64, 0, NULL, C_Spindread, R_Draw, &s_roboredfire2}; -statetype s_roboredfire2 = {ROBOREDLSPR, ROBOREDRSPR, step, false, true, 6, 0, 0, T_RoboShoot, C_Spindread, R_Draw, &s_roboredfire1}; -statetype s_rshot1 = {ROBOSHOT1SPR, ROBOSHOT1SPR, stepthink, false, false, 8, 0, 0, T_Velocity, C_RShot, R_RShot, &s_rshot2}; -statetype s_rshot2 = {ROBOSHOT2SPR, ROBOSHOT2SPR, stepthink, false, false, 8, 0, 0, T_Velocity, C_RShot, R_RShot, &s_rshot1}; -statetype s_rshothit1 = {ROBOSHOTHIT1SPR, ROBOSHOTHIT1SPR, step, false, false, 10, 0, 0, NULL, NULL, R_Draw, &s_rshothit2}; -statetype s_rshothit2 = {ROBOSHOTHIT2SPR, ROBOSHOTHIT2SPR, step, false, false, 10, 0, 0, NULL, NULL, R_Draw, NULL}; - -/* -=========================== -= -= SpawnRoboRed -= -=========================== -*/ - -void SpawnRoboRed(Uint16 tileX, Uint16 tileY) -{ - GetNewObj(false); - new->obclass = roboredobj; - new->active = ac_yes; - new->x = CONVERT_TILE_TO_GLOBAL(tileX); - new->y = CONVERT_TILE_TO_GLOBAL(tileY) + -4*TILEGLOBAL; - if (US_RndT() < 0x80) - { - new->xdir = 1; - } - else - { - new->xdir = -1; - } - NewState(new, &s_robored); -} - -/* -=========================== -= -= T_RoboRed -= -=========================== -*/ - -void T_RoboRed(objtype *ob) -{ - if (!(ob->x & (4*PIXGLOBAL)) && player->bottom > ob->top && player->top < ob->bottom && US_RndT() < 16) - { - if (ob->x > player->x) - { - ob->xdir = -1; - } - else - { - ob->xdir = 1; - } - ob->temp1 = 10; // shoot 10 times - ob->state = &s_roboredfire0; - } -} - -/* -=========================== -= -= C_RoboRed -= -=========================== -*/ - -void C_RoboRed(objtype *ob, objtype *hit) -{ - if (hit->obclass == stunshotobj) - { - ExplodeShot(hit); - ob->xdir = (player->x > ob->x)? 1 : -1; - ob->temp1 = 10; // shoot 10 times - ChangeState(ob, &s_roboredfire0); - } - else if (hit->obclass == keenobj) - { - KillKeen(); - } -} - -/* -=========================== -= -= T_RoboShoot -= -=========================== -*/ - -void T_RoboShoot(objtype *ob) -{ - Uint16 x; - - if (--ob->temp1 == 0) - { - ob->state = &s_robored; - } - if (ob->xdir == 1) - { - x = ob->x + 56*PIXGLOBAL; - } - else - { - x = ob->x; - } - if (CheckSpawnShot(x, ob->y + 32*PIXGLOBAL, &s_rshot1) != -1) - { - new->xspeed = ob->xdir * 60; - if (ob->temp1 & 1) - { - new->yspeed = 8; - } - else - { - new->yspeed = -8; - } - SD_PlaySound(SND_ENEMYSHOT); - xtry = (ob->xdir == 1)? -4*PIXGLOBAL : 4*PIXGLOBAL; - } -} - -/* -=========================== -= -= C_RShot -= -=========================== -*/ - -void C_RShot(objtype *ob, objtype *hit) -{ - if (hit->obclass == keenobj) - { - KillKeen(); - ChangeState(ob, &s_rshothit1); - } -} - -/* -=========================== -= -= R_RShot -= -=========================== -*/ - -void R_RShot(objtype *ob) -{ - if (ob->hitnorth || ob->hiteast || ob->hitsouth || ob->hitwest) - { - SD_PlaySound(SND_ENEMYSHOTEXPLODE); - ChangeState(ob, &s_rshothit1); - } - RF_PlaceSprite(&ob->sprite, ob->x, ob->y, ob->shapenum, spritedraw, ob->priority); -} - -/* -============================================================================= - - SPIROGRIP - -============================================================================= -*/ - -statetype s_gripsitd = {SPIROSITDSPR, SPIROSITDSPR, step, false, false, 150, 0, 0, NULL, C_Spindread, R_Draw, &s_gripjumpd}; -statetype s_gripjumpd = {SPIROSITDSPR, SPIROSITDSPR, slide, false, false, 64, 0, -16, NULL, C_Spindread, R_Draw, &s_gripspin7}; -statetype s_gripsitl = {SPIROSITLSPR, SPIROSITLSPR, step, false, false, 150, 0, 0, NULL, C_Spindread, R_Draw, &s_gripjumpl}; -statetype s_gripjumpl = {SPIROSITLSPR, SPIROSITLSPR, slide, false, false, 64, 16, 0, NULL, C_Spindread, R_Draw, &s_gripspin1}; -statetype s_gripsitr = {SPIROSITRSPR, SPIROSITRSPR, step, false, false, 150, 0, 0, NULL, C_Spindread, R_Draw, &s_gripjumpr}; -statetype s_gripjumpr = {SPIROSITRSPR, SPIROSITRSPR, slide, false, false, 64, -16, 0, NULL, C_Spindread, R_Draw, &s_gripspin5}; -statetype s_gripsitu = {SPIROSITUSPR, SPIROSITUSPR, step, false, false, 150, 0, 0, NULL, C_Spindread, R_Draw, &s_gripjumpu}; -statetype s_gripjumpu = {SPIROSITUSPR, SPIROSITUSPR, slide, false, false, 64, 0, 16, NULL, C_Spindread, R_Draw, &s_gripspin3}; -statetype s_gripspin1 = {SPIROSPINULSPR, SPIROSPINULSPR, step, false, false, 8, 0, 0, NULL, C_Spindread, R_Draw, &s_gripspin2}; -statetype s_gripspin2 = {SPIROSPINUSPR, SPIROSPINUSPR, step, false, false, 8, 0, 0, T_SpiroLaunch, C_Spindread, R_Draw, &s_gripspin3}; -statetype s_gripspin3 = {SPIROSPINURSPR, SPIROSPINURSPR, step, false, false, 8, 0, 0, NULL, C_Spindread, R_Draw, &s_gripspin4}; -statetype s_gripspin4 = {SPIROSPINRSPR, SPIROSPINRSPR, step, false, false, 8, 0, 0, T_SpiroLaunch, C_Spindread, R_Draw, &s_gripspin5}; -statetype s_gripspin5 = {SPIROSPINDRSPR, SPIROSPINDRSPR, step, false, false, 8, 0, 0, NULL, C_Spindread, R_Draw, &s_gripspin6}; -statetype s_gripspin6 = {SPIROSPINDSPR, SPIROSPINDSPR, step, false, false, 8, 0, 0, T_SpiroLaunch, C_Spindread, R_Draw, &s_gripspin7}; -statetype s_gripspin7 = {SPIROSPINDLSPR, SPIROSPINDLSPR, step, false, false, 8, 0, 0, NULL, C_Spindread, R_Draw, &s_gripspin8}; -statetype s_gripspin8 = {SPIROSPINLSPR, SPIROSPINLSPR, step, false, false, 8, 0, 0, T_SpiroLaunch, C_Spindread, R_Draw, &s_gripspin1}; -statetype s_gripflyd = {SPIROSITDSPR, SPIROSITDSPR, slide, false, false, 0, 0, 48, NULL, C_Spindread, R_SpiroFly, &s_gripsitd}; -statetype s_gripflyl = {SPIROSITLSPR, SPIROSITLSPR, slide, false, false, 0, -48, 0, NULL, C_Spindread, R_SpiroFly, &s_gripsitl}; -statetype s_gripflyr = {SPIROSITRSPR, SPIROSITRSPR, slide, false, false, 0, 48, 0, NULL, C_Spindread, R_SpiroFly, &s_gripsitr}; -statetype s_gripflyu = {SPIROSITUSPR, SPIROSITUSPR, slide, false, false, 0, 0, -48, NULL, C_Spindread, R_SpiroFly, &s_gripsitu}; - -/* -=========================== -= -= SpawnSpirogrip -= -=========================== -*/ - -void SpawnSpirogrip(Uint16 tileX, Uint16 tileY) -{ - GetNewObj(false); - new->obclass = spirogripobj; - new->active = ac_yes; - new->x = CONVERT_TILE_TO_GLOBAL(tileX); - new->y = CONVERT_TILE_TO_GLOBAL(tileY) + -1*TILEGLOBAL; - new->xdir = 1; - new->ydir = 1; - NewState(new, &s_gripsitd); -} - -/* -=========================== -= -= T_SpiroLaunch -= -=========================== -*/ - -void T_SpiroLaunch(objtype *ob) -{ - if (US_RndT() <= 20) - { - SD_PlaySound(SND_SPIROFLY); - if (ob->state == &s_gripspin2) - { - ob->state = &s_gripflyu; - } - else if (ob->state == &s_gripspin4) - { - ob->state = &s_gripflyr; - } - else if (ob->state == &s_gripspin6) - { - ob->state = &s_gripflyd; - } - else if (ob->state == &s_gripspin8) - { - ob->state = &s_gripflyl; - } - } -} - -/* -=========================== -= -= R_SpiroFly -= -=========================== -*/ - -void R_SpiroFly(objtype *ob) -{ - RF_PlaceSprite(&ob->sprite, ob->x, ob->y, ob->shapenum, spritedraw, ob->priority); - if (ob->hitnorth || ob->hiteast || ob->hitsouth || ob->hitwest) - { - ChangeState(ob, ob->state->nextstate); - SD_PlaySound(SND_SPIROGRAB); - } -} - -/* -============================================================================= - - SPINDRED - -temp1 = bounce counter - -============================================================================= -*/ - -statetype s_spindred1 = {SPINDRED1SPR, SPINDRED1SPR, stepthink, false, false, 8, 0, 0, T_Spindread, C_Spindread, R_Spindread, &s_spindred2}; -statetype s_spindred2 = {SPINDRED2SPR, SPINDRED2SPR, stepthink, false, false, 8, 0, 0, T_Spindread, C_Spindread, R_Spindread, &s_spindred3}; -statetype s_spindred3 = {SPINDRED3SPR, SPINDRED3SPR, stepthink, false, false, 8, 0, 0, T_Spindread, C_Spindread, R_Spindread, &s_spindred4}; -statetype s_spindred4 = {SPINDRED4SPR, SPINDRED4SPR, stepthink, false, false, 8, 0, 0, T_Spindread, C_Spindread, R_Spindread, &s_spindred1}; - -/* -=========================== -= -= SpawnSpindread -= -=========================== -*/ - -void SpawnSpindread(Uint16 tileX, Uint16 tileY) -{ - GetNewObj(false); - new->obclass = spindredobj; - new->active = ac_yes; - new->priority = 0; - new->x = CONVERT_TILE_TO_GLOBAL(tileX); - new->y = CONVERT_TILE_TO_GLOBAL(tileY) + -8*PIXGLOBAL; - new->ydir = 1; - NewState(new, &s_spindred1); -} - -/* -=========================== -= -= T_Spindread -= -=========================== -*/ - -void T_Spindread(objtype *ob) -{ - Sint32 i; - - // BUG: this might be executed twice during the same frame if the - // object's animation/state changed during that frame, causing the - // object to move at twice the speed during that frame! - // To avoid that, return if ytry is not 0. - - for (i=lasttimecount-tics; iydir == 1) - { - if (ob->yspeed < 0 && ob->yspeed >= -3) - { - ytry += ob->yspeed; - ob->yspeed = 0; - return; - } - else - { - ob->yspeed += 3; - if (ob->yspeed > 70) - { - ob->yspeed = 70; - } - } - } - else - { - if (ob->yspeed > 0 && ob->yspeed <= 3) - { - ytry += ob->yspeed; - ob->yspeed = 0; - return; - } - else - { - ob->yspeed -= 3; - if (ob->yspeed < -70) - { - ob->yspeed = -70; - } - } - } - } - ytry += ob->yspeed; - } -} - -/* -=========================== -= -= C_Spindread -= -=========================== -*/ - -#pragma argsused -void C_Spindread(objtype *ob, objtype *hit) -{ - if (hit->obclass == stunshotobj) - { - ExplodeShot(hit); - } - else if (hit->obclass == keenobj) - { - KillKeen(); - } -} - -/* -=========================== -= -= R_Spindread -= -=========================== -*/ - -void R_Spindread(objtype *ob) -{ - if (ob->hitsouth) - { - ob->yspeed = 0; - if (ob->ydir == -1) - { - if (++ob->temp1 == 3) - { - ob->temp1 = 0; - ob->yspeed = 68; - ob->ydir = -ob->ydir; - SD_PlaySound(SND_SPINDREDFLIP); - } - else - { - SD_PlaySound(SND_SPINDREDBOUNCE); - ob->yspeed = 40; - } - } - } - if (ob->hitnorth) - { - ob->yspeed = 0; - if (ob->ydir == 1) - { - if (++ob->temp1 == 3) - { - ob->temp1 = 0; - ob->yspeed = -68; - ob->ydir = -ob->ydir; - SD_PlaySound(SND_BOUNCE); - } - else - { - SD_PlaySound(SND_SPINDREDBOUNCE); - ob->yspeed = -40; - } - } - } - RF_PlaceSprite(&ob->sprite, ob->x, ob->y, ob->shapenum, spritedraw, ob->priority); -} - -/* -============================================================================= - - SHIKADI MASTER - -temp1 = defines next action (0 = shoot, 1 = teleport) - -============================================================================= -*/ - -statetype s_master1 = {MASTER1SPR, MASTER1SPR, step, false, false, 8, 0, 0, NULL, C_Master, R_Draw, &s_master2}; -statetype s_master2 = {MASTER2SPR, MASTER2SPR, step, false, false, 8, 0, 0, NULL, C_Master, R_Draw, &s_master3}; -statetype s_master3 = {MASTER3SPR, MASTER3SPR, step, false, false, 8, 0, 0, NULL, C_Master, R_Draw, &s_master4}; -statetype s_master4 = {MASTER4SPR, MASTER4SPR, step, false, false, 8, 0, 0, T_Master, C_Master, R_Draw, &s_master1}; -statetype s_mastershoot1 = {SHIKMASTERCASTLSPR, SHIKMASTERCASTRSPR, step, false, false, 30, 0, 0, T_MasterShoot, C_Spindread, R_Draw, &s_mastershoot2}; -statetype s_mastershoot2 = {SHIKMASTERCASTLSPR, SHIKMASTERCASTRSPR, step, false, false, 8, 0, 0, NULL, C_Spindread, R_Draw, &s_master1}; -statetype s_mastertport1 = {MASTERTELEPORT1SPR, MASTERTELEPORT1SPR, step, false, true, 20, 0, 0, NULL, C_Spindread, R_Draw, &s_mastertport2}; -statetype s_mastertport2 = {MASTERTELEPORT2SPR, MASTERTELEPORT2SPR, step, false, true, 20, 0, 0, T_MasterTPort, C_Spindread, R_Draw, &s_mastertport3}; -statetype s_mastertport3 = {MASTERTELEPORT2SPR, MASTERTELEPORT2SPR, think, false, false, 0, 0, 0, T_Projectile, NULL, R_Land, &s_mastertport4}; -statetype s_mastertport4 = {MASTERTELEPORT2SPR, MASTERTELEPORT2SPR, step, false, false, 60, 0, 0, NULL, C_Spindread, R_Draw, &s_master1}; -statetype s_mshot1 = {MASTERSHOT4SPR, MASTERSHOT1SPR, stepthink, false, false, 8, 0, 0, T_WeakProjectile, C_MShot, R_MShot, &s_mshot2}; -statetype s_mshot2 = {MASTERSHOT3SPR, MASTERSHOT2SPR, stepthink, false, false, 8, 0, 0, T_WeakProjectile, C_MShot, R_MShot, &s_mshot3}; -statetype s_mshot3 = {MASTERSHOT2SPR, MASTERSHOT3SPR, stepthink, false, false, 8, 0, 0, T_WeakProjectile, C_MShot, R_MShot, &s_mshot4}; -statetype s_mshot4 = {MASTERSHOT1SPR, MASTERSHOT4SPR, stepthink, false, false, 8, 0, 0, T_WeakProjectile, C_MShot, R_MShot, &s_mshot1}; -statetype s_mspray1 = {MASTERFLOORSPARK1SPR, MASTERFLOORSPARK1SPR, stepthink, false, false, 6, 0, 0, T_Projectile, C_MShot, R_MSpray, &s_mspray2}; -statetype s_mspray2 = {MASTERFLOORSPARK2SPR, MASTERFLOORSPARK2SPR, stepthink, false, false, 6, 0, 0, T_Projectile, C_MShot, R_MSpray, &s_mspray3}; -statetype s_mspray3 = {MASTERFLOORSPARK3SPR, MASTERFLOORSPARK3SPR, stepthink, false, false, 6, 0, 0, T_Projectile, C_MShot, R_MSpray, &s_mspray4}; -statetype s_mspray4 = {MASTERFLOORSPARK4SPR, MASTERFLOORSPARK4SPR, stepthink, false, false, 6, 0, 0, T_Projectile, C_MShot, R_MSpray, &s_mspray1}; - -/* -=========================== -= -= SpawnMaster -= -=========================== -*/ - -void SpawnMaster(Uint16 tileX, Uint16 tileY) -{ - GetNewObj(false); - new->obclass = shikadimasterobj; - new->active = ac_yes; - new->x = CONVERT_TILE_TO_GLOBAL(tileX); - new->y = CONVERT_TILE_TO_GLOBAL(tileY) + -24*PIXGLOBAL; - NewState(new, &s_master1); -} - -/* -=========================== -= -= T_Master -= -=========================== -*/ - -void T_Master(objtype *ob) -{ - Sint16 randval; - - randval = US_RndT(); - if (randval < 0x40) - { - if (ob->temp1) - { - ob->state = &s_mastertport1; - ob->temp1 = 0; - } - else - { - ob->temp1 = 1; - if (player->x > ob->x) - { - ob->xdir = 1; - } - else - { - ob->xdir = -1; - } - ob->state = &s_mastershoot1; - } - } -} - -/* -=========================== -= -= T_MasterShoot -= -=========================== -*/ - -void T_MasterShoot(objtype *ob) -{ - Uint16 x; - - if (ob->xdir == 1) - { - x = ob->x + 16*PIXGLOBAL; - } - else - { - x = ob->x; - } - if (CheckSpawnShot(x, ob->y+8*PIXGLOBAL, &s_mshot1) != -1) - { - new->xspeed = ob->xdir * 48; - new->yspeed = -16; - SD_PlaySound(SND_MASTERATTACK); - } -} - -/* -=========================== -= -= C_Master -= -=========================== -*/ - -void C_Master(objtype *ob, objtype *hit) -{ - if (hit->obclass == stunshotobj) - { - ExplodeShot(hit); - ob->xdir = (player->x > ob->x)? 1 : -1; - ob->temp1 = 1; - ChangeState(ob, &s_mastershoot1); - } - else if (hit->obclass == keenobj) - { - KillKeen(); - } -} - -/* -=========================== -= -= T_MasterTPort -= -=========================== -*/ - -void T_MasterTPort(objtype *ob) -{ - Uint16 tile; - Sint16 tx, ty, redos, oldx, oldy; - - oldx = ob->x; - oldy = ob->y; - - GetNewObj(true); - new->x = ob->x; - new->y = ob->y; - new->xspeed = 48; - NewState(new, &s_mspray1); // BUG? new object is not made removable - - GetNewObj(true); - new->x = ob->x; - new->y = ob->y; - new->xspeed = -48; - NewState(new, &s_mspray1); // BUG? new object is not made removable - - SD_PlaySound(SND_MASTERBLAST); - - redos = 0; -redo: - if (++redos == 10) - { - US_RndT(); // call it, but ignore the result - // probably to avoid repeatedly getting the same same "random" values - // due to having an even number of US_RndT() calls in this routine and - // an even number of elements in the random table. - - ob->state = &s_master1; - ob->x = oldx - 1; - ob->y = oldy; - xtry = 1; - ytry = 0; - } - else - { - tx = player->tilemidx - 16 + (US_RndT()>>3); - ty = player->tilebottom - 16 + (US_RndT()>>3); - if (tx < 2 || ty < 2 || tx > mapwidth-5 || ty > mapheight-5) - goto redo; - - - ob->x = CONVERT_TILE_TO_GLOBAL(tx); - ob->y = CONVERT_TILE_TO_GLOBAL(ty); - ob->tileleft = tx-1; - ob->tileright = tx+4; - ob->tiletop = ty-1; - ob->tilebottom = ty+4; - - { - Uint16 x, y; - Uint16 far *map; - Uint16 mapdelta; - - map = (Uint16 far *)mapsegs[1] + mapbwidthtable[ob->tiletop]/2 + ob->tileleft; - mapdelta = mapwidth - (ob->tileright - ob->tileleft + 1); - - for (y = ob->tiletop; ob->tilebottom >= y; y++, map+=mapdelta) - { - for (x = ob->tileleft; ob->tileright >= x; x++) - { - tile = *map++; - if ((tinf[tile+INTILE] & INTILE_FOREGROUND) || tinf[tile+NORTHWALL] || tinf[tile+EASTWALL] - || tinf[tile+SOUTHWALL] || tinf[tile+WESTWALL]) - { - goto redo; - } - } - } - xtry = ytry = 0; - } - } -} - -/* -=========================== -= -= C_MShot -= -=========================== -*/ - -void C_MShot(objtype *ob, objtype *hit) -{ - if (hit->obclass == keenobj) - { - KillKeen(); - RemoveObj(ob); - } - else if (hit->obclass == stunshotobj) - { - ExplodeShot(hit); - RemoveObj(ob); - } -} - -/* -=========================== -= -= R_MShot -= -=========================== -*/ - -void R_MShot(objtype *ob) -{ - if (ob->hiteast || ob->hitwest) - { - ob->xspeed = -ob->xspeed; - } - if (ob->hitsouth) - { - ob->yspeed = 0; - } - if (ob->hitnorth) - { - SD_PlaySound(SND_MASTERATTACK); - ob->xspeed = 48; - ChangeState(ob, &s_mspray1); - - GetNewObj(true); - new->x = ob->x; - new->y = ob->y; - new->xspeed = -48; - NewState(new, &s_mspray1); // BUG? new object is not made removable - } - RF_PlaceSprite(&ob->sprite, ob->x, ob->y, ob->shapenum, spritedraw, ob->priority); -} - -/* -=========================== -= -= R_MSpray -= -=========================== -*/ - -void R_MSpray(objtype *ob) -{ - if (ob->hiteast || ob->hitwest) - { - RemoveObj(ob); - } - else - { - RF_PlaceSprite(&ob->sprite, ob->x, ob->y, ob->shapenum, spritedraw, ob->priority); - } -} - -/* -============================================================================= - - SHIKADI - -temp1 = x tile position of the pole being grabbed (is set but never used) -temp2 = health -temp3 = flash countdown - -============================================================================= -*/ - -statetype s_shikadi1 = {SHIKADI1SPR, SHIKADI1SPR, step, false, true, 8, 0, 0, NULL, C_Shikadi, R_Shikadi, &s_shikadi2}; -statetype s_shikadi2 = {SHIKADI2SPR, SHIKADI2SPR, step, false, true, 8, 0, 0, NULL, C_Shikadi, R_Shikadi, &s_shikadi3}; -statetype s_shikadi3 = {SHIKADI3SPR, SHIKADI3SPR, step, false, true, 8, 0, 0, NULL, C_Shikadi, R_Shikadi, &s_shikadi4}; -statetype s_shikadi4 = {SHIKADI4SPR, SHIKADI4SPR, step, false, true, 8, 0, 0, NULL, C_Shikadi, R_Shikadi, &s_shikadiwalk1}; -statetype s_shikadiwalk1 = {SHIKADIWALKL1SPR, SHIKADIWALKR1SPR, step, false, true, 8, 128, 0, T_Shikadi, C_Shikadi, R_Shikadi, &s_shikadiwalk2}; -statetype s_shikadiwalk2 = {SHIKADIWALKL2SPR, SHIKADIWALKR2SPR, step, false, true, 8, 128, 0, T_Shikadi, C_Shikadi, R_Shikadi, &s_shikadiwalk3}; -statetype s_shikadiwalk3 = {SHIKADIWALKL3SPR, SHIKADIWALKR3SPR, step, false, true, 8, 128, 0, T_Shikadi, C_Shikadi, R_Shikadi, &s_shikadiwalk4}; -statetype s_shikadiwalk4 = {SHIKADIWALKL4SPR, SHIKADIWALKR4SPR, step, false, true, 8, 128, 0, T_Shikadi, C_Shikadi, R_Shikadi, &s_shikadiwalk1}; -statetype s_shikadigrab = {SHIKADIGRABLSPR, SHIKADIGRABRSPR, step, false, true, 20, 0, 0, T_PoleShock, C_Shikadi, R_Shikadi, &s_shikadigrab2}; -statetype s_shikadigrab2 = {SHIKADIGRABLSPR, SHIKADIGRABRSPR, step, false, true, 20, 0, 0, NULL, C_Shikadi, R_Shikadi, &s_shikadiwalk1}; -statetype s_shikadistun = {SHIKADISTUNSPR, SHIKADISTUNSPR, think, false, false, 0, 0, 0, T_Projectile, NULL, R_Stunned, NULL}; - -statetype s_polespark1 = {SHIKADIPOLESPARK1SPR, SHIKADIPOLESPARK1SPR, stepthink, false, false, 0, 0, 0, T_PoleSpark, C_Lethal, R_Draw, &s_polespark2}; -statetype s_polespark2 = {SHIKADIPOLESPARK1SPR, SHIKADIPOLESPARK1SPR, stepthink, false, false, 0, 0, 0, T_PoleSpark, C_Lethal, R_Draw, &s_polespark1}; - -/* -=========================== -= -= SpawnShikadi -= -=========================== -*/ - -void SpawnShikadi(Uint16 tileX, Uint16 tileY) -{ - GetNewObj(false); - new->obclass = shikadiobj; - new->active = ac_yes; - new->x = CONVERT_TILE_TO_GLOBAL(tileX); - new->y = CONVERT_TILE_TO_GLOBAL(tileY) + -1*TILEGLOBAL; - new->temp2 = 4; // health - if (US_RndT() < 0x80) - { - new->xdir = 1; - } - else - { - new->xdir = -1; - } - NewState(new, &s_shikadi1); -} - -/* -=========================== -= -= T_Shikadi -= -=========================== -*/ - -void T_Shikadi(objtype *ob) -{ - Uint16 tx, tile; - - if (player->state->contact == &KeenPosContact - || ob->bottom - player->bottom + TILEGLOBAL <= 2*TILEGLOBAL) - { - if (ob->x > player->x + TILEGLOBAL) - { - ob->xdir = -1; - } - else if (ob->x < player->x - TILEGLOBAL) - { - ob->xdir = 1; - } - if (ob->xdir == 1) - { - tx = ob->tileright; - } - else - { - tx = ob->tileleft; - } - - if (player->tilemidx != tx) - return; - } - else - { - if (US_RndT() < 0x10) - { - xtry = 0; - ob->state = &s_shikadi1; - return; - } - if ((ob->x & 0xFF) || !OnScreen(ob)) - return; - - if (ob->xdir == 1) - { - tx = ob->tileright; - } - else - { - tx = ob->tileleft; - } - } - - tile = *(mapsegs[1]+mapbwidthtable[ob->tiletop]/2 + tx); - if (tinf[tile+INTILE] == INTILE_POLE) - { - ob->temp1 = tx; - ob->state = &s_shikadigrab; - xtry = 0; - SD_PlaySound(SND_SHIKADIATTACK); - } -} - -/* -=========================== -= -= C_Shikadi -= -=========================== -*/ - -void C_Shikadi(objtype *ob, objtype *hit) -{ - if (hit->obclass == keenobj) - { - KillKeen(); - } - if (hit->obclass == stunshotobj) - { - if (--ob->temp2 == 0) // handle health - { - ob->xspeed = 0; - ob->yspeed = 0; - StunObj(ob, hit, &s_shikadistun); - } - else - { - ob->temp3 = 2; // draw white two times - ob->needtoreact = true; - ExplodeShot(hit); - } - } -} - -/* -=========================== -= -= T_PoleShock -= -=========================== -*/ - -void T_PoleShock(objtype *ob) -{ - Uint16 x; - - ob->nothink = 2; - if (ob->xdir == 1) - { - x = CONVERT_TILE_TO_GLOBAL(ob->tileright); - } - else - { - x = CONVERT_TILE_TO_GLOBAL(ob->tileleft); - } - - GetNewObj(true); - new->x = x; - new->y = ob->y + 8*PIXGLOBAL; - new->obclass = mshotobj; - new->active = ac_removable; - new->needtoclip = cl_noclip; - NewState(new, &s_polespark1); - if (ob->y < player->y) - { - new->ydir = 1; - } - else - { - new->ydir = -1; - } - SD_PlaySound(SND_SHIKADIATTACK); -} - -/* -=========================== -= -= T_PoleSpark -= -=========================== -*/ - -void T_PoleSpark(objtype *ob) -{ - Uint16 tile; - - if (ytry == 0) - { - ytry = ob->ydir * 48; - tile = *(mapsegs[1]+mapbwidthtable[ob->tiletop]/2 + ob->tilemidx); - if (tinf[tile+INTILE] != INTILE_POLE) - { - ob->state = NULL; - } - } -} - -/* -=========================== -= -= R_Shikadi -= -=========================== -*/ - -void R_Shikadi(objtype *ob) -{ - if (ob->xdir == 1 && ob->hitwest) - { - ob->x -= ob->xmove; - ob->xdir = -1; - ob->nothink = US_RndT() >> 5; - ChangeState(ob, ob->state); - } - else if (ob->xdir == -1 && ob->hiteast) - { - ob->x -= ob->xmove; - ob->xdir = 1; - ob->nothink = US_RndT() >> 5; - ChangeState(ob, ob->state); - } - else if (!ob->hitnorth) - { - ob->x -= ob->xmove; - ob->xdir = -ob->xdir; - ob->nothink = US_RndT() >> 5; - ChangeState(ob, ob->state); - } - if (ob->temp3) - { - ob->temp3--; - RF_PlaceSprite(&ob->sprite, ob->x, ob->y, ob->shapenum, maskdraw, ob->priority); - } - else - { - RF_PlaceSprite(&ob->sprite, ob->x, ob->y, ob->shapenum, spritedraw, ob->priority); - } -} - -/* -============================================================================= - - PET (a.k.a. SHOCKSHUND) - -temp1 = countdown for sit animation -temp2 = health -temp3 = flash countdown - -============================================================================= -*/ - -statetype s_petsit1 = {PETSIT1SPR, PETSIT1SPR, step, false, true, 8, 0, 0, NULL, C_Pet, R_Pet, &s_petsit2}; -statetype s_petsit2 = {PETSIT2SPR, PETSIT2SPR, step, false, true, 8, 0, 0, T_PetSit, C_Pet, R_Pet, &s_petsit1}; -statetype s_petbark1 = {PETBARKL1SPR, PETBARKR1SPR, step, false, true, 8, 0, 0, NULL, C_Pet, R_Pet, &s_petbark2}; -statetype s_petbark2 = {PETBARKL2SPR, PETBARKR2SPR, step, false, true, 8, 0, 0, T_PetBark, C_Pet, R_Pet, &s_pet1}; -statetype s_pet1 = {PETRUNL1SPR, PETRUNR1SPR, step, false, true, 8, 128, 0, NULL, C_Pet, R_Pet, &s_pet2}; -statetype s_pet2 = {PETRUNL2SPR, PETRUNR2SPR, step, false, true, 8, 128, 0, NULL, C_Pet, R_Pet, &s_pet3}; -statetype s_pet3 = {PETRUNL3SPR, PETRUNR3SPR, step, false, true, 8, 128, 0, NULL, C_Pet, R_Pet, &s_pet4}; -statetype s_pet4 = {PETRUNL4SPR, PETRUNR4SPR, step, false, true, 8, 128, 0, T_Pet, C_Pet, R_Pet, &s_pet1}; -statetype s_petjump = {PETJUMPLSPR, PETJUMPRSPR, think, false, false, 8, 128, 0, T_Projectile, C_Pet, R_PetJump, &s_pet2}; -statetype s_pshot1 = {PETSPARK1SPR, PETSPARK1SPR, stepthink, false, false, 8, 0, 0, T_Velocity, C_PShot, R_PShot, &s_pshot2}; -statetype s_pshot2 = {PETSPARK2SPR, PETSPARK2SPR, stepthink, false, false, 8, 0, 0, T_Velocity, C_PShot, R_PShot, &s_pshot1}; -statetype s_pshothot1 = {PETSPARKHIT1SPR, PETSPARKHIT1SPR, step, false, false, 10, 0, 0, NULL, NULL, R_Draw, &s_pshothot2}; -statetype s_pshothot2 = {PETSPARKHIT2SPR, PETSPARKHIT2SPR, step, false, false, 10, 0, 0, NULL, NULL, R_Draw, NULL}; -statetype s_petstun = {PETSTUNSPR, PETSTUNSPR, think, false, false, 0, 0, 0, T_Projectile, NULL, R_Stunned, NULL}; - -/* -=========================== -= -= SpawnPet -= -=========================== -*/ - -void SpawnPet(Uint16 tileX, Uint16 tileY) -{ - GetNewObj(false); - new->obclass = petobj; - new->active = ac_yes; - new->x = CONVERT_TILE_TO_GLOBAL(tileX); - new->y = CONVERT_TILE_TO_GLOBAL(tileY) + -8*PIXGLOBAL; - new->temp2 = 2; // health - new->xdir = new->ydir = 1; - NewState(new, &s_pet1); -} - -/* -=========================== -= -= T_Pet -= -=========================== -*/ - -void T_Pet(objtype *ob) -{ - if (ob->x > player->x) - { - ob->xdir = -1; - } - else - { - ob->xdir = 1; - } - if (US_RndT() < 0x10) - { - xtry = 0; - ob->state = &s_petsit1; - ob->temp1 = 10; // repeat animation 10 times; - } - else - { - if (ob->bottom != player->bottom) - { - ob->state = &s_petjump; - if (ob->xdir == 1) - { - ob->xspeed = 40; - } - else - { - ob->xspeed = -40; - } - ob->yspeed = -40; - } - if (US_RndT() < 0x80) - { - xtry = 0; - ob->state = &s_petbark1; - } - } -} - -/* -=========================== -= -= T_PetSit -= -=========================== -*/ - -void T_PetSit(objtype *ob) -{ - if (--ob->temp1 == 0) - { - ob->state = &s_pet1; - } -} - -/* -=========================== -= -= T_PetBark -= -=========================== -*/ - -void T_PetBark(objtype *ob) -{ - Uint16 x; - - if (ob->xdir == 1) - { - x = ob->x + 7*PIXGLOBAL; - } - else - { - x = ob->x; - } - if (CheckSpawnShot(x, ob->y+4*PIXGLOBAL, &s_pshot1) != -1) - { - new->xspeed = ob->xdir * 60; - new->xdir = ob->xdir; - SD_PlaySound(SND_SHOCKSHUNDBARK); - } -} - -/* -=========================== -= -= C_Pet -= -=========================== -*/ - -void C_Pet(objtype *ob, objtype *hit) -{ - if (hit->obclass == keenobj) - { - KillKeen(); - } - if (hit->obclass == stunshotobj) // no 'else if' in the original code! - { - if (--ob->temp2 == 0) // handle health - { - ob->xspeed = 0; - ob->yspeed = 0; - StunObj(ob, hit, &s_petstun); - } - else - { - ob->temp3 = 2; // draw white two times - ob->needtoreact = true; - ExplodeShot(hit); - } - } -} - -/* -=========================== -= -= R_Pet -= -=========================== -*/ - -void R_Pet(objtype *ob) -{ - if (ob->xdir == 1 && ob->hitwest) - { - ob->x -= ob->xmove; - ob->xdir = -1; - ob->nothink = US_RndT() >> 5; - ChangeState(ob, ob->state); - } - else if (ob->xdir == -1 && ob->hiteast) - { - ob->x -= ob->xmove; - ob->xdir = 1; - ob->nothink = US_RndT() >> 5; - ChangeState(ob, ob->state); - } - else if (!ob->hitnorth) - { - if ((ob->xdir == 1 && player->x > ob->x) || (ob->xdir == -1 && player->x < ob->x)) - { - ChangeState(ob, &s_petjump); - if (ob->xdir == 1) - { - ob->xspeed = 40; - } - else - { - ob->xspeed = -40; - } - ob->yspeed = -40; - } - else - { - ob->x -= ob->xmove*2; - ob->xdir = -ob->xdir; - ob->nothink = US_RndT() >> 5; - ChangeState(ob, ob->state); - } - } - if (ob->temp3) - { - ob->temp3--; - RF_PlaceSprite(&ob->sprite, ob->x, ob->y, ob->shapenum, maskdraw, ob->priority); - } - else - { - RF_PlaceSprite(&ob->sprite, ob->x, ob->y, ob->shapenum, spritedraw, ob->priority); - } -} - -/* -=========================== -= -= R_PetJump -= -=========================== -*/ - -void R_PetJump(objtype *ob) -{ - if (ob->hitnorth) - { - ob->nothink = US_RndT() >> 5; - ChangeState(ob, &s_pet1); - } - if (ob->temp3) - { - ob->temp3--; - RF_PlaceSprite(&ob->sprite, ob->x, ob->y, ob->shapenum, maskdraw, ob->priority); - } - else - { - RF_PlaceSprite(&ob->sprite, ob->x, ob->y, ob->shapenum, spritedraw, ob->priority); - } -} - -/* -=========================== -= -= C_PShot -= -=========================== -*/ - -void C_PShot(objtype *ob, objtype *hit) -{ - if (hit->obclass == keenobj) - { - KillKeen(); - ChangeState(ob, &s_pshothot1); - } - else if (hit->obclass == stunshotobj) - { - ExplodeShot(hit); - ChangeState(ob, &s_pshothot1); - } -} - -/* -=========================== -= -= R_PShot -= -=========================== -*/ - -void R_PShot(objtype *ob) -{ - if (ob->hitnorth || ob->hiteast || ob->hitsouth || ob->hitwest) - { - SD_PlaySound(SND_SHOCKBALLEXPLODE); - ChangeState(ob, &s_pshothot1); - } - RF_PlaceSprite(&ob->sprite, ob->x, ob->y, ob->shapenum, spritedraw, ob->priority); -} - -/* -============================================================================= - - SPHEREFUL - -temp1 ... temp4 = sprite pointers for the guards circling around the sphere - -============================================================================= -*/ - -statetype s_sphereful1 = {SPHEREFUL1SPR, SPHEREFUL1SPR, stepthink, false, false, 6, 0, 0, T_Sphereful, C_Spindread, R_Sphereful, &s_sphereful2}; -statetype s_sphereful2 = {SPHEREFUL2SPR, SPHEREFUL2SPR, stepthink, false, false, 6, 0, 0, T_Sphereful, C_Spindread, R_Sphereful, &s_sphereful3}; -statetype s_sphereful3 = {SPHEREFUL3SPR, SPHEREFUL3SPR, stepthink, false, false, 6, 0, 0, T_Sphereful, C_Spindread, R_Sphereful, &s_sphereful4}; -statetype s_sphereful4 = {SPHEREFUL4SPR, SPHEREFUL4SPR, stepthink, false, false, 6, 0, 0, T_Sphereful, C_Spindread, R_Sphereful, &s_sphereful1}; - -/* -=========================== -= -= SpawnSphereful -= -=========================== -*/ - -void SpawnSphereful(Uint16 tileX, Uint16 tileY) -{ - GetNewObj(false); - new->obclass = spherefulobj; - new->needtoclip = cl_fullclip; - new->active = ac_yes; - new->x = CONVERT_TILE_TO_GLOBAL(tileX); - new->y = CONVERT_TILE_TO_GLOBAL(tileY) + -1*TILEGLOBAL; - new->priority = 1; - NewState(new, &s_sphereful1); -} - -/* -=========================== -= -= T_Sphereful -= -=========================== -*/ - -void T_Sphereful(objtype *ob) -{ - Sint32 i; - ob->needtoreact = true; - - // - // 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 == 0 && ytry == 0) - { - for (i=lasttimecount-tics; iyspeed < 8) - ob->yspeed++; - - if (ob->x < player->x && ob->xspeed < 8) - ob->xspeed++; - - if (ob->x > player->x && ob->xspeed > -8) - ob->xspeed--; - } - ytry += ob->yspeed; - xtry += ob->xspeed; - } - } -} - -/* -=========================== -= -= R_Sphereful -= -=========================== -*/ - -void R_Sphereful(objtype *ob) -{ - static Uint16 circle[16] = { - 384, 369, 328, 265, 192, 119, 58, 15, - 0, 15, 58, 119, 192, 265, 328, 369 - }; - - Uint16 index, shapenum, priority; - - if (ob->hitwest || ob->hiteast) - { - ob->xspeed = -ob->xspeed; - SD_PlaySound(SND_SPHEREFULBOUNCE); - } - if (ob->hitsouth) - { - ob->yspeed = -ob->yspeed; - SD_PlaySound(SND_SPHEREFULBOUNCE); - } - - if (ob->hitnorth) - { - ob->yspeed = -ob->yspeed; - if (player->y < ob->y) - { - ob->yspeed--; - } - else - { - ob->yspeed++; - } - if (ob->yspeed > -4) - { - ob->yspeed = -4; - } - else if (ob->yspeed < -12) - { - ob->yspeed = -12; - } - SD_PlaySound(SND_BOUNCE); - } - RF_PlaceSprite(&ob->sprite, ob->x, ob->y, ob->shapenum, spritedraw, ob->priority); - - index = ((Uint16)lasttimecount / 8) & 0xF; - shapenum = index / 4 + SPHEREGUARD1SPR; - if (index >= 8) - { - priority = 2; - } - else - { - priority = 0; - } - RF_PlaceSprite((void**)&ob->temp1, ob->x+circle[index], ob->y+circle[index], shapenum, spritedraw, priority); - RF_PlaceSprite((void**)&ob->temp2, ob->x+24*PIXGLOBAL-circle[index], ob->y+circle[index], shapenum, spritedraw, priority); - - index += 8; - index &= 0xF; - if (index >= 8) - { - priority = 2; - } - else - { - priority = 0; - } - RF_PlaceSprite((void**)&ob->temp3, ob->x+circle[index], ob->y+circle[index], shapenum, spritedraw, priority); - RF_PlaceSprite((void**)&ob->temp4, ob->x+24*PIXGLOBAL-circle[index], ob->y+circle[index], shapenum, spritedraw, priority); -} - -/* -============================================================================= - - SCOTTIE - -============================================================================= -*/ - -statetype s_scottie1 = {SCOTTIEWALKL1SPR, SCOTTIEWALKR1SPR, step, false, true, 8, 128, 0, T_Scottie, C_Scottie, R_Walk, &s_scottie2}; -statetype s_scottie2 = {SCOTTIEWALKL2SPR, SCOTTIEWALKR2SPR, step, false, true, 8, 128, 0, T_Scottie, C_Scottie, R_Walk, &s_scottie3}; -statetype s_scottie3 = {SCOTTIEWALKL3SPR, SCOTTIEWALKR3SPR, step, false, true, 8, 128, 0, T_Scottie, C_Scottie, R_Walk, &s_scottie4}; -statetype s_scottie4 = {SCOTTIEWALKL4SPR, SCOTTIEWALKR4SPR, step, false, true, 8, 128, 0, T_Scottie, C_Scottie, R_Walk, &s_scottie1}; -statetype s_scottieface = {SCOTTIEFACESPR, SCOTTIEFACESPR, step, false, true, 30, 0, 0, NULL, C_Scottie, R_Walk, &s_scottie1}; -statetype s_scottiestun = {SCOTTIESTUNSPR, SCOTTIESTUNSPR, think, false, false, 0, 0, 0, T_Projectile, NULL, R_Stunned, NULL}; - -/* -=========================== -= -= SpawnScottie -= -=========================== -*/ - -void SpawnScottie(Uint16 tileX, Uint16 tileY) -{ - GetNewObj(false); - new->obclass = scottieobj; - new->active = ac_yes; - new->x = CONVERT_TILE_TO_GLOBAL(tileX); - new->y = CONVERT_TILE_TO_GLOBAL(tileY) + -8*PIXGLOBAL; - if (US_RndT() < 0x80) - { - new->xdir = 1; - } - else - { - new->xdir = -1; - } - NewState(new, &s_scottie1); -} - -/* -=========================== -= -= T_Scottie -= -=========================== -*/ - -void T_Scottie(objtype *ob) -{ - if (US_RndT() < 0x10) - { - xtry = 0; - if (US_RndT() < 0x80) - { - ob->xdir = 1; - } - else - { - ob->xdir = -1; - } - ob->state = &s_scottieface; - } -} - -/* -=========================== -= -= C_Scottie -= -=========================== -*/ - -void C_Scottie(objtype *ob, objtype *hit) -{ - if (hit->obclass == keenobj && hit->state->contact) - { - ClipToSpriteSide(hit, ob); - } - else if (hit->obclass == stunshotobj) - { - StunObj(ob, hit, &s_scottiestun); - } -} - -/* -============================================================================= - - QED - -============================================================================= -*/ - -statetype s_qed = {-1, -1, step, false, true, 8, 128, 0, NULL, NULL, NULL, &s_qed}; - -/* -=========================== -= -= SpawnQed -= -=========================== -*/ - -void SpawnQed(Uint16 tileX, Uint16 tileY) -{ - GetNewObj(false); - new->obclass = qedobj; - new->active = ac_yes; - new->tileleft = tileX; - new->tiletop = tileY; - new->tileright = new->tileleft + 1; - new->tilebottom = new->tiletop + 1; - new->x = new->left = CONVERT_TILE_TO_GLOBAL(tileX) + -1*PIXGLOBAL; - new->y = new->top = CONVERT_TILE_TO_GLOBAL(tileY) + -1*PIXGLOBAL; - new->right = new->left + 34*PIXGLOBAL; - new->bottom = new->top + 34*PIXGLOBAL; - NewState(new, &s_qed); -} \ No newline at end of file