Subversion Repositories Games.Rick Dangerous

Rev

Rev 1 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 pmbaty 1
/*
2
 * src/e_them.c
3
 *
4
 * Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
5
 *
6
 * The use and distribution terms for this software are contained in the file
7
 * named README, which can be found in the root of this distribution. By
8
 * using this software in any fashion, you are agreeing to be bound by the
9
 * terms of this license.
10
 *
11
 * You must not remove this notice, or any other, from this software.
12
 */
13
 
14
#include "system.h"
15
#include "game.h"
16
#include "ents.h"
17
#include "e_them.h"
18
 
19
#include "e_rick.h"
20
#include "e_bomb.h"
21
#include "e_bullet.h"
22
#include "maps.h"
23
#include "util.h"
24
 
25
#define TYPE_1A (0x00)
26
#define TYPE_1B (0xff)
27
 
28
 
29
/*
30
 * public vars
31
 */
32
U32 e_them_rndseed = 0;
33
 
34
 
35
/*
36
 * local vars
37
 */
38
static U16 e_them_rndnbr = 0;
39
 
40
 
41
/*
42
 * Check if entity boxtests with a lethal e_them i.e. something lethal
43
 * in slot 0 and 4 to 8.
44
 *
45
 * ASM 122E
46
 *
47
 * e: entity slot number.
48
 * ret: TRUE/boxtests, FALSE/not
49
 */
50
U8 u_themtest (U8 e)
51
{
52
   U8 i;
53
 
54
   if ((ent_ents[0].n & ENT_LETHAL) && u_boxtest (e, 0))
55
      return TRUE;
56
 
57
   for (i = 4; i < 9; i++)
58
      if ((ent_ents[i].n & ENT_LETHAL) && u_boxtest (e, i))
59
         return TRUE;
60
 
61
   return FALSE;
62
}
63
 
64
 
65
/*
66
 * Go zombie
67
 *
68
 * ASM 237B
69
 */
70
void e_them_gozombie (U8 e)
71
{
72
#define offsx c1
73
   ent_ents[e].n = 0x47;   /* zombie entity */
74
   ent_ents[e].front = TRUE;
75
   ent_ents[e].offsy = -0x0400;
76
   syssnd_play(WAV_DIE, 1);
77
   game_score += 50;
78
   if (ent_ents[e].flags & ENT_FLG_ONCE)
79
   {
80
      /* make sure entity won't be activated again */
81
      map_marks[ent_ents[e].mark].ent |= MAP_MARK_NACT;
82
   }
83
   ent_ents[e].offsx = (ent_ents[e].x >= 0x80 ? -0x02 : 0x02);
84
#undef offsx
85
}
86
 
87
 
88
/*
89
 * Action sub-function for e_them _t1a and _t1b
90
 *
91
 * Those two types move horizontally, and fall if they have to.
92
 * Type 1a moves horizontally over a given distance and then
93
 * u-turns and repeats; type 1b is more subtle as it does u-turns
94
 * in order to move horizontally towards rick.
95
 *
96
 * ASM 2242
97
 */
