OSDN Git Service

going on vacation >.<
[proj16/16.git] / src / lib / hb / act / kd_act1.c
1 /* Keen Dreams Source Code\r
2  * Copyright (C) 2014 Javier M. Chavez\r
3  *\r
4  * This program is free software; you can redistribute it and/or modify\r
5  * it under the terms of the GNU General Public License as published by\r
6  * the Free Software Foundation; either version 2 of the License, or\r
7  * (at your option) any later version.\r
8  *\r
9  * This program is distributed in the hope that it will be useful,\r
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
12  * GNU General Public License for more details.\r
13  *\r
14  * You should have received a copy of the GNU General Public License along\r
15  * with this program; if not, write to the Free Software Foundation, Inc.,\r
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
17  */\r
18 \r
19 // KD_ACT1.C\r
20 #include "KD_DEF.H"\r
21 #pragma hdrstop\r
22 \r
23 \r
24 /*\r
25 =============================================================================\r
26 \r
27                                                  LOCAL CONSTANTS\r
28 \r
29 =============================================================================\r
30 */\r
31 \r
32 \r
33 #define PLACESPRITE RF_PlaceSprite (&ob->sprite,ob->x,ob->y,ob->shapenum, \\r
34         spritedraw,0);\r
35 \r
36 /*\r
37 =============================================================================\r
38 \r
39                                                  GLOBAL VARIABLES\r
40 \r
41 =============================================================================\r
42 */\r
43 \r
44 \r
45 /*\r
46 =============================================================================\r
47 \r
48                                                  LOCAL VARIABLES\r
49 \r
50 =============================================================================\r
51 */\r
52 \r
53 int     flowertime[4] = {700,700,350,175};\r
54 \r
55 /*\r
56 =============================================================================\r
57 \r
58                                                 MISC ACTOR STUFF\r
59 \r
60 =============================================================================\r
61 */\r
62 \r
63 /*\r
64 ==================\r
65 =\r
66 = DoGravity\r
67 =\r
68 = Changes speed and location\r
69 =\r
70 ==================\r
71 */\r
72 \r
73 \r
74 void DoGravity (objtype *ob)\r
75 {\r
76         long    i;\r
77 //\r
78 // only accelerate on odd tics, because of limited precision\r
79 //\r
80         for (i=lasttimecount-tics;i<lasttimecount;i++)\r
81         {\r
82                 if (i&1)\r
83                 {\r
84                         if (ob->yspeed < 0 && ob->yspeed >= -ACCGRAVITY)\r
85                         {\r
86                         // stop at apex of jump\r
87                                 ob->ymove += ob->yspeed;\r
88                                 ob->yspeed = 0;\r
89                                 return;\r
90                         }\r
91                         ob->yspeed+=ACCGRAVITY;\r
92                         if (ob->yspeed>SPDMAXY)\r
93                           ob->yspeed=SPDMAXY;\r
94                 }\r
95                 ob->ymove+=ob->yspeed;\r
96         }\r
97 }\r
98 \r
99 \r
100 /*\r
101 ===============\r
102 =\r
103 = AccelerateX\r
104 =\r
105 ===============\r
106 */\r
107 \r
108 void AccelerateX (objtype *ob,int dir,int max)\r
109 {\r
110         long    i;\r
111         unsigned        olddir;\r
112 \r
113         olddir = ob->xspeed & 0x8000;\r
114 //\r
115 // only accelerate on odd tics, because of limited precision\r
116 //\r
117         for (i=lasttimecount-tics;i<lasttimecount;i++)\r
118         {\r
119                 if (i&1)\r
120                 {\r
121                         ob->xspeed+=dir;\r
122                         if ( (ob->xspeed & 0x8000) != olddir)\r
123                         {\r
124                                 olddir = ob->xspeed & 0x8000;\r
125                                 ob->xdir = olddir ? -1 : 1;\r
126                         }\r
127                         if (ob->xspeed>max)\r
128                           ob->xspeed=max;\r
129                         else if (ob->xspeed<-max)\r
130                           ob->xspeed=-max;\r
131                 }\r
132                 ob->xmove+=ob->xspeed;\r
133         }\r
134 }\r
135 \r
136 \r
137 /*\r
138 ===============\r
139 =\r
140 = FrictionX\r
141 =\r
142 ===============\r
143 */\r
144 \r
145 void FrictionX (objtype *ob)\r
146 {\r
147         long    i;\r
148         int             dir;\r
149         unsigned        olddir;\r
150 \r
151         olddir = ob->xspeed & 0x8000;\r
152 \r
153         if (ob->xspeed > 0)\r
154                 dir = -1;\r
155         else if (ob->xspeed < 0)\r
156                 dir = 1;\r
157         else\r
158                 dir = 0;\r
159 //\r
160 // only accelerate on odd tics, because of limited precision\r
161 //\r
162         for (i=lasttimecount-tics;i<lasttimecount;i++)\r
163         {\r
164                 if (i&1)\r
165                 {\r
166                         ob->xspeed+=dir;\r
167                         if ( (ob->xspeed & 0x8000) != olddir)\r
168                                 ob->xspeed = 0;\r
169                 }\r
170                 ob->xmove+=ob->xspeed;\r
171         }\r
172 }\r
173 \r
174 \r
175 /*\r
176 ===============\r
177 =\r
178 = ProjectileThink\r
179 =\r
180 ===============\r
181 */\r
182 \r
183 void ProjectileThink (objtype *ob)\r
184 {\r
185         DoGravity (ob);\r
186         ob->xmove = tics*ob->xspeed;\r
187 }\r
188 \r
189 /*\r
190 ===============\r
191 =\r
192 = VelocityThink\r
193 =\r
194 ===============\r
195 */\r
196 \r
197 void VelocityThink (objtype *ob)\r
198 {\r
199         ob->xmove = tics*ob->xspeed;\r
200         ob->ymove = tics*ob->yspeed;\r
201 }\r
202 \r
203 /*\r
204 ===============\r
205 =\r
206 = DrawReact\r
207 =\r
208 ===============\r
209 */\r
210 \r
211 void DrawReact (objtype *ob)\r
212 {\r
213         RF_PlaceSprite (&ob->sprite,ob->x,ob->y,ob->shapenum,spritedraw,1);\r
214 }\r
215 \r
216 void DrawReact2 (objtype *ob)\r
217 {\r
218         RF_PlaceSprite (&ob->sprite,ob->x,ob->y,ob->shapenum,spritedraw,2);\r
219 }\r
220 \r
221 void DrawReact3 (objtype *ob)\r
222 {\r
223         RF_PlaceSprite (&ob->sprite,ob->x,ob->y,ob->shapenum,spritedraw,3);\r
224 }\r
225 \r
226 /*\r
227 ==================\r
228 =\r
229 = ChangeState\r
230 =\r
231 ==================\r
232 */\r
233 \r
234 void ChangeState (objtype *ob, statetype *state)\r
235 {\r
236         ob->state = state;\r
237         ob->ticcount = 0;\r
238         if (state->rightshapenum)\r
239         {\r
240                 if (ob->xdir>0)\r
241                         ob->shapenum = state->rightshapenum;\r
242                 else\r
243                         ob->shapenum = state->leftshapenum;\r
244         }\r
245 \r
246         ob->xmove = 0;\r
247         ob->ymove = 0;\r
248 \r
249         ob->needtoreact = true;                 // it will need to be redrawn this frame\r
250         ClipToWalls (ob);\r
251 }\r
252 \r
253 \r
254 /*\r
255 ====================\r
256 =\r
257 = WalkReact\r
258 =\r
259 ====================\r
260 */\r
261 \r
262 void WalkReact (objtype *ob)\r
263 {\r
264         if (ob->xdir == 1 && ob->hitwest)\r
265         {\r
266                 ob->x -= ob->xmove;\r
267                 ob->xdir = -1;\r
268                 ob->nothink = US_RndT()>>5;\r
269                 ChangeState (ob,ob->state);\r
270         }\r
271         else if (ob->xdir == -1 && ob->hiteast)\r
272         {\r
273                 ob->x -= ob->xmove;\r
274                 ob->xdir = 1;\r
275                 ob->nothink = US_RndT()>>5;\r
276                 ChangeState (ob,ob->state);\r
277         }\r
278         else if (!ob->hitnorth)\r
279         {\r
280                 ob->x -= 2*ob->xmove;\r
281                 ob->y -= ob->ymove;\r
282 \r
283                 ob->xdir = -ob->xdir;\r
284                 ob->nothink = US_RndT()>>5;\r
285                 ChangeState (ob,ob->state);\r
286         }\r
287 \r
288         PLACESPRITE;\r
289 }\r
290 \r
291 \r
292 /*\r
293 =============================================================================\r
294 \r
295                                                         DOOR\r
296 \r
297 =============================================================================\r
298 */\r
299 \r
300 void    DoorContact (objtype *ob, objtype *hit);\r
301 \r
302 extern  statetype s_door;\r
303 extern  statetype s_doorraise;\r
304 \r
305 statetype s_door         = {DOORSPR,DOORSPR,think,false,\r
306         false,0, 0,0, NULL, DoorContact, DrawReact, &s_door};\r
307 statetype s_doorraise = {DOORSPR,DOORSPR,slide,false,\r
308         false,24, 0,32, NULL, DoorContact, DrawReact, NULL};\r
309 \r
310 /*\r
311 ======================\r
312 =\r
313 = SpawnDoor\r
314 =\r
315 ======================\r
316 */\r
317 \r
318 void    SpawnDoor (int tilex, int tiley)\r
319 {\r
320         GetNewObj (false);\r
321 \r
322         new->obclass = doorobj;\r
323         new->x = tilex<<G_T_SHIFT;\r
324         new->y = (tiley<<G_T_SHIFT)-2*BLOCKSIZE;\r
325         new->xdir = 1;\r
326         new->ydir = -1;\r
327         new->needtoclip = false;\r
328         NewState (new,&s_door);\r
329 }\r
330 \r
331 /*\r
332 ======================\r
333 =\r
334 = DoorContact\r
335 =\r
336 ======================\r
337 */\r
338 \r
339 void    DoorContact (objtype *ob, objtype *hit)\r
340 {\r
341         ClipToSpriteSide (hit,ob);\r
342 }\r
343 \r
344 /*\r
345 =============================================================================\r
346 \r
347                                                         FLOWER\r
348 \r
349 temp1 = original class\r
350 temp2 = original state\r
351 temp3 = flower count\r
352 \r
353 =============================================================================\r
354 */\r
355 \r
356 void ChangeToFlower (objtype *ob);\r
357 void FlowerThink (objtype *ob);\r
358 void ChangeFromFlower (objtype *ob);\r
359 \r
360 extern  statetype s_flower1;\r
361 extern  statetype s_flower2;\r
362 extern  statetype s_flower3;\r
363 extern  statetype s_flower4;\r
364 extern  statetype s_flower5;\r
365 extern  statetype s_flower6;\r
366 \r
367 extern  statetype s_poofto1;\r
368 extern  statetype s_poofto2;\r
369 extern  statetype s_poofto3;\r
370 extern  statetype s_poofto4;\r
371 \r
372 extern  statetype s_pooffrom1;\r
373 extern  statetype s_pooffrom2;\r
374 extern  statetype s_pooffrom3;\r
375 extern  statetype s_pooffrom4;\r
376 extern  statetype s_pooffrom5;\r
377 extern  statetype s_pooffrom6;\r
378 extern  statetype s_pooffrom7;\r
379 \r
380 extern  statetype s_bonus1;\r
381 \r
382 #pragma warn -sus\r
383 \r
384 statetype s_flower1      = {FLOWER1SPR,FLOWER1SPR,stepthink,false,\r
385         false,20, 0,0, FlowerThink, NULL, DrawReact, &s_flower2};\r
386 statetype s_flower2      = {FLOWER2SPR,FLOWER2SPR,stepthink,false,\r
387         false,20, 0,0, FlowerThink, NULL, DrawReact, &s_flower3};\r
388 statetype s_flower3      = {FLOWER3SPR,FLOWER3SPR,stepthink,false,\r
389         false,20, 0,0, FlowerThink, NULL, DrawReact, &s_flower4};\r
390 statetype s_flower4      = {FLOWER4SPR,FLOWER4SPR,stepthink,false,\r
391         false,20, 0,0, FlowerThink, NULL, DrawReact, &s_flower5};\r
392 statetype s_flower5      = {FLOWER3SPR,FLOWER3SPR,stepthink,false,\r
393         false,20, 0,0, FlowerThink, NULL, DrawReact, &s_flower6};\r
394 statetype s_flower6      = {FLOWER2SPR,FLOWER2SPR,stepthink,false,\r
395         false,20, 0,0, FlowerThink, NULL, DrawReact, &s_flower1};\r
396 \r
397 statetype s_poofto1              = {POOF1SPR,POOF1SPR,step,false,\r
398         false,10, 0,0, NULL, NULL, DrawReact2, &s_poofto2};\r
399 statetype s_poofto2              = {POOF2SPR,POOF2SPR,step,false,\r
400         false,10, 0,0, NULL, NULL, DrawReact2, &s_poofto3};\r
401 statetype s_poofto3              = {POOF3SPR,POOF3SPR,step,false,\r
402         false,10, 0,0, NULL, NULL, DrawReact2, &s_poofto4};\r
403 statetype s_poofto4              = {POOF4SPR,POOF4SPR,step,false,\r
404         false,10, 0,0, NULL, NULL, DrawReact2, NULL};\r
405 \r
406 statetype s_pooffrom1    = {POOF4SPR,POOF4SPR,step,false,\r
407         false,10, 0,0, NULL, NULL, DrawReact2, &s_pooffrom2};\r
408 statetype s_pooffrom2    = {POOF3SPR,POOF3SPR,step,false,\r
409         false,10, 0,0, NULL, NULL, DrawReact2, &s_pooffrom3};\r
410 statetype s_pooffrom3    = {POOF2SPR,POOF2SPR,step,false,\r
411         false,10, 0,0, NULL, NULL, DrawReact2, &s_pooffrom4};\r
412 statetype s_pooffrom4    = {POOF1SPR,POOF1SPR,step,false,\r
413         false,20, 0,0, ChangeFromFlower, NULL, DrawReact2, &s_pooffrom5};\r
414 statetype s_pooffrom5    = {POOF2SPR,POOF2SPR,step,false,\r
415         false,10, 0,0, NULL, NULL, DrawReact2, &s_pooffrom6};\r
416 statetype s_pooffrom6    = {POOF3SPR,POOF3SPR,step,false,\r
417         false,10, 0,0, NULL, NULL, DrawReact2, &s_pooffrom7};\r
418 statetype s_pooffrom7    = {POOF4SPR,POOF4SPR,step,false,\r
419         false,10, 0,0, NULL, NULL, DrawReact2, NULL};\r
420 \r
421 \r
422 #pragma warn +sus\r
423 \r
424 \r
425 /*\r
426 ======================\r
427 =\r
428 = ChangeToFlower\r
429 =\r
430 ======================\r
431 */\r
432 \r
433 void ChangeToFlower (objtype *ob)\r
434 {\r
435         SD_PlaySound (FLOWERPOWERSND);\r
436         ob->y = ob->bottom-TILEGLOBAL*2;\r
437         ob->temp1 = (int)ob->obclass;\r
438         ob->temp2 = (int)ob->state;\r
439         ob->temp3 = 0;\r
440         ob->needtoclip = true;\r
441         ob->obclass = inertobj;\r
442         ob->xspeed = 0;\r
443         ChangeState (ob,&s_flower1);\r
444         ob->active = allways;                   // flower never deactivated\r
445         GetNewObj (true);\r
446         new->x = ob->x;\r
447         new->y = ob->y;\r
448         NewState (new,&s_poofto1);\r
449         new->active = removable;\r
450 }\r
451 \r
452 \r
453 /*\r
454 ======================\r
455 =\r
456 = FlowerThink\r
457 =\r
458 ======================\r
459 */\r
460 \r
461 void FlowerThink (objtype *ob)\r
462 {\r
463         ProjectileThink (ob);\r
464         if ( (ob->temp3+=tics) >= flowertime[gamestate.difficulty])\r
465         {\r
466                 GetNewObj (true);\r
467                 new->active = allways;\r
468                 new->temp1 = (int)ob;\r
469                 new->x = ob->x;\r
470                 new->y = ob->y;\r
471                 NewState (new,&s_pooffrom1);\r
472                 ob->temp3 = 0;\r
473         }\r
474 }\r
475 \r
476 \r
477 /*\r
478 ======================\r
479 =\r
480 = ChangeFromFlower\r
481 =\r
482 ======================\r
483 */\r
484 \r
485 void ChangeFromFlower (objtype *ob)\r
486 {\r
487         objtype *flower;\r
488         statetype *state;\r
489         unsigned        oldbottom;\r
490 \r
491         SD_PlaySound (UNFLOWERPOWERSND);\r
492         flower = (objtype *)ob->temp1;\r
493 \r
494         oldbottom = flower->bottom;\r
495         ChangeState (flower,(statetype *)flower->temp2);\r
496         flower->y += oldbottom - flower->bottom;\r
497 \r
498         flower->obclass = flower->temp1;\r
499         flower->active = yes;                   // allow it to unspawn now if off screen\r
500 }\r
501 \r
502 \r
503 /*\r
504 =============================================================================\r
505 \r
506                                                         BONUS\r
507 \r
508 temp1 = bonus type\r
509 temp2 = base shape number\r
510 temp3 = last animated shape number +1\r
511 \r
512 =============================================================================\r
513 */\r
514 \r
515 void BonusThink (objtype *ob);\r
516 \r
517 extern  statetype s_bonus1;\r
518 \r
519 #pragma warn -sus\r
520 \r
521 statetype s_bonus        = {NULL,NULL,step,false,\r
522         false,20, 0,0, BonusThink, NULL, DrawReact2, &s_bonus};\r
523 \r
524 statetype s_bonusrise    = {NULL,NULL,slide,false,\r
525         false,40, 0,8, NULL, NULL, DrawReact3, NULL};\r
526 \r
527 #pragma warn +sus\r
528 \r
529 /*\r
530 ====================\r
531 =\r
532 = SpawnBonus\r
533 =\r
534 ====================\r
535 */\r
536 \r
537 int bonusshape[12] = {PEPPERMINT1SPR,COOKIE1SPR,CANDYCANE1SPR,CANDYBAR1SPR,\r
538         LOLLIPOP1SPR,COTTONCANDY1SPR,EXTRAKEEN1SPR,SUPERBONUS1SPR,FLOWERPOWER1SPR,\r
539         FLOWERPOWERUP1SPR,BOOBUSBOMB1SPR,MAGICKEY1SPR};\r
540 \r
541 void SpawnBonus (int tilex, int tiley, int type)\r
542 {\r
543         GetNewObj (false);\r
544 \r
545         new->needtoclip = false;\r
546         new->obclass = bonusobj;\r
547         new->x = tilex<<G_T_SHIFT;\r
548         new->y = tiley<<G_T_SHIFT;\r
549 \r
550         if (type == 9)\r
551                 new->y -= 8*PIXGLOBAL;  // flower power up one block\r
552 \r
553         new->ydir = -1;                 // bonus stuff flies up when touched\r
554 \r
555         new->temp1 = type;\r
556         new->temp2 = new->shapenum = bonusshape[type];\r
557         if (type != 7)\r
558                 new->temp3 = new->temp2 + 2;\r
559         else\r
560                 new->temp3 = new->temp2 + 4;    // super bonus is 4 stage animation\r
561 \r
562         NewState (new,&s_bonus);\r
563 }\r
564 \r
565 /*\r
566 ====================\r
567 =\r
568 = BonusThink\r
569 =\r
570 ====================\r
571 */\r
572 \r
573 void BonusThink (objtype *ob)\r
574 {\r
575         if (++ob->shapenum == ob->temp3)\r
576                 ob->shapenum = ob->temp2;\r
577 }\r
578 \r
579 \r
580 \r
581 /*\r
582 =============================================================================\r
583 \r
584                                                 BROCCOLASH\r
585 \r
586 =============================================================================\r
587 */\r
588 \r
589 void BroccoThink (objtype *ob);\r
590 void BroccoGetUp (objtype *ob);\r
591 \r
592 extern  statetype s_broccowalk1;\r
593 extern  statetype s_broccowalk2;\r
594 extern  statetype s_broccowalk3;\r
595 extern  statetype s_broccowalk4;\r
596 \r
597 extern  statetype s_broccosmash1;\r
598 extern  statetype s_broccosmash2;\r
599 extern  statetype s_broccosmash3;\r
600 extern  statetype s_broccosmash4;\r
601 extern  statetype s_broccosmash5;\r
602 extern  statetype s_broccosmash6;\r
603 extern  statetype s_broccosmash7;\r
604 extern  statetype s_broccosmash8;\r
605 extern  statetype s_broccosmash9;\r
606 \r
607 #pragma warn -sus\r
608 \r
609 statetype s_broccowalk1  = {BROCCOLASHRUNL1SPR,BROCCOLASHRUNR1SPR,step,false,\r
610         true,7, 128,0, BroccoThink, NULL, WalkReact, &s_broccowalk2};\r
611 statetype s_broccowalk2  = {BROCCOLASHRUNL2SPR,BROCCOLASHRUNR2SPR,step,false,\r
612         true,7, 128,0, BroccoThink, NULL, WalkReact, &s_broccowalk3};\r
613 statetype s_broccowalk3  = {BROCCOLASHRUNL3SPR,BROCCOLASHRUNR3SPR,step,false,\r
614         true,7, 128,0, BroccoThink, NULL, WalkReact, &s_broccowalk4};\r
615 statetype s_broccowalk4  = {BROCCOLASHRUNL4SPR,BROCCOLASHRUNR4SPR,step,false,\r
616         true,7, 128,0, BroccoThink, NULL, WalkReact, &s_broccowalk1};\r
617 \r
618 statetype s_broccosmash1 = {BROCCOLASHSMASHL1SPR,BROCCOLASHSMASHR1SPR,step,true,\r
619         false,3, 0,0, NULL, NULL, DrawReact, &s_broccosmash2};\r
620 statetype s_broccosmash2 = {BROCCOLASHSMASHL2SPR,BROCCOLASHSMASHR2SPR,step,true,\r
621         false,3, 0,0, NULL, NULL, DrawReact, &s_broccosmash3};\r
622 statetype s_broccosmash3 = {BROCCOLASHSMASHL3SPR,BROCCOLASHSMASHR3SPR,step,true,\r
623         false,3, 0,0, NULL, NULL, DrawReact, &s_broccosmash4};\r
624 statetype s_broccosmash4 = {BROCCOLASHSMASHL4SPR,BROCCOLASHSMASHR4SPR,step,false,\r
625         false,7, 0,0, NULL, NULL, DrawReact, &s_broccosmash5};\r
626 statetype s_broccosmash5 = {BROCCOLASHSMASHL3SPR,BROCCOLASHSMASHR3SPR,step,true,\r
627         false,6, 0,0, NULL, NULL, DrawReact, &s_broccosmash6};\r
628 statetype s_broccosmash6 = {BROCCOLASHSMASHL2SPR,BROCCOLASHSMASHR2SPR,step,true,\r
629         false,6, 0,0, NULL, NULL, DrawReact, &s_broccosmash7};\r
630 statetype s_broccosmash7 = {BROCCOLASHSMASHL1SPR,BROCCOLASHSMASHR1SPR,step,true,\r
631         false,6, 0,0, NULL, NULL, DrawReact, &s_broccosmash8};\r
632 statetype s_broccosmash8 = {BROCCOLASHRUNL1SPR,BROCCOLASHRUNR1SPR,step,true,\r
633         false,6, 0,0, BroccoGetUp, NULL, DrawReact, &s_broccosmash9};\r
634 statetype s_broccosmash9 = {BROCCOLASHRUNL1SPR,BROCCOLASHRUNR1SPR,step,true,\r
635         false,6, 128,0, NULL, NULL, WalkReact, &s_broccowalk1};\r
636 \r
637 #pragma warn +sus\r
638 \r
639 /*\r
640 ====================\r
641 =\r
642 = SpawnBrocco\r
643 =\r
644 ====================\r
645 */\r
646 \r
647 void SpawnBrocco (int tilex, int tiley)\r
648 {\r
649         GetNewObj (false);\r
650 \r
651         new->obclass = broccoobj;\r
652         new->x = tilex<<G_T_SHIFT;\r
653         new->y = (tiley<<G_T_SHIFT)-2*BLOCKSIZE;\r
654         new->xdir = 1;\r
655         NewState (new,&s_broccowalk1);\r
656 }\r
657 \r
658 /*\r
659 ====================\r
660 =\r
661 = BroccoGetUp\r
662 =\r
663 ====================\r
664 */\r
665 \r
666 void BroccoGetUp (objtype *ob)\r
667 {\r
668         ob->needtoclip = true;\r
669 }\r
670 \r
671 \r
672 /*\r
673 ====================\r
674 =\r
675 = BroccoThink\r
676 =\r
677 ====================\r
678 */\r
679 \r
680 void BroccoThink (objtype *ob)\r
681 {\r
682         int delta;\r
683 \r
684         if (ob->top > player->bottom || ob->bottom < player->top)\r
685                 return;\r
686 \r
687         delta = player->x - ob->x;\r
688 \r
689         if ( ob->xdir == -1 )\r
690         {\r
691                 if (delta < -3*TILEGLOBAL)\r
692                         return;\r
693                 if (delta > TILEGLOBAL/2)\r
694                 {\r
695                         ob->xdir = 1;\r
696                         return;\r
697                 }\r
698                 ob->state = &s_broccosmash1;\r
699                 ob->needtoclip = false;\r
700                 ob->xmove = 0;\r
701                 return;\r
702         }\r
703         else\r
704         {\r
705                 delta = player->left - ob->right;\r
706                 if (delta > 3*TILEGLOBAL)\r
707                         return;\r
708                 if (delta < -TILEGLOBAL/2)\r
709                 {\r
710                         ob->xdir = -1;\r
711                         return;\r
712                 }\r
713                 ob->state = &s_broccosmash1;\r
714                 ob->needtoclip = false;\r
715                 ob->xmove = 0;\r
716                 return;\r
717         }\r
718 }\r
719 \r
720 \r
721 /*\r
722 =============================================================================\r
723 \r
724                                                  TOMATOOTH\r
725 \r
726 ob->temp1 = jumptime\r
727 \r
728 =============================================================================\r
729 */\r
730 \r
731 #define SPDTOMATBOUNCE  30\r
732 #define TICTOMATJUMP    10\r
733 #define SPDTOMAT                16\r
734 \r
735 void TomatBounceThink (objtype *ob);\r
736 void TomatReact (objtype *ob);\r
737 \r
738 extern  statetype s_tomatbounce;\r
739 extern  statetype s_tomatbounce2;\r
740 \r
741 #pragma warn -sus\r
742 \r
743 statetype s_tomatbounce  = {TOMATOOTHL1SPR,TOMATOOTHR1SPR,stepthink,false,\r
744         false,20, 0,0, TomatBounceThink, NULL, TomatReact, &s_tomatbounce2};\r
745 statetype s_tomatbounce2 = {TOMATOOTHL2SPR,TOMATOOTHR2SPR,stepthink,false,\r
746         false,20, 0,0, TomatBounceThink, NULL, TomatReact, &s_tomatbounce};\r
747 \r
748 #pragma warn +sus\r
749 \r
750 /*\r
751 ====================\r
752 =\r
753 = SpawnTomat\r
754 =\r
755 ====================\r
756 */\r
757 \r
758 void SpawnTomat (int tilex, int tiley)\r
759 {\r
760         GetNewObj (false);\r
761 \r
762         new->obclass = tomatobj;\r
763         new->x = tilex<<G_T_SHIFT;\r
764         new->y = (tiley<<G_T_SHIFT)-1*BLOCKSIZE;\r
765         new->xdir = 1;\r
766         NewState (new,&s_tomatbounce);\r
767 }\r
768 \r
769 /*\r
770 ====================\r
771 =\r
772 = TomatBounceThink\r
773 =\r
774 ====================\r
775 */\r
776 \r
777 void TomatBounceThink (objtype *ob)\r
778 {\r
779         AccelerateX (ob,ob->x > player->x ? -1 : 1,SPDTOMAT);\r
780         if (ob->xspeed > 0)\r
781                 ob->xdir = 1;\r
782         else\r
783                 ob->xdir = -1;\r
784 \r
785         if (ob->temp1)\r
786         {\r
787                 if (ob->temp1<tics)\r
788                 {\r
789                         ob->ymove = ob->yspeed*ob->temp1;\r
790                         ob->temp1 = 0;\r
791                 }\r
792                 else\r
793                 {\r
794                         ob->ymove = ob->yspeed*tics;\r
795                         ob->temp1-=tics;\r
796                 }\r
797         }\r
798         else\r
799                 DoGravity(ob);\r
800 \r
801 }\r
802 \r
803 \r
804 /*\r
805 ====================\r
806 =\r
807 = TomatReactThink\r
808 =\r
809 ====================\r
810 */\r
811 \r
812 void TomatReact (objtype *ob)\r
813 {\r
814         if (ob->hiteast || ob->hitwest)\r
815         {\r
816                 ob->xdir = -ob->xdir;\r
817                 ob->xspeed = -ob->xspeed;\r
818         }\r
819 \r
820         if (ob->hitsouth)\r
821         {\r
822                 if (ob->tileright >= originxtile\r
823                 && ob->tileleft <= originxtilemax\r
824                 && ob->tiletop >= originytile\r
825                 && ob->tilebottom <= originytilemax)\r
826                         SD_PlaySound (BOUNCESND);\r
827                 ob->yspeed = -ob->yspeed;\r
828         }\r
829 \r
830         if (ob->hitnorth)\r
831         {\r
832                 if (ob->tileright >= originxtile\r
833                 && ob->tileleft <= originxtilemax\r
834                 && ob->tiletop >= originytile\r
835                 && ob->tilebottom <= originytilemax)\r
836                         SD_PlaySound (BOUNCESND);\r
837                 ob->yspeed = -SPDTOMATBOUNCE-(US_RndT()>>4);\r
838                 ob->temp1 = TICTOMATJUMP;\r
839         }\r
840 \r
841         PLACESPRITE;\r
842 }\r
843 \r
844 \r
845 /*\r
846 =============================================================================\r
847 \r
848                                                  CARROT COURIER\r
849 \r
850 =============================================================================\r
851 */\r
852 \r
853 #define SPDCARROTLEAPX  32\r
854 #define SPDCARROTLEAPY  40\r
855 \r
856 void CarrotThink (objtype *ob);\r
857 void CarrotReact (objtype *ob);\r
858 void CarrotAirReact (objtype *ob);\r
859 \r
860 extern  statetype s_carrotwalk1;\r
861 extern  statetype s_carrotwalk2;\r
862 extern  statetype s_carrotwalk3;\r
863 extern  statetype s_carrotwalk4;\r
864 \r
865 extern  statetype s_carrotleap;\r
866 \r
867 #pragma warn -sus\r
868 \r
869 statetype s_carrotwalk1  = {CARROTRUNL1SPR,CARROTRUNR1SPR,step,false,\r
870         true,5, 128,0, NULL, NULL, CarrotReact, &s_carrotwalk2};\r
871 statetype s_carrotwalk2  = {CARROTRUNL2SPR,CARROTRUNR2SPR,step,false,\r
872         true,5, 128,0, NULL, NULL, CarrotReact, &s_carrotwalk3};\r
873 statetype s_carrotwalk3  = {CARROTRUNL3SPR,CARROTRUNR3SPR,step,false,\r
874         true,5, 128,0, NULL, NULL, CarrotReact, &s_carrotwalk4};\r
875 statetype s_carrotwalk4  = {CARROTRUNL4SPR,CARROTRUNR4SPR,step,false,\r
876         true,5, 128,0, NULL, NULL, CarrotReact, &s_carrotwalk1};\r
877 \r
878 statetype s_carrotleap   = {CARROTLEAPL1SPR,CARROTLEAPR1SPR,think,false,\r
879         false,0, 0,0, ProjectileThink, NULL, CarrotAirReact, NULL};\r
880 \r
881 #pragma warn +sus\r
882 \r
883 /*\r
884 ====================\r
885 =\r
886 = SpawnCarrot\r
887 =\r
888 ====================\r
889 */\r
890 \r
891 void SpawnCarrot (int tilex, int tiley)\r
892 {\r
893         GetNewObj (false);\r
894 \r
895         new->obclass = carrotobj;\r
896         new->x = tilex<<G_T_SHIFT;\r
897         new->y = (tiley<<G_T_SHIFT)-2*BLOCKSIZE;\r
898         new->xdir = 1;\r
899         new->ydir = 1;\r
900         NewState (new,&s_carrotwalk1);\r
901         new->hitnorth = 1;\r
902 }\r
903 \r
904 \r
905 /*\r
906 ====================\r
907 =\r
908 = CarrotReact\r
909 =\r
910 ====================\r
911 */\r
912 \r
913 void CarrotReact (objtype *ob)\r
914 {\r
915         unsigned x, width, bot, far *map;\r
916 \r
917         if (ob->xdir == 1 && ob->hitwest)\r
918         {\r
919                 ob->xdir = -1;\r
920         }\r
921         else if (ob->xdir == -1 && ob->hiteast)\r
922         {\r
923                 ob->xdir = 1;\r
924         }\r
925         else if (!ob->hitnorth)\r
926         {\r
927                 ob->x -= ob->xmove;\r
928                 ob->y -= ob->ymove;\r
929 \r
930                 ob->yspeed = -SPDCARROTLEAPY;\r
931                 ob->xspeed = SPDCARROTLEAPX*ob->xdir;\r
932                 ChangeState (ob,&s_carrotleap);\r
933         }\r
934 \r
935         PLACESPRITE;\r
936 }\r
937 \r
938 \r
939 /*\r
940 ====================\r
941 =\r
942 = CarrotAirReact\r
943 =\r
944 ====================\r
945 */\r
946 \r
947 void CarrotAirReact (objtype *ob)\r
948 {\r
949         if (ob->hitsouth)\r
950                 ob->yspeed = 0;\r
951 \r
952         if (ob->hitnorth)\r
953                 ChangeState (ob,&s_carrotwalk1);\r
954 \r
955         PLACESPRITE;\r
956 }\r
957 \r
958 \r
959 \r
960 /*\r
961 =============================================================================\r
962 \r
963                                                    ASPARAGUSTO\r
964 \r
965 =============================================================================\r
966 */\r
967 \r
968 void AsparThink (objtype *ob);\r
969 \r
970 extern  statetype s_asparwalk1;\r
971 extern  statetype s_asparwalk2;\r
972 extern  statetype s_asparwalk3;\r
973 extern  statetype s_asparwalk4;\r
974 \r
975 #pragma warn -sus\r
976 \r
977 statetype s_asparwalk1   = {ASPARAGUSRUNL1SPR,ASPARAGUSRUNR1SPR,step,true,\r
978         true,3, 100,0, NULL, NULL, WalkReact, &s_asparwalk2};\r
979 statetype s_asparwalk2   = {ASPARAGUSRUNL2SPR,ASPARAGUSRUNR2SPR,step,false,\r
980         true,3, 100,0, NULL, NULL, WalkReact, &s_asparwalk3};\r
981 statetype s_asparwalk3   = {ASPARAGUSRUNL3SPR,ASPARAGUSRUNR3SPR,step,true,\r
982         true,3, 100,0, NULL, NULL, WalkReact, &s_asparwalk4};\r
983 statetype s_asparwalk4   = {ASPARAGUSRUNL4SPR,ASPARAGUSRUNR4SPR,step,false,\r
984         true,3, 100,0, NULL, NULL, WalkReact, &s_asparwalk1};\r
985 \r
986 #pragma warn +sus\r
987 \r
988 /*\r
989 ====================\r
990 =\r
991 = SpawnAspar\r
992 =\r
993 ====================\r
994 */\r
995 \r
996 void SpawnAspar (int tilex, int tiley)\r
997 {\r
998         GetNewObj (false);\r
999 \r
1000         new->obclass = asparobj;\r
1001         new->x = tilex<<G_T_SHIFT;\r
1002         new->y = tiley<<G_T_SHIFT;\r
1003         new->xdir = 1;\r
1004         NewState (new,&s_asparwalk1);\r
1005 }\r
1006 \r
1007 \r
1008 /*\r
1009 =============================================================================\r
1010 \r
1011                                                    SOUR GRAPE\r
1012 \r
1013 =============================================================================\r
1014 */\r
1015 \r
1016 void GrapeThink (objtype *ob);\r
1017 void GrapeRiseReact (objtype *ob);\r
1018 void GrapeFallReact (objtype *ob);\r
1019 \r
1020 extern  statetype s_grapewait;\r
1021 extern  statetype s_grapefall;\r
1022 extern  statetype s_grapesit;\r
1023 extern  statetype s_graperise;\r
1024 \r
1025 #pragma warn -sus\r
1026 \r
1027 statetype s_grapewait   = {GRAPEONVINESPR,GRAPEONVINESPR,think,false,\r
1028         false,0, 0,0, GrapeThink, NULL, DrawReact, NULL};\r
1029 \r
1030 statetype s_grapefall   = {GRAPEFALLINGSPR,GRAPEFALLINGSPR,think,false,\r
1031         false,0, 0,0, ProjectileThink, NULL, GrapeFallReact, NULL};\r
1032 \r
1033 statetype s_grapesit    = {GRAPEONVINESPR,GRAPEONVINESPR,step,false,\r
1034         false,30, 0,0, NULL, NULL, DrawReact, &s_graperise};\r
1035 statetype s_graperise   = {GRAPEONVINESPR,GRAPEONVINESPR,slide,false,\r
1036         false,0, 0,-16, NULL, NULL, GrapeRiseReact, NULL};\r
1037 \r
1038 #pragma warn +sus\r
1039 \r
1040 /*\r
1041 ====================\r
1042 =\r
1043 = SpawnGrape\r
1044 =\r
1045 ====================\r
1046 */\r
1047 \r
1048 void SpawnGrape (int tilex, int tiley)\r
1049 {\r
1050         GetNewObj (false);\r
1051 \r
1052         new->obclass = grapeobj;\r
1053         new->x = tilex<<G_T_SHIFT;\r
1054         new->y = tiley<<G_T_SHIFT;\r
1055         new->xdir = 1;\r
1056         new->ydir = 1;\r
1057         NewState (new,&s_grapewait);\r
1058 }\r
1059 \r
1060 \r
1061 /*\r
1062 ====================\r
1063 =\r
1064 = GrapeThink\r
1065 =\r
1066 ====================\r
1067 */\r
1068 \r
1069 void GrapeThink (objtype *ob)\r
1070 {\r
1071         unsigned y,starty,endy, far *map;\r
1072 \r
1073         if (player->left > ob->right\r
1074                 || player->right < ob->left\r
1075                 || player->y < ob->y )\r
1076                 return;\r
1077 \r
1078 //\r
1079 // see if there are any walls between grape and player\r
1080 //\r
1081         starty = ob->tilebottom;\r
1082         endy = player->tiletop;\r
1083 \r
1084         map = mapsegs[1] + mapbwidthtable[starty]/2 + ob->tilemidx;\r
1085         for (y = starty ; y<endy ; y++,map+=mapwidth)\r
1086                 if (tinf[NORTHWALL+*map])\r
1087                         return;\r
1088 \r
1089         ob->state = &s_grapefall;\r
1090         SD_PlaySound (GRAPESCREAMSND);\r
1091 \r
1092 }\r
1093 \r
1094 \r
1095 /*\r
1096 ====================\r
1097 =\r
1098 = GrapeRiseReact\r
1099 =\r
1100 ====================\r
1101 */\r
1102 \r
1103 void GrapeRiseReact (objtype *ob)\r
1104 {\r
1105         if (ob->hitsouth)\r
1106                 ChangeState(ob,&s_grapewait);\r
1107         PLACESPRITE;\r
1108 }\r
1109 \r
1110 \r
1111 /*\r
1112 ====================\r
1113 =\r
1114 = GrapeFallReact\r
1115 =\r
1116 ====================\r
1117 */\r
1118 \r
1119 void GrapeFallReact (objtype *ob)\r
1120 {\r
1121         if (ob->hitnorth)\r
1122         {\r
1123                 SD_PlaySound (BOUNCESND);\r
1124                 ob->yspeed = -(ob->yspeed<<1)/3;\r
1125                 if (ob->yspeed > -32)\r
1126                         ChangeState(ob,&s_grapesit);\r
1127         }\r
1128         PLACESPRITE;\r
1129 }\r
1130 \r