avp/3dc/avp/Player.c

2184 lines
62 KiB
C
Raw Normal View History

/* KJL 16:23:20 10/25/96 - I'm moved all the weapon stuff to the newly created weapon.c,
so player.c is looking a bit bare at the moment. */
#include "3dc.h"
#include "module.h"
#include "inline.h"
#include "stratdef.h"
#include "gamedef.h"
#include "bh_types.h"
#include "inventry.h"
#include "gameplat.h"
#include "dynblock.h"
#include "dynamics.h"
#include "comp_shp.h"
#include "weapons.h"
#include "vision.h"
#include "pheromon.h"
#include "avpview.h"
#include "particle.h"
#include "scream.h"
#include "savegame.h"
#if SupportWindows95
#include "rebmenus.hpp"
#endif
#define UseLocalAssert Yes
#include "ourasert.h"
#include "psnd.h"
#include "psndplat.h"
/* for win 95 net support */
#if SupportWindows95
#include "pldnet.h"
#include "pldghost.h"
#include "dp_func.h"
#endif
#include "ShowCmds.h"
#include "BonusAbilities.h"
#define PLAYER_HMODEL 0
/*KJL****************************************************************************************
* G L O B A L S *
****************************************************************************************KJL*/
VECTORCH PlayerStartLocation;
MATRIXCH PlayerStartMat;
extern int NormalFrameTime;
extern ACTIVESOUNDSAMPLE ActiveSounds[];
extern int PlayerDamagedOverlayIntensity;
extern int playerNoise;
extern int predHUDSoundHandle;
extern int predOVision_SoundHandle;
extern int AIModuleArraySize;
int GimmeChargeCalls;
int HtoHStrikes;
int CurrentLightAtPlayer;
int TauntSoundPlayed;
int TrickleCharge=9000;
int CloakDrain=12000;
int CloakThreshold=(5*ONE_FIXED);
int CloakPowerOnDrain=(2*ONE_FIXED);
extern DPID myNetworkKillerId;
extern DPID myIgniterId;
extern int MyHitBodyPartId;
extern HMODELCONTROLLER PlayersWeaponHModelController;
extern SECTION_DATA *PWMFSDP; /* PlayersWeaponMuzzleFlashSectionDataPointer */
/*KJL****************************************************************************************
* P R O T O T Y P E S *
****************************************************************************************KJL*/
void InitPlayer(STRATEGYBLOCK* sbPtr, int sb_type);
void MaintainPlayer(void);
void PlayerIsDamaged(STRATEGYBLOCK *sbPtr, DAMAGE_PROFILE *damage, int multiplier,VECTORCH* incoming);
static void PlayerIsDead(DAMAGE_PROFILE *damage,int multiplier,VECTORCH* incoming);
extern int LightIntensityAtPoint(VECTORCH *pointPtr);
extern SECTION * GetNamedHierarchyFromLibrary(const char * rif_name, const char * hier_name);
extern int SlotForThisWeapon(enum WEAPON_ID weaponID);
extern void PointAlert(int level, VECTORCH *point);
extern void RemoveAllThisPlayersDiscs(void);
void ShowAdjacencies(void);
extern int ShowAdj;
/*KJL****************************************************************************************
* F U N C T I O N S *
****************************************************************************************KJL*/
PLAYER_STATUS* PlayerStatusPtr = NULL;
static PLAYER_STATUS PlayerStatusBlock;
int ShowPredoStats=0;
int Observer=0;
/* Patrick 22/8/97------------------------------------------------
Cloaking stuff
------------------------------------------------------------------*/
void InitPlayerCloakingSystem(void);
static void DoPlayerCloakingSystem(void);
void InitPlayer(STRATEGYBLOCK* sbPtr, int sb_type)
{
/*KJL**************************************************************************************
* InitPlayer() was written by me. It attaches the extra player data to the strategy block *
* and fills in some initial values. *
**************************************************************************************KJL*/
SECTION *root_section;
PLAYER_STATUS *psPtr = &PlayerStatusBlock;
GLOBALASSERT(psPtr);
GLOBALASSERT(sbPtr);
// set up our global
PlayerStatusPtr = psPtr;
sbPtr->I_SBtype = sb_type;
sbPtr->SBdataptr = (void*)psPtr;
InitialisePlayersInventory(psPtr);
/* Initialise Player's stats */
{
NPC_DATA *NpcData;
NPC_TYPES PlayerType;
switch(AvP.PlayerType)
{
case(I_Marine):
{
switch (AvP.Difficulty) {
case I_Easy:
PlayerType=I_PC_Marine_Easy;
break;
default:
case I_Medium:
PlayerType=I_PC_Marine_Medium;
break;
case I_Hard:
PlayerType=I_PC_Marine_Hard;
break;
case I_Impossible:
PlayerType=I_PC_Marine_Impossible;
break;
}
#if 0 //this hmodel isn't being set up for the moment - Richard
root_section=GetNamedHierarchyFromLibrary("hnpcmarine","Template");
if (!root_section) {
GLOBALASSERT(0);
/* Sorry, there's just no bouncing back from this one. Fix it. */
return;
}
#if PLAYER_HMODEL
Create_HModel(&psPtr->HModelController,root_section);
InitHModelSequence(&psPtr->HModelController,0,0,ONE_FIXED);
#endif
/* Doesn't matter what the sequence is... */
#endif
break;
}
case(I_Predator):
{
switch (AvP.Difficulty) {
case I_Easy:
PlayerType=I_PC_Predator_Easy;
break;
default:
case I_Medium:
PlayerType=I_PC_Predator_Medium;
break;
case I_Hard:
PlayerType=I_PC_Predator_Hard;
break;
case I_Impossible:
PlayerType=I_PC_Predator_Impossible;
break;
}
#if 0 //this hmodel isn't being set up for the moment - Richard
root_section=GetNamedHierarchyFromLibrary("hnpcpredator","Template");
if (!root_section) {
GLOBALASSERT(0);
/* Sorry, there's just no bouncing back from this one. Fix it. */
return;
}
#if PLAYER_HMODEL
Create_HModel(&psPtr->HModelController,root_section);
InitHModelSequence(&psPtr->HModelController,0,0,ONE_FIXED);
#endif
/* Doesn't matter what the sequence is... */
#endif
break;
}
case(I_Alien):
{
switch (AvP.Difficulty) {
case I_Easy:
PlayerType=I_PC_Alien_Easy;
break;
default:
case I_Medium:
PlayerType=I_PC_Alien_Medium;
break;
case I_Hard:
PlayerType=I_PC_Alien_Hard;
break;
case I_Impossible:
PlayerType=I_PC_Alien_Impossible;
break;
}
#if 0 //this hmodel isn't being set up for the moment - Richard
root_section=GetNamedHierarchyFromLibrary("hnpcalien","alien");
if (!root_section) {
GLOBALASSERT(0);
/* Sorry, there's just no bouncing back from this one. Fix it. */
return;
}
#if PLAYER_HMODEL
Create_HModel(&psPtr->HModelController,root_section);
InitHModelSequence(&psPtr->HModelController,0,0,ONE_FIXED);
#endif
/* Doesn't matter what the sequence is... */
#endif
break;
}
default:
{
LOCALASSERT(1==0);
break;
}
}
NpcData=GetThisNpcData(PlayerType);
LOCALASSERT(NpcData);
sbPtr->SBDamageBlock.Health=NpcData->StartingStats.Health<<ONE_FIXED_SHIFT;
sbPtr->SBDamageBlock.Armour=NpcData->StartingStats.Armour<<ONE_FIXED_SHIFT;
sbPtr->SBDamageBlock.SB_H_flags=NpcData->StartingStats.SB_H_flags;
sbPtr->SBDamageBlock.IsOnFire=0;
//{
// int *nptr,i;
// nptr=(int *)sbPtr->SBname;
// for (i=0; i<(SB_NAME_LENGTH>>2); i++) {
// *nptr=FastRandom();
// nptr++;
// }
// sbPtr->SBname[SB_NAME_LENGTH-1]=3; /* Just to make sure... */
//}
AssignNewSBName(sbPtr);
}
//psPtr->Health=STARTOFGAME_MARINE_HEALTH;
psPtr->Energy=STARTOFGAME_MARINE_ENERGY;
//psPtr->Armour=STARTOFGAME_MARINE_ARMOUR;
psPtr->Encumberance.MovementMultiple=ONE_FIXED;
psPtr->Encumberance.TurningMultiple=ONE_FIXED;
psPtr->Encumberance.JumpingMultiple=ONE_FIXED;
psPtr->Encumberance.CanCrouch=1;
psPtr->Encumberance.CanRun=1;
psPtr->incidentFlag=0;
psPtr->incidentTimer=0;
/* CDF 16/9/97 Now, those health and armour stats are those of the last cycle. */
psPtr->Health=sbPtr->SBDamageBlock.Health;
psPtr->Armour=sbPtr->SBDamageBlock.Armour;
psPtr->IsAlive = 1;
psPtr->IHaveAPlacedAutogun = 0;
psPtr->MyFaceHugger=NULL;
psPtr->MyCorpse=NULL;
psPtr->tauntTimer=0;
TauntSoundPlayed=0;
psPtr->fireTimer=0;
psPtr->invulnerabilityTimer=0;
/* Better safe than sorry. */
psPtr->soundHandle=SOUND_NOACTIVEINDEX;
psPtr->soundHandle3=SOUND_NOACTIVEINDEX;
psPtr->soundHandle4=SOUND_NOACTIVEINDEX;
psPtr->soundHandle5=SOUND_NOACTIVEINDEX;
psPtr->soundHandleForPredatorCloakDamaged=SOUND_NOACTIVEINDEX;
InitPlayerCloakingSystem();/* Patrick 22/8/97 : Cloaking stuff */
/* KJL 12:06:01 11/14/96 - allocate dynamics block & fill from template */
sbPtr->DynPtr = AllocateDynamicsBlock(DYNAMICS_TEMPLATE_MARINE_PLAYER);
/* for the time being get world position and orientation from the displayblock */
{
DISPLAYBLOCK *dPtr = sbPtr->SBdptr;
DYNAMICSBLOCK *dynPtr = sbPtr->DynPtr;
GLOBALASSERT(dPtr);
GLOBALASSERT(dynPtr);
dynPtr->Position = PlayerStartLocation;
dynPtr->OrientMat = PlayerStartMat;
MatrixToEuler(&dynPtr->OrientMat,&dynPtr->OrientEuler);
//dynPtr->OrientEuler = dPtr->ObEuler;
dynPtr->PrevPosition = dynPtr->Position;
dynPtr->PrevOrientMat = dynPtr->OrientMat;
dynPtr->PrevOrientEuler = dynPtr->OrientEuler;
/* let alien walk on walls & ceiling */
if (AvP.PlayerType == I_Alien)
{
dynPtr->ToppleForce = TOPPLE_FORCE_ALIEN;
}
/* KJL 10:56:57 11/24/97 - set ObRadius to a sensible value */
dPtr->ObRadius = 1200;
/*
if (AvP.PlayerType == I_Alien) sbPtr->I_SBtype = I_BehaviourAlienPlayer;
if (AvP.PlayerType == I_Predator) sbPtr->I_SBtype = I_BehaviourPredatorPlayer;*/
/* KJL 18:30:09 11/11/98 - datum used for falling damage */
{
extern int PlayersMaxHeightWhilstNotInContactWithGround;
PlayersMaxHeightWhilstNotInContactWithGround=dynPtr->Position.vy;
}
}
/* zero inertia values */
psPtr->ForwardInertia=0;
psPtr->StrafeInertia=0;
psPtr->TurnInertia=0;
psPtr->IsMovingInWater = 0;
PlayerDamagedOverlayIntensity = 0;
/* a little addition by patrick */
InitPlayerMovementData(sbPtr);
/* security clearance */
psPtr->securityClearances = 0;
/* thou art mortal */
psPtr->IsImmortal = 0;
if (AvP.Network==I_No_Network)
{
SoundSys_FadeIn();
}
else
{
SoundSys_ResetFadeLevel();
}
//restore the number of saves allowed
ResetNumberOfSaves();
#if SupportWindows95
//choosing a start position now occurs later on
// if(AvP.Network!=I_No_Network) TeleportNetPlayerToAStartingPosition(sbPtr, 1);
#endif
}
void ChangeToMarine()
{
if(AvP.Network!=I_No_Network)
{
AvP.PlayerType=I_Marine;
NetPlayerRespawn(Player->ObStrategyBlock);
InitPlayerMovementData(Player->ObStrategyBlock);
Player->ObStrategyBlock->DynPtr->ToppleForce=TOPPLE_FORCE_NONE;
netGameData.myCharacterType=netGameData.myNextCharacterType=NGCT_Marine;
//reorient the player
{
EULER e;
MatrixToEuler(&Player->ObStrategyBlock->DynPtr->OrientMat,&e);
e.EulerX=0;
e.EulerZ=0;
CreateEulerMatrix(&e,&Player->ObStrategyBlock->DynPtr->OrientMat);
TransposeMatrixCH(&Player->ObStrategyBlock->DynPtr->OrientMat);
Player->ObStrategyBlock->DynPtr->UseStandardGravity=1;
}
/* CDF 15/3/99, delete all discs... */
RemoveAllThisPlayersDiscs();
}
}
void ChangeToAlien()
{
if(AvP.Network!=I_No_Network)
{
AvP.PlayerType=I_Alien;
NetPlayerRespawn(Player->ObStrategyBlock);
InitPlayerMovementData(Player->ObStrategyBlock);
Player->ObStrategyBlock->DynPtr->ToppleForce=TOPPLE_FORCE_ALIEN;
netGameData.myCharacterType=netGameData.myNextCharacterType=NGCT_Alien;
/* CDF 15/3/99, delete all discs... */
RemoveAllThisPlayersDiscs();
}
}
void ChangeToPredator()
{
if(AvP.Network!=I_No_Network)
{
AvP.PlayerType=I_Predator;
NetPlayerRespawn(Player->ObStrategyBlock);
InitPlayerMovementData(Player->ObStrategyBlock);
Player->ObStrategyBlock->DynPtr->ToppleForce=TOPPLE_FORCE_NONE;
netGameData.myCharacterType=netGameData.myNextCharacterType=NGCT_Predator;
//reorient the player
{
EULER e;
MatrixToEuler(&Player->ObStrategyBlock->DynPtr->OrientMat,&e);
e.EulerX=0;
e.EulerZ=0;
CreateEulerMatrix(&e,&Player->ObStrategyBlock->DynPtr->OrientMat);
TransposeMatrixCH(&Player->ObStrategyBlock->DynPtr->OrientMat);
Player->ObStrategyBlock->DynPtr->UseStandardGravity=1;
}
/* CDF 15/3/99, delete all discs... */
RemoveAllThisPlayersDiscs();
}
}
void MaintainPlayer(void)
{
int rand = FastRandom();
PLAYER_STATUS *playerStatusPtr= (PLAYER_STATUS *) (Player->ObStrategyBlock->SBdataptr);
if (playerStatusPtr->IsAlive)
{
MaintainPlayersInventory();
}
if (ShowAdj) {
ShowAdjacencies();
}
/* Set here, as first point. */
playerNoise=0;
/* Incident handling. */
playerStatusPtr->incidentFlag=0;
playerStatusPtr->incidentTimer-=NormalFrameTime;
if (playerStatusPtr->incidentTimer<0) {
playerStatusPtr->incidentFlag=1;
playerStatusPtr->incidentTimer=32767+(FastRandom()&65535);
}
/* CDF 9/6/98 - I can't believe this isn't done!!! */
Player->ObStrategyBlock->containingModule = playerPherModule;
if (Observer) {
textprint("Observer Mode...\n");
}
textprint("HtoH Strikes %d\n",HtoHStrikes);
DoPlayerCloakingSystem();/* Patrick 22/8/97 : Cloaking stuff */
// HandlePredatorVisionModes();
CurrentLightAtPlayer=LightIntensityAtPoint(&Player->ObStrategyBlock->DynPtr->Position);
#if 1
textprint("PlayerLight %d\n",CurrentLightAtPlayer);
#endif
#if SupportWindows95
#if 0//UseRebMenus
if(playerStatusPtr->Mvt_InputRequests.Flags.Rqst_PauseGame)
{
REBMENUS_ProcessPauseRequest();
}
#else
if(AvP.Network==I_No_Network)
{
#if 1
if(playerStatusPtr->Mvt_InputRequests.Flags.Rqst_PauseGame)
{
// go to start menu
AvP.MainLoopRunning = 0;
}
#endif
}
else
if(playerStatusPtr->Mvt_InputRequests.Flags.Rqst_PauseGame)
{
if (AvP.Network == I_Host)
{
TransmitEndOfGameNetMsg();
netGameData.myGameState = NGS_EndGame;
}
else if (AvP.Network == I_Peer)
{
TransmitPlayerLeavingNetMsg();
netGameData.myGameState = NGS_Leaving;
}
// go to start menu
AvP.MainLoopRunning = 0;
}
#endif
#endif
//Update the player's invulnerabilty timer
if(playerStatusPtr->invulnerabilityTimer>0)
{
playerStatusPtr->invulnerabilityTimer-=NormalFrameTime;
if(playerStatusPtr->invulnerabilityTimer<=0)
{
playerStatusPtr->invulnerabilityTimer=0;
}
//lose invulnerability if player is firing
if(playerStatusPtr->Mvt_InputRequests.Flags.Rqst_FirePrimaryWeapon)
{
PLAYER_WEAPON_DATA *weaponPtr = &(playerStatusPtr->WeaponSlot[playerStatusPtr->SelectedWeaponSlot]);
if(weaponPtr->WeaponIDNumber!=WEAPON_PRED_MEDICOMP)
{
playerStatusPtr->invulnerabilityTimer=0;
}
}
if(playerStatusPtr->Mvt_InputRequests.Flags.Rqst_FireSecondaryWeapon)
{
//not many weapons have an offensive secondary fire
PLAYER_WEAPON_DATA *weaponPtr = &(playerStatusPtr->WeaponSlot[playerStatusPtr->SelectedWeaponSlot]);
if(weaponPtr->WeaponIDNumber == WEAPON_PULSERIFLE ||
weaponPtr->WeaponIDNumber == WEAPON_CUDGEL ||
weaponPtr->WeaponIDNumber == WEAPON_MARINE_PISTOL ||
weaponPtr->WeaponIDNumber == WEAPON_TWO_PISTOLS ||
weaponPtr->WeaponIDNumber == WEAPON_PRED_WRISTBLADE ||
weaponPtr->WeaponIDNumber == WEAPON_ALIEN_CLAW)
{
playerStatusPtr->invulnerabilityTimer=0;
}
}
}
if (AvP.DestructTimer>0) {
extern int NormalFrameTime;
AvP.DestructTimer-=NormalFrameTime;
if (AvP.DestructTimer<0) AvP.DestructTimer=0;
} else if (AvP.DestructTimer==0) {
// ...Destruct?
CauseDamageToObject(Player->ObStrategyBlock,&TemplateAmmo[AMMO_SADAR_TOW].MaxDamage[AvP.Difficulty], 25*ONE_FIXED,NULL);
// That'll learn 'em.
}
/* Take speed sample. */
{
int speed;
speed=Approximate3dMagnitude(&Player->ObStrategyBlock->DynPtr->LinVelocity);
CurrentGameStats_SpeedSample(speed,NormalFrameTime);
}
/* Is the player on fire? */
if (Player->ObStrategyBlock->SBDamageBlock.IsOnFire) {
myNetworkKillerId=myIgniterId;
CauseDamageToObject(Player->ObStrategyBlock,&firedamage,NormalFrameTime,NULL);
myNetworkKillerId=AVPDPNetID;
if (playerStatusPtr->soundHandle3!=SOUND_NOACTIVEINDEX) {
if (ActiveSounds[playerStatusPtr->soundHandle3].soundIndex!=SID_FIRE) {
Sound_Stop(playerStatusPtr->soundHandle3);
Sound_Play(SID_FIRE,"dlev",&(Player->ObStrategyBlock->DynPtr->Position),&playerStatusPtr->soundHandle3,127);
} else {
Sound_Update3d(playerStatusPtr->soundHandle3,&(Player->ObStrategyBlock->DynPtr->Position));
}
} else if (playerStatusPtr->IsAlive) {
Sound_Play(SID_FIRE,"dlev",&(Player->ObStrategyBlock->DynPtr->Position),&playerStatusPtr->soundHandle3,127);
}
/* Put the fire out... */
#if 1
{
int speed;
/* Go out? */
speed=Approximate3dMagnitude(&Player->ObStrategyBlock->DynPtr->LinVelocity);
if (speed>22000) {
/* Jumping alien. */
playerStatusPtr->fireTimer-=(NormalFrameTime*6);
} else if (speed>15000) {
/* Running alien. */
playerStatusPtr->fireTimer-=(NormalFrameTime<<2);
} else {
/* Normal bloke. */
playerStatusPtr->fireTimer-=NormalFrameTime;
}
if(playerStatusPtr->invulnerabilityTimer>0)
{
//player is invulnerable, so put him out.
playerStatusPtr->fireTimer=0;
}
if (playerStatusPtr->fireTimer<=0) {
/* Go out. */
Player->ObStrategyBlock->SBDamageBlock.IsOnFire=0;
playerStatusPtr->fireTimer=0;
}
}
#else
if (playerStatusPtr->incidentFlag) {
int speed;
/* Go out? */
speed=Approximate3dMagnitude(&Player->ObStrategyBlock->DynPtr->LinVelocity);
if (speed>15000) {
/* Running alien. */
if ((FastRandom()&65535)<13107) {
Player->ObStrategyBlock->SBDamageBlock.IsOnFire=0;
}
} else {
/* Normal bloke. */
if ((FastRandom()&65535)<3000) {
Player->ObStrategyBlock->SBDamageBlock.IsOnFire=0;
}
}
}
#endif
} else {
if (playerStatusPtr->soundHandle3!=SOUND_NOACTIVEINDEX) {
Sound_Stop(playerStatusPtr->soundHandle3);
}
}
if (playerStatusPtr->IsMovingInWater)
{
#if 0
if (playerStatusPtr->soundHandle4==SOUND_NOACTIVEINDEX) {
switch (rand % 4) {
case 0:
Sound_Play(SID_SPLASH1,"dev",&(Player->ObStrategyBlock->DynPtr->Position),&playerStatusPtr->soundHandle4,127);
break;
case 1:
Sound_Play(SID_SPLASH2,"dev",&(Player->ObStrategyBlock->DynPtr->Position),&playerStatusPtr->soundHandle4,127);
break;
case 2:
Sound_Play(SID_SPLASH3,"dev",&(Player->ObStrategyBlock->DynPtr->Position),&playerStatusPtr->soundHandle4,127);
break;
default:
Sound_Play(SID_SPLASH4,"dev",&(Player->ObStrategyBlock->DynPtr->Position),&playerStatusPtr->soundHandle4,127);
break;
}
}
#else
/* KJL 19:07:57 25/05/98 - make a noise at most every 1/4 of a sec */
if (playerStatusPtr->soundHandle4<=0)
{
switch (rand&3)
{
case 0:
Sound_Play(SID_SPLASH1,"d",&(Player->ObStrategyBlock->DynPtr->Position));
break;
case 1:
Sound_Play(SID_SPLASH2,"d",&(Player->ObStrategyBlock->DynPtr->Position));
break;
case 2:
Sound_Play(SID_SPLASH3,"d",&(Player->ObStrategyBlock->DynPtr->Position));
break;
default:
Sound_Play(SID_SPLASH4,"d",&(Player->ObStrategyBlock->DynPtr->Position));
break;
}
playerStatusPtr->soundHandle4=16384;
}
else
{
playerStatusPtr->soundHandle4-=NormalFrameTime;
}
#endif
}
/* KJL 14:54:48 25/05/98 - reset water flag to zero for next frame */
playerStatusPtr->IsMovingInWater = 0;
/* Taunt effects. */
if (playerStatusPtr->tauntTimer) {
int ex,ey,ez;
playerNoise=1;
/* An actual noise, too, would probably be good. */
if (AvP.PlayerType==I_Alien) {
//if (playerStatusPtr->tauntTimer>(TAUNT_LENGTH>>1)) {
if (TauntSoundPlayed==0) {
/* That should make sure we don't get more than one. */
if (playerStatusPtr->soundHandle==SOUND_NOACTIVEINDEX) {
#if 0
Sound_Play(SID_ALIEN_SCREAM,"de",&(Player->ObStrategyBlock->DynPtr->Position),&playerStatusPtr->soundHandle);
#else
PlayAlienSound(0,ASC_Taunt,0,&playerStatusPtr->soundHandle,&(Player->ObStrategyBlock->DynPtr->Position));
if(AvP.Network!=I_No_Network) netGameData.myLastScream=ASC_Taunt;
#endif
TauntSoundPlayed=1;
}
}
/* Wave the head around? */
ex=0;
ey=0;
ez=0;
ex=MUL_FIXED(64,GetSin(((playerStatusPtr->tauntTimer>>6)&wrap360)));
ey=MUL_FIXED(128,GetSin(((playerStatusPtr->tauntTimer>>5)&wrap360)));
ez=MUL_FIXED(-64,GetSin(((playerStatusPtr->tauntTimer>>5)&wrap360)));
ex&=wrap360;
ey&=wrap360;
ez&=wrap360;
HeadOrientation.EulerX=ex;
HeadOrientation.EulerY=ey;
HeadOrientation.EulerZ=ez;
} else if (AvP.PlayerType==I_Marine) {
if (TauntSoundPlayed==0) {
/* That should make sure we don't get more than one. */
if (playerStatusPtr->soundHandle==SOUND_NOACTIVEINDEX) {
PlayMarineScream(0,SC_Taunt,0,&playerStatusPtr->soundHandle,NULL);
if(AvP.Network!=I_No_Network) netGameData.myLastScream=SC_Taunt;
TauntSoundPlayed=1;
}
}
} else if (AvP.PlayerType==I_Predator) {
if (TauntSoundPlayed==0) {
/* That should make sure we don't get more than one. */
if (playerStatusPtr->soundHandle==SOUND_NOACTIVEINDEX) {
PlayPredatorSound(0,PSC_Taunt,0,&playerStatusPtr->soundHandle,NULL);
if(AvP.Network!=I_No_Network) netGameData.myLastScream=PSC_Taunt;
TauntSoundPlayed=1;
}
}
} else {
GLOBALASSERT(0);
}
}
/* Decay alien superhealth. */
if (AvP.PlayerType==I_Alien) {
NPC_DATA *NpcData;
switch (AvP.Difficulty) {
case I_Easy:
NpcData=GetThisNpcData(I_PC_Alien_Easy);
break;
default:
case I_Medium:
NpcData=GetThisNpcData(I_PC_Alien_Medium);
break;
case I_Hard:
NpcData=GetThisNpcData(I_PC_Alien_Hard);
break;
case I_Impossible:
NpcData=GetThisNpcData(I_PC_Alien_Impossible);
break;
}
LOCALASSERT(NpcData);
if (Player->ObStrategyBlock->SBDamageBlock.Health>(NpcData->StartingStats.Health<<ONE_FIXED_SHIFT)) {
/* Decay health a bit. */
Player->ObStrategyBlock->SBDamageBlock.Health-=(NormalFrameTime);
if (Player->ObStrategyBlock->SBDamageBlock.Health<(NpcData->StartingStats.Health<<ONE_FIXED_SHIFT)) {
Player->ObStrategyBlock->SBDamageBlock.Health=NpcData->StartingStats.Health<<ONE_FIXED_SHIFT;
}
PlayerStatusPtr->Health=Player->ObStrategyBlock->SBDamageBlock.Health;
}
}
}
void PlayerIsDamaged(STRATEGYBLOCK *sbPtr, DAMAGE_PROFILE *damage, int multiplier,VECTORCH* incoming)
{
int rand = FastRandom();
int pitch = (rand & 255) - 128;
int deltaHealth;
int deltaArmour;
/* access the extra data hanging off the strategy block */
PLAYER_STATUS *playerStatusPtr= (PLAYER_STATUS *) (sbPtr->SBdataptr);
GLOBALASSERT(playerStatusPtr);
deltaHealth=playerStatusPtr->Health-sbPtr->SBDamageBlock.Health;
deltaArmour=playerStatusPtr->Armour-sbPtr->SBDamageBlock.Armour;
CurrentGameStats_DamageTaken(deltaHealth,deltaArmour);
/* Patrick 4/8/97--------------------------------------------------
A little hack-et to make the predator tougher in multiplayer games
------------------------------------------------------------------*/
//if((AvP.Network!=I_No_Network)&&(AvP.PlayerType==I_Predator)) damage>>=1;
/* ChrisF 16/9/97 No, predators are now... wait for it... tough. */
if (playerStatusPtr->IsAlive)
{
#if 0
damage <<= 16;
if (playerStatusPtr->Armour > 0)
{
if (playerStatusPtr->Armour >= damage/2)
{
playerStatusPtr->Armour -= damage/2;
playerStatusPtr->Health -= damage/4;
}
else
{
damage -= playerStatusPtr->Armour*2;
playerStatusPtr->Health -= playerStatusPtr->Armour/2 + damage;
playerStatusPtr->Armour = 0;
}
}
else
{
playerStatusPtr->Health -= damage;
}
#endif
{
int maxTilt = deltaHealth>>12;
int halfTilt = maxTilt/2;
if (maxTilt)
{
HeadOrientation.EulerX = (FastRandom()%maxTilt)-halfTilt;
HeadOrientation.EulerY = (FastRandom()%maxTilt)-halfTilt;
HeadOrientation.EulerZ = (FastRandom()%maxTilt)-halfTilt;
if (HeadOrientation.EulerX < 0) HeadOrientation.EulerX += 4096;
if (HeadOrientation.EulerY < 0) HeadOrientation.EulerY += 4096;
if (HeadOrientation.EulerZ < 0) HeadOrientation.EulerZ += 4096;
}
}
if ((playerStatusPtr->soundHandle==SOUND_NOACTIVEINDEX)&&(deltaHealth||deltaArmour)) {
switch (AvP.PlayerType)
{
case I_Alien:
{
if ((damage->Impact==0)
&&(damage->Cutting==0)
&&(damage->Penetrative==0)
&&(damage->Fire>0)
&&(damage->Electrical==0)
&&(damage->Acid==0)
) {
PlayAlienSound(0,ASC_PC_OnFire,pitch,&playerStatusPtr->soundHandle,NULL);
if(AvP.Network!=I_No_Network) netGameData.myLastScream=ASC_PC_OnFire;
} else {
PlayAlienSound(0,ASC_Scream_Hurt,pitch,&playerStatusPtr->soundHandle,NULL);
if(AvP.Network!=I_No_Network) netGameData.myLastScream=ASC_Scream_Hurt;
}
break;
}
case I_Marine:
{
if (damage->Id==AMMO_FACEHUGGER) {
PlayMarineScream(0,SC_Facehugged,pitch,&playerStatusPtr->soundHandle,NULL);
} else if (damage->Id==AMMO_FALLING_POSTMAX) {
PlayMarineScream(0,SC_Falling,pitch,&playerStatusPtr->soundHandle,NULL);
} else if ((damage->Impact==0)
&&(damage->Cutting==0)
&&(damage->Penetrative==0)
&&(damage->Fire==0)
&&(damage->Electrical==0)
&&(damage->Acid>0)
) {
PlayMarineScream(0,SC_Acid,pitch,&playerStatusPtr->soundHandle,NULL);
if(AvP.Network!=I_No_Network) netGameData.myLastScream=SC_Acid;
} else if ((damage->Impact==0)
&&(damage->Cutting==0)
&&(damage->Penetrative==0)
&&(damage->Fire>0)
&&(damage->Electrical==0)
&&(damage->Acid==0)
) {
PlayMarineScream(0,SC_PC_OnFire,pitch,&playerStatusPtr->soundHandle,NULL);
if(AvP.Network!=I_No_Network) netGameData.myLastScream=SC_PC_OnFire;
} else {
PlayMarineScream(0,SC_Pain,pitch,&playerStatusPtr->soundHandle,NULL);
if(AvP.Network!=I_No_Network) netGameData.myLastScream=SC_Pain;
}
break;
}
case I_Predator:
{
if (damage->Id==AMMO_FACEHUGGER) {
PlayPredatorSound(0,PSC_Facehugged,pitch,&playerStatusPtr->soundHandle,NULL);
} else if ((damage->Impact==0)
&&(damage->Cutting==0)
&&(damage->Penetrative==0)
&&(damage->Fire==0)
&&(damage->Electrical==0)
&&(damage->Acid>0)
) {
PlayPredatorSound(0,PSC_Acid,pitch,&playerStatusPtr->soundHandle,NULL);
if(AvP.Network!=I_No_Network) netGameData.myLastScream=PSC_Acid;
} else if ((damage->Impact==0)
&&(damage->Cutting==0)
&&(damage->Penetrative==0)
&&(damage->Fire>0)
&&(damage->Electrical==0)
&&(damage->Acid==0)
) {
PlayPredatorSound(0,PSC_PC_OnFire,pitch,&playerStatusPtr->soundHandle,NULL);
if(AvP.Network!=I_No_Network) netGameData.myLastScream=PSC_PC_OnFire;
} else {
PlayPredatorSound(0,PSC_Scream_Hurt,pitch,&playerStatusPtr->soundHandle,NULL);
if(AvP.Network!=I_No_Network) netGameData.myLastScream=PSC_Scream_Hurt;
}
break;
}
default:
{
break;
}
}
playerNoise=1;
/* Alert marines, pretty much whoever you are. */
if (AvP.PlayerType==I_Marine) {
PointAlert(3, &Player->ObStrategyBlock->DynPtr->Position);
} else {
#if 0
PointAlert(2, &Player->ObStrategyBlock->DynPtr->Position);
#endif
}
}
{
NPC_DATA *NpcData;
int scaled_DeltaHealth;
switch (AvP.PlayerType)
{
case I_Marine:
switch (AvP.Difficulty) {
case I_Easy:
NpcData=GetThisNpcData(I_PC_Marine_Easy);
break;
default:
case I_Medium:
NpcData=GetThisNpcData(I_PC_Marine_Medium);
break;
case I_Hard:
NpcData=GetThisNpcData(I_PC_Marine_Hard);
break;
case I_Impossible:
NpcData=GetThisNpcData(I_PC_Marine_Impossible);
break;
}
break;
case I_Alien:
switch (AvP.Difficulty) {
case I_Easy:
NpcData=GetThisNpcData(I_PC_Alien_Easy);
break;
default:
case I_Medium:
NpcData=GetThisNpcData(I_PC_Alien_Medium);
break;
case I_Hard:
NpcData=GetThisNpcData(I_PC_Alien_Hard);
break;
case I_Impossible:
NpcData=GetThisNpcData(I_PC_Alien_Impossible);
break;
}
break;
case I_Predator:
switch (AvP.Difficulty) {
case I_Easy:
NpcData=GetThisNpcData(I_PC_Predator_Easy);
break;
default:
case I_Medium:
NpcData=GetThisNpcData(I_PC_Predator_Medium);
break;
case I_Hard:
NpcData=GetThisNpcData(I_PC_Predator_Hard);
break;
case I_Impossible:
NpcData=GetThisNpcData(I_PC_Predator_Impossible);
break;
}
break;
default:
LOCALASSERT(0);
break;
}
/* Compute scaled deltaHealth... */
scaled_DeltaHealth=MUL_FIXED(deltaHealth,100);
scaled_DeltaHealth=DIV_FIXED(scaled_DeltaHealth,NpcData->StartingStats.Health);
if (scaled_DeltaHealth>PlayerDamagedOverlayIntensity)
{
PlayerDamagedOverlayIntensity=scaled_DeltaHealth;
}
}
if (deltaHealth>ONE_FIXED)
{
VECTORCH abovePosition = Global_VDB_Ptr->VDB_World;
abovePosition.vy-=1000;
switch (AvP.PlayerType)
{
case I_Alien:
MakeBloodExplosion(&Global_VDB_Ptr->VDB_World, 127, &abovePosition, deltaHealth/ONE_FIXED, PARTICLE_ALIEN_BLOOD);
break;
case I_Marine:
MakeBloodExplosion(&Global_VDB_Ptr->VDB_World, 127, &abovePosition, deltaHealth/ONE_FIXED, PARTICLE_HUMAN_BLOOD);
break;
case I_Predator:
MakeBloodExplosion(&Global_VDB_Ptr->VDB_World, 127, &abovePosition, deltaHealth/ONE_FIXED, PARTICLE_PREDATOR_BLOOD);
break;
}
}
if (sbPtr->SBDamageBlock.Health <= 0)
{
if (playerStatusPtr->IsImmortal) sbPtr->SBDamageBlock.Health=0;
else
{
PlayerIsDead(damage,multiplier,incoming);
}
}
playerStatusPtr->Health=sbPtr->SBDamageBlock.Health;
playerStatusPtr->Armour=sbPtr->SBDamageBlock.Armour;
}
}
extern EULER deathTargetOrientation;
extern int deathFadeLevel;
extern int weaponHandle;
static void PlayerIsDead(DAMAGE_PROFILE* damage,int multiplier,VECTORCH* incoming)
{
STRATEGYBLOCK *sbPtr = Player->ObStrategyBlock;
PLAYER_STATUS *playerStatusPtr= (PLAYER_STATUS *) (sbPtr->SBdataptr);
DYNAMICSBLOCK *dynPtr = sbPtr->DynPtr;
/* Stop pred hud sound. */
if(predHUDSoundHandle != SOUND_NOACTIVEINDEX) {
Sound_Stop(predHUDSoundHandle);
}
if(predOVision_SoundHandle != SOUND_NOACTIVEINDEX) {
Sound_Stop(predOVision_SoundHandle);
}
if(weaponHandle != SOUND_NOACTIVEINDEX) {
Sound_Stop(weaponHandle);
}
// Do some death sounds
switch (AvP.PlayerType)
{
case I_Alien:
{
PlayAlienSound(0,ASC_Scream_Dying,0,NULL,NULL);
break;
}
case I_Marine:
{
if (damage->Id==AMMO_FACEHUGGER) {
PlayMarineScream(0,SC_Facehugged,0,NULL,NULL);
} else {
PlayMarineScream(0,SC_Death,0,NULL,NULL);
}
break;
}
case I_Predator:
{
if (damage->Id==AMMO_FACEHUGGER) {
PlayPredatorSound(0,PSC_Facehugged,0,NULL,NULL);
} else {
PlayPredatorSound(0,PSC_Scream_Dying,0,NULL,NULL);
}
{
VECTORCH abovePosition = Global_VDB_Ptr->VDB_World;
abovePosition.vy-=1000;
MakeBloodExplosion(&Global_VDB_Ptr->VDB_World, 127, &abovePosition, 200, PARTICLE_PREDATOR_BLOOD);
}
break;
}
default:
{
break;
}
}
/* Well, it was nice knowing you. */
//playerStatusPtr->Health = 0;
sbPtr->SBDamageBlock.Health=0;
playerStatusPtr->IsAlive = 0;
/* make player fall to the ground */
// Player->ObShape=I_ShapeMarinePlayerLieDown;
// MapBlockInit(Player);
/* give player a little bounce */
dynPtr->Elasticity = 16384;
/* but a lot of friction */
// dynPtr->Friction = 1<<20;
// dynPtr->Mass = 1<<20;
/* cancel any velocity */
dynPtr->LinVelocity.vx = 0;
dynPtr->LinVelocity.vy = 0;
dynPtr->LinVelocity.vz = 0;
deathTargetOrientation.EulerX = 0;//1024-(FastRandom()&255);
deathFadeLevel=65536;
/* if in single player, fade out sound... */
if (AvP.Network==I_No_Network)
{
SoundSys_FadeOut();
}
if (AvP.PlayerType == I_Alien)
{
sbPtr->DynPtr->UseStandardGravity=1;
}
/* network support... */
#if SupportWindows95
if(AvP.Network!=I_No_Network)
{
playerStatusPtr->MyCorpse=MakeNewCorpse();
AddNetMsg_PlayerKilled((*((int *)(&(playerStatusPtr->MyCorpse->SBname[4])))),damage);
/*---------------------------------------------------------**
** handle various special body being torn apart cases **
**---------------------------------------------------------*/
/*Note that we need to apply the damage to the corpse before we can determine a
suitable death anim sequence*/
if(damage)
{
HMODELCONTROLLER* hmodel=playerStatusPtr->MyCorpse->SBdptr->HModelControlBlock;
//was the player killed by a jaw attack?
if(damage->Id==AMMO_ALIEN_BITE_KILLSECTION && AvP.PlayerType!=I_Alien)
{
//knock the head of the corpse
SECTION_DATA *head;
head=GetThisSectionData(playerStatusPtr->MyCorpse->SBdptr->HModelControlBlock->section_data,"head");
//do lots of damage to it
if(head)
{
CauseDamageToHModel(playerStatusPtr->MyCorpse->SBdptr->HModelControlBlock,playerStatusPtr->MyCorpse, &TemplateAmmo[AMMO_ALIEN_BITE_KILLSECTION].MaxDamage[AvP.Difficulty],
ONE_FIXED,head,NULL,NULL,0);
}
//play the head being bitten off sound
Sound_Play(SID_ALIEN_JAW_ATTACK,"d",&(Player->ObStrategyBlock->DynPtr->Position));
}
//chopped by predator disc?
else if(damage->Id==AMMO_PRED_DISC && AvP.PlayerType!=I_Predator)
{
SECTION_DATA *firstSectionPtr;
SECTION_DATA *chest_section=0;
firstSectionPtr=hmodel->section_data;
LOCALASSERT(firstSectionPtr);
LOCALASSERT(firstSectionPtr->flags&section_data_initialised);
/* look for the object's torso in preference */
chest_section =GetThisSectionData(hmodel->section_data,"chest");
if (chest_section)
{
CauseDamageToHModel(hmodel,playerStatusPtr->MyCorpse,damage, ONE_FIXED, chest_section,incoming,&chest_section->World_Offset,0);
}
else
{
CauseDamageToObject(playerStatusPtr->MyCorpse,damage, ONE_FIXED,incoming);
}
}
//blown up by shoulder cannon?
else if(damage->Id==AMMO_PLASMACASTER_PCKILL && AvP.PlayerType!=I_Predator)
{
SECTION_DATA *firstSectionPtr;
SECTION_DATA *chest_section=0;
firstSectionPtr=hmodel->section_data;
LOCALASSERT(firstSectionPtr);
LOCALASSERT(firstSectionPtr->flags&section_data_initialised);
/* look for the object's torso in preference */
chest_section =GetThisSectionData(hmodel->section_data,"chest");
if (chest_section)
{
//spherical blood explosion for aliens
if(AvP.PlayerType==I_Alien)
CauseDamageToHModel(hmodel,playerStatusPtr->MyCorpse,damage, ONE_FIXED, chest_section,NULL,&chest_section->World_Offset,0);
else
CauseDamageToHModel(hmodel,playerStatusPtr->MyCorpse,damage, ONE_FIXED, chest_section,incoming,&chest_section->World_Offset,0);
}
else
{
CauseDamageToObject(playerStatusPtr->MyCorpse,damage, ONE_FIXED,NULL);
}
}
else
{
SECTION_DATA *section_data=0;
if(MyHitBodyPartId!=-1)
{
//we have the id of the section that was hit when we died
//so try to find the section
section_data=GetThisSectionData_FromID(hmodel->section_data,MyHitBodyPartId);
}
//damage the corpse with the fatal blow
if(section_data)
{
DISPLAYBLOCK *fragged_section=0;
fragged_section=CauseDamageToHModel(hmodel,playerStatusPtr->MyCorpse,damage,
multiplier,section_data,incoming,NULL,0);
if(fragged_section && incoming && damage->Id==AMMO_PRED_RIFLE)
{
//a speargun has fragged off a body part , so we need to create a spear
VECTORCH direction=*incoming;
RotateVector(&direction,&Player->ObMat);
CreateSpearPossiblyWithFragment(fragged_section,&fragged_section->ObWorld,&direction);
}
}
else
{
CauseDamageToObject(playerStatusPtr->MyCorpse,damage,multiplier,incoming);
}
}
}
/*---------------------------------**
** Choose death anim sequence **
**---------------------------------*/
{
int deathId;
switch(AvP.PlayerType)
{
case I_Marine :
deathId = Deduce_PlayerMarineDeathSequence(playerStatusPtr->MyCorpse,damage,multiplier,incoming);
break;
case I_Alien :
deathId = Deduce_PlayerAlienDeathSequence(playerStatusPtr->MyCorpse,damage,multiplier,incoming);
break;
case I_Predator :
deathId = Deduce_PlayerPredatorDeathSequence(playerStatusPtr->MyCorpse,damage,multiplier,incoming);
break;
}
//apply the animation
ApplyCorpseDeathAnim(playerStatusPtr->MyCorpse,deathId);
//tell everyone else about the chosen death
AddNetMsg_PlayerDeathAnim(deathId,*(int*)&playerStatusPtr->MyCorpse->SBname[4]);
}
// if(AvP.Network==I_Host) DoNetScoresForHostDeath();
//does this death require a change in character type?
if(netGameData.gameType==NGT_LastManStanding)
{
//Am I a marine or predator?
if(AvP.PlayerType!=I_Alien)
{
//was I killed by an alien?
if(myNetworkKillerId && myNetworkKillerId!=AVPDPNetID)
{
int killer_index=PlayerIdInPlayerList(myNetworkKillerId);
GLOBALASSERT(killer_index!=NET_IDNOTINPLAYERLIST);
if(netGameData.playerData[killer_index].characterType==NGCT_Alien)
{
//set the next character to be an alien then
netGameData.myNextCharacterType=NGCT_Alien;
}
}
else
{
//suicide , so become an alien anyway
netGameData.myNextCharacterType=NGCT_Alien;
}
}
}
else if(netGameData.gameType==NGT_PredatorTag || netGameData.gameType==NGT_AlienTag)
{
//we may need to change character
extern void SpeciesTag_DetermineMyNextCharacterType();
SpeciesTag_DetermineMyNextCharacterType();
}
}
#endif
if (playerStatusPtr->soundHandle!=SOUND_NOACTIVEINDEX) {
Sound_Stop(playerStatusPtr->soundHandle);
}
if (playerStatusPtr->soundHandle3!=SOUND_NOACTIVEINDEX) {
Sound_Stop(playerStatusPtr->soundHandle3);
}
/* KJL 15:36:41 10/09/98 - don't hang around on my behalf */
DisengageGrapplingHook();
}
void ActivateSelfDestructSequence (int seconds)
{
// Currently does nothing, called when sequence is activated
if (AvP.DestructTimer==-1) {
AvP.DestructTimer=ONE_FIXED*seconds; //2 1/2 mins.
}
}
void DeInitialisePlayer(void) {
/* I thought it would be logical to put it here... */
int slot = MAX_NO_OF_WEAPON_SLOTS;
PLAYER_STATUS *playerStatusPtr= (PLAYER_STATUS *) (Player->ObStrategyBlock->SBdataptr);
do {
TXACTRLBLK *txactrl,*txactrl_next;
PLAYER_WEAPON_DATA *wdPtr = &PlayerStatusBlock.WeaponSlot[--slot];
txactrl_next = wdPtr->TxAnimCtrl;
while(txactrl_next)
{
txactrl = txactrl_next;
txactrl_next = txactrl->tac_next;
DeallocateMem((void*)txactrl);
}
wdPtr->TxAnimCtrl=NULL;
} while(slot);
#if 0 //this hmodel isn't being set up for the moment - Richard
Dispel_HModel(&playerStatusPtr->HModelController);
#endif
}
static int cloakDebounce = 1;
void InitPlayerCloakingSystem(void)
{
PLAYER_STATUS *playerStatusPtr= (PLAYER_STATUS *) (Player->ObStrategyBlock->SBdataptr);
LOCALASSERT(playerStatusPtr);
playerStatusPtr->cloakOn = 0;
playerStatusPtr->cloakPositionGivenAway = 0;
playerStatusPtr->CloakingEffectiveness = 0;
playerStatusPtr->FieldCharge = PLAYERCLOAK_MAXENERGY;
playerStatusPtr->cloakPositionGivenAwayTimer = 0;
playerStatusPtr->PlasmaCasterCharge=0;
GimmeChargeCalls=0;
HtoHStrikes=0;
CurrentLightAtPlayer=0;
}
static void DoPlayerCloakingSystem(void)
{
extern int NormalFrameTime;
PLAYER_STATUS *playerStatusPtr= (PLAYER_STATUS *) (Player->ObStrategyBlock->SBdataptr);
LOCALASSERT(playerStatusPtr);
if(AvP.PlayerType!=I_Predator) return;
if(!(playerStatusPtr->IsAlive)) return;
/* Handle controls. */
if (playerStatusPtr->Mvt_InputRequests.Flags.Rqst_ChangeVision)
{
if (cloakDebounce)
{
cloakDebounce = 0;
if (playerStatusPtr->cloakOn)
{
Sound_Play(SID_PRED_CLOAKOFF,"h");
playerStatusPtr->cloakOn = 0;
//playerNoise=1;
} else {
/* Check validity. */
if ((playerStatusPtr->FieldCharge>CloakThreshold)
&&(playerStatusPtr->FieldCharge>CloakPowerOnDrain)) {
PLAYER_WEAPON_DATA *weaponPtr;
TEMPLATE_WEAPON_DATA *twPtr;
weaponPtr = &(playerStatusPtr->WeaponSlot[playerStatusPtr->SelectedWeaponSlot]);
twPtr = &TemplateWeapon[weaponPtr->WeaponIDNumber];
if (!(((weaponPtr->CurrentState==WEAPONSTATE_FIRING_PRIMARY)||(weaponPtr->CurrentState==WEAPONSTATE_FIRING_SECONDARY))
&&(twPtr->FireWhenCloaked==0)))
{
playerStatusPtr->FieldCharge-=CloakPowerOnDrain;
CurrentGameStats_ChargeUsed(CloakPowerOnDrain);
playerStatusPtr->cloakOn = 1;
playerStatusPtr->CloakingEffectiveness = 0;
Sound_Play(SID_PRED_CLOAKON,"h");
//playerNoise=1;
}
}
}
}
}
else
{
cloakDebounce = 1;
if (playerStatusPtr->cloakOn)
{
int maxPossibleEffectiveness;
VECTORCH velocity;
DYNAMICSBLOCK *dynPtr=Player->ObStrategyBlock->DynPtr;
velocity.vx = dynPtr->Position.vx - dynPtr->PrevPosition.vx;
velocity.vy = dynPtr->Position.vy - dynPtr->PrevPosition.vy;
velocity.vz = dynPtr->Position.vz - dynPtr->PrevPosition.vz;
if (playerStatusPtr->IsMovingInWater)
{
maxPossibleEffectiveness = 0;
if(playerStatusPtr->soundHandleForPredatorCloakDamaged==SOUND_NOACTIVEINDEX)
Sound_Play(SID_PREDATOR_CLOAKING_DAMAGED,"el",playerStatusPtr->soundHandleForPredatorCloakDamaged);
}
else
{
if(playerStatusPtr->soundHandleForPredatorCloakDamaged!=SOUND_NOACTIVEINDEX)
Sound_Stop(playerStatusPtr->soundHandleForPredatorCloakDamaged);
maxPossibleEffectiveness = ONE_FIXED - DIV_FIXED(Magnitude(&velocity)*2,NormalFrameTime);
if (maxPossibleEffectiveness<0) maxPossibleEffectiveness = 0;
}
playerStatusPtr->CloakingEffectiveness += NormalFrameTime;
if (playerStatusPtr->CloakingEffectiveness>maxPossibleEffectiveness)
{
playerStatusPtr->CloakingEffectiveness = maxPossibleEffectiveness;
}
}
else
{
playerStatusPtr->CloakingEffectiveness -= NormalFrameTime;
if (playerStatusPtr->CloakingEffectiveness<0)
{
playerStatusPtr->CloakingEffectiveness=0;
}
if(playerStatusPtr->soundHandleForPredatorCloakDamaged!=SOUND_NOACTIVEINDEX)
Sound_Stop(playerStatusPtr->soundHandleForPredatorCloakDamaged);
}
}
#if 1
/* position-given-away-timer runs whatever state the cloak is in */
if(playerStatusPtr->cloakPositionGivenAway)
{
playerStatusPtr->cloakPositionGivenAwayTimer-=NormalFrameTime;
if(playerStatusPtr->cloakPositionGivenAwayTimer<=0)
{
playerStatusPtr->cloakPositionGivenAwayTimer = 0;
playerStatusPtr->cloakPositionGivenAway = 0;
playerStatusPtr->CloakingEffectiveness = 0;
}
}
/* now sort out energy discharge/recharge */
if(playerStatusPtr->cloakOn)
{
int chargeUsed;
chargeUsed=MUL_FIXED(NormalFrameTime,CloakDrain);
if (playerStatusPtr->IsMovingInWater) {
chargeUsed<<=2;
}
if (chargeUsed>playerStatusPtr->FieldCharge) {
chargeUsed=playerStatusPtr->FieldCharge;
}
playerStatusPtr->FieldCharge -= chargeUsed;
CurrentGameStats_ChargeUsed(chargeUsed);
if(playerStatusPtr->FieldCharge <= 0)
{
playerStatusPtr->FieldCharge = 0;
playerStatusPtr->cloakOn = 0;
playerStatusPtr->Mvt_InputRequests.Flags.Rqst_ChangeVision = 1;
Sound_Play(SID_PRED_CLOAKOFF,"h");
//playerNoise=1;
}
/* TrickleCharge Difficulty Variation! */
if ((AvP.Difficulty==I_Hard)||(AvP.Difficulty==I_Impossible)) {
playerStatusPtr->FieldCharge += MUL_FIXED(NormalFrameTime,(TrickleCharge>>1));
} else {
playerStatusPtr->FieldCharge += MUL_FIXED(NormalFrameTime,TrickleCharge);
}
if(playerStatusPtr->FieldCharge > PLAYERCLOAK_MAXENERGY) {
playerStatusPtr->FieldCharge = PLAYERCLOAK_MAXENERGY;
}
}
else
{
if(playerStatusPtr->FieldCharge < PLAYERCLOAK_MAXENERGY)
{
/* TrickleCharge Difficulty Variation! */
if ((AvP.Difficulty==I_Hard)||(AvP.Difficulty==I_Impossible)) {
playerStatusPtr->FieldCharge += MUL_FIXED(NormalFrameTime,(TrickleCharge>>1));
} else {
playerStatusPtr->FieldCharge += MUL_FIXED(NormalFrameTime,TrickleCharge);
}
if(playerStatusPtr->FieldCharge > PLAYERCLOAK_MAXENERGY) {
playerStatusPtr->FieldCharge = PLAYERCLOAK_MAXENERGY;
}
#if 0
/* Infinite field charge? */
playerStatusPtr->FieldCharge = PLAYERCLOAK_MAXENERGY;
#endif
}
}
#endif
if (ShowPredoStats) {
/* for testing */
PrintDebuggingText("Cloak on: %d \n",playerStatusPtr->cloakOn);
PrintDebuggingText("Field Charge: %d \n",playerStatusPtr->FieldCharge);
{
int a;
/* Speargun ammo count */
a=SlotForThisWeapon(WEAPON_PRED_RIFLE);
if (a!=-1) {
PrintDebuggingText("Speargun Rounds: %d Clips: %d\n",(playerStatusPtr->WeaponSlot[a].PrimaryRoundsRemaining>>ONE_FIXED_SHIFT),playerStatusPtr->WeaponSlot[a].PrimaryMagazinesRemaining);
} else {
PrintDebuggingText("Speargun not possessed.\n");
}
}
PrintDebuggingText("Cloak given away: %d \n", playerStatusPtr->cloakPositionGivenAway);
PrintDebuggingText("Cloak given away timer: %d \n", playerStatusPtr->cloakPositionGivenAwayTimer);
PrintDebuggingText("Cloaking Effectiveness: %d \n", playerStatusPtr->CloakingEffectiveness);
PrintDebuggingText("Gimme_Charge Calls: %d \n",GimmeChargeCalls);
}
#if 1
/* now, if we are cloaked, lets see if we have given away our position...
if we have already given away our position, we may do so again */
if(playerStatusPtr->cloakOn)
{
PLAYER_WEAPON_DATA *weaponPtr;
TEMPLATE_WEAPON_DATA *twPtr;
weaponPtr = &(playerStatusPtr->WeaponSlot[playerStatusPtr->SelectedWeaponSlot]);
twPtr = &TemplateWeapon[weaponPtr->WeaponIDNumber];
/* weapon fire ?*/
if(((PlayerStatusPtr->WeaponSlot[PlayerStatusPtr->SelectedWeaponSlot].CurrentState==WEAPONSTATE_FIRING_PRIMARY)&&(!twPtr->PrimaryIsMeleeWeapon))||
((PlayerStatusPtr->WeaponSlot[PlayerStatusPtr->SelectedWeaponSlot].CurrentState==WEAPONSTATE_FIRING_SECONDARY)&&(!twPtr->SecondaryIsMeleeWeapon)))
{
playerStatusPtr->cloakPositionGivenAway = 1;
playerStatusPtr->cloakPositionGivenAwayTimer = PLAYERCLOAK_POSTIONGIVENAWAYTIME;
}
/* collision with npc ?*/
{
struct collisionreport *nextReport;
LOCALASSERT(Player->ObStrategyBlock->DynPtr);
nextReport = Player->ObStrategyBlock->DynPtr->CollisionReportPtr;
while(nextReport)
{
if(nextReport->ObstacleSBPtr)
{
if((nextReport->ObstacleSBPtr->I_SBtype==I_BehaviourAlien)||
(nextReport->ObstacleSBPtr->I_SBtype==I_BehaviourMarine)||
(nextReport->ObstacleSBPtr->I_SBtype==I_BehaviourXenoborg)||
(nextReport->ObstacleSBPtr->I_SBtype==I_BehaviourPredatorAlien)||
(nextReport->ObstacleSBPtr->I_SBtype==I_BehaviourQueenAlien)||
(nextReport->ObstacleSBPtr->I_SBtype==I_BehaviourFaceHugger)||
(nextReport->ObstacleSBPtr->I_SBtype==I_BehaviourSeal))
{
playerStatusPtr->cloakPositionGivenAway = 1;
playerStatusPtr->cloakPositionGivenAwayTimer = PLAYERCLOAK_POSTIONGIVENAWAYTIME;
break;
}
}
nextReport = nextReport->NextCollisionReportPtr;
}
}
}
#endif
if (playerStatusPtr->cloakOn) {
CurrentGameStats_CloakOn();
}
}
void GimmeCharge(void) {
PLAYER_STATUS *playerStatusPtr= (PLAYER_STATUS *) (Player->ObStrategyBlock->SBdataptr);
LOCALASSERT(playerStatusPtr);
if(AvP.PlayerType!=I_Predator) return;
playerStatusPtr->FieldCharge = PLAYERCLOAK_MAXENERGY;
GimmeChargeCalls++;
}
#define AUTOSPOT_RANGE (1000)
int AlienPCIsCurrentlyVisible(int checktime,STRATEGYBLOCK *sbPtr) {
PLAYER_WEAPON_DATA *weaponPtr;
int range;
DYNAMICSBLOCK *dynPtr=(Player->ObStrategyBlock->DynPtr);
PLAYER_STATUS *playerStatusPtr= (PLAYER_STATUS *) (Player->ObStrategyBlock->SBdataptr);
LOCALASSERT(playerStatusPtr);
/* sbPtr is the viewer. */
if (AvP.PlayerType!=I_Alien) {
/* Just to be sure. */
return(1);
}
weaponPtr = &(playerStatusPtr->WeaponSlot[playerStatusPtr->SelectedWeaponSlot]);
/* Set a default range? */
range=-1;
/* Maybe we also need an autospot range. */
if (sbPtr) {
VECTORCH offset;
offset.vx=dynPtr->Position.vx-sbPtr->DynPtr->Position.vx;
offset.vy=dynPtr->Position.vy-sbPtr->DynPtr->Position.vy;
offset.vz=dynPtr->Position.vz-sbPtr->DynPtr->Position.vz;
range=Approximate3dMagnitude(&offset);
/* In fact, let's turn this around... */
if (playerStatusPtr->ShapeState==PMph_Standing) {
if (range>=(CurrentLightAtPlayer)+AUTOSPOT_RANGE) {
return(0);
}
} else {
if (range>=(CurrentLightAtPlayer>>1)+AUTOSPOT_RANGE) {
/* Half that range if crouching? */
return(0);
}
}
/* I guess, if we're in _pitch_ darkness... see nothing outside that range? */
if (CurrentLightAtPlayer<=2560) {
if (playerStatusPtr->ShapeState==PMph_Standing) {
if (range<=(CurrentLightAtPlayer)+AUTOSPOT_RANGE) {
return(1);
}
} else {
if (range<=(CurrentLightAtPlayer>>1)+AUTOSPOT_RANGE) {
/* Half that range if crouching? */
return(1);
}
}
return(0);
}
}
if (playerStatusPtr->ShapeState==PMph_Standing) {
/* Default to visible, unless stationary and in near darkness. */
if (weaponPtr->CurrentState!=WEAPONSTATE_IDLE) {
/* Don't even breathe. */
return(1);
}
if ((dynPtr->Position.vx!=dynPtr->PrevPosition.vx)||
(dynPtr->Position.vy!=dynPtr->PrevPosition.vy)||
(dynPtr->Position.vz!=dynPtr->PrevPosition.vz)) {
/* Stand perfectly still. */
return(1);
}
if (checktime) {
int chance;
/* There is a chance of being seen regardless. */
chance=32767; /* Lets say. */
if ((FastRandom()&65535)<chance) {
return(1);
}
}
if (CurrentLightAtPlayer<5000) {
return(0);
}
return(1);
} else {
int speed;
/* Crouching. Default to cloaked, unless they get 'lucky'. */
if (weaponPtr->CurrentState==WEAPONSTATE_FIRING_PRIMARY) {
/* Just don't claw. */
return(1);
}
if (CurrentLightAtPlayer>17000) {
/* It's too bright, mere crouching won't save you. */
return(1);
}
#if 0
if ((dynPtr->Position.vx!=dynPtr->PrevPosition.vx)||
(dynPtr->Position.vy!=dynPtr->PrevPosition.vy)||
(dynPtr->Position.vz!=dynPtr->PrevPosition.vz)) {
/* Stand perfectly still? */
return(1);
}
#else
speed=Approximate3dMagnitude(&Player->ObStrategyBlock->DynPtr->LinVelocity);
/* Speed: < 5000 = standing. > 22000 = jumping.
In practice, walk/fall = 18000 ish, jump = 27000 ish. */
if (speed>22000) {
/* Not getting away with that, mate. */
return(1);
}
speed-=5000;
if (speed<0) {
speed=0;
}
/* Now should be 0->17000 ish. */
speed<<=1;
#endif
if (checktime) {
int chance;
/* There is a chance of being seen. */
chance=CurrentLightAtPlayer-5000;
#if 1
chance+=speed;
#endif
if ((FastRandom()&65535)<chance) {
return(1);
}
}
return(0);
}
}
#if 0
static void HandlePredatorVisionModes(void)
{
extern unsigned char DebouncedKeyboardInput[];
if (DebouncedKeyboardInput[KEY_K])
{
ChangePredatorVisionMode();
}
}
#endif
void ShowAdjacencies(void) {
int moduleCounter;
AIMODULE **AdjModuleRefPtr;
AIMODULE *thisModule;
AIMODULE *ModuleListPointer;
/* Utility function... */
PrintDebuggingText("Adjacencies FROM Player's Module (%s):\n",
(*(playerPherModule->m_aimodule->m_module_ptrs))->name);
thisModule=playerPherModule->m_aimodule;
AdjModuleRefPtr = thisModule->m_link_ptrs;
if(AdjModuleRefPtr) /* check that there is a list of adjacent modules */
{
while(*AdjModuleRefPtr != 0)
{
/* Probably want some validity test for the link. */
if (AIModuleIsPhysical(*AdjModuleRefPtr)) {
/* Probably a valid link... */
if (CheckAdjacencyValidity((*AdjModuleRefPtr),thisModule,0)) {
PrintDebuggingText("--AI Module of %s, general.\n",(*((*AdjModuleRefPtr)->m_module_ptrs))->name);
} else if (CheckAdjacencyValidity((*AdjModuleRefPtr),thisModule,1)) {
PrintDebuggingText("--AI Module of %s, alien only.\n",(*((*AdjModuleRefPtr)->m_module_ptrs))->name);
} else {
PrintDebuggingText("--AI Module of %s, fails validity test!\n",(*((*AdjModuleRefPtr)->m_module_ptrs))->name);
}
}
/* next adjacent module reference pointer */
AdjModuleRefPtr++;
}
}
PrintDebuggingText("Adjacencies TO Player's Module:\n");
{
extern AIMODULE *AIModuleArray;
ModuleListPointer = AIModuleArray;
}
/* go through each aimodule in the environment */
for(moduleCounter = 0; moduleCounter < AIModuleArraySize; moduleCounter++)
{
/* get a pointer to the next current module */
thisModule = &(ModuleListPointer[moduleCounter]);
LOCALASSERT(thisModule);
AdjModuleRefPtr = thisModule->m_link_ptrs;
if(AdjModuleRefPtr) /* check that there is a list of adjacent modules */
{
while(*AdjModuleRefPtr != 0)
{
/* Probably want some validity test for the link. */
if (AIModuleIsPhysical(*AdjModuleRefPtr)) {
/* Is this the target? */
if ((*AdjModuleRefPtr)==(playerPherModule->m_aimodule)) {
/* Probably a valid link... */
if (CheckAdjacencyValidity((*AdjModuleRefPtr),thisModule,0)) {
PrintDebuggingText("--AI Module of %s, general.\n",(*(thisModule->m_module_ptrs))->name);
} else if (CheckAdjacencyValidity((*AdjModuleRefPtr),thisModule,1)) {
PrintDebuggingText("--AI Module of %s, alien only.\n",(*(thisModule->m_module_ptrs))->name);
} else {
PrintDebuggingText("--AI Module of %s, fails validity test!\n",(*(thisModule->m_module_ptrs))->name);
}
}
}
/* next adjacent module reference pointer */
AdjModuleRefPtr++;
}
}
}
}
/*---------------------------**
** Loading and saving player **
**---------------------------*/
typedef struct player_save_block
{
SAVE_BLOCK_STRATEGY_HEADER header;
//behaviour block things
PLAYER_WEAPON_DATA WeaponSlot[MAX_NO_OF_WEAPON_SLOTS];
enum WEAPON_SLOT SelectedWeaponSlot;
enum WEAPON_SLOT SwapToWeaponSlot;
enum WEAPON_SLOT PreviouslySelectedWeaponSlot;
int Health; /* in 16.16 */
int Energy; /* in 16.16 */
int Armour; /* in 16.16 */
enum player_morph_state ShapeState; /* for controlling morphing */
signed int ForwardInertia;
signed int StrafeInertia;
signed int TurnInertia;
int ViewPanX; /* the looking up/down value that used to be in displayblock */
unsigned int securityClearances;
unsigned int IsAlive :1;
unsigned int IsImmortal :1;
unsigned int Mvt_AnalogueTurning :1;
unsigned int Mvt_AnaloguePitching :1;
unsigned int Absolute_Pitching :1;
unsigned int SwappingIsDebounced :1;
unsigned int DemoMode :1;
unsigned int IHaveAPlacedAutogun :1;
unsigned int IsMovingInWater :1;
unsigned int JetpackEnabled :1;
unsigned int GrapplingHookEnabled :1;
unsigned int MTrackerType;
unsigned int cloakOn :1;
unsigned int cloakPositionGivenAway :1;
int FieldCharge;
int cloakPositionGivenAwayTimer;
int PlasmaCasterCharge;
int CloakingEffectiveness;
ENCUMBERANCE_STATE Encumberance;
int tauntTimer;
int incidentFlag;
int incidentTimer;
int fireTimer;
//some stuff for the weapon displayblock
VECTORCH Weapon_World;
EULER Weapon_Euler;
MATRIXCH Weapon_Matrix;
//and globals
enum VISION_MODE_ID CurrentVisionMode;
SMARTGUN_MODES SmartgunMode;
GRENADE_LAUNCHER_DATA GrenadeLauncherData;
//strategy block stuff
DYNAMICSBLOCK dynamics;
int integrity;
DAMAGEBLOCK SBDamageBlock;
}PLAYER_SAVE_BLOCK;
//defines for load/save macros
#define SAVELOAD_BLOCK block
#define SAVELOAD_BEHAV playerStatusPtr
void SaveStrategy_Player(STRATEGYBLOCK* sbPtr)
{
PLAYER_STATUS *playerStatusPtr= (PLAYER_STATUS *) (sbPtr->SBdataptr);
PLAYER_SAVE_BLOCK* block;
int i;
GET_STRATEGY_SAVE_BLOCK(block,sbPtr);
COPYELEMENT_SAVE(SelectedWeaponSlot)
COPYELEMENT_SAVE(SwapToWeaponSlot)
COPYELEMENT_SAVE(PreviouslySelectedWeaponSlot)
COPYELEMENT_SAVE(Health) /* in 16.16 */
COPYELEMENT_SAVE(Energy) /* in 16.16 */
COPYELEMENT_SAVE(Armour) /* in 16.16 */
COPYELEMENT_SAVE(ShapeState) /* for controlling morphing */
COPYELEMENT_SAVE(ForwardInertia)
COPYELEMENT_SAVE(StrafeInertia)
COPYELEMENT_SAVE(TurnInertia)
COPYELEMENT_SAVE(ViewPanX) /* the looking up/down value that used to be in displayblock */
COPYELEMENT_SAVE(securityClearances)
COPYELEMENT_SAVE(IsAlive)
COPYELEMENT_SAVE(IsImmortal)
COPYELEMENT_SAVE(Mvt_AnalogueTurning)
COPYELEMENT_SAVE(Mvt_AnaloguePitching)
COPYELEMENT_SAVE(Absolute_Pitching)
COPYELEMENT_SAVE(SwappingIsDebounced)
COPYELEMENT_SAVE(DemoMode)
COPYELEMENT_SAVE(IHaveAPlacedAutogun)
COPYELEMENT_SAVE(IsMovingInWater)
COPYELEMENT_SAVE(JetpackEnabled)
COPYELEMENT_SAVE(GrapplingHookEnabled )
COPYELEMENT_SAVE(MTrackerType)
COPYELEMENT_SAVE(cloakOn)
COPYELEMENT_SAVE(cloakPositionGivenAway)
COPYELEMENT_SAVE(FieldCharge)
COPYELEMENT_SAVE(cloakPositionGivenAwayTimer)
COPYELEMENT_SAVE(PlasmaCasterCharge)
COPYELEMENT_SAVE(CloakingEffectiveness)
COPYELEMENT_SAVE(Encumberance)
COPYELEMENT_SAVE(tauntTimer)
COPYELEMENT_SAVE(incidentFlag)
COPYELEMENT_SAVE(incidentTimer)
COPYELEMENT_SAVE(fireTimer)
for(i=0;i<MAX_NO_OF_WEAPON_SLOTS;i++)
{
block->WeaponSlot[i].WeaponIDNumber = playerStatusPtr->WeaponSlot[i].WeaponIDNumber;
block->WeaponSlot[i].CurrentState = playerStatusPtr->WeaponSlot[i].CurrentState;
block->WeaponSlot[i].StateTimeOutCounter = playerStatusPtr->WeaponSlot[i].StateTimeOutCounter;
block->WeaponSlot[i].PrimaryRoundsRemaining = playerStatusPtr->WeaponSlot[i].PrimaryRoundsRemaining;
block->WeaponSlot[i].SecondaryRoundsRemaining = playerStatusPtr->WeaponSlot[i].SecondaryRoundsRemaining;
block->WeaponSlot[i].PrimaryMagazinesRemaining = playerStatusPtr->WeaponSlot[i].PrimaryMagazinesRemaining;
block->WeaponSlot[i].SecondaryMagazinesRemaining = playerStatusPtr->WeaponSlot[i].SecondaryMagazinesRemaining;
block->WeaponSlot[i].PositionOffset = playerStatusPtr->WeaponSlot[i].PositionOffset;
block->WeaponSlot[i].DirectionOffset = playerStatusPtr->WeaponSlot[i].DirectionOffset;
block->WeaponSlot[i].Possessed = playerStatusPtr->WeaponSlot[i].Possessed;
}
//some stuff for the weapon displayblock
block->Weapon_World = PlayersWeapon.ObWorld;
block->Weapon_Euler = PlayersWeapon.ObEuler;
block->Weapon_Matrix = PlayersWeapon.ObMat;
//global
block->CurrentVisionMode = CurrentVisionMode;
block->SmartgunMode = SmartgunMode;
block->GrenadeLauncherData = GrenadeLauncherData;
//strategy block stuff
block->integrity = sbPtr->integrity;
block->SBDamageBlock = sbPtr->SBDamageBlock;
block->dynamics = *sbPtr->DynPtr;
block->dynamics.CollisionReportPtr=0;
//save the weapon hierarchy
SaveHierarchy(&PlayersWeaponHModelController);
Save_SoundState(&playerStatusPtr->soundHandle);
Save_SoundState(&playerStatusPtr->soundHandle3);
Save_SoundState(&playerStatusPtr->soundHandle5);
Save_SoundState(&playerStatusPtr->soundHandleForPredatorCloakDamaged);
}
void LoadStrategy_Player(SAVE_BLOCK_STRATEGY_HEADER* header)
{
PLAYER_SAVE_BLOCK* block = (PLAYER_SAVE_BLOCK*) header;
STRATEGYBLOCK* sbPtr = Player->ObStrategyBlock;
PLAYER_STATUS *playerStatusPtr= (PLAYER_STATUS *) (sbPtr->SBdataptr);
int i;
if(block->header.size != sizeof(*block)) return;
COPY_NAME(sbPtr->SBname,header->SBname);
COPYELEMENT_LOAD(SelectedWeaponSlot)
COPYELEMENT_LOAD(SwapToWeaponSlot)
COPYELEMENT_LOAD(PreviouslySelectedWeaponSlot)
COPYELEMENT_LOAD(Health) /* in 16.16 */
COPYELEMENT_LOAD(Energy) /* in 16.16 */
COPYELEMENT_LOAD(Armour) /* in 16.16 */
COPYELEMENT_LOAD(ShapeState) /* for controlling morphing */
COPYELEMENT_LOAD(ForwardInertia)
COPYELEMENT_LOAD(StrafeInertia)
COPYELEMENT_LOAD(TurnInertia)
COPYELEMENT_LOAD(ViewPanX) /* the looking up/down value that used to be in displayblock */
COPYELEMENT_LOAD(securityClearances)
COPYELEMENT_LOAD(IsAlive)
COPYELEMENT_LOAD(IsImmortal)
COPYELEMENT_LOAD(Mvt_AnalogueTurning)
COPYELEMENT_LOAD(Mvt_AnaloguePitching)
COPYELEMENT_LOAD(Absolute_Pitching)
COPYELEMENT_LOAD(SwappingIsDebounced)
COPYELEMENT_LOAD(DemoMode)
COPYELEMENT_LOAD(IHaveAPlacedAutogun)
COPYELEMENT_LOAD(IsMovingInWater)
COPYELEMENT_LOAD(JetpackEnabled)
COPYELEMENT_LOAD(GrapplingHookEnabled )
COPYELEMENT_LOAD(MTrackerType)
COPYELEMENT_LOAD(cloakOn)
COPYELEMENT_LOAD(cloakPositionGivenAway)
COPYELEMENT_LOAD(FieldCharge)
COPYELEMENT_LOAD(cloakPositionGivenAwayTimer)
COPYELEMENT_LOAD(PlasmaCasterCharge)
COPYELEMENT_LOAD(CloakingEffectiveness)
COPYELEMENT_LOAD(Encumberance)
COPYELEMENT_LOAD(tauntTimer)
COPYELEMENT_LOAD(incidentFlag)
COPYELEMENT_LOAD(incidentTimer)
COPYELEMENT_LOAD(fireTimer)
// playerStatusPtr->SwapToWeaponSlot = block->SelectedWeaponSlot;
for(i=0;i<MAX_NO_OF_WEAPON_SLOTS;i++)
{
playerStatusPtr->WeaponSlot[i].WeaponIDNumber = block->WeaponSlot[i].WeaponIDNumber;
playerStatusPtr->WeaponSlot[i].CurrentState = block->WeaponSlot[i].CurrentState;
playerStatusPtr->WeaponSlot[i].StateTimeOutCounter = block->WeaponSlot[i].StateTimeOutCounter;
playerStatusPtr->WeaponSlot[i].PrimaryRoundsRemaining = block->WeaponSlot[i].PrimaryRoundsRemaining;
playerStatusPtr->WeaponSlot[i].SecondaryRoundsRemaining = block->WeaponSlot[i].SecondaryRoundsRemaining;
playerStatusPtr->WeaponSlot[i].PrimaryMagazinesRemaining = block->WeaponSlot[i].PrimaryMagazinesRemaining;
playerStatusPtr->WeaponSlot[i].SecondaryMagazinesRemaining = block->WeaponSlot[i].SecondaryMagazinesRemaining;
playerStatusPtr->WeaponSlot[i].PositionOffset = block->WeaponSlot[i].PositionOffset;
playerStatusPtr->WeaponSlot[i].DirectionOffset = block->WeaponSlot[i].DirectionOffset;
playerStatusPtr->WeaponSlot[i].Possessed = block->WeaponSlot[i].Possessed;
}
//some stuff for the weapon displayblock
PlayersWeapon.ObWorld = block->Weapon_World;
PlayersWeapon.ObEuler = block->Weapon_Euler;
PlayersWeapon.ObMat = block->Weapon_Matrix;
//global
CurrentVisionMode = block->CurrentVisionMode;
SmartgunMode = block->SmartgunMode;
GrenadeLauncherData = block->GrenadeLauncherData;
//strategy block stuff
*sbPtr->DynPtr = block->dynamics;
sbPtr->integrity = block->integrity;
sbPtr->SBDamageBlock = block->SBDamageBlock;
{
extern VIEWDESCRIPTORBLOCK* Global_VDB_Ptr;
sbPtr->containingModule = ModuleFromPosition(&(sbPtr->DynPtr->Position), (MODULE*)0);
Global_VDB_Ptr->VDB_World = sbPtr->DynPtr->Position;
}
//load the weapon hierarchy
{
SAVE_BLOCK_HEADER* hier_header = GetNextBlockIfOfType(SaveBlock_Hierarchy);
if(hier_header)
{
LoadHierarchy(hier_header,&PlayersWeaponHModelController);
}
else
{
Dispel_HModel(&PlayersWeaponHModelController);
}
}
PlayersWeapon.HModelControlBlock = &PlayersWeaponHModelController;
//get the section data pointers
PWMFSDP=GetThisSectionData(PlayersWeaponHModelController.section_data,"dum flash");
if (PWMFSDP==NULL) {
PWMFSDP=GetThisSectionData(PlayersWeaponHModelController.section_data,"Dum flash");
}
Load_SoundState(&playerStatusPtr->soundHandle);
Load_SoundState(&playerStatusPtr->soundHandle3);
Load_SoundState(&playerStatusPtr->soundHandle5);
Load_SoundState(&playerStatusPtr->soundHandleForPredatorCloakDamaged);
}