98
void e_them_t1_action2 (U8 e, U8 type)
99
{
100
#define offsx c1
101
#define step_count c2
102
   U32 i;
103
   S16 x, y;
104
   U8 env0, env1;
105
 
106
   /* by default, try vertical move. calculate new y */
107
   i = (ent_ents[e].y << 8) + ent_ents[e].offsy + ent_ents[e].ylow;
108
   y = (S16) (i >> 8);
109
 
110
   /* deactivate if outside vertical boundaries */
111
   /* no need to test zero since e_them _t1a/b don't go up */
112
   /* FIXME what if they got scrolled out ? */
113
   if (y > 0x140)
114
   {
115
      ent_ents[e].n = 0;
116
      return;
117
   }
118
 
119
   /* test environment */
120
   u_envtest (ent_ents[e].x, y, FALSE, &env0, &env1);
121
 
122
   if (!(env1 & (MAP_EFLG_VERT | MAP_EFLG_SOLID | MAP_EFLG_SPAD | MAP_EFLG_WAYUP)))
123
   {
124
      /* vertical move possible: falling */
125
      if (env1 & MAP_EFLG_LETHAL)
126
      {
127
         /* lethal entities kill e_them */
128
         e_them_gozombie (e);
129
         return;
130
      }
131
 
132
      /* save, cleanup and return */
133
      ent_ents[e].y = y;
134
      ent_ents[e].ylow = (U8) i;
135
      ent_ents[e].offsy += 0x0080;
136
 
137
      if (ent_ents[e].offsy > 0x0800)
138
         ent_ents[e].offsy = 0x0800;
139
 
140
      return;
141
   }
142
 
143
   /* vertical move not possible. calculate new sprite */
144
   ent_ents[e].sprite = ent_ents[e].sprbase + ent_sprseq[(ent_ents[e].x & 0x1c) >> 3] + (ent_ents[e].offsx < 0 ? 0x03 : 0x00);
145
 
146
   /* reset offsy */
147
   ent_ents[e].offsy = 0x0080;
148
 
149
   /* align to ground */
150
   ent_ents[e].y &= 0xfff8;
151
   ent_ents[e].y |= 0x0003;
152
 
153
   /* latency: if not zero then decrease and return */
154
   if (ent_ents[e].latency > 0)
155
   {
156
      ent_ents[e].latency--;
157
      return;
158
   }
159
 
160
   /* horizontal move. calculate new x */
161
   if (ent_ents[e].offsx == 0)   /* not supposed to move -> don't */
162
      return;
163
 
164
   x = ent_ents[e].x + ent_ents[e].offsx;
165
   if (ent_ents[e].x < 0x01 || ent_ents[e].x > 0xe8)
166
   {
167
      /* deactivate if reaching horizontal boundaries */
168
      ent_ents[e].n = 0;
169
      return;
170
   }
171
 
172
   /* test environment */
173
   u_envtest (x, ent_ents[e].y, FALSE, &env0, &env1);
174
 
175
   if (env1 & (MAP_EFLG_VERT|MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_WAYUP))
176
   {
177
      /* horizontal move not possible: u-turn and return */
178
      ent_ents[e].step_count = 0;
179
      ent_ents[e].offsx = -ent_ents[e].offsx;
180
      return;
181
   }
182
 
183
   /* horizontal move possible */
184
   if (env1 & MAP_EFLG_LETHAL)
185
   {
186
      /* lethal entities kill e_them */
187
      e_them_gozombie (e);
188
      return;
189
   }
190
 
191
   /* save */
192
   ent_ents[e].x = x;
193
 
194
   /* depending on type, */
195
   if (type == TYPE_1B)
196
   {
197
      /* set direction to move horizontally towards rick */
198
      if ((ent_ents[e].x & 0x1e) != 0x10) /* prevents too frequent u-turns */
199
         return;
200
      ent_ents[e].offsx = (ent_ents[e].x < E_RICK_ENT.x) ? 0x02 : -0x02;
201
      return;
202
   }
203
   else
204
   {
205
      /* set direction according to step counter */
206
      ent_ents[e].step_count++;
207
 
208
      /* FIXME why trig_x (b16) ?? */
209
      if ((ent_ents[e].trig_x >> 1) > ent_ents[e].step_count)
210
         return;
9 pmbaty 211
 
212
      /* type is 1A and step counter reached its limit: u-turn */
213
      ent_ents[e].step_count = 0;
214
      ent_ents[e].offsx = -ent_ents[e].offsx;
1 pmbaty 215
   }
216
#undef offsx
217
#undef step_count
218
}
219
 
220
 
221
/*
222
 * ASM 21CF
223
 */
