1 /*
2 Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13 See the GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19 */
20
21 #ifdef DOS
22 #include <dos.h>
23 #endif
24
25 #include <string.h>
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <stdarg.h>
29
30 #include "rt_def.h"
31 #include "watcom.h"
32 #include "rt_sound.h"
33 #include "gmove.h"
34 #include "states.h"
35 #include "rt_sqrt.h"
36 #include "rt_actor.h"
37 #include "rt_main.h"
38 #include "rt_playr.h"
39 #include "isr.h"
40 #include "rt_draw.h"
41 #include "rt_ted.h"
42 #include "rt_door.h"
43 #include "rt_menu.h"
44 #include "rt_view.h"
45 #include "rt_com.h"
46 #include "rt_in.h"
47 #include "rt_util.h"
48 #include "rt_game.h"
49 #include "rt_rand.h"
50 #include "z_zone.h"
51 #include "rt_swift.h"
52 #include "engine.h"
53 #include "_rt_play.h"
54 #include "rt_cfg.h"
55 #include "rt_spbal.h"
56 #include "rt_floor.h"
57 #include "develop.h"
58 #include "rt_msg.h"
59 #include "rt_debug.h"
60 #include "sprites.h"
61 #include "rt_net.h"
62 #include "rt_dmand.h"
63 //MED
64 #include "memcheck.h"
65
66
67 #define FLYINGZMOM 350000
68
69
70 #if (DEVELOPMENT == 1)
71 #include "rt_str.h"
72 #endif
73
74 specials CurrentSpecialsTimes =
75 {
76 60*VBLCOUNTER, // god
77 60*VBLCOUNTER, // dog
78 20*VBLCOUNTER, // shrooms
79 20*VBLCOUNTER, // elasto
80 60*VBLCOUNTER, // asbestos vest
81 60*VBLCOUNTER, // bullet proof vest
82 GASTICS, // gas mask
83 60*VBLCOUNTER, // mercury mode
84
85 300*VBLCOUNTER, // god respawn
86 60*VBLCOUNTER, // dog respawn
87 60*VBLCOUNTER, // shrooms respawn
88 60*VBLCOUNTER, // elasto respawn
89 60*VBLCOUNTER, // asbestos vest respawn
90 60*VBLCOUNTER, // bullet proof vest respawn
91 60*VBLCOUNTER, // gas mask respawn
92 60*VBLCOUNTER // mercury mode respawn
93 };
94
95 int GRAVITY = NORMAL_GRAVITY;
96
97 ROTTCHARS characters[5]={
98 {0x2100,0x4800,100,2,25}, // Taradino Cassatt
99 {0x2200,0x5200,85,3,32}, // Thi Barrett
100 {0x1f00,0x4000,150,3,20}, // Doug Wendt
101 {0x2300,0x5500,70,2,33}, // Lorelei Ni
102 {0x2000,0x4400,120,3,25}}; // Ian Paul Freeley
103
104 static const int TD = MINACTORDIST+0x1000;
105 static const int STRAFEAMOUNT = ((KEYBOARDNORMALTURNAMOUNT >> 10) + (KEYBOARDNORMALTURNAMOUNT >> 12));
106
107
108 static const int GODYZANGLE = -(9*FINEANGLES/360);
109 static const int DOGYZANGLE = (4*FINEANGLES/360);
110 static const int SHROOMYZANGLE = (15*FINEANGLES/360);
111 static const int FALLINGYZANGLE = -(15*FINEANGLES/360);
112 static const int NORMALYZANGLE = 0;
113
114
115 /*
116 =============================================================================
117
118 GLOBAL VARIABLES
119
120 =============================================================================
121 */
122
123 int controlbuf[3];
124 int buttonbits;
125 extern _2Dpoint LASTSOUND;
126 //
127 // player state info
128 //
129
130 statobj_t *DEADPLAYER[MAXDEAD];
131 int NUMDEAD;
132 int lastpolltime;
133
134 statobj_t *BulletHoles[MAXBULLETS];
135 int BulletHoleNum;
136
137 objtype *PLAYER[MAXPLAYERS],*player;
138 playertype PLAYERSTATE[MAXPLAYERS],*locplayerstate;
139
140 gametype gamestate;
141
142 boolean godmode = false;
143
144 boolean missilecam=false;
145 objtype * missobj=NULL;
146 // Player control variables
147
148 int KX = 0;
149 int KY = 0;
150 int MX = 0;
151 int MY = 0;
152 int JX = 0;
153 int JY = 0;
154 int CX = 0;
155 int CY = 0;
156 boolean vrenabled = false;
157 int VX = 0;
158 int VY = 0;
159
160 int oldcyberx = 0;
161 int oldcybery = 0;
162 int CYBERDEADRANGE = 6000;
163 boolean CYBERLOOKUP,CYBERLOOKDOWN;
164
165 int leftmom = 0;
166 int rightmom = 0;
167 int lastmom = 0;
168 int first = 1;
169
170 int pausedstartedticcount;
171 boolean RefreshPause = true;
172
173 boolean buttonpoll[NUMBUTTONS];
174
175 int buttonscan[NUMBUTTONS] = {sc_Control, sc_Alt, sc_RShift, sc_Space,
176 sc_PgUp,sc_PgDn,sc_Enter,sc_Delete,
177 sc_Home,sc_End,sc_1,sc_2,sc_3,sc_4,
178 sc_CapsLock, sc_F12,
179 sc_Comma,sc_Period,sc_BackSpace,sc_A,
180 sc_UpArrow, sc_RightArrow,
181 sc_DownArrow, sc_LeftArrow,
182 sc_Tab, sc_T, sc_Z };
183
184 int joyxmax = 0, joyymax = 0, joyxmin = 0, joyymin = 0;
185
186 #ifdef DC
187 int buttonmouse[MAX_MOUSEBTN*2] = {bt_attack, bt_strafe, di_north,bt_nobutton,bt_nobutton,
188 bt_nobutton, bt_use, bt_nobutton,bt_nobutton,bt_nobutton,};
189
190
191 int buttonjoy[MAX_JOYBTN*2] = {
192 bt_attack, bt_strafe, bt_run, bt_use,
193 bt_lookup, bt_lookdown, bt_swapweapon, bt_map,
194 bt_strafeleft, bt_straferight,
195 bt_nobutton, bt_nobutton, bt_nobutton, bt_nobutton, bt_nobutton, bt_nobutton, bt_nobutton, bt_nobutton, bt_nobutton, bt_nobutton
196 };
197 #else
198 int buttonmouse[MAX_MOUSEBTN*2] = {bt_attack, bt_strafe, di_north,
199 bt_nobutton, bt_use, bt_nobutton };
200
201 int buttonjoy[MAX_JOYBTN*2] = {bt_attack, bt_strafe, bt_run, bt_use,
202 bt_nobutton, bt_nobutton, bt_nobutton, bt_nobutton };
203 #endif
204
205 williamdidthis FREE = {84,5,0,0,9,{{done,2,1},{done,2,2},{done,2,3},
206 {done,2,4},{done,2,5},{done,2,6},{done,2,7},{done,2,8},
207 {reset,2,9}}};
208
209 williamdidthis DOGSCRATCH = {128,5,0,0,4,{{done,2,8},{at_pulltrigger,2,9},{done,2,10},
210 {reset,2,11}}};
211
212 williamdidthis DOGLICK = {128,5,0,0,4,{{done,2,4},{done,2,5},{done,2,6},
213 {reset,2,7}}};
214
215
216 williamdidthis WEAPONS[MAXWEAPONS] =
217
218 {
219 {100,-1,10,0x2000l,3,{{at_pulltrigger,4,1},{done,4,2},{reset,4,0}}}, //single pistol
220 {100,-1,10,0x2000l,6,{{at_pulltrigger,2,1},{done,2,2},{done,2,3},
221 {at_pulltrigger,2,4},{done,2,5},{reset,2,3}}}, // double pistol
222 {70,-1,10,0x2000l,2,{{at_pulltrigger,2,1},{reset,1,2}}}, //mp 40
223 {80,5,10,0x50000l,4,{{at_missileweapon,2,1},{done,2,2},{reset,2,3},{reset2,6,0}}}, //bazooka
224 {80,5,10,0x10000l,4,{{at_missileweapon,2,1},{done,2,2},{reset,2,3},{reset2,6,0}}}, //firebomb
225 {80,5,10,0x50000l,4,{{at_missileweapon,2,1},{done,2,2},{reset,2,3},{reset2,6,0}}}, //heatseeker
226 {80,5,10,0x10000l,4,{{at_missileweapon,2,1},{done,2,2},{reset,2,3},{reset2,6,0}}}, //drunk
227 {80,5,7,0x10000l,4,{{at_missileweapon,2,1},{done,2,2},{reset,2,2},{reset2,6,0}}}, // firewall
228 {125,5,7,0x10000l,7,{{done,3,1},{done,3,2},{done,3,3},{done,3,4},
229 {at_missileweapon,3,5},{done,3,6},{reset,3,7}}}, //GODHAND
230
231 #if (SHAREWARE == 0)
232 {80,5,7,0x10000l,4,{{at_missileweapon,2,1},{done,2,2},{reset,2,3},{reset2,6,0}}}, //split
233 {80,5,7,0x10000l,9,{{done,5,1},{done,5,2},{done,5,3},{done,5,4},
234 {at_missileweapon,10,5},{done,5,4},{done,5,3}, // kes
235 {done,5,2},{reset,5,1}}},
236 {200,5,7,0x10000l,6,{{done,1,1},{done,1,2},{at_pulltrigger,1,3},{at_pulltrigger,1,4},
237 {at_pulltrigger,1,5},{reset,1,6}}}, //BAT
238 {128,5,7,0x10000l,3,{{done,2,1},{at_pulltrigger,2,2},{reset,2,3}}}
239 #endif
240 };
241
242
243
244 /*
245 =============================================================================
246
247 LOCAL FUNCTION PROTOTYPES and VARIABLES
248
249 =============================================================================
250 */
251
252 void CheckPlayerSpecials(objtype * ob);
253 void CheckWeaponStates(objtype * ob);
254 boolean CheckSprite (statobj_t* ,int *);
255 void T_Tag (objtype *ob);
256 void T_Player (objtype *ob);
257 void T_BatBlast(objtype*ob);
258 void T_Attack (objtype *ob);
259 void T_Free (objtype *ob);
260 void T_DogUse (objtype *ob);
261 void PlayerMove(objtype * ob);
262 void Thrust (objtype * ob);
263 void CheckWeaponChange (objtype * ob);
264 void PlayerMissileAttack(objtype* );
265 void Cmd_Use(objtype*);
266 //void ComError (char *error, ...);
267
268 statetype s_free = {false,0,0,T_Free,0,&s_free};
269 statetype s_inelevator = {false,0,420,T_Player,0,&s_player};
270
271 #if (SHAREWARE == 0)
272 statetype s_dogwait = {true,SERIALDOG_W11,50,T_Player,SF_DOGSTATE,&s_serialdog};
273
274 statetype s_doguse = {true,SERIALDOG_W11,140,T_DogUse,SF_DOGSTATE,&s_serialdog};
275 statetype s_doglick = {true,SERIALDOG_W11,0,T_DogLick,SF_DOGSTATE,&s_doglick};
276 #endif
277
278 statetype s_tag = {false,CASSATT_S1,20,T_Tag,0,&s_player};
279
280 static SWIFT_3DStatus SWIFTStatus;
281
282 //
283 // curent user input
284 //
285
286 static int turnheldtime;
287 static int turnaround = 0;
288 static int turnaroundtime;
289
290 //
291 // Double Click variables
292 //
293
294 static int DoubleClickTimer[ MAX_MOUSEBTN ] = { 0 };
295 static byte DoubleClickCount[ MAX_MOUSEBTN ] = { 0 };
296 static byte DoubleClickPressed[ MAX_MOUSEBTN ] = { false };
297 static int JoyDblClickTimer[ MAX_JOYBTN ] = { 0 };
298 static byte JoyDblClickCount[ MAX_JOYBTN ] = { 0 };
299 static byte JoyDblClickPressed[ MAX_JOYBTN ] = { false };
300
301
302 static int PlayerRecording=-1;
303 static int nettics;
304
305 void Move_Player_From_Exit_To_Start(objtype *ob);
306 void CheckTagGame(objtype *actor1,objtype*actor2);
307 void CheckFlying(objtype*ob,playertype *pstate);
308
309 /*
310 ===============
311 =
312 = LoadPlayer
313 =
314 ===============
315 */
LoadPlayer(void)316 void LoadPlayer ( void )
317 {
318 memset (locplayerstate->buttonstate, 0, sizeof(locplayerstate->buttonstate));
319 locplayerstate->anglefrac=player->angle<<ANGLEBITS;
320 areabyplayer[player->areanumber]=true;
321 ConnectAreas();
322 }
323
324
MaxHitpointsForCharacter(playertype * pstate)325 int MaxHitpointsForCharacter(playertype*pstate)
326 {
327 if (BATTLEMODE && (gamestate.BattleOptions.HitPoints != bo_character_hitpoints))
328 {
329 return( gamestate.BattleOptions.HitPoints );
330 }
331 return characters[pstate->player].hitpoints;
332 }
333
InitializeWeapons(playertype * pstate)334 void InitializeWeapons(playertype*pstate)
335 {
336
337
338 #if (SHAREWARE == 0)
339 if (gamestate.SpawnEluder)
340 {pstate->new_weapon = pstate->weapon = pstate->missileweapon = wp_dog;
341 pstate->oldweapon = pstate->oldmissileweapon = wp_dog;
342 pstate->bulletweapon = -1;
343 pstate->HASBULLETWEAPON[wp_pistol] = 0;
344 pstate->HASBULLETWEAPON[wp_twopistol] = 0;
345 pstate->HASBULLETWEAPON[wp_mp40] = 0;
346 }
347 else
348 #endif
349 {if (gamestate.PlayerHasGun[pstate-&PLAYERSTATE[0]])
350 {pstate->new_weapon = pstate->weapon = pstate->oldweapon =
351 pstate->bulletweapon = wp_pistol;
352 pstate->HASBULLETWEAPON[wp_pistol] = 1;
353 pstate->HASBULLETWEAPON[wp_twopistol] = 0;
354 pstate->HASBULLETWEAPON[wp_mp40] = 0;
355 pstate->missileweapon = pstate->oldmissileweapon = -1;
356 }
357 else
358 {pstate->new_weapon = pstate->weapon = pstate->oldweapon =
359 pstate->bulletweapon = -1;
360 pstate->HASBULLETWEAPON[wp_pistol] = 0;
361 pstate->HASBULLETWEAPON[wp_twopistol] = 0;
362 pstate->HASBULLETWEAPON[wp_mp40] = 0;
363 pstate->missileweapon = pstate->oldmissileweapon = -1;
364 }
365 }
366
367
368 pstate->ammo = -1;
369 }
370
ResetPlayerstate(playertype * pstate)371 void ResetPlayerstate(playertype*pstate)
372 {
373
374 pstate->batblast = 0;
375 pstate->poweruptime = pstate->protectiontime = 0;
376 pstate->NETCAPTURED = 0;
377 MISCVARS->NET_IN_FLIGHT = 0;
378 pstate->weaponuptics = 0;
379 pstate->weapondowntics = 0;
380 if ((insetupgame==false) || NewGame)
381 pstate->health = MaxHitpointsForCharacter(pstate);
382 pstate->keys = 0;
383
384 // Give players all the keys in battle game
385
386 if ( BATTLEMODE )
387 {
388 pstate->keys = 0x0f;
389 }
390 pstate->attackframe = pstate->attackcount =
391 pstate->weaponframe = 0;
392 if (gamestate.battlemode == battle_Tag)
393 pstate->weaponheight = TAGHANDHEIGHT;
394 else
395 pstate->weaponheight = 0;
396 pstate->heightoffset = pstate->oldheightoffset = 0;
397 if (gamestate.SpawnEluder)
398 pstate->playerheight = 40;
399 else
400 pstate->playerheight = characters[pstate->player].height;
401 pstate->falling = false;
402 memset (pstate->buttonstate, 0, sizeof(pstate->buttonstate));
403 SetPlayerHorizon(pstate,NORMALYZANGLE);
404 }
405
406
407
408
409 /*
410 ===============
411 =
412 = SetupPlayerobj
413 =
414 ===============
415 */
SetupPlayerobj(int tilex,int tiley,int dir,objtype * ob)416 void SetupPlayerobj (int tilex, int tiley, int dir, objtype * ob)
417 {
418 playertype *pstate;
419
420 M_LINKSTATE(ob,pstate);
421
422 ob->obclass = playerobj;
423 ob->tilex = tilex;
424 ob->tiley = tiley;
425 actorat[tilex][tiley] = ob;
426 ob->areanumber = MAPSPOT(tilex,tiley,0)-AREATILE;
427 MakeLastInArea(ob);
428 ob->x = ((long)tilex<<TILESHIFT)+TILEGLOBAL/2;
429 ob->y = ((long)tiley<<TILESHIFT)+TILEGLOBAL/2;
430 ob->z = PlatformHeight(tilex,tiley);
431 if ((ob->z == -10) || DiskAt(tilex,tiley))
432 ob->z = 0;
433
434 ob->angle = (1-dir)*ANG90;
435 ob->which = ACTOR;
436 Fix(ob->angle);
437 ob->yzangle = 0;
438
439 ob->dir = angletodir[ob->angle];
440 ob->flags = (FL_SHOOTABLE|FL_ABP|FL_BLOCK|FL_COLORED);
441 ob->drawx=ob->x;
442 ob->drawy=ob->y;
443 ob->hitpoints = pstate->health;
444 pstate->anglefrac= (ob->angle<<ANGLEBITS);
445 pstate->angle=0;
446 areabyplayer[ob->areanumber]=true;
447
448
449 if (ob == player)
450 {
451 playerdead=false; // local player dead flag
452 }
453 if (!gamestate.SpawnEluder)
454 ob->shapeoffset = pstate->player*REMOTEOFFSET;
455
456 memset (pstate->buttonstate, 0, sizeof(pstate->buttonstate));
457 if (SCREENEYE != NULL)
458 {
459 NewState(SCREENEYE,&s_megaremove);
460 SCREENEYE = NULL;
461 }
462 }
463
464
465
SetShapeoffset(objtype * ob)466 void SetShapeoffset(objtype*ob)
467 {playertype *pstate;
468
469 M_LINKSTATE(ob,pstate);
470 ob->shapeoffset = pstate->player*REMOTEOFFSET;
471 ob->flags |= FL_COLORED;
472 ob->flags &= ~FL_DYING;
473
474 }
475
476
477 /*
478 ===============
479 =
480 = RevivePlayerobj
481 =
482 ===============
483 */
RevivePlayerobj(int tilex,int tiley,int dir,objtype * ob)484 void RevivePlayerobj (int tilex, int tiley, int dir, objtype*ob)
485 {
486 playertype *pstate;
487 statetype *tstate;
488
489 M_LINKSTATE(ob,pstate);
490 tstate = ob->state;
491 RemoveFromArea(ob);
492 TurnActorIntoSprite(ob);
493 if ((LASTSTAT->z < nominalheight) && (!IsPlatform(LASTSTAT->tilex,LASTSTAT->tiley)))
494 {
495 SpawnParticles(ob,GUTS,10 + gamestate.difficulty);
496 RemoveStatic(LASTSTAT);
497 }
498 else
499 {if (DEADPLAYER[NUMDEAD])
500 RemoveStatic(DEADPLAYER[NUMDEAD]);
501 DEADPLAYER[NUMDEAD] = LASTSTAT;
502 LASTSTAT->linked_to = NUMDEAD;
503 NUMDEAD = (NUMDEAD+1)&(MAXDEAD-1);
504 }
505
506 ob->state = tstate;
507
508 SetupPlayerobj (tilex, tiley, dir, ob);
509 ConnectAreas();
510
511 ResetPlayerstate(pstate);
512 InitializeWeapons(pstate);
513 SD_PlaySoundRTP(SD_PLAYERSPAWNSND,ob->x,ob->y);
514 if (!gamestate.SpawnEluder)
515 {
516 ob->shapeoffset = 0;
517 ob->flags &= ~FL_COLORED;
518 ob->flags |= FL_DYING;
519 NewState(ob,&s_respawn1);
520 if (gamestate.battlemode == battle_Tag)
521 {
522 if (BATTLE_Team[ob->dirchoosetime] == BATTLE_It)
523
524 {
525 pstate->missileweapon = pstate->oldweapon = pstate->new_weapon =
526 pstate->oldmissileweapon = pstate->weapon = wp_godhand;
527 pstate->bulletweapon = -1;
528 ob->flags |= FL_DESIGNATED;
529 }
530 else
531 {
532 pstate->weaponheight = 0;
533 }
534 }
535 }
536 #if (SHAREWARE == 0)
537 else
538 NewState(ob,&s_serialdog);
539 #endif
540 if (ob==player)
541 DrawPlayScreen(false);
542 ob->momentumx = ob->momentumy = ob->momentumz = 0;
543 }
544
545
546 /*
547 ===============
548 =
549 = SpawnPlayerobj
550 =
551 ===============
552 */
SpawnPlayerobj(int tilex,int tiley,int dir,int playerindex)553 void SpawnPlayerobj (int tilex, int tiley, int dir, int playerindex)
554 {
555 playertype *pstate;
556
557 pstate = &PLAYERSTATE[playerindex];
558
559 GetNewActor();
560 MakeActive(new);
561
562 // Set player number
563
564 new->dirchoosetime = playerindex;
565
566 // Save off if local player
567
568 if (playerindex==consoleplayer)
569 player=new;
570
571 PLAYER[playerindex] = new;
572
573 SetupPlayerobj (tilex, tiley, dir, new);
574
575 if (!gamestate.SpawnEluder)
576 NewState(new,&s_player);
577 #if (SHAREWARE == 0)
578 else
579 NewState(new,&s_serialdog);
580 #endif
581
582
583 }
584
585 /*
586 ===============
587 =
588 = SetupBulletHoleLink
589 =
590 ===============
591 */
SetupBulletHoleLink(int num,statobj_t * item)592 void SetupBulletHoleLink (int num, statobj_t * item)
593 {
594 BulletHoles[num] = item;
595 }
596
597 /*
598 ===============
599 =
600 = SpawnBulletHole
601 =
602 ===============
603 */
SpawnBulletHole(int x,int y,int z)604 void SpawnBulletHole (int x, int y, int z)
605 {
606 if (M_ISDOOR(x>>16,y>>16))
607 return;
608 if (BulletHoles[MISCVARS->BulletHoleNum])
609 RemoveStatic(BulletHoles[MISCVARS->BulletHoleNum]);
610 SpawnInertStatic(x,y,z,stat_bullethole);
611 BulletHoles[MISCVARS->BulletHoleNum]=LASTSTAT;
612 LASTSTAT->linked_to=MISCVARS->BulletHoleNum;
613 MISCVARS->BulletHoleNum = (MISCVARS->BulletHoleNum+1)&(MAXBULLETS-1);
614 }
615
616
617
618
SpawnGunSmoke(int x,int y,int z,int angle,int bullethole)619 void SpawnGunSmoke(int x, int y, int z, int angle, int bullethole)
620
621 {
622 int chance;
623
624 if ((x<=0) || (y<=0))
625 {
626 SoftError("SpawnGunSmoke: xy below angle=%ld\n",angle);
627 return;
628 }
629
630 if ((bullethole!=0) && (z>=-32) && (z<=maxheight))
631 switch (bullethole)
632 {
633 case 1:
634 SpawnBulletHole(x-BULLETHOLEOFFSET,y,z);
635 break;
636 case 2:
637 SpawnBulletHole(x+BULLETHOLEOFFSET,y,z);
638 break;
639 case 3:
640 SpawnBulletHole(x,y-BULLETHOLEOFFSET,z);
641 break;
642 case 4:
643 SpawnBulletHole(x,y+BULLETHOLEOFFSET,z);
644 break;
645 case 5:
646 SpawnBulletHole(x,y,z);
647 break;
648 default:
649 Error("Invalid bullethole value\n");
650 break;
651 }
652
653 SpawnInertActor(x,y,z);
654
655 NewState(new,&s_gunsmoke1);
656
657 if (angle < ANGLES/4)
658 {if ((angle < (3*ANGLES/16)) && (angle > (ANGLES/16)))
659 chance = 128;
660 else
661 chance = 20;
662 }
663 else if (angle < ANGLES/2)
664 {if ((angle < (7*ANGLES/16)) && (angle > (5*ANGLES/16)))
665 chance = 128;
666 else
667 chance = 20;
668 }
669 else if (angle < 3*ANGLES/4)
670 {if ((angle < (11*ANGLES/16)) && (angle > (9*ANGLES/16)))
671 chance = 128;
672 else
673 chance = 20;
674 }
675 else
676 {if ((angle < (15*ANGLES/16)) && (angle > (13*ANGLES/16)))
677 chance = 128;
678 else
679 chance = 20;
680 }
681
682 if (RandomNumber("Wall ricochet check",0)<chance)
683 {int rand;
684
685 rand = RandomNumber("Spawn Ricochet Sound in SpawnGunSmoke",0);
686 if (rand < 80)
687 SD_PlaySoundRTP(SD_RICOCHET1SND,new->x,new->y);
688 else if (rand < 160)
689 SD_PlaySoundRTP(SD_RICOCHET2SND,new->x,new->y);
690 else
691 SD_PlaySoundRTP(SD_RICOCHET3SND,new->x,new->y);
692 }
693 }
694
SpawnBlood(objtype * ob,int angle)695 void SpawnBlood(objtype * ob, int angle)
696 {
697
698 SpawnInertActor(ob->x-(costable[angle]>>5),
699 ob->y+(sintable[angle]>>5),ob->z);
700
701 NewState(new,&s_bloodspurt1);
702
703 if ((new->x<=0) || (new->y<=0))
704 Error("SpawnBlood: bad x,y obj->obclass=%ld\n",ob->obclass);
705 }
706
SpawnMetalSparks(objtype * ob,int angle)707 void SpawnMetalSparks(objtype * ob, int angle)
708 {
709 int rand,dispx=0,dispy=0;
710
711
712 if (ob->which == ACTOR)
713 {
714 dispx = ob->momentumx;
715 dispy = ob->momentumy;
716 }
717
718 SpawnInertActor(ob->x-(costable[angle]>>3)+dispx,
719 ob->y+(sintable[angle]>>3)+dispy,ob->z);
720
721 if (GameRandomNumber("Spawn Metal Sparks",0)<128)
722 NewState(new,&s_hitmetalactor1);
723 else
724 NewState(new,&s_hitmetalwall1);
725
726 rand = RandomNumber("Spawn Ricochet Sound",0);
727 if (rand < 80)
728 SD_PlaySoundRTP(SD_RICOCHET1SND,new->x,new->y);
729 else if (rand < 160)
730 SD_PlaySoundRTP(SD_RICOCHET2SND,new->x,new->y);
731 else
732 SD_PlaySoundRTP(SD_RICOCHET3SND,new->x,new->y);
733 if ((new->x<=0) || (new->y<=0))
734 Error("SpawnMetalSparks: bad x,y obj->obclass=%ld\n",ob->obclass);
735 }
736
737 /*
738 ===============
739 =
740 = UnTargetActor ( objtype * target )
741 =
742 ===============
743 */
UnTargetActor(objtype * target)744 void UnTargetActor ( objtype * target )
745 {
746 int i;
747
748 for (i=0;i<numplayers;i++)
749 {
750 if (PLAYERSTATE[i].guntarget==target)
751 {
752 PLAYERSTATE[i].guntarget=NULL;
753 SetNormalHorizon(PLAYER[i]);
754 }
755 }
756 }
757
758
759
760 //=============================================================
761
GetWeaponForItem(int itemnumber)762 int GetWeaponForItem(int itemnumber)
763 {
764 switch (itemnumber)
765 {
766
767
768 case stat_twopistol:
769 return wp_twopistol;
770
771 case stat_mp40:
772 return wp_mp40;
773
774 case stat_bazooka:
775 return wp_bazooka;
776
777 case stat_heatseeker:
778 return wp_heatseeker;
779
780 case stat_drunkmissile:
781 return wp_drunk;
782
783 case stat_firebomb:
784 return wp_firebomb;
785
786 case stat_firewall:
787 return wp_firewall;
788
789 case stat_godmode:
790 return wp_godhand;
791
792 #if (SHAREWARE == 0)
793
794
795 case stat_splitmissile:
796 return wp_split;
797
798 case stat_kes:
799 return wp_kes;
800
801 case stat_bat:
802 return wp_bat;
803
804
805 case stat_dogmode:
806 return wp_dog;
807 #endif
808 }
809 return 0;
810 }
811
812
GetItemForWeapon(int weapon)813 int GetItemForWeapon(int weapon)
814 {
815 switch (weapon)
816 {
817
818 case wp_twopistol:
819 return stat_twopistol;
820
821 case wp_mp40:
822 return stat_mp40;
823
824 case wp_bazooka:
825 return stat_bazooka;
826
827 case wp_heatseeker:
828 return stat_heatseeker;
829
830 case wp_drunk:
831 return stat_drunkmissile;
832
833 case wp_firebomb:
834 return stat_firebomb;
835
836 case wp_firewall:
837 return stat_firewall;
838
839 case wp_godhand:
840 return stat_godmode;
841
842 #if (SHAREWARE == 0)
843
844 case wp_split:
845 return stat_splitmissile;
846
847 case wp_kes:
848 return stat_kes;
849
850 case wp_bat:
851 return stat_bat;
852
853
854 case wp_dog:
855 return stat_dogmode;
856 #endif
857 }
858 return -1;
859 }
860
861
862
863 #define MF_SINGULAR 0x01
864
865 missile_stats PlayerMissileData[13] =
866
867 {
868 {0,0,0,0,0},
869 {0,0,0,0,0},
870 {0,0,0,0,0},
871
872 {&s_p_bazooka1,0x6000,p_bazookaobj,0x7000,MF_SINGULAR},
873 {&s_p_bazooka1,0x8000,p_heatseekobj,0x7000,MF_SINGULAR},
874 {&s_p_bazooka1,0x6000,p_drunkmissileobj,0x7000,0},
875 {&s_p_bazooka1,0x8000,p_firebombobj,0x7000,MF_SINGULAR},
876 {&s_p_grenade,0x4000,p_firewallobj,0x8000,0},
877 {&s_godfire1,0x3800,p_godballobj,0x8000,0},
878 {&s_p_bazooka1,0x8000,p_splitmissileobj,0x7000,MF_SINGULAR},
879 #if (SHAREWARE == 0)
880 {&s_kessphere1,0xc000,p_kesobj,0x5000,MF_SINGULAR},
881 #else
882 {0,0,0,0,0},
883 #endif
884 {0,0,0,0,0},
885 {0,0,0,0,0}
886
887 };
888
889
MissileAutoTarget(objtype * ob,missile_stats * mdata)890 void MissileAutoTarget(objtype *ob,missile_stats *mdata)
891 {
892 int dx,dy,angle,mindist,currdist,magangle,saveangle,
893 xydist,dz,yzangle,oldyzangle,saveyzangle;
894 objtype *target,*temp;
895
896 mindist = 0x7fffffff;
897 target = NULL;
898 for(temp = firstactive;temp;temp=temp->nextactive)
899 {
900 if (temp == ob)
901 continue;
902 if ((!(temp->flags & FL_SHOOTABLE)) || (temp->flags & FL_DYING))
903 continue;
904 if (!CheckLine(ob,temp,SHOOT))
905 continue;
906
907 dx = temp->x-ob->x;
908 dy = ob->y-temp->y;
909 dz = ob->z-temp->z;
910 xydist = FindDistance(dx,dy);
911 yzangle = atan2_appx(xydist,dz<<10);
912
913 angle = atan2_appx(dx,dy);
914
915 magangle = abs(ob->angle - angle);
916 if (magangle > VANG180)
917 magangle = ANGLES - magangle;
918
919 if (magangle > ANGLESDIV8)
920 continue;
921
922 currdist = FindDistance(ob->x-temp->x,ob->y-temp->y);
923 if (currdist < mindist)
924 {
925 mindist = currdist;
926 target = temp;
927 saveangle = angle;
928 saveyzangle = yzangle;
929 }
930 }
931
932 if (target)
933 {
934 oldyzangle = ob->yzangle;
935 ob->yzangle = saveyzangle;
936 SpawnMissile(ob,mdata->obclass,mdata->speed,saveangle,
937 mdata->state,mdata->offset);
938 ob->yzangle = oldyzangle;
939 }
940
941 else if (ob->flags&FL_GODMODE)
942 {
943 int saveangle;
944
945 saveangle=ob->yzangle;
946 ob->yzangle -= GODYZANGLE;
947 Fix(ob->yzangle);
948 SpawnMissile(ob,mdata->obclass,mdata->speed,
949 ob->angle,mdata->state,mdata->offset);
950 ob->yzangle=saveangle;
951 }
952 else
953 SpawnMissile(ob,mdata->obclass,mdata->speed,ob->angle,
954 mdata->state,mdata->offset);
955
956 }
957
958
PlayerMissileAttack(objtype * ob)959 void PlayerMissileAttack(objtype*ob)
960
961 {
962 playertype * pstate;
963 missile_stats *newmissiledata;
964 M_LINKSTATE(ob,pstate);
965
966
967 MISCVARS->madenoise = true;
968 newmissiledata = &PlayerMissileData[pstate->missileweapon];
969
970 // ready to annihilate this poor bastard
971
972 if ((newmissiledata->obclass == p_godballobj) ||
973 (newmissiledata->obclass == p_kesobj))
974 MissileAutoTarget(ob,newmissiledata);
975
976 else
977 {
978 SpawnMissile(ob,newmissiledata->obclass,newmissiledata->speed,ob->angle,
979 newmissiledata->state,newmissiledata->offset);
980
981 if (newmissiledata->obclass == p_drunkmissileobj)
982 {
983 int i;
984
985 for(i=0;i<4;i++)
986 {
987 if (!MissileTryMove(new,new->x+new->momentumx,new->y+new->momentumy,new->z))
988 {
989 new->x = new->drawx = ob->x + (costable[new->angle]>>3);
990 new->y = new->drawy = ob->y - (sintable[new->angle]>>3);
991
992 ob->momentumx = -FixedMul(0x5000l,costable[ob->angle]);
993 ob->momentumy = FixedMul(0x5000l,sintable[ob->angle]);
994 }
995
996 SpawnMissile(ob,newmissiledata->obclass,newmissiledata->speed,ob->angle,
997 newmissiledata->state,newmissiledata->offset);
998
999
1000 }
1001 }
1002 }
1003
1004
1005 if (newmissiledata->flags & MF_SINGULAR)
1006 PLAYER0MISSILE = new;
1007
1008 SD_PlaySoundRTP(BAS[new->obclass].fire,ob->x,ob->y);
1009
1010 // if (new->obclass == p_godballobj)
1011 // new->z += 10;
1012
1013 new->dirchoosetime = 5;
1014 if (missilecam==true)
1015 missobj=new;
1016 if (!MissileTryMove(new,new->x+new->momentumx,new->y+new->momentumy,new->z))
1017 {
1018 new->x = new->drawx = ob->x + (costable[new->angle]>>3);
1019 new->y = new->drawy = ob->y - (sintable[new->angle]>>3);
1020
1021 ob->momentumx = -FixedMul(0x5000l,costable[ob->angle]);
1022 ob->momentumy = FixedMul(0x5000l,sintable[ob->angle]);
1023 }
1024
1025 }
1026
1027 //====================================================================
1028
1029
InRange(objtype * p,objtype * victim,int distance)1030 boolean InRange (objtype *p, objtype *victim, int distance)
1031 {
1032 int dx,dy;
1033 int angle;
1034 int magangle;
1035
1036 if (victim->which==SPRITE)
1037 {
1038 dx = ((statobj_t *)victim)->x - p->x;
1039 dy = p->y - ((statobj_t *)victim)->y;
1040 }
1041 else
1042 {
1043 dx = victim->x - p->x;
1044 dy = p->y - victim->y;
1045 }
1046 angle = atan2_appx (dx,dy);
1047
1048 magangle = abs(p->angle - angle);
1049 if (magangle > VANG180)
1050 magangle = ANGLES - magangle;
1051 if (magangle<(75-(distance>>16)))
1052 return true;
1053 else
1054 return false;
1055 }
1056
1057
DogAttack(objtype * ob)1058 void DogAttack(objtype*ob)
1059 {
1060 objtype *temp;
1061 int dx,dy,dz;
1062
1063 SD_PlaySoundRTP(SD_DOGMODEBITE1SND+(RandomNumber("DogAttack",0)>>7),ob->x,ob->y);
1064 for(temp=firstareaactor[ob->areanumber];temp;temp=temp->nextinarea)
1065 {
1066
1067 if (temp->obclass > b_heinrichobj)
1068 continue;
1069
1070
1071 if ((temp == ob) || (temp->obclass == roboguardobj))
1072 continue;
1073
1074 if ((!(temp->flags & FL_SHOOTABLE)) || (temp->flags & FL_DYING))
1075 continue;
1076 if (temp->obclass == collectorobj)
1077 continue;
1078
1079
1080 dx = abs(temp->x - ob->x);
1081 if (dx > 0xc000)
1082 continue;
1083
1084 dy = abs(temp->y - ob->y);
1085 if (dy > 0xc000)
1086 continue;
1087
1088 dz = abs(temp->z - ob->z);
1089 if (dz > (0xc000>>10))
1090 continue;
1091
1092 DamageThing(temp,30);
1093 if (gamestate.violence == vl_excessive)
1094 SpawnParticles(temp,GUTS,15);
1095 Collision(temp,ob,-temp->momentumx,-temp->momentumy);
1096 if ((temp->obclass == playerobj) && (temp->flags & FL_DYING))
1097 BATTLE_PlayerKilledPlayer(battle_kill_with_missile,ob->dirchoosetime,temp->dirchoosetime);
1098
1099 return;
1100 }
1101 }
1102
1103
DogBlast(objtype * ob)1104 void DogBlast(objtype*ob)
1105 {
1106 int txl,txh,tyl,tyh,radius = 0x70000,x,y,tile;
1107 objtype*temp;
1108 statobj_t*tstat;
1109
1110 txl = ((ob->x - radius)>>TILESHIFT);
1111 tyl = ((ob->y - radius)>>TILESHIFT);
1112
1113 txh = ((ob->x + radius)>>TILESHIFT);
1114 tyh = ((ob->y + radius)>>TILESHIFT);
1115
1116 if (txl < 1)
1117 txl = 1;
1118 if (txh > MAPSIZE-1)
1119 txh = MAPSIZE-1;
1120 if (tyl < 1)
1121 tyl = 1;
1122 if (tyh > MAPSIZE-1)
1123 tyh = MAPSIZE-1;
1124
1125 for(x=txl;x<=txh;x++)
1126 for(y=tyl;y<=tyh;y++)
1127 {
1128 temp = (objtype*)actorat[x][y];
1129
1130 if (temp && (temp->which == ACTOR) && (temp->flags & FL_SHOOTABLE) &&
1131 (temp != ob) && (temp->obclass < roboguardobj) &&
1132 (temp->flags & FL_ABP)
1133 )
1134 {
1135 DamageThing(temp,100);
1136 if ((temp->hitpoints<=0) && (temp->obclass < roboguardobj))
1137 {
1138 MISCVARS->supergibflag = true;
1139 temp->flags |= FL_HBM;
1140 }
1141 Collision(temp,ob,0,0);
1142 MISCVARS->supergibflag = false;
1143
1144 if ((temp->obclass == playerobj) && (temp->flags & FL_DYING))
1145 BATTLE_PlayerKilledPlayer(battle_kill_with_missile,ob->dirchoosetime,temp->dirchoosetime);
1146
1147 }
1148
1149 tile = tilemap[x][y];
1150 if ((tile & 0x4000) && (tile & 0x8000))
1151 {
1152 maskedwallobj_t * mw;
1153
1154 mw=maskobjlist[tile&0x3ff];
1155 if ((mw->flags & MW_SHOOTABLE) && (mw->flags & MW_ABP))
1156 UpdateMaskedWall(tile&0x3ff);
1157 }
1158
1159 tstat = sprites[x][y];
1160 if (tstat && (tstat->flags & FL_SHOOTABLE) && (tstat->flags & FL_ABP))
1161 DamageThing(tstat,50);
1162 }
1163 }
1164 /*
1165 void DogBlast(objtype*ob)
1166 {
1167 int txl,txh,tyl,tyh,radius = 0x70000,x,y,tile;
1168 objtype*temp;
1169 statobj_t*tstat;
1170
1171 txl = ((ob->x - radius)>>TILESHIFT);
1172 tyl = ((ob->y - radius)>>TILESHIFT);
1173
1174 txh = ((ob->x + radius)>>TILESHIFT);
1175 tyh = ((ob->y + radius)>>TILESHIFT);
1176
1177 if (txl < 1)
1178 txl = 1;
1179 if (txh > MAPSIZE-1)
1180 txh = MAPSIZE-1;
1181 if (tyl < 1)
1182 tyl = 1;
1183 if (tyh > MAPSIZE-1)
1184 tyh = MAPSIZE-1;
1185
1186 for(x=txl;x<=txh;x++)
1187 for(y=tyl;y<=tyh;y++)
1188 {
1189 temp = (objtype*)actorat[x][y];
1190
1191 if (temp && (temp->which == ACTOR) && (temp->flags & FL_SHOOTABLE) &&
1192 (temp != ob) && (temp->obclass < roboguardobj))
1193 {
1194 DamageThing(temp,100);
1195 if ((temp->hitpoints<=0) && (temp->obclass < roboguardobj))
1196 {
1197 MISCVARS->supergibflag = true;
1198 temp->flags |= FL_HBM;
1199 }
1200 Collision(temp,ob,0,0);
1201 MISCVARS->supergibflag = false;
1202
1203 if ((temp->obclass == playerobj) && (temp->flags & FL_DYING))
1204 BATTLE_PlayerKilledPlayer(battle_kill_with_missile,ob->dirchoosetime,temp->dirchoosetime);
1205
1206 }
1207
1208 tile = tilemap[x][y];
1209 if ((tile & 0x4000) && (tile & 0x8000))
1210 {
1211 maskedwallobj_t * mw;
1212
1213 mw=maskobjlist[tile&0x3ff];
1214 if (mw->flags & MW_SHOOTABLE)
1215 UpdateMaskedWall(tile&0x3ff);
1216 }
1217
1218 tstat = sprites[x][y];
1219 if (tstat && (tstat->flags & FL_SHOOTABLE))
1220 DamageThing(tstat,50);
1221 }
1222 }
1223 */
1224
BatBlast(objtype * ob)1225 void BatBlast(objtype*ob)
1226 {int angle;
1227 playertype *pstate;
1228
1229 M_LINKSTATE(ob,pstate);
1230
1231 angle = ob->angle - ANGLES/8 + ((++pstate->batblast)*ANGLES/48);
1232 Fix(angle);
1233 #if (SHAREWARE == 0)
1234 SpawnMissile(ob,p_bazookaobj,0x6000,angle,&s_batblast1,0xa000);
1235 #endif
1236
1237 }
1238
1239
1240
BatAttack(objtype * ob)1241 void BatAttack(objtype*ob)
1242 {objtype *temp,*temp2;
1243 objtype *grenadetarget;
1244 statobj_t*tstat;
1245 int dx,dy,dz,angle,momx,momy,op,magangle;
1246 int tilexlow,tilexhigh;
1247 int tileylow,tileyhigh;
1248 int radius =0x10000;
1249 int x,y;
1250
1251 SD_PlaySoundRTP(SD_EXCALISWINGSND,ob->x,ob->y);
1252 for(temp=firstareaactor[ob->areanumber];temp;temp=temp->nextinarea)
1253 {if (temp == ob)
1254 continue;
1255
1256 if (temp->flags & FL_DYING)
1257 continue;
1258
1259 if ((temp->obclass != grenadeobj) &&
1260 (!((temp->obclass >= grenadeobj) && (temp->obclass <= p_godballobj))) &&
1261 (!(temp->flags & FL_SHOOTABLE) ||
1262 (temp->obclass >= roboguardobj))
1263 )
1264 continue;
1265
1266 dx = abs(temp->x - ob->x);
1267 dy = abs(temp->y - ob->y);
1268 dz = abs(temp->z - ob->z);
1269 if ((dx > 0x10000) || (dy > 0x10000) || (dz > 20))
1270 continue;
1271
1272 magangle = abs(ob->angle - AngleBetween(ob,temp));
1273 if (magangle > VANG180)
1274 magangle = ANGLES - magangle;
1275
1276 if (magangle > ANGLES/8)
1277 continue;
1278
1279
1280 angle= ob->angle+ANGLES/16;
1281 Fix(angle);
1282
1283 if ((temp->obclass >= grenadeobj) && (temp->obclass <= p_godballobj))
1284 {
1285 temp->angle += ANGLES/2;
1286 Fix(temp->angle);
1287 temp->momentumx = temp->momentumy = temp->momentumz = 0;
1288 ParseMomentum(temp,temp->angle);
1289 temp->whatever = ob;
1290 temp->target = NULL;
1291 continue;
1292 }
1293
1294
1295 else if (temp->obclass != grenadeobj)
1296 {momx = FixedMul(0x3000l,costable[angle]);
1297 momy = -FixedMul(0x3000l,sintable[angle]);
1298 if (levelheight > 2)
1299 {op = FixedMul(GRAVITY,(maxheight-100)<<16) << 1;
1300 temp->momentumz = -FixedSqrtHP(op);
1301 }
1302 temp->flags |= FL_NOFRICTION;
1303 SD_PlaySoundRTP(SD_EXCALIHITSND,ob->x,ob->y);
1304 if ((gamestate.violence == vl_excessive) && (GameRandomNumber("Bat Gibs",0) < 150))
1305 {temp->flags |= FL_HBM;
1306 DamageThing(temp,50);
1307 }
1308 else
1309 DamageThing(temp,10);
1310 if ((temp->flags & FL_HBM) && (temp->hitpoints > 0))
1311 temp->flags &= ~FL_HBM;
1312 Collision(temp,ob,momx,momy);
1313 if ((temp->obclass == blitzguardobj) && (temp->state == &s_blitzplead7))
1314 {temp->shapeoffset += deathshapeoffset[temp->obclass];
1315 temp->flags |= FL_ALTERNATE;
1316 NewState(temp,&s_blitzdie3);
1317 temp->momentumx = temp->momentumy = 0;
1318 }
1319 }
1320 else // find target to hit grenade back at
1321 {int rand;
1322
1323 rand = GameRandomNumber("bat/grenade target",0);
1324 if (rand < 80)
1325 {grenadetarget = (objtype*)(temp->whatever); // hit back at george
1326 GetMomenta(grenadetarget,ob,&(temp->momentumx),&(temp->momentumy),&(temp->momentumz),0x3000);
1327 }
1328 else if (rand < 160) // hit back at first eligible
1329 {
1330
1331 for(temp2 = firstareaactor[ob->areanumber];temp2;temp2 = temp2->nextinarea)
1332 {magangle = abs(ob->angle-AngleBetween(ob,temp2));
1333 if (magangle > VANG180)
1334 magangle = ANGLES - magangle;
1335
1336 if (magangle > ANGLES/8)
1337 continue;
1338 GetMomenta(temp2,ob,&(temp->momentumx),&(temp->momentumy),&(temp->momentumz),0x3000);
1339 break;
1340 }
1341 }
1342 else // hit wherever
1343 {ob->angle += (rand >> 1);
1344 Fix(ob->angle);
1345 ob->momentumx = ob->momentumy = 0;
1346 ParseMomentum(ob,ob->angle);
1347 }
1348
1349
1350 temp->temp1 = 0x70000;
1351 NewState(temp,&s_grenade1);
1352 }
1353 break;
1354 }
1355
1356 for(tstat=firstactivestat;tstat;tstat=tstat->statnext)
1357 {
1358 if (!(tstat->flags & FL_SHOOTABLE))
1359 continue;
1360
1361 dx = abs(tstat->x - ob->x);
1362 dy = abs(tstat->y - ob->y);
1363 dz = abs(tstat->z - ob->z);
1364
1365 if ((dx > 0xc000) || (dy > 0xc000) || (dz > 20))
1366 continue;
1367
1368 magangle = abs(ob->angle - AngleBetween(ob,(objtype*)tstat));
1369 if (magangle > VANG180)
1370 magangle = ANGLES - magangle;
1371
1372 if (magangle > ANGLES/8)
1373 continue;
1374
1375 DamageThing(tstat,50);
1376
1377
1378 }
1379
1380 tilexlow = (int)((ob->x-radius) >>TILESHIFT);
1381 tileylow = (int)((ob->y-radius) >>TILESHIFT);
1382
1383 tilexhigh = (int)((ob->x+radius) >>TILESHIFT);
1384 tileyhigh = (int)((ob->y+radius) >>TILESHIFT);
1385
1386 for (y=tileylow;y<=tileyhigh;y++)
1387 for (x=tilexlow;x<=tilexhigh;x++)
1388 {if ((tilemap[x][y]&0x8000) && (tilemap[x][y]&0x4000))
1389 {maskedwallobj_t * mw;
1390
1391 mw=maskobjlist[tilemap[x][y]&0x3ff];
1392 if (mw->flags&MW_SHOOTABLE)
1393 UpdateMaskedWall(tilemap[x][y]&0x3ff);
1394 }
1395 }
1396
1397 }
1398
AutoTargetHorizon(objtype * ob)1399 void AutoTargetHorizon(objtype *ob)
1400 {
1401 int dx,dy,angle,mindist,magangle,
1402 xydist,dz;
1403 objtype *temp;
1404 playertype * pstate;
1405
1406 M_LINKSTATE(ob,pstate);
1407
1408 mindist = 0x7fffffff;
1409 for(temp = firstactive;temp;temp=temp->nextactive)
1410 {
1411 if (temp == ob)
1412 continue;
1413 if ((!(temp->flags & FL_SHOOTABLE)) || (temp->flags & FL_DYING))
1414 continue;
1415 if (!CheckLine(ob,temp,SHOOT))
1416 continue;
1417
1418 dx = temp->x-ob->x;
1419 dy = ob->y-temp->y;
1420 dz = ob->z-temp->z;//-pstate->playerheight+32;
1421
1422 xydist = FindDistance(dx,dy);
1423 if (abs(dz<<10)>xydist)
1424 continue;
1425
1426
1427 angle = atan2_appx(dx,dy);
1428
1429 magangle = ob->angle - angle;
1430 Fix(magangle);
1431
1432 if (
1433 (magangle>=(ANGLESDIV8/4)) &&
1434 (magangle<=(FINEANGLES-(ANGLESDIV8/4)))
1435 )
1436 {
1437 continue;
1438 }
1439
1440 if (xydist < mindist)
1441 {
1442 mindist = xydist;
1443 pstate->guntarget=temp;
1444 temp->flags |= FL_TARGET;
1445 pstate->targettime=oldpolltime+(VBLCOUNTER);
1446 }
1447 }
1448 }
1449
GunAttack(objtype * ob)1450 void GunAttack (objtype *ob)
1451 {
1452 playertype * pstate;
1453 int damage;
1454
1455 M_LINKSTATE(ob,pstate);
1456
1457 MISCVARS->madenoise = true;
1458
1459 switch (pstate->weapon)
1460 {
1461 case wp_pistol:
1462 SD_PlaySoundRTP(SD_ATKPISTOLSND,ob->x,ob->y);
1463 damage=DMG_PISTOL;
1464 break;
1465
1466 case wp_mp40:
1467 SD_PlaySoundRTP(SD_ATKMP40SND,ob->x,ob->y);
1468 damage=DMG_MP40;
1469 break;
1470
1471 case wp_twopistol:
1472 SD_PlaySoundRTP(SD_ATKTWOPISTOLSND,ob->x,ob->y);
1473 damage=DMG_PISTOL;
1474 break;
1475 }
1476
1477 AutoTargetHorizon(ob);
1478 RayShoot (ob, damage, (characters[pstate->player].accuracy+gamestate.difficulty)<<3);
1479
1480 }
1481
1482
1483 /*
1484 ===============
1485 =
1486 = Cmd_Fire
1487 =
1488 ===============
1489 */
Cmd_Fire(objtype * ob)1490 void Cmd_Fire (objtype*ob)
1491 {
1492 playertype *pstate;
1493
1494 M_LINKSTATE(ob,pstate);
1495
1496 // pstate->buttonheld[bt_attack] = true;
1497
1498 if (pstate->NETCAPTURED && (!pstate->HASKNIFE))
1499 return;
1500
1501 if (W_CHANGE(pstate))
1502 return;
1503
1504 pstate->attackframe = 0;
1505
1506 if ((ob==player) && (pstate->weapon < wp_mp40) && (!pstate->NETCAPTURED))
1507 gamestate.DODEMOCRATICBONUS1 = false;
1508
1509 if (!pstate->NETCAPTURED)
1510 {
1511 if (pstate->weapon <= wp_mp40)
1512 NewState(ob,&s_pgunattack1);
1513 #if (SHAREWARE == 0)
1514 else if ((pstate->weapon == wp_bat) && (pstate->batblast >= BBTIME))
1515 {
1516 pstate->batblast = 0;
1517 NewState(ob,&s_pbatblast);
1518 }
1519 else if (pstate->weapon == wp_dog)
1520 NewState(ob,&s_serialdogattack);
1521 #endif
1522 else
1523 NewState(ob,&s_pmissattack1);
1524
1525 #if (SHAREWARE == 0)
1526
1527 if ((pstate->weapon == wp_dog) && (!ob->momentumz))
1528 ob->momentumz = -0x50000;
1529 #endif
1530 pstate->attackcount = WEAPONS[pstate->weapon].attackinfo[0].mtics;
1531 pstate->weaponframe = WEAPONS[pstate->weapon].attackinfo[0].frame;
1532 }
1533
1534 else if (pstate->NETCAPTURED == 1)
1535 {
1536 NewState(player,&s_free);
1537 pstate->attackcount = FREE.attackinfo[0].mtics;
1538 pstate->weaponframe = FREE.attackinfo[0].frame;
1539 }
1540
1541 }
1542
PlayNoWaySound(void)1543 void PlayNoWaySound ( void )
1544 {
1545 if (player->flags & FL_DOGMODE)
1546 SD_Play(SD_DOGMODEBITE2SND);
1547 else if ((locplayerstate->player == 1) || (locplayerstate->player == 3))
1548 SD_Play(SD_PLAYERTBHURTSND);
1549 else
1550 SD_Play(SD_NOWAYSND);
1551 }
1552
1553
1554 /*
1555 ===============
1556 =
1557 = Cmd_Use
1558 =
1559 ===============
1560 */
1561
Cmd_Use(objtype * ob)1562 void Cmd_Use (objtype*ob)
1563 {
1564 int checkx,checky,doorn,
1565 /*newtilex,newtiley,oldtilex,oldtiley,*/elevnum,
1566 wallx,wally;
1567 // statobj_t* tempsprite=NULL;
1568 objtype* tempactor= NULL;
1569 doorobj_t* tempdoor=NULL;
1570 pwallobj_t* temppwall=NULL;
1571 wall_t* tempwall=NULL;
1572 int index;
1573 playertype * pstate;
1574
1575
1576
1577 M_LINKSTATE(ob,pstate);
1578
1579 #if (SHAREWARE == 0)
1580
1581 if ((pstate->weapon == wp_dog) && (ob->state != &s_doguse) &&
1582 (ob->state != &s_dogwait) && (!W_CHANGE(pstate))
1583 )
1584 {
1585 pstate->attackframe = 0;
1586 NewState(ob,&s_doguse);
1587 pstate->attackcount = DOGSCRATCH.attackinfo[0].mtics;
1588 pstate->weaponframe = DOGSCRATCH.attackinfo[0].frame;
1589 ob->momentumz = -0x40000;
1590 return;
1591
1592 }
1593
1594 else
1595 #endif
1596 if ((ob->flags & FL_DESIGNATED) && (BATTLEMODE) && (gamestate.battlemode == battle_Tag))
1597 {
1598 NewState(ob,&s_tag);
1599 //return;
1600 }
1601 //
1602 // find which cardinal direction the player is facing
1603 //
1604 if (ob->angle < FINEANGLES/8 || ob->angle > 7*FINEANGLES/8)
1605 {
1606 checkx = ob->tilex + 1;
1607 checky = ob->tiley;
1608 ob->dir = east;
1609 wallx = (checkx << TILESHIFT);
1610 wally = (checky << TILESHIFT) + TILEGLOBAL/2;
1611 }
1612 else if (ob->angle < 3*FINEANGLES/8)
1613 {
1614 checkx = ob->tilex;
1615 checky = ob->tiley-1;
1616 ob->dir = north;
1617 wally = (checky << TILESHIFT) + TILEGLOBAL;
1618 wallx = (checkx << TILESHIFT) + TILEGLOBAL/2;
1619 }
1620 else if (ob->angle < 5*FINEANGLES/8)
1621 {
1622 checkx = ob->tilex - 1;
1623 checky = ob->tiley;
1624 ob->dir = west;
1625 wallx = (checkx << TILESHIFT) + TILEGLOBAL;
1626 wally = (checky << TILESHIFT) + TILEGLOBAL/2;
1627 }
1628 else
1629 {
1630 checkx = ob->tilex;
1631 checky = ob->tiley + 1;
1632 ob->dir = south;
1633 wally = (checky << TILESHIFT);
1634 wallx = (checkx << TILESHIFT) + TILEGLOBAL/2;
1635 }
1636
1637
1638 if (actorat[checkx][checky])
1639 {
1640 tempdoor=(doorobj_t*)actorat[checkx][checky];
1641 tempactor = (objtype*)actorat[checkx][checky];
1642 tempwall = (wall_t*)actorat[checkx][checky];
1643 }
1644 doorn = tilemap[checkx][checky] & ~0x2000;
1645 // if (sprites[checkx][checky])
1646 // tempsprite = sprites[checkx][checky];
1647 if (doorn == (elevatorstart + 6))
1648 return;
1649
1650 if (pstate->buttonheld[bt_use])
1651 return;
1652
1653 if (doorn == (elevatorstart + 1))
1654 {
1655 tilemap[checkx][checky]++; // flip switch
1656 if (MAPSPOT(ob->tilex,ob->tiley,1) == ALTELEVATORTILE);
1657 // playstate = ex_secretlevel;
1658 else if (ob==player)
1659 playstate = ex_completed;
1660 }
1661
1662
1663 else if (doorn == (elevatorstart + 5))
1664
1665 {
1666 elevnum = MAPSPOT(ob->tilex,ob->tiley,1) - 90;
1667 tempwall->flags |= FL_S_FLIPPED;
1668 OperateElevatorSwitch(ob,elevnum,checkx,checky);
1669 }
1670 else if (tempdoor && tempdoor->which==PWALL)
1671 {
1672 temppwall=(pwallobj_t *)tempdoor;
1673 OperatePushWall (temppwall->num,ob->dir, ob == player );
1674 }
1675 else if ((doorn&0x8000) && (!(doorn&0x4000)))
1676 {
1677 doorobj_t* dptr = doorobjlist[doorn&0x3ff];
1678 int dnum = doorn&0x3ff;
1679 int lock;
1680
1681 OperateDoor (pstate->keys, dnum, (ob == player));
1682 if (dptr->eindex != -1)
1683 {
1684 elevator_t*eptr;
1685
1686
1687 lock = dptr->lock;
1688 if ( lock && !( pstate->keys & ( 1 << ( lock - 1 ) ) ) )
1689 {
1690 if (ob==player)
1691 {
1692 // locked
1693 switch (lock)
1694 {
1695 case 1:
1696 AddMessage("You need the \\EGOLD key",MSG_DOOR);
1697 break;
1698
1699 case 2:
1700 AddMessage("You need the \\FSILVER key",MSG_DOOR);
1701 break;
1702
1703 case 3:
1704 AddMessage("You need the \\8IRON key",MSG_DOOR);
1705 break;
1706
1707 case 4:
1708 AddMessage("You need the \\AOSCURO key",MSG_DOOR);
1709 break;
1710
1711 default:
1712 AddMessage("This door appears to be locked",MSG_DOOR);
1713 break;
1714 }
1715
1716 SD_Play( SD_NOITEMSND );
1717 }
1718 return;
1719 }
1720
1721 eptr = &ELEVATOR[dptr->eindex];
1722 if (((dnum == eptr->door1) && (eptr->state == ev_rad)) ||
1723 ((dnum == eptr->door2) && (eptr->state == ev_ras))
1724 )
1725 if (ob == player)
1726 AddMessage("Elevator is on the way.",MSG_GAME);
1727
1728 OperateElevatorDoor(dnum);
1729 }
1730
1731 }
1732
1733 else if ((tempactor) && (tempactor->which == ACTOR) &&
1734 (tempactor->obclass == pillarobj) &&
1735 DISTOK(ob->x,tempactor->x,TD) &&
1736 DISTOK(ob->y,tempactor->y,TD) &&
1737 (!(tempactor->flags & FL_DONE)) &&
1738 (!MAPSPOT(tempactor->tilex,tempactor->tiley,2))
1739 )
1740
1741 {if ((tempactor->dir == nodir) ||
1742 (tempactor->dir == ob->dir))
1743 {if (tempactor->dir == nodir)
1744 {
1745 tempactor->dir = ob->dir;
1746 ParseMomentum(tempactor,dirangle8[tempactor->dir]);
1747 }
1748 SD_PlaySoundRTP ( SD_PUSHWALLSND, tempactor->x, tempactor->y );
1749 tempactor->flags |= FL_ACTIVE;
1750 tempactor->flags |= FL_FLIPPED;
1751 // MakeActive(tempactor);
1752 tempactor->whatever = ob;
1753 gamestate.secretcount++;
1754 }
1755
1756 }
1757 else if ((tempwall) && (tempwall->which == WALL) &&
1758 (tempwall->flags & FL_SWITCH) )
1759 {
1760 tempwall->flags |= FL_S_FLIPPED;
1761 if ((tempwall->flags & FL_W_INVERTED) &&
1762 DISTOK(ob->x,wallx,TD) &&
1763 DISTOK(ob->y,wally,TD) &&
1764 DISTOK(ob->z,0,32)
1765 )
1766 {
1767 index = touchindices[checkx][checky]-1;
1768 if (!(tempwall->flags & FL_ON))
1769 {
1770 maskobjlist[tilemap[checkx][checky]&0x3ff]->toptexture++;
1771 tempwall->flags |= FL_ON;
1772 TRIGGER[index] = 1;
1773 SD_PlaySoundRTP(SD_TOUCHPLATESND,ob->x,ob->y);
1774 if (ob==player)
1775 AddMessage("Switch turned on.",MSG_GAME);
1776 }
1777 else if (tempwall->flags & FL_REVERSIBLE)
1778 {
1779 maskobjlist[tilemap[checkx][checky]&0x3ff]->toptexture--;
1780 tempwall->flags &= ~FL_ON;
1781 TRIGGER[index] = 1;
1782 SD_PlaySoundRTP(SD_TOUCHPLATESND,ob->x,ob->y);
1783 if (ob==player)
1784 AddMessage("Switch turned off.",MSG_GAME);
1785 }
1786
1787 }
1788 else if (DISTOK(ob->x,wallx,TD) &&
1789 DISTOK(ob->y,wally,TD) &&
1790 !(tempwall->flags & FL_W_INVERTED)
1791 )
1792 {
1793 index = touchindices[checkx][checky]-1;
1794 if (!(tempwall->flags & FL_ON))
1795 {
1796 tilemap[checkx][checky]++;
1797 tempwall->flags |= FL_ON;
1798 TRIGGER[index] = 1;
1799 SD_PlaySoundRTP(SD_TOUCHPLATESND,ob->x,ob->y);
1800 if (ob==player)
1801 AddMessage("Switch turned on.",MSG_GAME);
1802 }
1803 else if (tempwall->flags & FL_REVERSIBLE)
1804 {
1805 tilemap[checkx][checky]--;
1806 tempwall->flags &= ~FL_ON;
1807 TRIGGER[index] = 1;
1808 SD_PlaySoundRTP(SD_TOUCHPLATESND,ob->x,ob->y);
1809 if (ob==player)
1810 AddMessage("Switch turned off.",MSG_GAME);
1811 }
1812
1813 }
1814 }
1815 else if ((tempwall) && (tempwall->which == WALL) && (ob==player))
1816 PlayNoWaySound();
1817 // else
1818 // SD_PlaySoundRTP (SD_NOWAYSND,ob->x,ob->y);
1819 // pstate->buttonheld[bt_use] = true;
1820 }
1821
1822
1823 /*
1824 =============================================================================
1825
1826 USER CONTROL
1827
1828 =============================================================================
1829 */
1830
1831
1832 //******************************************************************************
1833 //
1834 // PollKeyboardButtons
1835 //
1836 //******************************************************************************
1837
PollKeyboardButtons(void)1838 void PollKeyboardButtons (void)
1839 {
1840 int i;
1841
1842 QueueLetterInput ();
1843 IN_UpdateKeyboard();
1844
1845 for (i = 0; i < NUMBUTTONS; i++)
1846 {
1847 if (Keystate[buttonscan[i]])
1848 {
1849 buttonpoll[i] = true;
1850 }
1851 }
1852 }
1853
1854 //******************************************************************************
1855 //
1856 // PollMouseButtons
1857 //
1858 //******************************************************************************
1859
PollMouseButtons(void)1860 void PollMouseButtons (void)
1861 {
1862 int i;
1863 int buttons;
1864 int mask;
1865 int press;
1866
1867 buttons = IN_GetMouseButtons();
1868
1869 mask = 1;
1870 for( i = 0; i < MAX_MOUSEBTN; i++, mask <<= 1 )
1871 {
1872 press = buttons & mask;
1873
1874 if ( press )
1875 {
1876 // if ( ( buttonmouse[ i ] != bt_nobutton ) &&
1877 // ( DoubleClickCount[ i ] != 2 ) )
1878 if ( buttonmouse[ i ] != bt_nobutton )
1879 {
1880 buttonpoll[ buttonmouse[ i ] ] = true;
1881 }
1882 }
1883
1884 // Check double-click
1885 if ( buttonmouse[ i + MAX_MOUSEBTN ] != bt_nobutton )
1886 {
1887 if ( press )
1888 {
1889 // Was the button pressed last tic?
1890 if ( !DoubleClickPressed[ i ] )
1891 {
1892 // Yes, take note of it
1893 DoubleClickPressed[ i ] = true;
1894
1895 // Is this the first click, or a really late click?
1896 if ( ( DoubleClickCount[ i ] == 0 ) ||
1897 ( GetTicCount() >= DoubleClickTimer[ i ] ) )
1898 {
1899 // Yes, now wait for a second click
1900 DoubleClickTimer[ i ] = GetTicCount() + DoubleClickSpeed;
1901
1902 //( tics << 5 );
1903 DoubleClickCount[ i ] = 1;
1904 }
1905 else
1906 {
1907 // Second click
1908 buttonpoll[ buttonmouse[ i + MAX_MOUSEBTN ] ] = true;
1909 DoubleClickTimer[ i ] = 0;
1910 DoubleClickCount[ i ] = 2;
1911 }
1912 }
1913 else
1914 {
1915 // After second click, button remains pressed
1916 // until user releases it
1917 if ( DoubleClickCount[ i ] == 2 )
1918 {
1919 buttonpoll[ buttonmouse[ i + MAX_MOUSEBTN ] ] = true;
1920 }
1921 }
1922 }
1923 else
1924 {
1925 if ( DoubleClickCount[ i ] == 2 )
1926 {
1927 DoubleClickCount[ i ] = 0;
1928 }
1929 DoubleClickPressed[ i ] = false;
1930 }
1931 }
1932 }
1933 }
1934
1935
1936 //******************************************************************************
1937 //
1938 // PollJoystickButtons
1939 //
1940 //******************************************************************************
PollJoystickButtons(void)1941 void PollJoystickButtons
1942 (
1943 void
1944 )
1945
1946 {
1947 int i;
1948 int buttons;
1949 int mask;
1950 int num;
1951 int press;
1952
1953 buttons = IN_JoyButtons ();
1954
1955 #ifdef DC
1956 num = MAX_JOYBTN;
1957 mask = 1;
1958 #else
1959 if ( joypadenabled )
1960 {
1961 num = 4;
1962 mask = 1;
1963 }
1964 else
1965 {
1966 num = 2;
1967 if ( joystickport )
1968 {
1969 mask = 4;
1970 }
1971 else
1972 {
1973 mask = 1;
1974 }
1975 }
1976 #endif
1977
1978 for( i = 0; i < num; i++, mask <<= 1 )
1979 {
1980 press = buttons & mask;
1981
1982 if ( press )
1983 {
1984 // if ( ( buttonjoy[ i ] != bt_nobutton ) &&
1985 // ( JoyDblClickCount[ i ] != 2 ) )
1986 if ( buttonjoy[ i ] != bt_nobutton )
1987 {
1988 buttonpoll[ buttonjoy[ i ] ] = true;
1989 }
1990 }
1991
1992 // Check double-click
1993 if ( buttonjoy[ i + MAX_JOYBTN ] != bt_nobutton )
1994 {
1995 if ( press )
1996 {
1997 // Was the button pressed last tic?
1998 if ( !JoyDblClickPressed[ i ] )
1999 {
2000 // Yes, take note of it
2001 JoyDblClickPressed[ i ] = true;
2002
2003 // Is this the first click, or a really late click?
2004 if ( ( JoyDblClickCount[ i ] == 0 ) ||
2005 ( GetTicCount() >= JoyDblClickTimer[ i ] ) )
2006 {
2007 // Yes, now wait for a second click
2008 JoyDblClickTimer[ i ] = GetTicCount() + DoubleClickSpeed;
2009
2010 //( tics << 5 );
2011 JoyDblClickCount[ i ] = 1;
2012 }
2013 else
2014 {
2015 // Second click
2016 buttonpoll[ buttonjoy[ i + MAX_JOYBTN ] ] = true;
2017 JoyDblClickTimer[ i ] = 0;
2018 JoyDblClickCount[ i ] = 2;
2019 }
2020 }
2021 else
2022 {
2023 // After second click, button remains pressed
2024 // until user releases it
2025 if ( JoyDblClickCount[ i ] == 2 )
2026 {
2027 buttonpoll[ buttonjoy[ i + MAX_JOYBTN ] ] = true;
2028 }
2029 }
2030 }
2031 else
2032 {
2033 if ( JoyDblClickCount[ i ] == 2 )
2034 {
2035 JoyDblClickCount[ i ] = 0;
2036 }
2037 JoyDblClickPressed[ i ] = false;
2038 }
2039 }
2040 }
2041 }
2042
2043
2044 //===========================================================================
2045
2046 //******************************************************************************
2047 //
2048 // PollKeyboardMove
2049 //
2050 //******************************************************************************
2051
PollKeyboardMove(void)2052 void PollKeyboardMove
2053 (
2054 void
2055 )
2056
2057 {
2058 if ( ( buttonpoll[ bt_turnaround ] ) && ( turnaround == 0 ) )
2059 {
2060 turnaround = 1;
2061 turnaroundtime = 15 + tics;
2062 turnheldtime = 0;
2063 }
2064 if ( turnaround == 0 )
2065 {
2066 if ( buttonpoll[ di_east ] )
2067 {
2068 turnheldtime+=tics;
2069 if (turnheldtime>=TURBOTURNTIME)
2070 {
2071 KX = -KEYBOARDNORMALTURNAMOUNT;
2072 }
2073 else
2074 {
2075 KX = -KEYBOARDPREAMBLETURNAMOUNT;
2076 }
2077 }
2078 else if ( buttonpoll[ di_west ] )
2079 {
2080 turnheldtime+=tics;
2081 if (turnheldtime>=TURBOTURNTIME)
2082 {
2083 KX = KEYBOARDNORMALTURNAMOUNT;
2084 }
2085 else
2086 {
2087 KX = KEYBOARDPREAMBLETURNAMOUNT;
2088 }
2089 }
2090 else
2091 {
2092 KX = 0;
2093 turnheldtime=0;
2094 }
2095 if ( (buttonpoll[bt_run]) &&
2096 ( (turnheldtime>=TURBOTURNTIME) || (turnheldtime==0) )
2097 )
2098 KX = FixedMul(KX,TURBOTURNAMOUNT);
2099 }
2100 else
2101 {
2102 KX=TURNAROUNDSPEED;
2103 turnaroundtime-=tics;
2104 if (turnaroundtime<=0)
2105 {
2106 turnaround=0;
2107 KX=((turnaroundtime*TURNAROUNDSPEED)>>1);
2108 }
2109 }
2110
2111 if ( buttonpoll[ di_north ] )
2112 {
2113 KY = -BASEMOVE;
2114 }
2115 else if ( buttonpoll[ di_south ] )
2116 {
2117 KY = BASEMOVE;
2118 }
2119 else
2120 KY = 0;
2121
2122 if (buttonpoll[bt_run])
2123 {
2124 KY <<= 1;
2125 }
2126 }
2127
2128 //******************************************************************************
2129 //
2130 // PollMouseMove
2131 //
2132 //******************************************************************************
2133
2134 //#define MOUSE_RY_SHIFT 12
2135 //#define MOUSE_TZ_SHIFT 3
2136 #define MOUSE_TZ_SENSITIVITY_SCALE 65535
2137 #define MOUSE_RY_SENSITIVITY_SCALE 18725
2138 //#define MOUSE_RY_INPUT_SCALE 6000
2139 #define MOUSE_TZ_INPUT_SCALE 20
2140 int mouse_ry_input_scale = 5000;
2141
2142 int sensitivity_scalar[15] =
2143 {
2144 0,1,2,3,4,5,6,8,11,13,15,18,12,13,14
2145 };
2146
2147 //#define MOUSE_RY_SCALE 65535
2148
2149 //#define MOUSE_TZ_SCALE 65535
2150 #define MAXMOUSETURN 7000000
2151
PollMouseMove(void)2152 void PollMouseMove (void)
2153 {
2154 int mousexmove, mouseymove;
2155
2156 INL_GetMouseDelta(&mousexmove, &mouseymove);
2157
2158 if (abs(mousexmove)>abs(mouseymove))
2159 mouseymove/=2;
2160 else
2161 mousexmove/=2;
2162 MX = 0;
2163 MY = 0;
2164
2165
2166 if ((abs (mouseymove)) >= threshold)
2167 {
2168 MY = MOUSE_TZ_INPUT_SCALE*mouseymove;
2169
2170 // MY += FixedMul(MY,mouseadjustment*MOUSE_TZ_SENSITIVITY_SCALE);
2171 if (abs(mouseymove)>200)
2172 {
2173 buttonpoll[bt_run]=true;
2174 }
2175 }
2176
2177 if ((abs (mousexmove)) >= threshold)
2178 {
2179 //MX = -MOUSE_RY_INPUT_SCALE*mousexmove;
2180 MX = -mouse_ry_input_scale*mousexmove;
2181 MX += FixedMul(MX,sensitivity_scalar[mouseadjustment]*MOUSE_RY_SENSITIVITY_SCALE);
2182 // if (abs(MX) > MAXMOUSETURN)
2183 // MX = MAXMOUSETURN*SGN(MX);
2184 if (abs(mouseymove)>10)
2185 {
2186 buttonpoll[bt_run]=true;
2187 }
2188 }
2189
2190 // if (MY > 0)
2191 // MX -= (MX/2);
2192 }
2193
2194
2195 //******************************************************************************
2196 //
2197 // PollJoystickMove
2198 //
2199 //******************************************************************************
2200
PollJoystickMove(void)2201 void PollJoystickMove (void)
2202 {
2203 int joyx,joyy;
2204
2205 INL_GetJoyDelta (joystickport, &joyx, &joyy);
2206 if ( joypadenabled )
2207 {
2208 if (joyx >= threshold)
2209 {
2210 buttonpoll[ di_east ] = true;
2211 }
2212 if (-joyx >= threshold)
2213 {
2214 buttonpoll[ di_west ] = true;
2215 }
2216 if ( joyy >= threshold )
2217 {
2218 buttonpoll[ di_south ] = true;
2219 }
2220 if ( -joyy >= threshold )
2221 {
2222 buttonpoll[ di_north ] = true;
2223 }
2224 }
2225 else
2226 {
2227 if ((abs (joyx)) >= threshold)
2228 {
2229 JX = ((-joyx)<<13)+((-joyx)<<11);
2230 turnheldtime += tics;
2231 }
2232 else
2233 JX = 0;
2234
2235 if ((abs (joyy)) >= threshold)
2236 {
2237 JY = joyy<<4;
2238 }
2239 else
2240 JY = 0;
2241 if (buttonpoll[bt_run])
2242 {
2243 JX <<= 1;
2244 JY <<= 1;
2245 }
2246 }
2247 }
2248
2249 //******************************************************************************
2250 //
2251 // StartVRFeedback
2252 //
2253 //******************************************************************************
2254
StartVRFeedback(int guntype)2255 void StartVRFeedback (int guntype)
2256 {
2257 #ifdef DOS
2258 union REGS inregs;
2259 union REGS outregs;
2260
2261 inregs.x.eax = VR_FEEDBACK_SERVICE;
2262 inregs.x.ebx = 1;
2263 inregs.x.ecx = guntype;
2264 int386 (0x33, &inregs, &outregs);
2265 #else
2266 STUB_FUNCTION;
2267 #endif
2268 }
2269
2270 //******************************************************************************
2271 //
2272 // StopVRFeedback
2273 //
2274 //******************************************************************************
2275
StopVRFeedback(void)2276 void StopVRFeedback (void)
2277 {
2278 #ifdef DOS
2279 union REGS inregs;
2280 union REGS outregs;
2281
2282 inregs.x.eax = VR_FEEDBACK_SERVICE;
2283 inregs.x.ebx = 0;
2284 int386 (0x33, &inregs, &outregs);
2285 #else
2286 STUB_FUNCTION;
2287 #endif
2288 }
2289
2290 //******************************************************************************
2291 //
2292 // PollVirtualReality
2293 //
2294 //******************************************************************************
2295
2296 #define VR_BUTTON(x) ((vr_buttons>>x) & 1)
2297
PollVirtualReality(void)2298 void PollVirtualReality (void)
2299 {
2300 #ifdef DOS
2301 union REGS inregs;
2302 union REGS outregs;
2303 short int mousexmove,
2304 mouseymove;
2305 word vr_buttons;
2306
2307 inregs.x.eax = VR_INPUT_SERVICE;
2308
2309 inregs.x.ebx = player->angle;
2310 inregs.x.ecx = player->yzangle;
2311
2312 int386 (0x33, &inregs, &outregs);
2313
2314 vr_buttons = outregs.w.bx;
2315
2316 buttonpoll[bt_run ] |= VR_BUTTON(VR_RUNBUTTON );
2317 buttonpoll[bt_strafeleft ] |= VR_BUTTON(VR_STRAFELEFTBUTTON );
2318 buttonpoll[bt_straferight ] |= VR_BUTTON(VR_STRAFERIGHTBUTTON );
2319 buttonpoll[bt_attack ] |= VR_BUTTON(VR_ATTACKBUTTON );
2320 buttonpoll[bt_lookup ] |= VR_BUTTON(VR_LOOKUPBUTTON );
2321 buttonpoll[bt_lookdown ] |= VR_BUTTON(VR_LOOKDOWNBUTTON );
2322 buttonpoll[bt_swapweapon ] |= VR_BUTTON(VR_SWAPWEAPONBUTTON );
2323 buttonpoll[bt_use ] |= VR_BUTTON(VR_USEBUTTON );
2324 buttonpoll[bt_horizonup ] |= VR_BUTTON(VR_HORIZONUPBUTTON );
2325 buttonpoll[bt_horizondown ] |= VR_BUTTON(VR_HORIZONDOWNBUTTON );
2326 buttonpoll[bt_map ] |= VR_BUTTON(VR_MAPBUTTON );
2327 buttonpoll[bt_pistol ] |= VR_BUTTON(VR_PISTOLBUTTON );
2328 buttonpoll[bt_dualpistol ] |= VR_BUTTON(VR_DUALPISTOLBUTTON );
2329 buttonpoll[bt_mp40 ] |= VR_BUTTON(VR_MP40BUTTON );
2330 buttonpoll[bt_missileweapon] |= VR_BUTTON(VR_MISSILEWEAPONBUTTON);
2331 buttonpoll[bt_recordsound ] |= VR_BUTTON(VR_RECORDBUTTON );
2332
2333 mousexmove = outregs.w.cx;
2334 mouseymove = outregs.w.dx;
2335
2336 VX = 0;
2337 VY = 0;
2338
2339
2340 if ((abs (mouseymove)) >= threshold)
2341 {
2342 VY = MOUSE_TZ_INPUT_SCALE*mouseymove;
2343 if (abs(mouseymove)>200)
2344 {
2345 buttonpoll[bt_run]=true;
2346 }
2347 }
2348
2349 if ((abs (mousexmove)) >= threshold)
2350 {
2351 VX = -mouse_ry_input_scale*mousexmove;
2352 VX += FixedMul(MX,sensitivity_scalar[mouseadjustment]*MOUSE_RY_SENSITIVITY_SCALE);
2353 if (abs(mousexmove)>10)
2354 {
2355 buttonpoll[bt_run]=true;
2356 }
2357 }
2358 #else
2359 STUB_FUNCTION;
2360 #endif
2361 }
2362
2363
2364 //******************************************************************************
2365 //
2366 // PollMove ()
2367 //
2368 //******************************************************************************
2369
2370 boolean aimbuttonpressed=false;
PollMove(void)2371 void PollMove (void)
2372 {
2373 int angle;
2374 int x, y;
2375
2376
2377 x = KX + MX + JX + CX + VX;
2378 y = KY + MY + JY + CY + VY;
2379
2380 if (buttonpoll[bt_aimbutton])
2381 {
2382 if (y>0)
2383 {
2384 buttonpoll[bt_horizonup]=1;
2385 y=0;
2386 aimbuttonpressed=true;
2387 }
2388 else if (y<0)
2389 {
2390 buttonpoll[bt_horizondown]=1;
2391 y=0;
2392 aimbuttonpressed=true;
2393 }
2394 else if (aimbuttonpressed==false)
2395 {
2396 buttonpoll[bt_lookup]=1;
2397 buttonpoll[bt_lookdown]=1;
2398 }
2399 }
2400 else
2401 {
2402 aimbuttonpressed=false;
2403 }
2404
2405 if (player->flags & FL_FLEET)
2406 y += y>>1;
2407
2408 if ((locplayerstate->NETCAPTURED == 1) && (!locplayerstate->HASKNIFE))
2409 {
2410 if (first)
2411 {
2412 nettics = GetTicCount() + (VBLCOUNTER * 4);
2413 first = 0;
2414 }
2415
2416 if (x > 0)
2417 {
2418 rightmom += NETMOM;
2419 if (lastmom!=0)
2420 controlbuf[2]=x<<1;
2421 lastmom=0;
2422 }
2423 else
2424 if (x < 0)
2425 {
2426 leftmom += NETMOM;
2427 if (lastmom!=1)
2428 controlbuf[2]=x<<1;
2429 lastmom=1;
2430 }
2431 else
2432 {
2433 rightmom -= (NETMOM >> 2);
2434 if (rightmom < 0)
2435 rightmom = 0;
2436 leftmom -= (NETMOM >> 2);
2437 if (leftmom < 0)
2438 leftmom = 0;
2439 }
2440
2441 if ((GetTicCount() > nettics) && (rightmom > (NETMOM * 2)) &&
2442 (leftmom > (NETMOM * 2)))
2443 {
2444 rightmom = 0;
2445 leftmom = 0;
2446 first = 1;
2447 lastmom^=1;
2448 locplayerstate->NETCAPTURED = 0;
2449 MISCVARS->NET_IN_FLIGHT = false;
2450 NewState(player, &s_player);
2451 locplayerstate->weaponuptics = WEAPONS[locplayerstate->weapon].screenheight/GMOVE;
2452 locplayerstate->weaponheight = locplayerstate->weaponuptics*GMOVE ;
2453 }
2454 }
2455 else if ((buttonpoll[bt_strafe]) && (turnaround==0))
2456 {
2457 // strafing
2458 if (x < 0)
2459 {
2460 angle = (player->angle - FINEANGLES/4)&(FINEANGLES-1);
2461
2462 x = (x>>10) + (x >> 11);
2463
2464 controlbuf[0] = -(FixedMul (x, costable[angle]));
2465 controlbuf[1] = FixedMul (x, sintable[angle]);
2466 }
2467 else if (x > 0)
2468 {
2469 angle = (player->angle + FINEANGLES/4)&(FINEANGLES-1);
2470
2471 x = (x>>10) + (x >> 11);
2472
2473 controlbuf[0] = FixedMul (x, costable[angle]);
2474 controlbuf[1] = -(FixedMul (x, sintable[angle]));
2475 }
2476 if (y != 0)
2477 {
2478 controlbuf[0] += -(FixedMul (y, viewcos));
2479 controlbuf[1] += (FixedMul (y, viewsin));
2480 }
2481 }
2482 else
2483 {
2484 if (y != 0)
2485 {
2486 controlbuf[0] = -FixedMul (y, viewcos);
2487 controlbuf[1] = FixedMul (y, viewsin);
2488 }
2489
2490 if (x != 0)
2491 controlbuf[2] = x;
2492 }
2493
2494 if (buttonpoll[bt_strafeleft])
2495 {
2496 angle = (player->angle - FINEANGLES/4)&(FINEANGLES-1);
2497 controlbuf[0] += -(FixedMul (STRAFEAMOUNT, costable[angle]));
2498 controlbuf[1] += FixedMul (STRAFEAMOUNT, sintable[angle]);
2499 }
2500 else if (buttonpoll[bt_straferight])
2501 {
2502 angle = (player->angle + FINEANGLES/4)&(FINEANGLES-1);
2503 controlbuf[0] += -(FixedMul (STRAFEAMOUNT, costable[angle]));
2504 controlbuf[1] += FixedMul (STRAFEAMOUNT, sintable[angle]);
2505 }
2506 }
2507
2508
2509 //******************************************************************************
2510 //
2511 // PollCyberman ()
2512 //
2513 //******************************************************************************
2514
PollCyberman(void)2515 void PollCyberman (void)
2516 {
2517 int i;
2518 int mask;
2519 int press;
2520
2521 SWIFT_Get3DStatus (&SWIFTStatus);
2522
2523 mask = 1<<(MAX_MOUSEBTN-1);
2524 for( i = 0; i < MAX_MOUSEBTN; i++, mask >>= 1 )
2525 {
2526 press = SWIFTStatus.buttons & mask;
2527
2528 if ( press )
2529 {
2530 // if ( ( buttonmouse[ i ] != bt_nobutton ) &&
2531 // ( DoubleClickCount[ i ] != 2 ) )
2532 if ( buttonmouse[ i ] != bt_nobutton )
2533 {
2534 buttonpoll[ buttonmouse[ i ] ] = true;
2535 }
2536 }
2537
2538 // Check double-click
2539 if ( buttonmouse[ i + MAX_MOUSEBTN ] != bt_nobutton )
2540 {
2541 if ( press )
2542 {
2543 // Was the button pressed last tic?
2544 if ( !DoubleClickPressed[ i ] )
2545 {
2546 // Yes, take note of it
2547 DoubleClickPressed[ i ] = true;
2548
2549 // Is this the first click, or a really late click?
2550 if ( ( DoubleClickCount[ i ] == 0 ) ||
2551 ( GetTicCount() >= DoubleClickTimer[ i ] ) )
2552 {
2553 // Yes, now wait for a second click
2554 DoubleClickTimer[ i ] = GetTicCount() + DoubleClickSpeed;
2555
2556 //( tics << 5 );
2557 DoubleClickCount[ i ] = 1;
2558 }
2559 else
2560 {
2561 // Second click
2562 buttonpoll[ buttonmouse[ i + MAX_MOUSEBTN ] ] = true;
2563 DoubleClickTimer[ i ] = 0;
2564 DoubleClickCount[ i ] = 2;
2565 }
2566 }
2567 else
2568 {
2569 // After second click, button remains pressed
2570 // until user releases it
2571 if ( DoubleClickCount[ i ] == 2 )
2572 {
2573 buttonpoll[ buttonmouse[ i + MAX_MOUSEBTN ] ] = true;
2574 }
2575 }
2576 }
2577 else
2578 {
2579 if ( DoubleClickCount[ i ] == 2 )
2580 {
2581 DoubleClickCount[ i ] = 0;
2582 }
2583 DoubleClickPressed[ i ] = false;
2584 }
2585 }
2586 }
2587
2588 if (SWIFTStatus.pitch > 0)
2589 CYBERLOOKUP = true;
2590 else if (SWIFTStatus.pitch < 0)
2591 CYBERLOOKDOWN = true;
2592
2593 if ((abs (SWIFTStatus.x)) > CYBERDEADRANGE)
2594 {
2595 CX = -(SGN (SWIFTStatus.x) * (( (abs(SWIFTStatus.x)-CYBERDEADRANGE) ) << 10));
2596 turnheldtime += tics;
2597 }
2598 else
2599 if (SWIFTStatus.x != oldcyberx)
2600 {
2601 turnheldtime += tics;
2602 if (SWIFTStatus.x > oldcyberx)
2603 CX = -(0xB8000);
2604 else
2605 CX = 0xB8000;
2606
2607 oldcyberx = SWIFTStatus.x;
2608 }
2609 else
2610 CX = 0;
2611
2612 if ((abs (SWIFTStatus.y)) > CYBERDEADRANGE)
2613 {
2614 CY = SWIFTStatus.y >> 2;
2615 }
2616 else
2617 CY = 0;
2618 }
2619
2620 //******************************************************************************
2621 //
2622 // PollAssassin ()
2623 //
2624 //******************************************************************************
2625
2626 #define MAXRAMPS 5
2627 typedef struct
2628 {
2629 int min;
2630 int factor;
2631 } RampType;
PollAssassin(void)2632 void PollAssassin (void)
2633 {
2634 int i;
2635 int mask;
2636 int press;
2637 int yaw;
2638 int strafeAngle;
2639 int acc;
2640 int numramps=4;
2641 RampType ramp[MAXRAMPS]={
2642 {0,280000},
2643 {4,380000},
2644 {10,480000},
2645 {25,680000},
2646 // {25,( (1<<26)/80 )}
2647 };
2648
2649 SWIFT_Get3DStatus (&SWIFTStatus);
2650
2651 mask = 1<<(MAX_MOUSEBTN-1);
2652 for( i = 0; i < MAX_MOUSEBTN; i++, mask >>= 1 )
2653 {
2654 press = SWIFTStatus.buttons & mask;
2655
2656 if ( press )
2657 {
2658 // if ( ( buttonmouse[ i ] != bt_nobutton ) &&
2659 // ( DoubleClickCount[ i ] != 2 ) )
2660 if ( buttonmouse[ i ] != bt_nobutton )
2661 {
2662 buttonpoll[ buttonmouse[ i ] ] = true;
2663 }
2664 }
2665
2666 // Check double-click
2667 if ( buttonmouse[ i + MAX_MOUSEBTN ] != bt_nobutton )
2668 {
2669 if ( press )
2670 {
2671 // Was the button pressed last tic?
2672 if ( !DoubleClickPressed[ i ] )
2673 {
2674 // Yes, take note of it
2675 DoubleClickPressed[ i ] = true;
2676
2677 // Is this the first click, or a really late click?
2678 if ( ( DoubleClickCount[ i ] == 0 ) ||
2679 ( GetTicCount() >= DoubleClickTimer[ i ] ) )
2680 {
2681 // Yes, now wait for a second click
2682 DoubleClickTimer[ i ] = GetTicCount() + DoubleClickSpeed;
2683
2684 //( tics << 5 );
2685 DoubleClickCount[ i ] = 1;
2686 }
2687 else
2688 {
2689 // Second click
2690 buttonpoll[ buttonmouse[ i + MAX_MOUSEBTN ] ] = true;
2691 DoubleClickTimer[ i ] = 0;
2692 DoubleClickCount[ i ] = 2;
2693 }
2694 }
2695 else
2696 {
2697 // After second click, button remains pressed
2698 // until user releases it
2699 if ( DoubleClickCount[ i ] == 2 )
2700 {
2701 buttonpoll[ buttonmouse[ i + MAX_MOUSEBTN ] ] = true;
2702 }
2703 }
2704 }
2705 else
2706 {
2707 if ( DoubleClickCount[ i ] == 2 )
2708 {
2709 DoubleClickCount[ i ] = 0;
2710 }
2711 DoubleClickPressed[ i ] = false;
2712 }
2713 }
2714 }
2715
2716 buttonpoll[bt_horizonup] |= ((SWIFTStatus.buttons>>7) & 1);
2717 buttonpoll[bt_horizondown] |= ((SWIFTStatus.buttons>>8) & 1);
2718
2719 if ( abs(SWIFTStatus.pitch) < (20<<6) )
2720 {
2721 SWIFTStatus.pitch = 0;
2722 }
2723 else
2724 {
2725 SWIFTStatus.pitch -= SGN(SWIFTStatus.pitch)*(20<<6);
2726 }
2727
2728 if ( abs(SWIFTStatus.pitch) > (60<<6) )
2729 {
2730 buttonpoll[bt_run] = 1;
2731 }
2732
2733 if ( abs(SWIFTStatus.roll) > (80<<6) )
2734 {
2735 buttonpoll[bt_run] = 1;
2736 }
2737
2738
2739 if ( abs(SWIFTStatus.roll) < (20<<6) )
2740 {
2741 SWIFTStatus.roll = 0;
2742 }
2743 else
2744 {
2745 SWIFTStatus.roll -= SGN(SWIFTStatus.roll)*(20<<6);
2746 }
2747
2748 strafeAngle = (player->angle - FINEANGLES/4)&(FINEANGLES-1);
2749
2750 controlbuf[0] += -(FixedMulShift (SWIFTStatus.pitch, viewcos,16))+
2751 FixedMulShift (-SWIFTStatus.roll, costable[strafeAngle], 16);
2752
2753 controlbuf[1] += FixedMulShift (SWIFTStatus.pitch, viewsin,16) -
2754 FixedMulShift (-SWIFTStatus.roll, sintable[strafeAngle], 16);
2755
2756 yaw = abs(SWIFTStatus.yaw);
2757 acc = 0;
2758 for (i=0;i<numramps;i++)
2759 {
2760 if (yaw > ramp[i].min)
2761 {
2762 if (i>0)
2763 {
2764 acc += ramp[i].min*(ramp[i].factor-ramp[i-1].factor);
2765 }
2766 }
2767 else
2768 {
2769 i++;
2770 break;
2771 }
2772 }
2773 controlbuf[2]= SWIFTStatus.yaw * ramp[i-1].factor - acc;
2774 }
2775
2776
2777 //******************************************************************************
2778 //
2779 // PollControls
2780 //
2781 // Gets user or demo input, call once each frame
2782 //
2783 // controlx set between -100 and 100 per tic
2784 // controly
2785 //
2786 //******************************************************************************
2787
2788
PollControls(void)2789 void PollControls (void)
2790 {
2791 int i;
2792
2793 if (standalone==true)
2794 return;
2795
2796 lastpolltime=controlupdatetime;
2797
2798 memset (buttonpoll, 0, sizeof(buttonpoll));
2799
2800 controlbuf[0] = controlbuf[1] = controlbuf[2] = 0;
2801 CYBERLOOKUP = CYBERLOOKDOWN = false;
2802
2803 if (gamestate.autorun==1)
2804 buttonpoll[bt_run] = true;
2805
2806
2807 //
2808 // get button states
2809 //
2810 PollKeyboardButtons ();
2811
2812 if (mouseenabled && !cybermanenabled)
2813 PollMouseButtons ();
2814
2815 if (joystickenabled)
2816 PollJoystickButtons ();
2817
2818
2819 //
2820 // get movements
2821 //
2822 if (joystickenabled)
2823 PollJoystickMove ();
2824
2825 if (cybermanenabled)
2826 PollCyberman ();
2827
2828 else if (mouseenabled && MousePresent)
2829 PollMouseMove ();
2830
2831 PollKeyboardMove ();
2832
2833 if (vrenabled)
2834 PollVirtualReality ();
2835
2836 PollMove ();
2837
2838 if (spaceballenabled)
2839 PollSpaceBall ();
2840
2841 else if (assassinenabled)
2842 PollAssassin ();
2843
2844
2845 buttonbits = 0;
2846 if (player->flags & FL_DYING) // Player has died
2847 {
2848 if ((playerdead==true) &&
2849 ( buttonpoll[ bt_strafe ] ||
2850 buttonpoll[ bt_attack ] ||
2851 buttonpoll[ bt_use ] ||
2852 ((gamestate.battlemode == battle_Hunter) &&
2853 (BATTLE_Team[player->dirchoosetime] == BATTLE_It)
2854 )
2855 )
2856 )
2857 {
2858 AddRespawnCommand();
2859 }
2860 memset (buttonpoll, 0, sizeof(buttonpoll));
2861 controlbuf[0] = controlbuf[1] = controlbuf[2] = 0;
2862 }
2863
2864 if ((PausePressed==true) && (modemgame==false))
2865 {
2866 PausePressed=false;
2867 if (GamePaused==true)
2868 AddPauseStateCommand(COM_UNPAUSE);
2869 else
2870 {
2871 AddPauseStateCommand(COM_PAUSE);
2872 }
2873 }
2874 if (Keyboard[sc_Insert] && Keyboard[sc_X])
2875 AddExitCommand();
2876
2877 for (i = (NUMTXBUTTONS-1); i >= 0; i--)
2878 {
2879 buttonbits <<= 1;
2880 if (buttonpoll[i])
2881 buttonbits |= 1;
2882 }
2883
2884 UpdateClientControls();
2885 }
2886
2887
ResetWeapons(objtype * ob)2888 void ResetWeapons(objtype *ob)
2889 {playertype *pstate;
2890
2891 M_LINKSTATE(ob,pstate);
2892
2893 pstate->weapondowntics = WEAPONS[pstate->weapon].screenheight/GMOVE;
2894 pstate->new_weapon = pstate->oldweapon;
2895 pstate->missileweapon = pstate->oldmissileweapon;
2896 ob->shapeoffset = pstate->oldshapeoffset;
2897 pstate->attackframe = pstate->weaponframe = 0;
2898
2899 if ((ob==player) && SHOW_BOTTOM_STATUS_BAR() )
2900 DrawBarAmmo (false);
2901 }
2902
2903
2904
2905
SaveWeapons(objtype * ob)2906 void SaveWeapons(objtype*ob)
2907 {playertype *pstate;
2908
2909 if ((ob->flags&FL_DOGMODE) || (ob->flags&FL_GODMODE))
2910 return;
2911
2912 //pstate = (ob==player)?(&playerstate):(&remoteplayerstate);
2913 M_LINKSTATE(ob,pstate);
2914
2915 pstate->weapondowntics = WEAPONS[pstate->weapon].screenheight/GMOVE;
2916 pstate->oldweapon = pstate->new_weapon;
2917 pstate->oldmissileweapon = pstate->missileweapon;
2918 pstate->oldshapeoffset = ob->shapeoffset;
2919
2920 }
2921
2922 /*
2923 void SaveWeapons(objtype*ob)
2924 {playertype *pstate;
2925
2926 if ((ob->flags&FL_DOGMODE) || (ob->flags&FL_GODMODE))
2927 return;
2928
2929 //pstate = (ob==player)?(&playerstate):(&remoteplayerstate);
2930 M_LINKSTATE(ob,pstate);
2931
2932 pstate->weapondowntics = WEAPONS[pstate->weapon].screenheight/GMOVE;
2933 pstate->oldweapon = pstate->weapon;
2934 pstate->oldmissileweapon = pstate->missileweapon;
2935 pstate->oldshapeoffset = ob->shapeoffset;
2936
2937 }
2938 */
2939
2940
2941 #define GiveProtection(flag,time,sound) \
2942 { \
2943 if ((ob->flags & flag) || (ob->flags & FL_GODMODE) || \
2944 (ob->flags & FL_DOGMODE)) \
2945 return; \
2946 ob->flags &= ~(FL_BPV|FL_GASMASK|FL_AV); \
2947 ob->flags |= flag; \
2948 SD_PlaySoundRTP(sound,ob->x, ob->y); \
2949 pstate->protectiontime = time; \
2950 gamestate.supercount ++; \
2951 }
2952
2953
2954
2955
GivePowerup(objtype * ob,int flag,int time,int sound)2956 boolean GivePowerup(objtype *ob,int flag,int time,int sound)
2957 {
2958 playertype *pstate;
2959
2960
2961 if ((ob->flags & flag) ||
2962 (ob->flags & FL_GODMODE) ||
2963 (ob->flags & FL_DOGMODE)
2964 )
2965 return false;
2966
2967
2968 M_LINKSTATE(ob,pstate);
2969
2970 /*
2971 if (ob->flags & FL_DOGMODE)
2972 {
2973 ob->temp2 = DOGMODERISE;
2974 ResetWeapons(ob);
2975 if (ob->state->condition & SF_DOGSTATE)
2976 NewState(ob,&s_player);
2977 }
2978 else if (ob->flags & FL_GODMODE)
2979 {
2980 ob->temp2 = GODMODEFALL;
2981 ResetWeapons(ob);
2982 }
2983 */
2984 ob->flags &= ~(FL_SHROOMS|FL_FLEET|FL_ELASTO|FL_GODMODE|FL_DOGMODE);
2985 ob->flags |= flag;
2986 pstate->poweruptime = time;
2987 pstate->soundtime = 0;
2988 SD_PlaySoundRTP(sound,ob->x, ob->y);
2989 gamestate.supercount ++;
2990 return true;
2991
2992 }
2993
2994
2995
GiveLifePoints(objtype * ob,int points)2996 void GiveLifePoints(objtype *ob,int points)
2997 {
2998 SD_PlaySoundRTP(SD_GETBONUSSND,ob->x, ob->y);
2999
3000 UpdateTriads (ob,points);
3001 if (ob==player)
3002 DrawTriads (false);
3003
3004 }
3005
3006
GiveBulletWeapon(objtype * ob,int bulletweapon,statobj_t * check)3007 boolean GiveBulletWeapon(objtype *ob,int bulletweapon,statobj_t*check)
3008 {
3009 playertype *pstate;
3010
3011 M_LINKSTATE(ob,pstate);
3012
3013 if ((ob->flags & FL_DOGMODE) || (ob->flags & FL_GODMODE))
3014 return false;
3015
3016 if (!ARMED(ob->dirchoosetime))
3017 return false;
3018
3019 if (pstate->HASBULLETWEAPON[bulletweapon])
3020 return false;
3021
3022 GiveWeapon(ob,bulletweapon);
3023 if ( gamestate.BattleOptions.WeaponPersistence )
3024 {
3025 LASTSTAT->z = check->z;
3026 }
3027 SD_PlaySoundRTP(SD_GETWEAPONSND,ob->x, ob->y);
3028 return true;
3029
3030 }
3031
3032
GivePlayerMissileWeapon(objtype * ob,playertype * pstate,statobj_t * check)3033 boolean GivePlayerMissileWeapon(objtype *ob, playertype *pstate,
3034 statobj_t *check)
3035 {
3036 if ((ob->flags & FL_DOGMODE) || (ob->flags & FL_GODMODE))
3037 return false;
3038
3039
3040 if (!ARMED(ob->dirchoosetime))
3041 return false;
3042
3043 if ((GetWeaponForItem(check->itemnumber) == pstate->missileweapon) &&
3044 (check->ammo == stats[check->itemnumber].ammo) &&
3045 (pstate->ammo == stats[check->itemnumber].ammo)
3046 )
3047 return false;
3048
3049 SD_PlaySoundRTP(SD_GETWEAPONSND,ob->x, ob->y);
3050 GiveMissileWeapon(ob,GetWeaponForItem(check->itemnumber));
3051 if (gamestate.BattleOptions.WeaponPersistence)
3052 LASTSTAT->z = check->z;
3053
3054 gamestate.missilecount ++;
3055
3056 if (BATTLEMODE && (gamestate.BattleOptions.Ammo != bo_normal_shots))
3057 {if (gamestate.BattleOptions.Ammo == bo_one_shot)
3058 pstate->ammo = 1;
3059 else
3060 pstate->ammo = -1;
3061 }
3062 else
3063 pstate->ammo = check->ammo;
3064 if ((ob==player) && SHOW_BOTTOM_STATUS_BAR() )
3065 DrawBarAmmo (false);
3066
3067 return true;
3068
3069 }
3070
3071
3072 #define LocalBonusMessage(string) \
3073 { \
3074 if (ob == player) \
3075 AddMessage(string,MSG_BONUS); \
3076 }
3077 #define LocalBonus1Message(string) \
3078 { \
3079 if (ob == player) \
3080 AddMessage(string,MSG_BONUS1); \
3081 }
3082
3083
3084 /*
3085 =================================
3086 =
3087 = GetBonusTimeForItem
3088 =
3089 =================================
3090 */
3091
GetBonusTimeForItem(int itemnumber)3092 int GetBonusTimeForItem(int itemnumber)
3093 {
3094 specials *which;
3095
3096 if ( BATTLEMODE )
3097 {
3098 which = &gamestate.SpecialsTimes;
3099 }
3100 else
3101 {
3102 which = &CurrentSpecialsTimes;
3103 }
3104
3105 switch(itemnumber)
3106 {
3107 case stat_godmode:
3108 return which->GodModeTime;
3109
3110 case stat_dogmode:
3111 return which->DogModeTime;
3112
3113 case stat_mushroom:
3114 return which->ShroomsModeTime;
3115
3116 case stat_elastic:
3117 return which->ElastoModeTime;
3118
3119 case stat_asbesto:
3120 return which->AsbestosVestTime;
3121
3122 case stat_bulletproof:
3123 return which->BulletProofVestTime;
3124
3125 case stat_gasmask:
3126 return which->GasMaskTime;
3127
3128 case stat_fleetfeet:
3129 return which->MercuryModeTime;
3130 }
3131
3132 return -1;
3133
3134 }
3135
3136
3137
3138
3139 /*
3140 =================================
3141 =
3142 = GetRespawnTimeForItem
3143 =
3144 =================================
3145 */
3146
3147
3148
GetRespawnTimeForItem(int itemnumber)3149 int GetRespawnTimeForItem(int itemnumber)
3150 {
3151 switch(itemnumber)
3152 {
3153 case stat_godmode:
3154 return gamestate.SpecialsTimes.GodModeRespawnTime;
3155
3156 case stat_dogmode:
3157 return gamestate.SpecialsTimes.DogModeRespawnTime;
3158
3159 case stat_mushroom:
3160 return gamestate.SpecialsTimes.ShroomsModeRespawnTime;
3161
3162 case stat_elastic:
3163 return gamestate.SpecialsTimes.ElastoModeRespawnTime;
3164
3165 case stat_asbesto:
3166 return gamestate.SpecialsTimes.AsbestosVestRespawnTime;
3167
3168 case stat_bulletproof:
3169 return gamestate.SpecialsTimes.BulletProofVestRespawnTime;
3170
3171 case stat_gasmask:
3172 return gamestate.SpecialsTimes.GasMaskRespawnTime;
3173
3174 case stat_fleetfeet:
3175 return gamestate.SpecialsTimes.MercuryModeRespawnTime;
3176
3177 }
3178
3179 return gamestate.BattleOptions.RespawnTime * VBLCOUNTER;
3180
3181
3182 }
3183
3184
3185 /*
3186 ===================
3187 =
3188 = GetBonus
3189 =
3190 ===================
3191 */
GetBonus(objtype * ob,statobj_t * check)3192 void GetBonus (objtype*ob,statobj_t *check)
3193 {
3194 int heal;
3195 playertype * pstate;
3196 boolean randompowerup;
3197
3198 M_LINKSTATE(ob,pstate);
3199
3200 randompowerup=false;
3201
3202 randomlabel:
3203 switch (check->itemnumber)
3204 {
3205
3206 case stat_knifestatue:
3207 SD_PlaySoundRTP(SD_GETKNIFESND,ob->x, ob->y);
3208 if (ob==player)
3209 locplayerstate->HASKNIFE = 1;
3210 SD_PlaySoundRTP(PlayerSnds[locplayerstate->player], ob->x, ob->y);
3211 LocalBonusMessage("You found a knife.");
3212 break;
3213 case stat_pedgoldkey:
3214 LocalBonusMessage("You found the \\EGold key.");
3215 goto keys;
3216 case stat_pedsilverkey:
3217 LocalBonusMessage("You got the \\FSilver key.");
3218 goto keys;
3219 case stat_pedironkey:
3220 LocalBonusMessage("You got the \\8Iron key.");
3221 goto keys;
3222 case stat_pedcrystalkey:
3223 LocalBonusMessage("You got the \\4Oscuro key.");
3224 keys:
3225 GiveKey (check->itemnumber - stat_pedgoldkey);
3226 SD_PlaySoundRTP (SD_GETKEYSND,ob->x, ob->y);
3227 break;
3228 case stat_monkmeal:
3229 if (pstate->health == MaxHitpointsForCharacter(pstate))
3230 return;
3231 SD_PlaySoundRTP (SD_GETHEALTH1SND,ob->x, ob->y);
3232 LocalBonusMessage("You ate some Monk Meal.");
3233 HealPlayer (10,ob);
3234 gamestate.healthcount ++;
3235 break;
3236 case stat_monkcrystal1:
3237 if (pstate->health == MaxHitpointsForCharacter(pstate))
3238 return;
3239 SD_PlaySoundRTP (SD_GETHEALTH2SND,ob->x, ob->y);
3240 LocalBonusMessage("You picked up a small Monk Crystal.");
3241
3242 HealPlayer (10,ob);
3243 gamestate.healthcount ++;
3244 break;
3245 case stat_monkcrystal2:
3246 if (pstate->health == MaxHitpointsForCharacter(pstate))
3247 return;
3248 SD_PlaySoundRTP (SD_GETHEALTH2SND,ob->x, ob->y);
3249 LocalBonusMessage("You picked up a large Monk Crystal.");
3250
3251 HealPlayer (50,ob);
3252 gamestate.healthcount ++;
3253 break;
3254 case stat_priestporridge:
3255 if (pstate->health == MaxHitpointsForCharacter(pstate))
3256 return;
3257 SD_PlaySoundRTP (SD_GETHEALTH1SND,ob->x, ob->y);
3258 if (check->flags & FL_ACTIVE)
3259 {
3260 HealPlayer (50,ob);
3261 LocalBonusMessage("You ate some Priest Porridge Hot.");
3262 }
3263 else
3264 {
3265 HealPlayer (20,ob);
3266
3267 LocalBonusMessage("You ate some Priest Porridge.");
3268 }
3269 gamestate.healthcount ++;
3270 break;
3271
3272 case stat_healingbasin:
3273 if (pstate->health == MaxHitpointsForCharacter(pstate))
3274 return;
3275 SD_PlaySoundRTP (SD_GETHEALTH2SND,ob->x, ob->y);
3276 heal = 25 + (GameRandomNumber("GetBonus",0) >> 2);
3277 HealPlayer (heal,ob);
3278 LocalBonusMessage("You drank from the healing basin.");
3279
3280 gamestate.healthcount ++;
3281 gamestate.democraticcount ++;
3282 break;
3283
3284 case stat_oneup:
3285 if (abs(pstate->health - MaxHitpointsForCharacter(pstate))
3286 < (MaxHitpointsForCharacter(pstate)>>2) )
3287 {
3288 GiveLives(1);
3289 LocalBonusMessage("Extra Life!");
3290 }
3291 else
3292 {
3293 HealPlayer(MaxHitpointsForCharacter(pstate),ob);
3294 LocalBonusMessage("Full Health!");
3295 }
3296 SD_PlaySoundRTP(SD_GET1UPSND,ob->x, ob->y);
3297 break;
3298 case stat_threeup:
3299 if (abs(pstate->health - MaxHitpointsForCharacter(pstate))
3300 < (MaxHitpointsForCharacter(pstate)>>2) )
3301 {
3302 GiveLives(3);
3303 LocalBonusMessage("Three Extra Lives!");
3304
3305 }
3306 else
3307 {
3308 HealPlayer(MaxHitpointsForCharacter(pstate),ob);
3309 GiveLives(2);
3310 LocalBonusMessage("Full Health AND Two Extra Lives!");
3311
3312 }
3313 SD_PlaySoundRTP(SD_GET3UPSND,ob->x, ob->y);
3314 break;
3315
3316 case stat_scotthead:
3317 // Give Apogee's phone number as points
3318 GivePoints( 2764331 );
3319 LocalBonusMessage( "Whoa...Scott's Mystical Head!");
3320 LocalBonus1Message( "You get 2,764,331 points!");
3321 SD_PlaySoundRTP(SD_GETHEADSND,ob->x, ob->y);
3322 break;
3323
3324 case stat_twopistol:
3325 if (GiveBulletWeapon(ob,wp_twopistol,check)==false)
3326 return;
3327 LocalBonusMessage("You got an extra pistol.");
3328
3329 break;
3330 case stat_mp40:
3331 if (GiveBulletWeapon(ob,wp_mp40,check)==false)
3332 return;
3333 LocalBonusMessage("You picked up an MP40.");
3334
3335 break;
3336
3337 case stat_bazooka:
3338 if (GivePlayerMissileWeapon(ob,pstate,check)==false)
3339 return;
3340
3341 LocalBonusMessage("You bagged a bazooka!");
3342 break;
3343
3344 case stat_firebomb:
3345 if (GivePlayerMissileWeapon(ob,pstate,check)==false)
3346 return;
3347
3348 LocalBonusMessage("You found a Firebomb!");
3349 break;
3350
3351
3352 case stat_heatseeker:
3353 if (GivePlayerMissileWeapon(ob,pstate,check)==false)
3354 return;
3355
3356 LocalBonusMessage("You have a Heat-seeker!");
3357 break;
3358
3359
3360 case stat_drunkmissile:
3361 if (GivePlayerMissileWeapon(ob,pstate,check)==false)
3362 return;
3363
3364 LocalBonusMessage("You recovered a Drunk Missile!");
3365 break;
3366
3367 case stat_firewall:
3368 if (GivePlayerMissileWeapon(ob,pstate,check)==false)
3369 return;
3370
3371 LocalBonusMessage("You filched a FlameWall!");
3372 break;
3373
3374 case stat_splitmissile:
3375 if (GivePlayerMissileWeapon(ob,pstate,check)==false)
3376 return;
3377
3378 LocalBonusMessage("You snagged a Split Missile!");
3379 break;
3380
3381 case stat_kes:
3382 if (GivePlayerMissileWeapon(ob,pstate,check)==false)
3383 return;
3384
3385 LocalBonusMessage("You wield the Dark Staff!");
3386 break;
3387
3388 case stat_bat:
3389 if (GivePlayerMissileWeapon(ob,pstate,check)==false)
3390 return;
3391
3392 LocalBonusMessage("You picked up the Excalibat.");
3393 break;
3394
3395
3396 case stat_lifeitem1:
3397 GiveLifePoints(ob,1);
3398 if (timelimitenabled)
3399 timelimit+=(VBLCOUNTER);
3400
3401 break;
3402
3403 case stat_lifeitem2:
3404 GiveLifePoints(ob,5);
3405 if (timelimitenabled)
3406 timelimit+=(2*VBLCOUNTER);
3407 break;
3408
3409 case stat_lifeitem3:
3410 GiveLifePoints(ob,10);
3411 if (timelimitenabled)
3412 timelimit+=(5*VBLCOUNTER);
3413 break;
3414
3415 case stat_lifeitem4:
3416 GiveLifePoints(ob,25);
3417 if (timelimitenabled)
3418 timelimit+=(10*VBLCOUNTER);
3419 break;
3420
3421 case stat_random:
3422 switch (GameRandomNumber("GetBonus",0)>>6)
3423 {
3424 case 0:
3425 check->itemnumber=stat_godmode;
3426 break;
3427 case 1:
3428 check->itemnumber=stat_elastic;
3429 break;
3430 case 2:
3431 check->itemnumber=stat_dogmode;
3432 break;
3433 case 3:
3434 check->itemnumber=stat_mushroom;
3435 break;
3436 }
3437 randompowerup=true;
3438 LocalBonus1Message("Random powerup gives you . . .");
3439 goto randomlabel;
3440 break;
3441
3442 case stat_bulletproof:
3443 GiveProtection(FL_BPV, GetBonusTimeForItem(stat_bulletproof),
3444 SD_GETBVESTSND);
3445 LocalBonusMessage("Bulletproof Armor!");
3446
3447 goto drw;
3448
3449 case stat_gasmask:
3450 GiveProtection(FL_GASMASK, GetBonusTimeForItem(stat_gasmask),
3451 SD_GETMASKSND);
3452 LocalBonusMessage("You put on a Gas Mask.");
3453
3454 goto drw;
3455
3456 case stat_asbesto:
3457 GiveProtection(FL_AV,GetBonusTimeForItem(stat_asbesto),
3458 SD_GETAVESTSND);
3459 LocalBonusMessage("Asbestos Armor! Oh so itchy!");
3460
3461 goto drw;
3462
3463 case stat_elastic:
3464 if (GivePowerup(ob,FL_ELASTO,GetBonusTimeForItem(stat_elastic),
3465 SD_GETELASTSND) == false)
3466 return;
3467 LocalBonusMessage("Elasto Mode!");
3468
3469 ob->flags |= FL_NOFRICTION;
3470 goto drw;
3471
3472 case stat_fleetfeet:
3473 if (GivePowerup(ob,FL_FLEET,GetBonusTimeForItem(stat_fleetfeet),
3474 SD_GETFLEETSND) == false)
3475 return;
3476
3477 LocalBonus1Message("Mercury Mode!");
3478 LocalBonusMessage("Press Look Up and Down to fly.");
3479
3480 ob->flags &= ~FL_NOFRICTION;
3481 goto drw;
3482
3483
3484 case stat_mushroom:
3485 if (GivePowerup(ob,FL_SHROOMS,GetBonusTimeForItem(stat_mushroom),
3486 SD_GETSHROOMSSND) == false)
3487 return;
3488 LocalBonusMessage("Shrooms Mode!");
3489
3490 ob->flags &= ~FL_NOFRICTION;
3491 gamestate.democraticcount ++;
3492 goto drw;
3493
3494
3495 case stat_godmode:
3496
3497 if (ob->flags & FL_GODMODE)
3498 return;
3499
3500 if (!ARMED(ob->dirchoosetime))
3501 return;
3502
3503 ob->flags &= ~FL_NOFRICTION;
3504
3505 if (ob->flags & FL_DOGMODE)
3506 {
3507 ob->temp2 = DOGMODERISE;
3508 ResetWeapons(ob);
3509 if (ob->state->condition & SF_DOGSTATE)
3510 NewState(ob,&s_player);
3511 }
3512
3513 SaveWeapons(ob);
3514 SpawnNewObj(ob->tilex,ob->tiley,&s_flash1,inertobj);
3515 new->flags |= FL_ABP;
3516 new->x = new->drawx = ob->x;
3517 new->y = new->drawy = ob->y;
3518 MakeActive(new);
3519 new->z = ob->z;
3520
3521
3522 SetPlayerHorizon(pstate,GODYZANGLE);
3523
3524 ob->flags &= ~(FL_GODMODE|FL_SHROOMS|FL_ELASTO|FL_FLEET|FL_DOGMODE);
3525 ob->flags |= FL_GODMODE;
3526 ob->temp2 = GODMODERISE;
3527 pstate->poweruptime = GetBonusTimeForItem(stat_godmode);
3528 pstate->soundtime = 0;
3529 GiveMissileWeapon(ob,wp_godhand);
3530 SD_PlaySoundRTP(SD_GETGODSND,ob->x, ob->y);
3531 gamestate.supercount ++;
3532 LocalBonusMessage("God Mode!");
3533
3534 goto drw;
3535
3536
3537 #if (SHAREWARE == 0)
3538 case stat_dogmode:
3539 if (ob->flags & FL_DOGMODE)
3540 return;
3541
3542 if (!ARMED(ob->dirchoosetime))
3543 return;
3544
3545 ob->flags &= ~FL_NOFRICTION;
3546
3547 if (ob->flags & FL_GODMODE)
3548 {
3549 ob->temp2 = GODMODEFALL;
3550 ResetWeapons(ob);
3551 }
3552
3553
3554 SaveWeapons(ob);
3555 ob->shapeoffset = 0;
3556 NewState(ob,&s_serialdog);
3557
3558 SpawnNewObj(ob->tilex,ob->tiley,&s_flash1,inertobj);
3559 new->flags |= FL_ABP;
3560 new->x = new->drawx = ob->x;
3561 new->y = new->drawy = ob->y;
3562 MakeActive(new);
3563 new->z = ob->z;
3564
3565 SetPlayerHorizon(pstate,DOGYZANGLE);
3566
3567 ob->flags &= ~(FL_DOGMODE|FL_SHROOMS|FL_ELASTO|FL_FLEET|FL_GODMODE);
3568 ob->flags |= FL_DOGMODE;
3569 ob->temp2 = DOGMODEFALL;
3570 pstate->poweruptime = GetBonusTimeForItem(stat_dogmode);
3571 pstate->soundtime = 0;
3572 GiveMissileWeapon(ob,wp_dog);
3573 SD_PlaySoundRTP(SD_GETDOGSND,ob->x, ob->y);
3574 gamestate.supercount ++;
3575 LocalBonusMessage("Dog Mode!");
3576
3577 goto drw;
3578 #endif
3579
3580 drw:
3581
3582 if (ob==player)
3583 GM_DrawBonus (check->itemnumber);
3584
3585 break;
3586
3587 case stat_dipball1:
3588 case stat_dipball2:
3589 case stat_dipball3:
3590 SD_PlaySoundRTP(SD_GETBONUSSND,ob->x, ob->y);
3591 gamestate.dipballs++;
3592 LocalBonusMessage("You discovered a Developer Ball!");
3593
3594 break;
3595
3596 case stat_collector:
3597 if (gamestate.battlemode==battle_CaptureTheTriad)
3598 {if (pstate->team == check->hitpoints)
3599 return;
3600 ob->flags |= FL_DESIGNATED;
3601 UpdateKills = true;
3602 LocalBonusMessage( "You picked up a triad! RUN!!!");
3603 }
3604 else
3605 BATTLE_CheckGameStatus(battle_get_collector_item,ob->dirchoosetime);
3606
3607 SD_PlaySoundRTP(SD_GETBONUSSND,ob->x, ob->y);
3608 break;
3609 #if (SHAREWARE == 0)
3610 case stat_mine:
3611 SpawnNewObj(check->tilex,check->tiley,&s_grexplosion1,inertobj);
3612 new->flags |= FL_ABP;
3613 new->whatever = check;
3614 new->temp2 = 100;
3615 MakeActive(new);
3616 SD_PlaySoundRTP(SD_EXPLODESND,check->x,check->y);
3617 break;
3618 #endif
3619 default:
3620 SD_PlaySoundRTP(SD_GETHEADSND,ob->x, ob->y);
3621 break;
3622 }
3623 //StartBonusFlash ();
3624 if (check->flags & FL_CHANGES)
3625 {
3626 switch (check->itemnumber)
3627 {
3628 case stat_pedgoldkey:
3629 case stat_pedsilverkey:
3630 case stat_pedironkey:
3631 case stat_pedcrystalkey:
3632 check->itemnumber = stat_emptypedestal;
3633 check->shapenum = stats[stat_emptypedestal].picnum;
3634 check->flags = stats[stat_emptypedestal].flags|FL_ABP;
3635 check->count = 0;
3636 check->numanims = 0;
3637 break;
3638 case stat_healingbasin:
3639 check->itemnumber = stat_emptybasin;
3640 check->shapenum = stats[stat_emptybasin].picnum;
3641 check->flags = stats[stat_emptybasin].flags|FL_ABP;
3642 check->count = 0;
3643 check->numanims = 0;
3644 break;
3645 /*
3646 case stat_tablebullets:
3647 check->itemnumber = stat_emptytable;
3648 check->shapenum = stats[stat_emptytable].picnum;
3649 check->flags = stats[stat_emptytable].flags|FL_ABP;
3650 break;
3651 case stat_statuewithpole:
3652 check->itemnumber = stat_armornopole;
3653 check->shapenum = stats[stat_armornopole].picnum;
3654 check->flags = stats[stat_armornopole].flags|FL_ABP;
3655 break; */
3656 case stat_pit:
3657 check->shapenum ++;
3658 check->flags &= ~FL_CHANGES;
3659 check->flags &= ~FL_BONUS;
3660 break;
3661 case stat_knifestatue:
3662 check->itemnumber = stat_emptystatue;
3663 check->shapenum = stats[stat_emptystatue].picnum;
3664 check->flags = stats[stat_emptystatue].flags|FL_ABP;
3665 break;
3666
3667 default:
3668 ;
3669 }
3670 }
3671 else
3672 {if (check == sprites[check->tilex][check->tiley])
3673 {
3674 statobj_t *checkstat;
3675
3676 checkstat = (statobj_t*)DiskAt(check->tilex,check->tiley);
3677 if (checkstat && (checkstat->which == SPRITE))
3678 sprites[check->tilex][check->tiley] = checkstat;
3679 else
3680 sprites[check->tilex][check->tiley] = NULL;
3681 }
3682
3683 if (randompowerup==true)
3684 check->itemnumber = stat_random;
3685 RemoveStatic(check);
3686 }
3687 }
3688
3689
3690 /*
3691 ===================
3692 =
3693 = DropWeapon
3694 =
3695 ===================
3696 */
3697
DropWeapon(objtype * ob)3698 void DropWeapon(objtype *ob)
3699 {playertype *pstate;
3700 int dtilex,dtiley;
3701
3702
3703
3704 M_LINKSTATE(ob,pstate);
3705
3706 if ((pstate->missileweapon == -1) || (pstate->missileweapon == wp_godhand)
3707 #if (SHAREWARE == 0)
3708 || (pstate->missileweapon == wp_dog)
3709 #endif
3710 )
3711 return;
3712
3713 pstate->weapondowntics = WEAPONS[pstate->weapon].screenheight/3;
3714 pstate->new_weapon = pstate->bulletweapon;
3715
3716 dtilex = ob->tilex;
3717 dtiley = ob->tiley;
3718
3719 FindEmptyTile(&dtilex, &dtiley);
3720
3721
3722 SpawnStatic(dtilex,dtiley,GetItemForWeapon(pstate->missileweapon),9);
3723 gamestate.missiletotal ++;
3724
3725 LASTSTAT->ammo = pstate->ammo;
3726 LASTSTAT->flags |= FL_ABP;
3727 LASTSTAT->flags &= ~FL_RESPAWN;
3728 MakeStatActive(LASTSTAT);
3729 pstate->weaponx = ob->tilex;
3730 pstate->weapony = ob->tiley;
3731 pstate->ammo = -1;
3732 pstate->missileweapon = -1;
3733 if ((ob==player) && SHOW_BOTTOM_STATUS_BAR() )
3734 DrawBarAmmo (false);
3735 }
3736
3737
3738 /*
3739 ===================
3740 =
3741 = Thrust
3742 =
3743 ===================
3744 */
3745
Thrust(objtype * ob)3746 void Thrust ( objtype * ob )
3747 {statobj_t *tstat;
3748 int dx,dy,dz,rad,index,otherteam;
3749 objtype*temp;
3750 playertype * pstate;
3751
3752 PlayerMove(ob);
3753 M_LINKSTATE(ob,pstate);
3754
3755 if ((gamestate.battlemode == battle_CaptureTheTriad) &&
3756 (ob->flags & FL_DESIGNATED) &&
3757 (ob->tilex == TEAM[pstate->team].tilex) &&
3758 (ob->tiley == TEAM[pstate->team].tiley))
3759 {if (ob == player)
3760 SD_Play(PlayerSnds[locplayerstate->player]);
3761
3762 if (BATTLE_CheckGameStatus(battle_captured_triad,ob->dirchoosetime)==
3763 battle_no_event)
3764 {
3765 ob->flags &= ~FL_DESIGNATED;
3766 UpdateKills = true;
3767 otherteam = (pstate->team ^ 1);
3768 SpawnStatic(TEAM[otherteam].tilex,TEAM[otherteam].tiley,stat_collector,9);
3769 LASTSTAT->flags |= FL_COLORED;
3770 LASTSTAT->hitpoints = otherteam;
3771 LASTSTAT->flags |= FL_ABP;
3772 MakeStatActive(LASTSTAT);
3773 }
3774 return;
3775 }
3776
3777 if ((ob->tilex != pstate->weaponx) || (ob->tiley != pstate->weapony))
3778 pstate->weaponx = pstate->weapony = 0;
3779
3780 index = touchindices[ob->tilex][ob->tiley];
3781 if (index && (abs(ob->z - nominalheight) < 5))
3782 {if (!TRIGGER[index-1])
3783 {if (touchplate[index-1]->complete)
3784 SD_PlaySoundRTP(SD_BADTOUCHSND,ob->x,ob->y);
3785 else
3786 {
3787 SD_PlaySoundRTP(SD_TOUCHPLATESND,ob->x,ob->y);
3788 if (ob == player)
3789 AddMessage("Touchplate triggered.",MSG_GAME); }
3790 }
3791 TRIGGER[index-1] = 1;
3792 }
3793
3794 tstat = sprites[ob->tilex][ob->tiley];
3795 if (tstat)
3796
3797 {dx = abs(ob->x - tstat->x);
3798 dy = abs(ob->y - tstat->y);
3799 dz = abs(ob->z - tstat->z);
3800 if ((dx < 0x8000) && (dy < 0x8000) && (dz<=35))
3801 {
3802 #define OBJECT_IS_BONUS( tstat ) ( ( tstat )->flags & FL_BONUS )
3803 #define PLAYER_IS_SWITCHING_WEAPONS( pstate ) ( W_CHANGE( pstate ) )
3804 //#define IS_ATTACKING( ob ) ( ( ( ob )->state->think == T_Attack ) || ( ( ob )->state->think == T_BatBlast ) )
3805 #define IS_WEAPON( tstat ) ( ( tstat )->flags & FL_WEAPON )
3806 #define PLAYER_MAY_NOT_GET_WEAPON( pstate, ob ) ( PLAYER_IS_SWITCHING_WEAPONS( pstate ))// || IS_ATTACKING( ob ) )
3807 #define OK_TO_PICK_UP( tstat, pstate, ob ) ( !( IS_WEAPON( tstat ) && PLAYER_MAY_NOT_GET_WEAPON( pstate, ob ) ) )
3808 #define WHERE_PLAYER_DROPPED_WEAPON( ob, pstate ) ( ( ( ob )->tilex == ( pstate )->weaponx ) && ( ( ob )->tiley == ( pstate )->weapony ) )
3809
3810 if ( OBJECT_IS_BONUS( tstat ) &&
3811 OK_TO_PICK_UP( tstat, pstate, ob ) &&
3812 (!WHERE_PLAYER_DROPPED_WEAPON( ob, pstate ))
3813 )
3814 {
3815 GetBonus(ob,tstat);
3816 if (PLAYER_IS_SWITCHING_WEAPONS( pstate ))
3817 {statetype *nstate;
3818 #if (SHAREWARE == 0)
3819 if (ob->state->condition & SF_DOGSTATE)
3820 nstate = &s_serialdog;
3821 else
3822 #endif
3823 nstate = &s_player;
3824 pstate->attackframe = pstate->weaponframe = pstate->batblast = 0;
3825 NewState(ob,nstate);
3826 }
3827
3828
3829 }
3830 else if ((tstat->itemnumber == stat_pit) &&
3831 (ob->temp2 != PITFALL) &&
3832 (!(ob->flags & FL_FLEET))
3833 )
3834 {ob->temp2 = PITFALL;
3835 ob->momentumx = ob->momentumy = 0;
3836 //ob->momentumz = 4;
3837 ob->momentumz = GRAVITY;
3838
3839 if (ob->whatever == NULL)
3840 {ob->whatever = tstat;
3841 SD_PlaySoundRTP(SD_PITTRAPSND,ob->x,ob->y);
3842 tstat->shapenum = stats[tstat->itemnumber].picnum + 1;
3843 MakeStatInactive(tstat);
3844 //tstat->flags &= ~FL_ABP;
3845 }
3846 }
3847 else if ((tstat->itemnumber == stat_heatgrate) &&
3848 (!(ob->flags & FL_DYING)) && (!(ob->flags & FL_AV))
3849 )
3850 {DamageThing(ob,1);
3851 Collision(ob,(objtype*)tstat,0,0);
3852 M_CheckPlayerKilled(ob);
3853 }
3854
3855
3856 }
3857 }
3858
3859 //================ Check special player/actor links ======================
3860
3861 if (ob->whatever)
3862 {temp = (objtype*)(ob->whatever);
3863
3864 dx = abs(ob->x - temp->x);
3865 dy = abs(ob->y - temp->y);
3866 dz = abs(ob->z - temp->z);
3867 if (ob->flags & FL_RIDING)
3868 rad = MINACTORDIST;
3869 else
3870 rad = 0x8000;
3871
3872 if ((dx >rad) || (dy > rad) || (dz > 64))
3873 {
3874 if ((temp->obclass == bladeobj) || (temp->obclass == diskobj))
3875 {temp->whatever = NULL;
3876 ob->flags &= ~FL_RIDING;
3877 }
3878
3879 else if (ob->temp2 == COLUMNCRUSH)
3880 ob->temp2 = RENORMALIZE;
3881 else if (ob->z < nominalheight)
3882 ob->momentumz = 40000;
3883 else if (temp->which == SPRITE)
3884 {tstat = (statobj_t*)(ob->whatever);
3885 MakeStatActive(tstat);
3886 SetNormalHorizon(ob);
3887 }
3888 ob->whatever = NULL;
3889 }
3890 }
3891
3892 //=========================================================================
3893
3894
3895 if (BATTLEMODE && (MAPSPOT(ob->tilex,ob->tiley,1) == EXITTILE))
3896 {
3897 Move_Player_From_Exit_To_Start(ob);
3898 return;
3899 }
3900
3901 if (ob==player)
3902 {
3903 if (MAPSPOT(ob->tilex,ob->tiley,1) == EXITTILE)
3904 playstate=ex_completed;
3905 else if ( ( MAPSPOT( ob->tilex, ob->tiley, 2 ) & 0xff00 ) == 0xe400 )
3906 playstate = ex_secretdone;
3907 else if (MAPSPOT(ob->tilex,ob->tiley,1) == SECRETEXITTILE)
3908 playstate=ex_secretlevel;
3909 }
3910 }
3911
3912
3913
Move_Player_From_Exit_To_Start(objtype * ob)3914 void Move_Player_From_Exit_To_Start(objtype *ob)
3915 {
3916 int i = 0,oldarea,newarea;
3917 objtype *tplayer;
3918 int travelangle,dangle;
3919 playertype *pstate;
3920
3921 M_LINKSTATE(ob,pstate);
3922
3923
3924 oldarea = ob->areanumber;
3925 newarea = AREANUMBER(FIRST.x,FIRST.y);
3926 if (oldarea != newarea)
3927 {
3928 RemoveFromArea(ob);
3929 ob->areanumber = newarea;
3930 MakeLastInArea(ob);
3931 }
3932
3933 SetTilePosition(ob,FIRST.x,FIRST.y);
3934 ob->z = PlatformHeight(ob->tilex,ob->tiley);
3935 if ((ob->z == -10) || DiskAt(ob->tilex,ob->tiley))
3936 ob->z = 0;
3937
3938 ConnectAreas();
3939 travelangle = atan2_appx(ob->momentumx,ob->momentumy);
3940 dangle = ob->angle - travelangle;
3941
3942 ob->angle = (1-FIRST.dir)*ANG90 + dangle;
3943 Fix(ob->angle);
3944
3945 ob->dir = angletodir[ob->angle];
3946 pstate->anglefrac= (ob->angle<<ANGLEBITS);
3947 pstate->angle=0;
3948
3949
3950 for(i=0;i<numplayers;i++)
3951 {
3952 tplayer = PLAYER[i];
3953
3954 if (ob == tplayer)
3955 continue;
3956
3957 if (
3958 (tplayer->tilex == FIRST.x) &&
3959 (tplayer->tiley == FIRST.y) &&
3960 (!(tplayer->flags & FL_DYING))
3961 )
3962 {
3963 playertype *pstate;
3964
3965 M_LINKSTATE(tplayer,pstate);
3966
3967 pstate->health = tplayer->hitpoints = 0;
3968 tplayer->flags |= FL_HBM;
3969 Collision(tplayer,ob,0,0);
3970 BATTLE_PlayerKilledPlayer(battle_kill_by_crushing,ob->dirchoosetime,tplayer->dirchoosetime);\
3971
3972 }
3973 }
3974
3975
3976 }
3977
3978
3979
PlayerSlideMove(objtype * ob)3980 void PlayerSlideMove(objtype * ob)
3981 {int tryx, tryy, tryz;
3982
3983 tryx = ob->x + ob->momentumx;
3984 tryy = ob->y + ob->momentumy;
3985 tryz = ob->z + (ob->momentumz >> 16);
3986
3987 if (ActorTryMove(ob,ob->x,tryy,tryz))
3988 {
3989 if (ob->momentumx>HITWALLSPEED)
3990 SD_PlaySoundRTP(SD_HITWALLSND,ob->x,ob->y);
3991 ob->momentumx=0;
3992 }
3993 else if (ActorTryMove(ob,tryx,ob->y,tryz))
3994 {
3995 if (ob->momentumy>HITWALLSPEED)
3996 SD_PlaySoundRTP(SD_HITWALLSND,ob->x,ob->y);
3997 ob->momentumy=0;
3998 }
3999 else
4000 {
4001 if (FindDistance(ob->momentumx,ob->momentumy)>(HITWALLSPEED*3/2))
4002 SD_PlaySoundRTP(SD_HITWALLSND,ob->x,ob->y);
4003 ob->momentumx=0;
4004 ob->momentumy=0;
4005 }
4006 }
4007
4008 /*
4009 ===================
4010 =
4011 = SetNormalHorizon
4012 =
4013 ===================
4014 */
4015
SetNormalHorizon(objtype * ob)4016 void SetNormalHorizon (objtype * ob)
4017 {
4018 playertype * pstate;
4019
4020 M_LINKSTATE(ob,pstate);
4021
4022 if (ob->flags&FL_DOGMODE)
4023 {
4024 SetPlayerHorizon(pstate,DOGYZANGLE);
4025 }
4026 else if (ob->flags&FL_GODMODE)
4027 {
4028 SetPlayerHorizon(pstate,GODYZANGLE);
4029 }
4030 else
4031 {
4032 SetPlayerHorizon(pstate,NORMALYZANGLE);
4033 }
4034 }
4035
4036 /*
4037 ===================
4038 =
4039 = PlayerTiltHead
4040 =
4041 ===================
4042 */
4043
PlayerTiltHead(objtype * ob)4044 void PlayerTiltHead (objtype * ob)
4045 {
4046 playertype * pstate;
4047 int dyz=0;
4048 int yzangle;
4049
4050 M_LINKSTATE(ob,pstate);
4051
4052 yzangle=ob->yzangle+HORIZONYZOFFSET;
4053 Fix(yzangle);
4054
4055 if (
4056 (pstate->lastmomz!=ob->momentumz) &&
4057 (ob->momentumz==0) &&
4058 (
4059 (!(ob->flags&FL_FLEET)) ||
4060 (
4061 (ob->flags&FL_FLEET) &&
4062 (ob->z==nominalheight)
4063 )
4064 )
4065 )
4066 SetNormalHorizon(ob);
4067
4068 pstate->lastmomz=ob->momentumz;
4069
4070 if (ob->flags&FL_SHROOMS)
4071 {
4072 ob->yzangle = FixedMulShift(SHROOMYZANGLE,sintable[(oldpolltime<<6)&(FINEANGLES-1)],16);
4073 Fix(ob->yzangle);
4074 return;
4075 }
4076 else if (pstate->guntarget)
4077 {
4078 int dx,dy,dz;
4079 int xydist;
4080 int yzangle;
4081
4082 dx = ob->x - pstate->guntarget->x;
4083 dy = ob->y - pstate->guntarget->y;
4084 xydist = FindDistance(dx,dy)-0x8000;
4085 if (ob->z==pstate->guntarget->z)
4086 dz = 0;
4087 else
4088 {
4089 dz = (ob->z-pstate->guntarget->z)<<10;
4090 }
4091 yzangle = atan2_appx(xydist,dz);
4092
4093 yzangle += HORIZONYZOFFSET;
4094 Fix(yzangle);
4095 SetPlayerHorizon(pstate,yzangle-HORIZONYZOFFSET);
4096
4097 if (oldpolltime>pstate->targettime)
4098 {
4099 if (pstate->guntarget)
4100 pstate->guntarget->flags &= ~FL_TARGET;
4101 pstate->guntarget=NULL;
4102 SetNormalHorizon(ob);
4103 }
4104 }
4105 else
4106 {
4107 if (pstate->buttonstate[bt_horizonup])
4108 {
4109 if (yzangle!=pstate->horizon)
4110 {
4111 SetPlayerHorizon(pstate,yzangle-HORIZONYZOFFSET);
4112 }
4113 else
4114 {
4115 SetPlayerHorizon(pstate,(pstate->horizon-HORIZONYZOFFSET+YZHORIZONSPEED));
4116 }
4117 }
4118 else if (pstate->buttonstate[bt_horizondown])
4119 {
4120 if (yzangle!=pstate->horizon)
4121 {
4122 SetPlayerHorizon(pstate,yzangle-HORIZONYZOFFSET);
4123 }
4124 else
4125 {
4126 SetPlayerHorizon(pstate,(pstate->horizon-HORIZONYZOFFSET-YZHORIZONSPEED));
4127 }
4128 }
4129 if (pstate->buttonstate[bt_lookup] || CYBERLOOKUP)
4130 {
4131 if (!(ob->flags & FL_FLEET))
4132 {
4133 dyz=YZTILTSPEED;
4134 if (pstate->buttonstate[bt_lookdown] || CYBERLOOKDOWN)
4135 {
4136 dyz=0;
4137 }
4138
4139 SetNormalHorizon(ob);
4140 }
4141 }
4142 if (pstate->buttonstate[bt_lookdown] || CYBERLOOKDOWN)
4143 {
4144 if (!(ob->flags & FL_FLEET))
4145 {
4146 dyz=-YZTILTSPEED;
4147 if (pstate->buttonstate[bt_lookup] || CYBERLOOKUP)
4148 {
4149 dyz=0;
4150 }
4151 SetNormalHorizon(ob);
4152 }
4153 }
4154 if (!(ob->flags&FL_DOGMODE) &&
4155 !(ob->flags&FL_GODMODE) &&
4156 !(ob->flags&FL_FLEET) &&
4157 !(ob->flags&FL_RIDING) &&
4158 (ob->momentumz > (GRAVITY<<1))//(ob->momentumz>0x1000)
4159 )
4160 {
4161 SetPlayerHorizon(pstate,FALLINGYZANGLE);
4162 }
4163 }
4164
4165
4166
4167 if ((yzangle!=pstate->horizon) && (dyz==0))
4168 {
4169 int speed;
4170
4171 speed=SNAPBACKSPEED;
4172 if (yzangle<pstate->horizon)
4173 yzangle+=speed;
4174 else
4175 yzangle-=speed;
4176 if ((abs(yzangle-pstate->horizon))<SNAPBACKSPEED)
4177 yzangle=pstate->horizon;
4178 }
4179 yzangle+=dyz;
4180 if (yzangle-HORIZONYZOFFSET>YZANGLELIMIT)
4181 yzangle=HORIZONYZOFFSET+YZANGLELIMIT;
4182 else if (yzangle-HORIZONYZOFFSET<-YZANGLELIMIT)
4183 yzangle=HORIZONYZOFFSET-YZANGLELIMIT;
4184
4185 ob->yzangle=yzangle-HORIZONYZOFFSET;
4186 Fix(ob->yzangle);
4187 }
4188
4189 /*
4190 ===================
4191 =
4192 = UpdatePlayers
4193 =
4194 ===================
4195 */
UpdatePlayers(void)4196 void UpdatePlayers ( void )
4197 {
4198 objtype * obj;
4199 // playertype * pstate;
4200
4201 for (obj = FIRSTACTOR; obj->obclass==playerobj; obj = obj->next)
4202 {
4203 obj->speed=FindDistance(obj->momentumx, obj->momentumy);
4204 // M_LINKSTATE(obj,pstate);
4205 // pstate->steptime-=obj->speed;
4206 // if (pstate->steptime<0)
4207 // {
4208 // while (pstate->steptime<0)
4209 // pstate->steptime+=PLAYERSTEPTIME;
4210 // pstate->stepwhich^=1;
4211 // SD_PlaySoundRTP(SD_WALK1SND+pstate->stepwhich,obj->x,obj->y);
4212 // }
4213 }
4214 }
4215
4216
4217 /*
4218 ===================
4219 =
4220 = PlayerMove
4221 =
4222 ===================
4223 */
4224
PlayerMove(objtype * ob)4225 void PlayerMove ( objtype * ob )
4226 {playertype *pstate;
4227
4228 M_LINKSTATE(ob,pstate);
4229 if (ob->flags & FL_FLEET)
4230 CheckFlying(ob,pstate);
4231 ActorMovement(ob);
4232 pstate->anglefrac = (pstate->anglefrac+pstate->angle)&((FINEANGLES<<ANGLEBITS)-1);
4233 ob->angle = (pstate->anglefrac >> ANGLEBITS);
4234 ob->dir = angletodir[ob->angle];
4235 if (ob==player)
4236 UpdateLightLevel(player->areanumber);
4237
4238 PlayerTiltHead(ob);
4239
4240 if (IsWindow(ob->tilex,ob->tiley))
4241 {
4242 if (!(ob->flags & FL_DYING))
4243 {
4244 pstate->health = 0;
4245 pstate->falling=true;
4246 if ((ob->flags & FL_GODMODE) || (ob->flags & FL_DOGMODE) ||
4247 (gamestate.battlemode == battle_Eluder) || (godmode==true))
4248 {
4249 KillActor(ob);
4250 NewState(ob,&s_remotedie1);
4251 }
4252 else
4253 Collision(ob,(objtype*)NULL,0,0);
4254 ob->flags |= FL_DYING;
4255 M_CheckPlayerKilled(ob);
4256 }
4257 }
4258 }
4259
4260 /*
4261 ===============
4262 =
4263 = T_Tag
4264 =
4265 ===============
4266 */
4267
T_Tag(objtype * ob)4268 void T_Tag (objtype *ob)
4269 {
4270 playertype *pstate;
4271
4272 CheckPlayerSpecials(ob);
4273 //CheckWeaponStates(ob);
4274 M_LINKSTATE(ob,pstate);
4275 Thrust(ob);
4276
4277 if (ob->ticcount > 4)
4278 pstate->weaponheight -= GMOVE;
4279 else
4280 pstate->weaponheight += GMOVE;
4281
4282 if ((ob->ticcount > 1) && (ob->ticcount < 8) && (!(ob->flags & FL_DIDTAG)))
4283 {int i,dx,dy,magangle;
4284
4285 for(i=0;i<numplayers;i++)
4286 {if (PLAYER[i] == ob)
4287 continue;
4288
4289 dx = abs(PLAYER[i]->x - ob->x);
4290 dy = abs(PLAYER[i]->y - ob->y);
4291 if ((dx > 0xc000) || (dy > 0xc000))
4292 continue;
4293 magangle = abs(ob->angle - AngleBetween(ob,PLAYER[i]));
4294 if (magangle > VANG180)
4295 magangle = ANGLES - magangle;
4296
4297 if (magangle > ANGLES/8)
4298 continue;
4299 CheckTagGame(ob,PLAYER[i]);
4300 break;
4301 }
4302
4303 }
4304
4305
4306 //Commented out until we find if it's valid
4307 /*
4308 if (!ob->ticcount)
4309 {if ( pstate->buttonstate[bt_use] && !pstate->buttonheld[bt_use] )
4310 pstate->buttonstate[bt_use] = false;
4311 if ( pstate->buttonstate[bt_attack] && !pstate->buttonheld[bt_attack])
4312 pstate->buttonstate[bt_attack] = false;
4313 }
4314 */
4315 }
4316
4317 #if (SHAREWARE == 0)
4318 #define GET_RESETSTATE(ob,resetstate) \
4319 { \
4320 if (ob->state->condition & SF_DOGSTATE) \
4321 resetstate = &s_serialdog; \
4322 else \
4323 resetstate = &s_player; \
4324 }
4325 #else
4326 #define GET_RESETSTATE(ob,resetstate) \
4327 { \
4328 resetstate = &s_player; \
4329 }
4330 #endif
4331
4332 /*
4333 ===============
4334 =
4335 = T_Attack
4336 =
4337 ===============
4338 */
4339
T_Attack(objtype * ob)4340 void T_Attack (objtype *ob)
4341 {
4342 attack_t *cur;
4343
4344 playertype *pstate;
4345 statetype *resetstate;
4346
4347
4348 Thrust(ob);
4349 if (ob->flags & FL_DYING)
4350 return;
4351
4352 resetstate = ob->state;
4353 CheckPlayerSpecials(ob);
4354 if (resetstate != ob->state)
4355 {
4356 return;
4357 }
4358
4359
4360 if ((ob->flags & FL_PAIN) && (!ob->ticcount))
4361 ob->flags &= ~FL_PAIN;
4362
4363 CheckWeaponStates(ob);
4364 M_LINKSTATE(ob,pstate);
4365 GET_RESETSTATE(ob,resetstate);
4366
4367
4368 if (ARMED(ob->dirchoosetime)
4369 //(gamestate.battlemode != battle_Tag)
4370 )
4371
4372 {
4373 if (pstate->weapondowntics == 1) // change to up; during change, up and down
4374 // are never zero at the same time
4375 {
4376 #if (SHAREWARE == 0)
4377 if (pstate->weapon == wp_kes)
4378 {
4379 pstate->weapondowntics = 0;
4380 pstate->weaponuptics = KESTICS/(2*GMOVE);
4381 }
4382 else
4383 #endif
4384 {
4385 pstate->weapondowntics = 0;
4386 pstate->weaponframe = pstate->attackframe = 0;
4387
4388 if (pstate->NETCAPTURED == -1)
4389 {
4390 pstate->weaponuptics = FREE.screenheight/GMOVE;
4391 pstate->weaponheight = pstate->weaponuptics*GMOVE ;
4392 pstate->NETCAPTURED = 1;
4393 // return;
4394 }
4395 else if (pstate->NETCAPTURED == -2)
4396 {
4397 pstate->weaponuptics = WEAPONS[pstate->weapon].screenheight/GMOVE;
4398 pstate->weaponheight = pstate->weaponuptics*GMOVE ;
4399 pstate->NETCAPTURED = 0;
4400
4401 //return;
4402 }
4403 else
4404 {
4405 pstate->weaponuptics = WEAPONS[pstate->new_weapon].screenheight/GMOVE;
4406 pstate->weapon = pstate->new_weapon;
4407 pstate->weaponheight = pstate->weaponuptics*GMOVE ;
4408 }
4409 }
4410 }
4411 }
4412 else if (gamestate.battlemode == battle_Hunter)
4413 {
4414 if (pstate->weapondowntics == 1)
4415
4416 {
4417 pstate->weapondowntics = 0;
4418 pstate->weaponframe = pstate->attackframe = pstate->batblast = 0;
4419 pstate->weapon = pstate->new_weapon;
4420 NewState(ob,resetstate);
4421 return;
4422 }
4423 }
4424
4425
4426
4427
4428 #if (SHAREWARE==0)
4429 if ((pstate->buttonstate[bt_use]) &&
4430 (pstate->weapon != wp_dog)
4431 )
4432 #else
4433 if (pstate->buttonstate[bt_use])
4434 #endif
4435 Cmd_Use (ob);
4436
4437 if (pstate->attackframe >= WEAPONS[pstate->weapon].numattacks)
4438 Error("\n attackframe %d for weapon %d gt numattacks %d",
4439 pstate->attackframe,pstate->weapon,
4440 WEAPONS[pstate->weapon].numattacks
4441 );
4442
4443 cur = &(WEAPONS[pstate->weapon].attackinfo[pstate->attackframe]);
4444 if (! pstate->attackcount)
4445 {
4446 switch (cur->attack)
4447 {
4448 case reset:
4449 if (vrenabled && (ob==player))
4450 {
4451 StopVRFeedback();
4452 }
4453 ob->flags &= ~FL_FULLLIGHT;
4454 if (pstate->ammo)
4455 {
4456 if (BATTLEMODE && (pstate->weapon == wp_firewall))
4457 break;
4458 if (BATTLEMODE && (pstate->weapon == wp_firebomb))
4459 break;
4460 if ((pstate->buttonstate[bt_attack]) && (pstate->weapon <= wp_firewall))
4461 {
4462 if (pstate->weapon <= wp_mp40)
4463 {
4464 if (pstate->weapon == wp_twopistol)
4465 pstate->attackframe -= 6;
4466 else if (pstate->weapon == wp_pistol)
4467 pstate->attackframe -= 3;
4468 else if (pstate->weapon == wp_mp40)
4469 pstate->attackframe -= 2;
4470
4471 if (ob->state == &s_pmissattack2)
4472 NewState(ob,&s_pmissattack1);
4473 else if (ob->state == &s_pgunattack2)
4474 NewState(ob,&s_pgunattack1);
4475
4476 }
4477
4478 }
4479 else
4480 {
4481 NewState(ob,resetstate);
4482 pstate->attackframe = pstate->weaponframe = 0;
4483 pstate->batblast = 0;
4484 return;
4485 }
4486 }
4487 else
4488 {
4489 NewState(ob,resetstate);
4490 pstate->attackframe = pstate->weaponframe = 0;
4491 pstate->new_weapon = pstate->bulletweapon;
4492 pstate->batblast = 0;
4493 pstate->ammo = -1;
4494 pstate->missileweapon = -1;
4495 pstate->weapondowntics = WEAPONS[pstate->weapon].screenheight/GMOVE;
4496
4497 if ((ob==player) && SHOW_BOTTOM_STATUS_BAR() )
4498 DrawBarAmmo (false);
4499
4500 return;
4501 }
4502 break;
4503
4504 case reset2:
4505 if (vrenabled && (ob==player))
4506 {
4507 StopVRFeedback();
4508 }
4509 ob->flags &= ~FL_FULLLIGHT;
4510 if (pstate->buttonstate[bt_attack] && pstate->ammo)
4511 {
4512 pstate->attackframe -= 4;
4513 if (ob->state == &s_pmissattack2)
4514 NewState(ob,&s_pmissattack1);
4515 else if (ob->state == &s_pgunattack2)
4516 NewState(ob,&s_pgunattack1);
4517 }
4518 else
4519 {
4520 NewState(ob,resetstate);
4521 pstate->attackframe = pstate->weaponframe = 0;
4522 pstate->batblast = 0;
4523 return;
4524 }
4525
4526 break;
4527
4528
4529 case at_pulltrigger:
4530 if (vrenabled && (ob==player))
4531 {
4532 StartVRFeedback(1);
4533 }
4534 ob->flags |= FL_FULLLIGHT;
4535
4536 #if (SHAREWARE == 0)
4537
4538 if (pstate->batblast >= BBTIME)
4539 DogBlast(ob);
4540
4541 else if (pstate->weapon == wp_dog)
4542 DogAttack(ob);
4543 else if (pstate->weapon == wp_bat)
4544 BatAttack (ob);
4545 else
4546 #endif
4547 GunAttack(ob);
4548
4549 break;
4550
4551 case at_missileweapon:
4552 if (!pstate->ammo)
4553 {
4554 pstate->attackframe = pstate->weaponframe = 0;
4555 pstate->batblast = 0;
4556 return;
4557 }
4558
4559 if (vrenabled && (ob==player))
4560 {
4561 StartVRFeedback(1);
4562 }
4563 ob->flags |= FL_FULLLIGHT;
4564 if (ob==player)
4565 SetIllumination(2);
4566 PlayerMissileAttack(ob);
4567
4568
4569 if (!(ob->flags & FL_GODMODE) && !godmode)
4570 {
4571 if (!BATTLEMODE || (gamestate.BattleOptions.Ammo != bo_infinite_shots))
4572 pstate->ammo--;
4573
4574 if ((ob==player) && SHOW_BOTTOM_STATUS_BAR() )
4575 DrawBarAmmo (false);
4576 }
4577 #if (SHAREWARE == 0)
4578 if (pstate->weapon == wp_kes)
4579 pstate->weapondowntics = KESTICS/(2*GMOVE);
4580 #endif
4581 break;
4582
4583 default:
4584 ;
4585 }
4586
4587 pstate->attackframe++;
4588 cur = &(WEAPONS[pstate->weapon].attackinfo[pstate->attackframe]);
4589 pstate->weaponframe = cur->frame;
4590 pstate->attackcount = cur->mtics;
4591
4592 }
4593 else
4594 pstate->attackcount --;
4595 }
4596
4597 /*
4598 ===============
4599 =
4600 = T_BatBlast
4601 =
4602 ===============
4603 */
4604
T_BatBlast(objtype * ob)4605 void T_BatBlast (objtype *ob)
4606 {
4607 attack_t *cur;
4608 playertype *pstate;
4609
4610
4611 Thrust(ob);
4612 CheckPlayerSpecials(ob);
4613 M_LINKSTATE(ob,pstate);
4614
4615
4616 //Commented out until we find if it's valid
4617 /*
4618 if (!ob->ticcount)
4619 {if ( pstate->buttonstate[bt_use] && !pstate->buttonheld[bt_use] )
4620 pstate->buttonstate[bt_use] = false;
4621
4622 if ( pstate->buttonstate[bt_attack] && !pstate->buttonheld[bt_attack])
4623 pstate->buttonstate[bt_attack] = false;
4624 }
4625 */
4626 //
4627 // change frame and fire
4628 //
4629
4630 BatBlast(ob);
4631
4632
4633
4634 if (pstate->attackframe >= WEAPONS[pstate->weapon].numattacks)
4635 Error("\n attackframe %d for weapon %d gt numattacks %d",
4636 pstate->attackframe,pstate->weapon,
4637 WEAPONS[pstate->weapon].numattacks
4638 );
4639
4640
4641
4642 cur = &(WEAPONS[pstate->weapon].attackinfo[pstate->attackframe]);
4643 if (! pstate->attackcount)
4644 {if (cur->attack == reset)
4645 {
4646 if (!(ob->flags & FL_GODMODE) && (!godmode))
4647 {pstate->ammo --;
4648 if ((ob==player) && SHOW_BOTTOM_STATUS_BAR() )
4649 DrawBarAmmo (false);
4650 }
4651
4652 if (!pstate->ammo)
4653 {pstate->new_weapon = pstate->bulletweapon;
4654 pstate->ammo = -1;
4655 pstate->missileweapon = -1;
4656 pstate->weapondowntics = WEAPONS[pstate->weapon].screenheight/GMOVE;
4657
4658 }
4659
4660 NewState(ob,&s_player);
4661 pstate->attackframe = pstate->weaponframe = 0;
4662 pstate->batblast = 0;
4663 return;
4664 }
4665 pstate->attackframe++;
4666 pstate->weaponframe = WEAPONS[pstate->weapon].attackinfo[pstate->attackframe].frame;
4667 cur = &(WEAPONS[pstate->weapon].attackinfo[pstate->attackframe]);
4668 pstate->attackcount = cur->mtics;
4669 }
4670 else
4671 pstate->attackcount --;
4672
4673 }
4674
4675
4676
4677
T_Free(objtype * ob)4678 void T_Free (objtype *ob)
4679 {
4680 attack_t *cur;
4681
4682
4683 if (!ob->ticcount)
4684 {
4685
4686
4687 //Commented out until we find if it's valid
4688 /*
4689 if ( locplayerstate->buttonstate[bt_use] && !locplayerstate->buttonheld[bt_use] )
4690 locplayerstate->buttonstate[bt_use] = false;
4691
4692 if ( locplayerstate->buttonstate[bt_attack] && !locplayerstate->buttonheld[bt_attack])
4693 locplayerstate->buttonstate[bt_attack] = false;
4694 */
4695 Thrust(ob);
4696
4697 }
4698 CheckPlayerSpecials(ob);
4699
4700
4701
4702
4703
4704
4705 cur = &(FREE.attackinfo[locplayerstate->attackframe]);
4706
4707 if (!locplayerstate->attackcount)
4708 {
4709 if ((locplayerstate->weaponframe > 3) && (locplayerstate->weaponframe < 8))
4710 locplayerstate->NETCAPTURED ++;
4711 else if (locplayerstate->weaponframe == 8)
4712 {
4713 locplayerstate->NETCAPTURED = -2;
4714 MISCVARS->NET_IN_FLIGHT = false;
4715 NewState(ob,&s_player);
4716 locplayerstate->weapondowntics = FREE.screenheight/GMOVE;
4717 return;
4718 }
4719
4720 locplayerstate->attackframe++;
4721 cur = &(FREE.attackinfo[locplayerstate->attackframe]);
4722 locplayerstate->weaponframe = cur->frame;
4723
4724 locplayerstate->attackcount = cur->mtics;
4725
4726 }
4727 else
4728 locplayerstate->attackcount --;
4729 }
4730
4731
4732
Switch_Who_Is_It_For_Tag(objtype * actor1,objtype * actor2)4733 void Switch_Who_Is_It_For_Tag(objtype *actor1,objtype *actor2)
4734 {
4735 playertype *pstate;
4736
4737 M_LINKSTATE(actor1,pstate);
4738 if (pstate->buttonstate[bt_use])
4739 {playertype *pstate2;
4740
4741 M_LINKSTATE(actor2,pstate2);
4742 pstate2->oldmissileweapon = pstate2->oldweapon = pstate2->new_weapon =
4743 pstate2->missileweapon = pstate2->weapon = wp_godhand;
4744 pstate2->weaponheight = 144;
4745 pstate2->weaponuptics = (144 - TAGHANDHEIGHT)/GMOVE;
4746 pstate2->weapondowntics = 0;
4747 actor1->flags |= FL_DIDTAG;
4748 actor2->flags |= FL_DESIGNATED;
4749 UpdateKills = true;
4750
4751 actor1->flags &= ~FL_DESIGNATED;
4752 BATTLE_PlayerKilledPlayer(battle_player_tagged,
4753 actor1->dirchoosetime, actor2->dirchoosetime);
4754 }
4755
4756 }
4757
4758
4759
CheckTagGame(objtype * actor1,objtype * actor2)4760 void CheckTagGame(objtype *actor1,objtype*actor2)
4761 {
4762 //if ((actor1->obclass != playerobj) || (actor2->obclass != playerobj))
4763 //return;
4764
4765 if (!BATTLEMODE)
4766 return;
4767
4768 if (gamestate.battlemode != battle_Tag)
4769 return;
4770
4771 SD_PlaySoundRTP(SD_GETBONUSSND,actor1->x,actor1->y);
4772
4773 if (actor1->flags & FL_DESIGNATED)
4774 Switch_Who_Is_It_For_Tag(actor1,actor2);
4775 else if (actor2->flags & FL_DESIGNATED)
4776 Switch_Who_Is_It_For_Tag(actor2,actor1);
4777
4778 }
4779
4780
4781
4782
4783
4784
4785 /*
4786 ======================
4787 =
4788 = CheckWeaponChange
4789 =
4790 = Keys 1-4 change weapons
4791 =
4792 ======================
4793 */
4794
CheckWeaponChange(objtype * ob)4795 void CheckWeaponChange (objtype * ob)
4796 {
4797 // int i;
4798
4799 playertype * pstate;
4800
4801
4802 M_LINKSTATE(ob,pstate);
4803 //pstate = (ob == player)?(&playerstate):(&remoteplayerstate);
4804 if (W_CHANGE(pstate))
4805 return;
4806
4807 if (!ARMED(ob->dirchoosetime))
4808 return;
4809
4810 if ((ob->flags & FL_DOGMODE) || (ob->flags & FL_GODMODE))
4811 return;
4812
4813 #if (WEAPONCHEAT==1)
4814 if (godmode && Keyboard[sc_Insert])
4815 {
4816 SD_Play(SD_SELECTWPNSND);
4817
4818 // FOR DEBUG only
4819 /*
4820 if (pstate->buttonstate[bt_run])
4821 {
4822 if (pstate->weapon == 0)
4823 pstate->new_weapon = wp_bat;
4824 else
4825 pstate->new_weapon --;
4826 }
4827 else
4828 {*/
4829 if (pstate->weapon == MAXWEAPONS-1)
4830 pstate->new_weapon = 0;
4831 else
4832 pstate->new_weapon ++;
4833 //}
4834 if (pstate->new_weapon <= wp_mp40)
4835 {pstate->bulletweapon = pstate->new_weapon;
4836 pstate->HASBULLETWEAPON[pstate->new_weapon] = 1;
4837 }
4838 else
4839 pstate->missileweapon = pstate->new_weapon;
4840
4841 pstate->ammo = stats[GetItemForWeapon(pstate->missileweapon)].ammo;
4842 if (pstate->ammo<1)
4843 pstate->ammo=5;
4844 StartWeaponChange;
4845 //pstate->weapondowntics = WEAPONS[pstate->weapon].screenheight/GMOVE;
4846 //if ((ob==player) && SHOW_BOTTOM_STATUS_BAR() )
4847 // DrawBarAmmo (false);
4848 }
4849 else if (pstate->buttonstate[bt_swapweapon])
4850 #else
4851 if (pstate->buttonstate[bt_swapweapon])
4852 #endif
4853 {
4854 if ((pstate->weapon == pstate->bulletweapon) &&
4855 (pstate->missileweapon != -1))
4856 {pstate->new_weapon = pstate->missileweapon;
4857 StartWeaponChange;
4858 }
4859
4860 else if (pstate->weapon != pstate->bulletweapon)
4861 {pstate->new_weapon = pstate->bulletweapon;
4862 StartWeaponChange;
4863 }
4864 }
4865 else if ((pstate->buttonstate[bt_dropweapon]) &&
4866 (!gamestate.BattleOptions.WeaponPersistence))
4867 {
4868 if (pstate->weapon==pstate->bulletweapon)
4869 {
4870 if ((ob==player) && (!(pstate->buttonheld[bt_dropweapon])))
4871 PlayNoWaySound();
4872 }
4873 else
4874 {
4875 if (sprites[ob->tilex][ob->tiley])
4876 {
4877 if ((ob==player) && (!(pstate->buttonheld[bt_dropweapon])))
4878 PlayNoWaySound();
4879 }
4880 else
4881 {
4882 DropWeapon(ob);
4883 }
4884 }
4885 }
4886
4887
4888
4889 if (pstate->buttonstate[bt_pistol])
4890 {if (pstate->weapon != wp_pistol)
4891 {pstate->new_weapon = pstate->bulletweapon = wp_pistol;
4892 StartWeaponChange;
4893 }
4894 }
4895
4896 else if (pstate->buttonstate[bt_dualpistol])
4897 {if ((pstate->weapon != wp_twopistol) && pstate->HASBULLETWEAPON[wp_twopistol])
4898 {pstate->new_weapon = pstate->bulletweapon = wp_twopistol;
4899 StartWeaponChange;
4900 }
4901 }
4902 else if (pstate->buttonstate[bt_mp40])
4903 {if ((pstate->weapon != wp_mp40) && pstate->HASBULLETWEAPON[wp_mp40])
4904 {pstate->new_weapon = pstate->bulletweapon = wp_mp40;
4905 StartWeaponChange;
4906 }
4907 }
4908 else if (pstate->buttonstate[bt_missileweapon])
4909 {if ((pstate->weapon != pstate->missileweapon) && (pstate->missileweapon != -1))
4910 {pstate->new_weapon = pstate->missileweapon;
4911 StartWeaponChange;
4912 }
4913 }
4914 }
4915
4916
SetWhoHaveWeapons(void)4917 void SetWhoHaveWeapons(void)
4918 {
4919 playertype *pstate;
4920 objtype *ob;
4921 int i;
4922
4923 for ( i = 0; i < numplayers; i++ )
4924 {
4925 ob = PLAYER[ i ];
4926 M_LINKSTATE( ob, pstate );
4927
4928 if ( ARMED( ob->dirchoosetime ))
4929 {
4930 if (pstate->weapon == -1)
4931 {
4932 if (( pstate->missileweapon != -1 ) && (pstate->ammo>0))
4933 pstate->new_weapon = pstate->missileweapon;
4934
4935 else
4936 {
4937 if ( pstate->bulletweapon == -1 )
4938 {
4939 pstate->HASBULLETWEAPON[ wp_pistol ] = 1;
4940 pstate->bulletweapon = wp_pistol;
4941 }
4942 pstate->new_weapon = pstate->bulletweapon;
4943 pstate->ammo = -1;
4944 }
4945
4946 pstate->weapon = pstate->new_weapon;
4947 pstate->weapondowntics = 0;
4948 pstate->weaponuptics = WEAPONS[pstate->new_weapon].screenheight/GMOVE;
4949 pstate->weaponheight = pstate->weaponuptics*GMOVE ;
4950 pstate->attackframe = pstate->weaponframe =
4951 pstate->batblast = 0;
4952 if (i == consoleplayer)
4953 DrawBarAmmo(false);
4954 }
4955 }
4956 else
4957 {
4958 if (ob->flags & FL_DOGMODE)
4959 {
4960 ob->temp2 = DOGMODERISE;
4961 pstate->oldweapon = -1;
4962 ResetWeapons(ob);
4963 if (ob->state->condition & SF_DOGSTATE)
4964 NewState(ob,&s_player);
4965 }
4966 else if (ob->flags & FL_GODMODE)
4967 {
4968 ob->temp2 = GODMODEFALL;
4969 pstate->oldweapon = -1;
4970 ResetWeapons(ob);
4971 }
4972 else
4973 {
4974 pstate->new_weapon = -1;
4975 StartWeaponChange;
4976 }
4977 pstate->attackframe = pstate->weaponframe =
4978 pstate->batblast = 0;
4979 }
4980 }
4981 }
4982
4983
4984
4985
4986
4987
4988
4989
CheckWeaponStates(objtype * ob)4990 void CheckWeaponStates(objtype*ob)
4991 {playertype *pstate;
4992
4993 M_LINKSTATE(ob,pstate);
4994
4995 if (gamestate.battlemode == battle_Tag)
4996 {if (pstate->weapondowntics)
4997 {pstate->weaponheight += GMOVE;
4998 pstate->weapondowntics --;
4999 if (!pstate->weapondowntics)
5000 pstate->weapon = pstate->missileweapon = pstate->bulletweapon =
5001 pstate->new_weapon = pstate->oldweapon = pstate->oldmissileweapon = -1;
5002
5003 }
5004
5005
5006 if (pstate->weaponuptics)
5007 {pstate->weaponheight -= GMOVE;
5008 pstate->weaponuptics --;
5009 }
5010 return;
5011 }
5012
5013 if (pstate->weapondowntics)
5014 {pstate->weaponheight += GMOVE;
5015 #if (SHAREWARE == 0)
5016 if ((pstate->weapon == wp_kes) && pstate->attackframe)
5017 pstate->weaponheight += GMOVE;
5018 #endif
5019 pstate->weapondowntics --;
5020 }
5021 else if (pstate->weaponuptics)
5022 {pstate->weaponheight -= GMOVE;
5023 #if (SHAREWARE == 0)
5024 if ((pstate->weapon == wp_kes) && pstate->attackframe)
5025 pstate->weaponheight -= GMOVE;
5026 #endif
5027
5028 pstate->weaponuptics --;
5029 }
5030 else if ((pstate->weapon == pstate->new_weapon) && (!pstate->NETCAPTURED))
5031 pstate->weaponheight = 0;
5032
5033 }
5034
5035
5036 /*
5037 =============================
5038 =
5039 = CheckSpecialSounds
5040 =
5041 =============================
5042 */
5043
5044 #define REGDOGSTATE(ob) \
5045 ((ob->state == &s_serialdog) || (ob->state == &s_serialdog2) || \
5046 (ob->state == &s_serialdog3) || (ob->state == &s_serialdog4) \
5047 )
5048
5049 static int dyingvolume=255;
CheckSpecialSounds(objtype * ob,playertype * pstate)5050 void CheckSpecialSounds(objtype *ob, playertype *pstate)
5051 {
5052 int shift;
5053
5054 if ((!BATTLEMODE) && (ob == player))
5055 {
5056 if (pstate->health < MaxHitpointsForCharacter(locplayerstate)/5)
5057 {
5058 pstate->healthtime ++;
5059 if (pstate->healthtime > 2*VBLCOUNTER)
5060 {
5061 pstate->healthtime = 0;
5062 SD_PlayPitchedSound ( SD_PLAYERDYINGSND, dyingvolume, 0 );
5063 if (dyingvolume>80)
5064 dyingvolume-=40;
5065 }
5066 }
5067 else
5068 {
5069 dyingvolume=255;
5070 }
5071 }
5072
5073 if (((ob->flags & FL_GODMODE) || (ob->flags & FL_DOGMODE)) &&
5074 (!W_CHANGE(pstate))
5075 )
5076 {
5077 pstate->soundtime++;
5078 if (pstate->soundtime > (2*VBLCOUNTER))
5079 {
5080 int rand;
5081
5082 rand = GameRandomNumber("player special sound",0);
5083 shift = (pstate->soundtime>>5);
5084 if ((rand << shift) > 3500)
5085 {
5086 int sound;
5087
5088 pstate->soundtime = 0;
5089
5090 rand = GameRandomNumber("player god scare",0);
5091
5092 if (ob->flags & FL_GODMODE)
5093 {
5094 sound = SD_GODMODE1SND;
5095 if (rand < 160)
5096 sound++;
5097 if (rand < 80)
5098 sound ++;
5099 SD_PlaySoundRTP(sound,ob->x,ob->y);
5100 }
5101 #if (SHAREWARE == 0)
5102 else if ((!pstate->batblast) && (!ob->momentumz) &&
5103 (REGDOGSTATE(ob))
5104 )
5105 {
5106 sound = SD_DOGMODEPANTSND;
5107 if (rand < 128)
5108 sound += 2;
5109 NewState(ob,&s_doglick);
5110 pstate->attackframe = pstate->weaponframe =
5111 pstate->batblast = 0;
5112 SD_PlaySoundRTP(sound,ob->x,ob->y);
5113 }
5114 #endif
5115 }
5116 }
5117 }
5118
5119
5120
5121
5122 else if (ob->flags & FL_GASMASK)
5123 {
5124 pstate->soundtime ++;
5125
5126 if (pstate->soundtime > (3*VBLCOUNTER))
5127 {
5128 pstate->soundtime = 0;
5129 SD_PlaySoundRTP(SD_GASMASKSND,ob->x,ob->y);
5130 }
5131 }
5132
5133
5134 else if (MISCVARS->GASON)
5135 {
5136 pstate->soundtime ++;
5137 if (pstate->soundtime > (2*VBLCOUNTER))
5138 {
5139 int rand;
5140
5141 rand = GameRandomNumber("player cough sound",0);
5142 shift = (pstate->soundtime>>5);
5143 if ((rand << shift) > 2000)
5144 {
5145 pstate->soundtime = 0;
5146 if ((pstate->player == 1) || (pstate->player == 3))
5147 SD_PlaySoundRTP(SD_PLAYERCOUGHFSND,ob->x,ob->y);
5148 else
5149 SD_PlaySoundRTP(SD_PLAYERCOUGHMSND,ob->x,ob->y);
5150 }
5151 }
5152 }
5153 }
5154
5155 /*
5156 static int dyingvolume=255;
5157 void CheckSpecialSounds(objtype *ob, playertype *pstate)
5158 {
5159 int shift;
5160
5161 if ((!BATTLEMODE) && (ob == player))
5162 {
5163 if (pstate->health < MaxHitpointsForCharacter(locplayerstate)/5)
5164 {
5165 pstate->healthtime ++;
5166 if (pstate->healthtime > 2*VBLCOUNTER)
5167 {
5168 pstate->healthtime = 0;
5169 SD_PlayPitchedSound ( SD_PLAYERDYINGSND, dyingvolume, 0 );
5170 if (dyingvolume>80)
5171 dyingvolume-=40;
5172 }
5173 }
5174 else
5175 {
5176 dyingvolume=255;
5177 }
5178 }
5179
5180 if (((ob->flags & FL_GODMODE) || (ob->flags & FL_DOGMODE)) &&
5181 (!W_CHANGE(pstate))
5182 )
5183 {
5184 pstate->soundtime++;
5185 if (pstate->soundtime > (2*VBLCOUNTER))
5186 {
5187 int rand;
5188
5189 rand = GameRandomNumber("player special sound",0);
5190 shift = (pstate->soundtime>>5);
5191 if ((rand << shift) > 3500)
5192 {
5193 int sound;
5194
5195 pstate->soundtime = 0;
5196
5197 rand = GameRandomNumber("player god scare",0);
5198
5199 if (ob->flags & FL_GODMODE)
5200 {
5201 sound = SD_GODMODE1SND;
5202 if (rand < 160)
5203 sound++;
5204 if (rand < 80)
5205 sound ++;
5206 SD_PlaySoundRTP(sound,ob->x,ob->y);
5207 }
5208 #if (SHAREWARE == 0)
5209 else if (!pstate->batblast)
5210 {
5211 sound = SD_DOGMODEPANTSND;
5212 if (rand < 128)
5213 sound += 2;
5214 NewState(ob,&s_doglick);
5215 pstate->attackframe = pstate->weaponframe =
5216 pstate->batblast = 0;
5217 SD_PlaySoundRTP(sound,ob->x,ob->y);
5218 }
5219 #endif
5220 }
5221 }
5222 }
5223
5224
5225
5226
5227 else if (ob->flags & FL_GASMASK)
5228 {
5229 pstate->soundtime ++;
5230
5231 if (pstate->soundtime > (3*VBLCOUNTER))
5232 {
5233 pstate->soundtime = 0;
5234 SD_PlaySoundRTP(SD_GASMASKSND,ob->x,ob->y);
5235 }
5236 }
5237
5238
5239 else if (MISCVARS->GASON)
5240 {
5241 pstate->soundtime ++;
5242 if (pstate->soundtime > (2*VBLCOUNTER))
5243 {
5244 int rand;
5245
5246 rand = GameRandomNumber("player cough sound",0);
5247 shift = (pstate->soundtime>>5);
5248 if ((rand << shift) > 2000)
5249 {
5250 pstate->soundtime = 0;
5251 if ((pstate->player == 1) || (pstate->player == 3))
5252 SD_PlaySoundRTP(SD_PLAYERCOUGHFSND,ob->x,ob->y);
5253 else
5254 SD_PlaySoundRTP(SD_PLAYERCOUGHMSND,ob->x,ob->y);
5255 }
5256 }
5257 }
5258 }
5259
5260 */
5261
5262
5263 /*
5264 =============================
5265 =
5266 = CheckProtectionsAndPowerups
5267 =
5268 =============================
5269 */
5270
5271
5272
CheckProtectionsAndPowerups(objtype * ob,playertype * pstate)5273 void CheckProtectionsAndPowerups(objtype *ob, playertype *pstate)
5274 {
5275 if (pstate->poweruptime)
5276 {
5277 pstate->poweruptime --;
5278 if (pstate->poweruptime < 0)
5279 pstate->poweruptime = 0;
5280 if (ob==player)
5281 GM_UpdateBonus (pstate->poweruptime, true);
5282 }
5283 else
5284 {
5285 if (ob->flags & FL_ELASTO)
5286 {
5287 ob->flags &= ~FL_NOFRICTION;
5288 if (ob==player)
5289 GM_UpdateBonus (pstate->poweruptime, true);
5290 SD_PlaySoundRTP(SD_LOSEMODESND,ob->x, ob->y);
5291 }
5292 else if (ob->flags & FL_GODMODE)
5293 {ob->temp2 = GODMODEFALL;
5294 if ((pstate->player == 1) || (pstate->player == 3))
5295 SD_PlaySoundRTP(SD_GODWOMANSND,ob->x, ob->y);
5296 else
5297 SD_PlaySoundRTP(SD_GODMANSND,ob->x, ob->y);
5298 ResetWeapons(ob);
5299 }
5300 else if (ob->flags & FL_DOGMODE)
5301 {int wall;
5302
5303 wall = tilemap[ob->tilex][ob->tiley];
5304 if ((wall & 0x4000) && (wall & 0x8000))
5305 {maskedwallobj_t * mw;
5306
5307 mw=maskobjlist[wall&0x3ff];
5308 if (mw->flags&MW_NONDOGBLOCKING)
5309 return;
5310 }
5311
5312
5313 ob->temp2 = DOGMODERISE;
5314 if ((pstate->player == 1) || (pstate->player == 3))
5315 SD_PlaySoundRTP(SD_DOGWOMANSND,ob->x, ob->y);
5316 else
5317 SD_PlaySoundRTP(SD_DOGMANSND,ob->x, ob->y);
5318 ResetWeapons(ob);
5319 if (ob->state->condition & SF_DOGSTATE)
5320 {
5321 NewState(ob,&s_player);
5322 pstate->attackframe = pstate->weaponframe = pstate->batblast = 0;
5323 }
5324 }
5325 else if (ob->flags & FL_SHROOMS)
5326 {
5327 ResetFocalWidth ();
5328 SD_PlaySoundRTP(SD_LOSEMODESND,ob->x, ob->y);
5329 }
5330 else if (ob->flags & FL_FLEET)
5331 SD_PlaySoundRTP(SD_LOSEMODESND,ob->x, ob->y);
5332
5333 ob->flags &= ~(FL_SHROOMS|FL_ELASTO|FL_FLEET|FL_GODMODE|FL_DOGMODE);
5334 }
5335
5336 if (pstate->protectiontime)
5337 {
5338 pstate->protectiontime --;
5339 if (pstate->protectiontime <= 0)
5340 {
5341 SD_PlaySoundRTP(SD_LOSEMODESND,ob->x, ob->y);
5342 pstate->protectiontime = 0;
5343 }
5344 if (ob==player)
5345 GM_UpdateBonus (pstate->protectiontime, false);
5346 }
5347 else
5348 ob->flags &= ~(FL_BPV|FL_AV|FL_GASMASK);
5349
5350 }
5351
5352
5353
5354 /*
5355 =============================
5356 =
5357 = CheckFlying
5358 =
5359 =============================
5360 */
5361
CheckFlying(objtype * ob,playertype * pstate)5362 void CheckFlying(objtype*ob,playertype *pstate)
5363 {
5364
5365
5366 if (pstate->buttonstate[bt_lookup] || CYBERLOOKUP)
5367 {
5368 ob->momentumz = -FLYINGZMOM;
5369 }
5370 if (pstate->buttonstate[bt_lookdown] || CYBERLOOKDOWN)
5371 {
5372 ob->momentumz = FLYINGZMOM;
5373 }
5374
5375 /*
5376 if (!M_ISDOOR(((ob->x + costable[ob->angle])>>16),
5377 ((ob->y - sintable[ob->angle])>>16)) &&
5378 (pstate->buttonstate[bt_use]) &&
5379 (!pstate->buttonheld[bt_use])
5380 )
5381 {
5382 int op;
5383 int dist;
5384
5385 dist=JETPACKTHRUST;
5386 if (ob->z-dist<-15)
5387 dist=ob->z+15;
5388 if (dist>0)
5389 {
5390 op = FixedMul(GRAVITY,(dist<<16)) << 1;
5391 ob->momentumz = -FixedSqrtHP(op);
5392 SD_PlaySoundRTP(SD_FLYINGSND,ob->x,ob->y);
5393 }
5394 }
5395 */
5396 }
5397
5398
5399
5400 /*
5401 =============================
5402 =
5403 = CheckTemp2Codes
5404 =
5405 =============================
5406 */
5407
5408
5409 #define IN_AIR(ob) \
5410 (!((ob->z == nominalheight) || \
5411 (IsPlatform(ob->tilex,ob->tiley)) || \
5412 (DiskAt(ob->tilex,ob->tiley)) \
5413 ) \
5414 ) \
5415
5416
CheckTemp2Codes(objtype * ob,playertype * pstate)5417 void CheckTemp2Codes(objtype *ob,playertype *pstate)
5418 {
5419 int pitheight;
5420 int godheight;
5421 int dogheight;
5422 int height;
5423 int oldz;
5424 int destheightoffset;
5425
5426
5427 pitheight = maxheight - 8;
5428 height = ob->z + pstate->playerheight;
5429 dogheight = ob->z + DOGOFFSET;
5430 godheight = ob->z + GODOFFSET;
5431
5432 //SoftError("\nheightoffset: %d, temp2: %d",pstate->heightoffset,ob->temp2);
5433
5434
5435 if (!((ob->temp2 == PITFALL) || (ob->temp2 == PITRISE)))
5436 {
5437
5438 oldz = ob->z;
5439 //SoftError("\n zmom %d, oldz %d, newz %d",ob->momentumz,oldz,ob->z);
5440
5441 if (ob->flags & FL_FLEET)
5442 {
5443 if (IN_AIR(ob))
5444 pstate->heightoffset = FixedMulShift(0x4000,sintable[(oldpolltime<<6)&2047],28);
5445
5446 ob->z += ((ob->momentumz+0x8000)>>16);
5447 ob->momentumz = 0;
5448
5449 }
5450 else
5451 {
5452 ob->z += (ob->momentumz>>16);
5453 ob->momentumz += GRAVITY;
5454 }
5455
5456
5457 if (ob->z >= nominalheight)
5458 {
5459 ob->z = nominalheight;
5460 ob->momentumz = 0;
5461 //if (platform == nominalheight)
5462 //{//ob->temp2 = 0;
5463 //ob->momentumz = 0;
5464 if ((oldz < nominalheight) && (!(ob->flags & FL_RIDING)))
5465 {
5466 SD_PlaySoundRTP(SD_PLAYERLANDSND,ob->x,ob->y);
5467 }
5468
5469 if (!(ob->flags & FL_ELASTO))
5470 ob->flags &= ~FL_NOFRICTION;
5471 // }
5472 }
5473 else if (height < 1)
5474 {
5475 ob->momentumz = 0;
5476 ob->z = 1-pstate->playerheight;
5477 }
5478
5479
5480
5481 switch (ob->temp2)
5482 {case RENORMALIZE:
5483 pstate->heightoffset --;
5484
5485 if (ob->flags & FL_DOGMODE)
5486 destheightoffset = DOGOFFSET-pstate->playerheight;
5487 else
5488 destheightoffset = 0;
5489
5490 if (pstate->heightoffset <= destheightoffset)
5491 {
5492 ob->temp2 = 0;
5493 pstate->heightoffset = 0;
5494 }
5495 pstate->oldheightoffset = pstate->heightoffset;
5496
5497 break;
5498
5499 case COLUMNCRUSH:
5500 pstate->heightoffset += 4;
5501 if (pstate->heightoffset >= 30)
5502 pstate->heightoffset = 30;
5503
5504 pstate->oldheightoffset = pstate->heightoffset;
5505 break;
5506
5507 case GODMODERISE:
5508 pstate->heightoffset --;
5509 pstate->oldheightoffset = pstate->heightoffset;
5510 if ((height+pstate->heightoffset) <= godheight)
5511 {
5512 ob->temp2 = 0;
5513 pstate->poweruptime = POWERUPTICS;
5514 }
5515 break;
5516
5517
5518 case GODMODEFALL:
5519 pstate->heightoffset ++;
5520 pstate->oldheightoffset = pstate->heightoffset;
5521 SetPlayerHorizon(pstate,NORMALYZANGLE);
5522 if (pstate->heightoffset >= 0)
5523 {
5524 ob->temp2 = 0;
5525 ob->flags &= ~FL_GODMODE;
5526 SetNormalHorizon(ob);
5527 }
5528 break;
5529
5530 case DOGMODERISE:
5531 pstate->heightoffset --;
5532 pstate->oldheightoffset = pstate->heightoffset;
5533 SetPlayerHorizon(pstate,NORMALYZANGLE);
5534 if (pstate->heightoffset <= 0)
5535 {
5536 ob->temp2 = 0;
5537 ob->flags &= ~FL_DOGMODE;
5538 SetNormalHorizon(ob);
5539 }
5540 break;
5541
5542
5543 case DOGMODEFALL:
5544 pstate->heightoffset ++;
5545 pstate->oldheightoffset = pstate->heightoffset;
5546 if (pstate->heightoffset >= (DOGOFFSET-pstate->playerheight))
5547 {
5548 ob->temp2 = 0;
5549 pstate->poweruptime = POWERUPTICS;
5550 }
5551 break;
5552
5553 case STEPUP:
5554 //Debug("\n\n heightoffset adjusted from %d to %d",
5555 // pstate->heightoffset,pstate->heightoffset - STEPADJUST);
5556 pstate->heightoffset -= STEPADJUST;
5557 if (pstate->heightoffset <= pstate->oldheightoffset)
5558 {ob->temp2 = 0;
5559 //Debug("\n done adjusting heightoffset");
5560 pstate->heightoffset = pstate->oldheightoffset;
5561 }
5562 break;
5563
5564 case STEPDOWN:
5565 pstate->heightoffset += STEPADJUST;
5566 if (pstate->heightoffset >= pstate->oldheightoffset)
5567 {ob->temp2 = 0;
5568 pstate->heightoffset = pstate->oldheightoffset;
5569 }
5570 break;
5571
5572 case 0:
5573 if (!((ob->flags & FL_FLEET) ||
5574 (ob->flags & FL_DOGMODE) ||
5575 (ob->flags & FL_GODMODE)
5576 )
5577 )
5578 pstate->heightoffset = 0;
5579 break;
5580
5581 }
5582
5583
5584 }
5585
5586
5587 else if (ob->temp2 == PITFALL)
5588 {
5589 if (ob->z != pitheight)
5590 {
5591 ob->z += (ob->momentumz>>16);
5592 ob->momentumz += GRAVITY;
5593 if (ob->z >= pitheight)
5594 {
5595 ob->z = pitheight;
5596 ob->momentumz = 0;
5597 if (!(ob->flags & FL_DYING))
5598 {DamageThing(ob,10);
5599 Collision(ob,(objtype*)NULL,0,0);
5600 M_CheckPlayerKilled(ob);
5601 }
5602 }
5603 }
5604 else if (ob->momentumx || ob->momentumy)
5605 {
5606 ob->temp2 = PITRISE;
5607 ob->momentumz = -2;
5608 }
5609 }
5610
5611 else if (ob->temp2 == PITRISE)
5612 {ob->z += ob->momentumz;
5613 if (ob->z <= nominalheight)
5614 {ob->z = nominalheight;
5615 ob->temp2 = 0;
5616 ob->momentumz = 0;
5617 if (pstate->heightoffset)
5618 ob->temp2 = RENORMALIZE;
5619 }
5620 }
5621
5622
5623
5624
5625
5626
5627 }
5628
5629
5630
5631 /*
5632 =============================
5633 =
5634 = CheckRemoteRecording
5635 =
5636 =============================
5637 */
5638
CheckRemoteRecording(objtype * ob,playertype * pstate)5639 void CheckRemoteRecording(objtype *ob,playertype *pstate)
5640 {
5641 if (networkgame==true)
5642 {
5643 if ( (pstate->buttonstate[bt_recordsound]) &&
5644 (!pstate->buttonheld[bt_recordsound])
5645 )
5646 {
5647 if (SD_RecordingActive()==false)
5648 {
5649 SD_SetRecordingActive ();
5650 PlayerRecording=ob->dirchoosetime;
5651 if (ob==player)
5652 {
5653 SD_StartRecordingSound();
5654 UpdateClientControls();
5655 }
5656 }
5657 }
5658 else if ( (pstate->buttonheld[bt_recordsound]) &&
5659 (!pstate->buttonstate[bt_recordsound])
5660 )
5661 {
5662 if (SD_RecordingActive()==true)
5663 {
5664 if (ob->dirchoosetime==PlayerRecording)
5665 {
5666 if (ob==player)
5667 SD_StopRecordingSound();
5668 SD_ClearRecordingActive();
5669 PlayerRecording=-1;
5670 UpdateClientControls();
5671 }
5672 }
5673 }
5674 }
5675 }
5676
5677
5678 /*
5679 =============================
5680 =
5681 = CheckPlayerSpecials
5682 =
5683 =============================
5684 */
5685
5686
CheckPlayerSpecials(objtype * ob)5687 void CheckPlayerSpecials(objtype * ob)
5688 {
5689 playertype * pstate;
5690
5691 M_LINKSTATE(ob,pstate);
5692
5693 // Check for recording of sound
5694
5695 CheckRemoteRecording(ob,pstate);
5696 CheckTemp2Codes(ob,pstate);
5697
5698 if (ob->flags & FL_DYING)
5699 return;
5700
5701 CheckSpecialSounds(ob,pstate);
5702 CheckProtectionsAndPowerups(ob,pstate);
5703 }
5704
5705 #if (SHAREWARE == 0)
5706 /*
5707 ===============
5708 =
5709 = T_DogUse
5710 =
5711 ===============
5712 */
5713
T_DogUse(objtype * ob)5714 void T_DogUse (objtype *ob)
5715 {
5716 attack_t *cur;
5717 playertype *pstate;
5718 statetype *oldstate;
5719
5720 M_LINKSTATE(ob,pstate);
5721
5722 Thrust(ob);
5723 oldstate = ob->state;
5724 CheckPlayerSpecials(ob);
5725 if (ob->state != oldstate)
5726 {
5727 return;
5728 }
5729
5730
5731
5732
5733 //Commented out until we find if it's valid
5734 /*
5735 if (!ob->ticcount)
5736 {if ( pstate->buttonstate[bt_use] && !pstate->buttonheld[bt_use] )
5737 pstate->buttonstate[bt_use] = false;
5738 }
5739 */
5740
5741 if (pstate->attackframe >= DOGSCRATCH.numattacks)
5742 Error("\n attackframe %d for DOGSCRATCH gt numattacks %d",
5743 pstate->attackframe,DOGSCRATCH.numattacks
5744 );
5745
5746
5747
5748 cur = &(DOGSCRATCH.attackinfo[pstate->attackframe]);
5749 if (! pstate->attackcount)
5750 {switch (cur->attack)
5751 {case reset:
5752 {
5753 NewState(ob,&s_dogwait);
5754 pstate->attackframe = pstate->weaponframe = pstate->batblast = 0;
5755 return;
5756 }
5757 break;
5758 case at_pulltrigger:
5759 pstate->buttonheld[bt_use]=false;
5760 Cmd_Use(ob);
5761 break;
5762 default:
5763 break;
5764 }
5765 pstate->attackframe++;
5766 cur = &(DOGSCRATCH.attackinfo[pstate->attackframe]);
5767 pstate->weaponframe = cur->frame;
5768 pstate->attackcount = cur->mtics;
5769
5770 }
5771 else
5772 pstate->attackcount --;
5773
5774
5775
5776 }
5777
5778 /*
5779 ===============
5780 =
5781 = T_DogLick
5782 =
5783 ===============
5784 */
5785
5786
5787
T_DogLick(objtype * ob)5788 void T_DogLick (objtype *ob)
5789 {
5790 attack_t *cur;
5791 playertype *pstate;
5792 statetype *oldstate;
5793
5794 M_LINKSTATE(ob,pstate);
5795
5796 Thrust(ob);
5797 oldstate = ob->state;
5798 CheckPlayerSpecials(ob);
5799 if (ob->state != oldstate)
5800 {
5801 return;
5802 }
5803
5804
5805
5806 //Commented out until we find if it's valid
5807 /*
5808 if (!ob->ticcount)
5809 {if ( pstate->buttonstate[bt_use] && !pstate->buttonheld[bt_use] )
5810 pstate->buttonstate[bt_use] = false;
5811 }
5812 */
5813
5814
5815 if (pstate->attackframe >= DOGLICK.numattacks)
5816 Error("\n attackframe %d for DOGLICK gt numattacks %d",
5817 pstate->attackframe,DOGLICK.numattacks
5818 );
5819
5820
5821 cur = &(DOGLICK.attackinfo[pstate->attackframe]);
5822 if (! pstate->attackcount)
5823 {if (cur->attack == reset)
5824 {
5825 NewState(ob,&s_serialdog);
5826 pstate->attackframe = pstate->weaponframe = 0;
5827 return;
5828 }
5829 pstate->attackframe++;
5830 cur = &(DOGLICK.attackinfo[pstate->attackframe]);
5831 pstate->weaponframe = cur->frame;
5832 pstate->attackcount = cur->mtics;
5833
5834 }
5835 else
5836 pstate->attackcount --;
5837
5838 // if ( playerstate.buttonstate[bt_attack] && (!playerstate.buttonheld[bt_attack]) && (!W_CHANGE))
5839 // Cmd_Fire (ob);
5840
5841
5842 }
5843
5844 #endif
5845
T_DeadWait(objtype * ob)5846 void T_DeadWait(objtype*ob)
5847 {
5848 playertype *pstate;
5849
5850 M_LINKSTATE(ob,pstate);
5851 if ((ob->flags & FL_DESIGNATED) && (gamestate.battlemode == battle_CaptureTheTriad))
5852 {int otherteam = (pstate->team ^ 1);
5853
5854 ob->flags &= ~FL_DESIGNATED;
5855 UpdateKills = true;
5856 SpawnStatic(TEAM[otherteam].tilex,TEAM[otherteam].tiley,stat_collector,9);
5857 LASTSTAT->flags |= FL_COLORED;
5858 LASTSTAT->hitpoints = otherteam;
5859 LASTSTAT->flags |= FL_ABP;
5860 MakeStatActive(LASTSTAT);
5861
5862 }
5863 //ob->momentumx=0;
5864 //ob->momentumy=0;
5865
5866 if (pstate->heightoffset<36)
5867 {pstate->heightoffset++;
5868 pstate->oldheightoffset = pstate->heightoffset;
5869 }
5870
5871 if (ob==player)
5872 {
5873 UpdateLightLevel(player->areanumber);
5874 if ((pstate->falling==true) || (ob->momentumz==0))
5875 {
5876 if (BATTLEMODE)
5877 playerdead=true;
5878 else
5879 playstate = ex_died;
5880 }
5881 }
5882 /*
5883 if (BATTLEMODE)
5884 {
5885 objtype * killer=(objtype *)ob->target;
5886
5887 dx = killer->x - ob->x;
5888 dy = ob->y - killer->y;
5889
5890 if (dx && dy)
5891 ob->angle = atan2_appx (dx,dy);
5892 }
5893 */
5894 //CheckPlayerSpecials(ob);
5895 }
5896
5897 /*
5898 ===============
5899 =
5900 = T_Player
5901 =
5902 ===============
5903 */
5904
T_Player(objtype * ob)5905 void T_Player (objtype *ob)
5906 {
5907 playertype *pstate;
5908 statetype *oldstate;
5909
5910 #if (SHAREWARE == 0)
5911 int eluder;
5912 #endif
5913
5914 M_LINKSTATE(ob,pstate);
5915
5916
5917
5918 #if (SHAREWARE == 0)
5919 eluder = ((pstate->weapon == wp_dog) && gamestate.SpawnEluder);
5920 #endif
5921
5922 oldstate = ob->state;
5923
5924 if (ob->flags&FL_DYING)
5925 {
5926
5927 CheckPlayerSpecials(ob);
5928 PlayerMove(ob);
5929 if (
5930 (pstate->falling==true) ||
5931 (
5932 (!ob->momentumx) &&
5933 (!ob->momentumy) &&
5934 (!ob->momentumz) &&
5935 (!ob->state->tictime)
5936 )
5937 )
5938 {
5939 KillActor(ob);
5940 if (ob->state == &s_remoteguts12)
5941 NewState(ob,&s_gutwait);
5942 else
5943 NewState(ob,&s_deadwait);
5944 }
5945 return;
5946 }
5947
5948 Thrust(ob);
5949 if (ob->flags & FL_DYING)
5950 return;
5951
5952 oldstate = ob->state;
5953 CheckPlayerSpecials(ob);
5954 if (ob->state != oldstate)
5955 {
5956 if (ob->flags & FL_DYING)
5957 return;
5958 }
5959
5960 if (!(ob->flags & FL_PAIN))
5961 {if (!(ob->state->condition & SF_DOGSTATE))
5962 {if ((ob->momentumx || ob->momentumy) && (ob->state->condition != SF_DOWN))
5963 NewState(ob,&s_remotemove1);
5964 else if (NOMOM && (ob->state != &s_player))
5965 NewState(ob,&s_player);
5966 }
5967 else if (NOMOM
5968 #if (SHAREWARE == 0)
5969
5970 && (ob->state != &s_dogwait)
5971 #endif
5972
5973 )
5974
5975 NewState(ob,ob->state);
5976
5977 }
5978 else if (!ob->ticcount)
5979 {if (!(ob->state->condition & SF_DOGSTATE))
5980 NewState(ob,&s_player);
5981
5982 ob->flags &= ~FL_PAIN;
5983
5984 }
5985
5986 if (ob->flags & FL_DIDTAG)
5987 {ob->flags &= ~FL_DIDTAG;
5988 pstate->weapondowntics = (144 - TAGHANDHEIGHT)/GMOVE;
5989 }
5990
5991
5992 CheckWeaponStates(ob);
5993
5994
5995 if (ARMED(ob->dirchoosetime)
5996 //(gamestate.battlemode != battle_Tag)
5997 )
5998 {
5999 if (pstate->weapondowntics == 1) // change to up; during change, up and down
6000 // are never zero at the same time
6001 {
6002 pstate->weapondowntics = 0;
6003 pstate->weaponframe = pstate->attackframe = 0;
6004
6005 if (pstate->NETCAPTURED == -1)
6006 {
6007 pstate->weaponuptics = FREE.screenheight/GMOVE;
6008 pstate->weaponheight = pstate->weaponuptics*GMOVE ;
6009 pstate->NETCAPTURED = 1;
6010 // return;
6011 }
6012 else if (pstate->NETCAPTURED == -2)
6013 {
6014 pstate->weaponuptics = WEAPONS[pstate->weapon].screenheight/GMOVE;
6015 pstate->weaponheight = pstate->weaponuptics*GMOVE ;
6016 pstate->NETCAPTURED = 0;
6017
6018 //return;
6019 }
6020 else
6021 {
6022 pstate->weaponuptics = WEAPONS[pstate->new_weapon].screenheight/GMOVE;
6023 pstate->weapon = pstate->new_weapon;
6024
6025 pstate->weaponheight = pstate->weaponuptics*GMOVE ;
6026 }
6027 }
6028
6029 else
6030 CheckWeaponChange (ob);
6031 }
6032
6033 else if (gamestate.battlemode == battle_Hunter)
6034 {
6035 if (pstate->weapondowntics == 1)
6036
6037 {
6038 pstate->weapondowntics = 0;
6039 pstate->weaponframe = pstate->attackframe = pstate->batblast = 0;
6040 pstate->weapon = pstate->new_weapon;
6041 }
6042 }
6043
6044 // if ( pstate->buttonstate[bt_use] && (!W_CHANGE(pstate)) )
6045
6046 if ( pstate->buttonstate[bt_use] )
6047 Cmd_Use (ob);
6048
6049
6050 if (W_CHANGE(pstate))
6051 return;
6052
6053
6054
6055
6056 if ((!ARMED(ob->dirchoosetime))
6057 #if (SHAREWARE == 0)
6058 && (pstate->weapon != wp_dog)
6059 #endif
6060 )
6061 return;
6062
6063 if (pstate->buttonstate[bt_attack])
6064 {
6065 #if (SHAREWARE == 0)
6066
6067 if (eluder)
6068 Cmd_Fire(ob);
6069
6070 else if ((pstate->weapon == wp_bat) ||
6071 (pstate->weapon == wp_dog)
6072 )
6073 {
6074 int oldblast=pstate->batblast;
6075
6076 pstate->batblast ++;
6077
6078 if (pstate->weapon==wp_bat)
6079 {
6080 if (pstate->batblast == 20)
6081 SD_PlaySoundRTP(SD_EXCALIBUILDSND,ob->x,ob->y);
6082 }
6083 else
6084 {
6085 if ((pstate->batblast>>4)!=(oldblast>>4))
6086 {
6087 int handle;
6088
6089 handle=SD_PlaySoundRTP(SD_DOGMODEPREPBLASTSND,ob->x,ob->y);
6090 SD_SetSoundPitch(handle,-(BBTIME<<3)+(pstate->batblast<<3));
6091 }
6092 }
6093 if (pstate->batblast < BBTIME)
6094 return;
6095
6096 if (pstate->weapon == wp_bat)
6097 SD_PlaySoundRTP(SD_EXCALIBLASTSND,ob->x,ob->y);
6098 else
6099 SD_PlaySoundRTP(SD_DOGMODEBLASTSND,ob->x,ob->y);
6100 }
6101
6102 if ((pstate->weapon != wp_split) || (!pstate->buttonheld[bt_attack]))
6103 #endif
6104 // if (!pstate->buttonheld[bt_attack])
6105 //#endif
6106 {
6107
6108 #if (SHAREWARE == 0)
6109
6110 if (pstate->weapon == wp_kes)
6111 SD_PlaySoundRTP(SD_GRAVBUILDSND,ob->x,ob->y);
6112 #endif
6113
6114 Cmd_Fire (ob);
6115 }
6116 }
6117
6118 #if (SHAREWARE == 0)
6119
6120 else if (
6121 ((pstate->weapon == wp_bat) ||
6122 ((pstate->weapon == wp_dog) && (!eluder))
6123 ) &&
6124 (pstate->buttonheld[bt_attack])
6125 )
6126 {
6127 if (pstate->weapon == wp_bat)
6128 SD_StopSound(SD_EXCALIBUILDSND);
6129 pstate->batblast = 0;
6130 Cmd_Fire(ob);
6131 }
6132 #endif
6133
6134 }
6135
6136
6137
6138