X-Git-Url: http://4ch.mooo.com/gitweb/?p=16.git;a=blobdiff_plain;f=16%2Fkeen456%2FKEEN4-6%2FCK_KEEN.C;fp=16%2Fkeen456%2FKEEN4-6%2FCK_KEEN.C;h=0000000000000000000000000000000000000000;hp=3cb12b9ac9299e99158e80e771ebdf39317902bc;hb=a387b1ff6f02e2da93e870a330af886d1c8233da;hpb=7d1948e210bb7b58af0a0412e71f2a0a0a2010af diff --git a/16/keen456/KEEN4-6/CK_KEEN.C b/16/keen456/KEEN4-6/CK_KEEN.C deleted file mode 100755 index 3cb12b9a..00000000 --- a/16/keen456/KEEN4-6/CK_KEEN.C +++ /dev/null @@ -1,2509 +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. - */ - -/* -CK_KEEN.C -========= - -Contains the following actor types (in this order): - -- Keen (regular levels) - -*/ - -#include "CK_DEF.H" - -/* -============================================================================= - - GLOBAL VARIABLES - -============================================================================= -*/ - -Sint16 singlegravity; // left over from Keen Dreams, not used in Keen 4-6 - -Uint16 bounceangle [8][8] = -{ - { 0, 0, 0, 0, 0, 0, 0, 0}, - { 7, 6, 5, 4, 3, 2, 1, 0}, - { 5, 4, 3, 2, 1, 0, 15, 14}, - { 5, 4, 3, 2, 1, 0, 15, 14}, - { 3, 2, 1, 0, 15, 14, 13, 12}, - { 9, 8, 7, 6, 5, 4, 3, 2}, - { 9, 8, 7, 6, 5, 4, 3, 2}, - {11, 10, 9, 8, 7, 6, 5, 4} -}; - -#ifndef KEEN4 -arrowdirtype arrowflip[] = {arrow_South, arrow_West, arrow_North, arrow_East, arrow_SouthWest, arrow_NorthWest, arrow_NorthEast, arrow_SouthEast}; -#endif - -statetype s_keenstand = {KEENSTANDLSPR, KEENSTANDRSPR, stepthink, false, true, 4, 0, 32, KeenPauseThink, KeenContact, KeenStandReact, &s_keenstand}; - -#ifdef KEEN5 -statetype s_keenride = {KEENONPLATSPR, KEENONPLATSPR, stepthink, false, true, 4, 0, 32, KeenStandThink, KeenContact, KeenStandReact, &s_keenride}; -#endif - -statetype s_keenpauselook = {KEENLOOKUSPR, KEENLOOKUSPR, stepthink, false, true, 60, 0, 0, KeenPauseThink, KeenContact, KeenStandReact, &s_keenstand}; - -statetype s_keenwait1 = {KEENWAITR2SPR, KEENWAITR2SPR, stepthink, false, true, 90, 0, 0, KeenPauseThink, KeenContact, KeenStandReact, &s_keenwait2}; -statetype s_keenwait2 = {KEENWAITR1SPR, KEENWAITR1SPR, stepthink, false, true, 10, 0, 0, KeenPauseThink, KeenContact, KeenStandReact, &s_keenwait3}; -statetype s_keenwait3 = {KEENWAITR2SPR, KEENWAITR2SPR, stepthink, false, true, 90, 0, 0, KeenPauseThink, KeenContact, KeenStandReact, &s_keenwait4}; -statetype s_keenwait4 = {KEENWAITR1SPR, KEENWAITR1SPR, stepthink, false, true, 10, 0, 0, KeenPauseThink, KeenContact, KeenStandReact, &s_keenwait5}; -statetype s_keenwait5 = {KEENWAITR2SPR, KEENWAITR2SPR, stepthink, false, true, 90, 0, 0, KeenPauseThink, KeenContact, KeenStandReact, &s_keenwait6}; -statetype s_keenwait6 = {KEENWAITR3SPR, KEENWAITR3SPR, stepthink, false, true, 70, 0, 0, KeenPauseThink, KeenContact, KeenStandReact, &s_keenstand}; - -#ifdef KEEN4 -statetype s_keenmoon1 = {KEENMOON1SPR, KEENMOON1SPR, stepthink, false, true, 20, 0, 0, KeenPauseThink, KeenContact, KeenStandReact, &s_keenmoon2}; -statetype s_keenmoon2 = {KEENMOON2SPR, KEENMOON2SPR, stepthink, false, true, 90, 0, 0, KeenPauseThink, KeenContact, KeenStandReact, &s_keenmoon3}; -statetype s_keenmoon3 = {KEENMOON1SPR, KEENMOON1SPR, stepthink, false, true, 20, 0, 0, KeenPauseThink, KeenContact, KeenStandReact, &s_keenstand}; -#endif - -statetype s_keenread = {KEENSITREAD1SPR, KEENSITREAD1SPR, step, false, true, 16, 0, 0, 0, KeenContact, KeenStandReact, &s_keenread2}; -statetype s_keenread2 = {KEENSITREAD2SPR, KEENSITREAD2SPR, step, false, true, 16, 0, 0, 0, KeenContact, KeenStandReact, &s_keenread3}; -statetype s_keenread3 = {KEENSITREAD3SPR, KEENSITREAD3SPR, step, false, true, 16, 0, 0, 0, KeenContact, KeenStandReact, &s_keenread4}; -statetype s_keenread4 = {KEENSITREAD4SPR, KEENSITREAD4SPR, step, false, true, 16, 0, 0, 0, KeenContact, KeenStandReact, &s_keenread5}; -statetype s_keenread5 = {KEENREAD1SPR, KEENREAD1SPR, stepthink, false, true, 300, 0, 0, KeenReadThink, KeenContact, KeenStandReact, &s_keenread6}; -statetype s_keenread6 = {KEENREAD2SPR, KEENREAD2SPR, stepthink, false, true, 16, 0, 0, KeenReadThink, KeenContact, KeenStandReact, &s_keenread7}; -statetype s_keenread7 = {KEENREAD3SPR, KEENREAD3SPR, stepthink, false, true, 16, 0, 0, KeenReadThink, KeenContact, KeenStandReact, &s_keenread5}; -statetype s_keenstopread = {KEENSTOPREAD1SPR, KEENSTOPREAD1SPR, step, false, true, 12, 0, 0, 0, KeenContact, KeenStandReact, &s_keenstopread2}; -statetype s_keenstopread2 = {KEENSTOPREAD2SPR, KEENSTOPREAD2SPR, step, false, true, 12, 0, 0, 0, KeenContact, KeenStandReact, &s_keenstopread3}; -statetype s_keenstopread3 = {KEENSITREAD2SPR, KEENSITREAD2SPR, step, false, true, 12, 0, 0, 0, KeenContact, KeenStandReact, &s_keenstand}; - -statetype s_keenlookup = {KEENLOOKUSPR, KEENLOOKUSPR, stepthink, false, true, 30, 0, 0, KeenLookUpThink, KeenContact, KeenStandReact, &s_keenlookup2}; -statetype s_keenlookup2 = {KEENLOOKUSPR, KEENLOOKUSPR, think, false, true, 0, 0, 0, KeenLookUpThink, KeenPosContact, KeenStandReact, NULL}; - -statetype s_keenlookdown = {KEENLOOKD1SPR, KEENLOOKD1SPR, stepthink, false, true, 6, 0, 0, KeenLookDownThink, KeenContact, KeenStandReact, &s_keenlookdown2}; -statetype s_keenlookdown2 = {KEENLOOKD2SPR, KEENLOOKD2SPR, stepthink, false, true, 24, 0, 0, KeenLookDownThink, KeenPosContact, KeenStandReact, &s_keenlookdown3}; -statetype s_keenlookdown3 = {KEENLOOKD2SPR, KEENLOOKD2SPR, think, false, true, 0, 0, 0, KeenLookDownThink, KeenPosContact, KeenStandReact, NULL}; -statetype s_keenlookdown4 = {KEENLOOKD1SPR, KEENLOOKD1SPR, step, false, true, 6, 0, 0, 0, KeenContact, KeenStandReact, &s_keenstand}; - -statetype s_keendrop = {KEENLOOKD1SPR, KEENLOOKD1SPR, step, false, false, 0, 0, 0, KeenDropDownThink, KeenContact, KeenSimpleReact, &s_keenjump3}; -statetype s_keendead = {-1, -1, think, false, false, 10, 0, 0, 0, 0, R_Draw, NULL}; - -statetype s_keendie1 = {KEENDIE1SPR, KEENDIE1SPR, think, false, false, 100, 0, 0, KeenDieThink, 0, R_Draw, &s_keendie1}; -statetype s_keendie2 = {KEENDIE2SPR, KEENDIE2SPR, think, false, false, 100, 0, 0, KeenDieThink, 0, R_Draw, &s_keendie2}; - -#ifdef KEEN4 -statetype s_keensuitdie1 = {SCUBAKEENDEAD1SPR, SCUBAKEENDEAD1SPR, think, false, false, 100, 0, 0, KeenDieThink, NULL, R_Draw, &s_keensuitdie1}; -statetype s_keensuitdie2 = {SCUBAKEENDEAD2SPR, SCUBAKEENDEAD2SPR, think, false, false, 100, 0, 0, KeenDieThink, NULL, R_Draw, &s_keensuitdie2}; -#endif - -statetype s_keenshoot1 = {KEENSHOOTLSPR, KEENSHOOTRSPR, step, false, true, 9, 0, 0, KeenShootThink, KeenContact, KeenStandReact, &s_keenshoot2}; -statetype s_keenshoot2 = {KEENSHOOTLSPR, KEENSHOOTRSPR, step, false, true, 6, 0, 0, 0, KeenContact, KeenStandReact, &s_keenstand}; - -statetype s_keenshootup1 = {KEENSHOOTUSPR, KEENSHOOTUSPR, step, false, true, 9, 0, 0, KeenShootThink, KeenContact, KeenStandReact, &s_keenshootup2}; -statetype s_keenshootup2 = {KEENSHOOTUSPR, KEENSHOOTUSPR, step, false, true, 6, 0, 0, 0, KeenContact, KeenStandReact, &s_keenlookup}; - -statetype s_keenswitch = {KEENENTER1SPR, KEENENTER1SPR, step, false, true, 8, 0, 0, KeenSwitchThink, NULL, KeenStandReact, &s_keenswitch2}; -statetype s_keenswitch2 = {KEENENTER1SPR, KEENENTER1SPR, step, false, true, 8, 0, 0, 0, 0, KeenStandReact, &s_keenstand}; -statetype s_keenkey = {KEENENTER1SPR, KEENENTER1SPR, step, false, true, 6, 0, 0, KeenKeyThink, NULL, KeenStandReact, &s_keenswitch2}; - -statetype s_keenlineup = {KEENENTER1SPR, KEENENTER1SPR, think, false, false, 0, 0, 0, T_LineUp, 0, R_Draw, NULL}; -#ifdef KEEN5 -statetype s_keenenter0 = {KEENENTER1SPR, KEENENTER1SPR, step, false, false, 45, 0, -64, NULL, NULL, R_Draw, &s_keenenter1}; -statetype s_keenteleport = {KEENWAITR2SPR, KEENWAITR2SPR, think, false, false, 0, 0, 0, NULL, NULL, R_Draw, NULL}; -#endif - -statetype s_keenenter1 = {KEENENTER1SPR, KEENENTER1SPR, step, false, false, 9, 0, -64, WalkSound1, NULL, R_Draw, &s_keenenter2}; -statetype s_keenenter2 = {KEENENTER2SPR, KEENENTER2SPR, step, false, false, 9, 0, -64, WalkSound2, NULL, R_Draw, &s_keenenter3}; -statetype s_keenenter3 = {KEENENTER3SPR, KEENENTER3SPR, step, false, false, 9, 0, -64, WalkSound1, NULL, R_Draw, &s_keenenter4}; -statetype s_keenenter4 = {KEENENTER4SPR, KEENENTER4SPR, step, false, false, 9, 0, -64, WalkSound2, NULL, R_Draw, &s_keenenter5}; -statetype s_keenenter5 = {KEENENTER5SPR, KEENENTER5SPR, step, false, false, 9, 0, -64, KeenEnterThink, NULL, R_Draw, &s_keenstand}; -#ifdef KEEN5 -statetype s_keenenter6 = {-1, -1, step, false, false, 9, 0, -64, KeenEnterThink, 0, R_Draw, &s_keenstand}; -#endif - -statetype s_keenpole = {KEENSHINNYL1SPR, KEENSHINNYR1SPR, think, false, false, 0, 0, 0, KeenPoleThink, KeenPosContact, KeenSimpleReact, &s_keenpole}; - -statetype s_keenclimb1 = {KEENSHINNYL1SPR, KEENSHINNYR1SPR, slidethink, false, false, 8, 0, 8, KeenClimbThink, KeenPosContact, KeenSimpleReact, &s_keenclimb2}; -statetype s_keenclimb2 = {KEENSHINNYL2SPR, KEENSHINNYR2SPR, slidethink, false, false, 8, 0, 8, KeenClimbThink, KeenPosContact, KeenSimpleReact, &s_keenclimb3}; -statetype s_keenclimb3 = {KEENSHINNYL3SPR, KEENSHINNYR3SPR, slidethink, false, false, 8, 0, 8, KeenClimbThink, KeenPosContact, KeenSimpleReact, &s_keenclimb1}; - -statetype s_keenslide1 = {KEENSLIDED1SPR, KEENSLIDED1SPR, slide, false, false, 8, 0, 24, KeenDropThink, KeenPosContact, KeenPoleReact, &s_keenslide2}; -statetype s_keenslide2 = {KEENSLIDED2SPR, KEENSLIDED2SPR, slide, false, false, 8, 0, 24, KeenDropThink, KeenPosContact, KeenPoleReact, &s_keenslide3}; -statetype s_keenslide3 = {KEENSLIDED3SPR, KEENSLIDED3SPR, slide, false, false, 8, 0, 24, KeenDropThink, KeenPosContact, KeenPoleReact, &s_keenslide4}; -statetype s_keenslide4 = {KEENSLIDED4SPR, KEENSLIDED4SPR, slide, false, false, 8, 0, 24, KeenDropThink, KeenPosContact, KeenPoleReact, &s_keenslide1}; - -statetype s_keenpoleshoot1 = {KEENPSHOOTLSPR, KEENPSHOOTRSPR, step, false, false, 9, 0, 0, KeenShootThink, KeenPosContact, KeenSimpleReact, &s_keenpoleshoot2}; -statetype s_keenpoleshoot2 = {KEENPSHOOTLSPR, KEENPSHOOTRSPR, step, false, false, 6, 0, 0, 0, KeenPosContact, KeenSimpleReact, &s_keenpole}; - -statetype s_keenpoleshootup1 = {KEENPLSHOOTUSPR, KEENPRSHOOTUSPR, step, false, false, 9, 0, 0, KeenShootThink, KeenPosContact, KeenSimpleReact, &s_keenpoleshootup2}; -statetype s_keenpoleshootup2 = {KEENPLSHOOTUSPR, KEENPRSHOOTUSPR, step, false, false, 6, 0, 0, 0, KeenPosContact, KeenSimpleReact, &s_keenpole}; - -statetype s_keenpoleshootdown1 = {KEENPLSHOOTDSPR, KEENPRSHOOTDSPR, step, false, false, 9, 0, 0, KeenShootThink, KeenPosContact, KeenSimpleReact, &s_keenpoleshootdown2}; -statetype s_keenpoleshootdown2 = {KEENPLSHOOTDSPR, KEENPRSHOOTDSPR, step, false, false, 6, 0, 0, 0, KeenPosContact, KeenSimpleReact, &s_keenpole}; - -statetype s_keenwalk1 = {KEENRUNL1SPR, KEENRUNR1SPR, slidethink, true, true, 6, 24, 0, KeenWalkThink, KeenContact, KeenWalkReact, &s_keenwalk2}; -statetype s_keenwalk2 = {KEENRUNL2SPR, KEENRUNR2SPR, slidethink, true, true, 6, 24, 0, KeenWalkThink, KeenContact, KeenWalkReact, &s_keenwalk3}; -statetype s_keenwalk3 = {KEENRUNL3SPR, KEENRUNR3SPR, slidethink, true, true, 6, 24, 0, KeenWalkThink, KeenContact, KeenWalkReact, &s_keenwalk4}; -statetype s_keenwalk4 = {KEENRUNL4SPR, KEENRUNR4SPR, slidethink, true, true, 6, 24, 0, KeenWalkThink, KeenContact, KeenWalkReact, &s_keenwalk1}; - -statetype s_keenpogodown = {KEENPOGOL2SPR, KEENPOGOR2SPR, step, true, false, 1, 0, 0, KeenBounceThink, KeenContact, KeenPogoReact, &s_keenpogo}; -statetype s_keenpogo = {KEENPOGOL2SPR, KEENPOGOR2SPR, think, true, false, 0, 0, 0, KeenPogoThink, KeenContact, KeenPogoReact, &s_keenpogo2}; -statetype s_keenpogo2 = {KEENPOGOL1SPR, KEENPOGOR1SPR, think, true, false, 0, 0, 0, KeenPogoThink, KeenContact, KeenPogoReact, NULL}; - -statetype s_keenjump1 = {KEENJUMPL1SPR, KEENJUMPR1SPR, think, false, false, 0, 0, 0, KeenAirThink, KeenContact, KeenAirReact, &s_keenjump2}; -statetype s_keenjump2 = {KEENJUMPL2SPR, KEENJUMPR2SPR, think, false, false, 0, 0, 0, KeenAirThink, KeenContact, KeenAirReact, &s_keenjump3}; -statetype s_keenjump3 = {KEENJUMPL3SPR, KEENJUMPR3SPR, stepthink, false, false, 50, 0, 0, KeenAirThink, KeenContact, KeenAirReact, &s_keenjump4}; -statetype s_keenjump4 = {KEENJUMPL2SPR, KEENJUMPR2SPR, stepthink, false, false, 40, 0, 0, KeenAirThink, KeenContact, KeenAirReact, &s_keenjump3}; - -statetype s_keenairshoot1 = {KEENJLSHOOTLSPR, KEENJRSHOOTRSPR, stepthink, false, false, 9, 0, 0, T_Projectile, KeenContact, KeenAirReact, &s_keenairshoot2}; -statetype s_keenairshoot2 = {KEENJLSHOOTLSPR, KEENJRSHOOTRSPR, stepthink, true, false, 1, 0, 0, KeenShootThink, KeenContact, KeenAirReact, &s_keenairshoot3}; -statetype s_keenairshoot3 = {KEENJLSHOOTLSPR, KEENJRSHOOTRSPR, stepthink, false, false, 6, 0, 0, T_Projectile, KeenContact, KeenAirReact, &s_keenjump3}; - -statetype s_keenairshootup1 = {KEENJSHOOTUSPR, KEENJSHOOTUSPR, stepthink, false, false, 9, 0, 0, T_Projectile, KeenContact, KeenAirReact, &s_keenairshootup2}; -statetype s_keenairshootup2 = {KEENJSHOOTUSPR, KEENJSHOOTUSPR, stepthink, true, false, 1, 0, 0, KeenShootThink, KeenContact, KeenAirReact, &s_keenairshootup3}; -statetype s_keenairshootup3 = {KEENJSHOOTUSPR, KEENJSHOOTUSPR, stepthink, false, false, 6, 0, 0, T_Projectile, KeenContact, KeenAirReact, &s_keenjump3}; - -statetype s_keenairshootdown1 = {KEENJSHOOTDSPR, KEENJSHOOTDSPR, stepthink, false, false, 9, 0, 0, T_Projectile, KeenContact, KeenAirReact, &s_keenairshootdown2}; -statetype s_keenairshootdown2 = {KEENJSHOOTDSPR, KEENJSHOOTDSPR, stepthink, true, false, 1, 0, 0, KeenShootThink, KeenContact, KeenAirReact, &s_keenairshootdown3}; -statetype s_keenairshootdown3 = {KEENJSHOOTDSPR, KEENJSHOOTDSPR, stepthink, false, false, 6, 0, 0, T_Projectile, KeenContact, KeenAirReact, &s_keenjump3}; - -statetype s_keenholdon = {KEENHANGLSPR, KEENHANGRSPR, step, false, false, 12, 0, 0, 0, KeenPosContact, KeenSimpleReact, &s_keenholdon2}; -statetype s_keenholdon2 = {KEENHANGLSPR, KEENHANGRSPR, think, false, false, 0, 0, 0, KeenHoldThink, KeenPosContact, KeenSimpleReact, NULL}; - -statetype s_keenclimbup = {KEENCLIMBEDGEL1SPR, KEENCLIMBEDGER1SPR, step, false, false, 10, 0, 0, T_PullUp1, KeenPosContact, KeenSimpleReact, &s_keenclimbup2}; -statetype s_keenclimbup2 = {KEENCLIMBEDGEL2SPR, KEENCLIMBEDGER2SPR, step, false, false, 10, 0, 0, T_PullUp2, KeenPosContact, KeenSimpleReact, &s_keenclimbup3}; -statetype s_keenclimbup3 = {KEENCLIMBEDGEL3SPR, KEENCLIMBEDGER3SPR, step, false, false, 10, 0, 0, T_PullUp3, KeenPosContact, KeenSimpleReact, &s_keenclimbup4}; -statetype s_keenclimbup4 = {KEENCLIMBEDGEL4SPR, KEENCLIMBEDGER4SPR, step, false, false, 10, 0, 0, T_PulledUp, KeenPosContact, KeenSimpleReact, &s_keenclimbup5}; -statetype s_keenclimbup5 = {KEENSTANDLSPR, KEENSTANDRSPR, step, false, false, 6, 0, 0, 0, KeenPosContact, KeenSimpleReact, &s_keenstand}; - -Sint16 slopespeed[8] = {0, 0, 4, 4, 8, -4, -4, -8}; -Sint16 polexspeed[3] = {-8, 0, 8}; - -Sint16 shotsinclip[4] = {0, 8, 5, 5}; -Sint16 bonussound[] = { - SND_GETKEY,SND_GETKEY,SND_GETKEY,SND_GETKEY, - SND_GETPOINTS,SND_GETPOINTS,SND_GETPOINTS, - SND_GETPOINTS,SND_GETPOINTS,SND_GETPOINTS, - SND_EXTRAKEEN, - SND_GETAMMO -#ifdef KEEN5 - ,SND_GETKEYCARD -#endif -}; -Sint16 bonuspoints[] = { - 0, 0, 0, 0, - 100, 200, 500, - 1000, 2000, 5000, - 0, - 0 -#ifdef KEEN5 - ,0 -#endif -}; -Sint16 bonussprite[] = { - BONUSGEMSPR, BONUSGEMSPR, BONUSGEMSPR, BONUSGEMSPR, - BONUS100SPR, BONUS200SPR, BONUS500SPR, - BONUS1000SPR, BONUS2000SPR, BONUS5000SPR, - BONUS1UPSPR, - BONUSCLIPSPR -#ifdef KEEN5 - ,BONUSCARDSPR -#endif -}; - -Uint16 zeromap = 0; - -// uninitialized variables: - -/* -============================================================================= - - LOCAL VARIABLES - -============================================================================= -*/ - -Sint16 jumptime; -Sint32 leavepoletime; -Sint16 moonok; - -/* -============================================================================= - - KEEN - -player->temp1 = pausetime / pointer to zees when sleeping -player->temp2 = pausecount / stagecount -player->temp3 = -player->temp4 = - -============================================================================= -*/ - - -/* -=============== -= -= SpawnKeen -= -=============== -*/ - -void SpawnKeen(Sint16 x, Sint16 y, Sint16 dir) -{ - player->obclass = keenobj; - player->active = ac_allways; - player->priority = 1; - player->x = CONVERT_TILE_TO_GLOBAL(x); - player->y = CONVERT_TILE_TO_GLOBAL(y) - 0xF1; //TODO: weird - - player->xdir = dir; - player->ydir = 1; - NewState(player, &s_keenstand); -} - -//========================================================================== - -/* -====================== -= -= CheckGrabPole -= -====================== -*/ - -boolean CheckGrabPole(objtype *ob) -{ - Uint16 far *map; - -// -// kludgy bit to not let you grab a pole the instant you jump off it -// - if (lasttimecount < leavepoletime) - { - leavepoletime = 0; - } - else if (lasttimecount-leavepoletime < 19) - { - return false; - } - - if (c.yaxis == -1) - { - map = mapsegs[1] + mapbwidthtable[(ob->top+6*PIXGLOBAL)/TILEGLOBAL]/2; - } - else - { - map = mapsegs[1] + mapbwidthtable[ob->tilebottom+1]/2; - } - - map += ob->tilemidx; - - if ((tinf[INTILE + *map] & 0x7F) == INTILE_POLE) - { - ob->x = CONVERT_TILE_TO_GLOBAL(ob->tilemidx-1) + 8*PIXGLOBAL; - xtry = 0; - ytry = c.yaxis * 32; - ob->needtoclip = cl_noclip; // can climb through pole holes - ob->state = &s_keenpole; - return true; - } - return false; -} - -//========================================================================== - -/* -====================== -= -= CheckEnterHouse -= -= Checks for tiles that Keen can interact with by pressing up -= -====================== -*/ - -boolean CheckEnterHouse(objtype *ob) -{ - Uint16 temp; -#ifdef KEEN5 - Uint16 infoval; -#endif - Uint16 intile, intile2; - - intile = tinf[INTILE + *(mapsegs[1]+mapbwidthtable[ob->tiletop]/2+ob->tilemidx)]; - if (intile == INTILE_SWITCH0 || intile == INTILE_SWITCH1 || intile == INTILE_BRIDGESWITCH) - { - temp = CONVERT_TILE_TO_GLOBAL(ob->tilemidx) - 4*PIXGLOBAL; - if (ob->x != temp) - { - ob->temp1 = temp; - ob->state = &s_keenlineup; - } - else - { - ob->state = &s_keenswitch; - } - upheld = true; - return true; - } - else if (intile == INTILE_DOOR || intile == INTILE_KEYCARDDOOR) - { - temp = CONVERT_TILE_TO_GLOBAL(ob->tilemidx) + 6*PIXGLOBAL; - intile2 = tinf[INTILE + *(mapsegs[1]+mapbwidthtable[ob->tiletop]/2+ob->tilemidx-1)]; - if (intile2 == 2 || intile2 == 32) - temp -= TILEGLOBAL; - - // BUG: - // - // The s_keenenter? states rely on Keen's ydir being set to 1, - // which may not always be the case (e.g. if Keen was pushed off - // a pole by another actor in the level). - // If ydir is not 1, Keen will not move up during that animation - // which means the teleport coordinates won't be read from the - // intended tile position and Keen might end up teleporting to - // position 0, 0 in the map and thus win the current level. - // - // That can easily be avoided by setting ob->ydir to 1 when - // changing ob->state to s_keenenter0 or s_keenenter1. - - if (ob->x != temp) - { - ob->temp1 = temp; - ob->state = &s_keenlineup; - } -#ifdef KEEN5 - else if (intile == INTILE_KEYCARDDOOR) - { - if (gamestate.keycard) - { - gamestate.keycard = false; - SD_PlaySound(SND_OPENCARDDOOR); - GetNewObj(false); - new->x = ob->tilemidx - 2; - new->y = ob->tilebottom - 4; - new->active = ac_allways; - new->needtoclip = cl_noclip; - new->obclass = inertobj; - NewState(new, &s_carddoor); - // Note: no invincibility here - card doors were always used as level exits in Keen 5 - ob->state = &s_keenenter0; - ob->priority = 0; - upheld = true; - return true; - } - else - { - SD_PlaySound(SND_NOWAY); - ob->state = &s_keenstand; - upheld = true; - return false; - } - } -#endif - else - { - invincible = 110; //about 1.57 seconds - ob->state = &s_keenenter1; - ob->priority = 0; -#ifdef KEEN5 - { - infoval = *(mapsegs[2]+mapbwidthtable[ob->tiletop]/2+ob->tilemidx); - if (!infoval) - SpawnTeleport(); - } -#endif - } - upheld = true; - return true; - } - return false; -} - -//========================================================================== - -/* -============================ -= -= WalkSound1 -= -============================ -*/ - -void WalkSound1(objtype *ob) -{ - SD_PlaySound(SND_WORLDWALK1); - ob++; // shut up compiler -} - -/* -============================ -= -= WalkSound2 -= -============================ -*/ - -void WalkSound2(objtype *ob) -{ - SD_PlaySound(SND_WORLDWALK2); - ob++; // shut up compiler -} - -//========================================================================== - -/* -============================ -= -= KeenStandThink -= -============================ -*/ - -void KeenStandThink(objtype *ob) -{ -#ifdef KEEN5 - if (ob->hitnorth == 25 && ob->state != &s_keenride) - { - ob->state = &s_keenride; - } -#endif - - if (c.xaxis) - { - // started walking - ob->state = &s_keenwalk1; - KeenWalkThink(ob); - xtry = (Sint16)(ob->xdir * ob->state->xmove * tics) / 4; - } - else if (firebutton && !fireheld) - { - // shoot current xdir - fireheld = true; - if (c.yaxis == -1) - { - ob->state = &s_keenshootup1; - } - else - { - ob->state = &s_keenshoot1; - } - } - else if (jumpbutton && ! jumpheld) - { - // jump straight up - jumpheld = true; - SD_PlaySound(SND_JUMP); - ob->xspeed = 0; - ob->yspeed = -40; - ytry = 0; - jumptime = 18; - ob->state = &s_keenjump1; - } - else if (pogobutton && !pogoheld) - { - // get on pogo - pogoheld = true; - SD_PlaySound(SND_JUMP); - ob->state = &s_keenpogodown; - ob->xspeed = 0; - ob->yspeed = -48; - ytry = 0; - jumptime = 24; - } - else - { - switch (c.yaxis) - { - case -1: - if (CheckGrabPole(ob)) - break; - if (upheld || !CheckEnterHouse(ob)) - { - ob->state = &s_keenlookup; - } - break; - case 1: - if (CheckGrabPole(ob)) - break; - ob->state = &s_keenlookdown; - } - return; - } -} - -//=========================================================================== - -/* -======================= -= -= KeenPauseThink -= -= Do special animations in time -= -======================= -*/ - -void KeenPauseThink(objtype *ob) -{ -#ifdef KEEN5 - if (ob->hitnorth == 25 && ob->state != &s_keenride) - { - ob->state = &s_keenride; - } -#endif - - if (c.dir != dir_None || jumpbutton || pogobutton || firebutton) - { - ob->temp1 = ob->temp2 = 0; // not paused any more - ob->state = &s_keenstand; - KeenStandThink(ob); - } - else - { - //only increase idle counter when NOT standing on a sprite: - if ((ob->hitnorth & ~7) != 0x18) - ob->temp1 = ob->temp1 + tics; - - switch (ob->temp2) - { - case 0: - if (ob->temp1 > 200) - { - ob->temp2++; - ob->state = &s_keenpauselook; - ob->temp1 = 0; - } - break; - case 1: - if (ob->temp1 > 300) - { - ob->temp2++; - ob->temp1 = 0; -#ifdef KEEN4 - if (moonok == 1) - { - moonok = 2; //don't moon again unless the level is restarted - ob->state = &s_keenmoon1; - } - else -#endif - { - ob->state = &s_keenwait1; - } - } - break; - case 2: - if (ob->temp1 > 700) - { - ob->temp2++; - ob->state = &s_keenread; - ob->temp1 = 0; - } - break; - } - } -} - -//=========================================================================== - -/* -======================= -= -= KeenReadThink -= -======================= -*/ - -void KeenReadThink(objtype *ob) -{ - if (storedemo) - { - playstate = ex_abortgame; - IN_ClearKeysDown(); - } - if (c.dir != dir_None || jumpbutton || pogobutton) - { - ob->temp1 = ob->temp2 = 0; - ob->state = &s_keenstopread; - } -} - -//=========================================================================== - -/* -======================= -= -= KeenLookUpThink -= -======================= -*/ - -void KeenLookUpThink(objtype *ob) -{ - if (c.yaxis != -1 || c.xaxis - || (jumpbutton && !jumpheld) - || (pogobutton && !pogoheld) - || firebutton) - { - ob->state = &s_keenstand; - KeenStandThink(ob); - } -} - -//=========================================================================== - -/* -======================= -= -= KeenLookDownThink -= -======================= -*/ - -void KeenLookDownThink(objtype *ob) -{ - Uint16 far *map; - Sint16 y, ymove; - Uint16 tile; - - if (jumpbutton && ! jumpheld && (ob->hitnorth & 7) == 1) - { - // - // drop down a level - // - jumpheld = true; - - y = ob->tilebottom; - map = (Uint16 far *)mapsegs[1] + mapbwidthtable[y]/2 + ob->tilemidx; - tile = *map; - if (tinf[WESTWALL+tile] || tinf[EASTWALL+tile] || tinf[SOUTHWALL+tile]) - return; // wall prevents drop down - - map += mapwidth; - tile = *map; - if (tinf[WESTWALL+tile] || tinf[EASTWALL+tile] || tinf[SOUTHWALL+tile]) - return; // wall prevents drop down - - ymove = max(4, tics) * PIXGLOBAL; - if (gamestate.riding) - ymove += gamestate.riding->ymove; - ob->bottom += ymove; - gamestate.riding = NULL; - ob->y += ymove; - xtry = ytry = 0; - ob->state = &s_keenjump3; - ob->xspeed = ob->yspeed = 0; - SD_PlaySound(SND_PLUMMET); - } - else if (c.yaxis != 1 || c.xaxis - || (jumpbutton && !jumpheld) - || (pogobutton && !pogoheld)) - { - ob->state = &s_keenlookdown4; - } -} - -//=========================================================================== - -/* -======================= -= -= KeenWalkThink -= -======================= -*/ - -void KeenWalkThink(objtype *ob) -{ - Sint16 xmove; - - if (c.xaxis == 0) - { - // - // stopped running - // - ob->state = &s_keenstand; - KeenStandThink(ob); - return; - } - - ob->xdir = c.xaxis; - - switch (c.yaxis) - { - case -1: - if (CheckGrabPole(ob)) - return; - if (upheld) - return; - if (!CheckEnterHouse(ob)) - break;; - return; - - case 1: - if (!CheckGrabPole(ob)) - break; - return; - } - - if (firebutton && !fireheld) - { - // - // shoot - // - fireheld = true; - if (c.yaxis == -1) - { - ob->state = &s_keenshootup1; - } - else - { - ob->state = &s_keenshoot1; - } - return; - } - - if (jumpbutton && !jumpheld) - { - // - // running jump - // - jumpheld = true; - SD_PlaySound(SND_JUMP); - ob->xspeed = ob->xdir * 16; - ob->yspeed = -40; - xtry = ytry = 0; - jumptime = 18; - ob->state = &s_keenjump1; - } - - if (pogobutton && !pogoheld) - { - // - // get on pogo - // - pogoheld = true; - ob->state = &s_keenpogodown; - SD_PlaySound(SND_JUMP); - ob->xspeed = ob->xdir * 16; - ob->yspeed = -48; - xtry = 0; - jumptime = 24; - return; - } - - // - // give speed for slopes - // - xmove = slopespeed[ob->hitnorth & 7] * tics; - xtry += xmove; - - // - // handle walking sounds - // - if (ob->state == &s_keenwalk1 && ob->temp3 == 0) - { - SD_PlaySound(SND_WORLDWALK1); - ob->temp3 = 1; - } - else if (ob->state == &s_keenwalk3 && ob->temp3 == 0) - { - SD_PlaySound(SND_WORLDWALK2); - ob->temp3 = 1; - } - else if (ob->state == &s_keenwalk2 ||ob->state == &s_keenwalk4) - { - ob->temp3 = 0; - } -} - -//=========================================================================== - -/* -======================= -= -= T_LineUp -= -= Lines up Keen's position for interacting with tiles (temp1 is desired x) -= -======================= -*/ - -void T_LineUp(objtype *ob) -{ - Sint16 xmove; - - xmove = ob->temp1 - ob->x; - if (xmove < 0) - { - xtry = xtry - tics * 16; - if (xtry > xmove) - return; - } - else if (xmove > 0) - { - xtry = xtry + tics * 16; - if (xtry < xmove) - return; - } - xtry = xmove; - ob->temp1 = 0; - if (!CheckEnterHouse(ob)) - ob->state = &s_keenstand; -} - -//=========================================================================== - -/* -======================= -= -= KeenEnterThink -= -======================= -*/ - -void KeenEnterThink(objtype *ob) -{ - Uint16 info; - Uint16 far *map; - - map = mapsegs[2] + mapbwidthtable[ob->tilebottom]/2 + ob->tileleft; - info = *map; -#ifdef KEEN5 - if (!info) - { - playstate = ex_portout; - ob->state = &s_keenenter6; - return; - } - else if (info == 0xB1B1) - { - playstate = ex_completed; - ob->state = &s_keenenter6; - return; - } -#endif - ob->y = (CONVERT_TILE_TO_GLOBAL(info & 0xFF) - TILEGLOBAL) + 15; - ob->x = CONVERT_TILE_TO_GLOBAL(info >> 8); - ob->priority = 1; - ob->needtoclip = cl_noclip; - ChangeState(ob, ob->state->nextstate); - ob->needtoclip = cl_midclip; - CenterActor(ob); -} - -//=========================================================================== - -/* -======================= -= -= KeenSwitchThink -= -======================= -*/ - -void KeenSwitchThink(objtype *ob) -{ - Uint16 intile, maptile, newtile, info, sx, sy, tileoff; - Uint16 far *map; - Uint16 tile, x, y; - Sint8 manim; - - tileoff = mapbwidthtable[ob->tiletop]/2 + ob->tilemidx; - maptile = mapsegs[1][tileoff]; - newtile = maptile + (Sint8)tinf[MANIM + maptile]; - info = mapsegs[2][tileoff]; - sx = info >> 8; - sy = info & 0xFF; - intile = tinf[INTILE + maptile]; - - RF_MemToMap(&newtile, 1, ob->tilemidx, ob->tiletop, 1, 1); - SD_PlaySound(SND_USESWITCH); - if (intile == INTILE_BRIDGESWITCH) - { - //toggle bridge: - for (y = sy; sy+2 > y; y++) - { - map = mapsegs[1] + mapbwidthtable[y]/2 + sx - (y != sy); - for (x = sx - (y != sy); x < mapwidth; x++) - { - tile = *(map++); - manim = tinf[MANIM + tile]; - if (!manim) - break; - - tile += manim; - RF_MemToMap(&tile, 1, x, y, 1, 1); - } - } - } - else - { - //toggle platform blocker: - map = mapsegs[2] + mapbwidthtable[sy]/2 + sx; - tile = *map; -#ifdef KEEN5 - if (tile >= DIRARROWSTART && tile < DIRARROWEND) - { - *map = arrowflip[tile-DIRARROWSTART]+DIRARROWSTART; - return; - } -#endif - *map = tile ^ PLATFORMBLOCK; - } -} - -//=========================================================================== - -/* -======================= -= -= KeenKeyThink -= -======================= -*/ - -void KeenKeyThink(objtype *ob) -{ - Uint16 newtile, info, x, y, tileoff; - Uint16 far *map; - Uint16 tile, h; - - tileoff = mapbwidthtable[ob->tilebottom]/2 + ob->tilemidx; - newtile = mapsegs[1][tileoff] + 18; - info = mapsegs[2][tileoff]; - x = info >> 8; - y = info & 0xFF; - RF_MemToMap(&newtile, 1, ob->tilemidx, ob->tilebottom, 1, 1); - SD_PlaySound(SND_OPENDOOR); - GetNewObj(false); - new->x = x; - new->y = y; - - if (x > mapwidth || x < 2 || y > mapheight || y < 2) - Quit("Keyholder points to a bad spot!"); - - map = mapsegs[1] + mapbwidthtable[y]/2 + x; - tile = *map; - h = 1; - map += mapwidth; - while (*map == tile) - { - h++; - map += mapwidth; - } - new->temp1 = h; - new->active = ac_allways; - new->needtoclip = cl_noclip; - new->obclass = inertobj; - NewState(new, &s_door1); -} - -//=========================================================================== - -/* -======================= -= -= KeenAirThink -= -======================= -*/ - -void KeenAirThink(objtype *ob) -{ - if (jumpcheat && jumpbutton) - { - ob->yspeed = -40; - jumptime = 18; - jumpheld = true; - } - if (jumptime) - { - if (jumptime <= tics) - { - ytry = ob->yspeed * jumptime; - jumptime = 0; - } - else - { - ytry = ob->yspeed * tics; - if (!jumpcheat) - jumptime = jumptime - tics; - } - if (!jumpbutton) - jumptime = 0; - - if (jumptime == 0 && ob->state->nextstate) - ob->state = ob->state->nextstate; // switch to second jump stage - } - else - { - if (gamestate.difficulty == gd_Easy) - { - DoWeakGravity(ob); - } - else - { - DoGravity(ob); - } - if (ob->yspeed > 0 && ob->state != &s_keenjump3 && ob->state != &s_keenjump4) - { - ob->state = ob->state->nextstate; // switch to third jump stage - } - } - -//------------- - - if (c.xaxis) - { - ob->xdir = c.xaxis; - AccelerateX(ob, c.xaxis*2, 24); - } - else - { - FrictionX(ob); - } - - if (ob->hitsouth == 17) // going through a pole hole - { - ob->xspeed = xtry = 0; - } - - if (firebutton && !fireheld) - { - fireheld = true; - // - // shoot - // - switch (c.yaxis) - { - case -1: - ob->state = &s_keenairshootup1; - return; - case 0: - ob->state = &s_keenairshoot1; - return; - case 1: - ob->state = &s_keenairshootdown1; - return; - } - } - - if (pogobutton && !pogoheld) - { - pogoheld = true; - ob->state = &s_keenpogo; - jumptime = 0; - return; - } - - if (c.yaxis == -1) - CheckGrabPole(ob); -} - -//=========================================================================== - -/* -======================= -= -= KeenBounceThink -= -= Gives an extra bit of height on the first pogo bounce and creates -= the "impossible pogo trick" when the jump key is held down -= -======================= -*/ - -void KeenBounceThink(objtype *ob) -{ - ob->yspeed = -48; - ytry = ob->yspeed * 6; - jumptime = 24; - SD_PlaySound(SND_POGOBOUNCE); -} - -//=========================================================================== - -/* -======================= -= -= KeenPogoThink -= -======================= -*/ - -void KeenPogoThink(objtype *ob) -{ - if (jumptime) - { - if (jumpbutton || jumptime <= 9) - { - DoTinyGravity(ob); - } - else - { - DoGravity(ob); - } - if (jumptime <= tics) - { - jumptime = 0; - } - else - { - jumptime = jumptime - tics; - } - if (jumptime == 0 && ob->state->nextstate) - ob->state = ob->state->nextstate; - } - else - { - if (gamestate.difficulty == gd_Easy) - { - DoWeakGravity(ob); - } - else - { - DoGravity(ob); - } - } - - if (c.xaxis) - { - if (ob->xspeed == 0) - ob->xdir = c.xaxis; - AccelerateX(ob, c.xaxis, 24); - } - else - { - xtry = xtry + ob->xspeed * tics; - if (ob->xspeed > 0) - { - ob->xdir = 1; - } - else if (ob->xspeed < 0) - { - ob->xdir = -1; - } - } - - if (ob->hitsouth == 17) // going through a pole hole - { - ob->xspeed = xtry = 0; - } - - if (firebutton && !fireheld) - { - fireheld = true; - switch (c.yaxis) - { - case -1: - ob->state = &s_keenairshootup1; - return; - case 0: - ob->state = &s_keenairshoot1; - return; - case 1: - ob->state = &s_keenairshootdown1; - return; - } - } - - if (pogobutton && !pogoheld) - { - pogoheld = true; - ob->state = &s_keenjump3; - } -} - -//=========================================================================== - -/* -======================= -= -= PoleActions -= -======================= -*/ - -void PoleActions(objtype *ob) -{ - if (c.xaxis) - ob->xdir = c.xaxis; - - if (firebutton && !fireheld) - { - fireheld = true; - switch (c.yaxis) - { - case -1: - ob->state = &s_keenpoleshootup1; - break; - case 0: - ob->state = &s_keenpoleshoot1; - break; - case 1: - ob->state = &s_keenpoleshootdown1; - break; - } - } - - if (jumpbutton && !jumpheld) // jump off the pole - { - jumpheld = true; - SD_PlaySound(SND_JUMP); - ob->xspeed = polexspeed[c.xaxis+1]; - ob->yspeed = -20; - ob->needtoclip = cl_midclip; - jumptime = 10; - ob->state = &s_keenjump1; - ob->ydir = 1; - leavepoletime = lasttimecount; - } -} - -/* -======================= -= -= KeenPoleThink -= -======================= -*/ - -void KeenPoleThink(objtype *ob) -{ - Uint16 tile; - Uint16 far *map; - - switch (c.yaxis) - { - case -1: - ob->state = &s_keenclimb1; - ob->ydir = -1; - return; - case 1: - ob->state = &s_keenslide1; - ob->ydir = 1; - KeenDropThink(ob); - return; - } - - if (c.xaxis) - { - // - // walk off pole if right next to ground - // - map = mapsegs[1] + (mapbwidthtable[ob->tilebottom+1]/2 + ob->tilemidx); - tile = *map; - if (tinf[NORTHWALL+tile]) - { - ob->xspeed = 0; - ob->yspeed = 0; - ob->needtoclip = cl_midclip; - jumptime = 0; - ob->state = &s_keenjump3; - ob->ydir = 1; - SD_PlaySound(SND_PLUMMET); - return; - } - } - PoleActions(ob); -} - -/* -======================= -= -= KeenClimbThink -= -======================= -*/ - -void KeenClimbThink(objtype *ob) -{ - Uint16 far *map; - - map = mapsegs[1] + mapbwidthtable[ob->tiletop]/2 + ob->tilemidx; - - if ((tinf[INTILE+*map] & 0x7F) != INTILE_POLE) - { - ytry = 0; - ob->state = &s_keenpole; // ran out of pole - PoleActions(ob); - return; - } - - switch (c.yaxis) - { - case 0: - ob->state = &s_keenpole; - ob->ydir = 0; - break; - - case 1: - ob->state = &s_keenslide1; - ob->ydir = 1; - KeenDropThink(ob); - break; - } - - PoleActions(ob); -} - -/* -======================= -= -= KeenDropThink -= -======================= -*/ - -void KeenDropThink(objtype *ob) -{ - Uint16 far *map; - Uint16 y; - - y = CONVERT_GLOBAL_TO_TILE(ob->bottom - 4*PIXGLOBAL); - map = mapsegs[1] + mapbwidthtable[y]/2 + ob->tilemidx; - - if ((tinf[INTILE+*map] & 0x7F) != INTILE_POLE) - { - SD_PlaySound(SND_PLUMMET); - ob->state = &s_keenjump3; // ran out of pole - jumptime = 0; - ob->xspeed = polexspeed[c.xaxis+1]; - ob->yspeed = 0; - ob->needtoclip = cl_midclip; - ob->tilebottom--; - return; - } - - switch (c.yaxis) - { - case -1: - ob->state = &s_keenclimb1; - ob->ydir = -1; - break; - - case 0: - ob->state = &s_keenpole; - ob->ydir = 0; - break; - } - - PoleActions(ob); -} - -//=========================================================================== - -/* -======================= -= -= KeenDropDownThink -= -======================= -*/ - -void KeenDropDownThink(objtype *ob) -{ - ob->needtoclip = cl_midclip; -} - -//=========================================================================== - -/* -======================= -= -= KeenHoldThink -= -======================= -*/ - -void KeenHoldThink(objtype *ob) -{ - Uint16 tile; - - if (c.yaxis == -1 || ob->xdir == c.xaxis) - { - ob->state = &s_keenclimbup; - if (ob->xdir == 1) - { - tile = *(mapsegs[1]+mapbwidthtable[ob->tiletop-1]/2+ob->tileright); - } - else - { - tile = *(mapsegs[1]+mapbwidthtable[ob->tiletop-1]/2+ob->tileleft); - } - if (ob->xdir == 1) - { - ytry = -16*PIXGLOBAL; - } - else - { - ytry = -8*PIXGLOBAL; - } - if (!(tinf[INTILE+tile] & INTILE_FOREGROUND)) - ob->priority = 3; - } - else if (c.yaxis == 1 || c.xaxis && ob->xdir != c.xaxis) - { - ob->state = &s_keenjump3; - ob->needtoclip = cl_midclip; - } -} - -//=========================================================================== - -/* -======================= -= -= KeenShootThink -= -======================= -*/ - -void KeenShootThink(objtype *ob) -{ -// can't use & in a switch statement... - - if (ob->state == &s_keenshoot1) - { - if (ob->xdir == 1) - { - SpawnShot(ob->x + 16*PIXGLOBAL, ob->y + 4*PIXGLOBAL, dir_East); - } - else - { - SpawnShot(ob->x - 8*PIXGLOBAL, ob->y + 4*PIXGLOBAL, dir_West); - } - } - if (ob->state == &s_keenairshoot2) - { - if (ob->xdir == 1) - { - SpawnShot(ob->x + 16*PIXGLOBAL, ob->y + 2*PIXGLOBAL, dir_East); - } - else - { - SpawnShot(ob->x, ob->y + 2*PIXGLOBAL, dir_West); - } - } - if (ob->state == &s_keenairshootdown2) - { - SpawnShot(ob->x + 8*PIXGLOBAL, ob->y + 18*PIXGLOBAL, dir_South); - } - if (ob->state == &s_keenairshootup2) - { - SpawnShot(ob->x + 5*PIXGLOBAL, ob->y - 10*PIXGLOBAL, dir_North); - } - if (ob->state == &s_keenshootup1) - { - SpawnShot(ob->x + 5*PIXGLOBAL, ob->y - 10*PIXGLOBAL, dir_North); - } - if (ob->state == &s_keenpoleshoot1) - { - if (ob->xdir == 1) - { - SpawnShot(ob->x + 16*PIXGLOBAL, ob->y + 4*PIXGLOBAL, dir_East); - } - else - { - SpawnShot(ob->x - 8*PIXGLOBAL, ob->y + 4*PIXGLOBAL, dir_West); - } - } - if (ob->state == &s_keenpoleshootup1) - { - if (ob->xdir == 1) - { - SpawnShot(ob->x + 6*PIXGLOBAL, ob->y + 4*PIXGLOBAL, dir_North); - } - else - { - SpawnShot(ob->x + 12*PIXGLOBAL, ob->y + 4*PIXGLOBAL, dir_North); - } - } - if (ob->state == &s_keenpoleshootdown1) - { - if (ob->xdir == 1) - { - SpawnShot(ob->x + 6*PIXGLOBAL, ob->y + 24*PIXGLOBAL, dir_South); - } - else - { - SpawnShot(ob->x + 12*PIXGLOBAL, ob->y + 24*PIXGLOBAL, dir_South); - } - } -} - -//=========================================================================== - -/* -======================= -= -= T_PullUp1 -= -======================= -*/ - -void T_PullUp1(objtype *ob) -{ - if (ob->xdir == 1) - { - xtry = 8*PIXGLOBAL; - } - else - { - ytry = -8*PIXGLOBAL; - } -} - -/* -======================= -= -= T_PullUp2 -= -======================= -*/ - -void T_PullUp2(objtype *ob) -{ - if (ob->xdir == 1) - { - xtry = 8*PIXGLOBAL; - ytry = -8*PIXGLOBAL; - } - else - { - xtry = -8*PIXGLOBAL; - ytry = -8*PIXGLOBAL; - } -} - -/* -======================= -= -= T_PullUp3 -= -======================= -*/ - -#pragma argsused -void T_PullUp3(objtype *ob) -{ - ytry = -8*PIXGLOBAL; -} - -/* -======================= -= -= T_PulledUp -= -======================= -*/ - -void T_PulledUp(objtype *ob) -{ - ob->needtoclip = cl_midclip; - ob->priority = 1; - ytry = 8*PIXGLOBAL; -} - -//=========================================================================== - -/* -======================= -= -= KeenDieThink -= -======================= -*/ - -void KeenDieThink(objtype *ob) -{ - DoWeakGravity(ob); - xtry = ob->xspeed * tics; - if (!OnScreen(ob)) - playstate = ex_died; -} - -/* -============================================================================= - - CONTACT ROUTINES - -============================================================================= -*/ - -/* -============================ -= -= KillKeen -= -============================ -*/ - -void KillKeen(void) -{ - if (invincible || godmode) - return; - - if (player->state != &s_keendead) - { - - moonok = 0; - invincible = 30; //0.43 seconds - keenkilled = true; - player->needtoclip = cl_noclip; - player->priority = 3; -#ifdef KEEN4 - if (mapon == 17) - { - if (US_RndT() < 0x80) - { - ChangeState(player, &s_keensuitdie1); - } - else - { - ChangeState(player, &s_keensuitdie2); - } - } - else -#endif - { - if (US_RndT() < 0x80) - { - ChangeState(player, &s_keendie1); - } - else - { - ChangeState(player, &s_keendie2); - } - } - SD_PlaySound(SND_KEENDEAD); - player->yspeed = -40; - player->xspeed = 16; - } -} - -/* -============================ -= -= KeenContact -= -============================ -*/ - -void KeenContact(objtype *ob, objtype *hit) -{ - switch (hit->obclass) - { - case bonusobj: - switch (hit->temp1) - { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - case 8: - case 9: - case 10: - case 11: -#ifdef KEEN5 - case 12: -#endif - SD_PlaySound(bonussound[hit->temp1]); - hit->obclass = inertobj; - hit->priority = 3; - hit->shapenum = bonussprite[hit->temp1]; - GivePoints(bonuspoints[hit->temp1]); - if (hit->temp1 < 4) - { - gamestate.keys[hit->temp1]++; - } - else if (hit->temp1 == 10) - { - gamestate.lives++; - } - else if (hit->temp1 == 11) - { - gamestate.ammo += shotsinclip[gamestate.difficulty]; - } -#ifdef KEEN5 - else if (hit->temp1 == 12) - { - gamestate.keycard = true; - } -#endif - ChangeState(hit, &s_bonusrise); - } - break; - -#if defined KEEN4 - case oracleobj: - if (!ob->hitnorth) - break; - - if (mapon == 14) - { - RescueJanitor(); - RF_ForceRefresh(); - RemoveObj(hit); - } - else - { - SD_PlaySound(SND_LINDSEY); - playstate = ex_rescued; - } - break; - case stunnedobj: - if (hit->temp4 != bounderobj) - break; - //no break here -- drop through to platformobj is intended! - case platformobj: - if (!gamestate.riding) - { - ClipToSpriteTop(ob, hit); - } - else - return; - break; - case bounderobj: - ClipToSprite(ob, hit, false); - break; - case lindseyobj: - PrincessLindsey(); - RemoveObj(hit); - RF_ForceRefresh(); - break; - case footobj: - playstate = ex_foot; - break; -#elif defined KEEN5 - case platformobj: - if (!gamestate.riding) - ClipToSpriteTop(ob, hit); - break; -#elif defined KEEN6 - case stunshotobj: - if (hit->temp4) - { - ExplodeShot(hit); - ChangeState(ob, &s_keenstun); - } - // BUG: there is no break here - this causes the impossible bullet bug - case platformobj: - if (!gamestate.riding) - ClipToSpriteTop(ob, hit); - break; -#endif - } -} - -/* -============================ -= -= KeenPosContact -= -============================ -*/ - -void KeenPosContact(objtype *ob, objtype *hit) -{ - switch (hit->obclass) - { -#if defined KEEN4 - case platformobj: - // BUG: priority is not reset here - ob->needtoclip = cl_midclip; - ChangeState(ob, &s_keenjump3); - jumptime = ob->xspeed = ob->yspeed = 0; - ClipToSpriteTop(ob, hit); - break; - case madmushroomobj: - case arachnutobj: - case berkeloidobj: - KillKeen(); - break; - case bounderobj: - ob->priority = 1; - ob->needtoclip = cl_midclip; - ChangeState(ob, &s_keenjump3); - jumptime = ob->xspeed = ob->yspeed = 0; - ClipToSprite(ob, hit, false); - break; -#elif defined KEEN5 - case platformobj: - // BUG: priority is not reset here - ob->needtoclip = cl_midclip; - ChangeState(ob, &s_keenjump3); - jumptime = ob->xspeed = ob->yspeed = 0; - ClipToSpriteTop(ob, hit); - break; - case amptonobj: - case scottieobj: - ob->priority = 1; - ob->needtoclip = cl_midclip; - ChangeState(ob, &s_keenjump3); - jumptime = ob->xspeed = ob->yspeed = 0; - break; -#elif defined KEEN6 - case platformobj: - case gikobj: - case flectobj: - case bloogletobj: - ob->priority = 1; - ob->needtoclip = cl_midclip; - ChangeState(ob, &s_keenjump3); - jumptime = ob->xspeed = ob->yspeed = 0; - ClipToSpriteTop(ob, hit); // BUG: allows Keen to stand on Blooglets and Flects - break; -#endif - } -} - -/* -============================ -= -= HandleRiding -= -============================ -*/ - -void HandleRiding(objtype *ob) -{ - objtype *plat; - - plat = gamestate.riding; - if (ob->right < plat->left || ob->left > plat->right) - { - gamestate.riding = NULL; - } - else if (ob->ymove < 0) - { - gamestate.riding = NULL; - if (plat->ymove < 0) - { - xtry = 0; - ytry = plat->ymove; - PushObj(ob); - } - } - else - { - xtry = plat->xmove; - ytry = plat->top - ob->bottom - 16; - PushObj(ob); - -#if GRMODE == CGAGR - if (ob->xmove == plat->xmove) - { - ob->x &= ~0x3F; - ob->x |= plat->x & 0x3F; - } -#else - if (nopan) - { - ob->x &= ~0x7F; - ob->x |= plat->x & 0x7F; - } - else - { - ob->x |= plat->x & 0x1F; - } -#endif - - if (ob->hitsouth) - { - gamestate.riding = NULL; - } - else - { - ob->hitnorth = 25; - } - } -} - -/* -============================ -= -= TileBonus -= -============================ -*/ - -void TileBonus(Uint16 x, Uint16 y, Uint16 bonus) -{ - RF_MemToMap(&zeromap, 1, x, y, 1, 1); - SD_PlaySound(bonussound[bonus]); - GivePoints(bonuspoints[bonus]); - if (bonus < 4) - { - gamestate.keys[bonus]++; - } - else if (bonus == 10) - { - gamestate.lives++; - } - else if (bonus == 11) - { - gamestate.ammo += shotsinclip[gamestate.difficulty]; - } - GetNewObj(true); - new->obclass = inertobj; - new->priority = 3; - new->x = CONVERT_TILE_TO_GLOBAL(x); - new->y = CONVERT_TILE_TO_GLOBAL(y); - new->ydir = -1; - new->temp2 = new->shapenum = bonussprite[bonus]; - NewState(new, &s_bonusrise); - new->needtoclip = cl_noclip; -} - -/* -============================ -= -= GiveDrop -= -============================ -*/ - -void GiveDrop(Uint16 x, Uint16 y) -{ - RF_MemToMap(&zeromap, 1, x, y, 1, 1); - SD_PlaySound(SND_GETWATER); - SpawnSplash(x, y); - if (++gamestate.drops == 100) - { - gamestate.drops = 0; - SD_PlaySound(SND_EXTRAKEEN); - gamestate.lives++; - GetNewObj(true); - new->obclass = inertobj; - new->priority = 3; - new->x = CONVERT_TILE_TO_GLOBAL(x); - new->y = CONVERT_TILE_TO_GLOBAL(y-1); - new->ydir = -1; - new->temp2 = new->shapenum = BONUS100UPSPR; - NewState(new, &s_bonusrise); - new->needtoclip = cl_noclip; - } -} - -/* -============================ -= -= CheckInTiles -= -============================ -*/ - -void CheckInTiles(objtype *ob) -{ - Uint16 x, y; - Uint16 far *map; - Uint16 rowdelta, intile, midx; - - if (moonok == 1) - moonok = 0; - - map = mapsegs[1] + mapbwidthtable[ob->tiletop]/2 + ob->tileleft; - rowdelta = mapwidth - (ob->tileright - ob->tileleft + 1); - for (y = ob->tiletop; y <= ob->tilebottom; y++, map += rowdelta) - { - for (x = ob->tileleft; x <= ob->tileright; x++, map++) - { - if ((intile = tinf[INTILE + *map] & INTILE_TYPEMASK) != 0) - { - switch (intile) - { - case INTILE_DEADLY: - KillKeen(); - break; - - case INTILE_DROP: - GiveDrop(x, y); - break; - - case INTILE_GEMSOCKET0: - case INTILE_GEMSOCKET1: - case INTILE_GEMSOCKET2: - case INTILE_GEMSOCKET3: - if (ob->tilebottom != y || !ob->hitnorth - || ob->state == &s_keenkey - || !gamestate.keys[intile-INTILE_GEMSOCKET0]) - { - return; - } - - midx = CONVERT_TILE_TO_GLOBAL(x) + -4*PIXGLOBAL; - if (ob->x != midx) - { - ob->temp1 = midx; - ob->state = &s_keenlineup; - return; - } - else - { - gamestate.keys[intile-INTILE_GEMSOCKET0]--; - ChangeState(ob, &s_keenkey); - } - break; - - case INTILE_MOON: - if (moonok == 0) - moonok = 1; - break; - - case INTILE_BONUS100: - case INTILE_BONUS200: - case INTILE_BONUS500: - case INTILE_BONUS1000: - case INTILE_BONUS2000: - case INTILE_BONUS5000: - case INTILE_EXTRALIFE: - case INTILE_AMMO: - TileBonus(x, y, (intile-INTILE_BONUS100)+4); - break; - } - } - } - } -} - -/* -============================================================================= - - REACTION ROUTINES - -============================================================================= -*/ - - -/* -============================ -= -= KeenSimpleReact -= -============================ -*/ - -void KeenSimpleReact(objtype *ob) -{ - RF_PlaceSprite(&ob->sprite, ob->x, ob->y, ob->shapenum, spritedraw, ob->priority); -} - - -/* -============================ -= -= KeenStandReact -= -============================ -*/ - -void KeenStandReact(objtype *ob) -{ - if (!ob->hitnorth) - { - // - // walked off an edge - // - SD_PlaySound(SND_PLUMMET); - ob->xspeed = ob->xdir * 8; - ob->yspeed = 0; - ChangeState(ob, &s_keenjump3); - jumptime = 0; - } - else if ((ob->hitnorth & ~7) == 8) // deadly floor! - { - KillKeen(); - } - else if (ob->hitnorth == 41) - { - xtry = tics * 8; - ytry = 0; - ob->temp1 = 0; - ClipToWalls(ob); - } - else if (ob->hitnorth == 49) - { - xtry = tics * -8; - ytry = 0; - ob->temp1 = 0; - ClipToWalls(ob); - } - - RF_PlaceSprite(&ob->sprite, ob->x, ob->y, ob->shapenum, spritedraw, ob->priority); -} - -/* -============================ -= -= KeenWalkReact -= -============================ -*/ - -void KeenWalkReact(objtype *ob) -{ - if (!ob->hitnorth) - { - // - // walked off an edge - // - SD_PlaySound(SND_PLUMMET); - ob->xspeed = ob->xdir * 8; - ob->yspeed = 0; - ChangeState(ob, &s_keenjump3); - jumptime = 0; - } - else if ((ob->hitnorth & ~7) == 8) // deadly floor! - { - KillKeen(); - } - else if (ob->hitnorth == 41) - { - xtry = tics * 8; - ytry = 0; - ClipToWalls(ob); - } - else if (ob->hitnorth == 49) - { - xtry = tics * -8; - ytry = 0; - ClipToWalls(ob); - } - else if (ob->hiteast && ob->xdir == -1 || ob->hitwest && ob->xdir == 1) - { - // - // ran into a wall - // - ob->ticcount = 0; - ob->state = &s_keenstand; - ob->shapenum = ob->xdir == 1? s_keenstand.rightshapenum : s_keenstand.leftshapenum; - } - - RF_PlaceSprite(&ob->sprite, ob->x, ob->y, ob->shapenum, spritedraw, ob->priority); -} - -/* -============================ -= -= KeenAirReact -= -============================ -*/ - -void KeenAirReact(objtype *ob) -{ - Uint16 far *map; - Uint16 oldtop, graby, ty, tile; - - if (ob->hiteast && ob->xdir == -1 || ob->hitwest && ob->xdir == 1) - ob->xspeed = 0; - - if (ob->hitsouth) - { - if (ob->hitsouth == 17) // jumping up through a pole hole - { - ob->y -= 2*PIXGLOBAL; - ob->top -= 2*PIXGLOBAL; - ob->xspeed = 0; - ob->x = CONVERT_TILE_TO_GLOBAL(ob->tilemidx) - 2*PIXGLOBAL; - } - else - { -#ifdef KEEN6 - if (ob->hitsouth == 33) - { - FlipBigSwitch(ob, false); - } -#endif - if (!jumpcheat) - { - SD_PlaySound(SND_HELMETHIT); - if (ob->hitsouth > 1) - { - ob->yspeed += 16; - if (ob->yspeed < 0) // push away from slopes - ob->yspeed = 0; - } - else - { - ob->yspeed = 0; - } - jumptime = 0; - } - } - } - - if (ob->hitnorth) - { - ob->ymove = 0; - if ((ob->hitnorth & ~7) == 8) // deadly floor! - { - KillKeen(); - } - else - { -#if defined KEEN5 - if (ob->hitnorth == 57) - { - SD_PlaySound(SND_LANDONFUSE); - } -#elif defined KEEN6 - if (ob->hitnorth == 33) - { - FlipBigSwitch(ob, true); - } -#endif - if (ob->hitnorth != 25 || !jumptime) // KLUDGE to allow jumping off - { - ob->temp1 = ob->temp2 = 0; - if (ob->state == &s_keenairshoot1) - { - ChangeState(ob, &s_keenshoot1); - } - else if (ob->state == &s_keenairshootup1) - { - ChangeState(ob, &s_keenshootup1); - } - else if (c.xaxis) - { - ChangeState(ob, &s_keenwalk1); - } - else - { - ChangeState(ob, &s_keenstand); - } - SD_PlaySound(SND_LAND); - } - } - } - else if (ob->ymove > 0) - { -// -// check if there is an edge to grab -// - oldtop = ob->top - ob->ymove; - graby = ((ob->top - 4*PIXGLOBAL) & 0xFF00) + 4*PIXGLOBAL; - ty = CONVERT_GLOBAL_TO_TILE(graby) - 1; - if (oldtop < graby && ob->top >= graby) - { - if (c.xaxis == -1) - { - map = mapsegs[1] + mapbwidthtable[ty]/2 + ob->tileleft; - if (ob->hiteast) - map--; - tile = *map; - if (!tinf[EASTWALL + tile] && !tinf[WESTWALL + tile] - && !tinf[NORTHWALL + tile] && !tinf[SOUTHWALL + tile] - && tinf[EASTWALL + map[mapwidth]] && tinf[NORTHWALL + map[mapwidth]] - ) - { - ob->xdir = -1; - ob->needtoclip = cl_noclip; - ob->x = (ob->x & 0xFF00) + 8*PIXGLOBAL; - ob->y = graby - 4*PIXGLOBAL; - ob->yspeed = ob->ymove = 0; - ChangeState(ob, &s_keenholdon); - } - } - else if (c.xaxis == 1) - { - map = mapsegs[1] + mapbwidthtable[ty]/2 + ob->tileright; - if (ob->hitwest) - map++; - tile = *map; - if (!tinf[EASTWALL + tile] && !tinf[WESTWALL + tile] - && !tinf[NORTHWALL + tile] && !tinf[SOUTHWALL + tile] - && tinf[WESTWALL + map[mapwidth]] && tinf[NORTHWALL + map[mapwidth]] - ) - { - ob->xdir = 1; - ob->needtoclip = cl_noclip; - ob->x = (ob->x & 0xFF00) + 16*PIXGLOBAL; - ob->y = graby - 4*PIXGLOBAL; - ob->yspeed = ob->ymove = 0; - ChangeState(ob, &s_keenholdon); - } - } - } - } - - RF_PlaceSprite(&ob->sprite, ob->x, ob->y, ob->shapenum, spritedraw, ob->priority); -} - -#ifdef KEEN5 -/* -============================ -= -= BreakFuse -= -============================ -*/ - -void BreakFuse(Uint16 tileX, Uint16 tileY) -{ - Uint16 tiles[] = {1932, 1950}; // should be 'static' for less overhead - - // The original disassembly had some code here equivalent to this: - // - // _AX = tiles[0]; - // _DX = 4; - // - // As it turned out, that was just a compiler quirk. - - SpawnFuseFlash(tileX, tileY); - if (--gamestate.numfuses == 0) - { - SpawnDeadMachine(); - } - RF_MemToMap(tiles, 1, tileX, tileY, 1, 2); -} -#endif - -/* -============================ -= -= KeenPogoReact -= -============================ -*/ - -void KeenPogoReact(objtype *ob) -{ - if (ob->hiteast && ob->xdir == -1 || ob->hitwest && ob->xdir == 1) - ob->xspeed = 0; - - if (ob->hitsouth) - { - if (ob->hitsouth == 17) // jumping up through a pole hole - { - ob->y -= 2*PIXGLOBAL; - ob->top -= 2*PIXGLOBAL; - ob->xspeed = 0; - ob->x = CONVERT_TILE_TO_GLOBAL(ob->tilemidx) - 2*PIXGLOBAL; - } - else - { -#ifdef KEEN6 - if (ob->hitsouth == 33) - { - FlipBigSwitch(ob, false); - } -#endif - if (!jumpcheat) - { - SD_PlaySound(SND_HELMETHIT); - if (ob->hitsouth > 1) - { - ob->yspeed += 16; - if (ob->yspeed < 0) // push away from slopes - ob->yspeed = 0; - } - else - { - ob->yspeed = 0; - } - jumptime = 0; - } - } - } - - if (ob->hitnorth) - { - ob->ymove = 0; - if ((ob->hitnorth & ~7) == 8) // deadly floor! - { - KillKeen(); - } - else - { -#if defined KEEN5 - if (ob->hitnorth == 57) - { - if (ob->yspeed < 48) - { - SD_PlaySound(SND_LANDONFUSE); - } - else - { - BreakFuse(ob->tilemidx, ob->tilebottom); - RF_PlaceSprite(&ob->sprite, ob->x, ob->y, ob->shapenum, spritedraw, ob->priority); - return; - } - } -#elif defined KEEN6 - if (ob->hitnorth == 33) - { - FlipBigSwitch(ob, true); - } - else if (ob->hitnorth == 41) - { - ob->xspeed += 8; - if (ob->xspeed > 8) - ob->xspeed = 8; - } - else if (ob->hitnorth == 49) - { - ob->xspeed -= 8; - if (ob->xspeed < -8) - ob->xspeed = -8; - } -#endif - if (ob->hitnorth != 25 || !jumptime) // KLUDGE to allow jumping off - { - ob->yspeed = -48; - jumptime = 24; - SD_PlaySound(SND_POGOBOUNCE); - ChangeState(ob, &s_keenpogo); - } - } - } - - RF_PlaceSprite(&ob->sprite, ob->x, ob->y, ob->shapenum, spritedraw, ob->priority); -} - -/* -============================ -= -= KeenPoleReact -= -============================ -*/ - -void KeenPoleReact(objtype *ob) -{ - Uint16 far *map; - Uint16 ymove; - - map = mapsegs[1] + mapbwidthtable[ob->tilebottom]/2 + ob->tilemidx; - if (tinf[NORTHWALL + *map] == 1) - { - ymove = (ob->bottom & 0xFF) + 1; - ob->y -= ymove; - ob->bottom -= ymove; - ob->tilebottom--; - ob->needtoclip = cl_midclip; - ChangeState(ob, &s_keenlookdown); - } - - RF_PlaceSprite(&ob->sprite, ob->x, ob->y, ob->shapenum, spritedraw, ob->priority); -}