2020-09-08 22:10:45 +00:00
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
Doom 3 GPL Source Code
Copyright ( C ) 1999 - 2011 id Software LLC , a ZeniMax Media company .
This file is part of the Doom 3 GPL Source Code ( " Doom 3 Source Code " ) .
Doom 3 Source Code is free software : you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation , either version 3 of the License , or
( at your option ) any later version .
Doom 3 Source Code is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with Doom 3 Source Code . If not , see < http : //www.gnu.org/licenses/>.
In addition , the Doom 3 Source Code is also subject to certain additional terms . You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code . If not , please request a copy in writing from id Software at the address below .
If you have questions concerning this license or the applicable additional terms , you may contact in writing id Software LLC , c / o ZeniMax Media Inc . , Suite 120 , Rockville , Maryland 20850 USA .
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
2020-11-15 18:52:37 +00:00
# include <idlib/containers/Sort.h>
2020-09-08 22:10:45 +00:00
# include "sys/platform.h"
# include "framework/DeclEntityDef.h"
# include "framework/DeclSkin.h"
# include "framework/Session.h"
# include "gamesys/SysCvar.h"
# include "ai/AI.h"
# include "Player.h"
# include "Trigger.h"
# include "SmokeParticles.h"
# include "WorldSpawn.h"
# include "Weapon.h"
2020-11-15 18:52:37 +00:00
# include "Vr.h"
2020-09-08 22:10:45 +00:00
extern bool IsDoom3DemoVersion ( ) ; // DG: hack to support the Demo version of Doom3
2020-11-15 18:52:37 +00:00
// Koz begin
idClipModel * PDAclipModel ; // Koz fixme pda more crappy globals.
idCVar vr_guiH ( " vr_guiH " , " 100 " , CVAR_INTEGER , " " ) ;
idCVar vr_guiA ( " vr_guiA " , " 100 " , CVAR_INTEGER , " " ) ;
idCVar vr_throwPower ( " vr_throwPower " , " 4.0 " , CVAR_FLOAT | CVAR_GAME | CVAR_ARCHIVE , " Throw power " ) ;
// Koz end
2020-09-08 22:10:45 +00:00
/***********************************************************************
idWeapon
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
//
// 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 " ) ;
2020-11-29 14:49:20 +00:00
const idEventDef EV_Weapon_GrabberHasTarget ( " grabberHasTarget " , NULL , ' d ' ) ;
const idEventDef EV_Weapon_Grabber ( " grabber " , " d " ) ;
const idEventDef EV_Weapon_Grabber_SetGrabDistance ( " grabberGrabDistance " , " f " ) ;
2020-11-15 18:52:37 +00:00
// Koz
const idEventDef EV_Weapon_GetWeaponSkin ( " getWeaponSkin " , NULL , ' s ' ) ;
const idEventDef EV_Weapon_IsMotionControlled ( " isMotionControlled " , NULL , ' d ' ) ;
2020-09-08 22:10:45 +00:00
//
// class def
//
CLASS_DECLARATION ( idAnimatedEntity , idWeapon )
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 )
2020-11-29 14:49:20 +00:00
EVENT ( EV_Weapon_Grabber , idWeapon : : Event_Grabber )
EVENT ( EV_Weapon_GrabberHasTarget , idWeapon : : Event_GrabberHasTarget )
EVENT ( EV_Weapon_Grabber_SetGrabDistance , idWeapon : : Event_GrabberSetGrabDistance )
2020-11-15 18:52:37 +00:00
EVENT ( EV_Weapon_GetWeaponSkin , idWeapon : : Event_GetWeaponSkin )
EVENT ( EV_Weapon_IsMotionControlled , idWeapon : : Event_IsMotionControlled )
2020-09-08 22:10:45 +00:00
END_CLASS
/***********************************************************************
init
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
= = = = = = = = = = = = = = = =
idWeapon : : idWeapon ( )
= = = = = = = = = = = = = = = =
*/
idWeapon : : idWeapon ( ) {
owner = NULL ;
worldModel = NULL ;
weaponDef = NULL ;
thread = NULL ;
memset ( & guiLight , 0 , sizeof ( guiLight ) ) ;
memset ( & muzzleFlash , 0 , sizeof ( muzzleFlash ) ) ;
memset ( & worldMuzzleFlash , 0 , sizeof ( worldMuzzleFlash ) ) ;
memset ( & nozzleGlow , 0 , sizeof ( nozzleGlow ) ) ;
muzzleFlashEnd = 0 ;
flashColor = vec3_origin ;
muzzleFlashHandle = - 1 ;
worldMuzzleFlashHandle = - 1 ;
guiLightHandle = - 1 ;
nozzleGlowHandle = - 1 ;
modelDefHandle = - 1 ;
2020-11-29 14:49:20 +00:00
grabberState = - 1 ;
2020-09-08 22:10:45 +00:00
berserk = 2 ;
brassDelay = 0 ;
allowDrop = true ;
2020-11-15 18:52:37 +00:00
isPlayerFlashlight = false ;
isPlayerLeftHand = false ; // Koz
2020-09-08 22:10:45 +00:00
2020-11-15 18:52:37 +00:00
lastIdentifiedFrame = 0 ;
currentIdentifiedWeapon = WEAPON_NONE ;
lastIdentifiedWeapon = WEAPON_NONE ; // lastweapon holds the last actual weapon value, so the weapon enum will never return a value of 'weapon_flaslight'. nothing to do with the players previous weapon
fraccos = 0.0f ;
fraccos2 = 0.0f ;
Clear ( ) ;
2020-09-08 22:10:45 +00:00
fl . networkSync = true ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : ~ idWeapon ( )
= = = = = = = = = = = = = = = =
*/
idWeapon : : ~ idWeapon ( ) {
Clear ( ) ;
delete worldModel . GetEntity ( ) ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : Spawn
= = = = = = = = = = = = = = = =
*/
void idWeapon : : Spawn ( void ) {
if ( ! gameLocal . isClient ) {
// setup the world model
worldModel = static_cast < idAnimatedEntity * > ( gameLocal . SpawnEntityType ( idAnimatedEntity : : Type , NULL ) ) ;
worldModel . GetEntity ( ) - > fl . networkSync = true ;
}
2020-11-29 14:49:20 +00:00
grabber . Initialize ( ) ;
2020-09-08 22:10:45 +00:00
thread = new idThread ( ) ;
thread - > ManualDelete ( ) ;
thread - > ManualControl ( ) ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : SetOwner
Only called at player spawn time , not each weapon switch
= = = = = = = = = = = = = = = =
*/
2020-11-15 18:52:37 +00:00
void idWeapon : : SetOwner ( idPlayer * _owner , int ownerHand ) {
assert ( ! owner ) ;
owner = _owner ;
hand = ownerHand ;
const char * handNames [ 2 ] = { " right " , " left " } ;
if ( hand < 0 | | hand > = 2 | | hand = = vr_weaponHand . GetInteger ( ) )
{
SetName ( va ( " %s_weapon " , owner - > name . c_str ( ) ) ) ;
}
else
{
SetName ( va ( " %s_weapon_%s " , owner - > name . c_str ( ) , handNames [ hand ] ) ) ;
}
2020-09-08 22:10:45 +00:00
2020-11-15 18:52:37 +00:00
if ( worldModel . GetEntity ( ) )
{
worldModel . GetEntity ( ) - > SetName ( va ( " %s_worldmodel " , name . c_str ( ) ) ) ;
}
2020-09-08 22:10:45 +00:00
}
/*
= = = = = = = = = = = = = = = =
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 .
= = = = = = = = = = = = = = = =
*/
bool idWeapon : : ShouldConstructScriptObjectAtSpawn ( void ) const {
return false ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : CacheWeapon
= = = = = = = = = = = = = = = =
*/
void idWeapon : : CacheWeapon ( const char * weaponName ) {
const idDeclEntityDef * weaponDef ;
const char * brassDefName ;
const char * clipModelName ;
idTraceModel trm ;
const char * guiName ;
weaponDef = gameLocal . FindEntityDef ( weaponName , false ) ;
if ( ! weaponDef ) {
return ;
}
// precache the brass collision model
brassDefName = weaponDef - > dict . GetString ( " def_ejectBrass " ) ;
if ( brassDefName [ 0 ] ) {
const idDeclEntityDef * brassDef = gameLocal . FindEntityDef ( brassDefName , false ) ;
if ( brassDef ) {
brassDef - > dict . GetString ( " clipmodel " , " " , & clipModelName ) ;
if ( ! clipModelName [ 0 ] ) {
clipModelName = brassDef - > dict . GetString ( " model " ) ; // use the visual model
}
// load the trace model
collisionModelManager - > TrmFromModel ( clipModelName , trm ) ;
}
}
guiName = weaponDef - > dict . GetString ( " gui " ) ;
if ( guiName [ 0 ] ) {
uiManager - > FindGui ( guiName , true , false , true ) ;
}
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : Save
= = = = = = = = = = = = = = = =
*/
void idWeapon : : Save ( idSaveGame * savefile ) const {
savefile - > WriteInt ( status ) ;
savefile - > WriteObject ( thread ) ;
savefile - > WriteString ( state ) ;
savefile - > WriteString ( idealState ) ;
savefile - > WriteInt ( animBlendFrames ) ;
savefile - > WriteInt ( animDoneTime ) ;
savefile - > WriteBool ( isLinked ) ;
savefile - > WriteObject ( owner ) ;
worldModel . Save ( savefile ) ;
savefile - > WriteInt ( hideTime ) ;
savefile - > WriteFloat ( hideDistance ) ;
savefile - > WriteInt ( hideStartTime ) ;
savefile - > WriteFloat ( hideStart ) ;
savefile - > WriteFloat ( hideEnd ) ;
savefile - > WriteFloat ( hideOffset ) ;
savefile - > WriteBool ( hide ) ;
savefile - > WriteBool ( disabled ) ;
savefile - > WriteInt ( berserk ) ;
savefile - > WriteVec3 ( playerViewOrigin ) ;
savefile - > WriteMat3 ( playerViewAxis ) ;
savefile - > WriteVec3 ( viewWeaponOrigin ) ;
savefile - > WriteMat3 ( viewWeaponAxis ) ;
savefile - > WriteVec3 ( muzzleOrigin ) ;
savefile - > WriteMat3 ( muzzleAxis ) ;
savefile - > WriteVec3 ( pushVelocity ) ;
savefile - > WriteString ( weaponDef - > GetName ( ) ) ;
savefile - > WriteFloat ( meleeDistance ) ;
savefile - > WriteString ( meleeDefName ) ;
savefile - > WriteInt ( brassDelay ) ;
savefile - > WriteString ( icon ) ;
savefile - > WriteInt ( guiLightHandle ) ;
savefile - > WriteRenderLight ( guiLight ) ;
savefile - > WriteInt ( muzzleFlashHandle ) ;
savefile - > WriteRenderLight ( muzzleFlash ) ;
savefile - > WriteInt ( worldMuzzleFlashHandle ) ;
savefile - > WriteRenderLight ( worldMuzzleFlash ) ;
savefile - > WriteVec3 ( flashColor ) ;
savefile - > WriteInt ( muzzleFlashEnd ) ;
savefile - > WriteInt ( flashTime ) ;
savefile - > WriteBool ( lightOn ) ;
savefile - > WriteBool ( silent_fire ) ;
savefile - > WriteInt ( kick_endtime ) ;
savefile - > WriteInt ( muzzle_kick_time ) ;
savefile - > WriteInt ( muzzle_kick_maxtime ) ;
savefile - > WriteAngles ( muzzle_kick_angles ) ;
savefile - > WriteVec3 ( muzzle_kick_offset ) ;
savefile - > WriteInt ( ammoType ) ;
savefile - > WriteInt ( ammoRequired ) ;
savefile - > WriteInt ( clipSize ) ;
savefile - > WriteInt ( ammoClip ) ;
savefile - > WriteInt ( lowAmmo ) ;
savefile - > WriteBool ( powerAmmo ) ;
// savegames <= 17
savefile - > WriteInt ( 0 ) ;
savefile - > WriteInt ( zoomFov ) ;
savefile - > WriteJoint ( barrelJointView ) ;
savefile - > WriteJoint ( flashJointView ) ;
savefile - > WriteJoint ( ejectJointView ) ;
savefile - > WriteJoint ( guiLightJointView ) ;
savefile - > WriteJoint ( ventLightJointView ) ;
savefile - > WriteJoint ( flashJointWorld ) ;
savefile - > WriteJoint ( barrelJointWorld ) ;
savefile - > WriteJoint ( ejectJointWorld ) ;
savefile - > WriteBool ( hasBloodSplat ) ;
savefile - > WriteSoundShader ( sndHum ) ;
savefile - > WriteParticle ( weaponSmoke ) ;
savefile - > WriteInt ( weaponSmokeStartTime ) ;
savefile - > WriteBool ( continuousSmoke ) ;
savefile - > WriteParticle ( strikeSmoke ) ;
savefile - > WriteInt ( strikeSmokeStartTime ) ;
savefile - > WriteVec3 ( strikePos ) ;
savefile - > WriteMat3 ( strikeAxis ) ;
savefile - > WriteInt ( nextStrikeFx ) ;
savefile - > WriteBool ( nozzleFx ) ;
savefile - > WriteInt ( nozzleFxFade ) ;
savefile - > WriteInt ( lastAttack ) ;
savefile - > WriteInt ( nozzleGlowHandle ) ;
savefile - > WriteRenderLight ( nozzleGlow ) ;
savefile - > WriteVec3 ( nozzleGlowColor ) ;
savefile - > WriteMaterial ( nozzleGlowShader ) ;
savefile - > WriteFloat ( nozzleGlowRadius ) ;
savefile - > WriteInt ( weaponAngleOffsetAverages ) ;
savefile - > WriteFloat ( weaponAngleOffsetScale ) ;
savefile - > WriteFloat ( weaponAngleOffsetMax ) ;
savefile - > WriteFloat ( weaponOffsetTime ) ;
savefile - > WriteFloat ( weaponOffsetScale ) ;
savefile - > WriteBool ( allowDrop ) ;
savefile - > WriteObject ( projectileEnt ) ;
2020-11-29 14:49:20 +00:00
savefile - > WriteStaticObject ( grabber ) ;
savefile - > WriteInt ( grabberState ) ;
2020-11-15 18:52:37 +00:00
savefile - > WriteJoint ( smokeJointView ) ;
// Koz begin
for ( int i = 0 ; i < 2 ; i + + )
{
savefile - > WriteJoint ( weaponHandAttacher [ i ] ) ;
savefile - > WriteVec3 ( weaponHandDefaultPos [ i ] ) ;
savefile - > WriteMat3 ( weaponHandDefaultAxis [ i ] ) ;
}
// Koz end
2020-09-08 22:10:45 +00:00
}
2020-11-15 18:52:37 +00:00
/*
= = = = = = = = = = = = = = = =
idWeapon : : SetFlashlightOwner
Only called at player spawn time , not each weapon switch
= = = = = = = = = = = = = = = =
*/
void idWeapon : : SetFlashlightOwner ( idPlayer * _owner )
{
assert ( ! owner ) ;
owner = _owner ;
SetName ( va ( " %s_weapon_flashlight " , owner - > name . c_str ( ) ) ) ;
if ( worldModel . GetEntity ( ) )
{
worldModel . GetEntity ( ) - > SetName ( va ( " %s_weapon_flashlight_worldmodel " , owner - > name . c_str ( ) ) ) ;
}
}
2020-09-08 22:10:45 +00:00
/*
= = = = = = = = = = = = = = = =
idWeapon : : Restore
= = = = = = = = = = = = = = = =
*/
void idWeapon : : Restore ( idRestoreGame * savefile ) {
savefile - > ReadInt ( ( int & ) status ) ;
savefile - > ReadObject ( reinterpret_cast < idClass * & > ( thread ) ) ;
savefile - > ReadString ( state ) ;
savefile - > ReadString ( idealState ) ;
savefile - > ReadInt ( animBlendFrames ) ;
savefile - > ReadInt ( animDoneTime ) ;
savefile - > ReadBool ( isLinked ) ;
// Re-link script fields
WEAPON_ATTACK . LinkTo ( scriptObject , " WEAPON_ATTACK " ) ;
WEAPON_RELOAD . LinkTo ( scriptObject , " WEAPON_RELOAD " ) ;
WEAPON_NETRELOAD . LinkTo ( scriptObject , " WEAPON_NETRELOAD " ) ;
WEAPON_NETENDRELOAD . LinkTo ( scriptObject , " WEAPON_NETENDRELOAD " ) ;
if ( ! IsDoom3DemoVersion ( ) ) // the demo assets don't support WEAPON_NETFIRING
WEAPON_NETFIRING . LinkTo ( scriptObject , " WEAPON_NETFIRING " ) ;
WEAPON_RAISEWEAPON . LinkTo ( scriptObject , " WEAPON_RAISEWEAPON " ) ;
WEAPON_LOWERWEAPON . LinkTo ( scriptObject , " WEAPON_LOWERWEAPON " ) ;
savefile - > ReadObject ( reinterpret_cast < idClass * & > ( owner ) ) ;
worldModel . Restore ( savefile ) ;
savefile - > ReadInt ( hideTime ) ;
savefile - > ReadFloat ( hideDistance ) ;
savefile - > ReadInt ( hideStartTime ) ;
savefile - > ReadFloat ( hideStart ) ;
savefile - > ReadFloat ( hideEnd ) ;
savefile - > ReadFloat ( hideOffset ) ;
savefile - > ReadBool ( hide ) ;
savefile - > ReadBool ( disabled ) ;
savefile - > ReadInt ( berserk ) ;
savefile - > ReadVec3 ( playerViewOrigin ) ;
savefile - > ReadMat3 ( playerViewAxis ) ;
savefile - > ReadVec3 ( viewWeaponOrigin ) ;
savefile - > ReadMat3 ( viewWeaponAxis ) ;
savefile - > ReadVec3 ( muzzleOrigin ) ;
savefile - > ReadMat3 ( muzzleAxis ) ;
savefile - > ReadVec3 ( pushVelocity ) ;
idStr objectname ;
savefile - > ReadString ( objectname ) ;
weaponDef = gameLocal . FindEntityDef ( objectname ) ;
meleeDef = gameLocal . FindEntityDef ( weaponDef - > dict . GetString ( " def_melee " ) , false ) ;
const idDeclEntityDef * projectileDef = gameLocal . FindEntityDef ( weaponDef - > dict . GetString ( " def_projectile " ) , false ) ;
if ( projectileDef ) {
projectileDict = projectileDef - > dict ;
} else {
projectileDict . Clear ( ) ;
}
const idDeclEntityDef * brassDef = gameLocal . FindEntityDef ( weaponDef - > dict . GetString ( " def_ejectBrass " ) , false ) ;
if ( brassDef ) {
brassDict = brassDef - > dict ;
} else {
brassDict . Clear ( ) ;
}
savefile - > ReadFloat ( meleeDistance ) ;
savefile - > ReadString ( meleeDefName ) ;
savefile - > ReadInt ( brassDelay ) ;
savefile - > ReadString ( icon ) ;
savefile - > ReadInt ( guiLightHandle ) ;
savefile - > ReadRenderLight ( guiLight ) ;
savefile - > ReadInt ( muzzleFlashHandle ) ;
savefile - > ReadRenderLight ( muzzleFlash ) ;
savefile - > ReadInt ( worldMuzzleFlashHandle ) ;
savefile - > ReadRenderLight ( worldMuzzleFlash ) ;
savefile - > ReadVec3 ( flashColor ) ;
savefile - > ReadInt ( muzzleFlashEnd ) ;
savefile - > ReadInt ( flashTime ) ;
savefile - > ReadBool ( lightOn ) ;
savefile - > ReadBool ( silent_fire ) ;
savefile - > ReadInt ( kick_endtime ) ;
savefile - > ReadInt ( muzzle_kick_time ) ;
savefile - > ReadInt ( muzzle_kick_maxtime ) ;
savefile - > ReadAngles ( muzzle_kick_angles ) ;
savefile - > ReadVec3 ( muzzle_kick_offset ) ;
savefile - > ReadInt ( ( int & ) ammoType ) ;
savefile - > ReadInt ( ammoRequired ) ;
savefile - > ReadInt ( clipSize ) ;
savefile - > ReadInt ( ammoClip ) ;
savefile - > ReadInt ( lowAmmo ) ;
savefile - > ReadBool ( powerAmmo ) ;
// savegame versions <= 17
int foo ;
savefile - > ReadInt ( foo ) ;
savefile - > ReadInt ( zoomFov ) ;
savefile - > ReadJoint ( barrelJointView ) ;
savefile - > ReadJoint ( flashJointView ) ;
savefile - > ReadJoint ( ejectJointView ) ;
savefile - > ReadJoint ( guiLightJointView ) ;
savefile - > ReadJoint ( ventLightJointView ) ;
savefile - > ReadJoint ( flashJointWorld ) ;
savefile - > ReadJoint ( barrelJointWorld ) ;
savefile - > ReadJoint ( ejectJointWorld ) ;
savefile - > ReadBool ( hasBloodSplat ) ;
savefile - > ReadSoundShader ( sndHum ) ;
savefile - > ReadParticle ( weaponSmoke ) ;
savefile - > ReadInt ( weaponSmokeStartTime ) ;
savefile - > ReadBool ( continuousSmoke ) ;
savefile - > ReadParticle ( strikeSmoke ) ;
savefile - > ReadInt ( strikeSmokeStartTime ) ;
savefile - > ReadVec3 ( strikePos ) ;
savefile - > ReadMat3 ( strikeAxis ) ;
savefile - > ReadInt ( nextStrikeFx ) ;
savefile - > ReadBool ( nozzleFx ) ;
savefile - > ReadInt ( nozzleFxFade ) ;
savefile - > ReadInt ( lastAttack ) ;
savefile - > ReadInt ( nozzleGlowHandle ) ;
savefile - > ReadRenderLight ( nozzleGlow ) ;
savefile - > ReadVec3 ( nozzleGlowColor ) ;
savefile - > ReadMaterial ( nozzleGlowShader ) ;
savefile - > ReadFloat ( nozzleGlowRadius ) ;
savefile - > ReadInt ( weaponAngleOffsetAverages ) ;
savefile - > ReadFloat ( weaponAngleOffsetScale ) ;
savefile - > ReadFloat ( weaponAngleOffsetMax ) ;
savefile - > ReadFloat ( weaponOffsetTime ) ;
savefile - > ReadFloat ( weaponOffsetScale ) ;
savefile - > ReadBool ( allowDrop ) ;
savefile - > ReadObject ( reinterpret_cast < idClass * & > ( projectileEnt ) ) ;
2020-11-15 18:52:37 +00:00
2020-11-29 14:49:20 +00:00
savefile - > ReadStaticObject ( grabber ) ;
savefile - > ReadInt ( grabberState ) ;
2020-11-15 18:52:37 +00:00
savefile - > ReadJoint ( smokeJointView ) ;
for ( int i = 0 ; i < 2 ; i + + ) {
savefile - > ReadJoint ( weaponHandAttacher [ i ] ) ;
savefile - > ReadVec3 ( weaponHandDefaultPos [ i ] ) ;
savefile - > ReadMat3 ( weaponHandDefaultAxis [ i ] ) ;
}
// gui for stats device on player wrist in VR.
rvrStatGui = uiManager - > FindGui ( " guis/weapons/rvrstatgui.gui " , true , false , true ) ;
lvrStatGui = uiManager - > FindGui ( " guis/weapons/lvrstatgui.gui " , true , false , true ) ;
//scale = 1.0f; // koz code to scale weapon models in the world borks the viewmodel when loading quick or autosaves, so make sure scale is correct here.
2020-09-08 22:10:45 +00:00
}
/***********************************************************************
Weapon definition management
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
= = = = = = = = = = = = = = = =
idWeapon : : Clear
= = = = = = = = = = = = = = = =
*/
void idWeapon : : Clear ( void ) {
CancelEvents ( & EV_Weapon_Clear ) ;
DeconstructScriptObject ( ) ;
scriptObject . Free ( ) ;
WEAPON_ATTACK . Unlink ( ) ;
WEAPON_RELOAD . Unlink ( ) ;
WEAPON_NETRELOAD . Unlink ( ) ;
WEAPON_NETENDRELOAD . Unlink ( ) ;
if ( WEAPON_NETFIRING . IsLinked ( ) )
WEAPON_NETFIRING . Unlink ( ) ;
WEAPON_RAISEWEAPON . Unlink ( ) ;
WEAPON_LOWERWEAPON . Unlink ( ) ;
if ( muzzleFlashHandle ! = - 1 ) {
gameRenderWorld - > FreeLightDef ( muzzleFlashHandle ) ;
muzzleFlashHandle = - 1 ;
}
if ( muzzleFlashHandle ! = - 1 ) {
gameRenderWorld - > FreeLightDef ( muzzleFlashHandle ) ;
muzzleFlashHandle = - 1 ;
}
if ( worldMuzzleFlashHandle ! = - 1 ) {
gameRenderWorld - > FreeLightDef ( worldMuzzleFlashHandle ) ;
worldMuzzleFlashHandle = - 1 ;
}
if ( guiLightHandle ! = - 1 ) {
gameRenderWorld - > FreeLightDef ( guiLightHandle ) ;
guiLightHandle = - 1 ;
}
if ( nozzleGlowHandle ! = - 1 ) {
gameRenderWorld - > FreeLightDef ( nozzleGlowHandle ) ;
nozzleGlowHandle = - 1 ;
}
memset ( & renderEntity , 0 , sizeof ( renderEntity ) ) ;
renderEntity . entityNum = entityNumber ;
renderEntity . noShadow = true ;
renderEntity . noSelfShadow = true ;
renderEntity . customSkin = NULL ;
// set default shader parms
renderEntity . shaderParms [ SHADERPARM_RED ] = 1.0f ;
renderEntity . shaderParms [ SHADERPARM_GREEN ] = 1.0f ;
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 ;
if ( refSound . referenceSound ) {
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 ;
if ( owner ) {
// don't spatialize the weapon sounds
refSound . listenerId = owner - > GetListenerId ( ) ;
}
// clear out the sounds from our spawnargs since we'll copy them from the weapon def
const idKeyValue * kv = spawnArgs . MatchPrefix ( " snd_ " ) ;
while ( kv ) {
spawnArgs . Delete ( kv - > GetKey ( ) ) ;
kv = spawnArgs . MatchPrefix ( " snd_ " ) ;
}
hideTime = 300 ;
hideDistance = - 15.0f ;
hideStartTime = gameLocal . time - hideTime ;
hideStart = 0.0f ;
hideEnd = 0.0f ;
hideOffset = 0.0f ;
hide = false ;
disabled = false ;
weaponSmoke = NULL ;
weaponSmokeStartTime = 0 ;
continuousSmoke = false ;
strikeSmoke = NULL ;
strikeSmokeStartTime = 0 ;
strikePos . Zero ( ) ;
strikeAxis = mat3_identity ;
nextStrikeFx = 0 ;
icon = " " ;
playerViewAxis . Identity ( ) ;
playerViewOrigin . Zero ( ) ;
viewWeaponAxis . Identity ( ) ;
viewWeaponOrigin . Zero ( ) ;
muzzleAxis . Identity ( ) ;
muzzleOrigin . Zero ( ) ;
pushVelocity . Zero ( ) ;
status = WP_HOLSTERED ;
state = " " ;
idealState = " " ;
animBlendFrames = 0 ;
animDoneTime = 0 ;
projectileDict . Clear ( ) ;
meleeDef = NULL ;
meleeDefName = " " ;
meleeDistance = 0.0f ;
brassDict . Clear ( ) ;
flashTime = 250 ;
lightOn = false ;
silent_fire = false ;
2020-11-29 14:49:20 +00:00
grabberState = - 1 ;
grabber . Update ( owner , this , true ) ;
2020-09-08 22:10:45 +00:00
ammoType = 0 ;
ammoRequired = 0 ;
ammoClip = 0 ;
clipSize = 0 ;
lowAmmo = 0 ;
powerAmmo = false ;
kick_endtime = 0 ;
muzzle_kick_time = 0 ;
muzzle_kick_maxtime = 0 ;
muzzle_kick_angles . Zero ( ) ;
muzzle_kick_offset . Zero ( ) ;
zoomFov = 90 ;
barrelJointView = INVALID_JOINT ;
flashJointView = INVALID_JOINT ;
ejectJointView = INVALID_JOINT ;
guiLightJointView = INVALID_JOINT ;
ventLightJointView = INVALID_JOINT ;
barrelJointWorld = INVALID_JOINT ;
flashJointWorld = INVALID_JOINT ;
ejectJointWorld = INVALID_JOINT ;
2020-11-15 18:52:37 +00:00
smokeJointView = INVALID_JOINT ;
2020-09-08 22:10:45 +00:00
hasBloodSplat = false ;
nozzleFx = false ;
nozzleFxFade = 1500 ;
lastAttack = 0 ;
nozzleGlowHandle = - 1 ;
nozzleGlowShader = NULL ;
nozzleGlowRadius = 10 ;
nozzleGlowColor . Zero ( ) ;
weaponAngleOffsetAverages = 0 ;
weaponAngleOffsetScale = 0.0f ;
weaponAngleOffsetMax = 0.0f ;
weaponOffsetTime = 0.0f ;
weaponOffsetScale = 0.0f ;
allowDrop = true ;
animator . ClearAllAnims ( gameLocal . time , 0 ) ;
FreeModelDef ( ) ;
sndHum = NULL ;
isLinked = false ;
projectileEnt = NULL ;
isFiring = false ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : InitWorldModel
= = = = = = = = = = = = = = = =
*/
void idWeapon : : InitWorldModel ( const idDeclEntityDef * def ) {
idEntity * ent ;
ent = worldModel . GetEntity ( ) ;
assert ( ent ) ;
assert ( def ) ;
const char * model = def - > dict . GetString ( " model_world " ) ;
const char * attach = def - > dict . GetString ( " joint_attach " ) ;
ent - > SetSkin ( NULL ) ;
if ( model [ 0 ] & & attach [ 0 ] ) {
ent - > Show ( ) ;
ent - > SetModel ( model ) ;
if ( ent - > GetAnimator ( ) - > ModelDef ( ) ) {
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 ) ;
// supress model in player views, but allow it in mirrors and remote views
renderEntity_t * worldModelRenderEntity = ent - > GetRenderEntity ( ) ;
if ( worldModelRenderEntity ) {
2020-11-15 18:52:37 +00:00
// Koz begin
if ( game - > isVR & & ! strstr ( def - > dict . GetString ( " model_world " ) , " flashlight " ) )
{
// Koz dont show the worldmodel if the player body is shown in vr.
worldModelRenderEntity - > suppressSurfaceInViewID = 0 ;
worldModelRenderEntity - > suppressShadowInViewID = 0 ;
}
else
{
//Carl: Don't suppress drawing the weapon's world model or it's shadow in 1st person, if they want to see it (in VR)
worldModelRenderEntity - > suppressSurfaceInViewID = owner - > entityNumber + 1 ;
worldModelRenderEntity - > suppressShadowInViewID = owner - > entityNumber + 1 ;
}
// Koz end
2020-09-08 22:10:45 +00:00
worldModelRenderEntity - > suppressShadowInLightID = LIGHTID_VIEW_MUZZLE_FLASH + owner - > entityNumber ;
}
} else {
ent - > SetModel ( " " ) ;
ent - > Hide ( ) ;
}
flashJointWorld = ent - > GetAnimator ( ) - > GetJointHandle ( " flash " ) ;
barrelJointWorld = ent - > GetAnimator ( ) - > GetJointHandle ( " muzzle " ) ;
ejectJointWorld = ent - > GetAnimator ( ) - > GetJointHandle ( " eject " ) ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : GetWeaponDef
= = = = = = = = = = = = = = = =
*/
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 ;
int ammoAvail ;
Clear ( ) ;
if ( ! objectname | | ! objectname [ 0 ] ) {
return ;
}
assert ( owner ) ;
weaponDef = gameLocal . FindEntityDef ( objectname ) ;
ammoType = GetAmmoNumForName ( weaponDef - > dict . GetString ( " ammoType " ) ) ;
ammoRequired = weaponDef - > dict . GetInt ( " ammoRequired " ) ;
clipSize = weaponDef - > dict . GetInt ( " clipSize " ) ;
lowAmmo = weaponDef - > dict . GetInt ( " lowAmmo " ) ;
icon = weaponDef - > dict . GetString ( " icon " ) ;
silent_fire = weaponDef - > dict . GetBool ( " silent_fire " ) ;
powerAmmo = weaponDef - > dict . GetBool ( " powerAmmo " ) ;
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 " ) ;
hideTime = SEC2MS ( weaponDef - > dict . GetFloat ( " hide_time " , " 0.3 " ) ) ;
hideDistance = weaponDef - > dict . GetFloat ( " hide_distance " , " -15 " ) ;
// muzzle smoke
smokeName = weaponDef - > dict . GetString ( " smoke_muzzle " ) ;
if ( * smokeName ! = ' \0 ' ) {
weaponSmoke = static_cast < const idDeclParticle * > ( declManager - > FindType ( DECL_PARTICLE , smokeName ) ) ;
} else {
weaponSmoke = NULL ;
}
continuousSmoke = weaponDef - > dict . GetBool ( " continuousSmoke " ) ;
weaponSmokeStartTime = ( continuousSmoke ) ? gameLocal . time : 0 ;
smokeName = weaponDef - > dict . GetString ( " smoke_strike " ) ;
if ( * smokeName ! = ' \0 ' ) {
strikeSmoke = static_cast < const idDeclParticle * > ( declManager - > FindType ( DECL_PARTICLE , smokeName ) ) ;
} else {
strikeSmoke = NULL ;
}
strikeSmokeStartTime = 0 ;
strikePos . Zero ( ) ;
strikeAxis = mat3_identity ;
nextStrikeFx = 0 ;
// setup gui light
memset ( & guiLight , 0 , sizeof ( guiLight ) ) ;
const char * guiLightShader = weaponDef - > dict . GetString ( " mtr_guiLightShader " ) ;
if ( * guiLightShader ! = ' \0 ' ) {
2020-11-15 18:52:37 +00:00
// Koz begin
// the PDA model was scaled by a factor of 2.5 to make it easier to read in VR.
// The weapon guilight size isn't stored in the weapon def, it's hardcoded here,
// so check if PDA and resize the guilight accordingly
int lightRad = 3 ;
if ( game - > isVR )
{
const char * weapName = weaponDef - > dict . GetString ( " inv_name " ) ;
if ( strstr ( weapName , " PDA " ) )
{
lightRad * = 3 ; // the PDA guilight needs to be bigger in VR
}
}
guiLight . shader = declManager - > FindMaterial ( guiLightShader , false ) ;
guiLight . lightRadius [ 0 ] = guiLight . lightRadius [ 1 ] = guiLight . lightRadius [ 2 ] = lightRad ;
2020-09-08 22:10:45 +00:00
guiLight . pointLight = true ;
}
// setup the view model
vmodel = weaponDef - > dict . GetString ( " model_view " ) ;
SetModel ( vmodel ) ;
2020-11-15 18:52:37 +00:00
// Koz weapon shadows
renderEntity . noShadow = false ;
2020-09-08 22:10:45 +00:00
// setup the world model
InitWorldModel ( weaponDef ) ;
2020-11-15 18:52:37 +00:00
worldModel . GetEntity ( ) - > GetRenderEntity ( ) - > noShadow = true ; // Koz fixme only if using viewweapon for body model
2020-09-08 22:10:45 +00:00
// copy the sounds from the weapon view model def into out spawnargs
const idKeyValue * kv = weaponDef - > dict . MatchPrefix ( " snd_ " ) ;
while ( kv ) {
spawnArgs . Set ( kv - > GetKey ( ) , kv - > GetValue ( ) ) ;
kv = weaponDef - > dict . MatchPrefix ( " snd_ " , kv ) ;
}
2020-11-15 18:52:37 +00:00
if ( game - > isVR )
{
weaponHandAttacher [ 0 ] = animator . GetJointHandle ( " RhandAttacher " ) ;
if ( weaponHandAttacher [ 0 ] ! = INVALID_JOINT )
{
// Koz debug common->Printf( "Weapon %s RhandAttacherJoint Found\n", objectname );
animator . GetJointTransform ( weaponHandAttacher [ 0 ] , gameLocal . time , weaponHandDefaultPos [ 0 ] , weaponHandDefaultAxis [ 0 ] ) ;
// Koz debug common->Printf( "Default pos %s default axis %s\n", weaponHandDefaultPos[0].ToString(), weaponHandDefaultAxis[0].ToAngles().ToString() );
}
weaponHandAttacher [ 1 ] = animator . GetJointHandle ( " LhandAttacher " ) ;
if ( weaponHandAttacher [ 1 ] ! = INVALID_JOINT )
{
// Koz debug common->Printf( "Weapon %s LhandAttacherJoint Found\n", objectname );
animator . GetJointTransform ( weaponHandAttacher [ 1 ] , gameLocal . time , weaponHandDefaultPos [ 1 ] , weaponHandDefaultAxis [ 1 ] ) ;
// Koz debug common->Printf( "Default pos %s default axis %s\n", weaponHandDefaultPos[1].ToString(), weaponHandDefaultAxis[1].ToAngles().ToString() );
}
laserSightOffset = weaponDef - > dict . GetVector ( " laserSightOffset " ) ;
}
2020-09-08 22:10:45 +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 " ) ;
2020-11-15 18:52:37 +00:00
idStr smokeJoint = weaponDef - > dict . GetString ( " smoke_joint " ) ;
if ( smokeJoint . Length ( ) > 0 )
{
smokeJointView = animator . GetJointHandle ( smokeJoint ) ;
}
else
{
smokeJointView = INVALID_JOINT ;
}
2020-09-08 22:10:45 +00:00
// get the projectile
projectileDict . Clear ( ) ;
projectileName = weaponDef - > dict . GetString ( " def_projectile " ) ;
if ( projectileName [ 0 ] ! = ' \0 ' ) {
const idDeclEntityDef * projectileDef = gameLocal . FindEntityDef ( projectileName , false ) ;
if ( ! projectileDef ) {
gameLocal . Warning ( " Unknown projectile '%s' in weapon '%s' " , projectileName , objectname ) ;
} else {
const char * spawnclass = projectileDef - > dict . GetString ( " spawnclass " ) ;
idTypeInfo * cls = idClass : : GetClass ( spawnclass ) ;
if ( ! cls | | ! cls - > IsType ( idProjectile : : Type ) ) {
gameLocal . Warning ( " Invalid spawnclass '%s' on projectile '%s' (used by weapon '%s') " , spawnclass , projectileName , objectname ) ;
} else {
projectileDict = projectileDef - > dict ;
}
}
}
// set up muzzleflash render light
const idMaterial * flashShader ;
idVec3 flashTarget ;
idVec3 flashUp ;
idVec3 flashRight ;
float flashRadius ;
bool flashPointLight ;
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 ) ;
flashRadius = ( float ) weaponDef - > dict . GetInt ( " flashRadius " ) ; // if 0, no light will spawn
flashTime = SEC2MS ( weaponDef - > dict . GetFloat ( " flashTime " , " 0.25 " ) ) ;
flashTarget = weaponDef - > dict . GetVector ( " flashTarget " ) ;
flashUp = weaponDef - > dict . GetVector ( " flashUp " ) ;
flashRight = weaponDef - > dict . GetVector ( " flashRight " ) ;
memset ( & muzzleFlash , 0 , sizeof ( muzzleFlash ) ) ;
muzzleFlash . lightId = LIGHTID_VIEW_MUZZLE_FLASH + owner - > entityNumber ;
muzzleFlash . allowLightInViewID = owner - > entityNumber + 1 ;
// the weapon lights will only be in first person
guiLight . allowLightInViewID = owner - > entityNumber + 1 ;
nozzleGlow . allowLightInViewID = owner - > entityNumber + 1 ;
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 ;
muzzleFlash . lightRadius [ 0 ] = flashRadius ;
muzzleFlash . lightRadius [ 1 ] = flashRadius ;
muzzleFlash . lightRadius [ 2 ] = flashRadius ;
if ( ! flashPointLight ) {
muzzleFlash . target = flashTarget ;
muzzleFlash . up = flashUp ;
muzzleFlash . right = flashRight ;
muzzleFlash . end = flashTarget ;
}
// the world muzzle flash is the same, just positioned differently
worldMuzzleFlash = muzzleFlash ;
worldMuzzleFlash . suppressLightInViewID = owner - > entityNumber + 1 ;
worldMuzzleFlash . allowLightInViewID = 0 ;
worldMuzzleFlash . lightId = LIGHTID_WORLD_MUZZLE_FLASH + owner - > entityNumber ;
//-----------------------------------
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 " ) ;
weaponDef - > dict . GetString ( " mtr_nozzleGlowShader " , " " , & shader ) ;
nozzleGlowShader = declManager - > FindMaterial ( shader , false ) ;
// get the melee damage def
meleeDistance = weaponDef - > dict . GetFloat ( " melee_distance " ) ;
meleeDefName = weaponDef - > dict . GetString ( " def_melee " ) ;
if ( meleeDefName . Length ( ) ) {
meleeDef = gameLocal . FindEntityDef ( meleeDefName , false ) ;
if ( ! meleeDef ) {
gameLocal . Error ( " Unknown melee '%s' " , meleeDefName . c_str ( ) ) ;
}
}
// get the brass def
brassDict . Clear ( ) ;
brassDelay = weaponDef - > dict . GetInt ( " ejectBrassDelay " , " 0 " ) ;
brassDefName = weaponDef - > dict . GetString ( " def_ejectBrass " ) ;
if ( brassDefName [ 0 ] ) {
const idDeclEntityDef * brassDef = gameLocal . FindEntityDef ( brassDefName , false ) ;
if ( ! brassDef ) {
gameLocal . Warning ( " Unknown brass '%s' " , brassDefName ) ;
} else {
brassDict = brassDef - > dict ;
}
}
if ( ( ammoType < 0 ) | | ( ammoType > = AMMO_NUMTYPES ) ) {
gameLocal . Warning ( " Unknown ammotype in object '%s' " , objectname ) ;
}
ammoClip = ammoinclip ;
if ( ( ammoClip < 0 ) | | ( ammoClip > clipSize ) ) {
// first time using this weapon so have it fully loaded to start
ammoClip = clipSize ;
ammoAvail = owner - > inventory . HasAmmo ( ammoType , ammoRequired ) ;
if ( ammoClip > ammoAvail ) {
ammoClip = ammoAvail ;
}
}
renderEntity . gui [ 0 ] = NULL ;
guiName = weaponDef - > dict . GetString ( " gui " ) ;
if ( guiName [ 0 ] ) {
renderEntity . gui [ 0 ] = uiManager - > FindGui ( guiName , true , false , true ) ;
}
2020-11-15 18:52:37 +00:00
// Koz begin - gui for stats device on player wrist in VR.
rvrStatGui = uiManager - > FindGui ( " guis/weapons/rvrstatgui.gui " , true , false , true ) ;
lvrStatGui = uiManager - > FindGui ( " guis/weapons/lvrstatgui.gui " , true , false , true ) ;
// Koz end
2020-09-08 22:10:45 +00:00
zoomFov = weaponDef - > dict . GetInt ( " zoomFov " , " 70 " ) ;
berserk = weaponDef - > dict . GetInt ( " berserk " , " 2 " ) ;
weaponAngleOffsetAverages = weaponDef - > dict . GetInt ( " weaponAngleOffsetAverages " , " 10 " ) ;
weaponAngleOffsetScale = weaponDef - > dict . GetFloat ( " weaponAngleOffsetScale " , " 0.25 " ) ;
weaponAngleOffsetMax = weaponDef - > dict . GetFloat ( " weaponAngleOffsetMax " , " 10 " ) ;
weaponOffsetTime = weaponDef - > dict . GetFloat ( " weaponOffsetTime " , " 400 " ) ;
weaponOffsetScale = weaponDef - > dict . GetFloat ( " weaponOffsetScale " , " 0.005 " ) ;
if ( ! weaponDef - > dict . GetString ( " weapon_scriptobject " , NULL , & objectType ) ) {
gameLocal . Error ( " No 'weapon_scriptobject' set on '%s'. " , objectname ) ;
}
// setup script object
if ( ! scriptObject . SetType ( objectType ) ) {
gameLocal . Error ( " Script object '%s' not found on weapon '%s'. " , objectType , objectname ) ;
}
WEAPON_ATTACK . LinkTo ( scriptObject , " WEAPON_ATTACK " ) ;
WEAPON_RELOAD . LinkTo ( scriptObject , " WEAPON_RELOAD " ) ;
WEAPON_NETRELOAD . LinkTo ( scriptObject , " WEAPON_NETRELOAD " ) ;
WEAPON_NETENDRELOAD . LinkTo ( scriptObject , " WEAPON_NETENDRELOAD " ) ;
if ( ! IsDoom3DemoVersion ( ) ) // the demo assets don't support WEAPON_NETFIRING
WEAPON_NETFIRING . LinkTo ( scriptObject , " WEAPON_NETFIRING " ) ;
WEAPON_RAISEWEAPON . LinkTo ( scriptObject , " WEAPON_RAISEWEAPON " ) ;
WEAPON_LOWERWEAPON . LinkTo ( scriptObject , " WEAPON_LOWERWEAPON " ) ;
spawnArgs = weaponDef - > dict ;
shader = spawnArgs . GetString ( " snd_hum " ) ;
if ( shader & & * shader ) {
sndHum = declManager - > FindSound ( shader ) ;
StartSoundShader ( sndHum , SND_CHANNEL_BODY , 0 , false , NULL ) ;
}
isLinked = true ;
// call script object's constructor
ConstructScriptObject ( ) ;
// make sure we have the correct skin
UpdateSkin ( ) ;
}
/***********************************************************************
GUIs
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
= = = = = = = = = = = = = = = =
idWeapon : : Icon
= = = = = = = = = = = = = = = =
*/
const char * idWeapon : : Icon ( void ) const {
return icon ;
}
2020-11-15 18:52:37 +00:00
/*
= = = = = = = = = = = = = = =
idWeapon : : IdentifyWeapon
Koz return weapon enumeration
= = = = = = = = = = = = = = =
*/
weapon_t idWeapon : : IdentifyWeapon ( )
{
2020-11-16 23:44:42 +00:00
int currentFrameNumber = common - > GetFrameNumber ( ) ;
if ( lastIdentifiedFrame = = currentFrameNumber ) // only check once per game frame.
2020-11-15 18:52:37 +00:00
{
2020-11-16 23:44:42 +00:00
return currentIdentifiedWeapon ;
2020-11-15 18:52:37 +00:00
}
2020-11-16 23:44:42 +00:00
lastIdentifiedFrame = currentFrameNumber ;
2020-11-15 18:52:37 +00:00
currentIdentifiedWeapon = WEAPON_NONE ;
if ( this )
{
if ( weaponDef ! = NULL )
{
idStr weaponName = weaponDef - > GetName ( ) ;
2020-11-18 14:48:17 +00:00
if ( idStr : : Icmp ( " weapon_fists " , weaponDef - > GetName ( ) ) = = 0 ) currentIdentifiedWeapon = WEAPON_FISTS ;
else if ( idStr : : Icmp ( " weapon_chainsaw " , weaponDef - > GetName ( ) ) = = 0 ) currentIdentifiedWeapon = WEAPON_CHAINSAW ;
else if ( idStr : : Icmp ( " weapon_pistol " , weaponDef - > GetName ( ) ) = = 0 ) currentIdentifiedWeapon = WEAPON_PISTOL ;
else if ( idStr : : Icmp ( " weapon_shotgun " , weaponDef - > GetName ( ) ) = = 0 ) currentIdentifiedWeapon = WEAPON_SHOTGUN ;
else if ( idStr : : Icmp ( " weapon_machinegun " , weaponDef - > GetName ( ) ) = = 0 ) currentIdentifiedWeapon = WEAPON_MACHINEGUN ;
else if ( idStr : : Icmp ( " weapon_chaingun " , weaponDef - > GetName ( ) ) = = 0 ) currentIdentifiedWeapon = WEAPON_CHAINGUN ;
else if ( idStr : : Icmp ( " weapon_handgrenade " , weaponDef - > GetName ( ) ) = = 0 ) currentIdentifiedWeapon = WEAPON_HANDGRENADE ;
else if ( idStr : : Icmp ( " weapon_plasmagun " , weaponDef - > GetName ( ) ) = = 0 ) currentIdentifiedWeapon = WEAPON_PLASMAGUN ;
else if ( idStr : : Icmp ( " weapon_rocketlauncher " , weaponDef - > GetName ( ) ) = = 0 ) currentIdentifiedWeapon = WEAPON_ROCKETLAUNCHER ;
else if ( idStr : : Icmp ( " weapon_bfg " , weaponDef - > GetName ( ) ) = = 0 ) currentIdentifiedWeapon = WEAPON_BFG ;
else if ( idStr : : Icmp ( " weapon_soulcube " , weaponDef - > GetName ( ) ) = = 0 ) currentIdentifiedWeapon = WEAPON_SOULCUBE ;
else if ( idStr : : Icmp ( " weapon_shotgun_double_mp " , weaponDef - > GetName ( ) ) = = 0 ) currentIdentifiedWeapon = WEAPON_SHOTGUN_DOUBLE_MP ;
else if ( idStr : : Icmp ( " weapon_grabber " , weaponDef - > GetName ( ) ) = = 0 ) currentIdentifiedWeapon = WEAPON_GRABBER ;
else if ( idStr : : Icmp ( " weapon_shotgun_double " , weaponDef - > GetName ( ) ) = = 0 ) currentIdentifiedWeapon = WEAPON_SHOTGUN_DOUBLE ;
else if ( idStr : : Icmp ( " weapon_artifact " , weaponDef - > GetName ( ) ) = = 0 ) currentIdentifiedWeapon = WEAPON_ARTIFACT ;
else if ( idStr : : Icmp ( " weapon_bloodstone_passive " , weaponDef - > GetName ( ) ) = = 0 ) currentIdentifiedWeapon = WEAPON_ARTIFACT ;
else if ( idStr : : Icmp ( " weapon_bloodstone_active1 " , weaponDef - > GetName ( ) ) = = 0 ) currentIdentifiedWeapon = WEAPON_ARTIFACT ;
else if ( idStr : : Icmp ( " weapon_bloodstone_active2 " , weaponDef - > GetName ( ) ) = = 0 ) currentIdentifiedWeapon = WEAPON_ARTIFACT ;
else if ( idStr : : Icmp ( " weapon_bloodstone_active3 " , weaponDef - > GetName ( ) ) = = 0 ) currentIdentifiedWeapon = WEAPON_ARTIFACT ;
else if ( idStr : : Icmp ( " weapon_pda " , weaponDef - > GetName ( ) ) = = 0 ) currentIdentifiedWeapon = WEAPON_PDA ;
else if ( idStr : : Icmp ( " weapon_flashlight_new " , weaponDef - > GetName ( ) ) = = 0 ) currentIdentifiedWeapon = lastIdentifiedWeapon ;
2020-11-29 14:49:20 +00:00
//else if ( idStr::Icmp( "weapon_flashlight_new", weaponDef->GetName() ) == 0 ) currentWeapon = WEAPON_FLASHLIGHT;
//else if ( idStr::Icmp( "weapon_flashlight", weaponDef->GetName() ) == 0 ) currentWeapon = WEAPON_FLASHLIGHT;
2020-11-18 14:48:17 +00:00
else currentIdentifiedWeapon = WEAPON_NONE ;
lastIdentifiedWeapon = currentIdentifiedWeapon ;
2020-11-15 18:52:37 +00:00
}
}
if ( currentIdentifiedWeapon = = WEAPON_FLASHLIGHT ) common - > Printf ( " Identify weapon returned %s \n " , weaponDef - > GetName ( ) ) ;
return currentIdentifiedWeapon ;
}
2020-09-08 22:10:45 +00:00
/*
= = = = = = = = = = = = = = = =
idWeapon : : UpdateGUI
= = = = = = = = = = = = = = = =
*/
void idWeapon : : UpdateGUI ( void ) {
2020-11-15 18:52:37 +00:00
if ( game - > isVR ) UpdateVRGUI ( ) ;
2020-09-08 22:10:45 +00:00
if ( ! renderEntity . gui [ 0 ] ) {
return ;
}
if ( status = = WP_HOLSTERED ) {
return ;
}
if ( owner - > weaponGone ) {
// 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 ;
}
if ( gameLocal . localClientNum ! = owner - > entityNumber ) {
// if updating the hud for a followed client
if ( gameLocal . localClientNum > = 0 & & gameLocal . entities [ gameLocal . localClientNum ] & & gameLocal . entities [ gameLocal . localClientNum ] - > IsType ( idPlayer : : Type ) ) {
idPlayer * p = static_cast < idPlayer * > ( gameLocal . entities [ gameLocal . localClientNum ] ) ;
if ( ! p - > spectating | | p - > spectator ! = owner - > entityNumber ) {
return ;
}
} else {
return ;
}
}
int inclip = AmmoInClip ( ) ;
int ammoamount = AmmoAvailable ( ) ;
if ( ammoamount < 0 ) {
// show infinite ammo
renderEntity . gui [ 0 ] - > SetStateString ( " player_ammo " , " " ) ;
} else {
// show remaining ammo
renderEntity . gui [ 0 ] - > SetStateString ( " player_totalammo " , va ( " %i " , ammoamount - inclip ) ) ;
renderEntity . gui [ 0 ] - > SetStateString ( " player_ammo " , ClipSize ( ) ? va ( " %i " , inclip ) : " -- " ) ;
renderEntity . gui [ 0 ] - > SetStateString ( " player_clips " , ClipSize ( ) ? va ( " %i " , ammoamount / ClipSize ( ) ) : " -- " ) ;
renderEntity . gui [ 0 ] - > SetStateString ( " player_allammo " , va ( " %i/%i " , inclip , ammoamount - inclip ) ) ;
}
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 ) ) ;
2020-11-29 14:49:20 +00:00
//Grabber Gui Info
renderEntity . gui [ 0 ] - > SetStateString ( " grabber_state " , va ( " %i " , grabberState ) ) ;
2020-09-08 22:10:45 +00:00
}
/***********************************************************************
Model and muzzleflash
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
= = = = = = = = = = = = = = = =
idWeapon : : UpdateFlashPosition
= = = = = = = = = = = = = = = =
*/
void idWeapon : : UpdateFlashPosition ( void ) {
// the flash has an explicit joint for locating it
GetGlobalJointTransform ( true , flashJointView , muzzleFlash . origin , muzzleFlash . axis ) ;
2020-11-15 18:52:37 +00:00
if ( isPlayerFlashlight )
{
static float pscale = 2.0f ;
static float yscale = 0.25f ;
// 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];
muzzleFlash . origin + = owner - > GetViewBob ( ) ;
// 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()*/ ;
}
// 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 ;
2020-09-08 22:10:45 +00:00
2020-11-15 18:52:37 +00:00
muzzleFlash . noShadows = ! g_weaponShadows . GetBool ( ) ;
// put the world muzzle flash on the end of the joint, no matter what
GetGlobalJointTransform ( false , flashJointWorld , worldMuzzleFlash . origin , worldMuzzleFlash . axis ) ;
2020-09-08 22:10:45 +00:00
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : MuzzleFlashLight
= = = = = = = = = = = = = = = =
*/
void idWeapon : : MuzzleFlashLight ( void ) {
if ( ! lightOn & & ( ! g_muzzleFlash . GetBool ( ) | | ! muzzleFlash . lightRadius [ 0 ] ) ) {
return ;
}
if ( flashJointView = = INVALID_JOINT ) {
return ;
}
UpdateFlashPosition ( ) ;
// these will be different each fire
muzzleFlash . shaderParms [ SHADERPARM_TIMEOFFSET ] = - MS2SEC ( gameLocal . time ) ;
muzzleFlash . shaderParms [ SHADERPARM_DIVERSITY ] = renderEntity . shaderParms [ SHADERPARM_DIVERSITY ] ;
worldMuzzleFlash . shaderParms [ SHADERPARM_TIMEOFFSET ] = - MS2SEC ( gameLocal . time ) ;
worldMuzzleFlash . shaderParms [ SHADERPARM_DIVERSITY ] = renderEntity . shaderParms [ SHADERPARM_DIVERSITY ] ;
// the light will be removed at this time
muzzleFlashEnd = gameLocal . time + flashTime ;
if ( muzzleFlashHandle ! = - 1 ) {
gameRenderWorld - > UpdateLightDef ( muzzleFlashHandle , & muzzleFlash ) ;
gameRenderWorld - > UpdateLightDef ( worldMuzzleFlashHandle , & worldMuzzleFlash ) ;
} else {
muzzleFlashHandle = gameRenderWorld - > AddLightDef ( & muzzleFlash ) ;
worldMuzzleFlashHandle = gameRenderWorld - > AddLightDef ( & worldMuzzleFlash ) ;
}
}
2020-11-15 18:52:37 +00:00
/*
= = = = = = = = = = = = = = = =
idWeapon : : UpdateVRGUI
= = = = = = = = = = = = = = = =
*/
void idWeapon : : UpdateVRGUI ( )
{
float healthv = 0.0f ;
float armorv = 0.0f ;
float armorb = 0.0f ;
float healthb = 0.0f ;
idPlayer * player ;
player = gameLocal . GetLocalPlayer ( ) ;
if ( ! player ) return ;
if ( rvrStatGui = = NULL )
{
return ;
}
if ( status = = WP_HOLSTERED )
{
return ;
}
if ( isPlayerFlashlight | | isPlayerLeftHand ) return ;
if ( owner - > weaponGone )
{
// dropping weapons was implemented weird, so we have to not update the gui when it happens or we'll get a negative ammo count
return ;
}
int inclip [ 2 ] ;
int ammoamount [ 2 ] ;
int clipsize [ 2 ] ;
bool harvester [ 2 ] ;
bool ammoEmpty [ 2 ] ;
bool clipEmpty [ 2 ] ;
bool clipLow [ 2 ] ;
for ( int h = 0 ; h < 2 ; h + + )
{
inclip [ h ] = player - > hands [ h ] . weapon . GetEntity ( ) - > AmmoInClip ( ) ;
ammoamount [ h ] = player - > hands [ h ] . weapon . GetEntity ( ) - > AmmoAvailable ( ) ;
harvester [ h ] = player - > hands [ h ] . weapon . GetEntity ( ) - > IdentifyWeapon ( ) = = WEAPON_ARTIFACT | | player - > hands [ h ] . weapon . GetEntity ( ) - > IdentifyWeapon ( ) = = WEAPON_SOULCUBE ;
clipsize [ h ] = player - > hands [ h ] . weapon . GetEntity ( ) - > ClipSize ( ) ;
ammoEmpty [ h ] = ( ammoamount [ h ] = = 0 ) ;
clipEmpty [ h ] = ( player - > hands [ h ] . weapon . GetEntity ( ) - > ClipSize ( ) & & inclip [ h ] = = 0 ) ;
clipLow [ h ] = ( player - > hands [ h ] . weapon . GetEntity ( ) - > ClipSize ( ) & & player - > hands [ h ] . weapon . GetEntity ( ) - > LowAmmo ( ) ) ;
}
//int inclip = AmmoInClip();
//int ammoamount = AmmoAvailable();
// update the right hand statwatch
if ( ammoamount [ HAND_RIGHT ] < 0 )
{
// show infinite ammo
rvrStatGui - > SetStateString ( " player_ammo " , " " ) ;
}
else
{
// show remaining ammo
rvrStatGui - > SetStateString ( " player_totalammo " , va ( " %i " , ammoamount [ HAND_RIGHT ] ) ) ;
rvrStatGui - > SetStateString ( " player_ammo " , clipsize [ HAND_RIGHT ] ? va ( " %i " , inclip [ HAND_RIGHT ] ) : " -- " ) ;
rvrStatGui - > SetStateString ( " player_clips " , clipsize [ HAND_RIGHT ] ? va ( " %i " , ammoamount [ HAND_RIGHT ] / clipsize [ HAND_RIGHT ] ) : " -- " ) ;
rvrStatGui - > SetStateString ( " player_allammo " , va ( " %i/%i " , inclip [ HAND_RIGHT ] , ammoamount [ HAND_RIGHT ] ) ) ;
}
rvrStatGui - > SetStateBool ( " player_ammo_empty " , ( ammoEmpty [ HAND_RIGHT ] ) ) ;
rvrStatGui - > SetStateBool ( " player_clip_empty " , ( clipEmpty [ HAND_RIGHT ] ) ) ;
rvrStatGui - > SetStateBool ( " player_clip_low " , ( clipLow [ HAND_RIGHT ] ) ) ;
// koz todo
// need to get the ammocount from the hand structures, not sure right now, in the interim just use the ammo amount.
//Let the GUI know the total amount of ammo regardless of the ammo required value
//rvrStatGui->SetStateString( "player_ammo_count", va( "%i", AmmoCount() ) );
rvrStatGui - > SetStateString ( " player_ammo_count " , va ( " %i " , ammoamount [ HAND_RIGHT ] ) ) ;
// koz end
2020-11-29 14:49:20 +00:00
// koz todo also need to figure this out for dual guis
//Grabber Gui Info
rvrStatGui - > SetStateString ( " grabber_state " , va ( " %i " , grabberState ) ) ;
2020-11-15 18:52:37 +00:00
//health and armor
if ( player )
{
healthv = ( float ) player - > health ;
if ( player - > inventory . armor )
{
armorv = ( float ) player - > inventory . armor ;
}
//healthv = vr_guiH.GetInteger();
//armorv = vr_guiA.GetInteger();
healthv = idMath : : ClampFloat ( 0.0 , 100.0 , healthv ) ;
armorv = idMath : : ClampFloat ( 0.0 , 100.0 , armorv ) ;
if ( healthv > = 75.0 ) healthb = ( healthv / 100.0f ) ;
if ( armorv > = 75.0 ) armorb = ( armorv / 100.0f ) ;
healthb = idMath : : ClampFloat ( 0.0 , 100.0 , healthb ) ;
armorb = idMath : : ClampFloat ( 0.0 , 100.0 , armorb ) ;
}
rvrStatGui - > SetStateString ( " player_health " , va ( " %f " , healthv ) ) ;
//vrStatGui->SetStateString( "player_armor", va( "%i%%", armorv ) );
rvrStatGui - > SetStateString ( " player_armor " , va ( " %f " , armorv ) ) ;
rvrStatGui - > SetStateString ( " player_healthb " , va ( " %f " , healthb ) ) ;
rvrStatGui - > SetStateString ( " player_armorb " , va ( " %f " , armorb ) ) ;
// update the left hand stat watch gui.
if ( lvrStatGui = = NULL )
{
common - > Printf ( " Left Hand stat gui not found. \n " ) ;
return ;
}
lvrStatGui - > SetStateString ( " player_health " , va ( " %f " , healthv ) ) ;
//vrStatGui->SetStateString( "player_armor", va( "%i%%", armorv ) );
lvrStatGui - > SetStateString ( " player_armor " , va ( " %f " , armorv ) ) ;
lvrStatGui - > SetStateString ( " player_healthb " , va ( " %f " , healthb ) ) ;
lvrStatGui - > SetStateString ( " player_armorb " , va ( " %f " , armorb ) ) ;
if ( ammoamount [ HAND_LEFT ] < 0 )
{
// show infinite ammo
lvrStatGui - > SetStateString ( " player_ammo " , " " ) ;
}
else
{
// show remaining ammo
lvrStatGui - > SetStateString ( " player_totalammo " , va ( " %i " , ammoamount [ HAND_LEFT ] ) ) ;
lvrStatGui - > SetStateString ( " player_ammo " , clipsize [ HAND_LEFT ] ? va ( " %i " , inclip [ HAND_LEFT ] ) : " -- " ) ;
lvrStatGui - > SetStateString ( " player_clips " , clipsize [ HAND_LEFT ] ? va ( " %i " , ammoamount [ HAND_LEFT ] / clipsize [ HAND_LEFT ] ) : " -- " ) ;
lvrStatGui - > SetStateString ( " player_allammo " , va ( " %i/%i " , inclip [ HAND_LEFT ] , ammoamount [ HAND_LEFT ] ) ) ;
}
lvrStatGui - > SetStateBool ( " player_ammo_empty " , ( ammoEmpty [ HAND_LEFT ] ) ) ;
lvrStatGui - > SetStateBool ( " player_clip_empty " , ( clipEmpty [ HAND_LEFT ] ) ) ;
lvrStatGui - > SetStateBool ( " player_clip_low " , ( clipLow [ HAND_LEFT ] ) ) ;
// koz todo
// need to get the ammocount from the hand structures, not sure right now, in the interim just use the ammo amount.
//Let the GUI know the total amount of ammo regardless of the ammo required value
//rvrStatGui->SetStateString( "player_ammo_count", va( "%i", AmmoCount() ) );
lvrStatGui - > SetStateString ( " player_ammo_count " , va ( " %i " , ammoamount [ HAND_LEFT ] ) ) ;
// koz end
// koz todo also need to figure this out for dual guis
2020-11-29 14:49:20 +00:00
//Grabber Gui Info
lvrStatGui - > SetStateString ( " grabber_state " , va ( " %i " , grabberState ) ) ;
2020-11-15 18:52:37 +00:00
}
/*
= = = = = = = = = = = = = = = =
Koz
idWeapon : : UpdateWeaponClipPosition
= = = = = = = = = = = = = = = =
*/
void idWeapon : : UpdateWeaponClipPosition ( idVec3 & origin , idMat3 & axis )
{
/*PDAclipModel->SetPosition( origin, axis );
PDAclipModel - > Link ( gameLocal . clip ) ;
*/
}
2020-09-08 22:10:45 +00:00
/*
= = = = = = = = = = = = = = = =
idWeapon : : UpdateSkin
= = = = = = = = = = = = = = = =
*/
bool idWeapon : : UpdateSkin ( void ) {
const function_t * func ;
if ( ! isLinked ) {
return false ;
}
func = scriptObject . GetFunction ( " UpdateSkin " ) ;
if ( ! func ) {
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 ( ) ;
return true ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : SetModel
= = = = = = = = = = = = = = = =
*/
void idWeapon : : SetModel ( const char * modelname ) {
assert ( modelname ) ;
if ( modelDefHandle > = 0 ) {
gameRenderWorld - > RemoveDecals ( modelDefHandle ) ;
}
renderEntity . hModel = animator . SetModel ( modelname ) ;
if ( renderEntity . hModel ) {
renderEntity . customSkin = animator . ModelDef ( ) - > GetDefaultSkin ( ) ;
animator . GetJoints ( & renderEntity . numJoints , & renderEntity . joints ) ;
} else {
renderEntity . customSkin = NULL ;
renderEntity . callback = NULL ;
renderEntity . numJoints = 0 ;
renderEntity . joints = NULL ;
}
// 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
= = = = = = = = = = = = = = = =
*/
bool idWeapon : : GetGlobalJointTransform ( bool viewModel , const jointHandle_t jointHandle , idVec3 & offset , idMat3 & axis ) {
if ( viewModel ) {
// view model
if ( animator . GetJointTransform ( jointHandle , gameLocal . time , offset , axis ) ) {
offset = offset * viewWeaponAxis + viewWeaponOrigin ;
axis = axis * viewWeaponAxis ;
return true ;
}
} else {
// world model
if ( worldModel . GetEntity ( ) & & worldModel . GetEntity ( ) - > GetAnimator ( ) - > GetJointTransform ( jointHandle , gameLocal . time , offset , axis ) ) {
offset = worldModel . GetEntity ( ) - > GetPhysics ( ) - > GetOrigin ( ) + offset * worldModel . GetEntity ( ) - > GetPhysics ( ) - > GetAxis ( ) ;
axis = axis * worldModel . GetEntity ( ) - > GetPhysics ( ) - > GetAxis ( ) ;
return true ;
}
}
offset = viewWeaponOrigin ;
axis = viewWeaponAxis ;
return false ;
}
2020-11-15 18:52:37 +00:00
// Carl: dual wielding, check which hand, if any, the weapon is in
int idWeapon : : GetHand ( )
{
if ( ! owner )
return - 1 ;
for ( int h = 0 ; h < 2 ; h + + )
{
if ( owner - > hands [ h ] . weapon . GetEntity ( ) = = this )
return h ;
}
return - 1 ;
}
/*
= = = = = = = = = = = = = = = =
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 .
= = = = = = = = = = = = = = = =
*/
bool idWeapon : : GetMuzzlePositionWithHacks ( idVec3 & origin , idMat3 & axis )
{
static weapon_t currentWeap = WEAPON_NONE ;
idVec3 discardedOrigin ;
origin = playerViewOrigin ;
axis = playerViewAxis ;
currentWeap = IdentifyWeapon ( ) ;
switch ( currentWeap )
{
case WEAPON_NONE :
case WEAPON_FISTS :
case WEAPON_SOULCUBE :
case WEAPON_PDA :
origin = commonVr - > lastViewOrigin ; // Koz fixme set the origin and axis to the players view
axis = commonVr - > lastViewAxis ;
return false ;
break ;
case WEAPON_HANDGRENADE :
origin = viewWeaponOrigin ; // Koz fixme set the origin and axis to the weapon default
axis = viewWeaponAxis ;
return false ;
break ;
case WEAPON_CHAINSAW :
{
if ( barrelJointView = = INVALID_JOINT )
{
origin = viewWeaponOrigin ; // Koz fixme set the origin and axis to the weapon default
axis = viewWeaponAxis ;
return false ;
break ;
}
else
{
GetGlobalJointTransform ( true , barrelJointView , origin , axis ) ;
std : : swap ( axis [ 0 ] , axis [ 2 ] ) ; // barrel joint points right, rotate &
axis [ 0 ] = - axis [ 0 ] ; // make it point forward.
// the barrel joint is not actually aligned with the blade of the chainsaw.
// Move the origin to align with the tip of the blade.
// fixme -34 forward is a hack to compensate for an overly long
// melee range value in VR. Otherwise you can saw something 3 feet away
// from the tip of the blade.
// should probably change the weapon def instead of using this mess.
idVec3 move ( - 34.0f , 2.0f , - 6.0f ) ; // fwd,up,right
origin + = move * axis ;
}
return false ;
break ;
}
}
if ( barrelJointView ! = INVALID_JOINT )
{
GetGlobalJointTransform ( true , barrelJointView , origin , axis ) ;
}
else if ( guiLightJointView ! = INVALID_JOINT )
{
GetGlobalJointTransform ( true , guiLightJointView , origin , axis ) ;
}
else
{
return false ;
}
switch ( currentWeap )
{
case WEAPON_PISTOL :
{
// muzzle doesn't animate during firing, Bod does
const jointHandle_t bodJoint = animator . GetJointHandle ( " Bod " ) ;
GetGlobalJointTransform ( true , bodJoint , discardedOrigin , axis ) ;
break ;
}
case WEAPON_ROCKETLAUNCHER :
// joint doesn't point straight, so rotate it
std : : swap ( axis [ 0 ] , axis [ 2 ] ) ;
break ;
case WEAPON_SHOTGUN :
{
// joint doesn't point straight, so rotate it
//const jointHandle_t bodJoint = animator.GetJointHandle( "trigger" );
const jointHandle_t bodJoint = animator . GetJointHandle ( " body " ) ;
GetGlobalJointTransform ( true , bodJoint , discardedOrigin , axis ) ;
std : : swap ( axis [ 0 ] , axis [ 2 ] ) ;
axis [ 0 ] = - axis [ 0 ] ;
break ;
}
2020-11-18 14:48:17 +00:00
case WEAPON_SHOTGUN_DOUBLE :
{
// 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 ] ) ; // Koz fixme just swap like the rocketlauncher this should work now test and cleanup
//axis[0] = -axis[0];
//common->Printf( "GMPWH returning value for WEAPON_SHOTGUN_DOUBLE \n" );
break ;
}
case WEAPON_GRABBER :
{
idVec3 forward = axis [ 0 ] ;
forward . Normalize ( ) ;
const float scaleOffset = 4.0f ;
forward * = scaleOffset ;
origin + = forward ;
break ;
}
2020-11-15 18:52:37 +00:00
case WEAPON_PLASMAGUN :
{
// the barrel of the plasma rifle is angled down by default, bring it up a little so it shoots straight.
const idMat3 adj = idAngles ( 0.0f , 4.0f , 0.0f ) . ToMat3 ( ) ;
axis = adj * axis ;
break ;
}
}
return true ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : GetProjectileLaunchOriginAndAxis
= = = = = = = = = = = = = = = =
*/
void idWeapon : : GetProjectileLaunchOriginAndAxis ( idVec3 & origin , idMat3 & axis )
{
assert ( owner ! = NULL ) ;
if ( game - > isVR )
{
static weapon_t curWeap = WEAPON_NONE ;
// Koz debug common->Printf( "GPLOAA getting muzzle position w/ hacks\n" ); // Koz delete me
GetMuzzlePositionWithHacks ( origin , axis ) ;
curWeap = IdentifyWeapon ( ) ;
switch ( curWeap )
{
case WEAPON_BFG :
{
// BFG pitches up when fired before the projectile is launched.
// Hack to correct pitch so projectile doesn't shoot high.
static idMat3 bfgCorrection = idAngles ( 0.0 , - 15.0 , 0.0 ) . ToMat3 ( ) ;
axis = bfgCorrection * axis ;
}
break ;
case WEAPON_HANDGRENADE :
{
// if using motion controls, the muzzle axis should be the tracked direction of
// hand movement, not the barrel axis. (unless the controller is mounted on something like a topshot, then you have a grenade launcher.)
if ( commonVr - > VR_USE_MOTION_CONTROLS & & ! vr_mountedWeaponController . GetBool ( ) )
{
axis = owner - > hands [ GetHand ( ) ] . throwDirection . ToMat3 ( ) ;
break ;
}
}
default :
break ;
}
return ;
}
// calculate the muzzle position
if ( barrelJointView ! = INVALID_JOINT & & projectileDict . GetBool ( " launchFromBarrel " ) )
{
// there is an explicit joint for the muzzle
// GetGlobalJointTransform( true, barrelJointView, muzzleOrigin, muzzleAxis );
GetMuzzlePositionWithHacks ( origin , axis ) ;
}
else
{
// go straight out of the view
origin = playerViewOrigin ;
axis = playerViewAxis ;
}
axis = playerViewAxis ; // Fix for plasma rifle not firing correctly on initial shot of a burst fire
}
2020-09-08 22:10:45 +00:00
/*
= = = = = = = = = = = = = = = =
idWeapon : : SetPushVelocity
= = = = = = = = = = = = = = = =
*/
void idWeapon : : SetPushVelocity ( const idVec3 & pushVelocity ) {
this - > pushVelocity = pushVelocity ;
}
/***********************************************************************
State control / player interface
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
= = = = = = = = = = = = = = = =
idWeapon : : Think
= = = = = = = = = = = = = = = =
*/
void idWeapon : : Think ( void ) {
// do nothing because the present is called from the player through PresentWeapon
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : Raise
= = = = = = = = = = = = = = = =
*/
void idWeapon : : Raise ( void ) {
if ( isLinked ) {
WEAPON_RAISEWEAPON = true ;
}
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : PutAway
= = = = = = = = = = = = = = = =
*/
void idWeapon : : PutAway ( void ) {
hasBloodSplat = false ;
if ( isLinked ) {
WEAPON_LOWERWEAPON = true ;
}
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : Reload
NOTE : this is only for impulse - triggered reload , auto reload is scripted
= = = = = = = = = = = = = = = =
*/
void idWeapon : : Reload ( void ) {
if ( isLinked ) {
WEAPON_RELOAD = true ;
}
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : LowerWeapon
= = = = = = = = = = = = = = = =
*/
void idWeapon : : LowerWeapon ( void ) {
2020-11-15 18:52:37 +00:00
if ( game - > isVR & & commonVr - > handInGui ) return ; // Koz never lower weapon if hand is in gui
if ( ! owner - > GuiActive ( ) & & ! gameLocal . inCinematic ) return ;
if ( ! hide ) {
2020-09-08 22:10:45 +00:00
hideStart = 0.0f ;
hideEnd = hideDistance ;
if ( gameLocal . time - hideStartTime < hideTime ) {
hideStartTime = gameLocal . time - ( hideTime - ( gameLocal . time - hideStartTime ) ) ;
} else {
hideStartTime = gameLocal . time ;
}
hide = true ;
}
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : RaiseWeapon
= = = = = = = = = = = = = = = =
*/
void idWeapon : : RaiseWeapon ( void ) {
Show ( ) ;
if ( hide ) {
hideStart = hideDistance ;
hideEnd = 0.0f ;
if ( gameLocal . time - hideStartTime < hideTime ) {
hideStartTime = gameLocal . time - ( hideTime - ( gameLocal . time - hideStartTime ) ) ;
} else {
hideStartTime = gameLocal . time ;
}
hide = false ;
}
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : HideWeapon
= = = = = = = = = = = = = = = =
*/
void idWeapon : : HideWeapon ( void ) {
Hide ( ) ;
if ( worldModel . GetEntity ( ) ) {
worldModel . GetEntity ( ) - > Hide ( ) ;
}
muzzleFlashEnd = 0 ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : ShowWeapon
= = = = = = = = = = = = = = = =
*/
void idWeapon : : ShowWeapon ( void ) {
Show ( ) ;
if ( worldModel . GetEntity ( ) ) {
worldModel . GetEntity ( ) - > Show ( ) ;
}
if ( lightOn ) {
MuzzleFlashLight ( ) ;
}
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : HideWorldModel
= = = = = = = = = = = = = = = =
*/
void idWeapon : : HideWorldModel ( void ) {
if ( worldModel . GetEntity ( ) ) {
worldModel . GetEntity ( ) - > Hide ( ) ;
}
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : ShowWorldModel
= = = = = = = = = = = = = = = =
*/
void idWeapon : : ShowWorldModel ( void ) {
if ( worldModel . GetEntity ( ) ) {
worldModel . GetEntity ( ) - > Show ( ) ;
}
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : OwnerDied
= = = = = = = = = = = = = = = =
*/
void idWeapon : : OwnerDied ( void ) {
if ( isLinked ) {
SetState ( " OwnerDied " , 0 ) ;
thread - > Execute ( ) ;
2020-11-29 14:49:20 +00:00
// Update the grabber effects
if ( grabberState ! = - 1 )
{
grabber . Update ( owner , this , hide ) ;
}
2020-09-08 22:10:45 +00:00
}
Hide ( ) ;
if ( worldModel . GetEntity ( ) ) {
worldModel . GetEntity ( ) - > Hide ( ) ;
}
// 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
= = = = = = = = = = = = = = = =
*/
void idWeapon : : BeginAttack ( void ) {
if ( status ! = WP_OUTOFAMMO ) {
lastAttack = gameLocal . time ;
}
if ( ! isLinked ) {
return ;
}
if ( ! WEAPON_ATTACK ) {
2020-11-29 14:49:20 +00:00
if ( sndHum & & grabberState = = - 1 ) { // _D3XP :: don't stop grabber hum
2020-09-08 22:10:45 +00:00
StopSound ( SND_CHANNEL_BODY , false ) ;
}
}
WEAPON_ATTACK = true ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : EndAttack
= = = = = = = = = = = = = = = =
*/
void idWeapon : : EndAttack ( void ) {
if ( ! WEAPON_ATTACK . IsLinked ( ) ) {
return ;
}
if ( WEAPON_ATTACK ) {
WEAPON_ATTACK = false ;
2020-11-29 14:49:20 +00:00
if ( sndHum & & grabberState = = - 1 ) { // _D3XP :: don't stop grabber hum
2020-09-08 22:10:45 +00:00
StartSoundShader ( sndHum , SND_CHANNEL_BODY , 0 , false , NULL ) ;
}
}
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : isReady
= = = = = = = = = = = = = = = =
*/
bool idWeapon : : IsReady ( void ) const {
return ! hide & & ! IsHidden ( ) & & ( ( status = = WP_RELOAD ) | | ( status = = WP_READY ) | | ( status = = WP_OUTOFAMMO ) ) ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : IsReloading
= = = = = = = = = = = = = = = =
*/
bool idWeapon : : IsReloading ( void ) const {
return ( status = = WP_RELOAD ) ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : IsHolstered
= = = = = = = = = = = = = = = =
*/
bool idWeapon : : IsHolstered ( void ) const {
return ( status = = WP_HOLSTERED ) ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : ShowCrosshair
= = = = = = = = = = = = = = = =
*/
bool idWeapon : : ShowCrosshair ( void ) const {
return ! ( state = = idStr ( WP_RISING ) | | state = = idStr ( WP_LOWERING ) | | state = = idStr ( WP_HOLSTERED ) ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idWeapon : : CanDrop
= = = = = = = = = = = = = = = = = = = = =
*/
bool idWeapon : : CanDrop ( void ) const {
if ( ! weaponDef | | ! worldModel . GetEntity ( ) ) {
return false ;
}
const char * classname = weaponDef - > dict . GetString ( " def_dropItem " ) ;
if ( ! classname [ 0 ] ) {
return false ;
}
return true ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : WeaponStolen
= = = = = = = = = = = = = = = =
*/
void idWeapon : : WeaponStolen ( void ) {
assert ( ! gameLocal . isClient ) ;
if ( projectileEnt ) {
if ( isLinked ) {
SetState ( " WeaponStolen " , 0 ) ;
thread - > Execute ( ) ;
}
projectileEnt = NULL ;
}
// set to holstered so we can switch weapons right away
status = WP_HOLSTERED ;
HideWeapon ( ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idWeapon : : DropItem
= = = = = = = = = = = = = = = = = = = = =
*/
idEntity * idWeapon : : DropItem ( const idVec3 & velocity , int activateDelay , int removeDelay , bool died ) {
if ( ! weaponDef | | ! worldModel . GetEntity ( ) ) {
return NULL ;
}
if ( ! allowDrop ) {
return NULL ;
}
const char * classname = weaponDef - > dict . GetString ( " def_dropItem " ) ;
if ( ! classname [ 0 ] ) {
return NULL ;
}
StopSound ( SND_CHANNEL_BODY , true ) ;
StopSound ( SND_CHANNEL_BODY3 , true ) ;
return idMoveableItem : : DropItem ( classname , worldModel . GetEntity ( ) - > GetPhysics ( ) - > GetOrigin ( ) , worldModel . GetEntity ( ) - > GetPhysics ( ) - > GetAxis ( ) , velocity , activateDelay , removeDelay ) ;
}
/***********************************************************************
Script state management
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
= = = = = = = = = = = = = = = = = = = = =
idWeapon : : SetState
= = = = = = = = = = = = = = = = = = = = =
*/
void idWeapon : : SetState ( const char * statename , int blendFrames ) {
const function_t * func ;
if ( ! isLinked ) {
return ;
}
func = scriptObject . GetFunction ( statename ) ;
if ( ! func ) {
assert ( 0 ) ;
gameLocal . Error ( " Can't find function '%s' in object '%s' " , statename , scriptObject . GetTypeName ( ) ) ;
}
thread - > CallFunction ( this , func , true ) ;
state = statename ;
animBlendFrames = blendFrames ;
if ( g_debugWeapon . GetBool ( ) ) {
gameLocal . Printf ( " %d: weapon state : %s \n " , gameLocal . time , statename ) ;
}
idealState = " " ;
}
/***********************************************************************
Particles / Effects
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
= = = = = = = = = = = = = = = =
idWeapon : : UpdateNozzelFx
= = = = = = = = = = = = = = = =
*/
void idWeapon : : UpdateNozzleFx ( void ) {
if ( ! nozzleFx ) {
return ;
}
//
// shader parms
//
int la = gameLocal . time - lastAttack + 1 ;
float s = 1.0f ;
float l = 0.0f ;
if ( la < nozzleFxFade ) {
s = ( ( float ) la / nozzleFxFade ) ;
l = 1.0f - s ;
}
renderEntity . shaderParms [ 5 ] = s ;
renderEntity . shaderParms [ 6 ] = l ;
if ( ventLightJointView = = INVALID_JOINT ) {
return ;
}
//
// vent light
//
if ( nozzleGlowHandle = = - 1 ) {
memset ( & nozzleGlow , 0 , sizeof ( nozzleGlow ) ) ;
if ( owner ) {
nozzleGlow . allowLightInViewID = owner - > entityNumber + 1 ;
}
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 ) ;
nozzleGlowHandle = gameRenderWorld - > AddLightDef ( & nozzleGlow ) ;
}
GetGlobalJointTransform ( true , ventLightJointView , nozzleGlow . origin , nozzleGlow . axis ) ;
nozzleGlow . shaderParms [ SHADERPARM_RED ] = nozzleGlowColor . x * s ;
nozzleGlow . shaderParms [ SHADERPARM_GREEN ] = nozzleGlowColor . y * s ;
nozzleGlow . shaderParms [ SHADERPARM_BLUE ] = nozzleGlowColor . z * s ;
gameRenderWorld - > UpdateLightDef ( nozzleGlowHandle , & nozzleGlow ) ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : BloodSplat
= = = = = = = = = = = = = = = =
*/
bool idWeapon : : BloodSplat ( float size ) {
float s , c ;
idMat3 localAxis , axistemp ;
idVec3 localOrigin , normal ;
if ( hasBloodSplat ) {
return true ;
}
hasBloodSplat = true ;
if ( modelDefHandle < 0 ) {
return false ;
}
if ( ! GetGlobalJointTransform ( true , ejectJointView , localOrigin , localAxis ) ) {
return false ;
}
localOrigin [ 0 ] + = gameLocal . random . RandomFloat ( ) * - 10.0f ;
localOrigin [ 1 ] + = gameLocal . random . RandomFloat ( ) * 1.0f ;
localOrigin [ 2 ] + = gameLocal . random . RandomFloat ( ) * - 2.0f ;
normal = idVec3 ( gameLocal . random . CRandomFloat ( ) , - gameLocal . random . RandomFloat ( ) , - 1 ) ;
normal . Normalize ( ) ;
idMath : : SinCos16 ( gameLocal . random . RandomFloat ( ) * idMath : : TWO_PI , s , c ) ;
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 ;
localAxis [ 0 ] * = 1.0f / size ;
localAxis [ 1 ] * = 1.0f / size ;
idPlane localPlane [ 2 ] ;
localPlane [ 0 ] = localAxis [ 0 ] ;
localPlane [ 0 ] [ 3 ] = - ( localOrigin * localAxis [ 0 ] ) + 0.5f ;
localPlane [ 1 ] = localAxis [ 1 ] ;
localPlane [ 1 ] [ 3 ] = - ( localOrigin * localAxis [ 1 ] ) + 0.5f ;
const idMaterial * mtr = declManager - > FindMaterial ( " textures/decals/duffysplatgun " ) ;
gameRenderWorld - > ProjectOverlay ( modelDefHandle , localPlane , mtr ) ;
return true ;
}
/***********************************************************************
Visual presentation
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
= = = = = = = = = = = = = = = =
idWeapon : : MuzzleRise
The machinegun and chaingun will incrementally back up as they are being fired
= = = = = = = = = = = = = = = =
*/
void idWeapon : : MuzzleRise ( idVec3 & origin , idMat3 & axis ) {
int time ;
float amount ;
idAngles ang ;
idVec3 offset ;
time = kick_endtime - gameLocal . time ;
if ( time < = 0 ) {
return ;
}
if ( muzzle_kick_maxtime < = 0 ) {
return ;
}
if ( time > muzzle_kick_maxtime ) {
time = muzzle_kick_maxtime ;
}
amount = ( float ) time / ( float ) muzzle_kick_maxtime ;
ang = muzzle_kick_angles * amount ;
offset = muzzle_kick_offset * amount ;
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 .
= = = = = = = = = = = = = = = =
*/
idThread * idWeapon : : ConstructScriptObject ( void ) {
const function_t * constructor ;
thread - > EndThread ( ) ;
// call script object's constructor
constructor = scriptObject . GetConstructor ( ) ;
if ( ! constructor ) {
gameLocal . Error ( " Missing constructor on '%s' for weapon " , scriptObject . GetTypeName ( ) ) ;
}
// init the script object's data
scriptObject . ClearObject ( ) ;
thread - > CallFunction ( this , constructor , true ) ;
thread - > Execute ( ) ;
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 .
= = = = = = = = = = = = = = = =
*/
void idWeapon : : DeconstructScriptObject ( void ) {
const function_t * destructor ;
if ( ! thread ) {
return ;
}
// don't bother calling the script object's destructor on map shutdown
if ( gameLocal . GameState ( ) = = GAMESTATE_SHUTDOWN ) {
return ;
}
thread - > EndThread ( ) ;
// call script object's destructor
destructor = scriptObject . GetDestructor ( ) ;
if ( destructor ) {
// start a thread that will run immediately and end
thread - > CallFunction ( this , destructor , true ) ;
thread - > Execute ( ) ;
thread - > EndThread ( ) ;
}
// clear out the object's memory
scriptObject . ClearObject ( ) ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : UpdateScript
= = = = = = = = = = = = = = = =
*/
void idWeapon : : UpdateScript ( void ) {
int count ;
if ( ! isLinked ) {
return ;
}
// only update the script on new frames
if ( ! gameLocal . isNewFrame ) {
return ;
}
if ( idealState . Length ( ) ) {
SetState ( idealState , animBlendFrames ) ;
}
// update script state, which may call Event_LaunchProjectiles, among other things
count = 10 ;
while ( ( thread - > Execute ( ) | | idealState . Length ( ) ) & & count - - ) {
// happens for weapons with no clip (like grenades)
if ( idealState . Length ( ) ) {
SetState ( idealState , animBlendFrames ) ;
}
}
WEAPON_RELOAD = false ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : AlertMonsters
= = = = = = = = = = = = = = = =
*/
void idWeapon : : AlertMonsters ( void ) {
trace_t tr ;
idEntity * ent ;
idVec3 end = muzzleFlash . origin + muzzleFlash . axis * muzzleFlash . target ;
gameLocal . clip . TracePoint ( tr , muzzleFlash . origin , end , CONTENTS_OPAQUE | MASK_SHOT_RENDERMODEL | CONTENTS_FLASHLIGHT_TRIGGER , owner ) ;
if ( g_debugWeapon . GetBool ( ) ) {
gameRenderWorld - > DebugLine ( colorYellow , muzzleFlash . origin , end , 0 ) ;
gameRenderWorld - > DebugArrow ( colorGreen , muzzleFlash . origin , tr . endpos , 2 , 0 ) ;
}
if ( tr . fraction < 1.0f ) {
ent = gameLocal . GetTraceEntity ( tr ) ;
if ( ent - > IsType ( idAI : : Type ) ) {
static_cast < idAI * > ( ent ) - > TouchedByFlashlight ( owner ) ;
} else if ( ent - > IsType ( idTrigger : : Type ) ) {
ent - > Signal ( SIG_TOUCH ) ;
ent - > ProcessEvent ( & EV_Touch , owner , & tr ) ;
}
}
// 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 ) ;
if ( g_debugWeapon . GetBool ( ) ) {
gameRenderWorld - > DebugLine ( colorYellow , muzzleFlash . origin , end , 0 ) ;
gameRenderWorld - > DebugArrow ( colorGreen , muzzleFlash . origin , tr . endpos , 2 , 0 ) ;
}
if ( tr . fraction < 1.0f ) {
ent = gameLocal . GetTraceEntity ( tr ) ;
if ( ent - > IsType ( idAI : : Type ) ) {
static_cast < idAI * > ( ent ) - > TouchedByFlashlight ( owner ) ;
} else if ( ent - > IsType ( idTrigger : : Type ) ) {
ent - > Signal ( SIG_TOUCH ) ;
ent - > ProcessEvent ( & EV_Touch , owner , & tr ) ;
}
}
}
/*
= = = = = = = = = = = = = = = =
2020-11-15 18:52:37 +00:00
idWeapon : : CalculateHideRise
2020-09-08 22:10:45 +00:00
= = = = = = = = = = = = = = = =
*/
2020-11-15 18:52:37 +00:00
void idWeapon : : CalculateHideRise ( idVec3 & origin , idMat3 & axis )
{
// 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
if ( gameLocal . time - hideStartTime < hideTime )
2020-09-20 11:10:53 +00:00
{
2020-11-15 18:52:37 +00:00
float frac = ( float ) ( gameLocal . time - hideStartTime ) / ( float ) hideTime ;
if ( hideStart < hideEnd )
{
2020-09-08 22:10:45 +00:00
frac = 1.0f - frac ;
frac = 1.0f - frac * frac ;
2020-11-15 18:52:37 +00:00
}
else
{
2020-09-08 22:10:45 +00:00
frac = frac * frac ;
}
2020-11-15 18:52:37 +00:00
hideOffset = hideStart + ( hideEnd - hideStart ) * frac ;
}
else
{
2020-09-08 22:10:45 +00:00
hideOffset = hideEnd ;
2020-11-15 18:52:37 +00:00
if ( hide & & disabled )
{
2020-09-08 22:10:45 +00:00
Hide ( ) ;
}
}
2020-11-15 18:52:37 +00:00
//viewWeaponOrigin += hideOffset * viewWeaponAxis[2]; // Koz adjust the gui pointer by this offset later
//viewWeaponOrigin.z += hideOffset;
origin . z + = hideOffset ;
2020-09-08 22:10:45 +00:00
// kick up based on repeat firing
2020-11-15 18:52:37 +00:00
MuzzleRise ( origin , axis ) ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : PresentWeapon
= = = = = = = = = = = = = = = =
*/
void idWeapon : : PresentWeapon ( bool showViewModel , int hand ) {
2020-09-08 22:10:45 +00:00
2020-11-15 18:52:37 +00:00
worldModel . GetEntity ( ) - > GetRenderEntity ( ) - > allowSurfaceInViewID = - 1 ;
playerViewOrigin = owner - > firstPersonViewOrigin ;
playerViewAxis = owner - > firstPersonViewAxis ;
weapon_t currentWeapon = WEAPON_NONE ;
currentWeapon = IdentifyWeapon ( ) ;
if ( isPlayerFlashlight )
2020-09-20 11:10:53 +00:00
{
2020-11-15 18:52:37 +00:00
viewWeaponOrigin = playerViewOrigin ;
viewWeaponAxis = playerViewAxis ;
owner - > CalculateViewFlashlightPos ( viewWeaponOrigin , viewWeaponAxis , flashlightOffsets [ int ( currentWeapon ) ] ) ;
2020-09-20 11:10:53 +00:00
}
2020-11-15 18:52:37 +00:00
else if ( isPlayerLeftHand ) // Koz left hand
{
2020-09-20 11:10:53 +00:00
2020-11-15 18:52:37 +00:00
}
else
{
// calculate weapon position based on player movement bobbing
owner - > CalculateViewWeaponPos ( hand , viewWeaponOrigin , viewWeaponAxis ) ;
// Koz hide weapon and muzzlerise was here, now called as weapon::CalculateHideRise in player->CalculateViewWeaponPosition to allow hand animations
}
2020-09-08 22:10:45 +00:00
2020-11-15 18:52:37 +00:00
// set the physics position and orientation
GetPhysics ( ) - > SetOrigin ( viewWeaponOrigin ) ;
GetPhysics ( ) - > SetAxis ( viewWeaponAxis ) ;
2020-09-08 22:10:45 +00:00
2020-11-15 18:52:37 +00:00
UpdateVisuals ( ) ;
2020-09-08 22:10:45 +00:00
2020-11-15 18:52:37 +00:00
// update the weapon script
UpdateScript ( ) ;
2020-09-08 22:10:45 +00:00
2020-11-15 18:52:37 +00:00
UpdateGUI ( ) ;
2020-09-08 22:10:45 +00:00
2020-11-15 18:52:37 +00:00
// update animation
UpdateAnimation ( ) ;
2020-09-08 22:10:45 +00:00
2020-11-15 18:52:37 +00:00
// in VR don't suppress drawing the player's body
// also show the viewmodel
if ( ( hide & & disabled ) ) // hide the weapon if in a cinematic
{
renderEntity . allowSurfaceInViewID = - 1 ;
showViewModel = false ;
} //show the viewmodel in all views - flashlight visibilty set in calcViewFlashPosition
else if ( ! isPlayerFlashlight & & ! commonVr - > handInGui ) renderEntity . allowSurfaceInViewID = 0 ; // Koz fixme
owner - > GetRenderEntity ( ) - > suppressSurfaceInViewID = 0 ;
2020-09-08 22:10:45 +00:00
2020-11-15 18:52:37 +00:00
// crunch the depth range so it never pokes into walls this breaks the machine gun gui
renderEntity . weaponDepthHack = g_useWeaponDepthHack . GetBool ( ) ;
2020-09-08 22:10:45 +00:00
2020-11-15 18:52:37 +00:00
// present the model
if ( showViewModel )
{
Present ( ) ;
}
else
{
FreeModelDef ( ) ;
}
2020-09-08 22:10:45 +00:00
2020-11-15 18:52:37 +00:00
if ( worldModel . GetEntity ( ) & & worldModel . GetEntity ( ) - > GetRenderEntity ( ) )
{
// deal with the third-person visible world model
// don't show shadows of the world model in first person
if ( g_showPlayerShadow . GetBool ( ) | | pm_thirdPerson . GetBool ( ) | | game - > isVR ) // Koz fixme only in vr
{
worldModel . GetEntity ( ) - > GetRenderEntity ( ) - > suppressShadowInViewID = 0 ;
}
else
{
worldModel . GetEntity ( ) - > GetRenderEntity ( ) - > suppressShadowInViewID = owner - > entityNumber + 1 ;
worldModel . GetEntity ( ) - > GetRenderEntity ( ) - > suppressShadowInLightID = LIGHTID_VIEW_MUZZLE_FLASH + owner - > entityNumber ;
}
}
2020-09-08 22:10:45 +00:00
2020-11-15 18:52:37 +00:00
if ( nozzleFx )
{
UpdateNozzleFx ( ) ;
}
2020-09-08 22:10:45 +00:00
2020-11-15 18:52:37 +00:00
// muzzle smoke
if ( showViewModel & & ! disabled & & weaponSmoke & & ( weaponSmokeStartTime ! = 0 ) )
{
// use the barrel joint if available
if ( smokeJointView ! = INVALID_JOINT )
{
GetGlobalJointTransform ( true , smokeJointView , muzzleOrigin , muzzleAxis ) ;
}
else if ( barrelJointView ! = INVALID_JOINT )
{
GetGlobalJointTransform ( true , barrelJointView , muzzleOrigin , muzzleAxis ) ;
}
else
{
// default to going straight out the view
muzzleOrigin = playerViewOrigin ;
muzzleAxis = playerViewAxis ;
}
// spit out a particle
if ( ! gameLocal . smokeParticles - > EmitSmoke ( weaponSmoke , weaponSmokeStartTime , gameLocal . random . RandomFloat ( ) , muzzleOrigin , muzzleAxis ) )
{
weaponSmokeStartTime = ( continuousSmoke ) ? gameLocal . time : 0 ;
}
}
2020-09-08 22:10:45 +00:00
2020-11-15 18:52:37 +00:00
if ( showViewModel & & strikeSmoke & & strikeSmokeStartTime ! = 0 )
{
// spit out a particle
if ( ! gameLocal . smokeParticles - > EmitSmoke ( strikeSmoke , strikeSmokeStartTime , gameLocal . random . RandomFloat ( ) , strikePos , strikeAxis ) )
{
strikeSmokeStartTime = 0 ;
}
}
2020-09-08 22:10:45 +00:00
2020-11-15 18:52:37 +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 )
{
GetGlobalJointTransform ( true , part - > joint , muzzleOrigin , muzzleAxis ) ;
}
else
{
// default to going straight out the view
muzzleOrigin = playerViewOrigin ;
muzzleAxis = playerViewAxis ;
}
if ( ! gameLocal . smokeParticles - > EmitSmoke ( part - > particle , part - > startTime , gameLocal . random . RandomFloat ( ) , muzzleOrigin , muzzleAxis ) )
{
part - > active = false ; // all done
part - > startTime = 0 ;
}
}
else
{
if ( part - > emitter ! = NULL )
{
//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 ) ;
if ( part - > emitter - > GetModelDefHandle ( ) ! = - 1 )
{
gameRenderWorld - > UpdateEntityDef ( part - > emitter - > GetModelDefHandle ( ) , rendEnt ) ;
}
}
}
}
}
for ( int i = 0 ; i < weaponLights . Num ( ) ; i + + )
{
WeaponLight_t * light = weaponLights . GetIndex ( i ) ;
if ( light - > active )
{
GetGlobalJointTransform ( true , light - > joint , light - > light . origin , light - > light . axis ) ;
if ( ( light - > lightHandle ! = - 1 ) )
{
gameRenderWorld - > UpdateLightDef ( light - > lightHandle , & light - > light ) ;
}
else
{
light - > lightHandle = gameRenderWorld - > AddLightDef ( & light - > light ) ;
}
}
}
}
2020-09-08 22:10:45 +00:00
2020-11-29 14:49:20 +00:00
// Update the grabber effects
if ( grabberState ! = - 1 )
{
grabberState = grabber . Update ( owner , this , hide ) ;
}
2020-11-15 18:52:37 +00:00
// remove the muzzle flash light when it's done
if ( ( ! lightOn & & ( gameLocal . time > = muzzleFlashEnd ) ) | | IsHidden ( ) )
{
if ( muzzleFlashHandle ! = - 1 )
{
gameRenderWorld - > FreeLightDef ( muzzleFlashHandle ) ;
muzzleFlashHandle = - 1 ;
}
if ( worldMuzzleFlashHandle ! = - 1 )
{
gameRenderWorld - > FreeLightDef ( worldMuzzleFlashHandle ) ;
worldMuzzleFlashHandle = - 1 ;
}
}
2020-09-08 22:10:45 +00:00
2020-11-15 18:52:37 +00:00
// update the muzzle flash light, so it moves with the gun
if ( muzzleFlashHandle ! = - 1 )
{
UpdateFlashPosition ( ) ;
gameRenderWorld - > UpdateLightDef ( muzzleFlashHandle , & muzzleFlash ) ;
gameRenderWorld - > UpdateLightDef ( worldMuzzleFlashHandle , & worldMuzzleFlash ) ;
// wake up monsters with the flashlight
if ( lightOn & & ! owner - > fl . notarget )
{
AlertMonsters ( ) ;
}
}
2020-09-08 22:10:45 +00:00
2020-11-15 18:52:37 +00:00
// update the gui light
if ( guiLight . lightRadius [ 0 ] & & guiLightJointView ! = INVALID_JOINT )
{
GetGlobalJointTransform ( true , guiLightJointView , guiLight . origin , guiLight . axis ) ;
if ( ( guiLightHandle ! = - 1 ) )
{
gameRenderWorld - > UpdateLightDef ( guiLightHandle , & guiLight ) ;
}
else
{
guiLightHandle = gameRenderWorld - > AddLightDef ( & guiLight ) ;
}
}
if ( status ! = WP_READY & & sndHum )
{
StopSound ( SND_CHANNEL_BODY , false ) ;
}
2020-09-08 22:10:45 +00:00
2020-11-15 18:52:37 +00:00
UpdateSound ( ) ;
// 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 " ) ;
if ( vr_rumbleChainsaw . GetBool ( ) | | ! commonVr - > VR_USE_MOTION_CONTROLS )
owner - > hands [ hand ] . SetControllerShake ( highMagnitude , highDuration , lowMagnitude , lowDuration ) ;
2020-09-08 22:10:45 +00:00
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : EnterCinematic
= = = = = = = = = = = = = = = =
*/
void idWeapon : : EnterCinematic ( void ) {
StopSound ( SND_CHANNEL_ANY , false ) ;
if ( isLinked ) {
SetState ( " EnterCinematic " , 0 ) ;
thread - > Execute ( ) ;
WEAPON_ATTACK = false ;
WEAPON_RELOAD = false ;
WEAPON_NETRELOAD = false ;
WEAPON_NETENDRELOAD = false ;
if ( WEAPON_NETFIRING . IsLinked ( ) )
WEAPON_NETFIRING = false ;
WEAPON_RAISEWEAPON = false ;
WEAPON_LOWERWEAPON = false ;
}
disabled = true ;
LowerWeapon ( ) ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : ExitCinematic
= = = = = = = = = = = = = = = =
*/
void idWeapon : : ExitCinematic ( void ) {
disabled = false ;
if ( isLinked ) {
SetState ( " ExitCinematic " , 0 ) ;
thread - > Execute ( ) ;
}
RaiseWeapon ( ) ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : NetCatchup
= = = = = = = = = = = = = = = =
*/
void idWeapon : : NetCatchup ( void ) {
if ( isLinked ) {
SetState ( " NetCatchup " , 0 ) ;
thread - > Execute ( ) ;
}
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : GetZoomFov
= = = = = = = = = = = = = = = =
*/
int idWeapon : : GetZoomFov ( void ) {
return zoomFov ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : GetWeaponAngleOffsets
= = = = = = = = = = = = = = = =
*/
void idWeapon : : GetWeaponAngleOffsets ( int * average , float * scale , float * max ) {
* average = weaponAngleOffsetAverages ;
* scale = weaponAngleOffsetScale ;
* max = weaponAngleOffsetMax ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : GetWeaponTimeOffsets
= = = = = = = = = = = = = = = =
*/
void idWeapon : : GetWeaponTimeOffsets ( float * time , float * scale ) {
* time = weaponOffsetTime ;
* scale = weaponOffsetScale ;
}
/***********************************************************************
Ammo
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
= = = = = = = = = = = = = = = =
idWeapon : : GetAmmoNumForName
= = = = = = = = = = = = = = = =
*/
ammo_t idWeapon : : GetAmmoNumForName ( const char * ammoname ) {
int num ;
const idDict * ammoDict ;
assert ( ammoname ) ;
ammoDict = gameLocal . FindEntityDefDict ( " ammo_types " , false ) ;
if ( ! ammoDict ) {
gameLocal . Error ( " Could not find entity definition for 'ammo_types' \n " ) ;
}
if ( ! ammoname [ 0 ] ) {
return 0 ;
}
if ( ! ammoDict - > GetInt ( ammoname , " -1 " , num ) ) {
gameLocal . Error ( " Unknown ammo type '%s' " , ammoname ) ;
}
if ( ( num < 0 ) | | ( num > = AMMO_NUMTYPES ) ) {
gameLocal . Error ( " Ammo type '%s' value out of range. Maximum ammo types is %d. \n " , ammoname , AMMO_NUMTYPES ) ;
}
return ( ammo_t ) num ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : GetAmmoNameForNum
= = = = = = = = = = = = = = = =
*/
const char * idWeapon : : GetAmmoNameForNum ( ammo_t ammonum ) {
int i ;
int num ;
const idDict * ammoDict ;
const idKeyValue * kv ;
char text [ 32 ] ;
ammoDict = gameLocal . FindEntityDefDict ( " ammo_types " , false ) ;
if ( ! ammoDict ) {
gameLocal . Error ( " Could not find entity definition for 'ammo_types' \n " ) ;
}
sprintf ( text , " %d " , ammonum ) ;
num = ammoDict - > GetNumKeyVals ( ) ;
for ( i = 0 ; i < num ; i + + ) {
kv = ammoDict - > GetKeyVal ( i ) ;
if ( kv - > GetValue ( ) = = text ) {
return kv - > GetKey ( ) ;
}
}
return NULL ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : GetAmmoPickupNameForNum
= = = = = = = = = = = = = = = =
*/
const char * idWeapon : : GetAmmoPickupNameForNum ( ammo_t ammonum ) {
int i ;
int num ;
const idDict * ammoDict ;
const idKeyValue * kv ;
ammoDict = gameLocal . FindEntityDefDict ( " ammo_names " , false ) ;
if ( ! ammoDict ) {
gameLocal . Error ( " Could not find entity definition for 'ammo_names' \n " ) ;
}
const char * name = GetAmmoNameForNum ( ammonum ) ;
if ( name & & * name ) {
num = ammoDict - > GetNumKeyVals ( ) ;
for ( i = 0 ; i < num ; i + + ) {
kv = ammoDict - > GetKeyVal ( i ) ;
if ( idStr : : Icmp ( kv - > GetKey ( ) , name ) = = 0 ) {
return kv - > GetValue ( ) ;
}
}
}
return " " ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : AmmoAvailable
= = = = = = = = = = = = = = = =
*/
int idWeapon : : AmmoAvailable ( void ) const {
if ( owner ) {
return owner - > inventory . HasAmmo ( ammoType , ammoRequired ) ;
} else {
2020-11-15 18:52:37 +00:00
if ( g_infiniteAmmo . GetBool ( ) )
{
return 10 ; // arbitrary number, just so whatever's calling thinks there's sufficient ammo...
}
else
{
return 0 ;
}
}
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : AmmoCount
Returns the total number of rounds regardless of the required ammo
= = = = = = = = = = = = = = = =
*/
int idWeapon : : AmmoCount ( ) const
{
if ( owner )
{
return owner - > inventory . HasAmmo ( ammoType , 1 ) ;
}
else
{
2020-09-08 22:10:45 +00:00
return 0 ;
}
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : AmmoInClip
= = = = = = = = = = = = = = = =
*/
int idWeapon : : AmmoInClip ( void ) const {
return ammoClip ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : ResetAmmoClip
= = = = = = = = = = = = = = = =
*/
void idWeapon : : ResetAmmoClip ( void ) {
ammoClip = - 1 ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : GetAmmoType
= = = = = = = = = = = = = = = =
*/
ammo_t idWeapon : : GetAmmoType ( void ) const {
return ammoType ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : ClipSize
= = = = = = = = = = = = = = = =
*/
int idWeapon : : ClipSize ( void ) const {
return clipSize ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : LowAmmo
= = = = = = = = = = = = = = = =
*/
int idWeapon : : LowAmmo ( ) const {
return lowAmmo ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : AmmoRequired
= = = = = = = = = = = = = = = =
*/
int idWeapon : : AmmoRequired ( void ) const {
return ammoRequired ;
}
2020-11-29 14:49:20 +00:00
/*
= = = = = = = = = = = = = = = =
idWeapon : : GetGrabberState
Returns the current grabberState
= = = = = = = = = = = = = = = =
*/
int idWeapon : : GetGrabberState ( ) const
{
return grabberState ;
}
2020-09-08 22:10:45 +00:00
/*
= = = = = = = = = = = = = = = =
idWeapon : : WriteToSnapshot
= = = = = = = = = = = = = = = =
*/
void idWeapon : : WriteToSnapshot ( idBitMsgDelta & msg ) const {
msg . WriteBits ( ammoClip , ASYNC_PLAYER_INV_CLIP_BITS ) ;
msg . WriteBits ( worldModel . GetSpawnId ( ) , 32 ) ;
msg . WriteBits ( lightOn , 1 ) ;
msg . WriteBits ( isFiring ? 1 : 0 , 1 ) ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : ReadFromSnapshot
= = = = = = = = = = = = = = = =
*/
void idWeapon : : ReadFromSnapshot ( const idBitMsgDelta & msg ) {
ammoClip = msg . ReadBits ( ASYNC_PLAYER_INV_CLIP_BITS ) ;
worldModel . SetSpawnId ( msg . ReadBits ( 32 ) ) ;
bool snapLight = msg . ReadBits ( 1 ) ! = 0 ;
isFiring = msg . ReadBits ( 1 ) ! = 0 ;
// WEAPON_NETFIRING is only turned on for other clients we're predicting. not for local client
if ( owner & & gameLocal . localClientNum ! = owner - > entityNumber & & WEAPON_NETFIRING . IsLinked ( ) ) {
// immediately go to the firing state so we don't skip fire animations
if ( ! WEAPON_NETFIRING & & isFiring ) {
idealState = " Fire " ;
}
// immediately switch back to idle
if ( WEAPON_NETFIRING & & ! isFiring ) {
idealState = " Idle " ;
}
WEAPON_NETFIRING = isFiring ;
}
if ( snapLight ! = lightOn ) {
Reload ( ) ;
}
}
2020-11-15 18:52:37 +00:00
/*
= = = = = = = = = = = = = = = =
idWeapon : : RemoveMuzzleFlashlight
= = = = = = = = = = = = = = = =
*/
void idWeapon : : RemoveMuzzleFlashlight ( )
{
if ( muzzleFlashHandle ! = - 1 )
{
gameRenderWorld - > FreeLightDef ( muzzleFlashHandle ) ;
muzzleFlashHandle = - 1 ;
}
if ( worldMuzzleFlashHandle ! = - 1 )
{
gameRenderWorld - > FreeLightDef ( worldMuzzleFlashHandle ) ;
worldMuzzleFlashHandle = - 1 ;
}
}
2020-09-08 22:10:45 +00:00
/*
= = = = = = = = = = = = = = = =
idWeapon : : ClientReceiveEvent
= = = = = = = = = = = = = = = =
*/
bool idWeapon : : ClientReceiveEvent ( int event , int time , const idBitMsg & msg ) {
switch ( event ) {
case EVENT_RELOAD : {
if ( gameLocal . time - time < 1000 ) {
if ( WEAPON_NETRELOAD . IsLinked ( ) ) {
WEAPON_NETRELOAD = true ;
WEAPON_NETENDRELOAD = false ;
}
}
return true ;
}
case EVENT_ENDRELOAD : {
if ( WEAPON_NETENDRELOAD . IsLinked ( ) ) {
WEAPON_NETENDRELOAD = true ;
}
return true ;
}
case EVENT_CHANGESKIN : {
int index = gameLocal . ClientRemapDecl ( DECL_SKIN , msg . ReadInt ( ) ) ;
renderEntity . customSkin = ( index ! = - 1 ) ? static_cast < const idDeclSkin * > ( declManager - > DeclByIndex ( DECL_SKIN , index ) ) : NULL ;
UpdateVisuals ( ) ;
if ( worldModel . GetEntity ( ) ) {
worldModel . GetEntity ( ) - > SetSkin ( renderEntity . customSkin ) ;
}
return true ;
}
default :
break ;
}
return idEntity : : ClientReceiveEvent ( event , time , msg ) ;
}
/***********************************************************************
Script events
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
= = = = = = = = = = = = = = =
idWeapon : : Event_Clear
= = = = = = = = = = = = = = =
*/
void idWeapon : : Event_Clear ( void ) {
Clear ( ) ;
}
/*
= = = = = = = = = = = = = = =
idWeapon : : Event_GetOwner
= = = = = = = = = = = = = = =
*/
void idWeapon : : Event_GetOwner ( void ) {
idThread : : ReturnEntity ( owner ) ;
}
/*
= = = = = = = = = = = = = = =
idWeapon : : Event_WeaponState
= = = = = = = = = = = = = = =
*/
void idWeapon : : Event_WeaponState ( const char * statename , int blendFrames ) {
const function_t * func ;
func = scriptObject . GetFunction ( statename ) ;
if ( ! func ) {
assert ( 0 ) ;
gameLocal . Error ( " Can't find function '%s' in object '%s' " , statename , scriptObject . GetTypeName ( ) ) ;
}
idealState = statename ;
if ( ! idealState . Icmp ( " Fire " ) ) {
isFiring = true ;
} else {
isFiring = false ;
}
animBlendFrames = blendFrames ;
thread - > DoneProcessing ( ) ;
}
2020-11-15 18:52:37 +00:00
/*
= = = = = = = = = = = = = = = =
idWeapon : : FlashlightOn
= = = = = = = = = = = = = = = =
*/
void idWeapon : : FlashlightOn ( )
{
const function_t * func ;
if ( ! isLinked )
{
return ;
}
func = scriptObject . GetFunction ( " TurnOn " ) ;
if ( ! func )
{
common - > Warning ( " Can't find function 'TurnOn' in object '%s' " , scriptObject . GetTypeName ( ) ) ;
return ;
}
// use the frameCommandThread since it's safe to use outside of framecommands
gameLocal . frameCommandThread - > CallFunction ( this , func , true ) ;
gameLocal . frameCommandThread - > Execute ( ) ;
return ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : FlashlightOff
= = = = = = = = = = = = = = = =
*/
void idWeapon : : FlashlightOff ( )
{
const function_t * func ;
if ( ! isLinked )
{
return ;
}
func = scriptObject . GetFunction ( " TurnOff " ) ;
if ( ! func )
{
common - > Warning ( " Can't find function 'TurnOff' in object '%s' " , scriptObject . GetTypeName ( ) ) ;
return ;
}
// use the frameCommandThread since it's safe to use outside of framecommands
gameLocal . frameCommandThread - > CallFunction ( this , func , true ) ;
gameLocal . frameCommandThread - > Execute ( ) ;
return ;
}
2020-09-08 22:10:45 +00:00
/*
= = = = = = = = = = = = = = =
idWeapon : : Event_WeaponReady
= = = = = = = = = = = = = = =
*/
void idWeapon : : Event_WeaponReady ( void ) {
status = WP_READY ;
if ( isLinked ) {
WEAPON_RAISEWEAPON = false ;
}
if ( sndHum ) {
StartSoundShader ( sndHum , SND_CHANNEL_BODY , 0 , false , NULL ) ;
}
}
/*
= = = = = = = = = = = = = = =
idWeapon : : Event_WeaponOutOfAmmo
= = = = = = = = = = = = = = =
*/
void idWeapon : : Event_WeaponOutOfAmmo ( void ) {
status = WP_OUTOFAMMO ;
if ( isLinked ) {
WEAPON_RAISEWEAPON = false ;
}
}
/*
= = = = = = = = = = = = = = =
idWeapon : : Event_WeaponReloading
= = = = = = = = = = = = = = =
*/
void idWeapon : : Event_WeaponReloading ( void ) {
status = WP_RELOAD ;
}
/*
= = = = = = = = = = = = = = =
idWeapon : : Event_WeaponHolstered
= = = = = = = = = = = = = = =
*/
void idWeapon : : Event_WeaponHolstered ( void ) {
status = WP_HOLSTERED ;
if ( isLinked ) {
WEAPON_LOWERWEAPON = false ;
}
}
/*
= = = = = = = = = = = = = = =
idWeapon : : Event_WeaponRising
= = = = = = = = = = = = = = =
*/
void idWeapon : : Event_WeaponRising ( void ) {
status = WP_RISING ;
if ( isLinked ) {
WEAPON_LOWERWEAPON = false ;
}
owner - > WeaponRisingCallback ( ) ;
}
/*
= = = = = = = = = = = = = = =
idWeapon : : Event_WeaponLowering
= = = = = = = = = = = = = = =
*/
void idWeapon : : Event_WeaponLowering ( void ) {
status = WP_LOWERING ;
if ( isLinked ) {
WEAPON_RAISEWEAPON = false ;
}
owner - > WeaponLoweringCallback ( ) ;
}
/*
= = = = = = = = = = = = = = =
idWeapon : : Event_UseAmmo
= = = = = = = = = = = = = = =
*/
void idWeapon : : Event_UseAmmo ( int amount ) {
if ( gameLocal . isClient ) {
return ;
}
owner - > inventory . UseAmmo ( ammoType , ( powerAmmo ) ? amount : ( amount * ammoRequired ) ) ;
if ( clipSize & & ammoRequired ) {
ammoClip - = powerAmmo ? amount : ( amount * ammoRequired ) ;
if ( ammoClip < 0 ) {
ammoClip = 0 ;
}
}
}
/*
= = = = = = = = = = = = = = =
idWeapon : : Event_AddToClip
= = = = = = = = = = = = = = =
*/
void idWeapon : : Event_AddToClip ( int amount ) {
int ammoAvail ;
if ( gameLocal . isClient ) {
return ;
}
ammoClip + = amount ;
if ( ammoClip > clipSize ) {
ammoClip = clipSize ;
}
ammoAvail = owner - > inventory . HasAmmo ( ammoType , ammoRequired ) ;
if ( ammoClip > ammoAvail ) {
ammoClip = ammoAvail ;
}
}
/*
= = = = = = = = = = = = = = =
idWeapon : : Event_AmmoInClip
= = = = = = = = = = = = = = =
*/
void idWeapon : : Event_AmmoInClip ( void ) {
int ammo = AmmoInClip ( ) ;
idThread : : ReturnFloat ( ammo ) ;
}
/*
= = = = = = = = = = = = = = =
idWeapon : : Event_AmmoAvailable
= = = = = = = = = = = = = = =
*/
void idWeapon : : Event_AmmoAvailable ( void ) {
int ammoAvail = owner - > inventory . HasAmmo ( ammoType , ammoRequired ) ;
idThread : : ReturnFloat ( ammoAvail ) ;
}
/*
= = = = = = = = = = = = = = =
idWeapon : : Event_TotalAmmoCount
= = = = = = = = = = = = = = =
*/
void idWeapon : : Event_TotalAmmoCount ( void ) {
int ammoAvail = owner - > inventory . HasAmmo ( ammoType , 1 ) ;
idThread : : ReturnFloat ( ammoAvail ) ;
}
/*
= = = = = = = = = = = = = = =
idWeapon : : Event_ClipSize
= = = = = = = = = = = = = = =
*/
void idWeapon : : Event_ClipSize ( void ) {
idThread : : ReturnFloat ( clipSize ) ;
}
/*
= = = = = = = = = = = = = = =
idWeapon : : Event_AutoReload
= = = = = = = = = = = = = = =
*/
void idWeapon : : Event_AutoReload ( void ) {
assert ( owner ) ;
if ( gameLocal . isClient ) {
idThread : : ReturnFloat ( 0.0f ) ;
return ;
}
idThread : : ReturnFloat ( gameLocal . userInfo [ owner - > entityNumber ] . GetBool ( " ui_autoReload " ) ) ;
}
/*
= = = = = = = = = = = = = = =
idWeapon : : Event_NetReload
= = = = = = = = = = = = = = =
*/
void idWeapon : : Event_NetReload ( void ) {
assert ( owner ) ;
if ( gameLocal . isServer ) {
ServerSendEvent ( EVENT_RELOAD , NULL , false , - 1 ) ;
}
}
/*
= = = = = = = = = = = = = = =
idWeapon : : Event_NetEndReload
= = = = = = = = = = = = = = =
*/
void idWeapon : : Event_NetEndReload ( void ) {
assert ( owner ) ;
if ( gameLocal . isServer ) {
ServerSendEvent ( EVENT_ENDRELOAD , NULL , false , - 1 ) ;
}
}
/*
= = = = = = = = = = = = = = =
idWeapon : : Event_PlayAnim
= = = = = = = = = = = = = = =
*/
void idWeapon : : Event_PlayAnim ( int channel , const char * animname ) {
int anim ;
anim = animator . GetAnim ( animname ) ;
if ( ! anim ) {
gameLocal . Warning ( " missing '%s' animation on '%s' (%s) " , animname , name . c_str ( ) , GetEntityDefName ( ) ) ;
animator . Clear ( channel , gameLocal . time , FRAME2MS ( animBlendFrames ) ) ;
animDoneTime = 0 ;
} else {
if ( ! ( owner & & owner - > GetInfluenceLevel ( ) ) ) {
Show ( ) ;
}
animator . PlayAnim ( channel , anim , gameLocal . time , FRAME2MS ( animBlendFrames ) ) ;
animDoneTime = animator . CurrentAnim ( channel ) - > GetEndTime ( ) ;
if ( worldModel . GetEntity ( ) ) {
anim = worldModel . GetEntity ( ) - > GetAnimator ( ) - > GetAnim ( animname ) ;
if ( anim ) {
worldModel . GetEntity ( ) - > GetAnimator ( ) - > PlayAnim ( channel , anim , gameLocal . time , FRAME2MS ( animBlendFrames ) ) ;
}
}
}
animBlendFrames = 0 ;
idThread : : ReturnInt ( 0 ) ;
}
/*
= = = = = = = = = = = = = = =
idWeapon : : Event_PlayCycle
= = = = = = = = = = = = = = =
*/
void idWeapon : : Event_PlayCycle ( int channel , const char * animname ) {
int anim ;
anim = animator . GetAnim ( animname ) ;
if ( ! anim ) {
gameLocal . Warning ( " missing '%s' animation on '%s' (%s) " , animname , name . c_str ( ) , GetEntityDefName ( ) ) ;
animator . Clear ( channel , gameLocal . time , FRAME2MS ( animBlendFrames ) ) ;
animDoneTime = 0 ;
} else {
if ( ! ( owner & & owner - > GetInfluenceLevel ( ) ) ) {
Show ( ) ;
}
animator . CycleAnim ( channel , anim , gameLocal . time , FRAME2MS ( animBlendFrames ) ) ;
animDoneTime = animator . CurrentAnim ( channel ) - > GetEndTime ( ) ;
if ( worldModel . GetEntity ( ) ) {
anim = worldModel . GetEntity ( ) - > GetAnimator ( ) - > GetAnim ( animname ) ;
worldModel . GetEntity ( ) - > GetAnimator ( ) - > CycleAnim ( channel , anim , gameLocal . time , FRAME2MS ( animBlendFrames ) ) ;
}
}
animBlendFrames = 0 ;
idThread : : ReturnInt ( 0 ) ;
}
/*
= = = = = = = = = = = = = = =
idWeapon : : Event_AnimDone
= = = = = = = = = = = = = = =
*/
void idWeapon : : Event_AnimDone ( int channel , int blendFrames ) {
if ( animDoneTime - FRAME2MS ( blendFrames ) < = gameLocal . time ) {
idThread : : ReturnInt ( true ) ;
} else {
idThread : : ReturnInt ( false ) ;
}
}
/*
= = = = = = = = = = = = = = =
idWeapon : : Event_SetBlendFrames
= = = = = = = = = = = = = = =
*/
void idWeapon : : Event_SetBlendFrames ( int channel , int blendFrames ) {
animBlendFrames = blendFrames ;
}
/*
= = = = = = = = = = = = = = =
idWeapon : : Event_GetBlendFrames
= = = = = = = = = = = = = = =
*/
void idWeapon : : Event_GetBlendFrames ( int channel ) {
idThread : : ReturnInt ( animBlendFrames ) ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : Event_Next
= = = = = = = = = = = = = = = =
*/
void idWeapon : : Event_Next ( void ) {
// change to another weapon if possible
owner - > NextBestWeapon ( ) ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : Event_SetSkin
= = = = = = = = = = = = = = = =
*/
void idWeapon : : Event_SetSkin ( const char * skinname ) {
const idDeclSkin * skinDecl ;
if ( ! skinname | | ! skinname [ 0 ] ) {
skinDecl = NULL ;
} else {
skinDecl = declManager - > FindSkin ( skinname ) ;
}
2020-11-15 18:52:37 +00:00
// Don't update if the skin hasn't changed.
if ( renderEntity . customSkin = = skinDecl & & worldModel . GetEntity ( ) ! = NULL & & worldModel . GetEntity ( ) - > GetSkin ( ) = = skinDecl )
{
return ;
}
2020-09-08 22:10:45 +00:00
renderEntity . customSkin = skinDecl ;
UpdateVisuals ( ) ;
if ( worldModel . GetEntity ( ) ) {
worldModel . GetEntity ( ) - > SetSkin ( skinDecl ) ;
}
2020-11-15 18:52:37 +00:00
if ( gameLocal . isServer & & ! isPlayerFlashlight ) {
2020-09-08 22:10:45 +00:00
idBitMsg msg ;
byte msgBuf [ MAX_EVENT_PARAM_SIZE ] ;
msg . Init ( msgBuf , sizeof ( msgBuf ) ) ;
msg . WriteInt ( ( skinDecl ! = NULL ) ? gameLocal . ServerRemapDecl ( - 1 , DECL_SKIN , skinDecl - > Index ( ) ) : - 1 ) ;
ServerSendEvent ( EVENT_CHANGESKIN , & msg , false , - 1 ) ;
}
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : Event_Flashlight
= = = = = = = = = = = = = = = =
*/
void idWeapon : : Event_Flashlight ( int enable ) {
if ( enable ) {
lightOn = true ;
MuzzleFlashLight ( ) ;
} else {
lightOn = false ;
muzzleFlashEnd = 0 ;
}
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : Event_GetLightParm
= = = = = = = = = = = = = = = =
*/
void idWeapon : : Event_GetLightParm ( int parmnum ) {
if ( ( parmnum < 0 ) | | ( parmnum > = MAX_ENTITY_SHADER_PARMS ) ) {
gameLocal . Error ( " shader parm index (%d) out of range " , parmnum ) ;
}
idThread : : ReturnFloat ( muzzleFlash . shaderParms [ parmnum ] ) ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : Event_SetLightParm
= = = = = = = = = = = = = = = =
*/
void idWeapon : : Event_SetLightParm ( int parmnum , float value ) {
if ( ( parmnum < 0 ) | | ( parmnum > = MAX_ENTITY_SHADER_PARMS ) ) {
gameLocal . Error ( " shader parm index (%d) out of range " , parmnum ) ;
}
muzzleFlash . shaderParms [ parmnum ] = value ;
worldMuzzleFlash . shaderParms [ parmnum ] = value ;
UpdateVisuals ( ) ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : Event_SetLightParms
= = = = = = = = = = = = = = = =
*/
void idWeapon : : Event_SetLightParms ( float parm0 , float parm1 , float parm2 , float parm3 ) {
muzzleFlash . shaderParms [ SHADERPARM_RED ] = parm0 ;
muzzleFlash . shaderParms [ SHADERPARM_GREEN ] = parm1 ;
muzzleFlash . shaderParms [ SHADERPARM_BLUE ] = parm2 ;
muzzleFlash . shaderParms [ SHADERPARM_ALPHA ] = parm3 ;
worldMuzzleFlash . shaderParms [ SHADERPARM_RED ] = parm0 ;
worldMuzzleFlash . shaderParms [ SHADERPARM_GREEN ] = parm1 ;
worldMuzzleFlash . shaderParms [ SHADERPARM_BLUE ] = parm2 ;
worldMuzzleFlash . shaderParms [ SHADERPARM_ALPHA ] = parm3 ;
UpdateVisuals ( ) ;
}
2020-11-29 14:49:20 +00:00
/*
= = = = = = = = = = = = = = = =
idWeapon : : Event_Grabber
= = = = = = = = = = = = = = = =
*/
void idWeapon : : Event_Grabber ( int enable )
{
if ( enable )
{
grabberState = 0 ;
}
else
{
grabberState = - 1 ;
}
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : Event_GrabberHasTarget
= = = = = = = = = = = = = = = =
*/
void idWeapon : : Event_GrabberHasTarget ( )
{
idThread : : ReturnInt ( grabberState ) ;
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : Event_GrabberSetGrabDistance
= = = = = = = = = = = = = = = =
*/
void idWeapon : : Event_GrabberSetGrabDistance ( float dist )
{
grabber . SetDragDistance ( dist ) ;
}
2020-09-08 22:10:45 +00:00
/*
= = = = = = = = = = = = = = = =
idWeapon : : Event_CreateProjectile
= = = = = = = = = = = = = = = =
*/
void idWeapon : : Event_CreateProjectile ( void ) {
if ( ! gameLocal . isClient ) {
projectileEnt = NULL ;
gameLocal . SpawnEntityDef ( projectileDict , & projectileEnt , false ) ;
if ( projectileEnt ) {
projectileEnt - > SetOrigin ( GetPhysics ( ) - > GetOrigin ( ) ) ;
projectileEnt - > Bind ( owner , false ) ;
projectileEnt - > Hide ( ) ;
}
idThread : : ReturnEntity ( projectileEnt ) ;
} else {
idThread : : ReturnEntity ( NULL ) ;
}
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : Event_LaunchProjectiles
= = = = = = = = = = = = = = = =
*/
void idWeapon : : Event_LaunchProjectiles ( int num_projectiles , float spread , float fuseOffset , float launchPower , float dmgPower ) {
idProjectile * proj ;
idEntity * ent ;
int i ;
idVec3 dir ;
float ang ;
float spin ;
float distance ;
trace_t tr ;
idVec3 start ;
idVec3 muzzle_pos ;
idBounds ownerBounds , projBounds ;
2020-11-15 18:52:37 +00:00
// Koz the shotgun is supposed to be a closeup weapon in the game, but the depth provided in VR really changes
// how it feels. IMO, it seems underpowered unless you are on top of an enemy, due to the extreme pellet spread.
// This enables an optional 'choke' for the shotgun, by reducing the spread.
weapon_t currentWeap ;
currentWeap = IdentifyWeapon ( ) ;
2020-11-18 14:48:17 +00:00
if ( currentWeap = = WEAPON_SHOTGUN | | currentWeap = = WEAPON_SHOTGUN_DOUBLE | | currentWeap = = WEAPON_SHOTGUN_DOUBLE_MP )
2020-11-15 18:52:37 +00:00
{
//idPlayer *player;
//player = gameLocal.GetLocalPlayer();
//if ( 1 || player == owner )
//{
common - > Printf ( " Event_LaunchProjectiles spread = %f , " , spread ) ;
spread - = 14 * vr_shotgunChoke . GetFloat ( ) / 100.0f ;
spread = idMath : : ClampFloat ( 8.0f , 22.0f , spread ) ; // not too low, or the shotgun gets WAY too powerful at range.
common - > Printf ( " choke spread = %f \n " , spread ) ;
//}
}
assert ( owner ! = NULL ) ;
2020-09-08 22:10:45 +00:00
if ( IsHidden ( ) ) {
return ;
}
if ( ! projectileDict . GetNumKeyVals ( ) ) {
const char * classname = weaponDef - > dict . GetString ( " classname " ) ;
gameLocal . Warning ( " No projectile defined on '%s' " , classname ) ;
return ;
}
// avoid all ammo considerations on an MP client
if ( ! gameLocal . isClient ) {
// check if we're out of ammo or the clip is empty
int ammoAvail = owner - > inventory . HasAmmo ( ammoType , ammoRequired ) ;
if ( ! ammoAvail | | ( ( clipSize ! = 0 ) & & ( ammoClip < = 0 ) ) ) {
return ;
}
// if this is a power ammo weapon ( currently only the bfg ) then make sure
// we only fire as much power as available in each clip
if ( powerAmmo ) {
// 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
// can be done here.
dmgPower = ( int ) dmgPower + 1 ;
if ( dmgPower > ammoClip ) {
dmgPower = ammoClip ;
}
}
owner - > inventory . UseAmmo ( ammoType , ( powerAmmo ) ? dmgPower : ammoRequired ) ;
if ( clipSize & & ammoRequired ) {
ammoClip - = powerAmmo ? dmgPower : 1 ;
}
}
if ( ! silent_fire ) {
// wake up nearby monsters
gameLocal . AlertAI ( owner ) ;
}
// 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 ) ;
if ( worldModel . GetEntity ( ) ) {
worldModel . GetEntity ( ) - > SetShaderParm ( SHADERPARM_DIVERSITY , renderEntity . shaderParms [ SHADERPARM_DIVERSITY ] ) ;
worldModel . GetEntity ( ) - > SetShaderParm ( SHADERPARM_TIMEOFFSET , renderEntity . shaderParms [ SHADERPARM_TIMEOFFSET ] ) ;
}
// calculate the muzzle position
2020-11-15 18:52:37 +00:00
GetProjectileLaunchOriginAndAxis ( muzzleOrigin , muzzleAxis ) ;
// calculate the muzzle position
/*
2020-09-08 22:10:45 +00:00
if ( barrelJointView ! = INVALID_JOINT & & projectileDict . GetBool ( " launchFromBarrel " ) ) {
// there is an explicit joint for the muzzle
GetGlobalJointTransform ( true , barrelJointView , muzzleOrigin , muzzleAxis ) ;
} else {
2020-09-17 21:46:48 +00:00
muzzleOrigin = viewWeaponOrigin ;
muzzleAxis = viewWeaponAxis ;
2020-11-15 18:52:37 +00:00
} */
2020-09-08 22:10:45 +00:00
// add some to the kick time, incrementally moving repeat firing weapons back
if ( kick_endtime < gameLocal . realClientTime ) {
kick_endtime = gameLocal . realClientTime ;
}
kick_endtime + = muzzle_kick_time ;
if ( kick_endtime > gameLocal . realClientTime + muzzle_kick_maxtime ) {
kick_endtime = gameLocal . realClientTime + muzzle_kick_maxtime ;
}
2020-11-15 18:52:37 +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 = gameLocal . isServer | | attackerIsLocal | | isHitscan ;
if ( actuallySpawnProjectile )
{
ownerBounds = owner - > GetPhysics ( ) - > GetAbsBounds ( ) ;
owner - > AddProjectilesFired ( num_projectiles ) ;
float spreadRad = DEG2RAD ( spread ) ;
for ( i = 0 ; i < num_projectiles ; i + + )
{
ang = idMath : : Sin ( spreadRad * gameLocal . random . RandomFloat ( ) ) ;
spin = ( float ) DEG2RAD ( 360.0f ) * gameLocal . random . RandomFloat ( ) ;
dir = muzzleAxis [ 0 ] + muzzleAxis [ 2 ] * ( ang * idMath : : Sin ( spin ) ) - muzzleAxis [ 1 ] * ( ang * idMath : : Cos ( spin ) ) ;
dir . Normalize ( ) ;
if ( projectileEnt )
{
ent = projectileEnt ;
ent - > Show ( ) ;
ent - > Unbind ( ) ;
projectileEnt = NULL ;
}
else
{
if ( gameLocal . isClient )
{
// 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 ) ;
}
else
{
projectileDict . SetBool ( " net_skip_replication " , false ) ;
}
gameLocal . SpawnEntityDef ( projectileDict , & ent , false ) ;
}
if ( ent = = NULL | | ! ent - > IsType ( idProjectile : : Type ) )
{
const char * projectileName = weaponDef - > dict . GetString ( " def_projectile " ) ;
gameLocal . Error ( " '%s' is not an idProjectile " , projectileName ) ;
return ;
}
if ( projectileDict . GetBool ( " net_instanthit " ) )
{
// don't synchronize this on top of the already predicted effect
ent - > fl . networkSync = false ;
}
else if ( owner ! = NULL )
{
/*
int predictedKey = idEntity : : INVALID_PREDICTION_KEY ;
// Set the prediction key only for non-instanthit projectiles.
if ( gameLocal . isClient )
{
owner - > IncrementFireCount ( ) ;
}
predictedKey = gameLocal . GeneratePredictionKey ( this , owner , - 1 ) ;
ent - > SetPredictedKey ( predictedKey ) ; */
}
proj = static_cast < idProjectile * > ( ent ) ;
proj - > Create ( owner , muzzleOrigin , dir ) ;
projBounds = proj - > GetPhysics ( ) - > GetBounds ( ) . Rotate ( proj - > GetPhysics ( ) - > GetAxis ( ) ) ;
// make sure the projectile starts inside the bounding box of the owner
// Carl: unless it's a grenade, in which case we want to be able to drop it over a railing without inexplicably killing ourselves
if ( IdentifyWeapon ( ) = = WEAPON_HANDGRENADE & & game - > isVR & & commonVr - > VR_USE_MOTION_CONTROLS & & i = = 0 )
{
muzzle_pos = muzzleOrigin + muzzleAxis [ 0 ] * 2.0f ;
// Carl: check that there's a grenade-sized gap at hand height from the center of our chest to our grenade,
// so we can drop grenades over a railing, but not through a solid wall or glass window.
// Ideally start should be our right shoulder at grenade height, but I'm not sure how to get that.
start = ownerBounds . GetCenter ( ) ;
start . z = muzzleOrigin . z ;
// MASK_SHOT_RENDERMODEL goes through chainlink fences, but a grenade shouldn't.
gameLocal . clip . Translation ( tr , start , muzzle_pos , proj - > GetPhysics ( ) - > GetClipModel ( ) , proj - > GetPhysics ( ) - > GetClipModel ( ) - > GetAxis ( ) , MASK_SHOT_RENDERMODEL | CONTENTS_PLAYERCLIP , owner ) ;
// Try reaching down from neck height if sticking our hand out straight doesn't work.
// Ideally this should be our right shoulder at shoulder height, but I'm not sure how to get that.
if ( tr . fraction < 1.0f )
{
start . z = commonVr - > lastHMDViewOrigin . z - 6 ;
gameLocal . clip . Translation ( tr , start , muzzle_pos , proj - > GetPhysics ( ) - > GetClipModel ( ) , proj - > GetPhysics ( ) - > GetClipModel ( ) - > GetAxis ( ) , MASK_SHOT_RENDERMODEL | CONTENTS_PLAYERCLIP , owner ) ;
}
muzzle_pos = tr . endpos ;
}
else if ( i = = 0 )
{
muzzle_pos = muzzleOrigin + muzzleAxis [ 0 ] * 2.0f ;
if ( ( ownerBounds - projBounds ) . RayIntersection ( muzzle_pos , muzzleAxis [ 0 ] , distance ) )
{
start = muzzle_pos + distance * muzzleAxis [ 0 ] ;
}
else
{
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 ;
}
// Koz if throwing a grenade use the tracked hand velocity when using motion controls if the controller is not mounted
// Carl: Dual Wielding
float speed = 0 ;
if ( IdentifyWeapon ( ) = = WEAPON_HANDGRENADE & & game - > isVR & & commonVr - > VR_USE_MOTION_CONTROLS & & ! vr_mountedWeaponController . GetBool ( ) )
{
int h = GetHand ( ) ;
if ( h > = 0 )
speed = owner - > hands [ h ] . throwVelocity * vr_throwPower . GetFloat ( ) ;
}
// Koz end
// Normal launch
proj - > Launch ( muzzle_pos , dir , pushVelocity , fuseOffset , launchPower , dmgPower , speed ) ;
proj - > Launch ( muzzle_pos , dir , pushVelocity , fuseOffset , launchPower , dmgPower ) ;
}
// toss the brass
if ( brassDelay > = 0 )
{
PostEventMS ( & EV_Weapon_EjectBrass , brassDelay ) ;
}
}
/*if ( gameLocal.isClient ) {
2020-09-08 22:10:45 +00:00
// predict instant hit projectiles
if ( projectileDict . GetBool ( " net_instanthit " ) ) {
float spreadRad = DEG2RAD ( spread ) ;
2020-09-17 21:46:48 +00:00
//muzzle_pos = muzzleOrigin + playerViewAxis[ 0 ] * 2.0f;
muzzle_pos = muzzleOrigin + viewWeaponAxis [ 0 ] * 2.0f ;
2020-09-08 22:10:45 +00:00
for ( i = 0 ; i < num_projectiles ; i + + ) {
ang = idMath : : Sin ( spreadRad * gameLocal . random . RandomFloat ( ) ) ;
spin = ( float ) DEG2RAD ( 360.0f ) * gameLocal . random . RandomFloat ( ) ;
2020-09-20 21:56:36 +00:00
2020-09-17 21:46:48 +00:00
dir = viewWeaponAxis [ 0 ] + viewWeaponAxis [ 2 ] * ( ang * idMath : : Sin ( spin ) ) - viewWeaponAxis [ 1 ] * ( ang * idMath : : Cos ( spin ) ) ;
2020-09-08 22:10:45 +00:00
dir . Normalize ( ) ;
gameLocal . clip . Translation ( tr , muzzle_pos , muzzle_pos + dir * 4096.0f , NULL , mat3_identity , MASK_SHOT_RENDERMODEL , owner ) ;
if ( tr . fraction < 1.0f ) {
idProjectile : : ClientPredictionCollide ( this , projectileDict , tr , vec3_origin , true ) ;
}
}
}
} else {
ownerBounds = owner - > GetPhysics ( ) - > GetAbsBounds ( ) ;
owner - > AddProjectilesFired ( num_projectiles ) ;
float spreadRad = DEG2RAD ( spread ) ;
for ( i = 0 ; i < num_projectiles ; i + + ) {
ang = idMath : : Sin ( spreadRad * gameLocal . random . RandomFloat ( ) ) ;
spin = ( float ) DEG2RAD ( 360.0f ) * gameLocal . random . RandomFloat ( ) ;
2020-11-15 18:52:37 +00:00
dir = muzzleAxis [ 0 ] + muzzleAxis [ 2 ] * ( ang * idMath : : Sin ( spin ) ) - muzzleAxis [ 1 ] * ( ang * idMath : : Cos ( spin ) ) ;
dir . Normalize ( ) ;
2020-09-11 21:41:18 +00:00
2020-11-15 18:52:37 +00:00
/* vrClientInfo *pVRClientInfo = owner->GetVRClientInfo();
* if ( owner - > GetCurrentWeaponId ( ) = = WEAPON_HANDGRENADE & &
2020-09-20 21:56:36 +00:00
pVRClientInfo ! = nullptr & &
2020-09-26 10:30:46 +00:00
vr_throwables . GetBool ( ) )
2020-09-20 21:56:36 +00:00
{
idVec3 releaseOffset ( - pVRClientInfo - > throw_origin [ 2 ] ,
- pVRClientInfo - > throw_origin [ 0 ] ,
pVRClientInfo - > throw_origin [ 1 ] ) ;
idAngles a ( 0 , owner - > viewAngles . yaw - pVRClientInfo - > hmdorientation [ YAW ] , 0 ) ;
releaseOffset * = a . ToMat3 ( ) ;
releaseOffset * = cvarSystem - > GetCVarFloat ( " vr_worldscale " ) ;
muzzle_pos = owner - > firstPersonViewOrigin + releaseOffset ;
idVec3 throw_direction ( - pVRClientInfo - > throw_trajectory [ 2 ] ,
- pVRClientInfo - > throw_trajectory [ 0 ] ,
pVRClientInfo - > throw_trajectory [ 1 ] ) ;
throw_direction * = a . ToMat3 ( ) ;
throw_direction . Normalize ( ) ;
dir = throw_direction ;
2020-09-21 22:03:25 +00:00
launchPower = pVRClientInfo - > throw_power * 0.5f ;
2020-09-20 21:56:36 +00:00
} else {
dir = viewWeaponAxis [ 0 ] + viewWeaponAxis [ 2 ] * ( ang * idMath : : Sin ( spin ) ) -
viewWeaponAxis [ 1 ] * ( ang * idMath : : Cos ( spin ) ) ;
2020-09-11 21:41:18 +00:00
2020-09-20 21:56:36 +00:00
dir . Normalize ( ) ;
2020-11-15 18:52:37 +00:00
} * * *
2020-09-08 22:10:45 +00:00
if ( projectileEnt ) {
ent = projectileEnt ;
ent - > Show ( ) ;
ent - > Unbind ( ) ;
projectileEnt = NULL ;
} else {
gameLocal . SpawnEntityDef ( projectileDict , & ent , false ) ;
}
if ( ! ent | | ! ent - > IsType ( idProjectile : : Type ) ) {
const char * projectileName = weaponDef - > dict . GetString ( " def_projectile " ) ;
gameLocal . Error ( " '%s' is not an idProjectile " , projectileName ) ;
}
if ( projectileDict . GetBool ( " net_instanthit " ) ) {
// don't synchronize this on top of the already predicted effect
ent - > fl . networkSync = false ;
}
proj = static_cast < idProjectile * > ( ent ) ;
proj - > Create ( owner , muzzleOrigin , dir ) ;
projBounds = proj - > GetPhysics ( ) - > GetBounds ( ) . Rotate ( proj - > GetPhysics ( ) - > GetAxis ( ) ) ;
2020-11-15 18:52:37 +00:00
if ( owner - > GetCurrentWeaponId ( ) ! = WEAPON_HANDGRENADE | |
2020-09-26 10:30:46 +00:00
! vr_throwables . GetBool ( ) ) {
2020-09-20 21:56:36 +00:00
// make sure the projectile starts inside the bounding box of the owner
if ( i = = 0 ) {
//muzzle_pos = muzzleOrigin + playerViewAxis[ 0 ] * 2.0f;
muzzle_pos = muzzleOrigin + viewWeaponAxis [ 0 ] * 2.0f ;
// DG: sometimes the assertion in idBounds::operator-(const idBounds&) triggers
// (would get bounding box with negative volume)
// => check that before doing ownerBounds - projBounds (equivalent to the check in the assertion)
idVec3 obDiff = ownerBounds [ 1 ] - ownerBounds [ 0 ] ;
idVec3 pbDiff = projBounds [ 1 ] - projBounds [ 0 ] ;
bool boundsSubLegal =
obDiff . x > pbDiff . x & & obDiff . y > pbDiff . y & & obDiff . z > pbDiff . z ;
if ( boundsSubLegal & &
( ownerBounds - projBounds ) . RayIntersection ( muzzle_pos , viewWeaponAxis [ 0 ] ,
distance ) ) {
//start = muzzle_pos + distance * playerViewAxis[0];
start = muzzle_pos + distance * viewWeaponAxis [ 0 ] ;
} else {
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 ;
2020-09-08 22:10:45 +00:00
}
}
2020-09-20 21:56:36 +00:00
proj - > Launch ( muzzle_pos , dir , pushVelocity , fuseOffset , launchPower , dmgPower ) ;
2020-09-08 22:10:45 +00:00
}
// toss the brass
PostEventMS ( & EV_Weapon_EjectBrass , brassDelay ) ;
2020-11-15 18:52:37 +00:00
} */
2020-09-08 22:10:45 +00:00
// add the light for the muzzleflash
if ( ! lightOn ) {
MuzzleFlashLight ( ) ;
}
2020-11-15 18:52:37 +00:00
owner - > WeaponFireFeedback ( GetHand ( ) , & weaponDef - > dict ) ;
2020-09-08 22:10:45 +00:00
// reset muzzle smoke
weaponSmokeStartTime = gameLocal . realClientTime ;
}
2020-11-15 18:52:37 +00:00
2020-09-08 22:10:45 +00:00
/*
= = = = = = = = = = = = = = = = = = = = =
idWeapon : : Event_Melee
= = = = = = = = = = = = = = = = = = = = =
*/
void idWeapon : : Event_Melee ( void ) {
idEntity * ent ;
trace_t tr ;
if ( ! meleeDef ) {
gameLocal . Error ( " No meleeDef on '%s' " , weaponDef - > dict . GetString ( " classname " ) ) ;
}
if ( ! gameLocal . isClient ) {
2020-09-17 21:46:48 +00:00
idVec3 start = viewWeaponOrigin ;
//idVec3 end = start + playerViewAxis[0] * ( meleeDistance * owner->PowerUpModifier( MELEE_DISTANCE ) );
idVec3 end = start + viewWeaponAxis [ 0 ] * ( meleeDistance * owner - > PowerUpModifier ( MELEE_DISTANCE ) ) ;
2020-09-08 22:10:45 +00:00
gameLocal . clip . TracePoint ( tr , start , end , MASK_SHOT_RENDERMODEL , owner ) ;
if ( tr . fraction < 1.0f ) {
ent = gameLocal . GetTraceEntity ( tr ) ;
} else {
ent = NULL ;
}
if ( g_debugWeapon . GetBool ( ) ) {
gameRenderWorld - > DebugLine ( colorYellow , start , end , 100 ) ;
if ( ent ) {
gameRenderWorld - > DebugBounds ( colorRed , ent - > GetPhysics ( ) - > GetBounds ( ) , ent - > GetPhysics ( ) - > GetOrigin ( ) , 100 ) ;
}
}
bool hit = false ;
const char * hitSound = meleeDef - > dict . GetString ( " snd_miss " ) ;
if ( ent ) {
float push = meleeDef - > dict . GetFloat ( " push " ) ;
idVec3 impulse = - push * owner - > PowerUpModifier ( SPEED ) * tr . c . normal ;
if ( gameLocal . world - > spawnArgs . GetBool ( " no_Weapons " ) & & ( ent - > IsType ( idActor : : Type ) | | ent - > IsType ( idAFAttachment : : Type ) ) ) {
idThread : : ReturnInt ( 0 ) ;
return ;
}
ent - > ApplyImpulse ( this , tr . c . id , tr . c . point , impulse ) ;
// weapon stealing - do this before damaging so weapons are not dropped twice
if ( gameLocal . isMultiplayer
& & weaponDef & & 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 ) )
) {
owner - > StealWeapon ( static_cast < idPlayer * > ( ent ) ) ;
}
if ( ent - > fl . takedamage ) {
idVec3 kickDir , globalKickDir ;
meleeDef - > dict . GetVector ( " kickDir " , " 0 0 0 " , kickDir ) ;
globalKickDir = muzzleAxis * kickDir ;
ent - > Damage ( owner , owner , globalKickDir , meleeDefName , owner - > PowerUpModifier ( MELEE_DAMAGE ) , tr . c . id ) ;
hit = true ;
}
if ( weaponDef - > dict . GetBool ( " impact_damage_effect " ) ) {
if ( ent - > spawnArgs . GetBool ( " bleed " ) ) {
hitSound = meleeDef - > dict . GetString ( owner - > PowerUpActive ( BERSERK ) ? " snd_hit_berserk " : " snd_hit " ) ;
ent - > AddDamageEffect ( tr , impulse , meleeDef - > dict . GetString ( " classname " ) ) ;
} else {
int type = tr . c . material - > GetSurfaceType ( ) ;
if ( type = = SURFTYPE_NONE ) {
type = GetDefaultSurfaceType ( ) ;
}
const char * materialType = gameLocal . sufaceTypeNames [ type ] ;
// start impact sound based on material type
hitSound = meleeDef - > dict . GetString ( va ( " snd_%s " , materialType ) ) ;
if ( * hitSound = = ' \0 ' ) {
hitSound = meleeDef - > dict . GetString ( " snd_metal " ) ;
}
if ( gameLocal . time > nextStrikeFx ) {
const char * decal ;
// project decal
decal = weaponDef - > dict . GetString ( " mtr_strike " ) ;
if ( decal & & * decal ) {
gameLocal . ProjectDecal ( tr . c . point , - tr . c . normal , 8.0f , true , 6.0 , decal ) ;
}
nextStrikeFx = gameLocal . time + 200 ;
} else {
hitSound = " " ;
}
strikeSmokeStartTime = gameLocal . time ;
strikePos = tr . c . point ;
strikeAxis = - tr . endAxis ;
}
}
}
if ( * hitSound ! = ' \0 ' ) {
const idSoundShader * snd = declManager - > FindSound ( hitSound ) ;
StartSoundShader ( snd , SND_CHANNEL_BODY2 , 0 , true , NULL ) ;
}
idThread : : ReturnInt ( hit ) ;
2020-11-15 18:52:37 +00:00
owner - > WeaponFireFeedback ( GetHand ( ) , & weaponDef - > dict ) ;
2020-09-08 22:10:45 +00:00
return ;
}
idThread : : ReturnInt ( 0 ) ;
2020-11-15 18:52:37 +00:00
owner - > WeaponFireFeedback ( GetHand ( ) , & weaponDef - > dict ) ;
2020-09-08 22:10:45 +00:00
}
/*
= = = = = = = = = = = = = = = = = = = = =
idWeapon : : Event_GetWorldModel
= = = = = = = = = = = = = = = = = = = = =
*/
void idWeapon : : Event_GetWorldModel ( void ) {
idThread : : ReturnEntity ( worldModel . GetEntity ( ) ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
idWeapon : : Event_AllowDrop
= = = = = = = = = = = = = = = = = = = = =
*/
void idWeapon : : Event_AllowDrop ( int allow ) {
if ( allow ) {
allowDrop = true ;
} else {
allowDrop = false ;
}
}
/*
= = = = = = = = = = = = = = = =
idWeapon : : Event_EjectBrass
Toss a shell model out from the breach if the bone is present
= = = = = = = = = = = = = = = =
*/
void idWeapon : : Event_EjectBrass ( void ) {
if ( ! g_showBrass . GetBool ( ) | | ! owner - > CanShowWeaponViewmodel ( ) ) {
return ;
}
if ( ejectJointView = = INVALID_JOINT | | ! brassDict . GetNumKeyVals ( ) ) {
return ;
}
if ( gameLocal . isClient ) {
return ;
}
idMat3 axis ;
idVec3 origin , linear_velocity , angular_velocity ;
idEntity * ent ;
if ( ! GetGlobalJointTransform ( true , ejectJointView , origin , axis ) ) {
return ;
}
gameLocal . SpawnEntityDef ( brassDict , & ent , false ) ;
if ( ! ent | | ! ent - > IsType ( idDebris : : Type ) ) {
gameLocal . Error ( " '%s' is not an idDebris " , weaponDef ? weaponDef - > dict . GetString ( " def_ejectBrass " ) : " def_ejectBrass " ) ;
}
idDebris * debris = static_cast < idDebris * > ( ent ) ;
debris - > Create ( owner , origin , axis ) ;
debris - > Launch ( ) ;
2020-11-15 18:52:37 +00:00
// Koz begin
idAngles vwa = viewWeaponAxis . ToAngles ( ) ;
vwa . yaw + = 30.0f ;
idMat3 ba = vwa . Normalize180 ( ) . ToMat3 ( ) ;
//linear_velocity = 50 * (viewWeaponAxis[0] + viewWeaponAxis[1] + viewWeaponAxis[2]);
linear_velocity = 50 * ( ba [ 0 ] + ba [ 1 ] + ba [ 2 ] ) ;
// Koz end
2020-09-17 21:46:48 +00:00
//linear_velocity = 40 * ( playerViewAxis[0] + playerViewAxis[1] + playerViewAxis[2] );
2020-11-15 18:52:37 +00:00
//linear_velocity = 40 * ( viewWeaponAxis[0] + viewWeaponAxis[1] + viewWeaponAxis[2] );
2020-09-08 22:10:45 +00:00
angular_velocity . Set ( 10 * gameLocal . random . CRandomFloat ( ) , 10 * gameLocal . random . CRandomFloat ( ) , 10 * gameLocal . random . CRandomFloat ( ) ) ;
debris - > GetPhysics ( ) - > SetLinearVelocity ( linear_velocity ) ;
debris - > GetPhysics ( ) - > SetAngularVelocity ( angular_velocity ) ;
}
2020-11-15 18:52:37 +00:00
/*Koz - what a mess
= = = = = = = = = = = = = = =
idWeapon : : Event_GetWeaponSkin
= = = = = = = = = = = = = = =
*/
void idWeapon : : Event_GetWeaponSkin ( )
{
if ( ! owner | | ! game - > isVR )
{
idThread : : ReturnString ( " " ) ;
return ;
}
// game is vr, return a string name for the skin matching the hand/statwatch config.
static idStr vrSkinName ;
// Koz fixme - need to go through all the weapon models and delete the meshes for the hands and statwatch. Also need to delete all the skin definitions, no longer necessary.
// this has all changed. Originally, hands were part of the weapon models, and hands and statwatch were turned on and off
// by changing the skin for model. Now the hands are always drawn as part of the player body, so all the skins
// are no longer needed. The only skin used now is for the mini flashlight when mounted to the weapon.
if ( isPlayerFlashlight )
{
vrSkinName = ( commonVr - > GetCurrentFlashlightMode ( ) = = FLASHLIGHT_GUN | | commonVr - > GetCurrentFlashlightMode ( ) = = FLASHLIGHT_PISTOL ) ? " minivr/flashhands/0h " : " vr/flashhands/0h " ; // mini flashlight skin for gun mount : normal flashlight skin
}
else
{
//vrSkinName = "vr/weaponhands/0h";
vrSkinName = " " ;
}
//common->Printf( "idWeapon::Event_GetWeaponSkin() returning %s\n", vrSkinName.c_str() );
idThread : : ReturnString ( vrSkinName . c_str ( ) ) ;
}
/*
= = = = = = = = = = = = = = = = = =
idPlayer : : Event_IsMotionControlled
= = = = = = = = = = = = = = = = = =
*/
void idWeapon : : Event_IsMotionControlled ( )
{
static int isMC ;
//isMC = (game->isVR && commonVr->VR_USE_MOTION_CONTROLS) ? 1 : 0;
isMC = 1 ;
// Koz debug common->Printf( "Event_IsMotionControlled returning %d\n", isMC );
// idThread::ReturnInt( ( game->isVR && commonVr->VR_USE_MOTION_CONTROLS ) ? 1 : 0 );
idThread : : ReturnInt ( isMC ) ;
}
2020-09-08 22:10:45 +00:00
/*
= = = = = = = = = = = = = = =
idWeapon : : Event_IsInvisible
= = = = = = = = = = = = = = =
*/
void idWeapon : : Event_IsInvisible ( void ) {
if ( ! owner ) {
idThread : : ReturnFloat ( 0 ) ;
return ;
}
idThread : : ReturnFloat ( owner - > PowerUpActive ( INVISIBILITY ) ? 1 : 0 ) ;
}
/*
= = = = = = = = = = = = = = =
idWeapon : : ClientPredictionThink
= = = = = = = = = = = = = = =
*/
void idWeapon : : ClientPredictionThink ( void ) {
UpdateAnimation ( ) ;
}