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