2011-11-22 21:28:15 +00:00
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
Doom 3 GPL Source Code
2011-12-06 18:20:15 +00:00
Copyright ( C ) 1999 - 2011 id Software LLC , a ZeniMax Media company .
2011-11-22 21:28:15 +00:00
2011-12-06 16:14:59 +00:00
This file is part of the Doom 3 GPL Source Code ( " Doom 3 Source Code " ) .
2011-11-22 21:28:15 +00:00
Doom 3 Source Code 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 3 of the License , or
( at your option ) any later version .
Doom 3 Source Code 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 Doom 3 Source Code . If not , see < http : //www.gnu.org/licenses/>.
In addition , the Doom 3 Source Code is also subject to certain additional terms . You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code . If not , please request a copy in writing from id Software at the address below .
If you have questions concerning this license or the applicable additional terms , you may contact in writing id Software LLC , c / o ZeniMax Media Inc . , Suite 120 , Rockville , Maryland 20850 USA .
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
2011-12-16 22:28:29 +00:00
# include "sys/platform.h"
# include "idlib/LangDict.h"
# include "framework/async/NetworkSystem.h"
# include "framework/DeclEntityDef.h"
# include "renderer/RenderSystem.h"
# include "gamesys/SysCvar.h"
# include "script/Script_Thread.h"
# include "ai/AI.h"
# include "WorldSpawn.h"
# include "Player.h"
# include "Camera.h"
# include "Fx.h"
# include "Misc.h"
2011-11-22 21:28:15 +00:00
2011-12-02 16:22:12 +00:00
const int ASYNC_PLAYER_INV_AMMO_BITS = idMath : : BitsForInteger ( 999 ) ; // 9 bits to cover the range [0, 999]
const int ASYNC_PLAYER_INV_CLIP_BITS = - 7 ; // -7 bits to cover the range [-1, 60]
2011-11-22 21:28:15 +00:00
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
Player control of the Doom Marine .
This object handles all player movement and world interaction .
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
// distance between ladder rungs (actually is half that distance, but this sounds better)
const int LADDER_RUNG_DISTANCE = 32 ;
// amount of health per dose from the health station
const int HEALTH_PER_DOSE = 10 ;
// time before a weapon dropped to the floor disappears
const int WEAPON_DROP_TIME = 20 * 1000 ;
// time before a next or prev weapon switch happens
const int WEAPON_SWITCH_DELAY = 150 ;
// how many units to raise spectator above default view height so it's in the head of someone
const int SPECTATE_RAISE = 25 ;
const int HEALTHPULSE_TIME = 333 ;
// minimum speed to bob and play run/walk animations at
const float MIN_BOB_SPEED = 5.0f ;
const idEventDef EV_Player_GetButtons ( " getButtons " , NULL , ' d ' ) ;
const idEventDef EV_Player_GetMove ( " getMove " , NULL , ' v ' ) ;
const idEventDef EV_Player_GetViewAngles ( " getViewAngles " , NULL , ' v ' ) ;
const idEventDef EV_Player_StopFxFov ( " stopFxFov " ) ;
const idEventDef EV_Player_EnableWeapon ( " enableWeapon " ) ;
const idEventDef EV_Player_DisableWeapon ( " disableWeapon " ) ;
const idEventDef EV_Player_GetCurrentWeapon ( " getCurrentWeapon " , NULL , ' s ' ) ;
const idEventDef EV_Player_GetPreviousWeapon ( " getPreviousWeapon " , NULL , ' s ' ) ;
const idEventDef EV_Player_SelectWeapon ( " selectWeapon " , " s " ) ;
const idEventDef EV_Player_GetWeaponEntity ( " getWeaponEntity " , NULL , ' e ' ) ;
const idEventDef EV_Player_OpenPDA ( " openPDA " ) ;
const idEventDef EV_Player_InPDA ( " inPDA " , NULL , ' d ' ) ;
const idEventDef EV_Player_ExitTeleporter ( " exitTeleporter " ) ;
const idEventDef EV_Player_StopAudioLog ( " stopAudioLog " ) ;
const idEventDef EV_Player_HideTip ( " hideTip " ) ;
const idEventDef EV_Player_LevelTrigger ( " levelTrigger " ) ;
const idEventDef EV_SpectatorTouch ( " spectatorTouch " , " et " ) ;
const idEventDef EV_Player_GetIdealWeapon ( " getIdealWeapon " , NULL , ' s ' ) ;
2018-08-26 03:41:08 +00:00
const idEventDef EV_Player_WeaponAvailable ( " weaponAvailable " , " s " , ' d ' ) ; //
const idEventDef EV_Player_GetImpulseKey ( " getImpulseKey " , NULL , ' d ' ) ; // Added By Clone JC Denton
2011-11-22 21:28:15 +00:00
CLASS_DECLARATION ( idActor , idPlayer )
EVENT ( EV_Player_GetButtons , idPlayer : : Event_GetButtons )
EVENT ( EV_Player_GetMove , idPlayer : : Event_GetMove )
EVENT ( EV_Player_GetViewAngles , idPlayer : : Event_GetViewAngles )
EVENT ( EV_Player_StopFxFov , idPlayer : : Event_StopFxFov )
EVENT ( EV_Player_EnableWeapon , idPlayer : : Event_EnableWeapon )
EVENT ( EV_Player_DisableWeapon , idPlayer : : Event_DisableWeapon )
EVENT ( EV_Player_GetCurrentWeapon , idPlayer : : Event_GetCurrentWeapon )
EVENT ( EV_Player_GetPreviousWeapon , idPlayer : : Event_GetPreviousWeapon )
EVENT ( EV_Player_SelectWeapon , idPlayer : : Event_SelectWeapon )
EVENT ( EV_Player_GetWeaponEntity , idPlayer : : Event_GetWeaponEntity )
EVENT ( EV_Player_OpenPDA , idPlayer : : Event_OpenPDA )
EVENT ( EV_Player_InPDA , idPlayer : : Event_InPDA )
EVENT ( EV_Player_ExitTeleporter , idPlayer : : Event_ExitTeleporter )
EVENT ( EV_Player_StopAudioLog , idPlayer : : Event_StopAudioLog )
EVENT ( EV_Player_HideTip , idPlayer : : Event_HideTip )
EVENT ( EV_Player_LevelTrigger , idPlayer : : Event_LevelTrigger )
EVENT ( EV_Gibbed , idPlayer : : Event_Gibbed )
2018-08-26 03:41:08 +00:00
EVENT ( EV_Player_WeaponAvailable , idPlayer : : Event_WeaponAvailable ) //
EVENT ( EV_Player_GetImpulseKey , idPlayer : : Event_GetImpulseKey ) // Added By Clone JCD
2011-11-22 21:28:15 +00:00
EVENT ( EV_Player_GetIdealWeapon , idPlayer : : Event_GetIdealWeapon )
END_CLASS
const int MAX_RESPAWN_TIME = 10000 ;
const int RAGDOLL_DEATH_TIME = 3000 ;
const int MAX_PDAS = 64 ;
const int MAX_PDA_ITEMS = 128 ;
const int STEPUP_TIME = 200 ;
const int MAX_INVENTORY_ITEMS = 20 ;
idVec3 idPlayer : : colorBarTable [ 5 ] = {
idVec3 ( 0.25f , 0.25f , 0.25f ) ,
idVec3 ( 1.00f , 0.00f , 0.00f ) ,
idVec3 ( 0.00f , 0.80f , 0.10f ) ,
idVec3 ( 0.20f , 0.50f , 0.80f ) ,
idVec3 ( 1.00f , 0.80f , 0.10f )
} ;
/*
= = = = = = = = = = = = = =
idInventory : : Clear
= = = = = = = = = = = = = =
*/
void idInventory : : Clear ( void ) {
maxHealth = 0 ;
weapons = 0 ;
powerups = 0 ;
armor = 0 ;
maxarmor = 0 ;
deplete_armor = 0 ;
deplete_rate = 0.0f ;
deplete_ammount = 0 ;
nextArmorDepleteTime = 0 ;
memset ( ammo , 0 , sizeof ( ammo ) ) ;
ClearPowerUps ( ) ;
// set to -1 so that the gun knows to have a full clip the first time we get it and at the start of the level
memset ( clip , - 1 , sizeof ( clip ) ) ;
2011-12-06 18:20:15 +00:00
2011-11-22 21:28:15 +00:00
items . DeleteContents ( true ) ;
memset ( pdasViewed , 0 , 4 * sizeof ( pdasViewed [ 0 ] ) ) ;
pdas . Clear ( ) ;
videos . Clear ( ) ;
emails . Clear ( ) ;
selVideo = 0 ;
selEMail = 0 ;
selPDA = 0 ;
selAudio = 0 ;
pdaOpened = false ;
turkeyScore = false ;
levelTriggers . Clear ( ) ;
nextItemPickup = 0 ;
nextItemNum = 1 ;
onePickupTime = 0 ;
pickupItemNames . Clear ( ) ;
objectiveNames . Clear ( ) ;
ammoPredictTime = 0 ;
lastGiveTime = 0 ;
ammoPulse = false ;
weaponPulse = false ;
armorPulse = false ;
}
/*
= = = = = = = = = = = = = =
idInventory : : GivePowerUp
= = = = = = = = = = = = = =
*/
void idInventory : : GivePowerUp ( idPlayer * player , int powerup , int msec ) {
if ( ! msec ) {
// get the duration from the .def files
const idDeclEntityDef * def = NULL ;
switch ( powerup ) {
case BERSERK :
def = gameLocal . FindEntityDef ( " powerup_berserk " , false ) ;
break ;
case INVISIBILITY :
def = gameLocal . FindEntityDef ( " powerup_invisibility " , false ) ;
break ;
case MEGAHEALTH :
def = gameLocal . FindEntityDef ( " powerup_megahealth " , false ) ;
break ;
2011-12-06 18:20:15 +00:00
case ADRENALINE :
2011-11-22 21:28:15 +00:00
def = gameLocal . FindEntityDef ( " powerup_adrenaline " , false ) ;
break ;
}
assert ( def ) ;
msec = def - > dict . GetInt ( " time " ) * 1000 ;
}
powerups | = 1 < < powerup ;
powerupEndTime [ powerup ] = gameLocal . time + msec ;
}
/*
= = = = = = = = = = = = = =
idInventory : : ClearPowerUps
= = = = = = = = = = = = = =
*/
void idInventory : : ClearPowerUps ( void ) {
int i ;
for ( i = 0 ; i < MAX_POWERUPS ; i + + ) {
powerupEndTime [ i ] = 0 ;
}
powerups = 0 ;
}
/*
= = = = = = = = = = = = = =
idInventory : : GetPersistantData
= = = = = = = = = = = = = =
*/
void idInventory : : GetPersistantData ( idDict & dict ) {
int i ;
int num ;
idDict * item ;
idStr key ;
const idKeyValue * kv ;
const char * name ;
// armor
dict . SetInt ( " armor " , armor ) ;
2011-12-06 18:20:15 +00:00
// don't bother with powerups, maxhealth, maxarmor, or the clip
2011-11-22 21:28:15 +00:00
// ammo
for ( i = 0 ; i < AMMO_NUMTYPES ; i + + ) {
name = idWeapon : : GetAmmoNameForNum ( ( ammo_t ) i ) ;
if ( name ) {
dict . SetInt ( name , ammo [ i ] ) ;
}
}
2018-08-26 03:41:08 +00:00
//Save the clip data
for ( i = 0 ; i < MAX_WEAPONS ; i + + ) { //new
dict . SetInt ( va ( " clip%i " , i ) , clip [ i ] ) ;
}
2011-11-22 21:28:15 +00:00
// items
num = 0 ;
for ( i = 0 ; i < items . Num ( ) ; i + + ) {
item = items [ i ] ;
// copy all keys with "inv_"
kv = item - > MatchPrefix ( " inv_ " ) ;
if ( kv ) {
while ( kv ) {
sprintf ( key , " item_%i %s " , num , kv - > GetKey ( ) . c_str ( ) ) ;
dict . Set ( key , kv - > GetValue ( ) ) ;
kv = item - > MatchPrefix ( " inv_ " , kv ) ;
}
num + + ;
}
}
dict . SetInt ( " items " , num ) ;
// pdas viewed
for ( i = 0 ; i < 4 ; i + + ) {
dict . SetInt ( va ( " pdasViewed_%i " , i ) , pdasViewed [ i ] ) ;
}
dict . SetInt ( " selPDA " , selPDA ) ;
dict . SetInt ( " selVideo " , selVideo ) ;
dict . SetInt ( " selEmail " , selEMail ) ;
dict . SetInt ( " selAudio " , selAudio ) ;
dict . SetInt ( " pdaOpened " , pdaOpened ) ;
dict . SetInt ( " turkeyScore " , turkeyScore ) ;
// pdas
for ( i = 0 ; i < pdas . Num ( ) ; i + + ) {
sprintf ( key , " pda_%i " , i ) ;
dict . Set ( key , pdas [ i ] ) ;
}
dict . SetInt ( " pdas " , pdas . Num ( ) ) ;
// video cds
for ( i = 0 ; i < videos . Num ( ) ; i + + ) {
sprintf ( key , " video_%i " , i ) ;
dict . Set ( key , videos [ i ] . c_str ( ) ) ;
}
dict . SetInt ( " videos " , videos . Num ( ) ) ;
// emails
for ( i = 0 ; i < emails . Num ( ) ; i + + ) {
sprintf ( key , " email_%i " , i ) ;
dict . Set ( key , emails [ i ] . c_str ( ) ) ;
}
dict . SetInt ( " emails " , emails . Num ( ) ) ;
// weapons
dict . SetInt ( " weapon_bits " , weapons ) ;
dict . SetInt ( " levelTriggers " , levelTriggers . Num ( ) ) ;
for ( i = 0 ; i < levelTriggers . Num ( ) ; i + + ) {
sprintf ( key , " levelTrigger_Level_%i " , i ) ;
dict . Set ( key , levelTriggers [ i ] . levelName ) ;
sprintf ( key , " levelTrigger_Trigger_%i " , i ) ;
dict . Set ( key , levelTriggers [ i ] . triggerName ) ;
}
}
/*
= = = = = = = = = = = = = =
idInventory : : RestoreInventory
= = = = = = = = = = = = = =
*/
void idInventory : : RestoreInventory ( idPlayer * owner , const idDict & dict ) {
int i ;
int num ;
idDict * item ;
idStr key ;
idStr itemname ;
const idKeyValue * kv ;
const char * name ;
Clear ( ) ;
// health/armor
maxHealth = dict . GetInt ( " maxhealth " , " 100 " ) ;
armor = dict . GetInt ( " armor " , " 50 " ) ;
maxarmor = dict . GetInt ( " maxarmor " , " 100 " ) ;
deplete_armor = dict . GetInt ( " deplete_armor " , " 0 " ) ;
deplete_rate = dict . GetFloat ( " deplete_rate " , " 2.0 " ) ;
deplete_ammount = dict . GetInt ( " deplete_ammount " , " 1 " ) ;
// the clip and powerups aren't restored
// ammo
for ( i = 0 ; i < AMMO_NUMTYPES ; i + + ) {
name = idWeapon : : GetAmmoNameForNum ( ( ammo_t ) i ) ;
if ( name ) {
ammo [ i ] = dict . GetInt ( name ) ;
}
}
2018-08-26 03:41:08 +00:00
//Restore the clip data
for ( i = 0 ; i < MAX_WEAPONS ; i + + ) { //new
clip [ i ] = dict . GetInt ( va ( " clip%i " , i ) , " -1 " ) ;
}
2011-11-22 21:28:15 +00:00
// items
num = dict . GetInt ( " items " ) ;
items . SetNum ( num ) ;
for ( i = 0 ; i < num ; i + + ) {
item = new idDict ( ) ;
items [ i ] = item ;
sprintf ( itemname , " item_%i " , i ) ;
kv = dict . MatchPrefix ( itemname ) ;
while ( kv ) {
key = kv - > GetKey ( ) ;
key . Strip ( itemname ) ;
item - > Set ( key , kv - > GetValue ( ) ) ;
kv = dict . MatchPrefix ( itemname , kv ) ;
}
}
// pdas viewed
for ( i = 0 ; i < 4 ; i + + ) {
pdasViewed [ i ] = dict . GetInt ( va ( " pdasViewed_%i " , i ) ) ;
}
selPDA = dict . GetInt ( " selPDA " ) ;
selEMail = dict . GetInt ( " selEmail " ) ;
selVideo = dict . GetInt ( " selVideo " ) ;
selAudio = dict . GetInt ( " selAudio " ) ;
pdaOpened = dict . GetBool ( " pdaOpened " ) ;
turkeyScore = dict . GetBool ( " turkeyScore " ) ;
// pdas
num = dict . GetInt ( " pdas " ) ;
pdas . SetNum ( num ) ;
for ( i = 0 ; i < num ; i + + ) {
sprintf ( itemname , " pda_%i " , i ) ;
pdas [ i ] = dict . GetString ( itemname , " default " ) ;
}
// videos
num = dict . GetInt ( " videos " ) ;
videos . SetNum ( num ) ;
for ( i = 0 ; i < num ; i + + ) {
sprintf ( itemname , " video_%i " , i ) ;
videos [ i ] = dict . GetString ( itemname , " default " ) ;
}
// emails
num = dict . GetInt ( " emails " ) ;
emails . SetNum ( num ) ;
for ( i = 0 ; i < num ; i + + ) {
sprintf ( itemname , " email_%i " , i ) ;
emails [ i ] = dict . GetString ( itemname , " default " ) ;
}
// weapons are stored as a number for persistant data, but as strings in the entityDef
weapons = dict . GetInt ( " weapon_bits " , " 0 " ) ;
if ( g_skill . GetInteger ( ) > = 3 ) {
Give ( owner , dict , " weapon " , dict . GetString ( " weapon_nightmare " ) , NULL , false ) ;
} else {
Give ( owner , dict , " weapon " , dict . GetString ( " weapon " ) , NULL , false ) ;
}
num = dict . GetInt ( " levelTriggers " ) ;
for ( i = 0 ; i < num ; i + + ) {
sprintf ( itemname , " levelTrigger_Level_%i " , i ) ;
idLevelTriggerInfo lti ;
lti . levelName = dict . GetString ( itemname ) ;
sprintf ( itemname , " levelTrigger_Trigger_%i " , i ) ;
lti . triggerName = dict . GetString ( itemname ) ;
levelTriggers . Append ( lti ) ;
}
}
/*
= = = = = = = = = = = = = =
idInventory : : Save
= = = = = = = = = = = = = =
*/
void idInventory : : Save ( idSaveGame * savefile ) const {
int i ;
savefile - > WriteInt ( maxHealth ) ;
savefile - > WriteInt ( weapons ) ;
savefile - > WriteInt ( powerups ) ;
savefile - > WriteInt ( armor ) ;
savefile - > WriteInt ( maxarmor ) ;
savefile - > WriteInt ( ammoPredictTime ) ;
savefile - > WriteInt ( deplete_armor ) ;
savefile - > WriteFloat ( deplete_rate ) ;
savefile - > WriteInt ( deplete_ammount ) ;
savefile - > WriteInt ( nextArmorDepleteTime ) ;
for ( i = 0 ; i < AMMO_NUMTYPES ; i + + ) {
savefile - > WriteInt ( ammo [ i ] ) ;
}
for ( i = 0 ; i < MAX_WEAPONS ; i + + ) {
savefile - > WriteInt ( clip [ i ] ) ;
}
for ( i = 0 ; i < MAX_POWERUPS ; i + + ) {
savefile - > WriteInt ( powerupEndTime [ i ] ) ;
}
savefile - > WriteInt ( items . Num ( ) ) ;
for ( i = 0 ; i < items . Num ( ) ; i + + ) {
savefile - > WriteDict ( items [ i ] ) ;
}
savefile - > WriteInt ( pdasViewed [ 0 ] ) ;
savefile - > WriteInt ( pdasViewed [ 1 ] ) ;
savefile - > WriteInt ( pdasViewed [ 2 ] ) ;
savefile - > WriteInt ( pdasViewed [ 3 ] ) ;
2011-12-06 18:20:15 +00:00
2011-11-22 21:28:15 +00:00
savefile - > WriteInt ( selPDA ) ;
savefile - > WriteInt ( selVideo ) ;
savefile - > WriteInt ( selEMail ) ;
savefile - > WriteInt ( selAudio ) ;
savefile - > WriteBool ( pdaOpened ) ;
savefile - > WriteBool ( turkeyScore ) ;
savefile - > WriteInt ( pdas . Num ( ) ) ;
for ( i = 0 ; i < pdas . Num ( ) ; i + + ) {
savefile - > WriteString ( pdas [ i ] ) ;
}
savefile - > WriteInt ( pdaSecurity . Num ( ) ) ;
for ( i = 0 ; i < pdaSecurity . Num ( ) ; i + + ) {
savefile - > WriteString ( pdaSecurity [ i ] ) ;
}
savefile - > WriteInt ( videos . Num ( ) ) ;
for ( i = 0 ; i < videos . Num ( ) ; i + + ) {
savefile - > WriteString ( videos [ i ] ) ;
}
savefile - > WriteInt ( emails . Num ( ) ) ;
for ( i = 0 ; i < emails . Num ( ) ; i + + ) {
savefile - > WriteString ( emails [ i ] ) ;
}
savefile - > WriteInt ( nextItemPickup ) ;
savefile - > WriteInt ( nextItemNum ) ;
savefile - > WriteInt ( onePickupTime ) ;
savefile - > WriteInt ( pickupItemNames . Num ( ) ) ;
for ( i = 0 ; i < pickupItemNames . Num ( ) ; i + + ) {
savefile - > WriteString ( pickupItemNames [ i ] . icon ) ;
savefile - > WriteString ( pickupItemNames [ i ] . name ) ;
}
savefile - > WriteInt ( objectiveNames . Num ( ) ) ;
for ( i = 0 ; i < objectiveNames . Num ( ) ; i + + ) {
savefile - > WriteString ( objectiveNames [ i ] . screenshot ) ;
savefile - > WriteString ( objectiveNames [ i ] . text ) ;
savefile - > WriteString ( objectiveNames [ i ] . title ) ;
}
savefile - > WriteInt ( levelTriggers . Num ( ) ) ;
for ( i = 0 ; i < levelTriggers . Num ( ) ; i + + ) {
savefile - > WriteString ( levelTriggers [ i ] . levelName ) ;
savefile - > WriteString ( levelTriggers [ i ] . triggerName ) ;
}
savefile - > WriteBool ( ammoPulse ) ;
savefile - > WriteBool ( weaponPulse ) ;
savefile - > WriteBool ( armorPulse ) ;
savefile - > WriteInt ( lastGiveTime ) ;
}
/*
= = = = = = = = = = = = = =
idInventory : : Restore
= = = = = = = = = = = = = =
*/
void idInventory : : Restore ( idRestoreGame * savefile ) {
int i , num ;
savefile - > ReadInt ( maxHealth ) ;
savefile - > ReadInt ( weapons ) ;
savefile - > ReadInt ( powerups ) ;
savefile - > ReadInt ( armor ) ;
savefile - > ReadInt ( maxarmor ) ;
savefile - > ReadInt ( ammoPredictTime ) ;
savefile - > ReadInt ( deplete_armor ) ;
savefile - > ReadFloat ( deplete_rate ) ;
savefile - > ReadInt ( deplete_ammount ) ;
savefile - > ReadInt ( nextArmorDepleteTime ) ;
for ( i = 0 ; i < AMMO_NUMTYPES ; i + + ) {
savefile - > ReadInt ( ammo [ i ] ) ;
}
for ( i = 0 ; i < MAX_WEAPONS ; i + + ) {
savefile - > ReadInt ( clip [ i ] ) ;
}
for ( i = 0 ; i < MAX_POWERUPS ; i + + ) {
savefile - > ReadInt ( powerupEndTime [ i ] ) ;
}
savefile - > ReadInt ( num ) ;
for ( i = 0 ; i < num ; i + + ) {
idDict * itemdict = new idDict ;
savefile - > ReadDict ( itemdict ) ;
items . Append ( itemdict ) ;
}
// pdas
savefile - > ReadInt ( pdasViewed [ 0 ] ) ;
savefile - > ReadInt ( pdasViewed [ 1 ] ) ;
savefile - > ReadInt ( pdasViewed [ 2 ] ) ;
savefile - > ReadInt ( pdasViewed [ 3 ] ) ;
2011-12-06 18:20:15 +00:00
2011-11-22 21:28:15 +00:00
savefile - > ReadInt ( selPDA ) ;
savefile - > ReadInt ( selVideo ) ;
savefile - > ReadInt ( selEMail ) ;
savefile - > ReadInt ( selAudio ) ;
savefile - > ReadBool ( pdaOpened ) ;
savefile - > ReadBool ( turkeyScore ) ;
savefile - > ReadInt ( num ) ;
for ( i = 0 ; i < num ; i + + ) {
idStr strPda ;
savefile - > ReadString ( strPda ) ;
pdas . Append ( strPda ) ;
}
// pda security clearances
savefile - > ReadInt ( num ) ;
for ( i = 0 ; i < num ; i + + ) {
idStr invName ;
savefile - > ReadString ( invName ) ;
pdaSecurity . Append ( invName ) ;
}
// videos
savefile - > ReadInt ( num ) ;
for ( i = 0 ; i < num ; i + + ) {
idStr strVideo ;
savefile - > ReadString ( strVideo ) ;
videos . Append ( strVideo ) ;
}
// email
savefile - > ReadInt ( num ) ;
for ( i = 0 ; i < num ; i + + ) {
idStr strEmail ;
savefile - > ReadString ( strEmail ) ;
emails . Append ( strEmail ) ;
}
savefile - > ReadInt ( nextItemPickup ) ;
savefile - > ReadInt ( nextItemNum ) ;
savefile - > ReadInt ( onePickupTime ) ;
savefile - > ReadInt ( num ) ;
for ( i = 0 ; i < num ; i + + ) {
idItemInfo info ;
savefile - > ReadString ( info . icon ) ;
savefile - > ReadString ( info . name ) ;
pickupItemNames . Append ( info ) ;
}
savefile - > ReadInt ( num ) ;
for ( i = 0 ; i < num ; i + + ) {
idObjectiveInfo obj ;
savefile - > ReadString ( obj . screenshot ) ;
savefile - > ReadString ( obj . text ) ;
savefile - > ReadString ( obj . title ) ;
objectiveNames . Append ( obj ) ;
}
savefile - > ReadInt ( num ) ;
for ( i = 0 ; i < num ; i + + ) {
idLevelTriggerInfo lti ;
savefile - > ReadString ( lti . levelName ) ;
savefile - > ReadString ( lti . triggerName ) ;
levelTriggers . Append ( lti ) ;
}
savefile - > ReadBool ( ammoPulse ) ;
savefile - > ReadBool ( weaponPulse ) ;
savefile - > ReadBool ( armorPulse ) ;
savefile - > ReadInt ( lastGiveTime ) ;
}
/*
= = = = = = = = = = = = = =
idInventory : : AmmoIndexForAmmoClass
= = = = = = = = = = = = = =
*/
ammo_t idInventory : : AmmoIndexForAmmoClass ( const char * ammo_classname ) const {
return idWeapon : : GetAmmoNumForName ( ammo_classname ) ;
}
/*
= = = = = = = = = = = = = =
idInventory : : AmmoIndexForAmmoClass
= = = = = = = = = = = = = =
*/
int idInventory : : MaxAmmoForAmmoClass ( idPlayer * owner , const char * ammo_classname ) const {
return owner - > spawnArgs . GetInt ( va ( " max_%s " , ammo_classname ) , " 0 " ) ;
}
/*
= = = = = = = = = = = = = =
idInventory : : AmmoPickupNameForIndex
= = = = = = = = = = = = = =
*/
const char * idInventory : : AmmoPickupNameForIndex ( ammo_t ammonum ) const {
return idWeapon : : GetAmmoPickupNameForNum ( ammonum ) ;
}
/*
= = = = = = = = = = = = = =
idInventory : : WeaponIndexForAmmoClass
mapping could be prepared in the constructor
= = = = = = = = = = = = = =
*/
int idInventory : : WeaponIndexForAmmoClass ( const idDict & spawnArgs , const char * ammo_classname ) const {
int i ;
const char * weapon_classname ;
for ( i = 0 ; i < MAX_WEAPONS ; i + + ) {
weapon_classname = spawnArgs . GetString ( va ( " def_weapon%d " , i ) ) ;
if ( ! weapon_classname ) {
continue ;
}
const idDeclEntityDef * decl = gameLocal . FindEntityDef ( weapon_classname , false ) ;
if ( ! decl ) {
continue ;
}
if ( ! idStr : : Icmp ( ammo_classname , decl - > dict . GetString ( " ammoType " ) ) ) {
return i ;
}
}
return - 1 ;
}
/*
= = = = = = = = = = = = = =
idInventory : : AmmoIndexForWeaponClass
= = = = = = = = = = = = = =
*/
ammo_t idInventory : : AmmoIndexForWeaponClass ( const char * weapon_classname , int * ammoRequired ) {
const idDeclEntityDef * decl = gameLocal . FindEntityDef ( weapon_classname , false ) ;
if ( ! decl ) {
gameLocal . Error ( " Unknown weapon in decl '%s' " , weapon_classname ) ;
}
if ( ammoRequired ) {
* ammoRequired = decl - > dict . GetInt ( " ammoRequired " ) ;
}
ammo_t ammo_i = AmmoIndexForAmmoClass ( decl - > dict . GetString ( " ammoType " ) ) ;
return ammo_i ;
}
/*
= = = = = = = = = = = = = =
idInventory : : AddPickupName
= = = = = = = = = = = = = =
*/
2018-08-26 03:41:08 +00:00
//void idInventory::AddPickupName( const char *name, const char *icon ) {
void idInventory : : AddPickupName ( const char * name , const char * icon , idPlayer * owner ) { //New, Dont know what it does
2011-11-22 21:28:15 +00:00
int num ;
num = pickupItemNames . Num ( ) ;
if ( ( num = = 0 ) | | ( pickupItemNames [ num - 1 ] . name . Icmp ( name ) ! = 0 ) ) {
idItemInfo & info = pickupItemNames . Alloc ( ) ;
if ( idStr : : Cmpn ( name , STRTABLE_ID , STRTABLE_ID_LENGTH ) = = 0 ) {
info . name = common - > GetLanguageDict ( ) - > GetString ( name ) ;
} else {
info . name = name ;
}
info . icon = icon ;
2018-08-26 03:41:08 +00:00
if ( gameLocal . isServer ) {
idBitMsg msg ;
byte msgBuf [ MAX_EVENT_PARAM_SIZE ] ;
msg . Init ( msgBuf , sizeof ( msgBuf ) ) ;
msg . WriteString ( name , MAX_EVENT_PARAM_SIZE ) ;
owner - > ServerSendEvent ( idPlayer : : EVENT_PICKUPNAME , & msg , false , - 1 ) ;
}
2011-12-06 18:20:15 +00:00
}
2011-11-22 21:28:15 +00:00
}
/*
= = = = = = = = = = = = = =
idInventory : : Give
= = = = = = = = = = = = = =
*/
bool idInventory : : Give ( idPlayer * owner , const idDict & spawnArgs , const char * statname , const char * value , int * idealWeapon , bool updateHud ) {
int i ;
const char * pos ;
const char * end ;
int len ;
idStr weaponString ;
int max ;
const idDeclEntityDef * weaponDecl ;
bool tookWeapon ;
int amount ;
idItemInfo info ;
const char * name ;
if ( ! idStr : : Icmpn ( statname , " ammo_ " , 5 ) ) {
i = AmmoIndexForAmmoClass ( statname ) ;
max = MaxAmmoForAmmoClass ( owner , statname ) ;
if ( ammo [ i ] > = max ) {
return false ;
}
amount = atoi ( value ) ;
2011-12-06 18:20:15 +00:00
if ( amount ) {
2011-11-22 21:28:15 +00:00
ammo [ i ] + = amount ;
if ( ( max > 0 ) & & ( ammo [ i ] > max ) ) {
ammo [ i ] = max ;
}
ammoPulse = true ;
name = AmmoPickupNameForIndex ( i ) ;
if ( idStr : : Length ( name ) ) {
2018-08-26 03:41:08 +00:00
AddPickupName ( name , " " , owner ) ; //new _D3XP
2011-11-22 21:28:15 +00:00
}
}
} else if ( ! idStr : : Icmp ( statname , " armor " ) ) {
if ( armor > = maxarmor ) {
return false ; // can't hold any more, so leave the item
}
amount = atoi ( value ) ;
if ( amount ) {
armor + = amount ;
if ( armor > maxarmor ) {
armor = maxarmor ;
}
nextArmorDepleteTime = 0 ;
armorPulse = true ;
}
} else if ( idStr : : FindText ( statname , " inclip_ " ) = = 0 ) {
i = WeaponIndexForAmmoClass ( spawnArgs , statname + 7 ) ;
if ( i ! = - 1 ) {
// set, don't add. not going over the clip size limit.
2018-08-26 03:41:08 +00:00
// clip[ i ] = atoi( value ); // FIXME: what about this?
2011-11-22 21:28:15 +00:00
}
} else if ( ! idStr : : Icmp ( statname , " berserk " ) ) {
GivePowerUp ( owner , BERSERK , SEC2MS ( atof ( value ) ) ) ;
} else if ( ! idStr : : Icmp ( statname , " mega " ) ) {
GivePowerUp ( owner , MEGAHEALTH , SEC2MS ( atof ( value ) ) ) ;
} else if ( ! idStr : : Icmp ( statname , " weapon " ) ) {
tookWeapon = false ;
for ( pos = value ; pos ! = NULL ; pos = end ) {
end = strchr ( pos , ' , ' ) ;
if ( end ) {
len = end - pos ;
end + + ;
} else {
len = strlen ( pos ) ;
}
idStr weaponName ( pos , 0 , len ) ;
// find the number of the matching weapon name
for ( i = 0 ; i < MAX_WEAPONS ; i + + ) {
if ( weaponName = = spawnArgs . GetString ( va ( " def_weapon%d " , i ) ) ) {
break ;
}
}
if ( i > = MAX_WEAPONS ) {
2018-08-26 03:41:08 +00:00
gameLocal . Warning ( " Unknown weapon '%s' " , weaponName . c_str ( ) ) ;
continue ;
2011-11-22 21:28:15 +00:00
}
// cache the media for this weapon
weaponDecl = gameLocal . FindEntityDef ( weaponName , false ) ;
// don't pickup "no ammo" weapon types twice
// not for D3 SP .. there is only one case in the game where you can get a no ammo
// weapon when you might already have it, in that case it is more conistent to pick it up
if ( gameLocal . isMultiplayer & & weaponDecl & & ( weapons & ( 1 < < i ) ) & & ! weaponDecl - > dict . GetInt ( " ammoRequired " ) ) {
continue ;
}
if ( ! gameLocal . world - > spawnArgs . GetBool ( " no_Weapons " ) | | ( weaponName = = " weapon_fists " ) | | ( weaponName = = " weapon_soulcube " ) ) {
if ( ( weapons & ( 1 < < i ) ) = = 0 | | gameLocal . isMultiplayer ) {
if ( owner - > hud & & updateHud & & lastGiveTime + 1000 < gameLocal . time ) {
owner - > hud - > SetStateInt ( " newWeapon " , i ) ;
owner - > hud - > HandleNamedEvent ( " newWeapon " ) ;
lastGiveTime = gameLocal . time ;
}
weaponPulse = true ;
weapons | = ( 1 < < i ) ;
tookWeapon = true ;
}
}
}
return tookWeapon ;
} else if ( ! idStr : : Icmp ( statname , " item " ) | | ! idStr : : Icmp ( statname , " icon " ) | | ! idStr : : Icmp ( statname , " name " ) ) {
// ignore these as they're handled elsewhere
return false ;
} else {
// unknown item
gameLocal . Warning ( " Unknown stat '%s' added to player's inventory " , statname ) ;
return false ;
}
return true ;
}
/*
= = = = = = = = = = = = = = =
idInventoy : : Drop
= = = = = = = = = = = = = = =
*/
void idInventory : : Drop ( const idDict & spawnArgs , const char * weapon_classname , int weapon_index ) {
// remove the weapon bit
// also remove the ammo associated with the weapon as we pushed it in the item
assert ( weapon_index ! = - 1 | | weapon_classname ) ;
if ( weapon_index = = - 1 ) {
for ( weapon_index = 0 ; weapon_index < MAX_WEAPONS ; weapon_index + + ) {
if ( ! idStr : : Icmp ( weapon_classname , spawnArgs . GetString ( va ( " def_weapon%d " , weapon_index ) ) ) ) {
break ;
}
}
if ( weapon_index > = MAX_WEAPONS ) {
gameLocal . Error ( " Unknown weapon '%s' " , weapon_classname ) ;
}
} else if ( ! weapon_classname ) {
weapon_classname = spawnArgs . GetString ( va ( " def_weapon%d " , weapon_index ) ) ;
}
weapons & = ( 0xffffffff ^ ( 1 < < weapon_index ) ) ;
ammo_t ammo_i = AmmoIndexForWeaponClass ( weapon_classname , NULL ) ;
if ( ammo_i ) {
clip [ weapon_index ] = - 1 ;
ammo [ ammo_i ] = 0 ;
}
}
/*
= = = = = = = = = = = = = = =
idInventory : : HasAmmo
= = = = = = = = = = = = = = =
*/
int idInventory : : HasAmmo ( ammo_t type , int amount ) {
if ( ( type = = 0 ) | | ! amount ) {
// always allow weapons that don't use ammo to fire
return - 1 ;
}
// check if we have infinite ammo
if ( ammo [ type ] < 0 ) {
return - 1 ;
}
// return how many shots we can fire
return ammo [ type ] / amount ;
}
/*
= = = = = = = = = = = = = = =
idInventory : : HasAmmo
= = = = = = = = = = = = = = =
*/
2018-08-26 03:41:08 +00:00
int idInventory : : HasAmmo ( const char * weapon_classname , bool includeClip , idPlayer * owner ) { //_D3XP
2011-11-22 21:28:15 +00:00
int ammoRequired ;
ammo_t ammo_i = AmmoIndexForWeaponClass ( weapon_classname , & ammoRequired ) ;
2018-08-26 03:41:08 +00:00
int ammoCount = HasAmmo ( ammo_i , ammoRequired ) ;
if ( includeClip & & owner ) {
ammoCount + = clip [ owner - > SlotForWeapon ( weapon_classname ) ] ;
}
return ammoCount ;
2011-11-22 21:28:15 +00:00
}
/*
= = = = = = = = = = = = = = =
idInventory : : UseAmmo
= = = = = = = = = = = = = = =
*/
bool idInventory : : UseAmmo ( ammo_t type , int amount ) {
if ( ! HasAmmo ( type , amount ) ) {
return false ;
}
// take an ammo away if not infinite
if ( ammo [ type ] > = 0 ) {
ammo [ type ] - = amount ;
ammoPredictTime = gameLocal . time ; // mp client: we predict this. mark time so we're not confused by snapshots
}
return true ;
}
/*
= = = = = = = = = = = = = = =
idInventory : : UpdateArmor
= = = = = = = = = = = = = = =
*/
void idInventory : : UpdateArmor ( void ) {
if ( deplete_armor ! = 0.0f & & deplete_armor < armor ) {
if ( ! nextArmorDepleteTime ) {
nextArmorDepleteTime = gameLocal . time + deplete_rate * 1000 ;
} else if ( gameLocal . time > nextArmorDepleteTime ) {
armor - = deplete_ammount ;
if ( armor < deplete_armor ) {
armor = deplete_armor ;
}
nextArmorDepleteTime = gameLocal . time + deplete_rate * 1000 ;
}
}
}
/*
= = = = = = = = = = = = = =
idPlayer : : idPlayer
= = = = = = = = = = = = = =
*/
idPlayer : : idPlayer ( ) {
memset ( & usercmd , 0 , sizeof ( usercmd ) ) ;
noclip = false ;
godmode = false ;
spawnAnglesSet = false ;
spawnAngles = ang_zero ;
viewAngles = ang_zero ;
cmdAngles = ang_zero ;
oldButtons = 0 ;
buttonMask = 0 ;
oldFlags = 0 ;
lastHitTime = 0 ;
lastSndHitTime = 0 ;
lastSavingThrowTime = 0 ;
weapon = NULL ;
hud = NULL ;
objectiveSystem = NULL ;
objectiveSystemOpen = false ;
heartRate = BASE_HEARTRATE ;
heartInfo . Init ( 0 , 0 , 0 , 0 ) ;
lastHeartAdjust = 0 ;
lastHeartBeat = 0 ;
lastDmgTime = 0 ;
deathClearContentsTime = 0 ;
lastArmorPulse = - 10000 ;
stamina = 0.0f ;
healthPool = 0.0f ;
nextHealthPulse = 0 ;
healthPulse = false ;
nextHealthTake = 0 ;
healthTake = false ;
scoreBoardOpen = false ;
forceScoreBoard = false ;
forceRespawn = false ;
spectating = false ;
spectator = 0 ;
colorBar = vec3_zero ;
colorBarIndex = 0 ;
forcedReady = false ;
wantSpectate = false ;
lastHitToggle = false ;
minRespawnTime = 0 ;
maxRespawnTime = 0 ;
firstPersonViewOrigin = vec3_zero ;
firstPersonViewAxis = mat3_identity ;
hipJoint = INVALID_JOINT ;
chestJoint = INVALID_JOINT ;
headJoint = INVALID_JOINT ;
bobFoot = 0 ;
bobFrac = 0.0f ;
bobfracsin = 0.0f ;
bobCycle = 0 ;
xyspeed = 0.0f ;
stepUpTime = 0 ;
stepUpDelta = 0.0f ;
idealLegsYaw = 0.0f ;
legsYaw = 0.0f ;
legsForward = true ;
oldViewYaw = 0.0f ;
viewBobAngles = ang_zero ;
viewBob = vec3_zero ;
landChange = 0 ;
landTime = 0 ;
currentWeapon = - 1 ;
idealWeapon = - 1 ;
previousWeapon = - 1 ;
2018-08-26 03:41:08 +00:00
quickWeapon = - 1 ; //new
2011-11-22 21:28:15 +00:00
weaponSwitchTime = 0 ;
weaponEnabled = true ;
weapon_soulcube = - 1 ;
weapon_pda = - 1 ;
weapon_fists = - 1 ;
showWeaponViewModel = true ;
skin = NULL ;
powerUpSkin = NULL ;
baseSkinName = " " ;
numProjectilesFired = 0 ;
numProjectileHits = 0 ;
airless = false ;
airTics = 0 ;
lastAirDamage = 0 ;
gibDeath = false ;
gibsLaunched = false ;
gibsDir = vec3_zero ;
zoomFov . Init ( 0 , 0 , 0 , 0 ) ;
centerView . Init ( 0 , 0 , 0 , 0 ) ;
fxFov = false ;
influenceFov = 0 ;
influenceActive = 0 ;
influenceRadius = 0.0f ;
influenceEntity = NULL ;
influenceMaterial = NULL ;
influenceSkin = NULL ;
privateCameraView = NULL ;
memset ( loggedViewAngles , 0 , sizeof ( loggedViewAngles ) ) ;
memset ( loggedAccel , 0 , sizeof ( loggedAccel ) ) ;
currentLoggedAccel = 0 ;
focusTime = 0 ;
focusGUIent = NULL ;
focusUI = NULL ;
focusCharacter = NULL ;
talkCursor = 0 ;
focusVehicle = NULL ;
cursor = NULL ;
2011-12-06 18:20:15 +00:00
2011-11-22 21:28:15 +00:00
oldMouseX = 0 ;
oldMouseY = 0 ;
pdaAudio = " " ;
pdaVideo = " " ;
pdaVideoWave = " " ;
lastDamageDef = 0 ;
lastDamageDir = vec3_zero ;
lastDamageLocation = 0 ;
smoothedFrame = 0 ;
smoothedOriginUpdated = false ;
smoothedOrigin = vec3_zero ;
smoothedAngles = ang_zero ;
fl . networkSync = true ;
latchedTeam = - 1 ;
doingDeathSkin = false ;
weaponGone = false ;
useInitialSpawns = false ;
tourneyRank = 0 ;
lastSpectateTeleport = 0 ;
tourneyLine = 0 ;
hiddenWeapon = false ;
tipUp = false ;
objectiveUp = false ;
teleportEntity = NULL ;
teleportKiller = - 1 ;
respawning = false ;
ready = false ;
leader = false ;
lastSpectateChange = 0 ;
lastTeleFX = - 9999 ;
weaponCatchup = false ;
lastSnapshotSequence = 0 ;
MPAim = - 1 ;
lastMPAim = - 1 ;
lastMPAimTime = 0 ;
MPAimFadeTime = 0 ;
MPAimHighlight = false ;
spawnedTime = 0 ;
lastManOver = false ;
lastManPlayAgain = false ;
lastManPresent = false ;
isTelefragged = false ;
isLagged = false ;
isChatting = false ;
selfSmooth = false ;
2018-08-26 03:41:08 +00:00
# ifdef _DENTONMOD_PLAYER_CPP
memset ( & weaponZoom , 0 , sizeof ( weaponZoom ) ) ; // New
memset ( projectileType , 0 , sizeof ( projectileType ) ) ;
# endif //_DENTONMOD_PLAYER_CPP
2011-11-22 21:28:15 +00:00
}
/*
= = = = = = = = = = = = = =
idPlayer : : LinkScriptVariables
set up conditions for animation
= = = = = = = = = = = = = =
*/
void idPlayer : : LinkScriptVariables ( void ) {
AI_FORWARD . LinkTo ( scriptObject , " AI_FORWARD " ) ;
AI_BACKWARD . LinkTo ( scriptObject , " AI_BACKWARD " ) ;
AI_STRAFE_LEFT . LinkTo ( scriptObject , " AI_STRAFE_LEFT " ) ;
AI_STRAFE_RIGHT . LinkTo ( scriptObject , " AI_STRAFE_RIGHT " ) ;
AI_ATTACK_HELD . LinkTo ( scriptObject , " AI_ATTACK_HELD " ) ;
AI_WEAPON_FIRED . LinkTo ( scriptObject , " AI_WEAPON_FIRED " ) ;
AI_JUMP . LinkTo ( scriptObject , " AI_JUMP " ) ;
AI_DEAD . LinkTo ( scriptObject , " AI_DEAD " ) ;
AI_CROUCH . LinkTo ( scriptObject , " AI_CROUCH " ) ;
AI_ONGROUND . LinkTo ( scriptObject , " AI_ONGROUND " ) ;
AI_ONLADDER . LinkTo ( scriptObject , " AI_ONLADDER " ) ;
AI_HARDLANDING . LinkTo ( scriptObject , " AI_HARDLANDING " ) ;
AI_SOFTLANDING . LinkTo ( scriptObject , " AI_SOFTLANDING " ) ;
AI_RUN . LinkTo ( scriptObject , " AI_RUN " ) ;
AI_PAIN . LinkTo ( scriptObject , " AI_PAIN " ) ;
AI_RELOAD . LinkTo ( scriptObject , " AI_RELOAD " ) ;
AI_TELEPORT . LinkTo ( scriptObject , " AI_TELEPORT " ) ;
AI_TURN_LEFT . LinkTo ( scriptObject , " AI_TURN_LEFT " ) ;
AI_TURN_RIGHT . LinkTo ( scriptObject , " AI_TURN_RIGHT " ) ;
}
/*
= = = = = = = = = = = = = =
idPlayer : : SetupWeaponEntity
= = = = = = = = = = = = = =
*/
void idPlayer : : SetupWeaponEntity ( void ) {
int w ;
const char * weap ;
if ( weapon . GetEntity ( ) ) {
// get rid of old weapon
weapon . GetEntity ( ) - > Clear ( ) ;
currentWeapon = - 1 ;
} else if ( ! gameLocal . isClient ) {
weapon = static_cast < idWeapon * > ( gameLocal . SpawnEntityType ( idWeapon : : Type , NULL ) ) ;
weapon . GetEntity ( ) - > SetOwner ( this ) ;
currentWeapon = - 1 ;
}
for ( w = 0 ; w < MAX_WEAPONS ; w + + ) {
weap = spawnArgs . GetString ( va ( " def_weapon%d " , w ) ) ;
if ( weap & & * weap ) {
idWeapon : : CacheWeapon ( weap ) ;
}
}
}
/*
= = = = = = = = = = = = = =
idPlayer : : Init
= = = = = = = = = = = = = =
*/
void idPlayer : : Init ( void ) {
const char * value ;
const idKeyValue * kv ;
noclip = false ;
godmode = false ;
oldButtons = 0 ;
oldFlags = 0 ;
2018-08-26 03:41:08 +00:00
# ifdef _DENTONMOD_PLAYER_CPP
memset ( & weaponZoom , 0 , sizeof ( weaponZoom ) ) ; // New
# endif //_DENTONMOD_PLAYER_CPP
2011-11-22 21:28:15 +00:00
currentWeapon = - 1 ;
idealWeapon = - 1 ;
previousWeapon = - 1 ;
2018-08-26 03:41:08 +00:00
quickWeapon = - 1 ; //new
2011-11-22 21:28:15 +00:00
weaponSwitchTime = 0 ;
weaponEnabled = true ;
weapon_soulcube = SlotForWeapon ( " weapon_soulcube " ) ;
weapon_pda = SlotForWeapon ( " weapon_pda " ) ;
weapon_fists = SlotForWeapon ( " weapon_fists " ) ;
showWeaponViewModel = GetUserInfo ( ) - > GetBool ( " ui_showGun " ) ;
lastDmgTime = 0 ;
lastArmorPulse = - 10000 ;
lastHeartAdjust = 0 ;
lastHeartBeat = 0 ;
heartInfo . Init ( 0 , 0 , 0 , 0 ) ;
bobCycle = 0 ;
bobFrac = 0.0f ;
landChange = 0 ;
landTime = 0 ;
zoomFov . Init ( 0 , 0 , 0 , 0 ) ;
centerView . Init ( 0 , 0 , 0 , 0 ) ;
fxFov = false ;
influenceFov = 0 ;
influenceActive = 0 ;
influenceRadius = 0.0f ;
influenceEntity = NULL ;
influenceMaterial = NULL ;
influenceSkin = NULL ;
currentLoggedAccel = 0 ;
focusTime = 0 ;
focusGUIent = NULL ;
focusUI = NULL ;
focusCharacter = NULL ;
talkCursor = 0 ;
focusVehicle = NULL ;
// remove any damage effects
playerView . ClearEffects ( ) ;
// damage values
fl . takedamage = true ;
ClearPain ( ) ;
// restore persistent data
RestorePersistantInfo ( ) ;
bobCycle = 0 ;
stamina = 0.0f ;
healthPool = 0.0f ;
nextHealthPulse = 0 ;
healthPulse = false ;
nextHealthTake = 0 ;
healthTake = false ;
SetupWeaponEntity ( ) ;
currentWeapon = - 1 ;
previousWeapon = - 1 ;
2018-08-26 03:41:08 +00:00
quickWeapon = - 1 ; //new
2011-11-22 21:28:15 +00:00
heartRate = BASE_HEARTRATE ;
AdjustHeartRate ( BASE_HEARTRATE , 0.0f , 0.0f , true ) ;
idealLegsYaw = 0.0f ;
legsYaw = 0.0f ;
legsForward = true ;
oldViewYaw = 0.0f ;
// set the pm_ cvars
if ( ! gameLocal . isMultiplayer | | gameLocal . isServer ) {
kv = spawnArgs . MatchPrefix ( " pm_ " , NULL ) ;
while ( kv ) {
cvarSystem - > SetCVarString ( kv - > GetKey ( ) , kv - > GetValue ( ) ) ;
kv = spawnArgs . MatchPrefix ( " pm_ " , kv ) ;
}
}
// disable stamina on hell levels
if ( gameLocal . world & & gameLocal . world - > spawnArgs . GetBool ( " no_stamina " ) ) {
pm_stamina . SetFloat ( 0.0f ) ;
}
// stamina always initialized to maximum
stamina = pm_stamina . GetFloat ( ) ;
// air always initialized to maximum too
airTics = pm_airTics . GetFloat ( ) ;
airless = false ;
gibDeath = false ;
gibsLaunched = false ;
gibsDir . Zero ( ) ;
// set the gravity
physicsObj . SetGravity ( gameLocal . GetGravity ( ) ) ;
// start out standing
SetEyeHeight ( pm_normalviewheight . GetFloat ( ) ) ;
stepUpTime = 0 ;
stepUpDelta = 0.0f ;
viewBobAngles . Zero ( ) ;
viewBob . Zero ( ) ;
value = spawnArgs . GetString ( " model " ) ;
if ( value & & ( * value ! = 0 ) ) {
SetModel ( value ) ;
}
if ( cursor ) {
cursor - > SetStateInt ( " talkcursor " , 0 ) ;
cursor - > SetStateString ( " combatcursor " , " 1 " ) ;
cursor - > SetStateString ( " itemcursor " , " 0 " ) ;
cursor - > SetStateString ( " guicursor " , " 0 " ) ;
}
if ( ( gameLocal . isMultiplayer | | g_testDeath . GetBool ( ) ) & & skin ) {
SetSkin ( skin ) ;
renderEntity . shaderParms [ 6 ] = 0.0f ;
} else if ( spawnArgs . GetString ( " spawn_skin " , NULL , & value ) ) {
skin = declManager - > FindSkin ( value ) ;
SetSkin ( skin ) ;
renderEntity . shaderParms [ 6 ] = 0.0f ;
}
value = spawnArgs . GetString ( " bone_hips " , " " ) ;
hipJoint = animator . GetJointHandle ( value ) ;
if ( hipJoint = = INVALID_JOINT ) {
gameLocal . Error ( " Joint '%s' not found for 'bone_hips' on '%s' " , value , name . c_str ( ) ) ;
}
value = spawnArgs . GetString ( " bone_chest " , " " ) ;
chestJoint = animator . GetJointHandle ( value ) ;
if ( chestJoint = = INVALID_JOINT ) {
gameLocal . Error ( " Joint '%s' not found for 'bone_chest' on '%s' " , value , name . c_str ( ) ) ;
}
value = spawnArgs . GetString ( " bone_head " , " " ) ;
headJoint = animator . GetJointHandle ( value ) ;
if ( headJoint = = INVALID_JOINT ) {
gameLocal . Error ( " Joint '%s' not found for 'bone_head' on '%s' " , value , name . c_str ( ) ) ;
}
// initialize the script variables
AI_FORWARD = false ;
AI_BACKWARD = false ;
AI_STRAFE_LEFT = false ;
AI_STRAFE_RIGHT = false ;
AI_ATTACK_HELD = false ;
AI_WEAPON_FIRED = false ;
AI_JUMP = false ;
AI_DEAD = false ;
AI_CROUCH = false ;
AI_ONGROUND = true ;
AI_ONLADDER = false ;
AI_HARDLANDING = false ;
AI_SOFTLANDING = false ;
AI_RUN = false ;
AI_PAIN = false ;
AI_RELOAD = false ;
AI_TELEPORT = false ;
AI_TURN_LEFT = false ;
AI_TURN_RIGHT = false ;
// reset the script object
ConstructScriptObject ( ) ;
// execute the script so the script object's constructor takes effect immediately
scriptThread - > Execute ( ) ;
2011-12-06 18:20:15 +00:00
2011-11-22 21:28:15 +00:00
forceScoreBoard = false ;
forcedReady = false ;
privateCameraView = NULL ;
lastSpectateChange = 0 ;
lastTeleFX = - 9999 ;
hiddenWeapon = false ;
tipUp = false ;
objectiveUp = false ;
teleportEntity = NULL ;
teleportKiller = - 1 ;
leader = false ;
SetPrivateCameraView ( NULL ) ;
lastSnapshotSequence = 0 ;
MPAim = - 1 ;
lastMPAim = - 1 ;
lastMPAimTime = 0 ;
MPAimFadeTime = 0 ;
MPAimHighlight = false ;
if ( hud ) {
hud - > HandleNamedEvent ( " aim_clear " ) ;
}
cvarSystem - > SetCVarBool ( " ui_chat " , false ) ;
}
/*
= = = = = = = = = = = = = =
idPlayer : : Spawn
Prepare any resources used by the player .
= = = = = = = = = = = = = =
*/
void idPlayer : : Spawn ( void ) {
idStr temp ;
idBounds bounds ;
if ( entityNumber > = MAX_CLIENTS ) {
gameLocal . Error ( " entityNum > MAX_CLIENTS for player. Player may only be spawned with a client. " ) ;
}
// allow thinking during cinematics
cinematic = true ;
if ( gameLocal . isMultiplayer ) {
// always start in spectating state waiting to be spawned in
// do this before SetClipModel to get the right bounding box
spectating = true ;
}
// set our collision model
physicsObj . SetSelf ( this ) ;
SetClipModel ( ) ;
physicsObj . SetMass ( spawnArgs . GetFloat ( " mass " , " 100 " ) ) ;
physicsObj . SetContents ( CONTENTS_BODY ) ;
physicsObj . SetClipMask ( MASK_PLAYERSOLID ) ;
SetPhysics ( & physicsObj ) ;
InitAASLocation ( ) ;
skin = renderEntity . customSkin ;
// only the local player needs guis
if ( ! gameLocal . isMultiplayer | | entityNumber = = gameLocal . localClientNum ) {
// load HUD
if ( gameLocal . isMultiplayer ) {
hud = uiManager - > FindGui ( " guis/mphud.gui " , true , false , true ) ;
} else if ( spawnArgs . GetString ( " hud " , " " , temp ) ) {
hud = uiManager - > FindGui ( temp , true , false , true ) ;
}
if ( hud ) {
hud - > Activate ( true , gameLocal . time ) ;
}
// load cursor
if ( spawnArgs . GetString ( " cursor " , " " , temp ) ) {
cursor = uiManager - > FindGui ( temp , true , gameLocal . isMultiplayer , gameLocal . isMultiplayer ) ;
}
if ( cursor ) {
cursor - > Activate ( true , gameLocal . time ) ;
}
objectiveSystem = uiManager - > FindGui ( " guis/pda.gui " , true , false , true ) ;
objectiveSystemOpen = false ;
}
SetLastHitTime ( 0 ) ;
// load the armor sound feedback
declManager - > FindSound ( " player_sounds_hitArmor " ) ;
// set up conditions for animation
LinkScriptVariables ( ) ;
animator . RemoveOriginOffset ( true ) ;
// initialize user info related settings
// on server, we wait for the userinfo broadcast, as this controls when the player is initially spawned in game
if ( gameLocal . isClient | | entityNumber = = gameLocal . localClientNum ) {
UserInfoChanged ( false ) ;
}
// create combat collision hull for exact collision detection
SetCombatModel ( ) ;
// init the damage effects
playerView . SetPlayerEntity ( this ) ;
// supress model in non-player views, but allow it in mirrors and remote views
renderEntity . suppressSurfaceInViewID = entityNumber + 1 ;
// don't project shadow on self or weapon
renderEntity . noSelfShadow = true ;
idAFAttachment * headEnt = head . GetEntity ( ) ;
if ( headEnt ) {
headEnt - > GetRenderEntity ( ) - > suppressSurfaceInViewID = entityNumber + 1 ;
headEnt - > GetRenderEntity ( ) - > noSelfShadow = true ;
}
if ( gameLocal . isMultiplayer ) {
Init ( ) ;
Hide ( ) ; // properly hidden if starting as a spectator
if ( ! gameLocal . isClient ) {
// set yourself ready to spawn. idMultiplayerGame will decide when/if appropriate and call SpawnFromSpawnSpot
SetupWeaponEntity ( ) ;
SpawnFromSpawnSpot ( ) ;
forceRespawn = true ;
assert ( spectating ) ;
}
} else {
SetupWeaponEntity ( ) ;
SpawnFromSpawnSpot ( ) ;
}
// trigger playtesting item gives, if we didn't get here from a previous level
// the devmap key will be set on the first devmap, but cleared on any level
// transitions
if ( ! gameLocal . isMultiplayer & & gameLocal . serverInfo . FindKey ( " devmap " ) ) {
// fire a trigger with the name "devmap"
idEntity * ent = gameLocal . FindEntity ( " devmap " ) ;
if ( ent ) {
ent - > ActivateTargets ( this ) ;
}
}
if ( hud ) {
// We can spawn with a full soul cube, so we need to make sure the hud knows this
if ( weapon_soulcube > 0 & & ( inventory . weapons & ( 1 < < weapon_soulcube ) ) ) {
int max_souls = inventory . MaxAmmoForAmmoClass ( this , " ammo_souls " ) ;
if ( inventory . ammo [ idWeapon : : GetAmmoNumForName ( " ammo_souls " ) ] > = max_souls ) {
hud - > HandleNamedEvent ( " soulCubeReady " ) ;
}
}
hud - > HandleNamedEvent ( " itemPickup " ) ;
}
if ( GetPDA ( ) ) {
// Add any emails from the inventory
for ( int i = 0 ; i < inventory . emails . Num ( ) ; i + + ) {
GetPDA ( ) - > AddEmail ( inventory . emails [ i ] ) ;
}
GetPDA ( ) - > SetSecurity ( common - > GetLanguageDict ( ) - > GetString ( " #str_00066 " ) ) ;
}
if ( gameLocal . world - > spawnArgs . GetBool ( " no_Weapons " ) ) {
hiddenWeapon = true ;
if ( weapon . GetEntity ( ) ) {
weapon . GetEntity ( ) - > LowerWeapon ( ) ;
}
idealWeapon = 0 ;
} else {
hiddenWeapon = false ;
}
2011-12-06 18:20:15 +00:00
2011-11-22 21:28:15 +00:00
if ( hud ) {
UpdateHudWeapon ( ) ;
hud - > StateChanged ( gameLocal . time ) ;
}
tipUp = false ;
objectiveUp = false ;
if ( inventory . levelTriggers . Num ( ) ) {
PostEventMS ( & EV_Player_LevelTrigger , 0 ) ;
}
inventory . pdaOpened = false ;
inventory . selPDA = 0 ;
if ( ! gameLocal . isMultiplayer ) {
if ( g_skill . GetInteger ( ) < 2 ) {
if ( health < 25 ) {
health = 25 ;
}
if ( g_useDynamicProtection . GetBool ( ) ) {
g_damageScale . SetFloat ( 1.0f ) ;
}
} else {
g_damageScale . SetFloat ( 1.0f ) ;
g_armorProtection . SetFloat ( ( g_skill . GetInteger ( ) < 2 ) ? 0.4f : 0.2f ) ;
2012-07-01 22:02:40 +00:00
2011-11-22 21:28:15 +00:00
if ( g_skill . GetInteger ( ) = = 3 ) {
healthTake = true ;
nextHealthTake = gameLocal . time + g_healthTakeTime . GetInteger ( ) * 1000 ;
}
}
}
2018-08-26 03:41:08 +00:00
//Setup the weapon toggle lists //NEW
const idKeyValue * kv ;
kv = spawnArgs . MatchPrefix ( " weapontoggle " , NULL ) ;
while ( kv ) {
WeaponToggle_t newToggle ;
strcpy ( newToggle . name , kv - > GetKey ( ) . c_str ( ) ) ;
idStr toggleData = kv - > GetValue ( ) ;
idLexer src ;
idToken token ;
src . LoadMemory ( toggleData , toggleData . Length ( ) , " toggleData " ) ;
while ( 1 ) {
if ( ! src . ReadToken ( & token ) ) {
break ;
}
int index = atoi ( token . c_str ( ) ) ;
newToggle . toggleList . Append ( index ) ;
//Skip the ,
src . ReadToken ( & token ) ;
}
weaponToggles . Set ( newToggle . name , newToggle ) ;
kv = spawnArgs . MatchPrefix ( " weapontoggle " , kv ) ;
}
# ifdef _DENTONMOD_PLAYER_CPP
memset ( projectileType , 0 , sizeof ( projectileType ) ) ;
# endif
2011-11-22 21:28:15 +00:00
}
/*
= = = = = = = = = = = = = =
idPlayer : : ~ idPlayer ( )
Release any resources used by the player .
= = = = = = = = = = = = = =
*/
idPlayer : : ~ idPlayer ( ) {
delete weapon . GetEntity ( ) ;
weapon = NULL ;
}
/*
= = = = = = = = = = =
idPlayer : : Save
= = = = = = = = = = =
*/
void idPlayer : : Save ( idSaveGame * savefile ) const {
int i ;
savefile - > WriteUsercmd ( usercmd ) ;
playerView . Save ( savefile ) ;
savefile - > WriteBool ( noclip ) ;
savefile - > WriteBool ( godmode ) ;
// don't save spawnAnglesSet, since we'll have to reset them after loading the savegame
savefile - > WriteAngles ( spawnAngles ) ;
savefile - > WriteAngles ( viewAngles ) ;
savefile - > WriteAngles ( cmdAngles ) ;
savefile - > WriteInt ( buttonMask ) ;
savefile - > WriteInt ( oldButtons ) ;
savefile - > WriteInt ( oldFlags ) ;
savefile - > WriteInt ( lastHitTime ) ;
savefile - > WriteInt ( lastSndHitTime ) ;
savefile - > WriteInt ( lastSavingThrowTime ) ;
// idBoolFields don't need to be saved, just re-linked in Restore
inventory . Save ( savefile ) ;
weapon . Save ( savefile ) ;
savefile - > WriteUserInterface ( hud , false ) ;
savefile - > WriteUserInterface ( objectiveSystem , false ) ;
savefile - > WriteBool ( objectiveSystemOpen ) ;
savefile - > WriteInt ( weapon_soulcube ) ;
savefile - > WriteInt ( weapon_pda ) ;
savefile - > WriteInt ( weapon_fists ) ;
savefile - > WriteInt ( heartRate ) ;
savefile - > WriteFloat ( heartInfo . GetStartTime ( ) ) ;
savefile - > WriteFloat ( heartInfo . GetDuration ( ) ) ;
savefile - > WriteFloat ( heartInfo . GetStartValue ( ) ) ;
savefile - > WriteFloat ( heartInfo . GetEndValue ( ) ) ;
savefile - > WriteInt ( lastHeartAdjust ) ;
savefile - > WriteInt ( lastHeartBeat ) ;
savefile - > WriteInt ( lastDmgTime ) ;
savefile - > WriteInt ( deathClearContentsTime ) ;
savefile - > WriteBool ( doingDeathSkin ) ;
savefile - > WriteInt ( lastArmorPulse ) ;
savefile - > WriteFloat ( stamina ) ;
savefile - > WriteFloat ( healthPool ) ;
savefile - > WriteInt ( nextHealthPulse ) ;
savefile - > WriteBool ( healthPulse ) ;
savefile - > WriteInt ( nextHealthTake ) ;
savefile - > WriteBool ( healthTake ) ;
savefile - > WriteBool ( hiddenWeapon ) ;
soulCubeProjectile . Save ( savefile ) ;
savefile - > WriteInt ( spectator ) ;
savefile - > WriteVec3 ( colorBar ) ;
savefile - > WriteInt ( colorBarIndex ) ;
savefile - > WriteBool ( scoreBoardOpen ) ;
savefile - > WriteBool ( forceScoreBoard ) ;
savefile - > WriteBool ( forceRespawn ) ;
savefile - > WriteBool ( spectating ) ;
savefile - > WriteInt ( lastSpectateTeleport ) ;
savefile - > WriteBool ( lastHitToggle ) ;
savefile - > WriteBool ( forcedReady ) ;
savefile - > WriteBool ( wantSpectate ) ;
savefile - > WriteBool ( weaponGone ) ;
savefile - > WriteBool ( useInitialSpawns ) ;
savefile - > WriteInt ( latchedTeam ) ;
savefile - > WriteInt ( tourneyRank ) ;
savefile - > WriteInt ( tourneyLine ) ;
teleportEntity . Save ( savefile ) ;
savefile - > WriteInt ( teleportKiller ) ;
savefile - > WriteInt ( minRespawnTime ) ;
savefile - > WriteInt ( maxRespawnTime ) ;
savefile - > WriteVec3 ( firstPersonViewOrigin ) ;
savefile - > WriteMat3 ( firstPersonViewAxis ) ;
// don't bother saving dragEntity since it's a dev tool
savefile - > WriteJoint ( hipJoint ) ;
savefile - > WriteJoint ( chestJoint ) ;
savefile - > WriteJoint ( headJoint ) ;
savefile - > WriteStaticObject ( physicsObj ) ;
savefile - > WriteInt ( aasLocation . Num ( ) ) ;
for ( i = 0 ; i < aasLocation . Num ( ) ; i + + ) {
savefile - > WriteInt ( aasLocation [ i ] . areaNum ) ;
savefile - > WriteVec3 ( aasLocation [ i ] . pos ) ;
}
savefile - > WriteInt ( bobFoot ) ;
savefile - > WriteFloat ( bobFrac ) ;
savefile - > WriteFloat ( bobfracsin ) ;
savefile - > WriteInt ( bobCycle ) ;
savefile - > WriteFloat ( xyspeed ) ;
savefile - > WriteInt ( stepUpTime ) ;
savefile - > WriteFloat ( stepUpDelta ) ;
savefile - > WriteFloat ( idealLegsYaw ) ;
savefile - > WriteFloat ( legsYaw ) ;
savefile - > WriteBool ( legsForward ) ;
savefile - > WriteFloat ( oldViewYaw ) ;
savefile - > WriteAngles ( viewBobAngles ) ;
savefile - > WriteVec3 ( viewBob ) ;
savefile - > WriteInt ( landChange ) ;
savefile - > WriteInt ( landTime ) ;
savefile - > WriteInt ( currentWeapon ) ;
savefile - > WriteInt ( idealWeapon ) ;
savefile - > WriteInt ( previousWeapon ) ;
2018-08-26 03:41:08 +00:00
savefile - > WriteInt ( quickWeapon ) ; //new
2011-11-22 21:28:15 +00:00
savefile - > WriteInt ( weaponSwitchTime ) ;
savefile - > WriteBool ( weaponEnabled ) ;
savefile - > WriteBool ( showWeaponViewModel ) ;
savefile - > WriteSkin ( skin ) ;
savefile - > WriteSkin ( powerUpSkin ) ;
savefile - > WriteString ( baseSkinName ) ;
savefile - > WriteInt ( numProjectilesFired ) ;
savefile - > WriteInt ( numProjectileHits ) ;
savefile - > WriteBool ( airless ) ;
savefile - > WriteInt ( airTics ) ;
savefile - > WriteInt ( lastAirDamage ) ;
savefile - > WriteBool ( gibDeath ) ;
savefile - > WriteBool ( gibsLaunched ) ;
savefile - > WriteVec3 ( gibsDir ) ;
2018-08-26 03:41:08 +00:00
//Remeber the order of saving this info... cause last time I did a stupid mistake....
# ifdef _DENTONMOD_PLAYER_CPP
weaponZoom_s flags = weaponZoom ; // Save the weapon Zoom Info
LittleBitField ( & flags , sizeof ( flags ) ) ;
savefile - > Write ( & flags , sizeof ( flags ) ) ;
for ( i = 0 ; i < MAX_WEAPONS ; i + + ) {
savefile - > WriteByte ( projectileType [ i ] ) ;
}
# endif //_DENTONMOD_PLAYER_CPP
2011-11-22 21:28:15 +00:00
savefile - > WriteFloat ( zoomFov . GetStartTime ( ) ) ;
savefile - > WriteFloat ( zoomFov . GetDuration ( ) ) ;
savefile - > WriteFloat ( zoomFov . GetStartValue ( ) ) ;
savefile - > WriteFloat ( zoomFov . GetEndValue ( ) ) ;
savefile - > WriteFloat ( centerView . GetStartTime ( ) ) ;
savefile - > WriteFloat ( centerView . GetDuration ( ) ) ;
savefile - > WriteFloat ( centerView . GetStartValue ( ) ) ;
savefile - > WriteFloat ( centerView . GetEndValue ( ) ) ;
savefile - > WriteBool ( fxFov ) ;
savefile - > WriteFloat ( influenceFov ) ;
savefile - > WriteInt ( influenceActive ) ;
savefile - > WriteFloat ( influenceRadius ) ;
savefile - > WriteObject ( influenceEntity ) ;
savefile - > WriteMaterial ( influenceMaterial ) ;
savefile - > WriteSkin ( influenceSkin ) ;
savefile - > WriteObject ( privateCameraView ) ;
for ( i = 0 ; i < NUM_LOGGED_VIEW_ANGLES ; i + + ) {
savefile - > WriteAngles ( loggedViewAngles [ i ] ) ;
}
for ( i = 0 ; i < NUM_LOGGED_ACCELS ; i + + ) {
savefile - > WriteInt ( loggedAccel [ i ] . time ) ;
savefile - > WriteVec3 ( loggedAccel [ i ] . dir ) ;
}
savefile - > WriteInt ( currentLoggedAccel ) ;
savefile - > WriteObject ( focusGUIent ) ;
// can't save focusUI
savefile - > WriteObject ( focusCharacter ) ;
savefile - > WriteInt ( talkCursor ) ;
savefile - > WriteInt ( focusTime ) ;
savefile - > WriteObject ( focusVehicle ) ;
savefile - > WriteUserInterface ( cursor , false ) ;
savefile - > WriteInt ( oldMouseX ) ;
savefile - > WriteInt ( oldMouseY ) ;
savefile - > WriteString ( pdaAudio ) ;
savefile - > WriteString ( pdaVideo ) ;
savefile - > WriteString ( pdaVideoWave ) ;
savefile - > WriteBool ( tipUp ) ;
savefile - > WriteBool ( objectiveUp ) ;
savefile - > WriteInt ( lastDamageDef ) ;
savefile - > WriteVec3 ( lastDamageDir ) ;
savefile - > WriteInt ( lastDamageLocation ) ;
savefile - > WriteInt ( smoothedFrame ) ;
savefile - > WriteBool ( smoothedOriginUpdated ) ;
savefile - > WriteVec3 ( smoothedOrigin ) ;
savefile - > WriteAngles ( smoothedAngles ) ;
savefile - > WriteBool ( ready ) ;
savefile - > WriteBool ( respawning ) ;
savefile - > WriteBool ( leader ) ;
savefile - > WriteInt ( lastSpectateChange ) ;
savefile - > WriteInt ( lastTeleFX ) ;
savefile - > WriteFloat ( pm_stamina . GetFloat ( ) ) ;
if ( hud ) {
hud - > SetStateString ( " message " , common - > GetLanguageDict ( ) - > GetString ( " #str_02916 " ) ) ;
hud - > HandleNamedEvent ( " Message " ) ;
}
2018-08-26 03:41:08 +00:00
savefile - > WriteInt ( weaponToggles . Num ( ) ) ; //new, all lines from here
for ( i = 0 ; i < weaponToggles . Num ( ) ; i + + ) {
WeaponToggle_t * weaponToggle = weaponToggles . GetIndex ( i ) ;
savefile - > WriteString ( weaponToggle - > name ) ;
savefile - > WriteInt ( weaponToggle - > toggleList . Num ( ) ) ;
for ( int j = 0 ; j < weaponToggle - > toggleList . Num ( ) ; j + + ) {
savefile - > WriteInt ( weaponToggle - > toggleList [ j ] ) ;
}
}
2011-11-22 21:28:15 +00:00
}
/*
= = = = = = = = = = =
idPlayer : : Restore
= = = = = = = = = = =
*/
void idPlayer : : Restore ( idRestoreGame * savefile ) {
int i ;
int num ;
float set ;
savefile - > ReadUsercmd ( usercmd ) ;
playerView . Restore ( savefile ) ;
savefile - > ReadBool ( noclip ) ;
savefile - > ReadBool ( godmode ) ;
savefile - > ReadAngles ( spawnAngles ) ;
savefile - > ReadAngles ( viewAngles ) ;
savefile - > ReadAngles ( cmdAngles ) ;
memset ( usercmd . angles , 0 , sizeof ( usercmd . angles ) ) ;
SetViewAngles ( viewAngles ) ;
spawnAnglesSet = true ;
savefile - > ReadInt ( buttonMask ) ;
savefile - > ReadInt ( oldButtons ) ;
savefile - > ReadInt ( oldFlags ) ;
usercmd . flags = 0 ;
oldFlags = 0 ;
savefile - > ReadInt ( lastHitTime ) ;
savefile - > ReadInt ( lastSndHitTime ) ;
savefile - > ReadInt ( lastSavingThrowTime ) ;
// Re-link idBoolFields to the scriptObject, values will be restored in scriptObject's restore
LinkScriptVariables ( ) ;
inventory . Restore ( savefile ) ;
weapon . Restore ( savefile ) ;
for ( i = 0 ; i < inventory . emails . Num ( ) ; i + + ) {
GetPDA ( ) - > AddEmail ( inventory . emails [ i ] ) ;
}
savefile - > ReadUserInterface ( hud ) ;
savefile - > ReadUserInterface ( objectiveSystem ) ;
savefile - > ReadBool ( objectiveSystemOpen ) ;
savefile - > ReadInt ( weapon_soulcube ) ;
savefile - > ReadInt ( weapon_pda ) ;
savefile - > ReadInt ( weapon_fists ) ;
savefile - > ReadInt ( heartRate ) ;
savefile - > ReadFloat ( set ) ;
heartInfo . SetStartTime ( set ) ;
savefile - > ReadFloat ( set ) ;
heartInfo . SetDuration ( set ) ;
savefile - > ReadFloat ( set ) ;
heartInfo . SetStartValue ( set ) ;
savefile - > ReadFloat ( set ) ;
heartInfo . SetEndValue ( set ) ;
savefile - > ReadInt ( lastHeartAdjust ) ;
savefile - > ReadInt ( lastHeartBeat ) ;
savefile - > ReadInt ( lastDmgTime ) ;
savefile - > ReadInt ( deathClearContentsTime ) ;
savefile - > ReadBool ( doingDeathSkin ) ;
savefile - > ReadInt ( lastArmorPulse ) ;
savefile - > ReadFloat ( stamina ) ;
savefile - > ReadFloat ( healthPool ) ;
savefile - > ReadInt ( nextHealthPulse ) ;
savefile - > ReadBool ( healthPulse ) ;
savefile - > ReadInt ( nextHealthTake ) ;
savefile - > ReadBool ( healthTake ) ;
savefile - > ReadBool ( hiddenWeapon ) ;
soulCubeProjectile . Restore ( savefile ) ;
savefile - > ReadInt ( spectator ) ;
savefile - > ReadVec3 ( colorBar ) ;
savefile - > ReadInt ( colorBarIndex ) ;
savefile - > ReadBool ( scoreBoardOpen ) ;
savefile - > ReadBool ( forceScoreBoard ) ;
savefile - > ReadBool ( forceRespawn ) ;
savefile - > ReadBool ( spectating ) ;
savefile - > ReadInt ( lastSpectateTeleport ) ;
savefile - > ReadBool ( lastHitToggle ) ;
savefile - > ReadBool ( forcedReady ) ;
savefile - > ReadBool ( wantSpectate ) ;
savefile - > ReadBool ( weaponGone ) ;
savefile - > ReadBool ( useInitialSpawns ) ;
savefile - > ReadInt ( latchedTeam ) ;
savefile - > ReadInt ( tourneyRank ) ;
savefile - > ReadInt ( tourneyLine ) ;
teleportEntity . Restore ( savefile ) ;
savefile - > ReadInt ( teleportKiller ) ;
savefile - > ReadInt ( minRespawnTime ) ;
savefile - > ReadInt ( maxRespawnTime ) ;
savefile - > ReadVec3 ( firstPersonViewOrigin ) ;
savefile - > ReadMat3 ( firstPersonViewAxis ) ;
// don't bother saving dragEntity since it's a dev tool
dragEntity . Clear ( ) ;
savefile - > ReadJoint ( hipJoint ) ;
savefile - > ReadJoint ( chestJoint ) ;
savefile - > ReadJoint ( headJoint ) ;
savefile - > ReadStaticObject ( physicsObj ) ;
RestorePhysics ( & physicsObj ) ;
savefile - > ReadInt ( num ) ;
aasLocation . SetGranularity ( 1 ) ;
aasLocation . SetNum ( num ) ;
for ( i = 0 ; i < num ; i + + ) {
savefile - > ReadInt ( aasLocation [ i ] . areaNum ) ;
savefile - > ReadVec3 ( aasLocation [ i ] . pos ) ;
}
savefile - > ReadInt ( bobFoot ) ;
savefile - > ReadFloat ( bobFrac ) ;
savefile - > ReadFloat ( bobfracsin ) ;
savefile - > ReadInt ( bobCycle ) ;
savefile - > ReadFloat ( xyspeed ) ;
savefile - > ReadInt ( stepUpTime ) ;
savefile - > ReadFloat ( stepUpDelta ) ;
savefile - > ReadFloat ( idealLegsYaw ) ;
savefile - > ReadFloat ( legsYaw ) ;
savefile - > ReadBool ( legsForward ) ;
savefile - > ReadFloat ( oldViewYaw ) ;
savefile - > ReadAngles ( viewBobAngles ) ;
savefile - > ReadVec3 ( viewBob ) ;
savefile - > ReadInt ( landChange ) ;
savefile - > ReadInt ( landTime ) ;
savefile - > ReadInt ( currentWeapon ) ;
savefile - > ReadInt ( idealWeapon ) ;
savefile - > ReadInt ( previousWeapon ) ;
2018-08-26 03:41:08 +00:00
savefile - > ReadInt ( quickWeapon ) ; //new
2011-11-22 21:28:15 +00:00
savefile - > ReadInt ( weaponSwitchTime ) ;
savefile - > ReadBool ( weaponEnabled ) ;
savefile - > ReadBool ( showWeaponViewModel ) ;
savefile - > ReadSkin ( skin ) ;
savefile - > ReadSkin ( powerUpSkin ) ;
savefile - > ReadString ( baseSkinName ) ;
savefile - > ReadInt ( numProjectilesFired ) ;
savefile - > ReadInt ( numProjectileHits ) ;
savefile - > ReadBool ( airless ) ;
savefile - > ReadInt ( airTics ) ;
savefile - > ReadInt ( lastAirDamage ) ;
savefile - > ReadBool ( gibDeath ) ;
savefile - > ReadBool ( gibsLaunched ) ;
savefile - > ReadVec3 ( gibsDir ) ;
2018-08-26 03:41:08 +00:00
# ifdef _DENTONMOD_PLAYER_CPP
// Remember the order of saving this info...
savefile - > Read ( & weaponZoom , sizeof ( weaponZoom ) ) ;
LittleBitField ( & weaponZoom , sizeof ( weaponZoom ) ) ;
for ( i = 0 ; i < MAX_WEAPONS ; i + + ) {
savefile - > ReadByte ( projectileType [ i ] ) ;
}
# endif //_DENTONMOD_PLAYER_CPP
2011-11-22 21:28:15 +00:00
savefile - > ReadFloat ( set ) ;
zoomFov . SetStartTime ( set ) ;
savefile - > ReadFloat ( set ) ;
zoomFov . SetDuration ( set ) ;
savefile - > ReadFloat ( set ) ;
zoomFov . SetStartValue ( set ) ;
savefile - > ReadFloat ( set ) ;
zoomFov . SetEndValue ( set ) ;
savefile - > ReadFloat ( set ) ;
centerView . SetStartTime ( set ) ;
savefile - > ReadFloat ( set ) ;
centerView . SetDuration ( set ) ;
savefile - > ReadFloat ( set ) ;
centerView . SetStartValue ( set ) ;
savefile - > ReadFloat ( set ) ;
centerView . SetEndValue ( set ) ;
savefile - > ReadBool ( fxFov ) ;
savefile - > ReadFloat ( influenceFov ) ;
savefile - > ReadInt ( influenceActive ) ;
savefile - > ReadFloat ( influenceRadius ) ;
savefile - > ReadObject ( reinterpret_cast < idClass * & > ( influenceEntity ) ) ;
savefile - > ReadMaterial ( influenceMaterial ) ;
savefile - > ReadSkin ( influenceSkin ) ;
savefile - > ReadObject ( reinterpret_cast < idClass * & > ( privateCameraView ) ) ;
for ( i = 0 ; i < NUM_LOGGED_VIEW_ANGLES ; i + + ) {
savefile - > ReadAngles ( loggedViewAngles [ i ] ) ;
}
for ( i = 0 ; i < NUM_LOGGED_ACCELS ; i + + ) {
savefile - > ReadInt ( loggedAccel [ i ] . time ) ;
savefile - > ReadVec3 ( loggedAccel [ i ] . dir ) ;
}
savefile - > ReadInt ( currentLoggedAccel ) ;
savefile - > ReadObject ( reinterpret_cast < idClass * & > ( focusGUIent ) ) ;
// can't save focusUI
focusUI = NULL ;
savefile - > ReadObject ( reinterpret_cast < idClass * & > ( focusCharacter ) ) ;
savefile - > ReadInt ( talkCursor ) ;
savefile - > ReadInt ( focusTime ) ;
savefile - > ReadObject ( reinterpret_cast < idClass * & > ( focusVehicle ) ) ;
savefile - > ReadUserInterface ( cursor ) ;
savefile - > ReadInt ( oldMouseX ) ;
savefile - > ReadInt ( oldMouseY ) ;
savefile - > ReadString ( pdaAudio ) ;
savefile - > ReadString ( pdaVideo ) ;
savefile - > ReadString ( pdaVideoWave ) ;
savefile - > ReadBool ( tipUp ) ;
savefile - > ReadBool ( objectiveUp ) ;
savefile - > ReadInt ( lastDamageDef ) ;
savefile - > ReadVec3 ( lastDamageDir ) ;
savefile - > ReadInt ( lastDamageLocation ) ;
savefile - > ReadInt ( smoothedFrame ) ;
savefile - > ReadBool ( smoothedOriginUpdated ) ;
savefile - > ReadVec3 ( smoothedOrigin ) ;
savefile - > ReadAngles ( smoothedAngles ) ;
savefile - > ReadBool ( ready ) ;
savefile - > ReadBool ( respawning ) ;
savefile - > ReadBool ( leader ) ;
savefile - > ReadInt ( lastSpectateChange ) ;
savefile - > ReadInt ( lastTeleFX ) ;
// set the pm_ cvars
const idKeyValue * kv ;
kv = spawnArgs . MatchPrefix ( " pm_ " , NULL ) ;
while ( kv ) {
cvarSystem - > SetCVarString ( kv - > GetKey ( ) , kv - > GetValue ( ) ) ;
kv = spawnArgs . MatchPrefix ( " pm_ " , kv ) ;
}
savefile - > ReadFloat ( set ) ;
pm_stamina . SetFloat ( set ) ;
// create combat collision hull for exact collision detection
SetCombatModel ( ) ;
2020-09-06 02:49:18 +00:00
2018-08-26 03:41:08 +00:00
int weaponToggleCount ; //new all lines from here
savefile - > ReadInt ( weaponToggleCount ) ;
for ( i = 0 ; i < weaponToggleCount ; i + + ) {
WeaponToggle_t newToggle ;
memset ( & newToggle , 0 , sizeof ( newToggle ) ) ;
idStr name ;
savefile - > ReadString ( name ) ;
strcpy ( newToggle . name , name . c_str ( ) ) ;
int indexCount ;
savefile - > ReadInt ( indexCount ) ;
for ( int j = 0 ; j < indexCount ; j + + ) {
int temp ;
savefile - > ReadInt ( temp ) ;
newToggle . toggleList . Append ( temp ) ;
}
weaponToggles . Set ( newToggle . name , newToggle ) ;
}
2020-09-06 02:49:18 +00:00
// DG: workaround for lingering messages that are shown forever after loading a savegame
// (one way to get them is saving again, while the message from first save is still
// shown, and then load)
if ( hud ) {
hud - > SetStateString ( " message " , " " ) ;
}
2011-11-22 21:28:15 +00:00
}
/*
= = = = = = = = = = = = = = =
idPlayer : : PrepareForRestart
= = = = = = = = = = = = = = = =
*/
void idPlayer : : PrepareForRestart ( void ) {
ClearPowerUps ( ) ;
Spectate ( true ) ;
forceRespawn = true ;
2011-12-06 18:20:15 +00:00
2011-11-22 21:28:15 +00:00
// we will be restarting program, clear the client entities from program-related things first
ShutdownThreads ( ) ;
// the sound world is going to be cleared, don't keep references to emitters
FreeSoundEmitter ( false ) ;
}
/*
= = = = = = = = = = = = = = =
idPlayer : : Restart
= = = = = = = = = = = = = = = =
*/
void idPlayer : : Restart ( void ) {
idActor : : Restart ( ) ;
2011-12-06 18:20:15 +00:00
2011-11-22 21:28:15 +00:00
// client needs to setup the animation script object again
if ( gameLocal . isClient ) {
Init ( ) ;
} else {
// choose a random spot and prepare the point of view in case player is left spectating
assert ( spectating ) ;
SpawnFromSpawnSpot ( ) ;
}
useInitialSpawns = true ;
UpdateSkinSetup ( true ) ;
}
/*
= = = = = = = = = = = = = = =
idPlayer : : ServerSpectate
= = = = = = = = = = = = = = = =
*/
void idPlayer : : ServerSpectate ( bool spectate ) {
assert ( ! gameLocal . isClient ) ;
if ( spectating ! = spectate ) {
Spectate ( spectate ) ;
if ( spectate ) {
SetSpectateOrigin ( ) ;
} else {
if ( gameLocal . gameType = = GAME_DM ) {
// make sure the scores are reset so you can't exploit by spectating and entering the game back
// other game types don't matter, as you either can't join back, or it's team scores
gameLocal . mpGame . ClearFrags ( entityNumber ) ;
}
}
}
if ( ! spectate ) {
SpawnFromSpawnSpot ( ) ;
}
}
/*
= = = = = = = = = = =
idPlayer : : SelectInitialSpawnPoint
Try to find a spawn point marked ' initial ' , otherwise
use normal spawn selection .
= = = = = = = = = = = =
*/
void idPlayer : : SelectInitialSpawnPoint ( idVec3 & origin , idAngles & angles ) {
idEntity * spot ;
idStr skin ;
spot = gameLocal . SelectInitialSpawnPoint ( this ) ;
// set the player skin from the spawn location
if ( spot - > spawnArgs . GetString ( " skin " , NULL , skin ) ) {
spawnArgs . Set ( " spawn_skin " , skin ) ;
}
// activate the spawn locations targets
spot - > PostEventMS ( & EV_ActivateTargets , 0 , this ) ;
origin = spot - > GetPhysics ( ) - > GetOrigin ( ) ;
origin [ 2 ] + = 4.0f + CM_BOX_EPSILON ; // move up to make sure the player is at least an epsilon above the floor
angles = spot - > GetPhysics ( ) - > GetAxis ( ) . ToAngles ( ) ;
}
/*
= = = = = = = = = = =
idPlayer : : SpawnFromSpawnSpot
Chooses a spawn location and spawns the player
= = = = = = = = = = = =
*/
void idPlayer : : SpawnFromSpawnSpot ( void ) {
idVec3 spawn_origin ;
idAngles spawn_angles ;
2011-12-06 18:20:15 +00:00
2011-11-22 21:28:15 +00:00
SelectInitialSpawnPoint ( spawn_origin , spawn_angles ) ;
SpawnToPoint ( spawn_origin , spawn_angles ) ;
}
/*
= = = = = = = = = = =
idPlayer : : SpawnToPoint
Called every time a client is placed fresh in the world :
after the first ClientBegin , and after each respawn
Initializes all non - persistant parts of playerState
when called here with spectating set to true , just place yourself and init
= = = = = = = = = = = =
*/
void idPlayer : : SpawnToPoint ( const idVec3 & spawn_origin , const idAngles & spawn_angles ) {
idVec3 spec_origin ;
assert ( ! gameLocal . isClient ) ;
respawning = true ;
Init ( ) ;
fl . noknockback = false ;
// stop any ragdolls being used
StopRagdoll ( ) ;
// set back the player physics
SetPhysics ( & physicsObj ) ;
physicsObj . SetClipModelAxis ( ) ;
physicsObj . EnableClip ( ) ;
if ( ! spectating ) {
SetCombatContents ( true ) ;
}
physicsObj . SetLinearVelocity ( vec3_origin ) ;
// setup our initial view
if ( ! spectating ) {
SetOrigin ( spawn_origin ) ;
} else {
spec_origin = spawn_origin ;
spec_origin [ 2 ] + = pm_normalheight . GetFloat ( ) ;
spec_origin [ 2 ] + = SPECTATE_RAISE ;
SetOrigin ( spec_origin ) ;
}
// if this is the first spawn of the map, we don't have a usercmd yet,
// so the delta angles won't be correct. This will be fixed on the first think.
viewAngles = ang_zero ;
SetDeltaViewAngles ( ang_zero ) ;
SetViewAngles ( spawn_angles ) ;
spawnAngles = spawn_angles ;
spawnAnglesSet = false ;
legsForward = true ;
legsYaw = 0.0f ;
idealLegsYaw = 0.0f ;
oldViewYaw = viewAngles . yaw ;
if ( spectating ) {
Hide ( ) ;
} else {
Show ( ) ;
}
if ( gameLocal . isMultiplayer ) {
if ( ! spectating ) {
// we may be called twice in a row in some situations. avoid a double fx and 'fly to the roof'
if ( lastTeleFX < gameLocal . time - 1000 ) {
idEntityFx : : StartFx ( spawnArgs . GetString ( " fx_spawn " ) , & spawn_origin , NULL , this , true ) ;
lastTeleFX = gameLocal . time ;
}
}
AI_TELEPORT = true ;
} else {
AI_TELEPORT = false ;
}
// kill anything at the new position
if ( ! spectating ) {
physicsObj . SetClipMask ( MASK_PLAYERSOLID ) ; // the clip mask is usually maintained in Move(), but KillBox requires it
gameLocal . KillBox ( this ) ;
}
// don't allow full run speed for a bit
physicsObj . SetKnockBack ( 100 ) ;
// set our respawn time and buttons so that if we're killed we don't respawn immediately
minRespawnTime = gameLocal . time ;
maxRespawnTime = gameLocal . time ;
if ( ! spectating ) {
forceRespawn = false ;
}
privateCameraView = NULL ;
BecomeActive ( TH_THINK ) ;
// run a client frame to drop exactly to the floor,
// initialize animations and other things
Think ( ) ;
respawning = false ;
lastManOver = false ;
lastManPlayAgain = false ;
isTelefragged = false ;
}
/*
= = = = = = = = = = = = = = =
idPlayer : : SavePersistantInfo
Saves any inventory and player stats when changing levels .
= = = = = = = = = = = = = = =
*/
void idPlayer : : SavePersistantInfo ( void ) {
idDict & playerInfo = gameLocal . persistentPlayerInfo [ entityNumber ] ;
playerInfo . Clear ( ) ;
inventory . GetPersistantData ( playerInfo ) ;
playerInfo . SetInt ( " health " , health ) ;
playerInfo . SetInt ( " current_weapon " , currentWeapon ) ;
}
/*
= = = = = = = = = = = = = = =
idPlayer : : RestorePersistantInfo
Restores any inventory and player stats when changing levels .
= = = = = = = = = = = = = = =
*/
void idPlayer : : RestorePersistantInfo ( void ) {
if ( gameLocal . isMultiplayer ) {
gameLocal . persistentPlayerInfo [ entityNumber ] . Clear ( ) ;
}
spawnArgs . Copy ( gameLocal . persistentPlayerInfo [ entityNumber ] ) ;
inventory . RestoreInventory ( this , spawnArgs ) ;
health = spawnArgs . GetInt ( " health " , " 100 " ) ;
if ( ! gameLocal . isClient ) {
idealWeapon = spawnArgs . GetInt ( " current_weapon " , " 1 " ) ;
}
}
/*
= = = = = = = = = = = = = = = =
idPlayer : : GetUserInfo
= = = = = = = = = = = = = = = =
*/
idDict * idPlayer : : GetUserInfo ( void ) {
return & gameLocal . userInfo [ entityNumber ] ;
}
/*
= = = = = = = = = = = = = =
idPlayer : : UpdateSkinSetup
= = = = = = = = = = = = = =
*/
void idPlayer : : UpdateSkinSetup ( bool restart ) {
if ( restart ) {
team = ( idStr : : Icmp ( GetUserInfo ( ) - > GetString ( " ui_team " ) , " Blue " ) = = 0 ) ;
}
if ( gameLocal . gameType = = GAME_TDM ) {
if ( team ) {
baseSkinName = " skins/characters/player/marine_mp_blue " ;
} else {
baseSkinName = " skins/characters/player/marine_mp_red " ;
}
if ( ! gameLocal . isClient & & team ! = latchedTeam ) {
gameLocal . mpGame . SwitchToTeam ( entityNumber , latchedTeam , team ) ;
}
latchedTeam = team ;
} else {
baseSkinName = GetUserInfo ( ) - > GetString ( " ui_skin " ) ;
}
if ( ! baseSkinName . Length ( ) ) {
baseSkinName = " skins/characters/player/marine_mp " ;
}
skin = declManager - > FindSkin ( baseSkinName , false ) ;
assert ( skin ) ;
// match the skin to a color band for scoreboard
if ( baseSkinName . Find ( " red " ) ! = - 1 ) {
colorBarIndex = 1 ;
} else if ( baseSkinName . Find ( " green " ) ! = - 1 ) {
colorBarIndex = 2 ;
} else if ( baseSkinName . Find ( " blue " ) ! = - 1 ) {
colorBarIndex = 3 ;
} else if ( baseSkinName . Find ( " yellow " ) ! = - 1 ) {
colorBarIndex = 4 ;
} else {
colorBarIndex = 0 ;
}
colorBar = colorBarTable [ colorBarIndex ] ;
if ( PowerUpActive ( BERSERK ) ) {
powerUpSkin = declManager - > FindSkin ( baseSkinName + " _berserk " ) ;
}
}
/*
= = = = = = = = = = = = = =
idPlayer : : BalanceTDM
= = = = = = = = = = = = = =
*/
bool idPlayer : : BalanceTDM ( void ) {
int i , balanceTeam , teamCount [ 2 ] ;
idEntity * ent ;
teamCount [ 0 ] = teamCount [ 1 ] = 0 ;
for ( i = 0 ; i < gameLocal . numClients ; i + + ) {
ent = gameLocal . entities [ i ] ;
if ( ent & & ent - > IsType ( idPlayer : : Type ) ) {
teamCount [ static_cast < idPlayer * > ( ent ) - > team ] + + ;
}
}
balanceTeam = - 1 ;
if ( teamCount [ 0 ] < teamCount [ 1 ] ) {
balanceTeam = 0 ;
} else if ( teamCount [ 0 ] > teamCount [ 1 ] ) {
balanceTeam = 1 ;
}
if ( balanceTeam ! = - 1 & & team ! = balanceTeam ) {
common - > DPrintf ( " team balance: forcing player %d to %s team \n " , entityNumber , balanceTeam ? " blue " : " red " ) ;
team = balanceTeam ;
GetUserInfo ( ) - > Set ( " ui_team " , team ? " Blue " : " Red " ) ;
return true ;
}
return false ;
}
/*
= = = = = = = = = = = = = =
idPlayer : : UserInfoChanged
= = = = = = = = = = = = = =
*/
bool idPlayer : : UserInfoChanged ( bool canModify ) {
idDict * userInfo ;
bool modifiedInfo ;
bool spec ;
bool newready ;
userInfo = GetUserInfo ( ) ;
showWeaponViewModel = userInfo - > GetBool ( " ui_showGun " ) ;
if ( ! gameLocal . isMultiplayer ) {
return false ;
}
modifiedInfo = false ;
spec = ( idStr : : Icmp ( userInfo - > GetString ( " ui_spectate " ) , " Spectate " ) = = 0 ) ;
if ( gameLocal . serverInfo . GetBool ( " si_spectators " ) ) {
// never let spectators go back to game while sudden death is on
if ( canModify & & gameLocal . mpGame . GetGameState ( ) = = idMultiplayerGame : : SUDDENDEATH & & ! spec & & wantSpectate = = true ) {
userInfo - > Set ( " ui_spectate " , " Spectate " ) ;
modifiedInfo | = true ;
} else {
if ( spec ! = wantSpectate & & ! spec ) {
// returning from spectate, set forceRespawn so we don't get stuck in spectate forever
forceRespawn = true ;
}
wantSpectate = spec ;
}
} else {
if ( canModify & & spec ) {
userInfo - > Set ( " ui_spectate " , " Play " ) ;
modifiedInfo | = true ;
2011-12-06 18:20:15 +00:00
} else if ( spectating ) {
2011-11-22 21:28:15 +00:00
// allow player to leaving spectator mode if they were in it when si_spectators got turned off
forceRespawn = true ;
}
wantSpectate = false ;
}
newready = ( idStr : : Icmp ( userInfo - > GetString ( " ui_ready " ) , " Ready " ) = = 0 ) ;
if ( ready ! = newready & & gameLocal . mpGame . GetGameState ( ) = = idMultiplayerGame : : WARMUP & & ! wantSpectate ) {
gameLocal . mpGame . AddChatLine ( common - > GetLanguageDict ( ) - > GetString ( " #str_07180 " ) , userInfo - > GetString ( " ui_name " ) , newready ? common - > GetLanguageDict ( ) - > GetString ( " #str_04300 " ) : common - > GetLanguageDict ( ) - > GetString ( " #str_04301 " ) ) ;
}
ready = newready ;
team = ( idStr : : Icmp ( userInfo - > GetString ( " ui_team " ) , " Blue " ) = = 0 ) ;
// server maintains TDM balance
if ( canModify & & gameLocal . gameType = = GAME_TDM & & ! gameLocal . mpGame . IsInGame ( entityNumber ) & & g_balanceTDM . GetBool ( ) ) {
modifiedInfo | = BalanceTDM ( ) ;
}
UpdateSkinSetup ( false ) ;
2011-12-06 18:20:15 +00:00
2011-11-22 21:28:15 +00:00
isChatting = userInfo - > GetBool ( " ui_chat " , " 0 " ) ;
if ( canModify & & isChatting & & AI_DEAD ) {
// if dead, always force chat icon off.
isChatting = false ;
userInfo - > SetBool ( " ui_chat " , false ) ;
modifiedInfo | = true ;
}
return modifiedInfo ;
}
/*
= = = = = = = = = = = = = = =
idPlayer : : UpdateHudAmmo
= = = = = = = = = = = = = = =
*/
void idPlayer : : UpdateHudAmmo ( idUserInterface * _hud ) {
int inclip ;
int ammoamount ;
assert ( weapon . GetEntity ( ) ) ;
assert ( _hud ) ;
inclip = weapon . GetEntity ( ) - > AmmoInClip ( ) ;
ammoamount = weapon . GetEntity ( ) - > AmmoAvailable ( ) ;
if ( ammoamount < 0 | | ! weapon . GetEntity ( ) - > IsReady ( ) ) {
// show infinite ammo
_hud - > SetStateString ( " player_ammo " , " " ) ;
_hud - > SetStateString ( " player_totalammo " , " " ) ;
2011-12-06 18:20:15 +00:00
} else {
2011-11-22 21:28:15 +00:00
// show remaining ammo
2018-08-26 03:41:08 +00:00
_hud - > SetStateString ( " player_totalammo " , va ( " %i " , ammoamount ) ) ; //new
2011-11-22 21:28:15 +00:00
_hud - > SetStateString ( " player_ammo " , weapon . GetEntity ( ) - > ClipSize ( ) ? va ( " %i " , inclip ) : " -- " ) ; // how much in the current clip
_hud - > SetStateString ( " player_clips " , weapon . GetEntity ( ) - > ClipSize ( ) ? va ( " %i " , ammoamount / weapon . GetEntity ( ) - > ClipSize ( ) ) : " -- " ) ;
2018-08-26 03:41:08 +00:00
_hud - > SetStateString ( " player_allammo " , va ( " %i/%i " , inclip , ammoamount ) ) ; //new
2011-12-06 18:20:15 +00:00
}
2011-11-22 21:28:15 +00:00
_hud - > SetStateBool ( " player_ammo_empty " , ( ammoamount = = 0 ) ) ;
_hud - > SetStateBool ( " player_clip_empty " , ( weapon . GetEntity ( ) - > ClipSize ( ) ? inclip = = 0 : false ) ) ;
_hud - > SetStateBool ( " player_clip_low " , ( weapon . GetEntity ( ) - > ClipSize ( ) ? inclip < = weapon . GetEntity ( ) - > LowAmmo ( ) : false ) ) ;
2018-08-26 03:41:08 +00:00
// Let the HUD know the total amount of ammo regardless of the ammo required value
_hud - > SetStateString ( " player_ammo_count " , va ( " %i " , weapon . GetEntity ( ) - > AmmoCount ( ) ) ) ; // new
2011-11-22 21:28:15 +00:00
_hud - > HandleNamedEvent ( " updateAmmo " ) ;
}
/*
= = = = = = = = = = = = = = =
idPlayer : : UpdateHudStats
= = = = = = = = = = = = = = =
*/
void idPlayer : : UpdateHudStats ( idUserInterface * _hud ) {
int staminapercentage ;
float max_stamina ;
assert ( _hud ) ;
max_stamina = pm_stamina . GetFloat ( ) ;
if ( ! max_stamina ) {
// stamina disabled, so show full stamina bar
staminapercentage = 100.0f ;
} else {
staminapercentage = idMath : : FtoiFast ( 100.0f * stamina / max_stamina ) ;
}
_hud - > SetStateInt ( " player_health " , health ) ;
_hud - > SetStateInt ( " player_stamina " , staminapercentage ) ;
_hud - > SetStateInt ( " player_armor " , inventory . armor ) ;
_hud - > SetStateInt ( " player_hr " , heartRate ) ;
_hud - > SetStateInt ( " player_nostamina " , ( max_stamina = = 0 ) ? 1 : 0 ) ;
_hud - > HandleNamedEvent ( " updateArmorHealthAir " ) ;
if ( healthPulse ) {
_hud - > HandleNamedEvent ( " healthPulse " ) ;
StartSound ( " snd_healthpulse " , SND_CHANNEL_ITEM , 0 , false , NULL ) ;
healthPulse = false ;
}
if ( healthTake ) {
_hud - > HandleNamedEvent ( " healthPulse " ) ;
StartSound ( " snd_healthtake " , SND_CHANNEL_ITEM , 0 , false , NULL ) ;
healthTake = false ;
}
2011-12-06 18:20:15 +00:00
if ( inventory . ammoPulse ) {
2011-11-22 21:28:15 +00:00
_hud - > HandleNamedEvent ( " ammoPulse " ) ;
inventory . ammoPulse = false ;
}
if ( inventory . weaponPulse ) {
// We need to update the weapon hud manually, but not
// the armor/ammo/health because they are updated every
// frame no matter what
UpdateHudWeapon ( ) ;
_hud - > HandleNamedEvent ( " weaponPulse " ) ;
inventory . weaponPulse = false ;
}
2011-12-06 18:20:15 +00:00
if ( inventory . armorPulse ) {
2011-11-22 21:28:15 +00:00
_hud - > HandleNamedEvent ( " armorPulse " ) ;
inventory . armorPulse = false ;
}
UpdateHudAmmo ( _hud ) ;
}
/*
= = = = = = = = = = = = = = =
idPlayer : : UpdateHudWeapon
= = = = = = = = = = = = = = =
*/
void idPlayer : : UpdateHudWeapon ( bool flashWeapon ) {
idUserInterface * hud = idPlayer : : hud ;
// if updating the hud of a followed client
if ( gameLocal . localClientNum > = 0 & & gameLocal . entities [ gameLocal . localClientNum ] & & gameLocal . entities [ gameLocal . localClientNum ] - > IsType ( idPlayer : : Type ) ) {
idPlayer * p = static_cast < idPlayer * > ( gameLocal . entities [ gameLocal . localClientNum ] ) ;
if ( p - > spectating & & p - > spectator = = entityNumber ) {
assert ( p - > hud ) ;
hud = p - > hud ;
}
}
if ( ! hud ) {
return ;
}
for ( int i = 0 ; i < MAX_WEAPONS ; i + + ) {
const char * weapnum = va ( " def_weapon%d " , i ) ;
const char * hudWeap = va ( " weapon%d " , i ) ;
int weapstate = 0 ;
if ( inventory . weapons & ( 1 < < i ) ) {
const char * weap = spawnArgs . GetString ( weapnum ) ;
if ( weap & & * weap ) {
weapstate + + ;
}
if ( idealWeapon = = i ) {
weapstate + + ;
}
}
hud - > SetStateInt ( hudWeap , weapstate ) ;
}
if ( flashWeapon ) {
hud - > HandleNamedEvent ( " weaponChange " ) ;
}
}
/*
= = = = = = = = = = = = = = =
idPlayer : : DrawHUD
= = = = = = = = = = = = = = =
*/
void idPlayer : : DrawHUD ( idUserInterface * _hud ) {
if ( ! weapon . GetEntity ( ) | | influenceActive ! = INFLUENCE_NONE | | privateCameraView | | gameLocal . GetCamera ( ) | | ! _hud | | ! g_showHud . GetBool ( ) ) {
return ;
}
UpdateHudStats ( _hud ) ;
_hud - > SetStateString ( " weapicon " , weapon . GetEntity ( ) - > Icon ( ) ) ;
// FIXME: this is temp to allow the sound meter to show up in the hud
// it should be commented out before shipping but the code can remain
// for mod developers to enable for the same functionality
_hud - > SetStateInt ( " s_debug " , cvarSystem - > GetCVarInteger ( " s_showLevelMeter " ) ) ;
weapon . GetEntity ( ) - > UpdateGUI ( ) ;
_hud - > Redraw ( gameLocal . realClientTime ) ;
// weapon targeting crosshair
if ( ! GuiActive ( ) ) {
if ( cursor & & weapon . GetEntity ( ) - > ShowCrosshair ( ) ) {
cursor - > Redraw ( gameLocal . realClientTime ) ;
}
}
}
/*
= = = = = = = = = = = = = = =
idPlayer : : EnterCinematic
= = = = = = = = = = = = = = =
*/
void idPlayer : : EnterCinematic ( void ) {
Hide ( ) ;
StopAudioLog ( ) ;
StopSound ( SND_CHANNEL_PDA , false ) ;
if ( hud ) {
hud - > HandleNamedEvent ( " radioChatterDown " ) ;
}
2011-12-06 18:20:15 +00:00
2011-11-22 21:28:15 +00:00
physicsObj . SetLinearVelocity ( vec3_origin ) ;
2011-12-06 18:20:15 +00:00
2011-11-22 21:28:15 +00:00
SetState ( " EnterCinematic " ) ;
UpdateScript ( ) ;
if ( weaponEnabled & & weapon . GetEntity ( ) ) {
weapon . GetEntity ( ) - > EnterCinematic ( ) ;
}
AI_FORWARD = false ;
AI_BACKWARD = false ;
AI_STRAFE_LEFT = false ;
AI_STRAFE_RIGHT = false ;
AI_RUN = false ;
AI_ATTACK_HELD = false ;
AI_WEAPON_FIRED = false ;
AI_JUMP = false ;
AI_CROUCH = false ;
AI_ONGROUND = true ;
AI_ONLADDER = false ;
AI_DEAD = ( health < = 0 ) ;
AI_RUN = false ;
AI_PAIN = false ;
AI_HARDLANDING = false ;
AI_SOFTLANDING = false ;
AI_RELOAD = false ;
AI_TELEPORT = false ;
AI_TURN_LEFT = false ;
AI_TURN_RIGHT = false ;
}
/*
= = = = = = = = = = = = = = =
idPlayer : : ExitCinematic
= = = = = = = = = = = = = = =
*/
void idPlayer : : ExitCinematic ( void ) {
Show ( ) ;
if ( weaponEnabled & & weapon . GetEntity ( ) ) {
weapon . GetEntity ( ) - > ExitCinematic ( ) ;
}
SetState ( " ExitCinematic " ) ;
UpdateScript ( ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idPlayer : : UpdateConditions
= = = = = = = = = = = = = = = = = = = = =
*/
void idPlayer : : UpdateConditions ( void ) {
idVec3 velocity ;
float forwardspeed ;
float sidespeed ;
// minus the push velocity to avoid playing the walking animation and sounds when riding a mover
velocity = physicsObj . GetLinearVelocity ( ) - physicsObj . GetPushedLinearVelocity ( ) ;
if ( influenceActive ) {
AI_FORWARD = false ;
AI_BACKWARD = false ;
AI_STRAFE_LEFT = false ;
AI_STRAFE_RIGHT = false ;
} else if ( gameLocal . time - lastDmgTime < 500 ) {
forwardspeed = velocity * viewAxis [ 0 ] ;
sidespeed = velocity * viewAxis [ 1 ] ;
AI_FORWARD = AI_ONGROUND & & ( forwardspeed > 20.01f ) ;
AI_BACKWARD = AI_ONGROUND & & ( forwardspeed < - 20.01f ) ;
AI_STRAFE_LEFT = AI_ONGROUND & & ( sidespeed > 20.01f ) ;
AI_STRAFE_RIGHT = AI_ONGROUND & & ( sidespeed < - 20.01f ) ;
} else if ( xyspeed > MIN_BOB_SPEED ) {
AI_FORWARD = AI_ONGROUND & & ( usercmd . forwardmove > 0 ) ;
AI_BACKWARD = AI_ONGROUND & & ( usercmd . forwardmove < 0 ) ;
AI_STRAFE_LEFT = AI_ONGROUND & & ( usercmd . rightmove < 0 ) ;
AI_STRAFE_RIGHT = AI_ONGROUND & & ( usercmd . rightmove > 0 ) ;
} else {
AI_FORWARD = false ;
AI_BACKWARD = false ;
AI_STRAFE_LEFT = false ;
AI_STRAFE_RIGHT = false ;
}
AI_RUN = ( usercmd . buttons & BUTTON_RUN ) & & ( ( ! pm_stamina . GetFloat ( ) ) | | ( stamina > pm_staminathreshold . GetFloat ( ) ) ) ;
AI_DEAD = ( health < = 0 ) ;
}
/*
= = = = = = = = = = = = = = = = = =
WeaponFireFeedback
Called when a weapon fires , generates head twitches , etc
= = = = = = = = = = = = = = = = = =
*/
void idPlayer : : WeaponFireFeedback ( const idDict * weaponDef ) {
// force a blink
blink_time = 0 ;
// play the fire animation
AI_WEAPON_FIRED = true ;
// update view feedback
playerView . WeaponFireFeedback ( weaponDef ) ;
}
/*
= = = = = = = = = = = = = = =
idPlayer : : StopFiring
= = = = = = = = = = = = = = =
*/
void idPlayer : : StopFiring ( void ) {
AI_ATTACK_HELD = false ;
AI_WEAPON_FIRED = false ;
AI_RELOAD = false ;
if ( weapon . GetEntity ( ) ) {
weapon . GetEntity ( ) - > EndAttack ( ) ;
}
}
/*
= = = = = = = = = = = = = = =
idPlayer : : FireWeapon
= = = = = = = = = = = = = = =
*/
void idPlayer : : FireWeapon ( void ) {
idMat3 axis ;
idVec3 muzzle ;
if ( privateCameraView ) {
return ;
}
if ( g_editEntityMode . GetInteger ( ) ) {
GetViewPos ( muzzle , axis ) ;
if ( gameLocal . editEntities - > SelectEntity ( muzzle , axis [ 0 ] , this ) ) {
return ;
}
}
if ( ! hiddenWeapon & & weapon . GetEntity ( ) - > IsReady ( ) ) {
2018-08-26 03:41:08 +00:00
# ifdef _DENTONMOD
if ( ( weapon_soulcube > = 0 ) & & ( currentWeapon = = weapon_soulcube ) & & currentWeapon = = idealWeapon ) {
if ( hud ) {
hud - > HandleNamedEvent ( " soulCubeNotReady " ) ;
}
quickWeapon = weapon_soulcube ;
SelectWeapon ( previousWeapon , false ) ;
}
2011-11-22 21:28:15 +00:00
if ( weapon . GetEntity ( ) - > AmmoInClip ( ) | | weapon . GetEntity ( ) - > AmmoAvailable ( ) ) {
AI_ATTACK_HELD = true ;
weapon . GetEntity ( ) - > BeginAttack ( ) ;
2018-08-26 03:41:08 +00:00
# else
if ( weapon . GetEntity ( ) - > AmmoInClip ( ) | | weapon . GetEntity ( ) - > AmmoAvailable ( ) ) {
AI_ATTACK_HELD = true ;
weapon . GetEntity ( ) - > BeginAttack ( ) ;
2011-11-22 21:28:15 +00:00
if ( ( weapon_soulcube > = 0 ) & & ( currentWeapon = = weapon_soulcube ) ) {
if ( hud ) {
hud - > HandleNamedEvent ( " soulCubeNotReady " ) ;
}
SelectWeapon ( previousWeapon , false ) ;
}
2018-08-26 03:41:08 +00:00
# endif
2011-11-22 21:28:15 +00:00
} else {
NextBestWeapon ( ) ;
}
}
if ( hud ) {
if ( tipUp ) {
HideTip ( ) ;
}
// may want to track with with a bool as well
// keep from looking up named events so often
if ( objectiveUp ) {
HideObjective ( ) ;
}
}
}
/*
= = = = = = = = = = = = = = =
idPlayer : : CacheWeapons
= = = = = = = = = = = = = = =
*/
void idPlayer : : CacheWeapons ( void ) {
idStr weap ;
int w ;
// check if we have any weapons
if ( ! inventory . weapons ) {
return ;
}
2011-12-06 18:20:15 +00:00
2011-11-22 21:28:15 +00:00
for ( w = 0 ; w < MAX_WEAPONS ; w + + ) {
if ( inventory . weapons & ( 1 < < w ) ) {
weap = spawnArgs . GetString ( va ( " def_weapon%d " , w ) ) ;
if ( weap ! = " " ) {
idWeapon : : CacheWeapon ( weap ) ;
} else {
inventory . weapons & = ~ ( 1 < < w ) ;
}
}
}
}
/*
= = = = = = = = = = = = = = =
idPlayer : : Give
= = = = = = = = = = = = = = =
*/
bool idPlayer : : Give ( const char * statname , const char * value ) {
int amount ;
if ( AI_DEAD ) {
return false ;
}
if ( ! idStr : : Icmp ( statname , " health " ) ) {
if ( health > = inventory . maxHealth ) {
return false ;
}
amount = atoi ( value ) ;
if ( amount ) {
health + = amount ;
if ( health > inventory . maxHealth ) {
health = inventory . maxHealth ;
}
if ( hud ) {
hud - > HandleNamedEvent ( " healthPulse " ) ;
}
}
} else if ( ! idStr : : Icmp ( statname , " stamina " ) ) {
if ( stamina > = 100 ) {
return false ;
}
stamina + = atof ( value ) ;
if ( stamina > 100 ) {
stamina = 100 ;
}
} else if ( ! idStr : : Icmp ( statname , " heartRate " ) ) {
heartRate + = atoi ( value ) ;
if ( heartRate > MAX_HEARTRATE ) {
heartRate = MAX_HEARTRATE ;
}
} else if ( ! idStr : : Icmp ( statname , " air " ) ) {
if ( airTics > = pm_airTics . GetInteger ( ) ) {
return false ;
}
airTics + = atoi ( value ) / 100.0 * pm_airTics . GetInteger ( ) ;
if ( airTics > pm_airTics . GetInteger ( ) ) {
airTics = pm_airTics . GetInteger ( ) ;
}
} else {
return inventory . Give ( this , spawnArgs , statname , value , & idealWeapon , true ) ;
}
return true ;
}
/*
= = = = = = = = = = = = = = =
idPlayer : : GiveHealthPool
adds health to the player health pool
= = = = = = = = = = = = = = =
*/
void idPlayer : : GiveHealthPool ( float amt ) {
2011-12-06 18:20:15 +00:00
2011-11-22 21:28:15 +00:00
if ( AI_DEAD ) {
return ;
}
if ( health > 0 ) {
healthPool + = amt ;
if ( healthPool > inventory . maxHealth - health ) {
healthPool = inventory . maxHealth - health ;
}
nextHealthPulse = gameLocal . time ;
}
}
/*
= = = = = = = = = = = = = = =
idPlayer : : GiveItem
Returns false if the item shouldn ' t be picked up
= = = = = = = = = = = = = = =
*/
bool idPlayer : : GiveItem ( idItem * item ) {
int i ;
const idKeyValue * arg ;
idDict attr ;
bool gave ;
int numPickup ;
if ( gameLocal . isMultiplayer & & spectating ) {
return false ;
}
item - > GetAttributes ( attr ) ;
2011-12-06 18:20:15 +00:00
2011-11-22 21:28:15 +00:00
gave = false ;
numPickup = inventory . pickupItemNames . Num ( ) ;
for ( i = 0 ; i < attr . GetNumKeyVals ( ) ; i + + ) {
arg = attr . GetKeyVal ( i ) ;
if ( Give ( arg - > GetKey ( ) , arg - > GetValue ( ) ) ) {
gave = true ;
}
}
arg = item - > spawnArgs . MatchPrefix ( " inv_weapon " , NULL ) ;
if ( arg & & hud ) {
// We need to update the weapon hud manually, but not
// the armor/ammo/health because they are updated every
// frame no matter what
UpdateHudWeapon ( false ) ;
hud - > HandleNamedEvent ( " weaponPulse " ) ;
}
// display the pickup feedback on the hud
if ( gave & & ( numPickup = = inventory . pickupItemNames . Num ( ) ) ) {
2018-08-26 03:41:08 +00:00
// inventory.AddPickupName( item->spawnArgs.GetString( "inv_name" ), item->spawnArgs.GetString( "inv_icon" ) );
inventory . AddPickupName ( item - > spawnArgs . GetString ( " inv_name " ) , item - > spawnArgs . GetString ( " inv_icon " ) , this ) ; //New _D3XP
2011-11-22 21:28:15 +00:00
}
return gave ;
}
/*
= = = = = = = = = = = = = = =
idPlayer : : PowerUpModifier
= = = = = = = = = = = = = = =
*/
float idPlayer : : PowerUpModifier ( int type ) {
float mod = 1.0f ;
if ( PowerUpActive ( BERSERK ) ) {
switch ( type ) {
case SPEED : {
mod * = 1.7f ;
break ;
}
case PROJECTILE_DAMAGE : {
mod * = 2.0f ;
break ;
}
case MELEE_DAMAGE : {
mod * = 30.0f ;
break ;
}
case MELEE_DISTANCE : {
mod * = 2.0f ;
break ;
}
}
}
if ( gameLocal . isMultiplayer & & ! gameLocal . isClient ) {
if ( PowerUpActive ( MEGAHEALTH ) ) {
if ( healthPool < = 0 ) {
GiveHealthPool ( 100 ) ;
}
} else {
healthPool = 0 ;
}
}
return mod ;
}
/*
= = = = = = = = = = = = = = =
idPlayer : : PowerUpActive
= = = = = = = = = = = = = = =
*/
bool idPlayer : : PowerUpActive ( int powerup ) const {
return ( inventory . powerups & ( 1 < < powerup ) ) ! = 0 ;
}
/*
= = = = = = = = = = = = = = =
idPlayer : : GivePowerUp
= = = = = = = = = = = = = = =
*/
bool idPlayer : : GivePowerUp ( int powerup , int time ) {
const char * sound ;
const char * skin ;
if ( powerup > = 0 & & powerup < MAX_POWERUPS ) {
if ( gameLocal . isServer ) {
idBitMsg msg ;
byte msgBuf [ MAX_EVENT_PARAM_SIZE ] ;
msg . Init ( msgBuf , sizeof ( msgBuf ) ) ;
msg . WriteShort ( powerup ) ;
msg . WriteBits ( 1 , 1 ) ;
ServerSendEvent ( EVENT_POWERUP , & msg , false , - 1 ) ;
}
if ( powerup ! = MEGAHEALTH ) {
inventory . GivePowerUp ( this , powerup , time ) ;
}
const idDeclEntityDef * def = NULL ;
switch ( powerup ) {
case BERSERK : {
if ( spawnArgs . GetString ( " snd_berserk_third " , " " , & sound ) ) {
StartSoundShader ( declManager - > FindSound ( sound ) , SND_CHANNEL_DEMONIC , 0 , false , NULL ) ;
}
if ( baseSkinName . Length ( ) ) {
powerUpSkin = declManager - > FindSkin ( baseSkinName + " _berserk " ) ;
}
if ( ! gameLocal . isClient ) {
idealWeapon = 0 ;
}
break ;
}
case INVISIBILITY : {
spawnArgs . GetString ( " skin_invisibility " , " " , & skin ) ;
powerUpSkin = declManager - > FindSkin ( skin ) ;
// remove any decals from the model
if ( modelDefHandle ! = - 1 ) {
gameRenderWorld - > RemoveDecals ( modelDefHandle ) ;
}
if ( weapon . GetEntity ( ) ) {
weapon . GetEntity ( ) - > UpdateSkin ( ) ;
}
if ( spawnArgs . GetString ( " snd_invisibility " , " " , & sound ) ) {
StartSoundShader ( declManager - > FindSound ( sound ) , SND_CHANNEL_ANY , 0 , false , NULL ) ;
}
break ;
}
case ADRENALINE : {
stamina = 100.0f ;
break ;
}
case MEGAHEALTH : {
if ( spawnArgs . GetString ( " snd_megahealth " , " " , & sound ) ) {
StartSoundShader ( declManager - > FindSound ( sound ) , SND_CHANNEL_ANY , 0 , false , NULL ) ;
}
def = gameLocal . FindEntityDef ( " powerup_megahealth " , false ) ;
if ( def ) {
health = def - > dict . GetInt ( " inv_health " ) ;
}
break ;
}
}
if ( hud ) {
hud - > HandleNamedEvent ( " itemPickup " ) ;
}
return true ;
} else {
gameLocal . Warning ( " Player given power up %i \n which is out of range " , powerup ) ;
}
return false ;
}
/*
= = = = = = = = = = = = = =
idPlayer : : ClearPowerup
= = = = = = = = = = = = = =
*/
void idPlayer : : ClearPowerup ( int i ) {
if ( gameLocal . isServer ) {
idBitMsg msg ;
byte msgBuf [ MAX_EVENT_PARAM_SIZE ] ;
msg . Init ( msgBuf , sizeof ( msgBuf ) ) ;
msg . WriteShort ( i ) ;
msg . WriteBits ( 0 , 1 ) ;
ServerSendEvent ( EVENT_POWERUP , & msg , false , - 1 ) ;
}
powerUpSkin = NULL ;
inventory . powerups & = ~ ( 1 < < i ) ;
inventory . powerupEndTime [ i ] = 0 ;
switch ( i ) {
case BERSERK : {
StopSound ( SND_CHANNEL_DEMONIC , false ) ;
break ;
}
case INVISIBILITY : {
if ( weapon . GetEntity ( ) ) {
weapon . GetEntity ( ) - > UpdateSkin ( ) ;
}
break ;
}
}
}
/*
= = = = = = = = = = = = = =
idPlayer : : UpdatePowerUps
= = = = = = = = = = = = = =
*/
void idPlayer : : UpdatePowerUps ( void ) {
int i ;
if ( ! gameLocal . isClient ) {
for ( i = 0 ; i < MAX_POWERUPS ; i + + ) {
if ( PowerUpActive ( i ) & & inventory . powerupEndTime [ i ] < = gameLocal . time ) {
ClearPowerup ( i ) ;
}
}
}
if ( health > 0 ) {
if ( powerUpSkin ) {
renderEntity . customSkin = powerUpSkin ;
} else {
renderEntity . customSkin = skin ;
}
}
if ( healthPool & & gameLocal . time > nextHealthPulse & & ! AI_DEAD & & health > 0 ) {
assert ( ! gameLocal . isClient ) ; // healthPool never be set on client
int amt = ( healthPool > 5 ) ? 5 : healthPool ;
health + = amt ;
if ( health > inventory . maxHealth ) {
health = inventory . maxHealth ;
healthPool = 0 ;
} else {
healthPool - = amt ;
}
nextHealthPulse = gameLocal . time + HEALTHPULSE_TIME ;
healthPulse = true ;
}
2012-07-01 22:02:40 +00:00
2011-11-22 21:28:15 +00:00
if ( ! gameLocal . inCinematic & & influenceActive = = 0 & & g_skill . GetInteger ( ) = = 3 & & gameLocal . time > nextHealthTake & & ! AI_DEAD & & health > g_healthTakeLimit . GetInteger ( ) ) {
assert ( ! gameLocal . isClient ) ; // healthPool never be set on client
health - = g_healthTakeAmt . GetInteger ( ) ;
if ( health < g_healthTakeLimit . GetInteger ( ) ) {
health = g_healthTakeLimit . GetInteger ( ) ;
}
nextHealthTake = gameLocal . time + g_healthTakeTime . GetInteger ( ) * 1000 ;
healthTake = true ;
}
}
/*
= = = = = = = = = = = = = = =
idPlayer : : ClearPowerUps
= = = = = = = = = = = = = = =
*/
void idPlayer : : ClearPowerUps ( void ) {
int i ;
for ( i = 0 ; i < MAX_POWERUPS ; i + + ) {
if ( PowerUpActive ( i ) ) {
ClearPowerup ( i ) ;
}
}
inventory . ClearPowerUps ( ) ;
}
/*
= = = = = = = = = = = = = = =
idPlayer : : GiveInventoryItem
= = = = = = = = = = = = = = =
*/
bool idPlayer : : GiveInventoryItem ( idDict * item ) {
if ( gameLocal . isMultiplayer & & spectating ) {
return false ;
}
inventory . items . Append ( new idDict ( * item ) ) ;
idItemInfo info ;
const char * itemName = item - > GetString ( " inv_name " ) ;
if ( idStr : : Cmpn ( itemName , STRTABLE_ID , STRTABLE_ID_LENGTH ) = = 0 ) {
info . name = common - > GetLanguageDict ( ) - > GetString ( itemName ) ;
} else {
info . name = itemName ;
}
info . icon = item - > GetString ( " inv_icon " ) ;
inventory . pickupItemNames . Append ( info ) ;
if ( hud ) {
hud - > SetStateString ( " itemicon " , info . icon ) ;
hud - > HandleNamedEvent ( " invPickup " ) ;
}
return true ;
}
/*
= = = = = = = = = = = = = =
idPlayer : : UpdateObjectiveInfo
= = = = = = = = = = = = = =
*/
void idPlayer : : UpdateObjectiveInfo ( void ) {
if ( objectiveSystem = = NULL ) {
return ;
}
objectiveSystem - > SetStateString ( " objective1 " , " " ) ;
objectiveSystem - > SetStateString ( " objective2 " , " " ) ;
objectiveSystem - > SetStateString ( " objective3 " , " " ) ;
for ( int i = 0 ; i < inventory . objectiveNames . Num ( ) ; i + + ) {
objectiveSystem - > SetStateString ( va ( " objective%i " , i + 1 ) , " 1 " ) ;
objectiveSystem - > SetStateString ( va ( " objectivetitle%i " , i + 1 ) , inventory . objectiveNames [ i ] . title . c_str ( ) ) ;
objectiveSystem - > SetStateString ( va ( " objectivetext%i " , i + 1 ) , inventory . objectiveNames [ i ] . text . c_str ( ) ) ;
objectiveSystem - > SetStateString ( va ( " objectiveshot%i " , i + 1 ) , inventory . objectiveNames [ i ] . screenshot . c_str ( ) ) ;
}
objectiveSystem - > StateChanged ( gameLocal . time ) ;
}
/*
= = = = = = = = = = = = = = =
idPlayer : : GiveObjective
= = = = = = = = = = = = = = =
*/
void idPlayer : : GiveObjective ( const char * title , const char * text , const char * screenshot ) {
idObjectiveInfo info ;
info . title = title ;
info . text = text ;
info . screenshot = screenshot ;
inventory . objectiveNames . Append ( info ) ;
ShowObjective ( " newObjective " ) ;
if ( hud ) {
hud - > HandleNamedEvent ( " newObjective " ) ;
}
}
/*
= = = = = = = = = = = = = = =
idPlayer : : CompleteObjective
= = = = = = = = = = = = = = =
*/
void idPlayer : : CompleteObjective ( const char * title ) {
int c = inventory . objectiveNames . Num ( ) ;
for ( int i = 0 ; i < c ; i + + ) {
if ( idStr : : Icmp ( inventory . objectiveNames [ i ] . title , title ) = = 0 ) {
inventory . objectiveNames . RemoveIndex ( i ) ;
break ;
}
}
ShowObjective ( " newObjectiveComplete " ) ;
if ( hud ) {
hud - > HandleNamedEvent ( " newObjectiveComplete " ) ;
}
}
/*
= = = = = = = = = = = = = = =
idPlayer : : GiveVideo
= = = = = = = = = = = = = = =
*/
void idPlayer : : GiveVideo ( const char * videoName , idDict * item ) {
2011-11-30 22:14:44 +00:00
if ( videoName = = NULL | | * videoName = = 0 ) {
2011-11-22 21:28:15 +00:00
return ;
}
inventory . videos . AddUnique ( videoName ) ;
if ( item ) {
idItemInfo info ;
info . name = item - > GetString ( " inv_name " ) ;
info . icon = item - > GetString ( " inv_icon " ) ;
inventory . pickupItemNames . Append ( info ) ;
}
if ( hud ) {
hud - > HandleNamedEvent ( " videoPickup " ) ;
}
}
/*
= = = = = = = = = = = = = = =
idPlayer : : GiveSecurity
= = = = = = = = = = = = = = =
*/
void idPlayer : : GiveSecurity ( const char * security ) {
GetPDA ( ) - > SetSecurity ( security ) ;
if ( hud ) {
hud - > SetStateString ( " pda_security " , " 1 " ) ;
hud - > HandleNamedEvent ( " securityPickup " ) ;
}
}
/*
= = = = = = = = = = = = = = =
idPlayer : : GiveEmail
= = = = = = = = = = = = = = =
*/
void idPlayer : : GiveEmail ( const char * emailName ) {
2011-11-30 22:14:44 +00:00
if ( emailName = = NULL | | * emailName = = 0 ) {
2011-11-22 21:28:15 +00:00
return ;
}
inventory . emails . AddUnique ( emailName ) ;
GetPDA ( ) - > AddEmail ( emailName ) ;
if ( hud ) {
hud - > HandleNamedEvent ( " emailPickup " ) ;
}
}
/*
= = = = = = = = = = = = = = =
idPlayer : : GivePDA
= = = = = = = = = = = = = = =
*/
void idPlayer : : GivePDA ( const char * pdaName , idDict * item )
{
if ( gameLocal . isMultiplayer & & spectating ) {
return ;
}
if ( item ) {
inventory . pdaSecurity . AddUnique ( item - > GetString ( " inv_name " ) ) ;
}
2011-11-30 22:14:44 +00:00
if ( pdaName = = NULL | | * pdaName = = 0 ) {
2011-11-22 21:28:15 +00:00
pdaName = " personal " ;
}
const idDeclPDA * pda = static_cast < const idDeclPDA * > ( declManager - > FindType ( DECL_PDA , pdaName ) ) ;
inventory . pdas . AddUnique ( pdaName ) ;
// Copy any videos over
for ( int i = 0 ; i < pda - > GetNumVideos ( ) ; i + + ) {
const idDeclVideo * video = pda - > GetVideoByIndex ( i ) ;
if ( video ) {
inventory . videos . AddUnique ( video - > GetName ( ) ) ;
}
}
// This is kind of a hack, but it works nicely
// We don't want to display the 'you got a new pda' message during a map load
if ( gameLocal . GetFrameNum ( ) > 10 ) {
if ( pda & & hud ) {
idStr pdaName = pda - > GetPdaName ( ) ;
pdaName . RemoveColors ( ) ;
hud - > SetStateString ( " pda " , " 1 " ) ;
hud - > SetStateString ( " pda_text " , pdaName ) ;
const char * sec = pda - > GetSecurity ( ) ;
hud - > SetStateString ( " pda_security " , ( sec & & * sec ) ? " 1 " : " 0 " ) ;
hud - > HandleNamedEvent ( " pdaPickup " ) ;
}
if ( inventory . pdas . Num ( ) = = 1 ) {
GetPDA ( ) - > RemoveAddedEmailsAndVideos ( ) ;
if ( ! objectiveSystemOpen ) {
TogglePDA ( ) ;
}
objectiveSystem - > HandleNamedEvent ( " showPDATip " ) ;
//ShowTip( spawnArgs.GetString( "text_infoTitle" ), spawnArgs.GetString( "text_firstPDA" ), true );
}
if ( inventory . pdas . Num ( ) > 1 & & pda - > GetNumVideos ( ) > 0 & & hud ) {
hud - > HandleNamedEvent ( " videoPickup " ) ;
}
}
}
/*
= = = = = = = = = = = = = = =
idPlayer : : FindInventoryItem
= = = = = = = = = = = = = = =
*/
idDict * idPlayer : : FindInventoryItem ( const char * name ) {
for ( int i = 0 ; i < inventory . items . Num ( ) ; i + + ) {
const char * iname = inventory . items [ i ] - > GetString ( " inv_name " ) ;
if ( iname & & * iname ) {
if ( idStr : : Icmp ( name , iname ) = = 0 ) {
return inventory . items [ i ] ;
}
}
}
return NULL ;
}
/*
= = = = = = = = = = = = = = =
idPlayer : : RemoveInventoryItem
= = = = = = = = = = = = = = =
*/
void idPlayer : : RemoveInventoryItem ( const char * name ) {
idDict * item = FindInventoryItem ( name ) ;
if ( item ) {
RemoveInventoryItem ( item ) ;
}
}
/*
= = = = = = = = = = = = = = =
idPlayer : : RemoveInventoryItem
= = = = = = = = = = = = = = =
*/
void idPlayer : : RemoveInventoryItem ( idDict * item ) {
inventory . items . Remove ( item ) ;
delete item ;
}
/*
= = = = = = = = = = = = = = =
idPlayer : : GiveItem
= = = = = = = = = = = = = = =
*/
void idPlayer : : GiveItem ( const char * itemname ) {
idDict args ;
args . Set ( " classname " , itemname ) ;
args . Set ( " owner " , name . c_str ( ) ) ;
gameLocal . SpawnEntityDef ( args ) ;
if ( hud ) {
hud - > HandleNamedEvent ( " itemPickup " ) ;
}
}
/*
= = = = = = = = = = = = = = = = = =
idPlayer : : SlotForWeapon
= = = = = = = = = = = = = = = = = =
*/
int idPlayer : : SlotForWeapon ( const char * weaponName ) {
int i ;
for ( i = 0 ; i < MAX_WEAPONS ; i + + ) {
const char * weap = spawnArgs . GetString ( va ( " def_weapon%d " , i ) ) ;
if ( ! idStr : : Cmp ( weap , weaponName ) ) {
return i ;
}
}
// not found
return - 1 ;
}
/*
= = = = = = = = = = = = = = =
idPlayer : : Reload
= = = = = = = = = = = = = = =
*/
void idPlayer : : Reload ( void ) {
if ( gameLocal . isClient ) {
return ;
}
if ( spectating | | gameLocal . inCinematic | | influenceActive ) {
return ;
}
if ( weapon . GetEntity ( ) & & weapon . GetEntity ( ) - > IsLinked ( ) ) {
weapon . GetEntity ( ) - > Reload ( ) ;
}
}
2018-08-26 03:41:08 +00:00
/*
= = = = = = = = = = = = = = =
idPlayer : : WeaponSpecialFunction
Weapon special function - Added by Clone JC Denton
= = = = = = = = = = = = = = =
*/
void idPlayer : : WeaponSpecialFunction ( bool keyTapped ) {
if ( gameLocal . isClient ) {
return ;
}
if ( spectating | | gameLocal . inCinematic | | influenceActive ) {
return ;
}
if ( ! hiddenWeapon & & weapon . GetEntity ( ) & & weapon . GetEntity ( ) - > IsLinked ( ) ) {
weapon . GetEntity ( ) - > BeginSpecialFunction ( keyTapped ) ;
}
}
2011-11-22 21:28:15 +00:00
/*
= = = = = = = = = = = = = = =
idPlayer : : NextBestWeapon
= = = = = = = = = = = = = = =
*/
void idPlayer : : NextBestWeapon ( void ) {
const char * weap ;
int w = MAX_WEAPONS ;
2018-08-26 03:41:08 +00:00
# ifdef _DENTONMOD
if ( gameLocal . isClient | | ! weaponEnabled | | currentWeapon ! = idealWeapon ) {
# else
2011-11-22 21:28:15 +00:00
if ( gameLocal . isClient | | ! weaponEnabled ) {
2018-08-26 03:41:08 +00:00
# endif
2011-11-22 21:28:15 +00:00
return ;
}
while ( w > 0 ) {
w - - ;
weap = spawnArgs . GetString ( va ( " def_weapon%d " , w ) ) ;
2018-08-26 03:41:08 +00:00
if ( ! weap [ 0 ] | | ( ( inventory . weapons & ( 1 < < w ) ) = = 0 ) | | ( ! inventory . HasAmmo ( weap , true , this ) ) ) { //new
//if ( !weap[ 0 ] || ( ( inventory.weapons & ( 1 << w ) ) == 0 ) || ( !inventory.HasAmmo( weap ) ) ) {
2011-11-22 21:28:15 +00:00
continue ;
}
if ( ! spawnArgs . GetBool ( va ( " weapon%d_best " , w ) ) ) {
continue ;
}
break ;
}
2018-08-26 03:41:08 +00:00
# ifdef _DENTONMOD
if ( w ! = idealWeapon ) {
quickWeapon = idealWeapon ;
}
# endif
2011-11-22 21:28:15 +00:00
idealWeapon = w ;
weaponSwitchTime = gameLocal . time + WEAPON_SWITCH_DELAY ;
UpdateHudWeapon ( ) ;
}
/*
= = = = = = = = = = = = = = =
idPlayer : : NextWeapon
= = = = = = = = = = = = = = =
*/
void idPlayer : : NextWeapon ( void ) {
const char * weap ;
int w ;
if ( ! weaponEnabled | | spectating | | hiddenWeapon | | gameLocal . inCinematic | | gameLocal . world - > spawnArgs . GetBool ( " no_Weapons " ) | | health < 0 ) {
return ;
}
if ( gameLocal . isClient ) {
return ;
}
// check if we have any weapons
if ( ! inventory . weapons ) {
return ;
}
2011-12-06 18:20:15 +00:00
2011-11-22 21:28:15 +00:00
w = idealWeapon ;
while ( 1 ) {
w + + ;
if ( w > = MAX_WEAPONS ) {
w = 0 ;
2011-12-06 18:20:15 +00:00
}
2011-11-22 21:28:15 +00:00
weap = spawnArgs . GetString ( va ( " def_weapon%d " , w ) ) ;
if ( ! spawnArgs . GetBool ( va ( " weapon%d_cycle " , w ) ) ) {
continue ;
}
if ( ! weap [ 0 ] ) {
continue ;
}
if ( ( inventory . weapons & ( 1 < < w ) ) = = 0 ) {
continue ;
}
2018-08-26 03:41:08 +00:00
if ( inventory . HasAmmo ( weap , true , this ) ) { //new
// if ( inventory.HasAmmo( weap ) ) {
2011-11-22 21:28:15 +00:00
break ;
}
}
if ( ( w ! = currentWeapon ) & & ( w ! = idealWeapon ) ) {
idealWeapon = w ;
weaponSwitchTime = gameLocal . time + WEAPON_SWITCH_DELAY ;
UpdateHudWeapon ( ) ;
}
}
/*
= = = = = = = = = = = = = = =
idPlayer : : PrevWeapon
= = = = = = = = = = = = = = =
*/
void idPlayer : : PrevWeapon ( void ) {
const char * weap ;
int w ;
if ( ! weaponEnabled | | spectating | | hiddenWeapon | | gameLocal . inCinematic | | gameLocal . world - > spawnArgs . GetBool ( " no_Weapons " ) | | health < 0 ) {
return ;
}
if ( gameLocal . isClient ) {
return ;
}
// check if we have any weapons
if ( ! inventory . weapons ) {
return ;
}
w = idealWeapon ;
while ( 1 ) {
w - - ;
if ( w < 0 ) {
w = MAX_WEAPONS - 1 ;
}
weap = spawnArgs . GetString ( va ( " def_weapon%d " , w ) ) ;
if ( ! spawnArgs . GetBool ( va ( " weapon%d_cycle " , w ) ) ) {
continue ;
}
if ( ! weap [ 0 ] ) {
continue ;
}
if ( ( inventory . weapons & ( 1 < < w ) ) = = 0 ) {
continue ;
}
2018-08-26 03:41:08 +00:00
if ( inventory . HasAmmo ( weap , true , this ) ) { //new
//if ( inventory.HasAmmo( weap ) ) {
2011-11-22 21:28:15 +00:00
break ;
}
}
if ( ( w ! = currentWeapon ) & & ( w ! = idealWeapon ) ) {
idealWeapon = w ;
weaponSwitchTime = gameLocal . time + WEAPON_SWITCH_DELAY ;
UpdateHudWeapon ( ) ;
}
}
/*
= = = = = = = = = = = = = = =
idPlayer : : SelectWeapon
= = = = = = = = = = = = = = =
*/
2018-08-26 03:41:08 +00:00
void idPlayer : : SelectWeapon ( int num , bool force , const bool toggleWeapons ) {
2011-11-22 21:28:15 +00:00
const char * weap ;
if ( ! weaponEnabled | | spectating | | gameLocal . inCinematic | | health < 0 ) {
return ;
}
if ( ( num < 0 ) | | ( num > = MAX_WEAPONS ) ) {
return ;
}
if ( gameLocal . isClient ) {
return ;
}
if ( ( num ! = weapon_pda ) & & gameLocal . world - > spawnArgs . GetBool ( " no_Weapons " ) ) {
num = weapon_fists ;
hiddenWeapon ^ = 1 ;
if ( hiddenWeapon & & weapon . GetEntity ( ) ) {
weapon . GetEntity ( ) - > LowerWeapon ( ) ;
} else {
weapon . GetEntity ( ) - > RaiseWeapon ( ) ;
}
2011-12-06 18:20:15 +00:00
}
2011-11-22 21:28:15 +00:00
weap = spawnArgs . GetString ( va ( " def_weapon%d " , num ) ) ;
if ( ! weap [ 0 ] ) {
gameLocal . Printf ( " Invalid weapon \n " ) ;
return ;
}
2018-08-26 03:41:08 +00:00
WeaponToggle_t * weaponToggle ;
//Is the weapon a toggle weapon & player is trying to select it.
if ( weaponToggles . Get ( va ( " weapontoggle%d " , num ) , & weaponToggle ) & & toggleWeapons ) {
int weaponToggleIndex = 0 ;
//Find the current Weapon in the list
int currentIndex = - 1 ;
for ( int i = 0 ; i < weaponToggle - > toggleList . Num ( ) ; i + + ) {
if ( weaponToggle - > toggleList [ i ] = = idealWeapon ) {
currentIndex = i ;
break ;
}
}
if ( currentIndex = = - 1 ) {
//Didn't find the current weapon so select the first item
weaponToggleIndex = 0 ;
} else {
//Roll to the next available item in the list
weaponToggleIndex = currentIndex ;
weaponToggleIndex + + ;
if ( weaponToggleIndex > = weaponToggle - > toggleList . Num ( ) ) {
weaponToggleIndex = 0 ;
}
}
for ( int i = 0 ; i < weaponToggle - > toggleList . Num ( ) ; i + + ) {
//Is it available
if ( inventory . weapons & ( 1 < < weaponToggle - > toggleList [ weaponToggleIndex ] ) ) {
break ;
}
weaponToggleIndex + + ;
if ( weaponToggleIndex > = weaponToggle - > toggleList . Num ( ) ) {
weaponToggleIndex = 0 ;
}
}
num = weaponToggle - > toggleList [ weaponToggleIndex ] ;
}
2011-11-22 21:28:15 +00:00
if ( force | | ( inventory . weapons & ( 1 < < num ) ) ) {
2018-08-26 03:41:08 +00:00
if ( ! inventory . HasAmmo ( weap , true , this ) & & ! spawnArgs . GetBool ( va ( " weapon%d_allowempty " , num ) ) ) {
2011-11-22 21:28:15 +00:00
return ;
}
if ( ( previousWeapon > = 0 ) & & ( idealWeapon = = num ) & & ( spawnArgs . GetBool ( va ( " weapon%d_toggle " , num ) ) ) ) {
weap = spawnArgs . GetString ( va ( " def_weapon%d " , previousWeapon ) ) ;
2018-08-26 03:41:08 +00:00
if ( ! inventory . HasAmmo ( weap , true , this ) & & ! spawnArgs . GetBool ( va ( " weapon%d_allowempty " , previousWeapon ) ) ) {
2011-11-22 21:28:15 +00:00
return ;
}
idealWeapon = previousWeapon ;
} else if ( ( weapon_pda > = 0 ) & & ( num = = weapon_pda ) & & ( inventory . pdas . Num ( ) = = 0 ) ) {
ShowTip ( spawnArgs . GetString ( " text_infoTitle " ) , spawnArgs . GetString ( " text_noPDA " ) , true ) ;
return ;
} else {
idealWeapon = num ;
}
UpdateHudWeapon ( ) ;
}
}
/*
= = = = = = = = = = = = = = = = =
idPlayer : : DropWeapon
= = = = = = = = = = = = = = = = =
*/
void idPlayer : : DropWeapon ( bool died ) {
idVec3 forward , up ;
int inclip , ammoavailable ;
assert ( ! gameLocal . isClient ) ;
2011-12-06 18:20:15 +00:00
2011-11-22 21:28:15 +00:00
if ( spectating | | weaponGone | | weapon . GetEntity ( ) = = NULL ) {
return ;
}
2011-12-06 18:20:15 +00:00
2011-11-22 21:28:15 +00:00
if ( ( ! died & & ! weapon . GetEntity ( ) - > IsReady ( ) ) | | weapon . GetEntity ( ) - > IsReloading ( ) ) {
return ;
}
// ammoavailable is how many shots we can fire
// inclip is which amount is in clip right now
ammoavailable = weapon . GetEntity ( ) - > AmmoAvailable ( ) ;
inclip = weapon . GetEntity ( ) - > AmmoInClip ( ) ;
2011-12-06 18:20:15 +00:00
2011-11-22 21:28:15 +00:00
// don't drop a grenade if we have none left
if ( ! idStr : : Icmp ( idWeapon : : GetAmmoNameForNum ( weapon . GetEntity ( ) - > GetAmmoType ( ) ) , " ammo_grenades " ) & & ( ammoavailable - inclip < = 0 ) ) {
return ;
}
2018-08-26 03:41:08 +00:00
ammoavailable + = inclip ; //new
2011-11-22 21:28:15 +00:00
// expect an ammo setup that makes sense before doing any dropping
// ammoavailable is -1 for infinite ammo, and weapons like chainsaw
// a bad ammo config usually indicates a bad weapon state, so we should not drop
// used to be an assertion check, but it still happens in edge cases
if ( ( ammoavailable ! = - 1 ) & & ( ammoavailable - inclip < 0 ) ) {
common - > DPrintf ( " idPlayer::DropWeapon: bad ammo setup \n " ) ;
return ;
}
idEntity * item = NULL ;
if ( died ) {
// ain't gonna throw you no weapon if I'm dead
item = weapon . GetEntity ( ) - > DropItem ( vec3_origin , 0 , WEAPON_DROP_TIME , died ) ;
} else {
viewAngles . ToVectors ( & forward , NULL , & up ) ;
item = weapon . GetEntity ( ) - > DropItem ( 250.0f * forward + 150.0f * up , 500 , WEAPON_DROP_TIME , died ) ;
}
if ( ! item ) {
return ;
}
// set the appropriate ammo in the dropped object
const idKeyValue * keyval = item - > spawnArgs . MatchPrefix ( " inv_ammo_ " ) ;
if ( keyval ) {
item - > spawnArgs . SetInt ( keyval - > GetKey ( ) , ammoavailable ) ;
idStr inclipKey = keyval - > GetKey ( ) ;
inclipKey . Insert ( " inclip_ " , 4 ) ;
2018-08-26 03:41:08 +00:00
inclipKey . Insert ( va ( " %.2d " , currentWeapon ) , 11 ) ; //new
2011-11-22 21:28:15 +00:00
item - > spawnArgs . SetInt ( inclipKey , inclip ) ;
}
if ( ! died ) {
// remove from our local inventory completely
inventory . Drop ( spawnArgs , item - > spawnArgs . GetString ( " inv_weapon " ) , - 1 ) ;
weapon . GetEntity ( ) - > ResetAmmoClip ( ) ;
NextWeapon ( ) ;
weapon . GetEntity ( ) - > WeaponStolen ( ) ;
weaponGone = true ;
}
}
/*
= = = = = = = = = = = = = = = = =
idPlayer : : StealWeapon
steal the target player ' s current weapon
= = = = = = = = = = = = = = = = =
*/
void idPlayer : : StealWeapon ( idPlayer * player ) {
assert ( ! gameLocal . isClient ) ;
// make sure there's something to steal
idWeapon * player_weapon = static_cast < idWeapon * > ( player - > weapon . GetEntity ( ) ) ;
if ( ! player_weapon | | ! player_weapon - > CanDrop ( ) | | weaponGone ) {
return ;
}
// steal - we need to effectively force the other player to abandon his weapon
int newweap = player - > currentWeapon ;
if ( newweap = = - 1 ) {
return ;
}
// might be just dropped - check inventory
if ( ! ( player - > inventory . weapons & ( 1 < < newweap ) ) ) {
return ;
}
const char * weapon_classname = spawnArgs . GetString ( va ( " def_weapon%d " , newweap ) ) ;
assert ( weapon_classname ) ;
int ammoavailable = player - > weapon . GetEntity ( ) - > AmmoAvailable ( ) ;
int inclip = player - > weapon . GetEntity ( ) - > AmmoInClip ( ) ;
2018-08-26 03:41:08 +00:00
ammoavailable + = inclip ; //new
2011-11-22 21:28:15 +00:00
if ( ( ammoavailable ! = - 1 ) & & ( ammoavailable - inclip < 0 ) ) {
// see DropWeapon
common - > DPrintf ( " idPlayer::StealWeapon: bad ammo setup \n " ) ;
// we still steal the weapon, so let's use the default ammo levels
inclip = - 1 ;
const idDeclEntityDef * decl = gameLocal . FindEntityDef ( weapon_classname ) ;
assert ( decl ) ;
const idKeyValue * keypair = decl - > dict . MatchPrefix ( " inv_ammo_ " ) ;
assert ( keypair ) ;
ammoavailable = atoi ( keypair - > GetValue ( ) ) ;
}
player - > weapon . GetEntity ( ) - > WeaponStolen ( ) ;
player - > inventory . Drop ( player - > spawnArgs , NULL , newweap ) ;
player - > SelectWeapon ( weapon_fists , false ) ;
// in case the robbed player is firing rounds with a continuous fire weapon like the chaingun/plasma etc.
// this will ensure the firing actually stops
player - > weaponGone = true ;
// give weapon, setup the ammo count
Give ( " weapon " , weapon_classname ) ;
ammo_t ammo_i = player - > inventory . AmmoIndexForWeaponClass ( weapon_classname , NULL ) ;
idealWeapon = newweap ;
inventory . ammo [ ammo_i ] + = ammoavailable ;
inventory . clip [ newweap ] = inclip ;
}
/*
= = = = = = = = = = = = = = =
idPlayer : : ActiveGui
= = = = = = = = = = = = = = =
*/
idUserInterface * idPlayer : : ActiveGui ( void ) {
if ( objectiveSystemOpen ) {
return objectiveSystem ;
}
return focusUI ;
}
/*
= = = = = = = = = = = = = = =
idPlayer : : Weapon_Combat
= = = = = = = = = = = = = = =
*/
void idPlayer : : Weapon_Combat ( void ) {
if ( influenceActive | | ! weaponEnabled | | gameLocal . inCinematic | | privateCameraView ) {
return ;
}
weapon . GetEntity ( ) - > RaiseWeapon ( ) ;
if ( weapon . GetEntity ( ) - > IsReloading ( ) ) {
if ( ! AI_RELOAD ) {
AI_RELOAD = true ;
SetState ( " ReloadWeapon " ) ;
UpdateScript ( ) ;
}
} else {
AI_RELOAD = false ;
}
if ( idealWeapon = = weapon_soulcube & & soulCubeProjectile . GetEntity ( ) ! = NULL ) {
idealWeapon = currentWeapon ;
}
if ( idealWeapon ! = currentWeapon ) {
if ( weaponCatchup ) {
assert ( gameLocal . isClient ) ;
currentWeapon = idealWeapon ;
weaponGone = false ;
animPrefix = spawnArgs . GetString ( va ( " def_weapon%d " , currentWeapon ) ) ;
weapon . GetEntity ( ) - > GetWeaponDef ( animPrefix , inventory . clip [ currentWeapon ] ) ;
animPrefix . Strip ( " weapon_ " ) ;
weapon . GetEntity ( ) - > NetCatchup ( ) ;
const function_t * newstate = GetScriptFunction ( " NetCatchup " ) ;
if ( newstate ) {
SetState ( newstate ) ;
UpdateScript ( ) ;
}
2011-12-06 18:20:15 +00:00
weaponCatchup = false ;
2011-11-22 21:28:15 +00:00
} else {
if ( weapon . GetEntity ( ) - > IsReady ( ) ) {
weapon . GetEntity ( ) - > PutAway ( ) ;
}
if ( weapon . GetEntity ( ) - > IsHolstered ( ) ) {
assert ( idealWeapon > = 0 ) ;
assert ( idealWeapon < MAX_WEAPONS ) ;
if ( currentWeapon ! = weapon_pda & & ! spawnArgs . GetBool ( va ( " weapon%d_toggle " , currentWeapon ) ) ) {
previousWeapon = currentWeapon ;
}
currentWeapon = idealWeapon ;
weaponGone = false ;
animPrefix = spawnArgs . GetString ( va ( " def_weapon%d " , currentWeapon ) ) ;
weapon . GetEntity ( ) - > GetWeaponDef ( animPrefix , inventory . clip [ currentWeapon ] ) ;
animPrefix . Strip ( " weapon_ " ) ;
weapon . GetEntity ( ) - > Raise ( ) ;
}
}
} else {
2011-12-06 18:20:15 +00:00
weaponGone = false ; // if you drop and re-get weap, you may miss the = false above
2011-11-22 21:28:15 +00:00
if ( weapon . GetEntity ( ) - > IsHolstered ( ) ) {
if ( ! weapon . GetEntity ( ) - > AmmoAvailable ( ) ) {
2018-08-26 03:41:08 +00:00
# ifdef _DENTONMOD // If weapon with no ammo is soulcube, switch to previous weapon
if ( ( weapon_soulcube > = 0 ) & & ( currentWeapon = = weapon_soulcube ) & & currentWeapon = = idealWeapon ) {
if ( hud ) {
hud - > HandleNamedEvent ( " soulCubeNotReady " ) ;
}
quickWeapon = weapon_soulcube ;
SelectWeapon ( previousWeapon , false ) ;
} else {
// weapons can switch automatically if they have no more ammo
NextBestWeapon ( ) ;
}
# else
2011-11-22 21:28:15 +00:00
// weapons can switch automatically if they have no more ammo
NextBestWeapon ( ) ;
2018-08-26 03:41:08 +00:00
# endif
2011-11-22 21:28:15 +00:00
} else {
weapon . GetEntity ( ) - > Raise ( ) ;
state = GetScriptFunction ( " RaiseWeapon " ) ;
if ( state ) {
SetState ( state ) ;
}
}
}
}
// check for attack
AI_WEAPON_FIRED = false ;
if ( ! influenceActive ) {
if ( ( usercmd . buttons & BUTTON_ATTACK ) & & ! weaponGone ) {
FireWeapon ( ) ;
} else if ( oldButtons & BUTTON_ATTACK ) {
AI_ATTACK_HELD = false ;
weapon . GetEntity ( ) - > EndAttack ( ) ;
}
2018-08-26 03:41:08 +00:00
// check for Weapon special function, new
if ( ( usercmd . buttons & BUTTON_5 ) & & ! weaponGone ) { // BUTTON_5 is being used for weapon special function
WeaponSpecialFunction ( ! ( oldButtons & BUTTON_5 ) ) ; // The condition holds True when key is being tapped rather than held
} else if ( oldButtons & BUTTON_5 ) {
weapon . GetEntity ( ) - > EndSpecialFunction ( ) ;
}
2011-11-22 21:28:15 +00:00
}
// update our ammo clip in our inventory
if ( ( currentWeapon > = 0 ) & & ( currentWeapon < MAX_WEAPONS ) ) {
inventory . clip [ currentWeapon ] = weapon . GetEntity ( ) - > AmmoInClip ( ) ;
if ( hud & & ( currentWeapon = = idealWeapon ) ) {
UpdateHudAmmo ( hud ) ;
}
}
}
/*
= = = = = = = = = = = = = = =
idPlayer : : Weapon_NPC
= = = = = = = = = = = = = = =
*/
void idPlayer : : Weapon_NPC ( void ) {
if ( idealWeapon ! = currentWeapon ) {
Weapon_Combat ( ) ;
}
StopFiring ( ) ;
weapon . GetEntity ( ) - > LowerWeapon ( ) ;
if ( ( usercmd . buttons & BUTTON_ATTACK ) & & ! ( oldButtons & BUTTON_ATTACK ) ) {
buttonMask | = BUTTON_ATTACK ;
focusCharacter - > TalkTo ( this ) ;
}
}
/*
= = = = = = = = = = = = = = =
idPlayer : : LowerWeapon
= = = = = = = = = = = = = = =
*/
void idPlayer : : LowerWeapon ( void ) {
if ( weapon . GetEntity ( ) & & ! weapon . GetEntity ( ) - > IsHidden ( ) ) {
weapon . GetEntity ( ) - > LowerWeapon ( ) ;
}
}
/*
= = = = = = = = = = = = = = =
idPlayer : : RaiseWeapon
= = = = = = = = = = = = = = =
*/
void idPlayer : : RaiseWeapon ( void ) {
if ( weapon . GetEntity ( ) & & weapon . GetEntity ( ) - > IsHidden ( ) ) {
weapon . GetEntity ( ) - > RaiseWeapon ( ) ;
}
}
/*
= = = = = = = = = = = = = = =
idPlayer : : WeaponLoweringCallback
= = = = = = = = = = = = = = =
*/
void idPlayer : : WeaponLoweringCallback ( void ) {
SetState ( " LowerWeapon " ) ;
UpdateScript ( ) ;
}
/*
= = = = = = = = = = = = = = =
idPlayer : : WeaponRisingCallback
= = = = = = = = = = = = = = =
*/
void idPlayer : : WeaponRisingCallback ( void ) {
SetState ( " RaiseWeapon " ) ;
UpdateScript ( ) ;
}
/*
= = = = = = = = = = = = = = =
idPlayer : : Weapon_GUI
= = = = = = = = = = = = = = =
*/
void idPlayer : : Weapon_GUI ( void ) {
if ( ! objectiveSystemOpen ) {
if ( idealWeapon ! = currentWeapon ) {
Weapon_Combat ( ) ;
}
StopFiring ( ) ;
weapon . GetEntity ( ) - > LowerWeapon ( ) ;
}
// disable click prediction for the GUIs. handy to check the state sync does the right thing
if ( gameLocal . isClient & & ! net_clientPredictGUI . GetBool ( ) ) {
return ;
}
if ( ( oldButtons ^ usercmd . buttons ) & BUTTON_ATTACK ) {
sysEvent_t ev ;
const char * command = NULL ;
bool updateVisuals = false ;
idUserInterface * ui = ActiveGui ( ) ;
if ( ui ) {
ev = sys - > GenerateMouseButtonEvent ( 1 , ( usercmd . buttons & BUTTON_ATTACK ) ! = 0 ) ;
command = ui - > HandleEvent ( & ev , gameLocal . time , & updateVisuals ) ;
if ( updateVisuals & & focusGUIent & & ui = = focusUI ) {
focusGUIent - > UpdateVisuals ( ) ;
}
}
if ( gameLocal . isClient ) {
// we predict enough, but don't want to execute commands
return ;
}
if ( focusGUIent ) {
HandleGuiCommands ( focusGUIent , command ) ;
} else {
HandleGuiCommands ( this , command ) ;
}
}
}
/*
= = = = = = = = = = = = = = =
idPlayer : : UpdateWeapon
= = = = = = = = = = = = = = =
*/
void idPlayer : : UpdateWeapon ( void ) {
if ( health < = 0 ) {
return ;
}
assert ( ! spectating ) ;
if ( gameLocal . isClient ) {
// clients need to wait till the weapon and it's world model entity
// are present and synchronized ( weapon.worldModel idEntityPtr to idAnimatedEntity )
if ( ! weapon . GetEntity ( ) - > IsWorldModelReady ( ) ) {
return ;
}
}
// always make sure the weapon is correctly setup before accessing it
if ( ! weapon . GetEntity ( ) - > IsLinked ( ) ) {
if ( idealWeapon ! = - 1 ) {
animPrefix = spawnArgs . GetString ( va ( " def_weapon%d " , idealWeapon ) ) ;
weapon . GetEntity ( ) - > GetWeaponDef ( animPrefix , inventory . clip [ idealWeapon ] ) ;
assert ( weapon . GetEntity ( ) - > IsLinked ( ) ) ;
} else {
return ;
}
}
if ( hiddenWeapon & & tipUp & & usercmd . buttons & BUTTON_ATTACK ) {
HideTip ( ) ;
}
2011-12-06 18:20:15 +00:00
2011-11-22 21:28:15 +00:00
if ( g_dragEntity . GetBool ( ) ) {
StopFiring ( ) ;
weapon . GetEntity ( ) - > LowerWeapon ( ) ;
dragEntity . Update ( this ) ;
} else if ( ActiveGui ( ) ) {
// gui handling overrides weapon use
Weapon_GUI ( ) ;
2011-12-06 18:20:15 +00:00
} else if ( focusCharacter & & ( focusCharacter - > health > 0 ) ) {
2011-11-22 21:28:15 +00:00
Weapon_NPC ( ) ;
} else {
Weapon_Combat ( ) ;
}
2011-12-06 18:20:15 +00:00
2011-11-22 21:28:15 +00:00
if ( hiddenWeapon ) {
weapon . GetEntity ( ) - > LowerWeapon ( ) ;
}
// update weapon state, particles, dlights, etc
weapon . GetEntity ( ) - > PresentWeapon ( showWeaponViewModel ) ;
}
/*
= = = = = = = = = = = = = = =
idPlayer : : SpectateFreeFly
= = = = = = = = = = = = = = =
*/
void idPlayer : : SpectateFreeFly ( bool force ) {
idPlayer * player ;
idVec3 newOrig ;
idVec3 spawn_origin ;
idAngles spawn_angles ;
player = gameLocal . GetClientByNum ( spectator ) ;
if ( force | | gameLocal . time > lastSpectateChange ) {
spectator = entityNumber ;
if ( player & & player ! = this & & ! player - > spectating & & ! player - > IsInTeleport ( ) ) {
newOrig = player - > GetPhysics ( ) - > GetOrigin ( ) ;
if ( player - > physicsObj . IsCrouching ( ) ) {
newOrig [ 2 ] + = pm_crouchviewheight . GetFloat ( ) ;
} else {
newOrig [ 2 ] + = pm_normalviewheight . GetFloat ( ) ;
}
newOrig [ 2 ] + = SPECTATE_RAISE ;
idBounds b = idBounds ( vec3_origin ) . Expand ( pm_spectatebbox . GetFloat ( ) * 0.5f ) ;
idVec3 start = player - > GetPhysics ( ) - > GetOrigin ( ) ;
start [ 2 ] + = pm_spectatebbox . GetFloat ( ) * 0.5f ;
trace_t t ;
// assuming spectate bbox is inside stand or crouch box
gameLocal . clip . TraceBounds ( t , start , newOrig , b , MASK_PLAYERSOLID , player ) ;
newOrig . Lerp ( start , newOrig , t . fraction ) ;
SetOrigin ( newOrig ) ;
idAngles angle = player - > viewAngles ;
angle [ 2 ] = 0 ;
SetViewAngles ( angle ) ;
2011-12-06 18:20:15 +00:00
} else {
2011-11-22 21:28:15 +00:00
SelectInitialSpawnPoint ( spawn_origin , spawn_angles ) ;
spawn_origin [ 2 ] + = pm_normalviewheight . GetFloat ( ) ;
spawn_origin [ 2 ] + = SPECTATE_RAISE ;
SetOrigin ( spawn_origin ) ;
SetViewAngles ( spawn_angles ) ;
}
lastSpectateChange = gameLocal . time + 500 ;
}
}
/*
= = = = = = = = = = = = = = =
idPlayer : : SpectateCycle
= = = = = = = = = = = = = = =
*/
void idPlayer : : SpectateCycle ( void ) {
idPlayer * player ;
if ( gameLocal . time > lastSpectateChange ) {
int latchedSpectator = spectator ;
spectator = gameLocal . GetNextClientNum ( spectator ) ;
player = gameLocal . GetClientByNum ( spectator ) ;
assert ( player ) ; // never call here when the current spectator is wrong
// ignore other spectators
while ( latchedSpectator ! = spectator & & player - > spectating ) {
spectator = gameLocal . GetNextClientNum ( spectator ) ;
player = gameLocal . GetClientByNum ( spectator ) ;
}
lastSpectateChange = gameLocal . time + 500 ;
}
}
/*
= = = = = = = = = = = = = = =
idPlayer : : UpdateSpectating
= = = = = = = = = = = = = = =
*/
void idPlayer : : UpdateSpectating ( void ) {
assert ( spectating ) ;
assert ( ! gameLocal . isClient ) ;
assert ( IsHidden ( ) ) ;
idPlayer * player ;
if ( ! gameLocal . isMultiplayer ) {
return ;
}
player = gameLocal . GetClientByNum ( spectator ) ;
if ( ! player | | ( player - > spectating & & player ! = this ) ) {
SpectateFreeFly ( true ) ;
} else if ( usercmd . upmove > 0 ) {
SpectateFreeFly ( false ) ;
} else if ( usercmd . buttons & BUTTON_ATTACK ) {
SpectateCycle ( ) ;
}
}
/*
= = = = = = = = = = = = = = =
idPlayer : : HandleSingleGuiCommand
= = = = = = = = = = = = = = =
*/
bool idPlayer : : HandleSingleGuiCommand ( idEntity * entityGui , idLexer * src ) {
idToken token ;
if ( ! src - > ReadToken ( & token ) ) {
return false ;
}
if ( token = = " ; " ) {
return false ;
}
if ( token . Icmp ( " addhealth " ) = = 0 ) {
if ( entityGui & & health < 100 ) {
int _health = entityGui - > spawnArgs . GetInt ( " gui_parm1 " ) ;
int amt = ( _health > = HEALTH_PER_DOSE ) ? HEALTH_PER_DOSE : _health ;
_health - = amt ;
entityGui - > spawnArgs . SetInt ( " gui_parm1 " , _health ) ;
if ( entityGui - > GetRenderEntity ( ) & & entityGui - > GetRenderEntity ( ) - > gui [ 0 ] ) {
entityGui - > GetRenderEntity ( ) - > gui [ 0 ] - > SetStateInt ( " gui_parm1 " , _health ) ;
}
health + = amt ;
if ( health > 100 ) {
health = 100 ;
}
}
return true ;
}
if ( token . Icmp ( " ready " ) = = 0 ) {
PerformImpulse ( IMPULSE_17 ) ;
return true ;
}
if ( token . Icmp ( " updatepda " ) = = 0 ) {
UpdatePDAInfo ( true ) ;
return true ;
}
if ( token . Icmp ( " updatepda2 " ) = = 0 ) {
UpdatePDAInfo ( false ) ;
return true ;
}
if ( token . Icmp ( " stoppdavideo " ) = = 0 ) {
if ( objectiveSystem & & objectiveSystemOpen & & pdaVideoWave . Length ( ) > 0 ) {
StopSound ( SND_CHANNEL_PDA , false ) ;
}
return true ;
}
if ( token . Icmp ( " close " ) = = 0 ) {
if ( objectiveSystem & & objectiveSystemOpen ) {
TogglePDA ( ) ;
}
}
if ( token . Icmp ( " playpdavideo " ) = = 0 ) {
if ( objectiveSystem & & objectiveSystemOpen & & pdaVideo . Length ( ) > 0 ) {
const idMaterial * mat = declManager - > FindMaterial ( pdaVideo ) ;
if ( mat ) {
int c = mat - > GetNumStages ( ) ;
for ( int i = 0 ; i < c ; i + + ) {
const shaderStage_t * stage = mat - > GetStage ( i ) ;
if ( stage & & stage - > texture . cinematic ) {
stage - > texture . cinematic - > ResetTime ( gameLocal . time ) ;
}
}
if ( pdaVideoWave . Length ( ) ) {
const idSoundShader * shader = declManager - > FindSound ( pdaVideoWave ) ;
StartSoundShader ( shader , SND_CHANNEL_PDA , 0 , false , NULL ) ;
}
}
}
}
if ( token . Icmp ( " playpdaaudio " ) = = 0 ) {
if ( objectiveSystem & & objectiveSystemOpen & & pdaAudio . Length ( ) > 0 ) {
const idSoundShader * shader = declManager - > FindSound ( pdaAudio ) ;
int ms ;
StartSoundShader ( shader , SND_CHANNEL_PDA , 0 , false , & ms ) ;
StartAudioLog ( ) ;
CancelEvents ( & EV_Player_StopAudioLog ) ;
PostEventMS ( & EV_Player_StopAudioLog , ms + 150 ) ;
}
return true ;
}
if ( token . Icmp ( " stoppdaaudio " ) = = 0 ) {
if ( objectiveSystem & & objectiveSystemOpen & & pdaAudio . Length ( ) > 0 ) {
// idSoundShader *shader = declManager->FindSound( pdaAudio );
StopAudioLog ( ) ;
StopSound ( SND_CHANNEL_PDA , false ) ;
}
return true ;
}
src - > UnreadToken ( & token ) ;
return false ;
}
/*
= = = = = = = = = = = = = =
idPlayer : : Collide
= = = = = = = = = = = = = =
*/
bool idPlayer : : Collide ( const trace_t & collision , const idVec3 & velocity ) {
idEntity * other ;
if ( gameLocal . isClient ) {
return false ;
}
other = gameLocal . entities [ collision . c . entityNum ] ;
if ( other ) {
other - > Signal ( SIG_TOUCH ) ;
if ( ! spectating ) {
if ( other - > RespondsTo ( EV_Touch ) ) {
other - > ProcessEvent ( & EV_Touch , this , & collision ) ;
}
} else {
if ( other - > RespondsTo ( EV_SpectatorTouch ) ) {
other - > ProcessEvent ( & EV_SpectatorTouch , this , & collision ) ;
}
}
}
return false ;
}
/*
= = = = = = = = = = = = = = = =
idPlayer : : UpdateLocation
2011-12-06 18:20:15 +00:00
Searches nearby locations
2011-11-22 21:28:15 +00:00
= = = = = = = = = = = = = = = =
*/
void idPlayer : : UpdateLocation ( void ) {
if ( hud ) {
idLocationEntity * locationEntity = gameLocal . LocationForPoint ( GetEyePosition ( ) ) ;
if ( locationEntity ) {
hud - > SetStateString ( " location " , locationEntity - > GetLocation ( ) ) ;
} else {
hud - > SetStateString ( " location " , common - > GetLanguageDict ( ) - > GetString ( " #str_02911 " ) ) ;
}
}
}
/*
= = = = = = = = = = = = = = = =
idPlayer : : ClearFocus
Clears the focus cursor
= = = = = = = = = = = = = = = =
*/
void idPlayer : : ClearFocus ( void ) {
focusCharacter = NULL ;
focusGUIent = NULL ;
focusUI = NULL ;
focusVehicle = NULL ;
talkCursor = 0 ;
}
/*
= = = = = = = = = = = = = = = =
idPlayer : : UpdateFocus
Searches nearby entities for interactive guis , possibly making one of them
the focus and sending it a mouse move event
= = = = = = = = = = = = = = = =
*/
void idPlayer : : UpdateFocus ( void ) {
idClipModel * clipModelList [ MAX_GENTITIES ] ;
idClipModel * clip ;
int listedClipModels ;
idEntity * oldFocus ;
idEntity * ent ;
idUserInterface * oldUI ;
idAI * oldChar ;
int oldTalkCursor ;
int i , j ;
idVec3 start , end ;
bool allowFocus ;
const char * command ;
trace_t trace ;
guiPoint_t pt ;
const idKeyValue * kv ;
sysEvent_t ev ;
idUserInterface * ui ;
if ( gameLocal . inCinematic ) {
return ;
}
// only update the focus character when attack button isn't pressed so players
// can still chainsaw NPC's
if ( gameLocal . isMultiplayer | | ( ! focusCharacter & & ( usercmd . buttons & BUTTON_ATTACK ) ) ) {
allowFocus = false ;
} else {
allowFocus = true ;
}
oldFocus = focusGUIent ;
oldUI = focusUI ;
oldChar = focusCharacter ;
oldTalkCursor = talkCursor ;
if ( focusTime < = gameLocal . time ) {
ClearFocus ( ) ;
}
// don't let spectators interact with GUIs
if ( spectating ) {
return ;
}
start = GetEyePosition ( ) ;
end = start + viewAngles . ToForward ( ) * 80.0f ;
// player identification -> names to the hud
if ( gameLocal . isMultiplayer & & entityNumber = = gameLocal . localClientNum ) {
idVec3 end = start + viewAngles . ToForward ( ) * 768.0f ;
gameLocal . clip . TracePoint ( trace , start , end , MASK_SHOT_BOUNDINGBOX , this ) ;
int iclient = - 1 ;
if ( ( trace . fraction < 1.0f ) & & ( trace . c . entityNum < MAX_CLIENTS ) ) {
iclient = trace . c . entityNum ;
}
if ( MPAim ! = iclient ) {
lastMPAim = MPAim ;
MPAim = iclient ;
lastMPAimTime = gameLocal . realClientTime ;
}
}
idBounds bounds ( start ) ;
bounds . AddPoint ( end ) ;
listedClipModels = gameLocal . clip . ClipModelsTouchingBounds ( bounds , - 1 , clipModelList , MAX_GENTITIES ) ;
// no pretense at sorting here, just assume that there will only be one active
// gui within range along the trace
for ( i = 0 ; i < listedClipModels ; i + + ) {
clip = clipModelList [ i ] ;
ent = clip - > GetEntity ( ) ;
if ( ent - > IsHidden ( ) ) {
continue ;
}
if ( allowFocus ) {
if ( ent - > IsType ( idAFAttachment : : Type ) ) {
idEntity * body = static_cast < idAFAttachment * > ( ent ) - > GetBody ( ) ;
if ( body & & body - > IsType ( idAI : : Type ) & & ( static_cast < idAI * > ( body ) - > GetTalkState ( ) > = TALK_OK ) ) {
gameLocal . clip . TracePoint ( trace , start , end , MASK_SHOT_RENDERMODEL , this ) ;
if ( ( trace . fraction < 1.0f ) & & ( trace . c . entityNum = = ent - > entityNumber ) ) {
ClearFocus ( ) ;
focusCharacter = static_cast < idAI * > ( body ) ;
talkCursor = 1 ;
focusTime = gameLocal . time + FOCUS_TIME ;
break ;
}
}
continue ;
}
if ( ent - > IsType ( idAI : : Type ) ) {
if ( static_cast < idAI * > ( ent ) - > GetTalkState ( ) > = TALK_OK ) {
gameLocal . clip . TracePoint ( trace , start , end , MASK_SHOT_RENDERMODEL , this ) ;
if ( ( trace . fraction < 1.0f ) & & ( trace . c . entityNum = = ent - > entityNumber ) ) {
ClearFocus ( ) ;
focusCharacter = static_cast < idAI * > ( ent ) ;
talkCursor = 1 ;
focusTime = gameLocal . time + FOCUS_TIME ;
break ;
}
}
continue ;
}
if ( ent - > IsType ( idAFEntity_Vehicle : : Type ) ) {
gameLocal . clip . TracePoint ( trace , start , end , MASK_SHOT_RENDERMODEL , this ) ;
if ( ( trace . fraction < 1.0f ) & & ( trace . c . entityNum = = ent - > entityNumber ) ) {
ClearFocus ( ) ;
focusVehicle = static_cast < idAFEntity_Vehicle * > ( ent ) ;
focusTime = gameLocal . time + FOCUS_TIME ;
break ;
}
continue ;
}
}
if ( ! ent - > GetRenderEntity ( ) | | ! ent - > GetRenderEntity ( ) - > gui [ 0 ] | | ! ent - > GetRenderEntity ( ) - > gui [ 0 ] - > IsInteractive ( ) ) {
continue ;
}
if ( ent - > spawnArgs . GetBool ( " inv_item " ) ) {
// don't allow guis on pickup items focus
continue ;
}
pt = gameRenderWorld - > GuiTrace ( ent - > GetModelDefHandle ( ) , start , end ) ;
if ( pt . x ! = - 1 ) {
// we have a hit
renderEntity_t * focusGUIrenderEntity = ent - > GetRenderEntity ( ) ;
if ( ! focusGUIrenderEntity ) {
continue ;
}
if ( pt . guiId = = 1 ) {
ui = focusGUIrenderEntity - > gui [ 0 ] ;
} else if ( pt . guiId = = 2 ) {
ui = focusGUIrenderEntity - > gui [ 1 ] ;
} else {
ui = focusGUIrenderEntity - > gui [ 2 ] ;
}
2011-12-06 18:20:15 +00:00
2011-11-22 21:28:15 +00:00
if ( ui = = NULL ) {
continue ;
}
ClearFocus ( ) ;
focusGUIent = ent ;
focusUI = ui ;
if ( oldFocus ! = ent ) {
// new activation
// going to see if we have anything in inventory a gui might be interested in
// need to enumerate inventory items
focusUI - > SetStateInt ( " inv_count " , inventory . items . Num ( ) ) ;
for ( j = 0 ; j < inventory . items . Num ( ) ; j + + ) {
idDict * item = inventory . items [ j ] ;
const char * iname = item - > GetString ( " inv_name " ) ;
const char * iicon = item - > GetString ( " inv_icon " ) ;
const char * itext = item - > GetString ( " inv_text " ) ;
focusUI - > SetStateString ( va ( " inv_name_%i " , j ) , iname ) ;
focusUI - > SetStateString ( va ( " inv_icon_%i " , j ) , iicon ) ;
focusUI - > SetStateString ( va ( " inv_text_%i " , j ) , itext ) ;
kv = item - > MatchPrefix ( " inv_id " , NULL ) ;
if ( kv ) {
focusUI - > SetStateString ( va ( " inv_id_%i " , j ) , kv - > GetValue ( ) ) ;
}
focusUI - > SetStateInt ( iname , 1 ) ;
}
for ( j = 0 ; j < inventory . pdaSecurity . Num ( ) ; j + + ) {
const char * p = inventory . pdaSecurity [ j ] ;
if ( p & & * p ) {
focusUI - > SetStateInt ( p , 1 ) ;
}
}
int staminapercentage = ( int ) ( 100.0f * stamina / pm_stamina . GetFloat ( ) ) ;
focusUI - > SetStateString ( " player_health " , va ( " %i " , health ) ) ;
focusUI - > SetStateString ( " player_stamina " , va ( " %i%% " , staminapercentage ) ) ;
focusUI - > SetStateString ( " player_armor " , va ( " %i%% " , inventory . armor ) ) ;
kv = focusGUIent - > spawnArgs . MatchPrefix ( " gui_parm " , NULL ) ;
while ( kv ) {
focusUI - > SetStateString ( kv - > GetKey ( ) , kv - > GetValue ( ) ) ;
kv = focusGUIent - > spawnArgs . MatchPrefix ( " gui_parm " , kv ) ;
}
}
// clamp the mouse to the corner
ev = sys - > GenerateMouseMoveEvent ( - 2000 , - 2000 ) ;
command = focusUI - > HandleEvent ( & ev , gameLocal . time ) ;
2011-12-06 18:20:15 +00:00
HandleGuiCommands ( focusGUIent , command ) ;
2011-11-22 21:28:15 +00:00
// move to an absolute position
ev = sys - > GenerateMouseMoveEvent ( pt . x * SCREEN_WIDTH , pt . y * SCREEN_HEIGHT ) ;
command = focusUI - > HandleEvent ( & ev , gameLocal . time ) ;
HandleGuiCommands ( focusGUIent , command ) ;
focusTime = gameLocal . time + FOCUS_GUI_TIME ;
break ;
}
}
if ( focusGUIent & & focusUI ) {
if ( ! oldFocus | | oldFocus ! = focusGUIent ) {
command = focusUI - > Activate ( true , gameLocal . time ) ;
HandleGuiCommands ( focusGUIent , command ) ;
StartSound ( " snd_guienter " , SND_CHANNEL_ANY , 0 , false , NULL ) ;
// HideTip();
// HideObjective();
}
} else if ( oldFocus & & oldUI ) {
command = oldUI - > Activate ( false , gameLocal . time ) ;
HandleGuiCommands ( oldFocus , command ) ;
StartSound ( " snd_guiexit " , SND_CHANNEL_ANY , 0 , false , NULL ) ;
}
if ( cursor & & ( oldTalkCursor ! = talkCursor ) ) {
cursor - > SetStateInt ( " talkcursor " , talkCursor ) ;
}
if ( oldChar ! = focusCharacter & & hud ) {
if ( focusCharacter ) {
hud - > SetStateString ( " npc " , focusCharacter - > spawnArgs . GetString ( " npc_name " , " Joe " ) ) ;
hud - > HandleNamedEvent ( " showNPC " ) ;
// HideTip();
// HideObjective();
} else {
hud - > SetStateString ( " npc " , " " ) ;
hud - > HandleNamedEvent ( " hideNPC " ) ;
}
}
}
/*
= = = = = = = = = = = = = = = = =
idPlayer : : CrashLand
Check for hard landings that generate sound events
= = = = = = = = = = = = = = = = =
*/
void idPlayer : : CrashLand ( const idVec3 & oldOrigin , const idVec3 & oldVelocity ) {
idVec3 origin , velocity ;
idVec3 gravityVector , gravityNormal ;
float delta ;
float hardDelta , fatalDelta ;
float dist ;
float vel , acc ;
float t ;
float a , b , c , den ;
waterLevel_t waterLevel ;
bool noDamage ;
AI_SOFTLANDING = false ;
AI_HARDLANDING = false ;
// if the player is not on the ground
if ( ! physicsObj . HasGroundContacts ( ) ) {
return ;
}
gravityNormal = physicsObj . GetGravityNormal ( ) ;
// if the player wasn't going down
if ( ( oldVelocity * - gravityNormal ) > = 0.0f ) {
return ;
}
waterLevel = physicsObj . GetWaterLevel ( ) ;
// never take falling damage if completely underwater
if ( waterLevel = = WATERLEVEL_HEAD ) {
return ;
}
// no falling damage if touching a nodamage surface
noDamage = false ;
for ( int i = 0 ; i < physicsObj . GetNumContacts ( ) ; i + + ) {
const contactInfo_t & contact = physicsObj . GetContact ( i ) ;
if ( contact . material - > GetSurfaceFlags ( ) & SURF_NODAMAGE ) {
noDamage = true ;
StartSound ( " snd_land_hard " , SND_CHANNEL_ANY , 0 , false , NULL ) ;
break ;
}
}
origin = GetPhysics ( ) - > GetOrigin ( ) ;
gravityVector = physicsObj . GetGravity ( ) ;
// calculate the exact velocity on landing
dist = ( origin - oldOrigin ) * - gravityNormal ;
vel = oldVelocity * - gravityNormal ;
acc = - gravityVector . Length ( ) ;
a = acc / 2.0f ;
b = vel ;
c = - dist ;
den = b * b - 4.0f * a * c ;
if ( den < 0 ) {
return ;
}
t = ( - b - idMath : : Sqrt ( den ) ) / ( 2.0f * a ) ;
delta = vel + t * acc ;
delta = delta * delta * 0.0001 ;
// reduce falling damage if there is standing water
if ( waterLevel = = WATERLEVEL_WAIST ) {
delta * = 0.25f ;
}
if ( waterLevel = = WATERLEVEL_FEET ) {
delta * = 0.5f ;
}
if ( delta < 1.0f ) {
return ;
}
// allow falling a bit further for multiplayer
if ( gameLocal . isMultiplayer ) {
fatalDelta = 75.0f ;
hardDelta = 50.0f ;
} else {
fatalDelta = 65.0f ;
hardDelta = 45.0f ;
}
if ( delta > fatalDelta ) {
AI_HARDLANDING = true ;
landChange = - 32 ;
landTime = gameLocal . time ;
if ( ! noDamage ) {
pain_debounce_time = gameLocal . time + pain_delay + 1 ; // ignore pain since we'll play our landing anim
Damage ( NULL , NULL , idVec3 ( 0 , 0 , - 1 ) , " damage_fatalfall " , 1.0f , 0 ) ;
}
} else if ( delta > hardDelta ) {
AI_HARDLANDING = true ;
landChange = - 24 ;
landTime = gameLocal . time ;
if ( ! noDamage ) {
pain_debounce_time = gameLocal . time + pain_delay + 1 ; // ignore pain since we'll play our landing anim
Damage ( NULL , NULL , idVec3 ( 0 , 0 , - 1 ) , " damage_hardfall " , 1.0f , 0 ) ;
}
} else if ( delta > 30 ) {
AI_HARDLANDING = true ;
landChange = - 16 ;
landTime = gameLocal . time ;
if ( ! noDamage ) {
pain_debounce_time = gameLocal . time + pain_delay + 1 ; // ignore pain since we'll play our landing anim
Damage ( NULL , NULL , idVec3 ( 0 , 0 , - 1 ) , " damage_softfall " , 1.0f , 0 ) ;
}
} else if ( delta > 7 ) {
AI_SOFTLANDING = true ;
landChange = - 8 ;
landTime = gameLocal . time ;
} else if ( delta > 3 ) {
// just walk on
}
}
/*
= = = = = = = = = = = = = = =
idPlayer : : BobCycle
= = = = = = = = = = = = = = =
*/
void idPlayer : : BobCycle ( const idVec3 & pushVelocity ) {
float bobmove ;
int old , deltaTime ;
idVec3 vel , gravityDir , velocity ;
idMat3 viewaxis ;
float bob ;
float delta ;
float speed ;
float f ;
//
// calculate speed and cycle to be used for
// all cyclic walking effects
//
velocity = physicsObj . GetLinearVelocity ( ) - pushVelocity ;
gravityDir = physicsObj . GetGravityNormal ( ) ;
vel = velocity - ( velocity * gravityDir ) * gravityDir ;
xyspeed = vel . LengthFast ( ) ;
// do not evaluate the bob for other clients
// when doing a spectate follow, don't do any weapon bobbing
if ( gameLocal . isClient & & entityNumber ! = gameLocal . localClientNum ) {
viewBobAngles . Zero ( ) ;
viewBob . Zero ( ) ;
return ;
}
if ( ! physicsObj . HasGroundContacts ( ) | | influenceActive = = INFLUENCE_LEVEL2 | | ( gameLocal . isMultiplayer & & spectating ) ) {
// airborne
bobCycle = 0 ;
bobFoot = 0 ;
bobfracsin = 0 ;
} else if ( ( ! usercmd . forwardmove & & ! usercmd . rightmove ) | | ( xyspeed < = MIN_BOB_SPEED ) ) {
// start at beginning of cycle again
bobCycle = 0 ;
bobFoot = 0 ;
bobfracsin = 0 ;
} else {
if ( physicsObj . IsCrouching ( ) ) {
bobmove = pm_crouchbob . GetFloat ( ) ;
// ducked characters never play footsteps
} else {
// vary the bobbing based on the speed of the player
bobmove = pm_walkbob . GetFloat ( ) * ( 1.0f - bobFrac ) + pm_runbob . GetFloat ( ) * bobFrac ;
}
// check for footstep / splash sounds
old = bobCycle ;
bobCycle = ( int ) ( old + bobmove * gameLocal . msec ) & 255 ;
bobFoot = ( bobCycle & 128 ) > > 7 ;
bobfracsin = idMath : : Fabs ( sin ( ( bobCycle & 127 ) / 127.0 * idMath : : PI ) ) ;
}
// calculate angles for view bobbing
viewBobAngles . Zero ( ) ;
viewaxis = viewAngles . ToMat3 ( ) * physicsObj . GetGravityAxis ( ) ;
// add angles based on velocity
delta = velocity * viewaxis [ 0 ] ;
viewBobAngles . pitch + = delta * pm_runpitch . GetFloat ( ) ;
2011-12-06 18:20:15 +00:00
2011-11-22 21:28:15 +00:00
delta = velocity * viewaxis [ 1 ] ;
viewBobAngles . roll - = delta * pm_runroll . GetFloat ( ) ;
// add angles based on bob
// make sure the bob is visible even at low speeds
speed = xyspeed > 200 ? xyspeed : 200 ;
delta = bobfracsin * pm_bobpitch . GetFloat ( ) * speed ;
if ( physicsObj . IsCrouching ( ) ) {
delta * = 3 ; // crouching
}
viewBobAngles . pitch + = delta ;
delta = bobfracsin * pm_bobroll . GetFloat ( ) * speed ;
if ( physicsObj . IsCrouching ( ) ) {
delta * = 3 ; // crouching accentuates roll
}
if ( bobFoot & 1 ) {
delta = - delta ;
}
viewBobAngles . roll + = delta ;
// calculate position for view bobbing
viewBob . Zero ( ) ;
if ( physicsObj . HasSteppedUp ( ) ) {
// check for stepping up before a previous step is completed
deltaTime = gameLocal . time - stepUpTime ;
if ( deltaTime < STEPUP_TIME ) {
stepUpDelta = stepUpDelta * ( STEPUP_TIME - deltaTime ) / STEPUP_TIME + physicsObj . GetStepUp ( ) ;
} else {
stepUpDelta = physicsObj . GetStepUp ( ) ;
}
if ( stepUpDelta > 2.0f * pm_stepsize . GetFloat ( ) ) {
stepUpDelta = 2.0f * pm_stepsize . GetFloat ( ) ;
}
stepUpTime = gameLocal . time ;
}
idVec3 gravity = physicsObj . GetGravityNormal ( ) ;
// if the player stepped up recently
deltaTime = gameLocal . time - stepUpTime ;
if ( deltaTime < STEPUP_TIME ) {
viewBob + = gravity * ( stepUpDelta * ( STEPUP_TIME - deltaTime ) / STEPUP_TIME ) ;
}
// add bob height after any movement smoothing
bob = bobfracsin * xyspeed * pm_bobup . GetFloat ( ) ;
if ( bob > 6 ) {
bob = 6 ;
}
viewBob [ 2 ] + = bob ;
// add fall height
delta = gameLocal . time - landTime ;
if ( delta < LAND_DEFLECT_TIME ) {
f = delta / LAND_DEFLECT_TIME ;
viewBob - = gravity * ( landChange * f ) ;
} else if ( delta < LAND_DEFLECT_TIME + LAND_RETURN_TIME ) {
delta - = LAND_DEFLECT_TIME ;
f = 1.0 - ( delta / LAND_RETURN_TIME ) ;
viewBob - = gravity * ( landChange * f ) ;
}
}
/*
= = = = = = = = = = = = = = = =
idPlayer : : UpdateDeltaViewAngles
= = = = = = = = = = = = = = = =
*/
void idPlayer : : UpdateDeltaViewAngles ( const idAngles & angles ) {
// set the delta angle
idAngles delta ;
for ( int i = 0 ; i < 3 ; i + + ) {
delta [ i ] = angles [ i ] - SHORT2ANGLE ( usercmd . angles [ i ] ) ;
}
SetDeltaViewAngles ( delta ) ;
}
/*
= = = = = = = = = = = = = = = =
idPlayer : : SetViewAngles
= = = = = = = = = = = = = = = =
*/
void idPlayer : : SetViewAngles ( const idAngles & angles ) {
UpdateDeltaViewAngles ( angles ) ;
viewAngles = angles ;
}
/*
= = = = = = = = = = = = = = = =
idPlayer : : UpdateViewAngles
= = = = = = = = = = = = = = = =
*/
void idPlayer : : UpdateViewAngles ( void ) {
int i ;
idAngles delta ;
if ( ! noclip & & ( gameLocal . inCinematic | | privateCameraView | | gameLocal . GetCamera ( ) | | influenceActive = = INFLUENCE_LEVEL2 | | objectiveSystemOpen ) ) {
// no view changes at all, but we still want to update the deltas or else when
// we get out of this mode, our view will snap to a kind of random angle
UpdateDeltaViewAngles ( viewAngles ) ;
return ;
}
// if dead
if ( health < = 0 ) {
if ( pm_thirdPersonDeath . GetBool ( ) ) {
viewAngles . roll = 0.0f ;
viewAngles . pitch = 30.0f ;
} else {
viewAngles . roll = 40.0f ;
viewAngles . pitch = - 15.0f ;
}
return ;
}
// circularly clamp the angles with deltas
for ( i = 0 ; i < 3 ; i + + ) {
cmdAngles [ i ] = SHORT2ANGLE ( usercmd . angles [ i ] ) ;
if ( influenceActive = = INFLUENCE_LEVEL3 ) {
viewAngles [ i ] + = idMath : : ClampFloat ( - 1.0f , 1.0f , idMath : : AngleDelta ( idMath : : AngleNormalize180 ( SHORT2ANGLE ( usercmd . angles [ i ] ) + deltaViewAngles [ i ] ) , viewAngles [ i ] ) ) ;
} else {
viewAngles [ i ] = idMath : : AngleNormalize180 ( SHORT2ANGLE ( usercmd . angles [ i ] ) + deltaViewAngles [ i ] ) ;
}
}
if ( ! centerView . IsDone ( gameLocal . time ) ) {
viewAngles . pitch = centerView . GetCurrentValue ( gameLocal . time ) ;
}
// clamp the pitch
if ( noclip ) {
if ( viewAngles . pitch > 89.0f ) {
// don't let the player look down more than 89 degrees while noclipping
viewAngles . pitch = 89.0f ;
} else if ( viewAngles . pitch < - 89.0f ) {
// don't let the player look up more than 89 degrees while noclipping
viewAngles . pitch = - 89.0f ;
}
} else {
if ( viewAngles . pitch > pm_maxviewpitch . GetFloat ( ) ) {
// don't let the player look down enough to see the shadow of his (non-existant) feet
viewAngles . pitch = pm_maxviewpitch . GetFloat ( ) ;
} else if ( viewAngles . pitch < pm_minviewpitch . GetFloat ( ) ) {
// don't let the player look up more than 89 degrees
viewAngles . pitch = pm_minviewpitch . GetFloat ( ) ;
}
}
UpdateDeltaViewAngles ( viewAngles ) ;
// orient the model towards the direction we're looking
SetAngles ( idAngles ( 0 , viewAngles . yaw , 0 ) ) ;
// save in the log for analyzing weapon angle offsets
loggedViewAngles [ gameLocal . framenum & ( NUM_LOGGED_VIEW_ANGLES - 1 ) ] = viewAngles ;
}
/*
= = = = = = = = = = = = = =
idPlayer : : AdjustHeartRate
Player heartrate works as follows
DEF_HEARTRATE is resting heartrate
Taking damage when health is above 75 adjusts heart rate by 1 beat per second
Taking damage when health is below 75 adjusts heart rate by 5 beats per second
Maximum heartrate from damage is MAX_HEARTRATE
Firing a weapon adds 1 beat per second up to a maximum of COMBAT_HEARTRATE
Being at less than 25 % stamina adds 5 beats per second up to ZEROSTAMINA_HEARTRATE
All heartrates are target rates . . the heart rate will start falling as soon as there have been no adjustments for 5 seconds
Once it starts falling it always tries to get to DEF_HEARTRATE
2011-12-06 18:20:15 +00:00
The exception to the above rule is upon death at which point the rate is set to DYING_HEARTRATE and starts falling
2011-11-22 21:28:15 +00:00
immediately to zero
2011-12-06 18:20:15 +00:00
Heart rate volumes go from zero ( - 40 db for DEF_HEARTRATE to 5 db for MAX_HEARTRATE ) the volume is
2011-11-22 21:28:15 +00:00
scaled linearly based on the actual rate
Exception to the above rule is once the player is dead , the dying heart rate starts at either the current volume if
it is audible or - 10 db and scales to 8 db on the last few beats
= = = = = = = = = = = = = =
*/
void idPlayer : : AdjustHeartRate ( int target , float timeInSecs , float delay , bool force ) {
if ( heartInfo . GetEndValue ( ) = = target ) {
return ;
}
if ( AI_DEAD & & ! force ) {
return ;
}
2011-12-06 18:20:15 +00:00
lastHeartAdjust = gameLocal . time ;
2011-11-22 21:28:15 +00:00
heartInfo . Init ( gameLocal . time + delay * 1000 , timeInSecs * 1000 , heartRate , target ) ;
}
/*
= = = = = = = = = = = = = =
idPlayer : : GetBaseHeartRate
= = = = = = = = = = = = = =
*/
int idPlayer : : GetBaseHeartRate ( void ) {
int base = idMath : : FtoiFast ( ( BASE_HEARTRATE + LOWHEALTH_HEARTRATE_ADJ ) - ( ( float ) health / 100.0f ) * LOWHEALTH_HEARTRATE_ADJ ) ;
int rate = idMath : : FtoiFast ( base + ( ZEROSTAMINA_HEARTRATE - base ) * ( 1.0f - stamina / pm_stamina . GetFloat ( ) ) ) ;
int diff = ( lastDmgTime ) ? gameLocal . time - lastDmgTime : 99999 ;
rate + = ( diff < 5000 ) ? ( diff < 2500 ) ? ( diff < 1000 ) ? 15 : 10 : 5 : 0 ;
return rate ;
}
/*
= = = = = = = = = = = = = =
idPlayer : : SetCurrentHeartRate
= = = = = = = = = = = = = =
*/
void idPlayer : : SetCurrentHeartRate ( void ) {
int base = idMath : : FtoiFast ( ( BASE_HEARTRATE + LOWHEALTH_HEARTRATE_ADJ ) - ( ( float ) health / 100.0f ) * LOWHEALTH_HEARTRATE_ADJ ) ;
if ( PowerUpActive ( ADRENALINE ) ) {
heartRate = 135 ;
} else {
heartRate = idMath : : FtoiFast ( heartInfo . GetCurrentValue ( gameLocal . time ) ) ;
int currentRate = GetBaseHeartRate ( ) ;
if ( health > = 0 & & gameLocal . time > lastHeartAdjust + 2500 ) {
AdjustHeartRate ( currentRate , 2.5f , 0.0f , false ) ;
}
}
int bps = idMath : : FtoiFast ( 60.0f / heartRate * 1000.0f ) ;
if ( gameLocal . time - lastHeartBeat > bps ) {
int dmgVol = DMG_VOLUME ;
int deathVol = DEATH_VOLUME ;
int zeroVol = ZERO_VOLUME ;
float pct = 0.0 ;
if ( heartRate > BASE_HEARTRATE & & health > 0 ) {
pct = ( float ) ( heartRate - base ) / ( MAX_HEARTRATE - base ) ;
pct * = ( ( float ) dmgVol - ( float ) zeroVol ) ;
} else if ( health < = 0 ) {
pct = ( float ) ( heartRate - DYING_HEARTRATE ) / ( BASE_HEARTRATE - DYING_HEARTRATE ) ;
if ( pct > 1.0f ) {
pct = 1.0f ;
} else if ( pct < 0.0f ) {
pct = 0.0f ;
}
pct * = ( ( float ) deathVol - ( float ) zeroVol ) ;
2011-12-06 18:20:15 +00:00
}
2011-11-22 21:28:15 +00:00
pct + = ( float ) zeroVol ;
if ( pct ! = zeroVol ) {
StartSound ( " snd_heartbeat " , SND_CHANNEL_HEART , SSF_PRIVATE_SOUND , false , NULL ) ;
// modify just this channel to a custom volume
soundShaderParms_t parms ;
memset ( & parms , 0 , sizeof ( parms ) ) ;
parms . volume = pct ;
refSound . referenceSound - > ModifySound ( SND_CHANNEL_HEART , & parms ) ;
}
lastHeartBeat = gameLocal . time ;
}
}
/*
= = = = = = = = = = = = = =
idPlayer : : UpdateAir
= = = = = = = = = = = = = =
*/
2011-12-06 18:20:15 +00:00
void idPlayer : : UpdateAir ( void ) {
2011-11-22 21:28:15 +00:00
if ( health < = 0 ) {
return ;
}
// see if the player is connected to the info_vacuum
bool newAirless = false ;
if ( gameLocal . vacuumAreaNum ! = - 1 ) {
int num = GetNumPVSAreas ( ) ;
if ( num > 0 ) {
int areaNum ;
// if the player box spans multiple areas, get the area from the origin point instead,
// otherwise a rotating player box may poke into an outside area
if ( num = = 1 ) {
const int * pvsAreas = GetPVSAreas ( ) ;
areaNum = pvsAreas [ 0 ] ;
} else {
areaNum = gameRenderWorld - > PointInArea ( this - > GetPhysics ( ) - > GetOrigin ( ) ) ;
}
newAirless = gameRenderWorld - > AreasAreConnected ( gameLocal . vacuumAreaNum , areaNum , PS_BLOCK_AIR ) ;
}
}
if ( newAirless ) {
if ( ! airless ) {
StartSound ( " snd_decompress " , SND_CHANNEL_ANY , SSF_GLOBAL , false , NULL ) ;
StartSound ( " snd_noAir " , SND_CHANNEL_BODY2 , 0 , false , NULL ) ;
if ( hud ) {
hud - > HandleNamedEvent ( " noAir " ) ;
}
}
airTics - - ;
if ( airTics < 0 ) {
airTics = 0 ;
// check for damage
const idDict * damageDef = gameLocal . FindEntityDefDict ( " damage_noair " , false ) ;
int dmgTiming = 1000 * ( ( damageDef ) ? damageDef - > GetFloat ( " delay " , " 3.0 " ) : 3.0f ) ;
if ( gameLocal . time > lastAirDamage + dmgTiming ) {
Damage ( NULL , NULL , vec3_origin , " damage_noair " , 1.0f , 0 ) ;
lastAirDamage = gameLocal . time ;
}
}
2011-12-06 18:20:15 +00:00
2011-11-22 21:28:15 +00:00
} else {
if ( airless ) {
StartSound ( " snd_recompress " , SND_CHANNEL_ANY , SSF_GLOBAL , false , NULL ) ;
StopSound ( SND_CHANNEL_BODY2 , false ) ;
if ( hud ) {
hud - > HandleNamedEvent ( " Air " ) ;
}
}
airTics + = 2 ; // regain twice as fast as lose
if ( airTics > pm_airTics . GetInteger ( ) ) {
airTics = pm_airTics . GetInteger ( ) ;
}
}
airless = newAirless ;
if ( hud ) {
hud - > SetStateInt ( " player_air " , 100 * airTics / pm_airTics . GetInteger ( ) ) ;
}
}
/*
= = = = = = = = = = = = = =
idPlayer : : AddGuiPDAData
= = = = = = = = = = = = = =
*/
int idPlayer : : AddGuiPDAData ( const declType_t dataType , const char * listName , const idDeclPDA * src , idUserInterface * gui ) {
int c , i ;
idStr work ;
if ( dataType = = DECL_EMAIL ) {
c = src - > GetNumEmails ( ) ;
for ( i = 0 ; i < c ; i + + ) {
const idDeclEmail * email = src - > GetEmailByIndex ( i ) ;
if ( email = = NULL ) {
work = va ( " - \t Email %d not found \t - " , i ) ;
} else {
work = email - > GetFrom ( ) ;
work + = " \t " ;
work + = email - > GetSubject ( ) ;
work + = " \t " ;
work + = email - > GetDate ( ) ;
}
gui - > SetStateString ( va ( " %s_item_%i " , listName , i ) , work ) ;
}
return c ;
} else if ( dataType = = DECL_AUDIO ) {
c = src - > GetNumAudios ( ) ;
for ( i = 0 ; i < c ; i + + ) {
const idDeclAudio * audio = src - > GetAudioByIndex ( i ) ;
if ( audio = = NULL ) {
work = va ( " Audio Log %d not found " , i ) ;
} else {
work = audio - > GetAudioName ( ) ;
}
gui - > SetStateString ( va ( " %s_item_%i " , listName , i ) , work ) ;
}
return c ;
} else if ( dataType = = DECL_VIDEO ) {
c = inventory . videos . Num ( ) ;
for ( i = 0 ; i < c ; i + + ) {
const idDeclVideo * video = GetVideo ( i ) ;
if ( video = = NULL ) {
work = va ( " Video CD %s not found " , inventory . videos [ i ] . c_str ( ) ) ;
} else {
work = video - > GetVideoName ( ) ;
}
gui - > SetStateString ( va ( " %s_item_%i " , listName , i ) , work ) ;
}
return c ;
}
return 0 ;
}
/*
= = = = = = = = = = = = = =
idPlayer : : GetPDA
= = = = = = = = = = = = = =
*/
const idDeclPDA * idPlayer : : GetPDA ( void ) const {
if ( inventory . pdas . Num ( ) ) {
return static_cast < const idDeclPDA * > ( declManager - > FindType ( DECL_PDA , inventory . pdas [ 0 ] ) ) ;
} else {
return NULL ;
}
}
/*
= = = = = = = = = = = = = =
idPlayer : : GetVideo
= = = = = = = = = = = = = =
*/
const idDeclVideo * idPlayer : : GetVideo ( int index ) {
if ( index > = 0 & & index < inventory . videos . Num ( ) ) {
return static_cast < const idDeclVideo * > ( declManager - > FindType ( DECL_VIDEO , inventory . videos [ index ] , false ) ) ;
}
return NULL ;
}
/*
= = = = = = = = = = = = = =
idPlayer : : UpdatePDAInfo
= = = = = = = = = = = = = =
*/
void idPlayer : : UpdatePDAInfo ( bool updatePDASel ) {
int j , sel ;
if ( objectiveSystem = = NULL ) {
return ;
}
assert ( hud ) ;
int currentPDA = objectiveSystem - > State ( ) . GetInt ( " listPDA_sel_0 " , " 0 " ) ;
if ( currentPDA = = - 1 ) {
currentPDA = 0 ;
}
if ( updatePDASel ) {
objectiveSystem - > SetStateInt ( " listPDAVideo_sel_0 " , 0 ) ;
objectiveSystem - > SetStateInt ( " listPDAEmail_sel_0 " , 0 ) ;
objectiveSystem - > SetStateInt ( " listPDAAudio_sel_0 " , 0 ) ;
}
if ( currentPDA > 0 ) {
currentPDA = inventory . pdas . Num ( ) - currentPDA ;
}
// Mark in the bit array that this pda has been read
if ( currentPDA < 128 ) {
inventory . pdasViewed [ currentPDA > > 5 ] | = 1 < < ( currentPDA & 31 ) ;
}
pdaAudio = " " ;
pdaVideo = " " ;
pdaVideoWave = " " ;
idStr name , data , preview , info , wave ;
for ( j = 0 ; j < MAX_PDAS ; j + + ) {
objectiveSystem - > SetStateString ( va ( " listPDA_item_%i " , j ) , " " ) ;
}
for ( j = 0 ; j < MAX_PDA_ITEMS ; j + + ) {
objectiveSystem - > SetStateString ( va ( " listPDAVideo_item_%i " , j ) , " " ) ;
objectiveSystem - > SetStateString ( va ( " listPDAAudio_item_%i " , j ) , " " ) ;
objectiveSystem - > SetStateString ( va ( " listPDAEmail_item_%i " , j ) , " " ) ;
objectiveSystem - > SetStateString ( va ( " listPDASecurity_item_%i " , j ) , " " ) ;
}
for ( j = 0 ; j < inventory . pdas . Num ( ) ; j + + ) {
const idDeclPDA * pda = static_cast < const idDeclPDA * > ( declManager - > FindType ( DECL_PDA , inventory . pdas [ j ] , false ) ) ;
if ( pda = = NULL ) {
continue ;
}
int index = inventory . pdas . Num ( ) - j ;
if ( j = = 0 ) {
// Special case for the first PDA
index = 0 ;
}
if ( j ! = currentPDA & & j < 128 & & inventory . pdasViewed [ j > > 5 ] & ( 1 < < ( j & 31 ) ) ) {
// This pda has been read already, mark in gray
objectiveSystem - > SetStateString ( va ( " listPDA_item_%i " , index ) , va ( S_COLOR_GRAY " %s " , pda - > GetPdaName ( ) ) ) ;
} else {
// This pda has not been read yet
objectiveSystem - > SetStateString ( va ( " listPDA_item_%i " , index ) , pda - > GetPdaName ( ) ) ;
}
const char * security = pda - > GetSecurity ( ) ;
if ( j = = currentPDA | | ( currentPDA = = 0 & & security & & * security ) ) {
2011-11-30 22:14:44 +00:00
if ( * security = = 0 ) {
2011-11-22 21:28:15 +00:00
security = common - > GetLanguageDict ( ) - > GetString ( " #str_00066 " ) ;
}
objectiveSystem - > SetStateString ( " PDASecurityClearance " , security ) ;
}
if ( j = = currentPDA ) {
objectiveSystem - > SetStateString ( " pda_icon " , pda - > GetIcon ( ) ) ;
objectiveSystem - > SetStateString ( " pda_id " , pda - > GetID ( ) ) ;
objectiveSystem - > SetStateString ( " pda_title " , pda - > GetTitle ( ) ) ;
if ( j = = 0 ) {
// Selected, personal pda
// Add videos
if ( updatePDASel | | ! inventory . pdaOpened ) {
objectiveSystem - > HandleNamedEvent ( " playerPDAActive " ) ;
objectiveSystem - > SetStateString ( " pda_personal " , " 1 " ) ;
inventory . pdaOpened = true ;
}
objectiveSystem - > SetStateString ( " pda_location " , hud - > State ( ) . GetString ( " location " ) ) ;
objectiveSystem - > SetStateString ( " pda_name " , cvarSystem - > GetCVarString ( " ui_name " ) ) ;
AddGuiPDAData ( DECL_VIDEO , " listPDAVideo " , pda , objectiveSystem ) ;
sel = objectiveSystem - > State ( ) . GetInt ( " listPDAVideo_sel_0 " , " 0 " ) ;
const idDeclVideo * vid = NULL ;
if ( sel > = 0 & & sel < inventory . videos . Num ( ) ) {
vid = static_cast < const idDeclVideo * > ( declManager - > FindType ( DECL_VIDEO , inventory . videos [ sel ] , false ) ) ;
}
if ( vid ) {
pdaVideo = vid - > GetRoq ( ) ;
pdaVideoWave = vid - > GetWave ( ) ;
objectiveSystem - > SetStateString ( " PDAVideoTitle " , vid - > GetVideoName ( ) ) ;
objectiveSystem - > SetStateString ( " PDAVideoVid " , vid - > GetRoq ( ) ) ;
objectiveSystem - > SetStateString ( " PDAVideoIcon " , vid - > GetPreview ( ) ) ;
objectiveSystem - > SetStateString ( " PDAVideoInfo " , vid - > GetInfo ( ) ) ;
} else {
//FIXME: need to precache these in the player def
objectiveSystem - > SetStateString ( " PDAVideoVid " , " sound/vo/video/welcome.tga " ) ;
objectiveSystem - > SetStateString ( " PDAVideoIcon " , " sound/vo/video/welcome.tga " ) ;
objectiveSystem - > SetStateString ( " PDAVideoTitle " , " " ) ;
objectiveSystem - > SetStateString ( " PDAVideoInfo " , " " ) ;
}
} else {
// Selected, non-personal pda
// Add audio logs
if ( updatePDASel ) {
objectiveSystem - > HandleNamedEvent ( " playerPDANotActive " ) ;
objectiveSystem - > SetStateString ( " pda_personal " , " 0 " ) ;
inventory . pdaOpened = true ;
}
objectiveSystem - > SetStateString ( " pda_location " , pda - > GetPost ( ) ) ;
objectiveSystem - > SetStateString ( " pda_name " , pda - > GetFullName ( ) ) ;
int audioCount = AddGuiPDAData ( DECL_AUDIO , " listPDAAudio " , pda , objectiveSystem ) ;
objectiveSystem - > SetStateInt ( " audioLogCount " , audioCount ) ;
sel = objectiveSystem - > State ( ) . GetInt ( " listPDAAudio_sel_0 " , " 0 " ) ;
const idDeclAudio * aud = NULL ;
if ( sel > = 0 ) {
aud = pda - > GetAudioByIndex ( sel ) ;
}
if ( aud ) {
pdaAudio = aud - > GetWave ( ) ;
objectiveSystem - > SetStateString ( " PDAAudioTitle " , aud - > GetAudioName ( ) ) ;
objectiveSystem - > SetStateString ( " PDAAudioIcon " , aud - > GetPreview ( ) ) ;
objectiveSystem - > SetStateString ( " PDAAudioInfo " , aud - > GetInfo ( ) ) ;
} else {
objectiveSystem - > SetStateString ( " PDAAudioIcon " , " sound/vo/video/welcome.tga " ) ;
objectiveSystem - > SetStateString ( " PDAAutioTitle " , " " ) ;
objectiveSystem - > SetStateString ( " PDAAudioInfo " , " " ) ;
}
}
// add emails
name = " " ;
data = " " ;
int numEmails = pda - > GetNumEmails ( ) ;
if ( numEmails > 0 ) {
AddGuiPDAData ( DECL_EMAIL , " listPDAEmail " , pda , objectiveSystem ) ;
sel = objectiveSystem - > State ( ) . GetInt ( " listPDAEmail_sel_0 " , " -1 " ) ;
if ( sel > = 0 & & sel < numEmails ) {
const idDeclEmail * email = pda - > GetEmailByIndex ( sel ) ;
name = email - > GetSubject ( ) ;
data = email - > GetBody ( ) ;
}
}
objectiveSystem - > SetStateString ( " PDAEmailTitle " , name ) ;
objectiveSystem - > SetStateString ( " PDAEmailText " , data ) ;
}
}
if ( objectiveSystem - > State ( ) . GetInt ( " listPDA_sel_0 " , " -1 " ) = = - 1 ) {
objectiveSystem - > SetStateInt ( " listPDA_sel_0 " , 0 ) ;
}
objectiveSystem - > StateChanged ( gameLocal . time ) ;
}
/*
= = = = = = = = = = = = = =
idPlayer : : TogglePDA
= = = = = = = = = = = = = =
*/
void idPlayer : : TogglePDA ( void ) {
if ( objectiveSystem = = NULL ) {
return ;
}
if ( inventory . pdas . Num ( ) = = 0 ) {
ShowTip ( spawnArgs . GetString ( " text_infoTitle " ) , spawnArgs . GetString ( " text_noPDA " ) , true ) ;
return ;
}
assert ( hud ) ;
if ( ! objectiveSystemOpen ) {
int j , c = inventory . items . Num ( ) ;
objectiveSystem - > SetStateInt ( " inv_count " , c ) ;
for ( j = 0 ; j < MAX_INVENTORY_ITEMS ; j + + ) {
objectiveSystem - > SetStateString ( va ( " inv_name_%i " , j ) , " " ) ;
objectiveSystem - > SetStateString ( va ( " inv_icon_%i " , j ) , " " ) ;
objectiveSystem - > SetStateString ( va ( " inv_text_%i " , j ) , " " ) ;
}
for ( j = 0 ; j < c ; j + + ) {
idDict * item = inventory . items [ j ] ;
if ( ! item - > GetBool ( " inv_pda " ) ) {
const char * iname = item - > GetString ( " inv_name " ) ;
const char * iicon = item - > GetString ( " inv_icon " ) ;
const char * itext = item - > GetString ( " inv_text " ) ;
objectiveSystem - > SetStateString ( va ( " inv_name_%i " , j ) , iname ) ;
objectiveSystem - > SetStateString ( va ( " inv_icon_%i " , j ) , iicon ) ;
objectiveSystem - > SetStateString ( va ( " inv_text_%i " , j ) , itext ) ;
const idKeyValue * kv = item - > MatchPrefix ( " inv_id " , NULL ) ;
if ( kv ) {
objectiveSystem - > SetStateString ( va ( " inv_id_%i " , j ) , kv - > GetValue ( ) ) ;
}
}
}
for ( j = 0 ; j < MAX_WEAPONS ; j + + ) {
const char * weapnum = va ( " def_weapon%d " , j ) ;
const char * hudWeap = va ( " weapon%d " , j ) ;
int weapstate = 0 ;
if ( inventory . weapons & ( 1 < < j ) ) {
const char * weap = spawnArgs . GetString ( weapnum ) ;
if ( weap & & * weap ) {
weapstate + + ;
}
}
objectiveSystem - > SetStateInt ( hudWeap , weapstate ) ;
}
objectiveSystem - > SetStateInt ( " listPDA_sel_0 " , inventory . selPDA ) ;
objectiveSystem - > SetStateInt ( " listPDAVideo_sel_0 " , inventory . selVideo ) ;
objectiveSystem - > SetStateInt ( " listPDAAudio_sel_0 " , inventory . selAudio ) ;
objectiveSystem - > SetStateInt ( " listPDAEmail_sel_0 " , inventory . selEMail ) ;
UpdatePDAInfo ( false ) ;
UpdateObjectiveInfo ( ) ;
objectiveSystem - > Activate ( true , gameLocal . time ) ;
hud - > HandleNamedEvent ( " pdaPickupHide " ) ;
hud - > HandleNamedEvent ( " videoPickupHide " ) ;
} else {
inventory . selPDA = objectiveSystem - > State ( ) . GetInt ( " listPDA_sel_0 " ) ;
inventory . selVideo = objectiveSystem - > State ( ) . GetInt ( " listPDAVideo_sel_0 " ) ;
inventory . selAudio = objectiveSystem - > State ( ) . GetInt ( " listPDAAudio_sel_0 " ) ;
inventory . selEMail = objectiveSystem - > State ( ) . GetInt ( " listPDAEmail_sel_0 " ) ;
objectiveSystem - > Activate ( false , gameLocal . time ) ;
}
objectiveSystemOpen ^ = 1 ;
}
/*
= = = = = = = = = = = = = =
idPlayer : : ToggleScoreboard
= = = = = = = = = = = = = =
*/
void idPlayer : : ToggleScoreboard ( void ) {
scoreBoardOpen ^ = 1 ;
}
/*
= = = = = = = = = = = = = =
idPlayer : : Spectate
= = = = = = = = = = = = = =
*/
void idPlayer : : Spectate ( bool spectate ) {
idBitMsg msg ;
byte msgBuf [ MAX_EVENT_PARAM_SIZE ] ;
// track invisible player bug
// all hiding and showing should be performed through Spectate calls
// except for the private camera view, which is used for teleports
assert ( ( teleportEntity . GetEntity ( ) ! = NULL ) | | ( IsHidden ( ) = = spectating ) ) ;
if ( spectating = = spectate ) {
return ;
}
spectating = spectate ;
if ( gameLocal . isServer ) {
msg . Init ( msgBuf , sizeof ( msgBuf ) ) ;
msg . WriteBits ( spectating , 1 ) ;
ServerSendEvent ( EVENT_SPECTATE , & msg , false , - 1 ) ;
}
if ( spectating ) {
// join the spectators
ClearPowerUps ( ) ;
spectator = this - > entityNumber ;
Init ( ) ;
StopRagdoll ( ) ;
SetPhysics ( & physicsObj ) ;
physicsObj . DisableClip ( ) ;
Hide ( ) ;
Event_DisableWeapon ( ) ;
if ( hud ) {
hud - > HandleNamedEvent ( " aim_clear " ) ;
MPAimFadeTime = 0 ;
}
} else {
// put everything back together again
currentWeapon = - 1 ; // to make sure the def will be loaded if necessary
Show ( ) ;
Event_EnableWeapon ( ) ;
}
SetClipModel ( ) ;
}
/*
= = = = = = = = = = = = = =
idPlayer : : SetClipModel
= = = = = = = = = = = = = =
*/
void idPlayer : : SetClipModel ( void ) {
idBounds bounds ;
if ( spectating ) {
bounds = idBounds ( vec3_origin ) . Expand ( pm_spectatebbox . GetFloat ( ) * 0.5f ) ;
} else {
bounds [ 0 ] . Set ( - pm_bboxwidth . GetFloat ( ) * 0.5f , - pm_bboxwidth . GetFloat ( ) * 0.5f , 0 ) ;
bounds [ 1 ] . Set ( pm_bboxwidth . GetFloat ( ) * 0.5f , pm_bboxwidth . GetFloat ( ) * 0.5f , pm_normalheight . GetFloat ( ) ) ;
}
// the origin of the clip model needs to be set before calling SetClipModel
// otherwise our physics object's current origin value gets reset to 0
idClipModel * newClip ;
if ( pm_usecylinder . GetBool ( ) ) {
newClip = new idClipModel ( idTraceModel ( bounds , 8 ) ) ;
newClip - > Translate ( physicsObj . PlayerGetOrigin ( ) ) ;
physicsObj . SetClipModel ( newClip , 1.0f ) ;
} else {
newClip = new idClipModel ( idTraceModel ( bounds ) ) ;
newClip - > Translate ( physicsObj . PlayerGetOrigin ( ) ) ;
physicsObj . SetClipModel ( newClip , 1.0f ) ;
}
}
/*
= = = = = = = = = = = = = =
idPlayer : : UseVehicle
= = = = = = = = = = = = = =
*/
void idPlayer : : UseVehicle ( void ) {
trace_t trace ;
idVec3 start , end ;
idEntity * ent ;
if ( GetBindMaster ( ) & & GetBindMaster ( ) - > IsType ( idAFEntity_Vehicle : : Type ) ) {
Show ( ) ;
static_cast < idAFEntity_Vehicle * > ( GetBindMaster ( ) ) - > Use ( this ) ;
} else {
start = GetEyePosition ( ) ;
end = start + viewAngles . ToForward ( ) * 80.0f ;
gameLocal . clip . TracePoint ( trace , start , end , MASK_SHOT_RENDERMODEL , this ) ;
if ( trace . fraction < 1.0f ) {
ent = gameLocal . entities [ trace . c . entityNum ] ;
if ( ent & & ent - > IsType ( idAFEntity_Vehicle : : Type ) ) {
Hide ( ) ;
static_cast < idAFEntity_Vehicle * > ( ent ) - > Use ( this ) ;
}
}
}
}
/*
= = = = = = = = = = = = = =
idPlayer : : PerformImpulse
= = = = = = = = = = = = = =
*/
void idPlayer : : PerformImpulse ( int impulse ) {
2018-08-26 03:41:08 +00:00
int prevIdealWeap ;
2011-11-22 21:28:15 +00:00
if ( gameLocal . isClient ) {
idBitMsg msg ;
byte msgBuf [ MAX_EVENT_PARAM_SIZE ] ;
assert ( entityNumber = = gameLocal . localClientNum ) ;
msg . Init ( msgBuf , sizeof ( msgBuf ) ) ;
msg . BeginWriting ( ) ;
msg . WriteBits ( impulse , 6 ) ;
ClientSendEvent ( EVENT_IMPULSE , & msg ) ;
}
2018-08-26 03:41:08 +00:00
if ( impulse = = IMPULSE_21 | | ( impulse > = IMPULSE_23 & & impulse < = IMPULSE_27 ) ) {
int weap ;
if ( spawnArgs . GetInt ( va ( " impulse%d " , impulse ) , " 0 " , weap ) ) {
prevIdealWeap = idealWeapon ;
SelectWeapon ( weap , false ) ;
if ( idealWeapon ! = prevIdealWeap ) {
quickWeapon = prevIdealWeap ;
}
}
2011-11-22 21:28:15 +00:00
return ;
}
2018-08-26 03:41:08 +00:00
if ( impulse > = IMPULSE_0 & & impulse < = IMPULSE_12 ) {
WeaponToggle_t * weaponToggle ;
// This loop works as a small bug fix for toggle weapons -By Clone JC Denton
// It simply increments the impulse value if there are multiple weapons under one weapon slot.
for ( int i = 0 ; i < impulse ; i + + ) {
if ( weaponToggles . Get ( va ( " weapontoggle%d " , i ) , & weaponToggle ) )
impulse + = weaponToggle - > toggleList . Num ( ) - 1 ;
}
prevIdealWeap = idealWeapon ;
SelectWeapon ( impulse , false , true ) ;
if ( idealWeapon ! = prevIdealWeap ) {
quickWeapon = prevIdealWeap ;
}
return ;
}
2011-11-22 21:28:15 +00:00
switch ( impulse ) {
case IMPULSE_13 : {
Reload ( ) ;
break ;
}
case IMPULSE_14 : {
2018-08-26 03:41:08 +00:00
prevIdealWeap = idealWeapon ;
2011-11-22 21:28:15 +00:00
NextWeapon ( ) ;
2018-08-26 03:41:08 +00:00
if ( idealWeapon ! = prevIdealWeap ) {
quickWeapon = prevIdealWeap ;
}
2011-11-22 21:28:15 +00:00
break ;
}
case IMPULSE_15 : {
2018-08-26 03:41:08 +00:00
prevIdealWeap = idealWeapon ;
2011-11-22 21:28:15 +00:00
PrevWeapon ( ) ;
2018-08-26 03:41:08 +00:00
if ( idealWeapon ! = prevIdealWeap ) {
quickWeapon = prevIdealWeap ;
}
break ;
}
case IMPULSE_16 : { // New, for half-life style quick weapon
if ( quickWeapon = = - 1 ) {
return ;
}
prevIdealWeap = idealWeapon ;
SelectWeapon ( quickWeapon , false ) ;
quickWeapon = prevIdealWeap ;
2011-11-22 21:28:15 +00:00
break ;
}
case IMPULSE_17 : {
if ( gameLocal . isClient | | entityNumber = = gameLocal . localClientNum ) {
gameLocal . mpGame . ToggleReady ( ) ;
}
break ;
}
case IMPULSE_18 : {
centerView . Init ( gameLocal . time , 200 , viewAngles . pitch , 0 ) ;
break ;
}
case IMPULSE_19 : {
// when we're not in single player, IMPULSE_19 is used for showScores
// otherwise it opens the pda
if ( ! gameLocal . isMultiplayer ) {
if ( objectiveSystemOpen ) {
TogglePDA ( ) ;
} else if ( weapon_pda > = 0 ) {
SelectWeapon ( weapon_pda , true ) ;
}
}
break ;
}
case IMPULSE_20 : {
if ( gameLocal . isClient | | entityNumber = = gameLocal . localClientNum ) {
gameLocal . mpGame . ToggleTeam ( ) ;
}
break ;
}
case IMPULSE_22 : {
if ( gameLocal . isClient | | entityNumber = = gameLocal . localClientNum ) {
gameLocal . mpGame . ToggleSpectate ( ) ;
}
break ;
}
case IMPULSE_28 : {
if ( gameLocal . isClient | | entityNumber = = gameLocal . localClientNum ) {
gameLocal . mpGame . CastVote ( gameLocal . localClientNum , true ) ;
}
break ;
}
case IMPULSE_29 : {
if ( gameLocal . isClient | | entityNumber = = gameLocal . localClientNum ) {
gameLocal . mpGame . CastVote ( gameLocal . localClientNum , false ) ;
}
break ;
}
2018-08-26 03:41:08 +00:00
/* case IMPULSE_30: {
WeaponSpecialFunction ( ) ;
break ;
} */
2011-11-22 21:28:15 +00:00
case IMPULSE_40 : {
UseVehicle ( ) ;
break ;
}
2011-12-06 18:20:15 +00:00
}
2011-11-22 21:28:15 +00:00
}
bool idPlayer : : HandleESC ( void ) {
if ( gameLocal . inCinematic ) {
return SkipCinematic ( ) ;
}
if ( objectiveSystemOpen ) {
TogglePDA ( ) ;
return true ;
}
return false ;
}
bool idPlayer : : SkipCinematic ( void ) {
StartSound ( " snd_skipcinematic " , SND_CHANNEL_ANY , 0 , false , NULL ) ;
return gameLocal . SkipCinematic ( ) ;
}
/*
= = = = = = = = = = = = = =
idPlayer : : EvaluateControls
= = = = = = = = = = = = = =
*/
void idPlayer : : EvaluateControls ( void ) {
// check for respawning
if ( health < = 0 ) {
if ( ( gameLocal . time > minRespawnTime ) & & ( usercmd . buttons & BUTTON_ATTACK ) ) {
forceRespawn = true ;
} else if ( gameLocal . time > maxRespawnTime ) {
forceRespawn = true ;
}
}
// in MP, idMultiplayerGame decides spawns
if ( forceRespawn & & ! gameLocal . isMultiplayer & & ! g_testDeath . GetBool ( ) ) {
// in single player, we let the session handle restarting the level or loading a game
gameLocal . sessionCommand = " died " ;
}
if ( ( usercmd . flags & UCF_IMPULSE_SEQUENCE ) ! = ( oldFlags & UCF_IMPULSE_SEQUENCE ) ) {
PerformImpulse ( usercmd . impulse ) ;
}
scoreBoardOpen = ( ( usercmd . buttons & BUTTON_SCORES ) ! = 0 | | forceScoreBoard ) ;
oldFlags = usercmd . flags ;
AdjustSpeed ( ) ;
// update the viewangles
UpdateViewAngles ( ) ;
}
/*
= = = = = = = = = = = = = =
idPlayer : : AdjustSpeed
= = = = = = = = = = = = = =
*/
void idPlayer : : AdjustSpeed ( void ) {
float speed ;
float rate ;
if ( spectating ) {
speed = pm_spectatespeed . GetFloat ( ) ;
bobFrac = 0.0f ;
} else if ( noclip ) {
speed = pm_noclipspeed . GetFloat ( ) ;
bobFrac = 0.0f ;
} else if ( ! physicsObj . OnLadder ( ) & & ( usercmd . buttons & BUTTON_RUN ) & & ( usercmd . forwardmove | | usercmd . rightmove ) & & ( usercmd . upmove > = 0 ) ) {
if ( ! gameLocal . isMultiplayer & & ! physicsObj . IsCrouching ( ) & & ! PowerUpActive ( ADRENALINE ) ) {
stamina - = MS2SEC ( gameLocal . msec ) ;
}
if ( stamina < 0 ) {
stamina = 0 ;
}
if ( ( ! pm_stamina . GetFloat ( ) ) | | ( stamina > pm_staminathreshold . GetFloat ( ) ) ) {
bobFrac = 1.0f ;
} else if ( pm_staminathreshold . GetFloat ( ) < = 0.0001f ) {
bobFrac = 0.0f ;
} else {
bobFrac = stamina / pm_staminathreshold . GetFloat ( ) ;
}
speed = pm_walkspeed . GetFloat ( ) * ( 1.0f - bobFrac ) + pm_runspeed . GetFloat ( ) * bobFrac ;
} else {
rate = pm_staminarate . GetFloat ( ) ;
2011-12-06 18:20:15 +00:00
2011-11-22 21:28:15 +00:00
// increase 25% faster when not moving
if ( ( usercmd . forwardmove = = 0 ) & & ( usercmd . rightmove = = 0 ) & & ( ! physicsObj . OnLadder ( ) | | ( usercmd . upmove = = 0 ) ) ) {
rate * = 1.25f ;
}
stamina + = rate * MS2SEC ( gameLocal . msec ) ;
if ( stamina > pm_stamina . GetFloat ( ) ) {
stamina = pm_stamina . GetFloat ( ) ;
}
speed = pm_walkspeed . GetFloat ( ) ;
bobFrac = 0.0f ;
}
speed * = PowerUpModifier ( SPEED ) ;
if ( influenceActive = = INFLUENCE_LEVEL3 ) {
speed * = 0.33f ;
}
physicsObj . SetSpeed ( speed , pm_crouchspeed . GetFloat ( ) ) ;
}
/*
= = = = = = = = = = = = = =
idPlayer : : AdjustBodyAngles
= = = = = = = = = = = = = =
*/
void idPlayer : : AdjustBodyAngles ( void ) {
idMat3 lookAxis ;
idMat3 legsAxis ;
bool blend ;
float diff ;
float frac ;
float upBlend ;
float forwardBlend ;
float downBlend ;
if ( health < 0 ) {
return ;
}
blend = true ;
if ( ! physicsObj . HasGroundContacts ( ) ) {
idealLegsYaw = 0.0f ;
legsForward = true ;
} else if ( usercmd . forwardmove < 0 ) {
idealLegsYaw = idMath : : AngleNormalize180 ( idVec3 ( - usercmd . forwardmove , usercmd . rightmove , 0.0f ) . ToYaw ( ) ) ;
legsForward = false ;
} else if ( usercmd . forwardmove > 0 ) {
idealLegsYaw = idMath : : AngleNormalize180 ( idVec3 ( usercmd . forwardmove , - usercmd . rightmove , 0.0f ) . ToYaw ( ) ) ;
legsForward = true ;
} else if ( ( usercmd . rightmove ! = 0 ) & & physicsObj . IsCrouching ( ) ) {
if ( ! legsForward ) {
idealLegsYaw = idMath : : AngleNormalize180 ( idVec3 ( idMath : : Abs ( usercmd . rightmove ) , usercmd . rightmove , 0.0f ) . ToYaw ( ) ) ;
} else {
idealLegsYaw = idMath : : AngleNormalize180 ( idVec3 ( idMath : : Abs ( usercmd . rightmove ) , - usercmd . rightmove , 0.0f ) . ToYaw ( ) ) ;
}
} else if ( usercmd . rightmove ! = 0 ) {
idealLegsYaw = 0.0f ;
legsForward = true ;
} else {
legsForward = true ;
diff = idMath : : Fabs ( idealLegsYaw - legsYaw ) ;
idealLegsYaw = idealLegsYaw - idMath : : AngleNormalize180 ( viewAngles . yaw - oldViewYaw ) ;
if ( diff < 0.1f ) {
legsYaw = idealLegsYaw ;
blend = false ;
}
}
if ( ! physicsObj . IsCrouching ( ) ) {
legsForward = true ;
}
oldViewYaw = viewAngles . yaw ;
AI_TURN_LEFT = false ;
AI_TURN_RIGHT = false ;
if ( idealLegsYaw < - 45.0f ) {
idealLegsYaw = 0 ;
AI_TURN_RIGHT = true ;
blend = true ;
} else if ( idealLegsYaw > 45.0f ) {
idealLegsYaw = 0 ;
AI_TURN_LEFT = true ;
blend = true ;
}
if ( blend ) {
legsYaw = legsYaw * 0.9f + idealLegsYaw * 0.1f ;
}
legsAxis = idAngles ( 0.0f , legsYaw , 0.0f ) . ToMat3 ( ) ;
animator . SetJointAxis ( hipJoint , JOINTMOD_WORLD , legsAxis ) ;
// calculate the blending between down, straight, and up
frac = viewAngles . pitch / 90.0f ;
if ( frac > 0.0f ) {
downBlend = frac ;
forwardBlend = 1.0f - frac ;
upBlend = 0.0f ;
} else {
downBlend = 0.0f ;
forwardBlend = 1.0f + frac ;
upBlend = - frac ;
}
2011-12-06 18:20:15 +00:00
animator . CurrentAnim ( ANIMCHANNEL_TORSO ) - > SetSyncedAnimWeight ( 0 , downBlend ) ;
2011-11-22 21:28:15 +00:00
animator . CurrentAnim ( ANIMCHANNEL_TORSO ) - > SetSyncedAnimWeight ( 1 , forwardBlend ) ;
animator . CurrentAnim ( ANIMCHANNEL_TORSO ) - > SetSyncedAnimWeight ( 2 , upBlend ) ;
animator . CurrentAnim ( ANIMCHANNEL_LEGS ) - > SetSyncedAnimWeight ( 0 , downBlend ) ;
animator . CurrentAnim ( ANIMCHANNEL_LEGS ) - > SetSyncedAnimWeight ( 1 , forwardBlend ) ;
animator . CurrentAnim ( ANIMCHANNEL_LEGS ) - > SetSyncedAnimWeight ( 2 , upBlend ) ;
}
/*
= = = = = = = = = = = = = =
idPlayer : : InitAASLocation
= = = = = = = = = = = = = =
*/
void idPlayer : : InitAASLocation ( void ) {
int i ;
int num ;
idVec3 size ;
idBounds bounds ;
idAAS * aas ;
idVec3 origin ;
GetFloorPos ( 64.0f , origin ) ;
num = gameLocal . NumAAS ( ) ;
aasLocation . SetGranularity ( 1 ) ;
2011-12-06 18:20:15 +00:00
aasLocation . SetNum ( num ) ;
2011-11-22 21:28:15 +00:00
for ( i = 0 ; i < aasLocation . Num ( ) ; i + + ) {
aasLocation [ i ] . areaNum = 0 ;
aasLocation [ i ] . pos = origin ;
aas = gameLocal . GetAAS ( i ) ;
if ( aas & & aas - > GetSettings ( ) ) {
size = aas - > GetSettings ( ) - > boundingBoxes [ 0 ] [ 1 ] ;
bounds [ 0 ] = - size ;
size . z = 32.0f ;
bounds [ 1 ] = size ;
aasLocation [ i ] . areaNum = aas - > PointReachableAreaNum ( origin , bounds , AREA_REACHABLE_WALK ) ;
}
}
}
/*
= = = = = = = = = = = = = =
idPlayer : : SetAASLocation
= = = = = = = = = = = = = =
*/
void idPlayer : : SetAASLocation ( void ) {
int i ;
int areaNum ;
idVec3 size ;
idBounds bounds ;
idAAS * aas ;
idVec3 origin ;
if ( ! GetFloorPos ( 64.0f , origin ) ) {
return ;
}
2011-12-06 18:20:15 +00:00
2011-11-22 21:28:15 +00:00
for ( i = 0 ; i < aasLocation . Num ( ) ; i + + ) {
aas = gameLocal . GetAAS ( i ) ;
if ( ! aas ) {
continue ;
}
size = aas - > GetSettings ( ) - > boundingBoxes [ 0 ] [ 1 ] ;
bounds [ 0 ] = - size ;
size . z = 32.0f ;
bounds [ 1 ] = size ;
areaNum = aas - > PointReachableAreaNum ( origin , bounds , AREA_REACHABLE_WALK ) ;
if ( areaNum ) {
aasLocation [ i ] . pos = origin ;
aasLocation [ i ] . areaNum = areaNum ;
}
}
}
/*
= = = = = = = = = = = = = =
idPlayer : : GetAASLocation
= = = = = = = = = = = = = =
*/
void idPlayer : : GetAASLocation ( idAAS * aas , idVec3 & pos , int & areaNum ) const {
int i ;
if ( aas ! = NULL ) {
for ( i = 0 ; i < aasLocation . Num ( ) ; i + + ) {
if ( aas = = gameLocal . GetAAS ( i ) ) {
areaNum = aasLocation [ i ] . areaNum ;
pos = aasLocation [ i ] . pos ;
return ;
}
}
}
areaNum = 0 ;
pos = physicsObj . GetOrigin ( ) ;
}
/*
= = = = = = = = = = = = = =
idPlayer : : Move
= = = = = = = = = = = = = =
*/
void idPlayer : : Move ( void ) {
float newEyeOffset ;
idVec3 oldOrigin ;
idVec3 oldVelocity ;
idVec3 pushVelocity ;
// save old origin and velocity for crashlanding
oldOrigin = physicsObj . GetOrigin ( ) ;
oldVelocity = physicsObj . GetLinearVelocity ( ) ;
pushVelocity = physicsObj . GetPushedLinearVelocity ( ) ;
// set physics variables
physicsObj . SetMaxStepHeight ( pm_stepsize . GetFloat ( ) ) ;
physicsObj . SetMaxJumpHeight ( pm_jumpheight . GetFloat ( ) ) ;
if ( noclip ) {
physicsObj . SetContents ( 0 ) ;
physicsObj . SetMovementType ( PM_NOCLIP ) ;
} else if ( spectating ) {
physicsObj . SetContents ( 0 ) ;
physicsObj . SetMovementType ( PM_SPECTATOR ) ;
} else if ( health < = 0 ) {
physicsObj . SetContents ( CONTENTS_CORPSE | CONTENTS_MONSTERCLIP ) ;
physicsObj . SetMovementType ( PM_DEAD ) ;
} else if ( gameLocal . inCinematic | | gameLocal . GetCamera ( ) | | privateCameraView | | ( influenceActive = = INFLUENCE_LEVEL2 ) ) {
physicsObj . SetContents ( CONTENTS_BODY ) ;
physicsObj . SetMovementType ( PM_FREEZE ) ;
} else {
physicsObj . SetContents ( CONTENTS_BODY ) ;
physicsObj . SetMovementType ( PM_NORMAL ) ;
}
if ( spectating ) {
physicsObj . SetClipMask ( MASK_DEADSOLID ) ;
} else if ( health < = 0 ) {
physicsObj . SetClipMask ( MASK_DEADSOLID ) ;
} else {
physicsObj . SetClipMask ( MASK_PLAYERSOLID ) ;
}
physicsObj . SetDebugLevel ( g_debugMove . GetBool ( ) ) ;
physicsObj . SetPlayerInput ( usercmd , viewAngles ) ;
// FIXME: physics gets disabled somehow
BecomeActive ( TH_PHYSICS ) ;
RunPhysics ( ) ;
// update our last valid AAS location for the AI
SetAASLocation ( ) ;
if ( spectating ) {
newEyeOffset = 0.0f ;
} else if ( health < = 0 ) {
newEyeOffset = pm_deadviewheight . GetFloat ( ) ;
} else if ( physicsObj . IsCrouching ( ) ) {
newEyeOffset = pm_crouchviewheight . GetFloat ( ) ;
} else if ( GetBindMaster ( ) & & GetBindMaster ( ) - > IsType ( idAFEntity_Vehicle : : Type ) ) {
newEyeOffset = 0.0f ;
} else {
newEyeOffset = pm_normalviewheight . GetFloat ( ) ;
}
if ( EyeHeight ( ) ! = newEyeOffset ) {
if ( spectating ) {
SetEyeHeight ( newEyeOffset ) ;
} else {
// smooth out duck height changes
SetEyeHeight ( EyeHeight ( ) * pm_crouchrate . GetFloat ( ) + newEyeOffset * ( 1.0f - pm_crouchrate . GetFloat ( ) ) ) ;
}
}
if ( noclip | | gameLocal . inCinematic | | ( influenceActive = = INFLUENCE_LEVEL2 ) ) {
AI_CROUCH = false ;
AI_ONGROUND = ( influenceActive = = INFLUENCE_LEVEL2 ) ;
AI_ONLADDER = false ;
AI_JUMP = false ;
} else {
AI_CROUCH = physicsObj . IsCrouching ( ) ;
AI_ONGROUND = physicsObj . HasGroundContacts ( ) ;
AI_ONLADDER = physicsObj . OnLadder ( ) ;
AI_JUMP = physicsObj . HasJumped ( ) ;
// check if we're standing on top of a monster and give a push if we are
idEntity * groundEnt = physicsObj . GetGroundEntity ( ) ;
if ( groundEnt & & groundEnt - > IsType ( idAI : : Type ) ) {
idVec3 vel = physicsObj . GetLinearVelocity ( ) ;
if ( vel . ToVec2 ( ) . LengthSqr ( ) < 0.1f ) {
vel . ToVec2 ( ) = physicsObj . GetOrigin ( ) . ToVec2 ( ) - groundEnt - > GetPhysics ( ) - > GetAbsBounds ( ) . GetCenter ( ) . ToVec2 ( ) ;
vel . ToVec2 ( ) . NormalizeFast ( ) ;
vel . ToVec2 ( ) * = pm_walkspeed . GetFloat ( ) ;
} else {
// give em a push in the direction they're going
vel * = 1.1f ;
}
physicsObj . SetLinearVelocity ( vel ) ;
}
}
if ( AI_JUMP ) {
// bounce the view weapon
2011-12-06 18:20:15 +00:00
loggedAccel_t * acc = & loggedAccel [ currentLoggedAccel & ( NUM_LOGGED_ACCELS - 1 ) ] ;
2011-11-22 21:28:15 +00:00
currentLoggedAccel + + ;
acc - > time = gameLocal . time ;
acc - > dir [ 2 ] = 200 ;
acc - > dir [ 0 ] = acc - > dir [ 1 ] = 0 ;
}
if ( AI_ONLADDER ) {
int old_rung = oldOrigin . z / LADDER_RUNG_DISTANCE ;
int new_rung = physicsObj . GetOrigin ( ) . z / LADDER_RUNG_DISTANCE ;
if ( old_rung ! = new_rung ) {
StartSound ( " snd_stepladder " , SND_CHANNEL_ANY , 0 , false , NULL ) ;
}
}
BobCycle ( pushVelocity ) ;
CrashLand ( oldOrigin , oldVelocity ) ;
}
/*
= = = = = = = = = = = = = =
idPlayer : : UpdateHud
= = = = = = = = = = = = = =
*/
void idPlayer : : UpdateHud ( void ) {
idPlayer * aimed ;
if ( ! hud ) {
return ;
}
if ( entityNumber ! = gameLocal . localClientNum ) {
return ;
}
int c = inventory . pickupItemNames . Num ( ) ;
if ( c > 0 ) {
if ( gameLocal . time > inventory . nextItemPickup ) {
if ( inventory . nextItemPickup & & gameLocal . time - inventory . nextItemPickup > 2000 ) {
inventory . nextItemNum = 1 ;
}
int i ;
2011-12-02 19:55:32 +00:00
for ( i = 0 ; i < 5 & & i < c ; i + + ) {
2011-11-22 21:28:15 +00:00
hud - > SetStateString ( va ( " itemtext%i " , inventory . nextItemNum ) , inventory . pickupItemNames [ 0 ] . name ) ;
hud - > SetStateString ( va ( " itemicon%i " , inventory . nextItemNum ) , inventory . pickupItemNames [ 0 ] . icon ) ;
hud - > HandleNamedEvent ( va ( " itemPickup%i " , inventory . nextItemNum + + ) ) ;
inventory . pickupItemNames . RemoveIndex ( 0 ) ;
if ( inventory . nextItemNum = = 1 ) {
inventory . onePickupTime = gameLocal . time ;
2011-12-06 18:20:15 +00:00
} else if ( inventory . nextItemNum > 5 ) {
2011-11-22 21:28:15 +00:00
inventory . nextItemNum = 1 ;
inventory . nextItemPickup = inventory . onePickupTime + 2000 ;
} else {
inventory . nextItemPickup = gameLocal . time + 400 ;
}
}
}
}
if ( gameLocal . realClientTime = = lastMPAimTime ) {
if ( MPAim ! = - 1 & & gameLocal . gameType = = GAME_TDM
& & gameLocal . entities [ MPAim ] & & gameLocal . entities [ MPAim ] - > IsType ( idPlayer : : Type )
& & static_cast < idPlayer * > ( gameLocal . entities [ MPAim ] ) - > team = = team ) {
aimed = static_cast < idPlayer * > ( gameLocal . entities [ MPAim ] ) ;
hud - > SetStateString ( " aim_text " , gameLocal . userInfo [ MPAim ] . GetString ( " ui_name " ) ) ;
hud - > SetStateFloat ( " aim_color " , aimed - > colorBarIndex ) ;
hud - > HandleNamedEvent ( " aim_flash " ) ;
MPAimHighlight = true ;
MPAimFadeTime = 0 ; // no fade till loosing focus
} else if ( MPAimHighlight ) {
hud - > HandleNamedEvent ( " aim_fade " ) ;
MPAimFadeTime = gameLocal . realClientTime ;
MPAimHighlight = false ;
}
}
if ( MPAimFadeTime ) {
assert ( ! MPAimHighlight ) ;
if ( gameLocal . realClientTime - MPAimFadeTime > 2000 ) {
MPAimFadeTime = 0 ;
}
}
hud - > SetStateInt ( " g_showProjectilePct " , g_showProjectilePct . GetInteger ( ) ) ;
if ( numProjectilesFired ) {
hud - > SetStateString ( " projectilepct " , va ( " Hit %% %.1f " , ( ( float ) numProjectileHits / numProjectilesFired ) * 100 ) ) ;
} else {
hud - > SetStateString ( " projectilepct " , " Hit % 0.0 " ) ;
}
if ( isLagged & & gameLocal . isMultiplayer & & gameLocal . localClientNum = = entityNumber ) {
hud - > SetStateString ( " hudLag " , " 1 " ) ;
} else {
hud - > SetStateString ( " hudLag " , " 0 " ) ;
}
}
/*
= = = = = = = = = = = = = =
idPlayer : : UpdateDeathSkin
= = = = = = = = = = = = = =
*/
void idPlayer : : UpdateDeathSkin ( bool state_hitch ) {
if ( ! ( gameLocal . isMultiplayer | | g_testDeath . GetBool ( ) ) ) {
return ;
}
if ( health < = 0 ) {
if ( ! doingDeathSkin ) {
deathClearContentsTime = spawnArgs . GetInt ( " deathSkinTime " ) ;
doingDeathSkin = true ;
renderEntity . noShadow = true ;
if ( state_hitch ) {
renderEntity . shaderParms [ SHADERPARM_TIME_OF_DEATH ] = gameLocal . time * 0.001f - 2.0f ;
} else {
renderEntity . shaderParms [ SHADERPARM_TIME_OF_DEATH ] = gameLocal . time * 0.001f ;
}
UpdateVisuals ( ) ;
}
// wait a bit before switching off the content
if ( deathClearContentsTime & & gameLocal . time > deathClearContentsTime ) {
SetCombatContents ( false ) ;
deathClearContentsTime = 0 ;
}
} else {
renderEntity . noShadow = false ;
renderEntity . shaderParms [ SHADERPARM_TIME_OF_DEATH ] = 0.0f ;
UpdateVisuals ( ) ;
doingDeathSkin = false ;
}
}
/*
= = = = = = = = = = = = = =
idPlayer : : StartFxOnBone
= = = = = = = = = = = = = =
*/
void idPlayer : : StartFxOnBone ( const char * fx , const char * bone ) {
idVec3 offset ;
idMat3 axis ;
jointHandle_t jointHandle = GetAnimator ( ) - > GetJointHandle ( bone ) ;
if ( jointHandle = = INVALID_JOINT ) {
gameLocal . Printf ( " Cannot find bone %s \n " , bone ) ;
return ;
}
if ( GetAnimator ( ) - > GetJointTransform ( jointHandle , gameLocal . time , offset , axis ) ) {
offset = GetPhysics ( ) - > GetOrigin ( ) + offset * GetPhysics ( ) - > GetAxis ( ) ;
axis = axis * GetPhysics ( ) - > GetAxis ( ) ;
}
idEntityFx : : StartFx ( fx , & offset , & axis , this , true ) ;
}
/*
= = = = = = = = = = = = = =
idPlayer : : Think
Called every tic for each player
= = = = = = = = = = = = = =
*/
void idPlayer : : Think ( void ) {
renderEntity_t * headRenderEnt ;
UpdatePlayerIcons ( ) ;
// latch button actions
oldButtons = usercmd . buttons ;
// grab out usercmd
usercmd_t oldCmd = usercmd ;
usercmd = gameLocal . usercmds [ entityNumber ] ;
buttonMask & = usercmd . buttons ;
usercmd . buttons & = ~ buttonMask ;
if ( gameLocal . inCinematic & & gameLocal . skipCinematic ) {
return ;
}
// clear the ik before we do anything else so the skeleton doesn't get updated twice
walkIK . ClearJointMods ( ) ;
2011-12-06 18:20:15 +00:00
2011-11-22 21:28:15 +00:00
// if this is the very first frame of the map, set the delta view angles
// based on the usercmd angles
if ( ! spawnAnglesSet & & ( gameLocal . GameState ( ) ! = GAMESTATE_STARTUP ) ) {
spawnAnglesSet = true ;
SetViewAngles ( spawnAngles ) ;
oldFlags = usercmd . flags ;
}
if ( objectiveSystemOpen | | gameLocal . inCinematic | | influenceActive ) {
if ( objectiveSystemOpen & & AI_PAIN ) {
TogglePDA ( ) ;
}
usercmd . forwardmove = 0 ;
usercmd . rightmove = 0 ;
usercmd . upmove = 0 ;
}
// log movement changes for weapon bobbing effects
if ( usercmd . forwardmove ! = oldCmd . forwardmove ) {
loggedAccel_t * acc = & loggedAccel [ currentLoggedAccel & ( NUM_LOGGED_ACCELS - 1 ) ] ;
currentLoggedAccel + + ;
acc - > time = gameLocal . time ;
acc - > dir [ 0 ] = usercmd . forwardmove - oldCmd . forwardmove ;
acc - > dir [ 1 ] = acc - > dir [ 2 ] = 0 ;
}
if ( usercmd . rightmove ! = oldCmd . rightmove ) {
loggedAccel_t * acc = & loggedAccel [ currentLoggedAccel & ( NUM_LOGGED_ACCELS - 1 ) ] ;
currentLoggedAccel + + ;
acc - > time = gameLocal . time ;
acc - > dir [ 1 ] = usercmd . rightmove - oldCmd . rightmove ;
acc - > dir [ 0 ] = acc - > dir [ 2 ] = 0 ;
}
// freelook centering
if ( ( usercmd . buttons ^ oldCmd . buttons ) & BUTTON_MLOOK ) {
centerView . Init ( gameLocal . time , 200 , viewAngles . pitch , 0 ) ;
}
// zooming
if ( ( usercmd . buttons ^ oldCmd . buttons ) & BUTTON_ZOOM ) {
if ( ( usercmd . buttons & BUTTON_ZOOM ) & & weapon . GetEntity ( ) ) {
zoomFov . Init ( gameLocal . time , 200.0f , CalcFov ( false ) , weapon . GetEntity ( ) - > GetZoomFov ( ) ) ;
} else {
zoomFov . Init ( gameLocal . time , 200.0f , zoomFov . GetCurrentValue ( gameLocal . time ) , DefaultFov ( ) ) ;
}
}
2018-08-26 03:41:08 +00:00
# ifdef _DENTONMOD_PLAYER_CPP
// zooming, initiated by weapon script
if ( ( weaponZoom . oldZoomStatus ^ weaponZoom . startZoom ) ) {
if ( weaponZoom . startZoom & & weapon . GetEntity ( ) ) {
weaponZoom . oldZoomStatus = true ;
zoomFov . Init ( gameLocal . time , 200.0f , CalcFov ( false ) , weapon . GetEntity ( ) - > GetZoomFov ( ) ) ;
} else {
weaponZoom . oldZoomStatus = false ;
zoomFov . Init ( gameLocal . time , 200.0f , zoomFov . GetCurrentValue ( gameLocal . time ) , DefaultFov ( ) ) ;
}
}
# endif //_DENTONMOD_PLAYER_CPP
2011-11-22 21:28:15 +00:00
// if we have an active gui, we will unrotate the view angles as
// we turn the mouse movements into gui events
idUserInterface * gui = ActiveGui ( ) ;
if ( gui & & gui ! = focusUI ) {
RouteGuiMouse ( gui ) ;
}
// set the push velocity on the weapon before running the physics
if ( weapon . GetEntity ( ) ) {
weapon . GetEntity ( ) - > SetPushVelocity ( physicsObj . GetPushedLinearVelocity ( ) ) ;
}
EvaluateControls ( ) ;
if ( ! af . IsActive ( ) ) {
AdjustBodyAngles ( ) ;
CopyJointsFromBodyToHead ( ) ;
}
Move ( ) ;
if ( ! g_stopTime . GetBool ( ) ) {
if ( ! noclip & & ! spectating & & ( health > 0 ) & & ! IsHidden ( ) ) {
TouchTriggers ( ) ;
}
// not done on clients for various reasons. don't do it on server and save the sound channel for other things
if ( ! gameLocal . isMultiplayer ) {
SetCurrentHeartRate ( ) ;
float scale = g_damageScale . GetFloat ( ) ;
if ( g_useDynamicProtection . GetBool ( ) & & scale < 1.0f & & gameLocal . time - lastDmgTime > 500 ) {
if ( scale < 1.0f ) {
scale + = 0.05f ;
}
if ( scale > 1.0f ) {
scale = 1.0f ;
}
g_damageScale . SetFloat ( scale ) ;
}
}
// update GUIs, Items, and character interactions
UpdateFocus ( ) ;
2011-12-06 18:20:15 +00:00
2011-11-22 21:28:15 +00:00
UpdateLocation ( ) ;
// update player script
UpdateScript ( ) ;
// service animations
if ( ! spectating & & ! af . IsActive ( ) & & ! gameLocal . inCinematic ) {
2011-12-06 18:20:15 +00:00
UpdateConditions ( ) ;
2011-11-22 21:28:15 +00:00
UpdateAnimState ( ) ;
CheckBlink ( ) ;
}
// clear out our pain flag so we can tell if we recieve any damage between now and the next time we think
AI_PAIN = false ;
}
// calculate the exact bobbed view position, which is used to
// position the view weapon, among other things
CalculateFirstPersonView ( ) ;
// this may use firstPersonView, or a thirdPeroson / camera view
CalculateRenderView ( ) ;
inventory . UpdateArmor ( ) ;
if ( spectating ) {
UpdateSpectating ( ) ;
} else if ( health > 0 ) {
UpdateWeapon ( ) ;
}
UpdateAir ( ) ;
2011-12-06 18:20:15 +00:00
2011-11-22 21:28:15 +00:00
UpdateHud ( ) ;
UpdatePowerUps ( ) ;
UpdateDeathSkin ( false ) ;
if ( gameLocal . isMultiplayer ) {
DrawPlayerIcons ( ) ;
}
if ( head . GetEntity ( ) ) {
headRenderEnt = head . GetEntity ( ) - > GetRenderEntity ( ) ;
} else {
headRenderEnt = NULL ;
}
if ( headRenderEnt ) {
if ( influenceSkin ) {
headRenderEnt - > customSkin = influenceSkin ;
} else {
headRenderEnt - > customSkin = NULL ;
}
}
if ( gameLocal . isMultiplayer | | g_showPlayerShadow . GetBool ( ) ) {
renderEntity . suppressShadowInViewID = 0 ;
if ( headRenderEnt ) {
headRenderEnt - > suppressShadowInViewID = 0 ;
}
} else {
renderEntity . suppressShadowInViewID = entityNumber + 1 ;
if ( headRenderEnt ) {
headRenderEnt - > suppressShadowInViewID = entityNumber + 1 ;
}
}
// never cast shadows from our first-person muzzle flashes
renderEntity . suppressShadowInLightID = LIGHTID_VIEW_MUZZLE_FLASH + entityNumber ;
if ( headRenderEnt ) {
headRenderEnt - > suppressShadowInLightID = LIGHTID_VIEW_MUZZLE_FLASH + entityNumber ;
}
if ( ! g_stopTime . GetBool ( ) ) {
UpdateAnimation ( ) ;
2011-12-06 18:20:15 +00:00
Present ( ) ;
2011-11-22 21:28:15 +00:00
UpdateDamageEffects ( ) ;
LinkCombat ( ) ;
playerView . CalculateShake ( ) ;
}
if ( ! ( thinkFlags & TH_THINK ) ) {
gameLocal . Printf ( " player %d not thinking? \n " , entityNumber ) ;
}
if ( g_showEnemies . GetBool ( ) ) {
idActor * ent ;
int num = 0 ;
for ( ent = enemyList . Next ( ) ; ent ! = NULL ; ent = ent - > enemyNode . Next ( ) ) {
gameLocal . Printf ( " enemy (%d)'%s' \n " , ent - > entityNumber , ent - > name . c_str ( ) ) ;
gameRenderWorld - > DebugBounds ( colorRed , ent - > GetPhysics ( ) - > GetBounds ( ) . Expand ( 2 ) , ent - > GetPhysics ( ) - > GetOrigin ( ) ) ;
num + + ;
}
gameLocal . Printf ( " %d: enemies \n " , num ) ;
}
2018-08-26 03:41:08 +00:00
# ifdef _PORTALSKY
// determine if portal sky is in pvs
gameLocal . portalSkyActive = gameLocal . pvs . CheckAreasForPortalSky ( gameLocal . GetPlayerPVS ( ) , GetPhysics ( ) - > GetOrigin ( ) ) ;
# endif
2011-11-22 21:28:15 +00:00
}
/*
= = = = = = = = = = = = = = = = =
idPlayer : : RouteGuiMouse
= = = = = = = = = = = = = = = = =
*/
void idPlayer : : RouteGuiMouse ( idUserInterface * gui ) {
sysEvent_t ev ;
if ( usercmd . mx ! = oldMouseX | | usercmd . my ! = oldMouseY ) {
ev = sys - > GenerateMouseMoveEvent ( usercmd . mx - oldMouseX , usercmd . my - oldMouseY ) ;
2011-12-02 18:54:23 +00:00
gui - > HandleEvent ( & ev , gameLocal . time ) ;
2011-11-22 21:28:15 +00:00
oldMouseX = usercmd . mx ;
oldMouseY = usercmd . my ;
}
}
/*
= = = = = = = = = = = = = = = = = =
idPlayer : : LookAtKiller
= = = = = = = = = = = = = = = = = =
*/
void idPlayer : : LookAtKiller ( idEntity * inflictor , idEntity * attacker ) {
idVec3 dir ;
2011-12-06 18:20:15 +00:00
2011-11-22 21:28:15 +00:00
if ( attacker & & attacker ! = this ) {
dir = attacker - > GetPhysics ( ) - > GetOrigin ( ) - GetPhysics ( ) - > GetOrigin ( ) ;
} else if ( inflictor & & inflictor ! = this ) {
dir = inflictor - > GetPhysics ( ) - > GetOrigin ( ) - GetPhysics ( ) - > GetOrigin ( ) ;
} else {
dir = viewAxis [ 0 ] ;
}
idAngles ang ( 0 , dir . ToYaw ( ) , 0 ) ;
SetViewAngles ( ang ) ;
}
/*
= = = = = = = = = = = = = =
idPlayer : : Kill
= = = = = = = = = = = = = =
*/
void idPlayer : : Kill ( bool delayRespawn , bool nodamage ) {
if ( spectating ) {
SpectateFreeFly ( false ) ;
} else if ( health > 0 ) {
godmode = false ;
if ( nodamage ) {
ServerSpectate ( true ) ;
forceRespawn = true ;
} else {
Damage ( this , this , vec3_origin , " damage_suicide " , 1.0f , INVALID_JOINT ) ;
if ( delayRespawn ) {
forceRespawn = false ;
int delay = spawnArgs . GetFloat ( " respawn_delay " ) ;
minRespawnTime = gameLocal . time + SEC2MS ( delay ) ;
maxRespawnTime = minRespawnTime + MAX_RESPAWN_TIME ;
}
}
}
}
/*
= = = = = = = = = = = = = = = = = =
idPlayer : : Killed
= = = = = = = = = = = = = = = = = =
*/
void idPlayer : : Killed ( idEntity * inflictor , idEntity * attacker , int damage , const idVec3 & dir , int location ) {
float delay ;
assert ( ! gameLocal . isClient ) ;
// stop taking knockback once dead
fl . noknockback = true ;
if ( health < - 999 ) {
health = - 999 ;
}
if ( AI_DEAD ) {
AI_PAIN = true ;
return ;
}
heartInfo . Init ( 0 , 0 , 0 , BASE_HEARTRATE ) ;
AdjustHeartRate ( DEAD_HEARTRATE , 10.0f , 0.0f , true ) ;
if ( ! g_testDeath . GetBool ( ) ) {
playerView . Fade ( colorBlack , 12000 ) ;
}
AI_DEAD = true ;
SetAnimState ( ANIMCHANNEL_LEGS , " Legs_Death " , 4 ) ;
SetAnimState ( ANIMCHANNEL_TORSO , " Torso_Death " , 4 ) ;
SetWaitState ( " " ) ;
animator . ClearAllJoints ( ) ;
if ( StartRagdoll ( ) ) {
pm_modelView . SetInteger ( 0 ) ;
minRespawnTime = gameLocal . time + RAGDOLL_DEATH_TIME ;
maxRespawnTime = minRespawnTime + MAX_RESPAWN_TIME ;
} else {
// don't allow respawn until the death anim is done
// g_forcerespawn may force spawning at some later time
delay = spawnArgs . GetFloat ( " respawn_delay " ) ;
minRespawnTime = gameLocal . time + SEC2MS ( delay ) ;
maxRespawnTime = minRespawnTime + MAX_RESPAWN_TIME ;
}
physicsObj . SetMovementType ( PM_DEAD ) ;
StartSound ( " snd_death " , SND_CHANNEL_VOICE , 0 , false , NULL ) ;
StopSound ( SND_CHANNEL_BODY2 , false ) ;
fl . takedamage = true ; // can still be gibbed
// get rid of weapon
weapon . GetEntity ( ) - > OwnerDied ( ) ;
// drop the weapon as an item
DropWeapon ( true ) ;
if ( ! g_testDeath . GetBool ( ) ) {
LookAtKiller ( inflictor , attacker ) ;
}
if ( gameLocal . isMultiplayer | | g_testDeath . GetBool ( ) ) {
idPlayer * killer = NULL ;
// no gibbing in MP. Event_Gib will early out in MP
if ( attacker - > IsType ( idPlayer : : Type ) ) {
killer = static_cast < idPlayer * > ( attacker ) ;
if ( health < - 20 | | killer - > PowerUpActive ( BERSERK ) ) {
gibDeath = true ;
gibsDir = dir ;
gibsLaunched = false ;
}
}
gameLocal . mpGame . PlayerDeath ( this , killer , isTelefragged ) ;
} else {
physicsObj . SetContents ( CONTENTS_CORPSE | CONTENTS_MONSTERCLIP ) ;
}
ClearPowerUps ( ) ;
UpdateVisuals ( ) ;
isChatting = false ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idPlayer : : GetAIAimTargets
Returns positions for the AI to aim at .
= = = = = = = = = = = = = = = = = = = = =
*/
void idPlayer : : GetAIAimTargets ( const idVec3 & lastSightPos , idVec3 & headPos , idVec3 & chestPos ) {
idVec3 offset ;
idMat3 axis ;
idVec3 origin ;
2011-12-06 18:20:15 +00:00
2011-11-22 21:28:15 +00:00
origin = lastSightPos - physicsObj . GetOrigin ( ) ;
GetJointWorldTransform ( chestJoint , gameLocal . time , offset , axis ) ;
headPos = offset + origin ;
GetJointWorldTransform ( headJoint , gameLocal . time , offset , axis ) ;
chestPos = offset + origin ;
}
/*
= = = = = = = = = = = = = = = =
idPlayer : : DamageFeedback
callback function for when another entity received damage from this entity . damage can be adjusted and returned to the caller .
= = = = = = = = = = = = = = = =
*/
void idPlayer : : DamageFeedback ( idEntity * victim , idEntity * inflictor , int & damage ) {
assert ( ! gameLocal . isClient ) ;
damage * = PowerUpModifier ( BERSERK ) ;
if ( damage & & ( victim ! = this ) & & victim - > IsType ( idActor : : Type ) ) {
SetLastHitTime ( gameLocal . time ) ;
}
}
/*
= = = = = = = = = = = = = = = = =
idPlayer : : CalcDamagePoints
Calculates how many health and armor points will be inflicted , but
doesn ' t actually do anything with them . This is used to tell when an attack
would have killed the player , possibly allowing a " saving throw "
= = = = = = = = = = = = = = = = =
*/
void idPlayer : : CalcDamagePoints ( idEntity * inflictor , idEntity * attacker , const idDict * damageDef ,
const float damageScale , const int location , int * health , int * armor ) {
int damage ;
int armorSave ;
damageDef - > GetInt ( " damage " , " 20 " , damage ) ;
damage = GetDamageForLocation ( damage , location ) ;
idPlayer * player = attacker - > IsType ( idPlayer : : Type ) ? static_cast < idPlayer * > ( attacker ) : NULL ;
if ( ! gameLocal . isMultiplayer ) {
if ( inflictor ! = gameLocal . world ) {
switch ( g_skill . GetInteger ( ) ) {
2011-12-06 18:20:15 +00:00
case 0 :
2011-11-22 21:28:15 +00:00
damage * = 0.80f ;
if ( damage < 1 ) {
damage = 1 ;
}
break ;
case 2 :
damage * = 1.70f ;
break ;
case 3 :
damage * = 3.5f ;
break ;
default :
break ;
}
}
}
damage * = damageScale ;
// always give half damage if hurting self
if ( attacker = = this ) {
if ( gameLocal . isMultiplayer ) {
// only do this in mp so single player plasma and rocket splash is very dangerous in close quarters
damage * = damageDef - > GetFloat ( " selfDamageScale " , " 0.5 " ) ;
} else {
damage * = damageDef - > GetFloat ( " selfDamageScale " , " 1 " ) ;
}
}
// check for completely getting out of the damage
if ( ! damageDef - > GetBool ( " noGod " ) ) {
// check for godmode
if ( godmode ) {
damage = 0 ;
}
}
// inform the attacker that they hit someone
attacker - > DamageFeedback ( this , inflictor , damage ) ;
// save some from armor
if ( ! damageDef - > GetBool ( " noArmor " ) ) {
float armor_protection ;
armor_protection = ( gameLocal . isMultiplayer ) ? g_armorProtectionMP . GetFloat ( ) : g_armorProtection . GetFloat ( ) ;
armorSave = ceil ( damage * armor_protection ) ;
if ( armorSave > = inventory . armor ) {
armorSave = inventory . armor ;
}
if ( ! damage ) {
armorSave = 0 ;
} else if ( armorSave > = damage ) {
armorSave = damage - 1 ;
damage = 1 ;
} else {
damage - = armorSave ;
}
} else {
armorSave = 0 ;
}
// check for team damage
if ( gameLocal . gameType = = GAME_TDM
& & ! gameLocal . serverInfo . GetBool ( " si_teamDamage " )
& & ! damageDef - > GetBool ( " noTeam " )
& & player
& & player ! = this // you get self damage no matter what
& & player - > team = = team ) {
damage = 0 ;
}
* health = damage ;
* armor = armorSave ;
}
/*
= = = = = = = = = = = =
Damage
this entity that is being damaged
inflictor entity that is causing the damage
attacker entity that caused the inflictor to damage targ
example : this = monster , inflictor = rocket , attacker = player
dir direction of the attack for knockback in global space
damageDef an idDict with all the options for damage effects
inflictor , attacker , dir , and point can be NULL for environmental effects
= = = = = = = = = = = =
*/
void idPlayer : : Damage ( idEntity * inflictor , idEntity * attacker , const idVec3 & dir ,
const char * damageDefName , const float damageScale , const int location ) {
idVec3 kick ;
int damage ;
int armorSave ;
int knockback ;
idVec3 damage_from ;
2011-12-06 18:20:15 +00:00
idVec3 localDamageVector ;
2011-11-22 21:28:15 +00:00
float attackerPushScale ;
// damage is only processed on server
if ( gameLocal . isClient ) {
return ;
}
2011-12-06 18:20:15 +00:00
2011-11-22 21:28:15 +00:00
if ( ! fl . takedamage | | noclip | | spectating | | gameLocal . inCinematic ) {
return ;
}
if ( ! inflictor ) {
inflictor = gameLocal . world ;
}
if ( ! attacker ) {
attacker = gameLocal . world ;
}
if ( attacker - > IsType ( idAI : : Type ) ) {
if ( PowerUpActive ( BERSERK ) ) {
return ;
}
// don't take damage from monsters during influences
if ( influenceActive ! = 0 ) {
return ;
}
}
const idDeclEntityDef * damageDef = gameLocal . FindEntityDef ( damageDefName , false ) ;
if ( ! damageDef ) {
gameLocal . Warning ( " Unknown damageDef '%s' " , damageDefName ) ;
return ;
}
if ( damageDef - > dict . GetBool ( " ignore_player " ) ) {
return ;
}
CalcDamagePoints ( inflictor , attacker , & damageDef - > dict , damageScale , location , & damage , & armorSave ) ;
// determine knockback
damageDef - > dict . GetInt ( " knockback " , " 20 " , knockback ) ;
if ( knockback ! = 0 & & ! fl . noknockback ) {
if ( attacker = = this ) {
damageDef - > dict . GetFloat ( " attackerPushScale " , " 0 " , attackerPushScale ) ;
} else {
attackerPushScale = 1.0f ;
}
kick = dir ;
kick . Normalize ( ) ;
kick * = g_knockback . GetFloat ( ) * knockback * attackerPushScale / 200.0f ;
physicsObj . SetLinearVelocity ( physicsObj . GetLinearVelocity ( ) + kick ) ;
// set the timer so that the player can't cancel out the movement immediately
physicsObj . SetKnockBack ( idMath : : ClampInt ( 50 , 200 , knockback * 2 ) ) ;
}
// give feedback on the player view and audibly when armor is helping
if ( armorSave ) {
inventory . armor - = armorSave ;
if ( gameLocal . time > lastArmorPulse + 200 ) {
StartSound ( " snd_hitArmor " , SND_CHANNEL_ITEM , 0 , false , NULL ) ;
}
lastArmorPulse = gameLocal . time ;
}
2011-12-06 18:20:15 +00:00
2011-11-22 21:28:15 +00:00
if ( damageDef - > dict . GetBool ( " burn " ) ) {
StartSound ( " snd_burn " , SND_CHANNEL_BODY3 , 0 , false , NULL ) ;
} else if ( damageDef - > dict . GetBool ( " no_air " ) ) {
if ( ! armorSave & & health > 0 ) {
StartSound ( " snd_airGasp " , SND_CHANNEL_ITEM , 0 , false , NULL ) ;
}
}
if ( g_debugDamage . GetInteger ( ) ) {
2011-12-06 18:20:15 +00:00
gameLocal . Printf ( " client:%i health:%i damage:%i armor:%i \n " ,
2011-11-22 21:28:15 +00:00
entityNumber , health , damage , armorSave ) ;
}
// move the world direction vector to local coordinates
damage_from = dir ;
damage_from . Normalize ( ) ;
2011-12-06 18:20:15 +00:00
2011-11-22 21:28:15 +00:00
viewAxis . ProjectVector ( damage_from , localDamageVector ) ;
// add to the damage inflicted on a player this frame
// the total will be turned into screen blends and view angle kicks
// at the end of the frame
if ( health > 0 ) {
playerView . DamageImpulse ( localDamageVector , & damageDef - > dict ) ;
}
// do the damage
if ( damage > 0 ) {
if ( ! gameLocal . isMultiplayer ) {
float scale = g_damageScale . GetFloat ( ) ;
if ( g_useDynamicProtection . GetBool ( ) & & g_skill . GetInteger ( ) < 2 ) {
if ( gameLocal . time > lastDmgTime + 500 & & scale > 0.25f ) {
scale - = 0.05f ;
g_damageScale . SetFloat ( scale ) ;
}
}
if ( scale > 0.0f ) {
damage * = scale ;
}
}
if ( damage < 1 ) {
damage = 1 ;
}
health - = damage ;
if ( health < = 0 ) {
if ( health < - 999 ) {
health = - 999 ;
}
isTelefragged = damageDef - > dict . GetBool ( " telefrag " ) ;
lastDmgTime = gameLocal . time ;
Killed ( inflictor , attacker , damage , dir , location ) ;
} else {
// force a blink
blink_time = 0 ;
// let the anim script know we took damage
AI_PAIN = Pain ( inflictor , attacker , damage , dir , location ) ;
if ( ! g_testDeath . GetBool ( ) ) {
lastDmgTime = gameLocal . time ;
}
}
} else {
// don't accumulate impulses
if ( af . IsLoaded ( ) ) {
// clear impacts
af . Rest ( ) ;
// physics is turned off by calling af.Rest()
BecomeActive ( TH_PHYSICS ) ;
}
}
lastDamageDef = damageDef - > Index ( ) ;
lastDamageDir = damage_from ;
lastDamageLocation = location ;
}
/*
= = = = = = = = = = =
idPlayer : : Teleport
= = = = = = = = = = = =
*/
void idPlayer : : Teleport ( const idVec3 & origin , const idAngles & angles , idEntity * destination ) {
idVec3 org ;
if ( weapon . GetEntity ( ) ) {
weapon . GetEntity ( ) - > LowerWeapon ( ) ;
}
SetOrigin ( origin + idVec3 ( 0 , 0 , CM_CLIP_EPSILON ) ) ;
if ( ! gameLocal . isMultiplayer & & GetFloorPos ( 16.0f , org ) ) {
SetOrigin ( org ) ;
}
// clear the ik heights so model doesn't appear in the wrong place
walkIK . EnableAll ( ) ;
GetPhysics ( ) - > SetLinearVelocity ( vec3_origin ) ;
SetViewAngles ( angles ) ;
legsYaw = 0.0f ;
idealLegsYaw = 0.0f ;
oldViewYaw = viewAngles . yaw ;
if ( gameLocal . isMultiplayer ) {
playerView . Flash ( colorWhite , 140 ) ;
}
UpdateVisuals ( ) ;
teleportEntity = destination ;
if ( ! gameLocal . isClient & & ! noclip ) {
if ( gameLocal . isMultiplayer ) {
// kill anything at the new position or mark for kill depending on immediate or delayed teleport
gameLocal . KillBox ( this , destination ! = NULL ) ;
} else {
// kill anything at the new position
gameLocal . KillBox ( this , true ) ;
}
}
}
/*
= = = = = = = = = = = = = = = = = = = =
idPlayer : : SetPrivateCameraView
= = = = = = = = = = = = = = = = = = = =
*/
void idPlayer : : SetPrivateCameraView ( idCamera * camView ) {
privateCameraView = camView ;
if ( camView ) {
StopFiring ( ) ;
Hide ( ) ;
} else {
if ( ! spectating ) {
Show ( ) ;
}
}
}
/*
= = = = = = = = = = = = = = = = = = = =
idPlayer : : DefaultFov
Returns the base FOV
= = = = = = = = = = = = = = = = = = = =
*/
float idPlayer : : DefaultFov ( void ) const {
float fov ;
fov = g_fov . GetFloat ( ) ;
if ( gameLocal . isMultiplayer ) {
if ( fov < 90.0f ) {
return 90.0f ;
} else if ( fov > 110.0f ) {
return 110.0f ;
}
}
return fov ;
}
/*
= = = = = = = = = = = = = = = = = = = =
idPlayer : : CalcFov
Fixed fov at intermissions , otherwise account for fov variable and zooms .
= = = = = = = = = = = = = = = = = = = =
*/
float idPlayer : : CalcFov ( bool honorZoom ) {
float fov ;
if ( fxFov ) {
return DefaultFov ( ) + 10.0f + cos ( ( gameLocal . time + 2000 ) * 0.01 ) * 10.0f ;
}
if ( influenceFov ) {
return influenceFov ;
}
2018-08-26 03:41:08 +00:00
# ifdef _DENTONMOD_PLAYER_CPP
if ( zoomFov . IsDone ( gameLocal . time ) ) {
fov = ( honorZoom & & ( ( usercmd . buttons & BUTTON_ZOOM ) | | weaponZoom . startZoom ) ) & & weapon . GetEntity ( ) ? weapon . GetEntity ( ) - > GetZoomFov ( ) : DefaultFov ( ) ; // Updated By Clone JCD
# else
2011-11-22 21:28:15 +00:00
if ( zoomFov . IsDone ( gameLocal . time ) ) {
2018-08-26 03:41:08 +00:00
fov = ( honorZoom & & ( usercmd . buttons & BUTTON_ZOOM ) ) & & weapon . GetEntity ( ) ? weapon . GetEntity ( ) - > GetZoomFov ( ) : DefaultFov ( ) ; // Updated By Clone JCD
# endif // _DENTONMOD_PLAYER_CPP
2011-11-22 21:28:15 +00:00
} else {
fov = zoomFov . GetCurrentValue ( gameLocal . time ) ;
}
// bound normal viewsize
if ( fov < 1 ) {
fov = 1 ;
} else if ( fov > 179 ) {
fov = 179 ;
}
return fov ;
}
/*
= = = = = = = = = = = = = =
idPlayer : : GunTurningOffset
generate a rotational offset for the gun based on the view angle
history in loggedViewAngles
= = = = = = = = = = = = = =
*/
idAngles idPlayer : : GunTurningOffset ( void ) {
idAngles a ;
a . Zero ( ) ;
if ( gameLocal . framenum < NUM_LOGGED_VIEW_ANGLES ) {
return a ;
}
idAngles current = loggedViewAngles [ gameLocal . framenum & ( NUM_LOGGED_VIEW_ANGLES - 1 ) ] ;
idAngles av , base ;
int weaponAngleOffsetAverages ;
float weaponAngleOffsetScale , weaponAngleOffsetMax ;
weapon . GetEntity ( ) - > GetWeaponAngleOffsets ( & weaponAngleOffsetAverages , & weaponAngleOffsetScale , & weaponAngleOffsetMax ) ;
av = current ;
// calcualte this so the wrap arounds work properly
for ( int j = 1 ; j < weaponAngleOffsetAverages ; j + + ) {
idAngles a2 = loggedViewAngles [ ( gameLocal . framenum - j ) & ( NUM_LOGGED_VIEW_ANGLES - 1 ) ] ;
idAngles delta = a2 - current ;
if ( delta [ 1 ] > 180 ) {
delta [ 1 ] - = 360 ;
} else if ( delta [ 1 ] < - 180 ) {
delta [ 1 ] + = 360 ;
}
av + = delta * ( 1.0f / weaponAngleOffsetAverages ) ;
}
a = ( av - current ) * weaponAngleOffsetScale ;
for ( int i = 0 ; i < 3 ; i + + ) {
if ( a [ i ] < - weaponAngleOffsetMax ) {
a [ i ] = - weaponAngleOffsetMax ;
} else if ( a [ i ] > weaponAngleOffsetMax ) {
a [ i ] = weaponAngleOffsetMax ;
}
}
return a ;
}
/*
= = = = = = = = = = = = = =
idPlayer : : GunAcceleratingOffset
generate a positional offset for the gun based on the movement
history in loggedAccelerations
= = = = = = = = = = = = = =
*/
idVec3 idPlayer : : GunAcceleratingOffset ( void ) {
idVec3 ofs ;
float weaponOffsetTime , weaponOffsetScale ;
ofs . Zero ( ) ;
weapon . GetEntity ( ) - > GetWeaponTimeOffsets ( & weaponOffsetTime , & weaponOffsetScale ) ;
int stop = currentLoggedAccel - NUM_LOGGED_ACCELS ;
if ( stop < 0 ) {
stop = 0 ;
}
for ( int i = currentLoggedAccel - 1 ; i > stop ; i - - ) {
loggedAccel_t * acc = & loggedAccel [ i & ( NUM_LOGGED_ACCELS - 1 ) ] ;
float f ;
float t = gameLocal . time - acc - > time ;
if ( t > = weaponOffsetTime ) {
break ; // remainder are too old to care about
}
f = t / weaponOffsetTime ;
f = ( cos ( f * 2.0f * idMath : : PI ) - 1.0f ) * 0.5f ;
ofs + = f * weaponOffsetScale * acc - > dir ;
}
return ofs ;
}
/*
= = = = = = = = = = = = = =
idPlayer : : CalculateViewWeaponPos
Calculate the bobbing position of the view weapon
= = = = = = = = = = = = = =
*/
void idPlayer : : CalculateViewWeaponPos ( idVec3 & origin , idMat3 & axis ) {
float scale ;
float fracsin ;
idAngles angles ;
int delta ;
// CalculateRenderView must have been called first
const idVec3 & viewOrigin = firstPersonViewOrigin ;
const idMat3 & viewAxis = firstPersonViewAxis ;
// these cvars are just for hand tweaking before moving a value to the weapon def
idVec3 gunpos ( g_gun_x . GetFloat ( ) , g_gun_y . GetFloat ( ) , g_gun_z . GetFloat ( ) ) ;
// as the player changes direction, the gun will take a small lag
idVec3 gunOfs = GunAcceleratingOffset ( ) ;
origin = viewOrigin + ( gunpos + gunOfs ) * viewAxis ;
// on odd legs, invert some angles
if ( bobCycle & 128 ) {
scale = - xyspeed ;
} else {
scale = xyspeed ;
}
// gun angles from bobbing
angles . roll = scale * bobfracsin * 0.005f ;
angles . yaw = scale * bobfracsin * 0.01f ;
angles . pitch = xyspeed * bobfracsin * 0.005f ;
// gun angles from turning
if ( gameLocal . isMultiplayer ) {
idAngles offset = GunTurningOffset ( ) ;
offset * = g_mpWeaponAngleScale . GetFloat ( ) ;
angles + = offset ;
} else {
angles + = GunTurningOffset ( ) ;
}
idVec3 gravity = physicsObj . GetGravityNormal ( ) ;
// drop the weapon when landing after a jump / fall
delta = gameLocal . time - landTime ;
if ( delta < LAND_DEFLECT_TIME ) {
origin - = gravity * ( landChange * 0.25f * delta / LAND_DEFLECT_TIME ) ;
} else if ( delta < LAND_DEFLECT_TIME + LAND_RETURN_TIME ) {
origin - = gravity * ( landChange * 0.25f * ( LAND_DEFLECT_TIME + LAND_RETURN_TIME - delta ) / LAND_RETURN_TIME ) ;
}
// speed sensitive idle drift
scale = xyspeed + 40.0f ;
fracsin = scale * sin ( MS2SEC ( gameLocal . time ) ) * 0.01f ;
angles . roll + = fracsin ;
angles . yaw + = fracsin ;
angles . pitch + = fracsin ;
axis = angles . ToMat3 ( ) * viewAxis ;
}
/*
= = = = = = = = = = = = = = =
idPlayer : : OffsetThirdPersonView
= = = = = = = = = = = = = = =
*/
void idPlayer : : OffsetThirdPersonView ( float angle , float range , float height , bool clip ) {
idVec3 view ;
idVec3 focusAngles ;
trace_t trace ;
idVec3 focusPoint ;
float focusDist ;
float forwardScale , sideScale ;
idVec3 origin ;
idAngles angles ;
idMat3 axis ;
idBounds bounds ;
angles = viewAngles ;
GetViewPos ( origin , axis ) ;
if ( angle ) {
angles . pitch = 0.0f ;
}
if ( angles . pitch > 45.0f ) {
angles . pitch = 45.0f ; // don't go too far overhead
}
focusPoint = origin + angles . ToForward ( ) * THIRD_PERSON_FOCUS_DISTANCE ;
focusPoint . z + = height ;
view = origin ;
view . z + = 8 + height ;
angles . pitch * = 0.5f ;
renderView - > viewaxis = angles . ToMat3 ( ) * physicsObj . GetGravityAxis ( ) ;
idMath : : SinCos ( DEG2RAD ( angle ) , sideScale , forwardScale ) ;
view - = range * forwardScale * renderView - > viewaxis [ 0 ] ;
view + = range * sideScale * renderView - > viewaxis [ 1 ] ;
if ( clip ) {
// trace a ray from the origin to the viewpoint to make sure the view isn't
// in a solid block. Use an 8 by 8 block to prevent the view from near clipping anything
bounds = idBounds ( idVec3 ( - 4 , - 4 , - 4 ) , idVec3 ( 4 , 4 , 4 ) ) ;
gameLocal . clip . TraceBounds ( trace , origin , view , bounds , MASK_SOLID , this ) ;
if ( trace . fraction ! = 1.0f ) {
view = trace . endpos ;
view . z + = ( 1.0f - trace . fraction ) * 32.0f ;
// try another trace to this position, because a tunnel may have the ceiling
// close enough that this is poking out
gameLocal . clip . TraceBounds ( trace , origin , view , bounds , MASK_SOLID , this ) ;
view = trace . endpos ;
}
}
// select pitch to look at focus point from vieword
focusPoint - = view ;
focusDist = idMath : : Sqrt ( focusPoint [ 0 ] * focusPoint [ 0 ] + focusPoint [ 1 ] * focusPoint [ 1 ] ) ;
if ( focusDist < 1.0f ) {
focusDist = 1.0f ; // should never happen
}
angles . pitch = - RAD2DEG ( atan2 ( focusPoint . z , focusDist ) ) ;
angles . yaw - = angle ;
renderView - > vieworg = view ;
renderView - > viewaxis = angles . ToMat3 ( ) * physicsObj . GetGravityAxis ( ) ;
renderView - > viewID = 0 ;
}
/*
= = = = = = = = = = = = = = =
idPlayer : : GetEyePosition
= = = = = = = = = = = = = = =
*/
idVec3 idPlayer : : GetEyePosition ( void ) const {
idVec3 org ;
2011-12-06 18:20:15 +00:00
2011-11-22 21:28:15 +00:00
// use the smoothed origin if spectating another player in multiplayer
if ( gameLocal . isClient & & entityNumber ! = gameLocal . localClientNum ) {
org = smoothedOrigin ;
} else {
org = GetPhysics ( ) - > GetOrigin ( ) ;
}
return org + ( GetPhysics ( ) - > GetGravityNormal ( ) * - eyeOffset . z ) ;
}
/*
= = = = = = = = = = = = = = =
idPlayer : : GetViewPos
= = = = = = = = = = = = = = =
*/
void idPlayer : : GetViewPos ( idVec3 & origin , idMat3 & axis ) const {
idAngles angles ;
// if dead, fix the angle and don't add any kick
if ( health < = 0 ) {
angles . yaw = viewAngles . yaw ;
angles . roll = 40 ;
angles . pitch = - 15 ;
axis = angles . ToMat3 ( ) ;
origin = GetEyePosition ( ) ;
} else {
origin = GetEyePosition ( ) + viewBob ;
angles = viewAngles + viewBobAngles + playerView . AngleOffset ( ) ;
axis = angles . ToMat3 ( ) * physicsObj . GetGravityAxis ( ) ;
// adjust the origin based on the camera nodal distance (eye distance from neck)
origin + = physicsObj . GetGravityNormal ( ) * g_viewNodalZ . GetFloat ( ) ;
origin + = axis [ 0 ] * g_viewNodalX . GetFloat ( ) + axis [ 2 ] * g_viewNodalZ . GetFloat ( ) ;
}
}
/*
= = = = = = = = = = = = = = =
idPlayer : : CalculateFirstPersonView
= = = = = = = = = = = = = = =
*/
void idPlayer : : CalculateFirstPersonView ( void ) {
if ( ( pm_modelView . GetInteger ( ) = = 1 ) | | ( ( pm_modelView . GetInteger ( ) = = 2 ) & & ( health < = 0 ) ) ) {
// Displays the view from the point of view of the "camera" joint in the player model
idMat3 axis ;
idVec3 origin ;
idAngles ang ;
ang = viewBobAngles + playerView . AngleOffset ( ) ;
ang . yaw + = viewAxis [ 0 ] . ToYaw ( ) ;
2011-12-06 18:20:15 +00:00
2011-11-22 21:28:15 +00:00
jointHandle_t joint = animator . GetJointHandle ( " camera " ) ;
animator . GetJointTransform ( joint , gameLocal . time , origin , axis ) ;
firstPersonViewOrigin = ( origin + modelOffset ) * ( viewAxis * physicsObj . GetGravityAxis ( ) ) + physicsObj . GetOrigin ( ) + viewBob ;
firstPersonViewAxis = axis * ang . ToMat3 ( ) * physicsObj . GetGravityAxis ( ) ;
} else {
// offset for local bobbing and kicks
GetViewPos ( firstPersonViewOrigin , firstPersonViewAxis ) ;
#if 0
// shakefrom sound stuff only happens in first person
firstPersonViewAxis = firstPersonViewAxis * playerView . ShakeAxis ( ) ;
# endif
}
}
/*
= = = = = = = = = = = = = = = = = =
idPlayer : : GetRenderView
Returns the renderView that was calculated for this tic
= = = = = = = = = = = = = = = = = =
*/
renderView_t * idPlayer : : GetRenderView ( void ) {
return renderView ;
}
/*
= = = = = = = = = = = = = = = = = =
idPlayer : : CalculateRenderView
create the renderView for the current tic
= = = = = = = = = = = = = = = = = =
*/
void idPlayer : : CalculateRenderView ( void ) {
int i ;
float range ;
if ( ! renderView ) {
renderView = new renderView_t ;
}
memset ( renderView , 0 , sizeof ( * renderView ) ) ;
// copy global shader parms
for ( i = 0 ; i < MAX_GLOBAL_SHADER_PARMS ; i + + ) {
renderView - > shaderParms [ i ] = gameLocal . globalShaderParms [ i ] ;
}
renderView - > globalMaterial = gameLocal . GetGlobalMaterial ( ) ;
renderView - > time = gameLocal . time ;
// calculate size of 3D view
renderView - > x = 0 ;
renderView - > y = 0 ;
renderView - > width = SCREEN_WIDTH ;
renderView - > height = SCREEN_HEIGHT ;
renderView - > viewID = 0 ;
// check if we should be drawing from a camera's POV
if ( ! noclip & & ( gameLocal . GetCamera ( ) | | privateCameraView ) ) {
// get origin, axis, and fov
if ( privateCameraView ) {
privateCameraView - > GetViewParms ( renderView ) ;
} else {
gameLocal . GetCamera ( ) - > GetViewParms ( renderView ) ;
}
} else {
if ( g_stopTime . GetBool ( ) ) {
renderView - > vieworg = firstPersonViewOrigin ;
renderView - > viewaxis = firstPersonViewAxis ;
if ( ! pm_thirdPerson . GetBool ( ) ) {
// set the viewID to the clientNum + 1, so we can suppress the right player bodies and
// allow the right player view weapons
renderView - > viewID = entityNumber + 1 ;
}
} else if ( pm_thirdPerson . GetBool ( ) ) {
OffsetThirdPersonView ( pm_thirdPersonAngle . GetFloat ( ) , pm_thirdPersonRange . GetFloat ( ) , pm_thirdPersonHeight . GetFloat ( ) , pm_thirdPersonClip . GetBool ( ) ) ;
} else if ( pm_thirdPersonDeath . GetBool ( ) ) {
range = gameLocal . time < minRespawnTime ? ( gameLocal . time + RAGDOLL_DEATH_TIME - minRespawnTime ) * ( 120.0f / RAGDOLL_DEATH_TIME ) : 120.0f ;
OffsetThirdPersonView ( 0.0f , 20.0f + range , 0.0f , false ) ;
} else {
renderView - > vieworg = firstPersonViewOrigin ;
renderView - > viewaxis = firstPersonViewAxis ;
// set the viewID to the clientNum + 1, so we can suppress the right player bodies and
// allow the right player view weapons
renderView - > viewID = entityNumber + 1 ;
}
2011-12-06 18:20:15 +00:00
2011-11-22 21:28:15 +00:00
// field of view
gameLocal . CalcFov ( CalcFov ( true ) , renderView - > fov_x , renderView - > fov_y ) ;
}
if ( renderView - > fov_y = = 0 ) {
common - > Error ( " renderView->fov_y == 0 " ) ;
}
if ( g_showviewpos . GetBool ( ) ) {
gameLocal . Printf ( " %s : %s \n " , renderView - > vieworg . ToString ( ) , renderView - > viewaxis . ToAngles ( ) . ToString ( ) ) ;
}
}
/*
= = = = = = = = = = = = =
idPlayer : : AddAIKill
= = = = = = = = = = = = =
*/
void idPlayer : : AddAIKill ( void ) {
int max_souls ;
int ammo_souls ;
if ( ( weapon_soulcube < 0 ) | | ( inventory . weapons & ( 1 < < weapon_soulcube ) ) = = 0 ) {
return ;
}
assert ( hud ) ;
ammo_souls = idWeapon : : GetAmmoNumForName ( " ammo_souls " ) ;
max_souls = inventory . MaxAmmoForAmmoClass ( this , " ammo_souls " ) ;
if ( inventory . ammo [ ammo_souls ] < max_souls ) {
inventory . ammo [ ammo_souls ] + + ;
if ( inventory . ammo [ ammo_souls ] > = max_souls ) {
hud - > HandleNamedEvent ( " soulCubeReady " ) ;
StartSound ( " snd_soulcube_ready " , SND_CHANNEL_ANY , 0 , false , NULL ) ;
}
}
}
/*
= = = = = = = = = = = = =
idPlayer : : SetSoulCubeProjectile
= = = = = = = = = = = = =
*/
void idPlayer : : SetSoulCubeProjectile ( idProjectile * projectile ) {
soulCubeProjectile = projectile ;
}
/*
= = = = = = = = = = = = =
idPlayer : : AddProjectilesFired
= = = = = = = = = = = = =
*/
void idPlayer : : AddProjectilesFired ( int count ) {
numProjectilesFired + = count ;
}
/*
= = = = = = = = = = = = =
idPlayer : : AddProjectileHites
= = = = = = = = = = = = =
*/
void idPlayer : : AddProjectileHits ( int count ) {
numProjectileHits + = count ;
}
/*
= = = = = = = = = = = = =
idPlayer : : SetLastHitTime
= = = = = = = = = = = = =
*/
void idPlayer : : SetLastHitTime ( int time ) {
idPlayer * aimed = NULL ;
if ( time & & lastHitTime ! = time ) {
lastHitToggle ^ = 1 ;
}
lastHitTime = time ;
if ( ! time ) {
// level start and inits
return ;
}
if ( gameLocal . isMultiplayer & & ( time - lastSndHitTime ) > 10 ) {
lastSndHitTime = time ;
StartSound ( " snd_hit_feedback " , SND_CHANNEL_ANY , SSF_PRIVATE_SOUND , false , NULL ) ;
}
if ( cursor ) {
cursor - > HandleNamedEvent ( " hitTime " ) ;
}
if ( hud ) {
if ( MPAim ! = - 1 ) {
if ( gameLocal . entities [ MPAim ] & & gameLocal . entities [ MPAim ] - > IsType ( idPlayer : : Type ) ) {
aimed = static_cast < idPlayer * > ( gameLocal . entities [ MPAim ] ) ;
}
assert ( aimed ) ;
// full highlight, no fade till loosing aim
hud - > SetStateString ( " aim_text " , gameLocal . userInfo [ MPAim ] . GetString ( " ui_name " ) ) ;
if ( aimed ) {
hud - > SetStateFloat ( " aim_color " , aimed - > colorBarIndex ) ;
}
hud - > HandleNamedEvent ( " aim_flash " ) ;
MPAimHighlight = true ;
MPAimFadeTime = 0 ;
} else if ( lastMPAim ! = - 1 ) {
if ( gameLocal . entities [ lastMPAim ] & & gameLocal . entities [ lastMPAim ] - > IsType ( idPlayer : : Type ) ) {
aimed = static_cast < idPlayer * > ( gameLocal . entities [ lastMPAim ] ) ;
}
assert ( aimed ) ;
// start fading right away
hud - > SetStateString ( " aim_text " , gameLocal . userInfo [ lastMPAim ] . GetString ( " ui_name " ) ) ;
if ( aimed ) {
hud - > SetStateFloat ( " aim_color " , aimed - > colorBarIndex ) ;
}
hud - > HandleNamedEvent ( " aim_flash " ) ;
hud - > HandleNamedEvent ( " aim_fade " ) ;
MPAimHighlight = false ;
MPAimFadeTime = gameLocal . realClientTime ;
}
}
}
/*
= = = = = = = = = = = = =
idPlayer : : SetInfluenceLevel
= = = = = = = = = = = = =
*/
void idPlayer : : SetInfluenceLevel ( int level ) {
if ( level ! = influenceActive ) {
if ( level ) {
for ( idEntity * ent = gameLocal . spawnedEntities . Next ( ) ; ent ! = NULL ; ent = ent - > spawnNode . Next ( ) ) {
if ( ent - > IsType ( idProjectile : : Type ) ) {
// remove all projectiles
ent - > PostEventMS ( & EV_Remove , 0 ) ;
}
}
if ( weaponEnabled & & weapon . GetEntity ( ) ) {
weapon . GetEntity ( ) - > EnterCinematic ( ) ;
}
} else {
physicsObj . SetLinearVelocity ( vec3_origin ) ;
if ( weaponEnabled & & weapon . GetEntity ( ) ) {
weapon . GetEntity ( ) - > ExitCinematic ( ) ;
}
}
influenceActive = level ;
}
}
/*
= = = = = = = = = = = = =
idPlayer : : SetInfluenceView
= = = = = = = = = = = = =
*/
void idPlayer : : SetInfluenceView ( const char * mtr , const char * skinname , float radius , idEntity * ent ) {
influenceMaterial = NULL ;
influenceEntity = NULL ;
influenceSkin = NULL ;
if ( mtr & & * mtr ) {
influenceMaterial = declManager - > FindMaterial ( mtr ) ;
}
if ( skinname & & * skinname ) {
influenceSkin = declManager - > FindSkin ( skinname ) ;
if ( head . GetEntity ( ) ) {
head . GetEntity ( ) - > GetRenderEntity ( ) - > shaderParms [ SHADERPARM_TIMEOFFSET ] = - MS2SEC ( gameLocal . time ) ;
}
UpdateVisuals ( ) ;
}
influenceRadius = radius ;
if ( radius > 0.0f ) {
influenceEntity = ent ;
}
}
/*
= = = = = = = = = = = = =
idPlayer : : SetInfluenceFov
= = = = = = = = = = = = =
*/
void idPlayer : : SetInfluenceFov ( float fov ) {
influenceFov = fov ;
}
/*
= = = = = = = = = = = = = = = =
idPlayer : : OnLadder
= = = = = = = = = = = = = = = =
*/
bool idPlayer : : OnLadder ( void ) const {
return physicsObj . OnLadder ( ) ;
}
/*
= = = = = = = = = = = = = = = = = =
idPlayer : : Event_GetButtons
= = = = = = = = = = = = = = = = = =
*/
void idPlayer : : Event_GetButtons ( void ) {
idThread : : ReturnInt ( usercmd . buttons ) ;
}
/*
= = = = = = = = = = = = = = = = = =
idPlayer : : Event_GetMove
= = = = = = = = = = = = = = = = = =
*/
void idPlayer : : Event_GetMove ( void ) {
idVec3 move ( usercmd . forwardmove , usercmd . rightmove , usercmd . upmove ) ;
idThread : : ReturnVector ( move ) ;
}
/*
= = = = = = = = = = = = = = = =
idPlayer : : Event_GetViewAngles
= = = = = = = = = = = = = = = =
*/
void idPlayer : : Event_GetViewAngles ( void ) {
idThread : : ReturnVector ( idVec3 ( viewAngles [ 0 ] , viewAngles [ 1 ] , viewAngles [ 2 ] ) ) ;
}
/*
= = = = = = = = = = = = = = = = = =
idPlayer : : Event_StopFxFov
= = = = = = = = = = = = = = = = = =
*/
void idPlayer : : Event_StopFxFov ( void ) {
fxFov = false ;
}
/*
= = = = = = = = = = = = = = = = = =
2011-12-06 18:20:15 +00:00
idPlayer : : StartFxFov
2011-11-22 21:28:15 +00:00
= = = = = = = = = = = = = = = = = =
*/
2011-12-06 18:20:15 +00:00
void idPlayer : : StartFxFov ( float duration ) {
2011-11-22 21:28:15 +00:00
fxFov = true ;
PostEventSec ( & EV_Player_StopFxFov , duration ) ;
}
/*
= = = = = = = = = = = = = = = = = =
2011-12-06 18:20:15 +00:00
idPlayer : : Event_EnableWeapon
2011-11-22 21:28:15 +00:00
= = = = = = = = = = = = = = = = = =
*/
void idPlayer : : Event_EnableWeapon ( void ) {
hiddenWeapon = gameLocal . world - > spawnArgs . GetBool ( " no_Weapons " ) ;
weaponEnabled = true ;
if ( weapon . GetEntity ( ) ) {
weapon . GetEntity ( ) - > ExitCinematic ( ) ;
}
}
/*
= = = = = = = = = = = = = = = = = =
idPlayer : : Event_DisableWeapon
= = = = = = = = = = = = = = = = = =
*/
void idPlayer : : Event_DisableWeapon ( void ) {
hiddenWeapon = gameLocal . world - > spawnArgs . GetBool ( " no_Weapons " ) ;
weaponEnabled = false ;
if ( weapon . GetEntity ( ) ) {
weapon . GetEntity ( ) - > EnterCinematic ( ) ;
}
}
/*
= = = = = = = = = = = = = = = = = =
idPlayer : : Event_GetCurrentWeapon
= = = = = = = = = = = = = = = = = =
*/
void idPlayer : : Event_GetCurrentWeapon ( void ) {
const char * weapon ;
if ( currentWeapon > = 0 ) {
weapon = spawnArgs . GetString ( va ( " def_weapon%d " , currentWeapon ) ) ;
idThread : : ReturnString ( weapon ) ;
} else {
idThread : : ReturnString ( " " ) ;
}
}
/*
= = = = = = = = = = = = = = = = = =
idPlayer : : Event_GetPreviousWeapon
= = = = = = = = = = = = = = = = = =
*/
void idPlayer : : Event_GetPreviousWeapon ( void ) {
const char * weapon ;
if ( previousWeapon > = 0 ) {
int pw = ( gameLocal . world - > spawnArgs . GetBool ( " no_Weapons " ) ) ? 0 : previousWeapon ;
weapon = spawnArgs . GetString ( va ( " def_weapon%d " , pw ) ) ;
idThread : : ReturnString ( weapon ) ;
} else {
idThread : : ReturnString ( spawnArgs . GetString ( " def_weapon0 " ) ) ;
}
}
/*
= = = = = = = = = = = = = = = = = =
idPlayer : : Event_SelectWeapon
= = = = = = = = = = = = = = = = = =
*/
void idPlayer : : Event_SelectWeapon ( const char * weaponName ) {
int i ;
int weaponNum ;
if ( gameLocal . isClient ) {
gameLocal . Warning ( " Cannot switch weapons from script in multiplayer " ) ;
return ;
}
if ( hiddenWeapon & & gameLocal . world - > spawnArgs . GetBool ( " no_Weapons " ) ) {
2018-08-26 03:41:08 +00:00
# ifdef _DENTONMOD
idealWeapon = quickWeapon = weapon_fists ;
# else
2011-11-22 21:28:15 +00:00
idealWeapon = weapon_fists ;
2018-08-26 03:41:08 +00:00
# endif
2011-11-22 21:28:15 +00:00
weapon . GetEntity ( ) - > HideWeapon ( ) ;
return ;
}
weaponNum = - 1 ;
for ( i = 0 ; i < MAX_WEAPONS ; i + + ) {
if ( inventory . weapons & ( 1 < < i ) ) {
const char * weap = spawnArgs . GetString ( va ( " def_weapon%d " , i ) ) ;
if ( ! idStr : : Cmp ( weap , weaponName ) ) {
weaponNum = i ;
break ;
}
}
}
if ( weaponNum < 0 ) {
gameLocal . Warning ( " %s is not carrying weapon '%s' " , name . c_str ( ) , weaponName ) ;
return ;
}
hiddenWeapon = false ;
2018-08-26 03:41:08 +00:00
# ifdef _DENTONMOD
if ( idealWeapon ! = weaponNum ) {
quickWeapon = idealWeapon ;
}
2011-11-22 21:28:15 +00:00
idealWeapon = weaponNum ;
2018-08-26 03:41:08 +00:00
# endif
2011-11-22 21:28:15 +00:00
UpdateHudWeapon ( ) ;
}
/*
= = = = = = = = = = = = = = = = = =
idPlayer : : Event_GetWeaponEntity
= = = = = = = = = = = = = = = = = =
*/
void idPlayer : : Event_GetWeaponEntity ( void ) {
idThread : : ReturnEntity ( weapon . GetEntity ( ) ) ;
}
/*
= = = = = = = = = = = = = = = = = =
idPlayer : : Event_OpenPDA
= = = = = = = = = = = = = = = = = =
*/
void idPlayer : : Event_OpenPDA ( void ) {
if ( ! gameLocal . isMultiplayer ) {
TogglePDA ( ) ;
}
}
/*
= = = = = = = = = = = = = = = = = =
idPlayer : : Event_InPDA
= = = = = = = = = = = = = = = = = =
*/
void idPlayer : : Event_InPDA ( void ) {
idThread : : ReturnInt ( objectiveSystemOpen ) ;
}
/*
= = = = = = = = = = = = = = = = = =
idPlayer : : TeleportDeath
= = = = = = = = = = = = = = = = = =
*/
void idPlayer : : TeleportDeath ( int killer ) {
teleportKiller = killer ;
}
/*
= = = = = = = = = = = = = = = = = =
idPlayer : : Event_ExitTeleporter
= = = = = = = = = = = = = = = = = =
*/
void idPlayer : : Event_ExitTeleporter ( void ) {
idEntity * exitEnt ;
float pushVel ;
// verify and setup
exitEnt = teleportEntity . GetEntity ( ) ;
if ( ! exitEnt ) {
common - > DPrintf ( " Event_ExitTeleporter player %d while not being teleported \n " , entityNumber ) ;
return ;
}
pushVel = exitEnt - > spawnArgs . GetFloat ( " push " , " 300 " ) ;
if ( gameLocal . isServer ) {
ServerSendEvent ( EVENT_EXIT_TELEPORTER , NULL , false , - 1 ) ;
}
SetPrivateCameraView ( NULL ) ;
// setup origin and push according to the exit target
SetOrigin ( exitEnt - > GetPhysics ( ) - > GetOrigin ( ) + idVec3 ( 0 , 0 , CM_CLIP_EPSILON ) ) ;
SetViewAngles ( exitEnt - > GetPhysics ( ) - > GetAxis ( ) . ToAngles ( ) ) ;
physicsObj . SetLinearVelocity ( exitEnt - > GetPhysics ( ) - > GetAxis ( ) [ 0 ] * pushVel ) ;
physicsObj . ClearPushedVelocity ( ) ;
// teleport fx
playerView . Flash ( colorWhite , 120 ) ;
// clear the ik heights so model doesn't appear in the wrong place
walkIK . EnableAll ( ) ;
UpdateVisuals ( ) ;
StartSound ( " snd_teleport_exit " , SND_CHANNEL_ANY , 0 , false , NULL ) ;
if ( teleportKiller ! = - 1 ) {
// we got killed while being teleported
Damage ( gameLocal . entities [ teleportKiller ] , gameLocal . entities [ teleportKiller ] , vec3_origin , " damage_telefrag " , 1.0f , INVALID_JOINT ) ;
teleportKiller = - 1 ;
} else {
// kill anything that would have waited at teleport exit
gameLocal . KillBox ( this ) ;
}
teleportEntity = NULL ;
}
/*
= = = = = = = = = = = = = = = =
idPlayer : : ClientPredictionThink
= = = = = = = = = = = = = = = =
*/
void idPlayer : : ClientPredictionThink ( void ) {
renderEntity_t * headRenderEnt ;
oldFlags = usercmd . flags ;
oldButtons = usercmd . buttons ;
usercmd = gameLocal . usercmds [ entityNumber ] ;
if ( entityNumber ! = gameLocal . localClientNum ) {
// ignore attack button of other clients. that's no good for predictions
usercmd . buttons & = ~ BUTTON_ATTACK ;
}
buttonMask & = usercmd . buttons ;
usercmd . buttons & = ~ buttonMask ;
if ( objectiveSystemOpen ) {
usercmd . forwardmove = 0 ;
usercmd . rightmove = 0 ;
usercmd . upmove = 0 ;
}
// clear the ik before we do anything else so the skeleton doesn't get updated twice
walkIK . ClearJointMods ( ) ;
if ( gameLocal . isNewFrame ) {
if ( ( usercmd . flags & UCF_IMPULSE_SEQUENCE ) ! = ( oldFlags & UCF_IMPULSE_SEQUENCE ) ) {
PerformImpulse ( usercmd . impulse ) ;
}
}
scoreBoardOpen = ( ( usercmd . buttons & BUTTON_SCORES ) ! = 0 | | forceScoreBoard ) ;
AdjustSpeed ( ) ;
UpdateViewAngles ( ) ;
// update the smoothed view angles
if ( gameLocal . framenum > = smoothedFrame & & entityNumber ! = gameLocal . localClientNum ) {
idAngles anglesDiff = viewAngles - smoothedAngles ;
anglesDiff . Normalize180 ( ) ;
if ( idMath : : Fabs ( anglesDiff . yaw ) < 90.0f & & idMath : : Fabs ( anglesDiff . pitch ) < 90.0f ) {
// smoothen by pushing back to the previous angles
viewAngles - = gameLocal . clientSmoothing * anglesDiff ;
viewAngles . Normalize180 ( ) ;
}
smoothedAngles = viewAngles ;
}
smoothedOriginUpdated = false ;
if ( ! af . IsActive ( ) ) {
AdjustBodyAngles ( ) ;
}
if ( ! isLagged ) {
// don't allow client to move when lagged
Move ( ) ;
2011-12-06 18:20:15 +00:00
}
2011-11-22 21:28:15 +00:00
// update GUIs, Items, and character interactions
UpdateFocus ( ) ;
// service animations
if ( ! spectating & & ! af . IsActive ( ) ) {
2011-12-06 18:20:15 +00:00
UpdateConditions ( ) ;
2011-11-22 21:28:15 +00:00
UpdateAnimState ( ) ;
CheckBlink ( ) ;
}
// clear out our pain flag so we can tell if we recieve any damage between now and the next time we think
AI_PAIN = false ;
// calculate the exact bobbed view position, which is used to
// position the view weapon, among other things
CalculateFirstPersonView ( ) ;
// this may use firstPersonView, or a thirdPerson / camera view
CalculateRenderView ( ) ;
if ( ! gameLocal . inCinematic & & weapon . GetEntity ( ) & & ( health > 0 ) & & ! ( gameLocal . isMultiplayer & & spectating ) ) {
UpdateWeapon ( ) ;
}
UpdateHud ( ) ;
if ( gameLocal . isNewFrame ) {
UpdatePowerUps ( ) ;
}
UpdateDeathSkin ( false ) ;
if ( head . GetEntity ( ) ) {
headRenderEnt = head . GetEntity ( ) - > GetRenderEntity ( ) ;
} else {
headRenderEnt = NULL ;
}
if ( headRenderEnt ) {
if ( influenceSkin ) {
headRenderEnt - > customSkin = influenceSkin ;
} else {
headRenderEnt - > customSkin = NULL ;
}
}
if ( gameLocal . isMultiplayer | | g_showPlayerShadow . GetBool ( ) ) {
renderEntity . suppressShadowInViewID = 0 ;
if ( headRenderEnt ) {
headRenderEnt - > suppressShadowInViewID = 0 ;
}
} else {
renderEntity . suppressShadowInViewID = entityNumber + 1 ;
if ( headRenderEnt ) {
headRenderEnt - > suppressShadowInViewID = entityNumber + 1 ;
}
}
// never cast shadows from our first-person muzzle flashes
renderEntity . suppressShadowInLightID = LIGHTID_VIEW_MUZZLE_FLASH + entityNumber ;
if ( headRenderEnt ) {
headRenderEnt - > suppressShadowInLightID = LIGHTID_VIEW_MUZZLE_FLASH + entityNumber ;
}
if ( ! gameLocal . inCinematic ) {
UpdateAnimation ( ) ;
}
if ( gameLocal . isMultiplayer ) {
DrawPlayerIcons ( ) ;
}
Present ( ) ;
UpdateDamageEffects ( ) ;
LinkCombat ( ) ;
if ( gameLocal . isNewFrame & & entityNumber = = gameLocal . localClientNum ) {
playerView . CalculateShake ( ) ;
}
2018-08-26 03:41:08 +00:00
# ifdef _PORTALSKY
// determine if portal sky is in pvs
pvsHandle_t clientPVS = gameLocal . pvs . SetupCurrentPVS ( GetPVSAreas ( ) , GetNumPVSAreas ( ) ) ;
gameLocal . portalSkyActive = gameLocal . pvs . CheckAreasForPortalSky ( clientPVS , GetPhysics ( ) - > GetOrigin ( ) ) ;
gameLocal . pvs . FreeCurrentPVS ( clientPVS ) ;
# endif
2011-11-22 21:28:15 +00:00
}
/*
= = = = = = = = = = = = = = = =
idPlayer : : GetPhysicsToVisualTransform
= = = = = = = = = = = = = = = =
*/
bool idPlayer : : GetPhysicsToVisualTransform ( idVec3 & origin , idMat3 & axis ) {
if ( af . IsActive ( ) ) {
af . GetPhysicsToVisualTransform ( origin , axis ) ;
return true ;
}
// smoothen the rendered origin and angles of other clients
// smooth self origin if snapshots are telling us prediction is off
if ( gameLocal . isClient & & gameLocal . framenum > = smoothedFrame & & ( entityNumber ! = gameLocal . localClientNum | | selfSmooth ) ) {
// render origin and axis
idMat3 renderAxis = viewAxis * GetPhysics ( ) - > GetAxis ( ) ;
idVec3 renderOrigin = GetPhysics ( ) - > GetOrigin ( ) + modelOffset * renderAxis ;
// update the smoothed origin
if ( ! smoothedOriginUpdated ) {
idVec2 originDiff = renderOrigin . ToVec2 ( ) - smoothedOrigin . ToVec2 ( ) ;
if ( originDiff . LengthSqr ( ) < Square ( 100.0f ) ) {
// smoothen by pushing back to the previous position
if ( selfSmooth ) {
assert ( entityNumber = = gameLocal . localClientNum ) ;
renderOrigin . ToVec2 ( ) - = net_clientSelfSmoothing . GetFloat ( ) * originDiff ;
} else {
renderOrigin . ToVec2 ( ) - = gameLocal . clientSmoothing * originDiff ;
}
}
smoothedOrigin = renderOrigin ;
smoothedFrame = gameLocal . framenum ;
smoothedOriginUpdated = true ;
}
axis = idAngles ( 0.0f , smoothedAngles . yaw , 0.0f ) . ToMat3 ( ) ;
origin = ( smoothedOrigin - GetPhysics ( ) - > GetOrigin ( ) ) * axis . Transpose ( ) ;
} else {
axis = viewAxis ;
origin = modelOffset ;
}
return true ;
}
/*
= = = = = = = = = = = = = = = =
idPlayer : : GetPhysicsToSoundTransform
= = = = = = = = = = = = = = = =
*/
bool idPlayer : : GetPhysicsToSoundTransform ( idVec3 & origin , idMat3 & axis ) {
idCamera * camera ;
if ( privateCameraView ) {
camera = privateCameraView ;
} else {
camera = gameLocal . GetCamera ( ) ;
}
if ( camera ) {
renderView_t view ;
memset ( & view , 0 , sizeof ( view ) ) ;
camera - > GetViewParms ( & view ) ;
origin = view . vieworg ;
axis = view . viewaxis ;
return true ;
} else {
return idActor : : GetPhysicsToSoundTransform ( origin , axis ) ;
}
}
/*
= = = = = = = = = = = = = = = =
idPlayer : : WriteToSnapshot
= = = = = = = = = = = = = = = =
*/
void idPlayer : : WriteToSnapshot ( idBitMsgDelta & msg ) const {
physicsObj . WriteToSnapshot ( msg ) ;
WriteBindToSnapshot ( msg ) ;
msg . WriteDeltaFloat ( 0.0f , deltaViewAngles [ 0 ] ) ;
msg . WriteDeltaFloat ( 0.0f , deltaViewAngles [ 1 ] ) ;
msg . WriteDeltaFloat ( 0.0f , deltaViewAngles [ 2 ] ) ;
msg . WriteShort ( health ) ;
msg . WriteBits ( gameLocal . ServerRemapDecl ( - 1 , DECL_ENTITYDEF , lastDamageDef ) , gameLocal . entityDefBits ) ;
msg . WriteDir ( lastDamageDir , 9 ) ;
msg . WriteShort ( lastDamageLocation ) ;
msg . WriteBits ( idealWeapon , idMath : : BitsForInteger ( MAX_WEAPONS ) ) ;
msg . WriteBits ( inventory . weapons , MAX_WEAPONS ) ;
msg . WriteBits ( weapon . GetSpawnId ( ) , 32 ) ;
msg . WriteBits ( spectator , idMath : : BitsForInteger ( MAX_CLIENTS ) ) ;
msg . WriteBits ( lastHitToggle , 1 ) ;
msg . WriteBits ( weaponGone , 1 ) ;
msg . WriteBits ( isLagged , 1 ) ;
msg . WriteBits ( isChatting , 1 ) ;
}
/*
= = = = = = = = = = = = = = = =
idPlayer : : ReadFromSnapshot
= = = = = = = = = = = = = = = =
*/
void idPlayer : : ReadFromSnapshot ( const idBitMsgDelta & msg ) {
int i , oldHealth , newIdealWeapon , weaponSpawnId ;
bool newHitToggle , stateHitch ;
if ( snapshotSequence - lastSnapshotSequence > 1 ) {
stateHitch = true ;
} else {
stateHitch = false ;
}
lastSnapshotSequence = snapshotSequence ;
oldHealth = health ;
physicsObj . ReadFromSnapshot ( msg ) ;
ReadBindFromSnapshot ( msg ) ;
deltaViewAngles [ 0 ] = msg . ReadDeltaFloat ( 0.0f ) ;
deltaViewAngles [ 1 ] = msg . ReadDeltaFloat ( 0.0f ) ;
deltaViewAngles [ 2 ] = msg . ReadDeltaFloat ( 0.0f ) ;
health = msg . ReadShort ( ) ;
lastDamageDef = gameLocal . ClientRemapDecl ( DECL_ENTITYDEF , msg . ReadBits ( gameLocal . entityDefBits ) ) ;
lastDamageDir = msg . ReadDir ( 9 ) ;
lastDamageLocation = msg . ReadShort ( ) ;
newIdealWeapon = msg . ReadBits ( idMath : : BitsForInteger ( MAX_WEAPONS ) ) ;
inventory . weapons = msg . ReadBits ( MAX_WEAPONS ) ;
weaponSpawnId = msg . ReadBits ( 32 ) ;
spectator = msg . ReadBits ( idMath : : BitsForInteger ( MAX_CLIENTS ) ) ;
newHitToggle = msg . ReadBits ( 1 ) ! = 0 ;
weaponGone = msg . ReadBits ( 1 ) ! = 0 ;
isLagged = msg . ReadBits ( 1 ) ! = 0 ;
isChatting = msg . ReadBits ( 1 ) ! = 0 ;
// no msg reading below this
if ( weapon . SetSpawnId ( weaponSpawnId ) ) {
if ( weapon . GetEntity ( ) ) {
// maintain ownership locally
weapon . GetEntity ( ) - > SetOwner ( this ) ;
}
currentWeapon = - 1 ;
}
// if not a local client assume the client has all ammo types
if ( entityNumber ! = gameLocal . localClientNum ) {
for ( i = 0 ; i < AMMO_NUMTYPES ; i + + ) {
inventory . ammo [ i ] = 999 ;
}
}
if ( oldHealth > 0 & & health < = 0 ) {
if ( stateHitch ) {
// so we just hide and don't show a death skin
UpdateDeathSkin ( true ) ;
}
// die
AI_DEAD = true ;
ClearPowerUps ( ) ;
SetAnimState ( ANIMCHANNEL_LEGS , " Legs_Death " , 4 ) ;
SetAnimState ( ANIMCHANNEL_TORSO , " Torso_Death " , 4 ) ;
SetWaitState ( " " ) ;
animator . ClearAllJoints ( ) ;
if ( entityNumber = = gameLocal . localClientNum ) {
playerView . Fade ( colorBlack , 12000 ) ;
}
StartRagdoll ( ) ;
physicsObj . SetMovementType ( PM_DEAD ) ;
if ( ! stateHitch ) {
StartSound ( " snd_death " , SND_CHANNEL_VOICE , 0 , false , NULL ) ;
}
if ( weapon . GetEntity ( ) ) {
weapon . GetEntity ( ) - > OwnerDied ( ) ;
}
} else if ( oldHealth < = 0 & & health > 0 ) {
// respawn
Init ( ) ;
StopRagdoll ( ) ;
SetPhysics ( & physicsObj ) ;
physicsObj . EnableClip ( ) ;
SetCombatContents ( true ) ;
} else if ( health < oldHealth & & health > 0 ) {
if ( stateHitch ) {
lastDmgTime = gameLocal . time ;
} else {
// damage feedback
const idDeclEntityDef * def = static_cast < const idDeclEntityDef * > ( declManager - > DeclByIndex ( DECL_ENTITYDEF , lastDamageDef , false ) ) ;
if ( def ) {
playerView . DamageImpulse ( lastDamageDir * viewAxis . Transpose ( ) , & def - > dict ) ;
AI_PAIN = Pain ( NULL , NULL , oldHealth - health , lastDamageDir , lastDamageLocation ) ;
lastDmgTime = gameLocal . time ;
} else {
common - > Warning ( " NET: no damage def for damage feedback '%d' \n " , lastDamageDef ) ;
}
}
} else if ( health > oldHealth & & PowerUpActive ( MEGAHEALTH ) & & ! stateHitch ) {
// just pulse, for any health raise
healthPulse = true ;
}
// If the player is alive, restore proper physics object
if ( health > 0 & & IsActiveAF ( ) ) {
StopRagdoll ( ) ;
SetPhysics ( & physicsObj ) ;
physicsObj . EnableClip ( ) ;
SetCombatContents ( true ) ;
}
if ( idealWeapon ! = newIdealWeapon ) {
if ( stateHitch ) {
weaponCatchup = true ;
}
idealWeapon = newIdealWeapon ;
UpdateHudWeapon ( ) ;
}
if ( lastHitToggle ! = newHitToggle ) {
SetLastHitTime ( gameLocal . realClientTime ) ;
}
if ( msg . HasChanged ( ) ) {
UpdateVisuals ( ) ;
}
}
/*
= = = = = = = = = = = = = = = =
idPlayer : : WritePlayerStateToSnapshot
= = = = = = = = = = = = = = = =
*/
void idPlayer : : WritePlayerStateToSnapshot ( idBitMsgDelta & msg ) const {
int i ;
msg . WriteByte ( bobCycle ) ;
2012-06-28 11:15:40 +00:00
msg . WriteInt ( stepUpTime ) ;
2011-11-22 21:28:15 +00:00
msg . WriteFloat ( stepUpDelta ) ;
2018-08-26 03:41:08 +00:00
msg . WriteInt ( inventory . weapons ) ; //new
// msg.WriteShort( inventory.weapons );
2011-11-22 21:28:15 +00:00
msg . WriteByte ( inventory . armor ) ;
for ( i = 0 ; i < AMMO_NUMTYPES ; i + + ) {
msg . WriteBits ( inventory . ammo [ i ] , ASYNC_PLAYER_INV_AMMO_BITS ) ;
}
for ( i = 0 ; i < MAX_WEAPONS ; i + + ) {
msg . WriteBits ( inventory . clip [ i ] , ASYNC_PLAYER_INV_CLIP_BITS ) ;
}
}
/*
= = = = = = = = = = = = = = = =
idPlayer : : ReadPlayerStateFromSnapshot
= = = = = = = = = = = = = = = =
*/
void idPlayer : : ReadPlayerStateFromSnapshot ( const idBitMsgDelta & msg ) {
int i , ammo ;
bobCycle = msg . ReadByte ( ) ;
2012-06-28 11:19:14 +00:00
stepUpTime = msg . ReadInt ( ) ;
2011-11-22 21:28:15 +00:00
stepUpDelta = msg . ReadFloat ( ) ;
2018-08-26 03:41:08 +00:00
inventory . weapons = msg . ReadInt ( ) ; //new
// inventory.weapons = msg.ReadShort();
2011-11-22 21:28:15 +00:00
inventory . armor = msg . ReadByte ( ) ;
for ( i = 0 ; i < AMMO_NUMTYPES ; i + + ) {
ammo = msg . ReadBits ( ASYNC_PLAYER_INV_AMMO_BITS ) ;
if ( gameLocal . time > = inventory . ammoPredictTime ) {
inventory . ammo [ i ] = ammo ;
}
}
for ( i = 0 ; i < MAX_WEAPONS ; i + + ) {
inventory . clip [ i ] = msg . ReadBits ( ASYNC_PLAYER_INV_CLIP_BITS ) ;
}
}
/*
= = = = = = = = = = = = = = = =
idPlayer : : ServerReceiveEvent
= = = = = = = = = = = = = = = =
*/
bool idPlayer : : ServerReceiveEvent ( int event , int time , const idBitMsg & msg ) {
if ( idEntity : : ServerReceiveEvent ( event , time , msg ) ) {
return true ;
}
// client->server events
switch ( event ) {
case EVENT_IMPULSE : {
PerformImpulse ( msg . ReadBits ( 6 ) ) ;
return true ;
}
default : {
return false ;
}
}
}
/*
= = = = = = = = = = = = = = = =
idPlayer : : ClientReceiveEvent
= = = = = = = = = = = = = = = =
*/
bool idPlayer : : ClientReceiveEvent ( int event , int time , const idBitMsg & msg ) {
int powerup ;
bool start ;
switch ( event ) {
case EVENT_EXIT_TELEPORTER :
Event_ExitTeleporter ( ) ;
return true ;
case EVENT_ABORT_TELEPORTER :
SetPrivateCameraView ( NULL ) ;
return true ;
case EVENT_POWERUP : {
powerup = msg . ReadShort ( ) ;
start = msg . ReadBits ( 1 ) ! = 0 ;
if ( start ) {
GivePowerUp ( powerup , 0 ) ;
} else {
ClearPowerup ( powerup ) ;
2011-12-06 18:20:15 +00:00
}
2011-11-22 21:28:15 +00:00
return true ;
}
2018-08-26 03:41:08 +00:00
case EVENT_PICKUPNAME : { //New, Not so sure what it does
char buf [ MAX_EVENT_PARAM_SIZE ] ;
msg . ReadString ( buf , MAX_EVENT_PARAM_SIZE ) ;
inventory . AddPickupName ( buf , " " , this ) ; //New from_D3XP
return true ;
}
2011-11-22 21:28:15 +00:00
case EVENT_SPECTATE : {
bool spectate = ( msg . ReadBits ( 1 ) ! = 0 ) ;
Spectate ( spectate ) ;
return true ;
}
case EVENT_ADD_DAMAGE_EFFECT : {
if ( spectating ) {
// if we're spectating, ignore
// happens if the event and the spectate change are written on the server during the same frame (fraglimit)
return true ;
}
2012-01-15 12:39:23 +00:00
break ;
2011-11-22 21:28:15 +00:00
}
2012-01-15 12:39:23 +00:00
default :
break ;
2011-11-22 21:28:15 +00:00
}
2012-01-15 12:39:23 +00:00
return idActor : : ClientReceiveEvent ( event , time , msg ) ;
2011-11-22 21:28:15 +00:00
}
/*
= = = = = = = = = = = = = = = =
idPlayer : : Hide
= = = = = = = = = = = = = = = =
*/
void idPlayer : : Hide ( void ) {
idWeapon * weap ;
idActor : : Hide ( ) ;
weap = weapon . GetEntity ( ) ;
if ( weap ) {
weap - > HideWorldModel ( ) ;
}
}
/*
= = = = = = = = = = = = = = = =
idPlayer : : Show
= = = = = = = = = = = = = = = =
*/
void idPlayer : : Show ( void ) {
idWeapon * weap ;
2011-12-06 18:20:15 +00:00
2011-11-22 21:28:15 +00:00
idActor : : Show ( ) ;
weap = weapon . GetEntity ( ) ;
if ( weap ) {
weap - > ShowWorldModel ( ) ;
}
}
/*
= = = = = = = = = = = = = = =
idPlayer : : StartAudioLog
= = = = = = = = = = = = = = =
*/
void idPlayer : : StartAudioLog ( void ) {
if ( hud ) {
hud - > HandleNamedEvent ( " audioLogUp " ) ;
}
}
/*
= = = = = = = = = = = = = = =
idPlayer : : StopAudioLog
= = = = = = = = = = = = = = =
*/
void idPlayer : : StopAudioLog ( void ) {
if ( hud ) {
hud - > HandleNamedEvent ( " audioLogDown " ) ;
}
}
/*
= = = = = = = = = = = = = = =
idPlayer : : ShowTip
= = = = = = = = = = = = = = =
*/
void idPlayer : : ShowTip ( const char * title , const char * tip , bool autoHide ) {
if ( tipUp ) {
return ;
}
hud - > SetStateString ( " tip " , tip ) ;
hud - > SetStateString ( " tiptitle " , title ) ;
2011-12-06 18:20:15 +00:00
hud - > HandleNamedEvent ( " tipWindowUp " ) ;
2011-11-22 21:28:15 +00:00
if ( autoHide ) {
PostEventSec ( & EV_Player_HideTip , 5.0f ) ;
}
tipUp = true ;
}
/*
= = = = = = = = = = = = = = =
idPlayer : : HideTip
= = = = = = = = = = = = = = =
*/
void idPlayer : : HideTip ( void ) {
2011-12-06 18:20:15 +00:00
hud - > HandleNamedEvent ( " tipWindowDown " ) ;
2011-11-22 21:28:15 +00:00
tipUp = false ;
}
/*
= = = = = = = = = = = = = = =
idPlayer : : Event_HideTip
= = = = = = = = = = = = = = =
*/
void idPlayer : : Event_HideTip ( void ) {
HideTip ( ) ;
}
/*
= = = = = = = = = = = = = = =
idPlayer : : ShowObjective
= = = = = = = = = = = = = = =
*/
void idPlayer : : ShowObjective ( const char * obj ) {
hud - > HandleNamedEvent ( obj ) ;
objectiveUp = true ;
}
/*
= = = = = = = = = = = = = = =
idPlayer : : HideObjective
= = = = = = = = = = = = = = =
*/
void idPlayer : : HideObjective ( void ) {
hud - > HandleNamedEvent ( " closeObjective " ) ;
objectiveUp = false ;
}
/*
= = = = = = = = = = = = = = =
idPlayer : : Event_StopAudioLog
= = = = = = = = = = = = = = =
*/
void idPlayer : : Event_StopAudioLog ( void ) {
StopAudioLog ( ) ;
}
/*
= = = = = = = = = = = = = = =
idPlayer : : SetSpectateOrigin
= = = = = = = = = = = = = = =
*/
void idPlayer : : SetSpectateOrigin ( void ) {
idVec3 neworig ;
neworig = GetPhysics ( ) - > GetOrigin ( ) ;
neworig [ 2 ] + = EyeHeight ( ) ;
neworig [ 2 ] + = 25 ;
SetOrigin ( neworig ) ;
}
/*
= = = = = = = = = = = = = = =
idPlayer : : RemoveWeapon
= = = = = = = = = = = = = = =
*/
void idPlayer : : RemoveWeapon ( const char * weap ) {
if ( weap & & * weap ) {
inventory . Drop ( spawnArgs , spawnArgs . GetString ( weap ) , - 1 ) ;
}
}
/*
= = = = = = = = = = = = = = =
idPlayer : : CanShowWeaponViewmodel
= = = = = = = = = = = = = = =
*/
bool idPlayer : : CanShowWeaponViewmodel ( void ) const {
return showWeaponViewModel ;
}
/*
= = = = = = = = = = = = = = =
idPlayer : : SetLevelTrigger
= = = = = = = = = = = = = = =
*/
void idPlayer : : SetLevelTrigger ( const char * levelName , const char * triggerName ) {
if ( levelName & & * levelName & & triggerName & & * triggerName ) {
idLevelTriggerInfo lti ;
lti . levelName = levelName ;
lti . triggerName = triggerName ;
inventory . levelTriggers . Append ( lti ) ;
}
}
/*
= = = = = = = = = = = = = = =
idPlayer : : Event_LevelTrigger
= = = = = = = = = = = = = = =
*/
void idPlayer : : Event_LevelTrigger ( void ) {
idStr mapName = gameLocal . GetMapName ( ) ;
mapName . StripPath ( ) ;
mapName . StripFileExtension ( ) ;
for ( int i = inventory . levelTriggers . Num ( ) - 1 ; i > = 0 ; i - - ) {
if ( idStr : : Icmp ( mapName , inventory . levelTriggers [ i ] . levelName ) = = 0 ) {
idEntity * ent = gameLocal . FindEntity ( inventory . levelTriggers [ i ] . triggerName ) ;
if ( ent ) {
ent - > PostEventMS ( & EV_Activate , 1 , this ) ;
}
}
}
}
/*
= = = = = = = = = = = = = = =
idPlayer : : Event_Gibbed
= = = = = = = = = = = = = = =
*/
void idPlayer : : Event_Gibbed ( void ) {
}
/*
= = = = = = = = = = = = = = = = = =
2011-12-06 18:20:15 +00:00
idPlayer : : Event_GetIdealWeapon
2011-11-22 21:28:15 +00:00
= = = = = = = = = = = = = = = = = =
*/
void idPlayer : : Event_GetIdealWeapon ( void ) {
const char * weapon ;
if ( idealWeapon > = 0 ) {
weapon = spawnArgs . GetString ( va ( " def_weapon%d " , idealWeapon ) ) ;
idThread : : ReturnString ( weapon ) ;
} else {
idThread : : ReturnString ( " " ) ;
}
}
/*
= = = = = = = = = = = = = = =
idPlayer : : UpdatePlayerIcons
= = = = = = = = = = = = = = =
*/
void idPlayer : : UpdatePlayerIcons ( void ) {
int time = networkSystem - > ServerGetClientTimeSinceLastPacket ( entityNumber ) ;
if ( time > cvarSystem - > GetCVarInteger ( " net_clientMaxPrediction " ) ) {
isLagged = true ;
} else {
isLagged = false ;
}
}
/*
= = = = = = = = = = = = = = =
idPlayer : : DrawPlayerIcons
= = = = = = = = = = = = = = =
*/
void idPlayer : : DrawPlayerIcons ( void ) {
if ( ! NeedsIcon ( ) ) {
playerIcon . FreeIcon ( ) ;
return ;
}
playerIcon . Draw ( this , headJoint ) ;
}
/*
= = = = = = = = = = = = = = =
idPlayer : : HidePlayerIcons
= = = = = = = = = = = = = = =
*/
void idPlayer : : HidePlayerIcons ( void ) {
playerIcon . FreeIcon ( ) ;
}
/*
= = = = = = = = = = = = = = =
idPlayer : : NeedsIcon
= = = = = = = = = = = = = =
*/
bool idPlayer : : NeedsIcon ( void ) {
// local clients don't render their own icons... they're only info for other clients
return entityNumber ! = gameLocal . localClientNum & & ( isLagged | | isChatting ) ;
}
2018-08-26 03:41:08 +00:00
/*
= = = = = = = = = = = = = = = = = =
idPlayer : : Event_WeaponAvailable
= = = = = = = = = = = = = = = = = =
*/
void idPlayer : : Event_WeaponAvailable ( const char * name ) {
idThread : : ReturnInt ( WeaponAvailable ( name ) ? 1 : 0 ) ;
}
/*
= = = = = = = = = = = = = = = = = =
idPlayer : : Event_GetImpulseKey
= = = = = = = = = = = = = = = = = =
*/
void idPlayer : : Event_GetImpulseKey ( void ) {
idThread : : ReturnInt ( usercmd . impulse ) ;
}
bool idPlayer : : WeaponAvailable ( const char * name ) {
for ( int i = 0 ; i < MAX_WEAPONS ; i + + ) {
if ( inventory . weapons & ( 1 < < i ) ) {
const char * weap = spawnArgs . GetString ( va ( " def_weapon%d " , i ) ) ;
if ( ! idStr : : Cmp ( weap , name ) ) {
return true ;
}
}
}
return false ;
}
/*
= = = = = = = = = = = = = = = = =
idPlayer : : GetCurrentWeapon //New
= = = = = = = = = = = = = = = = =
idStr idPlayer : : GetCurrentWeapon ( ) {
const char * weapon ;
if ( currentWeapon > = 0 ) {
weapon = spawnArgs . GetString ( va ( " def_weapon%d " , currentWeapon ) ) ;
return weapon ;
} else {
return " " ;
}
}
*/