rott/rott/rt_playr.c

6383 lines
148 KiB
C
Executable File

/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifdef DOS
#include <dos.h>
#endif
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include "rt_def.h"
#include "watcom.h"
#include "rt_sound.h"
#include "gmove.h"
#include "states.h"
#include "rt_sqrt.h"
#include "rt_actor.h"
#include "rt_main.h"
#include "rt_playr.h"
#include "isr.h"
#include "rt_draw.h"
#include "rt_ted.h"
#include "rt_door.h"
#include "rt_menu.h"
#include "rt_view.h"
#include "rt_com.h"
#include "rt_in.h"
#include "rt_util.h"
#include "rt_game.h"
#include "rt_rand.h"
#include "z_zone.h"
#include "rt_swift.h"
#include "engine.h"
#include "_rt_play.h"
#include "rt_cfg.h"
#include "rt_spbal.h"
#include "rt_floor.h"
#include "develop.h"
#include "rt_msg.h"
#include "rt_debug.h"
#include "sprites.h"
#include "rt_net.h"
#include "rt_dmand.h"
//MED
#include "memcheck.h"
#define FLYINGZMOM 350000
#if (DEVELOPMENT == 1)
#include "rt_str.h"
#endif
extern boolean usejump;
specials CurrentSpecialsTimes =
{
60*VBLCOUNTER, // god
60*VBLCOUNTER, // dog
20*VBLCOUNTER, // shrooms
20*VBLCOUNTER, // elasto
60*VBLCOUNTER, // asbestos vest
60*VBLCOUNTER, // bullet proof vest
GASTICS, // gas mask
60*VBLCOUNTER, // mercury mode
300*VBLCOUNTER, // god respawn
60*VBLCOUNTER, // dog respawn
60*VBLCOUNTER, // shrooms respawn
60*VBLCOUNTER, // elasto respawn
60*VBLCOUNTER, // asbestos vest respawn
60*VBLCOUNTER, // bullet proof vest respawn
60*VBLCOUNTER, // gas mask respawn
60*VBLCOUNTER // mercury mode respawn
};
int GRAVITY = NORMAL_GRAVITY;
ROTTCHARS characters[5]={
{0x2100,0x4800,100,2,25}, // Taradino Cassatt
{0x2200,0x5200,85,3,32}, // Thi Barrett
{0x1f00,0x4000,150,3,20}, // Doug Wendt
{0x2300,0x5500,70,2,33}, // Lorelei Ni
{0x2000,0x4400,120,3,25}}; // Ian Paul Freeley
static const int TD = MINACTORDIST+0x1000;
static const int STRAFEAMOUNT = ((KEYBOARDNORMALTURNAMOUNT >> 10) + (KEYBOARDNORMALTURNAMOUNT >> 12));
static const int GODYZANGLE = -(9*FINEANGLES/360);
static const int DOGYZANGLE = (4*FINEANGLES/360);
static const int SHROOMYZANGLE = (15*FINEANGLES/360);
static const int FALLINGYZANGLE = -(15*FINEANGLES/360);
static const int NORMALYZANGLE = 0;
/*
=============================================================================
GLOBAL VARIABLES
=============================================================================
*/
int controlbuf[3];
int buttonbits;
extern _2Dpoint LASTSOUND;
//
// player state info
//
statobj_t *DEADPLAYER[MAXDEAD];
int NUMDEAD;
int lastpolltime;
statobj_t *BulletHoles[MAXBULLETS];
int BulletHoleNum;
objtype *PLAYER[MAXPLAYERS],*player;
playertype PLAYERSTATE[MAXPLAYERS],*locplayerstate;
gametype gamestate;
boolean godmode = false;
boolean missilecam=false;
objtype * missobj=NULL;
// Player control variables
int KX = 0;
int KY = 0;
int MX = 0;
int MY = 0;
int JX = 0;
int JY = 0;
int CX = 0;
int CY = 0;
boolean vrenabled = false;
int VX = 0;
int VY = 0;
int oldcyberx = 0;
int oldcybery = 0;
int CYBERDEADRANGE = 6000;
boolean CYBERLOOKUP,CYBERLOOKDOWN;
int leftmom = 0;
int rightmom = 0;
int lastmom = 0;
int first = 1;
int pausedstartedticcount;
boolean RefreshPause = true;
boolean buttonpoll[NUMBUTTONS];
int buttonscan[NUMBUTTONS] = {sc_Control, sc_Alt, sc_RShift, sc_Space,
sc_PgUp,sc_PgDn,sc_Enter,sc_Delete,
sc_Home,sc_End,sc_1,sc_2,sc_3,sc_4,
sc_CapsLock, sc_F12,
sc_Comma,sc_Period,sc_BackSpace,sc_A,
sc_UpArrow, sc_RightArrow,
sc_DownArrow, sc_LeftArrow,
sc_Tab, sc_T, sc_Z };
int joyxmax = 0, joyymax = 0, joyxmin = 0, joyymin = 0;
int buttonmouse[6] = {bt_attack, bt_strafe, di_north,
bt_nobutton, bt_use, bt_nobutton };
int buttonjoy[8] = {bt_attack, bt_strafe, bt_run, bt_use,
bt_nobutton, bt_nobutton, bt_nobutton, bt_nobutton };
williamdidthis FREE = {84,5,0,0,9,{{done,2,1},{done,2,2},{done,2,3},
{done,2,4},{done,2,5},{done,2,6},{done,2,7},{done,2,8},
{reset,2,9}}};
williamdidthis DOGSCRATCH = {128,5,0,0,4,{{done,2,8},{at_pulltrigger,2,9},{done,2,10},
{reset,2,11}}};
williamdidthis DOGLICK = {128,5,0,0,4,{{done,2,4},{done,2,5},{done,2,6},
{reset,2,7}}};
williamdidthis WEAPONS[MAXWEAPONS] =
{
{100,-1,10,0x2000l,3,{{at_pulltrigger,4,1},{done,4,2},{reset,4,0}}}, //single pistol
{100,-1,10,0x2000l,6,{{at_pulltrigger,2,1},{done,2,2},{done,2,3},
{at_pulltrigger,2,4},{done,2,5},{reset,2,3}}}, // double pistol
{70,-1,10,0x2000l,2,{{at_pulltrigger,2,1},{reset,1,2}}}, //mp 40
{80,5,10,0x50000l,4,{{at_missileweapon,2,1},{done,2,2},{reset,2,3},{reset2,6,0}}}, //bazooka
{80,5,10,0x10000l,4,{{at_missileweapon,2,1},{done,2,2},{reset,2,3},{reset2,6,0}}}, //firebomb
{80,5,10,0x50000l,4,{{at_missileweapon,2,1},{done,2,2},{reset,2,3},{reset2,6,0}}}, //heatseeker
{80,5,10,0x10000l,4,{{at_missileweapon,2,1},{done,2,2},{reset,2,3},{reset2,6,0}}}, //drunk
{80,5,7,0x10000l,4,{{at_missileweapon,2,1},{done,2,2},{reset,2,2},{reset2,6,0}}}, // firewall
{125,5,7,0x10000l,7,{{done,3,1},{done,3,2},{done,3,3},{done,3,4},
{at_missileweapon,3,5},{done,3,6},{reset,3,7}}}, //GODHAND
#if (SHAREWARE == 0)
{80,5,7,0x10000l,4,{{at_missileweapon,2,1},{done,2,2},{reset,2,3},{reset2,6,0}}}, //split
{80,5,7,0x10000l,9,{{done,5,1},{done,5,2},{done,5,3},{done,5,4},
{at_missileweapon,10,5},{done,5,4},{done,5,3}, // kes
{done,5,2},{reset,5,1}}},
{200,5,7,0x10000l,6,{{done,1,1},{done,1,2},{at_pulltrigger,1,3},{at_pulltrigger,1,4},
{at_pulltrigger,1,5},{reset,1,6}}}, //BAT
{128,5,7,0x10000l,3,{{done,2,1},{at_pulltrigger,2,2},{reset,2,3}}}
#endif
};
/*
=============================================================================
LOCAL FUNCTION PROTOTYPES and VARIABLES
=============================================================================
*/
void CheckPlayerSpecials(objtype * ob);
void CheckWeaponStates(objtype * ob);
boolean CheckSprite (statobj_t* ,int *);
void T_Tag (objtype *ob);
void T_Player (objtype *ob);
void T_BatBlast(objtype*ob);
void T_Attack (objtype *ob);
void T_Free (objtype *ob);
void T_DogUse (objtype *ob);
void PlayerMove(objtype * ob);
void Thrust (objtype * ob);
void CheckWeaponChange (objtype * ob);
void PlayerMissileAttack(objtype* );
void Cmd_Use(objtype*);
//void ComError (char *error, ...);
int FinddTopYZANGLELIMITvalue(objtype *ob);
statetype s_free = {false,0,0,T_Free,0,&s_free};
statetype s_inelevator = {false,0,420,T_Player,0,&s_player};
#if (SHAREWARE == 0)
statetype s_dogwait = {true,SERIALDOG_W11,50,T_Player,SF_DOGSTATE,&s_serialdog};
statetype s_doguse = {true,SERIALDOG_W11,140,T_DogUse,SF_DOGSTATE,&s_serialdog};
statetype s_doglick = {true,SERIALDOG_W11,0,T_DogLick,SF_DOGSTATE,&s_doglick};
#endif
statetype s_tag = {false,CASSATT_S1,20,T_Tag,0,&s_player};
static SWIFT_3DStatus SWIFTStatus;
//
// curent user input
//
static int turnheldtime;
static int turnaround = 0;
static int turnaroundtime;
//
// Double Click variables
//
static int DoubleClickTimer[ 3 ] = { 0 };
static byte DoubleClickCount[ 3 ] = { 0 };
static byte DoubleClickPressed[ 3 ] = { false };
static int JoyDblClickTimer[ 4 ] = { 0 };
static byte JoyDblClickCount[ 4 ] = { 0 };
static byte JoyDblClickPressed[ 4 ] = { false };
static int PlayerRecording=-1;
static int nettics;
void Move_Player_From_Exit_To_Start(objtype *ob);
void CheckTagGame(objtype *actor1,objtype*actor2);
void CheckFlying(objtype*ob,playertype *pstate);
/*
===============
=
= LoadPlayer
=
===============
*/
void LoadPlayer ( void )
{
memset (locplayerstate->buttonstate, 0, sizeof(locplayerstate->buttonstate));
locplayerstate->anglefrac=player->angle<<ANGLEBITS;
areabyplayer[player->areanumber]=true;
ConnectAreas();
}
int MaxHitpointsForCharacter(playertype*pstate)
{
if (BATTLEMODE && (gamestate.BattleOptions.HitPoints != bo_character_hitpoints))
{
return( gamestate.BattleOptions.HitPoints );
}
return characters[pstate->player].hitpoints;
}
void InitializeWeapons(playertype*pstate)
{
#if (SHAREWARE == 0)
if (gamestate.SpawnEluder)
{pstate->new_weapon = pstate->weapon = pstate->missileweapon = wp_dog;
pstate->oldweapon = pstate->oldmissileweapon = wp_dog;
pstate->bulletweapon = -1;
pstate->HASBULLETWEAPON[wp_pistol] = 0;
pstate->HASBULLETWEAPON[wp_twopistol] = 0;
pstate->HASBULLETWEAPON[wp_mp40] = 0;
}
else
#endif
{if (gamestate.PlayerHasGun[pstate-&PLAYERSTATE[0]])
{pstate->new_weapon = pstate->weapon = pstate->oldweapon =
pstate->bulletweapon = wp_pistol;
pstate->HASBULLETWEAPON[wp_pistol] = 1;
pstate->HASBULLETWEAPON[wp_twopistol] = 0;
pstate->HASBULLETWEAPON[wp_mp40] = 0;
pstate->missileweapon = pstate->oldmissileweapon = -1;
}
else
{pstate->new_weapon = pstate->weapon = pstate->oldweapon =
pstate->bulletweapon = -1;
pstate->HASBULLETWEAPON[wp_pistol] = 0;
pstate->HASBULLETWEAPON[wp_twopistol] = 0;
pstate->HASBULLETWEAPON[wp_mp40] = 0;
pstate->missileweapon = pstate->oldmissileweapon = -1;
}
}
pstate->ammo = -1;
}
void ResetPlayerstate(playertype*pstate)
{
pstate->batblast = 0;
pstate->poweruptime = pstate->protectiontime = 0;
pstate->NETCAPTURED = 0;
MISCVARS->NET_IN_FLIGHT = 0;
pstate->weaponuptics = 0;
pstate->weapondowntics = 0;
if ((insetupgame==false) || NewGame)
pstate->health = MaxHitpointsForCharacter(pstate);
pstate->keys = 0;
// Give players all the keys in battle game
if ( BATTLEMODE )
{
pstate->keys = 0x0f;
}
pstate->attackframe = pstate->attackcount =
pstate->weaponframe = 0;
if (gamestate.battlemode == battle_Tag)
pstate->weaponheight = TAGHANDHEIGHT;
else
pstate->weaponheight = 0;
pstate->heightoffset = pstate->oldheightoffset = 0;
if (gamestate.SpawnEluder)
pstate->playerheight = 40;
else
pstate->playerheight = characters[pstate->player].height;
pstate->falling = false;
memset (pstate->buttonstate, 0, sizeof(pstate->buttonstate));
SetPlayerHorizon(pstate,NORMALYZANGLE);
}
/*
===============
=
= SetupPlayerobj
=
===============
*/
void SetupPlayerobj (int tilex, int tiley, int dir, objtype * ob)
{
playertype *pstate;
M_LINKSTATE(ob,pstate);
ob->obclass = playerobj;
ob->tilex = tilex;
ob->tiley = tiley;
actorat[tilex][tiley] = ob;
ob->areanumber = MAPSPOT(tilex,tiley,0)-AREATILE;
MakeLastInArea(ob);
ob->x = ((long)tilex<<TILESHIFT)+TILEGLOBAL/2;
ob->y = ((long)tiley<<TILESHIFT)+TILEGLOBAL/2;
ob->z = PlatformHeight(tilex,tiley);
if ((ob->z == -10) || DiskAt(tilex,tiley))
ob->z = 0;
ob->angle = (1-dir)*ANG90;
ob->which = ACTOR;
Fix(ob->angle);
ob->yzangle = 0;
ob->dir = angletodir[ob->angle];
ob->flags = (FL_SHOOTABLE|FL_ABP|FL_BLOCK|FL_COLORED);
ob->drawx=ob->x;
ob->drawy=ob->y;
ob->hitpoints = pstate->health;
pstate->anglefrac= (ob->angle<<ANGLEBITS);
pstate->angle=0;
areabyplayer[ob->areanumber]=true;
if (ob == player)
{
playerdead=false; // local player dead flag
}
if (!gamestate.SpawnEluder)
ob->shapeoffset = pstate->player*REMOTEOFFSET;
memset (pstate->buttonstate, 0, sizeof(pstate->buttonstate));
if (SCREENEYE != NULL)
{
NewState(SCREENEYE,&s_megaremove);
SCREENEYE = NULL;
}
}
void SetShapeoffset(objtype*ob)
{playertype *pstate;
M_LINKSTATE(ob,pstate);
ob->shapeoffset = pstate->player*REMOTEOFFSET;
ob->flags |= FL_COLORED;
ob->flags &= ~FL_DYING;
}
/*
===============
=
= RevivePlayerobj
=
===============
*/
void RevivePlayerobj (int tilex, int tiley, int dir, objtype*ob)
{
playertype *pstate;
statetype *tstate;
M_LINKSTATE(ob,pstate);
tstate = ob->state;
RemoveFromArea(ob);
TurnActorIntoSprite(ob);
if ((LASTSTAT->z < nominalheight) && (!IsPlatform(LASTSTAT->tilex,LASTSTAT->tiley)))
{
SpawnParticles(ob,GUTS,10 + gamestate.difficulty);
RemoveStatic(LASTSTAT);
}
else
{if (DEADPLAYER[NUMDEAD])
RemoveStatic(DEADPLAYER[NUMDEAD]);
DEADPLAYER[NUMDEAD] = LASTSTAT;
LASTSTAT->linked_to = NUMDEAD;
NUMDEAD = (NUMDEAD+1)&(MAXDEAD-1);
}
ob->state = tstate;
SetupPlayerobj (tilex, tiley, dir, ob);
ConnectAreas();
ResetPlayerstate(pstate);
InitializeWeapons(pstate);
SD_PlaySoundRTP(SD_PLAYERSPAWNSND,ob->x,ob->y);
if (!gamestate.SpawnEluder)
{
ob->shapeoffset = 0;
ob->flags &= ~FL_COLORED;
ob->flags |= FL_DYING;
NewState(ob,&s_respawn1);
if (gamestate.battlemode == battle_Tag)
{
if (BATTLE_Team[ob->dirchoosetime] == BATTLE_It)
{
pstate->missileweapon = pstate->oldweapon = pstate->new_weapon =
pstate->oldmissileweapon = pstate->weapon = wp_godhand;
pstate->bulletweapon = -1;
ob->flags |= FL_DESIGNATED;
}
else
{
pstate->weaponheight = 0;
}
}
}
#if (SHAREWARE == 0)
else
NewState(ob,&s_serialdog);
#endif
if (ob==player)
DrawPlayScreen(false);
ob->momentumx = ob->momentumy = ob->momentumz = 0;
}
/*
===============
=
= SpawnPlayerobj
=
===============
*/
void SpawnPlayerobj (int tilex, int tiley, int dir, int playerindex)
{
playertype *pstate;
pstate = &PLAYERSTATE[playerindex];
GetNewActor();
MakeActive(new);
// Set player number
new->dirchoosetime = playerindex;
// Save off if local player
if (playerindex==consoleplayer)
player=new;
PLAYER[playerindex] = new;
SetupPlayerobj (tilex, tiley, dir, new);
if (!gamestate.SpawnEluder)
NewState(new,&s_player);
#if (SHAREWARE == 0)
else
NewState(new,&s_serialdog);
#endif
}
/*
===============
=
= SetupBulletHoleLink
=
===============
*/
void SetupBulletHoleLink (int num, statobj_t * item)
{
BulletHoles[num] = item;
}
/*
===============
=
= SpawnBulletHole
=
===============
*/
void SpawnBulletHole (int x, int y, int z)
{
if (M_ISDOOR(x>>16,y>>16))
return;
if (BulletHoles[MISCVARS->BulletHoleNum])
RemoveStatic(BulletHoles[MISCVARS->BulletHoleNum]);
SpawnInertStatic(x,y,z,stat_bullethole);
BulletHoles[MISCVARS->BulletHoleNum]=LASTSTAT;
LASTSTAT->linked_to=MISCVARS->BulletHoleNum;
MISCVARS->BulletHoleNum = (MISCVARS->BulletHoleNum+1)&(MAXBULLETS-1);
}
void SpawnGunSmoke(int x, int y, int z, int angle, int bullethole)
{
int chance;
if ((x<=0) || (y<=0))
{
SoftError("SpawnGunSmoke: xy below angle=%d\n",angle);
return;
}
if ((bullethole!=0) && (z>=-32) && (z<=maxheight))
switch (bullethole)
{
case 1:
SpawnBulletHole(x-BULLETHOLEOFFSET,y,z);
break;
case 2:
SpawnBulletHole(x+BULLETHOLEOFFSET,y,z);
break;
case 3:
SpawnBulletHole(x,y-BULLETHOLEOFFSET,z);
break;
case 4:
SpawnBulletHole(x,y+BULLETHOLEOFFSET,z);
break;
case 5:
SpawnBulletHole(x,y,z);
break;
default:
Error("Invalid bullethole value\n");
break;
}
SpawnInertActor(x,y,z);
NewState(new,&s_gunsmoke1);
if (angle < ANGLES/4)
{if ((angle < (3*ANGLES/16)) && (angle > (ANGLES/16)))
chance = 128;
else
chance = 20;
}
else if (angle < ANGLES/2)
{if ((angle < (7*ANGLES/16)) && (angle > (5*ANGLES/16)))
chance = 128;
else
chance = 20;
}
else if (angle < 3*ANGLES/4)
{if ((angle < (11*ANGLES/16)) && (angle > (9*ANGLES/16)))
chance = 128;
else
chance = 20;
}
else
{if ((angle < (15*ANGLES/16)) && (angle > (13*ANGLES/16)))
chance = 128;
else
chance = 20;
}
if (RandomNumber("Wall ricochet check",0)<chance)
{int rand;
rand = RandomNumber("Spawn Ricochet Sound in SpawnGunSmoke",0);
if (rand < 80)
SD_PlaySoundRTP(SD_RICOCHET1SND,new->x,new->y);
else if (rand < 160)
SD_PlaySoundRTP(SD_RICOCHET2SND,new->x,new->y);
else
SD_PlaySoundRTP(SD_RICOCHET3SND,new->x,new->y);
}
}
void SpawnBlood(objtype * ob, int angle)
{
SpawnInertActor(ob->x-(costable[angle]>>5),
ob->y+(sintable[angle]>>5),ob->z);
NewState(new,&s_bloodspurt1);
if ((new->x<=0) || (new->y<=0))
Error("SpawnBlood: bad x,y obj->obclass=%d\n",ob->obclass);
}
void SpawnMetalSparks(objtype * ob, int angle)
{
int rand,dispx=0,dispy=0;
if (ob->which == ACTOR)
{
dispx = ob->momentumx;
dispy = ob->momentumy;
}
SpawnInertActor(ob->x-(costable[angle]>>3)+dispx,
ob->y+(sintable[angle]>>3)+dispy,ob->z);
if (GameRandomNumber("Spawn Metal Sparks",0)<128)
NewState(new,&s_hitmetalactor1);
else
NewState(new,&s_hitmetalwall1);
rand = RandomNumber("Spawn Ricochet Sound",0);
if (rand < 80)
SD_PlaySoundRTP(SD_RICOCHET1SND,new->x,new->y);
else if (rand < 160)
SD_PlaySoundRTP(SD_RICOCHET2SND,new->x,new->y);
else
SD_PlaySoundRTP(SD_RICOCHET3SND,new->x,new->y);
if ((new->x<=0) || (new->y<=0))
Error("SpawnMetalSparks: bad x,y obj->obclass=%d\n",ob->obclass);
}
/*
===============
=
= UnTargetActor ( objtype * target )
=
===============
*/
void UnTargetActor ( objtype * target )
{
int i;
for (i=0;i<numplayers;i++)
{
if (PLAYERSTATE[i].guntarget==target)
{
PLAYERSTATE[i].guntarget=NULL;
SetNormalHorizon(PLAYER[i]);
}
}
}
//=============================================================
int GetWeaponForItem(int itemnumber)
{
switch (itemnumber)
{
case stat_twopistol:
return wp_twopistol;
case stat_mp40:
return wp_mp40;
case stat_bazooka:
return wp_bazooka;
case stat_heatseeker:
return wp_heatseeker;
case stat_drunkmissile:
return wp_drunk;
case stat_firebomb:
return wp_firebomb;
case stat_firewall:
return wp_firewall;
case stat_godmode:
return wp_godhand;
#if (SHAREWARE == 0)
case stat_splitmissile:
return wp_split;
case stat_kes:
return wp_kes;
case stat_bat:
return wp_bat;
case stat_dogmode:
return wp_dog;
#endif
}
return 0;
}
int GetItemForWeapon(int weapon)
{
switch (weapon)
{
case wp_twopistol:
return stat_twopistol;
case wp_mp40:
return stat_mp40;
case wp_bazooka:
return stat_bazooka;
case wp_heatseeker:
return stat_heatseeker;
case wp_drunk:
return stat_drunkmissile;
case wp_firebomb:
return stat_firebomb;
case wp_firewall:
return stat_firewall;
case wp_godhand:
return stat_godmode;
#if (SHAREWARE == 0)
case wp_split:
return stat_splitmissile;
case wp_kes:
return stat_kes;
case wp_bat:
return stat_bat;
case wp_dog:
return stat_dogmode;
#endif
}
return -1;
}
#define MF_SINGULAR 0x01
missile_stats PlayerMissileData[13] =
{
{0,0,0,0,0},
{0,0,0,0,0},
{0,0,0,0,0},
{&s_p_bazooka1,0x6000,p_bazookaobj,0x7000,MF_SINGULAR},
{&s_p_bazooka1,0x8000,p_heatseekobj,0x7000,MF_SINGULAR},
{&s_p_bazooka1,0x6000,p_drunkmissileobj,0x7000,0},
{&s_p_bazooka1,0x8000,p_firebombobj,0x7000,MF_SINGULAR},
{&s_p_grenade,0x4000,p_firewallobj,0x8000,0},
{&s_godfire1,0x3800,p_godballobj,0x8000,0},
{&s_p_bazooka1,0x8000,p_splitmissileobj,0x7000,MF_SINGULAR},
#if (SHAREWARE == 0)
{&s_kessphere1,0xc000,p_kesobj,0x5000,MF_SINGULAR},
#else
{0,0,0,0,0},
#endif
{0,0,0,0,0},
{0,0,0,0,0}
};
void MissileAutoTarget(objtype *ob,missile_stats *mdata)
{
int dx,dy,angle,mindist,currdist,magangle,saveangle,
xydist,dz,yzangle,oldyzangle,saveyzangle;
objtype *target,*temp;
mindist = 0x7fffffff;
target = NULL;
for(temp = firstactive;temp;temp=temp->nextactive)
{
if (temp == ob)
continue;
if ((!(temp->flags & FL_SHOOTABLE)) || (temp->flags & FL_DYING))
continue;
if (!CheckLine(ob,temp,SHOOT))
continue;
dx = temp->x-ob->x;
dy = ob->y-temp->y;
dz = ob->z-temp->z;
xydist = FindDistance(dx,dy);
yzangle = atan2_appx(xydist,dz<<10);
angle = atan2_appx(dx,dy);
magangle = abs(ob->angle - angle);
if (magangle > VANG180)
magangle = ANGLES - magangle;
if (magangle > ANGLESDIV8)
continue;
currdist = FindDistance(ob->x-temp->x,ob->y-temp->y);
if (currdist < mindist)
{
mindist = currdist;
target = temp;
saveangle = angle;
saveyzangle = yzangle;
}
}
if (target)
{
oldyzangle = ob->yzangle;
ob->yzangle = saveyzangle;
SpawnMissile(ob,mdata->obclass,mdata->speed,saveangle,
mdata->state,mdata->offset);
ob->yzangle = oldyzangle;
}
else if (ob->flags&FL_GODMODE)
{
int saveangle;
saveangle=ob->yzangle;
ob->yzangle -= GODYZANGLE;
Fix(ob->yzangle);
SpawnMissile(ob,mdata->obclass,mdata->speed,
ob->angle,mdata->state,mdata->offset);
ob->yzangle=saveangle;
}
else
SpawnMissile(ob,mdata->obclass,mdata->speed,ob->angle,
mdata->state,mdata->offset);
}
void PlayerMissileAttack(objtype*ob)
{
playertype * pstate;
missile_stats *newmissiledata;
M_LINKSTATE(ob,pstate);
MISCVARS->madenoise = true;
newmissiledata = &PlayerMissileData[pstate->missileweapon];
// ready to annihilate this poor bastard
if ((newmissiledata->obclass == p_godballobj) ||
(newmissiledata->obclass == p_kesobj))
MissileAutoTarget(ob,newmissiledata);
else
{
SpawnMissile(ob,newmissiledata->obclass,newmissiledata->speed,ob->angle,
newmissiledata->state,newmissiledata->offset);
if (newmissiledata->obclass == p_drunkmissileobj)
{
int i;
for(i=0;i<4;i++)
{
if (!MissileTryMove(new,new->x+new->momentumx,new->y+new->momentumy,new->z))
{
new->x = new->drawx = ob->x + (costable[new->angle]>>3);
new->y = new->drawy = ob->y - (sintable[new->angle]>>3);
ob->momentumx = -FixedMul(0x5000l,costable[ob->angle]);
ob->momentumy = FixedMul(0x5000l,sintable[ob->angle]);
}
SpawnMissile(ob,newmissiledata->obclass,newmissiledata->speed,ob->angle,
newmissiledata->state,newmissiledata->offset);
}
}
}
if (newmissiledata->flags & MF_SINGULAR)
PLAYER0MISSILE = new;
SD_PlaySoundRTP(BAS[new->obclass].fire,ob->x,ob->y);
// if (new->obclass == p_godballobj)
// new->z += 10;
new->dirchoosetime = 5;
if (missilecam==true)
missobj=new;
if (!MissileTryMove(new,new->x+new->momentumx,new->y+new->momentumy,new->z))
{
new->x = new->drawx = ob->x + (costable[new->angle]>>3);
new->y = new->drawy = ob->y - (sintable[new->angle]>>3);
ob->momentumx = -FixedMul(0x5000l,costable[ob->angle]);
ob->momentumy = FixedMul(0x5000l,sintable[ob->angle]);
}
}
//====================================================================
boolean InRange (objtype *p, objtype *victim, int distance)
{
int dx,dy;
int angle;
int magangle;
if (victim->which==SPRITE)
{
dx = ((statobj_t *)victim)->x - p->x;
dy = p->y - ((statobj_t *)victim)->y;
}
else
{
dx = victim->x - p->x;
dy = p->y - victim->y;
}
angle = atan2_appx (dx,dy);
magangle = abs(p->angle - angle);
if (magangle > VANG180)
magangle = ANGLES - magangle;
if (magangle<(75-(distance>>16)))
return true;
else
return false;
}
void DogAttack(objtype*ob)
{
objtype *temp;
int dx,dy,dz;
SD_PlaySoundRTP(SD_DOGMODEBITE1SND+(RandomNumber("DogAttack",0)>>7),ob->x,ob->y);
for(temp=firstareaactor[ob->areanumber];temp;temp=temp->nextinarea)
{
if (temp->obclass > b_heinrichobj)
continue;
if ((temp == ob) || (temp->obclass == roboguardobj))
continue;
if ((!(temp->flags & FL_SHOOTABLE)) || (temp->flags & FL_DYING))
continue;
if (temp->obclass == collectorobj)
continue;
dx = abs(temp->x - ob->x);
if (dx > 0xc000)
continue;
dy = abs(temp->y - ob->y);
if (dy > 0xc000)
continue;
dz = abs(temp->z - ob->z);
if (dz > (0xc000>>10))
continue;
DamageThing(temp,30);
if (gamestate.violence == vl_excessive)
SpawnParticles(temp,GUTS,15);
Collision(temp,ob,-temp->momentumx,-temp->momentumy);
if ((temp->obclass == playerobj) && (temp->flags & FL_DYING))
BATTLE_PlayerKilledPlayer(battle_kill_with_missile,ob->dirchoosetime,temp->dirchoosetime);
return;
}
}
void DogBlast(objtype*ob)
{
int txl,txh,tyl,tyh,radius = 0x70000,x,y,tile;
objtype*temp;
statobj_t*tstat;
txl = ((ob->x - radius)>>TILESHIFT);
tyl = ((ob->y - radius)>>TILESHIFT);
txh = ((ob->x + radius)>>TILESHIFT);
tyh = ((ob->y + radius)>>TILESHIFT);
if (txl < 1)
txl = 1;
if (txh > MAPSIZE-1)
txh = MAPSIZE-1;
if (tyl < 1)
tyl = 1;
if (tyh > MAPSIZE-1)
tyh = MAPSIZE-1;
for(x=txl;x<=txh;x++)
for(y=tyl;y<=tyh;y++)
{
temp = (objtype*)actorat[x][y];
if (temp && (temp->which == ACTOR) && (temp->flags & FL_SHOOTABLE) &&
(temp != ob) && (temp->obclass < roboguardobj) &&
(temp->flags & FL_ABP)
)
{
DamageThing(temp,100);
if ((temp->hitpoints<=0) && (temp->obclass < roboguardobj))
{
MISCVARS->supergibflag = true;
temp->flags |= FL_HBM;
}
Collision(temp,ob,0,0);
MISCVARS->supergibflag = false;
if ((temp->obclass == playerobj) && (temp->flags & FL_DYING))
BATTLE_PlayerKilledPlayer(battle_kill_with_missile,ob->dirchoosetime,temp->dirchoosetime);
}
tile = tilemap[x][y];
if ((tile & 0x4000) && (tile & 0x8000))
{
maskedwallobj_t * mw;
mw=maskobjlist[tile&0x3ff];
if ((mw->flags & MW_SHOOTABLE) && (mw->flags & MW_ABP))
UpdateMaskedWall(tile&0x3ff);
}
tstat = sprites[x][y];
if (tstat && (tstat->flags & FL_SHOOTABLE) && (tstat->flags & FL_ABP))
DamageThing(tstat,50);
}
}
/*
void DogBlast(objtype*ob)
{
int txl,txh,tyl,tyh,radius = 0x70000,x,y,tile;
objtype*temp;
statobj_t*tstat;
txl = ((ob->x - radius)>>TILESHIFT);
tyl = ((ob->y - radius)>>TILESHIFT);
txh = ((ob->x + radius)>>TILESHIFT);
tyh = ((ob->y + radius)>>TILESHIFT);
if (txl < 1)
txl = 1;
if (txh > MAPSIZE-1)
txh = MAPSIZE-1;
if (tyl < 1)
tyl = 1;
if (tyh > MAPSIZE-1)
tyh = MAPSIZE-1;
for(x=txl;x<=txh;x++)
for(y=tyl;y<=tyh;y++)
{
temp = (objtype*)actorat[x][y];
if (temp && (temp->which == ACTOR) && (temp->flags & FL_SHOOTABLE) &&
(temp != ob) && (temp->obclass < roboguardobj))
{
DamageThing(temp,100);
if ((temp->hitpoints<=0) && (temp->obclass < roboguardobj))
{
MISCVARS->supergibflag = true;
temp->flags |= FL_HBM;
}
Collision(temp,ob,0,0);
MISCVARS->supergibflag = false;
if ((temp->obclass == playerobj) && (temp->flags & FL_DYING))
BATTLE_PlayerKilledPlayer(battle_kill_with_missile,ob->dirchoosetime,temp->dirchoosetime);
}
tile = tilemap[x][y];
if ((tile & 0x4000) && (tile & 0x8000))
{
maskedwallobj_t * mw;
mw=maskobjlist[tile&0x3ff];
if (mw->flags & MW_SHOOTABLE)
UpdateMaskedWall(tile&0x3ff);
}
tstat = sprites[x][y];
if (tstat && (tstat->flags & FL_SHOOTABLE))
DamageThing(tstat,50);
}
}
*/
void BatBlast(objtype*ob)
{int angle;
playertype *pstate;
M_LINKSTATE(ob,pstate);
angle = ob->angle - ANGLES/8 + ((++pstate->batblast)*ANGLES/48);
Fix(angle);
#if (SHAREWARE == 0)
SpawnMissile(ob,p_bazookaobj,0x6000,angle,&s_batblast1,0xa000);
#endif
}
void BatAttack(objtype*ob)
{objtype *temp,*temp2;
objtype *grenadetarget;
statobj_t*tstat;
int dx,dy,dz,angle,momx,momy,op,magangle;
int tilexlow,tilexhigh;
int tileylow,tileyhigh;
int radius =0x10000;
int x,y;
SD_PlaySoundRTP(SD_EXCALISWINGSND,ob->x,ob->y);
for(temp=firstareaactor[ob->areanumber];temp;temp=temp->nextinarea)
{if (temp == ob)
continue;
if (temp->flags & FL_DYING)
continue;
if ((temp->obclass != grenadeobj) &&
(!((temp->obclass >= grenadeobj) && (temp->obclass <= p_godballobj))) &&
(!(temp->flags & FL_SHOOTABLE) ||
(temp->obclass >= roboguardobj))
)
continue;
dx = abs(temp->x - ob->x);
dy = abs(temp->y - ob->y);
dz = abs(temp->z - ob->z);
if ((dx > 0x10000) || (dy > 0x10000) || (dz > 20))
continue;
magangle = abs(ob->angle - AngleBetween(ob,temp));
if (magangle > VANG180)
magangle = ANGLES - magangle;
if (magangle > ANGLES/8)
continue;
angle= ob->angle+ANGLES/16;
Fix(angle);
if ((temp->obclass >= grenadeobj) && (temp->obclass <= p_godballobj))
{
temp->angle += ANGLES/2;
Fix(temp->angle);
temp->momentumx = temp->momentumy = temp->momentumz = 0;
ParseMomentum(temp,temp->angle);
temp->whatever = ob;
temp->target = NULL;
continue;
}
else if (temp->obclass != grenadeobj)
{momx = FixedMul(0x3000l,costable[angle]);
momy = -FixedMul(0x3000l,sintable[angle]);
if (levelheight > 2)
{op = FixedMul(GRAVITY,(maxheight-100)<<16) << 1;
temp->momentumz = -FixedSqrtHP(op);
}
temp->flags |= FL_NOFRICTION;
SD_PlaySoundRTP(SD_EXCALIHITSND,ob->x,ob->y);
if ((gamestate.violence == vl_excessive) && (GameRandomNumber("Bat Gibs",0) < 150))
{temp->flags |= FL_HBM;
DamageThing(temp,50);
}
else
DamageThing(temp,10);
if ((temp->flags & FL_HBM) && (temp->hitpoints > 0))
temp->flags &= ~FL_HBM;
Collision(temp,ob,momx,momy);
if ((temp->obclass == blitzguardobj) && (temp->state == &s_blitzplead7))
{temp->shapeoffset += deathshapeoffset[temp->obclass];
temp->flags |= FL_ALTERNATE;
NewState(temp,&s_blitzdie3);
temp->momentumx = temp->momentumy = 0;
}
}
else // find target to hit grenade back at
{int rand;
rand = GameRandomNumber("bat/grenade target",0);
if (rand < 80)
{grenadetarget = (objtype*)(temp->whatever); // hit back at george
GetMomenta(grenadetarget,ob,&(temp->momentumx),&(temp->momentumy),&(temp->momentumz),0x3000);
}
else if (rand < 160) // hit back at first eligible
{
for(temp2 = firstareaactor[ob->areanumber];temp2;temp2 = temp2->nextinarea)
{magangle = abs(ob->angle-AngleBetween(ob,temp2));
if (magangle > VANG180)
magangle = ANGLES - magangle;
if (magangle > ANGLES/8)
continue;
GetMomenta(temp2,ob,&(temp->momentumx),&(temp->momentumy),&(temp->momentumz),0x3000);
break;
}
}
else // hit wherever
{ob->angle += (rand >> 1);
Fix(ob->angle);
ob->momentumx = ob->momentumy = 0;
ParseMomentum(ob,ob->angle);
}
temp->temp1 = 0x70000;
NewState(temp,&s_grenade1);
}
break;
}
for(tstat=firstactivestat;tstat;tstat=tstat->statnext)
{
if (!(tstat->flags & FL_SHOOTABLE))
continue;
dx = abs(tstat->x - ob->x);
dy = abs(tstat->y - ob->y);
dz = abs(tstat->z - ob->z);
if ((dx > 0xc000) || (dy > 0xc000) || (dz > 20))
continue;
magangle = abs(ob->angle - AngleBetween(ob,(objtype*)tstat));
if (magangle > VANG180)
magangle = ANGLES - magangle;
if (magangle > ANGLES/8)
continue;
DamageThing(tstat,50);
}
tilexlow = (int)((ob->x-radius) >>TILESHIFT);
tileylow = (int)((ob->y-radius) >>TILESHIFT);
tilexhigh = (int)((ob->x+radius) >>TILESHIFT);
tileyhigh = (int)((ob->y+radius) >>TILESHIFT);
for (y=tileylow;y<=tileyhigh;y++)
for (x=tilexlow;x<=tilexhigh;x++)
{if ((tilemap[x][y]&0x8000) && (tilemap[x][y]&0x4000))
{maskedwallobj_t * mw;
mw=maskobjlist[tilemap[x][y]&0x3ff];
if (mw->flags&MW_SHOOTABLE)
UpdateMaskedWall(tilemap[x][y]&0x3ff);
}
}
}
void AutoTargetHorizon(objtype *ob)
{
int dx,dy,angle,mindist,magangle,
xydist,dz;
objtype *temp;
playertype * pstate;
M_LINKSTATE(ob,pstate);
mindist = 0x7fffffff;
for(temp = firstactive;temp;temp=temp->nextactive)
{
if (temp == ob)
continue;
if ((!(temp->flags & FL_SHOOTABLE)) || (temp->flags & FL_DYING))
continue;
if (!CheckLine(ob,temp,SHOOT))
continue;
dx = temp->x-ob->x;
dy = ob->y-temp->y;
dz = ob->z-temp->z;//-pstate->playerheight+32;
xydist = FindDistance(dx,dy);
if (abs(dz<<10)>xydist)
continue;
angle = atan2_appx(dx,dy);
magangle = ob->angle - angle;
Fix(magangle);
if (
(magangle>=(ANGLESDIV8/4)) &&
(magangle<=(FINEANGLES-(ANGLESDIV8/4)))
)
{
continue;
}
if (xydist < mindist)
{
mindist = xydist;
pstate->guntarget=temp;
temp->flags |= FL_TARGET;
pstate->targettime=oldpolltime+(VBLCOUNTER);
}
}
}
void GunAttack (objtype *ob)
{
playertype * pstate;
int damage;
M_LINKSTATE(ob,pstate);
MISCVARS->madenoise = true;
switch (pstate->weapon)
{
case wp_pistol:
SD_PlaySoundRTP(SD_ATKPISTOLSND,ob->x,ob->y);
damage=DMG_PISTOL;
break;
case wp_mp40:
SD_PlaySoundRTP(SD_ATKMP40SND,ob->x,ob->y);
damage=DMG_MP40;
break;
case wp_twopistol:
SD_PlaySoundRTP(SD_ATKTWOPISTOLSND,ob->x,ob->y);
damage=DMG_PISTOL;
break;
}
AutoTargetHorizon(ob);
RayShoot (ob, damage, (characters[pstate->player].accuracy+gamestate.difficulty)<<3);
}
/*
===============
=
= Cmd_Fire
=
===============
*/
void Cmd_Fire (objtype*ob)
{
playertype *pstate;
M_LINKSTATE(ob,pstate);
// pstate->buttonheld[bt_attack] = true;
if (pstate->NETCAPTURED && (!pstate->HASKNIFE))
return;
if (W_CHANGE(pstate))
return;
pstate->attackframe = 0;
if ((ob==player) && (pstate->weapon < wp_mp40) && (!pstate->NETCAPTURED))
gamestate.DODEMOCRATICBONUS1 = false;
if (!pstate->NETCAPTURED)
{
if (pstate->weapon <= wp_mp40)
NewState(ob,&s_pgunattack1);
#if (SHAREWARE == 0)
else if ((pstate->weapon == wp_bat) && (pstate->batblast >= BBTIME))
{
pstate->batblast = 0;
NewState(ob,&s_pbatblast);
}
else if (pstate->weapon == wp_dog)
NewState(ob,&s_serialdogattack);
#endif
else
NewState(ob,&s_pmissattack1);
#if (SHAREWARE == 0)
if ((pstate->weapon == wp_dog) && (!ob->momentumz))
ob->momentumz = -0x50000;
#endif
pstate->attackcount = WEAPONS[pstate->weapon].attackinfo[0].mtics;
pstate->weaponframe = WEAPONS[pstate->weapon].attackinfo[0].frame;
}
else if (pstate->NETCAPTURED == 1)
{
NewState(player,&s_free);
pstate->attackcount = FREE.attackinfo[0].mtics;
pstate->weaponframe = FREE.attackinfo[0].frame;
}
}
void PlayNoWaySound ( void )
{
if (player->flags & FL_DOGMODE)
SD_Play(SD_DOGMODEBITE2SND);
else if ((locplayerstate->player == 1) || (locplayerstate->player == 3))
SD_Play(SD_PLAYERTBHURTSND);
else
SD_Play(SD_NOWAYSND);
}
/*
===============
=
= Cmd_Use
=
===============
*/
boolean AreJumping = false;//bna added
int oldzval;
int donttilt=0;
void Cmd_Use (objtype*ob)
{
int checkx,checky,doorn,
/*newtilex,newtiley,oldtilex,oldtiley,*/elevnum,
wallx,wally;
// statobj_t* tempsprite=NULL;
objtype* tempactor= NULL;
doorobj_t* tempdoor=NULL;
pwallobj_t* temppwall=NULL;
wall_t* tempwall=NULL;
int index;
playertype * pstate;
M_LINKSTATE(ob,pstate);
#if (SHAREWARE == 0)
if ((pstate->weapon == wp_dog) && (ob->state != &s_doguse) &&
(ob->state != &s_dogwait) && (!W_CHANGE(pstate))
)
{
pstate->attackframe = 0;
NewState(ob,&s_doguse);
pstate->attackcount = DOGSCRATCH.attackinfo[0].mtics;
pstate->weaponframe = DOGSCRATCH.attackinfo[0].frame;
ob->momentumz = -0x40000;
return;
}
else
#endif
if ((ob->flags & FL_DESIGNATED) && (BATTLEMODE) && (gamestate.battlemode == battle_Tag))
{
NewState(ob,&s_tag);
//return;
}
//
// find which cardinal direction the player is facing
//
if (ob->angle < FINEANGLES/8 || ob->angle > 7*FINEANGLES/8)
{
checkx = ob->tilex + 1;
checky = ob->tiley;
ob->dir = east;
wallx = (checkx << TILESHIFT);
wally = (checky << TILESHIFT) + TILEGLOBAL/2;
}
else if (ob->angle < 3*FINEANGLES/8)
{
checkx = ob->tilex;
checky = ob->tiley-1;
ob->dir = north;
wally = (checky << TILESHIFT) + TILEGLOBAL;
wallx = (checkx << TILESHIFT) + TILEGLOBAL/2;
}
else if (ob->angle < 5*FINEANGLES/8)
{
checkx = ob->tilex - 1;
checky = ob->tiley;
ob->dir = west;
wallx = (checkx << TILESHIFT) + TILEGLOBAL;
wally = (checky << TILESHIFT) + TILEGLOBAL/2;
}
else
{
checkx = ob->tilex;
checky = ob->tiley + 1;
ob->dir = south;
wally = (checky << TILESHIFT);
wallx = (checkx << TILESHIFT) + TILEGLOBAL/2;
}
if (actorat[checkx][checky])
{
tempdoor=(doorobj_t*)actorat[checkx][checky];
tempactor = (objtype*)actorat[checkx][checky];
tempwall = (wall_t*)actorat[checkx][checky];
}
doorn = tilemap[checkx][checky] & ~0x2000;
// if (sprites[checkx][checky])
// tempsprite = sprites[checkx][checky];
if (doorn == (elevatorstart + 6))
return;
//bna ++ jumpmode
//SetTextMode ( );
if (!BATTLEMODE){//dont use jump in battle, spoils sync
if (usejump == true){
if (pstate->buttonheld[bt_use]){
if ((AreJumping == false)&&(ob->z > 0)&&(doorn==0)){
oldzval = ob->z;
ob->z -= 15;
ob->momentumz += GRAVITY;
AreJumping = true;
donttilt=10;
return;
}
AreJumping = false;
return;
}
}
}
//bna
if (pstate->buttonheld[bt_use])
return;
if (doorn == (elevatorstart + 1))
{
tilemap[checkx][checky]++; // flip switch
if (MAPSPOT(ob->tilex,ob->tiley,1) == ALTELEVATORTILE);
// playstate = ex_secretlevel;
else if (ob==player)
playstate = ex_completed;
}
else if (doorn == (elevatorstart + 5))
{
elevnum = MAPSPOT(ob->tilex,ob->tiley,1) - 90;
tempwall->flags |= FL_S_FLIPPED;
OperateElevatorSwitch(ob,elevnum,checkx,checky);
}
else if (tempdoor && tempdoor->which==PWALL)
{
temppwall=(pwallobj_t *)tempdoor;
OperatePushWall (temppwall->num,ob->dir, ob == player );
}
else if ((doorn&0x8000) && (!(doorn&0x4000)))
{
doorobj_t* dptr = doorobjlist[doorn&0x3ff];
int dnum = doorn&0x3ff;
int lock;
OperateDoor (pstate->keys, dnum, (ob == player));
if (dptr->eindex != -1)
{
elevator_t*eptr;
lock = dptr->lock;
if ( lock && !( pstate->keys & ( 1 << ( lock - 1 ) ) ) )
{
if (ob==player)
{
// locked
switch (lock)
{
case 1:
AddMessage("You need the \\EGOLD key",MSG_DOOR);
break;
case 2:
AddMessage("You need the \\FSILVER key",MSG_DOOR);
break;
case 3:
AddMessage("You need the \\8IRON key",MSG_DOOR);
break;
case 4:
AddMessage("You need the \\AOSCURO key",MSG_DOOR);
break;
default:
AddMessage("This door appears to be locked",MSG_DOOR);
break;
}
SD_Play( SD_NOITEMSND );
}
return;
}
eptr = &ELEVATOR[dptr->eindex];
if (((dnum == eptr->door1) && (eptr->state == ev_rad)) ||
((dnum == eptr->door2) && (eptr->state == ev_ras))
)
if (ob == player)
AddMessage("Elevator is on the way.",MSG_GAME);
OperateElevatorDoor(dnum);
}
}
else if ((tempactor) && (tempactor->which == ACTOR) &&
(tempactor->obclass == pillarobj) &&
DISTOK(ob->x,tempactor->x,TD) &&
DISTOK(ob->y,tempactor->y,TD) &&
(!(tempactor->flags & FL_DONE)) &&
(!MAPSPOT(tempactor->tilex,tempactor->tiley,2))
)
{if ((tempactor->dir == nodir) ||
(tempactor->dir == ob->dir))
{if (tempactor->dir == nodir)
{
tempactor->dir = ob->dir;
ParseMomentum(tempactor,dirangle8[tempactor->dir]);
}
SD_PlaySoundRTP ( SD_PUSHWALLSND, tempactor->x, tempactor->y );
tempactor->flags |= FL_ACTIVE;
tempactor->flags |= FL_FLIPPED;
// MakeActive(tempactor);
tempactor->whatever = ob;
gamestate.secretcount++;
}
}
else if ((tempwall) && (tempwall->which == WALL) &&
(tempwall->flags & FL_SWITCH) )
{
tempwall->flags |= FL_S_FLIPPED;
if ((tempwall->flags & FL_W_INVERTED) &&
DISTOK(ob->x,wallx,TD) &&
DISTOK(ob->y,wally,TD) &&
DISTOK(ob->z,0,32)
)
{
index = touchindices[checkx][checky]-1;
if (!(tempwall->flags & FL_ON))
{
maskobjlist[tilemap[checkx][checky]&0x3ff]->toptexture++;
tempwall->flags |= FL_ON;
TRIGGER[index] = 1;
SD_PlaySoundRTP(SD_TOUCHPLATESND,ob->x,ob->y);
if (ob==player)
AddMessage("Switch turned on.",MSG_GAME);
}
else if (tempwall->flags & FL_REVERSIBLE)
{
maskobjlist[tilemap[checkx][checky]&0x3ff]->toptexture--;
tempwall->flags &= ~FL_ON;
TRIGGER[index] = 1;
SD_PlaySoundRTP(SD_TOUCHPLATESND,ob->x,ob->y);
if (ob==player)
AddMessage("Switch turned off.",MSG_GAME);
}
}
else if (DISTOK(ob->x,wallx,TD) &&
DISTOK(ob->y,wally,TD) &&
!(tempwall->flags & FL_W_INVERTED)
)
{
index = touchindices[checkx][checky]-1;
if (!(tempwall->flags & FL_ON))
{
tilemap[checkx][checky]++;
tempwall->flags |= FL_ON;
TRIGGER[index] = 1;
SD_PlaySoundRTP(SD_TOUCHPLATESND,ob->x,ob->y);
if (ob==player)
AddMessage("Switch turned on.",MSG_GAME);
}
else if (tempwall->flags & FL_REVERSIBLE)
{
tilemap[checkx][checky]--;
tempwall->flags &= ~FL_ON;
TRIGGER[index] = 1;
SD_PlaySoundRTP(SD_TOUCHPLATESND,ob->x,ob->y);
if (ob==player)
AddMessage("Switch turned off.",MSG_GAME);
}
}
}
else if ((tempwall) && (tempwall->which == WALL) && (ob==player)){
PlayNoWaySound();
//bna ++ jumpmode
//SetTextMode ( );
if (!BATTLEMODE){//dint use jump in battle, spoils sync
if (usejump == true){
if (pstate->buttonheld[bt_use]){
if ((AreJumping == false)&&(ob->z > 0)&&(doorn==0)){
oldzval = ob->z;
ob->z -= 15;
ob->momentumz += GRAVITY;
AreJumping = true;
donttilt=10;
return;
}
AreJumping = false;
return;
}
}
}
//bna
}
// else
// SD_PlaySoundRTP (SD_NOWAYSND,ob->x,ob->y);
// pstate->buttonheld[bt_use] = true;
}
/*
=============================================================================
USER CONTROL
=============================================================================
*/
//******************************************************************************
//
// PollKeyboardButtons
//
//******************************************************************************
void PollKeyboardButtons (void)
{
int i;
QueueLetterInput ();
IN_UpdateKeyboard();
for (i = 0; i < NUMBUTTONS; i++)
{
if (Keystate[buttonscan[i]])
{
buttonpoll[i] = true;
}
}
}
//******************************************************************************
//
// PollMouseButtons
//
//******************************************************************************
extern boolean usemouselook;
void PollMouseButtons (void)
{
int i;
int buttons;
int mask;
int press;
buttons = IN_GetMouseButtons();
mask = 1;
for( i = 0; i < 3; i++, mask <<= 1 )
{
press = buttons & mask;
if ( press )
{//SetTextMode ( );
// if ( ( buttonmouse[ i ] != bt_nobutton ) &&
// ( DoubleClickCount[ i ] != 2 ) )
if ( buttonmouse[ i ] != bt_nobutton )
{
buttonpoll[ buttonmouse[ i ] ] = true;
//bna added
if ((i == 1)&&(usemouselook == true)){
//if rightclick set horizon to 512 (normall)
playertype * pstate;
pstate=&PLAYERSTATE[consoleplayer];
pstate->horizon = 512;
// SetNormalHorizon(PLAYER[0]);
}
//bna added
}
}
// Check double-click
if ( buttonmouse[ i + 3 ] != bt_nobutton )
{
if ( press )
{
// Was the button pressed last tic?
if ( !DoubleClickPressed[ i ] )
{
// Yes, take note of it
DoubleClickPressed[ i ] = true;
// Is this the first click, or a really late click?
if ( ( DoubleClickCount[ i ] == 0 ) ||
( GetTicCount() >= DoubleClickTimer[ i ] ) )
{
// Yes, now wait for a second click
DoubleClickTimer[ i ] = GetTicCount() + DoubleClickSpeed;
//( tics << 5 );
DoubleClickCount[ i ] = 1;
}
else
{
// Second click
buttonpoll[ buttonmouse[ i + 3 ] ] = true;
DoubleClickTimer[ i ] = 0;
DoubleClickCount[ i ] = 2;
}
}
else
{
// After second click, button remains pressed
// until user releases it
if ( DoubleClickCount[ i ] == 2 )
{
buttonpoll[ buttonmouse[ i + 3 ] ] = true;
}
}
}
else
{
if ( DoubleClickCount[ i ] == 2 )
{
DoubleClickCount[ i ] = 0;
}
DoubleClickPressed[ i ] = false;
}
}
}
}
//******************************************************************************
//
// PollJoystickButtons
//
//******************************************************************************
void PollJoystickButtons
(
void
)
{
int i;
int buttons;
int mask;
int num;
int press;
buttons = IN_JoyButtons ();
if ( joypadenabled )
{
num = 4;
mask = 1;
}
else
{
num = 2;
if ( joystickport )
{
mask = 4;
}
else
{
mask = 1;
}
}
for( i = 0; i < num; i++, mask <<= 1 )
{
press = buttons & mask;
if ( press )
{
// if ( ( buttonjoy[ i ] != bt_nobutton ) &&
// ( JoyDblClickCount[ i ] != 2 ) )
if ( buttonjoy[ i ] != bt_nobutton )
{
buttonpoll[ buttonjoy[ i ] ] = true;
}
}
// Check double-click
if ( buttonjoy[ i + 4 ] != bt_nobutton )
{
if ( press )
{
// Was the button pressed last tic?
if ( !JoyDblClickPressed[ i ] )
{
// Yes, take note of it
JoyDblClickPressed[ i ] = true;
// Is this the first click, or a really late click?
if ( ( JoyDblClickCount[ i ] == 0 ) ||
( GetTicCount() >= JoyDblClickTimer[ i ] ) )
{
// Yes, now wait for a second click
JoyDblClickTimer[ i ] = GetTicCount() + DoubleClickSpeed;
//( tics << 5 );
JoyDblClickCount[ i ] = 1;
}
else
{
// Second click
buttonpoll[ buttonjoy[ i + 4 ] ] = true;
JoyDblClickTimer[ i ] = 0;
JoyDblClickCount[ i ] = 2;
}
}
else
{
// After second click, button remains pressed
// until user releases it
if ( JoyDblClickCount[ i ] == 2 )
{
buttonpoll[ buttonjoy[ i + 4 ] ] = true;
}
}
}
else
{
if ( JoyDblClickCount[ i ] == 2 )
{
JoyDblClickCount[ i ] = 0;
}
JoyDblClickPressed[ i ] = false;
}
}
}
}
//===========================================================================
//******************************************************************************
//
// PollKeyboardMove
//
//******************************************************************************
void PollKeyboardMove
(
void
)
{
if ( ( buttonpoll[ bt_turnaround ] ) && ( turnaround == 0 ) )
{
turnaround = 1;
turnaroundtime = 15 + tics;
turnheldtime = 0;
}
if ( turnaround == 0 )
{
if ( buttonpoll[ di_east ] )
{
turnheldtime+=tics;
if (turnheldtime>=TURBOTURNTIME)
{
KX = -KEYBOARDNORMALTURNAMOUNT;
}
else
{
KX = -KEYBOARDPREAMBLETURNAMOUNT;
}
}
else if ( buttonpoll[ di_west ] )
{
turnheldtime+=tics;
if (turnheldtime>=TURBOTURNTIME)
{
KX = KEYBOARDNORMALTURNAMOUNT;
}
else
{
KX = KEYBOARDPREAMBLETURNAMOUNT;
}
}
else
{
KX = 0;
turnheldtime=0;
}
if ( (buttonpoll[bt_run]) &&
( (turnheldtime>=TURBOTURNTIME) || (turnheldtime==0) )
)
KX = FixedMul(KX,TURBOTURNAMOUNT);
}
else
{
KX=TURNAROUNDSPEED;
turnaroundtime-=tics;
if (turnaroundtime<=0)
{
turnaround=0;
KX=((turnaroundtime*TURNAROUNDSPEED)>>1);
}
}
if ( buttonpoll[ di_north ] )
{
KY = -BASEMOVE;
}
else if ( buttonpoll[ di_south ] )
{
KY = BASEMOVE;
}
else
KY = 0;
if (buttonpoll[bt_run])
{
KY <<= 1;
}
}
//******************************************************************************
//
// PollMouseMove
//
//******************************************************************************
//#define MOUSE_RY_SHIFT 12
//#define MOUSE_TZ_SHIFT 3
#define MOUSE_TZ_SENSITIVITY_SCALE 65535
#define MOUSE_RY_SENSITIVITY_SCALE 18725*2
//#define MOUSE_RY_INPUT_SCALE 6000
#define MOUSE_TZ_INPUT_SCALE 20
int mouse_ry_input_scale = 5000;
int sensitivity_scalar[15] =
{
0,1,2,3,4,5,6,8,11,13,15,18,12,13,14
};
//#define MOUSE_RY_SCALE 65535
//#define MOUSE_TZ_SCALE 65535
#define MAXMOUSETURN 7000000
/* use SDL mouse */
#define USESDLMOUSE 1
extern int inverse_mouse;
double Y_MouseSpeed=70;
void PollMouseMove (void)
{
int mousexmove, mouseymove;
double Ys;
//SetTextMode();
Ys=(Y_MouseSpeed/100);
//
// const long inverse_mouse = 1; //set to -1 to invert mouse
// inverse_mouse def moved to RT_CFG.C
#ifdef USESDLMOUSE
INL_GetMouseDelta(&mousexmove, &mouseymove);
#else
PollMouse();//Uses DirectInput mouse in DInput.cpp
mousexmove=MX;
mouseymove=MY;
#endif
if (abs(mousexmove)>abs(mouseymove))
mouseymove/=2;
else
mousexmove/=2;
MX = 0;
MY = 0;
if ((abs (mouseymove)) >= threshold)
{//
MY = MOUSE_TZ_INPUT_SCALE*mouseymove;
MY *= inverse_mouse;
if (usemouselook == true){
if (MY > 0){
playertype * pstate;
pstate=&PLAYERSTATE[consoleplayer];
//if (pstate->horizon > 512){
pstate->horizon -= Ys * (2*sensitivity_scalar[mouseadjustment]);
//}
}
else if (MY < 0){
playertype * pstate;
pstate=&PLAYERSTATE[consoleplayer];
//SetTextMode ( );
pstate->horizon += Ys * (2*sensitivity_scalar[mouseadjustment]);
//buttonpoll[ bt_horizonup ] = true;
}
MY = 0;
}else{
// MY += FixedMul(MY,mouseadjustment*MOUSE_TZ_SENSITIVITY_SCALE);
if (abs(mouseymove)>200)
{
buttonpoll[bt_run]=true;
// buttonpoll[ bt_lookup ] = true;
}
}
}
if ((abs (mousexmove)) >= threshold)
{
//MX = -MOUSE_RY_INPUT_SCALE*mousexmove;
MX = -mouse_ry_input_scale*mousexmove;
MX += FixedMul(MX,sensitivity_scalar[mouseadjustment]*MOUSE_RY_SENSITIVITY_SCALE);
// if (abs(MX) > MAXMOUSETURN)
// MX = MAXMOUSETURN*SGN(MX);
if (usemouselook == true){
if (abs(mouseymove)>10)
{
buttonpoll[bt_run]=true;
//buttonpoll[ bt_lookdown ] = true;
}
}
}
// if (MY > 0)
// MX -= (MX/2);
// MX=0;
// MY=0;
}
//******************************************************************************
//
// PollJoystickMove
//
//******************************************************************************
void PollJoystickMove (void)
{
int joyx,joyy;
INL_GetJoyDelta (joystickport, &joyx, &joyy);
if ( joypadenabled )
{
if (joyx >= threshold)
{
buttonpoll[ di_east ] = true;
}
if (-joyx >= threshold)
{
buttonpoll[ di_west ] = true;
}
if ( joyy >= threshold )
{
buttonpoll[ di_south ] = true;
}
if ( -joyy >= threshold )
{
buttonpoll[ di_north ] = true;
}
}
else
{
if ((abs (joyx)) >= threshold)
{
JX = ((-joyx)<<13)+((-joyx)<<11);
turnheldtime += tics;
}
else
JX = 0;
if ((abs (joyy)) >= threshold)
{
JY = joyy<<4;
}
else
JY = 0;
if (buttonpoll[bt_run])
{
JX <<= 1;
JY <<= 1;
}
}
}
//******************************************************************************
//
// StartVRFeedback
//
//******************************************************************************
void StartVRFeedback (int guntype)
{
#ifdef DOS
union REGS inregs;
union REGS outregs;
inregs.x.eax = VR_FEEDBACK_SERVICE;
inregs.x.ebx = 1;
inregs.x.ecx = guntype;
int386 (0x33, &inregs, &outregs);
#else
STUB_FUNCTION;
#endif
}
//******************************************************************************
//
// StopVRFeedback
//
//******************************************************************************
void StopVRFeedback (void)
{
#ifdef DOS
union REGS inregs;
union REGS outregs;
inregs.x.eax = VR_FEEDBACK_SERVICE;
inregs.x.ebx = 0;
int386 (0x33, &inregs, &outregs);
#else
STUB_FUNCTION;
#endif
}
//******************************************************************************
//
// PollVirtualReality
//
//******************************************************************************
#define VR_BUTTON(x) ((vr_buttons>>x) & 1)
void PollVirtualReality (void)
{
#ifdef DOS
union REGS inregs;
union REGS outregs;
short int mousexmove,
mouseymove;
word vr_buttons;
inregs.x.eax = VR_INPUT_SERVICE;
inregs.x.ebx = player->angle;
inregs.x.ecx = player->yzangle;
int386 (0x33, &inregs, &outregs);
vr_buttons = outregs.w.bx;
buttonpoll[bt_run ] |= VR_BUTTON(VR_RUNBUTTON );
buttonpoll[bt_strafeleft ] |= VR_BUTTON(VR_STRAFELEFTBUTTON );
buttonpoll[bt_straferight ] |= VR_BUTTON(VR_STRAFERIGHTBUTTON );
buttonpoll[bt_attack ] |= VR_BUTTON(VR_ATTACKBUTTON );
buttonpoll[bt_lookup ] |= VR_BUTTON(VR_LOOKUPBUTTON );
buttonpoll[bt_lookdown ] |= VR_BUTTON(VR_LOOKDOWNBUTTON );
buttonpoll[bt_swapweapon ] |= VR_BUTTON(VR_SWAPWEAPONBUTTON );
buttonpoll[bt_use ] |= VR_BUTTON(VR_USEBUTTON );
buttonpoll[bt_horizonup ] |= VR_BUTTON(VR_HORIZONUPBUTTON );
buttonpoll[bt_horizondown ] |= VR_BUTTON(VR_HORIZONDOWNBUTTON );
buttonpoll[bt_map ] |= VR_BUTTON(VR_MAPBUTTON );
buttonpoll[bt_pistol ] |= VR_BUTTON(VR_PISTOLBUTTON );
buttonpoll[bt_dualpistol ] |= VR_BUTTON(VR_DUALPISTOLBUTTON );
buttonpoll[bt_mp40 ] |= VR_BUTTON(VR_MP40BUTTON );
buttonpoll[bt_missileweapon] |= VR_BUTTON(VR_MISSILEWEAPONBUTTON);
buttonpoll[bt_recordsound ] |= VR_BUTTON(VR_RECORDBUTTON );
mousexmove = outregs.w.cx;
mouseymove = outregs.w.dx;
VX = 0;
VY = 0;
if ((abs (mouseymove)) >= threshold)
{
VY = MOUSE_TZ_INPUT_SCALE*mouseymove;
if (abs(mouseymove)>200)
{
buttonpoll[bt_run]=true;
}
}
if ((abs (mousexmove)) >= threshold)
{
VX = -mouse_ry_input_scale*mousexmove;
VX += FixedMul(MX,sensitivity_scalar[mouseadjustment]*MOUSE_RY_SENSITIVITY_SCALE);
if (abs(mousexmove)>10)
{
buttonpoll[bt_run]=true;
}
}
#else
STUB_FUNCTION;
#endif
}
//******************************************************************************
//
// PollMove ()
//
//******************************************************************************
boolean aimbuttonpressed=false;
void PollMove (void)
{
int angle;
int x, y;
x = KX + MX + JX + CX + VX;
y = KY + MY + JY + CY + VY;
if (buttonpoll[bt_aimbutton])
{
if (y>0)
{
buttonpoll[bt_horizonup]=1;
y=0;
aimbuttonpressed=true;
}
else if (y<0)
{
buttonpoll[bt_horizondown]=1;
y=0;
aimbuttonpressed=true;
}
else if (aimbuttonpressed==false)
{
buttonpoll[bt_lookup]=1;
buttonpoll[bt_lookdown]=1;
}
}
else
{
aimbuttonpressed=false;
}
if (player->flags & FL_FLEET)
y += y>>1;
if ((locplayerstate->NETCAPTURED == 1) && (!locplayerstate->HASKNIFE))
{
if (first)
{
nettics = GetTicCount() + (VBLCOUNTER * 4);
first = 0;
}
if (x > 0)
{
rightmom += NETMOM;
if (lastmom!=0)
controlbuf[2]=x<<1;
lastmom=0;
}
else
if (x < 0)
{
leftmom += NETMOM;
if (lastmom!=1)
controlbuf[2]=x<<1;
lastmom=1;
}
else
{
rightmom -= (NETMOM >> 2);
if (rightmom < 0)
rightmom = 0;
leftmom -= (NETMOM >> 2);
if (leftmom < 0)
leftmom = 0;
}
if ((GetTicCount() > nettics) && (rightmom > (NETMOM * 2)) &&
(leftmom > (NETMOM * 2)))
{
rightmom = 0;
leftmom = 0;
first = 1;
lastmom^=1;
locplayerstate->NETCAPTURED = 0;
MISCVARS->NET_IN_FLIGHT = false;
NewState(player, &s_player);
locplayerstate->weaponuptics = WEAPONS[locplayerstate->weapon].screenheight/GMOVE;
locplayerstate->weaponheight = locplayerstate->weaponuptics*GMOVE ;
}
}
else if ((buttonpoll[bt_strafe]) && (turnaround==0))
{
// strafing
if (x < 0)
{
angle = (player->angle - FINEANGLES/4)&(FINEANGLES-1);
x = (x>>10) + (x >> 11);
controlbuf[0] = -(FixedMul (x, costable[angle]));
controlbuf[1] = FixedMul (x, sintable[angle]);
}
else if (x > 0)
{
angle = (player->angle + FINEANGLES/4)&(FINEANGLES-1);
x = (x>>10) + (x >> 11);
controlbuf[0] = FixedMul (x, costable[angle]);
controlbuf[1] = -(FixedMul (x, sintable[angle]));
}
if (y != 0)
{
controlbuf[0] += -(FixedMul (y, viewcos));
controlbuf[1] += (FixedMul (y, viewsin));
}
}
else
{
if (y != 0)
{
controlbuf[0] = -FixedMul (y, viewcos);
controlbuf[1] = FixedMul (y, viewsin);
}
if (x != 0)
controlbuf[2] = x;
}
if (buttonpoll[bt_strafeleft])
{
angle = (player->angle - FINEANGLES/4)&(FINEANGLES-1);
controlbuf[0] += -(FixedMul (STRAFEAMOUNT, costable[angle]));
controlbuf[1] += FixedMul (STRAFEAMOUNT, sintable[angle]);
}
else if (buttonpoll[bt_straferight])
{
angle = (player->angle + FINEANGLES/4)&(FINEANGLES-1);
controlbuf[0] += -(FixedMul (STRAFEAMOUNT, costable[angle]));
controlbuf[1] += FixedMul (STRAFEAMOUNT, sintable[angle]);
}
}
//******************************************************************************
//
// PollCyberman ()
//
//******************************************************************************
void PollCyberman (void)
{
int i;
int mask;
int press;
SWIFT_Get3DStatus (&SWIFTStatus);
mask = 4;
for( i = 0; i < 3; i++, mask >>= 1 )
{
press = SWIFTStatus.buttons & mask;
if ( press )
{
// if ( ( buttonmouse[ i ] != bt_nobutton ) &&
// ( DoubleClickCount[ i ] != 2 ) )
if ( buttonmouse[ i ] != bt_nobutton )
{
buttonpoll[ buttonmouse[ i ] ] = true;
}
}
// Check double-click
if ( buttonmouse[ i + 3 ] != bt_nobutton )
{
if ( press )
{
// Was the button pressed last tic?
if ( !DoubleClickPressed[ i ] )
{
// Yes, take note of it
DoubleClickPressed[ i ] = true;
// Is this the first click, or a really late click?
if ( ( DoubleClickCount[ i ] == 0 ) ||
( GetTicCount() >= DoubleClickTimer[ i ] ) )
{
// Yes, now wait for a second click
DoubleClickTimer[ i ] = GetTicCount() + DoubleClickSpeed;
//( tics << 5 );
DoubleClickCount[ i ] = 1;
}
else
{
// Second click
buttonpoll[ buttonmouse[ i + 3 ] ] = true;
DoubleClickTimer[ i ] = 0;
DoubleClickCount[ i ] = 2;
}
}
else
{
// After second click, button remains pressed
// until user releases it
if ( DoubleClickCount[ i ] == 2 )
{
buttonpoll[ buttonmouse[ i + 3 ] ] = true;
}
}
}
else
{
if ( DoubleClickCount[ i ] == 2 )
{
DoubleClickCount[ i ] = 0;
}
DoubleClickPressed[ i ] = false;
}
}
}
if (SWIFTStatus.pitch > 0)
CYBERLOOKUP = true;
else if (SWIFTStatus.pitch < 0)
CYBERLOOKDOWN = true;
if ((abs (SWIFTStatus.x)) > CYBERDEADRANGE)
{
CX = -(SGN (SWIFTStatus.x) * (( (abs(SWIFTStatus.x)-CYBERDEADRANGE) ) << 10));
turnheldtime += tics;
}
else
if (SWIFTStatus.x != oldcyberx)
{
turnheldtime += tics;
if (SWIFTStatus.x > oldcyberx)
CX = -(0xB8000);
else
CX = 0xB8000;
oldcyberx = SWIFTStatus.x;
}
else
CX = 0;
if ((abs (SWIFTStatus.y)) > CYBERDEADRANGE)
{
CY = SWIFTStatus.y >> 2;
}
else
CY = 0;
}
//******************************************************************************
//
// PollAssassin ()
//
//******************************************************************************
#define MAXRAMPS 5
typedef struct
{
int min;
int factor;
} RampType;
void PollAssassin (void)
{
int i;
int mask;
int press;
int yaw;
int strafeAngle;
int acc;
int numramps=4;
RampType ramp[MAXRAMPS]={
{0,280000},
{4,380000},
{10,480000},
{25,680000},
// {25,( (1<<26)/80 )}
};
SWIFT_Get3DStatus (&SWIFTStatus);
mask = 4;
for( i = 0; i < 3; i++, mask >>= 1 )
{
press = SWIFTStatus.buttons & mask;
if ( press )
{
// if ( ( buttonmouse[ i ] != bt_nobutton ) &&
// ( DoubleClickCount[ i ] != 2 ) )
if ( buttonmouse[ i ] != bt_nobutton )
{
buttonpoll[ buttonmouse[ i ] ] = true;
}
}
// Check double-click
if ( buttonmouse[ i + 3 ] != bt_nobutton )
{
if ( press )
{
// Was the button pressed last tic?
if ( !DoubleClickPressed[ i ] )
{
// Yes, take note of it
DoubleClickPressed[ i ] = true;
// Is this the first click, or a really late click?
if ( ( DoubleClickCount[ i ] == 0 ) ||
( GetTicCount() >= DoubleClickTimer[ i ] ) )
{
// Yes, now wait for a second click
DoubleClickTimer[ i ] = GetTicCount() + DoubleClickSpeed;
//( tics << 5 );
DoubleClickCount[ i ] = 1;
}
else
{
// Second click
buttonpoll[ buttonmouse[ i + 3 ] ] = true;
DoubleClickTimer[ i ] = 0;
DoubleClickCount[ i ] = 2;
}
}
else
{
// After second click, button remains pressed
// until user releases it
if ( DoubleClickCount[ i ] == 2 )
{
buttonpoll[ buttonmouse[ i + 3 ] ] = true;
}
}
}
else
{
if ( DoubleClickCount[ i ] == 2 )
{
DoubleClickCount[ i ] = 0;
}
DoubleClickPressed[ i ] = false;
}
}
}
buttonpoll[bt_horizonup] |= ((SWIFTStatus.buttons>>7) & 1);
buttonpoll[bt_horizondown] |= ((SWIFTStatus.buttons>>8) & 1);
if ( abs(SWIFTStatus.pitch) < (20<<6) )
{
SWIFTStatus.pitch = 0;
}
else
{
SWIFTStatus.pitch -= SGN(SWIFTStatus.pitch)*(20<<6);
}
if ( abs(SWIFTStatus.pitch) > (60<<6) )
{
buttonpoll[bt_run] = 1;
}
if ( abs(SWIFTStatus.roll) > (80<<6) )
{
buttonpoll[bt_run] = 1;
}
if ( abs(SWIFTStatus.roll) < (20<<6) )
{
SWIFTStatus.roll = 0;
}
else
{
SWIFTStatus.roll -= SGN(SWIFTStatus.roll)*(20<<6);
}
strafeAngle = (player->angle - FINEANGLES/4)&(FINEANGLES-1);
controlbuf[0] += -(FixedMulShift (SWIFTStatus.pitch, viewcos,16))+
FixedMulShift (-SWIFTStatus.roll, costable[strafeAngle], 16);
controlbuf[1] += FixedMulShift (SWIFTStatus.pitch, viewsin,16) -
FixedMulShift (-SWIFTStatus.roll, sintable[strafeAngle], 16);
yaw = abs(SWIFTStatus.yaw);
acc = 0;
for (i=0;i<numramps;i++)
{
if (yaw > ramp[i].min)
{
if (i>0)
{
acc += ramp[i].min*(ramp[i].factor-ramp[i-1].factor);
}
}
else
{
i++;
break;
}
}
controlbuf[2]= SWIFTStatus.yaw * ramp[i-1].factor - acc;
}
//******************************************************************************
//
// PollControls
//
// Gets user or demo input, call once each frame
//
// controlx set between -100 and 100 per tic
// controly
//
//******************************************************************************
void PollControls (void)
{
int i;
if (standalone==true)
return;
lastpolltime=controlupdatetime;
memset (buttonpoll, 0, sizeof(buttonpoll));
controlbuf[0] = controlbuf[1] = controlbuf[2] = 0;
CYBERLOOKUP = CYBERLOOKDOWN = false;
if (gamestate.autorun==1)
buttonpoll[bt_run] = true;
//
// get button states
//
PollKeyboardButtons ();
if (mouseenabled && !cybermanenabled)
PollMouseButtons ();
if (joystickenabled)
PollJoystickButtons ();
//
// get movements
//
if (joystickenabled)
PollJoystickMove ();
if (cybermanenabled)
PollCyberman ();
else if (mouseenabled && MousePresent)
PollMouseMove ();
PollKeyboardMove ();
if (vrenabled)
PollVirtualReality ();
PollMove ();
if (spaceballenabled)
PollSpaceBall ();
else if (assassinenabled)
PollAssassin ();
buttonbits = 0;
if (player->flags & FL_DYING) // Player has died
{
if ((playerdead==true) &&
( buttonpoll[ bt_strafe ] ||
buttonpoll[ bt_attack ] ||
buttonpoll[ bt_use ] ||
((gamestate.battlemode == battle_Hunter) &&
(BATTLE_Team[player->dirchoosetime] == BATTLE_It)
)
)
)
{
AddRespawnCommand();
}
memset (buttonpoll, 0, sizeof(buttonpoll));
controlbuf[0] = controlbuf[1] = controlbuf[2] = 0;
}
if ((PausePressed==true) && (modemgame==false))
{
PausePressed=false;
if (GamePaused==true)
AddPauseStateCommand(COM_UNPAUSE);
else
{
AddPauseStateCommand(COM_PAUSE);
}
}
if (Keyboard[sc_Insert] && Keyboard[sc_X]){
AddExitCommand();
}
//bna section
if (Keyboard[sc_5]){
// SetTextMode ( );
weaponscale += 1000;
//testval++;
}
if (Keyboard[sc_6]){
// SetTextMode ( );
weaponscale -= 1000;
// testval--;
}
//bna section end
for (i = (NUMTXBUTTONS-1); i >= 0; i--)
{
buttonbits <<= 1;
if (buttonpoll[i])
buttonbits |= 1;
}
UpdateClientControls();
}
void ResetWeapons(objtype *ob)
{playertype *pstate;
M_LINKSTATE(ob,pstate);
pstate->weapondowntics = WEAPONS[pstate->weapon].screenheight/GMOVE;
pstate->new_weapon = pstate->oldweapon;
pstate->missileweapon = pstate->oldmissileweapon;
ob->shapeoffset = pstate->oldshapeoffset;
pstate->attackframe = pstate->weaponframe = 0;
if ((ob==player) && SHOW_BOTTOM_STATUS_BAR() )
DrawBarAmmo (false);
}
void SaveWeapons(objtype*ob)
{playertype *pstate;
if ((ob->flags&FL_DOGMODE) || (ob->flags&FL_GODMODE))
return;
//pstate = (ob==player)?(&playerstate):(&remoteplayerstate);
M_LINKSTATE(ob,pstate);
pstate->weapondowntics = WEAPONS[pstate->weapon].screenheight/GMOVE;
pstate->oldweapon = pstate->new_weapon;
pstate->oldmissileweapon = pstate->missileweapon;
pstate->oldshapeoffset = ob->shapeoffset;
}
/*
void SaveWeapons(objtype*ob)
{playertype *pstate;
if ((ob->flags&FL_DOGMODE) || (ob->flags&FL_GODMODE))
return;
//pstate = (ob==player)?(&playerstate):(&remoteplayerstate);
M_LINKSTATE(ob,pstate);
pstate->weapondowntics = WEAPONS[pstate->weapon].screenheight/GMOVE;
pstate->oldweapon = pstate->weapon;
pstate->oldmissileweapon = pstate->missileweapon;
pstate->oldshapeoffset = ob->shapeoffset;
}
*/
#define GiveProtection(flag,time,sound) \
{ \
if ((ob->flags & flag) || (ob->flags & FL_GODMODE) || \
(ob->flags & FL_DOGMODE)) \
return; \
ob->flags &= ~(FL_BPV|FL_GASMASK|FL_AV); \
ob->flags |= flag; \
SD_PlaySoundRTP(sound,ob->x, ob->y); \
pstate->protectiontime = time; \
gamestate.supercount ++; \
}
boolean GivePowerup(objtype *ob,int flag,int time,int sound)
{
playertype *pstate;
if ((ob->flags & flag) ||
(ob->flags & FL_GODMODE) ||
(ob->flags & FL_DOGMODE)
)
return false;
M_LINKSTATE(ob,pstate);
/*
if (ob->flags & FL_DOGMODE)
{
ob->temp2 = DOGMODERISE;
ResetWeapons(ob);
if (ob->state->condition & SF_DOGSTATE)
NewState(ob,&s_player);
}
else if (ob->flags & FL_GODMODE)
{
ob->temp2 = GODMODEFALL;
ResetWeapons(ob);
}
*/
ob->flags &= ~(FL_SHROOMS|FL_FLEET|FL_ELASTO|FL_GODMODE|FL_DOGMODE);
ob->flags |= flag;
pstate->poweruptime = time;
pstate->soundtime = 0;
SD_PlaySoundRTP(sound,ob->x, ob->y);
gamestate.supercount ++;
return true;
}
void GiveLifePoints(objtype *ob,int points)
{
SD_PlaySoundRTP(SD_GETBONUSSND,ob->x, ob->y);
UpdateTriads (ob,points);
if (ob==player)
DrawTriads (false);
}
boolean GiveBulletWeapon(objtype *ob,int bulletweapon,statobj_t*check)
{
playertype *pstate;
M_LINKSTATE(ob,pstate);
if ((ob->flags & FL_DOGMODE) || (ob->flags & FL_GODMODE))
return false;
if (!ARMED(ob->dirchoosetime))
return false;
if (pstate->HASBULLETWEAPON[bulletweapon])
return false;
GiveWeapon(ob,bulletweapon);
if ( gamestate.BattleOptions.WeaponPersistence )
{
LASTSTAT->z = check->z;
}
SD_PlaySoundRTP(SD_GETWEAPONSND,ob->x, ob->y);
return true;
}
boolean GivePlayerMissileWeapon(objtype *ob, playertype *pstate,
statobj_t *check)
{
if ((ob->flags & FL_DOGMODE) || (ob->flags & FL_GODMODE))
return false;
if (!ARMED(ob->dirchoosetime))
return false;
if ((GetWeaponForItem(check->itemnumber) == pstate->missileweapon) &&
(check->ammo == stats[check->itemnumber].ammo) &&
(pstate->ammo == stats[check->itemnumber].ammo)
)
return false;
SD_PlaySoundRTP(SD_GETWEAPONSND,ob->x, ob->y);
GiveMissileWeapon(ob,GetWeaponForItem(check->itemnumber));
if (gamestate.BattleOptions.WeaponPersistence)
LASTSTAT->z = check->z;
gamestate.missilecount ++;
if (BATTLEMODE && (gamestate.BattleOptions.Ammo != bo_normal_shots))
{if (gamestate.BattleOptions.Ammo == bo_one_shot)
pstate->ammo = 1;
else
pstate->ammo = -1;
}
else
pstate->ammo = check->ammo;
if ((ob==player) && SHOW_BOTTOM_STATUS_BAR() )
DrawBarAmmo (false);
return true;
}
#define LocalBonusMessage(string) \
{ \
if (ob == player) \
AddMessage(string,MSG_BONUS); \
}
#define LocalBonus1Message(string) \
{ \
if (ob == player) \
AddMessage(string,MSG_BONUS1); \
}
/*
=================================
=
= GetBonusTimeForItem
=
=================================
*/
int GetBonusTimeForItem(int itemnumber)
{
specials *which;
if ( BATTLEMODE )
{
which = &gamestate.SpecialsTimes;
}
else
{
which = &CurrentSpecialsTimes;
}
switch(itemnumber)
{
case stat_godmode:
return which->GodModeTime;
case stat_dogmode:
return which->DogModeTime;
case stat_mushroom:
return which->ShroomsModeTime;
case stat_elastic:
return which->ElastoModeTime;
case stat_asbesto:
return which->AsbestosVestTime;
case stat_bulletproof:
return which->BulletProofVestTime;
case stat_gasmask:
return which->GasMaskTime;
case stat_fleetfeet:
return which->MercuryModeTime;
}
return -1;
}
/*
=================================
=
= GetRespawnTimeForItem
=
=================================
*/
int GetRespawnTimeForItem(int itemnumber)
{
switch(itemnumber)
{
case stat_godmode:
return gamestate.SpecialsTimes.GodModeRespawnTime;
case stat_dogmode:
return gamestate.SpecialsTimes.DogModeRespawnTime;
case stat_mushroom:
return gamestate.SpecialsTimes.ShroomsModeRespawnTime;
case stat_elastic:
return gamestate.SpecialsTimes.ElastoModeRespawnTime;
case stat_asbesto:
return gamestate.SpecialsTimes.AsbestosVestRespawnTime;
case stat_bulletproof:
return gamestate.SpecialsTimes.BulletProofVestRespawnTime;
case stat_gasmask:
return gamestate.SpecialsTimes.GasMaskRespawnTime;
case stat_fleetfeet:
return gamestate.SpecialsTimes.MercuryModeRespawnTime;
}
return gamestate.BattleOptions.RespawnTime * VBLCOUNTER;
}
/*
===================
=
= GetBonus
=
===================
*/
void GetBonus (objtype*ob,statobj_t *check)
{
int heal;
playertype * pstate;
boolean randompowerup;
M_LINKSTATE(ob,pstate);
randompowerup=false;
randomlabel:
switch (check->itemnumber)
{
case stat_knifestatue:
SD_PlaySoundRTP(SD_GETKNIFESND,ob->x, ob->y);
if (ob==player)
locplayerstate->HASKNIFE = 1;
SD_PlaySoundRTP(PlayerSnds[locplayerstate->player], ob->x, ob->y);
LocalBonusMessage("You found a knife.");
break;
case stat_pedgoldkey:
LocalBonusMessage("You found the \\EGold key.");
goto keys;
case stat_pedsilverkey:
LocalBonusMessage("You got the \\FSilver key.");
goto keys;
case stat_pedironkey:
LocalBonusMessage("You got the \\8Iron key.");
goto keys;
case stat_pedcrystalkey:
LocalBonusMessage("You got the \\4Oscuro key.");
keys:
GiveKey (check->itemnumber - stat_pedgoldkey);
SD_PlaySoundRTP (SD_GETKEYSND,ob->x, ob->y);
break;
case stat_monkmeal:
if (pstate->health == MaxHitpointsForCharacter(pstate))
return;
SD_PlaySoundRTP (SD_GETHEALTH1SND,ob->x, ob->y);
LocalBonusMessage("You ate some Monk Meal.");
HealPlayer (10,ob);
gamestate.healthcount ++;
break;
case stat_monkcrystal1:
if (pstate->health == MaxHitpointsForCharacter(pstate))
return;
SD_PlaySoundRTP (SD_GETHEALTH2SND,ob->x, ob->y);
LocalBonusMessage("You picked up a small Monk Crystal.");
HealPlayer (10,ob);
gamestate.healthcount ++;
break;
case stat_monkcrystal2:
if (pstate->health == MaxHitpointsForCharacter(pstate))
return;
SD_PlaySoundRTP (SD_GETHEALTH2SND,ob->x, ob->y);
LocalBonusMessage("You picked up a large Monk Crystal.");
HealPlayer (50,ob);
gamestate.healthcount ++;
break;
case stat_priestporridge:
if (pstate->health == MaxHitpointsForCharacter(pstate))
return;
SD_PlaySoundRTP (SD_GETHEALTH1SND,ob->x, ob->y);
if (check->flags & FL_ACTIVE)
{
HealPlayer (50,ob);
LocalBonusMessage("You ate some Priest Porridge Hot.");
}
else
{
HealPlayer (20,ob);
LocalBonusMessage("You ate some Priest Porridge.");
}
gamestate.healthcount ++;
break;
case stat_healingbasin:
if (pstate->health == MaxHitpointsForCharacter(pstate))
return;
SD_PlaySoundRTP (SD_GETHEALTH2SND,ob->x, ob->y);
heal = 25 + (GameRandomNumber("GetBonus",0) >> 2);
HealPlayer (heal,ob);
LocalBonusMessage("You drank from the healing basin.");
gamestate.healthcount ++;
gamestate.democraticcount ++;
break;
case stat_oneup:
if (abs(pstate->health - MaxHitpointsForCharacter(pstate))
< (MaxHitpointsForCharacter(pstate)>>2) )
{
GiveLives(1);
LocalBonusMessage("Extra Life!");
}
else
{
HealPlayer(MaxHitpointsForCharacter(pstate),ob);
LocalBonusMessage("Full Health!");
}
SD_PlaySoundRTP(SD_GET1UPSND,ob->x, ob->y);
break;
case stat_threeup:
if (abs(pstate->health - MaxHitpointsForCharacter(pstate))
< (MaxHitpointsForCharacter(pstate)>>2) )
{
GiveLives(3);
LocalBonusMessage("Three Extra Lives!");
}
else
{
HealPlayer(MaxHitpointsForCharacter(pstate),ob);
GiveLives(2);
LocalBonusMessage("Full Health AND Two Extra Lives!");
}
SD_PlaySoundRTP(SD_GET3UPSND,ob->x, ob->y);
break;
case stat_scotthead:
// Give Apogee's phone number as points
GivePoints( 2764331 );
LocalBonusMessage( "Whoa...Scott's Mystical Head!");
LocalBonus1Message( "You get 2,764,331 points!");
SD_PlaySoundRTP(SD_GETHEADSND,ob->x, ob->y);
break;
case stat_twopistol:
if (GiveBulletWeapon(ob,wp_twopistol,check)==false)
return;
LocalBonusMessage("You got an extra pistol.");
break;
case stat_mp40:
if (GiveBulletWeapon(ob,wp_mp40,check)==false)
return;
LocalBonusMessage("You picked up an MP40.");
break;
case stat_bazooka:
if (GivePlayerMissileWeapon(ob,pstate,check)==false)
return;
LocalBonusMessage("You bagged a bazooka!");
break;
case stat_firebomb:
if (GivePlayerMissileWeapon(ob,pstate,check)==false)
return;
LocalBonusMessage("You found a Firebomb!");
break;
case stat_heatseeker:
if (GivePlayerMissileWeapon(ob,pstate,check)==false)
return;
LocalBonusMessage("You have a Heat-seeker!");
break;
case stat_drunkmissile:
if (GivePlayerMissileWeapon(ob,pstate,check)==false)
return;
LocalBonusMessage("You recovered a Drunk Missile!");
break;
case stat_firewall:
if (GivePlayerMissileWeapon(ob,pstate,check)==false)
return;
LocalBonusMessage("You filched a FlameWall!");
break;
case stat_splitmissile:
if (GivePlayerMissileWeapon(ob,pstate,check)==false)
return;
LocalBonusMessage("You snagged a Split Missile!");
break;
case stat_kes:
if (GivePlayerMissileWeapon(ob,pstate,check)==false)
return;
LocalBonusMessage("You wield the Dark Staff!");
break;
case stat_bat:
if (GivePlayerMissileWeapon(ob,pstate,check)==false)
return;
LocalBonusMessage("You picked up the Excalibat.");
break;
case stat_lifeitem1:
GiveLifePoints(ob,1);
if (timelimitenabled)
timelimit+=(VBLCOUNTER);
break;
case stat_lifeitem2:
GiveLifePoints(ob,5);
if (timelimitenabled)
timelimit+=(2*VBLCOUNTER);
break;
case stat_lifeitem3:
GiveLifePoints(ob,10);
if (timelimitenabled)
timelimit+=(5*VBLCOUNTER);
break;
case stat_lifeitem4:
GiveLifePoints(ob,25);
if (timelimitenabled)
timelimit+=(10*VBLCOUNTER);
break;
case stat_random:
switch (GameRandomNumber("GetBonus",0)>>6)
{
case 0:
check->itemnumber=stat_godmode;
break;
case 1:
check->itemnumber=stat_elastic;
break;
case 2:
check->itemnumber=stat_dogmode;
break;
case 3:
check->itemnumber=stat_mushroom;
break;
}
randompowerup=true;
LocalBonus1Message("Random powerup gives you . . .");
goto randomlabel;
break;
case stat_bulletproof:
GiveProtection(FL_BPV, GetBonusTimeForItem(stat_bulletproof),
SD_GETBVESTSND);
LocalBonusMessage("Bulletproof Armor!");
goto drw;
case stat_gasmask:
GiveProtection(FL_GASMASK, GetBonusTimeForItem(stat_gasmask),
SD_GETMASKSND);
LocalBonusMessage("You put on a Gas Mask.");
goto drw;
case stat_asbesto:
GiveProtection(FL_AV,GetBonusTimeForItem(stat_asbesto),
SD_GETAVESTSND);
LocalBonusMessage("Asbestos Armor! Oh so itchy!");
goto drw;
case stat_elastic:
if (GivePowerup(ob,FL_ELASTO,GetBonusTimeForItem(stat_elastic),
SD_GETELASTSND) == false)
return;
LocalBonusMessage("Elasto Mode!");
ob->flags |= FL_NOFRICTION;
goto drw;
case stat_fleetfeet:
if (GivePowerup(ob,FL_FLEET,GetBonusTimeForItem(stat_fleetfeet),
SD_GETFLEETSND) == false)
return;
LocalBonus1Message("Mercury Mode!");
LocalBonusMessage("Press Look Up and Down to fly.");
ob->flags &= ~FL_NOFRICTION;
goto drw;
case stat_mushroom:
if (GivePowerup(ob,FL_SHROOMS,GetBonusTimeForItem(stat_mushroom),
SD_GETSHROOMSSND) == false)
return;
LocalBonusMessage("Shrooms Mode!");
ob->flags &= ~FL_NOFRICTION;
gamestate.democraticcount ++;
goto drw;
case stat_godmode:
if (ob->flags & FL_GODMODE)
return;
if (!ARMED(ob->dirchoosetime))
return;
ob->flags &= ~FL_NOFRICTION;
if (ob->flags & FL_DOGMODE)
{
ob->temp2 = DOGMODERISE;
ResetWeapons(ob);
if (ob->state->condition & SF_DOGSTATE)
NewState(ob,&s_player);
}
SaveWeapons(ob);
SpawnNewObj(ob->tilex,ob->tiley,&s_flash1,inertobj);
new->flags |= FL_ABP;
new->x = new->drawx = ob->x;
new->y = new->drawy = ob->y;
MakeActive(new);
new->z = ob->z;
SetPlayerHorizon(pstate,GODYZANGLE);
ob->flags &= ~(FL_GODMODE|FL_SHROOMS|FL_ELASTO|FL_FLEET|FL_DOGMODE);
ob->flags |= FL_GODMODE;
ob->temp2 = GODMODERISE;
pstate->poweruptime = GetBonusTimeForItem(stat_godmode);
pstate->soundtime = 0;
GiveMissileWeapon(ob,wp_godhand);
SD_PlaySoundRTP(SD_GETGODSND,ob->x, ob->y);
gamestate.supercount ++;
LocalBonusMessage("God Mode!");
goto drw;
#if (SHAREWARE == 0)
case stat_dogmode:
if (ob->flags & FL_DOGMODE)
return;
if (!ARMED(ob->dirchoosetime))
return;
ob->flags &= ~FL_NOFRICTION;
if (ob->flags & FL_GODMODE)
{
ob->temp2 = GODMODEFALL;
ResetWeapons(ob);
}
SaveWeapons(ob);
ob->shapeoffset = 0;
NewState(ob,&s_serialdog);
SpawnNewObj(ob->tilex,ob->tiley,&s_flash1,inertobj);
new->flags |= FL_ABP;
new->x = new->drawx = ob->x;
new->y = new->drawy = ob->y;
MakeActive(new);
new->z = ob->z;
SetPlayerHorizon(pstate,DOGYZANGLE);
ob->flags &= ~(FL_DOGMODE|FL_SHROOMS|FL_ELASTO|FL_FLEET|FL_GODMODE);
ob->flags |= FL_DOGMODE;
ob->temp2 = DOGMODEFALL;
pstate->poweruptime = GetBonusTimeForItem(stat_dogmode);
pstate->soundtime = 0;
GiveMissileWeapon(ob,wp_dog);
SD_PlaySoundRTP(SD_GETDOGSND,ob->x, ob->y);
gamestate.supercount ++;
LocalBonusMessage("Dog Mode!");
goto drw;
#endif
drw:
if (ob==player)
GM_DrawBonus (check->itemnumber);
break;
case stat_dipball1:
case stat_dipball2:
case stat_dipball3:
SD_PlaySoundRTP(SD_GETBONUSSND,ob->x, ob->y);
gamestate.dipballs++;
LocalBonusMessage("You discovered a Developer Ball!");
break;
case stat_collector:
if (gamestate.battlemode==battle_CaptureTheTriad)
{if (pstate->team == check->hitpoints)
return;
ob->flags |= FL_DESIGNATED;
UpdateKills = true;
LocalBonusMessage( "You picked up a triad! RUN!!!");
}
else
BATTLE_CheckGameStatus(battle_get_collector_item,ob->dirchoosetime);
SD_PlaySoundRTP(SD_GETBONUSSND,ob->x, ob->y);
break;
#if (SHAREWARE == 0)
case stat_mine:
SpawnNewObj(check->tilex,check->tiley,&s_grexplosion1,inertobj);
new->flags |= FL_ABP;
new->whatever = check;
new->temp2 = 100;
MakeActive(new);
SD_PlaySoundRTP(SD_EXPLODESND,check->x,check->y);
break;
#endif
default:
SD_PlaySoundRTP(SD_GETHEADSND,ob->x, ob->y);
break;
}
//StartBonusFlash ();
if (check->flags & FL_CHANGES)
{
switch (check->itemnumber)
{
case stat_pedgoldkey:
case stat_pedsilverkey:
case stat_pedironkey:
case stat_pedcrystalkey:
check->itemnumber = stat_emptypedestal;
check->shapenum = stats[stat_emptypedestal].picnum;
check->flags = stats[stat_emptypedestal].flags|FL_ABP;
check->count = 0;
check->numanims = 0;
break;
case stat_healingbasin:
check->itemnumber = stat_emptybasin;
check->shapenum = stats[stat_emptybasin].picnum;
check->flags = stats[stat_emptybasin].flags|FL_ABP;
check->count = 0;
check->numanims = 0;
break;
/*
case stat_tablebullets:
check->itemnumber = stat_emptytable;
check->shapenum = stats[stat_emptytable].picnum;
check->flags = stats[stat_emptytable].flags|FL_ABP;
break;
case stat_statuewithpole:
check->itemnumber = stat_armornopole;
check->shapenum = stats[stat_armornopole].picnum;
check->flags = stats[stat_armornopole].flags|FL_ABP;
break; */
case stat_pit:
check->shapenum ++;
check->flags &= ~FL_CHANGES;
check->flags &= ~FL_BONUS;
break;
case stat_knifestatue:
check->itemnumber = stat_emptystatue;
check->shapenum = stats[stat_emptystatue].picnum;
check->flags = stats[stat_emptystatue].flags|FL_ABP;
break;
default:
;
}
}
else
{if (check == sprites[check->tilex][check->tiley])
{
statobj_t *checkstat;
checkstat = (statobj_t*)DiskAt(check->tilex,check->tiley);
if (checkstat && (checkstat->which == SPRITE))
sprites[check->tilex][check->tiley] = checkstat;
else
sprites[check->tilex][check->tiley] = NULL;
}
if (randompowerup==true)
check->itemnumber = stat_random;
RemoveStatic(check);
}
}
/*
===================
=
= DropWeapon
=
===================
*/
void DropWeapon(objtype *ob)
{playertype *pstate;
int dtilex,dtiley;
M_LINKSTATE(ob,pstate);
if ((pstate->missileweapon == -1) || (pstate->missileweapon == wp_godhand)
#if (SHAREWARE == 0)
|| (pstate->missileweapon == wp_dog)
#endif
)
return;
pstate->weapondowntics = WEAPONS[pstate->weapon].screenheight/3;
pstate->new_weapon = pstate->bulletweapon;
dtilex = ob->tilex;
dtiley = ob->tiley;
FindEmptyTile(&dtilex, &dtiley);
SpawnStatic(dtilex,dtiley,GetItemForWeapon(pstate->missileweapon),9);
gamestate.missiletotal ++;
LASTSTAT->ammo = pstate->ammo;
LASTSTAT->flags |= FL_ABP;
LASTSTAT->flags &= ~FL_RESPAWN;
MakeStatActive(LASTSTAT);
pstate->weaponx = ob->tilex;
pstate->weapony = ob->tiley;
pstate->ammo = -1;
pstate->missileweapon = -1;
if ((ob==player) && SHOW_BOTTOM_STATUS_BAR() )
DrawBarAmmo (false);
}
/*
===================
=
= Thrust
=
===================
*/
void Thrust ( objtype * ob )
{statobj_t *tstat;
int dx,dy,dz,rad,index,otherteam;
objtype*temp;
playertype * pstate;
PlayerMove(ob);
M_LINKSTATE(ob,pstate);
if ((gamestate.battlemode == battle_CaptureTheTriad) &&
(ob->flags & FL_DESIGNATED) &&
(ob->tilex == TEAM[pstate->team].tilex) &&
(ob->tiley == TEAM[pstate->team].tiley))
{if (ob == player)
SD_Play(PlayerSnds[locplayerstate->player]);
if (BATTLE_CheckGameStatus(battle_captured_triad,ob->dirchoosetime)==
battle_no_event)
{
ob->flags &= ~FL_DESIGNATED;
UpdateKills = true;
otherteam = (pstate->team ^ 1);
SpawnStatic(TEAM[otherteam].tilex,TEAM[otherteam].tiley,stat_collector,9);
LASTSTAT->flags |= FL_COLORED;
LASTSTAT->hitpoints = otherteam;
LASTSTAT->flags |= FL_ABP;
MakeStatActive(LASTSTAT);
}
return;
}
if ((ob->tilex != pstate->weaponx) || (ob->tiley != pstate->weapony))
pstate->weaponx = pstate->weapony = 0;
index = touchindices[ob->tilex][ob->tiley];
if (index && (abs(ob->z - nominalheight) < 5))
{if (!TRIGGER[index-1]){
#if (BNACRASHPREVENT == 1)
if (touchplate[index-1] != 0) { // CRASH IN SHAREWARE 'ride em cowboy' BNA FIX
//SetTextMode ( ); qwert // DONT ALLOW BAD touchplate ( == 0 ) see rt_door.c
#endif
if (touchplate[index-1]->complete)
SD_PlaySoundRTP(SD_BADTOUCHSND,ob->x,ob->y);
else {
SD_PlaySoundRTP(SD_TOUCHPLATESND,ob->x,ob->y);
if (ob == player)
AddMessage("Touchplate triggered.",MSG_GAME);
}
#if (BNACRASHPREVENT == 1)
}else{SD_PlaySoundRTP(SD_BADTOUCHSND,ob->x,ob->y);}
// CRASH IN SHAREWARE 'ride em cowboy' BNA FIX
#endif
}
TRIGGER[index-1] = 1;
}
tstat = sprites[ob->tilex][ob->tiley];
if (tstat)
{dx = abs(ob->x - tstat->x);
dy = abs(ob->y - tstat->y);
dz = abs(ob->z - tstat->z);
if ((dx < 0x8000) && (dy < 0x8000) && (dz<=35))
{
#define OBJECT_IS_BONUS( tstat ) ( ( tstat )->flags & FL_BONUS )
#define PLAYER_IS_SWITCHING_WEAPONS( pstate ) ( W_CHANGE( pstate ) )
//#define IS_ATTACKING( ob ) ( ( ( ob )->state->think == T_Attack ) || ( ( ob )->state->think == T_BatBlast ) )
#define IS_WEAPON( tstat ) ( ( tstat )->flags & FL_WEAPON )
#define PLAYER_MAY_NOT_GET_WEAPON( pstate, ob ) ( PLAYER_IS_SWITCHING_WEAPONS( pstate ))// || IS_ATTACKING( ob ) )
#define OK_TO_PICK_UP( tstat, pstate, ob ) ( !( IS_WEAPON( tstat ) && PLAYER_MAY_NOT_GET_WEAPON( pstate, ob ) ) )
#define WHERE_PLAYER_DROPPED_WEAPON( ob, pstate ) ( ( ( ob )->tilex == ( pstate )->weaponx ) && ( ( ob )->tiley == ( pstate )->weapony ) )
if ( OBJECT_IS_BONUS( tstat ) &&
OK_TO_PICK_UP( tstat, pstate, ob ) &&
(!WHERE_PLAYER_DROPPED_WEAPON( ob, pstate ))
)
{
GetBonus(ob,tstat);
if (PLAYER_IS_SWITCHING_WEAPONS( pstate ))
{statetype *nstate;
#if (SHAREWARE == 0)
if (ob->state->condition & SF_DOGSTATE)
nstate = &s_serialdog;
else
#endif
nstate = &s_player;
pstate->attackframe = pstate->weaponframe = pstate->batblast = 0;
NewState(ob,nstate);
}
}
else if ((tstat->itemnumber == stat_pit) &&
(ob->temp2 != PITFALL) &&
(!(ob->flags & FL_FLEET))
)
{ob->temp2 = PITFALL;
ob->momentumx = ob->momentumy = 0;
//ob->momentumz = 4;
ob->momentumz = GRAVITY;
if (ob->whatever == NULL)
{ob->whatever = tstat;
SD_PlaySoundRTP(SD_PITTRAPSND,ob->x,ob->y);
tstat->shapenum = stats[tstat->itemnumber].picnum + 1;
MakeStatInactive(tstat);
//tstat->flags &= ~FL_ABP;
}
}
else if ((tstat->itemnumber == stat_heatgrate) &&
(!(ob->flags & FL_DYING)) && (!(ob->flags & FL_AV))
)
{DamageThing(ob,1);
Collision(ob,(objtype*)tstat,0,0);
M_CheckPlayerKilled(ob);
}
}
}
//================ Check special player/actor links ======================
if (ob->whatever)
{temp = (objtype*)(ob->whatever);
dx = abs(ob->x - temp->x);
dy = abs(ob->y - temp->y);
dz = abs(ob->z - temp->z);
if (ob->flags & FL_RIDING)
rad = MINACTORDIST;
else
rad = 0x8000;
if ((dx >rad) || (dy > rad) || (dz > 64))
{
if ((temp->obclass == bladeobj) || (temp->obclass == diskobj))
{temp->whatever = NULL;
ob->flags &= ~FL_RIDING;
}
else if (ob->temp2 == COLUMNCRUSH)
ob->temp2 = RENORMALIZE;
else if (ob->z < nominalheight)
ob->momentumz = 40000;
else if (temp->which == SPRITE)
{tstat = (statobj_t*)(ob->whatever);
MakeStatActive(tstat);
SetNormalHorizon(ob);
}
ob->whatever = NULL;
}
}
//=========================================================================
if (BATTLEMODE && (MAPSPOT(ob->tilex,ob->tiley,1) == EXITTILE))
{
Move_Player_From_Exit_To_Start(ob);
return;
}
if (ob==player)
{
if (MAPSPOT(ob->tilex,ob->tiley,1) == EXITTILE)
playstate=ex_completed;
else if ( ( MAPSPOT( ob->tilex, ob->tiley, 2 ) & 0xff00 ) == 0xe400 )
playstate = ex_secretdone;
else if (MAPSPOT(ob->tilex,ob->tiley,1) == SECRETEXITTILE)
playstate=ex_secretlevel;
}
}
void Move_Player_From_Exit_To_Start(objtype *ob)
{
int i = 0,oldarea,newarea;
objtype *tplayer;
int travelangle,dangle;
playertype *pstate;
M_LINKSTATE(ob,pstate);
oldarea = ob->areanumber;
newarea = AREANUMBER(FIRST.x,FIRST.y);
if (oldarea != newarea)
{
RemoveFromArea(ob);
ob->areanumber = newarea;
MakeLastInArea(ob);
}
SetTilePosition(ob,FIRST.x,FIRST.y);
ob->z = PlatformHeight(ob->tilex,ob->tiley);
if ((ob->z == -10) || DiskAt(ob->tilex,ob->tiley))
ob->z = 0;
ConnectAreas();
travelangle = atan2_appx(ob->momentumx,ob->momentumy);
dangle = ob->angle - travelangle;
ob->angle = (1-FIRST.dir)*ANG90 + dangle;
Fix(ob->angle);
ob->dir = angletodir[ob->angle];
pstate->anglefrac= (ob->angle<<ANGLEBITS);
pstate->angle=0;
for(i=0;i<numplayers;i++)
{
tplayer = PLAYER[i];
if (ob == tplayer)
continue;
if (
(tplayer->tilex == FIRST.x) &&
(tplayer->tiley == FIRST.y) &&
(!(tplayer->flags & FL_DYING))
)
{
playertype *pstate;
M_LINKSTATE(tplayer,pstate);
pstate->health = tplayer->hitpoints = 0;
tplayer->flags |= FL_HBM;
Collision(tplayer,ob,0,0);
BATTLE_PlayerKilledPlayer(battle_kill_by_crushing,ob->dirchoosetime,tplayer->dirchoosetime);\
}
}
}
void PlayerSlideMove(objtype * ob)
{int tryx, tryy, tryz;
tryx = ob->x + ob->momentumx;
tryy = ob->y + ob->momentumy;
tryz = ob->z + (ob->momentumz >> 16);
if (ActorTryMove(ob,ob->x,tryy,tryz))
{
if (ob->momentumx>HITWALLSPEED)
SD_PlaySoundRTP(SD_HITWALLSND,ob->x,ob->y);
ob->momentumx=0;
}
else if (ActorTryMove(ob,tryx,ob->y,tryz))
{
if (ob->momentumy>HITWALLSPEED)
SD_PlaySoundRTP(SD_HITWALLSND,ob->x,ob->y);
ob->momentumy=0;
}
else
{
if (FindDistance(ob->momentumx,ob->momentumy)>(HITWALLSPEED*3/2))
SD_PlaySoundRTP(SD_HITWALLSND,ob->x,ob->y);
ob->momentumx=0;
ob->momentumy=0;
}
}
/*
===================
=
= SetNormalHorizon
=
===================
*/
void SetNormalHorizon (objtype * ob)
{
playertype * pstate;
M_LINKSTATE(ob,pstate);
if (ob->flags&FL_DOGMODE)
{
SetPlayerHorizon(pstate,DOGYZANGLE);
}
else if (ob->flags&FL_GODMODE)
{
SetPlayerHorizon(pstate,GODYZANGLE);
}
else
{
SetPlayerHorizon(pstate,NORMALYZANGLE);
}
}
/*
===================
=
= PlayerTiltHead
=
===================
*/
extern int iG_playerTilt;
extern double dTopYZANGLELIMIT;
void PlayerTiltHead (objtype * ob)
{
playertype * pstate;
int dyz=0;
int yzangle;
//bna++ jumpmode
if ((donttilt > 0)){
donttilt--;
return;
}
M_LINKSTATE(ob,pstate);
yzangle=ob->yzangle+HORIZONYZOFFSET;
Fix(yzangle);
if (
(pstate->lastmomz!=ob->momentumz) &&
(ob->momentumz==0) &&
(
(!(ob->flags&FL_FLEET)) ||
(
(ob->flags&FL_FLEET) &&
(ob->z==nominalheight)
)
)
)
SetNormalHorizon(ob);
pstate->lastmomz=ob->momentumz;
if (ob->flags&FL_SHROOMS)
{
ob->yzangle = FixedMulShift(SHROOMYZANGLE,sintable[(oldpolltime<<6)&(FINEANGLES-1)],16);
Fix(ob->yzangle);
return;
}
else if (pstate->guntarget)
{
int dx,dy,dz;
int xydist;
int yzangle;
dx = ob->x - pstate->guntarget->x;
dy = ob->y - pstate->guntarget->y;
xydist = FindDistance(dx,dy)-0x8000;
if (ob->z==pstate->guntarget->z)
dz = 0;
else
{
dz = (ob->z-pstate->guntarget->z)<<10;
}
yzangle = atan2_appx(xydist,dz);
yzangle += HORIZONYZOFFSET;
Fix(yzangle);
SetPlayerHorizon(pstate,yzangle-HORIZONYZOFFSET);
if (oldpolltime>pstate->targettime)
{
if (pstate->guntarget)
pstate->guntarget->flags &= ~FL_TARGET;
pstate->guntarget=NULL;
SetNormalHorizon(ob);
}
}
else
{
if (pstate->buttonstate[bt_horizonup])
{
if (yzangle!=pstate->horizon)
{
SetPlayerHorizon(pstate,yzangle-HORIZONYZOFFSET);
}
else
{
SetPlayerHorizon(pstate,(pstate->horizon-HORIZONYZOFFSET+YZHORIZONSPEED));
}
}
else if (pstate->buttonstate[bt_horizondown])
{
if (yzangle!=pstate->horizon)
{
SetPlayerHorizon(pstate,yzangle-HORIZONYZOFFSET);
}
else
{
SetPlayerHorizon(pstate,(pstate->horizon-HORIZONYZOFFSET-YZHORIZONSPEED));
}
}
if (pstate->buttonstate[bt_lookup] || CYBERLOOKUP)
{
if (!(ob->flags & FL_FLEET))
{
dyz=YZTILTSPEED;
if (pstate->buttonstate[bt_lookdown] || CYBERLOOKDOWN)
{
dyz=0;
}
SetNormalHorizon(ob);
}
}
if (pstate->buttonstate[bt_lookdown] || CYBERLOOKDOWN)
{
if (!(ob->flags & FL_FLEET))
{
dyz=-YZTILTSPEED;
if (pstate->buttonstate[bt_lookup] || CYBERLOOKUP)
{
dyz=0;
}
SetNormalHorizon(ob);
}
}
if (!(ob->flags&FL_DOGMODE) &&
!(ob->flags&FL_GODMODE) &&
!(ob->flags&FL_FLEET) &&
!(ob->flags&FL_RIDING) &&
(ob->momentumz > (GRAVITY<<1))//(ob->momentumz>0x1000)
)
{
SetPlayerHorizon(pstate,FALLINGYZANGLE);
}
}
if ((yzangle!=pstate->horizon) && (dyz==0))
{
int speed;
speed=SNAPBACKSPEED;
if (yzangle<pstate->horizon)
yzangle+=speed;
else
yzangle-=speed;
if ((abs(yzangle-pstate->horizon))<SNAPBACKSPEED)
yzangle=pstate->horizon;
}
//SetTextMode();
if (yzangle != 512){
FinddTopYZANGLELIMITvalue(ob);
}
yzangle+=dyz;
if (yzangle-HORIZONYZOFFSET>YZANGLELIMIT)
yzangle=HORIZONYZOFFSET+YZANGLELIMIT;
/* else if (yzangle-HORIZONYZOFFSET<-TopYZANGLELIMIT)//bnafix
yzangle=HORIZONYZOFFSET-TopYZANGLELIMIT;//bnafix
dTopYZANGLELIMIT*/
else if (yzangle-HORIZONYZOFFSET<-dTopYZANGLELIMIT)//bnafix
yzangle=HORIZONYZOFFSET-dTopYZANGLELIMIT;//bnafix
ob->yzangle=yzangle-HORIZONYZOFFSET;
Fix(ob->yzangle);
iG_playerTilt = ob->yzangle;
}
//----------------------------------------------------------------------
// bna added function
// if a player is to close to wall, looking down max
//,this func limit the dTopYZANGLELIMIT value when
// facing a wall
#define SMALLANGLE 90
//there is small angles where didnt work
//so we check for them to = 90/2048 = aprox, 15 degrees
int FinddTopYZANGLELIMITvalue(objtype *ob)
{/*
checkx = ob->tilex + 1;
checky = ob->tiley + 1;
if (actorat[checkx][checky]){
return 0;
}
return 1;
checkx = ob->tilex ;
checky = ob->tiley;
// find which direction the player is facing
//and check if it is a wall
*/
//use lowest down angle
dTopYZANGLELIMIT = (26*FINEANGLES/360);
if (ob->angle < 256 || ob->angle > 1792) {
if ((tilemap[ob->tilex + 1][ob->tiley])!=0){
return 0;
}
//ob->dir = east;
}else if (ob->angle < 768) {
if ((tilemap[ob->tilex][ob->tiley-1])!=0){
return 0;
}
}else if (ob->angle < 1280) {
if ((tilemap[ob->tilex-1][ob->tiley])!=0){
return 0;
}
}else{
if ((tilemap[ob->tilex][ob->tiley+1])!=0){
return 0;
}
}
//use middle down angle
dTopYZANGLELIMIT = (42*FINEANGLES/360);
if ((ob->angle > 768-SMALLANGLE)&&(ob->angle <= 768)) {
if ((tilemap[ob->tilex -1][ob->tiley])!=0){//ob->tiley-1
return 0;
}
}
if ((ob->angle < 1280+SMALLANGLE)&&(ob->angle >= 1280)) {
if ((tilemap[ob->tilex - 1][ob->tiley])!=0){//ob->tiley+1
return 0;
}
}
if ((ob->angle > 256)&&(ob->angle <= 256+SMALLANGLE)) {
if ((tilemap[ob->tilex + 1][ob->tiley])!=0){//ob->tiley-1
return 0;
}
}
if ((ob->angle < 1792)&&(ob->angle >= 1792-SMALLANGLE)) {
if ((tilemap[ob->tilex + 1][ob->tiley])!=0){//ob->tiley+1
return 0;
}
}
if ((ob->angle < 1280)&&(ob->angle >= 1280-SMALLANGLE)) {
if ((tilemap[ob->tilex ][ob->tiley+1])!=0){//ob->tilex-1
return 0;
}
}
if ((ob->angle > 1792)&&(ob->angle <= 1792+SMALLANGLE)) {
if ((tilemap[ob->tilex ][ob->tiley+1])!=0){//ob->tiley+1
return 0;
}
}
if ((ob->angle > 768)&&(ob->angle <= 768+SMALLANGLE)) {
if ((tilemap[ob->tilex][ob->tiley-1])!=0){//ob->tiley-1
return 0;
}
}
if ((ob->angle < 256)&&(ob->angle >= 256-SMALLANGLE)) {
if ((tilemap[ob->tilex][ob->tiley-1])!=0){//ob->tiley-1
return 0;
}
}
//use max down angle
dTopYZANGLELIMIT = (90*FINEANGLES/360);
return 1;
}
// bna added function end
//----------------------------------------------------------------------
/*
===================
=
= UpdatePlayers
=
=================== QWERTYU
*/
void UpdatePlayers ( void )
{
objtype * obj;
// playertype * pstate;
for (obj = FIRSTACTOR; obj->obclass==playerobj; obj = obj->next)
{
//ErrorDontQuit("obj->next = ",obj->next);
#if (BNACRASHPREVENT == 1)//crashed here when oscuro and larves were all killed
if (obj->next == 0){return;}
#endif
obj->speed=FindDistance(obj->momentumx, obj->momentumy);
// M_LINKSTATE(obj,pstate);
// pstate->steptime-=obj->speed;
// if (pstate->steptime<0)
// {
// while (pstate->steptime<0)
// pstate->steptime+=PLAYERSTEPTIME;
// pstate->stepwhich^=1;
// SD_PlaySoundRTP(SD_WALK1SND+pstate->stepwhich,obj->x,obj->y);
// }
}
}
/*
===================
=
= PlayerMove
=
===================
*/
void PlayerMove ( objtype * ob )
{playertype *pstate;
M_LINKSTATE(ob,pstate);
if (ob->flags & FL_FLEET)
CheckFlying(ob,pstate);
ActorMovement(ob);
pstate->anglefrac = (pstate->anglefrac+pstate->angle)&((FINEANGLES<<ANGLEBITS)-1);
ob->angle = (pstate->anglefrac >> ANGLEBITS);
ob->dir = angletodir[ob->angle];
if (ob==player)
UpdateLightLevel(player->areanumber);
PlayerTiltHead(ob);
if (IsWindow(ob->tilex,ob->tiley))
{
if (!(ob->flags & FL_DYING))
{
pstate->health = 0;
pstate->falling=true;
if ((ob->flags & FL_GODMODE) || (ob->flags & FL_DOGMODE) ||
(gamestate.battlemode == battle_Eluder) || (godmode==true))
{
KillActor(ob);
NewState(ob,&s_remotedie1);
}
else
Collision(ob,(objtype*)NULL,0,0);
ob->flags |= FL_DYING;
M_CheckPlayerKilled(ob);
}
}
}
/*
===============
=
= T_Tag
=
===============
*/
void T_Tag (objtype *ob)
{
playertype *pstate;
CheckPlayerSpecials(ob);
//CheckWeaponStates(ob);
M_LINKSTATE(ob,pstate);
Thrust(ob);
if (ob->ticcount > 4)
pstate->weaponheight -= GMOVE;
else
pstate->weaponheight += GMOVE;
if ((ob->ticcount > 1) && (ob->ticcount < 8) && (!(ob->flags & FL_DIDTAG)))
{int i,dx,dy,magangle;
for(i=0;i<numplayers;i++)
{if (PLAYER[i] == ob)
continue;
dx = abs(PLAYER[i]->x - ob->x);
dy = abs(PLAYER[i]->y - ob->y);
if ((dx > 0xc000) || (dy > 0xc000))
continue;
magangle = abs(ob->angle - AngleBetween(ob,PLAYER[i]));
if (magangle > VANG180)
magangle = ANGLES - magangle;
if (magangle > ANGLES/8)
continue;
CheckTagGame(ob,PLAYER[i]);
break;
}
}
//Commented out until we find if it's valid
/*
if (!ob->ticcount)
{if ( pstate->buttonstate[bt_use] && !pstate->buttonheld[bt_use] )
pstate->buttonstate[bt_use] = false;
if ( pstate->buttonstate[bt_attack] && !pstate->buttonheld[bt_attack])
pstate->buttonstate[bt_attack] = false;
}
*/
}
#if (SHAREWARE == 0)
#define GET_RESETSTATE(ob,resetstate) \
{ \
if (ob->state->condition & SF_DOGSTATE) \
resetstate = &s_serialdog; \
else \
resetstate = &s_player; \
}
#else
#define GET_RESETSTATE(ob,resetstate) \
{ \
resetstate = &s_player; \
}
#endif
/*
===============
=
= T_Attack
=
===============
*/
void T_Attack (objtype *ob)
{
attack_t *cur;
playertype *pstate;
statetype *resetstate;
Thrust(ob);
if (ob->flags & FL_DYING)
return;
resetstate = ob->state;
CheckPlayerSpecials(ob);
if (resetstate != ob->state)
{
return;
}
if ((ob->flags & FL_PAIN) && (!ob->ticcount))
ob->flags &= ~FL_PAIN;
CheckWeaponStates(ob);
M_LINKSTATE(ob,pstate);
GET_RESETSTATE(ob,resetstate);
if (ARMED(ob->dirchoosetime)
//(gamestate.battlemode != battle_Tag)
)
{
if (pstate->weapondowntics == 1) // change to up; during change, up and down
// are never zero at the same time
{
#if (SHAREWARE == 0)
if (pstate->weapon == wp_kes)
{
pstate->weapondowntics = 0;
pstate->weaponuptics = KESTICS/(2*GMOVE);
}
else
#endif
{
pstate->weapondowntics = 0;
pstate->weaponframe = pstate->attackframe = 0;
if (pstate->NETCAPTURED == -1)
{
pstate->weaponuptics = FREE.screenheight/GMOVE;
pstate->weaponheight = pstate->weaponuptics*GMOVE ;
pstate->NETCAPTURED = 1;
// return;
}
else if (pstate->NETCAPTURED == -2)
{
pstate->weaponuptics = WEAPONS[pstate->weapon].screenheight/GMOVE;
pstate->weaponheight = pstate->weaponuptics*GMOVE ;
pstate->NETCAPTURED = 0;
//return;
}
else
{
pstate->weaponuptics = WEAPONS[pstate->new_weapon].screenheight/GMOVE;
pstate->weapon = pstate->new_weapon;
pstate->weaponheight = pstate->weaponuptics*GMOVE ;
}
}
}
}
else if (gamestate.battlemode == battle_Hunter)
{
if (pstate->weapondowntics == 1)
{
pstate->weapondowntics = 0;
pstate->weaponframe = pstate->attackframe = pstate->batblast = 0;
pstate->weapon = pstate->new_weapon;
NewState(ob,resetstate);
return;
}
}
#if (SHAREWARE==0)
if ((pstate->buttonstate[bt_use]) &&
(pstate->weapon != wp_dog)
)
#else
if (pstate->buttonstate[bt_use])
#endif
Cmd_Use (ob);
if (pstate->attackframe >= WEAPONS[pstate->weapon].numattacks)
Error("\n attackframe %d for weapon %d gt numattacks %d",
pstate->attackframe,pstate->weapon,
WEAPONS[pstate->weapon].numattacks
);
cur = &(WEAPONS[pstate->weapon].attackinfo[pstate->attackframe]);
if (! pstate->attackcount)
{
switch (cur->attack)
{
case reset:
if (vrenabled && (ob==player))
{
StopVRFeedback();
}
ob->flags &= ~FL_FULLLIGHT;
if (pstate->ammo)
{
if (BATTLEMODE && (pstate->weapon == wp_firewall))
break;
if (BATTLEMODE && (pstate->weapon == wp_firebomb))
break;
if ((pstate->buttonstate[bt_attack]) && (pstate->weapon <= wp_firewall))
{
if (pstate->weapon <= wp_mp40)
{
if (pstate->weapon == wp_twopistol)
pstate->attackframe -= 6;
else if (pstate->weapon == wp_pistol)
pstate->attackframe -= 3;
else if (pstate->weapon == wp_mp40)
pstate->attackframe -= 2;
if (ob->state == &s_pmissattack2)
NewState(ob,&s_pmissattack1);
else if (ob->state == &s_pgunattack2)
NewState(ob,&s_pgunattack1);
}
}
else
{
NewState(ob,resetstate);
pstate->attackframe = pstate->weaponframe = 0;
pstate->batblast = 0;
return;
}
}
else
{
NewState(ob,resetstate);
pstate->attackframe = pstate->weaponframe = 0;
pstate->new_weapon = pstate->bulletweapon;
pstate->batblast = 0;
pstate->ammo = -1;
pstate->missileweapon = -1;
pstate->weapondowntics = WEAPONS[pstate->weapon].screenheight/GMOVE;
if ((ob==player) && SHOW_BOTTOM_STATUS_BAR() )
DrawBarAmmo (false);
return;
}
break;
case reset2:
if (vrenabled && (ob==player))
{
StopVRFeedback();
}
ob->flags &= ~FL_FULLLIGHT;
if (pstate->buttonstate[bt_attack] && pstate->ammo)
{
pstate->attackframe -= 4;
if (ob->state == &s_pmissattack2)
NewState(ob,&s_pmissattack1);
else if (ob->state == &s_pgunattack2)
NewState(ob,&s_pgunattack1);
}
else
{
NewState(ob,resetstate);
pstate->attackframe = pstate->weaponframe = 0;
pstate->batblast = 0;
return;
}
break;
case at_pulltrigger:
if (vrenabled && (ob==player))
{
StartVRFeedback(1);
}
ob->flags |= FL_FULLLIGHT;
#if (SHAREWARE == 0)
if (pstate->batblast >= BBTIME)
DogBlast(ob);
else if (pstate->weapon == wp_dog)
DogAttack(ob);
else if (pstate->weapon == wp_bat)
BatAttack (ob);
else
#endif
GunAttack(ob);
break;
case at_missileweapon:
if (!pstate->ammo)
{
pstate->attackframe = pstate->weaponframe = 0;
pstate->batblast = 0;
return;
}
if (vrenabled && (ob==player))
{
StartVRFeedback(1);
}
ob->flags |= FL_FULLLIGHT;
if (ob==player)
SetIllumination(2);
PlayerMissileAttack(ob);
if (!(ob->flags & FL_GODMODE) && !godmode)
{
if (!BATTLEMODE || (gamestate.BattleOptions.Ammo != bo_infinite_shots))
pstate->ammo--;
if ((ob==player) && SHOW_BOTTOM_STATUS_BAR() )
DrawBarAmmo (false);
}
#if (SHAREWARE == 0)
if (pstate->weapon == wp_kes)
pstate->weapondowntics = KESTICS/(2*GMOVE);
#endif
break;
default:
;
}
pstate->attackframe++;
cur = &(WEAPONS[pstate->weapon].attackinfo[pstate->attackframe]);
pstate->weaponframe = cur->frame;
pstate->attackcount = cur->mtics;
}
else
pstate->attackcount --;
}
/*
===============
=
= T_BatBlast
=
===============
*/
void T_BatBlast (objtype *ob)
{
attack_t *cur;
playertype *pstate;
Thrust(ob);
CheckPlayerSpecials(ob);
M_LINKSTATE(ob,pstate);
//Commented out until we find if it's valid
/*
if (!ob->ticcount)
{if ( pstate->buttonstate[bt_use] && !pstate->buttonheld[bt_use] )
pstate->buttonstate[bt_use] = false;
if ( pstate->buttonstate[bt_attack] && !pstate->buttonheld[bt_attack])
pstate->buttonstate[bt_attack] = false;
}
*/
//
// change frame and fire
//
BatBlast(ob);
if (pstate->attackframe >= WEAPONS[pstate->weapon].numattacks)
Error("\n attackframe %d for weapon %d gt numattacks %d",
pstate->attackframe,pstate->weapon,
WEAPONS[pstate->weapon].numattacks
);
cur = &(WEAPONS[pstate->weapon].attackinfo[pstate->attackframe]);
if (! pstate->attackcount)
{if (cur->attack == reset)
{
if (!(ob->flags & FL_GODMODE) && (!godmode))
{pstate->ammo --;
if ((ob==player) && SHOW_BOTTOM_STATUS_BAR() )
DrawBarAmmo (false);
}
if (!pstate->ammo)
{pstate->new_weapon = pstate->bulletweapon;
pstate->ammo = -1;
pstate->missileweapon = -1;
pstate->weapondowntics = WEAPONS[pstate->weapon].screenheight/GMOVE;
}
NewState(ob,&s_player);
pstate->attackframe = pstate->weaponframe = 0;
pstate->batblast = 0;
return;
}
pstate->attackframe++;
pstate->weaponframe = WEAPONS[pstate->weapon].attackinfo[pstate->attackframe].frame;
cur = &(WEAPONS[pstate->weapon].attackinfo[pstate->attackframe]);
pstate->attackcount = cur->mtics;
}
else
pstate->attackcount --;
}
void T_Free (objtype *ob)
{
attack_t *cur;
if (!ob->ticcount)
{
//Commented out until we find if it's valid
/*
if ( locplayerstate->buttonstate[bt_use] && !locplayerstate->buttonheld[bt_use] )
locplayerstate->buttonstate[bt_use] = false;
if ( locplayerstate->buttonstate[bt_attack] && !locplayerstate->buttonheld[bt_attack])
locplayerstate->buttonstate[bt_attack] = false;
*/
Thrust(ob);
}
CheckPlayerSpecials(ob);
cur = &(FREE.attackinfo[locplayerstate->attackframe]);
if (!locplayerstate->attackcount)
{
if ((locplayerstate->weaponframe > 3) && (locplayerstate->weaponframe < 8))
locplayerstate->NETCAPTURED ++;
else if (locplayerstate->weaponframe == 8)
{
locplayerstate->NETCAPTURED = -2;
MISCVARS->NET_IN_FLIGHT = false;
NewState(ob,&s_player);
locplayerstate->weapondowntics = FREE.screenheight/GMOVE;
return;
}
locplayerstate->attackframe++;
cur = &(FREE.attackinfo[locplayerstate->attackframe]);
locplayerstate->weaponframe = cur->frame;
locplayerstate->attackcount = cur->mtics;
}
else
locplayerstate->attackcount --;
}
void Switch_Who_Is_It_For_Tag(objtype *actor1,objtype *actor2)
{
playertype *pstate;
M_LINKSTATE(actor1,pstate);
if (pstate->buttonstate[bt_use])
{playertype *pstate2;
M_LINKSTATE(actor2,pstate2);
pstate2->oldmissileweapon = pstate2->oldweapon = pstate2->new_weapon =
pstate2->missileweapon = pstate2->weapon = wp_godhand;
pstate2->weaponheight = 144;
pstate2->weaponuptics = (144 - TAGHANDHEIGHT)/GMOVE;
pstate2->weapondowntics = 0;
actor1->flags |= FL_DIDTAG;
actor2->flags |= FL_DESIGNATED;
UpdateKills = true;
actor1->flags &= ~FL_DESIGNATED;
BATTLE_PlayerKilledPlayer(battle_player_tagged,
actor1->dirchoosetime, actor2->dirchoosetime);
}
}
void CheckTagGame(objtype *actor1,objtype*actor2)
{
//if ((actor1->obclass != playerobj) || (actor2->obclass != playerobj))
//return;
if (!BATTLEMODE)
return;
if (gamestate.battlemode != battle_Tag)
return;
SD_PlaySoundRTP(SD_GETBONUSSND,actor1->x,actor1->y);
if (actor1->flags & FL_DESIGNATED)
Switch_Who_Is_It_For_Tag(actor1,actor2);
else if (actor2->flags & FL_DESIGNATED)
Switch_Who_Is_It_For_Tag(actor2,actor1);
}
/*
======================
=
= CheckWeaponChange
=
= Keys 1-4 change weapons
=
======================
*/
void CheckWeaponChange (objtype * ob)
{
// int i;
playertype * pstate;
M_LINKSTATE(ob,pstate);
//pstate = (ob == player)?(&playerstate):(&remoteplayerstate);
if (W_CHANGE(pstate))
return;
if (!ARMED(ob->dirchoosetime))
return;
if ((ob->flags & FL_DOGMODE) || (ob->flags & FL_GODMODE))
return;
#if (WEAPONCHEAT==1)
if (godmode && Keyboard[sc_Insert])
{
SD_Play(SD_SELECTWPNSND);
// FOR DEBUG only
/*
if (pstate->buttonstate[bt_run])
{
if (pstate->weapon == 0)
pstate->new_weapon = wp_bat;
else
pstate->new_weapon --;
}
else
{*/
if (pstate->weapon == MAXWEAPONS-1)
pstate->new_weapon = 0;
else
pstate->new_weapon ++;
//}
if (pstate->new_weapon <= wp_mp40)
{pstate->bulletweapon = pstate->new_weapon;
pstate->HASBULLETWEAPON[pstate->new_weapon] = 1;
}
else
pstate->missileweapon = pstate->new_weapon;
pstate->ammo = stats[GetItemForWeapon(pstate->missileweapon)].ammo;
if (pstate->ammo<1)
pstate->ammo=5;
StartWeaponChange;
//pstate->weapondowntics = WEAPONS[pstate->weapon].screenheight/GMOVE;
//if ((ob==player) && SHOW_BOTTOM_STATUS_BAR() )
// DrawBarAmmo (false);
}
else if (pstate->buttonstate[bt_swapweapon])
#else
if (pstate->buttonstate[bt_swapweapon])
#endif
{
if ((pstate->weapon == pstate->bulletweapon) &&
(pstate->missileweapon != -1))
{pstate->new_weapon = pstate->missileweapon;
StartWeaponChange;
}
else if (pstate->weapon != pstate->bulletweapon)
{pstate->new_weapon = pstate->bulletweapon;
StartWeaponChange;
}
}
else if ((pstate->buttonstate[bt_dropweapon]) &&
(!gamestate.BattleOptions.WeaponPersistence))
{
if (pstate->weapon==pstate->bulletweapon)
{
if ((ob==player) && (!(pstate->buttonheld[bt_dropweapon])))
PlayNoWaySound();
}
else
{
if (sprites[ob->tilex][ob->tiley])
{
if ((ob==player) && (!(pstate->buttonheld[bt_dropweapon])))
PlayNoWaySound();
}
else
{
DropWeapon(ob);
}
}
}
if (pstate->buttonstate[bt_pistol])
{if (pstate->weapon != wp_pistol)
{pstate->new_weapon = pstate->bulletweapon = wp_pistol;
StartWeaponChange;
}
}
else if (pstate->buttonstate[bt_dualpistol])
{if ((pstate->weapon != wp_twopistol) && pstate->HASBULLETWEAPON[wp_twopistol])
{pstate->new_weapon = pstate->bulletweapon = wp_twopistol;
StartWeaponChange;
}
}
else if (pstate->buttonstate[bt_mp40])
{if ((pstate->weapon != wp_mp40) && pstate->HASBULLETWEAPON[wp_mp40])
{pstate->new_weapon = pstate->bulletweapon = wp_mp40;
StartWeaponChange;
}
}
else if (pstate->buttonstate[bt_missileweapon])
{if ((pstate->weapon != pstate->missileweapon) && (pstate->missileweapon != -1))
{pstate->new_weapon = pstate->missileweapon;
StartWeaponChange;
}
}
}
void SetWhoHaveWeapons(void)
{
playertype *pstate;
objtype *ob;
int i;
for ( i = 0; i < numplayers; i++ )
{
ob = PLAYER[ i ];
M_LINKSTATE( ob, pstate );
if ( ARMED( ob->dirchoosetime ))
{
if (pstate->weapon == -1)
{
if (( pstate->missileweapon != -1 ) && (pstate->ammo>0))
pstate->new_weapon = pstate->missileweapon;
else
{
if ( pstate->bulletweapon == -1 )
{
pstate->HASBULLETWEAPON[ wp_pistol ] = 1;
pstate->bulletweapon = wp_pistol;
}
pstate->new_weapon = pstate->bulletweapon;
pstate->ammo = -1;
}
pstate->weapon = pstate->new_weapon;
pstate->weapondowntics = 0;
pstate->weaponuptics = WEAPONS[pstate->new_weapon].screenheight/GMOVE;
pstate->weaponheight = pstate->weaponuptics*GMOVE ;
pstate->attackframe = pstate->weaponframe =
pstate->batblast = 0;
if (i == consoleplayer)
DrawBarAmmo(false);
}
}
else
{
if (ob->flags & FL_DOGMODE)
{
ob->temp2 = DOGMODERISE;
pstate->oldweapon = -1;
ResetWeapons(ob);
if (ob->state->condition & SF_DOGSTATE)
NewState(ob,&s_player);
}
else if (ob->flags & FL_GODMODE)
{
ob->temp2 = GODMODEFALL;
pstate->oldweapon = -1;
ResetWeapons(ob);
}
else
{
pstate->new_weapon = -1;
StartWeaponChange;
}
pstate->attackframe = pstate->weaponframe =
pstate->batblast = 0;
}
}
}
void CheckWeaponStates(objtype*ob)
{playertype *pstate;
M_LINKSTATE(ob,pstate);
if (gamestate.battlemode == battle_Tag)
{if (pstate->weapondowntics)
{pstate->weaponheight += GMOVE;
pstate->weapondowntics --;
if (!pstate->weapondowntics)
pstate->weapon = pstate->missileweapon = pstate->bulletweapon =
pstate->new_weapon = pstate->oldweapon = pstate->oldmissileweapon = -1;
}
if (pstate->weaponuptics)
{pstate->weaponheight -= GMOVE;
pstate->weaponuptics --;
}
return;
}
if (pstate->weapondowntics)
{pstate->weaponheight += GMOVE;
#if (SHAREWARE == 0)
if ((pstate->weapon == wp_kes) && pstate->attackframe)
pstate->weaponheight += GMOVE;
#endif
pstate->weapondowntics --;
}
else if (pstate->weaponuptics)
{pstate->weaponheight -= GMOVE;
#if (SHAREWARE == 0)
if ((pstate->weapon == wp_kes) && pstate->attackframe)
pstate->weaponheight -= GMOVE;
#endif
pstate->weaponuptics --;
}
else if ((pstate->weapon == pstate->new_weapon) && (!pstate->NETCAPTURED))
pstate->weaponheight = 0;
}
/*
=============================
=
= CheckSpecialSounds
=
=============================
*/
#define REGDOGSTATE(ob) \
((ob->state == &s_serialdog) || (ob->state == &s_serialdog2) || \
(ob->state == &s_serialdog3) || (ob->state == &s_serialdog4) \
)
static int dyingvolume=255;
void CheckSpecialSounds(objtype *ob, playertype *pstate)
{
int shift;
if ((!BATTLEMODE) && (ob == player))
{
if (pstate->health < MaxHitpointsForCharacter(locplayerstate)/5)
{
pstate->healthtime ++;
if (pstate->healthtime > 2*VBLCOUNTER)
{
pstate->healthtime = 0;
SD_PlayPitchedSound ( SD_PLAYERDYINGSND, dyingvolume, 0 );
if (dyingvolume>80)
dyingvolume-=40;
}
}
else
{
dyingvolume=255;
}
}
if (((ob->flags & FL_GODMODE) || (ob->flags & FL_DOGMODE)) &&
(!W_CHANGE(pstate))
)
{
pstate->soundtime++;
if (pstate->soundtime > (2*VBLCOUNTER))
{
int rand;
rand = GameRandomNumber("player special sound",0);
shift = (pstate->soundtime>>5);
if ((rand << shift) > 3500)
{
int sound;
pstate->soundtime = 0;
rand = GameRandomNumber("player god scare",0);
if (ob->flags & FL_GODMODE)
{
sound = SD_GODMODE1SND;
if (rand < 160)
sound++;
if (rand < 80)
sound ++;
SD_PlaySoundRTP(sound,ob->x,ob->y);
}
#if (SHAREWARE == 0)
else if ((!pstate->batblast) && (!ob->momentumz) &&
(REGDOGSTATE(ob))
)
{
sound = SD_DOGMODEPANTSND;
if (rand < 128)
sound += 2;
NewState(ob,&s_doglick);
pstate->attackframe = pstate->weaponframe =
pstate->batblast = 0;
SD_PlaySoundRTP(sound,ob->x,ob->y);
}
#endif
}
}
}
else if (ob->flags & FL_GASMASK)
{
pstate->soundtime ++;
if (pstate->soundtime > (3*VBLCOUNTER))
{
pstate->soundtime = 0;
SD_PlaySoundRTP(SD_GASMASKSND,ob->x,ob->y);
}
}
else if (MISCVARS->GASON)
{
pstate->soundtime ++;
if (pstate->soundtime > (2*VBLCOUNTER))
{
int rand;
rand = GameRandomNumber("player cough sound",0);
shift = (pstate->soundtime>>5);
if ((rand << shift) > 2000)
{
pstate->soundtime = 0;
if ((pstate->player == 1) || (pstate->player == 3))
SD_PlaySoundRTP(SD_PLAYERCOUGHFSND,ob->x,ob->y);
else
SD_PlaySoundRTP(SD_PLAYERCOUGHMSND,ob->x,ob->y);
}
}
}
}
/*
static int dyingvolume=255;
void CheckSpecialSounds(objtype *ob, playertype *pstate)
{
int shift;
if ((!BATTLEMODE) && (ob == player))
{
if (pstate->health < MaxHitpointsForCharacter(locplayerstate)/5)
{
pstate->healthtime ++;
if (pstate->healthtime > 2*VBLCOUNTER)
{
pstate->healthtime = 0;
SD_PlayPitchedSound ( SD_PLAYERDYINGSND, dyingvolume, 0 );
if (dyingvolume>80)
dyingvolume-=40;
}
}
else
{
dyingvolume=255;
}
}
if (((ob->flags & FL_GODMODE) || (ob->flags & FL_DOGMODE)) &&
(!W_CHANGE(pstate))
)
{
pstate->soundtime++;
if (pstate->soundtime > (2*VBLCOUNTER))
{
int rand;
rand = GameRandomNumber("player special sound",0);
shift = (pstate->soundtime>>5);
if ((rand << shift) > 3500)
{
int sound;
pstate->soundtime = 0;
rand = GameRandomNumber("player god scare",0);
if (ob->flags & FL_GODMODE)
{
sound = SD_GODMODE1SND;
if (rand < 160)
sound++;
if (rand < 80)
sound ++;
SD_PlaySoundRTP(sound,ob->x,ob->y);
}
#if (SHAREWARE == 0)
else if (!pstate->batblast)
{
sound = SD_DOGMODEPANTSND;
if (rand < 128)
sound += 2;
NewState(ob,&s_doglick);
pstate->attackframe = pstate->weaponframe =
pstate->batblast = 0;
SD_PlaySoundRTP(sound,ob->x,ob->y);
}
#endif
}
}
}
else if (ob->flags & FL_GASMASK)
{
pstate->soundtime ++;
if (pstate->soundtime > (3*VBLCOUNTER))
{
pstate->soundtime = 0;
SD_PlaySoundRTP(SD_GASMASKSND,ob->x,ob->y);
}
}
else if (MISCVARS->GASON)
{
pstate->soundtime ++;
if (pstate->soundtime > (2*VBLCOUNTER))
{
int rand;
rand = GameRandomNumber("player cough sound",0);
shift = (pstate->soundtime>>5);
if ((rand << shift) > 2000)
{
pstate->soundtime = 0;
if ((pstate->player == 1) || (pstate->player == 3))
SD_PlaySoundRTP(SD_PLAYERCOUGHFSND,ob->x,ob->y);
else
SD_PlaySoundRTP(SD_PLAYERCOUGHMSND,ob->x,ob->y);
}
}
}
}
*/
/*
=============================
=
= CheckProtectionsAndPowerups
=
=============================
*/
void CheckProtectionsAndPowerups(objtype *ob, playertype *pstate)
{
if (pstate->poweruptime)
{
pstate->poweruptime --;
if (pstate->poweruptime < 0)
pstate->poweruptime = 0;
if (ob==player)
GM_UpdateBonus (pstate->poweruptime, true);
}
else
{
if (ob->flags & FL_ELASTO)
{
ob->flags &= ~FL_NOFRICTION;
if (ob==player)
GM_UpdateBonus (pstate->poweruptime, true);
SD_PlaySoundRTP(SD_LOSEMODESND,ob->x, ob->y);
}
else if (ob->flags & FL_GODMODE)
{ob->temp2 = GODMODEFALL;
if ((pstate->player == 1) || (pstate->player == 3))
SD_PlaySoundRTP(SD_GODWOMANSND,ob->x, ob->y);
else
SD_PlaySoundRTP(SD_GODMANSND,ob->x, ob->y);
ResetWeapons(ob);
}
else if (ob->flags & FL_DOGMODE)
{int wall;
wall = tilemap[ob->tilex][ob->tiley];
if ((wall & 0x4000) && (wall & 0x8000))
{maskedwallobj_t * mw;
mw=maskobjlist[wall&0x3ff];
if (mw->flags&MW_NONDOGBLOCKING)
return;
}
ob->temp2 = DOGMODERISE;
if ((pstate->player == 1) || (pstate->player == 3))
SD_PlaySoundRTP(SD_DOGWOMANSND,ob->x, ob->y);
else
SD_PlaySoundRTP(SD_DOGMANSND,ob->x, ob->y);
ResetWeapons(ob);
if (ob->state->condition & SF_DOGSTATE)
{
NewState(ob,&s_player);
pstate->attackframe = pstate->weaponframe = pstate->batblast = 0;
}
}
else if (ob->flags & FL_SHROOMS)
{
ResetFocalWidth ();
SD_PlaySoundRTP(SD_LOSEMODESND,ob->x, ob->y);
}
else if (ob->flags & FL_FLEET)
SD_PlaySoundRTP(SD_LOSEMODESND,ob->x, ob->y);
ob->flags &= ~(FL_SHROOMS|FL_ELASTO|FL_FLEET|FL_GODMODE|FL_DOGMODE);
}
if (pstate->protectiontime)
{
pstate->protectiontime --;
if (pstate->protectiontime <= 0)
{
SD_PlaySoundRTP(SD_LOSEMODESND,ob->x, ob->y);
pstate->protectiontime = 0;
}
if (ob==player)
GM_UpdateBonus (pstate->protectiontime, false);
}
else
ob->flags &= ~(FL_BPV|FL_AV|FL_GASMASK);
}
/*
=============================
=
= CheckFlying
=
=============================
*/
void CheckFlying(objtype*ob,playertype *pstate)
{
if (pstate->buttonstate[bt_lookup] || CYBERLOOKUP)
{
ob->momentumz = -FLYINGZMOM;
}
if (pstate->buttonstate[bt_lookdown] || CYBERLOOKDOWN)
{
ob->momentumz = FLYINGZMOM;
}
/*
if (!M_ISDOOR(((ob->x + costable[ob->angle])>>16),
((ob->y - sintable[ob->angle])>>16)) &&
(pstate->buttonstate[bt_use]) &&
(!pstate->buttonheld[bt_use])
)
{
int op;
int dist;
dist=JETPACKTHRUST;
if (ob->z-dist<-15)
dist=ob->z+15;
if (dist>0)
{
op = FixedMul(GRAVITY,(dist<<16)) << 1;
ob->momentumz = -FixedSqrtHP(op);
SD_PlaySoundRTP(SD_FLYINGSND,ob->x,ob->y);
}
}
*/
}
/*
=============================
=
= CheckTemp2Codes
=
=============================
*/
#define IN_AIR(ob) \
(!((ob->z == nominalheight) || \
(IsPlatform(ob->tilex,ob->tiley)) || \
(DiskAt(ob->tilex,ob->tiley)) \
) \
) \
void CheckTemp2Codes(objtype *ob,playertype *pstate)
{
int pitheight;
int godheight;
int dogheight;
int height;
int oldz;
int destheightoffset;
pitheight = maxheight - 8;
height = ob->z + pstate->playerheight;
dogheight = ob->z + DOGOFFSET;
godheight = ob->z + GODOFFSET;
//SoftError("\nheightoffset: %d, temp2: %d",pstate->heightoffset,ob->temp2);
if (!((ob->temp2 == PITFALL) || (ob->temp2 == PITRISE)))
{
oldz = ob->z;
//SoftError("\n zmom %d, oldz %d, newz %d",ob->momentumz,oldz,ob->z);
if (ob->flags & FL_FLEET)
{
if (IN_AIR(ob))
pstate->heightoffset = FixedMulShift(0x4000,sintable[(oldpolltime<<6)&2047],28);
ob->z += ((ob->momentumz+0x8000)>>16);
ob->momentumz = 0;
}
else
{
ob->z += (ob->momentumz>>16);
ob->momentumz += GRAVITY;
}
if (ob->z >= nominalheight)
{
ob->z = nominalheight;
ob->momentumz = 0;
//if (platform == nominalheight)
//{//ob->temp2 = 0;
//ob->momentumz = 0;
if ((oldz < nominalheight) && (!(ob->flags & FL_RIDING)))
{
SD_PlaySoundRTP(SD_PLAYERLANDSND,ob->x,ob->y);
}
if (!(ob->flags & FL_ELASTO))
ob->flags &= ~FL_NOFRICTION;
// }
}
else if (height < 1)
{
ob->momentumz = 0;
ob->z = 1-pstate->playerheight;
}
switch (ob->temp2)
{case RENORMALIZE:
pstate->heightoffset --;
if (ob->flags & FL_DOGMODE)
destheightoffset = DOGOFFSET-pstate->playerheight;
else
destheightoffset = 0;
if (pstate->heightoffset <= destheightoffset)
{
ob->temp2 = 0;
pstate->heightoffset = 0;
}
pstate->oldheightoffset = pstate->heightoffset;
break;
case COLUMNCRUSH:
pstate->heightoffset += 4;
if (pstate->heightoffset >= 30)
pstate->heightoffset = 30;
pstate->oldheightoffset = pstate->heightoffset;
break;
case GODMODERISE:
pstate->heightoffset --;
pstate->oldheightoffset = pstate->heightoffset;
if ((height+pstate->heightoffset) <= godheight)
{
ob->temp2 = 0;
pstate->poweruptime = POWERUPTICS;
}
break;
case GODMODEFALL:
pstate->heightoffset ++;
pstate->oldheightoffset = pstate->heightoffset;
SetPlayerHorizon(pstate,NORMALYZANGLE);
if (pstate->heightoffset >= 0)
{
ob->temp2 = 0;
ob->flags &= ~FL_GODMODE;
SetNormalHorizon(ob);
}
break;
case DOGMODERISE:
pstate->heightoffset --;
pstate->oldheightoffset = pstate->heightoffset;
SetPlayerHorizon(pstate,NORMALYZANGLE);
if (pstate->heightoffset <= 0)
{
ob->temp2 = 0;
ob->flags &= ~FL_DOGMODE;
SetNormalHorizon(ob);
}
break;
case DOGMODEFALL:
pstate->heightoffset ++;
pstate->oldheightoffset = pstate->heightoffset;
if (pstate->heightoffset >= (DOGOFFSET-pstate->playerheight))
{
ob->temp2 = 0;
pstate->poweruptime = POWERUPTICS;
}
break;
case STEPUP:
//Debug("\n\n heightoffset adjusted from %d to %d",
// pstate->heightoffset,pstate->heightoffset - STEPADJUST);
pstate->heightoffset -= STEPADJUST;
if (pstate->heightoffset <= pstate->oldheightoffset)
{ob->temp2 = 0;
//Debug("\n done adjusting heightoffset");
pstate->heightoffset = pstate->oldheightoffset;
}
break;
case STEPDOWN:
pstate->heightoffset += STEPADJUST;
if (pstate->heightoffset >= pstate->oldheightoffset)
{ob->temp2 = 0;
pstate->heightoffset = pstate->oldheightoffset;
}
break;
case 0:
if (!((ob->flags & FL_FLEET) ||
(ob->flags & FL_DOGMODE) ||
(ob->flags & FL_GODMODE)
)
)
pstate->heightoffset = 0;
break;
}
}
else if (ob->temp2 == PITFALL)
{
if (ob->z != pitheight)
{
ob->z += (ob->momentumz>>16);
ob->momentumz += GRAVITY;
if (ob->z >= pitheight)
{
ob->z = pitheight;
ob->momentumz = 0;
if (!(ob->flags & FL_DYING))
{DamageThing(ob,10);
Collision(ob,(objtype*)NULL,0,0);
M_CheckPlayerKilled(ob);
}
}
}
else if (ob->momentumx || ob->momentumy)
{
ob->temp2 = PITRISE;
ob->momentumz = -2;
}
}
else if (ob->temp2 == PITRISE)
{ob->z += ob->momentumz;
if (ob->z <= nominalheight)
{ob->z = nominalheight;
ob->temp2 = 0;
ob->momentumz = 0;
if (pstate->heightoffset)
ob->temp2 = RENORMALIZE;
}
}
}
/*
=============================
=
= CheckRemoteRecording
=
=============================
*/
void CheckRemoteRecording(objtype *ob,playertype *pstate)
{
if (networkgame==true)
{
if ( (pstate->buttonstate[bt_recordsound]) &&
(!pstate->buttonheld[bt_recordsound])
)
{
if (SD_RecordingActive()==false)
{
SD_SetRecordingActive ();
PlayerRecording=ob->dirchoosetime;
if (ob==player)
{
SD_StartRecordingSound();
UpdateClientControls();
}
}
}
else if ( (pstate->buttonheld[bt_recordsound]) &&
(!pstate->buttonstate[bt_recordsound])
)
{
if (SD_RecordingActive()==true)
{
if (ob->dirchoosetime==PlayerRecording)
{
if (ob==player)
SD_StopRecordingSound();
SD_ClearRecordingActive();
PlayerRecording=-1;
UpdateClientControls();
}
}
}
}
}
/*
=============================
=
= CheckPlayerSpecials
=
=============================
*/
void CheckPlayerSpecials(objtype * ob)
{
playertype * pstate;
M_LINKSTATE(ob,pstate);
// Check for recording of sound
CheckRemoteRecording(ob,pstate);
CheckTemp2Codes(ob,pstate);
if (ob->flags & FL_DYING)
return;
CheckSpecialSounds(ob,pstate);
CheckProtectionsAndPowerups(ob,pstate);
}
#if (SHAREWARE == 0)
/*
===============
=
= T_DogUse
=
===============
*/
void T_DogUse (objtype *ob)
{
attack_t *cur;
playertype *pstate;
statetype *oldstate;
M_LINKSTATE(ob,pstate);
Thrust(ob);
oldstate = ob->state;
CheckPlayerSpecials(ob);
if (ob->state != oldstate)
{
return;
}
//Commented out until we find if it's valid
/*
if (!ob->ticcount)
{if ( pstate->buttonstate[bt_use] && !pstate->buttonheld[bt_use] )
pstate->buttonstate[bt_use] = false;
}
*/
if (pstate->attackframe >= DOGSCRATCH.numattacks)
Error("\n attackframe %d for DOGSCRATCH gt numattacks %d",
pstate->attackframe,DOGSCRATCH.numattacks
);
cur = &(DOGSCRATCH.attackinfo[pstate->attackframe]);
if (! pstate->attackcount)
{switch (cur->attack)
{case reset:
{
NewState(ob,&s_dogwait);
pstate->attackframe = pstate->weaponframe = pstate->batblast = 0;
return;
}
break;
case at_pulltrigger:
pstate->buttonheld[bt_use]=false;
Cmd_Use(ob);
break;
default:
break;
}
pstate->attackframe++;
cur = &(DOGSCRATCH.attackinfo[pstate->attackframe]);
pstate->weaponframe = cur->frame;
pstate->attackcount = cur->mtics;
}
else
pstate->attackcount --;
}
/*
===============
=
= T_DogLick
=
===============
*/
void T_DogLick (objtype *ob)
{
attack_t *cur;
playertype *pstate;
statetype *oldstate;
M_LINKSTATE(ob,pstate);
Thrust(ob);
oldstate = ob->state;
CheckPlayerSpecials(ob);
if (ob->state != oldstate)
{
return;
}
//Commented out until we find if it's valid
/*
if (!ob->ticcount)
{if ( pstate->buttonstate[bt_use] && !pstate->buttonheld[bt_use] )
pstate->buttonstate[bt_use] = false;
}
*/
if (pstate->attackframe >= DOGLICK.numattacks)
Error("\n attackframe %d for DOGLICK gt numattacks %d",
pstate->attackframe,DOGLICK.numattacks
);
cur = &(DOGLICK.attackinfo[pstate->attackframe]);
if (! pstate->attackcount)
{if (cur->attack == reset)
{
NewState(ob,&s_serialdog);
pstate->attackframe = pstate->weaponframe = 0;
return;
}
pstate->attackframe++;
cur = &(DOGLICK.attackinfo[pstate->attackframe]);
pstate->weaponframe = cur->frame;
pstate->attackcount = cur->mtics;
}
else
pstate->attackcount --;
// if ( playerstate.buttonstate[bt_attack] && (!playerstate.buttonheld[bt_attack]) && (!W_CHANGE))
// Cmd_Fire (ob);
}
#endif
void T_DeadWait(objtype*ob)
{
playertype *pstate;
M_LINKSTATE(ob,pstate);
if ((ob->flags & FL_DESIGNATED) && (gamestate.battlemode == battle_CaptureTheTriad))
{int otherteam = (pstate->team ^ 1);
ob->flags &= ~FL_DESIGNATED;
UpdateKills = true;
SpawnStatic(TEAM[otherteam].tilex,TEAM[otherteam].tiley,stat_collector,9);
LASTSTAT->flags |= FL_COLORED;
LASTSTAT->hitpoints = otherteam;
LASTSTAT->flags |= FL_ABP;
MakeStatActive(LASTSTAT);
}
//ob->momentumx=0;
//ob->momentumy=0;
if (pstate->heightoffset<36)
{pstate->heightoffset++;
pstate->oldheightoffset = pstate->heightoffset;
}
if (ob==player)
{
UpdateLightLevel(player->areanumber);
if ((pstate->falling==true) || (ob->momentumz==0))
{
if (BATTLEMODE)
playerdead=true;
else
playstate = ex_died;
}
}
/*
if (BATTLEMODE)
{
objtype * killer=(objtype *)ob->target;
dx = killer->x - ob->x;
dy = ob->y - killer->y;
if (dx && dy)
ob->angle = atan2_appx (dx,dy);
}
*/
//CheckPlayerSpecials(ob);
}
/*
===============
=
= T_Player
=
===============
*/
void T_Player (objtype *ob)
{
playertype *pstate;
statetype *oldstate;
#if (SHAREWARE == 0)
int eluder;
#endif
M_LINKSTATE(ob,pstate);
#if (SHAREWARE == 0)
eluder = ((pstate->weapon == wp_dog) && gamestate.SpawnEluder);
#endif
oldstate = ob->state;
if (ob->flags&FL_DYING)
{
CheckPlayerSpecials(ob);
PlayerMove(ob);
if (
(pstate->falling==true) ||
(
(!ob->momentumx) &&
(!ob->momentumy) &&
(!ob->momentumz) &&
(!ob->state->tictime)
)
)
{
KillActor(ob);
if (ob->state == &s_remoteguts12)
NewState(ob,&s_gutwait);
else
NewState(ob,&s_deadwait);
}
return;
}
Thrust(ob);
if (ob->flags & FL_DYING)
return;
oldstate = ob->state;
CheckPlayerSpecials(ob);
if (ob->state != oldstate)
{
if (ob->flags & FL_DYING)
return;
}
if (!(ob->flags & FL_PAIN))
{if (!(ob->state->condition & SF_DOGSTATE))
{if ((ob->momentumx || ob->momentumy) && (ob->state->condition != SF_DOWN))
NewState(ob,&s_remotemove1);
else if (NOMOM && (ob->state != &s_player))
NewState(ob,&s_player);
}
else if (NOMOM
#if (SHAREWARE == 0)
&& (ob->state != &s_dogwait)
#endif
)
NewState(ob,ob->state);
}
else if (!ob->ticcount)
{if (!(ob->state->condition & SF_DOGSTATE))
NewState(ob,&s_player);
ob->flags &= ~FL_PAIN;
}
if (ob->flags & FL_DIDTAG)
{ob->flags &= ~FL_DIDTAG;
pstate->weapondowntics = (144 - TAGHANDHEIGHT)/GMOVE;
}
CheckWeaponStates(ob);
if (ARMED(ob->dirchoosetime)
//(gamestate.battlemode != battle_Tag)
)
{
if (pstate->weapondowntics == 1) // change to up; during change, up and down
// are never zero at the same time
{
pstate->weapondowntics = 0;
pstate->weaponframe = pstate->attackframe = 0;
if (pstate->NETCAPTURED == -1)
{
pstate->weaponuptics = FREE.screenheight/GMOVE;
pstate->weaponheight = pstate->weaponuptics*GMOVE ;
pstate->NETCAPTURED = 1;
// return;
}
else if (pstate->NETCAPTURED == -2)
{
pstate->weaponuptics = WEAPONS[pstate->weapon].screenheight/GMOVE;
pstate->weaponheight = pstate->weaponuptics*GMOVE ;
pstate->NETCAPTURED = 0;
//return;
}
else
{
pstate->weaponuptics = WEAPONS[pstate->new_weapon].screenheight/GMOVE;
pstate->weapon = pstate->new_weapon;
pstate->weaponheight = pstate->weaponuptics*GMOVE ;
}
}
else
CheckWeaponChange (ob);
}
else if (gamestate.battlemode == battle_Hunter)
{
if (pstate->weapondowntics == 1)
{
pstate->weapondowntics = 0;
pstate->weaponframe = pstate->attackframe = pstate->batblast = 0;
pstate->weapon = pstate->new_weapon;
}
}
// if ( pstate->buttonstate[bt_use] && (!W_CHANGE(pstate)) )
if ( pstate->buttonstate[bt_use] )
Cmd_Use (ob);
if (W_CHANGE(pstate))
return;
if ((!ARMED(ob->dirchoosetime))
#if (SHAREWARE == 0)
&& (pstate->weapon != wp_dog)
#endif
)
return;
if (pstate->buttonstate[bt_attack])
{
#if (SHAREWARE == 0)
if (eluder)
Cmd_Fire(ob);
else if ((pstate->weapon == wp_bat) ||
(pstate->weapon == wp_dog)
)
{
int oldblast=pstate->batblast;
pstate->batblast ++;
if (pstate->weapon==wp_bat)
{
if (pstate->batblast == 20)
SD_PlaySoundRTP(SD_EXCALIBUILDSND,ob->x,ob->y);
}
else
{
if ((pstate->batblast>>4)!=(oldblast>>4))
{
int handle;
handle=SD_PlaySoundRTP(SD_DOGMODEPREPBLASTSND,ob->x,ob->y);
SD_SetSoundPitch(handle,-(BBTIME<<3)+(pstate->batblast<<3));
}
}
if (pstate->batblast < BBTIME)
return;
if (pstate->weapon == wp_bat)
SD_PlaySoundRTP(SD_EXCALIBLASTSND,ob->x,ob->y);
else
SD_PlaySoundRTP(SD_DOGMODEBLASTSND,ob->x,ob->y);
}
if ((pstate->weapon != wp_split) || (!pstate->buttonheld[bt_attack]))
#endif
// if (!pstate->buttonheld[bt_attack])
//#endif
{
#if (SHAREWARE == 0)
if (pstate->weapon == wp_kes)
SD_PlaySoundRTP(SD_GRAVBUILDSND,ob->x,ob->y);
#endif
Cmd_Fire (ob);
}
}
#if (SHAREWARE == 0)
else if (
((pstate->weapon == wp_bat) ||
((pstate->weapon == wp_dog) && (!eluder))
) &&
(pstate->buttonheld[bt_attack])
)
{
if (pstate->weapon == wp_bat)
SD_StopSound(SD_EXCALIBUILDSND);
pstate->batblast = 0;
Cmd_Fire(ob);
}
#endif
}