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 the following actor types (in this order):
\r
40 =============================================================================
\r
44 temp1 = flash countdown
\r
47 =============================================================================
\r
50 statetype s_fleexwalk1 = {FLEEXWALKL1SPR, FLEEXWALKR1SPR, step, false, true, 7, 128, 0, T_FleexWalk, C_Fleex, R_Blooguard, &s_fleexwalk2};
\r
51 statetype s_fleexwalk2 = {FLEEXWALKL2SPR, FLEEXWALKR2SPR, step, false, true, 7, 128, 0, T_FleexWalk, C_Fleex, R_Blooguard, &s_fleexwalk1};
\r
52 statetype s_fleexrun1 = {FLEEXWALKL1SPR, FLEEXWALKR1SPR, step, false, true, 7, 128, 0, NULL, C_Fleex, R_Blooguard, &s_fleexrun2};
\r
53 statetype s_fleexrun2 = {FLEEXWALKL2SPR, FLEEXWALKR2SPR, step, false, true, 7, 128, 0, NULL, C_Fleex, R_Blooguard, &s_fleexrun3};
\r
54 statetype s_fleexrun3 = {FLEEXWALKL1SPR, FLEEXWALKR1SPR, step, false, true, 7, 128, 0, NULL, C_Fleex, R_Blooguard, &s_fleexrun4};
\r
55 statetype s_fleexrun4 = {FLEEXWALKL2SPR, FLEEXWALKR2SPR, step, false, true, 7, 128, 0, NULL, C_Fleex, R_Blooguard, &s_fleexwalk1};
\r
56 statetype s_fleexlook1 = {FLEEXLOOK1SPR, FLEEXLOOK1SPR, step, false, true, 60, 0, 0, NULL, C_Fleex, R_Blooguard, &s_fleexlook2};
\r
57 statetype s_fleexlook2 = {FLEEXLOOK2SPR, FLEEXLOOK2SPR, step, false, true, 60, 0, 0, T_FleexLook, C_Fleex, R_Blooguard, &s_fleexrun1};
\r
58 statetype s_fleexstun = {FLEEXSTUNSPR, FLEEXSTUNSPR, think, false, false, 0, 0, 0, T_Projectile, NULL, R_Stunned, NULL};
\r
61 ===========================
\r
65 ===========================
\r
68 void SpawnFleex(Uint16 tileX, Uint16 tileY)
\r
71 new->obclass = fleexobj;
\r
72 new->active = ac_yes;
\r
74 new->x = CONVERT_TILE_TO_GLOBAL(tileX);
\r
75 new->y = CONVERT_TILE_TO_GLOBAL(tileY) + -40*PIXGLOBAL;
\r
76 if (US_RndT() < 0x80)
\r
85 NewState(new, &s_fleexwalk1);
\r
86 new->temp2 = 4; // health
\r
90 ===========================
\r
94 ===========================
\r
97 void T_FleexWalk(objtype *ob)
\r
99 if (!player->xmove && !ob->temp1)
\r
101 ob->state = &s_fleexlook1;
\r
105 ob->xdir = (ob->x < player->x)? 1 : -1;
\r
110 ===========================
\r
114 ===========================
\r
117 void T_FleexLook(objtype *ob)
\r
119 ob->xdir = (ob->x < player->x)? 1 : -1;
\r
123 ===========================
\r
127 ===========================
\r
130 void C_Fleex(objtype *ob, objtype *hit)
\r
132 if (hit->obclass == keenobj)
\r
136 if (hit->obclass == stunshotobj) // this is not 'else if' in the original code
\r
138 if (--ob->temp2 == 0)
\r
140 StunObj(ob, hit, &s_fleexstun);
\r
145 ob->temp1 = 2; // draw white twice
\r
146 ob->needtoreact = true;
\r
148 if (ob->state == &s_fleexlook1 || ob->state == &s_fleexlook2)
\r
150 ob->xdir = (ob->x < player->x)? 1 : -1;
\r
151 ChangeState(ob, &s_fleexwalk1);
\r
158 =============================================================================
\r
162 temp1 = jump counter
\r
164 =============================================================================
\r
167 statetype s_bobbajump1 = {BOBBAL2SPR, BOBBAR2SPR, stepthink, false, false, 8, 0, 0, T_Projectile, C_Bobba, R_Bobba, &s_bobbajump2};
\r
168 statetype s_bobbajump2 = {BOBBAL3SPR, BOBBAR3SPR, think, false, false, 8, 0, 0, T_Projectile, C_Bobba, R_Bobba, &s_bobbajump2};
\r
169 statetype s_bobbastand = {BOBBAL1SPR, BOBBAR1SPR, step, false, false, 20, 0, 0, T_BobbaStand, C_Bobba, R_Draw, &s_bobbajump1};
\r
170 statetype s_bobbaattack = {BOBBAL1SPR, BOBBAR1SPR, step, false, false, 40, 0, 0, NULL, C_Bobba, R_Draw, &s_bobbajump1};
\r
171 statetype s_bobbashot1 = {BOBBASHOT1SPR, BOBBASHOT1SPR, step, false, false, 8, 0, 0, NULL, NULL, R_Draw, &s_bobbashot2};
\r
172 statetype s_bobbashot2 = {BOBBASHOT2SPR, BOBBASHOT2SPR, step, false, false, 8, 0, 0, NULL, NULL, R_Draw, &s_bobbashot3};
\r
173 statetype s_bobbashot3 = {BOBBASHOT1SPR, BOBBASHOT1SPR, step, false, false, 8, 0, 0, NULL, NULL, R_Draw, &s_bobbashot4};
\r
174 statetype s_bobbashot4 = {BOBBASHOT2SPR, BOBBASHOT2SPR, step, false, false, 8, 0, 0, T_BobbaShot, NULL, R_Draw, &s_bobbashot5};
\r
175 statetype s_bobbashot5 = {BOBBASHOT3SPR, BOBBASHOT3SPR, slide, false, false, 8, 48, 0, NULL, C_Lethal, R_BobbaShot, &s_bobbashot6};
\r
176 statetype s_bobbashot6 = {BOBBASHOT4SPR, BOBBASHOT4SPR, slide, false, false, 8, 48, 0, NULL, C_Lethal, R_BobbaShot, &s_bobbashot7};
\r
177 statetype s_bobbashot7 = {BOBBASHOT5SPR, BOBBASHOT5SPR, slide, false, false, 8, 48, 0, NULL, C_Lethal, R_BobbaShot, &s_bobbashot8};
\r
178 statetype s_bobbashot8 = {BOBBASHOT6SPR, BOBBASHOT6SPR, slide, false, false, 8, 48, 0, NULL, C_Lethal, R_BobbaShot, &s_bobbashot5};
\r
179 statetype s_bobbashotvanish1 = {BOBBASHOT6SPR, BOBBASHOT6SPR, step, false, false, 8, 0, 0, NULL, NULL, R_Draw, &s_bobbashotvanish2};
\r
180 statetype s_bobbashotvanish2 = {BOBBASHOT6SPR, BOBBASHOT6SPR, step, false, false, 8, 0, 0, NULL, NULL, R_Draw, &s_bobbashotvanish3};
\r
181 statetype s_bobbashotvanish3 = {BOBBASHOT6SPR, BOBBASHOT6SPR, step, false, false, 8, 0, 0, NULL, NULL, R_Draw, NULL};
\r
184 ===========================
\r
188 ===========================
\r
191 void SpawnBobba(Uint16 tileX, Uint16 tileY)
\r
194 new->obclass = bobbaobj;
\r
195 new->active = ac_yes;
\r
197 new->x = CONVERT_TILE_TO_GLOBAL(tileX);
\r
198 new->y = CONVERT_TILE_TO_GLOBAL(tileY) + -2*TILEGLOBAL;
\r
199 if (US_RndT() < 0x80)
\r
208 NewState(new, &s_bobbajump1);
\r
212 ===========================
\r
216 ===========================
\r
220 void T_BobbaShot(objtype *ob)
\r
222 SD_PlaySound(SND_BOBBASHOT);
\r
226 ===========================
\r
230 ===========================
\r
233 void T_BobbaStand(objtype *ob)
\r
238 if (++ob->temp1 == 3)
\r
242 new->active = ac_removable;
\r
243 new->obclass = mshotobj;
\r
244 new->y = ob->y + 11*PIXGLOBAL;
\r
245 new->xdir = ob->xdir;
\r
248 new->x = ob->x + 16*PIXGLOBAL;
\r
252 new->x = ob->x + 11*PIXGLOBAL;
\r
254 NewState(new, &s_bobbashot1);
\r
256 ob->state = &s_bobbaattack;
\r
260 map = mapsegs[1] + mapbwidthtable[ob->tilebottom+1]/2 + ob->tilemidx;
\r
261 for (i=0; i<4; map += ob->xdir, i++)
\r
263 if ( !tinf[*map+NORTHWALL]
\r
264 && !tinf[*(map-mapwidth)+NORTHWALL]
\r
265 && !tinf[*(map+mapwidth)+NORTHWALL] )
\r
267 ob->xdir = -ob->xdir;
\r
271 ob->xspeed = ob->xdir << 5;
\r
273 SD_PlaySound(SND_BOBBAJUMP);
\r
278 ===========================
\r
282 ===========================
\r
285 void C_Bobba(objtype *ob, objtype *hit)
\r
287 if (hit->obclass == keenobj)
\r
291 else if (hit->obclass == stunshotobj)
\r
294 if (hit->xdir != 0)
\r
296 ob->xdir = -hit->xdir;
\r
302 ===========================
\r
306 ===========================
\r
309 void R_Bobba(objtype *ob)
\r
314 ob->xspeed = -ob->xspeed;
\r
316 else if (ob->hitwest)
\r
319 ob->xspeed = -ob->xspeed;
\r
327 SD_PlaySound(SND_BOBBALAND);
\r
328 ChangeState(ob, &s_bobbastand);
\r
330 RF_PlaceSprite(&ob->sprite, ob->x, ob->y, ob->shapenum, spritedraw, ob->priority);
\r
334 ===========================
\r
338 ===========================
\r
341 void R_BobbaShot(objtype *ob)
\r
343 if (ob->hitnorth || ob->hitsouth || ob->hiteast || ob->hitwest)
\r
345 ChangeState(ob, &s_bobbashotvanish1);
\r
347 RF_PlaceSprite(&ob->sprite, ob->x, ob->y, ob->shapenum, spritedraw, ob->priority);
\r
351 =============================================================================
\r
355 temp1 = jump counter (Babobba) / animation counter (Shot)
\r
357 =============================================================================
\r
360 statetype s_babobbajump1 = {BABOBBAL2SPR, BABOBBAR2SPR, stepthink, false, false, 8, 0, 0, T_Projectile, C_Babobba, R_Babobba, &s_babobbajump2};
\r
361 statetype s_babobbajump2 = {BABOBBAL3SPR, BABOBBAR3SPR, think, false, false, 8, 0, 0, T_Projectile, C_Babobba, R_Babobba, &s_babobbajump2};
\r
362 statetype s_babobbastand = {BABOBBAL1SPR, BABOBBAR1SPR, step, false, false, 20, 0, 0, T_BabobbaStand, C_Babobba, R_Draw, &s_babobbajump1};
\r
363 statetype s_babobbaattack = {BABOBBAL1SPR, BABOBBAR1SPR, step, false, false, 70, 0, 0, NULL, C_Babobba, R_Draw, &s_babobbastand};
\r
364 statetype s_babobbastun1 = {BABOBBAL2SPR, BABOBBAR2SPR, think, false, false, 0, 0, 0, T_Projectile, NULL, R_Stunned, &s_babobbastun2};
\r
365 statetype s_babobbastun2 = {BABOBBASTUNSPR, BABOBBASTUNSPR, think, false, false, 0, 0, 0, T_Projectile, NULL, R_Stunned, NULL};
\r
366 statetype s_babobbasleep1 = {BABOBBASLEEP1SPR, BABOBBASLEEP1SPR, step, false, false, 15, 0, 0, NULL, C_BabobbaSleep, R_Draw, &s_babobbasleep2};
\r
367 statetype s_babobbasleep2 = {BABOBBASLEEP2SPR, BABOBBASLEEP2SPR, step, false, false, 15, 0, 0, NULL, C_BabobbaSleep, R_Draw, &s_babobbasleep3};
\r
368 statetype s_babobbasleep3 = {BABOBBASLEEP3SPR, BABOBBASLEEP3SPR, step, false, false, 15, 0, 0, NULL, C_BabobbaSleep, R_Draw, &s_babobbasleep4};
\r
369 statetype s_babobbasleep4 = {BABOBBASLEEP4SPR, BABOBBASLEEP4SPR, step, false, false, 500, 0, 0, NULL, C_BabobbaSleep, R_Draw, &s_babobbasleep5};
\r
370 statetype s_babobbasleep5 = {BABOBBASLEEP3SPR, BABOBBASLEEP3SPR, step, false, false, 15, 0, 0, NULL, C_BabobbaSleep, R_Draw, &s_babobbasleep6};
\r
371 statetype s_babobbasleep6 = {BABOBBASLEEP2SPR, BABOBBASLEEP2SPR, step, false, false, 15, 0, 0, NULL, C_BabobbaSleep, R_Draw, &s_babobbasleep7};
\r
372 statetype s_babobbasleep7 = {BABOBBASLEEP1SPR, BABOBBASLEEP1SPR, step, false, false, 15, 0, 0, NULL, C_BabobbaSleep, R_Draw, &s_babobbastand};
\r
373 statetype s_babobbashot1 = {BABOBBASHOT1SPR, BABOBBASHOT1SPR, think, false, false, 0, 0, 0, T_Projectile, C_Lethal, R_Bounce, &s_babobbashot2};
\r
374 statetype s_babobbashot2 = {BABOBBASHOT2SPR, BABOBBASHOT2SPR, step, false, false, 8, 0, 0, T_BabobbaShot, C_Lethal, R_Draw, &s_babobbashot3};
\r
375 statetype s_babobbashot3 = {BABOBBASHOT1SPR, BABOBBASHOT1SPR, step, false, false, 8, 0, 0, NULL, C_Lethal, R_Draw, &s_babobbashot2};
\r
376 statetype s_babobbashotvanish1 = {BABOBBASHOT2SPR, BABOBBASHOT2SPR, step, false, false, 8, 0, 0, T_BabobbaShotVanish, C_Lethal, R_Draw, &s_babobbashotvanish2};
\r
377 statetype s_babobbashotvanish2 = {-1, -1, step, false, false, 8, 0, 0, NULL, NULL, R_Draw, &s_babobbashotvanish1};
\r
380 ===========================
\r
384 ===========================
\r
387 void SpawnBabobba(Uint16 tileX, Uint16 tileY)
\r
390 new->obclass = babobbaobj;
\r
391 new->active = ac_yes;
\r
393 new->x = CONVERT_TILE_TO_GLOBAL(tileX);
\r
394 new->y = CONVERT_TILE_TO_GLOBAL(tileY) + -2*TILEGLOBAL;
\r
395 if (US_RndT() < 0x80)
\r
404 NewState(new, &s_babobbajump1);
\r
408 ===========================
\r
412 ===========================
\r
415 void T_BabobbaStand(objtype *ob)
\r
423 ob->state = &s_babobbasleep1;
\r
425 else if (++ob->temp1 == 3)
\r
430 new->active = ac_removable;
\r
431 new->obclass = mshotobj;
\r
432 new->y = ob->y + 4*PIXGLOBAL;
\r
433 new->xdir = ob->xdir;
\r
436 new->x = ob->x + 16*PIXGLOBAL;
\r
440 new->x = ob->x + 11*PIXGLOBAL;
\r
442 new->xspeed = new->xdir << 5;
\r
443 NewState(new, &s_babobbashot1);
\r
445 ob->state = &s_babobbaattack;
\r
449 map = mapsegs[1] + mapbwidthtable[ob->tilebottom+1]/2 + ob->tilemidx;
\r
450 for (i=0; i<4; map += ob->xdir, i++)
\r
452 if ( !tinf[*map+NORTHWALL]
\r
453 && !tinf[*(map-mapwidth)+NORTHWALL]
\r
454 && !tinf[*(map+mapwidth)+NORTHWALL] )
\r
456 ob->xdir = -ob->xdir;
\r
460 ob->xspeed = ob->xdir *24;
\r
466 ===========================
\r
470 ===========================
\r
473 void C_Babobba(objtype *ob, objtype *hit)
\r
475 if (hit->obclass == keenobj)
\r
479 else if (hit->obclass == stunshotobj)
\r
481 StunObj(ob, hit, &s_babobbastun1);
\r
486 ===========================
\r
490 ===========================
\r
493 void C_BabobbaSleep(objtype *ob, objtype *hit)
\r
495 if (hit->obclass == stunshotobj)
\r
497 StunObj(ob, hit, &s_babobbastun1);
\r
502 ===========================
\r
506 ===========================
\r
509 void R_Babobba(objtype *ob)
\r
514 ob->xspeed = -ob->xspeed;
\r
516 else if (ob->hitwest)
\r
519 ob->xspeed = -ob->xspeed;
\r
527 ChangeState(ob, &s_babobbastand);
\r
529 RF_PlaceSprite(&ob->sprite, ob->x, ob->y, ob->shapenum, spritedraw, ob->priority);
\r
533 ===========================
\r
537 ===========================
\r
540 void T_BabobbaShot(objtype *ob)
\r
542 if (++ob->temp1 == 10)
\r
545 ob->state = &s_babobbashotvanish1;
\r
550 ===========================
\r
552 = T_BabobbaShotVanish
\r
554 ===========================
\r
557 void T_BabobbaShotVanish(objtype *ob)
\r
559 if (++ob->temp1 == 5)
\r
566 =============================================================================
\r
570 =============================================================================
\r
573 statetype s_blorb1 = {BLORB1SPR, BLORB1SPR, slide, false, false, 20, 8, 8, 0, C_Lethal, R_Blorb, &s_blorb2};
\r
574 statetype s_blorb2 = {BLORB2SPR, BLORB2SPR, slide, false, false, 20, 8, 8, 0, C_Lethal, R_Blorb, &s_blorb3};
\r
575 statetype s_blorb3 = {BLORB3SPR, BLORB3SPR, slide, false, false, 20, 8, 8, 0, C_Lethal, R_Blorb, &s_blorb1};
\r
578 ===========================
\r
582 ===========================
\r
585 void SpawnBlorb(Uint16 tileX, Uint16 tileY)
\r
588 new->obclass = blorbobj;
\r
589 new->active = ac_yes;
\r
591 new->x = CONVERT_TILE_TO_GLOBAL(tileX);
\r
592 new->y = CONVERT_TILE_TO_GLOBAL(tileY) + -8*PIXGLOBAL;
\r
593 if (US_RndT() < 0x80)
\r
601 if (US_RndT() < 0x80)
\r
609 new->needtoclip = cl_fullclip;
\r
610 NewState(new, &s_blorb1);
\r
614 ===========================
\r
618 ===========================
\r
621 void R_Blorb(objtype *ob)
\r
626 SD_PlaySound(SND_BLORBBOUNCE);
\r
628 else if (ob->hitsouth)
\r
631 SD_PlaySound(SND_BLORBBOUNCE);
\r
636 SD_PlaySound(SND_BLORBBOUNCE);
\r
638 else if (ob->hiteast)
\r
641 SD_PlaySound(SND_BLORBBOUNCE);
\r
643 RF_PlaceSprite(&ob->sprite, ob->x, ob->y, ob->shapenum, spritedraw, ob->priority);
\r
647 =============================================================================
\r
651 temp1 = initial y position
\r
653 =============================================================================
\r
656 statetype s_ceilickhidden = {TONGUE1SPR, TONGUE1SPR, think, false, false, 20, 0, 0, T_CeilickHidden, NULL, R_Draw, NULL};
\r
657 statetype s_ceilickattack1 = {TONGUE1SPR, TONGUE1SPR, step, false, false, 6, 0, 0, NULL, NULL, R_Draw, &s_ceilickattack2};
\r
658 statetype s_ceilickattack2 = {TONGUE2SPR, TONGUE2SPR, step, false, false, 6, 0, 0, NULL, C_Lethal, R_Draw, &s_ceilickattack3};
\r
659 statetype s_ceilickattack3 = {TONGUE3SPR, TONGUE3SPR, step, false, false, 6, 0, 0, NULL, C_Lethal, R_Draw, &s_ceilickattack4};
\r
660 statetype s_ceilickattack4 = {TONGUE4SPR, TONGUE4SPR, step, false, false, 6, 0, 0, NULL, C_Lethal, R_Draw, &s_ceilickattack5};
\r
661 statetype s_ceilickattack5 = {TONGUE5SPR, TONGUE5SPR, step, false, false, 6, 0, 0, NULL, C_Lethal, R_Draw, &s_ceilickattack6};
\r
662 statetype s_ceilickattack6 = {TONGUE4SPR, TONGUE4SPR, step, false, false, 6, 0, 0, NULL, C_Lethal, R_Draw, &s_ceilickattack7};
\r
663 statetype s_ceilickattack7 = {TONGUE3SPR, TONGUE3SPR, step, false, false, 6, 0, 0, NULL, C_Lethal, R_Draw, &s_ceilickattack8};
\r
664 statetype s_ceilickattack8 = {TONGUE4SPR, TONGUE4SPR, step, false, false, 6, 0, 0, NULL, C_Lethal, R_Draw, &s_ceilickattack9};
\r
665 statetype s_ceilickattack9 = {TONGUE5SPR, TONGUE5SPR, step, false, false, 6, 0, 0, NULL, C_Lethal, R_Draw, &s_ceilickattack10};
\r
666 statetype s_ceilickattack10 = {TONGUE2SPR, TONGUE2SPR, step, false, false, 10, 0, 0, NULL, C_Lethal, R_Draw, &s_ceilickattack11};
\r
667 statetype s_ceilickattack11 = {TONGUE1SPR, TONGUE1SPR, step, false, false, 10, 0, 0, NULL, NULL, R_Draw, &s_ceilicklaugh1};
\r
668 statetype s_ceilicklaugh1 = {CEILICK1SPR, CEILICK1SPR, slide, true, false, 16, 0, 16, T_CeilickLaugh, C_Ceilick, R_Draw, &s_ceilicklaugh2};
\r
669 statetype s_ceilicklaugh2 = {CEILICK2SPR, CEILICK2SPR, step, true, false, 10, 0, 0, NULL, C_Ceilick, R_Draw, &s_ceilicklaugh3};
\r
670 statetype s_ceilicklaugh3 = {CEILICK1SPR, CEILICK1SPR, step, true, false, 10, 0, 0, NULL, C_Ceilick, R_Draw, &s_ceilicklaugh4};
\r
671 statetype s_ceilicklaugh4 = {CEILICK2SPR, CEILICK2SPR, step, true, false, 10, 0, 0, NULL, C_Ceilick, R_Draw, &s_ceilicklaugh5};
\r
672 statetype s_ceilicklaugh5 = {CEILICK1SPR, CEILICK1SPR, step, true, false, 10, 0, 0, NULL, C_Ceilick, R_Draw, &s_ceilicklaugh6};
\r
673 statetype s_ceilicklaugh6 = {CEILICK2SPR, CEILICK2SPR, step, true, false, 10, 0, 0, NULL, C_Ceilick, R_Draw, &s_ceilicklaugh7};
\r
674 statetype s_ceilicklaugh7 = {CEILICK1SPR, CEILICK1SPR, step, true, false, 10, 0, 0, NULL, C_Ceilick, R_Draw, &s_ceilicklaugh8};
\r
675 statetype s_ceilicklaugh8 = {CEILICK1SPR, CEILICK1SPR, slide, true, false, 16, 0, -16, NULL, C_Ceilick, R_Draw, &s_ceilicklaugh9};
\r
676 statetype s_ceilicklaugh9 = {-1, -1, step, true, false, 60, 0, 0, NULL, C_Ceilick, R_Draw, &s_ceilickhidden};
\r
677 statetype s_ceilickstun = {CEILICKSTUNSPR, CEILICKSTUNSPR, think, true, false, 0, 0, 0, T_CeilickStunned, NULL, R_Stunned, NULL};
\r
680 ===========================
\r
684 ===========================
\r
687 void SpawnCeilick(Uint16 tileX, Uint16 tileY)
\r
690 new->obclass = ceilickobj;
\r
691 new->active = ac_yes;
\r
693 new->needtoclip = cl_noclip;
\r
694 new->x = CONVERT_TILE_TO_GLOBAL(tileX);
\r
695 new->y = new->temp1 = CONVERT_TILE_TO_GLOBAL(tileY);
\r
697 NewState(new, &s_ceilickhidden);
\r
701 ===========================
\r
705 ===========================
\r
708 void T_CeilickHidden(objtype *ob)
\r
710 if ( player->y - ob->y <= 40*PIXGLOBAL
\r
711 && player->left < ob->right+PIXGLOBAL
\r
712 && player->right > ob->left-PIXGLOBAL )
\r
714 SD_PlaySound(SND_CEILICKATTACK);
\r
715 ob->state = &s_ceilickattack1;
\r
720 ===========================
\r
724 ===========================
\r
728 void T_CeilickLaugh(objtype *ob)
\r
730 SD_PlaySound(SND_CEILICKLAUGH);
\r
734 ===========================
\r
738 ===========================
\r
741 void T_CeilickStunned(objtype *ob)
\r
743 ob->needtoreact = true; // to make sure the stunned stars animate
\r
747 ===========================
\r
751 ===========================
\r
754 void C_Ceilick(objtype *ob, objtype *hit)
\r
756 if (hit->obclass == stunshotobj)
\r
760 ob->temp1 = ob->temp2 = ob->temp3 = 0;
\r
761 ob->temp4 = ob->obclass;
\r
762 ChangeState(ob, &s_ceilickstun);
\r
763 ob->obclass = stunnedobj;
\r