224
void e_them_t1_action (U8 e, U8 type)
225
{
226
   e_them_t1_action2 (e, type);
227
 
228
   /* lethal entities kill them */
229
   if (u_themtest (e))
230
   {
231
      e_them_gozombie (e);
232
      return;
233
   }
234
 
235
   /* bullet kills them */
236
   if (E_BULLET_ENT.n && u_fboxtest (e, (S16) (E_BULLET_ENT.x + (e_bullet_offsx < 0 ? 0 : 0x18)), E_BULLET_ENT.y))
237
   {
238
      E_BULLET_ENT.n = 0;
239
      e_them_gozombie (e);
240
      return;
241
   }
242
 
243
   /* bomb kills them */
244
   if (e_bomb_lethal && e_bomb_hit (e))
245
   {
246
      e_them_gozombie (e);
247
      return;
248
   }
249
 
250
   if (E_RICK_STTST (E_RICK_STZOMBIE))
251
      return;
252
 
253
   /* rick stops them */
254
   if (E_RICK_STTST (E_RICK_STSTOP) && u_fboxtest (e, e_rick_stop_x, e_rick_stop_y))
255
      ent_ents[e].latency = 0x14;
256
 
257
   /* they kill rick */
258
   if (e_rick_boxtest (e))
259
      e_rick_gozombie ();
260
}
261
 
262
 
263
/*
264
 * Action function for e_them _t1a type (stays within boundaries)
265
 *
266
 * ASM 2452
267
 */
268
void e_them_t1a_action (U8 e)
269
{
270
   e_them_t1_action (e, TYPE_1A);
271
}
272
 
273
 
274
/*
275
 * Action function for e_them _t1b type (runs for rick)
276
 *
277
 * ASM 21CA
278
 */
279
void e_them_t1b_action (U8 e)
280
{
281
   e_them_t1_action (e, TYPE_1B);
282
}
283
 
284
 
285
/*
286
 * Action function for e_them _z (zombie) type
287
 *
288
 * ASM 23B8
289
 */
290
void e_them_z_action (U8 e)
291
{
292
#define offsx c1
293
   U32 i;
294
 
295
   /* calc new sprite */
296
   ent_ents[e].sprite = ent_ents[e].sprbase + ((ent_ents[e].x & 0x04) ? 0x07 : 0x06);
297
 
298
   /* calc new y */
299
   i = (ent_ents[e].y << 8) + ent_ents[e].offsy + ent_ents[e].ylow;
300
 
301
   /* deactivate if out of vertical boundaries */
302
   if (ent_ents[e].y < 0 || ent_ents[e].y > 0x0140)
303
   {
304
      ent_ents[e].n = 0;
305
      return;
306
   }
307
 
308
   /* save */
309
   ent_ents[e].offsy += 0x0080;
310
   ent_ents[e].ylow = (U8) i;
311
   ent_ents[e].y = (S16) (i >> 8);
312
 
313
   /* calc new x */
314
   ent_ents[e].x += ent_ents[e].offsx;
315
 
316
   /* must stay within horizontal boundaries */
317
   if (ent_ents[e].x < 0)
318
      ent_ents[e].x = 0;
319
   if (ent_ents[e].x > 0xe8)
320
      ent_ents[e].x = 0xe8;
321
#undef offsx
322
}
323
 
324
 
325
/*
326
 * Action sub-function for e_them _t2.
327
 *
328
 * Must document what it does.
329
 *
330
 * ASM 2792
331
 */
