2012-11-26 18:58:24 +00:00
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
Doom 3 BFG Edition GPL Source Code
2012-11-28 15:47:07 +00:00
Copyright ( C ) 1993 - 2012 id Software LLC , a ZeniMax Media company .
2012-11-26 18:58:24 +00:00
2012-11-28 15:47:07 +00:00
This file is part of the Doom 3 BFG Edition GPL Source Code ( " Doom 3 BFG Edition Source Code " ) .
2012-11-26 18:58:24 +00:00
Doom 3 BFG Edition 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 BFG Edition 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 BFG Edition Source Code . If not , see < http : //www.gnu.org/licenses/>.
In addition , the Doom 3 BFG Edition 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 BFG Edition 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 .
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-12-22 15:18:19 +00:00
# include "precompiled.h"
2012-11-26 18:58:24 +00:00
# pragma hdrstop
# include "Game_local.h"
# include "PredictedValue_impl.h"
/***********************************************************************
2012-11-28 15:47:07 +00:00
idWeapon
2012-11-26 18:58:24 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
//
// event defs
//
const idEventDef EV_Weapon_Clear ( " <clear> " ) ;
const idEventDef EV_Weapon_GetOwner ( " getOwner " , NULL , ' e ' ) ;
const idEventDef EV_Weapon_Next ( " nextWeapon " ) ;
const idEventDef EV_Weapon_State ( " weaponState " , " sd " ) ;
const idEventDef EV_Weapon_UseAmmo ( " useAmmo " , " d " ) ;
const idEventDef EV_Weapon_AddToClip ( " addToClip " , " d " ) ;
const idEventDef EV_Weapon_AmmoInClip ( " ammoInClip " , NULL , ' f ' ) ;
const idEventDef EV_Weapon_AmmoAvailable ( " ammoAvailable " , NULL , ' f ' ) ;
const idEventDef EV_Weapon_TotalAmmoCount ( " totalAmmoCount " , NULL , ' f ' ) ;
const idEventDef EV_Weapon_ClipSize ( " clipSize " , NULL , ' f ' ) ;
const idEventDef EV_Weapon_WeaponOutOfAmmo ( " weaponOutOfAmmo " ) ;
const idEventDef EV_Weapon_WeaponReady ( " weaponReady " ) ;
const idEventDef EV_Weapon_WeaponReloading ( " weaponReloading " ) ;
const idEventDef EV_Weapon_WeaponHolstered ( " weaponHolstered " ) ;
const idEventDef EV_Weapon_WeaponRising ( " weaponRising " ) ;
const idEventDef EV_Weapon_WeaponLowering ( " weaponLowering " ) ;
const idEventDef EV_Weapon_Flashlight ( " flashlight " , " d " ) ;
const idEventDef EV_Weapon_LaunchProjectiles ( " launchProjectiles " , " dffff " ) ;
const idEventDef EV_Weapon_CreateProjectile ( " createProjectile " , NULL , ' e ' ) ;
const idEventDef EV_Weapon_EjectBrass ( " ejectBrass " ) ;
const idEventDef EV_Weapon_Melee ( " melee " , NULL , ' d ' ) ;
const idEventDef EV_Weapon_GetWorldModel ( " getWorldModel " , NULL , ' e ' ) ;
const idEventDef EV_Weapon_AllowDrop ( " allowDrop " , " d " ) ;
const idEventDef EV_Weapon_AutoReload ( " autoReload " , NULL , ' f ' ) ;
const idEventDef EV_Weapon_NetReload ( " netReload " ) ;
const idEventDef EV_Weapon_IsInvisible ( " isInvisible " , NULL , ' f ' ) ;
const idEventDef EV_Weapon_NetEndReload ( " netEndReload " ) ;
const idEventDef EV_Weapon_GrabberHasTarget ( " grabberHasTarget " , NULL , ' d ' ) ;
const idEventDef EV_Weapon_Grabber ( " grabber " , " d " ) ;
const idEventDef EV_Weapon_Grabber_SetGrabDistance ( " grabberGrabDistance " , " f " ) ;
const idEventDef EV_Weapon_LaunchProjectilesEllipse ( " launchProjectilesEllipse " , " dffff " ) ;
const idEventDef EV_Weapon_LaunchPowerup ( " launchPowerup " , " sfd " ) ;
const idEventDef EV_Weapon_StartWeaponSmoke ( " startWeaponSmoke " ) ;
const idEventDef EV_Weapon_StopWeaponSmoke ( " stopWeaponSmoke " ) ;
const idEventDef EV_Weapon_StartWeaponParticle ( " startWeaponParticle " , " s " ) ;
const idEventDef EV_Weapon_StopWeaponParticle ( " stopWeaponParticle " , " s " ) ;
const idEventDef EV_Weapon_StartWeaponLight ( " startWeaponLight " , " s " ) ;
const idEventDef EV_Weapon_StopWeaponLight ( " stopWeaponLight " , " s " ) ;
//
// class def
//
CLASS_DECLARATION ( idAnimatedEntity , idWeapon )
2012-11-28 15:47:07 +00:00
EVENT ( EV_Weapon_Clear , idWeapon : : Event_Clear )
EVENT ( EV_Weapon_GetOwner , idWeapon : : Event_GetOwner )
EVENT ( EV_Weapon_State , idWeapon : : Event_WeaponState )
EVENT ( EV_Weapon_WeaponReady , idWeapon : : Event_WeaponReady )
EVENT ( EV_Weapon_WeaponOutOfAmmo , idWeapon : : Event_WeaponOutOfAmmo )
EVENT ( EV_Weapon_WeaponReloading , idWeapon : : Event_WeaponReloading )
EVENT ( EV_Weapon_WeaponHolstered , idWeapon : : Event_WeaponHolstered )
EVENT ( EV_Weapon_WeaponRising , idWeapon : : Event_WeaponRising )
EVENT ( EV_Weapon_WeaponLowering , idWeapon : : Event_WeaponLowering )
EVENT ( EV_Weapon_UseAmmo , idWeapon : : Event_UseAmmo )
EVENT ( EV_Weapon_AddToClip , idWeapon : : Event_AddToClip )
EVENT ( EV_Weapon_AmmoInClip , idWeapon : : Event_AmmoInClip )
EVENT ( EV_Weapon_AmmoAvailable , idWeapon : : Event_AmmoAvailable )
EVENT ( EV_Weapon_TotalAmmoCount , idWeapon : : Event_TotalAmmoCount )
EVENT ( EV_Weapon_ClipSize , idWeapon : : Event_ClipSize )
EVENT ( AI_PlayAnim , idWeapon : : Event_PlayAnim )
EVENT ( AI_PlayCycle , idWeapon : : Event_PlayCycle )
EVENT ( AI_SetBlendFrames , idWeapon : : Event_SetBlendFrames )
EVENT ( AI_GetBlendFrames , idWeapon : : Event_GetBlendFrames )
EVENT ( AI_AnimDone , idWeapon : : Event_AnimDone )
EVENT ( EV_Weapon_Next , idWeapon : : Event_Next )
EVENT ( EV_SetSkin , idWeapon : : Event_SetSkin )
EVENT ( EV_Weapon_Flashlight , idWeapon : : Event_Flashlight )
EVENT ( EV_Light_GetLightParm , idWeapon : : Event_GetLightParm )
EVENT ( EV_Light_SetLightParm , idWeapon : : Event_SetLightParm )
EVENT ( EV_Light_SetLightParms , idWeapon : : Event_SetLightParms )
EVENT ( EV_Weapon_LaunchProjectiles , idWeapon : : Event_LaunchProjectiles )
EVENT ( EV_Weapon_CreateProjectile , idWeapon : : Event_CreateProjectile )
EVENT ( EV_Weapon_EjectBrass , idWeapon : : Event_EjectBrass )
EVENT ( EV_Weapon_Melee , idWeapon : : Event_Melee )
EVENT ( EV_Weapon_GetWorldModel , idWeapon : : Event_GetWorldModel )
EVENT ( EV_Weapon_AllowDrop , idWeapon : : Event_AllowDrop )
EVENT ( EV_Weapon_AutoReload , idWeapon : : Event_AutoReload )
EVENT ( EV_Weapon_NetReload , idWeapon : : Event_NetReload )
EVENT ( EV_Weapon_IsInvisible , idWeapon : : Event_IsInvisible )
EVENT ( EV_Weapon_NetEndReload , idWeapon : : Event_NetEndReload )
EVENT ( EV_Weapon_Grabber , idWeapon : : Event_Grabber )
EVENT ( EV_Weapon_GrabberHasTarget , idWeapon : : Event_GrabberHasTarget )
EVENT ( EV_Weapon_Grabber_SetGrabDistance , idWeapon : : Event_GrabberSetGrabDistance )
EVENT ( EV_Weapon_LaunchProjectilesEllipse , idWeapon : : Event_LaunchProjectilesEllipse )
EVENT ( EV_Weapon_LaunchPowerup , idWeapon : : Event_LaunchPowerup )
EVENT ( EV_Weapon_StartWeaponSmoke , idWeapon : : Event_StartWeaponSmoke )
EVENT ( EV_Weapon_StopWeaponSmoke , idWeapon : : Event_StopWeaponSmoke )
EVENT ( EV_Weapon_StartWeaponParticle , idWeapon : : Event_StartWeaponParticle )
EVENT ( EV_Weapon_StopWeaponParticle , idWeapon : : Event_StopWeaponParticle )
EVENT ( EV_Weapon_StartWeaponLight , idWeapon : : Event_StartWeaponLight )
EVENT ( EV_Weapon_StopWeaponLight , idWeapon : : Event_StopWeaponLight )
2012-11-26 18:58:24 +00:00
END_CLASS
idCVar cg_projectile_clientAuthoritative_maxCatchup ( " cg_projectile_clientAuthoritative_maxCatchup " , " 500 " , CVAR_INTEGER , " " ) ;
idCVar g_useWeaponDepthHack ( " g_useWeaponDepthHack " , " 1 " , CVAR_BOOL , " Crunch z depth on weapons " ) ;
idCVar g_weaponShadows ( " g_weaponShadows " , " 0 " , CVAR_BOOL | CVAR_ARCHIVE , " Cast shadows from weapons " ) ;
extern idCVar cg_predictedSpawn_debug ;
/***********************************************************************
init
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
= = = = = = = = = = = = = = = =
idWeapon : : idWeapon ( )
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
idWeapon : : idWeapon ( )
{
2012-11-26 18:58:24 +00:00
owner = NULL ;
worldModel = NULL ;
weaponDef = NULL ;
thread = NULL ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
memset ( & guiLight , 0 , sizeof ( guiLight ) ) ;
memset ( & muzzleFlash , 0 , sizeof ( muzzleFlash ) ) ;
memset ( & worldMuzzleFlash , 0 , sizeof ( worldMuzzleFlash ) ) ;
memset ( & nozzleGlow , 0 , sizeof ( nozzleGlow ) ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
muzzleFlashEnd = 0 ;
flashColor = vec3_origin ;
muzzleFlashHandle = - 1 ;
worldMuzzleFlashHandle = - 1 ;
guiLightHandle = - 1 ;
nozzleGlowHandle = - 1 ;
modelDefHandle = - 1 ;
grabberState = - 1 ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
berserk = 2 ;
brassDelay = 0 ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
allowDrop = true ;
isPlayerFlashlight = false ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
fraccos = 0.0f ;
fraccos2 = 0.0f ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
Clear ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
fl . networkSync = true ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : ~ idWeapon ( )
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
idWeapon : : ~ idWeapon ( )
{
2012-11-26 18:58:24 +00:00
Clear ( ) ;
delete worldModel . GetEntity ( ) ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : Spawn
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : Spawn ( )
{
if ( ! common - > IsClient ( ) )
{
2012-11-26 18:58:24 +00:00
// setup the world model
2012-11-28 15:47:07 +00:00
worldModel = static_cast < idAnimatedEntity * > ( gameLocal . SpawnEntityType ( idAnimatedEntity : : Type , NULL ) ) ;
2012-11-26 18:58:24 +00:00
worldModel . GetEntity ( ) - > fl . networkSync = true ;
}
2012-11-28 15:47:07 +00:00
if ( 1 /*!common->IsMultiplayer()*/ )
{
2012-11-26 18:58:24 +00:00
grabber . Initialize ( ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
thread = new idThread ( ) ;
thread - > ManualDelete ( ) ;
thread - > ManualControl ( ) ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : SetOwner
Only called at player spawn time , not each weapon switch
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : SetOwner ( idPlayer * _owner )
{
2012-11-26 18:58:24 +00:00
assert ( ! owner ) ;
owner = _owner ;
SetName ( va ( " %s_weapon " , owner - > name . c_str ( ) ) ) ;
2012-11-28 15:47:07 +00:00
if ( worldModel . GetEntity ( ) )
{
2012-11-26 18:58:24 +00:00
worldModel . GetEntity ( ) - > SetName ( va ( " %s_weapon_worldmodel " , owner - > name . c_str ( ) ) ) ;
}
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : SetFlashlightOwner
Only called at player spawn time , not each weapon switch
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : SetFlashlightOwner ( idPlayer * _owner )
{
2012-11-26 18:58:24 +00:00
assert ( ! owner ) ;
owner = _owner ;
SetName ( va ( " %s_weapon_flashlight " , owner - > name . c_str ( ) ) ) ;
2012-11-28 15:47:07 +00:00
if ( worldModel . GetEntity ( ) )
{
2012-11-26 18:58:24 +00:00
worldModel . GetEntity ( ) - > SetName ( va ( " %s_weapon_flashlight_worldmodel " , owner - > name . c_str ( ) ) ) ;
}
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : ShouldConstructScriptObjectAtSpawn
Called during idEntity : : Spawn to see if it should construct the script object or not .
Overridden by subclasses that need to spawn the script object themselves .
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idWeapon : : ShouldConstructScriptObjectAtSpawn ( ) const
{
2012-11-26 18:58:24 +00:00
return false ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : CacheWeapon
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : CacheWeapon ( const char * weaponName )
{
const idDeclEntityDef * weaponDef ;
const char * brassDefName ;
const char * clipModelName ;
2012-11-26 18:58:24 +00:00
idTraceModel trm ;
2012-11-28 15:47:07 +00:00
const char * guiName ;
2012-11-26 18:58:24 +00:00
weaponDef = gameLocal . FindEntityDef ( weaponName , false ) ;
2012-11-28 15:47:07 +00:00
if ( ! weaponDef )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// precache the brass collision model
brassDefName = weaponDef - > dict . GetString ( " def_ejectBrass " ) ;
2012-11-28 15:47:07 +00:00
if ( brassDefName [ 0 ] )
{
const idDeclEntityDef * brassDef = gameLocal . FindEntityDef ( brassDefName , false ) ;
if ( brassDef )
{
2012-11-26 18:58:24 +00:00
brassDef - > dict . GetString ( " clipmodel " , " " , & clipModelName ) ;
2012-11-28 15:47:07 +00:00
if ( ! clipModelName [ 0 ] )
{
2012-11-26 18:58:24 +00:00
clipModelName = brassDef - > dict . GetString ( " model " ) ; // use the visual model
}
// load the trace model
collisionModelManager - > TrmFromModel ( clipModelName , trm ) ;
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
guiName = weaponDef - > dict . GetString ( " gui " ) ;
2012-11-28 15:47:07 +00:00
if ( guiName [ 0 ] )
{
2012-11-26 18:58:24 +00:00
uiManager - > FindGui ( guiName , true , false , true ) ;
}
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : Save
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : Save ( idSaveGame * savefile ) const
{
2012-11-26 18:58:24 +00:00
savefile - > WriteInt ( status ) ;
savefile - > WriteObject ( thread ) ;
savefile - > WriteString ( state ) ;
savefile - > WriteString ( idealState ) ;
savefile - > WriteInt ( animBlendFrames ) ;
savefile - > WriteInt ( animDoneTime ) ;
savefile - > WriteBool ( isLinked ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > WriteObject ( owner ) ;
worldModel . Save ( savefile ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > WriteInt ( hideTime ) ;
savefile - > WriteFloat ( hideDistance ) ;
savefile - > WriteInt ( hideStartTime ) ;
savefile - > WriteFloat ( hideStart ) ;
savefile - > WriteFloat ( hideEnd ) ;
savefile - > WriteFloat ( hideOffset ) ;
savefile - > WriteBool ( hide ) ;
savefile - > WriteBool ( disabled ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > WriteInt ( berserk ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > WriteVec3 ( playerViewOrigin ) ;
savefile - > WriteMat3 ( playerViewAxis ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > WriteVec3 ( viewWeaponOrigin ) ;
savefile - > WriteMat3 ( viewWeaponAxis ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > WriteVec3 ( muzzleOrigin ) ;
savefile - > WriteMat3 ( muzzleAxis ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > WriteVec3 ( pushVelocity ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > WriteString ( weaponDef - > GetName ( ) ) ;
savefile - > WriteFloat ( meleeDistance ) ;
savefile - > WriteString ( meleeDefName ) ;
savefile - > WriteInt ( brassDelay ) ;
savefile - > WriteString ( icon ) ;
savefile - > WriteString ( pdaIcon ) ;
savefile - > WriteString ( displayName ) ;
savefile - > WriteString ( itemDesc ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > WriteInt ( guiLightHandle ) ;
savefile - > WriteRenderLight ( guiLight ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > WriteInt ( muzzleFlashHandle ) ;
savefile - > WriteRenderLight ( muzzleFlash ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > WriteInt ( worldMuzzleFlashHandle ) ;
savefile - > WriteRenderLight ( worldMuzzleFlash ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > WriteVec3 ( flashColor ) ;
savefile - > WriteInt ( muzzleFlashEnd ) ;
savefile - > WriteInt ( flashTime ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > WriteBool ( lightOn ) ;
savefile - > WriteBool ( silent_fire ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > WriteInt ( kick_endtime ) ;
savefile - > WriteInt ( muzzle_kick_time ) ;
savefile - > WriteInt ( muzzle_kick_maxtime ) ;
savefile - > WriteAngles ( muzzle_kick_angles ) ;
savefile - > WriteVec3 ( muzzle_kick_offset ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > WriteInt ( ammoType ) ;
savefile - > WriteInt ( ammoRequired ) ;
savefile - > WriteInt ( clipSize ) ;
savefile - > WriteInt ( ammoClip . Get ( ) ) ;
savefile - > WriteInt ( lowAmmo ) ;
savefile - > WriteBool ( powerAmmo ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// savegames <= 17
savefile - > WriteInt ( 0 ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > WriteInt ( zoomFov ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > WriteJoint ( barrelJointView ) ;
savefile - > WriteJoint ( flashJointView ) ;
savefile - > WriteJoint ( ejectJointView ) ;
savefile - > WriteJoint ( guiLightJointView ) ;
savefile - > WriteJoint ( ventLightJointView ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > WriteJoint ( flashJointWorld ) ;
savefile - > WriteJoint ( barrelJointWorld ) ;
savefile - > WriteJoint ( ejectJointWorld ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > WriteBool ( hasBloodSplat ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > WriteSoundShader ( sndHum ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > WriteParticle ( weaponSmoke ) ;
savefile - > WriteInt ( weaponSmokeStartTime ) ;
savefile - > WriteBool ( continuousSmoke ) ;
savefile - > WriteParticle ( strikeSmoke ) ;
savefile - > WriteInt ( strikeSmokeStartTime ) ;
savefile - > WriteVec3 ( strikePos ) ;
savefile - > WriteMat3 ( strikeAxis ) ;
savefile - > WriteInt ( nextStrikeFx ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > WriteBool ( nozzleFx ) ;
savefile - > WriteInt ( nozzleFxFade ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > WriteInt ( lastAttack ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > WriteInt ( nozzleGlowHandle ) ;
savefile - > WriteRenderLight ( nozzleGlow ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > WriteVec3 ( nozzleGlowColor ) ;
savefile - > WriteMaterial ( nozzleGlowShader ) ;
savefile - > WriteFloat ( nozzleGlowRadius ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > WriteInt ( weaponAngleOffsetAverages ) ;
savefile - > WriteFloat ( weaponAngleOffsetScale ) ;
savefile - > WriteFloat ( weaponAngleOffsetMax ) ;
savefile - > WriteFloat ( weaponOffsetTime ) ;
savefile - > WriteFloat ( weaponOffsetScale ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > WriteBool ( allowDrop ) ;
savefile - > WriteObject ( projectileEnt ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > WriteStaticObject ( grabber ) ;
savefile - > WriteInt ( grabberState ) ;
2012-11-28 15:47:07 +00:00
savefile - > WriteJoint ( smokeJointView ) ;
savefile - > WriteInt ( weaponParticles . Num ( ) ) ;
for ( int i = 0 ; i < weaponParticles . Num ( ) ; i + + )
{
WeaponParticle_t * part = weaponParticles . GetIndex ( i ) ;
2012-11-26 18:58:24 +00:00
savefile - > WriteString ( part - > name ) ;
savefile - > WriteString ( part - > particlename ) ;
savefile - > WriteBool ( part - > active ) ;
savefile - > WriteInt ( part - > startTime ) ;
savefile - > WriteJoint ( part - > joint ) ;
savefile - > WriteBool ( part - > smoke ) ;
2012-11-28 15:47:07 +00:00
if ( ! part - > smoke )
{
savefile - > WriteObject ( part - > emitter ) ;
2012-11-26 18:58:24 +00:00
}
}
2012-11-28 15:47:07 +00:00
savefile - > WriteInt ( weaponLights . Num ( ) ) ;
for ( int i = 0 ; i < weaponLights . Num ( ) ; i + + )
{
WeaponLight_t * light = weaponLights . GetIndex ( i ) ;
2012-11-26 18:58:24 +00:00
savefile - > WriteString ( light - > name ) ;
savefile - > WriteBool ( light - > active ) ;
savefile - > WriteInt ( light - > startTime ) ;
savefile - > WriteJoint ( light - > joint ) ;
savefile - > WriteInt ( light - > lightHandle ) ;
savefile - > WriteRenderLight ( light - > light ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : Restore
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : Restore ( idRestoreGame * savefile )
{
2012-11-26 18:58:24 +00:00
2012-11-28 15:47:07 +00:00
savefile - > ReadInt ( ( int & ) status ) ;
savefile - > ReadObject ( reinterpret_cast < idClass * & > ( thread ) ) ;
2012-11-26 18:58:24 +00:00
savefile - > ReadString ( state ) ;
savefile - > ReadString ( idealState ) ;
savefile - > ReadInt ( animBlendFrames ) ;
savefile - > ReadInt ( animDoneTime ) ;
savefile - > ReadBool ( isLinked ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// Re-link script fields
2012-11-28 15:47:07 +00:00
WEAPON_ATTACK . LinkTo ( scriptObject , " WEAPON_ATTACK " ) ;
WEAPON_RELOAD . LinkTo ( scriptObject , " WEAPON_RELOAD " ) ;
2012-11-26 18:58:24 +00:00
WEAPON_NETRELOAD . LinkTo ( scriptObject , " WEAPON_NETRELOAD " ) ;
WEAPON_NETENDRELOAD . LinkTo ( scriptObject , " WEAPON_NETENDRELOAD " ) ;
WEAPON_NETFIRING . LinkTo ( scriptObject , " WEAPON_NETFIRING " ) ;
WEAPON_RAISEWEAPON . LinkTo ( scriptObject , " WEAPON_RAISEWEAPON " ) ;
WEAPON_LOWERWEAPON . LinkTo ( scriptObject , " WEAPON_LOWERWEAPON " ) ;
2012-11-28 15:47:07 +00:00
savefile - > ReadObject ( reinterpret_cast < idClass * & > ( owner ) ) ;
2012-11-26 18:58:24 +00:00
worldModel . Restore ( savefile ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > ReadInt ( hideTime ) ;
savefile - > ReadFloat ( hideDistance ) ;
savefile - > ReadInt ( hideStartTime ) ;
savefile - > ReadFloat ( hideStart ) ;
savefile - > ReadFloat ( hideEnd ) ;
savefile - > ReadFloat ( hideOffset ) ;
savefile - > ReadBool ( hide ) ;
savefile - > ReadBool ( disabled ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > ReadInt ( berserk ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > ReadVec3 ( playerViewOrigin ) ;
savefile - > ReadMat3 ( playerViewAxis ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > ReadVec3 ( viewWeaponOrigin ) ;
savefile - > ReadMat3 ( viewWeaponAxis ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > ReadVec3 ( muzzleOrigin ) ;
savefile - > ReadMat3 ( muzzleAxis ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > ReadVec3 ( pushVelocity ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idStr objectname ;
savefile - > ReadString ( objectname ) ;
weaponDef = gameLocal . FindEntityDef ( objectname ) ;
meleeDef = gameLocal . FindEntityDef ( weaponDef - > dict . GetString ( " def_melee " ) , false ) ;
2012-11-28 15:47:07 +00:00
const idDeclEntityDef * projectileDef = gameLocal . FindEntityDef ( weaponDef - > dict . GetString ( " def_projectile " ) , false ) ;
if ( projectileDef )
{
2012-11-26 18:58:24 +00:00
projectileDict = projectileDef - > dict ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
projectileDict . Clear ( ) ;
}
2012-11-28 15:47:07 +00:00
const idDeclEntityDef * brassDef = gameLocal . FindEntityDef ( weaponDef - > dict . GetString ( " def_ejectBrass " ) , false ) ;
if ( brassDef )
{
2012-11-26 18:58:24 +00:00
brassDict = brassDef - > dict ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
brassDict . Clear ( ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > ReadFloat ( meleeDistance ) ;
savefile - > ReadString ( meleeDefName ) ;
savefile - > ReadInt ( brassDelay ) ;
savefile - > ReadString ( icon ) ;
savefile - > ReadString ( pdaIcon ) ;
savefile - > ReadString ( displayName ) ;
savefile - > ReadString ( itemDesc ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > ReadInt ( guiLightHandle ) ;
savefile - > ReadRenderLight ( guiLight ) ;
2012-11-28 15:47:07 +00:00
if ( guiLightHandle > = 0 )
{
2012-11-26 18:58:24 +00:00
guiLightHandle = gameRenderWorld - > AddLightDef ( & guiLight ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > ReadInt ( muzzleFlashHandle ) ;
savefile - > ReadRenderLight ( muzzleFlash ) ;
2012-11-28 15:47:07 +00:00
if ( muzzleFlashHandle > = 0 )
{
2012-11-26 18:58:24 +00:00
muzzleFlashHandle = gameRenderWorld - > AddLightDef ( & muzzleFlash ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > ReadInt ( worldMuzzleFlashHandle ) ;
savefile - > ReadRenderLight ( worldMuzzleFlash ) ;
2012-11-28 15:47:07 +00:00
if ( worldMuzzleFlashHandle > = 0 )
{
2012-11-26 18:58:24 +00:00
worldMuzzleFlashHandle = gameRenderWorld - > AddLightDef ( & worldMuzzleFlash ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > ReadVec3 ( flashColor ) ;
savefile - > ReadInt ( muzzleFlashEnd ) ;
savefile - > ReadInt ( flashTime ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > ReadBool ( lightOn ) ;
savefile - > ReadBool ( silent_fire ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > ReadInt ( kick_endtime ) ;
savefile - > ReadInt ( muzzle_kick_time ) ;
savefile - > ReadInt ( muzzle_kick_maxtime ) ;
savefile - > ReadAngles ( muzzle_kick_angles ) ;
savefile - > ReadVec3 ( muzzle_kick_offset ) ;
2012-11-28 15:47:07 +00:00
savefile - > ReadInt ( ( int & ) ammoType ) ;
2012-11-26 18:58:24 +00:00
savefile - > ReadInt ( ammoRequired ) ;
savefile - > ReadInt ( clipSize ) ;
int savedAmmoClip = 0 ;
savefile - > ReadInt ( savedAmmoClip ) ;
ammoClip = savedAmmoClip ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > ReadInt ( lowAmmo ) ;
savefile - > ReadBool ( powerAmmo ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// savegame versions <= 17
int foo ;
savefile - > ReadInt ( foo ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > ReadInt ( zoomFov ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > ReadJoint ( barrelJointView ) ;
savefile - > ReadJoint ( flashJointView ) ;
savefile - > ReadJoint ( ejectJointView ) ;
savefile - > ReadJoint ( guiLightJointView ) ;
savefile - > ReadJoint ( ventLightJointView ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > ReadJoint ( flashJointWorld ) ;
savefile - > ReadJoint ( barrelJointWorld ) ;
savefile - > ReadJoint ( ejectJointWorld ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > ReadBool ( hasBloodSplat ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > ReadSoundShader ( sndHum ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > ReadParticle ( weaponSmoke ) ;
savefile - > ReadInt ( weaponSmokeStartTime ) ;
savefile - > ReadBool ( continuousSmoke ) ;
savefile - > ReadParticle ( strikeSmoke ) ;
savefile - > ReadInt ( strikeSmokeStartTime ) ;
savefile - > ReadVec3 ( strikePos ) ;
savefile - > ReadMat3 ( strikeAxis ) ;
savefile - > ReadInt ( nextStrikeFx ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > ReadBool ( nozzleFx ) ;
savefile - > ReadInt ( nozzleFxFade ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > ReadInt ( lastAttack ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > ReadInt ( nozzleGlowHandle ) ;
savefile - > ReadRenderLight ( nozzleGlow ) ;
2012-11-28 15:47:07 +00:00
if ( nozzleGlowHandle > = 0 )
{
2012-11-26 18:58:24 +00:00
nozzleGlowHandle = gameRenderWorld - > AddLightDef ( & nozzleGlow ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > ReadVec3 ( nozzleGlowColor ) ;
savefile - > ReadMaterial ( nozzleGlowShader ) ;
savefile - > ReadFloat ( nozzleGlowRadius ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > ReadInt ( weaponAngleOffsetAverages ) ;
savefile - > ReadFloat ( weaponAngleOffsetScale ) ;
savefile - > ReadFloat ( weaponAngleOffsetMax ) ;
savefile - > ReadFloat ( weaponOffsetTime ) ;
savefile - > ReadFloat ( weaponOffsetScale ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > ReadBool ( allowDrop ) ;
2012-11-28 15:47:07 +00:00
savefile - > ReadObject ( reinterpret_cast < idClass * & > ( projectileEnt ) ) ;
2012-11-26 18:58:24 +00:00
savefile - > ReadStaticObject ( grabber ) ;
savefile - > ReadInt ( grabberState ) ;
2012-11-28 15:47:07 +00:00
savefile - > ReadJoint ( smokeJointView ) ;
2012-11-26 18:58:24 +00:00
int particleCount ;
savefile - > ReadInt ( particleCount ) ;
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < particleCount ; i + + )
{
2012-11-26 18:58:24 +00:00
WeaponParticle_t newParticle ;
2012-11-28 15:47:07 +00:00
memset ( & newParticle , 0 , sizeof ( newParticle ) ) ;
2012-11-26 18:58:24 +00:00
idStr name , particlename ;
savefile - > ReadString ( name ) ;
savefile - > ReadString ( particlename ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
strcpy ( newParticle . name , name . c_str ( ) ) ;
strcpy ( newParticle . particlename , particlename . c_str ( ) ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > ReadBool ( newParticle . active ) ;
savefile - > ReadInt ( newParticle . startTime ) ;
savefile - > ReadJoint ( newParticle . joint ) ;
savefile - > ReadBool ( newParticle . smoke ) ;
2012-11-28 15:47:07 +00:00
if ( newParticle . smoke )
{
newParticle . particle = static_cast < const idDeclParticle * > ( declManager - > FindType ( DECL_PARTICLE , particlename , false ) ) ;
2012-11-26 18:58:24 +00:00
}
2012-11-28 15:47:07 +00:00
else
{
savefile - > ReadObject ( reinterpret_cast < idClass * & > ( newParticle . emitter ) ) ;
}
weaponParticles . Set ( newParticle . name , newParticle ) ;
2012-11-26 18:58:24 +00:00
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
int lightCount ;
savefile - > ReadInt ( lightCount ) ;
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < lightCount ; i + + )
{
2012-11-26 18:58:24 +00:00
WeaponLight_t newLight ;
2012-11-28 15:47:07 +00:00
memset ( & newLight , 0 , sizeof ( newLight ) ) ;
2012-11-26 18:58:24 +00:00
idStr name ;
savefile - > ReadString ( name ) ;
strcpy ( newLight . name , name . c_str ( ) ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
savefile - > ReadBool ( newLight . active ) ;
savefile - > ReadInt ( newLight . startTime ) ;
savefile - > ReadJoint ( newLight . joint ) ;
savefile - > ReadInt ( newLight . lightHandle ) ;
savefile - > ReadRenderLight ( newLight . light ) ;
2012-11-28 15:47:07 +00:00
if ( newLight . lightHandle > = 0 )
{
2012-11-26 18:58:24 +00:00
newLight . lightHandle = gameRenderWorld - > AddLightDef ( & newLight . light ) ;
}
2012-11-28 15:47:07 +00:00
weaponLights . Set ( newLight . name , newLight ) ;
2012-11-26 18:58:24 +00:00
}
}
/***********************************************************************
Weapon definition management
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
= = = = = = = = = = = = = = = =
idWeapon : : Clear
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : Clear ( )
{
2012-11-26 18:58:24 +00:00
CancelEvents ( & EV_Weapon_Clear ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
DeconstructScriptObject ( ) ;
scriptObject . Free ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
WEAPON_ATTACK . Unlink ( ) ;
WEAPON_RELOAD . Unlink ( ) ;
WEAPON_NETRELOAD . Unlink ( ) ;
WEAPON_NETENDRELOAD . Unlink ( ) ;
WEAPON_NETFIRING . Unlink ( ) ;
WEAPON_RAISEWEAPON . Unlink ( ) ;
WEAPON_LOWERWEAPON . Unlink ( ) ;
2012-11-28 15:47:07 +00:00
if ( muzzleFlashHandle ! = - 1 )
{
2012-11-26 18:58:24 +00:00
gameRenderWorld - > FreeLightDef ( muzzleFlashHandle ) ;
muzzleFlashHandle = - 1 ;
}
2012-11-28 15:47:07 +00:00
if ( worldMuzzleFlashHandle ! = - 1 )
{
2012-11-26 18:58:24 +00:00
gameRenderWorld - > FreeLightDef ( worldMuzzleFlashHandle ) ;
worldMuzzleFlashHandle = - 1 ;
}
2012-11-28 15:47:07 +00:00
if ( guiLightHandle ! = - 1 )
{
2012-11-26 18:58:24 +00:00
gameRenderWorld - > FreeLightDef ( guiLightHandle ) ;
guiLightHandle = - 1 ;
}
2012-11-28 15:47:07 +00:00
if ( nozzleGlowHandle ! = - 1 )
{
2012-11-26 18:58:24 +00:00
gameRenderWorld - > FreeLightDef ( nozzleGlowHandle ) ;
nozzleGlowHandle = - 1 ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
memset ( & renderEntity , 0 , sizeof ( renderEntity ) ) ;
renderEntity . entityNum = entityNumber ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
renderEntity . noShadow = true ;
renderEntity . noSelfShadow = true ;
renderEntity . customSkin = NULL ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// set default shader parms
renderEntity . shaderParms [ SHADERPARM_RED ] = 1.0f ;
2012-11-28 15:47:07 +00:00
renderEntity . shaderParms [ SHADERPARM_GREEN ] = 1.0f ;
2012-11-26 18:58:24 +00:00
renderEntity . shaderParms [ SHADERPARM_BLUE ] = 1.0f ;
renderEntity . shaderParms [ 3 ] = 1.0f ;
renderEntity . shaderParms [ SHADERPARM_TIMEOFFSET ] = 0.0f ;
renderEntity . shaderParms [ 5 ] = 0.0f ;
renderEntity . shaderParms [ 6 ] = 0.0f ;
renderEntity . shaderParms [ 7 ] = 0.0f ;
2012-11-28 15:47:07 +00:00
if ( refSound . referenceSound )
{
2012-11-26 18:58:24 +00:00
refSound . referenceSound - > Free ( true ) ;
}
memset ( & refSound , 0 , sizeof ( refSound_t ) ) ;
// setting diversity to 0 results in no random sound. -1 indicates random.
refSound . diversity = - 1.0f ;
2012-11-28 15:47:07 +00:00
if ( owner )
{
2012-11-26 18:58:24 +00:00
// don't spatialize the weapon sounds
refSound . listenerId = owner - > GetListenerId ( ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// clear out the sounds from our spawnargs since we'll copy them from the weapon def
2012-11-28 15:47:07 +00:00
const idKeyValue * kv = spawnArgs . MatchPrefix ( " snd_ " ) ;
while ( kv )
{
2012-11-26 18:58:24 +00:00
spawnArgs . Delete ( kv - > GetKey ( ) ) ;
kv = spawnArgs . MatchPrefix ( " snd_ " ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
hideTime = 300 ;
hideDistance = - 15.0f ;
hideStartTime = gameLocal . time - hideTime ;
hideStart = 0.0f ;
hideEnd = 0.0f ;
hideOffset = 0.0f ;
hide = false ;
disabled = false ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
weaponSmoke = NULL ;
weaponSmokeStartTime = 0 ;
continuousSmoke = false ;
strikeSmoke = NULL ;
strikeSmokeStartTime = 0 ;
strikePos . Zero ( ) ;
strikeAxis = mat3_identity ;
nextStrikeFx = 0 ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
icon = " " ;
pdaIcon = " " ;
displayName = " " ;
itemDesc = " " ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
playerViewAxis . Identity ( ) ;
playerViewOrigin . Zero ( ) ;
viewWeaponAxis . Identity ( ) ;
viewWeaponOrigin . Zero ( ) ;
muzzleAxis . Identity ( ) ;
muzzleOrigin . Zero ( ) ;
pushVelocity . Zero ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
status = WP_HOLSTERED ;
state = " " ;
idealState = " " ;
animBlendFrames = 0 ;
animDoneTime = 0 ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
projectileDict . Clear ( ) ;
meleeDef = NULL ;
meleeDefName = " " ;
meleeDistance = 0.0f ;
brassDict . Clear ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
flashTime = 250 ;
lightOn = false ;
silent_fire = false ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
grabberState = - 1 ;
grabber . Update ( owner , true ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
ammoType = 0 ;
ammoRequired = 0 ;
ammoClip = 0 ;
clipSize = 0 ;
lowAmmo = 0 ;
powerAmmo = false ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
kick_endtime = 0 ;
muzzle_kick_time = 0 ;
muzzle_kick_maxtime = 0 ;
muzzle_kick_angles . Zero ( ) ;
muzzle_kick_offset . Zero ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
zoomFov = 90 ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
barrelJointView = INVALID_JOINT ;
flashJointView = INVALID_JOINT ;
ejectJointView = INVALID_JOINT ;
guiLightJointView = INVALID_JOINT ;
ventLightJointView = INVALID_JOINT ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
barrelJointWorld = INVALID_JOINT ;
flashJointWorld = INVALID_JOINT ;
ejectJointWorld = INVALID_JOINT ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
smokeJointView = INVALID_JOINT ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
//Clean up the weapon particles
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < weaponParticles . Num ( ) ; i + + )
{
WeaponParticle_t * part = weaponParticles . GetIndex ( i ) ;
if ( ! part - > smoke )
{
if ( part - > emitter ! = NULL )
{
2012-11-26 18:58:24 +00:00
//Destroy the emitters
2012-11-28 15:47:07 +00:00
part - > emitter - > PostEventMS ( & EV_Remove , 0 ) ;
2012-11-26 18:58:24 +00:00
}
}
}
weaponParticles . Clear ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
//Clean up the weapon lights
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < weaponLights . Num ( ) ; i + + )
{
WeaponLight_t * light = weaponLights . GetIndex ( i ) ;
if ( light - > lightHandle ! = - 1 )
{
2012-11-26 18:58:24 +00:00
gameRenderWorld - > FreeLightDef ( light - > lightHandle ) ;
}
}
weaponLights . Clear ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
hasBloodSplat = false ;
nozzleFx = false ;
nozzleFxFade = 1500 ;
lastAttack = 0 ;
nozzleGlowHandle = - 1 ;
nozzleGlowShader = NULL ;
nozzleGlowRadius = 10 ;
nozzleGlowColor . Zero ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
weaponAngleOffsetAverages = 0 ;
weaponAngleOffsetScale = 0.0f ;
weaponAngleOffsetMax = 0.0f ;
weaponOffsetTime = 0.0f ;
weaponOffsetScale = 0.0f ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
allowDrop = true ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
animator . ClearAllAnims ( gameLocal . time , 0 ) ;
FreeModelDef ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
sndHum = NULL ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
isLinked = false ;
projectileEnt = NULL ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
isFiring = false ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : InitWorldModel
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : InitWorldModel ( const idDeclEntityDef * def )
{
idEntity * ent ;
2012-11-26 18:58:24 +00:00
ent = worldModel . GetEntity ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
assert ( ent ) ;
assert ( def ) ;
2012-11-28 15:47:07 +00:00
const char * model = def - > dict . GetString ( " model_world " ) ;
const char * attach = def - > dict . GetString ( " joint_attach " ) ;
2012-11-26 18:58:24 +00:00
ent - > SetSkin ( NULL ) ;
2012-11-28 15:47:07 +00:00
if ( model [ 0 ] & & attach [ 0 ] )
{
2012-11-26 18:58:24 +00:00
ent - > Show ( ) ;
ent - > SetModel ( model ) ;
2012-11-28 15:47:07 +00:00
if ( ent - > GetAnimator ( ) - > ModelDef ( ) )
{
2012-11-26 18:58:24 +00:00
ent - > SetSkin ( ent - > GetAnimator ( ) - > ModelDef ( ) - > GetDefaultSkin ( ) ) ;
}
ent - > GetPhysics ( ) - > SetContents ( 0 ) ;
ent - > GetPhysics ( ) - > SetClipModel ( NULL , 1.0f ) ;
ent - > BindToJoint ( owner , attach , true ) ;
ent - > GetPhysics ( ) - > SetOrigin ( vec3_origin ) ;
ent - > GetPhysics ( ) - > SetAxis ( mat3_identity ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// We don't want to interpolate the world model of weapons, let them
// just bind normally to the player's joint and be driven by the player's
// animation so that the weapon and the player don't appear out of sync.
ent - > SetUseClientInterpolation ( false ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// supress model in player views, but allow it in mirrors and remote views
2012-11-28 15:47:07 +00:00
renderEntity_t * worldModelRenderEntity = ent - > GetRenderEntity ( ) ;
if ( worldModelRenderEntity )
{
worldModelRenderEntity - > suppressSurfaceInViewID = owner - > entityNumber + 1 ;
worldModelRenderEntity - > suppressShadowInViewID = owner - > entityNumber + 1 ;
2012-11-26 18:58:24 +00:00
worldModelRenderEntity - > suppressShadowInLightID = LIGHTID_VIEW_MUZZLE_FLASH + owner - > entityNumber ;
}
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
ent - > SetModel ( " " ) ;
ent - > Hide ( ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
flashJointWorld = ent - > GetAnimator ( ) - > GetJointHandle ( " flash " ) ;
barrelJointWorld = ent - > GetAnimator ( ) - > GetJointHandle ( " muzzle " ) ;
ejectJointWorld = ent - > GetAnimator ( ) - > GetJointHandle ( " eject " ) ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : GetWeaponDef
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : GetWeaponDef ( const char * objectname , int ammoinclip )
{
const char * shader ;
const char * objectType ;
const char * vmodel ;
const char * guiName ;
const char * projectileName ;
const char * brassDefName ;
const char * smokeName ;
2012-11-26 18:58:24 +00:00
int ammoAvail ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
Clear ( ) ;
2012-11-28 15:47:07 +00:00
if ( ! objectname | | ! objectname [ 0 ] )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
assert ( owner ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
weaponDef = gameLocal . FindEntityDef ( objectname ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
ammoType = GetAmmoNumForName ( weaponDef - > dict . GetString ( " ammoType " ) ) ;
ammoRequired = weaponDef - > dict . GetInt ( " ammoRequired " ) ;
clipSize = weaponDef - > dict . GetInt ( " clipSize " ) ;
lowAmmo = weaponDef - > dict . GetInt ( " lowAmmo " ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
icon = weaponDef - > dict . GetString ( " icon " ) ;
pdaIcon = weaponDef - > dict . GetString ( " pdaIcon " ) ;
displayName = weaponDef - > dict . GetString ( " display_name " ) ;
itemDesc = weaponDef - > dict . GetString ( " inv_desc " ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
silent_fire = weaponDef - > dict . GetBool ( " silent_fire " ) ;
powerAmmo = weaponDef - > dict . GetBool ( " powerAmmo " ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
muzzle_kick_time = SEC2MS ( weaponDef - > dict . GetFloat ( " muzzle_kick_time " ) ) ;
muzzle_kick_maxtime = SEC2MS ( weaponDef - > dict . GetFloat ( " muzzle_kick_maxtime " ) ) ;
muzzle_kick_angles = weaponDef - > dict . GetAngles ( " muzzle_kick_angles " ) ;
muzzle_kick_offset = weaponDef - > dict . GetVector ( " muzzle_kick_offset " ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
hideTime = SEC2MS ( weaponDef - > dict . GetFloat ( " hide_time " , " 0.3 " ) ) ;
hideDistance = weaponDef - > dict . GetFloat ( " hide_distance " , " -15 " ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// muzzle smoke
smokeName = weaponDef - > dict . GetString ( " smoke_muzzle " ) ;
2012-11-28 15:47:07 +00:00
if ( * smokeName ! = ' \0 ' )
{
weaponSmoke = static_cast < const idDeclParticle * > ( declManager - > FindType ( DECL_PARTICLE , smokeName ) ) ;
}
else
{
2012-11-26 18:58:24 +00:00
weaponSmoke = NULL ;
}
continuousSmoke = weaponDef - > dict . GetBool ( " continuousSmoke " ) ;
weaponSmokeStartTime = ( continuousSmoke ) ? gameLocal . time : 0 ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
smokeName = weaponDef - > dict . GetString ( " smoke_strike " ) ;
2012-11-28 15:47:07 +00:00
if ( * smokeName ! = ' \0 ' )
{
strikeSmoke = static_cast < const idDeclParticle * > ( declManager - > FindType ( DECL_PARTICLE , smokeName ) ) ;
}
else
{
2012-11-26 18:58:24 +00:00
strikeSmoke = NULL ;
}
strikeSmokeStartTime = 0 ;
strikePos . Zero ( ) ;
strikeAxis = mat3_identity ;
nextStrikeFx = 0 ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// setup gui light
memset ( & guiLight , 0 , sizeof ( guiLight ) ) ;
2012-11-28 15:47:07 +00:00
const char * guiLightShader = weaponDef - > dict . GetString ( " mtr_guiLightShader " ) ;
if ( * guiLightShader ! = ' \0 ' )
{
2012-11-26 18:58:24 +00:00
guiLight . shader = declManager - > FindMaterial ( guiLightShader , false ) ;
guiLight . lightRadius [ 0 ] = guiLight . lightRadius [ 1 ] = guiLight . lightRadius [ 2 ] = 3 ;
guiLight . pointLight = true ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// setup the view model
vmodel = weaponDef - > dict . GetString ( " model_view " ) ;
SetModel ( vmodel ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// setup the world model
InitWorldModel ( weaponDef ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// copy the sounds from the weapon view model def into out spawnargs
2012-11-28 15:47:07 +00:00
const idKeyValue * kv = weaponDef - > dict . MatchPrefix ( " snd_ " ) ;
while ( kv )
{
2012-11-26 18:58:24 +00:00
spawnArgs . Set ( kv - > GetKey ( ) , kv - > GetValue ( ) ) ;
kv = weaponDef - > dict . MatchPrefix ( " snd_ " , kv ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// find some joints in the model for locating effects
barrelJointView = animator . GetJointHandle ( " barrel " ) ;
flashJointView = animator . GetJointHandle ( " flash " ) ;
ejectJointView = animator . GetJointHandle ( " eject " ) ;
guiLightJointView = animator . GetJointHandle ( " guiLight " ) ;
ventLightJointView = animator . GetJointHandle ( " ventLight " ) ;
2012-11-28 15:47:07 +00:00
idStr smokeJoint = weaponDef - > dict . GetString ( " smoke_joint " ) ;
if ( smokeJoint . Length ( ) > 0 )
{
2012-11-26 18:58:24 +00:00
smokeJointView = animator . GetJointHandle ( smokeJoint ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
smokeJointView = INVALID_JOINT ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// get the projectile
projectileDict . Clear ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
projectileName = weaponDef - > dict . GetString ( " def_projectile " ) ;
2012-11-28 15:47:07 +00:00
if ( projectileName [ 0 ] ! = ' \0 ' )
{
const idDeclEntityDef * projectileDef = gameLocal . FindEntityDef ( projectileName , false ) ;
if ( ! projectileDef )
{
2012-11-26 18:58:24 +00:00
gameLocal . Warning ( " Unknown projectile '%s' in weapon '%s' " , projectileName , objectname ) ;
2012-11-28 15:47:07 +00:00
}
else
{
const char * spawnclass = projectileDef - > dict . GetString ( " spawnclass " ) ;
idTypeInfo * cls = idClass : : GetClass ( spawnclass ) ;
if ( ! cls | | ! cls - > IsType ( idProjectile : : Type ) )
{
2012-11-26 18:58:24 +00:00
gameLocal . Warning ( " Invalid spawnclass '%s' on projectile '%s' (used by weapon '%s') " , spawnclass , projectileName , objectname ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
projectileDict = projectileDef - > dict ;
}
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// set up muzzleflash render light
2012-11-28 15:47:07 +00:00
const idMaterial * flashShader ;
2012-11-26 18:58:24 +00:00
idVec3 flashTarget ;
idVec3 flashUp ;
idVec3 flashRight ;
float flashRadius ;
bool flashPointLight ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
weaponDef - > dict . GetString ( " mtr_flashShader " , " " , & shader ) ;
flashShader = declManager - > FindMaterial ( shader , false ) ;
flashPointLight = weaponDef - > dict . GetBool ( " flashPointLight " , " 1 " ) ;
weaponDef - > dict . GetVector ( " flashColor " , " 0 0 0 " , flashColor ) ;
2012-11-28 15:47:07 +00:00
flashRadius = ( float ) weaponDef - > dict . GetInt ( " flashRadius " ) ; // if 0, no light will spawn
2012-11-26 18:58:24 +00:00
flashTime = SEC2MS ( weaponDef - > dict . GetFloat ( " flashTime " , " 0.25 " ) ) ;
flashTarget = weaponDef - > dict . GetVector ( " flashTarget " ) ;
flashUp = weaponDef - > dict . GetVector ( " flashUp " ) ;
flashRight = weaponDef - > dict . GetVector ( " flashRight " ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
memset ( & muzzleFlash , 0 , sizeof ( muzzleFlash ) ) ;
muzzleFlash . lightId = LIGHTID_VIEW_MUZZLE_FLASH + owner - > entityNumber ;
2012-11-28 15:47:07 +00:00
muzzleFlash . allowLightInViewID = owner - > entityNumber + 1 ;
2012-11-26 18:58:24 +00:00
// the weapon lights will only be in first person
2012-11-28 15:47:07 +00:00
guiLight . allowLightInViewID = owner - > entityNumber + 1 ;
nozzleGlow . allowLightInViewID = owner - > entityNumber + 1 ;
2012-11-26 18:58:24 +00:00
muzzleFlash . pointLight = flashPointLight ;
muzzleFlash . shader = flashShader ;
muzzleFlash . shaderParms [ SHADERPARM_RED ] = flashColor [ 0 ] ;
muzzleFlash . shaderParms [ SHADERPARM_GREEN ] = flashColor [ 1 ] ;
muzzleFlash . shaderParms [ SHADERPARM_BLUE ] = flashColor [ 2 ] ;
muzzleFlash . shaderParms [ SHADERPARM_TIMESCALE ] = 1.0f ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
muzzleFlash . lightRadius [ 0 ] = flashRadius ;
muzzleFlash . lightRadius [ 1 ] = flashRadius ;
muzzleFlash . lightRadius [ 2 ] = flashRadius ;
2012-11-28 15:47:07 +00:00
if ( ! flashPointLight )
{
2012-11-26 18:58:24 +00:00
muzzleFlash . target = flashTarget ;
muzzleFlash . up = flashUp ;
muzzleFlash . right = flashRight ;
muzzleFlash . end = flashTarget ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// the world muzzle flash is the same, just positioned differently
worldMuzzleFlash = muzzleFlash ;
2012-11-28 15:47:07 +00:00
worldMuzzleFlash . suppressLightInViewID = owner - > entityNumber + 1 ;
2012-11-26 18:58:24 +00:00
worldMuzzleFlash . allowLightInViewID = 0 ;
worldMuzzleFlash . lightId = LIGHTID_WORLD_MUZZLE_FLASH + owner - > entityNumber ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
//-----------------------------------
2012-11-28 15:47:07 +00:00
nozzleFx = weaponDef - > dict . GetBool ( " nozzleFx " ) ;
nozzleFxFade = weaponDef - > dict . GetInt ( " nozzleFxFade " , " 1500 " ) ;
nozzleGlowColor = weaponDef - > dict . GetVector ( " nozzleGlowColor " , " 1 1 1 " ) ;
nozzleGlowRadius = weaponDef - > dict . GetFloat ( " nozzleGlowRadius " , " 10 " ) ;
2012-11-26 18:58:24 +00:00
weaponDef - > dict . GetString ( " mtr_nozzleGlowShader " , " " , & shader ) ;
nozzleGlowShader = declManager - > FindMaterial ( shader , false ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// get the melee damage def
meleeDistance = weaponDef - > dict . GetFloat ( " melee_distance " ) ;
meleeDefName = weaponDef - > dict . GetString ( " def_melee " ) ;
2012-11-28 15:47:07 +00:00
if ( meleeDefName . Length ( ) )
{
2012-11-26 18:58:24 +00:00
meleeDef = gameLocal . FindEntityDef ( meleeDefName , false ) ;
2012-11-28 15:47:07 +00:00
if ( ! meleeDef )
{
2012-11-26 18:58:24 +00:00
gameLocal . Error ( " Unknown melee '%s' " , meleeDefName . c_str ( ) ) ;
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// get the brass def
brassDict . Clear ( ) ;
brassDelay = weaponDef - > dict . GetInt ( " ejectBrassDelay " , " 0 " ) ;
brassDefName = weaponDef - > dict . GetString ( " def_ejectBrass " ) ;
2012-11-28 15:47:07 +00:00
if ( brassDefName [ 0 ] )
{
const idDeclEntityDef * brassDef = gameLocal . FindEntityDef ( brassDefName , false ) ;
if ( ! brassDef )
{
2012-11-26 18:58:24 +00:00
gameLocal . Warning ( " Unknown brass '%s' " , brassDefName ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
brassDict = brassDef - > dict ;
}
}
2012-11-28 15:47:07 +00:00
if ( ( ammoType < 0 ) | | ( ammoType > = AMMO_NUMTYPES ) )
{
2012-11-26 18:58:24 +00:00
gameLocal . Warning ( " Unknown ammotype in object '%s' " , objectname ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
ammoClip = ammoinclip ;
2012-11-28 15:47:07 +00:00
if ( ( ammoClip . Get ( ) < 0 ) | | ( ammoClip . Get ( ) > clipSize ) )
{
2012-11-26 18:58:24 +00:00
// first time using this weapon so have it fully loaded to start
ammoClip = clipSize ;
ammoAvail = owner - > inventory . HasAmmo ( ammoType , ammoRequired ) ;
2012-11-28 15:47:07 +00:00
if ( ammoClip . Get ( ) > ammoAvail )
{
2012-11-26 18:58:24 +00:00
ammoClip = ammoAvail ;
}
//In D3XP we use ammo as soon as it is moved into the clip. This allows for weapons that share ammo
owner - > inventory . UseAmmo ( ammoType , ammoClip . Get ( ) ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
renderEntity . gui [ 0 ] = NULL ;
guiName = weaponDef - > dict . GetString ( " gui " ) ;
2012-11-28 15:47:07 +00:00
if ( guiName [ 0 ] )
{
2012-11-26 18:58:24 +00:00
renderEntity . gui [ 0 ] = uiManager - > FindGui ( guiName , true , false , true ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
zoomFov = weaponDef - > dict . GetInt ( " zoomFov " , " 70 " ) ;
berserk = weaponDef - > dict . GetInt ( " berserk " , " 2 " ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
weaponAngleOffsetAverages = weaponDef - > dict . GetInt ( " weaponAngleOffsetAverages " , " 10 " ) ;
weaponAngleOffsetScale = weaponDef - > dict . GetFloat ( " weaponAngleOffsetScale " , " 0.25 " ) ;
weaponAngleOffsetMax = weaponDef - > dict . GetFloat ( " weaponAngleOffsetMax " , " 10 " ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
weaponOffsetTime = weaponDef - > dict . GetFloat ( " weaponOffsetTime " , " 400 " ) ;
weaponOffsetScale = weaponDef - > dict . GetFloat ( " weaponOffsetScale " , " 0.005 " ) ;
2012-11-28 15:47:07 +00:00
if ( ! weaponDef - > dict . GetString ( " weapon_scriptobject " , NULL , & objectType ) )
{
2012-11-26 18:58:24 +00:00
gameLocal . Error ( " No 'weapon_scriptobject' set on '%s'. " , objectname ) ;
}
// setup script object
2012-11-28 15:47:07 +00:00
if ( ! scriptObject . SetType ( objectType ) )
{
2012-11-26 18:58:24 +00:00
gameLocal . Error ( " Script object '%s' not found on weapon '%s'. " , objectType , objectname ) ;
}
2012-11-28 15:47:07 +00:00
WEAPON_ATTACK . LinkTo ( scriptObject , " WEAPON_ATTACK " ) ;
WEAPON_RELOAD . LinkTo ( scriptObject , " WEAPON_RELOAD " ) ;
2012-11-26 18:58:24 +00:00
WEAPON_NETRELOAD . LinkTo ( scriptObject , " WEAPON_NETRELOAD " ) ;
WEAPON_NETENDRELOAD . LinkTo ( scriptObject , " WEAPON_NETENDRELOAD " ) ;
WEAPON_NETFIRING . LinkTo ( scriptObject , " WEAPON_NETFIRING " ) ;
WEAPON_RAISEWEAPON . LinkTo ( scriptObject , " WEAPON_RAISEWEAPON " ) ;
WEAPON_LOWERWEAPON . LinkTo ( scriptObject , " WEAPON_LOWERWEAPON " ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
spawnArgs = weaponDef - > dict ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
shader = spawnArgs . GetString ( " snd_hum " ) ;
2012-11-28 15:47:07 +00:00
if ( shader & & * shader )
{
2012-11-26 18:58:24 +00:00
sndHum = declManager - > FindSound ( shader ) ;
StartSoundShader ( sndHum , SND_CHANNEL_BODY , 0 , false , NULL ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
isLinked = true ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// call script object's constructor
ConstructScriptObject ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// make sure we have the correct skin
UpdateSkin ( ) ;
2012-11-28 15:47:07 +00:00
idEntity * ent = worldModel . GetEntity ( ) ;
2012-11-26 18:58:24 +00:00
DetermineTimeGroup ( weaponDef - > dict . GetBool ( " slowmo " , " 0 " ) ) ;
2012-11-28 15:47:07 +00:00
if ( ent )
{
2012-11-26 18:58:24 +00:00
ent - > DetermineTimeGroup ( weaponDef - > dict . GetBool ( " slowmo " , " 0 " ) ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
//Initialize the particles
2012-11-28 15:47:07 +00:00
if ( ! common - > IsMultiplayer ( ) )
{
const idKeyValue * pkv = weaponDef - > dict . MatchPrefix ( " weapon_particle " , NULL ) ;
while ( pkv )
{
2012-11-26 18:58:24 +00:00
WeaponParticle_t newParticle ;
memset ( & newParticle , 0 , sizeof ( newParticle ) ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idStr name = pkv - > GetValue ( ) ;
2012-11-28 15:47:07 +00:00
strcpy ( newParticle . name , name . c_str ( ) ) ;
idStr jointName = weaponDef - > dict . GetString ( va ( " %s_joint " , name . c_str ( ) ) ) ;
newParticle . joint = animator . GetJointHandle ( jointName . c_str ( ) ) ;
newParticle . smoke = weaponDef - > dict . GetBool ( va ( " %s_smoke " , name . c_str ( ) ) ) ;
2012-11-26 18:58:24 +00:00
newParticle . active = false ;
newParticle . startTime = 0 ;
2012-11-28 15:47:07 +00:00
idStr particle = weaponDef - > dict . GetString ( va ( " %s_particle " , name . c_str ( ) ) ) ;
strcpy ( newParticle . particlename , particle . c_str ( ) ) ;
if ( newParticle . smoke )
{
newParticle . particle = static_cast < const idDeclParticle * > ( declManager - > FindType ( DECL_PARTICLE , particle , false ) ) ;
}
else
{
2012-11-26 18:58:24 +00:00
idDict args ;
2012-11-28 15:47:07 +00:00
const idDeclEntityDef * emitterDef = gameLocal . FindEntityDef ( " func_emitter " , false ) ;
2012-11-26 18:58:24 +00:00
args = emitterDef - > dict ;
2012-11-28 15:47:07 +00:00
args . Set ( " model " , particle . c_str ( ) ) ;
args . SetBool ( " start_off " , true ) ;
2012-11-26 18:58:24 +00:00
idEntity * ent ;
2012-11-28 15:47:07 +00:00
gameLocal . SpawnEntityDef ( args , & ent , false ) ;
newParticle . emitter = ( idFuncEmitter * ) ent ;
if ( newParticle . emitter ! = NULL )
{
newParticle . emitter - > BecomeActive ( TH_THINK ) ;
2012-11-26 18:58:24 +00:00
}
}
2012-11-28 15:47:07 +00:00
weaponParticles . Set ( name . c_str ( ) , newParticle ) ;
2012-11-26 18:58:24 +00:00
pkv = weaponDef - > dict . MatchPrefix ( " weapon_particle " , pkv ) ;
}
2012-11-28 15:47:07 +00:00
const idKeyValue * lkv = weaponDef - > dict . MatchPrefix ( " weapon_light " , NULL ) ;
while ( lkv )
{
2012-11-26 18:58:24 +00:00
WeaponLight_t newLight ;
memset ( & newLight , 0 , sizeof ( newLight ) ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
newLight . lightHandle = - 1 ;
newLight . active = false ;
newLight . startTime = 0 ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idStr name = lkv - > GetValue ( ) ;
2012-11-28 15:47:07 +00:00
strcpy ( newLight . name , name . c_str ( ) ) ;
idStr jointName = weaponDef - > dict . GetString ( va ( " %s_joint " , name . c_str ( ) ) ) ;
newLight . joint = animator . GetJointHandle ( jointName . c_str ( ) ) ;
idStr shader = weaponDef - > dict . GetString ( va ( " %s_shader " , name . c_str ( ) ) ) ;
2012-11-26 18:58:24 +00:00
newLight . light . shader = declManager - > FindMaterial ( shader , false ) ;
2012-11-28 15:47:07 +00:00
float radius = weaponDef - > dict . GetFloat ( va ( " %s_radius " , name . c_str ( ) ) ) ;
2012-11-26 18:58:24 +00:00
newLight . light . lightRadius [ 0 ] = newLight . light . lightRadius [ 1 ] = newLight . light . lightRadius [ 2 ] = radius ;
newLight . light . pointLight = true ;
newLight . light . noShadows = true ;
2012-11-28 15:47:07 +00:00
newLight . light . allowLightInViewID = owner - > entityNumber + 1 ;
weaponLights . Set ( name . c_str ( ) , newLight ) ;
2012-11-26 18:58:24 +00:00
lkv = weaponDef - > dict . MatchPrefix ( " weapon_light " , lkv ) ;
}
}
}
/***********************************************************************
GUIs
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
= = = = = = = = = = = = = = = =
idWeapon : : Icon
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
const char * idWeapon : : Icon ( ) const
{
2012-11-26 18:58:24 +00:00
return icon ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : PdaIcon
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
const char * idWeapon : : PdaIcon ( ) const
{
2012-11-26 18:58:24 +00:00
return pdaIcon ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : DisplayName
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
const char * idWeapon : : DisplayName ( ) const
{
2012-11-26 18:58:24 +00:00
return idLocalization : : GetString ( displayName ) ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : Description
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
const char * idWeapon : : Description ( ) const
{
2012-11-26 18:58:24 +00:00
return idLocalization : : GetString ( itemDesc ) ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : UpdateGUI
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : UpdateGUI ( )
{
if ( ! renderEntity . gui [ 0 ] )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
if ( status = = WP_HOLSTERED )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
if ( owner - > weaponGone )
{
2012-11-26 18:58:24 +00:00
// dropping weapons was implemented wierd, so we have to not update the gui when it happens or we'll get a negative ammo count
return ;
}
2012-11-28 15:47:07 +00:00
if ( ! owner - > IsLocallyControlled ( ) )
{
2012-11-26 18:58:24 +00:00
// if updating the hud for a followed client
2012-11-28 15:47:07 +00:00
if ( gameLocal . GetLocalClientNum ( ) > = 0 & & gameLocal . entities [ gameLocal . GetLocalClientNum ( ) ] & & gameLocal . entities [ gameLocal . GetLocalClientNum ( ) ] - > IsType ( idPlayer : : Type ) )
{
idPlayer * p = static_cast < idPlayer * > ( gameLocal . entities [ gameLocal . GetLocalClientNum ( ) ] ) ;
if ( ! p - > spectating | | p - > spectator ! = owner - > entityNumber )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
return ;
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
int inclip = AmmoInClip ( ) ;
int ammoamount = AmmoAvailable ( ) ;
2012-11-28 15:47:07 +00:00
if ( ammoamount < 0 )
{
2012-11-26 18:58:24 +00:00
// show infinite ammo
renderEntity . gui [ 0 ] - > SetStateString ( " player_ammo " , " " ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
// show remaining ammo
2012-11-28 15:47:07 +00:00
renderEntity . gui [ 0 ] - > SetStateString ( " player_totalammo " , va ( " %i " , ammoamount ) ) ;
2012-11-26 18:58:24 +00:00
renderEntity . gui [ 0 ] - > SetStateString ( " player_ammo " , ClipSize ( ) ? va ( " %i " , inclip ) : " -- " ) ;
2012-11-28 15:47:07 +00:00
renderEntity . gui [ 0 ] - > SetStateString ( " player_clips " , ClipSize ( ) ? va ( " %i " , ammoamount / ClipSize ( ) ) : " -- " ) ;
2012-11-26 18:58:24 +00:00
renderEntity . gui [ 0 ] - > SetStateString ( " player_allammo " , va ( " %i/%i " , inclip , ammoamount ) ) ;
}
renderEntity . gui [ 0 ] - > SetStateBool ( " player_ammo_empty " , ( ammoamount = = 0 ) ) ;
renderEntity . gui [ 0 ] - > SetStateBool ( " player_clip_empty " , ( inclip = = 0 ) ) ;
renderEntity . gui [ 0 ] - > SetStateBool ( " player_clip_low " , ( inclip < = lowAmmo ) ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
//Let the HUD know the total amount of ammo regardless of the ammo required value
2012-11-28 15:47:07 +00:00
renderEntity . gui [ 0 ] - > SetStateString ( " player_ammo_count " , va ( " %i " , AmmoCount ( ) ) ) ;
2012-11-26 18:58:24 +00:00
//Grabber Gui Info
2012-11-28 15:47:07 +00:00
renderEntity . gui [ 0 ] - > SetStateString ( " grabber_state " , va ( " %i " , grabberState ) ) ;
2012-11-26 18:58:24 +00:00
}
/***********************************************************************
Model and muzzleflash
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
= = = = = = = = = = = = = = = =
idWeapon : : UpdateFlashPosition
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : UpdateFlashPosition ( )
{
2012-11-26 18:58:24 +00:00
// the flash has an explicit joint for locating it
GetGlobalJointTransform ( true , flashJointView , muzzleFlash . origin , muzzleFlash . axis ) ;
2012-11-28 15:47:07 +00:00
if ( isPlayerFlashlight )
{
2012-11-26 18:58:24 +00:00
static float pscale = 2.0f ;
static float yscale = 0.25f ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// static idVec3 baseAdjustPos = vec3_zero; //idVec3( 0.0f, 10.0f, 0.0f );
// idVec3 adjustPos = baseAdjustPos;
// muzzleFlash.origin += adjustPos.x * muzzleFlash.axis[1] + adjustPos.y * muzzleFlash.axis[0] + adjustPos.z * muzzleFlash.axis[2];
2012-11-28 15:47:07 +00:00
muzzleFlash . origin + = owner - > GetViewBob ( ) ;
2012-11-26 18:58:24 +00:00
// static idAngles baseAdjustAng = ang_zero; //idAngles( 0.0f, 10.0f, 0.0f );
idAngles adjustAng = /*baseAdjustAng +*/ idAngles ( fraccos * yscale , 0.0f , fraccos2 * pscale ) ;
idAngles bobAngles = owner - > GetViewBobAngles ( ) ;
SwapValues ( bobAngles . pitch , bobAngles . roll ) ;
adjustAng + = bobAngles * 3.0f ;
muzzleFlash . axis = adjustAng . ToMat3 ( ) * muzzleFlash . axis /** adjustAng.ToMat3()*/ ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// if the desired point is inside or very close to a wall, back it up until it is clear
idVec3 start = muzzleFlash . origin - playerViewAxis [ 0 ] * 16 ;
idVec3 end = muzzleFlash . origin + playerViewAxis [ 0 ] * 8 ;
trace_t tr ;
gameLocal . clip . TracePoint ( tr , start , end , MASK_SHOT_RENDERMODEL , owner ) ;
// be at least 8 units away from a solid
muzzleFlash . origin = tr . endpos - playerViewAxis [ 0 ] * 8 ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
muzzleFlash . noShadows = ! g_weaponShadows . GetBool ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// put the world muzzle flash on the end of the joint, no matter what
GetGlobalJointTransform ( false , flashJointWorld , worldMuzzleFlash . origin , worldMuzzleFlash . axis ) ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : MuzzleFlashLight
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : MuzzleFlashLight ( )
{
if ( ! lightOn & & ( ! g_muzzleFlash . GetBool ( ) | | ! muzzleFlash . lightRadius [ 0 ] ) )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
if ( flashJointView = = INVALID_JOINT )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
UpdateFlashPosition ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// these will be different each fire
muzzleFlash . shaderParms [ SHADERPARM_TIMEOFFSET ] = - MS2SEC ( gameLocal . time ) ;
muzzleFlash . shaderParms [ SHADERPARM_DIVERSITY ] = renderEntity . shaderParms [ SHADERPARM_DIVERSITY ] ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
worldMuzzleFlash . shaderParms [ SHADERPARM_TIMEOFFSET ] = - MS2SEC ( gameLocal . time ) ;
worldMuzzleFlash . shaderParms [ SHADERPARM_DIVERSITY ] = renderEntity . shaderParms [ SHADERPARM_DIVERSITY ] ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// the light will be removed at this time
muzzleFlashEnd = gameLocal . time + flashTime ;
2012-11-28 15:47:07 +00:00
if ( muzzleFlashHandle ! = - 1 )
{
2012-11-26 18:58:24 +00:00
gameRenderWorld - > UpdateLightDef ( muzzleFlashHandle , & muzzleFlash ) ;
gameRenderWorld - > UpdateLightDef ( worldMuzzleFlashHandle , & worldMuzzleFlash ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
muzzleFlashHandle = gameRenderWorld - > AddLightDef ( & muzzleFlash ) ;
worldMuzzleFlashHandle = gameRenderWorld - > AddLightDef ( & worldMuzzleFlash ) ;
}
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : UpdateSkin
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idWeapon : : UpdateSkin ( )
{
const function_t * func ;
if ( ! isLinked )
{
2012-11-26 18:58:24 +00:00
return false ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
func = scriptObject . GetFunction ( " UpdateSkin " ) ;
2012-11-28 15:47:07 +00:00
if ( ! func )
{
2012-11-26 18:58:24 +00:00
common - > Warning ( " Can't find function 'UpdateSkin' in object '%s' " , scriptObject . GetTypeName ( ) ) ;
return false ;
}
// use the frameCommandThread since it's safe to use outside of framecommands
gameLocal . frameCommandThread - > CallFunction ( this , func , true ) ;
gameLocal . frameCommandThread - > Execute ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return true ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : FlashlightOn
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : FlashlightOn ( )
{
const function_t * func ;
if ( ! isLinked )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
func = scriptObject . GetFunction ( " TurnOn " ) ;
2012-11-28 15:47:07 +00:00
if ( ! func )
{
2012-11-26 18:58:24 +00:00
common - > Warning ( " Can't find function 'TurnOn' in object '%s' " , scriptObject . GetTypeName ( ) ) ;
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// use the frameCommandThread since it's safe to use outside of framecommands
gameLocal . frameCommandThread - > CallFunction ( this , func , true ) ;
gameLocal . frameCommandThread - > Execute ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : FlashlightOff
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : FlashlightOff ( )
{
const function_t * func ;
if ( ! isLinked )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
func = scriptObject . GetFunction ( " TurnOff " ) ;
2012-11-28 15:47:07 +00:00
if ( ! func )
{
2012-11-26 18:58:24 +00:00
common - > Warning ( " Can't find function 'TurnOff' in object '%s' " , scriptObject . GetTypeName ( ) ) ;
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// use the frameCommandThread since it's safe to use outside of framecommands
gameLocal . frameCommandThread - > CallFunction ( this , func , true ) ;
gameLocal . frameCommandThread - > Execute ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : SetModel
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : SetModel ( const char * modelname )
{
2012-11-26 18:58:24 +00:00
assert ( modelname ) ;
2012-11-28 15:47:07 +00:00
if ( modelDefHandle > = 0 )
{
2012-11-26 18:58:24 +00:00
gameRenderWorld - > RemoveDecals ( modelDefHandle ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
renderEntity . hModel = animator . SetModel ( modelname ) ;
2012-11-28 15:47:07 +00:00
if ( renderEntity . hModel )
{
2012-11-26 18:58:24 +00:00
renderEntity . customSkin = animator . ModelDef ( ) - > GetDefaultSkin ( ) ;
animator . GetJoints ( & renderEntity . numJoints , & renderEntity . joints ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
renderEntity . customSkin = NULL ;
renderEntity . callback = NULL ;
renderEntity . numJoints = 0 ;
renderEntity . joints = NULL ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// hide the model until an animation is played
Hide ( ) ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : GetGlobalJointTransform
This returns the offset and axis of a weapon bone in world space , suitable for attaching models or lights
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idWeapon : : GetGlobalJointTransform ( bool viewModel , const jointHandle_t jointHandle , idVec3 & offset , idMat3 & axis )
{
if ( viewModel )
{
2012-11-26 18:58:24 +00:00
// view model
2012-11-28 15:47:07 +00:00
if ( animator . GetJointTransform ( jointHandle , gameLocal . time , offset , axis ) )
{
2012-11-26 18:58:24 +00:00
offset = offset * viewWeaponAxis + viewWeaponOrigin ;
axis = axis * viewWeaponAxis ;
return true ;
}
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
// world model
2012-11-28 15:47:07 +00:00
if ( worldModel . GetEntity ( ) & & worldModel . GetEntity ( ) - > GetAnimator ( ) - > GetJointTransform ( jointHandle , gameLocal . time , offset , axis ) )
{
2012-11-26 18:58:24 +00:00
offset = worldModel . GetEntity ( ) - > GetPhysics ( ) - > GetOrigin ( ) + offset * worldModel . GetEntity ( ) - > GetPhysics ( ) - > GetAxis ( ) ;
axis = axis * worldModel . GetEntity ( ) - > GetPhysics ( ) - > GetAxis ( ) ;
return true ;
}
}
offset = viewWeaponOrigin ;
axis = viewWeaponAxis ;
return false ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : SetPushVelocity
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : SetPushVelocity ( const idVec3 & pushVelocity )
{
2012-11-26 18:58:24 +00:00
this - > pushVelocity = pushVelocity ;
}
/***********************************************************************
State control / player interface
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
= = = = = = = = = = = = = = = =
idWeapon : : Think
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : Think ( )
{
2012-11-26 18:58:24 +00:00
// do nothing because the present is called from the player through PresentWeapon
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : Raise
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : Raise ( )
{
if ( isLinked )
{
2012-11-26 18:58:24 +00:00
WEAPON_RAISEWEAPON = true ;
}
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : PutAway
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : PutAway ( )
{
2012-11-26 18:58:24 +00:00
hasBloodSplat = false ;
2012-11-28 15:47:07 +00:00
if ( isLinked )
{
2012-11-26 18:58:24 +00:00
WEAPON_LOWERWEAPON = true ;
}
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : Reload
NOTE : this is only for impulse - triggered reload , auto reload is scripted
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : Reload ( )
{
if ( isLinked )
{
2012-11-26 18:58:24 +00:00
WEAPON_RELOAD = true ;
}
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : LowerWeapon
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : LowerWeapon ( )
{
if ( ! hide )
{
2012-11-26 18:58:24 +00:00
hideStart = 0.0f ;
hideEnd = hideDistance ;
2012-11-28 15:47:07 +00:00
if ( gameLocal . time - hideStartTime < hideTime )
{
2012-11-26 18:58:24 +00:00
hideStartTime = gameLocal . time - ( hideTime - ( gameLocal . time - hideStartTime ) ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
hideStartTime = gameLocal . time ;
}
hide = true ;
}
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : RaiseWeapon
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : RaiseWeapon ( )
{
2012-11-26 18:58:24 +00:00
Show ( ) ;
2012-11-28 15:47:07 +00:00
if ( hide )
{
2012-11-26 18:58:24 +00:00
hideStart = hideDistance ;
hideEnd = 0.0f ;
2012-11-28 15:47:07 +00:00
if ( gameLocal . time - hideStartTime < hideTime )
{
2012-11-26 18:58:24 +00:00
hideStartTime = gameLocal . time - ( hideTime - ( gameLocal . time - hideStartTime ) ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
hideStartTime = gameLocal . time ;
}
hide = false ;
}
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : HideWeapon
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : HideWeapon ( )
{
2012-11-26 18:58:24 +00:00
Hide ( ) ;
2012-11-28 15:47:07 +00:00
if ( worldModel . GetEntity ( ) )
{
2012-11-26 18:58:24 +00:00
worldModel . GetEntity ( ) - > Hide ( ) ;
}
muzzleFlashEnd = 0 ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : ShowWeapon
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : ShowWeapon ( )
{
2012-11-26 18:58:24 +00:00
Show ( ) ;
2012-11-28 15:47:07 +00:00
if ( worldModel . GetEntity ( ) )
{
2012-11-26 18:58:24 +00:00
worldModel . GetEntity ( ) - > Show ( ) ;
}
2012-11-28 15:47:07 +00:00
if ( lightOn )
{
2012-11-26 18:58:24 +00:00
MuzzleFlashLight ( ) ;
}
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : HideWorldModel
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : HideWorldModel ( )
{
if ( worldModel . GetEntity ( ) )
{
2012-11-26 18:58:24 +00:00
worldModel . GetEntity ( ) - > Hide ( ) ;
}
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : ShowWorldModel
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : ShowWorldModel ( )
{
if ( worldModel . GetEntity ( ) )
{
2012-11-26 18:58:24 +00:00
worldModel . GetEntity ( ) - > Show ( ) ;
}
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : OwnerDied
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : OwnerDied ( )
{
if ( isLinked )
{
2012-11-26 18:58:24 +00:00
SetState ( " OwnerDied " , 0 ) ;
thread - > Execute ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// Update the grabber effects
2012-11-28 15:47:07 +00:00
if ( /*!common->IsMultiplayer() &&*/ grabberState ! = - 1 )
{
2012-11-26 18:58:24 +00:00
grabber . Update ( owner , hide ) ;
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
Hide ( ) ;
2012-11-28 15:47:07 +00:00
if ( worldModel . GetEntity ( ) )
{
2012-11-26 18:58:24 +00:00
worldModel . GetEntity ( ) - > Hide ( ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// don't clear the weapon immediately since the owner might have killed himself by firing the weapon
// within the current stack frame
PostEventMS ( & EV_Weapon_Clear , 0 ) ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : BeginAttack
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : BeginAttack ( )
{
if ( status ! = WP_OUTOFAMMO )
{
2012-11-26 18:58:24 +00:00
lastAttack = gameLocal . time ;
}
2012-11-28 15:47:07 +00:00
if ( ! isLinked )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
if ( ! WEAPON_ATTACK )
{
if ( sndHum & & grabberState = = - 1 ) // _D3XP :: don't stop grabber hum
{
2012-11-26 18:58:24 +00:00
StopSound ( SND_CHANNEL_BODY , false ) ;
}
}
WEAPON_ATTACK = true ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : EndAttack
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : EndAttack ( )
{
if ( ! WEAPON_ATTACK . IsLinked ( ) )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
if ( WEAPON_ATTACK )
{
2012-11-26 18:58:24 +00:00
WEAPON_ATTACK = false ;
2012-11-28 15:47:07 +00:00
if ( sndHum & & grabberState = = - 1 ) // _D3XP :: don't stop grabber hum
{
2012-11-26 18:58:24 +00:00
StartSoundShader ( sndHum , SND_CHANNEL_BODY , 0 , false , NULL ) ;
}
}
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : isReady
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idWeapon : : IsReady ( ) const
{
2012-11-26 18:58:24 +00:00
return ! hide & & ! IsHidden ( ) & & ( ( status = = WP_RELOAD ) | | ( status = = WP_READY ) | | ( status = = WP_OUTOFAMMO ) ) ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : IsReloading
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idWeapon : : IsReloading ( ) const
{
2012-11-26 18:58:24 +00:00
return ( status = = WP_RELOAD ) ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : IsHolstered
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idWeapon : : IsHolstered ( ) const
{
2012-11-26 18:58:24 +00:00
return ( status = = WP_HOLSTERED ) ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : ShowCrosshair
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idWeapon : : ShowCrosshair ( ) const
{
2012-11-26 18:58:24 +00:00
// JDC: this code would never function as written, I'm assuming they wanted the following behavior
// return !( state == idStr( WP_RISING ) || state == idStr( WP_LOWERING ) || state == idStr( WP_HOLSTERED ) );
return ! ( status = = WP_RISING | | status = = WP_LOWERING | | status = = WP_HOLSTERED | | status = = WP_RELOAD ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idWeapon : : CanDrop
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idWeapon : : CanDrop ( ) const
{
if ( ! weaponDef | | ! worldModel . GetEntity ( ) )
{
2012-11-26 18:58:24 +00:00
return false ;
}
2012-11-28 15:47:07 +00:00
const char * classname = weaponDef - > dict . GetString ( " def_dropItem " ) ;
if ( ! classname [ 0 ] )
{
2012-11-26 18:58:24 +00:00
return false ;
}
return true ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : WeaponStolen
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : WeaponStolen ( )
{
2012-11-26 18:58:24 +00:00
assert ( ! common - > IsClient ( ) ) ;
2012-11-28 15:47:07 +00:00
if ( projectileEnt )
{
if ( isLinked )
{
2012-11-26 18:58:24 +00:00
SetState ( " WeaponStolen " , 0 ) ;
thread - > Execute ( ) ;
}
projectileEnt = NULL ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// set to holstered so we can switch weapons right away
status = WP_HOLSTERED ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
HideWeapon ( ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idWeapon : : DropItem
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
idEntity * idWeapon : : DropItem ( const idVec3 & velocity , int activateDelay , int removeDelay , bool died )
{
if ( ! weaponDef | | ! worldModel . GetEntity ( ) )
{
2012-11-26 18:58:24 +00:00
return NULL ;
}
2012-11-28 15:47:07 +00:00
if ( ! allowDrop )
{
2012-11-26 18:58:24 +00:00
return NULL ;
}
2012-11-28 15:47:07 +00:00
const char * classname = weaponDef - > dict . GetString ( " def_dropItem " ) ;
if ( ! classname [ 0 ] )
{
2012-11-26 18:58:24 +00:00
return NULL ;
}
StopSound ( SND_CHANNEL_BODY , true ) ;
StopSound ( SND_CHANNEL_BODY3 , true ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return idMoveableItem : : DropItem ( classname , worldModel . GetEntity ( ) - > GetPhysics ( ) - > GetOrigin ( ) , worldModel . GetEntity ( ) - > GetPhysics ( ) - > GetAxis ( ) , velocity , activateDelay , removeDelay ) ;
}
/***********************************************************************
Script state management
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
= = = = = = = = = = = = = = = = = = = = =
idWeapon : : SetState
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : SetState ( const char * statename , int blendFrames )
{
const function_t * func ;
if ( ! isLinked )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
func = scriptObject . GetFunction ( statename ) ;
2012-11-28 15:47:07 +00:00
if ( ! func )
{
2012-11-26 18:58:24 +00:00
assert ( 0 ) ;
gameLocal . Error ( " Can't find function '%s' in object '%s' " , statename , scriptObject . GetTypeName ( ) ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
thread - > CallFunction ( this , func , true ) ;
state = statename ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
animBlendFrames = blendFrames ;
2012-11-28 15:47:07 +00:00
if ( g_debugWeapon . GetBool ( ) )
{
2012-11-26 18:58:24 +00:00
gameLocal . Printf ( " %d: weapon state : %s \n " , gameLocal . time , statename ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idealState = " " ;
}
/***********************************************************************
Particles / Effects
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
= = = = = = = = = = = = = = = =
idWeapon : : UpdateNozzelFx
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : UpdateNozzleFx ( )
{
if ( ! nozzleFx )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
//
// shader parms
//
int la = gameLocal . time - lastAttack + 1 ;
float s = 1.0f ;
float l = 0.0f ;
2012-11-28 15:47:07 +00:00
if ( la < nozzleFxFade )
{
s = ( ( float ) la / nozzleFxFade ) ;
2012-11-26 18:58:24 +00:00
l = 1.0f - s ;
}
renderEntity . shaderParms [ 5 ] = s ;
renderEntity . shaderParms [ 6 ] = l ;
2012-11-28 15:47:07 +00:00
if ( ventLightJointView = = INVALID_JOINT )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
//
// vent light
//
2012-11-28 15:47:07 +00:00
if ( nozzleGlowHandle = = - 1 )
{
memset ( & nozzleGlow , 0 , sizeof ( nozzleGlow ) ) ;
if ( owner )
{
nozzleGlow . allowLightInViewID = owner - > entityNumber + 1 ;
2012-11-26 18:58:24 +00:00
}
nozzleGlow . pointLight = true ;
nozzleGlow . noShadows = true ;
nozzleGlow . lightRadius . x = nozzleGlowRadius ;
nozzleGlow . lightRadius . y = nozzleGlowRadius ;
nozzleGlow . lightRadius . z = nozzleGlowRadius ;
nozzleGlow . shader = nozzleGlowShader ;
nozzleGlow . shaderParms [ SHADERPARM_TIMESCALE ] = 1.0f ;
nozzleGlow . shaderParms [ SHADERPARM_TIMEOFFSET ] = - MS2SEC ( gameLocal . time ) ;
GetGlobalJointTransform ( true , ventLightJointView , nozzleGlow . origin , nozzleGlow . axis ) ;
2012-11-28 15:47:07 +00:00
nozzleGlowHandle = gameRenderWorld - > AddLightDef ( & nozzleGlow ) ;
2012-11-26 18:58:24 +00:00
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
GetGlobalJointTransform ( true , ventLightJointView , nozzleGlow . origin , nozzleGlow . axis ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
nozzleGlow . shaderParms [ SHADERPARM_RED ] = nozzleGlowColor . x * s ;
nozzleGlow . shaderParms [ SHADERPARM_GREEN ] = nozzleGlowColor . y * s ;
nozzleGlow . shaderParms [ SHADERPARM_BLUE ] = nozzleGlowColor . z * s ;
2012-11-28 15:47:07 +00:00
gameRenderWorld - > UpdateLightDef ( nozzleGlowHandle , & nozzleGlow ) ;
2012-11-26 18:58:24 +00:00
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : BloodSplat
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idWeapon : : BloodSplat ( float size )
{
2012-11-26 18:58:24 +00:00
float s , c ;
idMat3 localAxis , axistemp ;
idVec3 localOrigin , normal ;
2012-11-28 15:47:07 +00:00
if ( hasBloodSplat )
{
2012-11-26 18:58:24 +00:00
return true ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
hasBloodSplat = true ;
2012-11-28 15:47:07 +00:00
if ( modelDefHandle < 0 )
{
2012-11-26 18:58:24 +00:00
return false ;
}
2012-11-28 15:47:07 +00:00
if ( ! GetGlobalJointTransform ( true , ejectJointView , localOrigin , localAxis ) )
{
2012-11-26 18:58:24 +00:00
return false ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
localOrigin [ 0 ] + = gameLocal . random . RandomFloat ( ) * - 10.0f ;
localOrigin [ 1 ] + = gameLocal . random . RandomFloat ( ) * 1.0f ;
localOrigin [ 2 ] + = gameLocal . random . RandomFloat ( ) * - 2.0f ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
normal = idVec3 ( gameLocal . random . CRandomFloat ( ) , - gameLocal . random . RandomFloat ( ) , - 1 ) ;
normal . Normalize ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idMath : : SinCos16 ( gameLocal . random . RandomFloat ( ) * idMath : : TWO_PI , s , c ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
localAxis [ 2 ] = - normal ;
localAxis [ 2 ] . NormalVectors ( axistemp [ 0 ] , axistemp [ 1 ] ) ;
localAxis [ 0 ] = axistemp [ 0 ] * c + axistemp [ 1 ] * - s ;
localAxis [ 1 ] = axistemp [ 0 ] * - s + axistemp [ 1 ] * - c ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
localAxis [ 0 ] * = 1.0f / size ;
localAxis [ 1 ] * = 1.0f / size ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idPlane localPlane [ 2 ] ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
localPlane [ 0 ] = localAxis [ 0 ] ;
2012-11-28 15:47:07 +00:00
localPlane [ 0 ] [ 3 ] = - ( localOrigin * localAxis [ 0 ] ) + 0.5f ;
2012-11-26 18:58:24 +00:00
localPlane [ 1 ] = localAxis [ 1 ] ;
2012-11-28 15:47:07 +00:00
localPlane [ 1 ] [ 3 ] = - ( localOrigin * localAxis [ 1 ] ) + 0.5f ;
const idMaterial * mtr = declManager - > FindMaterial ( " textures/decals/duffysplatgun " ) ;
2012-11-26 18:58:24 +00:00
gameRenderWorld - > ProjectOverlay ( modelDefHandle , localPlane , mtr , gameLocal . slow . time ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return true ;
}
/***********************************************************************
Visual presentation
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
= = = = = = = = = = = = = = = =
idWeapon : : MuzzleRise
The machinegun and chaingun will incrementally back up as they are being fired
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : MuzzleRise ( idVec3 & origin , idMat3 & axis )
{
2012-11-26 18:58:24 +00:00
int time ;
float amount ;
idAngles ang ;
idVec3 offset ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
time = kick_endtime - gameLocal . time ;
2012-11-28 15:47:07 +00:00
if ( time < = 0 )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
if ( muzzle_kick_maxtime < = 0 )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
if ( time > muzzle_kick_maxtime )
{
2012-11-26 18:58:24 +00:00
time = muzzle_kick_maxtime ;
}
amount = ( float ) time / ( float ) muzzle_kick_maxtime ;
ang = muzzle_kick_angles * amount ;
offset = muzzle_kick_offset * amount ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
origin = origin - axis * offset ;
axis = ang . ToMat3 ( ) * axis ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : ConstructScriptObject
Called during idEntity : : Spawn . Calls the constructor on the script object .
Can be overridden by subclasses when a thread doesn ' t need to be allocated .
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
idThread * idWeapon : : ConstructScriptObject ( )
{
const function_t * constructor ;
2012-11-26 18:58:24 +00:00
thread - > EndThread ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// call script object's constructor
constructor = scriptObject . GetConstructor ( ) ;
2012-11-28 15:47:07 +00:00
if ( ! constructor )
{
2012-11-26 18:58:24 +00:00
gameLocal . Error ( " Missing constructor on '%s' for weapon " , scriptObject . GetTypeName ( ) ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// init the script object's data
scriptObject . ClearObject ( ) ;
thread - > CallFunction ( this , constructor , true ) ;
thread - > Execute ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return thread ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : DeconstructScriptObject
Called during idEntity : : ~ idEntity . Calls the destructor on the script object .
Can be overridden by subclasses when a thread doesn ' t need to be allocated .
Not called during idGameLocal : : MapShutdown .
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : DeconstructScriptObject ( )
{
const function_t * destructor ;
if ( ! thread )
{
2012-11-26 18:58:24 +00:00
return ;
}
// don't bother calling the script object's destructor on map shutdown
2012-11-28 15:47:07 +00:00
if ( gameLocal . GameState ( ) = = GAMESTATE_SHUTDOWN )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
thread - > EndThread ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// call script object's destructor
destructor = scriptObject . GetDestructor ( ) ;
2012-11-28 15:47:07 +00:00
if ( destructor )
{
2012-11-26 18:58:24 +00:00
// start a thread that will run immediately and end
thread - > CallFunction ( this , destructor , true ) ;
thread - > Execute ( ) ;
thread - > EndThread ( ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// clear out the object's memory
scriptObject . ClearObject ( ) ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : UpdateScript
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : UpdateScript ( )
{
2012-11-26 18:58:24 +00:00
int count ;
2012-11-28 15:47:07 +00:00
if ( ! isLinked )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// only update the script on new frames
2012-11-28 15:47:07 +00:00
if ( ! gameLocal . isNewFrame )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
if ( idealState . Length ( ) )
{
2012-11-26 18:58:24 +00:00
SetState ( idealState , animBlendFrames ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// update script state, which may call Event_LaunchProjectiles, among other things
count = 10 ;
2012-11-28 15:47:07 +00:00
while ( ( thread - > Execute ( ) | | idealState . Length ( ) ) & & count - - )
{
2012-11-26 18:58:24 +00:00
// happens for weapons with no clip (like grenades)
2012-11-28 15:47:07 +00:00
if ( idealState . Length ( ) )
{
2012-11-26 18:58:24 +00:00
SetState ( idealState , animBlendFrames ) ;
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
WEAPON_RELOAD = false ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : AlertMonsters
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : AlertMonsters ( )
{
2012-11-26 18:58:24 +00:00
trace_t tr ;
2012-11-28 15:47:07 +00:00
idEntity * ent ;
2012-11-26 18:58:24 +00:00
idVec3 end = muzzleFlash . origin + muzzleFlash . axis * muzzleFlash . target ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
gameLocal . clip . TracePoint ( tr , muzzleFlash . origin , end , CONTENTS_OPAQUE | MASK_SHOT_RENDERMODEL | CONTENTS_FLASHLIGHT_TRIGGER , owner ) ;
2012-11-28 15:47:07 +00:00
if ( g_debugWeapon . GetBool ( ) )
{
2012-11-26 18:58:24 +00:00
gameRenderWorld - > DebugLine ( colorYellow , muzzleFlash . origin , end , 0 ) ;
gameRenderWorld - > DebugArrow ( colorGreen , muzzleFlash . origin , tr . endpos , 2 , 0 ) ;
}
2012-11-28 15:47:07 +00:00
if ( tr . fraction < 1.0f )
{
2012-11-26 18:58:24 +00:00
ent = gameLocal . GetTraceEntity ( tr ) ;
2012-11-28 15:47:07 +00:00
if ( ent - > IsType ( idAI : : Type ) )
{
static_cast < idAI * > ( ent ) - > TouchedByFlashlight ( owner ) ;
}
else if ( ent - > IsType ( idTrigger : : Type ) )
{
2012-11-26 18:58:24 +00:00
ent - > Signal ( SIG_TOUCH ) ;
ent - > ProcessEvent ( & EV_Touch , owner , & tr ) ;
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// jitter the trace to try to catch cases where a trace down the center doesn't hit the monster
end + = muzzleFlash . axis * muzzleFlash . right * idMath : : Sin16 ( MS2SEC ( gameLocal . time ) * 31.34f ) ;
end + = muzzleFlash . axis * muzzleFlash . up * idMath : : Sin16 ( MS2SEC ( gameLocal . time ) * 12.17f ) ;
gameLocal . clip . TracePoint ( tr , muzzleFlash . origin , end , CONTENTS_OPAQUE | MASK_SHOT_RENDERMODEL | CONTENTS_FLASHLIGHT_TRIGGER , owner ) ;
2012-11-28 15:47:07 +00:00
if ( g_debugWeapon . GetBool ( ) )
{
2012-11-26 18:58:24 +00:00
gameRenderWorld - > DebugLine ( colorYellow , muzzleFlash . origin , end , 0 ) ;
gameRenderWorld - > DebugArrow ( colorGreen , muzzleFlash . origin , tr . endpos , 2 , 0 ) ;
}
2012-11-28 15:47:07 +00:00
if ( tr . fraction < 1.0f )
{
2012-11-26 18:58:24 +00:00
ent = gameLocal . GetTraceEntity ( tr ) ;
2012-11-28 15:47:07 +00:00
if ( ent - > IsType ( idAI : : Type ) )
{
static_cast < idAI * > ( ent ) - > TouchedByFlashlight ( owner ) ;
}
else if ( ent - > IsType ( idTrigger : : Type ) )
{
2012-11-26 18:58:24 +00:00
ent - > Signal ( SIG_TOUCH ) ;
ent - > ProcessEvent ( & EV_Touch , owner , & tr ) ;
}
}
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : GetMuzzlePositionWithHacks
Some weapons that have a barrel joint either have it pointing in the wrong
direction ( rocket launcher ) , or don ' t animate it properly ( pistol ) .
For good 3 D TV / head mounted display work , we need to display a laser sight
in the world .
Fixing the animated meshes would be ideal , but hacking it in code is
the pragmatic move right now .
Returns false for hands , grenades , and chainsaw .
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idWeapon : : GetMuzzlePositionWithHacks ( idVec3 & origin , idMat3 & axis )
{
2012-11-26 18:58:24 +00:00
// I couldn't find a simple enum to identify the weapons that need
// workaround hacks...
2012-11-28 15:47:07 +00:00
const idStr & weaponIconName = pdaIcon ;
2012-11-26 18:58:24 +00:00
origin = playerViewOrigin ;
axis = playerViewAxis ;
2012-11-28 15:47:07 +00:00
if ( weaponIconName = = " guis/assets/hud/icons/grenade_new.tga " )
{
2012-11-26 18:58:24 +00:00
return false ;
}
2012-11-28 15:47:07 +00:00
if ( weaponIconName = = " guis/assets/hud/icons/chainsaw_new.tga " )
{
2012-11-26 18:58:24 +00:00
return false ;
}
2012-11-28 15:47:07 +00:00
if ( weaponIconName = = " guis/assets/hud/icons/soul_cube.tga " )
{
2012-11-26 18:58:24 +00:00
return false ;
}
2012-11-28 15:47:07 +00:00
if ( barrelJointView ! = INVALID_JOINT )
{
2012-11-26 18:58:24 +00:00
GetGlobalJointTransform ( true , barrelJointView , origin , axis ) ;
2012-11-28 15:47:07 +00:00
}
else if ( guiLightJointView ! = INVALID_JOINT )
{
2012-11-26 18:58:24 +00:00
GetGlobalJointTransform ( true , guiLightJointView , origin , axis ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
return false ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// get better axis joints for weapons where the barrelJointView isn't
// animated properly
idVec3 discardedOrigin ;
2012-11-28 15:47:07 +00:00
if ( weaponIconName = = " guis/assets/hud/icons/pistol_new.tga " )
{
2012-11-26 18:58:24 +00:00
// muzzle doesn't animate during firing, Bod does
const jointHandle_t bodJoint = animator . GetJointHandle ( " Bod " ) ;
GetGlobalJointTransform ( true , bodJoint , discardedOrigin , axis ) ;
}
2012-11-28 15:47:07 +00:00
if ( weaponIconName = = " guis/assets/hud/icons/rocketlauncher_new.tga " )
{
2012-11-26 18:58:24 +00:00
// joint doesn't point straight, so rotate it
std : : swap ( axis [ 0 ] , axis [ 2 ] ) ;
}
2012-11-28 15:47:07 +00:00
if ( weaponIconName = = " guis/assets/hud/icons/shotgun_new.tga " )
{
2012-11-26 18:58:24 +00:00
// joint doesn't point straight, so rotate it
const jointHandle_t bodJoint = animator . GetJointHandle ( " trigger " ) ;
GetGlobalJointTransform ( true , bodJoint , discardedOrigin , axis ) ;
std : : swap ( axis [ 0 ] , axis [ 2 ] ) ;
axis [ 0 ] = - axis [ 0 ] ;
}
// we probably should fix the above hacks above that are based on texture names above at some
// point
2012-11-28 15:47:07 +00:00
if ( weaponDef ! = NULL )
{
if ( ( idStr : : Icmp ( " weapon_shotgun_double " , weaponDef - > GetName ( ) ) = = 0 ) | | ( idStr : : Icmp ( " weapon_shotgun_double_mp " , weaponDef - > GetName ( ) ) = = 0 ) )
{
2012-11-26 18:58:24 +00:00
// joint doesn't point straight, so rotate it
std : : swap ( axis [ 0 ] , axis [ 2 ] ) ;
2012-11-28 15:47:07 +00:00
}
else if ( idStr : : Icmp ( " weapon_grabber " , weaponDef - > GetName ( ) ) = = 0 )
{
2012-11-26 18:58:24 +00:00
idVec3 forward = axis [ 0 ] ;
forward . Normalize ( ) ;
const float scaleOffset = 4.0f ;
forward * = scaleOffset ;
origin + = forward ;
}
}
return true ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : PresentWeapon
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : PresentWeapon ( bool showViewModel )
{
2012-11-26 18:58:24 +00:00
playerViewOrigin = owner - > firstPersonViewOrigin ;
playerViewAxis = owner - > firstPersonViewAxis ;
2012-11-28 15:47:07 +00:00
if ( isPlayerFlashlight )
{
2012-11-26 18:58:24 +00:00
viewWeaponOrigin = playerViewOrigin ;
viewWeaponAxis = playerViewAxis ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
fraccos = cos ( ( gameLocal . framenum & 255 ) / 127.0f * idMath : : PI ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
static unsigned int divisor = 32 ;
unsigned int val = ( gameLocal . framenum + gameLocal . framenum / divisor ) & 255 ;
fraccos2 = cos ( val / 127.0f * idMath : : PI ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
static idVec3 baseAdjustPos = idVec3 ( - 8.0f , - 20.0f , - 10.0f ) ; // rt, fwd, up
static float pscale = 0.5f ;
static float yscale = 0.125f ;
idVec3 adjustPos = baseAdjustPos ; // + ( idVec3( fraccos, 0.0f, fraccos2 ) * scale );
viewWeaponOrigin + = adjustPos . x * viewWeaponAxis [ 1 ] + adjustPos . y * viewWeaponAxis [ 0 ] + adjustPos . z * viewWeaponAxis [ 2 ] ;
// viewWeaponOrigin += owner->viewBob;
static idAngles baseAdjustAng = idAngles ( 88.0f , 10.0f , 0.0f ) ; //
idAngles adjustAng = baseAdjustAng + idAngles ( fraccos * pscale , fraccos2 * yscale , 0.0f ) ;
// adjustAng += owner->GetViewBobAngles();
viewWeaponAxis = adjustAng . ToMat3 ( ) * viewWeaponAxis ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
// calculate weapon position based on player movement bobbing
owner - > CalculateViewWeaponPos ( viewWeaponOrigin , viewWeaponAxis ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// hide offset is for dropping the gun when approaching a GUI or NPC
// This is simpler to manage than doing the weapon put-away animation
2012-11-28 15:47:07 +00:00
if ( gameLocal . time - hideStartTime < hideTime )
{
2012-11-26 18:58:24 +00:00
float frac = ( float ) ( gameLocal . time - hideStartTime ) / ( float ) hideTime ;
2012-11-28 15:47:07 +00:00
if ( hideStart < hideEnd )
{
2012-11-26 18:58:24 +00:00
frac = 1.0f - frac ;
frac = 1.0f - frac * frac ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
frac = frac * frac ;
}
hideOffset = hideStart + ( hideEnd - hideStart ) * frac ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
hideOffset = hideEnd ;
2012-11-28 15:47:07 +00:00
if ( hide & & disabled )
{
2012-11-26 18:58:24 +00:00
Hide ( ) ;
}
}
viewWeaponOrigin + = hideOffset * viewWeaponAxis [ 2 ] ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// kick up based on repeat firing
MuzzleRise ( viewWeaponOrigin , viewWeaponAxis ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// set the physics position and orientation
GetPhysics ( ) - > SetOrigin ( viewWeaponOrigin ) ;
GetPhysics ( ) - > SetAxis ( viewWeaponAxis ) ;
UpdateVisuals ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// update the weapon script
UpdateScript ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
UpdateGUI ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// update animation
UpdateAnimation ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// only show the surface in player view
2012-11-28 15:47:07 +00:00
renderEntity . allowSurfaceInViewID = owner - > entityNumber + 1 ;
2012-11-26 18:58:24 +00:00
// crunch the depth range so it never pokes into walls this breaks the machine gun gui
renderEntity . weaponDepthHack = g_useWeaponDepthHack . GetBool ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// present the model
2012-11-28 15:47:07 +00:00
if ( showViewModel )
{
2012-11-26 18:58:24 +00:00
Present ( ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
FreeModelDef ( ) ;
}
2012-11-28 15:47:07 +00:00
if ( worldModel . GetEntity ( ) & & worldModel . GetEntity ( ) - > GetRenderEntity ( ) )
{
2012-11-26 18:58:24 +00:00
// deal with the third-person visible world model
// don't show shadows of the world model in first person
2012-11-28 15:47:07 +00:00
if ( common - > IsMultiplayer ( ) | | g_showPlayerShadow . GetBool ( ) | | pm_thirdPerson . GetBool ( ) )
{
2012-11-26 18:58:24 +00:00
worldModel . GetEntity ( ) - > GetRenderEntity ( ) - > suppressShadowInViewID = 0 ;
2012-11-28 15:47:07 +00:00
}
else
{
worldModel . GetEntity ( ) - > GetRenderEntity ( ) - > suppressShadowInViewID = owner - > entityNumber + 1 ;
2012-11-26 18:58:24 +00:00
worldModel . GetEntity ( ) - > GetRenderEntity ( ) - > suppressShadowInLightID = LIGHTID_VIEW_MUZZLE_FLASH + owner - > entityNumber ;
}
}
2012-11-28 15:47:07 +00:00
if ( nozzleFx )
{
2012-11-26 18:58:24 +00:00
UpdateNozzleFx ( ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// muzzle smoke
2012-11-28 15:47:07 +00:00
if ( showViewModel & & ! disabled & & weaponSmoke & & ( weaponSmokeStartTime ! = 0 ) )
{
2012-11-26 18:58:24 +00:00
// use the barrel joint if available
2012-11-28 15:47:07 +00:00
if ( smokeJointView ! = INVALID_JOINT )
{
2012-11-26 18:58:24 +00:00
GetGlobalJointTransform ( true , smokeJointView , muzzleOrigin , muzzleAxis ) ;
2012-11-28 15:47:07 +00:00
}
else if ( barrelJointView ! = INVALID_JOINT )
{
2012-11-26 18:58:24 +00:00
GetGlobalJointTransform ( true , barrelJointView , muzzleOrigin , muzzleAxis ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
// default to going straight out the view
muzzleOrigin = playerViewOrigin ;
muzzleAxis = playerViewAxis ;
}
// spit out a particle
2012-11-28 15:47:07 +00:00
if ( ! gameLocal . smokeParticles - > EmitSmoke ( weaponSmoke , weaponSmokeStartTime , gameLocal . random . RandomFloat ( ) , muzzleOrigin , muzzleAxis , timeGroup /*_D3XP*/ ) )
{
2012-11-26 18:58:24 +00:00
weaponSmokeStartTime = ( continuousSmoke ) ? gameLocal . time : 0 ;
}
}
2012-11-28 15:47:07 +00:00
if ( showViewModel & & strikeSmoke & & strikeSmokeStartTime ! = 0 )
{
2012-11-26 18:58:24 +00:00
// spit out a particle
2012-11-28 15:47:07 +00:00
if ( ! gameLocal . smokeParticles - > EmitSmoke ( strikeSmoke , strikeSmokeStartTime , gameLocal . random . RandomFloat ( ) , strikePos , strikeAxis , timeGroup /*_D3XP*/ ) )
{
2012-11-26 18:58:24 +00:00
strikeSmokeStartTime = 0 ;
}
}
2012-11-28 15:47:07 +00:00
if ( showViewModel & & ! hide )
{
for ( int i = 0 ; i < weaponParticles . Num ( ) ; i + + )
{
WeaponParticle_t * part = weaponParticles . GetIndex ( i ) ;
if ( part - > active )
{
if ( part - > smoke )
{
if ( part - > joint ! = INVALID_JOINT )
{
2012-11-26 18:58:24 +00:00
GetGlobalJointTransform ( true , part - > joint , muzzleOrigin , muzzleAxis ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
// default to going straight out the view
muzzleOrigin = playerViewOrigin ;
muzzleAxis = playerViewAxis ;
}
2012-11-28 15:47:07 +00:00
if ( ! gameLocal . smokeParticles - > EmitSmoke ( part - > particle , part - > startTime , gameLocal . random . RandomFloat ( ) , muzzleOrigin , muzzleAxis , timeGroup /*_D3XP*/ ) )
{
2012-11-26 18:58:24 +00:00
part - > active = false ; // all done
part - > startTime = 0 ;
}
2012-11-28 15:47:07 +00:00
}
else
{
if ( part - > emitter ! = NULL )
{
2012-11-26 18:58:24 +00:00
//Manually update the position of the emitter so it follows the weapon
renderEntity_t * rendEnt = part - > emitter - > GetRenderEntity ( ) ;
GetGlobalJointTransform ( true , part - > joint , rendEnt - > origin , rendEnt - > axis ) ;
2012-11-28 15:47:07 +00:00
if ( part - > emitter - > GetModelDefHandle ( ) ! = - 1 )
{
2012-11-26 18:58:24 +00:00
gameRenderWorld - > UpdateEntityDef ( part - > emitter - > GetModelDefHandle ( ) , rendEnt ) ;
}
}
}
}
}
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < weaponLights . Num ( ) ; i + + )
{
WeaponLight_t * light = weaponLights . GetIndex ( i ) ;
if ( light - > active )
{
2012-11-26 18:58:24 +00:00
GetGlobalJointTransform ( true , light - > joint , light - > light . origin , light - > light . axis ) ;
2012-11-28 15:47:07 +00:00
if ( ( light - > lightHandle ! = - 1 ) )
{
2012-11-26 18:58:24 +00:00
gameRenderWorld - > UpdateLightDef ( light - > lightHandle , & light - > light ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
light - > lightHandle = gameRenderWorld - > AddLightDef ( & light - > light ) ;
}
}
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// Update the grabber effects
2012-11-28 15:47:07 +00:00
if ( grabberState ! = - 1 )
{
2012-11-26 18:58:24 +00:00
grabberState = grabber . Update ( owner , hide ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// remove the muzzle flash light when it's done
2012-11-28 15:47:07 +00:00
if ( ( ! lightOn & & ( gameLocal . time > = muzzleFlashEnd ) ) | | IsHidden ( ) )
{
if ( muzzleFlashHandle ! = - 1 )
{
2012-11-26 18:58:24 +00:00
gameRenderWorld - > FreeLightDef ( muzzleFlashHandle ) ;
muzzleFlashHandle = - 1 ;
}
2012-11-28 15:47:07 +00:00
if ( worldMuzzleFlashHandle ! = - 1 )
{
2012-11-26 18:58:24 +00:00
gameRenderWorld - > FreeLightDef ( worldMuzzleFlashHandle ) ;
worldMuzzleFlashHandle = - 1 ;
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// update the muzzle flash light, so it moves with the gun
2012-11-28 15:47:07 +00:00
if ( muzzleFlashHandle ! = - 1 )
{
2012-11-26 18:58:24 +00:00
UpdateFlashPosition ( ) ;
gameRenderWorld - > UpdateLightDef ( muzzleFlashHandle , & muzzleFlash ) ;
gameRenderWorld - > UpdateLightDef ( worldMuzzleFlashHandle , & worldMuzzleFlash ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// wake up monsters with the flashlight
2012-11-28 15:47:07 +00:00
if ( ! common - > IsMultiplayer ( ) & & lightOn & & ! owner - > fl . notarget )
{
2012-11-26 18:58:24 +00:00
AlertMonsters ( ) ;
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// update the gui light
2012-11-28 15:47:07 +00:00
if ( guiLight . lightRadius [ 0 ] & & guiLightJointView ! = INVALID_JOINT )
{
2012-11-26 18:58:24 +00:00
GetGlobalJointTransform ( true , guiLightJointView , guiLight . origin , guiLight . axis ) ;
2012-11-28 15:47:07 +00:00
if ( ( guiLightHandle ! = - 1 ) )
{
2012-11-26 18:58:24 +00:00
gameRenderWorld - > UpdateLightDef ( guiLightHandle , & guiLight ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
guiLightHandle = gameRenderWorld - > AddLightDef ( & guiLight ) ;
}
}
2012-11-28 15:47:07 +00:00
if ( status ! = WP_READY & & sndHum )
{
2012-11-26 18:58:24 +00:00
StopSound ( SND_CHANNEL_BODY , false ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
UpdateSound ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// constant rumble...
float highMagnitude = weaponDef - > dict . GetFloat ( " controllerConstantShakeHighMag " ) ;
int highDuration = weaponDef - > dict . GetInt ( " controllerConstantShakeHighTime " ) ;
float lowMagnitude = weaponDef - > dict . GetFloat ( " controllerConstantShakeLowMag " ) ;
int lowDuration = weaponDef - > dict . GetInt ( " controllerConstantShakeLowTime " ) ;
2012-11-28 15:47:07 +00:00
if ( owner - > IsLocallyControlled ( ) )
{
2012-11-26 18:58:24 +00:00
owner - > SetControllerShake ( highMagnitude , highDuration , lowMagnitude , lowDuration ) ;
}
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : RemoveMuzzleFlashlight
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : RemoveMuzzleFlashlight ( )
{
if ( muzzleFlashHandle ! = - 1 )
{
2012-11-26 18:58:24 +00:00
gameRenderWorld - > FreeLightDef ( muzzleFlashHandle ) ;
muzzleFlashHandle = - 1 ;
}
2012-11-28 15:47:07 +00:00
if ( worldMuzzleFlashHandle ! = - 1 )
{
2012-11-26 18:58:24 +00:00
gameRenderWorld - > FreeLightDef ( worldMuzzleFlashHandle ) ;
worldMuzzleFlashHandle = - 1 ;
}
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : EnterCinematic
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : EnterCinematic ( )
{
2012-11-26 18:58:24 +00:00
StopSound ( SND_CHANNEL_ANY , false ) ;
2012-11-28 15:47:07 +00:00
if ( isLinked )
{
2012-11-26 18:58:24 +00:00
SetState ( " EnterCinematic " , 0 ) ;
thread - > Execute ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
WEAPON_ATTACK = false ;
WEAPON_RELOAD = false ;
WEAPON_NETRELOAD = false ;
WEAPON_NETENDRELOAD = false ;
WEAPON_NETFIRING = false ;
WEAPON_RAISEWEAPON = false ;
WEAPON_LOWERWEAPON = false ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
grabber . Update ( this - > GetOwner ( ) , true ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
disabled = true ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
LowerWeapon ( ) ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : ExitCinematic
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : ExitCinematic ( )
{
2012-11-26 18:58:24 +00:00
disabled = false ;
2012-11-28 15:47:07 +00:00
if ( isLinked )
{
2012-11-26 18:58:24 +00:00
SetState ( " ExitCinematic " , 0 ) ;
thread - > Execute ( ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
RaiseWeapon ( ) ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : NetCatchup
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : NetCatchup ( )
{
if ( isLinked )
{
2012-11-26 18:58:24 +00:00
SetState ( " NetCatchup " , 0 ) ;
thread - > Execute ( ) ;
}
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : GetZoomFov
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
int idWeapon : : GetZoomFov ( )
{
2012-11-26 18:58:24 +00:00
return zoomFov ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : GetWeaponAngleOffsets
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : GetWeaponAngleOffsets ( int * average , float * scale , float * max )
{
2012-11-26 18:58:24 +00:00
* average = weaponAngleOffsetAverages ;
* scale = weaponAngleOffsetScale ;
* max = weaponAngleOffsetMax ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : GetWeaponTimeOffsets
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : GetWeaponTimeOffsets ( float * time , float * scale )
{
2012-11-26 18:58:24 +00:00
* time = weaponOffsetTime ;
* scale = weaponOffsetScale ;
}
/***********************************************************************
Ammo
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
= = = = = = = = = = = = = = = =
idWeapon : : GetAmmoNumForName
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
ammo_t idWeapon : : GetAmmoNumForName ( const char * ammoname )
{
2012-11-26 18:58:24 +00:00
int num ;
2012-11-28 15:47:07 +00:00
const idDict * ammoDict ;
2012-11-26 18:58:24 +00:00
assert ( ammoname ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
ammoDict = gameLocal . FindEntityDefDict ( " ammo_types " , false ) ;
2012-11-28 15:47:07 +00:00
if ( ammoDict = = NULL )
{
2012-11-26 18:58:24 +00:00
gameLocal . Error ( " Could not find entity definition for 'ammo_types' \n " ) ;
return 0 ;
}
2012-11-28 15:47:07 +00:00
if ( ! ammoname [ 0 ] )
{
2012-11-26 18:58:24 +00:00
return 0 ;
}
2012-11-28 15:47:07 +00:00
if ( ! ammoDict - > GetInt ( ammoname , " -1 " , num ) )
{
2012-11-26 18:58:24 +00:00
}
2012-11-28 15:47:07 +00:00
if ( ( num < 0 ) | | ( num > = AMMO_NUMTYPES ) )
{
2012-11-26 18:58:24 +00:00
gameLocal . Warning ( " Ammo type '%s' value out of range. Maximum ammo types is %d. \n " , ammoname , AMMO_NUMTYPES ) ;
num = 0 ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return ( ammo_t ) num ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : GetAmmoNameForNum
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
const char * idWeapon : : GetAmmoNameForNum ( ammo_t ammonum )
{
2012-11-26 18:58:24 +00:00
int i ;
int num ;
2012-11-28 15:47:07 +00:00
const idDict * ammoDict ;
const idKeyValue * kv ;
2012-11-26 18:58:24 +00:00
char text [ 32 ] ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
ammoDict = gameLocal . FindEntityDefDict ( " ammo_types " , false ) ;
2012-11-28 15:47:07 +00:00
if ( ammoDict = = NULL )
{
2012-11-26 18:58:24 +00:00
gameLocal . Error ( " Could not find entity definition for 'ammo_types' \n " ) ;
return NULL ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
sprintf ( text , " %d " , ammonum ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
num = ammoDict - > GetNumKeyVals ( ) ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < num ; i + + )
{
2012-11-26 18:58:24 +00:00
kv = ammoDict - > GetKeyVal ( i ) ;
2012-11-28 15:47:07 +00:00
if ( kv - > GetValue ( ) = = text )
{
2012-11-26 18:58:24 +00:00
return kv - > GetKey ( ) ;
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return NULL ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : GetAmmoPickupNameForNum
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
const char * idWeapon : : GetAmmoPickupNameForNum ( ammo_t ammonum )
{
2012-11-26 18:58:24 +00:00
int i ;
int num ;
2012-11-28 15:47:07 +00:00
const idDict * ammoDict ;
const idKeyValue * kv ;
2012-11-26 18:58:24 +00:00
ammoDict = gameLocal . FindEntityDefDict ( " ammo_names " , false ) ;
2012-11-28 15:47:07 +00:00
if ( ! ammoDict )
{
2012-11-26 18:58:24 +00:00
gameLocal . Error ( " Could not find entity definition for 'ammo_names' \n " ) ;
}
2012-11-28 15:47:07 +00:00
const char * name = GetAmmoNameForNum ( ammonum ) ;
2012-12-02 21:37:32 +00:00
if ( name ! = NULL & & * name ! = ' \0 ' )
2012-11-28 15:47:07 +00:00
{
2012-11-26 18:58:24 +00:00
num = ammoDict - > GetNumKeyVals ( ) ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < num ; i + + )
{
2012-11-26 18:58:24 +00:00
kv = ammoDict - > GetKeyVal ( i ) ;
2012-11-28 15:47:07 +00:00
if ( idStr : : Icmp ( kv - > GetKey ( ) , name ) = = 0 )
{
2012-11-26 18:58:24 +00:00
return kv - > GetValue ( ) ;
}
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return " " ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : AmmoAvailable
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
int idWeapon : : AmmoAvailable ( ) const
{
if ( owner )
{
2012-11-26 18:58:24 +00:00
return owner - > inventory . HasAmmo ( ammoType , ammoRequired ) ;
2012-11-28 15:47:07 +00:00
}
else
{
if ( g_infiniteAmmo . GetBool ( ) )
{
2012-11-26 18:58:24 +00:00
return 10 ; // arbitrary number, just so whatever's calling thinks there's sufficient ammo...
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
return 0 ;
}
}
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : AmmoInClip
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
int idWeapon : : AmmoInClip ( ) const
{
2012-11-26 18:58:24 +00:00
return ammoClip . Get ( ) ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : ResetAmmoClip
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : ResetAmmoClip ( )
{
2012-11-26 18:58:24 +00:00
ammoClip = - 1 ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : GetAmmoType
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
ammo_t idWeapon : : GetAmmoType ( ) const
{
2012-11-26 18:58:24 +00:00
return ammoType ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : ClipSize
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
int idWeapon : : ClipSize ( ) const
{
2012-11-26 18:58:24 +00:00
return clipSize ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : LowAmmo
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
int idWeapon : : LowAmmo ( ) const
{
2012-11-26 18:58:24 +00:00
return lowAmmo ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : AmmoRequired
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
int idWeapon : : AmmoRequired ( ) const
{
2012-11-26 18:58:24 +00:00
return ammoRequired ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : GetGrabberState
Returns the current grabberState
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
int idWeapon : : GetGrabberState ( ) const
{
2012-11-26 18:58:24 +00:00
return grabberState ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : AmmoCount
Returns the total number of rounds regardless of the required ammo
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
int idWeapon : : AmmoCount ( ) const
{
2012-11-26 18:58:24 +00:00
2012-11-28 15:47:07 +00:00
if ( owner )
{
2012-11-26 18:58:24 +00:00
return owner - > inventory . HasAmmo ( ammoType , 1 ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
return 0 ;
}
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : WriteToSnapshot
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : WriteToSnapshot ( idBitMsg & msg ) const
{
2012-11-26 18:58:24 +00:00
msg . WriteBits ( ammoClip . Get ( ) , ASYNC_PLAYER_INV_CLIP_BITS ) ;
msg . WriteBits ( worldModel . GetSpawnId ( ) , 32 ) ;
msg . WriteBits ( lightOn , 1 ) ;
msg . WriteBits ( isFiring ? 1 : 0 , 1 ) ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : ReadFromSnapshot
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : ReadFromSnapshot ( const idBitMsg & msg )
{
2012-11-26 18:58:24 +00:00
const int snapshotAmmoClip = msg . ReadBits ( ASYNC_PLAYER_INV_CLIP_BITS ) ;
worldModel . SetSpawnId ( msg . ReadBits ( 32 ) ) ;
const bool snapshotLightOn = msg . ReadBits ( 1 ) ! = 0 ;
isFiring = msg . ReadBits ( 1 ) ! = 0 ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// Local clients predict the ammo in the clip. Only use the ammo cpunt from the snapshot for local clients
// if the server has processed the same usercmd in which we predicted the ammo count.
2012-11-28 15:47:07 +00:00
if ( owner ! = NULL )
{
2012-11-26 18:58:24 +00:00
ammoClip . UpdateFromSnapshot ( snapshotAmmoClip , owner - > GetEntityNumber ( ) ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// WEAPON_NETFIRING is only turned on for other clients we're predicting. not for local client
2012-11-28 15:47:07 +00:00
if ( owner & & ! owner - > IsLocallyControlled ( ) & & WEAPON_NETFIRING . IsLinked ( ) )
{
2012-11-26 18:58:24 +00:00
// immediately go to the firing state so we don't skip fire animations
2012-11-28 15:47:07 +00:00
if ( ! WEAPON_NETFIRING & & isFiring )
{
2012-11-26 18:58:24 +00:00
idealState = " Fire " ;
}
2012-11-28 15:47:07 +00:00
// immediately switch back to idle
if ( WEAPON_NETFIRING & & ! isFiring )
{
idealState = " Idle " ;
}
2012-11-26 18:58:24 +00:00
WEAPON_NETFIRING = isFiring ;
WEAPON_ATTACK = isFiring ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// Only update the flashlight state if it has changed, and if this isn't the local player.
// The local player sets their flashlight immediately for responsiveness.
2012-11-28 15:47:07 +00:00
if ( owner ! = NULL & & ! owner - > IsLocallyControlled ( ) & & lightOn ! = snapshotLightOn )
{
if ( snapshotLightOn )
{
2012-11-26 18:58:24 +00:00
FlashlightOn ( ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
FlashlightOff ( ) ;
}
}
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : ClientReceiveEvent
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idWeapon : : ClientReceiveEvent ( int event , int time , const idBitMsg & msg )
{
2012-11-26 18:58:24 +00:00
2012-11-28 15:47:07 +00:00
switch ( event )
{
case EVENT_RELOAD :
{
2012-11-26 18:58:24 +00:00
// Local clients predict reloads, only process this event for remote clients.
2012-11-28 15:47:07 +00:00
if ( owner ! = NULL & & ! owner - > IsLocallyControlled ( ) & & ( gameLocal . time - time < 1000 ) )
{
if ( WEAPON_NETRELOAD . IsLinked ( ) )
{
2012-11-26 18:58:24 +00:00
WEAPON_NETRELOAD = true ;
WEAPON_NETENDRELOAD = false ;
}
}
return true ;
}
2012-11-28 15:47:07 +00:00
case EVENT_ENDRELOAD :
{
2012-11-26 18:58:24 +00:00
// Local clients predict reloads, only process this event for remote clients.
2012-11-28 15:47:07 +00:00
if ( owner ! = NULL & & ! owner - > IsLocallyControlled ( ) & & WEAPON_NETENDRELOAD . IsLinked ( ) )
{
2012-11-26 18:58:24 +00:00
WEAPON_NETENDRELOAD = true ;
}
return true ;
}
2012-11-28 15:47:07 +00:00
case EVENT_CHANGESKIN :
{
2012-11-26 18:58:24 +00:00
int index = gameLocal . ClientRemapDecl ( DECL_SKIN , msg . ReadLong ( ) ) ;
2012-11-28 15:47:07 +00:00
renderEntity . customSkin = ( index ! = - 1 ) ? static_cast < const idDeclSkin * > ( declManager - > DeclByIndex ( DECL_SKIN , index ) ) : NULL ;
2012-11-26 18:58:24 +00:00
UpdateVisuals ( ) ;
2012-11-28 15:47:07 +00:00
if ( worldModel . GetEntity ( ) )
{
2012-11-26 18:58:24 +00:00
worldModel . GetEntity ( ) - > SetSkin ( renderEntity . customSkin ) ;
}
return true ;
}
2012-11-28 15:47:07 +00:00
default :
{
2012-11-26 18:58:24 +00:00
return idEntity : : ClientReceiveEvent ( event , time , msg ) ;
}
}
}
/***********************************************************************
Script events
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
= = = = = = = = = = = = = = =
idWeapon : : Event_Clear
= = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : Event_Clear ( )
{
2012-11-26 18:58:24 +00:00
Clear ( ) ;
}
/*
= = = = = = = = = = = = = = =
idWeapon : : Event_GetOwner
= = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : Event_GetOwner ( )
{
2012-11-26 18:58:24 +00:00
idThread : : ReturnEntity ( owner ) ;
}
/*
= = = = = = = = = = = = = = =
idWeapon : : Event_WeaponState
= = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : Event_WeaponState ( const char * statename , int blendFrames )
{
const function_t * func ;
2012-11-26 18:58:24 +00:00
func = scriptObject . GetFunction ( statename ) ;
2012-11-28 15:47:07 +00:00
if ( ! func )
{
2012-11-26 18:58:24 +00:00
assert ( 0 ) ;
gameLocal . Error ( " Can't find function '%s' in object '%s' " , statename , scriptObject . GetTypeName ( ) ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idealState = statename ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// HACK, Fixes reload animation on player not playing on second reload ( on non local client players, and only with host viewing. )
2012-11-28 15:47:07 +00:00
if ( common - > IsMultiplayer ( ) & & strcmp ( weaponDef - > GetName ( ) , " weapon_shotgun_double_mp " ) = = 0 )
{
if ( strcmp ( statename , " Reload " ) ! = 0 )
{
if ( status = = WP_RELOAD )
{
2012-11-26 18:58:24 +00:00
status = WP_READY ;
}
}
}
2012-11-28 15:47:07 +00:00
if ( ! idealState . Icmp ( " Fire " ) )
{
2012-11-26 18:58:24 +00:00
isFiring = true ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
isFiring = false ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
animBlendFrames = blendFrames ;
thread - > DoneProcessing ( ) ;
}
/*
= = = = = = = = = = = = = = =
idWeapon : : Event_WeaponReady
= = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : Event_WeaponReady ( )
{
2012-11-26 18:58:24 +00:00
status = WP_READY ;
idLib : : PrintfIf ( g_debugWeapon . GetBool ( ) , " Weapon Status WP_READY \n " ) ;
2012-11-28 15:47:07 +00:00
if ( isLinked )
{
2012-11-26 18:58:24 +00:00
WEAPON_RAISEWEAPON = false ;
}
2012-11-28 15:47:07 +00:00
if ( sndHum )
{
2012-11-26 18:58:24 +00:00
StartSoundShader ( sndHum , SND_CHANNEL_BODY , 0 , false , NULL ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
}
/*
= = = = = = = = = = = = = = =
idWeapon : : Event_WeaponOutOfAmmo
= = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : Event_WeaponOutOfAmmo ( )
{
2012-11-26 18:58:24 +00:00
status = WP_OUTOFAMMO ;
idLib : : PrintfIf ( g_debugWeapon . GetBool ( ) , " Weapon Status WP_OUTOFAMMO \n " ) ;
2012-11-28 15:47:07 +00:00
if ( isLinked )
{
2012-11-26 18:58:24 +00:00
WEAPON_RAISEWEAPON = false ;
}
}
/*
= = = = = = = = = = = = = = =
idWeapon : : Event_WeaponReloading
= = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : Event_WeaponReloading ( )
{
2012-11-26 18:58:24 +00:00
status = WP_RELOAD ;
idLib : : PrintfIf ( g_debugWeapon . GetBool ( ) , " Weapon Status WP_RELOAD \n " ) ;
}
/*
= = = = = = = = = = = = = = =
idWeapon : : Event_WeaponHolstered
= = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : Event_WeaponHolstered ( )
{
2012-11-26 18:58:24 +00:00
status = WP_HOLSTERED ;
idLib : : PrintfIf ( g_debugWeapon . GetBool ( ) , " Weapon Status WP_HOLSTERED \n " ) ;
2012-11-28 15:47:07 +00:00
if ( isLinked )
{
2012-11-26 18:58:24 +00:00
WEAPON_LOWERWEAPON = false ;
}
}
/*
= = = = = = = = = = = = = = =
idWeapon : : Event_WeaponRising
= = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : Event_WeaponRising ( )
{
2012-11-26 18:58:24 +00:00
status = WP_RISING ;
idLib : : PrintfIf ( g_debugWeapon . GetBool ( ) , " Weapon Status WP_RISING \n " ) ;
2012-11-28 15:47:07 +00:00
if ( isLinked )
{
2012-11-26 18:58:24 +00:00
WEAPON_LOWERWEAPON = false ;
}
owner - > WeaponRisingCallback ( ) ;
}
/*
= = = = = = = = = = = = = = =
idWeapon : : Event_WeaponLowering
= = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : Event_WeaponLowering ( )
{
2012-11-26 18:58:24 +00:00
status = WP_LOWERING ;
idLib : : PrintfIf ( g_debugWeapon . GetBool ( ) , " Weapon Status WP_LOWERING \n " ) ;
2012-11-28 15:47:07 +00:00
if ( isLinked )
{
2012-11-26 18:58:24 +00:00
WEAPON_RAISEWEAPON = false ;
}
owner - > WeaponLoweringCallback ( ) ;
}
/*
= = = = = = = = = = = = = = =
idWeapon : : Event_UseAmmo
= = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : Event_UseAmmo ( int amount )
{
if ( owner = = NULL | | ( common - > IsClient ( ) & & ! owner - > IsLocallyControlled ( ) ) )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
owner - > inventory . UseAmmo ( ammoType , ( powerAmmo ) ? amount : ( amount * ammoRequired ) ) ;
2012-11-28 15:47:07 +00:00
if ( clipSize & & ammoRequired )
{
2012-11-26 18:58:24 +00:00
ammoClip - = powerAmmo ? amount : ( amount * ammoRequired ) ;
2012-11-28 15:47:07 +00:00
if ( ammoClip . Get ( ) < 0 )
{
2012-11-26 18:58:24 +00:00
ammoClip = 0 ;
}
}
}
/*
= = = = = = = = = = = = = = =
idWeapon : : Event_AddToClip
= = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : Event_AddToClip ( int amount )
{
2012-11-26 18:58:24 +00:00
int ammoAvail ;
2012-11-28 15:47:07 +00:00
if ( owner = = NULL | | ( common - > IsClient ( ) & & ! owner - > IsLocallyControlled ( ) ) )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
int oldAmmo = ammoClip . Get ( ) ;
ammoAvail = owner - > inventory . HasAmmo ( ammoType , ammoRequired ) + AmmoInClip ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
ammoClip + = amount ;
2012-11-28 15:47:07 +00:00
if ( ammoClip . Get ( ) > clipSize )
{
2012-11-26 18:58:24 +00:00
ammoClip = clipSize ;
}
2012-11-28 15:47:07 +00:00
if ( ammoClip . Get ( ) > ammoAvail )
{
2012-11-26 18:58:24 +00:00
ammoClip = ammoAvail ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// for shared ammo we need to use the ammo when it is moved into the clip
int usedAmmo = ammoClip . Get ( ) - oldAmmo ;
2012-11-28 15:47:07 +00:00
owner - > inventory . UseAmmo ( ammoType , usedAmmo ) ;
2012-11-26 18:58:24 +00:00
}
/*
= = = = = = = = = = = = = = =
idWeapon : : Event_AmmoInClip
= = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : Event_AmmoInClip ( )
{
2012-11-26 18:58:24 +00:00
int ammo = AmmoInClip ( ) ;
2012-11-28 15:47:07 +00:00
idThread : : ReturnFloat ( ammo ) ;
2012-11-26 18:58:24 +00:00
}
/*
= = = = = = = = = = = = = = =
idWeapon : : Event_AmmoAvailable
= = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : Event_AmmoAvailable ( )
{
2012-11-26 18:58:24 +00:00
int ammoAvail = owner - > inventory . HasAmmo ( ammoType , ammoRequired ) ;
ammoAvail + = AmmoInClip ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idThread : : ReturnFloat ( ammoAvail ) ;
}
/*
= = = = = = = = = = = = = = =
idWeapon : : Event_TotalAmmoCount
= = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : Event_TotalAmmoCount ( )
{
2012-11-26 18:58:24 +00:00
int ammoAvail = owner - > inventory . HasAmmo ( ammoType , 1 ) ;
idThread : : ReturnFloat ( ammoAvail ) ;
}
/*
= = = = = = = = = = = = = = =
idWeapon : : Event_ClipSize
= = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : Event_ClipSize ( )
{
idThread : : ReturnFloat ( clipSize ) ;
2012-11-26 18:58:24 +00:00
}
/*
= = = = = = = = = = = = = = =
idWeapon : : Event_AutoReload
= = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : Event_AutoReload ( )
{
2012-11-26 18:58:24 +00:00
assert ( owner ) ;
2012-11-28 15:47:07 +00:00
if ( common - > IsClient ( ) & & owner ! = NULL & & ! owner - > IsLocallyControlled ( ) )
{
2012-11-26 18:58:24 +00:00
idThread : : ReturnFloat ( 0.0f ) ;
return ;
}
2012-11-28 15:47:07 +00:00
idLobbyBase & lobby = session - > GetActingGameStateLobbyBase ( ) ;
lobbyUserID_t & lobbyUserID = gameLocal . lobbyUserIDs [ owner - > entityNumber ] ;
2012-11-26 18:58:24 +00:00
idThread : : ReturnFloat ( lobby . GetLobbyUserWeaponAutoReload ( lobbyUserID ) ) ;
}
/*
= = = = = = = = = = = = = = =
idWeapon : : Event_NetReload
= = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : Event_NetReload ( )
{
2012-11-26 18:58:24 +00:00
assert ( owner ) ;
2012-11-28 15:47:07 +00:00
if ( common - > IsServer ( ) )
{
2012-11-26 18:58:24 +00:00
ServerSendEvent ( EVENT_RELOAD , NULL , false ) ;
}
}
/*
= = = = = = = = = = = = = = =
idWeapon : : Event_NetEndReload
= = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : Event_NetEndReload ( )
{
2012-11-26 18:58:24 +00:00
assert ( owner ) ;
2012-11-28 15:47:07 +00:00
if ( common - > IsServer ( ) )
{
2012-11-26 18:58:24 +00:00
ServerSendEvent ( EVENT_ENDRELOAD , NULL , false ) ;
}
}
/*
= = = = = = = = = = = = = = =
idWeapon : : Event_PlayAnim
= = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : Event_PlayAnim ( int channel , const char * animname )
{
2012-11-26 18:58:24 +00:00
int anim ;
anim = animator . GetAnim ( animname ) ;
2012-11-28 15:47:07 +00:00
if ( ! anim )
{
2012-11-26 18:58:24 +00:00
gameLocal . Warning ( " missing '%s' animation on '%s' (%s) " , animname , name . c_str ( ) , GetEntityDefName ( ) ) ;
animator . Clear ( channel , gameLocal . time , FRAME2MS ( animBlendFrames ) ) ;
animDoneTime = 0 ;
2012-11-28 15:47:07 +00:00
}
else
{
if ( ! ( owner & & owner - > GetInfluenceLevel ( ) ) )
{
2012-11-26 18:58:24 +00:00
Show ( ) ;
}
animator . PlayAnim ( channel , anim , gameLocal . time , FRAME2MS ( animBlendFrames ) ) ;
animDoneTime = animator . CurrentAnim ( channel ) - > GetEndTime ( ) ;
2012-11-28 15:47:07 +00:00
if ( worldModel . GetEntity ( ) )
{
2012-11-26 18:58:24 +00:00
anim = worldModel . GetEntity ( ) - > GetAnimator ( ) - > GetAnim ( animname ) ;
2012-11-28 15:47:07 +00:00
if ( anim )
{
2012-11-26 18:58:24 +00:00
worldModel . GetEntity ( ) - > GetAnimator ( ) - > PlayAnim ( channel , anim , gameLocal . time , FRAME2MS ( animBlendFrames ) ) ;
}
}
}
animBlendFrames = 0 ;
idThread : : ReturnInt ( 0 ) ;
}
/*
= = = = = = = = = = = = = = =
idWeapon : : Event_PlayCycle
= = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : Event_PlayCycle ( int channel , const char * animname )
{
2012-11-26 18:58:24 +00:00
int anim ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
anim = animator . GetAnim ( animname ) ;
2012-11-28 15:47:07 +00:00
if ( ! anim )
{
2012-11-26 18:58:24 +00:00
gameLocal . Warning ( " missing '%s' animation on '%s' (%s) " , animname , name . c_str ( ) , GetEntityDefName ( ) ) ;
animator . Clear ( channel , gameLocal . time , FRAME2MS ( animBlendFrames ) ) ;
animDoneTime = 0 ;
2012-11-28 15:47:07 +00:00
}
else
{
if ( ! ( owner & & owner - > GetInfluenceLevel ( ) ) )
{
2012-11-26 18:58:24 +00:00
Show ( ) ;
}
animator . CycleAnim ( channel , anim , gameLocal . time , FRAME2MS ( animBlendFrames ) ) ;
animDoneTime = animator . CurrentAnim ( channel ) - > GetEndTime ( ) ;
2012-11-28 15:47:07 +00:00
if ( worldModel . GetEntity ( ) )
{
2012-11-26 18:58:24 +00:00
anim = worldModel . GetEntity ( ) - > GetAnimator ( ) - > GetAnim ( animname ) ;
worldModel . GetEntity ( ) - > GetAnimator ( ) - > CycleAnim ( channel , anim , gameLocal . time , FRAME2MS ( animBlendFrames ) ) ;
}
}
animBlendFrames = 0 ;
idThread : : ReturnInt ( 0 ) ;
}
/*
= = = = = = = = = = = = = = =
idWeapon : : Event_AnimDone
= = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : Event_AnimDone ( int channel , int blendFrames )
{
if ( animDoneTime - FRAME2MS ( blendFrames ) < = gameLocal . time )
{
2012-11-26 18:58:24 +00:00
idThread : : ReturnInt ( true ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
idThread : : ReturnInt ( false ) ;
}
}
/*
= = = = = = = = = = = = = = =
idWeapon : : Event_SetBlendFrames
= = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : Event_SetBlendFrames ( int channel , int blendFrames )
{
2012-11-26 18:58:24 +00:00
animBlendFrames = blendFrames ;
}
/*
= = = = = = = = = = = = = = =
idWeapon : : Event_GetBlendFrames
= = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : Event_GetBlendFrames ( int channel )
{
2012-11-26 18:58:24 +00:00
idThread : : ReturnInt ( animBlendFrames ) ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : Event_Next
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : Event_Next ( )
{
2012-11-26 18:58:24 +00:00
// change to another weapon if possible
owner - > NextBestWeapon ( ) ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : Event_SetSkin
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : Event_SetSkin ( const char * skinname )
{
const idDeclSkin * skinDecl = NULL ;
if ( ! skinname | | ! skinname [ 0 ] )
{
2012-11-26 18:58:24 +00:00
skinDecl = NULL ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
skinDecl = declManager - > FindSkin ( skinname ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// Don't update if the skin hasn't changed.
2012-11-28 15:47:07 +00:00
if ( renderEntity . customSkin = = skinDecl & & worldModel . GetEntity ( ) ! = NULL & & worldModel . GetEntity ( ) - > GetSkin ( ) = = skinDecl )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
renderEntity . customSkin = skinDecl ;
UpdateVisuals ( ) ;
2012-11-28 15:47:07 +00:00
if ( worldModel . GetEntity ( ) )
{
2012-11-26 18:58:24 +00:00
worldModel . GetEntity ( ) - > SetSkin ( skinDecl ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// Hack, don't send message if flashlight, because clients process the flashlight instantly.
2012-11-28 15:47:07 +00:00
if ( common - > IsServer ( ) & & ! isPlayerFlashlight )
{
2012-11-26 18:58:24 +00:00
idBitMsg msg ;
byte msgBuf [ MAX_EVENT_PARAM_SIZE ] ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
msg . InitWrite ( msgBuf , sizeof ( msgBuf ) ) ;
msg . WriteLong ( ( skinDecl ! = NULL ) ? gameLocal . ServerRemapDecl ( - 1 , DECL_SKIN , skinDecl - > Index ( ) ) : - 1 ) ;
ServerSendEvent ( EVENT_CHANGESKIN , & msg , false ) ;
}
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : Event_Flashlight
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : Event_Flashlight ( int enable )
{
if ( enable )
{
2012-11-26 18:58:24 +00:00
lightOn = true ;
MuzzleFlashLight ( ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
lightOn = false ;
muzzleFlashEnd = 0 ;
}
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : Event_GetLightParm
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : Event_GetLightParm ( int parmnum )
{
if ( ( parmnum < 0 ) | | ( parmnum > = MAX_ENTITY_SHADER_PARMS ) )
{
2012-11-26 18:58:24 +00:00
gameLocal . Error ( " shader parm index (%d) out of range " , parmnum ) ;
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idThread : : ReturnFloat ( muzzleFlash . shaderParms [ parmnum ] ) ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : Event_SetLightParm
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : Event_SetLightParm ( int parmnum , float value )
{
if ( ( parmnum < 0 ) | | ( parmnum > = MAX_ENTITY_SHADER_PARMS ) )
{
2012-11-26 18:58:24 +00:00
gameLocal . Error ( " shader parm index (%d) out of range " , parmnum ) ;
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
muzzleFlash . shaderParms [ parmnum ] = value ;
worldMuzzleFlash . shaderParms [ parmnum ] = value ;
UpdateVisuals ( ) ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : Event_SetLightParms
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : Event_SetLightParms ( float parm0 , float parm1 , float parm2 , float parm3 )
{
2012-11-26 18:58:24 +00:00
muzzleFlash . shaderParms [ SHADERPARM_RED ] = parm0 ;
muzzleFlash . shaderParms [ SHADERPARM_GREEN ] = parm1 ;
muzzleFlash . shaderParms [ SHADERPARM_BLUE ] = parm2 ;
muzzleFlash . shaderParms [ SHADERPARM_ALPHA ] = parm3 ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
worldMuzzleFlash . shaderParms [ SHADERPARM_RED ] = parm0 ;
worldMuzzleFlash . shaderParms [ SHADERPARM_GREEN ] = parm1 ;
worldMuzzleFlash . shaderParms [ SHADERPARM_BLUE ] = parm2 ;
worldMuzzleFlash . shaderParms [ SHADERPARM_ALPHA ] = parm3 ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
UpdateVisuals ( ) ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : Event_Grabber
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : Event_Grabber ( int enable )
{
if ( enable )
{
2012-11-26 18:58:24 +00:00
grabberState = 0 ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
grabberState = - 1 ;
}
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : Event_GrabberHasTarget
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : Event_GrabberHasTarget ( )
{
2012-11-26 18:58:24 +00:00
idThread : : ReturnInt ( grabberState ) ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : Event_GrabberSetGrabDistance
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : Event_GrabberSetGrabDistance ( float dist )
{
2012-11-26 18:58:24 +00:00
grabber . SetDragDistance ( dist ) ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : Event_CreateProjectile
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : Event_CreateProjectile ( )
{
if ( ! common - > IsClient ( ) )
{
2012-11-26 18:58:24 +00:00
projectileEnt = NULL ;
gameLocal . SpawnEntityDef ( projectileDict , & projectileEnt , false ) ;
2012-11-28 15:47:07 +00:00
if ( projectileEnt )
{
2012-11-26 18:58:24 +00:00
projectileEnt - > SetOrigin ( GetPhysics ( ) - > GetOrigin ( ) ) ;
projectileEnt - > Bind ( owner , false ) ;
projectileEnt - > Hide ( ) ;
}
idThread : : ReturnEntity ( projectileEnt ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
idThread : : ReturnEntity ( NULL ) ;
}
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : GetProjectileLaunchOriginAndAxis
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : GetProjectileLaunchOriginAndAxis ( idVec3 & origin , idMat3 & axis )
{
2012-11-26 18:58:24 +00:00
assert ( owner ! = NULL ) ;
// calculate the muzzle position
2012-11-28 15:47:07 +00:00
if ( barrelJointView ! = INVALID_JOINT & & projectileDict . GetBool ( " launchFromBarrel " ) )
{
2012-11-26 18:58:24 +00:00
// there is an explicit joint for the muzzle
// GetGlobalJointTransform( true, barrelJointView, muzzleOrigin, muzzleAxis );
GetMuzzlePositionWithHacks ( origin , axis ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
// go straight out of the view
origin = playerViewOrigin ;
axis = playerViewAxis ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
axis = playerViewAxis ; // Fix for plasma rifle not firing correctly on initial shot of a burst fire
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : Event_LaunchProjectiles
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : Event_LaunchProjectiles ( int num_projectiles , float spread , float fuseOffset , float launchPower , float dmgPower )
{
idProjectile * proj ;
idEntity * ent ;
2012-11-26 18:58:24 +00:00
int i ;
idVec3 dir ;
float ang ;
float spin ;
float distance ;
trace_t tr ;
idVec3 start ;
idVec3 muzzle_pos ;
idBounds ownerBounds , projBounds ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
assert ( owner ! = NULL ) ;
2012-11-28 15:47:07 +00:00
if ( IsHidden ( ) )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
if ( ! projectileDict . GetNumKeyVals ( ) )
{
const char * classname = weaponDef - > dict . GetString ( " classname " ) ;
2012-11-26 18:58:24 +00:00
gameLocal . Warning ( " No projectile defined on '%s' " , classname ) ;
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// Predict clip ammo on locally controlled MP clients.
2012-11-28 15:47:07 +00:00
if ( common - > IsServer ( ) | | owner - > IsLocallyControlled ( ) )
{
if ( ( clipSize ! = 0 ) & & ( ammoClip . Get ( ) < = 0 ) )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
// if this is a power ammo weapon ( currently only the bfg ) then make sure
2012-11-26 18:58:24 +00:00
// we only fire as much power as available in each clip
2012-11-28 15:47:07 +00:00
if ( powerAmmo )
{
2012-11-26 18:58:24 +00:00
// power comes in as a float from zero to max
// if we use this on more than the bfg will need to define the max
// in the .def as opposed to just in the script so proper calcs
2012-11-28 15:47:07 +00:00
// can be done here.
2012-11-26 18:58:24 +00:00
dmgPower = ( int ) dmgPower + 1 ;
2012-11-28 15:47:07 +00:00
if ( dmgPower > ammoClip . Get ( ) )
{
2012-11-26 18:58:24 +00:00
dmgPower = ammoClip . Get ( ) ;
}
}
2012-11-28 15:47:07 +00:00
if ( clipSize = = 0 )
{
2012-11-26 18:58:24 +00:00
//Weapons with a clip size of 0 launch straight from inventory without moving to a clip
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
//In D3XP we used the ammo when the ammo was moved into the clip so we don't want to
//use it now.
owner - > inventory . UseAmmo ( ammoType , ( powerAmmo ) ? dmgPower : ammoRequired ) ;
}
2012-11-28 15:47:07 +00:00
if ( clipSize & & ammoRequired & & ! g_infiniteAmmo . GetBool ( ) )
{
2012-11-26 18:58:24 +00:00
ammoClip - = powerAmmo ? dmgPower : ammoRequired ;
}
}
2012-11-28 15:47:07 +00:00
if ( ! silent_fire )
{
2012-11-26 18:58:24 +00:00
// wake up nearby monsters
gameLocal . AlertAI ( owner ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// set the shader parm to the time of last projectile firing,
// which the gun material shaders can reference for single shot barrel glows, etc
renderEntity . shaderParms [ SHADERPARM_DIVERSITY ] = gameLocal . random . CRandomFloat ( ) ;
renderEntity . shaderParms [ SHADERPARM_TIMEOFFSET ] = - MS2SEC ( gameLocal . realClientTime ) ;
2012-11-28 15:47:07 +00:00
if ( worldModel . GetEntity ( ) )
{
2012-11-26 18:58:24 +00:00
worldModel . GetEntity ( ) - > SetShaderParm ( SHADERPARM_DIVERSITY , renderEntity . shaderParms [ SHADERPARM_DIVERSITY ] ) ;
worldModel . GetEntity ( ) - > SetShaderParm ( SHADERPARM_TIMEOFFSET , renderEntity . shaderParms [ SHADERPARM_TIMEOFFSET ] ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// calculate the muzzle position
GetProjectileLaunchOriginAndAxis ( muzzleOrigin , muzzleAxis ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// add some to the kick time, incrementally moving repeat firing weapons back
2012-11-28 15:47:07 +00:00
if ( kick_endtime < gameLocal . realClientTime )
{
2012-11-26 18:58:24 +00:00
kick_endtime = gameLocal . realClientTime ;
}
kick_endtime + = muzzle_kick_time ;
2012-11-28 15:47:07 +00:00
if ( kick_endtime > gameLocal . realClientTime + muzzle_kick_maxtime )
{
2012-11-26 18:58:24 +00:00
kick_endtime = gameLocal . realClientTime + muzzle_kick_maxtime ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// "Predict" damage effects on clients by just spawning a local projectile that deals no damage. Used only
// for sound & visual effects. Damage will be handled through reliable messages to the host.
const bool isHitscan = projectileDict . GetBool ( " net_instanthit " ) ;
const bool attackerIsLocal = owner - > IsLocallyControlled ( ) ;
const bool actuallySpawnProjectile = common - > IsServer ( ) | | attackerIsLocal | | isHitscan ;
2012-11-28 15:47:07 +00:00
if ( actuallySpawnProjectile )
{
2012-11-26 18:58:24 +00:00
ownerBounds = owner - > GetPhysics ( ) - > GetAbsBounds ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
owner - > AddProjectilesFired ( num_projectiles ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
float spreadRad = DEG2RAD ( spread ) ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < num_projectiles ; i + + )
{
2012-11-26 18:58:24 +00:00
ang = idMath : : Sin ( spreadRad * gameLocal . random . RandomFloat ( ) ) ;
2012-11-28 15:47:07 +00:00
spin = ( float ) DEG2RAD ( 360.0f ) * gameLocal . random . RandomFloat ( ) ;
2012-11-26 18:58:24 +00:00
dir = muzzleAxis [ 0 ] + muzzleAxis [ 2 ] * ( ang * idMath : : Sin ( spin ) ) - muzzleAxis [ 1 ] * ( ang * idMath : : Cos ( spin ) ) ;
dir . Normalize ( ) ;
2012-11-28 15:47:07 +00:00
if ( projectileEnt )
{
2012-11-26 18:58:24 +00:00
ent = projectileEnt ;
ent - > Show ( ) ;
ent - > Unbind ( ) ;
projectileEnt = NULL ;
2012-11-28 15:47:07 +00:00
}
else
{
if ( common - > IsClient ( ) )
{
2012-11-26 18:58:24 +00:00
// This is predicted on a client, don't replicate.
// Must be set before spawn, so that the entity can be spawned into the correct area of the entities array.
projectileDict . SetBool ( " net_skip_replication " , true ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
projectileDict . SetBool ( " net_skip_replication " , false ) ;
}
gameLocal . SpawnEntityDef ( projectileDict , & ent , false ) ;
}
2012-11-28 15:47:07 +00:00
if ( ent = = NULL | | ! ent - > IsType ( idProjectile : : Type ) )
{
const char * projectileName = weaponDef - > dict . GetString ( " def_projectile " ) ;
2012-11-26 18:58:24 +00:00
gameLocal . Error ( " '%s' is not an idProjectile " , projectileName ) ;
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
int predictedKey = idEntity : : INVALID_PREDICTION_KEY ;
2012-11-28 15:47:07 +00:00
if ( projectileDict . GetBool ( " net_instanthit " ) )
{
2012-11-26 18:58:24 +00:00
// don't synchronize this on top of the already predicted effect
ent - > fl . networkSync = false ;
2012-11-28 15:47:07 +00:00
}
else if ( owner ! = NULL )
{
// Set the prediction key only for non-instanthit projectiles.
if ( common - > IsClient ( ) )
{
owner - > IncrementFireCount ( ) ;
2012-11-26 18:58:24 +00:00
}
predictedKey = gameLocal . GeneratePredictionKey ( this , owner , - 1 ) ;
ent - > SetPredictedKey ( predictedKey ) ;
}
2012-11-28 15:47:07 +00:00
proj = static_cast < idProjectile * > ( ent ) ;
2012-11-26 18:58:24 +00:00
proj - > Create ( owner , muzzleOrigin , dir ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
projBounds = proj - > GetPhysics ( ) - > GetBounds ( ) . Rotate ( proj - > GetPhysics ( ) - > GetAxis ( ) ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// make sure the projectile starts inside the bounding box of the owner
2012-11-28 15:47:07 +00:00
if ( i = = 0 )
{
2012-11-26 18:58:24 +00:00
muzzle_pos = muzzleOrigin + muzzleAxis [ 0 ] * 2.0f ;
2012-11-28 15:47:07 +00:00
if ( ( ownerBounds - projBounds ) . RayIntersection ( muzzle_pos , muzzleAxis [ 0 ] , distance ) )
{
2012-11-26 18:58:24 +00:00
start = muzzle_pos + distance * muzzleAxis [ 0 ] ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
start = ownerBounds . GetCenter ( ) ;
}
gameLocal . clip . Translation ( tr , start , muzzle_pos , proj - > GetPhysics ( ) - > GetClipModel ( ) , proj - > GetPhysics ( ) - > GetClipModel ( ) - > GetAxis ( ) , MASK_SHOT_RENDERMODEL , owner ) ;
muzzle_pos = tr . endpos ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// If this is the server simulating a remote client, the client has spawned the projectile in the past.
// The server will catch-up the projectile so that its position will be as if the projectile had spawned
// when the client fired it.
2012-11-28 15:47:07 +00:00
if ( common - > IsServer ( ) & & owner ! = NULL & & ! owner - > IsLocallyControlled ( ) & & ! projectileDict . GetBool ( " net_instanthit " ) )
{
2012-11-26 18:58:24 +00:00
int serverTimeOnClient = owner - > usercmd . serverGameMilliseconds ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
int delta = idMath : : ClampInt ( 0 , cg_projectile_clientAuthoritative_maxCatchup . GetInteger ( ) , gameLocal . GetServerGameTimeMs ( ) - serverTimeOnClient ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
int startTime = gameLocal . GetServerGameTimeMs ( ) - delta ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
proj - > Launch ( muzzle_pos , dir , pushVelocity , fuseOffset , launchPower , dmgPower ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// predictively spawned, but no need to simulate - was needed for correct processing of client mines when spawned on the server (because we're futzing with the clip models)
proj - > QueueToSimulate ( startTime ) ;
2012-11-28 15:47:07 +00:00
if ( cg_predictedSpawn_debug . GetBool ( ) )
{
2012-11-26 18:58:24 +00:00
idLib : : Printf ( " Spawning throw item projectile for player %d. PredictiveKey: %d \n " , owner - > GetEntityNumber ( ) , predictedKey ) ;
}
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
// Normal launch
proj - > Launch ( muzzle_pos , dir , pushVelocity , fuseOffset , launchPower , dmgPower ) ;
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// toss the brass
2012-11-28 15:47:07 +00:00
if ( brassDelay > = 0 )
{
2012-11-26 18:58:24 +00:00
PostEventMS ( & EV_Weapon_EjectBrass , brassDelay ) ;
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// add the light for the muzzleflash
2012-11-28 15:47:07 +00:00
if ( ! lightOn )
{
2012-11-26 18:58:24 +00:00
MuzzleFlashLight ( ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
owner - > WeaponFireFeedback ( & weaponDef - > dict ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// reset muzzle smoke
weaponSmokeStartTime = gameLocal . realClientTime ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : Event_LaunchProjectilesEllipse
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : Event_LaunchProjectilesEllipse ( int num_projectiles , float spreada , float spreadb , float fuseOffset , float power )
{
idProjectile * proj ;
idEntity * ent ;
2012-11-26 18:58:24 +00:00
int i ;
idVec3 dir ;
float anga , angb ;
float spin ;
float distance ;
trace_t tr ;
idVec3 start ;
idVec3 muzzle_pos ;
idBounds ownerBounds , projBounds ;
2012-11-28 15:47:07 +00:00
if ( IsHidden ( ) )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
if ( ! projectileDict . GetNumKeyVals ( ) )
{
const char * classname = weaponDef - > dict . GetString ( " classname " ) ;
2012-11-26 18:58:24 +00:00
gameLocal . Warning ( " No projectile defined on '%s' " , classname ) ;
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// avoid all ammo considerations on a client
2012-11-28 15:47:07 +00:00
if ( ! common - > IsClient ( ) )
{
if ( ( clipSize ! = 0 ) & & ( ammoClip . Get ( ) < = 0 ) )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
if ( clipSize = = 0 )
{
2012-11-26 18:58:24 +00:00
//Weapons with a clip size of 0 launch strait from inventory without moving to a clip
owner - > inventory . UseAmmo ( ammoType , ammoRequired ) ;
}
2012-11-28 15:47:07 +00:00
if ( clipSize & & ammoRequired )
{
2012-11-26 18:58:24 +00:00
ammoClip - = ammoRequired ;
}
2012-11-28 15:47:07 +00:00
if ( ! silent_fire )
{
2012-11-26 18:58:24 +00:00
// wake up nearby monsters
gameLocal . AlertAI ( owner ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// set the shader parm to the time of last projectile firing,
// which the gun material shaders can reference for single shot barrel glows, etc
renderEntity . shaderParms [ SHADERPARM_DIVERSITY ] = gameLocal . random . CRandomFloat ( ) ;
renderEntity . shaderParms [ SHADERPARM_TIMEOFFSET ] = - MS2SEC ( gameLocal . time ) ;
2012-11-28 15:47:07 +00:00
if ( worldModel . GetEntity ( ) )
{
2012-11-26 18:58:24 +00:00
worldModel . GetEntity ( ) - > SetShaderParm ( SHADERPARM_DIVERSITY , renderEntity . shaderParms [ SHADERPARM_DIVERSITY ] ) ;
worldModel . GetEntity ( ) - > SetShaderParm ( SHADERPARM_TIMEOFFSET , renderEntity . shaderParms [ SHADERPARM_TIMEOFFSET ] ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// calculate the muzzle position
2012-11-28 15:47:07 +00:00
if ( barrelJointView ! = INVALID_JOINT & & projectileDict . GetBool ( " launchFromBarrel " ) )
{
2012-11-26 18:58:24 +00:00
// there is an explicit joint for the muzzle
GetGlobalJointTransform ( true , barrelJointView , muzzleOrigin , muzzleAxis ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
// go straight out of the view
muzzleOrigin = playerViewOrigin ;
muzzleAxis = playerViewAxis ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// add some to the kick time, incrementally moving repeat firing weapons back
2012-11-28 15:47:07 +00:00
if ( kick_endtime < gameLocal . time )
{
2012-11-26 18:58:24 +00:00
kick_endtime = gameLocal . time ;
}
kick_endtime + = muzzle_kick_time ;
2012-11-28 15:47:07 +00:00
if ( kick_endtime > gameLocal . time + muzzle_kick_maxtime )
{
2012-11-26 18:58:24 +00:00
kick_endtime = gameLocal . time + muzzle_kick_maxtime ;
}
2012-11-28 15:47:07 +00:00
if ( ! common - > IsClient ( ) )
{
2012-11-26 18:58:24 +00:00
ownerBounds = owner - > GetPhysics ( ) - > GetAbsBounds ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
owner - > AddProjectilesFired ( num_projectiles ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
float spreadRadA = DEG2RAD ( spreada ) ;
float spreadRadB = DEG2RAD ( spreadb ) ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < num_projectiles ; i + + )
{
2012-11-26 18:58:24 +00:00
//Ellipse Form
2012-11-28 15:47:07 +00:00
spin = ( float ) DEG2RAD ( 360.0f ) * gameLocal . random . RandomFloat ( ) ;
anga = idMath : : Sin ( spreadRadA * gameLocal . random . RandomFloat ( ) ) ;
angb = idMath : : Sin ( spreadRadB * gameLocal . random . RandomFloat ( ) ) ;
dir = playerViewAxis [ 0 ] + playerViewAxis [ 2 ] * ( angb * idMath : : Sin ( spin ) ) - playerViewAxis [ 1 ] * ( anga * idMath : : Cos ( spin ) ) ;
2012-11-26 18:58:24 +00:00
dir . Normalize ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
gameLocal . SpawnEntityDef ( projectileDict , & ent ) ;
2012-11-28 15:47:07 +00:00
if ( ent = = NULL | | ! ent - > IsType ( idProjectile : : Type ) )
{
const char * projectileName = weaponDef - > dict . GetString ( " def_projectile " ) ;
2012-11-26 18:58:24 +00:00
gameLocal . Error ( " '%s' is not an idProjectile " , projectileName ) ;
return ;
}
2012-11-28 15:47:07 +00:00
proj = static_cast < idProjectile * > ( ent ) ;
2012-11-26 18:58:24 +00:00
proj - > Create ( owner , muzzleOrigin , dir ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
projBounds = proj - > GetPhysics ( ) - > GetBounds ( ) . Rotate ( proj - > GetPhysics ( ) - > GetAxis ( ) ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// make sure the projectile starts inside the bounding box of the owner
2012-11-28 15:47:07 +00:00
if ( i = = 0 )
{
2012-11-26 18:58:24 +00:00
muzzle_pos = muzzleOrigin + playerViewAxis [ 0 ] * 2.0f ;
2012-11-28 15:47:07 +00:00
if ( ( ownerBounds - projBounds ) . RayIntersection ( muzzle_pos , playerViewAxis [ 0 ] , distance ) )
{
2012-11-26 18:58:24 +00:00
start = muzzle_pos + distance * playerViewAxis [ 0 ] ;
}
2012-11-28 15:47:07 +00:00
else
{
2012-11-26 18:58:24 +00:00
start = ownerBounds . GetCenter ( ) ;
}
gameLocal . clip . Translation ( tr , start , muzzle_pos , proj - > GetPhysics ( ) - > GetClipModel ( ) , proj - > GetPhysics ( ) - > GetClipModel ( ) - > GetAxis ( ) , MASK_SHOT_RENDERMODEL , owner ) ;
muzzle_pos = tr . endpos ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
proj - > Launch ( muzzle_pos , dir , pushVelocity , fuseOffset , power ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// toss the brass
2012-11-28 15:47:07 +00:00
if ( brassDelay > = 0 )
{
2012-11-26 18:58:24 +00:00
PostEventMS ( & EV_Weapon_EjectBrass , brassDelay ) ;
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// add the light for the muzzleflash
2012-11-28 15:47:07 +00:00
if ( ! lightOn )
{
2012-11-26 18:58:24 +00:00
MuzzleFlashLight ( ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
owner - > WeaponFireFeedback ( & weaponDef - > dict ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// reset muzzle smoke
weaponSmokeStartTime = gameLocal . time ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
}
2012-11-28 15:47:07 +00:00
/**
2012-11-26 18:58:24 +00:00
* Gives the player a powerup as if it were a weapon shot . It will use the ammo amount specified
* as ammoRequired .
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : Event_LaunchPowerup ( const char * powerup , float duration , int useAmmo )
{
2012-11-26 18:58:24 +00:00
2012-11-28 15:47:07 +00:00
if ( IsHidden ( ) )
{
return ;
2012-11-26 18:58:24 +00:00
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// check if we're out of ammo
2012-11-28 15:47:07 +00:00
if ( useAmmo )
{
2012-11-26 18:58:24 +00:00
int ammoAvail = owner - > inventory . HasAmmo ( ammoType , ammoRequired ) ;
2012-11-28 15:47:07 +00:00
if ( ! ammoAvail )
{
2012-11-26 18:58:24 +00:00
return ;
}
owner - > inventory . UseAmmo ( ammoType , ammoRequired ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// set the shader parm to the time of last projectile firing,
// which the gun material shaders can reference for single shot barrel glows, etc
renderEntity . shaderParms [ SHADERPARM_DIVERSITY ] = gameLocal . random . CRandomFloat ( ) ;
renderEntity . shaderParms [ SHADERPARM_TIMEOFFSET ] = - MS2SEC ( gameLocal . time ) ;
2012-11-28 15:47:07 +00:00
if ( worldModel . GetEntity ( ) )
{
2012-11-26 18:58:24 +00:00
worldModel . GetEntity ( ) - > SetShaderParm ( SHADERPARM_DIVERSITY , renderEntity . shaderParms [ SHADERPARM_DIVERSITY ] ) ;
worldModel . GetEntity ( ) - > SetShaderParm ( SHADERPARM_TIMEOFFSET , renderEntity . shaderParms [ SHADERPARM_TIMEOFFSET ] ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// add the light for the muzzleflash
2012-11-28 15:47:07 +00:00
if ( ! lightOn )
{
2012-11-26 18:58:24 +00:00
MuzzleFlashLight ( ) ;
}
2012-11-28 15:47:07 +00:00
owner - > Give ( powerup , va ( " %f " , duration ) , ITEM_GIVE_FEEDBACK | ITEM_GIVE_UPDATE_STATE | ITEM_GIVE_FROM_WEAPON ) ;
2012-11-26 18:58:24 +00:00
}
2012-11-28 15:47:07 +00:00
void idWeapon : : Event_StartWeaponSmoke ( )
{
2012-11-26 18:58:24 +00:00
// reset muzzle smoke
weaponSmokeStartTime = gameLocal . time ;
}
2012-11-28 15:47:07 +00:00
void idWeapon : : Event_StopWeaponSmoke ( )
{
2012-11-26 18:58:24 +00:00
// reset muzzle smoke
weaponSmokeStartTime = 0 ;
}
2012-11-28 15:47:07 +00:00
void idWeapon : : Event_StartWeaponParticle ( const char * name )
{
2012-11-26 18:58:24 +00:00
WeaponParticle_t * part ;
2012-11-28 15:47:07 +00:00
weaponParticles . Get ( name , & part ) ;
if ( part )
{
2012-11-26 18:58:24 +00:00
part - > active = true ;
part - > startTime = gameLocal . time ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
//Toggle the emitter
2012-11-28 15:47:07 +00:00
if ( ! part - > smoke & & part - > emitter ! = NULL )
{
2012-11-26 18:58:24 +00:00
part - > emitter - > Show ( ) ;
2012-11-28 15:47:07 +00:00
part - > emitter - > PostEventMS ( & EV_Activate , 0 , this ) ;
2012-11-26 18:58:24 +00:00
}
}
}
2012-11-28 15:47:07 +00:00
void idWeapon : : Event_StopWeaponParticle ( const char * name )
{
2012-11-26 18:58:24 +00:00
WeaponParticle_t * part ;
2012-11-28 15:47:07 +00:00
weaponParticles . Get ( name , & part ) ;
if ( part )
{
2012-11-26 18:58:24 +00:00
part - > active = false ;
part - > startTime = 0 ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
//Toggle the emitter
2012-11-28 15:47:07 +00:00
if ( ! part - > smoke )
{
if ( part - > emitter ! = NULL )
{
2012-11-26 18:58:24 +00:00
part - > emitter - > Hide ( ) ;
2012-11-28 15:47:07 +00:00
part - > emitter - > PostEventMS ( & EV_Activate , 0 , this ) ;
2012-11-26 18:58:24 +00:00
}
}
}
}
2012-11-28 15:47:07 +00:00
void idWeapon : : Event_StartWeaponLight ( const char * name )
{
2012-11-26 18:58:24 +00:00
WeaponLight_t * light ;
2012-11-28 15:47:07 +00:00
weaponLights . Get ( name , & light ) ;
if ( light )
{
2012-11-26 18:58:24 +00:00
light - > active = true ;
light - > startTime = gameLocal . time ;
}
}
2012-11-28 15:47:07 +00:00
void idWeapon : : Event_StopWeaponLight ( const char * name )
{
2012-11-26 18:58:24 +00:00
WeaponLight_t * light ;
2012-11-28 15:47:07 +00:00
weaponLights . Get ( name , & light ) ;
if ( light )
{
2012-11-26 18:58:24 +00:00
light - > active = false ;
light - > startTime = 0 ;
2012-11-28 15:47:07 +00:00
if ( light - > lightHandle ! = - 1 )
{
2012-11-26 18:58:24 +00:00
gameRenderWorld - > FreeLightDef ( light - > lightHandle ) ;
light - > lightHandle = - 1 ;
}
}
}
/*
= = = = = = = = = = = = = = = = = = = = =
idWeapon : : Event_Melee
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : Event_Melee ( )
{
idEntity * ent ;
2012-11-26 18:58:24 +00:00
trace_t tr ;
2012-11-28 15:47:07 +00:00
if ( weaponDef = = NULL )
{
2012-11-26 18:58:24 +00:00
gameLocal . Error ( " No weaponDef on '%s' " , this - > GetName ( ) ) ;
return ;
}
2012-11-28 15:47:07 +00:00
if ( meleeDef = = NULL )
{
2012-11-26 18:58:24 +00:00
gameLocal . Error ( " No meleeDef on '%s' " , weaponDef - > dict . GetString ( " classname " ) ) ;
return ;
}
2012-11-28 15:47:07 +00:00
if ( ! common - > IsClient ( ) )
{
2012-11-26 18:58:24 +00:00
idVec3 start = playerViewOrigin ;
idVec3 end = start + playerViewAxis [ 0 ] * ( meleeDistance * owner - > PowerUpModifier ( MELEE_DISTANCE ) ) ;
gameLocal . clip . TracePoint ( tr , start , end , MASK_SHOT_RENDERMODEL , owner ) ;
2012-11-28 15:47:07 +00:00
if ( tr . fraction < 1.0f )
{
2012-11-26 18:58:24 +00:00
ent = gameLocal . GetTraceEntity ( tr ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
ent = NULL ;
}
2012-11-28 15:47:07 +00:00
if ( g_debugWeapon . GetBool ( ) )
{
2012-11-26 18:58:24 +00:00
gameRenderWorld - > DebugLine ( colorYellow , start , end , 100 ) ;
2012-11-28 15:47:07 +00:00
if ( ent ! = NULL )
{
2012-11-26 18:58:24 +00:00
gameRenderWorld - > DebugBounds ( colorRed , ent - > GetPhysics ( ) - > GetBounds ( ) , ent - > GetPhysics ( ) - > GetOrigin ( ) , 100 ) ;
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
bool hit = false ;
2012-11-28 15:47:07 +00:00
const char * hitSound = meleeDef - > dict . GetString ( " snd_miss " ) ;
if ( ent ! = NULL )
{
2012-11-26 18:58:24 +00:00
float push = meleeDef - > dict . GetFloat ( " push " ) ;
idVec3 impulse = - push * owner - > PowerUpModifier ( SPEED ) * tr . c . normal ;
2012-11-28 15:47:07 +00:00
if ( gameLocal . world - > spawnArgs . GetBool ( " no_Weapons " ) & & ( ent - > IsType ( idActor : : Type ) | | ent - > IsType ( idAFAttachment : : Type ) ) )
{
2012-11-26 18:58:24 +00:00
idThread : : ReturnInt ( 0 ) ;
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
ent - > ApplyImpulse ( this , tr . c . id , tr . c . point , impulse ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// weapon stealing - do this before damaging so weapons are not dropped twice
2012-11-28 15:47:07 +00:00
if ( common - > IsMultiplayer ( )
& & weaponDef - > dict . GetBool ( " stealing " )
& & ent - > IsType ( idPlayer : : Type )
& & ! owner - > PowerUpActive ( BERSERK )
& & ( ( gameLocal . gameType ! = GAME_TDM ) | | gameLocal . serverInfo . GetBool ( " si_teamDamage " ) | | ( owner - > team ! = static_cast < idPlayer * > ( ent ) - > team ) )
)
{
if ( ! gameLocal . mpGame . IsGametypeFlagBased ( ) )
{
owner - > StealWeapon ( static_cast < idPlayer * > ( ent ) ) ;
2012-11-26 18:58:24 +00:00
}
}
2012-11-28 15:47:07 +00:00
if ( ent - > fl . takedamage )
{
2012-11-26 18:58:24 +00:00
idVec3 kickDir , globalKickDir ;
meleeDef - > dict . GetVector ( " kickDir " , " 0 0 0 " , kickDir ) ;
globalKickDir = muzzleAxis * kickDir ;
//Adjust the melee powerup modifier for the invulnerability boss fight
float mod = owner - > PowerUpModifier ( MELEE_DAMAGE ) ;
2012-11-28 15:47:07 +00:00
if ( ! strcmp ( ent - > GetEntityDefName ( ) , " monster_hunter_invul " ) )
{
2012-11-26 18:58:24 +00:00
//Only do a quater of the damage mod
mod * = 0.25f ;
}
ent - > Damage ( owner , owner , globalKickDir , meleeDefName , mod , tr . c . id ) ;
hit = true ;
}
2012-11-28 15:47:07 +00:00
if ( weaponDef - > dict . GetBool ( " impact_damage_effect " ) )
{
if ( ent - > spawnArgs . GetBool ( " bleed " ) )
{
2012-11-26 18:58:24 +00:00
hitSound = meleeDef - > dict . GetString ( owner - > PowerUpActive ( BERSERK ) ? " snd_hit_berserk " : " snd_hit " ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
ent - > AddDamageEffect ( tr , impulse , meleeDef - > dict . GetString ( " classname " ) ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
int type = tr . c . material - > GetSurfaceType ( ) ;
2012-11-28 15:47:07 +00:00
if ( type = = SURFTYPE_NONE )
{
2012-11-26 18:58:24 +00:00
type = GetDefaultSurfaceType ( ) ;
}
2012-11-28 15:47:07 +00:00
const char * materialType = gameLocal . sufaceTypeNames [ type ] ;
2012-11-26 18:58:24 +00:00
// start impact sound based on material type
hitSound = meleeDef - > dict . GetString ( va ( " snd_%s " , materialType ) ) ;
2012-11-28 15:47:07 +00:00
if ( * hitSound = = ' \0 ' )
{
2012-11-26 18:58:24 +00:00
hitSound = meleeDef - > dict . GetString ( " snd_metal " ) ;
}
2012-11-28 15:47:07 +00:00
if ( gameLocal . time > nextStrikeFx )
{
const char * decal ;
2012-11-26 18:58:24 +00:00
// project decal
decal = weaponDef - > dict . GetString ( " mtr_strike " ) ;
2012-12-11 22:48:55 +00:00
if ( decal ! = NULL & & * decal ! = ' \0 ' )
2012-11-28 15:47:07 +00:00
{
2012-11-26 18:58:24 +00:00
gameLocal . ProjectDecal ( tr . c . point , - tr . c . normal , 8.0f , true , 6.0 , decal ) ;
}
nextStrikeFx = gameLocal . time + 200 ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
hitSound = " " ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
strikeSmokeStartTime = gameLocal . time ;
strikePos = tr . c . point ;
strikeAxis = - tr . endAxis ;
}
}
}
2012-11-28 15:47:07 +00:00
if ( * hitSound ! = ' \0 ' )
{
const idSoundShader * snd = declManager - > FindSound ( hitSound ) ;
2012-11-26 18:58:24 +00:00
StartSoundShader ( snd , SND_CHANNEL_BODY2 , 0 , true , NULL ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idThread : : ReturnInt ( hit ) ;
owner - > WeaponFireFeedback ( & weaponDef - > dict ) ;
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idThread : : ReturnInt ( 0 ) ;
owner - > WeaponFireFeedback ( & weaponDef - > dict ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idWeapon : : Event_GetWorldModel
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : Event_GetWorldModel ( )
{
2012-11-26 18:58:24 +00:00
idThread : : ReturnEntity ( worldModel . GetEntity ( ) ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idWeapon : : Event_AllowDrop
= = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : Event_AllowDrop ( int allow )
{
if ( allow )
{
2012-11-26 18:58:24 +00:00
allowDrop = true ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
allowDrop = false ;
}
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : Event_EjectBrass
Toss a shell model out from the breach if the bone is present
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : Event_EjectBrass ( )
{
if ( ! g_showBrass . GetBool ( ) | | ! owner - > CanShowWeaponViewmodel ( ) )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
if ( ejectJointView = = INVALID_JOINT | | ! brassDict . GetNumKeyVals ( ) )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
if ( common - > IsClient ( ) )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idMat3 axis ;
idVec3 origin , linear_velocity , angular_velocity ;
2012-11-28 15:47:07 +00:00
idEntity * ent ;
if ( ! GetGlobalJointTransform ( true , ejectJointView , origin , axis ) )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
gameLocal . SpawnEntityDef ( brassDict , & ent , false ) ;
2012-11-28 15:47:07 +00:00
if ( ! ent | | ! ent - > IsType ( idDebris : : Type ) )
{
2012-11-26 18:58:24 +00:00
gameLocal . Error ( " '%s' is not an idDebris " , weaponDef ? weaponDef - > dict . GetString ( " def_ejectBrass " ) : " def_ejectBrass " ) ;
}
2012-11-28 15:47:07 +00:00
idDebris * debris = static_cast < idDebris * > ( ent ) ;
2012-11-26 18:58:24 +00:00
debris - > Create ( owner , origin , axis ) ;
debris - > Launch ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
linear_velocity = 40 * ( playerViewAxis [ 0 ] + playerViewAxis [ 1 ] + playerViewAxis [ 2 ] ) ;
angular_velocity . Set ( 10 * gameLocal . random . CRandomFloat ( ) , 10 * gameLocal . random . CRandomFloat ( ) , 10 * gameLocal . random . CRandomFloat ( ) ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
debris - > GetPhysics ( ) - > SetLinearVelocity ( linear_velocity ) ;
debris - > GetPhysics ( ) - > SetAngularVelocity ( angular_velocity ) ;
}
/*
= = = = = = = = = = = = = = =
idWeapon : : Event_IsInvisible
= = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : Event_IsInvisible ( )
{
if ( ! owner )
{
2012-11-26 18:58:24 +00:00
idThread : : ReturnFloat ( 0 ) ;
return ;
}
idThread : : ReturnFloat ( owner - > PowerUpActive ( INVISIBILITY ) ? 1 : 0 ) ;
}
/*
= = = = = = = = = = = = = = =
idWeapon : : ClientThink
= = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : ClientThink ( const int curTime , const float fraction , const bool predict )
{
UpdateAnimation ( ) ;
2012-11-26 18:58:24 +00:00
}
/*
= = = = = = = = = = = = = = =
idWeapon : : ClientPredictionThink
= = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWeapon : : ClientPredictionThink ( )
{
UpdateAnimation ( ) ;
2012-11-26 18:58:24 +00:00
}
2012-11-28 15:47:07 +00:00
void idWeapon : : ForceAmmoInClip ( )
{
2012-11-26 18:58:24 +00:00
ammoClip = clipSize ;
2012-12-02 21:37:32 +00:00
}