1 /* Reconstructed Commander Keen 4-6 Source Code
\r
2 * Copyright (C) 2021 K1n9_Duk3
\r
4 * This file is loosely based on:
\r
5 * Keen Dreams Source Code
\r
6 * Copyright (C) 2014 Javier M. Chavez
\r
8 * This program is free software; you can redistribute it and/or modify
\r
9 * it under the terms of the GNU General Public License as published by
\r
10 * the Free Software Foundation; either version 2 of the License, or
\r
11 * (at your option) any later version.
\r
13 * This program is distributed in the hope that it will be useful,
\r
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
16 * GNU General Public License for more details.
\r
18 * You should have received a copy of the GNU General Public License along
\r
19 * with this program; if not, write to the Free Software Foundation, Inc.,
\r
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
\r
27 Contains (in this order):
\r
30 - "Star Wars" crawl text
\r
31 - level names & messages
\r
32 - ScanInfoPlane() - for spawning the level objects and marking required sprites
\r
33 - messages for Lindsey, Janitor, Oracle Members and more
\r
35 - actor states & implementation for swimming Keen
\r
52 WOLRDKEEN_LUMP, // 10
\r
54 MADMUSHROOM_LUMP, // 12
\r
57 INCHWORM_LUMP, // 15
\r
62 DOPEFISH_LUMP, // 20
\r
63 SCHOOLFISH_LUMP, // 21
\r
64 ARACHNUT_LUMP, // 22
\r
66 WORMOUTH_LUMP, // 24
\r
68 PLATFORM_LUMP, // 26
\r
70 THUNDERCLOUD_LUMP, // 28
\r
71 BERKELOID_LUMP, // 29
\r
74 SCUBAKEEN_LUMP, // 32
\r
82 Uint16 lumpstart[NUMLUMPS] = {
\r
83 CONTROLS_LUMP_START,
\r
93 WORLDKEEN_LUMP_START,
\r
95 MADMUSHROOM_LUMP_START,
\r
98 INCHWORM_LUMP_START,
\r
100 COUNCIL_LUMP_START,
\r
101 EGGBIRD_LUMP_START,
\r
102 MIMROCK_LUMP_START,
\r
103 DOPEFISH_LUMP_START,
\r
104 SCHOOLFISH_LUMP_START,
\r
105 ARACHNUT_LUMP_START,
\r
106 SKYPEST_LUMP_START,
\r
107 WORMOUTH_LUMP_START,
\r
109 PLATFORM_LUMP_START,
\r
110 BOUNDER_LUMP_START,
\r
111 THUNDERCLOUD_LUMP_START,
\r
112 BERKELOID_LUMP_START,
\r
115 SCUBAKEEN_LUMP_START,
\r
122 Uint16 lumpend[NUMLUMPS] = {
\r
133 WORLDKEEN_LUMP_END,
\r
135 MADMUSHROOM_LUMP_END,
\r
144 SCHOOLFISH_LUMP_END,
\r
151 THUNDERCLOUD_LUMP_END,
\r
152 BERKELOID_LUMP_END,
\r
155 SCUBAKEEN_LUMP_END,
\r
162 boolean lumpneeded[NUMLUMPS];
\r
164 #if GRMODE == EGAGR
\r
166 char far swtext[] =
\r
169 "Secret of the Oracle\n"
\r
171 "After delivering a\n"
\r
172 "crippling blow to the\n"
\r
173 "plans of Mortimer\n"
\r
174 "McMire and receiving\n"
\r
175 "the praise of the\n"
\r
178 "returned to his home in\n"
\r
181 "Here he was forced to\n"
\r
182 "go to bed at an early\n"
\r
183 "hour, and to eat mashed\n"
\r
186 "Months later, Billy\n"
\r
187 "tinkered around with\n"
\r
188 "his latest invention,\n"
\r
190 "Transceiver, or faster-\n"
\r
191 "than-light radio. After\n"
\r
192 "picking up a lot of bad\n"
\r
193 "alien sitcoms, he\n"
\r
194 "stumbled upon a strange\n"
\r
195 "message of terrible\n"
\r
196 "importance....\n";
\r
200 char far l0n[] = "Shadowlands";
\r
201 char far l1n[] = "Border Village";
\r
202 char far l2n[] = "Slug Village";
\r
203 char far l3n[] = "The Perilous Pit";
\r
204 char far l4n[] = "Cave of the Descendents";
\r
205 char far l5n[] = "Chasm of Chills";
\r
206 char far l6n[] = "Crystalus";
\r
207 char far l7n[] = "Hillville";
\r
208 char far l8n[] = "Sand Yego";
\r
209 char far l9n[] = "Miragia";
\r
210 char far l10n[] = "Lifewater Oasis";
\r
211 char far l11n[] = "Pyramid of the Moons";
\r
212 char far l12n[] = "Pyramid of Shadows";
\r
213 char far l13n[] = "Pyramid of the\nGnosticene Ancients";
\r
214 char far l14n[] = "Pyramid of the Forbidden";
\r
215 char far l15n[] = "Isle of Tar";
\r
216 char far l16n[] = "Isle of Fire";
\r
217 char far l17n[] = "Well of Wishes";
\r
218 char far l18n[] = "Bean-with-Bacon\nMegarocket";
\r
220 char far l0e[] = "Keen enters the\nShadowlands";
\r
221 char far l1e[] = "Keen makes a run for\nthe Border Village";
\r
222 char far l2e[] = "Keen slips into\nSlug Village";
\r
223 char far l3e[] = "Keen plummets into\nthe The Perilous Pit"; // sic!
\r
224 char far l4e[] = "Keen plods down into\nthe Cave of the\nDescendents";
\r
225 char far l5e[] = "Keen shivers along\nthe Chasm of Chills";
\r
226 char far l6e[] = "Keen reflects upon\nentering Crystalus";
\r
227 char far l7e[] = "Keen stumbles upon\nHillville";
\r
228 char far l8e[] = "Keen grits his teeth\nand enters Sand Yego";
\r
229 char far l9e[] = "Keen disappears into\nMiragia";
\r
230 char far l10e[] = "Keen crawls into\nLifewater Oasis";
\r
231 char far l11e[] = "Keen backs into the\nPyramid of the Moons";
\r
232 char far l12e[] = "Keen move silently in\nthe Pyramid of Shadows"; // sic!
\r
233 char far l13e[] = "Keen reverently enters\nthe Pyramid of the\nGnosticene Ancients";
\r
234 char far l14e[] = "Keen hesitantly crosses\ninto the Pyramid of the\nForbidden";
\r
235 char far l15e[] = "Keen mucks along the\nIsle of Tar";
\r
236 char far l16e[] = "Keen blazes across the\nIsle of Fire";
\r
237 char far l17e[] = "Keen hopefully enters\nthe Well of Wishes";
\r
238 char far l18e[] = "Keen launches into the\nBean-with-Bacon\nMegarocket";
\r
240 char far *levelnames[GAMELEVELS] = {
\r
262 char far *levelenter[GAMELEVELS] = {
\r
284 Uint16 bonuslump[] = {
\r
285 KEYGEM_LUMP, KEYGEM_LUMP, KEYGEM_LUMP, KEYGEM_LUMP,
\r
286 SUGAR1_LUMP, SUGAR2_LUMP, SUGAR3_LUMP,
\r
287 SUGAR4_LUMP, SUGAR5_LUMP, SUGAR6_LUMP,
\r
288 ONEUP_LUMP, AMMO_LUMP
\r
291 //==========================================================================
\r
294 ==========================
\r
298 = Spawn all actors and mark down special places
\r
300 ==========================
\r
303 void ScanInfoPlane(void)
\r
306 Uint16 i, x, y, chunk;
\r
310 InitObjArray(); // start spawning things with a clean slate
\r
312 memset(lumpneeded, 0, sizeof(lumpneeded));
\r
315 for (y=0; y<mapheight; y++)
\r
317 for (x=0; x<mapwidth; x++)
\r
327 SpawnKeen(x, y, 1);
\r
329 lumpneeded[KEEN_LUMP] = true;
\r
330 CA_MarkGrChunk(SCOREBOXSPR);
\r
334 SpawnKeen(x, y, -1);
\r
336 lumpneeded[KEEN_LUMP] = true;
\r
337 CA_MarkGrChunk(SCOREBOXSPR);
\r
341 SpawnWorldKeen(x, y);
\r
343 lumpneeded[WOLRDKEEN_LUMP] = true;
\r
344 CA_MarkGrChunk(SCOREBOXSPR);
\r
348 SpawnCouncil(x, y);
\r
349 lumpneeded[COUNCIL_LUMP] = true;
\r
353 if (gamestate.difficulty < gd_Hard)
\r
356 if (gamestate.difficulty < gd_Normal)
\r
359 SpawnBerkeloid(x, y);
\r
360 lumpneeded[BERKELOID_LUMP] = true;
\r
364 SpawnLindsey(x, y);
\r
365 lumpneeded[LINDSEY_LUMP] = true;
\r
369 if (gamestate.difficulty < gd_Hard)
\r
372 if (gamestate.difficulty < gd_Normal)
\r
375 SpawnWormMouth(x, y);
\r
376 lumpneeded[WORMOUTH_LUMP] = true;
\r
380 if (gamestate.difficulty < gd_Hard)
\r
383 if (gamestate.difficulty < gd_Normal)
\r
386 SpawnSkypest(x, y);
\r
387 lumpneeded[SKYPEST_LUMP] = true;
\r
391 SpawnCloudster(x, y);
\r
392 lumpneeded[THUNDERCLOUD_LUMP] = true;
\r
397 lumpneeded[INCHWORM_LUMP] = true; // lump includes the foot sprite
\r
398 // Note: The smoke sprites aren't actually required for the foot!
\r
399 for (i=SMOKE1SPR; i<=SMOKE4SPR; i++)
\r
406 SpawnInchworm(x, y);
\r
407 lumpneeded[INCHWORM_LUMP] = true;
\r
408 for (i=SMOKE1SPR; i<=SMOKE4SPR; i++)
\r
415 SpawnBounder(x, y);
\r
416 lumpneeded[BOUNDER_LUMP] = true;
\r
420 SpawnEggbird(x, y);
\r
421 lumpneeded[EGGBIRD_LUMP] = true;
\r
422 lumpneeded[EGG_LUMP] = true;
\r
426 if (gamestate.difficulty < gd_Hard)
\r
429 if (gamestate.difficulty < gd_Normal)
\r
433 lumpneeded[LICK_LUMP] = true;
\r
437 if (gamestate.difficulty < gd_Hard)
\r
440 if (gamestate.difficulty < gd_Normal)
\r
443 SpawnDopefish(x, y);
\r
444 lumpneeded[DOPEFISH_LUMP] = true;
\r
448 SpawnSchoolfish(x, y);
\r
449 lumpneeded[SCHOOLFISH_LUMP] = true;
\r
453 if (gamestate.difficulty < gd_Hard)
\r
456 if (gamestate.difficulty < gd_Normal)
\r
460 lumpneeded[SPRITE_LUMP] = true;
\r
465 lumpneeded[EATER_LUMP] = true;
\r
469 SpawnMimrock(x, y);
\r
470 lumpneeded[MIMROCK_LUMP] = true;
\r
474 if (gamestate.difficulty < gd_Hard)
\r
477 if (gamestate.difficulty < gd_Normal)
\r
480 SpawnArachnut(x, y);
\r
481 lumpneeded[ARACHNUT_LUMP] = true;
\r
485 SpawnMadMushroom(x, y);
\r
486 lumpneeded[MADMUSHROOM_LUMP] = true;
\r
490 if (gamestate.difficulty < gd_Hard)
\r
493 if (gamestate.difficulty < gd_Normal)
\r
497 lumpneeded[SLUG_LUMP] = true;
\r
501 RF_SetScrollBlock(x, y, 1);
\r
505 RF_SetScrollBlock(x, y, 0);
\r
512 SpawnPlatform(x, y, info-27);
\r
513 lumpneeded[PLATFORM_LUMP] = true;;
\r
517 SpawnDropPlat(x, y);
\r
518 lumpneeded[PLATFORM_LUMP] = true;
\r
522 SpawnMiragia(x, y);
\r
526 if (gamestate.ammo < 5)
\r
528 SpawnBonus(x, y, 11);
\r
529 lumpneeded[bonuslump[11]] = true;
\r
535 CA_MarkGrChunk(SCUBASPR);
\r
539 SpawnSwimKeen(x, y);
\r
541 lumpneeded[SCUBAKEEN_LUMP] = true;
\r
542 //mark pickup shapes:
\r
543 for (i=BONUS100SPR; i<=BONUSCLIPSPR; i++)
\r
547 CA_MarkGrChunk(SCOREBOXSPR);
\r
554 if (gamestate.difficulty < gd_Hard)
\r
556 SpawnDartShooter(x, y, info-83);
\r
557 lumpneeded[DARTS_LUMP] = true;
\r
564 if (gamestate.difficulty < gd_Normal)
\r
566 SpawnDartShooter(x, y, info-79);
\r
567 lumpneeded[DARTS_LUMP] = true;
\r
574 SpawnDartShooter(x, y, info-53);
\r
575 lumpneeded[DARTS_LUMP] = true;
\r
590 SpawnBonus(x, y, info-57);
\r
591 lumpneeded[bonuslump[info-57]] = true;
\r
598 SpawnMine(x, y, info-69);
\r
599 lumpneeded[MINE_LUMP] = true;
\r
603 lumpneeded[MOON_LUMP] = true;
\r
607 if (gamestate.difficulty < gd_Hard)
\r
610 if (gamestate.difficulty < gd_Normal)
\r
613 SpawnEggbirdOut(x, y);
\r
614 lumpneeded[EGGBIRD_LUMP] = true;
\r
620 for (ob = player; ob; ob = ob->next)
\r
622 if (ob->active != ac_allways)
\r
623 ob->active = ac_no;
\r
626 for (i = 0; i < NUMLUMPS; i++)
\r
630 for (chunk = lumpstart[i]; chunk <= lumpend[i]; chunk++)
\r
632 CA_MarkGrChunk(chunk);
\r
638 //============================================================================
\r
641 ===========================
\r
645 ===========================
\r
648 char *lindseytext[2] =
\r
650 "There's gear to help\n"
\r
651 "you swim in Three-Tooth\n"
\r
652 "Lake. It is hidden in\n"
\r
655 "The way to the Pyramid\n"
\r
656 "of the Forbidden lies\n"
\r
657 "under the Pyramid of\n"
\r
661 char *klindseytext[2] =
\r
663 "Thanks, your Highness!"
\r
666 "mysterious clue,\n"
\r
670 void PrincessLindsey(void)
\r
672 SD_WaitSoundDone();
\r
675 CA_MarkGrChunk(LINDSEYPIC);
\r
676 CA_MarkGrChunk(KEENTALK1PIC);
\r
677 CA_MarkGrChunk(KEENTALK2PIC);
\r
678 CA_CacheMarks(NULL);
\r
679 VW_FixRefreshBuffer();
\r
681 US_CenterWindow(26, 8);
\r
682 VWB_DrawPic(WindowX, WindowY, LINDSEYPIC);
\r
686 US_CPrint("Princess Lindsey says:\n");
\r
689 US_CPrint(lindseytext[0]);
\r
693 US_CPrint(lindseytext[1]);
\r
696 SD_PlaySound(SND_MAKEFOOT);
\r
698 IN_ClearKeysDown();
\r
701 US_CenterWindow(26, 8);
\r
702 VWB_DrawPic(WindowX+WindowW-48, WindowY, KEENTALK1PIC);
\r
707 US_CPrint(klindseytext[0]);
\r
711 US_CPrint(klindseytext[1]);
\r
715 IN_ClearKeysDown();
\r
718 VWB_DrawPic(WindowX+WindowW, WindowY, KEENTALK2PIC);
\r
721 IN_ClearKeysDown();
\r
725 StartMusic(gamestate.mapon);
\r
727 //reset scorebox (sprite may have been re-cached by CA_DownLevel)
\r
728 scoreobj->temp2 = -1;
\r
729 scoreobj->temp1 = -1;
\r
730 scoreobj->temp3 = -1;
\r
731 scoreobj->temp4 = -1;
\r
734 //============================================================================
\r
737 ===========================
\r
741 ===========================
\r
744 char far jantext1[] =
\r
745 "Thanks for going to all\n"
\r
746 "that trouble, but I'm\n"
\r
747 "just the janitor for the\n"
\r
750 char far jantext2[] =
\r
751 "I tried to tell the\n"
\r
752 "Shikadi that but they\n"
\r
753 "just wouldn't listen...";
\r
755 char far keenjantext[] =
\r
756 "This had better\n"
\r
759 char far jantext3[] =
\r
760 "Sorry. You aren't\n"
\r
763 void RescueJanitor(void)
\r
767 SD_WaitSoundDone();
\r
769 CA_MarkGrChunk(ORACLEPIC);
\r
770 CA_MarkGrChunk(KEENTALK1PIC);
\r
771 CA_MarkGrChunk(KEENMADPIC);
\r
772 CA_CacheMarks(NULL);
\r
773 VW_FixRefreshBuffer();
\r
776 US_CenterWindow(26, 8);
\r
777 VWB_DrawPic(WindowX, WindowY, ORACLEPIC);
\r
781 _fstrcpy(str, jantext1);
\r
785 IN_ClearKeysDown();
\r
788 US_CenterWindow(26, 8);
\r
789 VWB_DrawPic(WindowX, WindowY, ORACLEPIC);
\r
793 _fstrcpy(str, jantext2);
\r
797 IN_ClearKeysDown();
\r
800 US_CenterWindow(26, 8);
\r
801 VWB_DrawPic(WindowX+WindowW-48, WindowY, KEENTALK1PIC);
\r
804 _fstrcpy(str, keenjantext);
\r
808 IN_ClearKeysDown();
\r
811 US_CenterWindow(26, 8);
\r
812 VWB_DrawPic(WindowX, WindowY, ORACLEPIC);
\r
816 _fstrcpy(str, jantext3);
\r
820 IN_ClearKeysDown();
\r
823 US_CenterWindow(26, 8);
\r
824 VWB_DrawPic(WindowX+WindowW-48, WindowY, KEENTALK1PIC);
\r
825 VWB_DrawPic(WindowX+WindowW-40, WindowY+24, KEENMADPIC);
\r
828 IN_ClearKeysDown();
\r
833 StartMusic(gamestate.mapon);
\r
835 //BUG: scorebox needs to be reset here (sprite may have been re-cached by CA_DownLevel)
\r
838 //============================================================================
\r
841 ===========================
\r
845 ===========================
\r
848 void CantSwim(void)
\r
850 SD_WaitSoundDone();
\r
851 CA_UpLevel(); // kinda useless without CA_CacheMarks or CA_SetGrPurge
\r
852 // BUG: haven't made anything purgable here, caching the pic may cause an "out of memory" crash
\r
853 CA_CacheGrChunk(KEENTALK1PIC);
\r
855 US_CenterWindow(26, 8);
\r
856 VWB_DrawPic(WindowX+WindowW-48, WindowY, KEENTALK1PIC);
\r
859 US_CPrint("I can't swim!");
\r
862 IN_ClearKeysDown();
\r
866 //Note: scorebox sprite has not been re-cached here (didn't use CA_CacheMarks or anything else that would have made the sprite purgable)
\r
869 //============================================================================
\r
872 ===========================
\r
876 ===========================
\r
879 void GotScuba(void)
\r
881 SD_WaitSoundDone();
\r
883 CA_MarkGrChunk(KEENTALK1PIC);
\r
884 CA_MarkGrChunk(KEENTALK2PIC);
\r
885 CA_CacheMarks(NULL);
\r
887 US_CenterWindow(26, 8);
\r
888 VWB_DrawPic(WindowX+WindowW-48, WindowY, KEENTALK1PIC);
\r
892 "Cool! I can breathe\n"
\r
897 IN_ClearKeysDown();
\r
900 VWB_DrawPic(WindowX+WindowW, WindowY, KEENTALK2PIC);
\r
903 IN_ClearKeysDown();
\r
908 //Note: scorebox sprite may have been re-cached by CA_DownLevel, but the level ends after this anyway
\r
911 //============================================================================
\r
914 ===========================
\r
918 ===========================
\r
921 char *keentext[] = {
\r
922 "No sweat, oh guardian\n"
\r
925 "Sounds like a plan,\n"
\r
930 "Great. You know, you\n"
\r
931 "look a lot like the\n"
\r
932 "last guy I rescued..."
\r
934 "Good idea, Gramps."
\r
936 "May the road rise\n"
\r
937 "to meet your feet,\n"
\r
940 "Wise plan of action,\n"
\r
941 "your ancientness."
\r
943 "You're the last one,\n"
\r
944 "fella. Let's both\n"
\r
945 "get back to the\n"
\r
949 void RescuedMember(void)
\r
951 SD_WaitSoundDone();
\r
953 CA_MarkGrChunk(ORACLEPIC);
\r
954 CA_MarkGrChunk(KEENTALK1PIC);
\r
955 CA_MarkGrChunk(KEENTALK2PIC);
\r
956 CA_CacheMarks(NULL);
\r
958 VW_FixRefreshBuffer();
\r
960 US_CenterWindow(26, 8);
\r
961 VWB_DrawPic(WindowX, WindowY, ORACLEPIC);
\r
968 "Ggoh thig you sogh mg\n"
\r
969 "fgor regscuing mgge!\n"
\r
970 "I'gll regur tgo the\n"
\r
971 "Goracle chagber\n"
\r
972 "igmediatggely. Blub."
\r
978 "Oh thank you so much\n"
\r
979 "for rescuing me!\n"
\r
980 "I'll return to the\n"
\r
987 IN_ClearKeysDown();
\r
990 US_CenterWindow(26, 8);
\r
991 VWB_DrawPic(WindowX+WindowW-48, WindowY, KEENTALK1PIC);
\r
994 US_CPrint(keentext[gamestate.rescued]);
\r
997 IN_ClearKeysDown();
\r
1000 VWB_DrawPic(WindowX+WindowW, WindowY, KEENTALK2PIC);
\r
1001 VW_UpdateScreen();
\r
1003 IN_ClearKeysDown();
\r
1006 gamestate.rescued++;
\r
1010 //Note: scorebox sprite may have been re-cached by CA_DownLevel, but the level ends after this anyway
\r
1014 =============================================================================
\r
1018 temp4 = counter for spawning bubbles
\r
1020 =============================================================================
\r
1023 statetype s_keenswimslow1 = {SCUBAKEENL1SPR, SCUBAKEENR1SPR, stepthink, false, false, 50, 0, 0, T_KeenSwimSlow, C_KeenSwim, R_KeenSwim, &s_keenswimslow2};
\r
1024 statetype s_keenswimslow2 = {SCUBAKEENL2SPR, SCUBAKEENR2SPR, stepthink, false, false, 50, 0, 0, T_KeenSwimSlow, C_KeenSwim, R_KeenSwim, &s_keenswimslow1};
\r
1025 statetype s_keenswim1 = {SCUBAKEENL1SPR, SCUBAKEENR1SPR, stepthink, false, false, 50, 0, 0, T_KeenSwim, C_KeenSwim, R_KeenSwim, &s_keenswimslow2};
\r
1026 statetype s_keenswim2 = {SCUBAKEENL2SPR, SCUBAKEENR2SPR, stepthink, false, false, 50, 0, 0, T_KeenSwim, C_KeenSwim, R_KeenSwim, &s_keenswimslow1};
\r
1027 //Note: the die states for swimming Keen are in CK_KEEN.C and K4_ACT3.C (dopefish section)
\r
1029 statetype s_kbubble1 = {SMALLBUBBLE1SPR, SMALLBUBBLE1SPR, think, false, false, 20, 0, 24, T_Bubble, NULL, R_Draw, &s_kbubble1};
\r
1030 statetype s_kbubble2 = {SMALLBUBBLE2SPR, SMALLBUBBLE2SPR, think, false, false, 20, 0, 24, T_Bubble, NULL, R_Draw, &s_kbubble2};
\r
1031 statetype s_kbubble3 = {SMALLBUBBLE3SPR, SMALLBUBBLE3SPR, think, false, false, 20, 0, 24, T_Bubble, NULL, R_Draw, &s_kbubble3};
\r
1032 statetype s_kbubble4 = {SMALLBUBBLE4SPR, SMALLBUBBLE4SPR, think, false, false, 20, 0, 24, T_Bubble, NULL, R_Draw, &s_kbubble4};
\r
1035 ===========================
\r
1039 ===========================
\r
1042 void SpawnSwimKeen(Sint16 x, Sint16 y)
\r
1044 player->obclass = keenobj;
\r
1045 player->active = ac_allways;
\r
1046 player->priority = 1;
\r
1047 player->x = CONVERT_TILE_TO_GLOBAL(x);
\r
1048 player->y = CONVERT_TILE_TO_GLOBAL(y);
\r
1051 player->needtoclip = cl_fullclip;
\r
1052 NewState(player, &s_keenswimslow1);
\r
1056 ===========================
\r
1060 ===========================
\r
1063 void SpawnKbubble(objtype *ob)
\r
1067 if (ob->xdir == -1)
\r
1073 new->x = ob->x + 24*PIXGLOBAL;
\r
1076 new->obclass = inertobj;
\r
1077 new->priority = 3;
\r
1078 new->active = ac_removable;
\r
1079 new->needtoclip = cl_noclip;
\r
1080 new->yspeed = -24;
\r
1082 switch (US_RndT() / 64)
\r
1085 NewState(new, &s_kbubble1);
\r
1088 NewState(new, &s_kbubble2);
\r
1091 NewState(new, &s_kbubble3);
\r
1094 NewState(new, &s_kbubble4);
\r
1097 SD_PlaySound(SND_BLUB);
\r
1101 ===========================
\r
1105 ===========================
\r
1108 void T_KeenSwimSlow(objtype *ob)
\r
1111 Sint16 vx, vy, xc, yc;
\r
1113 xc = ob->xspeed < 0;
\r
1114 yc = ob->yspeed < 4;
\r
1116 ob->temp4 = ob->temp4 + tics;
\r
1117 if (ob->temp4 > 60)
\r
1120 if (jumpbutton && !jumpheld)
\r
1124 ob->xspeed = c.xaxis * 18;
\r
1126 ob->yspeed = c.yaxis * 18;
\r
1127 ob->state = ob->state->nextstate;
\r
1130 ob->xdir = c.xaxis;
\r
1132 for (i = lasttimecount-tics; i < lasttimecount; i++)
\r
1136 if (ob->xspeed > 12)
\r
1140 else if (ob->xspeed > 0)
\r
1144 else if (ob->xspeed > -12)
\r
1156 if (c.xaxis == 0 && (ob->xspeed < 0) != xc)
\r
1159 if (ob->yspeed > 12)
\r
1163 else if (ob->yspeed > 4)
\r
1167 else if (ob->yspeed > -12)
\r
1179 if (c.yaxis == 0 && ob->yspeed > 4 && yc)
\r
1182 xtry += ob->xspeed;
\r
1183 ytry += ob->yspeed;
\r
1188 ===========================
\r
1192 ===========================
\r
1195 void T_KeenSwim(objtype *ob) //never actually used
\r
1197 ob->temp4 = ob->temp4 + tics;
\r
1198 if (ob->temp4 > 60)
\r
1201 if (jumpbutton && !jumpheld)
\r
1204 ob->xspeed = c.xaxis * 18;
\r
1206 ob->yspeed = c.yaxis * 18;
\r
1208 if (ob->state == &s_keenswim1)
\r
1210 ob->state = &s_keenswim2;
\r
1214 ob->state = &s_keenswim1;
\r
1218 xtry = xtry + ob->xspeed * tics;
\r
1219 ytry = ytry + ob->yspeed * tics;
\r
1224 else if (xtry < 0)
\r
1229 ytry = ytry + tics*4;
\r
1233 ===========================
\r
1237 ===========================
\r
1240 void C_KeenSwim(objtype *ob, objtype *hit)
\r
1242 switch (hit->obclass)
\r
1245 switch (hit->temp1)
\r
1259 SD_PlaySound(bonussound[hit->temp1]);
\r
1260 hit->obclass = inertobj;
\r
1261 hit->priority = 3;
\r
1262 hit->shapenum = bonussprite[hit->temp1];
\r
1263 GivePoints(bonuspoints[hit->temp1]);
\r
1264 if (hit->temp1 < 4)
\r
1266 gamestate.keys[hit->temp1]++;
\r
1268 else if (hit->temp1 == 10)
\r
1270 gamestate.lives++;
\r
1272 else if (hit->temp1 == 11)
\r
1274 gamestate.ammo += shotsinclip[gamestate.difficulty];
\r
1276 ChangeState(hit, &s_bonusrise);
\r
1282 playstate = ex_rescued;
\r
1285 ob++; // shut up compiler
\r
1289 ===========================
\r
1293 ===========================
\r
1296 void R_KeenSwim(objtype *ob)
\r
1298 if (ob->hiteast && ob->xspeed < 0 || ob->hitwest && ob->xspeed > 0)
\r
1301 if (ob->hitnorth && ob->yspeed > 0 || ob->hitsouth && ob->yspeed < 0)
\r
1304 RF_PlaceSprite(&ob->sprite, ob->x, ob->y, ob->shapenum, spritedraw, ob->priority);
\r