332
void e_them_t2_action2 (U8 e)
333
{
334
#define flgclmb c1
335
#define offsx c2
336
   U32 i;
337
   S16 x, y, yd;
338
   U8 env0, env1;
339
 
340
   /*
341
    * vars required by the Black Magic (tm) performance at the
342
    * end of this function.
343
    */
344
   static U16 bx;
345
   static U8 *bl = (U8 *)&bx;
346
   static U8 *bh = (U8 *)&bx + 1;
347
   static U16 cx;
348
   static U8 *cl = (U8 *)&cx;
349
   static U8 *ch = (U8 *)&cx + 1;
350
   static U16 *sl = (U16 *)&e_them_rndseed;
351
   static U16 *sh = (U16 *)&e_them_rndseed + 2;
352
 
353
   /*sys_printf("e_them_t2 ------------------------------\n");*/
354
 
355
   /* latency: if not zero then decrease */
356
   if (ent_ents[e].latency > 0)
357
      ent_ents[e].latency--;
358
 
359
   /* climbing? */
360
   if (ent_ents[e].flgclmb != TRUE)
361
      goto climbing_not;
362
 
363
   /* CLIMBING */
364
 
365
   /*sys_printf("e_them_t2 climbing\n");*/
366
 
367
   /* latency: if not zero then return */
368
   if (ent_ents[e].latency > 0)
369
      return;
370
 
371
   /* calc new sprite */
372
   ent_ents[e].sprite = ent_ents[e].sprbase + 0x08 + (((ent_ents[e].x ^ ent_ents[e].y) & 0x04) ? 1 : 0);
373
 
374
   /* reached rick's level? */
375
   if ((ent_ents[e].y & 0xfe) != (E_RICK_ENT.y & 0xfe))
376
      goto ymove;
377
 
378
xmove:
379
      /* calc new x and test environment */
380
      ent_ents[e].offsx = (ent_ents[e].x < E_RICK_ENT.x) ? 0x02 : -0x02;
381
      x = ent_ents[e].x + ent_ents[e].offsx;
382
      u_envtest (x, ent_ents[e].y, FALSE, &env0, &env1);
383
 
384
      if (env1 & (MAP_EFLG_SOLID | MAP_EFLG_SPAD | MAP_EFLG_WAYUP))
385
         return;
386
 
387
      if (env1 & MAP_EFLG_LETHAL)
388
      {
389
         e_them_gozombie(e);
390
         return;
391
      }
392
 
393
      ent_ents[e].x = x;
394
 
395
      if (env1 & (MAP_EFLG_VERT | MAP_EFLG_CLIMB))   /* still climbing */
396
         return;
397
 
398
      goto climbing_not;   /* not climbing anymore */
399
 
400
ymove:
401
      /* calc new y and test environment */
402
      yd = ent_ents[e].y < E_RICK_ENT.y ? 0x02 : -0x02;
403
      y = ent_ents[e].y + yd;
404
 
405
      if (y < 0 || y > 0x0140)
406
      {
407
         ent_ents[e].n = 0;
408
         return;
409
      }
410
 
411
      u_envtest (ent_ents[e].x, y, FALSE, &env0, &env1);
412
 
413
      if (env1 & (MAP_EFLG_SOLID | MAP_EFLG_SPAD | MAP_EFLG_WAYUP))
414
      {
415
         if (yd < 0)
416
            goto xmove;   /* can't go up */
417
         else
418
            goto climbing_not;   /* can't go down */
419
      }
420
 
421
      /* can move */
422
      ent_ents[e].y = y;
423
 
424
      if (env1 & (MAP_EFLG_VERT | MAP_EFLG_CLIMB))   /* still climbing */
425
         return;
426
 
427
      /* NOT CLIMBING */
428
 
429
climbing_not:
430
      /*sys_printf ("e_them_t2 climbing NOT\n");*/
431
 
432
      ent_ents[e].flgclmb = FALSE;   /* not climbing */
433
 
434
      /* calc new y (falling) and test environment */
435
      i = (ent_ents[e].y << 8) + ent_ents[e].offsy + ent_ents[e].ylow;
436
      y = (S16) (i >> 8);
437
 
438
      u_envtest (ent_ents[e].x, y, FALSE, &env0, &env1);
439
 
440
      if (!(env1 & (MAP_EFLG_SOLID | MAP_EFLG_SPAD | MAP_EFLG_WAYUP)))
441
      {
442
         /*sys_printf ("e_them_t2 y move OK\n");*/
443
         /* can go there */
444
         if (env1 & MAP_EFLG_LETHAL)
445
         {
446
            e_them_gozombie (e);
447
            return;
448
         }
449
 
450
         if (y > 0x0140)
451
         {
452
            /* deactivate if outside */
453
            ent_ents[e].n = 0;
454
            return;
455
         }
456
 
457
         if (!(env1 & MAP_EFLG_VERT))
458
         {
459
            /* save */
460
            ent_ents[e].y = y;
461
            ent_ents[e].ylow = (U8) i;
462
            ent_ents[e].offsy += 0x0080;
463
 
464
            if (ent_ents[e].offsy > 0x0800)
465
               ent_ents[e].offsy = 0x0800;
466
 
467
            return;
468
         }
469
 
470
         if (((ent_ents[e].x & 0x07) == 0x04) && (y < E_RICK_ENT.y))
471
         {
472
            /*sys_printf ("e_them_t2 climbing00\n");*/
473
            ent_ents[e].flgclmb = TRUE;   /* climbing */
474
            return;
475
         }
476
      }
477
 
478
      /*sys_printf("e_them_t2 ymove nok or ...\n");*/
479
      /* can't go there, or ... */
480
      ent_ents[e].y = (ent_ents[e].y & 0xf8) | 0x03;   /* align to ground */
481
      ent_ents[e].offsy = 0x0100;
482
      if (ent_ents[e].latency != 00)
483
         return;
484
 
485
      if ((env1 & MAP_EFLG_CLIMB) && ((ent_ents[e].x & 0x0e) == 0x04) && (ent_ents[e].y > E_RICK_ENT.y))
486
      {
487
         /*sys_printf ("e_them_t2 climbing01\n");*/
488
         ent_ents[e].flgclmb = TRUE;   /* climbing */
489
         return;
490
      }
491
 
492
      /* calc new sprite */
493
      ent_ents[e].sprite = ent_ents[e].sprbase + ent_sprseq[(ent_ents[e].offsx < 0 ? 4 : 0) + ((ent_ents[e].x & 0x0e) >> 3)];
494
      /*sys_printf ("e_them_t2 sprite %02x\n", ent_ents[e].sprite);*/
495
 
496
 
497
      /* */
498
      if (ent_ents[e].offsx == 0)
499
         ent_ents[e].offsx = 2;
500
 
501
      x = ent_ents[e].x + ent_ents[e].offsx;
502
 
503
      /*sys_printf ("e_them_t2 xmove x=%02x\n", x);*/
504
 
505
      if (x < 0xe8)
506
      {
507
         u_envtest (x, ent_ents[e].y, FALSE, &env0, &env1);
508
         if (!(env1 & (MAP_EFLG_VERT | MAP_EFLG_SOLID | MAP_EFLG_SPAD | MAP_EFLG_WAYUP)))
509
         {
510
            ent_ents[e].x = x;
511
 
512
            if ((x & 0x1e) != 0x08)
513
               return;
514
 
515
            /*
516
             * Black Magic (tm)
517
             *
518
             * this is obviously some sort of randomizer to define a direction
519
             * for the entity. it is an exact copy of what the assembler code
520
             * does but I can't explain.
521
             */
522
            bx = e_them_rndnbr + *sh + *sl + 0x0d;
523
            cx = *sh;
524
            *bl ^= *ch;
525
            *bl ^= *cl;
526
            *bl ^= *bh;
527
            e_them_rndnbr = bx;
528
 
529
            ent_ents[e].offsx = (*bl & 0x01) ? -0x02 : 0x02;
530
 
531
            /* back to normal */
532
 
533
            return;
534
         }
535
      }
536
 
537
      /* U-turn */
538
      /*sys_printf ("e_them_t2 u-turn\n");*/
539
      if (ent_ents[e].offsx == 0)
540
         ent_ents[e].offsx = 2;
541
      else
542
         ent_ents[e].offsx = -ent_ents[e].offsx;
543
#undef offsx
544
}
545
 
