X-Git-Url: http://4ch.mooo.com/gitweb/?p=16.git;a=blobdiff_plain;f=16%2Fkeen456%2FKEEN4-6%2FKEEN4%2FK4_SPEC.C;fp=16%2Fkeen456%2FKEEN4-6%2FKEEN4%2FK4_SPEC.C;h=45c2861562e9357d60a728c12b742e2c0349fea0;hp=0000000000000000000000000000000000000000;hb=7d1948e210bb7b58af0a0412e71f2a0a0a2010af;hpb=ebc247a0a67daa69a027f31d9d7d9572db765e56 diff --git a/16/keen456/KEEN4-6/KEEN4/K4_SPEC.C b/16/keen456/KEEN4-6/KEEN4/K4_SPEC.C new file mode 100755 index 00000000..45c28615 --- /dev/null +++ b/16/keen456/KEEN4-6/KEEN4/K4_SPEC.C @@ -0,0 +1,1305 @@ +/* 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. + */ + +/* +K4_SPEC.C +========= + +Contains (in this order): + +- lump definition +- "Star Wars" crawl text +- level names & messages +- ScanInfoPlane() - for spawning the level objects and marking required sprites +- messages for Lindsey, Janitor, Oracle Members and more + +- actor states & implementation for swimming Keen + +*/ + +#include "CK_DEF.H" + +enum { + CONTROLS_LUMP, // 0 + KEEN_LUMP, // 1 + SUGAR1_LUMP, // 2 + SUGAR2_LUMP, // 3 + SUGAR3_LUMP, // 4 + SUGAR4_LUMP, // 5 + SUGAR5_LUMP, // 6 + SUGAR6_LUMP, // 7 + ONEUP_LUMP, // 8 + AMMO_LUMP, // 9 + WOLRDKEEN_LUMP, // 10 + SLUG_LUMP, // 11 + MADMUSHROOM_LUMP, // 12 + UNUSED1_LUMP, // 13 + LINDSEY_LUMP, // 14 + INCHWORM_LUMP, // 15 + EATER_LUMP, // 16 + COUNCIL_LUMP, // 17 + EGGBIRD_LUMP, // 18 + MIMROCK_LUMP, // 19 + DOPEFISH_LUMP, // 20 + SCHOOLFISH_LUMP, // 21 + ARACHNUT_LUMP, // 22 + SKYPEST_LUMP, // 23 + WORMOUTH_LUMP, // 24 + LICK_LUMP, // 25 + PLATFORM_LUMP, // 26 + BOUNDER_LUMP, // 27 + THUNDERCLOUD_LUMP, // 28 + BERKELOID_LUMP, // 29 + KEYGEM_LUMP, // 30 + DARTS_LUMP, // 31 + SCUBAKEEN_LUMP, // 32 + SPRITE_LUMP, // 33 + MINE_LUMP, // 34 + MOON_LUMP, // 35 + EGG_LUMP, // 36 + NUMLUMPS // 37 +}; + +Uint16 lumpstart[NUMLUMPS] = { + CONTROLS_LUMP_START, + KEEN_LUMP_START, + SUGAR1_LUMP_START, + SUGAR2_LUMP_START, + SUGAR3_LUMP_START, + SUGAR4_LUMP_START, + SUGAR5_LUMP_START, + SUGAR6_LUMP_START, + ONEUP_LUMP_START, + AMMO_LUMP_START, + WORLDKEEN_LUMP_START, + SLUG_LUMP_START, + MADMUSHROOM_LUMP_START, + 0, + LINDSEY_LUMP_START, + INCHWORM_LUMP_START, + EATER_LUMP_START, + COUNCIL_LUMP_START, + EGGBIRD_LUMP_START, + MIMROCK_LUMP_START, + DOPEFISH_LUMP_START, + SCHOOLFISH_LUMP_START, + ARACHNUT_LUMP_START, + SKYPEST_LUMP_START, + WORMOUTH_LUMP_START, + LICK_LUMP_START, + PLATFORM_LUMP_START, + BOUNDER_LUMP_START, + THUNDERCLOUD_LUMP_START, + BERKELOID_LUMP_START, + KEYGEM_LUMP_START, + DARTS_LUMP_START, + SCUBAKEEN_LUMP_START, + SPRITE_LUMP_START, + MINE_LUMP_START, + MOON_LUMP_START, + EGG_LUMP_START +}; + +Uint16 lumpend[NUMLUMPS] = { + CONTROLS_LUMP_END, + KEEN_LUMP_END, + SUGAR1_LUMP_END, + SUGAR2_LUMP_END, + SUGAR3_LUMP_END, + SUGAR4_LUMP_END, + SUGAR5_LUMP_END, + SUGAR6_LUMP_END, + ONEUP_LUMP_END, + AMMO_LUMP_END, + WORLDKEEN_LUMP_END, + SLUG_LUMP_END, + MADMUSHROOM_LUMP_END, + 0, + LINDSEY_LUMP_END, + INCHWORM_LUMP_END, + EATER_LUMP_END, + COUNCIL_LUMP_END, + EGGBIRD_LUMP_END, + MIMROCK_LUMP_END, + DOPEFISH_LUMP_END, + SCHOOLFISH_LUMP_END, + ARACHNUT_LUMP_END, + SKYPEST_LUMP_END, + WORMOUTH_LUMP_END, + LICK_LUMP_END, + PLATFORM_LUMP_END, + BOUNDER_LUMP_END, + THUNDERCLOUD_LUMP_END, + BERKELOID_LUMP_END, + KEYGEM_LUMP_END, + DARTS_LUMP_END, + SCUBAKEEN_LUMP_END, + SPRITE_LUMP_END, + MINE_LUMP_END, + MOON_LUMP_END, + EGG_LUMP_END +}; + +boolean lumpneeded[NUMLUMPS]; + +#if GRMODE == EGAGR + +char far swtext[] = + "Episode Four\n" + "\n" + "Secret of the Oracle\n" + "\n" + "After delivering a\n" + "crippling blow to the\n" + "plans of Mortimer\n" + "McMire and receiving\n" + "the praise of the\n" + "Vorticon race,\n" + "Commander Keen\n" + "returned to his home in\n" + "the suburbs.\n" + "\n" + "Here he was forced to\n" + "go to bed at an early\n" + "hour, and to eat mashed\n" + "potatoes.\n" + "\n" + "Months later, Billy\n" + "tinkered around with\n" + "his latest invention,\n" + "the Photachyon\n" + "Transceiver, or faster-\n" + "than-light radio. After\n" + "picking up a lot of bad\n" + "alien sitcoms, he\n" + "stumbled upon a strange\n" + "message of terrible\n" + "importance....\n"; + +#endif + +char far l0n[] = "Shadowlands"; +char far l1n[] = "Border Village"; +char far l2n[] = "Slug Village"; +char far l3n[] = "The Perilous Pit"; +char far l4n[] = "Cave of the Descendents"; +char far l5n[] = "Chasm of Chills"; +char far l6n[] = "Crystalus"; +char far l7n[] = "Hillville"; +char far l8n[] = "Sand Yego"; +char far l9n[] = "Miragia"; +char far l10n[] = "Lifewater Oasis"; +char far l11n[] = "Pyramid of the Moons"; +char far l12n[] = "Pyramid of Shadows"; +char far l13n[] = "Pyramid of the\nGnosticene Ancients"; +char far l14n[] = "Pyramid of the Forbidden"; +char far l15n[] = "Isle of Tar"; +char far l16n[] = "Isle of Fire"; +char far l17n[] = "Well of Wishes"; +char far l18n[] = "Bean-with-Bacon\nMegarocket"; + +char far l0e[] = "Keen enters the\nShadowlands"; +char far l1e[] = "Keen makes a run for\nthe Border Village"; +char far l2e[] = "Keen slips into\nSlug Village"; +char far l3e[] = "Keen plummets into\nthe The Perilous Pit"; // sic! +char far l4e[] = "Keen plods down into\nthe Cave of the\nDescendents"; +char far l5e[] = "Keen shivers along\nthe Chasm of Chills"; +char far l6e[] = "Keen reflects upon\nentering Crystalus"; +char far l7e[] = "Keen stumbles upon\nHillville"; +char far l8e[] = "Keen grits his teeth\nand enters Sand Yego"; +char far l9e[] = "Keen disappears into\nMiragia"; +char far l10e[] = "Keen crawls into\nLifewater Oasis"; +char far l11e[] = "Keen backs into the\nPyramid of the Moons"; +char far l12e[] = "Keen move silently in\nthe Pyramid of Shadows"; // sic! +char far l13e[] = "Keen reverently enters\nthe Pyramid of the\nGnosticene Ancients"; +char far l14e[] = "Keen hesitantly crosses\ninto the Pyramid of the\nForbidden"; +char far l15e[] = "Keen mucks along the\nIsle of Tar"; +char far l16e[] = "Keen blazes across the\nIsle of Fire"; +char far l17e[] = "Keen hopefully enters\nthe Well of Wishes"; +char far l18e[] = "Keen launches into the\nBean-with-Bacon\nMegarocket"; + +char far *levelnames[GAMELEVELS] = { + l0n, + l1n, + l2n, + l3n, + l4n, + l5n, + l6n, + l7n, + l8n, + l9n, + l10n, + l11n, + l12n, + l13n, + l14n, + l15n, + l16n, + l17n, + l18n +}; + +char far *levelenter[GAMELEVELS] = { + l0e, + l1e, + l2e, + l3e, + l4e, + l5e, + l6e, + l7e, + l8e, + l9e, + l10e, + l11e, + l12e, + l13e, + l14e, + l15e, + l16e, + l17e, + l18e +}; + +Uint16 bonuslump[] = { + KEYGEM_LUMP, KEYGEM_LUMP, KEYGEM_LUMP, KEYGEM_LUMP, + SUGAR1_LUMP, SUGAR2_LUMP, SUGAR3_LUMP, + SUGAR4_LUMP, SUGAR5_LUMP, SUGAR6_LUMP, + ONEUP_LUMP, AMMO_LUMP +}; + +//========================================================================== + +/* +========================== += += ScanInfoPlane += += Spawn all actors and mark down special places += +========================== +*/ + +void ScanInfoPlane(void) +{ + objtype *ob; + Uint16 i, x, y, chunk; + Sint16 info; + Uint16 far *map; + + InitObjArray(); // start spawning things with a clean slate + + memset(lumpneeded, 0, sizeof(lumpneeded)); + map = mapsegs[2]; + + for (y=0; ynext) + { + if (ob->active != ac_allways) + ob->active = ac_no; + } + + for (i = 0; i < NUMLUMPS; i++) + { + if (lumpneeded[i]) + { + for (chunk = lumpstart[i]; chunk <= lumpend[i]; chunk++) + { + CA_MarkGrChunk(chunk); + } + } + } +} + +//============================================================================ + +/* +=========================== += += PrincessLindsey += +=========================== +*/ + +char *lindseytext[2] = +{ + "There's gear to help\n" + "you swim in Three-Tooth\n" + "Lake. It is hidden in\n" + "Miragia.\n" + , + "The way to the Pyramid\n" + "of the Forbidden lies\n" + "under the Pyramid of\n" + "Moons.\n" +}; + +char *klindseytext[2] = +{ + "Thanks, your Highness!" + , + "Thanks for the\n" + "mysterious clue,\n" + "Princess!\n" +}; + +void PrincessLindsey(void) +{ + SD_WaitSoundDone(); + StopMusic(); + CA_UpLevel(); + CA_MarkGrChunk(LINDSEYPIC); + CA_MarkGrChunk(KEENTALK1PIC); + CA_MarkGrChunk(KEENTALK2PIC); + CA_CacheMarks(NULL); + VW_FixRefreshBuffer(); + + US_CenterWindow(26, 8); + VWB_DrawPic(WindowX, WindowY, LINDSEYPIC); + PrintY += 6; + WindowW -= 48; + WindowX += 48; + US_CPrint("Princess Lindsey says:\n"); + if (mapon == 7) + { + US_CPrint(lindseytext[0]); + } + else + { + US_CPrint(lindseytext[1]); + } + VW_UpdateScreen(); + SD_PlaySound(SND_MAKEFOOT); + VW_WaitVBL(60); + IN_ClearKeysDown(); + IN_Ack(); + + US_CenterWindow(26, 8); + VWB_DrawPic(WindowX+WindowW-48, WindowY, KEENTALK1PIC); + WindowW -= 48; + PrintY += 12; + if (mapon == 7) + { + US_CPrint(klindseytext[0]); + } + else + { + US_CPrint(klindseytext[1]); + } + VW_UpdateScreen(); + VW_WaitVBL(30); + IN_ClearKeysDown(); + IN_Ack(); + + VWB_DrawPic(WindowX+WindowW, WindowY, KEENTALK2PIC); + VW_UpdateScreen(); + VW_WaitVBL(30); + IN_ClearKeysDown(); + IN_Ack(); + + CA_DownLevel(); + StartMusic(gamestate.mapon); + + //reset scorebox (sprite may have been re-cached by CA_DownLevel) + scoreobj->temp2 = -1; + scoreobj->temp1 = -1; + scoreobj->temp3 = -1; + scoreobj->temp4 = -1; +} + +//============================================================================ + +/* +=========================== += += RescueJanitor += +=========================== +*/ + +char far jantext1[] = + "Thanks for going to all\n" + "that trouble, but I'm\n" + "just the janitor for the\n" + "High Council."; + +char far jantext2[] = + "I tried to tell the\n" + "Shikadi that but they\n" + "just wouldn't listen..."; + +char far keenjantext[] = + "This had better\n" + "be a joke."; + +char far jantext3[] = + "Sorry. You aren't\n" + "mad, are you?"; + +void RescueJanitor(void) +{ + char str[200]; + + SD_WaitSoundDone(); + CA_UpLevel(); + CA_MarkGrChunk(ORACLEPIC); + CA_MarkGrChunk(KEENTALK1PIC); + CA_MarkGrChunk(KEENMADPIC); + CA_CacheMarks(NULL); + VW_FixRefreshBuffer(); + StartMusic(-1); + + US_CenterWindow(26, 8); + VWB_DrawPic(WindowX, WindowY, ORACLEPIC); + PrintY += 6; + WindowW -= 48; + WindowX += 48; + _fstrcpy(str, jantext1); + US_CPrint(str); + VW_UpdateScreen(); + VW_WaitVBL(60); + IN_ClearKeysDown(); + IN_Ack(); + + US_CenterWindow(26, 8); + VWB_DrawPic(WindowX, WindowY, ORACLEPIC); + PrintY += 6; + WindowW -= 48; + WindowX += 48; + _fstrcpy(str, jantext2); + US_CPrint(str); + VW_UpdateScreen(); + VW_WaitVBL(60); + IN_ClearKeysDown(); + IN_Ack(); + + US_CenterWindow(26, 8); + VWB_DrawPic(WindowX+WindowW-48, WindowY, KEENTALK1PIC); + WindowW -= 48; + PrintY += 12; + _fstrcpy(str, keenjantext); + US_CPrint(str); + VW_UpdateScreen(); + VW_WaitVBL(60); + IN_ClearKeysDown(); + IN_Ack(); + + US_CenterWindow(26, 8); + VWB_DrawPic(WindowX, WindowY, ORACLEPIC); + PrintY += 6; + WindowW -= 48; + WindowX += 48; + _fstrcpy(str, jantext3); + US_CPrint(str); + VW_UpdateScreen(); + VW_WaitVBL(60); + IN_ClearKeysDown(); + IN_Ack(); + + US_CenterWindow(26, 8); + VWB_DrawPic(WindowX+WindowW-48, WindowY, KEENTALK1PIC); + VWB_DrawPic(WindowX+WindowW-40, WindowY+24, KEENMADPIC); + VW_UpdateScreen(); + VW_WaitVBL(30); + IN_ClearKeysDown(); + IN_Ack(); + + StopMusic(); + CA_DownLevel(); + StartMusic(gamestate.mapon); + + //BUG: scorebox needs to be reset here (sprite may have been re-cached by CA_DownLevel) +} + +//============================================================================ + +/* +=========================== += += CanitSwim += +=========================== +*/ + +void CantSwim(void) +{ + SD_WaitSoundDone(); + CA_UpLevel(); // kinda useless without CA_CacheMarks or CA_SetGrPurge + // BUG: haven't made anything purgable here, caching the pic may cause an "out of memory" crash + CA_CacheGrChunk(KEENTALK1PIC); + + US_CenterWindow(26, 8); + VWB_DrawPic(WindowX+WindowW-48, WindowY, KEENTALK1PIC); + WindowW -= 48; + PrintY += 12; + US_CPrint("I can't swim!"); + VW_UpdateScreen(); + VW_WaitVBL(30); + IN_ClearKeysDown(); + IN_Ack(); + CA_DownLevel(); + + //Note: scorebox sprite has not been re-cached here (didn't use CA_CacheMarks or anything else that would have made the sprite purgable) +} + +//============================================================================ + +/* +=========================== += += GotScuba += +=========================== +*/ + +void GotScuba(void) +{ + SD_WaitSoundDone(); + CA_UpLevel(); + CA_MarkGrChunk(KEENTALK1PIC); + CA_MarkGrChunk(KEENTALK2PIC); + CA_CacheMarks(NULL); + + US_CenterWindow(26, 8); + VWB_DrawPic(WindowX+WindowW-48, WindowY, KEENTALK1PIC); + WindowW -= 48; + PrintY += 12; + US_CPrint( + "Cool! I can breathe\n" + "under water now!" + ); + VW_UpdateScreen(); + VW_WaitVBL(30); + IN_ClearKeysDown(); + IN_Ack(); + + VWB_DrawPic(WindowX+WindowW, WindowY, KEENTALK2PIC); + VW_UpdateScreen(); + VW_WaitVBL(30); + IN_ClearKeysDown(); + IN_Ack(); + + CA_DownLevel(); + + //Note: scorebox sprite may have been re-cached by CA_DownLevel, but the level ends after this anyway +} + +//============================================================================ + +/* +=========================== += += RescuedMember += +=========================== +*/ + +char *keentext[] = { + "No sweat, oh guardian\n" + "of wisdom!" + , + "Sounds like a plan,\n" + "bearded one!" + , + "No problemo." + , + "Great. You know, you\n" + "look a lot like the\n" + "last guy I rescued..." + , + "Good idea, Gramps." + , + "May the road rise\n" + "to meet your feet,\n" + "Mr. Member." + , + "Wise plan of action,\n" + "your ancientness." + , + "You're the last one,\n" + "fella. Let's both\n" + "get back to the\n" + "Oracle chamber!" +}; + +void RescuedMember(void) +{ + SD_WaitSoundDone(); + CA_UpLevel(); + CA_MarkGrChunk(ORACLEPIC); + CA_MarkGrChunk(KEENTALK1PIC); + CA_MarkGrChunk(KEENTALK2PIC); + CA_CacheMarks(NULL); + StartMusic(-1); + VW_FixRefreshBuffer(); + + US_CenterWindow(26, 8); + VWB_DrawPic(WindowX, WindowY, ORACLEPIC); + PrintY += 6; + WindowW -= 48; + WindowX += 48; + if (mapon == 17) + { + US_CPrint( + "Ggoh thig you sogh mg\n" + "fgor regscuing mgge!\n" + "I'gll regur tgo the\n" + "Goracle chagber\n" + "igmediatggely. Blub." + ); + } + else + { + US_CPrint( + "Oh thank you so much\n" + "for rescuing me!\n" + "I'll return to the\n" + "Oracle chamber\n" + "immediately." + ); + } + VW_UpdateScreen(); + VW_WaitVBL(60); + IN_ClearKeysDown(); + IN_Ack(); + + US_CenterWindow(26, 8); + VWB_DrawPic(WindowX+WindowW-48, WindowY, KEENTALK1PIC); + WindowW -= 48; + PrintY += 12; + US_CPrint(keentext[gamestate.rescued]); + VW_UpdateScreen(); + VW_WaitVBL(30); + IN_ClearKeysDown(); + IN_Ack(); + + VWB_DrawPic(WindowX+WindowW, WindowY, KEENTALK2PIC); + VW_UpdateScreen(); + VW_WaitVBL(30); + IN_ClearKeysDown(); + IN_Ack(); + + gamestate.rescued++; + CA_DownLevel(); + StopMusic(); + + //Note: scorebox sprite may have been re-cached by CA_DownLevel, but the level ends after this anyway +} + +/* +============================================================================= + + SWIMMING KEEN + +temp4 = counter for spawning bubbles + +============================================================================= +*/ + +statetype s_keenswimslow1 = {SCUBAKEENL1SPR, SCUBAKEENR1SPR, stepthink, false, false, 50, 0, 0, T_KeenSwimSlow, C_KeenSwim, R_KeenSwim, &s_keenswimslow2}; +statetype s_keenswimslow2 = {SCUBAKEENL2SPR, SCUBAKEENR2SPR, stepthink, false, false, 50, 0, 0, T_KeenSwimSlow, C_KeenSwim, R_KeenSwim, &s_keenswimslow1}; +statetype s_keenswim1 = {SCUBAKEENL1SPR, SCUBAKEENR1SPR, stepthink, false, false, 50, 0, 0, T_KeenSwim, C_KeenSwim, R_KeenSwim, &s_keenswimslow2}; +statetype s_keenswim2 = {SCUBAKEENL2SPR, SCUBAKEENR2SPR, stepthink, false, false, 50, 0, 0, T_KeenSwim, C_KeenSwim, R_KeenSwim, &s_keenswimslow1}; +//Note: the die states for swimming Keen are in CK_KEEN.C and K4_ACT3.C (dopefish section) + +statetype s_kbubble1 = {SMALLBUBBLE1SPR, SMALLBUBBLE1SPR, think, false, false, 20, 0, 24, T_Bubble, NULL, R_Draw, &s_kbubble1}; +statetype s_kbubble2 = {SMALLBUBBLE2SPR, SMALLBUBBLE2SPR, think, false, false, 20, 0, 24, T_Bubble, NULL, R_Draw, &s_kbubble2}; +statetype s_kbubble3 = {SMALLBUBBLE3SPR, SMALLBUBBLE3SPR, think, false, false, 20, 0, 24, T_Bubble, NULL, R_Draw, &s_kbubble3}; +statetype s_kbubble4 = {SMALLBUBBLE4SPR, SMALLBUBBLE4SPR, think, false, false, 20, 0, 24, T_Bubble, NULL, R_Draw, &s_kbubble4}; + +/* +=========================== += += SpawnSwimKeen += +=========================== +*/ + +void SpawnSwimKeen(Sint16 x, Sint16 y) +{ + player->obclass = keenobj; + player->active = ac_allways; + player->priority = 1; + player->x = CONVERT_TILE_TO_GLOBAL(x); + player->y = CONVERT_TILE_TO_GLOBAL(y); + player->xdir = 1; + player->ydir = 1; + player->needtoclip = cl_fullclip; + NewState(player, &s_keenswimslow1); +} + +/* +=========================== += += SpawnKbubble += +=========================== +*/ + +void SpawnKbubble(objtype *ob) +{ + ob->temp4 = 0; + GetNewObj(true); + if (ob->xdir == -1) + { + new->x = ob->x; + } + else + { + new->x = ob->x + 24*PIXGLOBAL; + } + new->y = ob->y; + new->obclass = inertobj; + new->priority = 3; + new->active = ac_removable; + new->needtoclip = cl_noclip; + new->yspeed = -24; + new->xspeed = 4; + switch (US_RndT() / 64) + { + case 0: + NewState(new, &s_kbubble1); + break; + case 1: + NewState(new, &s_kbubble2); + break; + case 2: + NewState(new, &s_kbubble3); + break; + case 3: + NewState(new, &s_kbubble4); + break; + } + SD_PlaySound(SND_BLUB); +} + +/* +=========================== += += T_KeenSwimSlow += +=========================== +*/ + +void T_KeenSwimSlow(objtype *ob) +{ + Sint32 i; + Sint16 vx, vy, xc, yc; + + xc = ob->xspeed < 0; + yc = ob->yspeed < 4; + + ob->temp4 = ob->temp4 + tics; + if (ob->temp4 > 60) + SpawnKbubble(ob); + + if (jumpbutton && !jumpheld) + { + jumpheld = true; + if (c.xaxis) + ob->xspeed = c.xaxis * 18; + if (c.yaxis) + ob->yspeed = c.yaxis * 18; + ob->state = ob->state->nextstate; + } + if (c.xaxis) + ob->xdir = c.xaxis; + + for (i = lasttimecount-tics; i < lasttimecount; i++) + { + if ((i & 7) == 0) + { + if (ob->xspeed > 12) + { + vx = -3; + } + else if (ob->xspeed > 0) + { + vx = -1; + } + else if (ob->xspeed > -12) + { + vx = 1; + } + else + { + vx = 3; + } + vx += c.xaxis; + vx += c.xaxis; + ob->xspeed += vx; + + if (c.xaxis == 0 && (ob->xspeed < 0) != xc) + ob->xspeed = 0; + + if (ob->yspeed > 12) + { + vy = -3; + } + else if (ob->yspeed > 4) + { + vy = -1; + } + else if (ob->yspeed > -12) + { + vy = 1; + } + else + { + vy = 3; + } + vy += c.yaxis; + vy += c.yaxis; + ob->yspeed += vy; + + if (c.yaxis == 0 && ob->yspeed > 4 && yc) + ob->yspeed = 0; + } + xtry += ob->xspeed; + ytry += ob->yspeed; + } +} + +/* +=========================== += += T_KeenSwim += +=========================== +*/ + +void T_KeenSwim(objtype *ob) //never actually used +{ + ob->temp4 = ob->temp4 + tics; + if (ob->temp4 > 60) + SpawnKbubble(ob); + + if (jumpbutton && !jumpheld) + { + jumpheld = true; + ob->xspeed = c.xaxis * 18; + if (c.yaxis) + ob->yspeed = c.yaxis * 18; + + if (ob->state == &s_keenswim1) + { + ob->state = &s_keenswim2; + } + else + { + ob->state = &s_keenswim1; + } + } + + xtry = xtry + ob->xspeed * tics; + ytry = ytry + ob->yspeed * tics; + if (xtry > 0) + { + ob->xdir = 1; + } + else if (xtry < 0) + { + ob->xdir = -1; + } + + ytry = ytry + tics*4; +} + +/* +=========================== += += C_KeenSwim += +=========================== +*/ + +void C_KeenSwim(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: + 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]; + } + ChangeState(hit, &s_bonusrise); + break; + } + break; + + case oracleobj: + playstate = ex_rescued; + break; + } + ob++; // shut up compiler +} + +/* +=========================== += += R_KeenSwim += +=========================== +*/ + +void R_KeenSwim(objtype *ob) +{ + if (ob->hiteast && ob->xspeed < 0 || ob->hitwest && ob->xspeed > 0) + ob->xspeed = 0; + + if (ob->hitnorth && ob->yspeed > 0 || ob->hitsouth && ob->yspeed < 0) + ob->yspeed = 0; + + RF_PlaceSprite(&ob->sprite, ob->x, ob->y, ob->shapenum, spritedraw, ob->priority); +}