diff options
author | Franklin Wei <git@fwei.tk> | 2019-07-07 22:00:20 -0400 |
---|---|---|
committer | Franklin Wei <git@fwei.tk> | 2019-07-09 11:20:55 -0400 |
commit | 3f59fc8b771625aca9c3aefe03cf1038d8461963 (patch) | |
tree | e0623a323613baa0b0993411b38bcaed144b27ed /apps/plugins/sdl/progs/wolf3d/wl_agent.c | |
parent | 439a0d1d91fa040d261fc39b87278bc9f5391dcc (diff) | |
download | rockbox-3f59fc8b771625aca9c3aefe03cf1038d8461963.tar.gz rockbox-3f59fc8b771625aca9c3aefe03cf1038d8461963.zip |
Wolfenstein 3-D!
This is a port of Wolf4SDL, which is derived from the original id
software source release. The port runs on top of the SDL plugin
runtime and is loaded as an overlay.
Licensing of the game code is not an issue, as discussed below
(essentially, the Debian project treats Wolf4SDL as GPLv2, with an
email from John Carmack backing it up):
http://forums.rockbox.org/index.php?topic=52872
Included is a copy of MAME's Yamaha OPL sound chip emulator
(fmopl_gpl.c). This file was not part of the original Wolf4SDL source
(which includes a non-GPL'd version), but was rather rebased from from
a later MAME source which had been relicensed to GPLv2.
Change-Id: I64c2ba035e0be7e2f49252f40640641416613439
Diffstat (limited to 'apps/plugins/sdl/progs/wolf3d/wl_agent.c')
-rw-r--r-- | apps/plugins/sdl/progs/wolf3d/wl_agent.c | 1499 |
1 files changed, 1499 insertions, 0 deletions
diff --git a/apps/plugins/sdl/progs/wolf3d/wl_agent.c b/apps/plugins/sdl/progs/wolf3d/wl_agent.c new file mode 100644 index 0000000000..6b9b124a64 --- /dev/null +++ b/apps/plugins/sdl/progs/wolf3d/wl_agent.c | |||
@@ -0,0 +1,1499 @@ | |||
1 | // WL_AGENT.C | ||
2 | |||
3 | #include "wl_def.h" | ||
4 | #pragma hdrstop | ||
5 | |||
6 | /* | ||
7 | ============================================================================= | ||
8 | |||
9 | LOCAL CONSTANTS | ||
10 | |||
11 | ============================================================================= | ||
12 | */ | ||
13 | |||
14 | #define MAXMOUSETURN 10 | ||
15 | |||
16 | |||
17 | #define MOVESCALE 150l | ||
18 | #define BACKMOVESCALE 100l | ||
19 | #define ANGLESCALE 20 | ||
20 | |||
21 | /* | ||
22 | ============================================================================= | ||
23 | |||
24 | GLOBAL VARIABLES | ||
25 | |||
26 | ============================================================================= | ||
27 | */ | ||
28 | |||
29 | |||
30 | |||
31 | // | ||
32 | // player state info | ||
33 | // | ||
34 | int32_t thrustspeed; | ||
35 | |||
36 | word plux,pluy; // player coordinates scaled to unsigned | ||
37 | |||
38 | short anglefrac; | ||
39 | |||
40 | objtype *LastAttacker; | ||
41 | |||
42 | /* | ||
43 | ============================================================================= | ||
44 | |||
45 | LOCAL VARIABLES | ||
46 | |||
47 | ============================================================================= | ||
48 | */ | ||
49 | |||
50 | |||
51 | void T_Player (objtype *ob); | ||
52 | void T_Attack (objtype *ob); | ||
53 | |||
54 | statetype s_player = {false,0,0,(statefunc) T_Player,NULL,NULL}; | ||
55 | statetype s_attack = {false,0,0,(statefunc) T_Attack,NULL,NULL}; | ||
56 | |||
57 | struct atkinf | ||
58 | { | ||
59 | int8_t tics,attack,frame; // attack is 1 for gun, 2 for knife | ||
60 | } attackinfo[4][14] = | ||
61 | { | ||
62 | { {6,0,1},{6,2,2},{6,0,3},{6,-1,4} }, | ||
63 | { {6,0,1},{6,1,2},{6,0,3},{6,-1,4} }, | ||
64 | { {6,0,1},{6,1,2},{6,3,3},{6,-1,4} }, | ||
65 | { {6,0,1},{6,1,2},{6,4,3},{6,-1,4} }, | ||
66 | }; | ||
67 | |||
68 | //=========================================================================== | ||
69 | |||
70 | //---------- | ||
71 | |||
72 | void Attack (void); | ||
73 | void Use (void); | ||
74 | void Search (objtype *ob); | ||
75 | void SelectWeapon (void); | ||
76 | void SelectItem (void); | ||
77 | |||
78 | //---------- | ||
79 | |||
80 | boolean TryMove (objtype *ob); | ||
81 | void T_Player (objtype *ob); | ||
82 | |||
83 | void ClipMove (objtype *ob, int32_t xmove, int32_t ymove); | ||
84 | |||
85 | /* | ||
86 | ============================================================================= | ||
87 | |||
88 | CONTROL STUFF | ||
89 | |||
90 | ============================================================================= | ||
91 | */ | ||
92 | |||
93 | /* | ||
94 | ====================== | ||
95 | = | ||
96 | = CheckWeaponChange | ||
97 | = | ||
98 | = Keys 1-4 change weapons | ||
99 | = | ||
100 | ====================== | ||
101 | */ | ||
102 | |||
103 | void CheckWeaponChange (void) | ||
104 | { | ||
105 | int newWeapon = -1; | ||
106 | |||
107 | if (!gamestate.ammo) // must use knife with no ammo | ||
108 | return; | ||
109 | |||
110 | if(buttonstate[bt_nextweapon] && !buttonheld[bt_nextweapon]) | ||
111 | { | ||
112 | newWeapon = gamestate.weapon + 1; | ||
113 | if(newWeapon > gamestate.bestweapon) newWeapon = 0; | ||
114 | } | ||
115 | else if(buttonstate[bt_prevweapon] && !buttonheld[bt_prevweapon]) | ||
116 | { | ||
117 | newWeapon = gamestate.weapon - 1; | ||
118 | if(newWeapon < 0) newWeapon = gamestate.bestweapon; | ||
119 | } | ||
120 | else | ||
121 | { | ||
122 | for(int i = wp_knife; i <= gamestate.bestweapon; i++) | ||
123 | { | ||
124 | if (buttonstate[bt_readyknife + i - wp_knife]) | ||
125 | { | ||
126 | newWeapon = i; | ||
127 | break; | ||
128 | } | ||
129 | } | ||
130 | } | ||
131 | |||
132 | if(newWeapon != -1) | ||
133 | { | ||
134 | gamestate.weapon = gamestate.chosenweapon = (weapontype) newWeapon; | ||
135 | DrawWeapon(); | ||
136 | } | ||
137 | } | ||
138 | |||
139 | |||
140 | /* | ||
141 | ======================= | ||
142 | = | ||
143 | = ControlMovement | ||
144 | = | ||
145 | = Takes controlx,controly, and buttonstate[bt_strafe] | ||
146 | = | ||
147 | = Changes the player's angle and position | ||
148 | = | ||
149 | = There is an angle hack because when going 70 fps, the roundoff becomes | ||
150 | = significant | ||
151 | = | ||
152 | ======================= | ||
153 | */ | ||
154 | |||
155 | void ControlMovement (objtype *ob) | ||
156 | { | ||
157 | int32_t oldx,oldy; | ||
158 | int angle; | ||
159 | int angleunits; | ||
160 | |||
161 | thrustspeed = 0; | ||
162 | |||
163 | oldx = player->x; | ||
164 | oldy = player->y; | ||
165 | |||
166 | if(buttonstate[bt_strafeleft]) | ||
167 | { | ||
168 | angle = ob->angle + ANGLES/4; | ||
169 | if(angle >= ANGLES) | ||
170 | angle -= ANGLES; | ||
171 | if(buttonstate[bt_run]) | ||
172 | Thrust(angle, RUNMOVE * MOVESCALE * tics); | ||
173 | else | ||
174 | Thrust(angle, BASEMOVE * MOVESCALE * tics); | ||
175 | } | ||
176 | |||
177 | if(buttonstate[bt_straferight]) | ||
178 | { | ||
179 | angle = ob->angle - ANGLES/4; | ||
180 | if(angle < 0) | ||
181 | angle += ANGLES; | ||
182 | if(buttonstate[bt_run]) | ||
183 | Thrust(angle, RUNMOVE * MOVESCALE * tics ); | ||
184 | else | ||
185 | Thrust(angle, BASEMOVE * MOVESCALE * tics); | ||
186 | } | ||
187 | |||
188 | // | ||
189 | // side to side move | ||
190 | // | ||
191 | if (buttonstate[bt_strafe]) | ||
192 | { | ||
193 | // | ||
194 | // strafing | ||
195 | // | ||
196 | // | ||
197 | if (controlx > 0) | ||
198 | { | ||
199 | angle = ob->angle - ANGLES/4; | ||
200 | if (angle < 0) | ||
201 | angle += ANGLES; | ||
202 | Thrust (angle,controlx*MOVESCALE); // move to left | ||
203 | } | ||
204 | else if (controlx < 0) | ||
205 | { | ||
206 | angle = ob->angle + ANGLES/4; | ||
207 | if (angle >= ANGLES) | ||
208 | angle -= ANGLES; | ||
209 | Thrust (angle,-controlx*MOVESCALE); // move to right | ||
210 | } | ||
211 | } | ||
212 | else | ||
213 | { | ||
214 | // | ||
215 | // not strafing | ||
216 | // | ||
217 | anglefrac += controlx; | ||
218 | angleunits = anglefrac/ANGLESCALE; | ||
219 | anglefrac -= angleunits*ANGLESCALE; | ||
220 | ob->angle -= angleunits; | ||
221 | |||
222 | if (ob->angle >= ANGLES) | ||
223 | ob->angle -= ANGLES; | ||
224 | if (ob->angle < 0) | ||
225 | ob->angle += ANGLES; | ||
226 | |||
227 | } | ||
228 | |||
229 | // | ||
230 | // forward/backwards move | ||
231 | // | ||
232 | if (controly < 0) | ||
233 | { | ||
234 | Thrust (ob->angle,-controly*MOVESCALE); // move forwards | ||
235 | } | ||
236 | else if (controly > 0) | ||
237 | { | ||
238 | angle = ob->angle + ANGLES/2; | ||
239 | if (angle >= ANGLES) | ||
240 | angle -= ANGLES; | ||
241 | Thrust (angle,controly*BACKMOVESCALE); // move backwards | ||
242 | } | ||
243 | |||
244 | if (gamestate.victoryflag) // watching the BJ actor | ||
245 | return; | ||
246 | } | ||
247 | |||
248 | /* | ||
249 | ============================================================================= | ||
250 | |||
251 | STATUS WINDOW STUFF | ||
252 | |||
253 | ============================================================================= | ||
254 | */ | ||
255 | |||
256 | |||
257 | /* | ||
258 | ================== | ||
259 | = | ||
260 | = StatusDrawPic | ||
261 | = | ||
262 | ================== | ||
263 | */ | ||
264 | |||
265 | void StatusDrawPic (unsigned x, unsigned y, unsigned picnum) | ||
266 | { | ||
267 | LatchDrawPicScaledCoord ((screenWidth-scaleFactor*320)/16 + scaleFactor*x, | ||
268 | screenHeight-scaleFactor*(STATUSLINES-y),picnum); | ||
269 | } | ||
270 | |||
271 | void StatusDrawFace(unsigned picnum) | ||
272 | { | ||
273 | StatusDrawPic(17, 4, picnum); | ||
274 | |||
275 | #ifdef _arch_dreamcast | ||
276 | DC_StatusDrawLCD(picnum); | ||
277 | #endif | ||
278 | } | ||
279 | |||
280 | |||
281 | /* | ||
282 | ================== | ||
283 | = | ||
284 | = DrawFace | ||
285 | = | ||
286 | ================== | ||
287 | */ | ||
288 | |||
289 | void DrawFace (void) | ||
290 | { | ||
291 | if(viewsize == 21 && ingame) return; | ||
292 | if (SD_SoundPlaying() == GETGATLINGSND) | ||
293 | StatusDrawFace(GOTGATLINGPIC); | ||
294 | else if (gamestate.health) | ||
295 | { | ||
296 | #ifdef SPEAR | ||
297 | if (godmode) | ||
298 | StatusDrawFace(GODMODEFACE1PIC+gamestate.faceframe); | ||
299 | else | ||
300 | #endif | ||
301 | StatusDrawFace(FACE1APIC+3*((100-gamestate.health)/16)+gamestate.faceframe); | ||
302 | } | ||
303 | else | ||
304 | { | ||
305 | #ifndef SPEAR | ||
306 | if (LastAttacker && LastAttacker->obclass == needleobj) | ||
307 | StatusDrawFace(MUTANTBJPIC); | ||
308 | else | ||
309 | #endif | ||
310 | StatusDrawFace(FACE8APIC); | ||
311 | } | ||
312 | } | ||
313 | |||
314 | /* | ||
315 | =============== | ||
316 | = | ||
317 | = UpdateFace | ||
318 | = | ||
319 | = Calls draw face if time to change | ||
320 | = | ||
321 | =============== | ||
322 | */ | ||
323 | |||
324 | int facecount = 0; | ||
325 | int facetimes = 0; | ||
326 | |||
327 | void UpdateFace (void) | ||
328 | { | ||
329 | // don't make demo depend on sound playback | ||
330 | if(demoplayback || demorecord) | ||
331 | { | ||
332 | if(facetimes > 0) | ||
333 | { | ||
334 | facetimes--; | ||
335 | return; | ||
336 | } | ||
337 | } | ||
338 | else if(SD_SoundPlaying() == GETGATLINGSND) | ||
339 | return; | ||
340 | |||
341 | facecount += tics; | ||
342 | if (facecount > US_RndT()) | ||
343 | { | ||
344 | gamestate.faceframe = (US_RndT()>>6); | ||
345 | if (gamestate.faceframe==3) | ||
346 | gamestate.faceframe = 1; | ||
347 | |||
348 | facecount = 0; | ||
349 | DrawFace (); | ||
350 | } | ||
351 | } | ||
352 | |||
353 | |||
354 | |||
355 | /* | ||
356 | =============== | ||
357 | = | ||
358 | = LatchNumber | ||
359 | = | ||
360 | = right justifies and pads with blanks | ||
361 | = | ||
362 | =============== | ||
363 | */ | ||
364 | |||
365 | static void LatchNumber (int x, int y, unsigned width, int32_t number) | ||
366 | { | ||
367 | unsigned length,c; | ||
368 | char str[20]; | ||
369 | |||
370 | ltoa (number,str,10); | ||
371 | |||
372 | length = (unsigned) strlen (str); | ||
373 | |||
374 | while (length<width) | ||
375 | { | ||
376 | StatusDrawPic (x,y,N_BLANKPIC); | ||
377 | x++; | ||
378 | width--; | ||
379 | } | ||
380 | |||
381 | c = length <= width ? 0 : length-width; | ||
382 | |||
383 | while (c<length) | ||
384 | { | ||
385 | StatusDrawPic (x,y,str[c]-'0'+ N_0PIC); | ||
386 | x++; | ||
387 | c++; | ||
388 | } | ||
389 | } | ||
390 | |||
391 | |||
392 | /* | ||
393 | =============== | ||
394 | = | ||
395 | = DrawHealth | ||
396 | = | ||
397 | =============== | ||
398 | */ | ||
399 | |||
400 | void DrawHealth (void) | ||
401 | { | ||
402 | if(viewsize == 21 && ingame) return; | ||
403 | LatchNumber (21,16,3,gamestate.health); | ||
404 | } | ||
405 | |||
406 | |||
407 | /* | ||
408 | =============== | ||
409 | = | ||
410 | = TakeDamage | ||
411 | = | ||
412 | =============== | ||
413 | */ | ||
414 | |||
415 | void TakeDamage (int points,objtype *attacker) | ||
416 | { | ||
417 | LastAttacker = attacker; | ||
418 | |||
419 | if (gamestate.victoryflag) | ||
420 | return; | ||
421 | if (gamestate.difficulty==gd_baby) | ||
422 | points>>=2; | ||
423 | |||
424 | if (!godmode) | ||
425 | gamestate.health -= points; | ||
426 | |||
427 | if (gamestate.health<=0) | ||
428 | { | ||
429 | gamestate.health = 0; | ||
430 | playstate = ex_died; | ||
431 | killerobj = attacker; | ||
432 | } | ||
433 | |||
434 | if (godmode != 2) | ||
435 | StartDamageFlash (points); | ||
436 | |||
437 | DrawHealth (); | ||
438 | DrawFace (); | ||
439 | |||
440 | // | ||
441 | // MAKE BJ'S EYES BUG IF MAJOR DAMAGE! | ||
442 | // | ||
443 | #ifdef SPEAR | ||
444 | if (points > 30 && gamestate.health!=0 && !godmode && viewsize != 21) | ||
445 | { | ||
446 | StatusDrawFace(BJOUCHPIC); | ||
447 | facecount = 0; | ||
448 | } | ||
449 | #endif | ||
450 | } | ||
451 | |||
452 | /* | ||
453 | =============== | ||
454 | = | ||
455 | = HealSelf | ||
456 | = | ||
457 | =============== | ||
458 | */ | ||
459 | |||
460 | void HealSelf (int points) | ||
461 | { | ||
462 | gamestate.health += points; | ||
463 | if (gamestate.health>100) | ||
464 | gamestate.health = 100; | ||
465 | |||
466 | DrawHealth (); | ||
467 | DrawFace (); | ||
468 | } | ||
469 | |||
470 | |||
471 | //=========================================================================== | ||
472 | |||
473 | |||
474 | /* | ||
475 | =============== | ||
476 | = | ||
477 | = DrawLevel | ||
478 | = | ||
479 | =============== | ||
480 | */ | ||
481 | |||
482 | void DrawLevel (void) | ||
483 | { | ||
484 | if(viewsize == 21 && ingame) return; | ||
485 | #ifdef SPEAR | ||
486 | if (gamestate.mapon == 20) | ||
487 | LatchNumber (2,16,2,18); | ||
488 | else | ||
489 | #endif | ||
490 | LatchNumber (2,16,2,gamestate.mapon+1); | ||
491 | } | ||
492 | |||
493 | //=========================================================================== | ||
494 | |||
495 | |||
496 | /* | ||
497 | =============== | ||
498 | = | ||
499 | = DrawLives | ||
500 | = | ||
501 | =============== | ||
502 | */ | ||
503 | |||
504 | void DrawLives (void) | ||
505 | { | ||
506 | if(viewsize == 21 && ingame) return; | ||
507 | LatchNumber (14,16,1,gamestate.lives); | ||
508 | } | ||
509 | |||
510 | |||
511 | /* | ||
512 | =============== | ||
513 | = | ||
514 | = GiveExtraMan | ||
515 | = | ||
516 | =============== | ||
517 | */ | ||
518 | |||
519 | void GiveExtraMan (void) | ||
520 | { | ||
521 | if (gamestate.lives<9) | ||
522 | gamestate.lives++; | ||
523 | DrawLives (); | ||
524 | SD_PlaySound (BONUS1UPSND); | ||
525 | } | ||
526 | |||
527 | //=========================================================================== | ||
528 | |||
529 | /* | ||
530 | =============== | ||
531 | = | ||
532 | = DrawScore | ||
533 | = | ||
534 | =============== | ||
535 | */ | ||
536 | |||
537 | void DrawScore (void) | ||
538 | { | ||
539 | if(viewsize == 21 && ingame) return; | ||
540 | LatchNumber (6,16,6,gamestate.score); | ||
541 | } | ||
542 | |||
543 | /* | ||
544 | =============== | ||
545 | = | ||
546 | = GivePoints | ||
547 | = | ||
548 | =============== | ||
549 | */ | ||
550 | |||
551 | void GivePoints (int32_t points) | ||
552 | { | ||
553 | gamestate.score += points; | ||
554 | while (gamestate.score >= gamestate.nextextra) | ||
555 | { | ||
556 | gamestate.nextextra += EXTRAPOINTS; | ||
557 | GiveExtraMan (); | ||
558 | } | ||
559 | DrawScore (); | ||
560 | } | ||
561 | |||
562 | //=========================================================================== | ||
563 | |||
564 | /* | ||
565 | ================== | ||
566 | = | ||
567 | = DrawWeapon | ||
568 | = | ||
569 | ================== | ||
570 | */ | ||
571 | |||
572 | void DrawWeapon (void) | ||
573 | { | ||
574 | if(viewsize == 21 && ingame) return; | ||
575 | StatusDrawPic (32,8,KNIFEPIC+gamestate.weapon); | ||
576 | } | ||
577 | |||
578 | |||
579 | /* | ||
580 | ================== | ||
581 | = | ||
582 | = DrawKeys | ||
583 | = | ||
584 | ================== | ||
585 | */ | ||
586 | |||
587 | void DrawKeys (void) | ||
588 | { | ||
589 | if(viewsize == 21 && ingame) return; | ||
590 | if (gamestate.keys & 1) | ||
591 | StatusDrawPic (30,4,GOLDKEYPIC); | ||
592 | else | ||
593 | StatusDrawPic (30,4,NOKEYPIC); | ||
594 | |||
595 | if (gamestate.keys & 2) | ||
596 | StatusDrawPic (30,20,SILVERKEYPIC); | ||
597 | else | ||
598 | StatusDrawPic (30,20,NOKEYPIC); | ||
599 | } | ||
600 | |||
601 | /* | ||
602 | ================== | ||
603 | = | ||
604 | = GiveWeapon | ||
605 | = | ||
606 | ================== | ||
607 | */ | ||
608 | |||
609 | void GiveWeapon (int weapon) | ||
610 | { | ||
611 | GiveAmmo (6); | ||
612 | |||
613 | if (gamestate.bestweapon<weapon) | ||
614 | gamestate.bestweapon = gamestate.weapon | ||
615 | = gamestate.chosenweapon = (weapontype) weapon; | ||
616 | |||
617 | DrawWeapon (); | ||
618 | } | ||
619 | |||
620 | //=========================================================================== | ||
621 | |||
622 | /* | ||
623 | =============== | ||
624 | = | ||
625 | = DrawAmmo | ||
626 | = | ||
627 | =============== | ||
628 | */ | ||
629 | |||
630 | void DrawAmmo (void) | ||
631 | { | ||
632 | if(viewsize == 21 && ingame) return; | ||
633 | LatchNumber (27,16,2,gamestate.ammo); | ||
634 | } | ||
635 | |||
636 | /* | ||
637 | =============== | ||
638 | = | ||
639 | = GiveAmmo | ||
640 | = | ||
641 | =============== | ||
642 | */ | ||
643 | |||
644 | void GiveAmmo (int ammo) | ||
645 | { | ||
646 | if (!gamestate.ammo) // knife was out | ||
647 | { | ||
648 | if (!gamestate.attackframe) | ||
649 | { | ||
650 | gamestate.weapon = gamestate.chosenweapon; | ||
651 | DrawWeapon (); | ||
652 | } | ||
653 | } | ||
654 | gamestate.ammo += ammo; | ||
655 | if (gamestate.ammo > 99) | ||
656 | gamestate.ammo = 99; | ||
657 | DrawAmmo (); | ||
658 | } | ||
659 | |||
660 | //=========================================================================== | ||
661 | |||
662 | /* | ||
663 | ================== | ||
664 | = | ||
665 | = GiveKey | ||
666 | = | ||
667 | ================== | ||
668 | */ | ||
669 | |||
670 | void GiveKey (int key) | ||
671 | { | ||
672 | gamestate.keys |= (1<<key); | ||
673 | DrawKeys (); | ||
674 | } | ||
675 | |||
676 | |||
677 | |||
678 | /* | ||
679 | ============================================================================= | ||
680 | |||
681 | MOVEMENT | ||
682 | |||
683 | ============================================================================= | ||
684 | */ | ||
685 | |||
686 | |||
687 | /* | ||
688 | =================== | ||
689 | = | ||
690 | = GetBonus | ||
691 | = | ||
692 | =================== | ||
693 | */ | ||
694 | void GetBonus (statobj_t *check) | ||
695 | { | ||
696 | switch (check->itemnumber) | ||
697 | { | ||
698 | case bo_firstaid: | ||
699 | if (gamestate.health == 100) | ||
700 | return; | ||
701 | |||
702 | SD_PlaySound (HEALTH2SND); | ||
703 | HealSelf (25); | ||
704 | break; | ||
705 | |||
706 | case bo_key1: | ||
707 | case bo_key2: | ||
708 | case bo_key3: | ||
709 | case bo_key4: | ||
710 | GiveKey (check->itemnumber - bo_key1); | ||
711 | SD_PlaySound (GETKEYSND); | ||
712 | break; | ||
713 | |||
714 | case bo_cross: | ||
715 | SD_PlaySound (BONUS1SND); | ||
716 | GivePoints (100); | ||
717 | gamestate.treasurecount++; | ||
718 | break; | ||
719 | case bo_chalice: | ||
720 | SD_PlaySound (BONUS2SND); | ||
721 | GivePoints (500); | ||
722 | gamestate.treasurecount++; | ||
723 | break; | ||
724 | case bo_bible: | ||
725 | SD_PlaySound (BONUS3SND); | ||
726 | GivePoints (1000); | ||
727 | gamestate.treasurecount++; | ||
728 | break; | ||
729 | case bo_crown: | ||
730 | SD_PlaySound (BONUS4SND); | ||
731 | GivePoints (5000); | ||
732 | gamestate.treasurecount++; | ||
733 | break; | ||
734 | |||
735 | case bo_clip: | ||
736 | if (gamestate.ammo == 99) | ||
737 | return; | ||
738 | |||
739 | SD_PlaySound (GETAMMOSND); | ||
740 | GiveAmmo (8); | ||
741 | break; | ||
742 | case bo_clip2: | ||
743 | if (gamestate.ammo == 99) | ||
744 | return; | ||
745 | |||
746 | SD_PlaySound (GETAMMOSND); | ||
747 | GiveAmmo (4); | ||
748 | break; | ||
749 | |||
750 | #ifdef SPEAR | ||
751 | case bo_25clip: | ||
752 | if (gamestate.ammo == 99) | ||
753 | return; | ||
754 | |||
755 | SD_PlaySound (GETAMMOBOXSND); | ||
756 | GiveAmmo (25); | ||
757 | break; | ||
758 | #endif | ||
759 | |||
760 | case bo_machinegun: | ||
761 | SD_PlaySound (GETMACHINESND); | ||
762 | GiveWeapon (wp_machinegun); | ||
763 | break; | ||
764 | case bo_chaingun: | ||
765 | SD_PlaySound (GETGATLINGSND); | ||
766 | facetimes = 38; | ||
767 | GiveWeapon (wp_chaingun); | ||
768 | |||
769 | if(viewsize != 21) | ||
770 | StatusDrawFace (GOTGATLINGPIC); | ||
771 | facecount = 0; | ||
772 | break; | ||
773 | |||
774 | case bo_fullheal: | ||
775 | SD_PlaySound (BONUS1UPSND); | ||
776 | HealSelf (99); | ||
777 | GiveAmmo (25); | ||
778 | GiveExtraMan (); | ||
779 | gamestate.treasurecount++; | ||
780 | break; | ||
781 | |||
782 | case bo_food: | ||
783 | if (gamestate.health == 100) | ||
784 | return; | ||
785 | |||
786 | SD_PlaySound (HEALTH1SND); | ||
787 | HealSelf (10); | ||
788 | break; | ||
789 | |||
790 | case bo_alpo: | ||
791 | if (gamestate.health == 100) | ||
792 | return; | ||
793 | |||
794 | SD_PlaySound (HEALTH1SND); | ||
795 | HealSelf (4); | ||
796 | break; | ||
797 | |||
798 | case bo_gibs: | ||
799 | if (gamestate.health >10) | ||
800 | return; | ||
801 | |||
802 | SD_PlaySound (SLURPIESND); | ||
803 | HealSelf (1); | ||
804 | break; | ||
805 | |||
806 | #ifdef SPEAR | ||
807 | case bo_spear: | ||
808 | spearflag = true; | ||
809 | spearx = player->x; | ||
810 | speary = player->y; | ||
811 | spearangle = player->angle; | ||
812 | playstate = ex_completed; | ||
813 | #endif | ||
814 | } | ||
815 | |||
816 | StartBonusFlash (); | ||
817 | check->shapenum = -1; // remove from list | ||
818 | } | ||
819 | |||
820 | /* | ||
821 | =================== | ||
822 | = | ||
823 | = TryMove | ||
824 | = | ||
825 | = returns true if move ok | ||
826 | = debug: use pointers to optimize | ||
827 | =================== | ||
828 | */ | ||
829 | |||
830 | boolean TryMove (objtype *ob) | ||
831 | { | ||
832 | int xl,yl,xh,yh,x,y; | ||
833 | objtype *check; | ||
834 | int32_t deltax,deltay; | ||
835 | |||
836 | xl = (ob->x-PLAYERSIZE) >>TILESHIFT; | ||
837 | yl = (ob->y-PLAYERSIZE) >>TILESHIFT; | ||
838 | |||
839 | xh = (ob->x+PLAYERSIZE) >>TILESHIFT; | ||
840 | yh = (ob->y+PLAYERSIZE) >>TILESHIFT; | ||
841 | |||
842 | #define PUSHWALLMINDIST PLAYERSIZE | ||
843 | |||
844 | // | ||
845 | // check for solid walls | ||
846 | // | ||
847 | for (y=yl;y<=yh;y++) | ||
848 | { | ||
849 | for (x=xl;x<=xh;x++) | ||
850 | { | ||
851 | check = actorat[x][y]; | ||
852 | if (check && !ISPOINTER(check)) | ||
853 | { | ||
854 | if(tilemap[x][y]==64 && x==pwallx && y==pwally) // back of moving pushwall? | ||
855 | { | ||
856 | switch(pwalldir) | ||
857 | { | ||
858 | case di_north: | ||
859 | if(ob->y-PUSHWALLMINDIST<=(pwally<<TILESHIFT)+((63-pwallpos)<<10)) | ||
860 | return false; | ||
861 | break; | ||
862 | case di_west: | ||
863 | if(ob->x-PUSHWALLMINDIST<=(pwallx<<TILESHIFT)+((63-pwallpos)<<10)) | ||
864 | return false; | ||
865 | break; | ||
866 | case di_east: | ||
867 | if(ob->x+PUSHWALLMINDIST>=(pwallx<<TILESHIFT)+(pwallpos<<10)) | ||
868 | return false; | ||
869 | break; | ||
870 | case di_south: | ||
871 | if(ob->y+PUSHWALLMINDIST>=(pwally<<TILESHIFT)+(pwallpos<<10)) | ||
872 | return false; | ||
873 | break; | ||
874 | } | ||
875 | } | ||
876 | else return false; | ||
877 | } | ||
878 | } | ||
879 | } | ||
880 | |||
881 | // | ||
882 | // check for actors | ||
883 | // | ||
884 | if (yl>0) | ||
885 | yl--; | ||
886 | if (yh<MAPSIZE-1) | ||
887 | yh++; | ||
888 | if (xl>0) | ||
889 | xl--; | ||
890 | if (xh<MAPSIZE-1) | ||
891 | xh++; | ||
892 | |||
893 | for (y=yl;y<=yh;y++) | ||
894 | { | ||
895 | for (x=xl;x<=xh;x++) | ||
896 | { | ||
897 | check = actorat[x][y]; | ||
898 | if (ISPOINTER(check) && check != player && (check->flags & FL_SHOOTABLE) ) | ||
899 | { | ||
900 | deltax = ob->x - check->x; | ||
901 | if (deltax < -MINACTORDIST || deltax > MINACTORDIST) | ||
902 | continue; | ||
903 | deltay = ob->y - check->y; | ||
904 | if (deltay < -MINACTORDIST || deltay > MINACTORDIST) | ||
905 | continue; | ||
906 | |||
907 | return false; | ||
908 | } | ||
909 | } | ||
910 | } | ||
911 | |||
912 | return true; | ||
913 | } | ||
914 | |||
915 | |||
916 | /* | ||
917 | =================== | ||
918 | = | ||
919 | = ClipMove | ||
920 | = | ||
921 | =================== | ||
922 | */ | ||
923 | |||
924 | void ClipMove (objtype *ob, int32_t xmove, int32_t ymove) | ||
925 | { | ||
926 | int32_t basex,basey; | ||
927 | |||
928 | basex = ob->x; | ||
929 | basey = ob->y; | ||
930 | |||
931 | ob->x = basex+xmove; | ||
932 | ob->y = basey+ymove; | ||
933 | if (TryMove (ob)) | ||
934 | return; | ||
935 | |||
936 | #ifndef REMDEBUG | ||
937 | if (noclip && ob->x > 2*TILEGLOBAL && ob->y > 2*TILEGLOBAL | ||
938 | && ob->x < (((int32_t)(mapwidth-1))<<TILESHIFT) | ||
939 | && ob->y < (((int32_t)(mapheight-1))<<TILESHIFT) ) | ||
940 | return; // walk through walls | ||
941 | #endif | ||
942 | |||
943 | if (!SD_SoundPlaying()) | ||
944 | SD_PlaySound (HITWALLSND); | ||
945 | |||
946 | ob->x = basex+xmove; | ||
947 | ob->y = basey; | ||
948 | if (TryMove (ob)) | ||
949 | return; | ||
950 | |||
951 | ob->x = basex; | ||
952 | ob->y = basey+ymove; | ||
953 | if (TryMove (ob)) | ||
954 | return; | ||
955 | |||
956 | ob->x = basex; | ||
957 | ob->y = basey; | ||
958 | } | ||
959 | |||
960 | //========================================================================== | ||
961 | |||
962 | /* | ||
963 | =================== | ||
964 | = | ||
965 | = VictoryTile | ||
966 | = | ||
967 | =================== | ||
968 | */ | ||
969 | |||
970 | void VictoryTile (void) | ||
971 | { | ||
972 | #ifndef SPEAR | ||
973 | SpawnBJVictory (); | ||
974 | #endif | ||
975 | |||
976 | gamestate.victoryflag = true; | ||
977 | } | ||
978 | |||
979 | /* | ||
980 | =================== | ||
981 | = | ||
982 | = Thrust | ||
983 | = | ||
984 | =================== | ||
985 | */ | ||
986 | |||
987 | // For player movement in demos exactly as in the original Wolf3D v1.4 source code | ||
988 | static fixed FixedByFracOrig(fixed a, fixed b) | ||
989 | { | ||
990 | int sign = 0; | ||
991 | if(b == 65536) b = 65535; | ||
992 | else if(b == -65536) b = 65535, sign = 1; | ||
993 | else if(b < 0) b = (-b), sign = 1; | ||
994 | |||
995 | if(a < 0) | ||
996 | { | ||
997 | a = -a; | ||
998 | sign = !sign; | ||
999 | } | ||
1000 | fixed res = (fixed)(((int64_t) a * b) >> 16); | ||
1001 | if(sign) | ||
1002 | res = -res; | ||
1003 | return res; | ||
1004 | } | ||
1005 | |||
1006 | void Thrust (int angle, int32_t speed) | ||
1007 | { | ||
1008 | int32_t xmove,ymove; | ||
1009 | unsigned offset; | ||
1010 | |||
1011 | |||
1012 | // | ||
1013 | // ZERO FUNNY COUNTER IF MOVED! | ||
1014 | // | ||
1015 | #ifdef SPEAR | ||
1016 | if (speed) | ||
1017 | funnyticount = 0; | ||
1018 | #endif | ||
1019 | |||
1020 | thrustspeed += speed; | ||
1021 | // | ||
1022 | // moving bounds speed | ||
1023 | // | ||
1024 | if (speed >= MINDIST*2) | ||
1025 | speed = MINDIST*2-1; | ||
1026 | |||
1027 | xmove = DEMOCHOOSE_ORIG_SDL( | ||
1028 | FixedByFracOrig(speed, costable[angle]), | ||
1029 | FixedMul(speed,costable[angle])); | ||
1030 | ymove = DEMOCHOOSE_ORIG_SDL( | ||
1031 | -FixedByFracOrig(speed, sintable[angle]), | ||
1032 | -FixedMul(speed,sintable[angle])); | ||
1033 | |||
1034 | ClipMove(player,xmove,ymove); | ||
1035 | |||
1036 | player->tilex = (short)(player->x >> TILESHIFT); // scale to tile values | ||
1037 | player->tiley = (short)(player->y >> TILESHIFT); | ||
1038 | |||
1039 | offset = (player->tiley<<mapshift)+player->tilex; | ||
1040 | player->areanumber = *(mapsegs[0] + offset) -AREATILE; | ||
1041 | |||
1042 | if (*(mapsegs[1] + offset) == EXITTILE) | ||
1043 | VictoryTile (); | ||
1044 | } | ||
1045 | |||
1046 | |||
1047 | /* | ||
1048 | ============================================================================= | ||
1049 | |||
1050 | ACTIONS | ||
1051 | |||
1052 | ============================================================================= | ||
1053 | */ | ||
1054 | |||
1055 | |||
1056 | /* | ||
1057 | =============== | ||
1058 | = | ||
1059 | = Cmd_Fire | ||
1060 | = | ||
1061 | =============== | ||
1062 | */ | ||
1063 | |||
1064 | void Cmd_Fire (void) | ||
1065 | { | ||
1066 | buttonheld[bt_attack] = true; | ||
1067 | |||
1068 | gamestate.weaponframe = 0; | ||
1069 | |||
1070 | player->state = &s_attack; | ||
1071 | |||
1072 | gamestate.attackframe = 0; | ||
1073 | gamestate.attackcount = | ||
1074 | attackinfo[gamestate.weapon][gamestate.attackframe].tics; | ||
1075 | gamestate.weaponframe = | ||
1076 | attackinfo[gamestate.weapon][gamestate.attackframe].frame; | ||
1077 | } | ||
1078 | |||
1079 | //=========================================================================== | ||
1080 | |||
1081 | /* | ||
1082 | =============== | ||
1083 | = | ||
1084 | = Cmd_Use | ||
1085 | = | ||
1086 | =============== | ||
1087 | */ | ||
1088 | |||
1089 | void Cmd_Use (void) | ||
1090 | { | ||
1091 | int checkx,checky,doornum,dir; | ||
1092 | boolean elevatorok; | ||
1093 | |||
1094 | // | ||
1095 | // find which cardinal direction the player is facing | ||
1096 | // | ||
1097 | if (player->angle < ANGLES/8 || player->angle > 7*ANGLES/8) | ||
1098 | { | ||
1099 | checkx = player->tilex + 1; | ||
1100 | checky = player->tiley; | ||
1101 | dir = di_east; | ||
1102 | elevatorok = true; | ||
1103 | } | ||
1104 | else if (player->angle < 3*ANGLES/8) | ||
1105 | { | ||
1106 | checkx = player->tilex; | ||
1107 | checky = player->tiley-1; | ||
1108 | dir = di_north; | ||
1109 | elevatorok = false; | ||
1110 | } | ||
1111 | else if (player->angle < 5*ANGLES/8) | ||
1112 | { | ||
1113 | checkx = player->tilex - 1; | ||
1114 | checky = player->tiley; | ||
1115 | dir = di_west; | ||
1116 | elevatorok = true; | ||
1117 | } | ||
1118 | else | ||
1119 | { | ||
1120 | checkx = player->tilex; | ||
1121 | checky = player->tiley + 1; | ||
1122 | dir = di_south; | ||
1123 | elevatorok = false; | ||
1124 | } | ||
1125 | |||
1126 | doornum = tilemap[checkx][checky]; | ||
1127 | if (*(mapsegs[1]+(checky<<mapshift)+checkx) == PUSHABLETILE) | ||
1128 | { | ||
1129 | // | ||
1130 | // pushable wall | ||
1131 | // | ||
1132 | |||
1133 | buttonheld[bt_use] = true; | ||
1134 | buttonstate[bt_attack] = false; | ||
1135 | |||
1136 | PushWall (checkx,checky,dir); | ||
1137 | return; | ||
1138 | } | ||
1139 | if (!buttonheld[bt_use] && doornum == ELEVATORTILE && elevatorok) | ||
1140 | { | ||
1141 | // | ||
1142 | // use elevator | ||
1143 | // | ||
1144 | buttonheld[bt_use] = true; | ||
1145 | buttonstate[bt_attack] = false; | ||
1146 | |||
1147 | tilemap[checkx][checky]++; // flip switch | ||
1148 | if (*(mapsegs[0]+(player->tiley<<mapshift)+player->tilex) == ALTELEVATORTILE) | ||
1149 | playstate = ex_secretlevel; | ||
1150 | else | ||
1151 | playstate = ex_completed; | ||
1152 | SD_PlaySound (LEVELDONESND); | ||
1153 | SD_WaitSoundDone(); | ||
1154 | } | ||
1155 | else if (!buttonheld[bt_use] && doornum & 0x80) | ||
1156 | { | ||
1157 | buttonheld[bt_use] = true; | ||
1158 | buttonstate[bt_attack] = false; | ||
1159 | OperateDoor (doornum & ~0x80); | ||
1160 | } | ||
1161 | else | ||
1162 | SD_PlaySound (DONOTHINGSND); | ||
1163 | } | ||
1164 | |||
1165 | /* | ||
1166 | ============================================================================= | ||
1167 | |||
1168 | PLAYER CONTROL | ||
1169 | |||
1170 | ============================================================================= | ||
1171 | */ | ||
1172 | |||
1173 | |||
1174 | |||
1175 | /* | ||
1176 | =============== | ||
1177 | = | ||
1178 | = SpawnPlayer | ||
1179 | = | ||
1180 | =============== | ||
1181 | */ | ||
1182 | |||
1183 | void SpawnPlayer (int tilex, int tiley, int dir) | ||
1184 | { | ||
1185 | player->obclass = playerobj; | ||
1186 | player->active = ac_yes; | ||
1187 | player->tilex = tilex; | ||
1188 | player->tiley = tiley; | ||
1189 | player->areanumber = (byte) *(mapsegs[0]+(player->tiley<<mapshift)+player->tilex); | ||
1190 | player->x = ((int32_t)tilex<<TILESHIFT)+TILEGLOBAL/2; | ||
1191 | player->y = ((int32_t)tiley<<TILESHIFT)+TILEGLOBAL/2; | ||
1192 | player->state = &s_player; | ||
1193 | player->angle = (1-dir)*90; | ||
1194 | if (player->angle<0) | ||
1195 | player->angle += ANGLES; | ||
1196 | player->flags = FL_NEVERMARK; | ||
1197 | Thrust (0,0); // set some variables | ||
1198 | |||
1199 | InitAreas (); | ||
1200 | } | ||
1201 | |||
1202 | |||
1203 | //=========================================================================== | ||
1204 | |||
1205 | /* | ||
1206 | =============== | ||
1207 | = | ||
1208 | = T_KnifeAttack | ||
1209 | = | ||
1210 | = Update player hands, and try to do damage when the proper frame is reached | ||
1211 | = | ||
1212 | =============== | ||
1213 | */ | ||
1214 | |||
1215 | void KnifeAttack (objtype *ob) | ||
1216 | { | ||
1217 | objtype *check,*closest; | ||
1218 | int32_t dist; | ||
1219 | |||
1220 | SD_PlaySound (ATKKNIFESND); | ||
1221 | // actually fire | ||
1222 | dist = 0x7fffffff; | ||
1223 | closest = NULL; | ||
1224 | for (check=ob->next; check; check=check->next) | ||
1225 | { | ||
1226 | if ( (check->flags & FL_SHOOTABLE) && (check->flags & FL_VISABLE) | ||
1227 | && abs(check->viewx-centerx) < shootdelta) | ||
1228 | { | ||
1229 | if (check->transx < dist) | ||
1230 | { | ||
1231 | dist = check->transx; | ||
1232 | closest = check; | ||
1233 | } | ||
1234 | } | ||
1235 | } | ||
1236 | |||
1237 | if (!closest || dist > 0x18000l) | ||
1238 | { | ||
1239 | // missed | ||
1240 | return; | ||
1241 | } | ||
1242 | |||
1243 | // hit something | ||
1244 | DamageActor (closest,US_RndT() >> 4); | ||
1245 | } | ||
1246 | |||
1247 | |||
1248 | |||
1249 | void GunAttack (objtype *ob) | ||
1250 | { | ||
1251 | objtype *check,*closest,*oldclosest; | ||
1252 | int damage; | ||
1253 | int dx,dy,dist; | ||
1254 | int32_t viewdist; | ||
1255 | |||
1256 | switch (gamestate.weapon) | ||
1257 | { | ||
1258 | case wp_pistol: | ||
1259 | SD_PlaySound (ATKPISTOLSND); | ||
1260 | break; | ||
1261 | case wp_machinegun: | ||
1262 | SD_PlaySound (ATKMACHINEGUNSND); | ||
1263 | break; | ||
1264 | case wp_chaingun: | ||
1265 | SD_PlaySound (ATKGATLINGSND); | ||
1266 | break; | ||
1267 | } | ||
1268 | |||
1269 | madenoise = true; | ||
1270 | |||
1271 | // | ||
1272 | // find potential targets | ||
1273 | // | ||
1274 | viewdist = 0x7fffffffl; | ||
1275 | closest = NULL; | ||
1276 | |||
1277 | while (1) | ||
1278 | { | ||
1279 | oldclosest = closest; | ||
1280 | |||
1281 | for (check=ob->next ; check ; check=check->next) | ||
1282 | { | ||
1283 | if ((check->flags & FL_SHOOTABLE) && (check->flags & FL_VISABLE) | ||
1284 | && abs(check->viewx-centerx) < shootdelta) | ||
1285 | { | ||
1286 | if (check->transx < viewdist) | ||
1287 | { | ||
1288 | viewdist = check->transx; | ||
1289 | closest = check; | ||
1290 | } | ||
1291 | } | ||
1292 | } | ||
1293 | |||
1294 | if (closest == oldclosest) | ||
1295 | return; // no more targets, all missed | ||
1296 | |||
1297 | // | ||
1298 | // trace a line from player to enemey | ||
1299 | // | ||
1300 | if (CheckLine(closest)) | ||
1301 | break; | ||
1302 | } | ||
1303 | |||
1304 | // | ||
1305 | // hit something | ||
1306 | // | ||
1307 | dx = ABS(closest->tilex - player->tilex); | ||
1308 | dy = ABS(closest->tiley - player->tiley); | ||
1309 | dist = dx>dy ? dx:dy; | ||
1310 | if (dist<2) | ||
1311 | damage = US_RndT() / 4; | ||
1312 | else if (dist<4) | ||
1313 | damage = US_RndT() / 6; | ||
1314 | else | ||
1315 | { | ||
1316 | if ( (US_RndT() / 12) < dist) // missed | ||
1317 | return; | ||
1318 | damage = US_RndT() / 6; | ||
1319 | } | ||
1320 | DamageActor (closest,damage); | ||
1321 | } | ||
1322 | |||
1323 | //=========================================================================== | ||
1324 | |||
1325 | /* | ||
1326 | =============== | ||
1327 | = | ||
1328 | = VictorySpin | ||
1329 | = | ||
1330 | =============== | ||
1331 | */ | ||
1332 | |||
1333 | void VictorySpin (void) | ||
1334 | { | ||
1335 | int32_t desty; | ||
1336 | |||
1337 | if (player->angle > 270) | ||
1338 | { | ||
1339 | player->angle -= (short)(tics * 3); | ||
1340 | if (player->angle < 270) | ||
1341 | player->angle = 270; | ||
1342 | } | ||
1343 | else if (player->angle < 270) | ||
1344 | { | ||
1345 | player->angle += (short)(tics * 3); | ||
1346 | if (player->angle > 270) | ||
1347 | player->angle = 270; | ||
1348 | } | ||
1349 | |||
1350 | desty = (((int32_t)player->tiley-5)<<TILESHIFT)-0x3000; | ||
1351 | |||
1352 | if (player->y > desty) | ||
1353 | { | ||
1354 | player->y -= tics*4096; | ||
1355 | if (player->y < desty) | ||
1356 | player->y = desty; | ||
1357 | } | ||
1358 | } | ||
1359 | |||
1360 | |||
1361 | //=========================================================================== | ||
1362 | |||
1363 | /* | ||
1364 | =============== | ||
1365 | = | ||
1366 | = T_Attack | ||
1367 | = | ||
1368 | =============== | ||
1369 | */ | ||
1370 | |||
1371 | void T_Attack (objtype *ob) | ||
1372 | { | ||
1373 | struct atkinf *cur; | ||
1374 | |||
1375 | UpdateFace (); | ||
1376 | |||
1377 | if (gamestate.victoryflag) // watching the BJ actor | ||
1378 | { | ||
1379 | VictorySpin (); | ||
1380 | return; | ||
1381 | } | ||
1382 | |||
1383 | if ( buttonstate[bt_use] && !buttonheld[bt_use] ) | ||
1384 | buttonstate[bt_use] = false; | ||
1385 | |||
1386 | if ( buttonstate[bt_attack] && !buttonheld[bt_attack]) | ||
1387 | buttonstate[bt_attack] = false; | ||
1388 | |||
1389 | ControlMovement (ob); | ||
1390 | if (gamestate.victoryflag) // watching the BJ actor | ||
1391 | return; | ||
1392 | |||
1393 | plux = (word) (player->x >> UNSIGNEDSHIFT); // scale to fit in unsigned | ||
1394 | pluy = (word) (player->y >> UNSIGNEDSHIFT); | ||
1395 | player->tilex = (short)(player->x >> TILESHIFT); // scale to tile values | ||
1396 | player->tiley = (short)(player->y >> TILESHIFT); | ||
1397 | |||
1398 | // | ||
1399 | // change frame and fire | ||
1400 | // | ||
1401 | gamestate.attackcount -= (short) tics; | ||
1402 | while (gamestate.attackcount <= 0) | ||
1403 | { | ||
1404 | cur = &attackinfo[gamestate.weapon][gamestate.attackframe]; | ||
1405 | switch (cur->attack) | ||
1406 | { | ||
1407 | case -1: | ||
1408 | ob->state = &s_player; | ||
1409 | if (!gamestate.ammo) | ||
1410 | { | ||
1411 | gamestate.weapon = wp_knife; | ||
1412 | DrawWeapon (); | ||
1413 | } | ||
1414 | else | ||
1415 | { | ||
1416 | if (gamestate.weapon != gamestate.chosenweapon) | ||
1417 | { | ||
1418 | gamestate.weapon = gamestate.chosenweapon; | ||
1419 | DrawWeapon (); | ||
1420 | } | ||
1421 | } | ||
1422 | gamestate.attackframe = gamestate.weaponframe = 0; | ||
1423 | return; | ||
1424 | |||
1425 | case 4: | ||
1426 | if (!gamestate.ammo) | ||
1427 | break; | ||
1428 | if (buttonstate[bt_attack]) | ||
1429 | gamestate.attackframe -= 2; | ||
1430 | case 1: | ||
1431 | if (!gamestate.ammo) | ||
1432 | { // can only happen with chain gun | ||
1433 | gamestate.attackframe++; | ||
1434 | break; | ||
1435 | } | ||
1436 | GunAttack (ob); | ||
1437 | if (!ammocheat) | ||
1438 | gamestate.ammo--; | ||
1439 | DrawAmmo (); | ||
1440 | break; | ||
1441 | |||
1442 | case 2: | ||
1443 | KnifeAttack (ob); | ||
1444 | break; | ||
1445 | |||
1446 | case 3: | ||
1447 | if (gamestate.ammo && buttonstate[bt_attack]) | ||
1448 | gamestate.attackframe -= 2; | ||
1449 | break; | ||
1450 | } | ||
1451 | |||
1452 | gamestate.attackcount += cur->tics; | ||
1453 | gamestate.attackframe++; | ||
1454 | gamestate.weaponframe = | ||
1455 | attackinfo[gamestate.weapon][gamestate.attackframe].frame; | ||
1456 | } | ||
1457 | } | ||
1458 | |||
1459 | |||
1460 | |||
1461 | //=========================================================================== | ||
1462 | |||
1463 | /* | ||
1464 | =============== | ||
1465 | = | ||
1466 | = T_Player | ||
1467 | = | ||
1468 | =============== | ||
1469 | */ | ||
1470 | |||
1471 | static int last_use = 0; | ||
1472 | |||
1473 | void T_Player (objtype *ob) | ||
1474 | { | ||
1475 | if (gamestate.victoryflag) // watching the BJ actor | ||
1476 | { | ||
1477 | VictorySpin (); | ||
1478 | return; | ||
1479 | } | ||
1480 | |||
1481 | UpdateFace (); | ||
1482 | CheckWeaponChange (); | ||
1483 | |||
1484 | // weird | ||
1485 | if( buttonstate[bt_attack] ) | ||
1486 | Cmd_Use (); | ||
1487 | |||
1488 | if ( buttonstate[bt_attack] && !buttonheld[bt_attack]) | ||
1489 | Cmd_Fire (); | ||
1490 | |||
1491 | ControlMovement (ob); | ||
1492 | if (gamestate.victoryflag) // watching the BJ actor | ||
1493 | return; | ||
1494 | |||
1495 | plux = (word) (player->x >> UNSIGNEDSHIFT); // scale to fit in unsigned | ||
1496 | pluy = (word) (player->y >> UNSIGNEDSHIFT); | ||
1497 | player->tilex = (short)(player->x >> TILESHIFT); // scale to tile values | ||
1498 | player->tiley = (short)(player->y >> TILESHIFT); | ||
1499 | } | ||