546
 
547
/*
548
 * Action function for e_them _t2 type
549
 *
550
 * ASM 2718
551
 */
552
void e_them_t2_action (U8 e)
553
{
554
   e_them_t2_action2 (e);
555
 
556
   /* they kill rick */
557
   if (e_rick_boxtest (e))
558
      e_rick_gozombie ();
559
 
560
   /* lethal entities kill them */
561
   if (u_themtest (e))
562
   {
563
      e_them_gozombie (e);
564
      return;
565
   }
566
 
567
   /* bullet kills them */
568
   if (E_BULLET_ENT.n && u_fboxtest (e, (S16) (E_BULLET_ENT.x + (e_bullet_offsx < 0 ? 00 : 0x18)), E_BULLET_ENT.y))
569
   {
570
      E_BULLET_ENT.n = 0;
571
      e_them_gozombie (e);
572
      return;
573
   }
574
 
575
   /* bomb kills them */
576
   if (e_bomb_lethal && e_bomb_hit (e))
577
   {
578
      e_them_gozombie (e);
579
      return;
580
   }
581
 
582
   /* rick stops them */
583
   if (E_RICK_STTST (E_RICK_STSTOP) && u_fboxtest (e, e_rick_stop_x, e_rick_stop_y))
584
      ent_ents[e].latency = 0x14;
585
}
586
 
