Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
8557 | maxcodehac | 1 | // WL_STATE.C |
2 | |||
3 | #include "wl_def.h" |
||
4 | #pragma hdrstop |
||
5 | |||
6 | /* |
||
7 | ============================================================================= |
||
8 | |||
9 | LOCAL CONSTANTS |
||
10 | |||
11 | ============================================================================= |
||
12 | */ |
||
13 | |||
14 | |||
15 | /* |
||
16 | ============================================================================= |
||
17 | |||
18 | GLOBAL VARIABLES |
||
19 | |||
20 | ============================================================================= |
||
21 | */ |
||
22 | |||
23 | |||
24 | static const dirtype opposite[9] = |
||
25 | {west,southwest,south,southeast,east,northeast,north,northwest,nodir}; |
||
26 | |||
27 | static const dirtype diagonal[9][9] = |
||
28 | { |
||
29 | /* east */ {nodir,nodir,northeast,nodir,nodir,nodir,southeast,nodir,nodir}, |
||
30 | {nodir,nodir,nodir,nodir,nodir,nodir,nodir,nodir,nodir}, |
||
31 | /* north */ {northeast,nodir,nodir,nodir,northwest,nodir,nodir,nodir,nodir}, |
||
32 | {nodir,nodir,nodir,nodir,nodir,nodir,nodir,nodir,nodir}, |
||
33 | /* west */ {nodir,nodir,northwest,nodir,nodir,nodir,southwest,nodir,nodir}, |
||
34 | {nodir,nodir,nodir,nodir,nodir,nodir,nodir,nodir,nodir}, |
||
35 | /* south */ {southeast,nodir,nodir,nodir,southwest,nodir,nodir,nodir,nodir}, |
||
36 | {nodir,nodir,nodir,nodir,nodir,nodir,nodir,nodir,nodir}, |
||
37 | {nodir,nodir,nodir,nodir,nodir,nodir,nodir,nodir,nodir} |
||
38 | }; |
||
39 | |||
40 | |||
41 | |||
42 | void SpawnNewObj (unsigned tilex, unsigned tiley, statetype *state); |
||
43 | void NewState (objtype *ob, statetype *state); |
||
44 | |||
45 | boolean TryWalk (objtype *ob); |
||
46 | void MoveObj (objtype *ob, int32_t move); |
||
47 | |||
48 | void KillActor (objtype *ob); |
||
49 | void DamageActor (objtype *ob, unsigned damage); |
||
50 | |||
51 | boolean CheckLine (objtype *ob); |
||
52 | void FirstSighting (objtype *ob); |
||
53 | boolean CheckSight (objtype *ob); |
||
54 | |||
55 | /* |
||
56 | ============================================================================= |
||
57 | |||
58 | LOCAL VARIABLES |
||
59 | |||
60 | ============================================================================= |
||
61 | */ |
||
62 | |||
63 | |||
64 | |||
65 | //=========================================================================== |
||
66 | |||
67 | |||
68 | /* |
||
69 | =================== |
||
70 | = |
||
71 | = SpawnNewObj |
||
72 | = |
||
73 | = Spaws a new actor at the given TILE coordinates, with the given state, and |
||
74 | = the given size in GLOBAL units. |
||
75 | = |
||
76 | = newobj = a pointer to an initialized new actor |
||
77 | = |
||
78 | =================== |
||
79 | */ |
||
80 | |||
81 | void SpawnNewObj (unsigned tilex, unsigned tiley, statetype *state) |
||
82 | { |
||
83 | GetNewActor (); |
||
84 | newobj->state = state; |
||
85 | if (state->tictime) |
||
86 | newobj->ticcount = DEMOCHOOSE_ORIG_SDL( |
||
87 | US_RndT () % state->tictime, |
||
88 | US_RndT () % state->tictime + 1); // Chris' moonwalk bugfix ;D |
||
89 | else |
||
90 | newobj->ticcount = 0; |
||
91 | |||
92 | newobj->tilex = (short) tilex; |
||
93 | newobj->tiley = (short) tiley; |
||
94 | newobj->x = ((int32_t)tilex< |
||
95 | newobj->y = ((int32_t)tiley< |
||
96 | newobj->dir = nodir; |
||
97 | |||
98 | actorat[tilex][tiley] = newobj; |
||
99 | newobj->areanumber = |
||
100 | *(mapsegs[0] + (newobj->tiley< |
||
101 | } |
||
102 | |||
103 | |||
104 | |||
105 | /* |
||
106 | =================== |
||
107 | = |
||
108 | = NewState |
||
109 | = |
||
110 | = Changes ob to a new state, setting ticcount to the max for that state |
||
111 | = |
||
112 | =================== |
||
113 | */ |
||
114 | |||
115 | void NewState (objtype *ob, statetype *state) |
||
116 | { |
||
117 | ob->state = state; |
||
118 | ob->ticcount = state->tictime; |
||
119 | } |
||
120 | |||
121 | |||
122 | |||
123 | /* |
||
124 | ============================================================================= |
||
125 | |||
126 | ENEMY TILE WORLD MOVEMENT CODE |
||
127 | |||
128 | ============================================================================= |
||
129 | */ |
||
130 | |||
131 | |||
132 | /* |
||
133 | ================================== |
||
134 | = |
||
135 | = TryWalk |
||
136 | = |
||
137 | = Attempts to move ob in its current (ob->dir) direction. |
||
138 | = |
||
139 | = If blocked by either a wall or an actor returns FALSE |
||
140 | = |
||
141 | = If move is either clear or blocked only by a door, returns TRUE and sets |
||
142 | = |
||
143 | = ob->tilex = new destination |
||
144 | = ob->tiley |
||
145 | = ob->areanumber = the floor tile number (0-(NUMAREAS-1)) of destination |
||
146 | = ob->distance = TILEGLOBAl, or -doornumber if a door is blocking the way |
||
147 | = |
||
148 | = If a door is in the way, an OpenDoor call is made to start it opening. |
||
149 | = The actor code should wait until |
||
150 | = doorobjlist[-ob->distance].action = dr_open, meaning the door has been |
||
151 | = fully opened |
||
152 | = |
||
153 | ================================== |
||
154 | */ |
||
155 | |||
156 | #define CHECKDIAG(x,y) \ |
||
157 | { \ |
||
158 | temp=(uintptr_t)actorat[x][y]; \ |
||
159 | if (temp) \ |
||
160 | { \ |
||
161 | if (temp<256) \ |
||
162 | return false; \ |
||
163 | if (((objtype *)temp)->flags&FL_SHOOTABLE) \ |
||
164 | return false; \ |
||
165 | } \ |
||
166 | } |
||
167 | |||
168 | #ifdef PLAYDEMOLIKEORIGINAL |
||
169 | #define DOORCHECK \ |
||
170 | if(DEMOCOND_ORIG) \ |
||
171 | doornum = temp&63; \ |
||
172 | else \ |
||
173 | { \ |
||
174 | doornum = (int) temp & 127; \ |
||
175 | OpenDoor(doornum); \ |
||
176 | ob->distance = -doornum - 1; \ |
||
177 | return true; \ |
||
178 | } |
||
179 | #else |
||
180 | #define DOORCHECK \ |
||
181 | doornum = (int) temp & 127; \ |
||
182 | OpenDoor(doornum); \ |
||
183 | ob->distance = -doornum - 1; \ |
||
184 | return true; |
||
185 | #endif |
||
186 | |||
187 | #define CHECKSIDE(x,y) \ |
||
188 | { \ |
||
189 | temp=(uintptr_t)actorat[x][y]; \ |
||
190 | if (temp) \ |
||
191 | { \ |
||
192 | if (temp<128) \ |
||
193 | return false; \ |
||
194 | if (temp<256) \ |
||
195 | { \ |
||
196 | DOORCHECK \ |
||
197 | } \ |
||
198 | else if (((objtype *)temp)->flags&FL_SHOOTABLE) \ |
||
199 | return false; \ |
||
200 | } \ |
||
201 | } |
||
202 | |||
203 | |||
204 | boolean TryWalk (objtype *ob) |
||
205 | { |
||
206 | int doornum = -1; |
||
207 | uintptr_t temp; |
||
208 | |||
209 | if (ob->obclass == inertobj) |
||
210 | { |
||
211 | switch (ob->dir) |
||
212 | { |
||
213 | case north: |
||
214 | ob->tiley--; |
||
215 | break; |
||
216 | |||
217 | case northeast: |
||
218 | ob->tilex++; |
||
219 | ob->tiley--; |
||
220 | break; |
||
221 | |||
222 | case east: |
||
223 | ob->tilex++; |
||
224 | break; |
||
225 | |||
226 | case southeast: |
||
227 | ob->tilex++; |
||
228 | ob->tiley++; |
||
229 | break; |
||
230 | |||
231 | case south: |
||
232 | ob->tiley++; |
||
233 | break; |
||
234 | |||
235 | case southwest: |
||
236 | ob->tilex--; |
||
237 | ob->tiley++; |
||
238 | break; |
||
239 | |||
240 | case west: |
||
241 | ob->tilex--; |
||
242 | break; |
||
243 | |||
244 | case northwest: |
||
245 | ob->tilex--; |
||
246 | ob->tiley--; |
||
247 | break; |
||
248 | } |
||
249 | } |
||
250 | else |
||
251 | { |
||
252 | switch (ob->dir) |
||
253 | { |
||
254 | case north: |
||
255 | if (ob->obclass == dogobj || ob->obclass == fakeobj |
||
256 | || ob->obclass == ghostobj || ob->obclass == spectreobj) |
||
257 | { |
||
258 | CHECKDIAG(ob->tilex,ob->tiley-1); |
||
259 | } |
||
260 | else |
||
261 | { |
||
262 | CHECKSIDE(ob->tilex,ob->tiley-1); |
||
263 | } |
||
264 | ob->tiley--; |
||
265 | break; |
||
266 | |||
267 | case northeast: |
||
268 | CHECKDIAG(ob->tilex+1,ob->tiley-1); |
||
269 | CHECKDIAG(ob->tilex+1,ob->tiley); |
||
270 | CHECKDIAG(ob->tilex,ob->tiley-1); |
||
271 | ob->tilex++; |
||
272 | ob->tiley--; |
||
273 | break; |
||
274 | |||
275 | case east: |
||
276 | if (ob->obclass == dogobj || ob->obclass == fakeobj |
||
277 | || ob->obclass == ghostobj || ob->obclass == spectreobj) |
||
278 | { |
||
279 | CHECKDIAG(ob->tilex+1,ob->tiley); |
||
280 | } |
||
281 | else |
||
282 | { |
||
283 | CHECKSIDE(ob->tilex+1,ob->tiley); |
||
284 | } |
||
285 | ob->tilex++; |
||
286 | break; |
||
287 | |||
288 | case southeast: |
||
289 | CHECKDIAG(ob->tilex+1,ob->tiley+1); |
||
290 | CHECKDIAG(ob->tilex+1,ob->tiley); |
||
291 | CHECKDIAG(ob->tilex,ob->tiley+1); |
||
292 | ob->tilex++; |
||
293 | ob->tiley++; |
||
294 | break; |
||
295 | |||
296 | case south: |
||
297 | if (ob->obclass == dogobj || ob->obclass == fakeobj |
||
298 | || ob->obclass == ghostobj || ob->obclass == spectreobj) |
||
299 | { |
||
300 | CHECKDIAG(ob->tilex,ob->tiley+1); |
||
301 | } |
||
302 | else |
||
303 | { |
||
304 | CHECKSIDE(ob->tilex,ob->tiley+1); |
||
305 | } |
||
306 | ob->tiley++; |
||
307 | break; |
||
308 | |||
309 | case southwest: |
||
310 | CHECKDIAG(ob->tilex-1,ob->tiley+1); |
||
311 | CHECKDIAG(ob->tilex-1,ob->tiley); |
||
312 | CHECKDIAG(ob->tilex,ob->tiley+1); |
||
313 | ob->tilex--; |
||
314 | ob->tiley++; |
||
315 | break; |
||
316 | |||
317 | case west: |
||
318 | if (ob->obclass == dogobj || ob->obclass == fakeobj |
||
319 | || ob->obclass == ghostobj || ob->obclass == spectreobj) |
||
320 | { |
||
321 | CHECKDIAG(ob->tilex-1,ob->tiley); |
||
322 | } |
||
323 | else |
||
324 | { |
||
325 | CHECKSIDE(ob->tilex-1,ob->tiley); |
||
326 | } |
||
327 | ob->tilex--; |
||
328 | break; |
||
329 | |||
330 | case northwest: |
||
331 | CHECKDIAG(ob->tilex-1,ob->tiley-1); |
||
332 | CHECKDIAG(ob->tilex-1,ob->tiley); |
||
333 | CHECKDIAG(ob->tilex,ob->tiley-1); |
||
334 | ob->tilex--; |
||
335 | ob->tiley--; |
||
336 | break; |
||
337 | |||
338 | case nodir: |
||
339 | return false; |
||
340 | |||
341 | default: |
||
342 | Quit ("Walk: Bad dir"); |
||
343 | } |
||
344 | } |
||
345 | |||
346 | #ifdef PLAYDEMOLIKEORIGINAL |
||
347 | if (DEMOCOND_ORIG && doornum != -1) |
||
348 | { |
||
349 | OpenDoor(doornum); |
||
350 | ob->distance = -doornum-1; |
||
351 | return true; |
||
352 | } |
||
353 | #endif |
||
354 | |||
355 | ob->areanumber = |
||
356 | *(mapsegs[0] + (ob->tiley< |
||
357 | |||
358 | ob->distance = TILEGLOBAL; |
||
359 | return true; |
||
360 | } |
||
361 | |||
362 | |||
363 | /* |
||
364 | ================================== |
||
365 | = |
||
366 | = SelectDodgeDir |
||
367 | = |
||
368 | = Attempts to choose and initiate a movement for ob that sends it towards |
||
369 | = the player while dodging |
||
370 | = |
||
371 | = If there is no possible move (ob is totally surrounded) |
||
372 | = |
||
373 | = ob->dir = nodir |
||
374 | = |
||
375 | = Otherwise |
||
376 | = |
||
377 | = ob->dir = new direction to follow |
||
378 | = ob->distance = TILEGLOBAL or -doornumber |
||
379 | = ob->tilex = new destination |
||
380 | = ob->tiley |
||
381 | = ob->areanumber = the floor tile number (0-(NUMAREAS-1)) of destination |
||
382 | = |
||
383 | ================================== |
||
384 | */ |
||
385 | |||
386 | void SelectDodgeDir (objtype *ob) |
||
387 | { |
||
388 | int deltax,deltay,i; |
||
389 | unsigned absdx,absdy; |
||
390 | dirtype dirtry[5]; |
||
391 | dirtype turnaround,tdir; |
||
392 | |||
393 | if (ob->flags & FL_FIRSTATTACK) |
||
394 | { |
||
395 | // |
||
396 | // turning around is only ok the very first time after noticing the |
||
397 | // player |
||
398 | // |
||
399 | turnaround = nodir; |
||
400 | ob->flags &= ~FL_FIRSTATTACK; |
||
401 | } |
||
402 | else |
||
403 | turnaround=opposite[ob->dir]; |
||
404 | |||
405 | deltax = player->tilex - ob->tilex; |
||
406 | deltay = player->tiley - ob->tiley; |
||
407 | |||
408 | // |
||
409 | // arange 5 direction choices in order of preference |
||
410 | // the four cardinal directions plus the diagonal straight towards |
||
411 | // the player |
||
412 | // |
||
413 | |||
414 | if (deltax>0) |
||
415 | { |
||
416 | dirtry[1]= east; |
||
417 | dirtry[3]= west; |
||
418 | } |
||
419 | else |
||
420 | { |
||
421 | dirtry[1]= west; |
||
422 | dirtry[3]= east; |
||
423 | } |
||
424 | |||
425 | if (deltay>0) |
||
426 | { |
||
427 | dirtry[2]= south; |
||
428 | dirtry[4]= north; |
||
429 | } |
||
430 | else |
||
431 | { |
||
432 | dirtry[2]= north; |
||
433 | dirtry[4]= south; |
||
434 | } |
||
435 | |||
436 | // |
||
437 | // randomize a bit for dodging |
||
438 | // |
||
439 | absdx = abs(deltax); |
||
440 | absdy = abs(deltay); |
||
441 | |||
442 | if (absdx > absdy) |
||
443 | { |
||
444 | tdir = dirtry[1]; |
||
445 | dirtry[1] = dirtry[2]; |
||
446 | dirtry[2] = tdir; |
||
447 | tdir = dirtry[3]; |
||
448 | dirtry[3] = dirtry[4]; |
||
449 | dirtry[4] = tdir; |
||
450 | } |
||
451 | |||
452 | if (US_RndT() < 128) |
||
453 | { |
||
454 | tdir = dirtry[1]; |
||
455 | dirtry[1] = dirtry[2]; |
||
456 | dirtry[2] = tdir; |
||
457 | tdir = dirtry[3]; |
||
458 | dirtry[3] = dirtry[4]; |
||
459 | dirtry[4] = tdir; |
||
460 | } |
||
461 | |||
462 | dirtry[0] = diagonal [ dirtry[1] ] [ dirtry[2] ]; |
||
463 | |||
464 | // |
||
465 | // try the directions util one works |
||
466 | // |
||
467 | for (i=0;i<5;i++) |
||
468 | { |
||
469 | if ( dirtry[i] == nodir || dirtry[i] == turnaround) |
||
470 | continue; |
||
471 | |||
472 | ob->dir = dirtry[i]; |
||
473 | if (TryWalk(ob)) |
||
474 | return; |
||
475 | } |
||
476 | |||
477 | // |
||
478 | // turn around only as a last resort |
||
479 | // |
||
480 | if (turnaround != nodir) |
||
481 | { |
||
482 | ob->dir = turnaround; |
||
483 | |||
484 | if (TryWalk(ob)) |
||
485 | return; |
||
486 | } |
||
487 | |||
488 | ob->dir = nodir; |
||
489 | } |
||
490 | |||
491 | |||
492 | /* |
||
493 | ============================ |
||
494 | = |
||
495 | = SelectChaseDir |
||
496 | = |
||
497 | = As SelectDodgeDir, but doesn't try to dodge |
||
498 | = |
||
499 | ============================ |
||
500 | */ |
||
501 | |||
502 | void SelectChaseDir (objtype *ob) |
||
503 | { |
||
504 | int deltax,deltay; |
||
505 | dirtype d[3]; |
||
506 | dirtype tdir, olddir, turnaround; |
||
507 | |||
508 | |||
509 | olddir=ob->dir; |
||
510 | turnaround=opposite[olddir]; |
||
511 | |||
512 | deltax=player->tilex - ob->tilex; |
||
513 | deltay=player->tiley - ob->tiley; |
||
514 | |||
515 | d[1]=nodir; |
||
516 | d[2]=nodir; |
||
517 | |||
518 | if (deltax>0) |
||
519 | d[1]= east; |
||
520 | else if (deltax<0) |
||
521 | d[1]= west; |
||
522 | if (deltay>0) |
||
523 | d[2]=south; |
||
524 | else if (deltay<0) |
||
525 | d[2]=north; |
||
526 | |||
527 | if (abs(deltay)>abs(deltax)) |
||
528 | { |
||
529 | tdir=d[1]; |
||
530 | d[1]=d[2]; |
||
531 | d[2]=tdir; |
||
532 | } |
||
533 | |||
534 | if (d[1]==turnaround) |
||
535 | d[1]=nodir; |
||
536 | if (d[2]==turnaround) |
||
537 | d[2]=nodir; |
||
538 | |||
539 | |||
540 | if (d[1]!=nodir) |
||
541 | { |
||
542 | ob->dir=d[1]; |
||
543 | if (TryWalk(ob)) |
||
544 | return; /*either moved forward or attacked*/ |
||
545 | } |
||
546 | |||
547 | if (d[2]!=nodir) |
||
548 | { |
||
549 | ob->dir=d[2]; |
||
550 | if (TryWalk(ob)) |
||
551 | return; |
||
552 | } |
||
553 | |||
554 | /* there is no direct path to the player, so pick another direction */ |
||
555 | |||
556 | if (olddir!=nodir) |
||
557 | { |
||
558 | ob->dir=olddir; |
||
559 | if (TryWalk(ob)) |
||
560 | return; |
||
561 | } |
||
562 | |||
563 | if (US_RndT()>128) /*randomly determine direction of search*/ |
||
564 | { |
||
565 | for (tdir=north; tdir<=west; tdir=(dirtype)(tdir+1)) |
||
566 | { |
||
567 | if (tdir!=turnaround) |
||
568 | { |
||
569 | ob->dir=tdir; |
||
570 | if ( TryWalk(ob) ) |
||
571 | return; |
||
572 | } |
||
573 | } |
||
574 | } |
||
575 | else |
||
576 | { |
||
577 | for (tdir=west; tdir>=north; tdir=(dirtype)(tdir-1)) |
||
578 | { |
||
579 | if (tdir!=turnaround) |
||
580 | { |
||
581 | ob->dir=tdir; |
||
582 | if ( TryWalk(ob) ) |
||
583 | return; |
||
584 | } |
||
585 | } |
||
586 | } |
||
587 | |||
588 | if (turnaround != nodir) |
||
589 | { |
||
590 | ob->dir=turnaround; |
||
591 | if (ob->dir != nodir) |
||
592 | { |
||
593 | if ( TryWalk(ob) ) |
||
594 | return; |
||
595 | } |
||
596 | } |
||
597 | |||
598 | ob->dir = nodir; // can't move |
||
599 | } |
||
600 | |||
601 | |||
602 | /* |
||
603 | ============================ |
||
604 | = |
||
605 | = SelectRunDir |
||
606 | = |
||
607 | = Run Away from player |
||
608 | = |
||
609 | ============================ |
||
610 | */ |
||
611 | |||
612 | void SelectRunDir (objtype *ob) |
||
613 | { |
||
614 | int deltax,deltay; |
||
615 | dirtype d[3]; |
||
616 | dirtype tdir; |
||
617 | |||
618 | |||
619 | deltax=player->tilex - ob->tilex; |
||
620 | deltay=player->tiley - ob->tiley; |
||
621 | |||
622 | if (deltax<0) |
||
623 | d[1]= east; |
||
624 | else |
||
625 | d[1]= west; |
||
626 | if (deltay<0) |
||
627 | d[2]=south; |
||
628 | else |
||
629 | d[2]=north; |
||
630 | |||
631 | if (abs(deltay)>abs(deltax)) |
||
632 | { |
||
633 | tdir=d[1]; |
||
634 | d[1]=d[2]; |
||
635 | d[2]=tdir; |
||
636 | } |
||
637 | |||
638 | ob->dir=d[1]; |
||
639 | if (TryWalk(ob)) |
||
640 | return; /*either moved forward or attacked*/ |
||
641 | |||
642 | ob->dir=d[2]; |
||
643 | if (TryWalk(ob)) |
||
644 | return; |
||
645 | |||
646 | /* there is no direct path to the player, so pick another direction */ |
||
647 | |||
648 | if (US_RndT()>128) /*randomly determine direction of search*/ |
||
649 | { |
||
650 | for (tdir=north; tdir<=west; tdir=(dirtype)(tdir+1)) |
||
651 | { |
||
652 | ob->dir=tdir; |
||
653 | if ( TryWalk(ob) ) |
||
654 | return; |
||
655 | } |
||
656 | } |
||
657 | else |
||
658 | { |
||
659 | for (tdir=west; tdir>=north; tdir=(dirtype)(tdir-1)) |
||
660 | { |
||
661 | ob->dir=tdir; |
||
662 | if ( TryWalk(ob) ) |
||
663 | return; |
||
664 | } |
||
665 | } |
||
666 | |||
667 | ob->dir = nodir; // can't move |
||
668 | } |
||
669 | |||
670 | |||
671 | /* |
||
672 | ================= |
||
673 | = |
||
674 | = MoveObj |
||
675 | = |
||
676 | = Moves ob be move global units in ob->dir direction |
||
677 | = Actors are not allowed to move inside the player |
||
678 | = Does NOT check to see if the move is tile map valid |
||
679 | = |
||
680 | = ob->x = adjusted for new position |
||
681 | = ob->y |
||
682 | = |
||
683 | ================= |
||
684 | */ |
||
685 | |||
686 | void MoveObj (objtype *ob, int32_t move) |
||
687 | { |
||
688 | int32_t deltax,deltay; |
||
689 | |||
690 | switch (ob->dir) |
||
691 | { |
||
692 | case north: |
||
693 | ob->y -= move; |
||
694 | break; |
||
695 | case northeast: |
||
696 | ob->x += move; |
||
697 | ob->y -= move; |
||
698 | break; |
||
699 | case east: |
||
700 | ob->x += move; |
||
701 | break; |
||
702 | case southeast: |
||
703 | ob->x += move; |
||
704 | ob->y += move; |
||
705 | break; |
||
706 | case south: |
||
707 | ob->y += move; |
||
708 | break; |
||
709 | case southwest: |
||
710 | ob->x -= move; |
||
711 | ob->y += move; |
||
712 | break; |
||
713 | case west: |
||
714 | ob->x -= move; |
||
715 | break; |
||
716 | case northwest: |
||
717 | ob->x -= move; |
||
718 | ob->y -= move; |
||
719 | break; |
||
720 | |||
721 | case nodir: |
||
722 | return; |
||
723 | |||
724 | default: |
||
725 | Quit ("MoveObj: bad dir!"); |
||
726 | } |
||
727 | |||
728 | // |
||
729 | // check to make sure it's not on top of player |
||
730 | // |
||
731 | if (areabyplayer[ob->areanumber]) |
||
732 | { |
||
733 | deltax = ob->x - player->x; |
||
734 | if (deltax < -MINACTORDIST || deltax > MINACTORDIST) |
||
735 | goto moveok; |
||
736 | deltay = ob->y - player->y; |
||
737 | if (deltay < -MINACTORDIST || deltay > MINACTORDIST) |
||
738 | goto moveok; |
||
739 | |||
740 | if (ob->hidden) // move closer until he meets CheckLine |
||
741 | goto moveok; |
||
742 | |||
743 | if (ob->obclass == ghostobj || ob->obclass == spectreobj) |
||
744 | TakeDamage (tics*2,ob); |
||
745 | |||
746 | // |
||
747 | // back up |
||
748 | // |
||
749 | switch (ob->dir) |
||
750 | { |
||
751 | case north: |
||
752 | ob->y += move; |
||
753 | break; |
||
754 | case northeast: |
||
755 | ob->x -= move; |
||
756 | ob->y += move; |
||
757 | break; |
||
758 | case east: |
||
759 | ob->x -= move; |
||
760 | break; |
||
761 | case southeast: |
||
762 | ob->x -= move; |
||
763 | ob->y -= move; |
||
764 | break; |
||
765 | case south: |
||
766 | ob->y -= move; |
||
767 | break; |
||
768 | case southwest: |
||
769 | ob->x += move; |
||
770 | ob->y -= move; |
||
771 | break; |
||
772 | case west: |
||
773 | ob->x += move; |
||
774 | break; |
||
775 | case northwest: |
||
776 | ob->x += move; |
||
777 | ob->y += move; |
||
778 | break; |
||
779 | |||
780 | case nodir: |
||
781 | return; |
||
782 | } |
||
783 | return; |
||
784 | } |
||
785 | moveok: |
||
786 | ob->distance -=move; |
||
787 | } |
||
788 | |||
789 | /* |
||
790 | ============================================================================= |
||
791 | |||
792 | STUFF |
||
793 | |||
794 | ============================================================================= |
||
795 | */ |
||
796 | |||
797 | /* |
||
798 | =============== |
||
799 | = |
||
800 | = DropItem |
||
801 | = |
||
802 | = Tries to drop a bonus item somewhere in the tiles surrounding the |
||
803 | = given tilex/tiley |
||
804 | = |
||
805 | =============== |
||
806 | */ |
||
807 | |||
808 | void DropItem (wl_stat_t itemtype, int tilex, int tiley) |
||
809 | { |
||
810 | int x,y,xl,xh,yl,yh; |
||
811 | |||
812 | // |
||
813 | // find a free spot to put it in |
||
814 | // |
||
815 | if (!actorat[tilex][tiley]) |
||
816 | { |
||
817 | PlaceItemType (itemtype, tilex,tiley); |
||
818 | return; |
||
819 | } |
||
820 | |||
821 | xl = tilex-1; |
||
822 | xh = tilex+1; |
||
823 | yl = tiley-1; |
||
824 | yh = tiley+1; |
||
825 | |||
826 | for (x=xl ; x<= xh ; x++) |
||
827 | { |
||
828 | for (y=yl ; y<= yh ; y++) |
||
829 | { |
||
830 | if (!actorat[x][y]) |
||
831 | { |
||
832 | PlaceItemType (itemtype, x,y); |
||
833 | return; |
||
834 | } |
||
835 | } |
||
836 | } |
||
837 | } |
||
838 | |||
839 | |||
840 | |||
841 | /* |
||
842 | =============== |
||
843 | = |
||
844 | = KillActor |
||
845 | = |
||
846 | =============== |
||
847 | */ |
||
848 | |||
849 | void KillActor (objtype *ob) |
||
850 | { |
||
851 | int tilex,tiley; |
||
852 | |||
853 | tilex = ob->tilex = (word)(ob->x >> TILESHIFT); // drop item on center |
||
854 | tiley = ob->tiley = (word)(ob->y >> TILESHIFT); |
||
855 | |||
856 | switch (ob->obclass) |
||
857 | { |
||
858 | case guardobj: |
||
859 | GivePoints (100); |
||
860 | NewState (ob,&s_grddie1); |
||
861 | PlaceItemType (bo_clip2,tilex,tiley); |
||
862 | break; |
||
863 | |||
864 | case officerobj: |
||
865 | GivePoints (400); |
||
866 | NewState (ob,&s_ofcdie1); |
||
867 | PlaceItemType (bo_clip2,tilex,tiley); |
||
868 | break; |
||
869 | |||
870 | case mutantobj: |
||
871 | GivePoints (700); |
||
872 | NewState (ob,&s_mutdie1); |
||
873 | PlaceItemType (bo_clip2,tilex,tiley); |
||
874 | break; |
||
875 | |||
876 | case ssobj: |
||
877 | GivePoints (500); |
||
878 | NewState (ob,&s_ssdie1); |
||
879 | if (gamestate.bestweapon < wp_machinegun) |
||
880 | PlaceItemType (bo_machinegun,tilex,tiley); |
||
881 | else |
||
882 | PlaceItemType (bo_clip2,tilex,tiley); |
||
883 | break; |
||
884 | |||
885 | case dogobj: |
||
886 | GivePoints (200); |
||
887 | NewState (ob,&s_dogdie1); |
||
888 | break; |
||
889 | |||
890 | #ifndef SPEAR |
||
891 | case bossobj: |
||
892 | GivePoints (5000); |
||
893 | NewState (ob,&s_bossdie1); |
||
894 | PlaceItemType (bo_key1,tilex,tiley); |
||
895 | break; |
||
896 | |||
897 | case gretelobj: |
||
898 | GivePoints (5000); |
||
899 | NewState (ob,&s_greteldie1); |
||
900 | PlaceItemType (bo_key1,tilex,tiley); |
||
901 | break; |
||
902 | |||
903 | case giftobj: |
||
904 | GivePoints (5000); |
||
905 | gamestate.killx = player->x; |
||
906 | gamestate.killy = player->y; |
||
907 | NewState (ob,&s_giftdie1); |
||
908 | break; |
||
909 | |||
910 | case fatobj: |
||
911 | GivePoints (5000); |
||
912 | gamestate.killx = player->x; |
||
913 | gamestate.killy = player->y; |
||
914 | NewState (ob,&s_fatdie1); |
||
915 | break; |
||
916 | |||
917 | case schabbobj: |
||
918 | GivePoints (5000); |
||
919 | gamestate.killx = player->x; |
||
920 | gamestate.killy = player->y; |
||
921 | NewState (ob,&s_schabbdie1); |
||
922 | break; |
||
923 | case fakeobj: |
||
924 | GivePoints (2000); |
||
925 | NewState (ob,&s_fakedie1); |
||
926 | break; |
||
927 | |||
928 | case mechahitlerobj: |
||
929 | GivePoints (5000); |
||
930 | NewState (ob,&s_mechadie1); |
||
931 | break; |
||
932 | case realhitlerobj: |
||
933 | GivePoints (5000); |
||
934 | gamestate.killx = player->x; |
||
935 | gamestate.killy = player->y; |
||
936 | NewState (ob,&s_hitlerdie1); |
||
937 | break; |
||
938 | #else |
||
939 | case spectreobj: |
||
940 | if (ob->flags&FL_BONUS) |
||
941 | { |
||
942 | GivePoints (200); // Get points once for each |
||
943 | ob->flags &= ~FL_BONUS; |
||
944 | } |
||
945 | NewState (ob,&s_spectredie1); |
||
946 | break; |
||
947 | |||
948 | case angelobj: |
||
949 | GivePoints (5000); |
||
950 | NewState (ob,&s_angeldie1); |
||
951 | break; |
||
952 | |||
953 | case transobj: |
||
954 | GivePoints (5000); |
||
955 | NewState (ob,&s_transdie0); |
||
956 | PlaceItemType (bo_key1,tilex,tiley); |
||
957 | break; |
||
958 | |||
959 | case uberobj: |
||
960 | GivePoints (5000); |
||
961 | NewState (ob,&s_uberdie0); |
||
962 | PlaceItemType (bo_key1,tilex,tiley); |
||
963 | break; |
||
964 | |||
965 | case willobj: |
||
966 | GivePoints (5000); |
||
967 | NewState (ob,&s_willdie1); |
||
968 | PlaceItemType (bo_key1,tilex,tiley); |
||
969 | break; |
||
970 | |||
971 | case deathobj: |
||
972 | GivePoints (5000); |
||
973 | NewState (ob,&s_deathdie1); |
||
974 | PlaceItemType (bo_key1,tilex,tiley); |
||
975 | break; |
||
976 | #endif |
||
977 | } |
||
978 | |||
979 | gamestate.killcount++; |
||
980 | ob->flags &= ~FL_SHOOTABLE; |
||
981 | actorat[ob->tilex][ob->tiley] = NULL; |
||
982 | ob->flags |= FL_NONMARK; |
||
983 | } |
||
984 | |||
985 | |||
986 | |||
987 | /* |
||
988 | =================== |
||
989 | = |
||
990 | = DamageActor |
||
991 | = |
||
992 | = Called when the player succesfully hits an enemy. |
||
993 | = |
||
994 | = Does damage points to enemy ob, either putting it into a stun frame or |
||
995 | = killing it. |
||
996 | = |
||
997 | =================== |
||
998 | */ |
||
999 | |||
1000 | void DamageActor (objtype *ob, unsigned damage) |
||
1001 | { |
||
1002 | madenoise = true; |
||
1003 | |||
1004 | // |
||
1005 | // do double damage if shooting a non attack mode actor |
||
1006 | // |
||
1007 | if ( !(ob->flags & FL_ATTACKMODE) ) |
||
1008 | damage <<= 1; |
||
1009 | |||
1010 | ob->hitpoints -= (short)damage; |
||
1011 | |||
1012 | if (ob->hitpoints<=0) |
||
1013 | KillActor (ob); |
||
1014 | else |
||
1015 | { |
||
1016 | if (! (ob->flags & FL_ATTACKMODE) ) |
||
1017 | FirstSighting (ob); // put into combat mode |
||
1018 | |||
1019 | switch (ob->obclass) // dogs only have one hit point |
||
1020 | { |
||
1021 | case guardobj: |
||
1022 | if (ob->hitpoints&1) |
||
1023 | NewState (ob,&s_grdpain); |
||
1024 | else |
||
1025 | NewState (ob,&s_grdpain1); |
||
1026 | break; |
||
1027 | |||
1028 | case officerobj: |
||
1029 | if (ob->hitpoints&1) |
||
1030 | NewState (ob,&s_ofcpain); |
||
1031 | else |
||
1032 | NewState (ob,&s_ofcpain1); |
||
1033 | break; |
||
1034 | |||
1035 | case mutantobj: |
||
1036 | if (ob->hitpoints&1) |
||
1037 | NewState (ob,&s_mutpain); |
||
1038 | else |
||
1039 | NewState (ob,&s_mutpain1); |
||
1040 | break; |
||
1041 | |||
1042 | case ssobj: |
||
1043 | if (ob->hitpoints&1) |
||
1044 | NewState (ob,&s_sspain); |
||
1045 | else |
||
1046 | NewState (ob,&s_sspain1); |
||
1047 | |||
1048 | break; |
||
1049 | } |
||
1050 | } |
||
1051 | } |
||
1052 | |||
1053 | /* |
||
1054 | ============================================================================= |
||
1055 | |||
1056 | CHECKSIGHT |
||
1057 | |||
1058 | ============================================================================= |
||
1059 | */ |
||
1060 | |||
1061 | |||
1062 | /* |
||
1063 | ===================== |
||
1064 | = |
||
1065 | = CheckLine |
||
1066 | = |
||
1067 | = Returns true if a straight line between the player and ob is unobstructed |
||
1068 | = |
||
1069 | ===================== |
||
1070 | */ |
||
1071 | |||
1072 | boolean CheckLine (objtype *ob) |
||
1073 | { |
||
1074 | int x1,y1,xt1,yt1,x2,y2,xt2,yt2; |
||
1075 | int x,y; |
||
1076 | int xdist,ydist,xstep,ystep; |
||
1077 | int partial,delta; |
||
1078 | int32_t ltemp; |
||
1079 | int xfrac,yfrac,deltafrac; |
||
1080 | unsigned value,intercept; |
||
1081 | |||
1082 | x1 = ob->x >> UNSIGNEDSHIFT; // 1/256 tile precision |
||
1083 | y1 = ob->y >> UNSIGNEDSHIFT; |
||
1084 | xt1 = x1 >> 8; |
||
1085 | yt1 = y1 >> 8; |
||
1086 | |||
1087 | x2 = plux; |
||
1088 | y2 = pluy; |
||
1089 | xt2 = player->tilex; |
||
1090 | yt2 = player->tiley; |
||
1091 | |||
1092 | xdist = abs(xt2-xt1); |
||
1093 | |||
1094 | if (xdist > 0) |
||
1095 | { |
||
1096 | if (xt2 > xt1) |
||
1097 | { |
||
1098 | partial = 256-(x1&0xff); |
||
1099 | xstep = 1; |
||
1100 | } |
||
1101 | else |
||
1102 | { |
||
1103 | partial = x1&0xff; |
||
1104 | xstep = -1; |
||
1105 | } |
||
1106 | |||
1107 | deltafrac = abs(x2-x1); |
||
1108 | delta = y2-y1; |
||
1109 | ltemp = ((int32_t)delta<<8)/deltafrac; |
||
1110 | if (ltemp > 0x7fffl) |
||
1111 | ystep = 0x7fff; |
||
1112 | else if (ltemp < -0x7fffl) |
||
1113 | ystep = -0x7fff; |
||
1114 | else |
||
1115 | ystep = ltemp; |
||
1116 | yfrac = y1 + (((int32_t)ystep*partial) >>8); |
||
1117 | |||
1118 | x = xt1+xstep; |
||
1119 | xt2 += xstep; |
||
1120 | do |
||
1121 | { |
||
1122 | y = yfrac>>8; |
||
1123 | yfrac += ystep; |
||
1124 | |||
1125 | value = (unsigned)tilemap[x][y]; |
||
1126 | x += xstep; |
||
1127 | |||
1128 | if (!value) |
||
1129 | continue; |
||
1130 | |||
1131 | if (value<128 || value>256) |
||
1132 | return false; |
||
1133 | |||
1134 | // |
||
1135 | // see if the door is open enough |
||
1136 | // |
||
1137 | value &= ~0x80; |
||
1138 | intercept = yfrac-ystep/2; |
||
1139 | |||
1140 | if (intercept>doorposition[value]) |
||
1141 | return false; |
||
1142 | |||
1143 | } while (x != xt2); |
||
1144 | } |
||
1145 | |||
1146 | ydist = abs(yt2-yt1); |
||
1147 | |||
1148 | if (ydist > 0) |
||
1149 | { |
||
1150 | if (yt2 > yt1) |
||
1151 | { |
||
1152 | partial = 256-(y1&0xff); |
||
1153 | ystep = 1; |
||
1154 | } |
||
1155 | else |
||
1156 | { |
||
1157 | partial = y1&0xff; |
||
1158 | ystep = -1; |
||
1159 | } |
||
1160 | |||
1161 | deltafrac = abs(y2-y1); |
||
1162 | delta = x2-x1; |
||
1163 | ltemp = ((int32_t)delta<<8)/deltafrac; |
||
1164 | if (ltemp > 0x7fffl) |
||
1165 | xstep = 0x7fff; |
||
1166 | else if (ltemp < -0x7fffl) |
||
1167 | xstep = -0x7fff; |
||
1168 | else |
||
1169 | xstep = ltemp; |
||
1170 | xfrac = x1 + (((int32_t)xstep*partial) >>8); |
||
1171 | |||
1172 | y = yt1 + ystep; |
||
1173 | yt2 += ystep; |
||
1174 | do |
||
1175 | { |
||
1176 | x = xfrac>>8; |
||
1177 | xfrac += xstep; |
||
1178 | |||
1179 | value = (unsigned)tilemap[x][y]; |
||
1180 | y += ystep; |
||
1181 | |||
1182 | if (!value) |
||
1183 | continue; |
||
1184 | |||
1185 | if (value<128 || value>256) |
||
1186 | return false; |
||
1187 | |||
1188 | // |
||
1189 | // see if the door is open enough |
||
1190 | // |
||
1191 | value &= ~0x80; |
||
1192 | intercept = xfrac-xstep/2; |
||
1193 | |||
1194 | if (intercept>doorposition[value]) |
||
1195 | return false; |
||
1196 | } while (y != yt2); |
||
1197 | } |
||
1198 | |||
1199 | return true; |
||
1200 | } |
||
1201 | |||
1202 | |||
1203 | /* |
||
1204 | ================ |
||
1205 | = |
||
1206 | = CheckSight |
||
1207 | = |
||
1208 | = Checks a straight line between player and current object |
||
1209 | = |
||
1210 | = If the sight is ok, check alertness and angle to see if they notice |
||
1211 | = |
||
1212 | = returns true if the player has been spoted |
||
1213 | = |
||
1214 | ================ |
||
1215 | */ |
||
1216 | |||
1217 | #define MINSIGHT 0x18000l |
||
1218 | |||
1219 | boolean CheckSight (objtype *ob) |
||
1220 | { |
||
1221 | int32_t deltax,deltay; |
||
1222 | |||
1223 | // |
||
1224 | // don't bother tracing a line if the area isn't connected to the player's |
||
1225 | // |
||
1226 | if (!areabyplayer[ob->areanumber]) |
||
1227 | return false; |
||
1228 | |||
1229 | // |
||
1230 | // if the player is real close, sight is automatic |
||
1231 | // |
||
1232 | deltax = player->x - ob->x; |
||
1233 | deltay = player->y - ob->y; |
||
1234 | |||
1235 | if (deltax > -MINSIGHT && deltax < MINSIGHT |
||
1236 | && deltay > -MINSIGHT && deltay < MINSIGHT) |
||
1237 | return true; |
||
1238 | |||
1239 | // |
||
1240 | // see if they are looking in the right direction |
||
1241 | // |
||
1242 | switch (ob->dir) |
||
1243 | { |
||
1244 | case north: |
||
1245 | if (deltay > 0) |
||
1246 | return false; |
||
1247 | break; |
||
1248 | |||
1249 | case east: |
||
1250 | if (deltax < 0) |
||
1251 | return false; |
||
1252 | break; |
||
1253 | |||
1254 | case south: |
||
1255 | if (deltay < 0) |
||
1256 | return false; |
||
1257 | break; |
||
1258 | |||
1259 | case west: |
||
1260 | if (deltax > 0) |
||
1261 | return false; |
||
1262 | break; |
||
1263 | |||
1264 | // check diagonal moving guards fix |
||
1265 | |||
1266 | case northwest: |
||
1267 | if (DEMOCOND_SDL && deltay > -deltax) |
||
1268 | return false; |
||
1269 | break; |
||
1270 | |||
1271 | case northeast: |
||
1272 | if (DEMOCOND_SDL && deltay > deltax) |
||
1273 | return false; |
||
1274 | break; |
||
1275 | |||
1276 | case southwest: |
||
1277 | if (DEMOCOND_SDL && deltax > deltay) |
||
1278 | return false; |
||
1279 | break; |
||
1280 | |||
1281 | case southeast: |
||
1282 | if (DEMOCOND_SDL && -deltax > deltay) |
||
1283 | return false; |
||
1284 | break; |
||
1285 | } |
||
1286 | |||
1287 | // |
||
1288 | // trace a line to check for blocking tiles (corners) |
||
1289 | // |
||
1290 | return CheckLine (ob); |
||
1291 | } |
||
1292 | |||
1293 | |||
1294 | /* |
||
1295 | =============== |
||
1296 | = |
||
1297 | = FirstSighting |
||
1298 | = |
||
1299 | = Puts an actor into attack mode and possibly reverses the direction |
||
1300 | = if the player is behind it |
||
1301 | = |
||
1302 | =============== |
||
1303 | */ |
||
1304 | |||
1305 | void FirstSighting (objtype *ob) |
||
1306 | { |
||
1307 | // |
||
1308 | // react to the player |
||
1309 | // |
||
1310 | switch (ob->obclass) |
||
1311 | { |
||
1312 | case guardobj: |
||
1313 | PlaySoundLocActor(HALTSND,ob); |
||
1314 | NewState (ob,&s_grdchase1); |
||
1315 | ob->speed *= 3; // go faster when chasing player |
||
1316 | break; |
||
1317 | |||
1318 | case officerobj: |
||
1319 | PlaySoundLocActor(SPIONSND,ob); |
||
1320 | NewState (ob,&s_ofcchase1); |
||
1321 | ob->speed *= 5; // go faster when chasing player |
||
1322 | break; |
||
1323 | |||
1324 | case mutantobj: |
||
1325 | NewState (ob,&s_mutchase1); |
||
1326 | ob->speed *= 3; // go faster when chasing player |
||
1327 | break; |
||
1328 | |||
1329 | case ssobj: |
||
1330 | PlaySoundLocActor(SCHUTZADSND,ob); |
||
1331 | NewState (ob,&s_sschase1); |
||
1332 | ob->speed *= 4; // go faster when chasing player |
||
1333 | break; |
||
1334 | |||
1335 | case dogobj: |
||
1336 | PlaySoundLocActor(DOGBARKSND,ob); |
||
1337 | NewState (ob,&s_dogchase1); |
||
1338 | ob->speed *= 2; // go faster when chasing player |
||
1339 | break; |
||
1340 | |||
1341 | #ifndef SPEAR |
||
1342 | case bossobj: |
||
1343 | SD_PlaySound(GUTENTAGSND); |
||
1344 | NewState (ob,&s_bosschase1); |
||
1345 | ob->speed = SPDPATROL*3; // go faster when chasing player |
||
1346 | break; |
||
1347 | |||
1348 | #ifndef APOGEE_1_0 |
||
1349 | case gretelobj: |
||
1350 | SD_PlaySound(KEINSND); |
||
1351 | NewState (ob,&s_gretelchase1); |
||
1352 | ob->speed *= 3; // go faster when chasing player |
||
1353 | break; |
||
1354 | |||
1355 | case giftobj: |
||
1356 | SD_PlaySound(EINESND); |
||
1357 | NewState (ob,&s_giftchase1); |
||
1358 | ob->speed *= 3; // go faster when chasing player |
||
1359 | break; |
||
1360 | |||
1361 | case fatobj: |
||
1362 | SD_PlaySound(ERLAUBENSND); |
||
1363 | NewState (ob,&s_fatchase1); |
||
1364 | ob->speed *= 3; // go faster when chasing player |
||
1365 | break; |
||
1366 | #endif |
||
1367 | |||
1368 | case schabbobj: |
||
1369 | SD_PlaySound(SCHABBSHASND); |
||
1370 | NewState (ob,&s_schabbchase1); |
||
1371 | ob->speed *= 3; // go faster when chasing player |
||
1372 | break; |
||
1373 | |||
1374 | case fakeobj: |
||
1375 | SD_PlaySound(TOT_HUNDSND); |
||
1376 | NewState (ob,&s_fakechase1); |
||
1377 | ob->speed *= 3; // go faster when chasing player |
||
1378 | break; |
||
1379 | |||
1380 | case mechahitlerobj: |
||
1381 | SD_PlaySound(DIESND); |
||
1382 | NewState (ob,&s_mechachase1); |
||
1383 | ob->speed *= 3; // go faster when chasing player |
||
1384 | break; |
||
1385 | |||
1386 | case realhitlerobj: |
||
1387 | SD_PlaySound(DIESND); |
||
1388 | NewState (ob,&s_hitlerchase1); |
||
1389 | ob->speed *= 5; // go faster when chasing player |
||
1390 | break; |
||
1391 | |||
1392 | case ghostobj: |
||
1393 | NewState (ob,&s_blinkychase1); |
||
1394 | ob->speed *= 2; // go faster when chasing player |
||
1395 | break; |
||
1396 | #else |
||
1397 | case spectreobj: |
||
1398 | SD_PlaySound(GHOSTSIGHTSND); |
||
1399 | NewState (ob,&s_spectrechase1); |
||
1400 | ob->speed = 800; // go faster when chasing player |
||
1401 | break; |
||
1402 | |||
1403 | case angelobj: |
||
1404 | SD_PlaySound(ANGELSIGHTSND); |
||
1405 | NewState (ob,&s_angelchase1); |
||
1406 | ob->speed = 1536; // go faster when chasing player |
||
1407 | break; |
||
1408 | |||
1409 | case transobj: |
||
1410 | SD_PlaySound(TRANSSIGHTSND); |
||
1411 | NewState (ob,&s_transchase1); |
||
1412 | ob->speed = 1536; // go faster when chasing player |
||
1413 | break; |
||
1414 | |||
1415 | case uberobj: |
||
1416 | NewState (ob,&s_uberchase1); |
||
1417 | ob->speed = 3000; // go faster when chasing player |
||
1418 | break; |
||
1419 | |||
1420 | case willobj: |
||
1421 | SD_PlaySound(WILHELMSIGHTSND); |
||
1422 | NewState (ob,&s_willchase1); |
||
1423 | ob->speed = 2048; // go faster when chasing player |
||
1424 | break; |
||
1425 | |||
1426 | case deathobj: |
||
1427 | SD_PlaySound(KNIGHTSIGHTSND); |
||
1428 | NewState (ob,&s_deathchase1); |
||
1429 | ob->speed = 2048; // go faster when chasing player |
||
1430 | break; |
||
1431 | #endif |
||
1432 | } |
||
1433 | |||
1434 | if (ob->distance < 0) |
||
1435 | ob->distance = 0; // ignore the door opening command |
||
1436 | |||
1437 | ob->flags |= FL_ATTACKMODE|FL_FIRSTATTACK; |
||
1438 | } |
||
1439 | |||
1440 | |||
1441 | |||
1442 | /* |
||
1443 | =============== |
||
1444 | = |
||
1445 | = SightPlayer |
||
1446 | = |
||
1447 | = Called by actors that ARE NOT chasing the player. If the player |
||
1448 | = is detected (by sight, noise, or proximity), the actor is put into |
||
1449 | = it's combat frame and true is returned. |
||
1450 | = |
||
1451 | = Incorporates a random reaction delay |
||
1452 | = |
||
1453 | =============== |
||
1454 | */ |
||
1455 | |||
1456 | boolean SightPlayer (objtype *ob) |
||
1457 | { |
||
1458 | if (ob->flags & FL_ATTACKMODE) |
||
1459 | Quit ("An actor in ATTACKMODE called SightPlayer!"); |
||
1460 | |||
1461 | if (ob->temp2) |
||
1462 | { |
||
1463 | // |
||
1464 | // count down reaction time |
||
1465 | // |
||
1466 | ob->temp2 -= (short) tics; |
||
1467 | if (ob->temp2 > 0) |
||
1468 | return false; |
||
1469 | ob->temp2 = 0; // time to react |
||
1470 | } |
||
1471 | else |
||
1472 | { |
||
1473 | if (!areabyplayer[ob->areanumber]) |
||
1474 | return false; |
||
1475 | |||
1476 | if (ob->flags & FL_AMBUSH) |
||
1477 | { |
||
1478 | if (!CheckSight (ob)) |
||
1479 | return false; |
||
1480 | ob->flags &= ~FL_AMBUSH; |
||
1481 | } |
||
1482 | else |
||
1483 | { |
||
1484 | if (!madenoise && !CheckSight (ob)) |
||
1485 | return false; |
||
1486 | } |
||
1487 | |||
1488 | |||
1489 | switch (ob->obclass) |
||
1490 | { |
||
1491 | case guardobj: |
||
1492 | ob->temp2 = 1+US_RndT()/4; |
||
1493 | break; |
||
1494 | case officerobj: |
||
1495 | ob->temp2 = 2; |
||
1496 | break; |
||
1497 | case mutantobj: |
||
1498 | ob->temp2 = 1+US_RndT()/6; |
||
1499 | break; |
||
1500 | case ssobj: |
||
1501 | ob->temp2 = 1+US_RndT()/6; |
||
1502 | break; |
||
1503 | case dogobj: |
||
1504 | ob->temp2 = 1+US_RndT()/8; |
||
1505 | break; |
||
1506 | |||
1507 | case bossobj: |
||
1508 | case schabbobj: |
||
1509 | case fakeobj: |
||
1510 | case mechahitlerobj: |
||
1511 | case realhitlerobj: |
||
1512 | case gretelobj: |
||
1513 | case giftobj: |
||
1514 | case fatobj: |
||
1515 | case spectreobj: |
||
1516 | case angelobj: |
||
1517 | case transobj: |
||
1518 | case uberobj: |
||
1519 | case willobj: |
||
1520 | case deathobj: |
||
1521 | ob->temp2 = 1; |
||
1522 | break; |
||
1523 | } |
||
1524 | return false; |
||
1525 | } |
||
1526 | |||
1527 | FirstSighting (ob); |
||
1528 | |||
1529 | return true; |
||
1530 | }>>>>>128>>8)/deltafrac; |