587
 
588
/*
589
 * Action sub-function for e_them _t3
590
 *
591
 * FIXME always starts asleep??
592
 *
593
 * Waits until triggered by something, then execute move steps from
594
 * ent_mvstep with sprite from ent_sprseq. When done, either restart
595
 * or disappear.
596
 *
597
 * Not always lethal ... but if lethal, kills rick.
598
 *
599
 * ASM: 255A
600
 */
601
void e_them_t3_action2 (U8 e)
602
{
603
#define sproffs c1
604
#define step_count c2
605
   U8 i;
606
   S16 x, y;
607
 
608
   while (1)
609
   {
610
      /* calc new sprite */
611
      i = ent_sprseq[ent_ents[e].sprbase + ent_ents[e].sproffs];
612
      if (i == 0xff)
613
         i = ent_sprseq[ent_ents[e].sprbase];
614
      ent_ents[e].sprite = i;
615
 
616
      if (ent_ents[e].sproffs != 0)
617
      {
618
         /* awake */
619
 
620
         /* rotate sprseq */
621
         if (ent_sprseq[ent_ents[e].sprbase + ent_ents[e].sproffs] != 0xff)
622
            ent_ents[e].sproffs++;
623
         if (ent_sprseq[ent_ents[e].sprbase + ent_ents[e].sproffs] == 0xff)
624
            ent_ents[e].sproffs = 1;
625
 
626
         if (ent_ents[e].step_count < ent_mvstep[ent_ents[e].step_no].count)
627
         {
628
            /*
629
             * still running this step: try to increment x and y while
630
             * checking that they remain within boudaries. if so, return.
631
             * else switch to next step.
632
             */
633
            ent_ents[e].step_count++;
634
            x = ent_ents[e].x + ent_mvstep[ent_ents[e].step_no].dx;
635
 
636
            /* check'n save */
637
            if (x > 0 && x < 0xe8)
638
            {
639
               ent_ents[e].x = x;
640
               /*FIXME*/
641
               /*
642
               y = ent_mvstep[ent_ents[e].step_no].dy;
643
               if (y < 0)
644
               y += 0xff00;
645
               y += ent_ents[e].y;
646
               */
647
               y = ent_ents[e].y + ent_mvstep[ent_ents[e].step_no].dy;
648
               if (y > 0 && y < 0x0140)
649
               {
650
                  ent_ents[e].y = y;
651
                  return;
652
               }
653
            }
654
         }
655
 
656
         /*
657
          * step is done, or x or y is outside boundaries. try to
658
          * switch to next step
659
          */
660
         ent_ents[e].step_no++;
661
         if (ent_mvstep[ent_ents[e].step_no].count != 0xff)
662
            ent_ents[e].step_count = 0; // there is a next step: init and loop
663
         else
664
         {
665
            /* there is no next step: restart or deactivate */
666
            if (!E_RICK_STTST (E_RICK_STZOMBIE) && !(ent_ents[e].flags & ENT_FLG_ONCE))
667
            {
668
               /* loop this entity */
669
               ent_ents[e].sproffs = 0;
670
               ent_ents[e].n &= ~ENT_LETHAL;
671
 
672
               if (ent_ents[e].flags & ENT_FLG_LETHALR)
673
                  ent_ents[e].n |= ENT_LETHAL;
674
 
675
               ent_ents[e].x = ent_ents[e].xsave;
676
               ent_ents[e].y = ent_ents[e].ysave;
677
 
678
               if (ent_ents[e].y < 0 || ent_ents[e].y > 0x140)
679
               {
680
                  ent_ents[e].n = 0;
681
                  return;
682
               }
683
            }
684
            else
685
            {
686
               /* deactivate this entity */
687
               ent_ents[e].n = 0;
688
               return;
689
            }
690
         }
691
      }
692
      else
693
      {
694
         /* ent_ents[e].sprseq1 == 0 -- waiting */
695
 
696
         /* ugly GOTOs */
697
 
698
         /* reacts to rick */
699
         if (ent_ents[e].flags & ENT_FLG_TRIGRICK)
700
         {
701
            /* wake up if triggered by rick */
702
            if (u_trigbox (e, (S16) (E_RICK_ENT.x + 0x0C), (S16) (E_RICK_ENT.y + 0x0A)))
703
               goto wakeup;
704
         }
705
 
706
         /* reacts to rick "stop" */
707
         if (ent_ents[e].flags & ENT_FLG_TRIGSTOP)
708
         {
709
            /* wake up if triggered by rick "stop" */
710
            if (E_RICK_STTST(E_RICK_STSTOP) && u_trigbox (e, e_rick_stop_x, e_rick_stop_y))
711
               goto wakeup;
712
         }
713
 
714
         /* reacts to bullets */
715
         if (ent_ents[e].flags & ENT_FLG_TRIGBULLET)
716
         {
717
            /* wake up if triggered by bullet */
718
            if (E_BULLET_ENT.n && u_trigbox(e, e_bullet_xc, e_bullet_yc))
719
            {
720
               E_BULLET_ENT.n = 0;
721
               goto wakeup;
722
            }
723
         }
724
 
725
         /* reacts to bombs */
726
         if (ent_ents[e].flags & ENT_FLG_TRIGBOMB)
727
         {
728
            /* wake up if triggered by bomb */
729
            if (e_bomb_lethal && u_trigbox(e, e_bomb_xc, e_bomb_yc))
730
               goto wakeup;
731
         }
732
 
733
         /* not triggered: keep waiting */
734
         return;
735
 
736
         /* something triggered the entity: wake up */
737
         /* initialize step counter */
738
wakeup:
739
         if (E_RICK_STTST (E_RICK_STZOMBIE))
740
            return;
741
 
742
         /*
743
          * FIXME the sound should come from a table, there are 10 of them
744
          * but I dont have the table yet. must rip the data off the game...
745
          * FIXME is it 8 of them, not 10?
746
          * FIXME testing below...
747
          */
748
         if ((ent_ents[e].trigsnd & 0x1F) != 0)
749
            syssnd_play(WAV_ENTITY[(ent_ents[e].trigsnd & 0x1F) - 0x14], 1);
750
 
751
         ent_ents[e].n &= ~ENT_LETHAL;
752
 
753
         if (ent_ents[e].flags & ENT_FLG_LETHALI)
754
            ent_ents[e].n |= ENT_LETHAL;
755
 
756
         ent_ents[e].sproffs = 1;
757
         ent_ents[e].step_count = 0;
758
         ent_ents[e].step_no = ent_ents[e].step_no_i;
759
         return;
760
      }
761
   }
762
#undef step_count
763
}
764
 
765
 
766
/*
767
 * Action function for e_them _t3 type
768
 *
769
 * ASM 2546
770
 */
771
void e_them_t3_action (U8 e)
772
{
773
   e_them_t3_action2 (e);
774
 
775
   /* if lethal, can kill rick */
776
   if ((ent_ents[e].n & ENT_LETHAL) && !E_RICK_STTST (E_RICK_STZOMBIE) && e_rick_boxtest (e))
777
      e_rick_gozombie (); // CALL 1130
778
}