diff --git a/neo/doom3/game/Weapon.cpp b/neo/doom3/game/Weapon.cpp index cca0d7c7..2845f931 100644 --- a/neo/doom3/game/Weapon.cpp +++ b/neo/doom3/game/Weapon.cpp @@ -2,9 +2,9 @@ =========================================================================== IceTech GPL Source Code -Copyright (C) 2026 Justin Marshall +Copyright (C) 2026 Justin Marshall -This file is part of the IceTech GPL Source Code (?IceTech Source Code?). +This file is part of the IceTech GPL Source Code (?IceTech Source Code?). IceTech 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 @@ -33,83 +33,279 @@ If you have questions concerning this license or the applicable additional terms /*********************************************************************** - idWeapon - + idWeapon + ***********************************************************************/ // // event defs // -const idEventDef EV_Weapon_Clear( "" ); -const idEventDef EV_Weapon_GetOwner( "getOwner", NULL, 'e' ); -const idEventDef EV_Weapon_Next( "nextWeapon" ); -const idEventDef EV_Weapon_State( "weaponState", "sd" ); -const idEventDef EV_Weapon_UseAmmo( "useAmmo", "d" ); -const idEventDef EV_Weapon_AddToClip( "addToClip", "d" ); -const idEventDef EV_Weapon_AmmoInClip( "ammoInClip", NULL, 'f' ); -const idEventDef EV_Weapon_AmmoAvailable( "ammoAvailable", NULL, 'f' ); -const idEventDef EV_Weapon_TotalAmmoCount( "totalAmmoCount", NULL, 'f' ); -const idEventDef EV_Weapon_ClipSize( "clipSize", NULL, 'f' ); -const idEventDef EV_Weapon_WeaponOutOfAmmo( "weaponOutOfAmmo" ); -const idEventDef EV_Weapon_WeaponReady( "weaponReady" ); -const idEventDef EV_Weapon_WeaponReloading( "weaponReloading" ); -const idEventDef EV_Weapon_WeaponHolstered( "weaponHolstered" ); -const idEventDef EV_Weapon_WeaponRising( "weaponRising" ); -const idEventDef EV_Weapon_WeaponLowering( "weaponLowering" ); -const idEventDef EV_Weapon_Flashlight( "flashlight", "d" ); -const idEventDef EV_Weapon_LaunchProjectiles( "launchProjectiles", "dffff" ); -const idEventDef EV_Weapon_CreateProjectile( "createProjectile", NULL, 'e' ); -const idEventDef EV_Weapon_EjectBrass( "ejectBrass" ); -const idEventDef EV_Weapon_Melee( "melee", NULL, 'd' ); -const idEventDef EV_Weapon_GetWorldModel( "getWorldModel", NULL, 'e' ); -const idEventDef EV_Weapon_AllowDrop( "allowDrop", "d" ); -const idEventDef EV_Weapon_AutoReload( "autoReload", NULL, 'f' ); -const idEventDef EV_Weapon_NetReload( "netReload" ); -const idEventDef EV_Weapon_IsInvisible( "isInvisible", NULL, 'f' ); -const idEventDef EV_Weapon_NetEndReload( "netEndReload" ); +const idEventDef EV_Weapon_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"); // // 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 ) +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) END_CLASS + +/* +================ +Weapon fire muzzle light + +This is intentionally separate from idWeapon::MuzzleFlashLight(). The old +MuzzleFlashLight path is used by weapon scripts as a flashlight / persistent +weapon light, so projectile firing gets its own short-lived light here. +================ +*/ +struct weaponFireMuzzleLightLocal_t { + int viewHandle; + int worldHandle; + int startTime; + int endTime; + int duration; + idVec3 baseColor; + float baseRadius; + renderLight_t viewLight; + renderLight_t worldLight; +}; + +static weaponFireMuzzleLightLocal_t weaponFireMuzzleLights[MAX_GENTITIES]; +static bool weaponFireMuzzleLightsInitialized = false; + +static void InitWeaponFireMuzzleLights(void) { + if (weaponFireMuzzleLightsInitialized) { + return; + } + + for (int i = 0; i < MAX_GENTITIES; i++) { + memset(&weaponFireMuzzleLights[i], 0, sizeof(weaponFireMuzzleLights[i])); + weaponFireMuzzleLights[i].viewHandle = -1; + weaponFireMuzzleLights[i].worldHandle = -1; + } + + weaponFireMuzzleLightsInitialized = true; +} + +static void FreeWeaponFireMuzzleLight(int entityNum) { + InitWeaponFireMuzzleLights(); + + if (entityNum < 0 || entityNum >= MAX_GENTITIES) { + return; + } + + weaponFireMuzzleLightLocal_t& fireLight = weaponFireMuzzleLights[entityNum]; + + if (fireLight.viewHandle != -1) { + gameRenderWorld->FreeLightDef(fireLight.viewHandle); + fireLight.viewHandle = -1; + } + if (fireLight.worldHandle != -1) { + gameRenderWorld->FreeLightDef(fireLight.worldHandle); + fireLight.worldHandle = -1; + } + + fireLight.startTime = 0; + fireLight.endTime = 0; + fireLight.duration = 0; + fireLight.baseColor.Zero(); + fireLight.baseRadius = 0.0f; + memset(&fireLight.viewLight, 0, sizeof(fireLight.viewLight)); + memset(&fireLight.worldLight, 0, sizeof(fireLight.worldLight)); +} + +static void StartWeaponFireMuzzleLight(int entityNum, int ownerEntityNum, const idVec3& viewOrigin, const idMat3& viewAxis, const idVec3& worldOrigin, const idMat3& worldAxis, const idMaterial* shader, const idVec3& color, float radius, int duration, float diversity) { + InitWeaponFireMuzzleLights(); + + if (entityNum < 0 || entityNum >= MAX_GENTITIES) { + return; + } + if (radius <= 0.0f || duration <= 0) { + return; + } + + weaponFireMuzzleLightLocal_t& fireLight = weaponFireMuzzleLights[entityNum]; + + memset(&fireLight.viewLight, 0, sizeof(fireLight.viewLight)); + memset(&fireLight.worldLight, 0, sizeof(fireLight.worldLight)); + + fireLight.startTime = gameLocal.time; + fireLight.endTime = gameLocal.time + duration; + fireLight.duration = duration; + fireLight.baseColor = color; + fireLight.baseRadius = radius * 5; + + fireLight.viewLight.pointLight = true; + fireLight.viewLight.noShadows = true; + fireLight.viewLight.shader = shader; + fireLight.viewLight.origin = viewOrigin; + fireLight.viewLight.axis = viewAxis; + fireLight.viewLight.lightRadius[0] = radius; + fireLight.viewLight.lightRadius[1] = radius; + fireLight.viewLight.lightRadius[2] = radius; + fireLight.viewLight.shaderParms[SHADERPARM_RED] = color.x; + fireLight.viewLight.shaderParms[SHADERPARM_GREEN] = color.y; + fireLight.viewLight.shaderParms[SHADERPARM_BLUE] = color.z; + fireLight.viewLight.shaderParms[SHADERPARM_ALPHA] = 1.0f; + fireLight.viewLight.shaderParms[SHADERPARM_TIMESCALE] = 1.0f; + fireLight.viewLight.shaderParms[SHADERPARM_TIMEOFFSET] = -MS2SEC(gameLocal.time); + fireLight.viewLight.shaderParms[SHADERPARM_DIVERSITY] = diversity; + + // Only the owning player should see the view-model light. This is what + // makes the light appear attached to the first-person muzzle flash joint. + if (ownerEntityNum >= 0) { + fireLight.viewLight.allowLightInViewID = ownerEntityNum + 1; + // Keep this separate from the old LIGHTID_VIEW_MUZZLE_FLASH path used by + // MuzzleFlashLight/flashlight so the two systems never fight each other. + fireLight.viewLight.lightId = LIGHTID_VIEW_MUZZLE_FLASH + ownerEntityNum + 256; + } + + fireLight.worldLight = fireLight.viewLight; + fireLight.worldLight.origin = worldOrigin; + fireLight.worldLight.axis = worldAxis; + fireLight.worldLight.allowLightInViewID = 0; + if (ownerEntityNum >= 0) { + fireLight.worldLight.suppressLightInViewID = ownerEntityNum + 1; + fireLight.worldLight.lightId = LIGHTID_WORLD_MUZZLE_FLASH + ownerEntityNum + 256; + } + + if (fireLight.viewHandle != -1) { + gameRenderWorld->UpdateLightDef(fireLight.viewHandle, &fireLight.viewLight); + } + else { + fireLight.viewHandle = gameRenderWorld->AddLightDef(&fireLight.viewLight); + } + + if (fireLight.worldHandle != -1) { + gameRenderWorld->UpdateLightDef(fireLight.worldHandle, &fireLight.worldLight); + } + else { + fireLight.worldHandle = gameRenderWorld->AddLightDef(&fireLight.worldLight); + } +} + +static bool UpdateWeaponFireMuzzleLight(int entityNum, const idVec3& viewOrigin, const idMat3& viewAxis, const idVec3& worldOrigin, const idMat3& worldAxis) { + InitWeaponFireMuzzleLights(); + + if (entityNum < 0 || entityNum >= MAX_GENTITIES) { + return false; + } + + weaponFireMuzzleLightLocal_t& fireLight = weaponFireMuzzleLights[entityNum]; + + if (fireLight.viewHandle == -1 && fireLight.worldHandle == -1) { + return false; + } + + if (gameLocal.time >= fireLight.endTime || fireLight.duration <= 0) { + FreeWeaponFireMuzzleLight(entityNum); + return false; + } + + float frac = (float)(fireLight.endTime - gameLocal.time) / (float)fireLight.duration; + if (frac < 0.0f) { + frac = 0.0f; + } + else if (frac > 1.0f) { + frac = 1.0f; + } + + // A squared falloff gives a hot first frame and then a quick natural fade. + float fade = frac * frac; + float radius = fireLight.baseRadius * (0.35f + 0.65f * fade); + + fireLight.viewLight.origin = viewOrigin; + fireLight.viewLight.axis = viewAxis; + fireLight.viewLight.lightRadius[0] = radius; + fireLight.viewLight.lightRadius[1] = radius; + fireLight.viewLight.lightRadius[2] = radius; + fireLight.viewLight.shaderParms[SHADERPARM_RED] = fireLight.baseColor.x * fade; + fireLight.viewLight.shaderParms[SHADERPARM_GREEN] = fireLight.baseColor.y * fade; + fireLight.viewLight.shaderParms[SHADERPARM_BLUE] = fireLight.baseColor.z * fade; + fireLight.viewLight.shaderParms[SHADERPARM_ALPHA] = fade; + + fireLight.worldLight.origin = worldOrigin; + fireLight.worldLight.axis = worldAxis; + fireLight.worldLight.lightRadius[0] = radius; + fireLight.worldLight.lightRadius[1] = radius; + fireLight.worldLight.lightRadius[2] = radius; + fireLight.worldLight.shaderParms[SHADERPARM_RED] = fireLight.baseColor.x * fade; + fireLight.worldLight.shaderParms[SHADERPARM_GREEN] = fireLight.baseColor.y * fade; + fireLight.worldLight.shaderParms[SHADERPARM_BLUE] = fireLight.baseColor.z * fade; + fireLight.worldLight.shaderParms[SHADERPARM_ALPHA] = fade; + + if (fireLight.viewHandle != -1) { + gameRenderWorld->UpdateLightDef(fireLight.viewHandle, &fireLight.viewLight); + } + if (fireLight.worldHandle != -1) { + gameRenderWorld->UpdateLightDef(fireLight.worldHandle, &fireLight.worldLight); + } + + return true; +} + /*********************************************************************** init @@ -122,28 +318,28 @@ idWeapon::idWeapon() ================ */ idWeapon::idWeapon() { - owner = NULL; - worldModel = NULL; - weaponDef = NULL; - thread = NULL; + 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 ) ); + 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; + muzzleFlashEnd = 0; + flashColor = vec3_origin; + muzzleFlashHandle = -1; + worldMuzzleFlashHandle = -1; + guiLightHandle = -1; + nozzleGlowHandle = -1; + modelDefHandle = -1; - berserk = 2; - brassDelay = 0; + berserk = 2; + brassDelay = 0; - allowDrop = true; + allowDrop = true; Clear(); @@ -166,10 +362,10 @@ idWeapon::~idWeapon() { idWeapon::Spawn ================ */ -void idWeapon::Spawn( void ) { - if ( !gameLocal.isClient ) { +void idWeapon::Spawn(void) { + if (!gameLocal.isClient) { // setup the world model - worldModel = static_cast< idAnimatedEntity * >( gameLocal.SpawnEntityType( idAnimatedEntity::Type, NULL ) ); + worldModel = static_cast(gameLocal.SpawnEntityType(idAnimatedEntity::Type, NULL)); worldModel.GetEntity()->fl.networkSync = true; } @@ -185,13 +381,13 @@ idWeapon::SetOwner Only called at player spawn time, not each weapon switch ================ */ -void idWeapon::SetOwner( idPlayer *_owner ) { - assert( !owner ); +void idWeapon::SetOwner(idPlayer* _owner) { + assert(!owner); owner = _owner; - SetName( va( "%s_weapon", owner->name.c_str() ) ); + SetName(va("%s_weapon", owner->name.c_str())); - if ( worldModel.GetEntity() ) { - worldModel.GetEntity()->SetName( va( "%s_weapon_worldmodel", owner->name.c_str() ) ); + if (worldModel.GetEntity()) { + worldModel.GetEntity()->SetName(va("%s_weapon_worldmodel", owner->name.c_str())); } } @@ -203,7 +399,7 @@ Called during idEntity::Spawn to see if it should construct the script object or Overridden by subclasses that need to spawn the script object themselves. ================ */ -bool idWeapon::ShouldConstructScriptObjectAtSpawn( void ) const { +bool idWeapon::ShouldConstructScriptObjectAtSpawn(void) const { return false; } @@ -212,35 +408,35 @@ bool idWeapon::ShouldConstructScriptObjectAtSpawn( void ) const { idWeapon::CacheWeapon ================ */ -void idWeapon::CacheWeapon( const char *weaponName ) { - const idDeclEntityDef *weaponDef; - const char *brassDefName; - const char *clipModelName; +void idWeapon::CacheWeapon(const char* weaponName) { + const idDeclEntityDef* weaponDef; + const char* brassDefName; + const char* clipModelName; idTraceModel trm; - const char *guiName; + const char* guiName; - weaponDef = gameLocal.FindEntityDef( weaponName, false ); - if ( !weaponDef ) { + 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 + 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 ); + collisionModelManager->TrmFromModel(clipModelName, trm); } } - guiName = weaponDef->dict.GetString( "gui" ); - if ( guiName[0] ) { - uiManager->FindGui( guiName, true, false, true ); + guiName = weaponDef->dict.GetString("gui"); + if (guiName[0]) { + uiManager->FindGui(guiName, true, false, true); } } @@ -249,124 +445,124 @@ void idWeapon::CacheWeapon( const char *weaponName ) { idWeapon::Save ================ */ -void idWeapon::Save( idSaveGame *savefile ) const { +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->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->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(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->WriteInt(berserk); - savefile->WriteVec3( playerViewOrigin ); - savefile->WriteMat3( playerViewAxis ); + savefile->WriteVec3(playerViewOrigin); + savefile->WriteMat3(playerViewAxis); - savefile->WriteVec3( viewWeaponOrigin ); - savefile->WriteMat3( viewWeaponAxis ); + savefile->WriteVec3(viewWeaponOrigin); + savefile->WriteMat3(viewWeaponAxis); - savefile->WriteVec3( muzzleOrigin ); - savefile->WriteMat3( muzzleAxis ); + savefile->WriteVec3(muzzleOrigin); + savefile->WriteMat3(muzzleAxis); - savefile->WriteVec3( pushVelocity ); + savefile->WriteVec3(pushVelocity); - savefile->WriteString( weaponDef->GetName() ); - savefile->WriteFloat( meleeDistance ); - savefile->WriteString( meleeDefName ); - savefile->WriteInt( brassDelay ); - savefile->WriteString( icon ); + savefile->WriteString(weaponDef->GetName()); + savefile->WriteFloat(meleeDistance); + savefile->WriteString(meleeDefName); + savefile->WriteInt(brassDelay); + savefile->WriteString(icon); - savefile->WriteInt( guiLightHandle ); - savefile->WriteRenderLight( guiLight ); + savefile->WriteInt(guiLightHandle); + savefile->WriteRenderLight(guiLight); - savefile->WriteInt( muzzleFlashHandle ); - savefile->WriteRenderLight( muzzleFlash ); + savefile->WriteInt(muzzleFlashHandle); + savefile->WriteRenderLight(muzzleFlash); - savefile->WriteInt( worldMuzzleFlashHandle ); - savefile->WriteRenderLight( worldMuzzleFlash ); + savefile->WriteInt(worldMuzzleFlashHandle); + savefile->WriteRenderLight(worldMuzzleFlash); - savefile->WriteVec3( flashColor ); - savefile->WriteInt( muzzleFlashEnd ); - savefile->WriteInt( flashTime ); + savefile->WriteVec3(flashColor); + savefile->WriteInt(muzzleFlashEnd); + savefile->WriteInt(flashTime); - savefile->WriteBool( lightOn ); - savefile->WriteBool( silent_fire ); + 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(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 ); + 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(0); - savefile->WriteInt( zoomFov ); + savefile->WriteInt(zoomFov); - savefile->WriteJoint( barrelJointView ); - savefile->WriteJoint( flashJointView ); - savefile->WriteJoint( ejectJointView ); - savefile->WriteJoint( guiLightJointView ); - savefile->WriteJoint( ventLightJointView ); + 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->WriteJoint(flashJointWorld); + savefile->WriteJoint(barrelJointWorld); + savefile->WriteJoint(ejectJointWorld); - savefile->WriteBool( hasBloodSplat ); + savefile->WriteBool(hasBloodSplat); - savefile->WriteSoundShader( sndHum ); + 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->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->WriteBool(nozzleFx); + savefile->WriteInt(nozzleFxFade); - savefile->WriteInt( lastAttack ); + savefile->WriteInt(lastAttack); - savefile->WriteInt( nozzleGlowHandle ); - savefile->WriteRenderLight( nozzleGlow ); + savefile->WriteInt(nozzleGlowHandle); + savefile->WriteRenderLight(nozzleGlow); - savefile->WriteVec3( nozzleGlowColor ); - savefile->WriteMaterial( nozzleGlowShader ); - savefile->WriteFloat( nozzleGlowRadius ); + 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->WriteInt(weaponAngleOffsetAverages); + savefile->WriteFloat(weaponAngleOffsetScale); + savefile->WriteFloat(weaponAngleOffsetMax); + savefile->WriteFloat(weaponOffsetTime); + savefile->WriteFloat(weaponOffsetScale); - savefile->WriteBool( allowDrop ); - savefile->WriteObject( projectileEnt ); + savefile->WriteBool(allowDrop); + savefile->WriteObject(projectileEnt); } @@ -375,152 +571,154 @@ void idWeapon::Save( idSaveGame *savefile ) const { idWeapon::Restore ================ */ -void idWeapon::Restore( idRestoreGame *savefile ) { +void idWeapon::Restore(idRestoreGame* savefile) { - savefile->ReadInt( (int &)status ); - savefile->ReadObject( reinterpret_cast( thread ) ); - savefile->ReadString( state ); - savefile->ReadString( idealState ); - savefile->ReadInt( animBlendFrames ); - savefile->ReadInt( animDoneTime ); - savefile->ReadBool( isLinked ); + savefile->ReadInt((int&)status); + savefile->ReadObject(reinterpret_cast(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" ); - WEAPON_NETFIRING.LinkTo( scriptObject, "WEAPON_NETFIRING" ); - WEAPON_RAISEWEAPON.LinkTo( scriptObject, "WEAPON_RAISEWEAPON" ); - WEAPON_LOWERWEAPON.LinkTo( scriptObject, "WEAPON_LOWERWEAPON" ); + WEAPON_ATTACK.LinkTo(scriptObject, "WEAPON_ATTACK"); + WEAPON_RELOAD.LinkTo(scriptObject, "WEAPON_RELOAD"); + WEAPON_NETRELOAD.LinkTo(scriptObject, "WEAPON_NETRELOAD"); + WEAPON_NETENDRELOAD.LinkTo(scriptObject, "WEAPON_NETENDRELOAD"); + WEAPON_NETFIRING.LinkTo(scriptObject, "WEAPON_NETFIRING"); + WEAPON_RAISEWEAPON.LinkTo(scriptObject, "WEAPON_RAISEWEAPON"); + WEAPON_LOWERWEAPON.LinkTo(scriptObject, "WEAPON_LOWERWEAPON"); - savefile->ReadObject( reinterpret_cast( owner ) ); - worldModel.Restore( savefile ); + savefile->ReadObject(reinterpret_cast(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(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->ReadInt(berserk); - savefile->ReadVec3( playerViewOrigin ); - savefile->ReadMat3( playerViewAxis ); + savefile->ReadVec3(playerViewOrigin); + savefile->ReadMat3(playerViewAxis); - savefile->ReadVec3( viewWeaponOrigin ); - savefile->ReadMat3( viewWeaponAxis ); + savefile->ReadVec3(viewWeaponOrigin); + savefile->ReadMat3(viewWeaponAxis); - savefile->ReadVec3( muzzleOrigin ); - savefile->ReadMat3( muzzleAxis ); + savefile->ReadVec3(muzzleOrigin); + savefile->ReadMat3(muzzleAxis); - savefile->ReadVec3( pushVelocity ); + savefile->ReadVec3(pushVelocity); idStr objectname; - savefile->ReadString( objectname ); - weaponDef = gameLocal.FindEntityDef( objectname ); - meleeDef = gameLocal.FindEntityDef( weaponDef->dict.GetString( "def_melee" ), false ); + 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 ) { + const idDeclEntityDef* projectileDef = gameLocal.FindEntityDef(weaponDef->dict.GetString("def_projectile"), false); + if (projectileDef) { projectileDict = projectileDef->dict; - } else { + } + else { projectileDict.Clear(); } - const idDeclEntityDef *brassDef = gameLocal.FindEntityDef( weaponDef->dict.GetString( "def_ejectBrass" ), false ); - if ( brassDef ) { + const idDeclEntityDef* brassDef = gameLocal.FindEntityDef(weaponDef->dict.GetString("def_ejectBrass"), false); + if (brassDef) { brassDict = brassDef->dict; - } else { + } + else { brassDict.Clear(); } - savefile->ReadFloat( meleeDistance ); - savefile->ReadString( meleeDefName ); - savefile->ReadInt( brassDelay ); - savefile->ReadString( icon ); + savefile->ReadFloat(meleeDistance); + savefile->ReadString(meleeDefName); + savefile->ReadInt(brassDelay); + savefile->ReadString(icon); - savefile->ReadInt( guiLightHandle ); - savefile->ReadRenderLight( guiLight ); + savefile->ReadInt(guiLightHandle); + savefile->ReadRenderLight(guiLight); - savefile->ReadInt( muzzleFlashHandle ); - savefile->ReadRenderLight( muzzleFlash ); + savefile->ReadInt(muzzleFlashHandle); + savefile->ReadRenderLight(muzzleFlash); - savefile->ReadInt( worldMuzzleFlashHandle ); - savefile->ReadRenderLight( worldMuzzleFlash ); + savefile->ReadInt(worldMuzzleFlashHandle); + savefile->ReadRenderLight(worldMuzzleFlash); - savefile->ReadVec3( flashColor ); - savefile->ReadInt( muzzleFlashEnd ); - savefile->ReadInt( flashTime ); + savefile->ReadVec3(flashColor); + savefile->ReadInt(muzzleFlashEnd); + savefile->ReadInt(flashTime); - savefile->ReadBool( lightOn ); - savefile->ReadBool( silent_fire ); + 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(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 ); + 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(foo); - savefile->ReadInt( zoomFov ); + savefile->ReadInt(zoomFov); - savefile->ReadJoint( barrelJointView ); - savefile->ReadJoint( flashJointView ); - savefile->ReadJoint( ejectJointView ); - savefile->ReadJoint( guiLightJointView ); - savefile->ReadJoint( ventLightJointView ); + 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->ReadJoint(flashJointWorld); + savefile->ReadJoint(barrelJointWorld); + savefile->ReadJoint(ejectJointWorld); - savefile->ReadBool( hasBloodSplat ); + savefile->ReadBool(hasBloodSplat); - savefile->ReadSoundShader( sndHum ); + 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->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->ReadBool(nozzleFx); + savefile->ReadInt(nozzleFxFade); - savefile->ReadInt( lastAttack ); + savefile->ReadInt(lastAttack); - savefile->ReadInt( nozzleGlowHandle ); - savefile->ReadRenderLight( nozzleGlow ); + savefile->ReadInt(nozzleGlowHandle); + savefile->ReadRenderLight(nozzleGlow); - savefile->ReadVec3( nozzleGlowColor ); - savefile->ReadMaterial( nozzleGlowShader ); - savefile->ReadFloat( nozzleGlowRadius ); + 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->ReadInt(weaponAngleOffsetAverages); + savefile->ReadFloat(weaponAngleOffsetScale); + savefile->ReadFloat(weaponAngleOffsetMax); + savefile->ReadFloat(weaponOffsetTime); + savefile->ReadFloat(weaponOffsetScale); - savefile->ReadBool( allowDrop ); - savefile->ReadObject( reinterpret_cast( projectileEnt ) ); + savefile->ReadBool(allowDrop); + savefile->ReadObject(reinterpret_cast(projectileEnt)); } /*********************************************************************** @@ -534,8 +732,8 @@ void idWeapon::Restore( idRestoreGame *savefile ) { idWeapon::Clear ================ */ -void idWeapon::Clear( void ) { - CancelEvents( &EV_Weapon_Clear ); +void idWeapon::Clear(void) { + CancelEvents(&EV_Weapon_Clear); DeconstructScriptObject(); scriptObject.Free(); @@ -548,83 +746,84 @@ void idWeapon::Clear( void ) { WEAPON_RAISEWEAPON.Unlink(); WEAPON_LOWERWEAPON.Unlink(); - if ( muzzleFlashHandle != -1 ) { - gameRenderWorld->FreeLightDef( muzzleFlashHandle ); + if (muzzleFlashHandle != -1) { + gameRenderWorld->FreeLightDef(muzzleFlashHandle); muzzleFlashHandle = -1; } - if ( muzzleFlashHandle != -1 ) { - gameRenderWorld->FreeLightDef( muzzleFlashHandle ); + if (muzzleFlashHandle != -1) { + gameRenderWorld->FreeLightDef(muzzleFlashHandle); muzzleFlashHandle = -1; } - if ( worldMuzzleFlashHandle != -1 ) { - gameRenderWorld->FreeLightDef( worldMuzzleFlashHandle ); + if (worldMuzzleFlashHandle != -1) { + gameRenderWorld->FreeLightDef(worldMuzzleFlashHandle); worldMuzzleFlashHandle = -1; } - if ( guiLightHandle != -1 ) { - gameRenderWorld->FreeLightDef( guiLightHandle ); + FreeWeaponFireMuzzleLight(entityNumber); + if (guiLightHandle != -1) { + gameRenderWorld->FreeLightDef(guiLightHandle); guiLightHandle = -1; } - if ( nozzleGlowHandle != -1 ) { - gameRenderWorld->FreeLightDef( nozzleGlowHandle ); + if (nozzleGlowHandle != -1) { + gameRenderWorld->FreeLightDef(nozzleGlowHandle); nozzleGlowHandle = -1; } - memset( &renderEntity, 0, sizeof( renderEntity ) ); - renderEntity.entityNum = entityNumber; + memset(&renderEntity, 0, sizeof(renderEntity)); + renderEntity.entityNum = entityNumber; - renderEntity.noShadow = true; - renderEntity.noSelfShadow = true; - renderEntity.customSkin = NULL; + 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[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[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 ); + if (refSound.referenceSound) { + refSound.referenceSound->Free(true); } - memset( &refSound, 0, sizeof( refSound_t ) ); - + memset(&refSound, 0, sizeof(refSound_t)); + // setting diversity to 0 results in no random sound. -1 indicates random. refSound.diversity = -1.0f; - if ( owner ) { + 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_" ); + 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; + hideTime = 300; + hideDistance = -15.0f; + hideStartTime = gameLocal.time - hideTime; + hideStart = 0.0f; + hideEnd = 0.0f; + hideOffset = 0.0f; + hide = false; + disabled = false; - weaponSmoke = NULL; + weaponSmoke = NULL; weaponSmokeStartTime = 0; continuousSmoke = false; - strikeSmoke = NULL; + strikeSmoke = NULL; strikeSmokeStartTime = 0; strikePos.Zero(); strikeAxis = mat3_identity; nextStrikeFx = 0; - icon = ""; + icon = ""; playerViewAxis.Identity(); playerViewOrigin.Zero(); @@ -634,73 +833,73 @@ void idWeapon::Clear( void ) { muzzleOrigin.Zero(); pushVelocity.Zero(); - status = WP_HOLSTERED; - state = ""; - idealState = ""; - animBlendFrames = 0; - animDoneTime = 0; + status = WP_HOLSTERED; + state = ""; + idealState = ""; + animBlendFrames = 0; + animDoneTime = 0; projectileDict.Clear(); - meleeDef = NULL; - meleeDefName = ""; - meleeDistance = 0.0f; + meleeDef = NULL; + meleeDefName = ""; + meleeDistance = 0.0f; brassDict.Clear(); - flashTime = 250; - lightOn = false; - silent_fire = false; + flashTime = 250; + lightOn = false; + silent_fire = false; - ammoType = 0; - ammoRequired = 0; - ammoClip = 0; - clipSize = 0; - lowAmmo = 0; - powerAmmo = false; + ammoType = 0; + ammoRequired = 0; + ammoClip = 0; + clipSize = 0; + lowAmmo = 0; + powerAmmo = false; - kick_endtime = 0; - muzzle_kick_time = 0; - muzzle_kick_maxtime = 0; + 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; + barrelJointView = INVALID_JOINT; + flashJointView = INVALID_JOINT; + ejectJointView = INVALID_JOINT; + guiLightJointView = INVALID_JOINT; + ventLightJointView = INVALID_JOINT; - barrelJointWorld = INVALID_JOINT; - flashJointWorld = INVALID_JOINT; - ejectJointWorld = INVALID_JOINT; + barrelJointWorld = INVALID_JOINT; + flashJointWorld = INVALID_JOINT; + ejectJointWorld = INVALID_JOINT; - hasBloodSplat = false; - nozzleFx = false; - nozzleFxFade = 1500; - lastAttack = 0; - nozzleGlowHandle = -1; - nozzleGlowShader = NULL; - nozzleGlowRadius = 10; + 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; + weaponAngleOffsetAverages = 0; + weaponAngleOffsetScale = 0.0f; + weaponAngleOffsetMax = 0.0f; + weaponOffsetTime = 0.0f; + weaponOffsetScale = 0.0f; - allowDrop = true; + allowDrop = true; - animator.ClearAllAnims( gameLocal.time, 0 ); + animator.ClearAllAnims(gameLocal.time, 0); FreeModelDef(); - sndHum = NULL; + sndHum = NULL; - isLinked = false; - projectileEnt = NULL; + isLinked = false; + projectileEnt = NULL; - isFiring = false; + isFiring = false; } /* @@ -708,45 +907,46 @@ void idWeapon::Clear( void ) { idWeapon::InitWorldModel ================ */ -void idWeapon::InitWorldModel( const idDeclEntityDef *def ) { - idEntity *ent; +void idWeapon::InitWorldModel(const idDeclEntityDef* def) { + idEntity* ent; ent = worldModel.GetEntity(); - assert( ent ); - assert( def ); + assert(ent); + assert(def); - const char *model = def->dict.GetString( "model_world" ); - const char *attach = def->dict.GetString( "joint_attach" ); + 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->SetSkin(NULL); + if (model[0] && attach[0]) { ent->Show(); - ent->SetModel( model ); - if ( ent->GetAnimator()->ModelDef() ) { - ent->SetSkin( ent->GetAnimator()->ModelDef()->GetDefaultSkin() ); + 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 ); + 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 ) { - worldModelRenderEntity->suppressSurfaceInViewID = owner->entityNumber+1; - worldModelRenderEntity->suppressShadowInViewID = owner->entityNumber+1; + renderEntity_t* worldModelRenderEntity = ent->GetRenderEntity(); + if (worldModelRenderEntity) { + worldModelRenderEntity->suppressSurfaceInViewID = owner->entityNumber + 1; + worldModelRenderEntity->suppressShadowInViewID = owner->entityNumber + 1; worldModelRenderEntity->suppressShadowInLightID = LIGHTID_VIEW_MUZZLE_FLASH + owner->entityNumber; } - } else { - ent->SetModel( "" ); + } + else { + ent->SetModel(""); ent->Hide(); } - flashJointWorld = ent->GetAnimator()->GetJointHandle( "flash" ); - barrelJointWorld = ent->GetAnimator()->GetJointHandle( "muzzle" ); - ejectJointWorld = ent->GetAnimator()->GetJointHandle( "eject" ); + flashJointWorld = ent->GetAnimator()->GetJointHandle("flash"); + barrelJointWorld = ent->GetAnimator()->GetJointHandle("muzzle"); + ejectJointWorld = ent->GetAnimator()->GetJointHandle("eject"); } /* @@ -754,57 +954,59 @@ void idWeapon::InitWorldModel( const idDeclEntityDef *def ) { 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; +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 ] ) { + if (!objectname || !objectname[0]) { return; } - assert( owner ); + assert(owner); - weaponDef = gameLocal.FindEntityDef( objectname ); + 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" ); + 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" ); + 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" ); + 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" ); + 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( declManager->FindType( DECL_PARTICLE, smokeName ) ); - } else { + smokeName = weaponDef->dict.GetString("smoke_muzzle"); + if (*smokeName != '\0') { + weaponSmoke = static_cast(declManager->FindType(DECL_PARTICLE, smokeName)); + } + else { weaponSmoke = NULL; } - continuousSmoke = weaponDef->dict.GetBool( "continuousSmoke" ); - weaponSmokeStartTime = ( continuousSmoke ) ? gameLocal.time : 0; + continuousSmoke = weaponDef->dict.GetBool("continuousSmoke"); + weaponSmokeStartTime = (continuousSmoke) ? gameLocal.time : 0; - smokeName = weaponDef->dict.GetString( "smoke_strike" ); - if ( *smokeName != '\0' ) { - strikeSmoke = static_cast( declManager->FindType( DECL_PARTICLE, smokeName ) ); - } else { + smokeName = weaponDef->dict.GetString("smoke_strike"); + if (*smokeName != '\0') { + strikeSmoke = static_cast(declManager->FindType(DECL_PARTICLE, smokeName)); + } + else { strikeSmoke = NULL; } strikeSmokeStartTime = 0; @@ -813,190 +1015,193 @@ void idWeapon::GetWeaponDef( const char *objectname, int ammoinclip ) { nextStrikeFx = 0; // setup gui light - memset( &guiLight, 0, sizeof( guiLight ) ); - const char *guiLightShader = weaponDef->dict.GetString( "mtr_guiLightShader" ); - if ( *guiLightShader != '\0' ) { - guiLight.shader = declManager->FindMaterial( guiLightShader, false ); + memset(&guiLight, 0, sizeof(guiLight)); + const char* guiLightShader = weaponDef->dict.GetString("mtr_guiLightShader"); + if (*guiLightShader != '\0') { + guiLight.shader = declManager->FindMaterial(guiLightShader, false); guiLight.lightRadius[0] = guiLight.lightRadius[1] = guiLight.lightRadius[2] = 3; guiLight.pointLight = true; } // setup the view model - vmodel = weaponDef->dict.GetString( "model_view" ); - SetModel( vmodel ); + vmodel = weaponDef->dict.GetString("model_view"); + SetModel(vmodel); // setup the world model - InitWorldModel( weaponDef ); + InitWorldModel(weaponDef); // 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 ); + const idKeyValue* kv = weaponDef->dict.MatchPrefix("snd_"); + while (kv) { + spawnArgs.Set(kv->GetKey(), kv->GetValue()); + kv = weaponDef->dict.MatchPrefix("snd_", kv); } // 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" ); + barrelJointView = animator.GetJointHandle("barrel"); + flashJointView = animator.GetJointHandle("flash"); + ejectJointView = animator.GetJointHandle("eject"); + guiLightJointView = animator.GetJointHandle("guiLight"); + ventLightJointView = animator.GetJointHandle("ventLight"); // 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 { + 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; + 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" ); + 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 ) ); + memset(&muzzleFlash, 0, sizeof(muzzleFlash)); muzzleFlash.lightId = LIGHTID_VIEW_MUZZLE_FLASH + owner->entityNumber; - muzzleFlash.allowLightInViewID = owner->entityNumber+1; + muzzleFlash.allowLightInViewID = owner->entityNumber + 1; // the weapon lights will only be in first person - guiLight.allowLightInViewID = owner->entityNumber+1; - nozzleGlow.allowLightInViewID = owner->entityNumber+1; + 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.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; + 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; + 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.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 ); + 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() ); + 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" ); + 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 { + 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 ); + if ((ammoType < 0) || (ammoType >= AMMO_NUMTYPES)) { + gameLocal.Warning("Unknown ammotype in object '%s'", objectname); } ammoClip = ammoinclip; - if ( ( ammoClip < 0 ) || ( ammoClip > clipSize ) ) { + 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 ) { + 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 ); + renderEntity.gui[0] = NULL; + guiName = weaponDef->dict.GetString("gui"); + if (guiName[0]) { + renderEntity.gui[0] = uiManager->FindGui(guiName, true, false, true); } - zoomFov = weaponDef->dict.GetInt( "zoomFov", "70" ); - berserk = weaponDef->dict.GetInt( "berserk", "2" ); + 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" ); + 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" ); + 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 ); + 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 ); + 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" ); - WEAPON_NETFIRING.LinkTo( scriptObject, "WEAPON_NETFIRING" ); - WEAPON_RAISEWEAPON.LinkTo( scriptObject, "WEAPON_RAISEWEAPON" ); - WEAPON_LOWERWEAPON.LinkTo( scriptObject, "WEAPON_LOWERWEAPON" ); + WEAPON_ATTACK.LinkTo(scriptObject, "WEAPON_ATTACK"); + WEAPON_RELOAD.LinkTo(scriptObject, "WEAPON_RELOAD"); + WEAPON_NETRELOAD.LinkTo(scriptObject, "WEAPON_NETRELOAD"); + WEAPON_NETENDRELOAD.LinkTo(scriptObject, "WEAPON_NETENDRELOAD"); + WEAPON_NETFIRING.LinkTo(scriptObject, "WEAPON_NETFIRING"); + WEAPON_RAISEWEAPON.LinkTo(scriptObject, "WEAPON_RAISEWEAPON"); + WEAPON_LOWERWEAPON.LinkTo(scriptObject, "WEAPON_LOWERWEAPON"); spawnArgs = weaponDef->dict; - shader = spawnArgs.GetString( "snd_hum" ); - if ( shader && *shader ) { - sndHum = declManager->FindSound( shader ); - StartSoundShader( sndHum, SND_CHANNEL_BODY, 0, false, NULL ); + shader = spawnArgs.GetString("snd_hum"); + if (shader && *shader) { + sndHum = declManager->FindSound(shader); + StartSoundShader(sndHum, SND_CHANNEL_BODY, 0, false, NULL); } isLinked = true; @@ -1019,7 +1224,7 @@ void idWeapon::GetWeaponDef( const char *objectname, int ammoinclip ) { idWeapon::Icon ================ */ -const char *idWeapon::Icon( void ) const { +const char* idWeapon::Icon(void) const { return icon; } @@ -1028,28 +1233,29 @@ const char *idWeapon::Icon( void ) const { idWeapon::UpdateGUI ================ */ -void idWeapon::UpdateGUI( void ) { - if ( !renderEntity.gui[ 0 ] ) { - return; - } - - if ( status == WP_HOLSTERED ) { +void idWeapon::UpdateGUI(void) { + if (!renderEntity.gui[0]) { return; } - if ( owner->weaponGone ) { + 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 (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 ) { + if (gameLocal.localClientNum >= 0 && gameLocal.entities[gameLocal.localClientNum] && gameLocal.entities[gameLocal.localClientNum]->IsType(idPlayer::Type)) { + idPlayer* p = static_cast(gameLocal.entities[gameLocal.localClientNum]); + if (!p->spectating || p->spectator != owner->entityNumber) { return; } - } else { + } + else { return; } } @@ -1057,19 +1263,20 @@ void idWeapon::UpdateGUI( void ) { int inclip = AmmoInClip(); int ammoamount = AmmoAvailable(); - if ( ammoamount < 0 ) { + 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]->SetStateString("player_ammo", ""); } - 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 ) ); + 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)); } /*********************************************************************** @@ -1083,20 +1290,20 @@ void idWeapon::UpdateGUI( void ) { idWeapon::UpdateFlashPosition ================ */ -void idWeapon::UpdateFlashPosition( void ) { +void idWeapon::UpdateFlashPosition(void) { // the flash has an explicit joint for locating it - GetGlobalJointTransform( true, flashJointView, muzzleFlash.origin, muzzleFlash.axis ); + GetGlobalJointTransform(true, flashJointView, muzzleFlash.origin, muzzleFlash.axis); // 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 ); + 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; // put the world muzzle flash on the end of the joint, no matter what - GetGlobalJointTransform( false, flashJointWorld, worldMuzzleFlash.origin, worldMuzzleFlash.axis ); + GetGlobalJointTransform(false, flashJointWorld, worldMuzzleFlash.origin, worldMuzzleFlash.axis); } /* @@ -1104,34 +1311,35 @@ void idWeapon::UpdateFlashPosition( void ) { idWeapon::MuzzleFlashLight ================ */ -void idWeapon::MuzzleFlashLight( void ) { - - if ( !lightOn && ( !g_muzzleFlash.GetBool() || !muzzleFlash.lightRadius[0] ) ) { +void idWeapon::MuzzleFlashLight(void) { + + if (!lightOn && (!g_muzzleFlash.GetBool() || !muzzleFlash.lightRadius[0])) { return; } - if ( flashJointView == INVALID_JOINT ) { + 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 ]; + 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 ]; + 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 ); + if (muzzleFlashHandle != -1) { + gameRenderWorld->UpdateLightDef(muzzleFlashHandle, &muzzleFlash); + gameRenderWorld->UpdateLightDef(worldMuzzleFlashHandle, &worldMuzzleFlash); + } + else { + muzzleFlashHandle = gameRenderWorld->AddLightDef(&muzzleFlash); + worldMuzzleFlashHandle = gameRenderWorld->AddLightDef(&worldMuzzleFlash); } } @@ -1140,21 +1348,21 @@ void idWeapon::MuzzleFlashLight( void ) { idWeapon::UpdateSkin ================ */ -bool idWeapon::UpdateSkin( void ) { - const function_t *func; +bool idWeapon::UpdateSkin(void) { + const function_t* func; - if ( !isLinked ) { + if (!isLinked) { return false; } - func = scriptObject.GetFunction( "UpdateSkin" ); - if ( !func ) { - common->Warning( "Can't find function 'UpdateSkin' in object '%s'", scriptObject.GetTypeName() ); + 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->CallFunction(this, func, true); gameLocal.frameCommandThread->Execute(); return true; @@ -1165,18 +1373,19 @@ bool idWeapon::UpdateSkin( void ) { idWeapon::SetModel ================ */ -void idWeapon::SetModel( const char *modelname ) { - assert( modelname ); +void idWeapon::SetModel(const char* modelname) { + assert(modelname); - if ( modelDefHandle >= 0 ) { - gameRenderWorld->RemoveDecals( modelDefHandle ); + if (modelDefHandle >= 0) { + gameRenderWorld->RemoveDecals(modelDefHandle); } - renderEntity.hModel = animator.SetModel( modelname ); - if ( renderEntity.hModel ) { + renderEntity.hModel = animator.SetModel(modelname); + if (renderEntity.hModel) { renderEntity.customSkin = animator.ModelDef()->GetDefaultSkin(); - animator.GetJoints( &renderEntity.numJoints, &renderEntity.joints ); - } else { + animator.GetJoints(&renderEntity.numJoints, &renderEntity.joints); + } + else { renderEntity.customSkin = NULL; renderEntity.callback = NULL; renderEntity.numJoints = 0; @@ -1194,17 +1403,18 @@ 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 ) { +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 ) ) { + if (animator.GetJointTransform(jointHandle, gameLocal.time, offset, axis)) { offset = offset * viewWeaponAxis + viewWeaponOrigin; axis = axis * viewWeaponAxis; return true; } - } else { + } + else { // world model - if ( worldModel.GetEntity() && worldModel.GetEntity()->GetAnimator()->GetJointTransform( jointHandle, gameLocal.time, offset, axis ) ) { + 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; @@ -1220,7 +1430,7 @@ bool idWeapon::GetGlobalJointTransform( bool viewModel, const jointHandle_t join idWeapon::SetPushVelocity ================ */ -void idWeapon::SetPushVelocity( const idVec3 &pushVelocity ) { +void idWeapon::SetPushVelocity(const idVec3& pushVelocity) { this->pushVelocity = pushVelocity; } @@ -1236,7 +1446,7 @@ void idWeapon::SetPushVelocity( const idVec3 &pushVelocity ) { idWeapon::Think ================ */ -void idWeapon::Think( void ) { +void idWeapon::Think(void) { // do nothing because the present is called from the player through PresentWeapon } @@ -1245,8 +1455,8 @@ void idWeapon::Think( void ) { idWeapon::Raise ================ */ -void idWeapon::Raise( void ) { - if ( isLinked ) { +void idWeapon::Raise(void) { + if (isLinked) { WEAPON_RAISEWEAPON = true; } } @@ -1256,9 +1466,9 @@ void idWeapon::Raise( void ) { idWeapon::PutAway ================ */ -void idWeapon::PutAway( void ) { +void idWeapon::PutAway(void) { hasBloodSplat = false; - if ( isLinked ) { + if (isLinked) { WEAPON_LOWERWEAPON = true; } } @@ -1269,8 +1479,8 @@ idWeapon::Reload NOTE: this is only for impulse-triggered reload, auto reload is scripted ================ */ -void idWeapon::Reload( void ) { - if ( isLinked ) { +void idWeapon::Reload(void) { + if (isLinked) { WEAPON_RELOAD = true; } } @@ -1280,13 +1490,14 @@ void idWeapon::Reload( void ) { idWeapon::LowerWeapon ================ */ -void idWeapon::LowerWeapon( void ) { - if ( !hide ) { - hideStart = 0.0f; - hideEnd = hideDistance; - if ( gameLocal.time - hideStartTime < hideTime ) { - hideStartTime = gameLocal.time - ( hideTime - ( gameLocal.time - hideStartTime ) ); - } else { +void idWeapon::LowerWeapon(void) { + if (!hide) { + hideStart = 0.0f; + hideEnd = hideDistance; + if (gameLocal.time - hideStartTime < hideTime) { + hideStartTime = gameLocal.time - (hideTime - (gameLocal.time - hideStartTime)); + } + else { hideStartTime = gameLocal.time; } hide = true; @@ -1298,15 +1509,16 @@ void idWeapon::LowerWeapon( void ) { idWeapon::RaiseWeapon ================ */ -void idWeapon::RaiseWeapon( void ) { +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 { + 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; @@ -1318,12 +1530,13 @@ void idWeapon::RaiseWeapon( void ) { idWeapon::HideWeapon ================ */ -void idWeapon::HideWeapon( void ) { +void idWeapon::HideWeapon(void) { Hide(); - if ( worldModel.GetEntity() ) { + if (worldModel.GetEntity()) { worldModel.GetEntity()->Hide(); } muzzleFlashEnd = 0; + FreeWeaponFireMuzzleLight(entityNumber); } /* @@ -1331,12 +1544,12 @@ void idWeapon::HideWeapon( void ) { idWeapon::ShowWeapon ================ */ -void idWeapon::ShowWeapon( void ) { +void idWeapon::ShowWeapon(void) { Show(); - if ( worldModel.GetEntity() ) { + if (worldModel.GetEntity()) { worldModel.GetEntity()->Show(); } - if ( lightOn ) { + if (lightOn) { MuzzleFlashLight(); } } @@ -1346,8 +1559,8 @@ void idWeapon::ShowWeapon( void ) { idWeapon::HideWorldModel ================ */ -void idWeapon::HideWorldModel( void ) { - if ( worldModel.GetEntity() ) { +void idWeapon::HideWorldModel(void) { + if (worldModel.GetEntity()) { worldModel.GetEntity()->Hide(); } } @@ -1357,8 +1570,8 @@ void idWeapon::HideWorldModel( void ) { idWeapon::ShowWorldModel ================ */ -void idWeapon::ShowWorldModel( void ) { - if ( worldModel.GetEntity() ) { +void idWeapon::ShowWorldModel(void) { + if (worldModel.GetEntity()) { worldModel.GetEntity()->Show(); } } @@ -1368,20 +1581,20 @@ void idWeapon::ShowWorldModel( void ) { idWeapon::OwnerDied ================ */ -void idWeapon::OwnerDied( void ) { - if ( isLinked ) { - SetState( "OwnerDied", 0 ); +void idWeapon::OwnerDied(void) { + if (isLinked) { + SetState("OwnerDied", 0); thread->Execute(); } Hide(); - if ( worldModel.GetEntity() ) { + 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 ); + PostEventMS(&EV_Weapon_Clear, 0); } /* @@ -1389,18 +1602,18 @@ void idWeapon::OwnerDied( void ) { idWeapon::BeginAttack ================ */ -void idWeapon::BeginAttack( void ) { - if ( status != WP_OUTOFAMMO ) { +void idWeapon::BeginAttack(void) { + if (status != WP_OUTOFAMMO) { lastAttack = gameLocal.time; } - if ( !isLinked ) { + if (!isLinked) { return; } - if ( !WEAPON_ATTACK ) { - if ( sndHum ) { - StopSound( SND_CHANNEL_BODY, false ); + if (!WEAPON_ATTACK) { + if (sndHum) { + StopSound(SND_CHANNEL_BODY, false); } } WEAPON_ATTACK = true; @@ -1411,14 +1624,14 @@ void idWeapon::BeginAttack( void ) { idWeapon::EndAttack ================ */ -void idWeapon::EndAttack( void ) { - if ( !WEAPON_ATTACK.IsLinked() ) { +void idWeapon::EndAttack(void) { + if (!WEAPON_ATTACK.IsLinked()) { return; } - if ( WEAPON_ATTACK ) { + if (WEAPON_ATTACK) { WEAPON_ATTACK = false; - if ( sndHum ) { - StartSoundShader( sndHum, SND_CHANNEL_BODY, 0, false, NULL ); + if (sndHum) { + StartSoundShader(sndHum, SND_CHANNEL_BODY, 0, false, NULL); } } } @@ -1428,8 +1641,8 @@ void idWeapon::EndAttack( void ) { idWeapon::isReady ================ */ -bool idWeapon::IsReady( void ) const { - return !hide && !IsHidden() && ( ( status == WP_RELOAD ) || ( status == WP_READY ) || ( status == WP_OUTOFAMMO ) ); +bool idWeapon::IsReady(void) const { + return !hide && !IsHidden() && ((status == WP_RELOAD) || (status == WP_READY) || (status == WP_OUTOFAMMO)); } /* @@ -1437,8 +1650,8 @@ bool idWeapon::IsReady( void ) const { idWeapon::IsReloading ================ */ -bool idWeapon::IsReloading( void ) const { - return ( status == WP_RELOAD ); +bool idWeapon::IsReloading(void) const { + return (status == WP_RELOAD); } /* @@ -1446,8 +1659,8 @@ bool idWeapon::IsReloading( void ) const { idWeapon::IsHolstered ================ */ -bool idWeapon::IsHolstered( void ) const { - return ( status == WP_HOLSTERED ); +bool idWeapon::IsHolstered(void) const { + return (status == WP_HOLSTERED); } /* @@ -1455,8 +1668,8 @@ bool idWeapon::IsHolstered( void ) const { idWeapon::ShowCrosshair ================ */ -bool idWeapon::ShowCrosshair( void ) const { - return !( state == idStr( WP_RISING ) || state == idStr( WP_LOWERING ) || state == idStr( WP_HOLSTERED ) ); +bool idWeapon::ShowCrosshair(void) const { + return !(state == idStr(WP_RISING) || state == idStr(WP_LOWERING) || state == idStr(WP_HOLSTERED)); } /* @@ -1464,12 +1677,12 @@ bool idWeapon::ShowCrosshair( void ) const { idWeapon::CanDrop ===================== */ -bool idWeapon::CanDrop( void ) const { - if ( !weaponDef || !worldModel.GetEntity() ) { +bool idWeapon::CanDrop(void) const { + if (!weaponDef || !worldModel.GetEntity()) { return false; } - const char *classname = weaponDef->dict.GetString( "def_dropItem" ); - if ( !classname[ 0 ] ) { + const char* classname = weaponDef->dict.GetString("def_dropItem"); + if (!classname[0]) { return false; } return true; @@ -1480,11 +1693,11 @@ bool idWeapon::CanDrop( void ) const { idWeapon::WeaponStolen ================ */ -void idWeapon::WeaponStolen( void ) { - assert( !gameLocal.isClient ); - if ( projectileEnt ) { - if ( isLinked ) { - SetState( "WeaponStolen", 0 ); +void idWeapon::WeaponStolen(void) { + assert(!gameLocal.isClient); + if (projectileEnt) { + if (isLinked) { + SetState("WeaponStolen", 0); thread->Execute(); } projectileEnt = NULL; @@ -1501,21 +1714,21 @@ void idWeapon::WeaponStolen( void ) { idWeapon::DropItem ===================== */ -idEntity * idWeapon::DropItem( const idVec3 &velocity, int activateDelay, int removeDelay, bool died ) { - if ( !weaponDef || !worldModel.GetEntity() ) { +idEntity* idWeapon::DropItem(const idVec3& velocity, int activateDelay, int removeDelay, bool died) { + if (!weaponDef || !worldModel.GetEntity()) { return NULL; } - if ( !allowDrop ) { + if (!allowDrop) { return NULL; } - const char *classname = weaponDef->dict.GetString( "def_dropItem" ); - if ( !classname[0] ) { + const char* classname = weaponDef->dict.GetString("def_dropItem"); + if (!classname[0]) { return NULL; } - StopSound( SND_CHANNEL_BODY, true ); - StopSound( SND_CHANNEL_BODY3, true ); + 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 ); + return idMoveableItem::DropItem(classname, worldModel.GetEntity()->GetPhysics()->GetOrigin(), worldModel.GetEntity()->GetPhysics()->GetAxis(), velocity, activateDelay, removeDelay); } /*********************************************************************** @@ -1529,25 +1742,25 @@ idEntity * idWeapon::DropItem( const idVec3 &velocity, int activateDelay, int re idWeapon::SetState ===================== */ -void idWeapon::SetState( const char *statename, int blendFrames ) { - const function_t *func; +void idWeapon::SetState(const char* statename, int blendFrames) { + const function_t* func; - if ( !isLinked ) { + if (!isLinked) { return; } - func = scriptObject.GetFunction( statename ); - if ( !func ) { - assert( 0 ); - gameLocal.Error( "Can't find function '%s' in object '%s'", statename, scriptObject.GetTypeName() ); + 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 ); + thread->CallFunction(this, func, true); state = statename; animBlendFrames = blendFrames; - if ( g_debugWeapon.GetBool() ) { - gameLocal.Printf( "%d: weapon state : %s\n", gameLocal.time, statename ); + if (g_debugWeapon.GetBool()) { + gameLocal.Printf("%d: weapon state : %s\n", gameLocal.time, statename); } idealState = ""; @@ -1565,8 +1778,8 @@ void idWeapon::SetState( const char *statename, int blendFrames ) { idWeapon::UpdateNozzelFx ================ */ -void idWeapon::UpdateNozzleFx( void ) { - if ( !nozzleFx ) { +void idWeapon::UpdateNozzleFx(void) { + if (!nozzleFx) { return; } @@ -1576,24 +1789,24 @@ void idWeapon::UpdateNozzleFx( void ) { int la = gameLocal.time - lastAttack + 1; float s = 1.0f; float l = 0.0f; - if ( la < nozzleFxFade ) { + if (la < nozzleFxFade) { s = ((float)la / nozzleFxFade); l = 1.0f - s; } renderEntity.shaderParms[5] = s; renderEntity.shaderParms[6] = l; - if ( ventLightJointView == INVALID_JOINT ) { + if (ventLightJointView == INVALID_JOINT) { return; } // // vent light // - if ( nozzleGlowHandle == -1 ) { + if (nozzleGlowHandle == -1) { memset(&nozzleGlow, 0, sizeof(nozzleGlow)); - if ( owner ) { - nozzleGlow.allowLightInViewID = owner->entityNumber+1; + if (owner) { + nozzleGlow.allowLightInViewID = owner->entityNumber + 1; } nozzleGlow.pointLight = true; nozzleGlow.noShadows = true; @@ -1601,17 +1814,17 @@ void idWeapon::UpdateNozzleFx( void ) { 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 ); + 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 ); + 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; + 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); } @@ -1621,22 +1834,22 @@ void idWeapon::UpdateNozzleFx( void ) { idWeapon::BloodSplat ================ */ -bool idWeapon::BloodSplat( float size ) { +bool idWeapon::BloodSplat(float size) { float s, c; idMat3 localAxis, axistemp; idVec3 localOrigin, normal; - if ( hasBloodSplat ) { + if (hasBloodSplat) { return true; } hasBloodSplat = true; - if ( modelDefHandle < 0 ) { + if (modelDefHandle < 0) { return false; } - if ( !GetGlobalJointTransform( true, ejectJointView, localOrigin, localAxis ) ) { + if (!GetGlobalJointTransform(true, ejectJointView, localOrigin, localAxis)) { return false; } @@ -1644,15 +1857,15 @@ bool idWeapon::BloodSplat( float size ) { localOrigin[1] += gameLocal.random.RandomFloat() * 1.0f; localOrigin[2] += gameLocal.random.RandomFloat() * -2.0f; - normal = idVec3( gameLocal.random.CRandomFloat(), -gameLocal.random.RandomFloat(), -1 ); + normal = idVec3(gameLocal.random.CRandomFloat(), -gameLocal.random.RandomFloat(), -1); normal.Normalize(); - idMath::SinCos16( gameLocal.random.RandomFloat() * idMath::TWO_PI, s, c ); + 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[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; @@ -1665,9 +1878,9 @@ bool idWeapon::BloodSplat( float size ) { localPlane[1] = localAxis[1]; localPlane[1][3] = -(localOrigin * localAxis[1]) + 0.5f; - const idMaterial *mtr = declManager->FindMaterial( "textures/decals/duffysplatgun" ); + const idMaterial* mtr = declManager->FindMaterial("textures/decals/duffysplatgun"); - gameRenderWorld->ProjectOverlay( modelDefHandle, localPlane, mtr ); + gameRenderWorld->ProjectOverlay(modelDefHandle, localPlane, mtr); return true; } @@ -1686,28 +1899,28 @@ idWeapon::MuzzleRise The machinegun and chaingun will incrementally back up as they are being fired ================ */ -void idWeapon::MuzzleRise( idVec3 &origin, idMat3 &axis ) { +void idWeapon::MuzzleRise(idVec3& origin, idMat3& axis) { int time; float amount; idAngles ang; idVec3 offset; time = kick_endtime - gameLocal.time; - if ( time <= 0 ) { + if (time <= 0) { return; } - if ( muzzle_kick_maxtime <= 0 ) { + if (muzzle_kick_maxtime <= 0) { return; } - if ( time > muzzle_kick_maxtime ) { + 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; + + 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; @@ -1721,20 +1934,20 @@ 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; +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() ); + 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->CallFunction(this, constructor, true); thread->Execute(); return thread; @@ -1749,15 +1962,15 @@ 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; +void idWeapon::DeconstructScriptObject(void) { + const function_t* destructor; - if ( !thread ) { + if (!thread) { return; } - + // don't bother calling the script object's destructor on map shutdown - if ( gameLocal.GameState() == GAMESTATE_SHUTDOWN ) { + if (gameLocal.GameState() == GAMESTATE_SHUTDOWN) { return; } @@ -1765,9 +1978,9 @@ void idWeapon::DeconstructScriptObject( void ) { // call script object's destructor destructor = scriptObject.GetDestructor(); - if ( destructor ) { + if (destructor) { // start a thread that will run immediately and end - thread->CallFunction( this, destructor, true ); + thread->CallFunction(this, destructor, true); thread->Execute(); thread->EndThread(); } @@ -1781,28 +1994,28 @@ void idWeapon::DeconstructScriptObject( void ) { idWeapon::UpdateScript ================ */ -void idWeapon::UpdateScript( void ) { +void idWeapon::UpdateScript(void) { int count; - if ( !isLinked ) { + if (!isLinked) { return; } // only update the script on new frames - if ( !gameLocal.isNewFrame ) { + if (!gameLocal.isNewFrame) { return; } - if ( idealState.Length() ) { - SetState( idealState, animBlendFrames ); + 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-- ) { + while ((thread->Execute() || idealState.Length()) && count--) { // happens for weapons with no clip (like grenades) - if ( idealState.Length() ) { - SetState( idealState, animBlendFrames ); + if (idealState.Length()) { + SetState(idealState, animBlendFrames); } } @@ -1814,43 +2027,45 @@ void idWeapon::UpdateScript( void ) { idWeapon::AlertMonsters ================ */ -void idWeapon::AlertMonsters( void ) { +void idWeapon::AlertMonsters(void) { trace_t tr; - idEntity *ent; + 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 ); + 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( ent )->TouchedByFlashlight( owner ); - } else if ( ent->IsType( idTrigger::Type ) ) { - ent->Signal( SIG_TOUCH ); - ent->ProcessEvent( &EV_Touch, owner, &tr ); + if (tr.fraction < 1.0f) { + ent = gameLocal.GetTraceEntity(tr); + if (ent->IsType(idAI::Type)) { + static_cast(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 ); + 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( ent )->TouchedByFlashlight( owner ); - } else if ( ent->IsType( idTrigger::Type ) ) { - ent->Signal( SIG_TOUCH ); - ent->ProcessEvent( &EV_Touch, owner, &tr ); + if (tr.fraction < 1.0f) { + ent = gameLocal.GetTraceEntity(tr); + if (ent->IsType(idAI::Type)) { + static_cast(ent)->TouchedByFlashlight(owner); + } + else if (ent->IsType(idTrigger::Type)) { + ent->Signal(SIG_TOUCH); + ent->ProcessEvent(&EV_Touch, owner, &tr); } } } @@ -1860,38 +2075,40 @@ void idWeapon::AlertMonsters( void ) { idWeapon::PresentWeapon ================ */ -void idWeapon::PresentWeapon( bool showViewModel ) { +void idWeapon::PresentWeapon(bool showViewModel) { playerViewOrigin = owner->firstPersonViewOrigin; playerViewAxis = owner->firstPersonViewAxis; // calculate weapon position based on player movement bobbing - owner->CalculateViewWeaponPos( viewWeaponOrigin, viewWeaponAxis ); + owner->CalculateViewWeaponPos(viewWeaponOrigin, viewWeaponAxis); // 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 ) { - float frac = ( float )( gameLocal.time - hideStartTime ) / ( float )hideTime; - if ( hideStart < hideEnd ) { + if (gameLocal.time - hideStartTime < hideTime) { + float frac = (float)(gameLocal.time - hideStartTime) / (float)hideTime; + if (hideStart < hideEnd) { frac = 1.0f - frac; frac = 1.0f - frac * frac; - } else { + } + else { frac = frac * frac; } - hideOffset = hideStart + ( hideEnd - hideStart ) * frac; - } else { + hideOffset = hideStart + (hideEnd - hideStart) * frac; + } + else { hideOffset = hideEnd; - if ( hide && disabled ) { + if (hide && disabled) { Hide(); } } - viewWeaponOrigin += hideOffset * viewWeaponAxis[ 2 ]; + viewWeaponOrigin += hideOffset * viewWeaponAxis[2]; // kick up based on repeat firing - MuzzleRise( viewWeaponOrigin, viewWeaponAxis ); + MuzzleRise(viewWeaponOrigin, viewWeaponAxis); // set the physics position and orientation - GetPhysics()->SetOrigin( viewWeaponOrigin ); - GetPhysics()->SetAxis( viewWeaponAxis ); + GetPhysics()->SetOrigin(viewWeaponOrigin); + GetPhysics()->SetAxis(viewWeaponAxis); UpdateVisuals(); // update the weapon script @@ -1903,93 +2120,131 @@ void idWeapon::PresentWeapon( bool showViewModel ) { UpdateAnimation(); // only show the surface in player view - renderEntity.allowSurfaceInViewID = owner->entityNumber+1; + renderEntity.allowSurfaceInViewID = owner->entityNumber + 1; // crunch the depth range so it never pokes into walls this breaks the machine gun gui renderEntity.weaponDepthHack = true; // present the model - if ( showViewModel ) { + if (showViewModel) { Present(); - } else { + } + else { FreeModelDef(); } - if ( worldModel.GetEntity() && worldModel.GetEntity()->GetRenderEntity() ) { + 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 ( gameLocal.isMultiplayer || g_showPlayerShadow.GetBool() || pm_thirdPerson.GetBool() ) { - worldModel.GetEntity()->GetRenderEntity()->suppressShadowInViewID = 0; - } else { - worldModel.GetEntity()->GetRenderEntity()->suppressShadowInViewID = owner->entityNumber+1; + if (gameLocal.isMultiplayer || g_showPlayerShadow.GetBool() || pm_thirdPerson.GetBool()) { + worldModel.GetEntity()->GetRenderEntity()->suppressShadowInViewID = 0; + } + else { + worldModel.GetEntity()->GetRenderEntity()->suppressShadowInViewID = owner->entityNumber + 1; worldModel.GetEntity()->GetRenderEntity()->suppressShadowInLightID = LIGHTID_VIEW_MUZZLE_FLASH + owner->entityNumber; } } - if ( nozzleFx ) { + if (nozzleFx) { UpdateNozzleFx(); } // muzzle smoke - if ( showViewModel && !disabled && weaponSmoke && ( weaponSmokeStartTime != 0 ) ) { + if (showViewModel && !disabled && weaponSmoke && (weaponSmokeStartTime != 0)) { // use the barrel joint if available - if ( barrelJointView ) { - GetGlobalJointTransform( true, barrelJointView, muzzleOrigin, muzzleAxis ); - } else { + if (barrelJointView) { + 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; + if (!gameLocal.smokeParticles->EmitSmoke(weaponSmoke, weaponSmokeStartTime, gameLocal.random.RandomFloat(), muzzleOrigin, muzzleAxis)) { + weaponSmokeStartTime = (continuousSmoke) ? gameLocal.time : 0; } } - if ( showViewModel && strikeSmoke && strikeSmokeStartTime != 0 ) { + if (showViewModel && strikeSmoke && strikeSmokeStartTime != 0) { // spit out a particle - if ( !gameLocal.smokeParticles->EmitSmoke( strikeSmoke, strikeSmokeStartTime, gameLocal.random.RandomFloat(), strikePos, strikeAxis ) ) { + if (!gameLocal.smokeParticles->EmitSmoke(strikeSmoke, strikeSmokeStartTime, gameLocal.random.RandomFloat(), strikePos, strikeAxis)) { strikeSmokeStartTime = 0; } } - // remove the muzzle flash light when it's done - if ( ( !lightOn && ( gameLocal.time >= muzzleFlashEnd ) ) || IsHidden() ) { - if ( muzzleFlashHandle != -1 ) { - gameRenderWorld->FreeLightDef( muzzleFlashHandle ); + // Update the separate weapon-fire muzzle light. This is the actual light + // spawned by firing the gun, and it stays attached to the flash joint while + // fading out independently from the flashlight/script light. + if (IsHidden()) { + FreeWeaponFireMuzzleLight(entityNumber); + } + else { + idVec3 fireViewOrigin; + idMat3 fireViewAxis; + idVec3 fireWorldOrigin; + idMat3 fireWorldAxis; + + if (flashJointView != INVALID_JOINT && GetGlobalJointTransform(true, flashJointView, fireViewOrigin, fireViewAxis)) { + idVec3 fireStart = fireViewOrigin - playerViewAxis[0] * 16.0f; + idVec3 fireEnd = fireViewOrigin + playerViewAxis[0] * 8.0f; + trace_t fireTr; + gameLocal.clip.TracePoint(fireTr, fireStart, fireEnd, MASK_SHOT_RENDERMODEL, owner); + fireViewOrigin = fireTr.endpos - playerViewAxis[0] * 8.0f; + + if (flashJointWorld != INVALID_JOINT && GetGlobalJointTransform(false, flashJointWorld, fireWorldOrigin, fireWorldAxis)) { + // valid world joint + } + else { + fireWorldOrigin = fireViewOrigin; + fireWorldAxis = fireViewAxis; + } + + UpdateWeaponFireMuzzleLight(entityNumber, fireViewOrigin, fireViewAxis, fireWorldOrigin, fireWorldAxis); + } + else { + FreeWeaponFireMuzzleLight(entityNumber); + } + } + + // remove the old script/flashlight muzzle 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 ); + if (worldMuzzleFlashHandle != -1) { + gameRenderWorld->FreeLightDef(worldMuzzleFlashHandle); worldMuzzleFlashHandle = -1; } } // update the muzzle flash light, so it moves with the gun - if ( muzzleFlashHandle != -1 ) { + if (muzzleFlashHandle != -1) { UpdateFlashPosition(); - gameRenderWorld->UpdateLightDef( muzzleFlashHandle, &muzzleFlash ); - gameRenderWorld->UpdateLightDef( worldMuzzleFlashHandle, &worldMuzzleFlash ); + gameRenderWorld->UpdateLightDef(muzzleFlashHandle, &muzzleFlash); + gameRenderWorld->UpdateLightDef(worldMuzzleFlashHandle, &worldMuzzleFlash); // wake up monsters with the flashlight - if ( !gameLocal.isMultiplayer && lightOn && !owner->fl.notarget ) { + if (!gameLocal.isMultiplayer && lightOn && !owner->fl.notarget) { AlertMonsters(); } } // update the gui light - if ( guiLight.lightRadius[0] && guiLightJointView != INVALID_JOINT ) { - GetGlobalJointTransform( true, guiLightJointView, guiLight.origin, guiLight.axis ); + 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 ((guiLightHandle != -1)) { + gameRenderWorld->UpdateLightDef(guiLightHandle, &guiLight); + } + else { + guiLightHandle = gameRenderWorld->AddLightDef(&guiLight); } } - if ( status != WP_READY && sndHum ) { - StopSound( SND_CHANNEL_BODY, false ); + if (status != WP_READY && sndHum) { + StopSound(SND_CHANNEL_BODY, false); } UpdateSound(); @@ -2000,20 +2255,20 @@ void idWeapon::PresentWeapon( bool showViewModel ) { idWeapon::EnterCinematic ================ */ -void idWeapon::EnterCinematic( void ) { - StopSound( SND_CHANNEL_ANY, false ); +void idWeapon::EnterCinematic(void) { + StopSound(SND_CHANNEL_ANY, false); - if ( isLinked ) { - SetState( "EnterCinematic", 0 ); + if (isLinked) { + SetState("EnterCinematic", 0); thread->Execute(); - WEAPON_ATTACK = false; - WEAPON_RELOAD = false; - WEAPON_NETRELOAD = false; - WEAPON_NETENDRELOAD = false; - WEAPON_NETFIRING = false; - WEAPON_RAISEWEAPON = false; - WEAPON_LOWERWEAPON = false; + WEAPON_ATTACK = false; + WEAPON_RELOAD = false; + WEAPON_NETRELOAD = false; + WEAPON_NETENDRELOAD = false; + WEAPON_NETFIRING = false; + WEAPON_RAISEWEAPON = false; + WEAPON_LOWERWEAPON = false; } disabled = true; @@ -2026,11 +2281,11 @@ void idWeapon::EnterCinematic( void ) { idWeapon::ExitCinematic ================ */ -void idWeapon::ExitCinematic( void ) { +void idWeapon::ExitCinematic(void) { disabled = false; - if ( isLinked ) { - SetState( "ExitCinematic", 0 ); + if (isLinked) { + SetState("ExitCinematic", 0); thread->Execute(); } @@ -2042,9 +2297,9 @@ void idWeapon::ExitCinematic( void ) { idWeapon::NetCatchup ================ */ -void idWeapon::NetCatchup( void ) { - if ( isLinked ) { - SetState( "NetCatchup", 0 ); +void idWeapon::NetCatchup(void) { + if (isLinked) { + SetState("NetCatchup", 0); thread->Execute(); } } @@ -2054,7 +2309,7 @@ void idWeapon::NetCatchup( void ) { idWeapon::GetZoomFov ================ */ -int idWeapon::GetZoomFov( void ) { +int idWeapon::GetZoomFov(void) { return zoomFov; } @@ -2063,7 +2318,7 @@ int idWeapon::GetZoomFov( void ) { idWeapon::GetWeaponAngleOffsets ================ */ -void idWeapon::GetWeaponAngleOffsets( int *average, float *scale, float *max ) { +void idWeapon::GetWeaponAngleOffsets(int* average, float* scale, float* max) { *average = weaponAngleOffsetAverages; *scale = weaponAngleOffsetScale; *max = weaponAngleOffsetMax; @@ -2074,7 +2329,7 @@ void idWeapon::GetWeaponAngleOffsets( int *average, float *scale, float *max ) { idWeapon::GetWeaponTimeOffsets ================ */ -void idWeapon::GetWeaponTimeOffsets( float *time, float *scale ) { +void idWeapon::GetWeaponTimeOffsets(float* time, float* scale) { *time = weaponOffsetTime; *scale = weaponOffsetScale; } @@ -2091,30 +2346,30 @@ void idWeapon::GetWeaponTimeOffsets( float *time, float *scale ) { idWeapon::GetAmmoNumForName ================ */ -ammo_t idWeapon::GetAmmoNumForName( const char *ammoname ) { +ammo_t idWeapon::GetAmmoNumForName(const char* ammoname) { int num; - const idDict *ammoDict; + const idDict* ammoDict; - assert( ammoname ); + assert(ammoname); - ammoDict = gameLocal.FindEntityDefDict( "ammo_types", false ); - if ( !ammoDict ) { - gameLocal.Error( "Could not find entity definition for 'ammo_types'\n" ); + ammoDict = gameLocal.FindEntityDefDict("ammo_types", false); + if (!ammoDict) { + gameLocal.Error("Could not find entity definition for 'ammo_types'\n"); } - if ( !ammoname[ 0 ] ) { + if (!ammoname[0]) { return 0; } - if ( !ammoDict->GetInt( ammoname, "-1", num ) ) { - gameLocal.Error( "Unknown ammo type '%s'", ammoname ); + 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 ); + 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; + return (ammo_t)num; } /* @@ -2122,24 +2377,24 @@ ammo_t idWeapon::GetAmmoNumForName( const char *ammoname ) { idWeapon::GetAmmoNameForNum ================ */ -const char *idWeapon::GetAmmoNameForNum( ammo_t ammonum ) { +const char* idWeapon::GetAmmoNameForNum(ammo_t ammonum) { int i; int num; - const idDict *ammoDict; - const idKeyValue *kv; - char text[ 32 ]; + 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" ); + ammoDict = gameLocal.FindEntityDefDict("ammo_types", false); + if (!ammoDict) { + gameLocal.Error("Could not find entity definition for 'ammo_types'\n"); } - sprintf( text, "%d", ammonum ); + sprintf(text, "%d", ammonum); num = ammoDict->GetNumKeyVals(); - for( i = 0; i < num; i++ ) { - kv = ammoDict->GetKeyVal( i ); - if ( kv->GetValue() == text ) { + for (i = 0; i < num; i++) { + kv = ammoDict->GetKeyVal(i); + if (kv->GetValue() == text) { return kv->GetKey(); } } @@ -2152,24 +2407,24 @@ const char *idWeapon::GetAmmoNameForNum( ammo_t ammonum ) { idWeapon::GetAmmoPickupNameForNum ================ */ -const char *idWeapon::GetAmmoPickupNameForNum( ammo_t ammonum ) { +const char* idWeapon::GetAmmoPickupNameForNum(ammo_t ammonum) { int i; int num; - const idDict *ammoDict; - const idKeyValue *kv; + 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" ); + ammoDict = gameLocal.FindEntityDefDict("ammo_names", false); + if (!ammoDict) { + gameLocal.Error("Could not find entity definition for 'ammo_names'\n"); } - const char *name = GetAmmoNameForNum( ammonum ); + const char* name = GetAmmoNameForNum(ammonum); - if ( name && *name ) { + if (name && *name) { num = ammoDict->GetNumKeyVals(); - for( i = 0; i < num; i++ ) { - kv = ammoDict->GetKeyVal( i ); - if ( idStr::Icmp( kv->GetKey(), name) == 0 ) { + for (i = 0; i < num; i++) { + kv = ammoDict->GetKeyVal(i); + if (idStr::Icmp(kv->GetKey(), name) == 0) { return kv->GetValue(); } } @@ -2183,10 +2438,11 @@ const char *idWeapon::GetAmmoPickupNameForNum( ammo_t ammonum ) { idWeapon::AmmoAvailable ================ */ -int idWeapon::AmmoAvailable( void ) const { - if ( owner ) { - return owner->inventory.HasAmmo( ammoType, ammoRequired ); - } else { +int idWeapon::AmmoAvailable(void) const { + if (owner) { + return owner->inventory.HasAmmo(ammoType, ammoRequired); + } + else { return 0; } } @@ -2196,7 +2452,7 @@ int idWeapon::AmmoAvailable( void ) const { idWeapon::AmmoInClip ================ */ -int idWeapon::AmmoInClip( void ) const { +int idWeapon::AmmoInClip(void) const { return ammoClip; } @@ -2205,7 +2461,7 @@ int idWeapon::AmmoInClip( void ) const { idWeapon::ResetAmmoClip ================ */ -void idWeapon::ResetAmmoClip( void ) { +void idWeapon::ResetAmmoClip(void) { ammoClip = -1; } @@ -2214,7 +2470,7 @@ void idWeapon::ResetAmmoClip( void ) { idWeapon::GetAmmoType ================ */ -ammo_t idWeapon::GetAmmoType( void ) const { +ammo_t idWeapon::GetAmmoType(void) const { return ammoType; } @@ -2223,7 +2479,7 @@ ammo_t idWeapon::GetAmmoType( void ) const { idWeapon::ClipSize ================ */ -int idWeapon::ClipSize( void ) const { +int idWeapon::ClipSize(void) const { return clipSize; } @@ -2241,7 +2497,7 @@ int idWeapon::LowAmmo() const { idWeapon::AmmoRequired ================ */ -int idWeapon::AmmoRequired( void ) const { +int idWeapon::AmmoRequired(void) const { return ammoRequired; } @@ -2250,11 +2506,11 @@ int idWeapon::AmmoRequired( void ) const { 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 ); +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); } /* @@ -2262,29 +2518,29 @@ void idWeapon::WriteToSnapshot( idBitMsgDelta &msg ) const { 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; +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() ) { + 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 ) { + if (!WEAPON_NETFIRING && isFiring) { idealState = "Fire"; } - // immediately switch back to idle - if ( WEAPON_NETFIRING && !isFiring ) { - idealState = "Idle"; - } + // immediately switch back to idle + if (WEAPON_NETFIRING && !isFiring) { + idealState = "Idle"; + } WEAPON_NETFIRING = isFiring; } - if ( snapLight != lightOn ) { + if (snapLight != lightOn) { Reload(); } } @@ -2294,36 +2550,36 @@ void idWeapon::ReadFromSnapshot( const idBitMsgDelta &msg ) { idWeapon::ClientReceiveEvent ================ */ -bool idWeapon::ClientReceiveEvent( int event, int time, const idBitMsg &msg ) { +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; - } + 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; + return true; + } + case EVENT_ENDRELOAD: { + if (WEAPON_NETENDRELOAD.IsLinked()) { + WEAPON_NETENDRELOAD = true; } - case EVENT_CHANGESKIN: { - int index = gameLocal.ClientRemapDecl( DECL_SKIN, msg.ReadLong() ); - renderEntity.customSkin = ( index != -1 ) ? static_cast( declManager->DeclByIndex( DECL_SKIN, index ) ) : NULL; - UpdateVisuals(); - if ( worldModel.GetEntity() ) { - worldModel.GetEntity()->SetSkin( renderEntity.customSkin ); - } - return true; - } - default: { - return idEntity::ClientReceiveEvent( event, time, msg ); + return true; + } + case EVENT_CHANGESKIN: { + int index = gameLocal.ClientRemapDecl(DECL_SKIN, msg.ReadLong()); + renderEntity.customSkin = (index != -1) ? static_cast(declManager->DeclByIndex(DECL_SKIN, index)) : NULL; + UpdateVisuals(); + if (worldModel.GetEntity()) { + worldModel.GetEntity()->SetSkin(renderEntity.customSkin); } + return true; + } + default: { + return idEntity::ClientReceiveEvent(event, time, msg); + } } return false; } @@ -2339,7 +2595,7 @@ bool idWeapon::ClientReceiveEvent( int event, int time, const idBitMsg &msg ) { idWeapon::Event_Clear =============== */ -void idWeapon::Event_Clear( void ) { +void idWeapon::Event_Clear(void) { Clear(); } @@ -2348,8 +2604,8 @@ void idWeapon::Event_Clear( void ) { idWeapon::Event_GetOwner =============== */ -void idWeapon::Event_GetOwner( void ) { - idThread::ReturnEntity( owner ); +void idWeapon::Event_GetOwner(void) { + idThread::ReturnEntity(owner); } /* @@ -2357,20 +2613,21 @@ void idWeapon::Event_GetOwner( void ) { idWeapon::Event_WeaponState =============== */ -void idWeapon::Event_WeaponState( const char *statename, int blendFrames ) { - const function_t *func; +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() ); + 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" ) ) { + if (!idealState.Icmp("Fire")) { isFiring = true; - } else { + } + else { isFiring = false; } @@ -2383,13 +2640,13 @@ void idWeapon::Event_WeaponState( const char *statename, int blendFrames ) { idWeapon::Event_WeaponReady =============== */ -void idWeapon::Event_WeaponReady( void ) { +void idWeapon::Event_WeaponReady(void) { status = WP_READY; - if ( isLinked ) { + if (isLinked) { WEAPON_RAISEWEAPON = false; } - if ( sndHum ) { - StartSoundShader( sndHum, SND_CHANNEL_BODY, 0, false, NULL ); + if (sndHum) { + StartSoundShader(sndHum, SND_CHANNEL_BODY, 0, false, NULL); } } @@ -2399,9 +2656,9 @@ void idWeapon::Event_WeaponReady( void ) { idWeapon::Event_WeaponOutOfAmmo =============== */ -void idWeapon::Event_WeaponOutOfAmmo( void ) { +void idWeapon::Event_WeaponOutOfAmmo(void) { status = WP_OUTOFAMMO; - if ( isLinked ) { + if (isLinked) { WEAPON_RAISEWEAPON = false; } } @@ -2411,7 +2668,7 @@ void idWeapon::Event_WeaponOutOfAmmo( void ) { idWeapon::Event_WeaponReloading =============== */ -void idWeapon::Event_WeaponReloading( void ) { +void idWeapon::Event_WeaponReloading(void) { status = WP_RELOAD; } @@ -2420,9 +2677,9 @@ void idWeapon::Event_WeaponReloading( void ) { idWeapon::Event_WeaponHolstered =============== */ -void idWeapon::Event_WeaponHolstered( void ) { +void idWeapon::Event_WeaponHolstered(void) { status = WP_HOLSTERED; - if ( isLinked ) { + if (isLinked) { WEAPON_LOWERWEAPON = false; } } @@ -2432,9 +2689,9 @@ void idWeapon::Event_WeaponHolstered( void ) { idWeapon::Event_WeaponRising =============== */ -void idWeapon::Event_WeaponRising( void ) { +void idWeapon::Event_WeaponRising(void) { status = WP_RISING; - if ( isLinked ) { + if (isLinked) { WEAPON_LOWERWEAPON = false; } owner->WeaponRisingCallback(); @@ -2445,9 +2702,9 @@ void idWeapon::Event_WeaponRising( void ) { idWeapon::Event_WeaponLowering =============== */ -void idWeapon::Event_WeaponLowering( void ) { +void idWeapon::Event_WeaponLowering(void) { status = WP_LOWERING; - if ( isLinked ) { + if (isLinked) { WEAPON_RAISEWEAPON = false; } owner->WeaponLoweringCallback(); @@ -2458,15 +2715,15 @@ void idWeapon::Event_WeaponLowering( void ) { idWeapon::Event_UseAmmo =============== */ -void idWeapon::Event_UseAmmo( int amount ) { - if ( gameLocal.isClient ) { +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 ) { + owner->inventory.UseAmmo(ammoType, (powerAmmo) ? amount : (amount * ammoRequired)); + if (clipSize && ammoRequired) { + ammoClip -= powerAmmo ? amount : (amount * ammoRequired); + if (ammoClip < 0) { ammoClip = 0; } } @@ -2477,20 +2734,20 @@ void idWeapon::Event_UseAmmo( int amount ) { idWeapon::Event_AddToClip =============== */ -void idWeapon::Event_AddToClip( int amount ) { +void idWeapon::Event_AddToClip(int amount) { int ammoAvail; - if ( gameLocal.isClient ) { + if (gameLocal.isClient) { return; } ammoClip += amount; - if ( ammoClip > clipSize ) { + if (ammoClip > clipSize) { ammoClip = clipSize; } - ammoAvail = owner->inventory.HasAmmo( ammoType, ammoRequired ); - if ( ammoClip > ammoAvail ) { + ammoAvail = owner->inventory.HasAmmo(ammoType, ammoRequired); + if (ammoClip > ammoAvail) { ammoClip = ammoAvail; } } @@ -2500,9 +2757,9 @@ void idWeapon::Event_AddToClip( int amount ) { idWeapon::Event_AmmoInClip =============== */ -void idWeapon::Event_AmmoInClip( void ) { +void idWeapon::Event_AmmoInClip(void) { int ammo = AmmoInClip(); - idThread::ReturnFloat( ammo ); + idThread::ReturnFloat(ammo); } /* @@ -2510,9 +2767,9 @@ void idWeapon::Event_AmmoInClip( void ) { idWeapon::Event_AmmoAvailable =============== */ -void idWeapon::Event_AmmoAvailable( void ) { - int ammoAvail = owner->inventory.HasAmmo( ammoType, ammoRequired ); - idThread::ReturnFloat( ammoAvail ); +void idWeapon::Event_AmmoAvailable(void) { + int ammoAvail = owner->inventory.HasAmmo(ammoType, ammoRequired); + idThread::ReturnFloat(ammoAvail); } /* @@ -2520,9 +2777,9 @@ void idWeapon::Event_AmmoAvailable( void ) { idWeapon::Event_TotalAmmoCount =============== */ -void idWeapon::Event_TotalAmmoCount( void ) { - int ammoAvail = owner->inventory.HasAmmo( ammoType, 1 ); - idThread::ReturnFloat( ammoAvail ); +void idWeapon::Event_TotalAmmoCount(void) { + int ammoAvail = owner->inventory.HasAmmo(ammoType, 1); + idThread::ReturnFloat(ammoAvail); } /* @@ -2530,8 +2787,8 @@ void idWeapon::Event_TotalAmmoCount( void ) { idWeapon::Event_ClipSize =============== */ -void idWeapon::Event_ClipSize( void ) { - idThread::ReturnFloat( clipSize ); +void idWeapon::Event_ClipSize(void) { + idThread::ReturnFloat(clipSize); } /* @@ -2539,13 +2796,13 @@ void idWeapon::Event_ClipSize( void ) { idWeapon::Event_AutoReload =============== */ -void idWeapon::Event_AutoReload( void ) { - assert( owner ); - if ( gameLocal.isClient ) { - idThread::ReturnFloat( 0.0f ); +void idWeapon::Event_AutoReload(void) { + assert(owner); + if (gameLocal.isClient) { + idThread::ReturnFloat(0.0f); return; } - idThread::ReturnFloat( gameLocal.userInfo[ owner->entityNumber ].GetBool( "ui_autoReload" ) ); + idThread::ReturnFloat(gameLocal.userInfo[owner->entityNumber].GetBool("ui_autoReload")); } /* @@ -2553,10 +2810,10 @@ void idWeapon::Event_AutoReload( void ) { idWeapon::Event_NetReload =============== */ -void idWeapon::Event_NetReload( void ) { - assert( owner ); - if ( gameLocal.isServer ) { - ServerSendEvent( EVENT_RELOAD, NULL, false, -1 ); +void idWeapon::Event_NetReload(void) { + assert(owner); + if (gameLocal.isServer) { + ServerSendEvent(EVENT_RELOAD, NULL, false, -1); } } @@ -2565,10 +2822,10 @@ void idWeapon::Event_NetReload( void ) { idWeapon::Event_NetEndReload =============== */ -void idWeapon::Event_NetEndReload( void ) { - assert( owner ); - if ( gameLocal.isServer ) { - ServerSendEvent( EVENT_ENDRELOAD, NULL, false, -1 ); +void idWeapon::Event_NetEndReload(void) { + assert(owner); + if (gameLocal.isServer) { + ServerSendEvent(EVENT_ENDRELOAD, NULL, false, -1); } } @@ -2577,29 +2834,30 @@ void idWeapon::Event_NetEndReload( void ) { idWeapon::Event_PlayAnim =============== */ -void idWeapon::Event_PlayAnim( int channel, const char *animname ) { +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 ) ); + + 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() ) ) { + } + 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 ) ); + 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 ); + idThread::ReturnInt(0); } /* @@ -2607,27 +2865,28 @@ void idWeapon::Event_PlayAnim( int channel, const char *animname ) { idWeapon::Event_PlayCycle =============== */ -void idWeapon::Event_PlayCycle( int channel, const char *animname ) { +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 ) ); + 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() ) ) { + } + 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 ) ); + 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 ); + idThread::ReturnInt(0); } /* @@ -2635,11 +2894,12 @@ void idWeapon::Event_PlayCycle( int channel, const char *animname ) { idWeapon::Event_AnimDone =============== */ -void idWeapon::Event_AnimDone( int channel, int blendFrames ) { - if ( animDoneTime - FRAME2MS( blendFrames ) <= gameLocal.time ) { - idThread::ReturnInt( true ); - } else { - idThread::ReturnInt( false ); +void idWeapon::Event_AnimDone(int channel, int blendFrames) { + if (animDoneTime - FRAME2MS(blendFrames) <= gameLocal.time) { + idThread::ReturnInt(true); + } + else { + idThread::ReturnInt(false); } } @@ -2648,7 +2908,7 @@ void idWeapon::Event_AnimDone( int channel, int blendFrames ) { idWeapon::Event_SetBlendFrames =============== */ -void idWeapon::Event_SetBlendFrames( int channel, int blendFrames ) { +void idWeapon::Event_SetBlendFrames(int channel, int blendFrames) { animBlendFrames = blendFrames; } @@ -2657,8 +2917,8 @@ void idWeapon::Event_SetBlendFrames( int channel, int blendFrames ) { idWeapon::Event_GetBlendFrames =============== */ -void idWeapon::Event_GetBlendFrames( int channel ) { - idThread::ReturnInt( animBlendFrames ); +void idWeapon::Event_GetBlendFrames(int channel) { + idThread::ReturnInt(animBlendFrames); } /* @@ -2666,7 +2926,7 @@ void idWeapon::Event_GetBlendFrames( int channel ) { idWeapon::Event_Next ================ */ -void idWeapon::Event_Next( void ) { +void idWeapon::Event_Next(void) { // change to another weapon if possible owner->NextBestWeapon(); } @@ -2676,29 +2936,30 @@ void idWeapon::Event_Next( void ) { idWeapon::Event_SetSkin ================ */ -void idWeapon::Event_SetSkin( const char *skinname ) { - const idDeclSkin *skinDecl; +void idWeapon::Event_SetSkin(const char* skinname) { + const idDeclSkin* skinDecl; - if ( !skinname || !skinname[ 0 ] ) { + if (!skinname || !skinname[0]) { skinDecl = NULL; - } else { - skinDecl = declManager->FindSkin( skinname ); + } + else { + skinDecl = declManager->FindSkin(skinname); } renderEntity.customSkin = skinDecl; UpdateVisuals(); - if ( worldModel.GetEntity() ) { - worldModel.GetEntity()->SetSkin( skinDecl ); + if (worldModel.GetEntity()) { + worldModel.GetEntity()->SetSkin(skinDecl); } - if ( gameLocal.isServer ) { + if (gameLocal.isServer) { idBitMsg msg; byte msgBuf[MAX_EVENT_PARAM_SIZE]; - msg.Init( msgBuf, sizeof( msgBuf ) ); - msg.WriteLong( ( skinDecl != NULL ) ? gameLocal.ServerRemapDecl( -1, DECL_SKIN, skinDecl->Index() ) : -1 ); - ServerSendEvent( EVENT_CHANGESKIN, &msg, false, -1 ); + msg.Init(msgBuf, sizeof(msgBuf)); + msg.WriteLong((skinDecl != NULL) ? gameLocal.ServerRemapDecl(-1, DECL_SKIN, skinDecl->Index()) : -1); + ServerSendEvent(EVENT_CHANGESKIN, &msg, false, -1); } } @@ -2707,11 +2968,12 @@ void idWeapon::Event_SetSkin( const char *skinname ) { idWeapon::Event_Flashlight ================ */ -void idWeapon::Event_Flashlight( int enable ) { - if ( enable ) { +void idWeapon::Event_Flashlight(int enable) { + if (enable) { lightOn = true; MuzzleFlashLight(); - } else { + } + else { lightOn = false; muzzleFlashEnd = 0; } @@ -2722,12 +2984,12 @@ void idWeapon::Event_Flashlight( int enable ) { 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 ); +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 ] ); + idThread::ReturnFloat(muzzleFlash.shaderParms[parmnum]); } /* @@ -2735,13 +2997,13 @@ void idWeapon::Event_GetLightParm( int 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 ); +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; + muzzleFlash.shaderParms[parmnum] = value; + worldMuzzleFlash.shaderParms[parmnum] = value; UpdateVisuals(); } @@ -2750,16 +3012,16 @@ void idWeapon::Event_SetLightParm( int parmnum, float value ) { 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; +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; + worldMuzzleFlash.shaderParms[SHADERPARM_RED] = parm0; + worldMuzzleFlash.shaderParms[SHADERPARM_GREEN] = parm1; + worldMuzzleFlash.shaderParms[SHADERPARM_BLUE] = parm2; + worldMuzzleFlash.shaderParms[SHADERPARM_ALPHA] = parm3; UpdateVisuals(); } @@ -2769,18 +3031,19 @@ void idWeapon::Event_SetLightParms( float parm0, float parm1, float parm2, float idWeapon::Event_CreateProjectile ================ */ -void idWeapon::Event_CreateProjectile( void ) { - if ( !gameLocal.isClient ) { +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 ); + gameLocal.SpawnEntityDef(projectileDict, &projectileEnt, false); + if (projectileEnt) { + projectileEnt->SetOrigin(GetPhysics()->GetOrigin()); + projectileEnt->Bind(owner, false); projectileEnt->Hide(); } - idThread::ReturnEntity( projectileEnt ); - } else { - idThread::ReturnEntity( NULL ); + idThread::ReturnEntity(projectileEnt); + } + else { + idThread::ReturnEntity(NULL); } } @@ -2789,9 +3052,9 @@ void idWeapon::Event_CreateProjectile( void ) { idWeapon::Event_LaunchProjectiles ================ */ -void idWeapon::Event_LaunchProjectiles( int num_projectiles, float spread, float fuseOffset, float launchPower, float dmgPower ) { - idProjectile *proj; - idEntity *ent; +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; @@ -2802,159 +3065,220 @@ void idWeapon::Event_LaunchProjectiles( int num_projectiles, float spread, float idVec3 muzzle_pos; idBounds ownerBounds, projBounds; - if ( IsHidden() ) { + if (IsHidden()) { return; } - if ( !projectileDict.GetNumKeyVals() ) { - const char *classname = weaponDef->dict.GetString( "classname" ); - gameLocal.Warning( "No projectile defined on '%s'", classname ); + 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 ) { + 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 ) ) ) { + 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 ) { + 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 = (int)dmgPower + 1; + if (dmgPower > ammoClip) { dmgPower = ammoClip; } } - owner->inventory.UseAmmo( ammoType, ( powerAmmo ) ? dmgPower : ammoRequired ); - if ( clipSize && ammoRequired ) { + owner->inventory.UseAmmo(ammoType, (powerAmmo) ? dmgPower : ammoRequired); + if (clipSize && ammoRequired) { ammoClip -= powerAmmo ? dmgPower : 1; } } - if ( !silent_fire ) { + if (!silent_fire) { // wake up nearby monsters - gameLocal.AlertAI( owner ); + 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 ); + 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 ] ); + 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 - if ( barrelJointView != INVALID_JOINT && projectileDict.GetBool( "launchFromBarrel" ) ) { + if (barrelJointView != INVALID_JOINT && projectileDict.GetBool("launchFromBarrel")) { // there is an explicit joint for the muzzle - GetGlobalJointTransform( true, barrelJointView, muzzleOrigin, muzzleAxis ); - } else { + GetGlobalJointTransform(true, barrelJointView, muzzleOrigin, muzzleAxis); + } + else { // go straight out of the view muzzleOrigin = playerViewOrigin; muzzleAxis = playerViewAxis; } // add some to the kick time, incrementally moving repeat firing weapons back - if ( kick_endtime < gameLocal.realClientTime ) { + if (kick_endtime < gameLocal.realClientTime) { kick_endtime = gameLocal.realClientTime; } kick_endtime += muzzle_kick_time; - if ( kick_endtime > gameLocal.realClientTime + muzzle_kick_maxtime ) { + if (kick_endtime > gameLocal.realClientTime + muzzle_kick_maxtime) { kick_endtime = gameLocal.realClientTime + muzzle_kick_maxtime; } - if ( gameLocal.isClient ) { + if (gameLocal.isClient) { // predict instant hit projectiles - if ( projectileDict.GetBool( "net_instanthit" ) ) { - float spreadRad = DEG2RAD( spread ); - muzzle_pos = muzzleOrigin + playerViewAxis[ 0 ] * 2.0f; - for( i = 0; i < num_projectiles; i++ ) { - ang = idMath::Sin( spreadRad * gameLocal.random.RandomFloat() ); - spin = (float)DEG2RAD( 360.0f ) * gameLocal.random.RandomFloat(); - dir = playerViewAxis[ 0 ] + playerViewAxis[ 2 ] * ( ang * idMath::Sin( spin ) ) - playerViewAxis[ 1 ] * ( ang * idMath::Cos( spin ) ); + if (projectileDict.GetBool("net_instanthit")) { + float spreadRad = DEG2RAD(spread); + muzzle_pos = muzzleOrigin + playerViewAxis[0] * 2.0f; + for (i = 0; i < num_projectiles; i++) { + ang = idMath::Sin(spreadRad * gameLocal.random.RandomFloat()); + spin = (float)DEG2RAD(360.0f) * gameLocal.random.RandomFloat(); + dir = playerViewAxis[0] + playerViewAxis[2] * (ang * idMath::Sin(spin)) - playerViewAxis[1] * (ang * idMath::Cos(spin)); 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 ); + 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 { + } + else { ownerBounds = owner->GetPhysics()->GetAbsBounds(); - owner->AddProjectilesFired( num_projectiles ); + 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 = playerViewAxis[ 0 ] + playerViewAxis[ 2 ] * ( ang * idMath::Sin( spin ) ) - playerViewAxis[ 1 ] * ( ang * idMath::Cos( spin ) ); + 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 = playerViewAxis[0] + playerViewAxis[2] * (ang * idMath::Sin(spin)) - playerViewAxis[1] * (ang * idMath::Cos(spin)); dir.Normalize(); - if ( projectileEnt ) { + if (projectileEnt) { ent = projectileEnt; ent->Show(); ent->Unbind(); projectileEnt = NULL; - } else { - gameLocal.SpawnEntityDef( projectileDict, &ent, false ); + } + 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 (!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" ) ) { + if (projectileDict.GetBool("net_instanthit")) { // don't synchronize this on top of the already predicted effect ent->fl.networkSync = false; } - proj = static_cast(ent); - proj->Create( owner, muzzleOrigin, dir ); + proj = static_cast(ent); + proj->Create(owner, muzzleOrigin, dir); - projBounds = proj->GetPhysics()->GetBounds().Rotate( proj->GetPhysics()->GetAxis() ); + projBounds = proj->GetPhysics()->GetBounds().Rotate(proj->GetPhysics()->GetAxis()); // make sure the projectile starts inside the bounding box of the owner - if ( i == 0 ) { - muzzle_pos = muzzleOrigin + playerViewAxis[ 0 ] * 2.0f; - if ( ( ownerBounds - projBounds).RayIntersection( muzzle_pos, playerViewAxis[0], distance ) ) { + if (i == 0) { + muzzle_pos = muzzleOrigin + playerViewAxis[0] * 2.0f; + if ((ownerBounds - projBounds).RayIntersection(muzzle_pos, playerViewAxis[0], distance)) { start = muzzle_pos + distance * playerViewAxis[0]; - } else { + } + else { start = ownerBounds.GetCenter(); } - gameLocal.clip.Translation( tr, start, muzzle_pos, proj->GetPhysics()->GetClipModel(), proj->GetPhysics()->GetClipModel()->GetAxis(), MASK_SHOT_RENDERMODEL, owner ); + gameLocal.clip.Translation(tr, start, muzzle_pos, proj->GetPhysics()->GetClipModel(), proj->GetPhysics()->GetClipModel()->GetAxis(), MASK_SHOT_RENDERMODEL, owner); muzzle_pos = tr.endpos; } - proj->Launch( muzzle_pos, dir, pushVelocity, fuseOffset, launchPower, dmgPower ); + proj->Launch(muzzle_pos, dir, pushVelocity, fuseOffset, launchPower, dmgPower); } // toss the brass - PostEventMS( &EV_Weapon_EjectBrass, brassDelay ); + PostEventMS(&EV_Weapon_EjectBrass, brassDelay); } - // add the light for the muzzleflash - if ( !lightOn ) { - MuzzleFlashLight(); + // Add a separate short-lived weapon-fire light. Do not use + // MuzzleFlashLight() here; that path is also used by the flashlight / script + // weapon light and it should not own normal muzzle-flash firing. + if (flashJointView != INVALID_JOINT) { + idVec3 fireViewOrigin; + idMat3 fireViewAxis; + idVec3 fireWorldOrigin; + idMat3 fireWorldAxis; + + GetGlobalJointTransform(true, flashJointView, fireViewOrigin, fireViewAxis); + + // Keep the view light on the muzzle flash joint, but back it away from + // walls the same way the old muzzle flash code did so it does not spawn + // inside opaque geometry. + idVec3 fireStart = fireViewOrigin - playerViewAxis[0] * 16.0f; + idVec3 fireEnd = fireViewOrigin + playerViewAxis[0] * 8.0f; + trace_t fireTr; + gameLocal.clip.TracePoint(fireTr, fireStart, fireEnd, MASK_SHOT_RENDERMODEL, owner); + fireViewOrigin = fireTr.endpos - playerViewAxis[0] * 8.0f; + + if (flashJointWorld != INVALID_JOINT) { + GetGlobalJointTransform(false, flashJointWorld, fireWorldOrigin, fireWorldAxis); + } + else { + fireWorldOrigin = fireViewOrigin; + fireWorldAxis = fireViewAxis; + } + + const char* fireShaderName = weaponDef->dict.GetString("mtr_weaponFireLightShader"); + if (!fireShaderName || !fireShaderName[0]) { + fireShaderName = weaponDef->dict.GetString("mtr_flashShader"); + } + + const idMaterial* fireShader = NULL; + if (fireShaderName && fireShaderName[0]) { + fireShader = declManager->FindMaterial(fireShaderName, false); + } + + idVec3 fireColor = weaponDef->dict.GetVector("weaponFireLightColor", flashColor.ToString()); + if (fireColor.x <= 0.0f && fireColor.y <= 0.0f && fireColor.z <= 0.0f) { + fireColor.Set(1.0f, 0.72f, 0.38f); + } + + float fireIntensity = weaponDef->dict.GetFloat("weaponFireLightIntensity", "1.0"); + if (fireIntensity <= 0.0f) { + fireIntensity = 1.0f; + } + fireColor *= fireIntensity; + + float fireRadius = weaponDef->dict.GetFloat("weaponFireLightRadius", va("%f", muzzleFlash.lightRadius[0])); + if (fireRadius <= 0.0f) { + fireRadius = 96.0f; + } + + int fireTime = SEC2MS(weaponDef->dict.GetFloat("weaponFireLightTime", weaponDef->dict.GetString("flashTime", "0.08"))); + if (fireTime <= 0) { + fireTime = 80; + } + + StartWeaponFireMuzzleLight(entityNumber, owner ? owner->entityNumber : -1, fireViewOrigin, fireViewAxis, fireWorldOrigin, fireWorldAxis, fireShader, fireColor, fireRadius, fireTime, renderEntity.shaderParms[SHADERPARM_DIVERSITY]); } - owner->WeaponFireFeedback( &weaponDef->dict ); + owner->WeaponFireFeedback(&weaponDef->dict); // reset muzzle smoke weaponSmokeStartTime = gameLocal.realClientTime; @@ -2965,96 +3289,99 @@ void idWeapon::Event_LaunchProjectiles( int num_projectiles, float spread, float idWeapon::Event_Melee ===================== */ -void idWeapon::Event_Melee( void ) { - idEntity *ent; +void idWeapon::Event_Melee(void) { + idEntity* ent; trace_t tr; - if ( !meleeDef ) { - gameLocal.Error( "No meleeDef on '%s'", weaponDef->dict.GetString( "classname" ) ); + if (!meleeDef) { + gameLocal.Error("No meleeDef on '%s'", weaponDef->dict.GetString("classname")); } - if ( !gameLocal.isClient ) { + if (!gameLocal.isClient) { idVec3 start = playerViewOrigin; - idVec3 end = start + playerViewAxis[0] * ( meleeDistance * owner->PowerUpModifier( MELEE_DISTANCE ) ); - gameLocal.clip.TracePoint( tr, start, end, MASK_SHOT_RENDERMODEL, owner ); - if ( tr.fraction < 1.0f ) { - ent = gameLocal.GetTraceEntity( tr ); - } else { + idVec3 end = start + playerViewAxis[0] * (meleeDistance * owner->PowerUpModifier(MELEE_DISTANCE)); + 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 ); + 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" ); + const char* hitSound = meleeDef->dict.GetString("snd_miss"); - if ( ent ) { + if (ent) { - float push = meleeDef->dict.GetFloat( "push" ); - idVec3 impulse = -push * owner->PowerUpModifier( SPEED ) * tr.c.normal; + 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 ); + 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 ); + 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 ) ) + 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(ent)->team)) ) { - owner->StealWeapon( static_cast< idPlayer * >( ent ) ); + owner->StealWeapon(static_cast(ent)); } - if ( ent->fl.takedamage ) { + if (ent->fl.takedamage) { idVec3 kickDir, globalKickDir; - meleeDef->dict.GetVector( "kickDir", "0 0 0", kickDir ); + meleeDef->dict.GetVector("kickDir", "0 0 0", kickDir); globalKickDir = muzzleAxis * kickDir; - ent->Damage( owner, owner, globalKickDir, meleeDefName, owner->PowerUpModifier( MELEE_DAMAGE ), tr.c.id ); + ent->Damage(owner, owner, globalKickDir, meleeDefName, owner->PowerUpModifier(MELEE_DAMAGE), tr.c.id); hit = true; } - if ( weaponDef->dict.GetBool( "impact_damage_effect" ) ) { + if (weaponDef->dict.GetBool("impact_damage_effect")) { - if ( ent->spawnArgs.GetBool( "bleed" ) ) { + if (ent->spawnArgs.GetBool("bleed")) { - hitSound = meleeDef->dict.GetString( owner->PowerUpActive( BERSERK ) ? "snd_hit_berserk" : "snd_hit" ); + hitSound = meleeDef->dict.GetString(owner->PowerUpActive(BERSERK) ? "snd_hit_berserk" : "snd_hit"); - ent->AddDamageEffect( tr, impulse, meleeDef->dict.GetString( "classname" ) ); + ent->AddDamageEffect(tr, impulse, meleeDef->dict.GetString("classname")); - } else { + } + else { int type = tr.c.material->GetSurfaceType(); - if ( type == SURFTYPE_NONE ) { + if (type == SURFTYPE_NONE) { type = GetDefaultSurfaceType(); } - const char *materialType = gameLocal.sufaceTypeNames[ type ]; + 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" ); + hitSound = meleeDef->dict.GetString(va("snd_%s", materialType)); + if (*hitSound == '\0') { + hitSound = meleeDef->dict.GetString("snd_metal"); } - if ( gameLocal.time > nextStrikeFx ) { - const char *decal; + 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 ); + 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 { + } + else { hitSound = ""; } @@ -3065,18 +3392,18 @@ void idWeapon::Event_Melee( void ) { } } - if ( *hitSound != '\0' ) { - const idSoundShader *snd = declManager->FindSound( hitSound ); - StartSoundShader( snd, SND_CHANNEL_BODY2, 0, true, NULL ); + if (*hitSound != '\0') { + const idSoundShader* snd = declManager->FindSound(hitSound); + StartSoundShader(snd, SND_CHANNEL_BODY2, 0, true, NULL); } - idThread::ReturnInt( hit ); - owner->WeaponFireFeedback( &weaponDef->dict ); + idThread::ReturnInt(hit); + owner->WeaponFireFeedback(&weaponDef->dict); return; } - idThread::ReturnInt( 0 ); - owner->WeaponFireFeedback( &weaponDef->dict ); + idThread::ReturnInt(0); + owner->WeaponFireFeedback(&weaponDef->dict); } /* @@ -3084,8 +3411,8 @@ void idWeapon::Event_Melee( void ) { idWeapon::Event_GetWorldModel ===================== */ -void idWeapon::Event_GetWorldModel( void ) { - idThread::ReturnEntity( worldModel.GetEntity() ); +void idWeapon::Event_GetWorldModel(void) { + idThread::ReturnEntity(worldModel.GetEntity()); } /* @@ -3093,10 +3420,11 @@ void idWeapon::Event_GetWorldModel( void ) { idWeapon::Event_AllowDrop ===================== */ -void idWeapon::Event_AllowDrop( int allow ) { - if ( allow ) { +void idWeapon::Event_AllowDrop(int allow) { + if (allow) { allowDrop = true; - } else { + } + else { allowDrop = false; } } @@ -3108,40 +3436,40 @@ 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() ) { +void idWeapon::Event_EjectBrass(void) { + if (!g_showBrass.GetBool() || !owner->CanShowWeaponViewmodel()) { return; } - if ( ejectJointView == INVALID_JOINT || !brassDict.GetNumKeyVals() ) { + if (ejectJointView == INVALID_JOINT || !brassDict.GetNumKeyVals()) { return; } - if ( gameLocal.isClient ) { + if (gameLocal.isClient) { return; } idMat3 axis; idVec3 origin, linear_velocity, angular_velocity; - idEntity *ent; + idEntity* ent; - if ( !GetGlobalJointTransform( true, ejectJointView, origin, axis ) ) { + 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" ); + 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(ent); - debris->Create( owner, origin, axis ); + idDebris* debris = static_cast(ent); + debris->Create(owner, origin, axis); debris->Launch(); - linear_velocity = 40 * ( playerViewAxis[0] + playerViewAxis[1] + playerViewAxis[2] ); - angular_velocity.Set( 10 * gameLocal.random.CRandomFloat(), 10 * gameLocal.random.CRandomFloat(), 10 * gameLocal.random.CRandomFloat() ); + linear_velocity = 40 * (playerViewAxis[0] + playerViewAxis[1] + playerViewAxis[2]); + 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 ); + debris->GetPhysics()->SetLinearVelocity(linear_velocity); + debris->GetPhysics()->SetAngularVelocity(angular_velocity); } /* @@ -3149,12 +3477,12 @@ void idWeapon::Event_EjectBrass( void ) { idWeapon::Event_IsInvisible =============== */ -void idWeapon::Event_IsInvisible( void ) { - if ( !owner ) { - idThread::ReturnFloat( 0 ); +void idWeapon::Event_IsInvisible(void) { + if (!owner) { + idThread::ReturnFloat(0); return; } - idThread::ReturnFloat( owner->PowerUpActive( INVISIBILITY ) ? 1 : 0 ); + idThread::ReturnFloat(owner->PowerUpActive(INVISIBILITY) ? 1 : 0); } /* @@ -3162,6 +3490,6 @@ void idWeapon::Event_IsInvisible( void ) { idWeapon::ClientPredictionThink =============== */ -void idWeapon::ClientPredictionThink( void ) { - UpdateAnimation(); +void idWeapon::ClientPredictionThink(void) { + UpdateAnimation(); } diff --git a/neo/doom3/game/ai/AI.cpp b/neo/doom3/game/ai/AI.cpp index f02aa089..24f63589 100644 --- a/neo/doom3/game/ai/AI.cpp +++ b/neo/doom3/game/ai/AI.cpp @@ -2,9 +2,9 @@ =========================================================================== IceTech GPL Source Code -Copyright (C) 2026 Justin Marshall +Copyright (C) 2026 Justin Marshall -This file is part of the IceTech GPL Source Code (?IceTech Source Code?). +This file is part of the IceTech GPL Source Code (?IceTech Source Code?). IceTech 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 @@ -31,7 +31,7 @@ If you have questions concerning this license or the applicable additional terms #include "../Game_local.h" -static const char *moveCommandString[ NUM_MOVE_COMMANDS ] = { +static const char* moveCommandString[NUM_MOVE_COMMANDS] = { "MOVE_NONE", "MOVE_FACE_ENEMY", "MOVE_FACE_ENTITY", @@ -53,25 +53,25 @@ idMoveState::idMoveState ===================== */ idMoveState::idMoveState() { - moveType = MOVETYPE_ANIM; - moveCommand = MOVE_NONE; - moveStatus = MOVE_STATUS_DONE; + moveType = MOVETYPE_ANIM; + moveCommand = MOVE_NONE; + moveStatus = MOVE_STATUS_DONE; moveDest.Zero(); - moveDir.Set( 1.0f, 0.0f, 0.0f ); - goalEntity = NULL; + moveDir.Set(1.0f, 0.0f, 0.0f); + goalEntity = NULL; goalEntityOrigin.Zero(); - toAreaNum = 0; - startTime = 0; - duration = 0; - speed = 0.0f; - range = 0.0f; - wanderYaw = 0; - nextWanderTime = 0; - blockTime = 0; - obstacle = NULL; - lastMoveOrigin = vec3_origin; - lastMoveTime = 0; - anim = 0; + toAreaNum = 0; + startTime = 0; + duration = 0; + speed = 0.0f; + range = 0.0f; + wanderYaw = 0; + nextWanderTime = 0; + blockTime = 0; + obstacle = NULL; + lastMoveOrigin = vec3_origin; + lastMoveTime = 0; + anim = 0; } /* @@ -79,26 +79,26 @@ idMoveState::idMoveState() { idMoveState::Save ===================== */ -void idMoveState::Save( idSaveGame *savefile ) const { - savefile->WriteInt( (int)moveType ); - savefile->WriteInt( (int)moveCommand ); - savefile->WriteInt( (int)moveStatus ); - savefile->WriteVec3( moveDest ); - savefile->WriteVec3( moveDir ); - goalEntity.Save( savefile ); - savefile->WriteVec3( goalEntityOrigin ); - savefile->WriteInt( toAreaNum ); - savefile->WriteInt( startTime ); - savefile->WriteInt( duration ); - savefile->WriteFloat( speed ); - savefile->WriteFloat( range ); - savefile->WriteFloat( wanderYaw ); - savefile->WriteInt( nextWanderTime ); - savefile->WriteInt( blockTime ); - obstacle.Save( savefile ); - savefile->WriteVec3( lastMoveOrigin ); - savefile->WriteInt( lastMoveTime ); - savefile->WriteInt( anim ); +void idMoveState::Save(idSaveGame* savefile) const { + savefile->WriteInt((int)moveType); + savefile->WriteInt((int)moveCommand); + savefile->WriteInt((int)moveStatus); + savefile->WriteVec3(moveDest); + savefile->WriteVec3(moveDir); + goalEntity.Save(savefile); + savefile->WriteVec3(goalEntityOrigin); + savefile->WriteInt(toAreaNum); + savefile->WriteInt(startTime); + savefile->WriteInt(duration); + savefile->WriteFloat(speed); + savefile->WriteFloat(range); + savefile->WriteFloat(wanderYaw); + savefile->WriteInt(nextWanderTime); + savefile->WriteInt(blockTime); + obstacle.Save(savefile); + savefile->WriteVec3(lastMoveOrigin); + savefile->WriteInt(lastMoveTime); + savefile->WriteInt(anim); } /* @@ -106,26 +106,26 @@ void idMoveState::Save( idSaveGame *savefile ) const { idMoveState::Restore ===================== */ -void idMoveState::Restore( idRestoreGame *savefile ) { - savefile->ReadInt( (int &)moveType ); - savefile->ReadInt( (int &)moveCommand ); - savefile->ReadInt( (int &)moveStatus ); - savefile->ReadVec3( moveDest ); - savefile->ReadVec3( moveDir ); - goalEntity.Restore( savefile ); - savefile->ReadVec3( goalEntityOrigin ); - savefile->ReadInt( toAreaNum ); - savefile->ReadInt( startTime ); - savefile->ReadInt( duration ); - savefile->ReadFloat( speed ); - savefile->ReadFloat( range ); - savefile->ReadFloat( wanderYaw ); - savefile->ReadInt( nextWanderTime ); - savefile->ReadInt( blockTime ); - obstacle.Restore( savefile ); - savefile->ReadVec3( lastMoveOrigin ); - savefile->ReadInt( lastMoveTime ); - savefile->ReadInt( anim ); +void idMoveState::Restore(idRestoreGame* savefile) { + savefile->ReadInt((int&)moveType); + savefile->ReadInt((int&)moveCommand); + savefile->ReadInt((int&)moveStatus); + savefile->ReadVec3(moveDest); + savefile->ReadVec3(moveDir); + goalEntity.Restore(savefile); + savefile->ReadVec3(goalEntityOrigin); + savefile->ReadInt(toAreaNum); + savefile->ReadInt(startTime); + savefile->ReadInt(duration); + savefile->ReadFloat(speed); + savefile->ReadFloat(range); + savefile->ReadFloat(wanderYaw); + savefile->ReadInt(nextWanderTime); + savefile->ReadInt(blockTime); + obstacle.Restore(savefile); + savefile->ReadVec3(lastMoveOrigin); + savefile->ReadInt(lastMoveTime); + savefile->ReadInt(anim); } /* @@ -133,13 +133,13 @@ void idMoveState::Restore( idRestoreGame *savefile ) { idAASFindCover::idAASFindCover ============ */ -idAASFindCover::idAASFindCover( const idVec3 &hideFromPos ) { +idAASFindCover::idAASFindCover(const idVec3& hideFromPos) { int numPVSAreas; - idBounds bounds( hideFromPos - idVec3( 16, 16, 0 ), hideFromPos + idVec3( 16, 16, 64 ) ); + idBounds bounds(hideFromPos - idVec3(16, 16, 0), hideFromPos + idVec3(16, 16, 64)); // setup PVS - numPVSAreas = gameLocal.pvs.GetPVSAreas( bounds, PVSAreas, idEntity::MAX_PVS_AREAS ); - hidePVS = gameLocal.pvs.SetupCurrentPVS( PVSAreas, numPVSAreas ); + numPVSAreas = gameLocal.pvs.GetPVSAreas(bounds, PVSAreas, idEntity::MAX_PVS_AREAS); + hidePVS = gameLocal.pvs.SetupCurrentPVS(PVSAreas, numPVSAreas); } /* @@ -148,7 +148,7 @@ idAASFindCover::~idAASFindCover ============ */ idAASFindCover::~idAASFindCover() { - gameLocal.pvs.FreeCurrentPVS( hidePVS ); + gameLocal.pvs.FreeCurrentPVS(hidePVS); } /* @@ -156,16 +156,16 @@ idAASFindCover::~idAASFindCover() { idAASFindCover::TestArea ============ */ -bool idAASFindCover::TestArea( const idAAS *aas, int areaNum ) { +bool idAASFindCover::TestArea(const idAAS* aas, int areaNum) { idVec3 areaCenter; int numPVSAreas; - int PVSAreas[ idEntity::MAX_PVS_AREAS ]; + int PVSAreas[idEntity::MAX_PVS_AREAS]; - areaCenter = aas->AreaCenter( areaNum ); - areaCenter[ 2 ] += 1.0f; + areaCenter = aas->AreaCenter(areaNum); + areaCenter[2] += 1.0f; - numPVSAreas = gameLocal.pvs.GetPVSAreas( idBounds( areaCenter ).Expand( 16.0f ), PVSAreas, idEntity::MAX_PVS_AREAS ); - if ( !gameLocal.pvs.InCurrentPVS( hidePVS, PVSAreas, numPVSAreas ) ) { + numPVSAreas = gameLocal.pvs.GetPVSAreas(idBounds(areaCenter).Expand(16.0f), PVSAreas, idEntity::MAX_PVS_AREAS); + if (!gameLocal.pvs.InCurrentPVS(hidePVS, PVSAreas, numPVSAreas)) { return true; } @@ -177,9 +177,9 @@ bool idAASFindCover::TestArea( const idAAS *aas, int areaNum ) { idAASFindAreaOutOfRange::idAASFindAreaOutOfRange ============ */ -idAASFindAreaOutOfRange::idAASFindAreaOutOfRange( const idVec3 &targetPos, float maxDist ) { - this->targetPos = targetPos; - this->maxDistSqr = maxDist * maxDist; +idAASFindAreaOutOfRange::idAASFindAreaOutOfRange(const idVec3& targetPos, float maxDist) { + this->targetPos = targetPos; + this->maxDistSqr = maxDist * maxDist; } /* @@ -187,19 +187,19 @@ idAASFindAreaOutOfRange::idAASFindAreaOutOfRange( const idVec3 &targetPos, float idAASFindAreaOutOfRange::TestArea ============ */ -bool idAASFindAreaOutOfRange::TestArea( const idAAS *aas, int areaNum ) { - const idVec3 &areaCenter = aas->AreaCenter( areaNum ); +bool idAASFindAreaOutOfRange::TestArea(const idAAS* aas, int areaNum) { + const idVec3& areaCenter = aas->AreaCenter(areaNum); trace_t trace; float dist; - dist = ( targetPos.ToVec2() - areaCenter.ToVec2() ).LengthSqr(); + dist = (targetPos.ToVec2() - areaCenter.ToVec2()).LengthSqr(); - if ( ( maxDistSqr > 0.0f ) && ( dist < maxDistSqr ) ) { + if ((maxDistSqr > 0.0f) && (dist < maxDistSqr)) { return false; } - gameLocal.clip.TracePoint( trace, targetPos, areaCenter + idVec3( 0.0f, 0.0f, 1.0f ), MASK_OPAQUE, NULL ); - if ( trace.fraction < 1.0f ) { + gameLocal.clip.TracePoint(trace, targetPos, areaCenter + idVec3(0.0f, 0.0f, 1.0f), MASK_OPAQUE, NULL); + if (trace.fraction < 1.0f) { return false; } @@ -211,22 +211,22 @@ bool idAASFindAreaOutOfRange::TestArea( const idAAS *aas, int areaNum ) { idAASFindAttackPosition::idAASFindAttackPosition ============ */ -idAASFindAttackPosition::idAASFindAttackPosition( const idAI *self, const idMat3 &gravityAxis, idEntity *target, const idVec3 &targetPos, const idVec3 &fireOffset ) { +idAASFindAttackPosition::idAASFindAttackPosition(const idAI* self, const idMat3& gravityAxis, idEntity* target, const idVec3& targetPos, const idVec3& fireOffset) { int numPVSAreas; - this->target = target; - this->targetPos = targetPos; - this->fireOffset = fireOffset; - this->self = self; - this->gravityAxis = gravityAxis; + this->target = target; + this->targetPos = targetPos; + this->fireOffset = fireOffset; + this->self = self; + this->gravityAxis = gravityAxis; - excludeBounds = idBounds( idVec3( -64.0, -64.0f, -8.0f ), idVec3( 64.0, 64.0f, 64.0f ) ); - excludeBounds.TranslateSelf( self->GetPhysics()->GetOrigin() ); + excludeBounds = idBounds(idVec3(-64.0, -64.0f, -8.0f), idVec3(64.0, 64.0f, 64.0f)); + excludeBounds.TranslateSelf(self->GetPhysics()->GetOrigin()); // setup PVS - idBounds bounds( targetPos - idVec3( 16, 16, 0 ), targetPos + idVec3( 16, 16, 64 ) ); - numPVSAreas = gameLocal.pvs.GetPVSAreas( bounds, PVSAreas, idEntity::MAX_PVS_AREAS ); - targetPVS = gameLocal.pvs.SetupCurrentPVS( PVSAreas, numPVSAreas ); + idBounds bounds(targetPos - idVec3(16, 16, 0), targetPos + idVec3(16, 16, 64)); + numPVSAreas = gameLocal.pvs.GetPVSAreas(bounds, PVSAreas, idEntity::MAX_PVS_AREAS); + targetPVS = gameLocal.pvs.SetupCurrentPVS(PVSAreas, numPVSAreas); } /* @@ -235,7 +235,7 @@ idAASFindAttackPosition::~idAASFindAttackPosition ============ */ idAASFindAttackPosition::~idAASFindAttackPosition() { - gameLocal.pvs.FreeCurrentPVS( targetPVS ); + gameLocal.pvs.FreeCurrentPVS(targetPVS); } /* @@ -243,37 +243,37 @@ idAASFindAttackPosition::~idAASFindAttackPosition() { idAASFindAttackPosition::TestArea ============ */ -bool idAASFindAttackPosition::TestArea( const idAAS *aas, int areaNum ) { +bool idAASFindAttackPosition::TestArea(const idAAS* aas, int areaNum) { idVec3 dir; idVec3 local_dir; idVec3 fromPos; idMat3 axis; idVec3 areaCenter; int numPVSAreas; - int PVSAreas[ idEntity::MAX_PVS_AREAS ]; + int PVSAreas[idEntity::MAX_PVS_AREAS]; - areaCenter = aas->AreaCenter( areaNum ); - areaCenter[ 2 ] += 1.0f; + areaCenter = aas->AreaCenter(areaNum); + areaCenter[2] += 1.0f; - if ( excludeBounds.ContainsPoint( areaCenter ) ) { + if (excludeBounds.ContainsPoint(areaCenter)) { // too close to where we already are return false; } - numPVSAreas = gameLocal.pvs.GetPVSAreas( idBounds( areaCenter ).Expand( 16.0f ), PVSAreas, idEntity::MAX_PVS_AREAS ); - if ( !gameLocal.pvs.InCurrentPVS( targetPVS, PVSAreas, numPVSAreas ) ) { + numPVSAreas = gameLocal.pvs.GetPVSAreas(idBounds(areaCenter).Expand(16.0f), PVSAreas, idEntity::MAX_PVS_AREAS); + if (!gameLocal.pvs.InCurrentPVS(targetPVS, PVSAreas, numPVSAreas)) { return false; } // calculate the world transform of the launch position dir = targetPos - areaCenter; - gravityAxis.ProjectVector( dir, local_dir ); + gravityAxis.ProjectVector(dir, local_dir); local_dir.z = 0.0f; local_dir.ToVec2().Normalize(); axis = local_dir.ToMat3(); fromPos = areaCenter + fireOffset * axis; - return self->GetAimDir( fromPos, target, self, dir ); + return self->GetAimDir(fromPos, target, self, dir); } /* @@ -282,81 +282,81 @@ idAI::idAI ===================== */ idAI::idAI() { - aas = NULL; - travelFlags = TFL_WALK|TFL_AIR; + aas = NULL; + travelFlags = TFL_WALK | TFL_AIR; - kickForce = 2048.0f; - ignore_obstacles = false; - blockedRadius = 0.0f; - blockedMoveTime = 750; - blockedAttackTime = 750; - turnRate = 360.0f; - turnVel = 0.0f; - anim_turn_yaw = 0.0f; - anim_turn_amount = 0.0f; - anim_turn_angles = 0.0f; - fly_offset = 0; - fly_seek_scale = 1.0f; - fly_roll_scale = 0.0f; - fly_roll_max = 0.0f; - fly_roll = 0.0f; - fly_pitch_scale = 0.0f; - fly_pitch_max = 0.0f; - fly_pitch = 0.0f; - allowMove = false; - allowHiddenMovement = false; - fly_speed = 0.0f; - fly_bob_strength = 0.0f; - fly_bob_vert = 0.0f; - fly_bob_horz = 0.0f; - lastHitCheckResult = false; - lastHitCheckTime = 0; - lastAttackTime = 0; - melee_range = 0.0f; + kickForce = 2048.0f; + ignore_obstacles = false; + blockedRadius = 0.0f; + blockedMoveTime = 750; + blockedAttackTime = 750; + turnRate = 360.0f; + turnVel = 0.0f; + anim_turn_yaw = 0.0f; + anim_turn_amount = 0.0f; + anim_turn_angles = 0.0f; + fly_offset = 0; + fly_seek_scale = 1.0f; + fly_roll_scale = 0.0f; + fly_roll_max = 0.0f; + fly_roll = 0.0f; + fly_pitch_scale = 0.0f; + fly_pitch_max = 0.0f; + fly_pitch = 0.0f; + allowMove = false; + allowHiddenMovement = false; + fly_speed = 0.0f; + fly_bob_strength = 0.0f; + fly_bob_vert = 0.0f; + fly_bob_horz = 0.0f; + lastHitCheckResult = false; + lastHitCheckTime = 0; + lastAttackTime = 0; + melee_range = 0.0f; projectile_height_to_distance_ratio = 1.0f; - projectileDef = NULL; - projectile = NULL; - projectileClipModel = NULL; - projectileRadius = 0.0f; - projectileVelocity = vec3_origin; - projectileGravity = vec3_origin; - projectileSpeed = 0.0f; - chat_snd = NULL; - chat_min = 0; - chat_max = 0; - chat_time = 0; - talk_state = TALK_NEVER; - talkTarget = NULL; + projectileDef = NULL; + projectile = NULL; + projectileClipModel = NULL; + projectileRadius = 0.0f; + projectileVelocity = vec3_origin; + projectileGravity = vec3_origin; + projectileSpeed = 0.0f; + chat_snd = NULL; + chat_min = 0; + chat_max = 0; + chat_time = 0; + talk_state = TALK_NEVER; + talkTarget = NULL; particles.Clear(); - restartParticles = true; - useBoneAxis = false; + restartParticles = true; + useBoneAxis = false; - wakeOnFlashlight = false; - memset( &worldMuzzleFlash, 0, sizeof ( worldMuzzleFlash ) ); + wakeOnFlashlight = false; + memset(&worldMuzzleFlash, 0, sizeof(worldMuzzleFlash)); worldMuzzleFlashHandle = -1; - enemy = NULL; + enemy = NULL; lastVisibleEnemyPos.Zero(); lastVisibleEnemyEyeOffset.Zero(); lastVisibleReachableEnemyPos.Zero(); lastReachableEnemyPos.Zero(); - shrivel_rate = 0.0f; - shrivel_start = 0; - fl.neverDormant = false; // AI's can go dormant - current_yaw = 0.0f; - ideal_yaw = 0.0f; + shrivel_rate = 0.0f; + shrivel_start = 0; + fl.neverDormant = false; // AI's can go dormant + current_yaw = 0.0f; + ideal_yaw = 0.0f; - num_cinematics = 0; - current_cinematic = 0; + num_cinematics = 0; + current_cinematic = 0; - allowEyeFocus = true; - allowPain = true; - allowJointMod = true; - focusEntity = NULL; - focusTime = 0; - alignHeadTime = 0; - forceAlignHeadTime = 0; + allowEyeFocus = true; + allowPain = true; + allowJointMod = true; + focusEntity = NULL; + focusTime = 0; + alignHeadTime = 0; + forceAlignHeadTime = 0; currentFocusPos.Zero(); eyeAng.Zero(); @@ -367,19 +367,19 @@ idAI::idAI() { eyeMin.Zero(); eyeMax.Zero(); - muzzleFlashEnd = 0; - flashTime = 0; - flashJointWorld = INVALID_JOINT; + muzzleFlashEnd = 0; + flashTime = 0; + flashJointWorld = INVALID_JOINT; - focusJoint = INVALID_JOINT; - orientationJoint = INVALID_JOINT; - flyTiltJoint = INVALID_JOINT; + focusJoint = INVALID_JOINT; + orientationJoint = INVALID_JOINT; + flyTiltJoint = INVALID_JOINT; - eyeVerticalOffset = 0.0f; + eyeVerticalOffset = 0.0f; eyeHorizontalOffset = 0.0f; - eyeFocusRate = 0.0f; - headFocusRate = 0.0f; - focusAlignTime = 0; + eyeFocusRate = 0.0f; + headFocusRate = 0.0f; + focusAlignTime = 0; } /* @@ -391,8 +391,8 @@ idAI::~idAI() { delete projectileClipModel; DeconstructScriptObject(); scriptObject.Free(); - if ( worldMuzzleFlashHandle != -1 ) { - gameRenderWorld->FreeLightDef( worldMuzzleFlashHandle ); + if (worldMuzzleFlashHandle != -1) { + gameRenderWorld->FreeLightDef(worldMuzzleFlashHandle); worldMuzzleFlashHandle = -1; } } @@ -402,131 +402,131 @@ idAI::~idAI() { idAI::Save ===================== */ -void idAI::Save( idSaveGame *savefile ) const { +void idAI::Save(idSaveGame* savefile) const { int i; - savefile->WriteInt( travelFlags ); - move.Save( savefile ); - savedMove.Save( savefile ); - savefile->WriteFloat( kickForce ); - savefile->WriteBool( ignore_obstacles ); - savefile->WriteFloat( blockedRadius ); - savefile->WriteInt( blockedMoveTime ); - savefile->WriteInt( blockedAttackTime ); + savefile->WriteInt(travelFlags); + move.Save(savefile); + savedMove.Save(savefile); + savefile->WriteFloat(kickForce); + savefile->WriteBool(ignore_obstacles); + savefile->WriteFloat(blockedRadius); + savefile->WriteInt(blockedMoveTime); + savefile->WriteInt(blockedAttackTime); - savefile->WriteFloat( ideal_yaw ); - savefile->WriteFloat( current_yaw ); - savefile->WriteFloat( turnRate ); - savefile->WriteFloat( turnVel ); - savefile->WriteFloat( anim_turn_yaw ); - savefile->WriteFloat( anim_turn_amount ); - savefile->WriteFloat( anim_turn_angles ); + savefile->WriteFloat(ideal_yaw); + savefile->WriteFloat(current_yaw); + savefile->WriteFloat(turnRate); + savefile->WriteFloat(turnVel); + savefile->WriteFloat(anim_turn_yaw); + savefile->WriteFloat(anim_turn_amount); + savefile->WriteFloat(anim_turn_angles); - savefile->WriteStaticObject( physicsObj ); + savefile->WriteStaticObject(physicsObj); - savefile->WriteFloat( fly_speed ); - savefile->WriteFloat( fly_bob_strength ); - savefile->WriteFloat( fly_bob_vert ); - savefile->WriteFloat( fly_bob_horz ); - savefile->WriteInt( fly_offset ); - savefile->WriteFloat( fly_seek_scale ); - savefile->WriteFloat( fly_roll_scale ); - savefile->WriteFloat( fly_roll_max ); - savefile->WriteFloat( fly_roll ); - savefile->WriteFloat( fly_pitch_scale ); - savefile->WriteFloat( fly_pitch_max ); - savefile->WriteFloat( fly_pitch ); + savefile->WriteFloat(fly_speed); + savefile->WriteFloat(fly_bob_strength); + savefile->WriteFloat(fly_bob_vert); + savefile->WriteFloat(fly_bob_horz); + savefile->WriteInt(fly_offset); + savefile->WriteFloat(fly_seek_scale); + savefile->WriteFloat(fly_roll_scale); + savefile->WriteFloat(fly_roll_max); + savefile->WriteFloat(fly_roll); + savefile->WriteFloat(fly_pitch_scale); + savefile->WriteFloat(fly_pitch_max); + savefile->WriteFloat(fly_pitch); - savefile->WriteBool( allowMove ); - savefile->WriteBool( allowHiddenMovement ); - savefile->WriteBool( disableGravity ); - savefile->WriteBool( af_push_moveables ); + savefile->WriteBool(allowMove); + savefile->WriteBool(allowHiddenMovement); + savefile->WriteBool(disableGravity); + savefile->WriteBool(af_push_moveables); - savefile->WriteBool( lastHitCheckResult ); - savefile->WriteInt( lastHitCheckTime ); - savefile->WriteInt( lastAttackTime ); - savefile->WriteFloat( melee_range ); - savefile->WriteFloat( projectile_height_to_distance_ratio ); + savefile->WriteBool(lastHitCheckResult); + savefile->WriteInt(lastHitCheckTime); + savefile->WriteInt(lastAttackTime); + savefile->WriteFloat(melee_range); + savefile->WriteFloat(projectile_height_to_distance_ratio); - savefile->WriteInt( missileLaunchOffset.Num() ); - for( i = 0; i < missileLaunchOffset.Num(); i++ ) { - savefile->WriteVec3( missileLaunchOffset[ i ] ); + savefile->WriteInt(missileLaunchOffset.Num()); + for (i = 0; i < missileLaunchOffset.Num(); i++) { + savefile->WriteVec3(missileLaunchOffset[i]); } idStr projectileName; - spawnArgs.GetString( "def_projectile", "", projectileName ); - savefile->WriteString( projectileName ); - savefile->WriteFloat( projectileRadius ); - savefile->WriteFloat( projectileSpeed ); - savefile->WriteVec3( projectileVelocity ); - savefile->WriteVec3( projectileGravity ); - projectile.Save( savefile ); - savefile->WriteString( attack ); + spawnArgs.GetString("def_projectile", "", projectileName); + savefile->WriteString(projectileName); + savefile->WriteFloat(projectileRadius); + savefile->WriteFloat(projectileSpeed); + savefile->WriteVec3(projectileVelocity); + savefile->WriteVec3(projectileGravity); + projectile.Save(savefile); + savefile->WriteString(attack); - savefile->WriteSoundShader( chat_snd ); - savefile->WriteInt( chat_min ); - savefile->WriteInt( chat_max ); - savefile->WriteInt( chat_time ); - savefile->WriteInt( talk_state ); - talkTarget.Save( savefile ); + savefile->WriteSoundShader(chat_snd); + savefile->WriteInt(chat_min); + savefile->WriteInt(chat_max); + savefile->WriteInt(chat_time); + savefile->WriteInt(talk_state); + talkTarget.Save(savefile); - savefile->WriteInt( num_cinematics ); - savefile->WriteInt( current_cinematic ); + savefile->WriteInt(num_cinematics); + savefile->WriteInt(current_cinematic); - savefile->WriteBool( allowJointMod ); - focusEntity.Save( savefile ); - savefile->WriteVec3( currentFocusPos ); - savefile->WriteInt( focusTime ); - savefile->WriteInt( alignHeadTime ); - savefile->WriteInt( forceAlignHeadTime ); - savefile->WriteAngles( eyeAng ); - savefile->WriteAngles( lookAng ); - savefile->WriteAngles( destLookAng ); - savefile->WriteAngles( lookMin ); - savefile->WriteAngles( lookMax ); + savefile->WriteBool(allowJointMod); + focusEntity.Save(savefile); + savefile->WriteVec3(currentFocusPos); + savefile->WriteInt(focusTime); + savefile->WriteInt(alignHeadTime); + savefile->WriteInt(forceAlignHeadTime); + savefile->WriteAngles(eyeAng); + savefile->WriteAngles(lookAng); + savefile->WriteAngles(destLookAng); + savefile->WriteAngles(lookMin); + savefile->WriteAngles(lookMax); - savefile->WriteInt( lookJoints.Num() ); - for( i = 0; i < lookJoints.Num(); i++ ) { - savefile->WriteJoint( lookJoints[ i ] ); - savefile->WriteAngles( lookJointAngles[ i ] ); + savefile->WriteInt(lookJoints.Num()); + for (i = 0; i < lookJoints.Num(); i++) { + savefile->WriteJoint(lookJoints[i]); + savefile->WriteAngles(lookJointAngles[i]); } - savefile->WriteFloat( shrivel_rate ); - savefile->WriteInt( shrivel_start ); + savefile->WriteFloat(shrivel_rate); + savefile->WriteInt(shrivel_start); - savefile->WriteInt( particles.Num() ); - for ( i = 0; i < particles.Num(); i++ ) { - savefile->WriteParticle( particles[i].particle ); - savefile->WriteInt( particles[i].time ); - savefile->WriteJoint( particles[i].joint ); + savefile->WriteInt(particles.Num()); + for (i = 0; i < particles.Num(); i++) { + savefile->WriteParticle(particles[i].particle); + savefile->WriteInt(particles[i].time); + savefile->WriteJoint(particles[i].joint); } - savefile->WriteBool( restartParticles ); - savefile->WriteBool( useBoneAxis ); + savefile->WriteBool(restartParticles); + savefile->WriteBool(useBoneAxis); - enemy.Save( savefile ); - savefile->WriteVec3( lastVisibleEnemyPos ); - savefile->WriteVec3( lastVisibleEnemyEyeOffset ); - savefile->WriteVec3( lastVisibleReachableEnemyPos ); - savefile->WriteVec3( lastReachableEnemyPos ); - savefile->WriteBool( wakeOnFlashlight ); + enemy.Save(savefile); + savefile->WriteVec3(lastVisibleEnemyPos); + savefile->WriteVec3(lastVisibleEnemyEyeOffset); + savefile->WriteVec3(lastVisibleReachableEnemyPos); + savefile->WriteVec3(lastReachableEnemyPos); + savefile->WriteBool(wakeOnFlashlight); - savefile->WriteAngles( eyeMin ); - savefile->WriteAngles( eyeMax ); + savefile->WriteAngles(eyeMin); + savefile->WriteAngles(eyeMax); - savefile->WriteFloat( eyeVerticalOffset ); - savefile->WriteFloat( eyeHorizontalOffset ); - savefile->WriteFloat( eyeFocusRate ); - savefile->WriteFloat( headFocusRate ); - savefile->WriteInt( focusAlignTime ); + savefile->WriteFloat(eyeVerticalOffset); + savefile->WriteFloat(eyeHorizontalOffset); + savefile->WriteFloat(eyeFocusRate); + savefile->WriteFloat(headFocusRate); + savefile->WriteInt(focusAlignTime); - savefile->WriteJoint( flashJointWorld ); - savefile->WriteInt( muzzleFlashEnd ); + savefile->WriteJoint(flashJointWorld); + savefile->WriteInt(muzzleFlashEnd); - savefile->WriteJoint( focusJoint ); - savefile->WriteJoint( orientationJoint ); - savefile->WriteJoint( flyTiltJoint ); + savefile->WriteJoint(focusJoint); + savefile->WriteJoint(orientationJoint); + savefile->WriteJoint(flyTiltJoint); - savefile->WriteBool( GetPhysics() == static_cast(&physicsObj) ); + savefile->WriteBool(GetPhysics() == static_cast(&physicsObj)); } /* @@ -534,152 +534,153 @@ void idAI::Save( idSaveGame *savefile ) const { idAI::Restore ===================== */ -void idAI::Restore( idRestoreGame *savefile ) { +void idAI::Restore(idRestoreGame* savefile) { bool restorePhysics; int i; int num; idBounds bounds; - savefile->ReadInt( travelFlags ); - move.Restore( savefile ); - savedMove.Restore( savefile ); - savefile->ReadFloat( kickForce ); - savefile->ReadBool( ignore_obstacles ); - savefile->ReadFloat( blockedRadius ); - savefile->ReadInt( blockedMoveTime ); - savefile->ReadInt( blockedAttackTime ); + savefile->ReadInt(travelFlags); + move.Restore(savefile); + savedMove.Restore(savefile); + savefile->ReadFloat(kickForce); + savefile->ReadBool(ignore_obstacles); + savefile->ReadFloat(blockedRadius); + savefile->ReadInt(blockedMoveTime); + savefile->ReadInt(blockedAttackTime); - savefile->ReadFloat( ideal_yaw ); - savefile->ReadFloat( current_yaw ); - savefile->ReadFloat( turnRate ); - savefile->ReadFloat( turnVel ); - savefile->ReadFloat( anim_turn_yaw ); - savefile->ReadFloat( anim_turn_amount ); - savefile->ReadFloat( anim_turn_angles ); + savefile->ReadFloat(ideal_yaw); + savefile->ReadFloat(current_yaw); + savefile->ReadFloat(turnRate); + savefile->ReadFloat(turnVel); + savefile->ReadFloat(anim_turn_yaw); + savefile->ReadFloat(anim_turn_amount); + savefile->ReadFloat(anim_turn_angles); - savefile->ReadStaticObject( physicsObj ); + savefile->ReadStaticObject(physicsObj); - savefile->ReadFloat( fly_speed ); - savefile->ReadFloat( fly_bob_strength ); - savefile->ReadFloat( fly_bob_vert ); - savefile->ReadFloat( fly_bob_horz ); - savefile->ReadInt( fly_offset ); - savefile->ReadFloat( fly_seek_scale ); - savefile->ReadFloat( fly_roll_scale ); - savefile->ReadFloat( fly_roll_max ); - savefile->ReadFloat( fly_roll ); - savefile->ReadFloat( fly_pitch_scale ); - savefile->ReadFloat( fly_pitch_max ); - savefile->ReadFloat( fly_pitch ); + savefile->ReadFloat(fly_speed); + savefile->ReadFloat(fly_bob_strength); + savefile->ReadFloat(fly_bob_vert); + savefile->ReadFloat(fly_bob_horz); + savefile->ReadInt(fly_offset); + savefile->ReadFloat(fly_seek_scale); + savefile->ReadFloat(fly_roll_scale); + savefile->ReadFloat(fly_roll_max); + savefile->ReadFloat(fly_roll); + savefile->ReadFloat(fly_pitch_scale); + savefile->ReadFloat(fly_pitch_max); + savefile->ReadFloat(fly_pitch); - savefile->ReadBool( allowMove ); - savefile->ReadBool( allowHiddenMovement ); - savefile->ReadBool( disableGravity ); - savefile->ReadBool( af_push_moveables ); + savefile->ReadBool(allowMove); + savefile->ReadBool(allowHiddenMovement); + savefile->ReadBool(disableGravity); + savefile->ReadBool(af_push_moveables); - savefile->ReadBool( lastHitCheckResult ); - savefile->ReadInt( lastHitCheckTime ); - savefile->ReadInt( lastAttackTime ); - savefile->ReadFloat( melee_range ); - savefile->ReadFloat( projectile_height_to_distance_ratio ); + savefile->ReadBool(lastHitCheckResult); + savefile->ReadInt(lastHitCheckTime); + savefile->ReadInt(lastAttackTime); + savefile->ReadFloat(melee_range); + savefile->ReadFloat(projectile_height_to_distance_ratio); - savefile->ReadInt( num ); - missileLaunchOffset.SetGranularity( 1 ); - missileLaunchOffset.SetNum( num ); - for( i = 0; i < num; i++ ) { - savefile->ReadVec3( missileLaunchOffset[ i ] ); + savefile->ReadInt(num); + missileLaunchOffset.SetGranularity(1); + missileLaunchOffset.SetNum(num); + for (i = 0; i < num; i++) { + savefile->ReadVec3(missileLaunchOffset[i]); } idStr projectileName; - savefile->ReadString( projectileName ); - if ( projectileName.Length() ) { - projectileDef = gameLocal.FindEntityDefDict( projectileName ); - } else { + savefile->ReadString(projectileName); + if (projectileName.Length()) { + projectileDef = gameLocal.FindEntityDefDict(projectileName); + } + else { projectileDef = NULL; } - savefile->ReadFloat( projectileRadius ); - savefile->ReadFloat( projectileSpeed ); - savefile->ReadVec3( projectileVelocity ); - savefile->ReadVec3( projectileGravity ); - projectile.Restore( savefile ); - savefile->ReadString( attack ); + savefile->ReadFloat(projectileRadius); + savefile->ReadFloat(projectileSpeed); + savefile->ReadVec3(projectileVelocity); + savefile->ReadVec3(projectileGravity); + projectile.Restore(savefile); + savefile->ReadString(attack); - savefile->ReadSoundShader( chat_snd ); - savefile->ReadInt( chat_min ); - savefile->ReadInt( chat_max ); - savefile->ReadInt( chat_time ); - savefile->ReadInt( i ); - talk_state = static_cast( i ); - talkTarget.Restore( savefile ); + savefile->ReadSoundShader(chat_snd); + savefile->ReadInt(chat_min); + savefile->ReadInt(chat_max); + savefile->ReadInt(chat_time); + savefile->ReadInt(i); + talk_state = static_cast(i); + talkTarget.Restore(savefile); - savefile->ReadInt( num_cinematics ); - savefile->ReadInt( current_cinematic ); + savefile->ReadInt(num_cinematics); + savefile->ReadInt(current_cinematic); - savefile->ReadBool( allowJointMod ); - focusEntity.Restore( savefile ); - savefile->ReadVec3( currentFocusPos ); - savefile->ReadInt( focusTime ); - savefile->ReadInt( alignHeadTime ); - savefile->ReadInt( forceAlignHeadTime ); - savefile->ReadAngles( eyeAng ); - savefile->ReadAngles( lookAng ); - savefile->ReadAngles( destLookAng ); - savefile->ReadAngles( lookMin ); - savefile->ReadAngles( lookMax ); + savefile->ReadBool(allowJointMod); + focusEntity.Restore(savefile); + savefile->ReadVec3(currentFocusPos); + savefile->ReadInt(focusTime); + savefile->ReadInt(alignHeadTime); + savefile->ReadInt(forceAlignHeadTime); + savefile->ReadAngles(eyeAng); + savefile->ReadAngles(lookAng); + savefile->ReadAngles(destLookAng); + savefile->ReadAngles(lookMin); + savefile->ReadAngles(lookMax); - savefile->ReadInt( num ); - lookJoints.SetGranularity( 1 ); - lookJoints.SetNum( num ); - lookJointAngles.SetGranularity( 1 ); - lookJointAngles.SetNum( num ); - for( i = 0; i < num; i++ ) { - savefile->ReadJoint( lookJoints[ i ] ); - savefile->ReadAngles( lookJointAngles[ i ] ); + savefile->ReadInt(num); + lookJoints.SetGranularity(1); + lookJoints.SetNum(num); + lookJointAngles.SetGranularity(1); + lookJointAngles.SetNum(num); + for (i = 0; i < num; i++) { + savefile->ReadJoint(lookJoints[i]); + savefile->ReadAngles(lookJointAngles[i]); } - savefile->ReadFloat( shrivel_rate ); - savefile->ReadInt( shrivel_start ); + savefile->ReadFloat(shrivel_rate); + savefile->ReadInt(shrivel_start); - savefile->ReadInt( num ); - particles.SetNum( num ); - for ( i = 0; i < particles.Num(); i++ ) { - savefile->ReadParticle( particles[i].particle ); - savefile->ReadInt( particles[i].time ); - savefile->ReadJoint( particles[i].joint ); + savefile->ReadInt(num); + particles.SetNum(num); + for (i = 0; i < particles.Num(); i++) { + savefile->ReadParticle(particles[i].particle); + savefile->ReadInt(particles[i].time); + savefile->ReadJoint(particles[i].joint); } - savefile->ReadBool( restartParticles ); - savefile->ReadBool( useBoneAxis ); + savefile->ReadBool(restartParticles); + savefile->ReadBool(useBoneAxis); - enemy.Restore( savefile ); - savefile->ReadVec3( lastVisibleEnemyPos ); - savefile->ReadVec3( lastVisibleEnemyEyeOffset ); - savefile->ReadVec3( lastVisibleReachableEnemyPos ); - savefile->ReadVec3( lastReachableEnemyPos ); + enemy.Restore(savefile); + savefile->ReadVec3(lastVisibleEnemyPos); + savefile->ReadVec3(lastVisibleEnemyEyeOffset); + savefile->ReadVec3(lastVisibleReachableEnemyPos); + savefile->ReadVec3(lastReachableEnemyPos); - savefile->ReadBool( wakeOnFlashlight ); + savefile->ReadBool(wakeOnFlashlight); - savefile->ReadAngles( eyeMin ); - savefile->ReadAngles( eyeMax ); + savefile->ReadAngles(eyeMin); + savefile->ReadAngles(eyeMax); - savefile->ReadFloat( eyeVerticalOffset ); - savefile->ReadFloat( eyeHorizontalOffset ); - savefile->ReadFloat( eyeFocusRate ); - savefile->ReadFloat( headFocusRate ); - savefile->ReadInt( focusAlignTime ); + savefile->ReadFloat(eyeVerticalOffset); + savefile->ReadFloat(eyeHorizontalOffset); + savefile->ReadFloat(eyeFocusRate); + savefile->ReadFloat(headFocusRate); + savefile->ReadInt(focusAlignTime); - savefile->ReadJoint( flashJointWorld ); - savefile->ReadInt( muzzleFlashEnd ); + savefile->ReadJoint(flashJointWorld); + savefile->ReadInt(muzzleFlashEnd); - savefile->ReadJoint( focusJoint ); - savefile->ReadJoint( orientationJoint ); - savefile->ReadJoint( flyTiltJoint ); + savefile->ReadJoint(focusJoint); + savefile->ReadJoint(orientationJoint); + savefile->ReadJoint(flyTiltJoint); - savefile->ReadBool( restorePhysics ); + savefile->ReadBool(restorePhysics); // Set the AAS if the character has the correct gravity vector - idVec3 gravity = spawnArgs.GetVector( "gravityDir", "0 0 -1" ); + idVec3 gravity = spawnArgs.GetVector("gravityDir", "0 0 -1"); gravity *= g_gravity.GetFloat(); - if ( gravity == gameLocal.GetGravity() ) { + if (gravity == gameLocal.GetGravity()) { SetAAS(); } @@ -691,8 +692,8 @@ void idAI::Restore( idRestoreGame *savefile ) { // Link the script variables back to the scriptobject LinkScriptVariables(); - if ( restorePhysics ) { - RestorePhysics( &physicsObj ); + if (restorePhysics) { + RestorePhysics(&physicsObj); } } @@ -701,233 +702,241 @@ void idAI::Restore( idRestoreGame *savefile ) { idAI::Spawn ===================== */ -void idAI::Spawn( void ) { - const char *jointname; - const idKeyValue *kv; +void idAI::Spawn(void) { + const char* jointname; + const idKeyValue* kv; idStr jointName; idAngles jointScale; jointHandle_t joint; idVec3 local_dir; bool talks; - if ( !g_monsters.GetBool() ) { - PostEventMS( &EV_Remove, 0 ); + if (!g_monsters.GetBool()) { + PostEventMS(&EV_Remove, 0); return; } - spawnArgs.GetInt( "team", "1", team ); - spawnArgs.GetInt( "rank", "0", rank ); - spawnArgs.GetInt( "fly_offset", "0", fly_offset ); - spawnArgs.GetFloat( "fly_speed", "100", fly_speed ); - spawnArgs.GetFloat( "fly_bob_strength", "50", fly_bob_strength ); - spawnArgs.GetFloat( "fly_bob_vert", "2", fly_bob_horz ); - spawnArgs.GetFloat( "fly_bob_horz", "2.7", fly_bob_vert ); - spawnArgs.GetFloat( "fly_seek_scale", "4", fly_seek_scale ); - spawnArgs.GetFloat( "fly_roll_scale", "90", fly_roll_scale ); - spawnArgs.GetFloat( "fly_roll_max", "60", fly_roll_max ); - spawnArgs.GetFloat( "fly_pitch_scale", "45", fly_pitch_scale ); - spawnArgs.GetFloat( "fly_pitch_max", "30", fly_pitch_max ); + spawnArgs.GetInt("team", "1", team); + spawnArgs.GetInt("rank", "0", rank); + spawnArgs.GetInt("fly_offset", "0", fly_offset); + spawnArgs.GetFloat("fly_speed", "100", fly_speed); + spawnArgs.GetFloat("fly_bob_strength", "50", fly_bob_strength); + spawnArgs.GetFloat("fly_bob_vert", "2", fly_bob_horz); + spawnArgs.GetFloat("fly_bob_horz", "2.7", fly_bob_vert); + spawnArgs.GetFloat("fly_seek_scale", "4", fly_seek_scale); + spawnArgs.GetFloat("fly_roll_scale", "90", fly_roll_scale); + spawnArgs.GetFloat("fly_roll_max", "60", fly_roll_max); + spawnArgs.GetFloat("fly_pitch_scale", "45", fly_pitch_scale); + spawnArgs.GetFloat("fly_pitch_max", "30", fly_pitch_max); - spawnArgs.GetFloat( "melee_range", "64", melee_range ); - spawnArgs.GetFloat( "projectile_height_to_distance_ratio", "1", projectile_height_to_distance_ratio ); - - spawnArgs.GetFloat( "turn_rate", "360", turnRate ); + spawnArgs.GetFloat("melee_range", "64", melee_range); + spawnArgs.GetFloat("projectile_height_to_distance_ratio", "1", projectile_height_to_distance_ratio); - spawnArgs.GetBool( "talks", "0", talks ); - if ( spawnArgs.GetString( "npc_name", NULL ) != NULL ) { - if ( talks ) { + spawnArgs.GetFloat("turn_rate", "360", turnRate); + + spawnArgs.GetBool("talks", "0", talks); + if (spawnArgs.GetString("npc_name", NULL) != NULL) { + if (talks) { talk_state = TALK_OK; - } else { + } + else { talk_state = TALK_BUSY; } - } else { + } + else { talk_state = TALK_NEVER; } - spawnArgs.GetBool( "animate_z", "0", disableGravity ); - spawnArgs.GetBool( "af_push_moveables", "0", af_push_moveables ); - spawnArgs.GetFloat( "kick_force", "4096", kickForce ); - spawnArgs.GetBool( "ignore_obstacles", "0", ignore_obstacles ); - spawnArgs.GetFloat( "blockedRadius", "-1", blockedRadius ); - spawnArgs.GetInt( "blockedMoveTime", "750", blockedMoveTime ); - spawnArgs.GetInt( "blockedAttackTime", "750", blockedAttackTime ); + spawnArgs.GetBool("animate_z", "0", disableGravity); + spawnArgs.GetBool("af_push_moveables", "0", af_push_moveables); + spawnArgs.GetFloat("kick_force", "4096", kickForce); + spawnArgs.GetBool("ignore_obstacles", "0", ignore_obstacles); + spawnArgs.GetFloat("blockedRadius", "-1", blockedRadius); + spawnArgs.GetInt("blockedMoveTime", "750", blockedMoveTime); + spawnArgs.GetInt("blockedAttackTime", "750", blockedAttackTime); - spawnArgs.GetInt( "num_cinematics", "0", num_cinematics ); + spawnArgs.GetInt("num_cinematics", "0", num_cinematics); current_cinematic = 0; LinkScriptVariables(); - fl.takedamage = !spawnArgs.GetBool( "noDamage" ); - enemy = NULL; - allowMove = true; + fl.takedamage = !spawnArgs.GetBool("noDamage"); + enemy = NULL; + allowMove = true; allowHiddenMovement = false; - animator.RemoveOriginOffset( true ); + animator.RemoveOriginOffset(true); // create combat collision hull for exact collision detection SetCombatModel(); - lookMin = spawnArgs.GetAngles( "look_min", "-80 -75 0" ); - lookMax = spawnArgs.GetAngles( "look_max", "80 75 0" ); + lookMin = spawnArgs.GetAngles("look_min", "-80 -75 0"); + lookMax = spawnArgs.GetAngles("look_max", "80 75 0"); - lookJoints.SetGranularity( 1 ); - lookJointAngles.SetGranularity( 1 ); - kv = spawnArgs.MatchPrefix( "look_joint", NULL ); - while( kv ) { + lookJoints.SetGranularity(1); + lookJointAngles.SetGranularity(1); + kv = spawnArgs.MatchPrefix("look_joint", NULL); + while (kv) { jointName = kv->GetKey(); - jointName.StripLeadingOnce( "look_joint " ); - joint = animator.GetJointHandle( jointName ); - if ( joint == INVALID_JOINT ) { - gameLocal.Warning( "Unknown look_joint '%s' on entity %s", jointName.c_str(), name.c_str() ); - } else { - jointScale = spawnArgs.GetAngles( kv->GetKey(), "0 0 0" ); + jointName.StripLeadingOnce("look_joint "); + joint = animator.GetJointHandle(jointName); + if (joint == INVALID_JOINT) { + gameLocal.Warning("Unknown look_joint '%s' on entity %s", jointName.c_str(), name.c_str()); + } + else { + jointScale = spawnArgs.GetAngles(kv->GetKey(), "0 0 0"); jointScale.roll = 0.0f; // if no scale on any component, then don't bother adding it. this may be done to // zero out rotation from an inherited entitydef. - if ( jointScale != ang_zero ) { - lookJoints.Append( joint ); - lookJointAngles.Append( jointScale ); + if (jointScale != ang_zero) { + lookJoints.Append(joint); + lookJointAngles.Append(jointScale); } } - kv = spawnArgs.MatchPrefix( "look_joint", kv ); + kv = spawnArgs.MatchPrefix("look_joint", kv); } // calculate joint positions on attack frames so we can do proper "can hit" tests CalculateAttackOffsets(); - eyeMin = spawnArgs.GetAngles( "eye_turn_min", "-10 -30 0" ); - eyeMax = spawnArgs.GetAngles( "eye_turn_max", "10 30 0" ); - eyeVerticalOffset = spawnArgs.GetFloat( "eye_verticle_offset", "5" ); - eyeHorizontalOffset = spawnArgs.GetFloat( "eye_horizontal_offset", "-8" ); - eyeFocusRate = spawnArgs.GetFloat( "eye_focus_rate", "0.5" ); - headFocusRate = spawnArgs.GetFloat( "head_focus_rate", "0.1" ); - focusAlignTime = SEC2MS( spawnArgs.GetFloat( "focus_align_time", "1" ) ); + eyeMin = spawnArgs.GetAngles("eye_turn_min", "-10 -30 0"); + eyeMax = spawnArgs.GetAngles("eye_turn_max", "10 30 0"); + eyeVerticalOffset = spawnArgs.GetFloat("eye_verticle_offset", "5"); + eyeHorizontalOffset = spawnArgs.GetFloat("eye_horizontal_offset", "-8"); + eyeFocusRate = spawnArgs.GetFloat("eye_focus_rate", "0.5"); + headFocusRate = spawnArgs.GetFloat("head_focus_rate", "0.1"); + focusAlignTime = SEC2MS(spawnArgs.GetFloat("focus_align_time", "1")); - flashJointWorld = animator.GetJointHandle( "flash" ); + flashJointWorld = animator.GetJointHandle("flash"); - if ( head.GetEntity() ) { - idAnimator *headAnimator = head.GetEntity()->GetAnimator(); + if (head.GetEntity()) { + idAnimator* headAnimator = head.GetEntity()->GetAnimator(); - jointname = spawnArgs.GetString( "bone_focus" ); - if ( *jointname ) { - focusJoint = headAnimator->GetJointHandle( jointname ); - if ( focusJoint == INVALID_JOINT ) { - gameLocal.Warning( "Joint '%s' not found on head on '%s'", jointname, name.c_str() ); + jointname = spawnArgs.GetString("bone_focus"); + if (*jointname) { + focusJoint = headAnimator->GetJointHandle(jointname); + if (focusJoint == INVALID_JOINT) { + gameLocal.Warning("Joint '%s' not found on head on '%s'", jointname, name.c_str()); } } - } else { - jointname = spawnArgs.GetString( "bone_focus" ); - if ( *jointname ) { - focusJoint = animator.GetJointHandle( jointname ); - if ( focusJoint == INVALID_JOINT ) { - gameLocal.Warning( "Joint '%s' not found on '%s'", jointname, name.c_str() ); + } + else { + jointname = spawnArgs.GetString("bone_focus"); + if (*jointname) { + focusJoint = animator.GetJointHandle(jointname); + if (focusJoint == INVALID_JOINT) { + gameLocal.Warning("Joint '%s' not found on '%s'", jointname, name.c_str()); } } } - jointname = spawnArgs.GetString( "bone_orientation" ); - if ( *jointname ) { - orientationJoint = animator.GetJointHandle( jointname ); - if ( orientationJoint == INVALID_JOINT ) { - gameLocal.Warning( "Joint '%s' not found on '%s'", jointname, name.c_str() ); + jointname = spawnArgs.GetString("bone_orientation"); + if (*jointname) { + orientationJoint = animator.GetJointHandle(jointname); + if (orientationJoint == INVALID_JOINT) { + gameLocal.Warning("Joint '%s' not found on '%s'", jointname, name.c_str()); } } - jointname = spawnArgs.GetString( "bone_flytilt" ); - if ( *jointname ) { - flyTiltJoint = animator.GetJointHandle( jointname ); - if ( flyTiltJoint == INVALID_JOINT ) { - gameLocal.Warning( "Joint '%s' not found on '%s'", jointname, name.c_str() ); + jointname = spawnArgs.GetString("bone_flytilt"); + if (*jointname) { + flyTiltJoint = animator.GetJointHandle(jointname); + if (flyTiltJoint == INVALID_JOINT) { + gameLocal.Warning("Joint '%s' not found on '%s'", jointname, name.c_str()); } } InitMuzzleFlash(); - physicsObj.SetSelf( this ); - physicsObj.SetClipModel( new idClipModel( GetPhysics()->GetClipModel() ), 1.0f ); - physicsObj.SetMass( spawnArgs.GetFloat( "mass", "100" ) ); + physicsObj.SetSelf(this); + physicsObj.SetClipModel(new idClipModel(GetPhysics()->GetClipModel()), 1.0f); + physicsObj.SetMass(spawnArgs.GetFloat("mass", "100")); - if ( spawnArgs.GetBool( "big_monster" ) ) { - physicsObj.SetContents( 0 ); - physicsObj.SetClipMask( MASK_MONSTERSOLID & ~CONTENTS_BODY ); - } else { - if ( use_combat_bbox ) { - physicsObj.SetContents( CONTENTS_BODY|CONTENTS_SOLID ); - } else { - physicsObj.SetContents( CONTENTS_BODY ); + if (spawnArgs.GetBool("big_monster")) { + physicsObj.SetContents(0); + physicsObj.SetClipMask(MASK_MONSTERSOLID & ~CONTENTS_BODY); + } + else { + if (use_combat_bbox) { + physicsObj.SetContents(CONTENTS_BODY | CONTENTS_SOLID); } - physicsObj.SetClipMask( MASK_MONSTERSOLID ); + else { + physicsObj.SetContents(CONTENTS_BODY); + } + physicsObj.SetClipMask(MASK_MONSTERSOLID); } // move up to make sure the monster is at least an epsilon above the floor - physicsObj.SetOrigin( GetPhysics()->GetOrigin() + idVec3( 0, 0, CM_CLIP_EPSILON ) ); - - if ( num_cinematics ) { - physicsObj.SetGravity( vec3_origin ); - } else { - idVec3 gravity = spawnArgs.GetVector( "gravityDir", "0 0 -1" ); + physicsObj.SetOrigin(GetPhysics()->GetOrigin() + idVec3(0, 0, CM_CLIP_EPSILON)); + + if (num_cinematics) { + physicsObj.SetGravity(vec3_origin); + } + else { + idVec3 gravity = spawnArgs.GetVector("gravityDir", "0 0 -1"); gravity *= g_gravity.GetFloat(); - physicsObj.SetGravity( gravity ); + physicsObj.SetGravity(gravity); } - SetPhysics( &physicsObj ); + SetPhysics(&physicsObj); - physicsObj.GetGravityAxis().ProjectVector( viewAxis[ 0 ], local_dir ); - current_yaw = local_dir.ToYaw(); - ideal_yaw = idMath::AngleNormalize180( current_yaw ); + physicsObj.GetGravityAxis().ProjectVector(viewAxis[0], local_dir); + current_yaw = local_dir.ToYaw(); + ideal_yaw = idMath::AngleNormalize180(current_yaw); move.blockTime = 0; SetAAS(); - projectile = NULL; - projectileDef = NULL; - projectileClipModel = NULL; + projectile = NULL; + projectileDef = NULL; + projectileClipModel = NULL; idStr projectileName; - if ( spawnArgs.GetString( "def_projectile", "", projectileName ) && projectileName.Length() ) { - projectileDef = gameLocal.FindEntityDefDict( projectileName ); - CreateProjectile( vec3_origin, viewAxis[ 0 ] ); - projectileRadius = projectile.GetEntity()->GetPhysics()->GetClipModel()->GetBounds().GetRadius(); - projectileVelocity = idProjectile::GetVelocity( projectileDef ); - projectileGravity = idProjectile::GetGravity( projectileDef ); - projectileSpeed = projectileVelocity.Length(); + if (spawnArgs.GetString("def_projectile", "", projectileName) && projectileName.Length()) { + projectileDef = gameLocal.FindEntityDefDict(projectileName); + CreateProjectile(vec3_origin, viewAxis[0]); + projectileRadius = projectile.GetEntity()->GetPhysics()->GetClipModel()->GetBounds().GetRadius(); + projectileVelocity = idProjectile::GetVelocity(projectileDef); + projectileGravity = idProjectile::GetGravity(projectileDef); + projectileSpeed = projectileVelocity.Length(); delete projectile.GetEntity(); projectile = NULL; } particles.Clear(); restartParticles = true; - useBoneAxis = spawnArgs.GetBool( "useBoneAxis" ); - SpawnParticles( "smokeParticleSystem" ); + useBoneAxis = spawnArgs.GetBool("useBoneAxis"); + SpawnParticles("smokeParticleSystem"); - if ( num_cinematics || spawnArgs.GetBool( "hide" ) || spawnArgs.GetBool( "teleport" ) || spawnArgs.GetBool( "trigger_anim" ) ) { + if (num_cinematics || spawnArgs.GetBool("hide") || spawnArgs.GetBool("teleport") || spawnArgs.GetBool("trigger_anim")) { fl.takedamage = false; - physicsObj.SetContents( 0 ); + physicsObj.SetContents(0); physicsObj.GetClipModel()->Unlink(); Hide(); - } else { + } + else { // play a looping ambient sound if we have one - StartSound( "snd_ambient", SND_CHANNEL_AMBIENT, 0, false, NULL ); + StartSound("snd_ambient", SND_CHANNEL_AMBIENT, 0, false, NULL); } - if ( health <= 0 ) { - gameLocal.Warning( "entity '%s' doesn't have health set", name.c_str() ); + if (health <= 0) { + gameLocal.Warning("entity '%s' doesn't have health set", name.c_str()); health = 1; } // set up monster chatter SetChatSound(); - BecomeActive( TH_THINK ); + BecomeActive(TH_THINK); - if ( af_push_moveables ) { - af.SetupPose( this, gameLocal.time ); + if (af_push_moveables) { + af.SetupPose(this, gameLocal.time); af.GetPhysics()->EnableClip(); } // init the move variables - StopMove( MOVE_STATUS_DONE ); + StopMove(MOVE_STATUS_DONE); } /* @@ -935,29 +944,51 @@ void idAI::Spawn( void ) { idAI::InitMuzzleFlash =================== */ -void idAI::InitMuzzleFlash( void ) { - const char *shader; +void idAI::InitMuzzleFlash(void) { + const char* shader; idVec3 flashColor; - spawnArgs.GetString( "mtr_flashShader", "muzzleflash", &shader ); - spawnArgs.GetVector( "flashColor", "0 0 0", flashColor ); - float flashRadius = spawnArgs.GetFloat( "flashRadius" ); - flashTime = SEC2MS( spawnArgs.GetFloat( "flashTime", "0.25" ) ); + // This light is the short-lived AI weapon-fire muzzle light. Do not tie this + // into any flashlight style behavior. It gets kicked by AI_MuzzleFlash / + // projectile launches, follows the muzzle joint while alive, then fades out. + spawnArgs.GetString("mtr_flashShader", "lights/defaultPointLight", &shader); + spawnArgs.GetVector("flashColor", "1 0.82 0.45", flashColor); + float flashRadius = spawnArgs.GetFloat("flashRadius", "0"); + if (flashRadius <= 0.0f) { + flashRadius = spawnArgs.GetFloat("muzzleLightRadius", "150"); + } + if (flashRadius <= 0.0f) { + flashRadius = 150.0f; + } - memset( &worldMuzzleFlash, 0, sizeof ( worldMuzzleFlash ) ); + flashTime = SEC2MS(spawnArgs.GetFloat("flashTime", "0.12")); + if (flashTime <= 0) { + flashTime = 120; + } + + memset(&worldMuzzleFlash, 0, sizeof(worldMuzzleFlash)); worldMuzzleFlash.pointLight = true; - worldMuzzleFlash.shader = declManager->FindMaterial( shader, false ); - worldMuzzleFlash.shaderParms[ SHADERPARM_RED ] = flashColor[0]; - worldMuzzleFlash.shaderParms[ SHADERPARM_GREEN ] = flashColor[1]; - worldMuzzleFlash.shaderParms[ SHADERPARM_BLUE ] = flashColor[2]; - worldMuzzleFlash.shaderParms[ SHADERPARM_ALPHA ] = 1.0f; - worldMuzzleFlash.shaderParms[ SHADERPARM_TIMESCALE ] = 1.0f; + worldMuzzleFlash.noShadows = true; + worldMuzzleFlash.shader = declManager->FindMaterial(shader, false); + if (worldMuzzleFlash.shader == NULL) { + worldMuzzleFlash.shader = declManager->FindMaterial("muzzleflash", false); + } + worldMuzzleFlash.shaderParms[SHADERPARM_RED] = flashColor[0]; + worldMuzzleFlash.shaderParms[SHADERPARM_GREEN] = flashColor[1]; + worldMuzzleFlash.shaderParms[SHADERPARM_BLUE] = flashColor[2]; + worldMuzzleFlash.shaderParms[SHADERPARM_ALPHA] = 1.0f; + worldMuzzleFlash.shaderParms[SHADERPARM_TIMESCALE] = 1.0f; + worldMuzzleFlash.shaderParms[SHADERPARM_TIMEOFFSET] = 0.0f; worldMuzzleFlash.lightRadius[0] = flashRadius; - worldMuzzleFlash.lightRadius[1] = flashRadius; - worldMuzzleFlash.lightRadius[2] = flashRadius; + worldMuzzleFlash.lightRadius[1] = flashRadius; + worldMuzzleFlash.lightRadius[2] = flashRadius; + if (worldMuzzleFlashHandle != -1) { + gameRenderWorld->FreeLightDef(worldMuzzleFlashHandle); + } worldMuzzleFlashHandle = -1; + muzzleFlashEnd = 0; } /* @@ -965,33 +996,34 @@ void idAI::InitMuzzleFlash( void ) { idAI::List_f =================== */ -void idAI::List_f( const idCmdArgs &args ) { +void idAI::List_f(const idCmdArgs& args) { int e; - idAI *check; + idAI* check; int count; - const char *statename; + const char* statename; count = 0; - gameLocal.Printf( "%-4s %-20s %s\n", " Num", "EntityDef", "Name" ); - gameLocal.Printf( "------------------------------------------------\n" ); - for( e = 0; e < MAX_GENTITIES; e++ ) { - check = static_cast(gameLocal.entities[ e ]); - if ( !check || !check->IsType( idAI::Type ) ) { + gameLocal.Printf("%-4s %-20s %s\n", " Num", "EntityDef", "Name"); + gameLocal.Printf("------------------------------------------------\n"); + for (e = 0; e < MAX_GENTITIES; e++) { + check = static_cast(gameLocal.entities[e]); + if (!check || !check->IsType(idAI::Type)) { continue; } - if ( check->state ) { + if (check->state) { statename = check->state->Name(); - } else { + } + else { statename = "NULL state"; } - gameLocal.Printf( "%4i: %-20s %-20s %s move: %d\n", e, check->GetEntityDefName(), check->name.c_str(), statename, check->allowMove ); + gameLocal.Printf("%4i: %-20s %-20s %s move: %d\n", e, check->GetEntityDefName(), check->name.c_str(), statename, check->allowMove); count++; } - gameLocal.Printf( "...%d monsters\n", count ); + gameLocal.Printf("...%d monsters\n", count); } /* @@ -1001,16 +1033,16 @@ idAI::DormantBegin called when entity becomes dormant ================ */ -void idAI::DormantBegin( void ) { +void idAI::DormantBegin(void) { // since dormant happens on a timer, we wont get to update particles to // hidden through the think loop, but we need to hide them though. - if ( particles.Num() ) { - for ( int i = 0; i < particles.Num(); i++ ) { + if (particles.Num()) { + for (int i = 0; i < particles.Num(); i++) { particles[i].time = 0; } } - if ( enemyNode.InList() ) { + if (enemyNode.InList()) { // remove ourselves from the enemy's enemylist enemyNode.Remove(); } @@ -1024,14 +1056,14 @@ idAI::DormantEnd called when entity wakes from being dormant ================ */ -void idAI::DormantEnd( void ) { - if ( enemy.GetEntity() && !enemyNode.InList() ) { +void idAI::DormantEnd(void) { + if (enemy.GetEntity() && !enemyNode.InList()) { // let our enemy know we're back on the trail - enemyNode.AddToEnd( enemy.GetEntity()->enemyList ); + enemyNode.AddToEnd(enemy.GetEntity()->enemyList); } - - if ( particles.Num() ) { - for ( int i = 0; i < particles.Num(); i++ ) { + + if (particles.Num()) { + for (int i = 0; i < particles.Num(); i++) { particles[i].time = gameLocal.time; } } @@ -1044,46 +1076,48 @@ void idAI::DormantEnd( void ) { idAI::Think ===================== */ -void idAI::Think( void ) { +void idAI::Think(void) { // if we are completely closed off from the player, don't do anything at all - if ( CheckDormant() ) { + if (CheckDormant()) { return; } - if ( thinkFlags & TH_THINK ) { + if (thinkFlags & TH_THINK) { // clear out the enemy when he dies or is hidden - idActor *enemyEnt = enemy.GetEntity(); - if ( enemyEnt ) { - if ( enemyEnt->health <= 0 ) { + idActor* enemyEnt = enemy.GetEntity(); + if (enemyEnt) { + if (enemyEnt->health <= 0) { EnemyDead(); } } current_yaw += deltaViewAngles.yaw; - ideal_yaw = idMath::AngleNormalize180( ideal_yaw + deltaViewAngles.yaw ); + ideal_yaw = idMath::AngleNormalize180(ideal_yaw + deltaViewAngles.yaw); deltaViewAngles.Zero(); - viewAxis = idAngles( 0, current_yaw, 0 ).ToMat3(); + viewAxis = idAngles(0, current_yaw, 0).ToMat3(); - if ( num_cinematics ) { - if ( !IsHidden() && torsoAnim.AnimDone( 0 ) ) { + if (num_cinematics) { + if (!IsHidden() && torsoAnim.AnimDone(0)) { PlayCinematic(); } RunPhysics(); - } else if ( !allowHiddenMovement && IsHidden() ) { + } + else if (!allowHiddenMovement && IsHidden()) { // hidden monsters UpdateAIScript(); - } else { + } + else { // clear the ik before we do anything else so the skeleton doesn't get updated twice walkIK.ClearJointMods(); - switch( move.moveType ) { - case MOVETYPE_DEAD : + switch (move.moveType) { + case MOVETYPE_DEAD: // dead monsters UpdateAIScript(); DeadMove(); break; - case MOVETYPE_FLY : + case MOVETYPE_FLY: // flying monsters UpdateEnemyPosition(); UpdateAIScript(); @@ -1092,7 +1126,7 @@ void idAI::Think( void ) { CheckBlink(); break; - case MOVETYPE_STATIC : + case MOVETYPE_STATIC: // static monsters UpdateEnemyPosition(); UpdateAIScript(); @@ -1101,7 +1135,7 @@ void idAI::Think( void ) { CheckBlink(); break; - case MOVETYPE_ANIM : + case MOVETYPE_ANIM: // animation based movement UpdateEnemyPosition(); UpdateAIScript(); @@ -1110,7 +1144,7 @@ void idAI::Think( void ) { CheckBlink(); break; - case MOVETYPE_SLIDE : + case MOVETYPE_SLIDE: // velocity based movement UpdateEnemyPosition(); UpdateAIScript(); @@ -1125,23 +1159,24 @@ void idAI::Think( void ) { AI_PAIN = false; AI_SPECIAL_DAMAGE = 0; AI_PUSHED = false; - } else if ( thinkFlags & TH_PHYSICS ) { + } + else if (thinkFlags & TH_PHYSICS) { RunPhysics(); } - if ( af_push_moveables ) { + if (af_push_moveables) { PushWithAF(); } - if ( fl.hidden && allowHiddenMovement ) { + if (fl.hidden && allowHiddenMovement) { // UpdateAnimation won't call frame commands when hidden, so call them here when we allow hidden movement - animator.ServiceAnims( gameLocal.previousTime, gameLocal.time ); + animator.ServiceAnims(gameLocal.previousTime, gameLocal.time); } -/* this still draws in retail builds.. not sure why.. don't care at this point. - if ( !aas && developer.GetBool() && !fl.hidden && !num_cinematics ) { - gameRenderWorld->DrawText( "No AAS", physicsObj.GetAbsBounds().GetCenter(), 0.1f, colorWhite, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, gameLocal.msec ); - } -*/ + /* this still draws in retail builds.. not sure why.. don't care at this point. + if ( !aas && developer.GetBool() && !fl.hidden && !num_cinematics ) { + gameRenderWorld->DrawText( "No AAS", physicsObj.GetAbsBounds().GetCenter(), 0.1f, colorWhite, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, gameLocal.msec ); + } + */ UpdateMuzzleFlash(); UpdateAnimation(); @@ -1162,25 +1197,25 @@ void idAI::Think( void ) { idAI::LinkScriptVariables ===================== */ -void idAI::LinkScriptVariables( void ) { - AI_TALK.LinkTo( scriptObject, "AI_TALK" ); - AI_DAMAGE.LinkTo( scriptObject, "AI_DAMAGE" ); - AI_PAIN.LinkTo( scriptObject, "AI_PAIN" ); - AI_SPECIAL_DAMAGE.LinkTo( scriptObject, "AI_SPECIAL_DAMAGE" ); - AI_DEAD.LinkTo( scriptObject, "AI_DEAD" ); - AI_ENEMY_VISIBLE.LinkTo( scriptObject, "AI_ENEMY_VISIBLE" ); - AI_ENEMY_IN_FOV.LinkTo( scriptObject, "AI_ENEMY_IN_FOV" ); - AI_ENEMY_DEAD.LinkTo( scriptObject, "AI_ENEMY_DEAD" ); - AI_MOVE_DONE.LinkTo( scriptObject, "AI_MOVE_DONE" ); - AI_ONGROUND.LinkTo( scriptObject, "AI_ONGROUND" ); - AI_ACTIVATED.LinkTo( scriptObject, "AI_ACTIVATED" ); - AI_FORWARD.LinkTo( scriptObject, "AI_FORWARD" ); - AI_JUMP.LinkTo( scriptObject, "AI_JUMP" ); - AI_BLOCKED.LinkTo( scriptObject, "AI_BLOCKED" ); - AI_DEST_UNREACHABLE.LinkTo( scriptObject, "AI_DEST_UNREACHABLE" ); - AI_HIT_ENEMY.LinkTo( scriptObject, "AI_HIT_ENEMY" ); - AI_OBSTACLE_IN_PATH.LinkTo( scriptObject, "AI_OBSTACLE_IN_PATH" ); - AI_PUSHED.LinkTo( scriptObject, "AI_PUSHED" ); +void idAI::LinkScriptVariables(void) { + AI_TALK.LinkTo(scriptObject, "AI_TALK"); + AI_DAMAGE.LinkTo(scriptObject, "AI_DAMAGE"); + AI_PAIN.LinkTo(scriptObject, "AI_PAIN"); + AI_SPECIAL_DAMAGE.LinkTo(scriptObject, "AI_SPECIAL_DAMAGE"); + AI_DEAD.LinkTo(scriptObject, "AI_DEAD"); + AI_ENEMY_VISIBLE.LinkTo(scriptObject, "AI_ENEMY_VISIBLE"); + AI_ENEMY_IN_FOV.LinkTo(scriptObject, "AI_ENEMY_IN_FOV"); + AI_ENEMY_DEAD.LinkTo(scriptObject, "AI_ENEMY_DEAD"); + AI_MOVE_DONE.LinkTo(scriptObject, "AI_MOVE_DONE"); + AI_ONGROUND.LinkTo(scriptObject, "AI_ONGROUND"); + AI_ACTIVATED.LinkTo(scriptObject, "AI_ACTIVATED"); + AI_FORWARD.LinkTo(scriptObject, "AI_FORWARD"); + AI_JUMP.LinkTo(scriptObject, "AI_JUMP"); + AI_BLOCKED.LinkTo(scriptObject, "AI_BLOCKED"); + AI_DEST_UNREACHABLE.LinkTo(scriptObject, "AI_DEST_UNREACHABLE"); + AI_HIT_ENEMY.LinkTo(scriptObject, "AI_HIT_ENEMY"); + AI_OBSTACLE_IN_PATH.LinkTo(scriptObject, "AI_OBSTACLE_IN_PATH"); + AI_PUSHED.LinkTo(scriptObject, "AI_PUSHED"); } /* @@ -1188,13 +1223,13 @@ void idAI::LinkScriptVariables( void ) { idAI::UpdateAIScript ===================== */ -void idAI::UpdateAIScript( void ) { +void idAI::UpdateAIScript(void) { UpdateScript(); // clear the hit enemy flag so we catch the next time we hit someone AI_HIT_ENEMY = false; - if ( allowHiddenMovement || !IsHidden() ) { + if (allowHiddenMovement || !IsHidden()) { // update the animstate if we're not hidden UpdateAnimState(); } @@ -1211,12 +1246,12 @@ void idAI::UpdateAIScript( void ) { idAI::KickObstacles ============ */ -void idAI::KickObstacles( const idVec3 &dir, float force, idEntity *alwaysKick ) { +void idAI::KickObstacles(const idVec3& dir, float force, idEntity* alwaysKick) { int i, numListedClipModels; idBounds clipBounds; - idEntity *obEnt; - idClipModel *clipModel; - idClipModel *clipModelList[ MAX_GENTITIES ]; + idEntity* obEnt; + idClipModel* clipModel; + idClipModel* clipModelList[MAX_GENTITIES]; int clipmask; idVec3 org; idVec3 forceVec; @@ -1227,24 +1262,24 @@ void idAI::KickObstacles( const idVec3 &dir, float force, idEntity *alwaysKick ) // find all possible obstacles clipBounds = physicsObj.GetAbsBounds(); - clipBounds.TranslateSelf( dir * 32.0f ); - clipBounds.ExpandSelf( 8.0f ); - clipBounds.AddPoint( org ); + clipBounds.TranslateSelf(dir * 32.0f); + clipBounds.ExpandSelf(8.0f); + clipBounds.AddPoint(org); clipmask = physicsObj.GetClipMask(); - numListedClipModels = gameLocal.clip.ClipModelsTouchingBounds( clipBounds, clipmask, clipModelList, MAX_GENTITIES ); - for ( i = 0; i < numListedClipModels; i++ ) { + numListedClipModels = gameLocal.clip.ClipModelsTouchingBounds(clipBounds, clipmask, clipModelList, MAX_GENTITIES); + for (i = 0; i < numListedClipModels; i++) { clipModel = clipModelList[i]; obEnt = clipModel->GetEntity(); - if ( obEnt == alwaysKick ) { + if (obEnt == alwaysKick) { // we'll kick this one outside the loop continue; } - if ( !clipModel->IsTraceModel() ) { + if (!clipModel->IsTraceModel()) { continue; } - if ( obEnt->IsType( idMoveable::Type ) && obEnt->GetPhysics()->IsPushable() ) { + if (obEnt->IsType(idMoveable::Type) && obEnt->GetPhysics()->IsPushable()) { delta = obEnt->GetPhysics()->GetOrigin() - org; delta.NormalizeFast(); perpendicular.x = -delta.y; @@ -1252,11 +1287,11 @@ void idAI::KickObstacles( const idVec3 &dir, float force, idEntity *alwaysKick ) delta.z += 0.5f; delta.ToVec2() += perpendicular * gameLocal.random.CRandomFloat() * 0.5f; forceVec = delta * force * obEnt->GetPhysics()->GetMass(); - obEnt->ApplyImpulse( this, 0, obEnt->GetPhysics()->GetOrigin(), forceVec ); + obEnt->ApplyImpulse(this, 0, obEnt->GetPhysics()->GetOrigin(), forceVec); } } - if ( alwaysKick ) { + if (alwaysKick) { delta = alwaysKick->GetPhysics()->GetOrigin() - org; delta.NormalizeFast(); perpendicular.x = -delta.y; @@ -1264,7 +1299,7 @@ void idAI::KickObstacles( const idVec3 &dir, float force, idEntity *alwaysKick ) delta.z += 0.5f; delta.ToVec2() += perpendicular * gameLocal.random.CRandomFloat() * 0.5f; forceVec = delta * force * alwaysKick->GetPhysics()->GetMass(); - alwaysKick->ApplyImpulse( this, 0, alwaysKick->GetPhysics()->GetOrigin(), forceVec ); + alwaysKick->ApplyImpulse(this, 0, alwaysKick->GetPhysics()->GetOrigin(), forceVec); } } @@ -1273,14 +1308,14 @@ void idAI::KickObstacles( const idVec3 &dir, float force, idEntity *alwaysKick ) ValidForBounds ============ */ -bool ValidForBounds( const idAASSettings *settings, const idBounds &bounds ) { +bool ValidForBounds(const idAASSettings* settings, const idBounds& bounds) { int i; - for ( i = 0; i < 3; i++ ) { - if ( bounds[0][i] < settings->boundingBoxes[0][0][i] ) { + for (i = 0; i < 3; i++) { + if (bounds[0][i] < settings->boundingBoxes[0][0][i]) { return false; } - if ( bounds[1][i] > settings->boundingBoxes[0][1][i] ) { + if (bounds[1][i] > settings->boundingBoxes[0][1][i]) { return false; } } @@ -1292,25 +1327,26 @@ bool ValidForBounds( const idAASSettings *settings, const idBounds &bounds ) { idAI::SetAAS ===================== */ -void idAI::SetAAS( void ) { +void idAI::SetAAS(void) { idStr use_aas; - spawnArgs.GetString( "use_aas", NULL, use_aas ); - aas = gameLocal.GetAAS( use_aas ); - if ( aas ) { - const idAASSettings *settings = aas->GetSettings(); - if ( settings ) { - if ( !ValidForBounds( settings, physicsObj.GetBounds() ) ) { - gameLocal.Error( "%s cannot use use_aas %s\n", name.c_str(), use_aas.c_str() ); + spawnArgs.GetString("use_aas", NULL, use_aas); + aas = gameLocal.GetAAS(use_aas); + if (aas) { + const idAASSettings* settings = aas->GetSettings(); + if (settings) { + if (!ValidForBounds(settings, physicsObj.GetBounds())) { + gameLocal.Error("%s cannot use use_aas %s\n", name.c_str(), use_aas.c_str()); } float height = settings->maxStepHeight; - physicsObj.SetMaxStepHeight( height ); + physicsObj.SetMaxStepHeight(height); return; - } else { + } + else { aas = NULL; } } - gameLocal.Printf( "WARNING: %s has no AAS file\n", name.c_str() ); + gameLocal.Printf("WARNING: %s has no AAS file\n", name.c_str()); } /* @@ -1318,12 +1354,13 @@ void idAI::SetAAS( void ) { idAI::DrawRoute ===================== */ -void idAI::DrawRoute( void ) const { - if ( aas && move.toAreaNum && move.moveCommand != MOVE_NONE && move.moveCommand != MOVE_WANDER && move.moveCommand != MOVE_FACE_ENEMY && move.moveCommand != MOVE_FACE_ENTITY && move.moveCommand != MOVE_TO_POSITION_DIRECT ) { - if ( move.moveType == MOVETYPE_FLY ) { - aas->ShowFlyPath( physicsObj.GetOrigin(), move.toAreaNum, move.moveDest ); - } else { - aas->ShowWalkPath( physicsObj.GetOrigin(), move.toAreaNum, move.moveDest ); +void idAI::DrawRoute(void) const { + if (aas && move.toAreaNum && move.moveCommand != MOVE_NONE && move.moveCommand != MOVE_WANDER && move.moveCommand != MOVE_FACE_ENEMY && move.moveCommand != MOVE_FACE_ENTITY && move.moveCommand != MOVE_TO_POSITION_DIRECT) { + if (move.moveType == MOVETYPE_FLY) { + aas->ShowFlyPath(physicsObj.GetOrigin(), move.toAreaNum, move.moveDest); + } + else { + aas->ShowWalkPath(physicsObj.GetOrigin(), move.toAreaNum, move.moveDest); } } } @@ -1333,22 +1370,24 @@ void idAI::DrawRoute( void ) const { idAI::ReachedPos ===================== */ -bool idAI::ReachedPos( const idVec3 &pos, const moveCommand_t moveCommand ) const { - if ( move.moveType == MOVETYPE_SLIDE ) { - idBounds bnds( idVec3( -4, -4.0f, -8.0f ), idVec3( 4.0f, 4.0f, 64.0f ) ); - bnds.TranslateSelf( physicsObj.GetOrigin() ); - if ( bnds.ContainsPoint( pos ) ) { +bool idAI::ReachedPos(const idVec3& pos, const moveCommand_t moveCommand) const { + if (move.moveType == MOVETYPE_SLIDE) { + idBounds bnds(idVec3(-4, -4.0f, -8.0f), idVec3(4.0f, 4.0f, 64.0f)); + bnds.TranslateSelf(physicsObj.GetOrigin()); + if (bnds.ContainsPoint(pos)) { return true; } - } else { - if ( ( moveCommand == MOVE_TO_ENEMY ) || ( moveCommand == MOVE_TO_ENTITY ) ) { - if ( physicsObj.GetAbsBounds().IntersectsBounds( idBounds( pos ).Expand( 8.0f ) ) ) { + } + else { + if ((moveCommand == MOVE_TO_ENEMY) || (moveCommand == MOVE_TO_ENTITY)) { + if (physicsObj.GetAbsBounds().IntersectsBounds(idBounds(pos).Expand(8.0f))) { return true; } - } else { - idBounds bnds( idVec3( -16.0, -16.0f, -8.0f ), idVec3( 16.0, 16.0f, 64.0f ) ); - bnds.TranslateSelf( physicsObj.GetOrigin() ); - if ( bnds.ContainsPoint( pos ) ) { + } + else { + idBounds bnds(idVec3(-16.0, -16.0f, -8.0f), idVec3(16.0, 16.0f, 64.0f)); + bnds.TranslateSelf(physicsObj.GetOrigin()); + if (bnds.ContainsPoint(pos)) { return true; } } @@ -1361,12 +1400,12 @@ bool idAI::ReachedPos( const idVec3 &pos, const moveCommand_t moveCommand ) cons idAI::PointReachableAreaNum ===================== */ -int idAI::PointReachableAreaNum( const idVec3 &pos, const float boundsScale ) const { +int idAI::PointReachableAreaNum(const idVec3& pos, const float boundsScale) const { int areaNum; idVec3 size; idBounds bounds; - if ( !aas ) { + if (!aas) { return 0; } @@ -1375,10 +1414,11 @@ int idAI::PointReachableAreaNum( const idVec3 &pos, const float boundsScale ) co size.z = 32.0f; bounds[1] = size; - if ( move.moveType == MOVETYPE_FLY ) { - areaNum = aas->PointReachableAreaNum( pos, bounds, AREA_REACHABLE_WALK | AREA_REACHABLE_FLY ); - } else { - areaNum = aas->PointReachableAreaNum( pos, bounds, AREA_REACHABLE_WALK ); + if (move.moveType == MOVETYPE_FLY) { + areaNum = aas->PointReachableAreaNum(pos, bounds, AREA_REACHABLE_WALK | AREA_REACHABLE_FLY); + } + else { + areaNum = aas->PointReachableAreaNum(pos, bounds, AREA_REACHABLE_WALK); } return areaNum; @@ -1389,30 +1429,31 @@ int idAI::PointReachableAreaNum( const idVec3 &pos, const float boundsScale ) co idAI::PathToGoal ===================== */ -bool idAI::PathToGoal( aasPath_t &path, int areaNum, const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin ) const { +bool idAI::PathToGoal(aasPath_t& path, int areaNum, const idVec3& origin, int goalAreaNum, const idVec3& goalOrigin) const { idVec3 org; idVec3 goal; - if ( !aas ) { + if (!aas) { return false; } org = origin; - aas->PushPointIntoAreaNum( areaNum, org ); - if ( !areaNum ) { + aas->PushPointIntoAreaNum(areaNum, org); + if (!areaNum) { return false; } goal = goalOrigin; - aas->PushPointIntoAreaNum( goalAreaNum, goal ); - if ( !goalAreaNum ) { + aas->PushPointIntoAreaNum(goalAreaNum, goal); + if (!goalAreaNum) { return false; } - if ( move.moveType == MOVETYPE_FLY ) { - return aas->FlyPathToGoal( path, areaNum, org, goalAreaNum, goal, travelFlags ); - } else { - return aas->WalkPathToGoal( path, areaNum, org, goalAreaNum, goal, travelFlags ); + if (move.moveType == MOVETYPE_FLY) { + return aas->FlyPathToGoal(path, areaNum, org, goalAreaNum, goal, travelFlags); + } + else { + return aas->WalkPathToGoal(path, areaNum, org, goalAreaNum, goal, travelFlags); } } @@ -1426,58 +1467,59 @@ This is feakin' slow, so it's not good to do it too many times per frame. It al are from the goal, so try to break the goals up into shorter distances. ===================== */ -float idAI::TravelDistance( const idVec3 &start, const idVec3 &end ) const { +float idAI::TravelDistance(const idVec3& start, const idVec3& end) const { int fromArea; int toArea; float dist; idVec2 delta; aasPath_t path; - if ( !aas ) { + if (!aas) { // no aas, so just take the straight line distance delta = end.ToVec2() - start.ToVec2(); dist = delta.LengthFast(); - if ( ai_debugMove.GetBool() ) { - gameRenderWorld->DebugLine( colorBlue, start, end, gameLocal.msec, false ); - gameRenderWorld->DrawText( va( "%d", ( int )dist ), ( start + end ) * 0.5f, 0.1f, colorWhite, gameLocal.GetLocalPlayer()->viewAngles.ToMat3() ); + if (ai_debugMove.GetBool()) { + gameRenderWorld->DebugLine(colorBlue, start, end, gameLocal.msec, false); + gameRenderWorld->DrawText(va("%d", (int)dist), (start + end) * 0.5f, 0.1f, colorWhite, gameLocal.GetLocalPlayer()->viewAngles.ToMat3()); } return dist; } - fromArea = PointReachableAreaNum( start ); - toArea = PointReachableAreaNum( end ); + fromArea = PointReachableAreaNum(start); + toArea = PointReachableAreaNum(end); - if ( !fromArea || !toArea ) { + if (!fromArea || !toArea) { // can't seem to get there return -1; } - if ( fromArea == toArea ) { + if (fromArea == toArea) { // same area, so just take the straight line distance delta = end.ToVec2() - start.ToVec2(); dist = delta.LengthFast(); - if ( ai_debugMove.GetBool() ) { - gameRenderWorld->DebugLine( colorBlue, start, end, gameLocal.msec, false ); - gameRenderWorld->DrawText( va( "%d", ( int )dist ), ( start + end ) * 0.5f, 0.1f, colorWhite, gameLocal.GetLocalPlayer()->viewAngles.ToMat3() ); + if (ai_debugMove.GetBool()) { + gameRenderWorld->DebugLine(colorBlue, start, end, gameLocal.msec, false); + gameRenderWorld->DrawText(va("%d", (int)dist), (start + end) * 0.5f, 0.1f, colorWhite, gameLocal.GetLocalPlayer()->viewAngles.ToMat3()); } return dist; } - idReachability *reach; + idReachability* reach; int travelTime; - if ( !aas->RouteToGoalArea( fromArea, start, toArea, travelFlags, travelTime, &reach ) ) { + if (!aas->RouteToGoalArea(fromArea, start, toArea, travelFlags, travelTime, &reach)) { return -1; } - if ( ai_debugMove.GetBool() ) { - if ( move.moveType == MOVETYPE_FLY ) { - aas->ShowFlyPath( start, toArea, end ); - } else { - aas->ShowWalkPath( start, toArea, end ); + if (ai_debugMove.GetBool()) { + if (move.moveType == MOVETYPE_FLY) { + aas->ShowFlyPath(start, toArea, end); + } + else { + aas->ShowWalkPath(start, toArea, end); } } @@ -1489,25 +1531,25 @@ float idAI::TravelDistance( const idVec3 &start, const idVec3 &end ) const { idAI::StopMove ===================== */ -void idAI::StopMove( moveStatus_t status ) { - AI_MOVE_DONE = true; - AI_FORWARD = false; - move.moveCommand = MOVE_NONE; - move.moveStatus = status; - move.toAreaNum = 0; - move.goalEntity = NULL; - move.moveDest = physicsObj.GetOrigin(); - AI_DEST_UNREACHABLE = false; +void idAI::StopMove(moveStatus_t status) { + AI_MOVE_DONE = true; + AI_FORWARD = false; + move.moveCommand = MOVE_NONE; + move.moveStatus = status; + move.toAreaNum = 0; + move.goalEntity = NULL; + move.moveDest = physicsObj.GetOrigin(); + AI_DEST_UNREACHABLE = false; AI_OBSTACLE_IN_PATH = false; - AI_BLOCKED = false; - move.startTime = gameLocal.time; - move.duration = 0; - move.range = 0.0f; - move.speed = 0.0f; - move.anim = 0; + AI_BLOCKED = false; + move.startTime = gameLocal.time; + move.duration = 0; + move.range = 0.0f; + move.speed = 0.0f; + move.anim = 0; move.moveDir.Zero(); move.lastMoveOrigin.Zero(); - move.lastMoveTime = gameLocal.time; + move.lastMoveTime = gameLocal.time; } /* @@ -1517,22 +1559,22 @@ idAI::FaceEnemy Continually face the enemy's last known position. MoveDone is always true in this case. ===================== */ -bool idAI::FaceEnemy( void ) { - idActor *enemyEnt = enemy.GetEntity(); - if ( !enemyEnt ) { - StopMove( MOVE_STATUS_DEST_NOT_FOUND ); +bool idAI::FaceEnemy(void) { + idActor* enemyEnt = enemy.GetEntity(); + if (!enemyEnt) { + StopMove(MOVE_STATUS_DEST_NOT_FOUND); return false; } - TurnToward( lastVisibleEnemyPos ); - move.goalEntity = enemyEnt; - move.moveDest = physicsObj.GetOrigin(); - move.moveCommand = MOVE_FACE_ENEMY; - move.moveStatus = MOVE_STATUS_WAITING; - move.startTime = gameLocal.time; - move.speed = 0.0f; - AI_MOVE_DONE = true; - AI_FORWARD = false; + TurnToward(lastVisibleEnemyPos); + move.goalEntity = enemyEnt; + move.moveDest = physicsObj.GetOrigin(); + move.moveCommand = MOVE_FACE_ENEMY; + move.moveStatus = MOVE_STATUS_WAITING; + move.startTime = gameLocal.time; + move.speed = 0.0f; + AI_MOVE_DONE = true; + AI_FORWARD = false; AI_DEST_UNREACHABLE = false; return true; @@ -1545,22 +1587,22 @@ idAI::FaceEntity Continually face the entity position. MoveDone is always true in this case. ===================== */ -bool idAI::FaceEntity( idEntity *ent ) { - if ( !ent ) { - StopMove( MOVE_STATUS_DEST_NOT_FOUND ); +bool idAI::FaceEntity(idEntity* ent) { + if (!ent) { + StopMove(MOVE_STATUS_DEST_NOT_FOUND); return false; } idVec3 entityOrg = ent->GetPhysics()->GetOrigin(); - TurnToward( entityOrg ); - move.goalEntity = ent; - move.moveDest = physicsObj.GetOrigin(); - move.moveCommand = MOVE_FACE_ENTITY; - move.moveStatus = MOVE_STATUS_WAITING; - move.startTime = gameLocal.time; - move.speed = 0.0f; - AI_MOVE_DONE = true; - AI_FORWARD = false; + TurnToward(entityOrg); + move.goalEntity = ent; + move.moveDest = physicsObj.GetOrigin(); + move.moveCommand = MOVE_FACE_ENTITY; + move.moveStatus = MOVE_STATUS_WAITING; + move.startTime = gameLocal.time; + move.speed = 0.0f; + AI_MOVE_DONE = true; + AI_FORWARD = false; AI_DEST_UNREACHABLE = false; return true; @@ -1571,27 +1613,27 @@ bool idAI::FaceEntity( idEntity *ent ) { idAI::DirectMoveToPosition ===================== */ -bool idAI::DirectMoveToPosition( const idVec3 &pos ) { - if ( ReachedPos( pos, move.moveCommand ) ) { - StopMove( MOVE_STATUS_DONE ); +bool idAI::DirectMoveToPosition(const idVec3& pos) { + if (ReachedPos(pos, move.moveCommand)) { + StopMove(MOVE_STATUS_DONE); return true; } - move.moveDest = pos; - move.goalEntity = NULL; - move.moveCommand = MOVE_TO_POSITION_DIRECT; - move.moveStatus = MOVE_STATUS_MOVING; - move.startTime = gameLocal.time; - move.speed = fly_speed; - AI_MOVE_DONE = false; + move.moveDest = pos; + move.goalEntity = NULL; + move.moveCommand = MOVE_TO_POSITION_DIRECT; + move.moveStatus = MOVE_STATUS_MOVING; + move.startTime = gameLocal.time; + move.speed = fly_speed; + AI_MOVE_DONE = false; AI_DEST_UNREACHABLE = false; - AI_FORWARD = true; + AI_FORWARD = true; - if ( move.moveType == MOVETYPE_FLY ) { + if (move.moveType == MOVETYPE_FLY) { idVec3 dir = pos - physicsObj.GetOrigin(); dir.Normalize(); dir *= fly_speed; - physicsObj.SetLinearVelocity( dir ); + physicsObj.SetLinearVelocity(dir); } return true; @@ -1602,23 +1644,23 @@ bool idAI::DirectMoveToPosition( const idVec3 &pos ) { idAI::MoveToEnemyHeight ===================== */ -bool idAI::MoveToEnemyHeight( void ) { - idActor *enemyEnt = enemy.GetEntity(); +bool idAI::MoveToEnemyHeight(void) { + idActor* enemyEnt = enemy.GetEntity(); - if ( !enemyEnt || ( move.moveType != MOVETYPE_FLY ) ) { - StopMove( MOVE_STATUS_DEST_NOT_FOUND ); + if (!enemyEnt || (move.moveType != MOVETYPE_FLY)) { + StopMove(MOVE_STATUS_DEST_NOT_FOUND); return false; } - move.moveDest.z = lastVisibleEnemyPos.z + enemyEnt->EyeOffset().z + fly_offset; - move.goalEntity = enemyEnt; - move.moveCommand = MOVE_TO_ENEMYHEIGHT; - move.moveStatus = MOVE_STATUS_MOVING; - move.startTime = gameLocal.time; - move.speed = 0.0f; - AI_MOVE_DONE = false; + move.moveDest.z = lastVisibleEnemyPos.z + enemyEnt->EyeOffset().z + fly_offset; + move.goalEntity = enemyEnt; + move.moveCommand = MOVE_TO_ENEMYHEIGHT; + move.moveStatus = MOVE_STATUS_MOVING; + move.startTime = gameLocal.time; + move.speed = 0.0f; + AI_MOVE_DONE = false; AI_DEST_UNREACHABLE = false; - AI_FORWARD = false; + AI_FORWARD = false; return true; } @@ -1628,69 +1670,69 @@ bool idAI::MoveToEnemyHeight( void ) { idAI::MoveToEnemy ===================== */ -bool idAI::MoveToEnemy( void ) { +bool idAI::MoveToEnemy(void) { int areaNum; aasPath_t path; - idActor *enemyEnt = enemy.GetEntity(); + idActor* enemyEnt = enemy.GetEntity(); - if ( !enemyEnt ) { - StopMove( MOVE_STATUS_DEST_NOT_FOUND ); + if (!enemyEnt) { + StopMove(MOVE_STATUS_DEST_NOT_FOUND); return false; } - if ( ReachedPos( lastVisibleReachableEnemyPos, MOVE_TO_ENEMY ) ) { - if ( !ReachedPos( lastVisibleEnemyPos, MOVE_TO_ENEMY ) || !AI_ENEMY_VISIBLE ) { - StopMove( MOVE_STATUS_DEST_UNREACHABLE ); + if (ReachedPos(lastVisibleReachableEnemyPos, MOVE_TO_ENEMY)) { + if (!ReachedPos(lastVisibleEnemyPos, MOVE_TO_ENEMY) || !AI_ENEMY_VISIBLE) { + StopMove(MOVE_STATUS_DEST_UNREACHABLE); AI_DEST_UNREACHABLE = true; return false; } - StopMove( MOVE_STATUS_DONE ); + StopMove(MOVE_STATUS_DONE); return true; } idVec3 pos = lastVisibleReachableEnemyPos; move.toAreaNum = 0; - if ( aas ) { - move.toAreaNum = PointReachableAreaNum( pos ); - aas->PushPointIntoAreaNum( move.toAreaNum, pos ); + if (aas) { + move.toAreaNum = PointReachableAreaNum(pos); + aas->PushPointIntoAreaNum(move.toAreaNum, pos); - areaNum = PointReachableAreaNum( physicsObj.GetOrigin() ); - if ( !PathToGoal( path, areaNum, physicsObj.GetOrigin(), move.toAreaNum, pos ) ) { + areaNum = PointReachableAreaNum(physicsObj.GetOrigin()); + if (!PathToGoal(path, areaNum, physicsObj.GetOrigin(), move.toAreaNum, pos)) { AI_DEST_UNREACHABLE = true; return false; } } - if ( !move.toAreaNum ) { + if (!move.toAreaNum) { // if only trying to update the enemy position - if ( move.moveCommand == MOVE_TO_ENEMY ) { - if ( !aas ) { + if (move.moveCommand == MOVE_TO_ENEMY) { + if (!aas) { // keep the move destination up to date for wandering move.moveDest = pos; } return false; } - if ( !NewWanderDir( pos ) ) { - StopMove( MOVE_STATUS_DEST_UNREACHABLE ); + if (!NewWanderDir(pos)) { + StopMove(MOVE_STATUS_DEST_UNREACHABLE); AI_DEST_UNREACHABLE = true; return false; } } - if ( move.moveCommand != MOVE_TO_ENEMY ) { - move.moveCommand = MOVE_TO_ENEMY; - move.startTime = gameLocal.time; + if (move.moveCommand != MOVE_TO_ENEMY) { + move.moveCommand = MOVE_TO_ENEMY; + move.startTime = gameLocal.time; } - move.moveDest = pos; - move.goalEntity = enemyEnt; - move.speed = fly_speed; - move.moveStatus = MOVE_STATUS_MOVING; - AI_MOVE_DONE = false; + move.moveDest = pos; + move.goalEntity = enemyEnt; + move.speed = fly_speed; + move.moveStatus = MOVE_STATUS_MOVING; + AI_MOVE_DONE = false; AI_DEST_UNREACHABLE = false; - AI_FORWARD = true; + AI_FORWARD = true; return true; } @@ -1700,68 +1742,68 @@ bool idAI::MoveToEnemy( void ) { idAI::MoveToEntity ===================== */ -bool idAI::MoveToEntity( idEntity *ent ) { +bool idAI::MoveToEntity(idEntity* ent) { int areaNum; aasPath_t path; idVec3 pos; - if ( !ent ) { - StopMove( MOVE_STATUS_DEST_NOT_FOUND ); + if (!ent) { + StopMove(MOVE_STATUS_DEST_NOT_FOUND); return false; } pos = ent->GetPhysics()->GetOrigin(); - if ( ( move.moveType != MOVETYPE_FLY ) && ( ( move.moveCommand != MOVE_TO_ENTITY ) || ( move.goalEntityOrigin != pos ) ) ) { - ent->GetFloorPos( 64.0f, pos ); + if ((move.moveType != MOVETYPE_FLY) && ((move.moveCommand != MOVE_TO_ENTITY) || (move.goalEntityOrigin != pos))) { + ent->GetFloorPos(64.0f, pos); } - if ( ReachedPos( pos, MOVE_TO_ENTITY ) ) { - StopMove( MOVE_STATUS_DONE ); + if (ReachedPos(pos, MOVE_TO_ENTITY)) { + StopMove(MOVE_STATUS_DONE); return true; } move.toAreaNum = 0; - if ( aas ) { - move.toAreaNum = PointReachableAreaNum( pos ); - aas->PushPointIntoAreaNum( move.toAreaNum, pos ); + if (aas) { + move.toAreaNum = PointReachableAreaNum(pos); + aas->PushPointIntoAreaNum(move.toAreaNum, pos); - areaNum = PointReachableAreaNum( physicsObj.GetOrigin() ); - if ( !PathToGoal( path, areaNum, physicsObj.GetOrigin(), move.toAreaNum, pos ) ) { + areaNum = PointReachableAreaNum(physicsObj.GetOrigin()); + if (!PathToGoal(path, areaNum, physicsObj.GetOrigin(), move.toAreaNum, pos)) { AI_DEST_UNREACHABLE = true; return false; } } - if ( !move.toAreaNum ) { + if (!move.toAreaNum) { // if only trying to update the entity position - if ( move.moveCommand == MOVE_TO_ENTITY ) { - if ( !aas ) { + if (move.moveCommand == MOVE_TO_ENTITY) { + if (!aas) { // keep the move destination up to date for wandering move.moveDest = pos; } return false; } - if ( !NewWanderDir( pos ) ) { - StopMove( MOVE_STATUS_DEST_UNREACHABLE ); + if (!NewWanderDir(pos)) { + StopMove(MOVE_STATUS_DEST_UNREACHABLE); AI_DEST_UNREACHABLE = true; return false; } } - if ( ( move.moveCommand != MOVE_TO_ENTITY ) || ( move.goalEntity.GetEntity() != ent ) ) { - move.startTime = gameLocal.time; - move.goalEntity = ent; - move.moveCommand = MOVE_TO_ENTITY; + if ((move.moveCommand != MOVE_TO_ENTITY) || (move.goalEntity.GetEntity() != ent)) { + move.startTime = gameLocal.time; + move.goalEntity = ent; + move.moveCommand = MOVE_TO_ENTITY; } - move.moveDest = pos; - move.goalEntityOrigin = ent->GetPhysics()->GetOrigin(); - move.moveStatus = MOVE_STATUS_MOVING; - move.speed = fly_speed; - AI_MOVE_DONE = false; - AI_DEST_UNREACHABLE = false; - AI_FORWARD = true; + move.moveDest = pos; + move.goalEntityOrigin = ent->GetPhysics()->GetOrigin(); + move.moveStatus = MOVE_STATUS_MOVING; + move.speed = fly_speed; + AI_MOVE_DONE = false; + AI_DEST_UNREACHABLE = false; + AI_FORWARD = true; return true; } @@ -1771,54 +1813,55 @@ bool idAI::MoveToEntity( idEntity *ent ) { idAI::MoveOutOfRange ===================== */ -bool idAI::MoveOutOfRange( idEntity *ent, float range ) { +bool idAI::MoveOutOfRange(idEntity* ent, float range) { int areaNum; aasObstacle_t obstacle; aasGoal_t goal; idBounds bounds; idVec3 pos; - if ( !aas || !ent ) { - StopMove( MOVE_STATUS_DEST_UNREACHABLE ); + if (!aas || !ent) { + StopMove(MOVE_STATUS_DEST_UNREACHABLE); AI_DEST_UNREACHABLE = true; return false; } - const idVec3 &org = physicsObj.GetOrigin(); - areaNum = PointReachableAreaNum( org ); + const idVec3& org = physicsObj.GetOrigin(); + areaNum = PointReachableAreaNum(org); // consider the entity the monster is getting close to as an obstacle obstacle.absBounds = ent->GetPhysics()->GetAbsBounds(); - if ( ent == enemy.GetEntity() ) { + if (ent == enemy.GetEntity()) { pos = lastVisibleEnemyPos; - } else { + } + else { pos = ent->GetPhysics()->GetOrigin(); } - idAASFindAreaOutOfRange findGoal( pos, range ); - if ( !aas->FindNearestGoal( goal, areaNum, org, pos, travelFlags, &obstacle, 1, findGoal ) ) { - StopMove( MOVE_STATUS_DEST_UNREACHABLE ); + idAASFindAreaOutOfRange findGoal(pos, range); + if (!aas->FindNearestGoal(goal, areaNum, org, pos, travelFlags, &obstacle, 1, findGoal)) { + StopMove(MOVE_STATUS_DEST_UNREACHABLE); AI_DEST_UNREACHABLE = true; return false; } - if ( ReachedPos( goal.origin, move.moveCommand ) ) { - StopMove( MOVE_STATUS_DONE ); + if (ReachedPos(goal.origin, move.moveCommand)) { + StopMove(MOVE_STATUS_DONE); return true; } - move.moveDest = goal.origin; - move.toAreaNum = goal.areaNum; - move.goalEntity = ent; - move.moveCommand = MOVE_OUT_OF_RANGE; - move.moveStatus = MOVE_STATUS_MOVING; - move.range = range; - move.speed = fly_speed; - move.startTime = gameLocal.time; - AI_MOVE_DONE = false; + move.moveDest = goal.origin; + move.toAreaNum = goal.areaNum; + move.goalEntity = ent; + move.moveCommand = MOVE_OUT_OF_RANGE; + move.moveStatus = MOVE_STATUS_MOVING; + move.range = range; + move.speed = fly_speed; + move.startTime = gameLocal.time; + AI_MOVE_DONE = false; AI_DEST_UNREACHABLE = false; - AI_FORWARD = true; + AI_FORWARD = true; return true; } @@ -1828,49 +1871,50 @@ bool idAI::MoveOutOfRange( idEntity *ent, float range ) { idAI::MoveToAttackPosition ===================== */ -bool idAI::MoveToAttackPosition( idEntity *ent, int attack_anim ) { +bool idAI::MoveToAttackPosition(idEntity* ent, int attack_anim) { int areaNum; aasObstacle_t obstacle; aasGoal_t goal; idBounds bounds; idVec3 pos; - if ( !aas || !ent ) { - StopMove( MOVE_STATUS_DEST_UNREACHABLE ); + if (!aas || !ent) { + StopMove(MOVE_STATUS_DEST_UNREACHABLE); AI_DEST_UNREACHABLE = true; return false; } - const idVec3 &org = physicsObj.GetOrigin(); - areaNum = PointReachableAreaNum( org ); + const idVec3& org = physicsObj.GetOrigin(); + areaNum = PointReachableAreaNum(org); // consider the entity the monster is getting close to as an obstacle obstacle.absBounds = ent->GetPhysics()->GetAbsBounds(); - if ( ent == enemy.GetEntity() ) { + if (ent == enemy.GetEntity()) { pos = lastVisibleEnemyPos; - } else { + } + else { pos = ent->GetPhysics()->GetOrigin(); } - idAASFindAttackPosition findGoal( this, physicsObj.GetGravityAxis(), ent, pos, missileLaunchOffset[ attack_anim ] ); - if ( !aas->FindNearestGoal( goal, areaNum, org, pos, travelFlags, &obstacle, 1, findGoal ) ) { - StopMove( MOVE_STATUS_DEST_UNREACHABLE ); + idAASFindAttackPosition findGoal(this, physicsObj.GetGravityAxis(), ent, pos, missileLaunchOffset[attack_anim]); + if (!aas->FindNearestGoal(goal, areaNum, org, pos, travelFlags, &obstacle, 1, findGoal)) { + StopMove(MOVE_STATUS_DEST_UNREACHABLE); AI_DEST_UNREACHABLE = true; return false; } - move.moveDest = goal.origin; - move.toAreaNum = goal.areaNum; - move.goalEntity = ent; - move.moveCommand = MOVE_TO_ATTACK_POSITION; - move.moveStatus = MOVE_STATUS_MOVING; - move.speed = fly_speed; - move.startTime = gameLocal.time; - move.anim = attack_anim; - AI_MOVE_DONE = false; + move.moveDest = goal.origin; + move.toAreaNum = goal.areaNum; + move.goalEntity = ent; + move.moveCommand = MOVE_TO_ATTACK_POSITION; + move.moveStatus = MOVE_STATUS_MOVING; + move.speed = fly_speed; + move.startTime = gameLocal.time; + move.anim = attack_anim; + AI_MOVE_DONE = false; AI_DEST_UNREACHABLE = false; - AI_FORWARD = true; + AI_FORWARD = true; return true; } @@ -1880,45 +1924,45 @@ bool idAI::MoveToAttackPosition( idEntity *ent, int attack_anim ) { idAI::MoveToPosition ===================== */ -bool idAI::MoveToPosition( const idVec3 &pos ) { +bool idAI::MoveToPosition(const idVec3& pos) { idVec3 org; int areaNum; aasPath_t path; - if ( ReachedPos( pos, move.moveCommand ) ) { - StopMove( MOVE_STATUS_DONE ); + if (ReachedPos(pos, move.moveCommand)) { + StopMove(MOVE_STATUS_DONE); return true; } org = pos; move.toAreaNum = 0; - if ( aas ) { - move.toAreaNum = PointReachableAreaNum( org ); - aas->PushPointIntoAreaNum( move.toAreaNum, org ); + if (aas) { + move.toAreaNum = PointReachableAreaNum(org); + aas->PushPointIntoAreaNum(move.toAreaNum, org); - areaNum = PointReachableAreaNum( physicsObj.GetOrigin() ); - if ( !PathToGoal( path, areaNum, physicsObj.GetOrigin(), move.toAreaNum, org ) ) { - StopMove( MOVE_STATUS_DEST_UNREACHABLE ); + areaNum = PointReachableAreaNum(physicsObj.GetOrigin()); + if (!PathToGoal(path, areaNum, physicsObj.GetOrigin(), move.toAreaNum, org)) { + StopMove(MOVE_STATUS_DEST_UNREACHABLE); AI_DEST_UNREACHABLE = true; return false; } } - if ( !move.toAreaNum && !NewWanderDir( org ) ) { - StopMove( MOVE_STATUS_DEST_UNREACHABLE ); + if (!move.toAreaNum && !NewWanderDir(org)) { + StopMove(MOVE_STATUS_DEST_UNREACHABLE); AI_DEST_UNREACHABLE = true; return false; } - move.moveDest = org; - move.goalEntity = NULL; - move.moveCommand = MOVE_TO_POSITION; - move.moveStatus = MOVE_STATUS_MOVING; - move.startTime = gameLocal.time; - move.speed = fly_speed; - AI_MOVE_DONE = false; + move.moveDest = org; + move.goalEntity = NULL; + move.moveCommand = MOVE_TO_POSITION; + move.moveStatus = MOVE_STATUS_MOVING; + move.startTime = gameLocal.time; + move.speed = fly_speed; + AI_MOVE_DONE = false; AI_DEST_UNREACHABLE = false; - AI_FORWARD = true; + AI_FORWARD = true; return true; } @@ -1928,46 +1972,46 @@ bool idAI::MoveToPosition( const idVec3 &pos ) { idAI::MoveToCover ===================== */ -bool idAI::MoveToCover( idEntity *entity, const idVec3 &hideFromPos ) { +bool idAI::MoveToCover(idEntity* entity, const idVec3& hideFromPos) { int areaNum; aasObstacle_t obstacle; aasGoal_t hideGoal; idBounds bounds; - if ( !aas || !entity ) { - StopMove( MOVE_STATUS_DEST_UNREACHABLE ); + if (!aas || !entity) { + StopMove(MOVE_STATUS_DEST_UNREACHABLE); AI_DEST_UNREACHABLE = true; return false; } - const idVec3 &org = physicsObj.GetOrigin(); - areaNum = PointReachableAreaNum( org ); + const idVec3& org = physicsObj.GetOrigin(); + areaNum = PointReachableAreaNum(org); // consider the entity the monster tries to hide from as an obstacle obstacle.absBounds = entity->GetPhysics()->GetAbsBounds(); - idAASFindCover findCover( hideFromPos ); - if ( !aas->FindNearestGoal( hideGoal, areaNum, org, hideFromPos, travelFlags, &obstacle, 1, findCover ) ) { - StopMove( MOVE_STATUS_DEST_UNREACHABLE ); + idAASFindCover findCover(hideFromPos); + if (!aas->FindNearestGoal(hideGoal, areaNum, org, hideFromPos, travelFlags, &obstacle, 1, findCover)) { + StopMove(MOVE_STATUS_DEST_UNREACHABLE); AI_DEST_UNREACHABLE = true; return false; } - if ( ReachedPos( hideGoal.origin, move.moveCommand ) ) { - StopMove( MOVE_STATUS_DONE ); + if (ReachedPos(hideGoal.origin, move.moveCommand)) { + StopMove(MOVE_STATUS_DONE); return true; } - move.moveDest = hideGoal.origin; - move.toAreaNum = hideGoal.areaNum; - move.goalEntity = entity; - move.moveCommand = MOVE_TO_COVER; - move.moveStatus = MOVE_STATUS_MOVING; - move.startTime = gameLocal.time; - move.speed = fly_speed; - AI_MOVE_DONE = false; + move.moveDest = hideGoal.origin; + move.toAreaNum = hideGoal.areaNum; + move.goalEntity = entity; + move.moveCommand = MOVE_TO_COVER; + move.moveStatus = MOVE_STATUS_MOVING; + move.startTime = gameLocal.time; + move.speed = fly_speed; + AI_MOVE_DONE = false; AI_DEST_UNREACHABLE = false; - AI_FORWARD = true; + AI_FORWARD = true; return true; } @@ -1977,22 +2021,22 @@ bool idAI::MoveToCover( idEntity *entity, const idVec3 &hideFromPos ) { idAI::SlideToPosition ===================== */ -bool idAI::SlideToPosition( const idVec3 &pos, float time ) { - StopMove( MOVE_STATUS_DONE ); +bool idAI::SlideToPosition(const idVec3& pos, float time) { + StopMove(MOVE_STATUS_DONE); - move.moveDest = pos; - move.goalEntity = NULL; - move.moveCommand = MOVE_SLIDE_TO_POSITION; - move.moveStatus = MOVE_STATUS_MOVING; - move.startTime = gameLocal.time; - move.duration = idPhysics::SnapTimeToPhysicsFrame( SEC2MS( time ) ); - AI_MOVE_DONE = false; + move.moveDest = pos; + move.goalEntity = NULL; + move.moveCommand = MOVE_SLIDE_TO_POSITION; + move.moveStatus = MOVE_STATUS_MOVING; + move.startTime = gameLocal.time; + move.duration = idPhysics::SnapTimeToPhysicsFrame(SEC2MS(time)); + AI_MOVE_DONE = false; AI_DEST_UNREACHABLE = false; - AI_FORWARD = false; + AI_FORWARD = false; - if ( move.duration > 0 ) { - move.moveDir = ( pos - physicsObj.GetOrigin() ) / MS2SEC( move.duration ); - if ( move.moveType != MOVETYPE_FLY ) { + if (move.duration > 0) { + move.moveDir = (pos - physicsObj.GetOrigin()) / MS2SEC(move.duration); + if (move.moveType != MOVETYPE_FLY) { move.moveDir.z = 0.0f; } move.speed = move.moveDir.LengthFast(); @@ -2006,22 +2050,22 @@ bool idAI::SlideToPosition( const idVec3 &pos, float time ) { idAI::WanderAround ===================== */ -bool idAI::WanderAround( void ) { - StopMove( MOVE_STATUS_DONE ); - - move.moveDest = physicsObj.GetOrigin() + viewAxis[ 0 ] * physicsObj.GetGravityAxis() * 256.0f; - if ( !NewWanderDir( move.moveDest ) ) { - StopMove( MOVE_STATUS_DEST_UNREACHABLE ); +bool idAI::WanderAround(void) { + StopMove(MOVE_STATUS_DONE); + + move.moveDest = physicsObj.GetOrigin() + viewAxis[0] * physicsObj.GetGravityAxis() * 256.0f; + if (!NewWanderDir(move.moveDest)) { + StopMove(MOVE_STATUS_DEST_UNREACHABLE); AI_DEST_UNREACHABLE = true; return false; } - move.moveCommand = MOVE_WANDER; - move.moveStatus = MOVE_STATUS_MOVING; - move.startTime = gameLocal.time; - move.speed = fly_speed; - AI_MOVE_DONE = false; - AI_FORWARD = true; + move.moveCommand = MOVE_WANDER; + move.moveStatus = MOVE_STATUS_MOVING; + move.startTime = gameLocal.time; + move.speed = fly_speed; + AI_MOVE_DONE = false; + AI_FORWARD = true; return true; } @@ -2031,8 +2075,8 @@ bool idAI::WanderAround( void ) { idAI::MoveDone ===================== */ -bool idAI::MoveDone( void ) const { - return ( move.moveCommand == MOVE_NONE ); +bool idAI::MoveDone(void) const { + return (move.moveCommand == MOVE_NONE); } /* @@ -2040,53 +2084,54 @@ bool idAI::MoveDone( void ) const { idAI::StepDirection ================ */ -bool idAI::StepDirection( float dir ) { +bool idAI::StepDirection(float dir) { predictedPath_t path; idVec3 org; move.wanderYaw = dir; - move.moveDir = idAngles( 0, move.wanderYaw, 0 ).ToForward(); + move.moveDir = idAngles(0, move.wanderYaw, 0).ToForward(); org = physicsObj.GetOrigin(); - idAI::PredictPath( this, aas, org, move.moveDir * 48.0f, 1000, 1000, ( move.moveType == MOVETYPE_FLY ) ? SE_BLOCKED : ( SE_ENTER_OBSTACLE | SE_BLOCKED | SE_ENTER_LEDGE_AREA ), path ); + idAI::PredictPath(this, aas, org, move.moveDir * 48.0f, 1000, 1000, (move.moveType == MOVETYPE_FLY) ? SE_BLOCKED : (SE_ENTER_OBSTACLE | SE_BLOCKED | SE_ENTER_LEDGE_AREA), path); - if ( path.blockingEntity && ( ( move.moveCommand == MOVE_TO_ENEMY ) || ( move.moveCommand == MOVE_TO_ENTITY ) ) && ( path.blockingEntity == move.goalEntity.GetEntity() ) ) { + if (path.blockingEntity && ((move.moveCommand == MOVE_TO_ENEMY) || (move.moveCommand == MOVE_TO_ENTITY)) && (path.blockingEntity == move.goalEntity.GetEntity())) { // don't report being blocked if we ran into our goal entity return true; } - if ( ( move.moveType == MOVETYPE_FLY ) && ( path.endEvent == SE_BLOCKED ) ) { + if ((move.moveType == MOVETYPE_FLY) && (path.endEvent == SE_BLOCKED)) { float z; move.moveDir = path.endVelocity * 1.0f / 48.0f; // trace down to the floor and see if we can go forward - idAI::PredictPath( this, aas, org, idVec3( 0.0f, 0.0f, -1024.0f ), 1000, 1000, SE_BLOCKED, path ); + idAI::PredictPath(this, aas, org, idVec3(0.0f, 0.0f, -1024.0f), 1000, 1000, SE_BLOCKED, path); idVec3 floorPos = path.endPos; - idAI::PredictPath( this, aas, floorPos, move.moveDir * 48.0f, 1000, 1000, SE_BLOCKED, path ); - if ( !path.endEvent ) { + idAI::PredictPath(this, aas, floorPos, move.moveDir * 48.0f, 1000, 1000, SE_BLOCKED, path); + if (!path.endEvent) { move.moveDir.z = -1.0f; return true; } // trace up to see if we can go over something and go forward - idAI::PredictPath( this, aas, org, idVec3( 0.0f, 0.0f, 256.0f ), 1000, 1000, SE_BLOCKED, path ); + idAI::PredictPath(this, aas, org, idVec3(0.0f, 0.0f, 256.0f), 1000, 1000, SE_BLOCKED, path); idVec3 ceilingPos = path.endPos; - for( z = org.z; z <= ceilingPos.z + 64.0f; z += 64.0f ) { + for (z = org.z; z <= ceilingPos.z + 64.0f; z += 64.0f) { idVec3 start; - if ( z <= ceilingPos.z ) { + if (z <= ceilingPos.z) { start.x = org.x; start.y = org.y; - start.z = z; - } else { + start.z = z; + } + else { start = ceilingPos; } - idAI::PredictPath( this, aas, start, move.moveDir * 48.0f, 1000, 1000, SE_BLOCKED, path ); - if ( !path.endEvent ) { + idAI::PredictPath(this, aas, start, move.moveDir * 48.0f, 1000, 1000, SE_BLOCKED, path); + if (!path.endEvent) { move.moveDir.z = 1.0f; return true; } @@ -2094,7 +2139,7 @@ bool idAI::StepDirection( float dir ) { return false; } - return ( path.endEvent == 0 ); + return (path.endEvent == 0); } /* @@ -2102,89 +2147,95 @@ bool idAI::StepDirection( float dir ) { idAI::NewWanderDir ================ */ -bool idAI::NewWanderDir( const idVec3 &dest ) { +bool idAI::NewWanderDir(const idVec3& dest) { float deltax, deltay; - float d[ 3 ]; + float d[3]; float tdir, olddir, turnaround; - move.nextWanderTime = gameLocal.time + ( gameLocal.random.RandomFloat() * 500 + 500 ); + move.nextWanderTime = gameLocal.time + (gameLocal.random.RandomFloat() * 500 + 500); - olddir = idMath::AngleNormalize360( ( int )( current_yaw / 45 ) * 45 ); - turnaround = idMath::AngleNormalize360( olddir - 180 ); + olddir = idMath::AngleNormalize360((int)(current_yaw / 45) * 45); + turnaround = idMath::AngleNormalize360(olddir - 180); idVec3 org = physicsObj.GetOrigin(); deltax = dest.x - org.x; deltay = dest.y - org.y; - if ( deltax > 10 ) { - d[ 1 ]= 0; - } else if ( deltax < -10 ) { - d[ 1 ] = 180; - } else { - d[ 1 ] = DI_NODIR; + if (deltax > 10) { + d[1] = 0; + } + else if (deltax < -10) { + d[1] = 180; + } + else { + d[1] = DI_NODIR; } - if ( deltay < -10 ) { - d[ 2 ] = 270; - } else if ( deltay > 10 ) { - d[ 2 ] = 90; - } else { - d[ 2 ] = DI_NODIR; + if (deltay < -10) { + d[2] = 270; + } + else if (deltay > 10) { + d[2] = 90; + } + else { + d[2] = DI_NODIR; } // try direct route - if ( d[ 1 ] != DI_NODIR && d[ 2 ] != DI_NODIR ) { - if ( d[ 1 ] == 0 ) { - tdir = d[ 2 ] == 90 ? 45 : 315; - } else { - tdir = d[ 2 ] == 90 ? 135 : 215; + if (d[1] != DI_NODIR && d[2] != DI_NODIR) { + if (d[1] == 0) { + tdir = d[2] == 90 ? 45 : 315; + } + else { + tdir = d[2] == 90 ? 135 : 215; } - if ( tdir != turnaround && StepDirection( tdir ) ) { + if (tdir != turnaround && StepDirection(tdir)) { return true; } } // try other directions - if ( ( gameLocal.random.RandomInt() & 1 ) || abs( deltay ) > abs( deltax ) ) { - tdir = d[ 1 ]; - d[ 1 ] = d[ 2 ]; - d[ 2 ] = tdir; + if ((gameLocal.random.RandomInt() & 1) || abs(deltay) > abs(deltax)) { + tdir = d[1]; + d[1] = d[2]; + d[2] = tdir; } - if ( d[ 1 ] != DI_NODIR && d[ 1 ] != turnaround && StepDirection( d[1] ) ) { + if (d[1] != DI_NODIR && d[1] != turnaround && StepDirection(d[1])) { return true; } - if ( d[ 2 ] != DI_NODIR && d[ 2 ] != turnaround && StepDirection( d[ 2 ] ) ) { + if (d[2] != DI_NODIR && d[2] != turnaround && StepDirection(d[2])) { return true; } // there is no direct path to the player, so pick another direction - if ( olddir != DI_NODIR && StepDirection( olddir ) ) { + if (olddir != DI_NODIR && StepDirection(olddir)) { return true; } - // randomly determine direction of search - if ( gameLocal.random.RandomInt() & 1 ) { - for( tdir = 0; tdir <= 315; tdir += 45 ) { - if ( tdir != turnaround && StepDirection( tdir ) ) { - return true; + // randomly determine direction of search + if (gameLocal.random.RandomInt() & 1) { + for (tdir = 0; tdir <= 315; tdir += 45) { + if (tdir != turnaround && StepDirection(tdir)) { + return true; } } - } else { - for ( tdir = 315; tdir >= 0; tdir -= 45 ) { - if ( tdir != turnaround && StepDirection( tdir ) ) { + } + else { + for (tdir = 315; tdir >= 0; tdir -= 45) { + if (tdir != turnaround && StepDirection(tdir)) { return true; } } } - if ( turnaround != DI_NODIR && StepDirection( turnaround ) ) { + if (turnaround != DI_NODIR && StepDirection(turnaround)) { return true; } // can't move - StopMove( MOVE_STATUS_DEST_UNREACHABLE ); + StopMove(MOVE_STATUS_DEST_UNREACHABLE); return false; } @@ -2193,7 +2244,7 @@ bool idAI::NewWanderDir( const idVec3 &dest ) { idAI::GetMovePos ===================== */ -bool idAI::GetMovePos( idVec3 &seekPos ) { +bool idAI::GetMovePos(idVec3& seekPos) { int areaNum; aasPath_t path; bool result; @@ -2202,85 +2253,89 @@ bool idAI::GetMovePos( idVec3 &seekPos ) { org = physicsObj.GetOrigin(); seekPos = org; - switch( move.moveCommand ) { - case MOVE_NONE : + switch (move.moveCommand) { + case MOVE_NONE: seekPos = move.moveDest; return false; break; - case MOVE_FACE_ENEMY : - case MOVE_FACE_ENTITY : + case MOVE_FACE_ENEMY: + case MOVE_FACE_ENTITY: seekPos = move.moveDest; return false; break; - case MOVE_TO_POSITION_DIRECT : + case MOVE_TO_POSITION_DIRECT: seekPos = move.moveDest; - if ( ReachedPos( move.moveDest, move.moveCommand ) ) { - StopMove( MOVE_STATUS_DONE ); + if (ReachedPos(move.moveDest, move.moveCommand)) { + StopMove(MOVE_STATUS_DONE); } return false; break; - - case MOVE_SLIDE_TO_POSITION : + + case MOVE_SLIDE_TO_POSITION: seekPos = org; return false; break; } - if ( move.moveCommand == MOVE_TO_ENTITY ) { - MoveToEntity( move.goalEntity.GetEntity() ); + if (move.moveCommand == MOVE_TO_ENTITY) { + MoveToEntity(move.goalEntity.GetEntity()); } move.moveStatus = MOVE_STATUS_MOVING; result = false; - if ( gameLocal.time > move.blockTime ) { - if ( move.moveCommand == MOVE_WANDER ) { - move.moveDest = org + viewAxis[ 0 ] * physicsObj.GetGravityAxis() * 256.0f; - } else { - if ( ReachedPos( move.moveDest, move.moveCommand ) ) { - StopMove( MOVE_STATUS_DONE ); - seekPos = org; + if (gameLocal.time > move.blockTime) { + if (move.moveCommand == MOVE_WANDER) { + move.moveDest = org + viewAxis[0] * physicsObj.GetGravityAxis() * 256.0f; + } + else { + if (ReachedPos(move.moveDest, move.moveCommand)) { + StopMove(MOVE_STATUS_DONE); + seekPos = org; return false; } } - if ( aas && move.toAreaNum ) { - areaNum = PointReachableAreaNum( org ); - if ( PathToGoal( path, areaNum, org, move.toAreaNum, move.moveDest ) ) { + if (aas && move.toAreaNum) { + areaNum = PointReachableAreaNum(org); + if (PathToGoal(path, areaNum, org, move.toAreaNum, move.moveDest)) { seekPos = path.moveGoal; result = true; move.nextWanderTime = 0; - } else { + } + else { AI_DEST_UNREACHABLE = true; } } } - if ( !result ) { + if (!result) { // wander around - if ( ( gameLocal.time > move.nextWanderTime ) || !StepDirection( move.wanderYaw ) ) { - result = NewWanderDir( move.moveDest ); - if ( !result ) { - StopMove( MOVE_STATUS_DEST_UNREACHABLE ); + if ((gameLocal.time > move.nextWanderTime) || !StepDirection(move.wanderYaw)) { + result = NewWanderDir(move.moveDest); + if (!result) { + StopMove(MOVE_STATUS_DEST_UNREACHABLE); AI_DEST_UNREACHABLE = true; - seekPos = org; + seekPos = org; return false; } - } else { + } + else { result = true; } seekPos = org + move.moveDir * 2048.0f; - if ( ai_debugMove.GetBool() ) { - gameRenderWorld->DebugLine( colorYellow, org, seekPos, gameLocal.msec, true ); + if (ai_debugMove.GetBool()) { + gameRenderWorld->DebugLine(colorYellow, org, seekPos, gameLocal.msec, true); } - } else { + } + else { AI_DEST_UNREACHABLE = false; } - if ( result && ( ai_debugMove.GetBool() ) ) { - gameRenderWorld->DebugLine( colorCyan, physicsObj.GetOrigin(), seekPos ); + if (result && (ai_debugMove.GetBool())) { + gameRenderWorld->DebugLine(colorCyan, physicsObj.GetOrigin(), seekPos); } return result; @@ -2291,19 +2346,19 @@ bool idAI::GetMovePos( idVec3 &seekPos ) { idAI::EntityCanSeePos ===================== */ -bool idAI::EntityCanSeePos( idActor *actor, const idVec3 &actorOrigin, const idVec3 &pos ) { +bool idAI::EntityCanSeePos(idActor* actor, const idVec3& actorOrigin, const idVec3& pos) { idVec3 eye, point; trace_t results; pvsHandle_t handle; - handle = gameLocal.pvs.SetupCurrentPVS( actor->GetPVSAreas(), actor->GetNumPVSAreas() ); + handle = gameLocal.pvs.SetupCurrentPVS(actor->GetPVSAreas(), actor->GetNumPVSAreas()); - if ( !gameLocal.pvs.InCurrentPVS( handle, GetPVSAreas(), GetNumPVSAreas() ) ) { - gameLocal.pvs.FreeCurrentPVS( handle ); + if (!gameLocal.pvs.InCurrentPVS(handle, GetPVSAreas(), GetNumPVSAreas())) { + gameLocal.pvs.FreeCurrentPVS(handle); return false; } - gameLocal.pvs.FreeCurrentPVS( handle ); + gameLocal.pvs.FreeCurrentPVS(handle); eye = actorOrigin + actor->EyeOffset(); @@ -2312,18 +2367,18 @@ bool idAI::EntityCanSeePos( idActor *actor, const idVec3 &actorOrigin, const idV physicsObj.DisableClip(); - gameLocal.clip.TracePoint( results, eye, point, MASK_SOLID, actor ); - if ( results.fraction >= 1.0f || ( gameLocal.GetTraceEntity( results ) == this ) ) { + gameLocal.clip.TracePoint(results, eye, point, MASK_SOLID, actor); + if (results.fraction >= 1.0f || (gameLocal.GetTraceEntity(results) == this)) { physicsObj.EnableClip(); return true; } - const idBounds &bounds = physicsObj.GetBounds(); + const idBounds& bounds = physicsObj.GetBounds(); point[2] += bounds[1][2] - bounds[0][2]; - gameLocal.clip.TracePoint( results, eye, point, MASK_SOLID, actor ); + gameLocal.clip.TracePoint(results, eye, point, MASK_SOLID, actor); physicsObj.EnableClip(); - if ( results.fraction >= 1.0f || ( gameLocal.GetTraceEntity( results ) == this ) ) { + if (results.fraction >= 1.0f || (gameLocal.GetTraceEntity(results) == this)) { return true; } return false; @@ -2334,17 +2389,17 @@ bool idAI::EntityCanSeePos( idActor *actor, const idVec3 &actorOrigin, const idV idAI::BlockedFailSafe ===================== */ -void idAI::BlockedFailSafe( void ) { - if ( !ai_blockedFailSafe.GetBool() || blockedRadius < 0.0f ) { +void idAI::BlockedFailSafe(void) { + if (!ai_blockedFailSafe.GetBool() || blockedRadius < 0.0f) { return; } - if ( !physicsObj.OnGround() || enemy.GetEntity() == NULL || - ( physicsObj.GetOrigin() - move.lastMoveOrigin ).LengthSqr() > Square( blockedRadius ) ) { + if (!physicsObj.OnGround() || enemy.GetEntity() == NULL || + (physicsObj.GetOrigin() - move.lastMoveOrigin).LengthSqr() > Square(blockedRadius)) { move.lastMoveOrigin = physicsObj.GetOrigin(); move.lastMoveTime = gameLocal.time; } - if ( move.lastMoveTime < gameLocal.time - blockedMoveTime ) { - if ( lastAttackTime < gameLocal.time - blockedAttackTime ) { + if (move.lastMoveTime < gameLocal.time - blockedMoveTime) { + if (lastAttackTime < gameLocal.time - blockedAttackTime) { AI_BLOCKED = true; move.lastMoveTime = gameLocal.time; } @@ -2362,70 +2417,74 @@ void idAI::BlockedFailSafe( void ) { idAI::Turn ===================== */ -void idAI::Turn( void ) { +void idAI::Turn(void) { float diff; float diff2; float turnAmount; animFlags_t animflags; - if ( !turnRate ) { + if (!turnRate) { return; } // check if the animator has marker this anim as non-turning - if ( !legsAnim.Disabled() && !legsAnim.AnimDone( 0 ) ) { + if (!legsAnim.Disabled() && !legsAnim.AnimDone(0)) { animflags = legsAnim.GetAnimFlags(); - } else { + } + else { animflags = torsoAnim.GetAnimFlags(); } - if ( animflags.ai_no_turn ) { + if (animflags.ai_no_turn) { return; } - if ( anim_turn_angles && animflags.anim_turn ) { + if (anim_turn_angles && animflags.anim_turn) { idMat3 rotateAxis; // set the blend between no turn and full turn float frac = anim_turn_amount / anim_turn_angles; - animator.CurrentAnim( ANIMCHANNEL_LEGS )->SetSyncedAnimWeight( 0, 1.0f - frac ); - animator.CurrentAnim( ANIMCHANNEL_LEGS )->SetSyncedAnimWeight( 1, frac ); - animator.CurrentAnim( ANIMCHANNEL_TORSO )->SetSyncedAnimWeight( 0, 1.0f - frac ); - animator.CurrentAnim( ANIMCHANNEL_TORSO )->SetSyncedAnimWeight( 1, frac ); + animator.CurrentAnim(ANIMCHANNEL_LEGS)->SetSyncedAnimWeight(0, 1.0f - frac); + animator.CurrentAnim(ANIMCHANNEL_LEGS)->SetSyncedAnimWeight(1, frac); + animator.CurrentAnim(ANIMCHANNEL_TORSO)->SetSyncedAnimWeight(0, 1.0f - frac); + animator.CurrentAnim(ANIMCHANNEL_TORSO)->SetSyncedAnimWeight(1, frac); // get the total rotation from the start of the anim - animator.GetDeltaRotation( 0, gameLocal.time, rotateAxis ); - current_yaw = idMath::AngleNormalize180( anim_turn_yaw + rotateAxis[ 0 ].ToYaw() ); - } else { - diff = idMath::AngleNormalize180( ideal_yaw - current_yaw ); - turnVel += AI_TURN_SCALE * diff * MS2SEC( gameLocal.msec ); - if ( turnVel > turnRate ) { + animator.GetDeltaRotation(0, gameLocal.time, rotateAxis); + current_yaw = idMath::AngleNormalize180(anim_turn_yaw + rotateAxis[0].ToYaw()); + } + else { + diff = idMath::AngleNormalize180(ideal_yaw - current_yaw); + turnVel += AI_TURN_SCALE * diff * MS2SEC(gameLocal.msec); + if (turnVel > turnRate) { turnVel = turnRate; - } else if ( turnVel < -turnRate ) { + } + else if (turnVel < -turnRate) { turnVel = -turnRate; } - turnAmount = turnVel * MS2SEC( gameLocal.msec ); - if ( ( diff >= 0.0f ) && ( turnAmount >= diff ) ) { - turnVel = diff / MS2SEC( gameLocal.msec ); + turnAmount = turnVel * MS2SEC(gameLocal.msec); + if ((diff >= 0.0f) && (turnAmount >= diff)) { + turnVel = diff / MS2SEC(gameLocal.msec); turnAmount = diff; - } else if ( ( diff <= 0.0f ) && ( turnAmount <= diff ) ) { - turnVel = diff / MS2SEC( gameLocal.msec ); + } + else if ((diff <= 0.0f) && (turnAmount <= diff)) { + turnVel = diff / MS2SEC(gameLocal.msec); turnAmount = diff; } current_yaw += turnAmount; - current_yaw = idMath::AngleNormalize180( current_yaw ); - diff2 = idMath::AngleNormalize180( ideal_yaw - current_yaw ); - if ( idMath::Fabs( diff2 ) < 0.1f ) { + current_yaw = idMath::AngleNormalize180(current_yaw); + diff2 = idMath::AngleNormalize180(ideal_yaw - current_yaw); + if (idMath::Fabs(diff2) < 0.1f) { current_yaw = ideal_yaw; } } - viewAxis = idAngles( 0, current_yaw, 0 ).ToMat3(); + viewAxis = idAngles(0, current_yaw, 0).ToMat3(); - if ( ai_debugMove.GetBool() ) { - const idVec3 &org = physicsObj.GetOrigin(); - gameRenderWorld->DebugLine( colorRed, org, org + idAngles( 0, ideal_yaw, 0 ).ToForward() * 64, gameLocal.msec ); - gameRenderWorld->DebugLine( colorGreen, org, org + idAngles( 0, current_yaw, 0 ).ToForward() * 48, gameLocal.msec ); - gameRenderWorld->DebugLine( colorYellow, org, org + idAngles( 0, current_yaw + turnVel, 0 ).ToForward() * 32, gameLocal.msec ); + if (ai_debugMove.GetBool()) { + const idVec3& org = physicsObj.GetOrigin(); + gameRenderWorld->DebugLine(colorRed, org, org + idAngles(0, ideal_yaw, 0).ToForward() * 64, gameLocal.msec); + gameRenderWorld->DebugLine(colorGreen, org, org + idAngles(0, current_yaw, 0).ToForward() * 48, gameLocal.msec); + gameRenderWorld->DebugLine(colorYellow, org, org + idAngles(0, current_yaw + turnVel, 0).ToForward() * 32, gameLocal.msec); } } @@ -2434,15 +2493,15 @@ void idAI::Turn( void ) { idAI::FacingIdeal ===================== */ -bool idAI::FacingIdeal( void ) { +bool idAI::FacingIdeal(void) { float diff; - if ( !turnRate ) { + if (!turnRate) { return true; } - diff = idMath::AngleNormalize180( current_yaw - ideal_yaw ); - if ( idMath::Fabs( diff ) < 0.01f ) { + diff = idMath::AngleNormalize180(current_yaw - ideal_yaw); + if (idMath::Fabs(diff) < 0.01f) { // force it to be exact current_yaw = ideal_yaw; return true; @@ -2456,8 +2515,8 @@ bool idAI::FacingIdeal( void ) { idAI::TurnToward ===================== */ -bool idAI::TurnToward( float yaw ) { - ideal_yaw = idMath::AngleNormalize180( yaw ); +bool idAI::TurnToward(float yaw) { + ideal_yaw = idMath::AngleNormalize180(yaw); bool result = FacingIdeal(); return result; } @@ -2467,17 +2526,17 @@ bool idAI::TurnToward( float yaw ) { idAI::TurnToward ===================== */ -bool idAI::TurnToward( const idVec3 &pos ) { +bool idAI::TurnToward(const idVec3& pos) { idVec3 dir; idVec3 local_dir; float lengthSqr; dir = pos - physicsObj.GetOrigin(); - physicsObj.GetGravityAxis().ProjectVector( dir, local_dir ); + physicsObj.GetGravityAxis().ProjectVector(dir, local_dir); local_dir.z = 0.0f; lengthSqr = local_dir.LengthSqr(); - if ( lengthSqr > Square( 2.0f ) || ( lengthSqr > Square( 0.1f ) && enemy.GetEntity() == NULL ) ) { - ideal_yaw = idMath::AngleNormalize180( local_dir.ToYaw() ); + if (lengthSqr > Square(2.0f) || (lengthSqr > Square(0.1f) && enemy.GetEntity() == NULL)) { + ideal_yaw = idMath::AngleNormalize180(local_dir.ToYaw()); } bool result = FacingIdeal(); @@ -2495,12 +2554,12 @@ bool idAI::TurnToward( const idVec3 &pos ) { idAI::ApplyImpulse ================ */ -void idAI::ApplyImpulse( idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse ) { +void idAI::ApplyImpulse(idEntity* ent, int id, const idVec3& point, const idVec3& impulse) { // FIXME: Jim take a look at this and see if this is a reasonable thing to do // instead of a spawnArg flag.. Sabaoth is the only slide monster ( and should be the only one for D3 ) // and we don't want him taking physics impulses as it can knock him off the path - if ( move.moveType != MOVETYPE_STATIC && move.moveType != MOVETYPE_SLIDE ) { - idActor::ApplyImpulse( ent, id, point, impulse ); + if (move.moveType != MOVETYPE_STATIC && move.moveType != MOVETYPE_SLIDE) { + idActor::ApplyImpulse(ent, id, point, impulse); } } @@ -2509,14 +2568,14 @@ void idAI::ApplyImpulse( idEntity *ent, int id, const idVec3 &point, const idVec idAI::GetMoveDelta ===================== */ -void idAI::GetMoveDelta( const idMat3 &oldaxis, const idMat3 &axis, idVec3 &delta ) { +void idAI::GetMoveDelta(const idMat3& oldaxis, const idMat3& axis, idVec3& delta) { idVec3 oldModelOrigin; idVec3 modelOrigin; - animator.GetDelta( gameLocal.time - gameLocal.msec, gameLocal.time, delta ); + animator.GetDelta(gameLocal.time - gameLocal.msec, gameLocal.time, delta); delta = axis * delta; - if ( modelOffset != vec3_zero ) { + if (modelOffset != vec3_zero) { // the pivot of the monster's model is around its origin, and not around the bounding // box's origin, so we have to compensate for this when the model is offset so that // the monster still appears to rotate around it's origin. @@ -2533,57 +2592,61 @@ void idAI::GetMoveDelta( const idMat3 &oldaxis, const idMat3 &axis, idVec3 &delt idAI::CheckObstacleAvoidance ===================== */ -void idAI::CheckObstacleAvoidance( const idVec3 &goalPos, idVec3 &newPos ) { - idEntity *obstacle; +void idAI::CheckObstacleAvoidance(const idVec3& goalPos, idVec3& newPos) { + idEntity* obstacle; obstaclePath_t path; idVec3 dir; float dist; bool foundPath; - if ( ignore_obstacles ) { + if (ignore_obstacles) { newPos = goalPos; move.obstacle = NULL; return; } - const idVec3 &origin = physicsObj.GetOrigin(); + const idVec3& origin = physicsObj.GetOrigin(); obstacle = NULL; AI_OBSTACLE_IN_PATH = false; - foundPath = FindPathAroundObstacles( &physicsObj, aas, enemy.GetEntity(), origin, goalPos, path ); - if ( ai_showObstacleAvoidance.GetBool() ) { - gameRenderWorld->DebugLine( colorBlue, goalPos + idVec3( 1.0f, 1.0f, 0.0f ), goalPos + idVec3( 1.0f, 1.0f, 64.0f ), gameLocal.msec ); - gameRenderWorld->DebugLine( foundPath ? colorYellow : colorRed, path.seekPos, path.seekPos + idVec3( 0.0f, 0.0f, 64.0f ), gameLocal.msec ); + foundPath = FindPathAroundObstacles(&physicsObj, aas, enemy.GetEntity(), origin, goalPos, path); + if (ai_showObstacleAvoidance.GetBool()) { + gameRenderWorld->DebugLine(colorBlue, goalPos + idVec3(1.0f, 1.0f, 0.0f), goalPos + idVec3(1.0f, 1.0f, 64.0f), gameLocal.msec); + gameRenderWorld->DebugLine(foundPath ? colorYellow : colorRed, path.seekPos, path.seekPos + idVec3(0.0f, 0.0f, 64.0f), gameLocal.msec); } - if ( !foundPath ) { + if (!foundPath) { // couldn't get around obstacles - if ( path.firstObstacle ) { + if (path.firstObstacle) { AI_OBSTACLE_IN_PATH = true; - if ( physicsObj.GetAbsBounds().Expand( 2.0f ).IntersectsBounds( path.firstObstacle->GetPhysics()->GetAbsBounds() ) ) { + if (physicsObj.GetAbsBounds().Expand(2.0f).IntersectsBounds(path.firstObstacle->GetPhysics()->GetAbsBounds())) { obstacle = path.firstObstacle; } - } else if ( path.startPosObstacle ) { + } + else if (path.startPosObstacle) { AI_OBSTACLE_IN_PATH = true; - if ( physicsObj.GetAbsBounds().Expand( 2.0f ).IntersectsBounds( path.startPosObstacle->GetPhysics()->GetAbsBounds() ) ) { + if (physicsObj.GetAbsBounds().Expand(2.0f).IntersectsBounds(path.startPosObstacle->GetPhysics()->GetAbsBounds())) { obstacle = path.startPosObstacle; } - } else { + } + else { // Blocked by wall move.moveStatus = MOVE_STATUS_BLOCKED_BY_WALL; } #if 0 - } else if ( path.startPosObstacle ) { + } + else if (path.startPosObstacle) { // check if we're past where the our origin was pushed out of the obstacle dir = goalPos - origin; dir.Normalize(); - dist = ( path.seekPos - origin ) * dir; - if ( dist < 1.0f ) { + dist = (path.seekPos - origin) * dir; + if (dist < 1.0f) { AI_OBSTACLE_IN_PATH = true; obstacle = path.startPosObstacle; } #endif - } else if ( path.seekPosObstacle ) { + } + else if (path.seekPosObstacle) { // if the AI is very close to the path.seekPos already and path.seekPosObstacle != NULL // then we want to push the path.seekPosObstacle entity out of the way AI_OBSTACLE_IN_PATH = true; @@ -2591,29 +2654,32 @@ void idAI::CheckObstacleAvoidance( const idVec3 &goalPos, idVec3 &newPos ) { // check if we're past where the goalPos was pushed out of the obstacle dir = goalPos - origin; dir.Normalize(); - dist = ( path.seekPos - origin ) * dir; - if ( dist < 1.0f ) { + dist = (path.seekPos - origin) * dir; + if (dist < 1.0f) { obstacle = path.seekPosObstacle; } } // if we had an obstacle, set our move status based on the type, and kick it out of the way if it's a moveable - if ( obstacle ) { - if ( obstacle->IsType( idActor::Type ) ) { + if (obstacle) { + if (obstacle->IsType(idActor::Type)) { // monsters aren't kickable - if ( obstacle == enemy.GetEntity() ) { + if (obstacle == enemy.GetEntity()) { move.moveStatus = MOVE_STATUS_BLOCKED_BY_ENEMY; - } else { + } + else { move.moveStatus = MOVE_STATUS_BLOCKED_BY_MONSTER; } - } else { + } + else { // try kicking the object out of the way move.moveStatus = MOVE_STATUS_BLOCKED_BY_OBJECT; } newPos = obstacle->GetPhysics()->GetOrigin(); //newPos = path.seekPos; move.obstacle = obstacle; - } else { + } + else { newPos = path.seekPos; move.obstacle = NULL; } @@ -2624,14 +2690,14 @@ void idAI::CheckObstacleAvoidance( const idVec3 &goalPos, idVec3 &newPos ) { idAI::DeadMove ===================== */ -void idAI::DeadMove( void ) { +void idAI::DeadMove(void) { idVec3 delta; monsterMoveResult_t moveResult; idVec3 org = physicsObj.GetOrigin(); - GetMoveDelta( viewAxis, viewAxis, delta ); - physicsObj.SetDelta( delta ); + GetMoveDelta(viewAxis, viewAxis, delta); + physicsObj.SetDelta(delta); RunPhysics(); @@ -2644,7 +2710,7 @@ void idAI::DeadMove( void ) { idAI::AnimMove ===================== */ -void idAI::AnimMove( void ) { +void idAI::AnimMove(void) { idVec3 goalPos; idVec3 delta; idVec3 goalDelta; @@ -2657,69 +2723,76 @@ void idAI::AnimMove( void ) { AI_BLOCKED = false; - if ( move.moveCommand < NUM_NONMOVING_COMMANDS ){ + if (move.moveCommand < NUM_NONMOVING_COMMANDS) { move.lastMoveOrigin.Zero(); move.lastMoveTime = gameLocal.time; } move.obstacle = NULL; - if ( ( move.moveCommand == MOVE_FACE_ENEMY ) && enemy.GetEntity() ) { - TurnToward( lastVisibleEnemyPos ); + if ((move.moveCommand == MOVE_FACE_ENEMY) && enemy.GetEntity()) { + TurnToward(lastVisibleEnemyPos); goalPos = oldorigin; - } else if ( ( move.moveCommand == MOVE_FACE_ENTITY ) && move.goalEntity.GetEntity() ) { - TurnToward( move.goalEntity.GetEntity()->GetPhysics()->GetOrigin() ); + } + else if ((move.moveCommand == MOVE_FACE_ENTITY) && move.goalEntity.GetEntity()) { + TurnToward(move.goalEntity.GetEntity()->GetPhysics()->GetOrigin()); goalPos = oldorigin; - } else if ( GetMovePos( goalPos ) ) { - if ( move.moveCommand != MOVE_WANDER ) { - CheckObstacleAvoidance( goalPos, newDest ); - TurnToward( newDest ); - } else { - TurnToward( goalPos ); + } + else if (GetMovePos(goalPos)) { + if (move.moveCommand != MOVE_WANDER) { + CheckObstacleAvoidance(goalPos, newDest); + TurnToward(newDest); + } + else { + TurnToward(goalPos); } } Turn(); - if ( move.moveCommand == MOVE_SLIDE_TO_POSITION ) { - if ( gameLocal.time < move.startTime + move.duration ) { - goalPos = move.moveDest - move.moveDir * MS2SEC( move.startTime + move.duration - gameLocal.time ); + if (move.moveCommand == MOVE_SLIDE_TO_POSITION) { + if (gameLocal.time < move.startTime + move.duration) { + goalPos = move.moveDest - move.moveDir * MS2SEC(move.startTime + move.duration - gameLocal.time); delta = goalPos - oldorigin; delta.z = 0.0f; - } else { + } + else { delta = move.moveDest - oldorigin; delta.z = 0.0f; - StopMove( MOVE_STATUS_DONE ); + StopMove(MOVE_STATUS_DONE); } - } else if ( allowMove ) { - GetMoveDelta( oldaxis, viewAxis, delta ); - } else { + } + else if (allowMove) { + GetMoveDelta(oldaxis, viewAxis, delta); + } + else { delta.Zero(); } - if ( move.moveCommand == MOVE_TO_POSITION ) { + if (move.moveCommand == MOVE_TO_POSITION) { goalDelta = move.moveDest - oldorigin; goalDist = goalDelta.LengthFast(); - if ( goalDist < delta.LengthFast() ) { + if (goalDist < delta.LengthFast()) { delta = goalDelta; } } - physicsObj.SetDelta( delta ); - physicsObj.ForceDeltaMove( disableGravity ); + physicsObj.SetDelta(delta); + physicsObj.ForceDeltaMove(disableGravity); RunPhysics(); - if ( ai_debugMove.GetBool() ) { - gameRenderWorld->DebugLine( colorCyan, oldorigin, physicsObj.GetOrigin(), 5000 ); + if (ai_debugMove.GetBool()) { + gameRenderWorld->DebugLine(colorCyan, oldorigin, physicsObj.GetOrigin(), 5000); } moveResult = physicsObj.GetMoveResult(); - if ( !af_push_moveables && attack.Length() && TestMelee() ) { - DirectDamage( attack, enemy.GetEntity() ); - } else { - idEntity *blockEnt = physicsObj.GetSlideMoveEntity(); - if ( blockEnt && blockEnt->IsType( idMoveable::Type ) && blockEnt->GetPhysics()->IsPushable() ) { - KickObstacles( viewAxis[ 0 ], kickForce, blockEnt ); + if (!af_push_moveables && attack.Length() && TestMelee()) { + DirectDamage(attack, enemy.GetEntity()); + } + else { + idEntity* blockEnt = physicsObj.GetSlideMoveEntity(); + if (blockEnt && blockEnt->IsType(idMoveable::Type) && blockEnt->GetPhysics()->IsPushable()) { + KickObstacles(viewAxis[0], kickForce, blockEnt); } } @@ -2728,14 +2801,14 @@ void idAI::AnimMove( void ) { AI_ONGROUND = physicsObj.OnGround(); idVec3 org = physicsObj.GetOrigin(); - if ( oldorigin != org ) { + if (oldorigin != org) { TouchTriggers(); } - if ( ai_debugMove.GetBool() ) { - gameRenderWorld->DebugBounds( colorMagenta, physicsObj.GetBounds(), org, gameLocal.msec ); - gameRenderWorld->DebugBounds( colorMagenta, physicsObj.GetBounds(), move.moveDest, gameLocal.msec ); - gameRenderWorld->DebugLine( colorYellow, org + EyeOffset(), org + EyeOffset() + viewAxis[ 0 ] * physicsObj.GetGravityAxis() * 16.0f, gameLocal.msec, true ); + if (ai_debugMove.GetBool()) { + gameRenderWorld->DebugBounds(colorMagenta, physicsObj.GetBounds(), org, gameLocal.msec); + gameRenderWorld->DebugBounds(colorMagenta, physicsObj.GetBounds(), move.moveDest, gameLocal.msec); + gameRenderWorld->DebugLine(colorYellow, org + EyeOffset(), org + EyeOffset() + viewAxis[0] * physicsObj.GetGravityAxis() * 16.0f, gameLocal.msec, true); DrawRoute(); } } @@ -2745,7 +2818,7 @@ void idAI::AnimMove( void ) { Seek ===================== */ -idVec3 Seek( idVec3 &vel, const idVec3 &org, const idVec3 &goal, float prediction ) { +idVec3 Seek(idVec3& vel, const idVec3& org, const idVec3& goal, float prediction) { idVec3 predictedPos; idVec3 goalDelta; idVec3 seekVel; @@ -2753,7 +2826,7 @@ idVec3 Seek( idVec3 &vel, const idVec3 &org, const idVec3 &goal, float predictio // predict our position predictedPos = org + vel * prediction; goalDelta = goal - predictedPos; - seekVel = goalDelta * MS2SEC( gameLocal.msec ); + seekVel = goalDelta * MS2SEC(gameLocal.msec); return seekVel; } @@ -2763,7 +2836,7 @@ idVec3 Seek( idVec3 &vel, const idVec3 &org, const idVec3 &goal, float predictio idAI::SlideMove ===================== */ -void idAI::SlideMove( void ) { +void idAI::SlideMove(void) { idVec3 goalPos; idVec3 delta; idVec3 goalDelta; @@ -2776,37 +2849,40 @@ void idAI::SlideMove( void ) { AI_BLOCKED = false; - if ( move.moveCommand < NUM_NONMOVING_COMMANDS ){ + if (move.moveCommand < NUM_NONMOVING_COMMANDS) { move.lastMoveOrigin.Zero(); move.lastMoveTime = gameLocal.time; } move.obstacle = NULL; - if ( ( move.moveCommand == MOVE_FACE_ENEMY ) && enemy.GetEntity() ) { - TurnToward( lastVisibleEnemyPos ); + if ((move.moveCommand == MOVE_FACE_ENEMY) && enemy.GetEntity()) { + TurnToward(lastVisibleEnemyPos); goalPos = move.moveDest; - } else if ( ( move.moveCommand == MOVE_FACE_ENTITY ) && move.goalEntity.GetEntity() ) { - TurnToward( move.goalEntity.GetEntity()->GetPhysics()->GetOrigin() ); + } + else if ((move.moveCommand == MOVE_FACE_ENTITY) && move.goalEntity.GetEntity()) { + TurnToward(move.goalEntity.GetEntity()->GetPhysics()->GetOrigin()); goalPos = move.moveDest; - } else if ( GetMovePos( goalPos ) ) { - CheckObstacleAvoidance( goalPos, newDest ); - TurnToward( newDest ); + } + else if (GetMovePos(goalPos)) { + CheckObstacleAvoidance(goalPos, newDest); + TurnToward(newDest); goalPos = newDest; } - if ( move.moveCommand == MOVE_SLIDE_TO_POSITION ) { - if ( gameLocal.time < move.startTime + move.duration ) { - goalPos = move.moveDest - move.moveDir * MS2SEC( move.startTime + move.duration - gameLocal.time ); - } else { + if (move.moveCommand == MOVE_SLIDE_TO_POSITION) { + if (gameLocal.time < move.startTime + move.duration) { + goalPos = move.moveDest - move.moveDir * MS2SEC(move.startTime + move.duration - gameLocal.time); + } + else { goalPos = move.moveDest; - StopMove( MOVE_STATUS_DONE ); + StopMove(MOVE_STATUS_DONE); } } - if ( move.moveCommand == MOVE_TO_POSITION ) { + if (move.moveCommand == MOVE_TO_POSITION) { goalDelta = move.moveDest - oldorigin; goalDist = goalDelta.LengthFast(); - if ( goalDist < delta.LengthFast() ) { + if (goalDist < delta.LengthFast()) { delta = goalDelta; } } @@ -2817,38 +2893,41 @@ void idAI::SlideMove( void ) { // seek the goal position goalDelta = goalPos - predictedPos; - vel -= vel * AI_FLY_DAMPENING * MS2SEC( gameLocal.msec ); - vel += goalDelta * MS2SEC( gameLocal.msec ); + vel -= vel * AI_FLY_DAMPENING * MS2SEC(gameLocal.msec); + vel += goalDelta * MS2SEC(gameLocal.msec); // cap our speed - vel.Truncate( fly_speed ); + vel.Truncate(fly_speed); vel.z = z; - physicsObj.SetLinearVelocity( vel ); - physicsObj.UseVelocityMove( true ); + physicsObj.SetLinearVelocity(vel); + physicsObj.UseVelocityMove(true); RunPhysics(); - if ( ( move.moveCommand == MOVE_FACE_ENEMY ) && enemy.GetEntity() ) { - TurnToward( lastVisibleEnemyPos ); - } else if ( ( move.moveCommand == MOVE_FACE_ENTITY ) && move.goalEntity.GetEntity() ) { - TurnToward( move.goalEntity.GetEntity()->GetPhysics()->GetOrigin() ); - } else if ( move.moveCommand != MOVE_NONE ) { - if ( vel.ToVec2().LengthSqr() > 0.1f ) { - TurnToward( vel.ToYaw() ); + if ((move.moveCommand == MOVE_FACE_ENEMY) && enemy.GetEntity()) { + TurnToward(lastVisibleEnemyPos); + } + else if ((move.moveCommand == MOVE_FACE_ENTITY) && move.goalEntity.GetEntity()) { + TurnToward(move.goalEntity.GetEntity()->GetPhysics()->GetOrigin()); + } + else if (move.moveCommand != MOVE_NONE) { + if (vel.ToVec2().LengthSqr() > 0.1f) { + TurnToward(vel.ToYaw()); } } Turn(); - if ( ai_debugMove.GetBool() ) { - gameRenderWorld->DebugLine( colorCyan, oldorigin, physicsObj.GetOrigin(), 5000 ); + if (ai_debugMove.GetBool()) { + gameRenderWorld->DebugLine(colorCyan, oldorigin, physicsObj.GetOrigin(), 5000); } moveResult = physicsObj.GetMoveResult(); - if ( !af_push_moveables && attack.Length() && TestMelee() ) { - DirectDamage( attack, enemy.GetEntity() ); - } else { - idEntity *blockEnt = physicsObj.GetSlideMoveEntity(); - if ( blockEnt && blockEnt->IsType( idMoveable::Type ) && blockEnt->GetPhysics()->IsPushable() ) { - KickObstacles( viewAxis[ 0 ], kickForce, blockEnt ); + if (!af_push_moveables && attack.Length() && TestMelee()) { + DirectDamage(attack, enemy.GetEntity()); + } + else { + idEntity* blockEnt = physicsObj.GetSlideMoveEntity(); + if (blockEnt && blockEnt->IsType(idMoveable::Type) && blockEnt->GetPhysics()->IsPushable()) { + KickObstacles(viewAxis[0], kickForce, blockEnt); } } @@ -2857,14 +2936,14 @@ void idAI::SlideMove( void ) { AI_ONGROUND = physicsObj.OnGround(); idVec3 org = physicsObj.GetOrigin(); - if ( oldorigin != org ) { + if (oldorigin != org) { TouchTriggers(); } - if ( ai_debugMove.GetBool() ) { - gameRenderWorld->DebugBounds( colorMagenta, physicsObj.GetBounds(), org, gameLocal.msec ); - gameRenderWorld->DebugBounds( colorMagenta, physicsObj.GetBounds(), move.moveDest, gameLocal.msec ); - gameRenderWorld->DebugLine( colorYellow, org + EyeOffset(), org + EyeOffset() + viewAxis[ 0 ] * physicsObj.GetGravityAxis() * 16.0f, gameLocal.msec, true ); + if (ai_debugMove.GetBool()) { + gameRenderWorld->DebugBounds(colorMagenta, physicsObj.GetBounds(), org, gameLocal.msec); + gameRenderWorld->DebugBounds(colorMagenta, physicsObj.GetBounds(), move.moveDest, gameLocal.msec); + gameRenderWorld->DebugLine(colorYellow, org + EyeOffset(), org + EyeOffset() + viewAxis[0] * physicsObj.GetGravityAxis() * 16.0f, gameLocal.msec, true); DrawRoute(); } } @@ -2874,7 +2953,7 @@ void idAI::SlideMove( void ) { idAI::AdjustFlyingAngles ===================== */ -void idAI::AdjustFlyingAngles( void ) { +void idAI::AdjustFlyingAngles(void) { idVec3 vel; float speed; float roll; @@ -2883,21 +2962,24 @@ void idAI::AdjustFlyingAngles( void ) { vel = physicsObj.GetLinearVelocity(); speed = vel.Length(); - if ( speed < 5.0f ) { + if (speed < 5.0f) { roll = 0.0f; pitch = 0.0f; - } else { - roll = vel * viewAxis[ 1 ] * -fly_roll_scale / fly_speed; - if ( roll > fly_roll_max ) { + } + else { + roll = vel * viewAxis[1] * -fly_roll_scale / fly_speed; + if (roll > fly_roll_max) { roll = fly_roll_max; - } else if ( roll < -fly_roll_max ) { + } + else if (roll < -fly_roll_max) { roll = -fly_roll_max; } - pitch = vel * viewAxis[ 2 ] * -fly_pitch_scale / fly_speed; - if ( pitch > fly_pitch_max ) { + pitch = vel * viewAxis[2] * -fly_pitch_scale / fly_speed; + if (pitch > fly_pitch_max) { pitch = fly_pitch_max; - } else if ( pitch < -fly_pitch_max ) { + } + else if (pitch < -fly_pitch_max) { pitch = -fly_pitch_max; } } @@ -2905,10 +2987,11 @@ void idAI::AdjustFlyingAngles( void ) { fly_roll = fly_roll * 0.95f + roll * 0.05f; fly_pitch = fly_pitch * 0.95f + pitch * 0.05f; - if ( flyTiltJoint != INVALID_JOINT ) { - animator.SetJointAxis( flyTiltJoint, JOINTMOD_WORLD, idAngles( fly_pitch, 0.0f, fly_roll ).ToMat3() ); - } else { - viewAxis = idAngles( fly_pitch, current_yaw, fly_roll ).ToMat3(); + if (flyTiltJoint != INVALID_JOINT) { + animator.SetJointAxis(flyTiltJoint, JOINTMOD_WORLD, idAngles(fly_pitch, 0.0f, fly_roll).ToMat3()); + } + else { + viewAxis = idAngles(fly_pitch, current_yaw, fly_roll).ToMat3(); } } @@ -2917,17 +3000,17 @@ void idAI::AdjustFlyingAngles( void ) { idAI::AddFlyBob ===================== */ -void idAI::AddFlyBob( idVec3 &vel ) { +void idAI::AddFlyBob(idVec3& vel) { idVec3 fly_bob_add; float t; - if ( fly_bob_strength ) { - t = MS2SEC( gameLocal.time + entityNumber * 497 ); - fly_bob_add = ( viewAxis[ 1 ] * idMath::Sin16( t * fly_bob_horz ) + viewAxis[ 2 ] * idMath::Sin16( t * fly_bob_vert ) ) * fly_bob_strength; - vel += fly_bob_add * MS2SEC( gameLocal.msec ); - if ( ai_debugMove.GetBool() ) { - const idVec3 &origin = physicsObj.GetOrigin(); - gameRenderWorld->DebugArrow( colorOrange, origin, origin + fly_bob_add, 0 ); + if (fly_bob_strength) { + t = MS2SEC(gameLocal.time + entityNumber * 497); + fly_bob_add = (viewAxis[1] * idMath::Sin16(t * fly_bob_horz) + viewAxis[2] * idMath::Sin16(t * fly_bob_vert)) * fly_bob_strength; + vel += fly_bob_add * MS2SEC(gameLocal.msec); + if (ai_debugMove.GetBool()) { + const idVec3& origin = physicsObj.GetOrigin(); + gameRenderWorld->DebugArrow(colorOrange, origin, origin + fly_bob_add, 0); } } } @@ -2937,46 +3020,47 @@ void idAI::AddFlyBob( idVec3 &vel ) { idAI::AdjustFlyHeight ===================== */ -void idAI::AdjustFlyHeight( idVec3 &vel, const idVec3 &goalPos ) { - const idVec3 &origin = physicsObj.GetOrigin(); +void idAI::AdjustFlyHeight(idVec3& vel, const idVec3& goalPos) { + const idVec3& origin = physicsObj.GetOrigin(); predictedPath_t path; idVec3 end; idVec3 dest; trace_t trace; - idActor *enemyEnt; + idActor* enemyEnt; bool goLower; // make sure we're not flying too high to get through doors goLower = false; - if ( origin.z > goalPos.z ) { + if (origin.z > goalPos.z) { dest = goalPos; dest.z = origin.z + 128.0f; - idAI::PredictPath( this, aas, goalPos, dest - origin, 1000, 1000, SE_BLOCKED, path ); - if ( path.endPos.z < origin.z ) { - idVec3 addVel = Seek( vel, origin, path.endPos, AI_SEEK_PREDICTION ); + idAI::PredictPath(this, aas, goalPos, dest - origin, 1000, 1000, SE_BLOCKED, path); + if (path.endPos.z < origin.z) { + idVec3 addVel = Seek(vel, origin, path.endPos, AI_SEEK_PREDICTION); vel.z += addVel.z; goLower = true; } - - if ( ai_debugMove.GetBool() ) { - gameRenderWorld->DebugBounds( goLower ? colorRed : colorGreen, physicsObj.GetBounds(), path.endPos, gameLocal.msec ); + + if (ai_debugMove.GetBool()) { + gameRenderWorld->DebugBounds(goLower ? colorRed : colorGreen, physicsObj.GetBounds(), path.endPos, gameLocal.msec); } } - if ( !goLower ) { + if (!goLower) { // make sure we don't fly too low end = origin; enemyEnt = enemy.GetEntity(); - if ( enemyEnt ) { + if (enemyEnt) { end.z = lastVisibleEnemyPos.z + lastVisibleEnemyEyeOffset.z + fly_offset; - } else { + } + else { // just use the default eye height for the player end.z = goalPos.z + DEFAULT_FLY_OFFSET + fly_offset; } - gameLocal.clip.Translation( trace, origin, end, physicsObj.GetClipModel(), mat3_identity, MASK_MONSTERSOLID, this ); - vel += Seek( vel, origin, trace.endpos, AI_SEEK_PREDICTION ); + gameLocal.clip.Translation(trace, origin, end, physicsObj.GetClipModel(), mat3_identity, MASK_MONSTERSOLID, this); + vel += Seek(vel, origin, trace.endpos, AI_SEEK_PREDICTION); } } @@ -2985,11 +3069,11 @@ void idAI::AdjustFlyHeight( idVec3 &vel, const idVec3 &goalPos ) { idAI::FlySeekGoal ===================== */ -void idAI::FlySeekGoal( idVec3 &vel, idVec3 &goalPos ) { +void idAI::FlySeekGoal(idVec3& vel, idVec3& goalPos) { idVec3 seekVel; - + // seek the goal position - seekVel = Seek( vel, physicsObj.GetOrigin(), goalPos, AI_SEEK_PREDICTION ); + seekVel = Seek(vel, physicsObj.GetOrigin(), goalPos, AI_SEEK_PREDICTION); seekVel *= fly_seek_scale; vel += seekVel; } @@ -2999,18 +3083,19 @@ void idAI::FlySeekGoal( idVec3 &vel, idVec3 &goalPos ) { idAI::AdjustFlySpeed ===================== */ -void idAI::AdjustFlySpeed( idVec3 &vel ) { +void idAI::AdjustFlySpeed(idVec3& vel) { float speed; // apply dampening - vel -= vel * AI_FLY_DAMPENING * MS2SEC( gameLocal.msec ); + vel -= vel * AI_FLY_DAMPENING * MS2SEC(gameLocal.msec); // gradually speed up/slow down to desired speed speed = vel.Normalize(); - speed += ( move.speed - speed ) * MS2SEC( gameLocal.msec ); - if ( speed < 0.0f ) { + speed += (move.speed - speed) * MS2SEC(gameLocal.msec); + if (speed < 0.0f) { speed = 0.0f; - } else if ( move.speed && ( speed > move.speed ) ) { + } + else if (move.speed && (speed > move.speed)) { speed = move.speed; } @@ -3022,15 +3107,17 @@ void idAI::AdjustFlySpeed( idVec3 &vel ) { idAI::FlyTurn ===================== */ -void idAI::FlyTurn( void ) { - if ( move.moveCommand == MOVE_FACE_ENEMY ) { - TurnToward( lastVisibleEnemyPos ); - } else if ( ( move.moveCommand == MOVE_FACE_ENTITY ) && move.goalEntity.GetEntity() ) { - TurnToward( move.goalEntity.GetEntity()->GetPhysics()->GetOrigin() ); - } else if ( move.speed > 0.0f ) { - const idVec3 &vel = physicsObj.GetLinearVelocity(); - if ( vel.ToVec2().LengthSqr() > 0.1f ) { - TurnToward( vel.ToYaw() ); +void idAI::FlyTurn(void) { + if (move.moveCommand == MOVE_FACE_ENEMY) { + TurnToward(lastVisibleEnemyPos); + } + else if ((move.moveCommand == MOVE_FACE_ENTITY) && move.goalEntity.GetEntity()) { + TurnToward(move.goalEntity.GetEntity()->GetPhysics()->GetOrigin()); + } + else if (move.speed > 0.0f) { + const idVec3& vel = physicsObj.GetLinearVelocity(); + if (vel.ToVec2().LengthSqr() > 0.1f) { + TurnToward(vel.ToYaw()); } } Turn(); @@ -3041,42 +3128,42 @@ void idAI::FlyTurn( void ) { idAI::FlyMove ===================== */ -void idAI::FlyMove( void ) { +void idAI::FlyMove(void) { idVec3 goalPos; idVec3 oldorigin; idVec3 newDest; AI_BLOCKED = false; - if ( ( move.moveCommand != MOVE_NONE ) && ReachedPos( move.moveDest, move.moveCommand ) ) { - StopMove( MOVE_STATUS_DONE ); + if ((move.moveCommand != MOVE_NONE) && ReachedPos(move.moveDest, move.moveCommand)) { + StopMove(MOVE_STATUS_DONE); } - if ( ai_debugMove.GetBool() ) { - gameLocal.Printf( "%d: %s: %s, vel = %.2f, sp = %.2f, maxsp = %.2f\n", gameLocal.time, name.c_str(), moveCommandString[ move.moveCommand ], physicsObj.GetLinearVelocity().Length(), move.speed, fly_speed ); + if (ai_debugMove.GetBool()) { + gameLocal.Printf("%d: %s: %s, vel = %.2f, sp = %.2f, maxsp = %.2f\n", gameLocal.time, name.c_str(), moveCommandString[move.moveCommand], physicsObj.GetLinearVelocity().Length(), move.speed, fly_speed); } - if ( move.moveCommand != MOVE_TO_POSITION_DIRECT ) { + if (move.moveCommand != MOVE_TO_POSITION_DIRECT) { idVec3 vel = physicsObj.GetLinearVelocity(); - if ( GetMovePos( goalPos ) ) { - CheckObstacleAvoidance( goalPos, newDest ); + if (GetMovePos(goalPos)) { + CheckObstacleAvoidance(goalPos, newDest); goalPos = newDest; } - if ( move.speed ) { - FlySeekGoal( vel, goalPos ); + if (move.speed) { + FlySeekGoal(vel, goalPos); } // add in bobbing - AddFlyBob( vel ); + AddFlyBob(vel); - if ( enemy.GetEntity() && ( move.moveCommand != MOVE_TO_POSITION ) ) { - AdjustFlyHeight( vel, goalPos ); + if (enemy.GetEntity() && (move.moveCommand != MOVE_TO_POSITION)) { + AdjustFlyHeight(vel, goalPos); } - AdjustFlySpeed( vel ); + AdjustFlySpeed(vel); - physicsObj.SetLinearVelocity( vel ); + physicsObj.SetLinearVelocity(vel); } // turn @@ -3084,37 +3171,39 @@ void idAI::FlyMove( void ) { // run the physics for this frame oldorigin = physicsObj.GetOrigin(); - physicsObj.UseFlyMove( true ); - physicsObj.UseVelocityMove( false ); - physicsObj.SetDelta( vec3_zero ); - physicsObj.ForceDeltaMove( disableGravity ); + physicsObj.UseFlyMove(true); + physicsObj.UseVelocityMove(false); + physicsObj.SetDelta(vec3_zero); + physicsObj.ForceDeltaMove(disableGravity); RunPhysics(); monsterMoveResult_t moveResult = physicsObj.GetMoveResult(); - if ( !af_push_moveables && attack.Length() && TestMelee() ) { - DirectDamage( attack, enemy.GetEntity() ); - } else { - idEntity *blockEnt = physicsObj.GetSlideMoveEntity(); - if ( blockEnt && blockEnt->IsType( idMoveable::Type ) && blockEnt->GetPhysics()->IsPushable() ) { - KickObstacles( viewAxis[ 0 ], kickForce, blockEnt ); - } else if ( moveResult == MM_BLOCKED ) { + if (!af_push_moveables && attack.Length() && TestMelee()) { + DirectDamage(attack, enemy.GetEntity()); + } + else { + idEntity* blockEnt = physicsObj.GetSlideMoveEntity(); + if (blockEnt && blockEnt->IsType(idMoveable::Type) && blockEnt->GetPhysics()->IsPushable()) { + KickObstacles(viewAxis[0], kickForce, blockEnt); + } + else if (moveResult == MM_BLOCKED) { move.blockTime = gameLocal.time + 500; AI_BLOCKED = true; } } idVec3 org = physicsObj.GetOrigin(); - if ( oldorigin != org ) { + if (oldorigin != org) { TouchTriggers(); } - if ( ai_debugMove.GetBool() ) { - gameRenderWorld->DebugLine( colorCyan, oldorigin, physicsObj.GetOrigin(), 4000 ); - gameRenderWorld->DebugBounds( colorOrange, physicsObj.GetBounds(), org, gameLocal.msec ); - gameRenderWorld->DebugBounds( colorMagenta, physicsObj.GetBounds(), move.moveDest, gameLocal.msec ); - gameRenderWorld->DebugLine( colorRed, org, org + physicsObj.GetLinearVelocity(), gameLocal.msec, true ); - gameRenderWorld->DebugLine( colorBlue, org, goalPos, gameLocal.msec, true ); - gameRenderWorld->DebugLine( colorYellow, org + EyeOffset(), org + EyeOffset() + viewAxis[ 0 ] * physicsObj.GetGravityAxis() * 16.0f, gameLocal.msec, true ); + if (ai_debugMove.GetBool()) { + gameRenderWorld->DebugLine(colorCyan, oldorigin, physicsObj.GetOrigin(), 4000); + gameRenderWorld->DebugBounds(colorOrange, physicsObj.GetBounds(), org, gameLocal.msec); + gameRenderWorld->DebugBounds(colorMagenta, physicsObj.GetBounds(), move.moveDest, gameLocal.msec); + gameRenderWorld->DebugLine(colorRed, org, org + physicsObj.GetLinearVelocity(), gameLocal.msec, true); + gameRenderWorld->DebugLine(colorBlue, org, goalPos, gameLocal.msec, true); + gameRenderWorld->DebugLine(colorYellow, org + EyeOffset(), org + EyeOffset() + viewAxis[0] * physicsObj.GetGravityAxis() * 16.0f, gameLocal.msec, true); DrawRoute(); } } @@ -3124,36 +3213,38 @@ void idAI::FlyMove( void ) { idAI::StaticMove ===================== */ -void idAI::StaticMove( void ) { - idActor *enemyEnt = enemy.GetEntity(); +void idAI::StaticMove(void) { + idActor* enemyEnt = enemy.GetEntity(); - if ( AI_DEAD ) { + if (AI_DEAD) { return; } - if ( ( move.moveCommand == MOVE_FACE_ENEMY ) && enemyEnt ) { - TurnToward( lastVisibleEnemyPos ); - } else if ( ( move.moveCommand == MOVE_FACE_ENTITY ) && move.goalEntity.GetEntity() ) { - TurnToward( move.goalEntity.GetEntity()->GetPhysics()->GetOrigin() ); - } else if ( move.moveCommand != MOVE_NONE ) { - TurnToward( move.moveDest ); + if ((move.moveCommand == MOVE_FACE_ENEMY) && enemyEnt) { + TurnToward(lastVisibleEnemyPos); + } + else if ((move.moveCommand == MOVE_FACE_ENTITY) && move.goalEntity.GetEntity()) { + TurnToward(move.goalEntity.GetEntity()->GetPhysics()->GetOrigin()); + } + else if (move.moveCommand != MOVE_NONE) { + TurnToward(move.moveDest); } Turn(); - physicsObj.ForceDeltaMove( true ); // disable gravity + physicsObj.ForceDeltaMove(true); // disable gravity RunPhysics(); AI_ONGROUND = false; - if ( !af_push_moveables && attack.Length() && TestMelee() ) { - DirectDamage( attack, enemyEnt ); + if (!af_push_moveables && attack.Length() && TestMelee()) { + DirectDamage(attack, enemyEnt); } - if ( ai_debugMove.GetBool() ) { - const idVec3 &org = physicsObj.GetOrigin(); - gameRenderWorld->DebugBounds( colorMagenta, physicsObj.GetBounds(), org, gameLocal.msec ); - gameRenderWorld->DebugLine( colorBlue, org, move.moveDest, gameLocal.msec, true ); - gameRenderWorld->DebugLine( colorYellow, org + EyeOffset(), org + EyeOffset() + viewAxis[ 0 ] * physicsObj.GetGravityAxis() * 16.0f, gameLocal.msec, true ); + if (ai_debugMove.GetBool()) { + const idVec3& org = physicsObj.GetOrigin(); + gameRenderWorld->DebugBounds(colorMagenta, physicsObj.GetBounds(), org, gameLocal.msec); + gameRenderWorld->DebugLine(colorBlue, org, move.moveDest, gameLocal.msec, true); + gameRenderWorld->DebugLine(colorYellow, org + EyeOffset(), org + EyeOffset() + viewAxis[0] * physicsObj.GetGravityAxis() * 16.0f, gameLocal.msec, true); } } @@ -3168,26 +3259,26 @@ void idAI::StaticMove( void ) { idAI::ReactionTo ===================== */ -int idAI::ReactionTo( const idEntity *ent ) { +int idAI::ReactionTo(const idEntity* ent) { - if ( ent->fl.hidden ) { + if (ent->fl.hidden) { // ignore hidden entities return ATTACK_IGNORE; } - if ( !ent->IsType( idActor::Type ) ) { + if (!ent->IsType(idActor::Type)) { return ATTACK_IGNORE; } - const idActor *actor = static_cast( ent ); - if ( actor->IsType( idPlayer::Type ) && static_cast(actor)->noclip ) { + const idActor* actor = static_cast(ent); + if (actor->IsType(idPlayer::Type) && static_cast(actor)->noclip) { // ignore players in noclip mode return ATTACK_IGNORE; } // actors on different teams will always fight each other - if ( actor->team != team ) { - if ( actor->fl.notarget ) { + if (actor->team != team) { + if (actor->fl.notarget) { // don't attack on sight when attacker is notargeted return ATTACK_ON_DAMAGE | ATTACK_ON_ACTIVATE; } @@ -3195,7 +3286,7 @@ int idAI::ReactionTo( const idEntity *ent ) { } // monsters will fight when attacked by lower ranked monsters. rank 0 never fights back. - if ( rank && ( actor->rank < rank ) ) { + if (rank && (actor->rank < rank)) { return ATTACK_ON_DAMAGE; } @@ -3209,33 +3300,34 @@ int idAI::ReactionTo( const idEntity *ent ) { idAI::Pain ===================== */ -bool idAI::Pain( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ) { - idActor *actor; +bool idAI::Pain(idEntity* inflictor, idEntity* attacker, int damage, const idVec3& dir, int location) { + idActor* actor; - AI_PAIN = idActor::Pain( inflictor, attacker, damage, dir, location ); + AI_PAIN = idActor::Pain(inflictor, attacker, damage, dir, location); AI_DAMAGE = true; // force a blink blink_time = 0; // ignore damage from self - if ( attacker != this ) { - if ( inflictor ) { - AI_SPECIAL_DAMAGE = inflictor->spawnArgs.GetInt( "special_damage" ); - } else { + if (attacker != this) { + if (inflictor) { + AI_SPECIAL_DAMAGE = inflictor->spawnArgs.GetInt("special_damage"); + } + else { AI_SPECIAL_DAMAGE = 0; } - if ( enemy.GetEntity() != attacker && attacker->IsType( idActor::Type ) ) { - actor = ( idActor * )attacker; - if ( ReactionTo( actor ) & ATTACK_ON_DAMAGE ) { - gameLocal.AlertAI( actor ); - SetEnemy( actor ); + if (enemy.GetEntity() != attacker && attacker->IsType(idActor::Type)) { + actor = (idActor*)attacker; + if (ReactionTo(actor) & ATTACK_ON_DAMAGE) { + gameLocal.AlertAI(actor); + SetEnemy(actor); } } } - return ( AI_PAIN != 0 ); + return (AI_PAIN != 0); } @@ -3244,27 +3336,27 @@ bool idAI::Pain( idEntity *inflictor, idEntity *attacker, int damage, const idVe idAI::SpawnParticles ===================== */ -void idAI::SpawnParticles( const char *keyName ) { - const idKeyValue *kv = spawnArgs.MatchPrefix( keyName, NULL ); - while ( kv ) { +void idAI::SpawnParticles(const char* keyName) { + const idKeyValue* kv = spawnArgs.MatchPrefix(keyName, NULL); + while (kv) { particleEmitter_t pe; idStr particleName = kv->GetValue(); - if ( particleName.Length() ) { + if (particleName.Length()) { idStr jointName = kv->GetValue(); int dash = jointName.Find('-'); - if ( dash > 0 ) { - particleName = particleName.Left( dash ); - jointName = jointName.Right( jointName.Length() - dash - 1 ); + if (dash > 0) { + particleName = particleName.Left(dash); + jointName = jointName.Right(jointName.Length() - dash - 1); } - SpawnParticlesOnJoint( pe, particleName, jointName ); - particles.Append( pe ); + SpawnParticlesOnJoint(pe, particleName, jointName); + particles.Append(pe); } - kv = spawnArgs.MatchPrefix( keyName, kv ); + kv = spawnArgs.MatchPrefix(keyName, kv); } } @@ -3273,33 +3365,35 @@ void idAI::SpawnParticles( const char *keyName ) { idAI::SpawnParticlesOnJoint ===================== */ -const idDeclParticle *idAI::SpawnParticlesOnJoint( particleEmitter_t &pe, const char *particleName, const char *jointName ) { +const idDeclParticle* idAI::SpawnParticlesOnJoint(particleEmitter_t& pe, const char* particleName, const char* jointName) { idVec3 origin; idMat3 axis; - if ( *particleName == '\0' ) { - memset( &pe, 0, sizeof( pe ) ); + if (*particleName == '\0') { + memset(&pe, 0, sizeof(pe)); return pe.particle; } - pe.joint = animator.GetJointHandle( jointName ); - if ( pe.joint == INVALID_JOINT ) { - gameLocal.Warning( "Unknown particleJoint '%s' on '%s'", jointName, name.c_str() ); + pe.joint = animator.GetJointHandle(jointName); + if (pe.joint == INVALID_JOINT) { + gameLocal.Warning("Unknown particleJoint '%s' on '%s'", jointName, name.c_str()); pe.time = 0; pe.particle = NULL; - } else { - animator.GetJointTransform( pe.joint, gameLocal.time, origin, axis ); + } + else { + animator.GetJointTransform(pe.joint, gameLocal.time, origin, axis); origin = renderEntity.origin + origin * renderEntity.axis; - BecomeActive( TH_UPDATEPARTICLES ); - if ( !gameLocal.time ) { + BecomeActive(TH_UPDATEPARTICLES); + if (!gameLocal.time) { // particles with time of 0 don't show, so set the time differently on the first frame pe.time = 1; - } else { + } + else { pe.time = gameLocal.time; } - pe.particle = static_cast( declManager->FindType( DECL_PARTICLE, particleName ) ); - gameLocal.smokeParticles->EmitSmoke( pe.particle, pe.time, gameLocal.random.CRandomFloat(), origin, axis ); + pe.particle = static_cast(declManager->FindType(DECL_PARTICLE, particleName)); + gameLocal.smokeParticles->EmitSmoke(pe.particle, pe.time, gameLocal.random.CRandomFloat(), origin, axis); } return pe.particle; @@ -3310,99 +3404,100 @@ const idDeclParticle *idAI::SpawnParticlesOnJoint( particleEmitter_t &pe, const idAI::Killed ===================== */ -void idAI::Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ) { +void idAI::Killed(idEntity* inflictor, idEntity* attacker, int damage, const idVec3& dir, int location) { idAngles ang; - const char *modelDeath; + const char* modelDeath; // make sure the monster is activated EndAttack(); - if ( g_debugDamage.GetBool() ) { - gameLocal.Printf( "Damage: joint: '%s', zone '%s'\n", animator.GetJointName( ( jointHandle_t )location ), - GetDamageGroup( location ) ); + if (g_debugDamage.GetBool()) { + gameLocal.Printf("Damage: joint: '%s', zone '%s'\n", animator.GetJointName((jointHandle_t)location), + GetDamageGroup(location)); } - if ( inflictor ) { - AI_SPECIAL_DAMAGE = inflictor->spawnArgs.GetInt( "special_damage" ); - } else { + if (inflictor) { + AI_SPECIAL_DAMAGE = inflictor->spawnArgs.GetInt("special_damage"); + } + else { AI_SPECIAL_DAMAGE = 0; } - if ( AI_DEAD ) { + if (AI_DEAD) { AI_PAIN = true; AI_DAMAGE = true; return; } // stop all voice sounds - StopSound( SND_CHANNEL_VOICE, false ); - if ( head.GetEntity() ) { - head.GetEntity()->StopSound( SND_CHANNEL_VOICE, false ); - head.GetEntity()->GetAnimator()->ClearAllAnims( gameLocal.time, 100 ); + StopSound(SND_CHANNEL_VOICE, false); + if (head.GetEntity()) { + head.GetEntity()->StopSound(SND_CHANNEL_VOICE, false); + head.GetEntity()->GetAnimator()->ClearAllAnims(gameLocal.time, 100); } disableGravity = false; move.moveType = MOVETYPE_DEAD; af_push_moveables = false; - physicsObj.UseFlyMove( false ); - physicsObj.ForceDeltaMove( false ); + physicsObj.UseFlyMove(false); + physicsObj.ForceDeltaMove(false); // end our looping ambient sound - StopSound( SND_CHANNEL_AMBIENT, false ); + StopSound(SND_CHANNEL_AMBIENT, false); - if ( attacker && attacker->IsType( idActor::Type ) ) { - gameLocal.AlertAI( ( idActor * )attacker ); + if (attacker && attacker->IsType(idActor::Type)) { + gameLocal.AlertAI((idActor*)attacker); } // activate targets - ActivateTargets( attacker ); + ActivateTargets(attacker); RemoveAttachments(); RemoveProjectile(); - StopMove( MOVE_STATUS_DONE ); + StopMove(MOVE_STATUS_DONE); ClearEnemy(); - AI_DEAD = true; + AI_DEAD = true; // make monster nonsolid - physicsObj.SetContents( 0 ); + physicsObj.SetContents(0); physicsObj.GetClipModel()->Unlink(); Unbind(); - if ( StartRagdoll() ) { - StartSound( "snd_death", SND_CHANNEL_VOICE, 0, false, NULL ); + if (StartRagdoll()) { + StartSound("snd_death", SND_CHANNEL_VOICE, 0, false, NULL); } - if ( spawnArgs.GetString( "model_death", "", &modelDeath ) ) { + if (spawnArgs.GetString("model_death", "", &modelDeath)) { // lost soul is only case that does not use a ragdoll and has a model_death so get the death sound in here - StartSound( "snd_death", SND_CHANNEL_VOICE, 0, false, NULL ); - renderEntity.shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( gameLocal.time ); - SetModel( modelDeath ); - physicsObj.SetLinearVelocity( vec3_zero ); + StartSound("snd_death", SND_CHANNEL_VOICE, 0, false, NULL); + renderEntity.shaderParms[SHADERPARM_TIMEOFFSET] = -MS2SEC(gameLocal.time); + SetModel(modelDeath); + physicsObj.SetLinearVelocity(vec3_zero); physicsObj.PutToRest(); physicsObj.DisableImpact(); } restartParticles = false; - state = GetScriptFunction( "state_Killed" ); - SetState( state ); - SetWaitState( "" ); + state = GetScriptFunction("state_Killed"); + SetState(state); + SetWaitState(""); - const idKeyValue *kv = spawnArgs.MatchPrefix( "def_drops", NULL ); - while( kv ) { + const idKeyValue* kv = spawnArgs.MatchPrefix("def_drops", NULL); + while (kv) { idDict args; - args.Set( "classname", kv->GetValue() ); - args.Set( "origin", physicsObj.GetOrigin().ToString() ); - gameLocal.SpawnEntityDef( args ); - kv = spawnArgs.MatchPrefix( "def_drops", kv ); + args.Set("classname", kv->GetValue()); + args.Set("origin", physicsObj.GetOrigin().ToString()); + gameLocal.SpawnEntityDef(args); + kv = spawnArgs.MatchPrefix("def_drops", kv); } - if ( ( attacker && attacker->IsType( idPlayer::Type ) ) && ( inflictor && !inflictor->IsType( idSoulCubeMissile::Type ) ) ) { - static_cast< idPlayer* >( attacker )->AddAIKill(); + if ((attacker && attacker->IsType(idPlayer::Type)) && (inflictor && !inflictor->IsType(idSoulCubeMissile::Type))) { + static_cast(attacker)->AddAIKill(); } } @@ -3417,18 +3512,18 @@ void idAI::Killed( idEntity *inflictor, idEntity *attacker, int damage, const id idAI::PlayCinematic ===================== */ -void idAI::PlayCinematic( void ) { - const char *animname; +void idAI::PlayCinematic(void) { + const char* animname; - if ( current_cinematic >= num_cinematics ) { - if ( g_debugCinematic.GetBool() ) { - gameLocal.Printf( "%d: '%s' stop\n", gameLocal.framenum, GetName() ); + if (current_cinematic >= num_cinematics) { + if (g_debugCinematic.GetBool()) { + gameLocal.Printf("%d: '%s' stop\n", gameLocal.framenum, GetName()); } - if ( !spawnArgs.GetBool( "cinematic_no_hide" ) ) { + if (!spawnArgs.GetBool("cinematic_no_hide")) { Hide(); } current_cinematic = 0; - ActivateTargets( gameLocal.GetLocalPlayer() ); + ActivateTargets(gameLocal.GetLocalPlayer()); fl.neverDormant = false; return; } @@ -3439,14 +3534,14 @@ void idAI::PlayCinematic( void ) { allowJointMod = false; allowEyeFocus = false; - spawnArgs.GetString( va( "anim%d", current_cinematic ), NULL, &animname ); - if ( !animname ) { - gameLocal.Warning( "missing 'anim%d' key on %s", current_cinematic, name.c_str() ); + spawnArgs.GetString(va("anim%d", current_cinematic), NULL, &animname); + if (!animname) { + gameLocal.Warning("missing 'anim%d' key on %s", current_cinematic, name.c_str()); return; } - if ( g_debugCinematic.GetBool() ) { - gameLocal.Printf( "%d: '%s' start '%s'\n", gameLocal.framenum, GetName(), animname ); + if (g_debugCinematic.GetBool()) { + gameLocal.Printf("%d: '%s' start '%s'\n", gameLocal.framenum, GetName(), animname); } headAnim.animBlendFrames = 0; @@ -3459,7 +3554,7 @@ void idAI::PlayCinematic( void ) { torsoAnim.animBlendFrames = 0; torsoAnim.lastAnimBlendFrames = 0; - ProcessEvent( &AI_PlayAnim, ANIMCHANNEL_TORSO, animname ); + ProcessEvent(&AI_PlayAnim, ANIMCHANNEL_TORSO, animname); // make sure our model gets updated animator.ForceUpdate(); @@ -3469,7 +3564,7 @@ void idAI::PlayCinematic( void ) { UpdateVisuals(); Present(); - if ( head.GetEntity() ) { + if (head.GetEntity()) { // since the body anim was updated, we need to run physics to update the position of the head RunPhysics(); @@ -3492,10 +3587,10 @@ idAI::Activate Notifies the script that a monster has been activated by a trigger or flashlight ===================== */ -void idAI::Activate( idEntity *activator ) { - idPlayer *player; +void idAI::Activate(idEntity* activator) { + idPlayer* player; - if ( AI_DEAD ) { + if (AI_DEAD) { // ignore it when they're dead return; } @@ -3503,23 +3598,25 @@ void idAI::Activate( idEntity *activator ) { // make sure he's not dormant dormantStart = 0; - if ( num_cinematics ) { + if (num_cinematics) { PlayCinematic(); - } else { + } + else { AI_ACTIVATED = true; - if ( !activator || !activator->IsType( idPlayer::Type ) ) { + if (!activator || !activator->IsType(idPlayer::Type)) { player = gameLocal.GetLocalPlayer(); - } else { - player = static_cast( activator ); + } + else { + player = static_cast(activator); } - if ( ReactionTo( player ) & ATTACK_ON_ACTIVATE ) { - SetEnemy( player ); + if (ReactionTo(player) & ATTACK_ON_ACTIVATE) { + SetEnemy(player); } // update the script in cinematics so that entities don't start anims or show themselves a frame late. - if ( cinematic ) { - UpdateAIScript(); + if (cinematic) { + UpdateAIScript(); // make sure our model gets updated animator.ForceUpdate(); @@ -3529,7 +3626,7 @@ void idAI::Activate( idEntity *activator ) { UpdateVisuals(); Present(); - if ( head.GetEntity() ) { + if (head.GetEntity()) { // since the body anim was updated, we need to run physics to update the position of the head RunPhysics(); @@ -3550,7 +3647,7 @@ void idAI::Activate( idEntity *activator ) { idAI::EnemyDead ===================== */ -void idAI::EnemyDead( void ) { +void idAI::EnemyDead(void) { ClearEnemy(); AI_ENEMY_DEAD = true; } @@ -3560,15 +3657,16 @@ void idAI::EnemyDead( void ) { idAI::TalkTo ===================== */ -void idAI::TalkTo( idActor *actor ) { - if ( talk_state != TALK_OK ) { +void idAI::TalkTo(idActor* actor) { + if (talk_state != TALK_OK) { return; } talkTarget = actor; - if ( actor ) { + if (actor) { AI_TALK = true; - } else { + } + else { AI_TALK = false; } } @@ -3578,7 +3676,7 @@ void idAI::TalkTo( idActor *actor ) { idAI::GetEnemy ===================== */ -idActor *idAI::GetEnemy( void ) const { +idActor* idAI::GetEnemy(void) const { return enemy.GetEntity(); } @@ -3587,11 +3685,11 @@ idActor *idAI::GetEnemy( void ) const { idAI::GetTalkState ===================== */ -talkState_t idAI::GetTalkState( void ) const { - if ( ( talk_state != TALK_NEVER ) && AI_DEAD ) { +talkState_t idAI::GetTalkState(void) const { + if ((talk_state != TALK_NEVER) && AI_DEAD) { return TALK_DEAD; } - if ( IsHidden() ) { + if (IsHidden()) { return TALK_NEVER; } return talk_state; @@ -3602,9 +3700,9 @@ talkState_t idAI::GetTalkState( void ) const { idAI::TouchedByFlashlight ===================== */ -void idAI::TouchedByFlashlight( idActor *flashlight_owner ) { - if ( wakeOnFlashlight ) { - Activate( flashlight_owner ); +void idAI::TouchedByFlashlight(idActor* flashlight_owner) { + if (wakeOnFlashlight) { + Activate(flashlight_owner); } } @@ -3613,16 +3711,16 @@ void idAI::TouchedByFlashlight( idActor *flashlight_owner ) { idAI::ClearEnemy ===================== */ -void idAI::ClearEnemy( void ) { - if ( move.moveCommand == MOVE_TO_ENEMY ) { - StopMove( MOVE_STATUS_DEST_NOT_FOUND ); +void idAI::ClearEnemy(void) { + if (move.moveCommand == MOVE_TO_ENEMY) { + StopMove(MOVE_STATUS_DEST_NOT_FOUND); } enemyNode.Remove(); - enemy = NULL; - AI_ENEMY_IN_FOV = false; - AI_ENEMY_VISIBLE = false; - AI_ENEMY_DEAD = true; + enemy = NULL; + AI_ENEMY_IN_FOV = false; + AI_ENEMY_VISIBLE = false; + AI_ENEMY_DEAD = true; SetChatSound(); } @@ -3632,21 +3730,21 @@ void idAI::ClearEnemy( void ) { idAI::EnemyPositionValid ===================== */ -bool idAI::EnemyPositionValid( void ) const { +bool idAI::EnemyPositionValid(void) const { trace_t tr; idVec3 muzzle; idMat3 axis; - if ( !enemy.GetEntity() ) { + if (!enemy.GetEntity()) { return false; } - if ( AI_ENEMY_VISIBLE ) { + if (AI_ENEMY_VISIBLE) { return true; } - gameLocal.clip.TracePoint( tr, GetEyePosition(), lastVisibleEnemyPos + lastVisibleEnemyEyeOffset, MASK_OPAQUE, this ); - if ( tr.fraction < 1.0f ) { + gameLocal.clip.TracePoint(tr, GetEyePosition(), lastVisibleEnemyPos + lastVisibleEnemyEyeOffset, MASK_OPAQUE, this); + if (tr.fraction < 1.0f) { // can't see the area yet, so don't know if he's there or not return true; } @@ -3659,8 +3757,8 @@ bool idAI::EnemyPositionValid( void ) const { idAI::SetEnemyPosition ===================== */ -void idAI::SetEnemyPosition( void ) { - idActor *enemyEnt = enemy.GetEntity(); +void idAI::SetEnemyPosition(void) { + idActor* enemyEnt = enemy.GetEntity(); int enemyAreaNum; int areaNum; int lastVisibleReachableEnemyAreaNum; @@ -3668,25 +3766,26 @@ void idAI::SetEnemyPosition( void ) { idVec3 pos; bool onGround; - if ( !enemyEnt ) { + if (!enemyEnt) { return; } lastVisibleReachableEnemyPos = lastReachableEnemyPos; lastVisibleEnemyEyeOffset = enemyEnt->EyeOffset(); lastVisibleEnemyPos = enemyEnt->GetPhysics()->GetOrigin(); - if ( move.moveType == MOVETYPE_FLY ) { + if (move.moveType == MOVETYPE_FLY) { pos = lastVisibleEnemyPos; onGround = true; - } else { - onGround = enemyEnt->GetFloorPos( 64.0f, pos ); - if ( enemyEnt->OnLadder() ) { + } + else { + onGround = enemyEnt->GetFloorPos(64.0f, pos); + if (enemyEnt->OnLadder()) { onGround = false; } } - if ( !onGround ) { - if ( move.moveCommand == MOVE_TO_ENEMY ) { + if (!onGround) { + if (move.moveCommand == MOVE_TO_ENEMY) { AI_DEST_UNREACHABLE = true; } return; @@ -3694,56 +3793,60 @@ void idAI::SetEnemyPosition( void ) { // when we don't have an AAS, we can't tell if an enemy is reachable or not, // so just assume that he is. - if ( !aas ) { + if (!aas) { lastVisibleReachableEnemyPos = lastVisibleEnemyPos; - if ( move.moveCommand == MOVE_TO_ENEMY ) { + if (move.moveCommand == MOVE_TO_ENEMY) { AI_DEST_UNREACHABLE = false; } enemyAreaNum = 0; areaNum = 0; - } else { + } + else { lastVisibleReachableEnemyAreaNum = move.toAreaNum; - enemyAreaNum = PointReachableAreaNum( lastVisibleEnemyPos, 1.0f ); - if ( !enemyAreaNum ) { - enemyAreaNum = PointReachableAreaNum( lastReachableEnemyPos, 1.0f ); + enemyAreaNum = PointReachableAreaNum(lastVisibleEnemyPos, 1.0f); + if (!enemyAreaNum) { + enemyAreaNum = PointReachableAreaNum(lastReachableEnemyPos, 1.0f); pos = lastReachableEnemyPos; } - if ( !enemyAreaNum ) { - if ( move.moveCommand == MOVE_TO_ENEMY ) { + if (!enemyAreaNum) { + if (move.moveCommand == MOVE_TO_ENEMY) { AI_DEST_UNREACHABLE = true; } areaNum = 0; - } else { - const idVec3 &org = physicsObj.GetOrigin(); - areaNum = PointReachableAreaNum( org ); - if ( PathToGoal( path, areaNum, org, enemyAreaNum, pos ) ) { + } + else { + const idVec3& org = physicsObj.GetOrigin(); + areaNum = PointReachableAreaNum(org); + if (PathToGoal(path, areaNum, org, enemyAreaNum, pos)) { lastVisibleReachableEnemyPos = pos; lastVisibleReachableEnemyAreaNum = enemyAreaNum; - if ( move.moveCommand == MOVE_TO_ENEMY ) { + if (move.moveCommand == MOVE_TO_ENEMY) { AI_DEST_UNREACHABLE = false; } - } else if ( move.moveCommand == MOVE_TO_ENEMY ) { + } + else if (move.moveCommand == MOVE_TO_ENEMY) { AI_DEST_UNREACHABLE = true; } } } - if ( move.moveCommand == MOVE_TO_ENEMY ) { - if ( !aas ) { + if (move.moveCommand == MOVE_TO_ENEMY) { + if (!aas) { // keep the move destination up to date for wandering move.moveDest = lastVisibleReachableEnemyPos; - } else if ( enemyAreaNum ) { + } + else if (enemyAreaNum) { move.toAreaNum = lastVisibleReachableEnemyAreaNum; move.moveDest = lastVisibleReachableEnemyPos; } - if ( move.moveType == MOVETYPE_FLY ) { + if (move.moveType == MOVETYPE_FLY) { predictedPath_t path; idVec3 end = move.moveDest; end.z += enemyEnt->EyeOffset().z + fly_offset; - idAI::PredictPath( this, aas, move.moveDest, end - move.moveDest, 1000, 1000, SE_BLOCKED, path ); + idAI::PredictPath(this, aas, move.moveDest, end - move.moveDest, 1000, 1000, SE_BLOCKED, path); move.moveDest = path.endPos; - move.toAreaNum = PointReachableAreaNum( move.moveDest, 1.0f ); + move.toAreaNum = PointReachableAreaNum(move.moveDest, 1.0f); } } } @@ -3753,8 +3856,8 @@ void idAI::SetEnemyPosition( void ) { idAI::UpdateEnemyPosition ===================== */ -void idAI::UpdateEnemyPosition( void ) { - idActor *enemyEnt = enemy.GetEntity(); +void idAI::UpdateEnemyPosition(void) { + idActor* enemyEnt = enemy.GetEntity(); int enemyAreaNum; int areaNum; aasPath_t path; @@ -3762,62 +3865,65 @@ void idAI::UpdateEnemyPosition( void ) { idVec3 enemyPos; bool onGround; - if ( !enemyEnt ) { + if (!enemyEnt) { return; } - const idVec3 &org = physicsObj.GetOrigin(); + const idVec3& org = physicsObj.GetOrigin(); - if ( move.moveType == MOVETYPE_FLY ) { + if (move.moveType == MOVETYPE_FLY) { enemyPos = enemyEnt->GetPhysics()->GetOrigin(); onGround = true; - } else { - onGround = enemyEnt->GetFloorPos( 64.0f, enemyPos ); - if ( enemyEnt->OnLadder() ) { + } + else { + onGround = enemyEnt->GetFloorPos(64.0f, enemyPos); + if (enemyEnt->OnLadder()) { onGround = false; } } - if ( onGround ) { + if (onGround) { // when we don't have an AAS, we can't tell if an enemy is reachable or not, // so just assume that he is. - if ( !aas ) { + if (!aas) { enemyAreaNum = 0; lastReachableEnemyPos = enemyPos; - } else { - enemyAreaNum = PointReachableAreaNum( enemyPos, 1.0f ); - if ( enemyAreaNum ) { - areaNum = PointReachableAreaNum( org ); - if ( PathToGoal( path, areaNum, org, enemyAreaNum, enemyPos ) ) { + } + else { + enemyAreaNum = PointReachableAreaNum(enemyPos, 1.0f); + if (enemyAreaNum) { + areaNum = PointReachableAreaNum(org); + if (PathToGoal(path, areaNum, org, enemyAreaNum, enemyPos)) { lastReachableEnemyPos = enemyPos; } } } } - AI_ENEMY_IN_FOV = false; - AI_ENEMY_VISIBLE = false; + AI_ENEMY_IN_FOV = false; + AI_ENEMY_VISIBLE = false; - if ( CanSee( enemyEnt, false ) ) { + if (CanSee(enemyEnt, false)) { AI_ENEMY_VISIBLE = true; - if ( CheckFOV( enemyEnt->GetPhysics()->GetOrigin() ) ) { + if (CheckFOV(enemyEnt->GetPhysics()->GetOrigin())) { AI_ENEMY_IN_FOV = true; } SetEnemyPosition(); - } else { + } + else { // check if we heard any sounds in the last frame - if ( enemyEnt == gameLocal.GetAlertEntity() ) { - float dist = ( enemyEnt->GetPhysics()->GetOrigin() - org ).LengthSqr(); - if ( dist < Square( AI_HEARING_RANGE ) ) { + if (enemyEnt == gameLocal.GetAlertEntity()) { + float dist = (enemyEnt->GetPhysics()->GetOrigin() - org).LengthSqr(); + if (dist < Square(AI_HEARING_RANGE)) { SetEnemyPosition(); } } } - if ( ai_debugMove.GetBool() ) { - gameRenderWorld->DebugBounds( colorLtGrey, enemyEnt->GetPhysics()->GetBounds(), lastReachableEnemyPos, gameLocal.msec ); - gameRenderWorld->DebugBounds( colorWhite, enemyEnt->GetPhysics()->GetBounds(), lastVisibleReachableEnemyPos, gameLocal.msec ); + if (ai_debugMove.GetBool()) { + gameRenderWorld->DebugBounds(colorLtGrey, enemyEnt->GetPhysics()->GetBounds(), lastReachableEnemyPos, gameLocal.msec); + gameRenderWorld->DebugBounds(colorWhite, enemyEnt->GetPhysics()->GetBounds(), lastVisibleReachableEnemyPos, gameLocal.msec); } } @@ -3826,34 +3932,35 @@ void idAI::UpdateEnemyPosition( void ) { idAI::SetEnemy ===================== */ -void idAI::SetEnemy( idActor *newEnemy ) { +void idAI::SetEnemy(idActor* newEnemy) { int enemyAreaNum; - if ( AI_DEAD ) { + if (AI_DEAD) { ClearEnemy(); return; } AI_ENEMY_DEAD = false; - if ( !newEnemy ) { + if (!newEnemy) { ClearEnemy(); - } else if ( enemy.GetEntity() != newEnemy ) { + } + else if (enemy.GetEntity() != newEnemy) { enemy = newEnemy; - enemyNode.AddToEnd( newEnemy->enemyList ); - if ( newEnemy->health <= 0 ) { + enemyNode.AddToEnd(newEnemy->enemyList); + if (newEnemy->health <= 0) { EnemyDead(); return; } // let the monster know where the enemy is - newEnemy->GetAASLocation( aas, lastReachableEnemyPos, enemyAreaNum ); + newEnemy->GetAASLocation(aas, lastReachableEnemyPos, enemyAreaNum); SetEnemyPosition(); SetChatSound(); lastReachableEnemyPos = lastVisibleEnemyPos; lastVisibleReachableEnemyPos = lastReachableEnemyPos; - enemyAreaNum = PointReachableAreaNum( lastReachableEnemyPos, 1.0f ); - if ( aas && enemyAreaNum ) { - aas->PushPointIntoAreaNum( enemyAreaNum, lastReachableEnemyPos ); + enemyAreaNum = PointReachableAreaNum(lastReachableEnemyPos, 1.0f); + if (aas && enemyAreaNum) { + aas->PushPointIntoAreaNum(enemyAreaNum, lastReachableEnemyPos); lastVisibleReachableEnemyPos = lastReachableEnemyPos; } } @@ -3864,43 +3971,43 @@ void idAI::SetEnemy( idActor *newEnemy ) { idAI::FirstVisiblePointOnPath ============ */ -idVec3 idAI::FirstVisiblePointOnPath( const idVec3 origin, const idVec3 &target, int travelFlags ) const { +idVec3 idAI::FirstVisiblePointOnPath(const idVec3 origin, const idVec3& target, int travelFlags) const { int i, areaNum, targetAreaNum, curAreaNum, travelTime; idVec3 curOrigin; - idReachability *reach; + idReachability* reach; - if ( !aas ) { + if (!aas) { return origin; } - areaNum = PointReachableAreaNum( origin ); - targetAreaNum = PointReachableAreaNum( target ); + areaNum = PointReachableAreaNum(origin); + targetAreaNum = PointReachableAreaNum(target); - if ( !areaNum || !targetAreaNum ) { + if (!areaNum || !targetAreaNum) { return origin; } - if ( ( areaNum == targetAreaNum ) || PointVisible( origin ) ) { + if ((areaNum == targetAreaNum) || PointVisible(origin)) { return origin; } curAreaNum = areaNum; curOrigin = origin; - for( i = 0; i < 10; i++ ) { + for (i = 0; i < 10; i++) { - if ( !aas->RouteToGoalArea( curAreaNum, curOrigin, targetAreaNum, travelFlags, travelTime, &reach ) ) { + if (!aas->RouteToGoalArea(curAreaNum, curOrigin, targetAreaNum, travelFlags, travelTime, &reach)) { break; } - if ( !reach ) { + if (!reach) { return target; } curAreaNum = reach->toAreaNum; curOrigin = reach->end; - if ( PointVisible( curOrigin ) ) { + if (PointVisible(curOrigin)) { return curOrigin; } } @@ -3915,47 +4022,47 @@ idAI::CalculateAttackOffsets calculate joint positions on attack frames so we can do proper "can hit" tests =================== */ -void idAI::CalculateAttackOffsets( void ) { - const idDeclModelDef *modelDef; +void idAI::CalculateAttackOffsets(void) { + const idDeclModelDef* modelDef; int num; int i; int frame; - const frameCommand_t *command; + const frameCommand_t* command; idMat3 axis; - const idAnim *anim; + const idAnim* anim; jointHandle_t joint; modelDef = animator.ModelDef(); - if ( !modelDef ) { + if (!modelDef) { return; } num = modelDef->NumAnims(); - + // needs to be off while getting the offsets so that we account for the distance the monster moves in the attack anim - animator.RemoveOriginOffset( false ); + animator.RemoveOriginOffset(false); // anim number 0 is reserved for non-existant anims. to avoid off by one issues, just allocate an extra spot for // launch offsets so that anim number can be used without subtracting 1. - missileLaunchOffset.SetGranularity( 1 ); - missileLaunchOffset.SetNum( num + 1 ); - missileLaunchOffset[ 0 ].Zero(); + missileLaunchOffset.SetGranularity(1); + missileLaunchOffset.SetNum(num + 1); + missileLaunchOffset[0].Zero(); - for( i = 1; i <= num; i++ ) { - missileLaunchOffset[ i ].Zero(); - anim = modelDef->GetAnim( i ); - if ( anim ) { - frame = anim->FindFrameForFrameCommand( FC_LAUNCHMISSILE, &command ); - if ( frame >= 0 ) { - joint = animator.GetJointHandle( command->string->c_str() ); - if ( joint == INVALID_JOINT ) { - gameLocal.Error( "Invalid joint '%s' on 'launch_missile' frame command on frame %d of model '%s'", command->string->c_str(), frame, modelDef->GetName() ); + for (i = 1; i <= num; i++) { + missileLaunchOffset[i].Zero(); + anim = modelDef->GetAnim(i); + if (anim) { + frame = anim->FindFrameForFrameCommand(FC_LAUNCHMISSILE, &command); + if (frame >= 0) { + joint = animator.GetJointHandle(command->string->c_str()); + if (joint == INVALID_JOINT) { + gameLocal.Error("Invalid joint '%s' on 'launch_missile' frame command on frame %d of model '%s'", command->string->c_str(), frame, modelDef->GetName()); } - GetJointTransformForAnim( joint, i, FRAME2MS( frame ), missileLaunchOffset[ i ], axis ); + GetJointTransformForAnim(joint, i, FRAME2MS(frame), missileLaunchOffset[i], axis); } } } - animator.RemoveOriginOffset( true ); + animator.RemoveOriginOffset(true); } /* @@ -3963,11 +4070,11 @@ void idAI::CalculateAttackOffsets( void ) { idAI::CreateProjectileClipModel ===================== */ -void idAI::CreateProjectileClipModel( void ) const { - if ( projectileClipModel == NULL ) { - idBounds projectileBounds( vec3_origin ); - projectileBounds.ExpandSelf( projectileRadius ); - projectileClipModel = new idClipModel( idTraceModel( projectileBounds ) ); +void idAI::CreateProjectileClipModel(void) const { + if (projectileClipModel == NULL) { + idBounds projectileBounds(vec3_origin); + projectileBounds.ExpandSelf(projectileRadius); + projectileClipModel = new idClipModel(idTraceModel(projectileBounds)); } } @@ -3976,7 +4083,7 @@ void idAI::CreateProjectileClipModel( void ) const { idAI::GetAimDir ===================== */ -bool idAI::GetAimDir( const idVec3 &firePos, idEntity *aimAtEnt, const idEntity *ignore, idVec3 &aimDir ) const { +bool idAI::GetAimDir(const idVec3& firePos, idEntity* aimAtEnt, const idEntity* ignore, idVec3& aimDir) const { idVec3 targetPos1; idVec3 targetPos2; idVec3 delta; @@ -3984,20 +4091,22 @@ bool idAI::GetAimDir( const idVec3 &firePos, idEntity *aimAtEnt, const idEntity bool result; // if no aimAtEnt or projectile set - if ( !aimAtEnt || !projectileDef ) { - aimDir = viewAxis[ 0 ] * physicsObj.GetGravityAxis(); + if (!aimAtEnt || !projectileDef) { + aimDir = viewAxis[0] * physicsObj.GetGravityAxis(); return false; } - if ( projectileClipModel == NULL ) { + if (projectileClipModel == NULL) { CreateProjectileClipModel(); } - if ( aimAtEnt == enemy.GetEntity() ) { - static_cast( aimAtEnt )->GetAIAimTargets( lastVisibleEnemyPos, targetPos1, targetPos2 ); - } else if ( aimAtEnt->IsType( idActor::Type ) ) { - static_cast( aimAtEnt )->GetAIAimTargets( aimAtEnt->GetPhysics()->GetOrigin(), targetPos1, targetPos2 ); - } else { + if (aimAtEnt == enemy.GetEntity()) { + static_cast(aimAtEnt)->GetAIAimTargets(lastVisibleEnemyPos, targetPos1, targetPos2); + } + else if (aimAtEnt->IsType(idActor::Type)) { + static_cast(aimAtEnt)->GetAIAimTargets(aimAtEnt->GetPhysics()->GetOrigin(), targetPos1, targetPos2); + } + else { targetPos1 = aimAtEnt->GetPhysics()->GetAbsBounds().GetCenter(); targetPos2 = targetPos1; } @@ -4005,15 +4114,15 @@ bool idAI::GetAimDir( const idVec3 &firePos, idEntity *aimAtEnt, const idEntity // try aiming for chest delta = firePos - targetPos1; max_height = delta.LengthFast() * projectile_height_to_distance_ratio; - result = PredictTrajectory( firePos, targetPos1, projectileSpeed, projectileGravity, projectileClipModel, MASK_SHOT_RENDERMODEL, max_height, ignore, aimAtEnt, ai_debugTrajectory.GetBool() ? 1000 : 0, aimDir ); - if ( result || !aimAtEnt->IsType( idActor::Type ) ) { + result = PredictTrajectory(firePos, targetPos1, projectileSpeed, projectileGravity, projectileClipModel, MASK_SHOT_RENDERMODEL, max_height, ignore, aimAtEnt, ai_debugTrajectory.GetBool() ? 1000 : 0, aimDir); + if (result || !aimAtEnt->IsType(idActor::Type)) { return result; } // try aiming for head delta = firePos - targetPos2; max_height = delta.LengthFast() * projectile_height_to_distance_ratio; - result = PredictTrajectory( firePos, targetPos2, projectileSpeed, projectileGravity, projectileClipModel, MASK_SHOT_RENDERMODEL, max_height, ignore, aimAtEnt, ai_debugTrajectory.GetBool() ? 1000 : 0, aimDir ); + result = PredictTrajectory(firePos, targetPos2, projectileSpeed, projectileGravity, projectileClipModel, MASK_SHOT_RENDERMODEL, max_height, ignore, aimAtEnt, ai_debugTrajectory.GetBool() ? 1000 : 0, aimDir); return result; } @@ -4023,7 +4132,7 @@ bool idAI::GetAimDir( const idVec3 &firePos, idEntity *aimAtEnt, const idEntity idAI::BeginAttack ===================== */ -void idAI::BeginAttack( const char *name ) { +void idAI::BeginAttack(const char* name) { attack = name; lastAttackTime = gameLocal.time; } @@ -4033,7 +4142,7 @@ void idAI::BeginAttack( const char *name ) { idAI::EndAttack ===================== */ -void idAI::EndAttack( void ) { +void idAI::EndAttack(void) { attack = ""; } @@ -4042,25 +4151,25 @@ void idAI::EndAttack( void ) { idAI::CreateProjectile ===================== */ -idProjectile *idAI::CreateProjectile( const idVec3 &pos, const idVec3 &dir ) { - idEntity *ent; - const char *clsname; +idProjectile* idAI::CreateProjectile(const idVec3& pos, const idVec3& dir) { + idEntity* ent; + const char* clsname; - if ( !projectile.GetEntity() ) { - gameLocal.SpawnEntityDef( *projectileDef, &ent, false ); - if ( !ent ) { - clsname = projectileDef->GetString( "classname" ); - gameLocal.Error( "Could not spawn entityDef '%s'", clsname ); + if (!projectile.GetEntity()) { + gameLocal.SpawnEntityDef(*projectileDef, &ent, false); + if (!ent) { + clsname = projectileDef->GetString("classname"); + gameLocal.Error("Could not spawn entityDef '%s'", clsname); } - - if ( !ent->IsType( idProjectile::Type ) ) { + + if (!ent->IsType(idProjectile::Type)) { clsname = ent->GetClassname(); - gameLocal.Error( "'%s' is not an idProjectile", clsname ); + gameLocal.Error("'%s' is not an idProjectile", clsname); } - projectile = ( idProjectile * )ent; + projectile = (idProjectile*)ent; } - projectile.GetEntity()->Create( this, pos, dir ); + projectile.GetEntity()->Create(this, pos, dir); return projectile.GetEntity(); } @@ -4070,9 +4179,9 @@ idProjectile *idAI::CreateProjectile( const idVec3 &pos, const idVec3 &dir ) { idAI::RemoveProjectile ===================== */ -void idAI::RemoveProjectile( void ) { - if ( projectile.GetEntity() ) { - projectile.GetEntity()->PostEventMS( &EV_Remove, 0 ); +void idAI::RemoveProjectile(void) { + if (projectile.GetEntity()) { + projectile.GetEntity()->PostEventMS(&EV_Remove, 0); projectile = NULL; } } @@ -4082,14 +4191,14 @@ void idAI::RemoveProjectile( void ) { idAI::LaunchProjectile ===================== */ -idProjectile *idAI::LaunchProjectile( const char *jointname, idEntity *target, bool clampToAttackCone ) { +idProjectile* idAI::LaunchProjectile(const char* jointname, idEntity* target, bool clampToAttackCone) { idVec3 muzzle; idVec3 dir; idVec3 start; trace_t tr; idBounds projBounds; float distance; - const idClipModel *projClip; + const idClipModel* projClip; float attack_accuracy; float attack_cone; float projectile_spread; @@ -4101,31 +4210,32 @@ idProjectile *idAI::LaunchProjectile( const char *jointname, idEntity *target, b int i; idMat3 axis; idVec3 tmp; - idProjectile *lastProjectile; + idProjectile* lastProjectile; - if ( !projectileDef ) { - gameLocal.Warning( "%s (%s) doesn't have a projectile specified", name.c_str(), GetEntityDefName() ); + if (!projectileDef) { + gameLocal.Warning("%s (%s) doesn't have a projectile specified", name.c_str(), GetEntityDefName()); return NULL; } - attack_accuracy = spawnArgs.GetFloat( "attack_accuracy", "7" ); - attack_cone = spawnArgs.GetFloat( "attack_cone", "70" ); - projectile_spread = spawnArgs.GetFloat( "projectile_spread", "0" ); - num_projectiles = spawnArgs.GetInt( "num_projectiles", "1" ); + attack_accuracy = spawnArgs.GetFloat("attack_accuracy", "7"); + attack_cone = spawnArgs.GetFloat("attack_cone", "70"); + projectile_spread = spawnArgs.GetFloat("projectile_spread", "0"); + num_projectiles = spawnArgs.GetInt("num_projectiles", "1"); - GetMuzzle( jointname, muzzle, axis ); + GetMuzzle(jointname, muzzle, axis); - if ( !projectile.GetEntity() ) { - CreateProjectile( muzzle, axis[ 0 ] ); + if (!projectile.GetEntity()) { + CreateProjectile(muzzle, axis[0]); } lastProjectile = projectile.GetEntity(); - if ( target != NULL ) { + if (target != NULL) { tmp = target->GetPhysics()->GetAbsBounds().GetCenter() - muzzle; tmp.Normalize(); axis = tmp.ToMat3(); - } else { + } + else { axis = viewAxis; } @@ -4135,67 +4245,70 @@ idProjectile *idAI::LaunchProjectile( const char *jointname, idEntity *target, b axis[0] = -tmp; // make sure the projectile starts inside the monster bounding box - const idBounds &ownerBounds = physicsObj.GetAbsBounds(); + const idBounds& ownerBounds = physicsObj.GetAbsBounds(); projClip = lastProjectile->GetPhysics()->GetClipModel(); - projBounds = projClip->GetBounds().Rotate( axis ); + projBounds = projClip->GetBounds().Rotate(axis); // check if the owner bounds is bigger than the projectile bounds - if ( ( ( ownerBounds[1][0] - ownerBounds[0][0] ) > ( projBounds[1][0] - projBounds[0][0] ) ) && - ( ( ownerBounds[1][1] - ownerBounds[0][1] ) > ( projBounds[1][1] - projBounds[0][1] ) ) && - ( ( ownerBounds[1][2] - ownerBounds[0][2] ) > ( projBounds[1][2] - projBounds[0][2] ) ) ) { - if ( (ownerBounds - projBounds).RayIntersection( muzzle, viewAxis[ 0 ], distance ) ) { - start = muzzle + distance * viewAxis[ 0 ]; - } else { + if (((ownerBounds[1][0] - ownerBounds[0][0]) > (projBounds[1][0] - projBounds[0][0])) && + ((ownerBounds[1][1] - ownerBounds[0][1]) > (projBounds[1][1] - projBounds[0][1])) && + ((ownerBounds[1][2] - ownerBounds[0][2]) > (projBounds[1][2] - projBounds[0][2]))) { + if ((ownerBounds - projBounds).RayIntersection(muzzle, viewAxis[0], distance)) { + start = muzzle + distance * viewAxis[0]; + } + else { start = ownerBounds.GetCenter(); } - } else { + } + else { // projectile bounds bigger than the owner bounds, so just start it from the center start = ownerBounds.GetCenter(); } - gameLocal.clip.Translation( tr, start, muzzle, projClip, axis, MASK_SHOT_RENDERMODEL, this ); + gameLocal.clip.Translation(tr, start, muzzle, projClip, axis, MASK_SHOT_RENDERMODEL, this); muzzle = tr.endpos; // set aiming direction - GetAimDir( muzzle, target, this, dir ); + GetAimDir(muzzle, target, this, dir); ang = dir.ToAngles(); // adjust his aim so it's not perfect. uses sine based movement so the tracers appear less random in their spread. - float t = MS2SEC( gameLocal.time + entityNumber * 497 ); - ang.pitch += idMath::Sin16( t * 5.1 ) * attack_accuracy; - ang.yaw += idMath::Sin16( t * 6.7 ) * attack_accuracy; + float t = MS2SEC(gameLocal.time + entityNumber * 497); + ang.pitch += idMath::Sin16(t * 5.1) * attack_accuracy; + ang.yaw += idMath::Sin16(t * 6.7) * attack_accuracy; - if ( clampToAttackCone ) { + if (clampToAttackCone) { // clamp the attack direction to be within monster's attack cone so he doesn't do // things like throw the missile backwards if you're behind him - diff = idMath::AngleDelta( ang.yaw, current_yaw ); - if ( diff > attack_cone ) { + diff = idMath::AngleDelta(ang.yaw, current_yaw); + if (diff > attack_cone) { ang.yaw = current_yaw + attack_cone; - } else if ( diff < -attack_cone ) { + } + else if (diff < -attack_cone) { ang.yaw = current_yaw - attack_cone; } } axis = ang.ToMat3(); - float spreadRad = DEG2RAD( projectile_spread ); - for( i = 0; i < num_projectiles; i++ ) { + float spreadRad = DEG2RAD(projectile_spread); + for (i = 0; i < num_projectiles; i++) { // spread the projectiles out - angle = idMath::Sin( spreadRad * gameLocal.random.RandomFloat() ); - spin = (float)DEG2RAD( 360.0f ) * gameLocal.random.RandomFloat(); - dir = axis[ 0 ] + axis[ 2 ] * ( angle * idMath::Sin( spin ) ) - axis[ 1 ] * ( angle * idMath::Cos( spin ) ); + angle = idMath::Sin(spreadRad * gameLocal.random.RandomFloat()); + spin = (float)DEG2RAD(360.0f) * gameLocal.random.RandomFloat(); + dir = axis[0] + axis[2] * (angle * idMath::Sin(spin)) - axis[1] * (angle * idMath::Cos(spin)); dir.Normalize(); // launch the projectile - if ( !projectile.GetEntity() ) { - CreateProjectile( muzzle, dir ); + if (!projectile.GetEntity()) { + CreateProjectile(muzzle, dir); } lastProjectile = projectile.GetEntity(); - lastProjectile->Launch( muzzle, dir, vec3_origin ); + lastProjectile->Launch(muzzle, dir, vec3_origin); projectile = NULL; } - TriggerWeaponEffects( muzzle ); + TriggerWeaponEffects(muzzle); lastAttackTime = gameLocal.time; @@ -4212,12 +4325,13 @@ FIXME: This gets called when we call idPlayer::CalcDamagePoints from idAI::Attac possibly forcing a miss. This is harmless behavior ATM, but is not intuitive. ================ */ -void idAI::DamageFeedback( idEntity *victim, idEntity *inflictor, int &damage ) { - if ( ( victim == this ) && inflictor->IsType( idProjectile::Type ) ) { +void idAI::DamageFeedback(idEntity* victim, idEntity* inflictor, int& damage) { + if ((victim == this) && inflictor->IsType(idProjectile::Type)) { // monsters only get half damage from their own projectiles - damage = ( damage + 1 ) / 2; // round up so we don't do 0 damage + damage = (damage + 1) / 2; // round up so we don't do 0 damage - } else if ( victim == enemy.GetEntity() ) { + } + else if (victim == enemy.GetEntity()) { AI_HIT_ENEMY = true; } } @@ -4232,38 +4346,38 @@ kickDir is specified in the monster's coordinate system, and gives the direction that the view kick and knockback should go ===================== */ -void idAI::DirectDamage( const char *meleeDefName, idEntity *ent ) { - const idDict *meleeDef; - const char *p; - const idSoundShader *shader; +void idAI::DirectDamage(const char* meleeDefName, idEntity* ent) { + const idDict* meleeDef; + const char* p; + const idSoundShader* shader; - meleeDef = gameLocal.FindEntityDefDict( meleeDefName, false ); - if ( !meleeDef ) { - gameLocal.Error( "Unknown damage def '%s' on '%s'", meleeDefName, name.c_str() ); + meleeDef = gameLocal.FindEntityDefDict(meleeDefName, false); + if (!meleeDef) { + gameLocal.Error("Unknown damage def '%s' on '%s'", meleeDefName, name.c_str()); } - if ( !ent->fl.takedamage ) { - const idSoundShader *shader = declManager->FindSound(meleeDef->GetString( "snd_miss" )); - StartSoundShader( shader, SND_CHANNEL_DAMAGE, 0, false, NULL ); + if (!ent->fl.takedamage) { + const idSoundShader* shader = declManager->FindSound(meleeDef->GetString("snd_miss")); + StartSoundShader(shader, SND_CHANNEL_DAMAGE, 0, false, NULL); return; } // // do the damage // - p = meleeDef->GetString( "snd_hit" ); - if ( p && *p ) { - shader = declManager->FindSound( p ); - StartSoundShader( shader, SND_CHANNEL_DAMAGE, 0, false, NULL ); + p = meleeDef->GetString("snd_hit"); + if (p && *p) { + shader = declManager->FindSound(p); + StartSoundShader(shader, SND_CHANNEL_DAMAGE, 0, false, NULL); } idVec3 kickDir; - meleeDef->GetVector( "kickDir", "0 0 0", kickDir ); + meleeDef->GetVector("kickDir", "0 0 0", kickDir); idVec3 globalKickDir; - globalKickDir = ( viewAxis * physicsObj.GetGravityAxis() ) * kickDir; + globalKickDir = (viewAxis * physicsObj.GetGravityAxis()) * kickDir; - ent->Damage( this, this, globalKickDir, meleeDefName, 1.0f, INVALID_JOINT ); + ent->Damage(this, this, globalKickDir, meleeDefName, 1.0f, INVALID_JOINT); // end the attack if we're a multiframe attack EndAttack(); @@ -4274,17 +4388,17 @@ void idAI::DirectDamage( const char *meleeDefName, idEntity *ent ) { idAI::TestMelee ===================== */ -bool idAI::TestMelee( void ) const { +bool idAI::TestMelee(void) const { trace_t trace; - idActor *enemyEnt = enemy.GetEntity(); + idActor* enemyEnt = enemy.GetEntity(); - if ( !enemyEnt || !melee_range ) { + if (!enemyEnt || !melee_range) { return false; } //FIXME: make work with gravity vector idVec3 org = physicsObj.GetOrigin(); - const idBounds &myBounds = physicsObj.GetBounds(); + const idBounds& myBounds = physicsObj.GetBounds(); idBounds bounds; // expand the bounds out by our melee range @@ -4294,25 +4408,25 @@ bool idAI::TestMelee( void ) const { bounds[1][0] = melee_range; bounds[1][1] = melee_range; bounds[1][2] = myBounds[1][2] + 4.0f; - bounds.TranslateSelf( org ); + bounds.TranslateSelf(org); idVec3 enemyOrg = enemyEnt->GetPhysics()->GetOrigin(); idBounds enemyBounds = enemyEnt->GetPhysics()->GetBounds(); - enemyBounds.TranslateSelf( enemyOrg ); + enemyBounds.TranslateSelf(enemyOrg); - if ( ai_debugMove.GetBool() ) { - gameRenderWorld->DebugBounds( colorYellow, bounds, vec3_zero, gameLocal.msec ); + if (ai_debugMove.GetBool()) { + gameRenderWorld->DebugBounds(colorYellow, bounds, vec3_zero, gameLocal.msec); } - if ( !bounds.IntersectsBounds( enemyBounds ) ) { + if (!bounds.IntersectsBounds(enemyBounds)) { return false; } idVec3 start = GetEyePosition(); idVec3 end = enemyEnt->GetEyePosition(); - gameLocal.clip.TracePoint( trace, start, end, MASK_SHOT_BOUNDINGBOX, this ); - if ( ( trace.fraction == 1.0f ) || ( gameLocal.GetTraceEntity( trace ) == enemyEnt ) ) { + gameLocal.clip.TracePoint(trace, start, end, MASK_SHOT_BOUNDINGBOX, this); + if ((trace.fraction == 1.0f) || (gameLocal.GetTraceEntity(trace) == enemyEnt)) { return true; } @@ -4331,22 +4445,22 @@ kickDir is specified in the monster's coordinate system, and gives the direction that the view kick and knockback should go ===================== */ -bool idAI::AttackMelee( const char *meleeDefName ) { - const idDict *meleeDef; - idActor *enemyEnt = enemy.GetEntity(); - const char *p; - const idSoundShader *shader; +bool idAI::AttackMelee(const char* meleeDefName) { + const idDict* meleeDef; + idActor* enemyEnt = enemy.GetEntity(); + const char* p; + const idSoundShader* shader; - meleeDef = gameLocal.FindEntityDefDict( meleeDefName, false ); - if ( !meleeDef ) { - gameLocal.Error( "Unknown melee '%s'", meleeDefName ); + meleeDef = gameLocal.FindEntityDefDict(meleeDefName, false); + if (!meleeDef) { + gameLocal.Error("Unknown melee '%s'", meleeDefName); } - if ( !enemyEnt ) { - p = meleeDef->GetString( "snd_miss" ); - if ( p && *p ) { - shader = declManager->FindSound( p ); - StartSoundShader( shader, SND_CHANNEL_DAMAGE, 0, false, NULL ); + if (!enemyEnt) { + p = meleeDef->GetString("snd_miss"); + if (p && *p) { + shader = declManager->FindSound(p); + StartSoundShader(shader, SND_CHANNEL_DAMAGE, 0, false, NULL); } return false; } @@ -4354,31 +4468,31 @@ bool idAI::AttackMelee( const char *meleeDefName ) { // check for the "saving throw" automatic melee miss on lethal blow // stupid place for this. bool forceMiss = false; - if ( enemyEnt->IsType( idPlayer::Type ) && g_skill.GetInteger() < 2 ) { + if (enemyEnt->IsType(idPlayer::Type) && g_skill.GetInteger() < 2) { int damage, armor; - idPlayer *player = static_cast( enemyEnt ); - player->CalcDamagePoints( this, this, meleeDef, 1.0f, INVALID_JOINT, &damage, &armor ); + idPlayer* player = static_cast(enemyEnt); + player->CalcDamagePoints(this, this, meleeDef, 1.0f, INVALID_JOINT, &damage, &armor); - if ( enemyEnt->health <= damage ) { + if (enemyEnt->health <= damage) { int t = gameLocal.time - player->lastSavingThrowTime; - if ( t > SAVING_THROW_TIME ) { + if (t > SAVING_THROW_TIME) { player->lastSavingThrowTime = gameLocal.time; t = 0; } - if ( t < 1000 ) { - gameLocal.Printf( "Saving throw.\n" ); + if (t < 1000) { + gameLocal.Printf("Saving throw.\n"); forceMiss = true; } } } // make sure the trace can actually hit the enemy - if ( forceMiss || !TestMelee() ) { + if (forceMiss || !TestMelee()) { // missed - p = meleeDef->GetString( "snd_miss" ); - if ( p && *p ) { - shader = declManager->FindSound( p ); - StartSoundShader( shader, SND_CHANNEL_DAMAGE, 0, false, NULL ); + p = meleeDef->GetString("snd_miss"); + if (p && *p) { + shader = declManager->FindSound(p); + StartSoundShader(shader, SND_CHANNEL_DAMAGE, 0, false, NULL); } return false; } @@ -4386,19 +4500,19 @@ bool idAI::AttackMelee( const char *meleeDefName ) { // // do the damage // - p = meleeDef->GetString( "snd_hit" ); - if ( p && *p ) { - shader = declManager->FindSound( p ); - StartSoundShader( shader, SND_CHANNEL_DAMAGE, 0, false, NULL ); + p = meleeDef->GetString("snd_hit"); + if (p && *p) { + shader = declManager->FindSound(p); + StartSoundShader(shader, SND_CHANNEL_DAMAGE, 0, false, NULL); } idVec3 kickDir; - meleeDef->GetVector( "kickDir", "0 0 0", kickDir ); + meleeDef->GetVector("kickDir", "0 0 0", kickDir); idVec3 globalKickDir; - globalKickDir = ( viewAxis * physicsObj.GetGravityAxis() ) * kickDir; + globalKickDir = (viewAxis * physicsObj.GetGravityAxis()) * kickDir; - enemyEnt->Damage( this, this, globalKickDir, meleeDefName, 1.0f, INVALID_JOINT ); + enemyEnt->Damage(this, this, globalKickDir, meleeDefName, 1.0f, INVALID_JOINT); lastAttackTime = gameLocal.time; @@ -4410,38 +4524,39 @@ bool idAI::AttackMelee( const char *meleeDefName ) { idAI::PushWithAF ================ */ -void idAI::PushWithAF( void ) { +void idAI::PushWithAF(void) { int i, j; - afTouch_t touchList[ MAX_GENTITIES ]; - idEntity *pushed_ents[ MAX_GENTITIES ]; - idEntity *ent; + afTouch_t touchList[MAX_GENTITIES]; + idEntity* pushed_ents[MAX_GENTITIES]; + idEntity* ent; idVec3 vel; int num_pushed; num_pushed = 0; - af.ChangePose( this, gameLocal.time ); - int num = af.EntitiesTouchingAF( touchList ); - for( i = 0; i < num; i++ ) { - if ( touchList[ i ].touchedEnt->IsType( idProjectile::Type ) ) { + af.ChangePose(this, gameLocal.time); + int num = af.EntitiesTouchingAF(touchList); + for (i = 0; i < num; i++) { + if (touchList[i].touchedEnt->IsType(idProjectile::Type)) { // skip projectiles continue; } // make sure we havent pushed this entity already. this avoids causing double damage - for( j = 0; j < num_pushed; j++ ) { - if ( pushed_ents[ j ] == touchList[ i ].touchedEnt ) { + for (j = 0; j < num_pushed; j++) { + if (pushed_ents[j] == touchList[i].touchedEnt) { break; } } - if ( j >= num_pushed ) { - ent = touchList[ i ].touchedEnt; + if (j >= num_pushed) { + ent = touchList[i].touchedEnt; pushed_ents[num_pushed++] = ent; - vel = ent->GetPhysics()->GetAbsBounds().GetCenter() - touchList[ i ].touchedByBody->GetWorldOrigin(); + vel = ent->GetPhysics()->GetAbsBounds().GetCenter() - touchList[i].touchedByBody->GetWorldOrigin(); vel.Normalize(); - if ( attack.Length() && ent->IsType( idActor::Type ) ) { - ent->Damage( this, this, vel, attack, 1.0f, INVALID_JOINT ); - } else { - ent->GetPhysics()->SetLinearVelocity( 100.0f * vel, touchList[ i ].touchedClipModel->GetId() ); + if (attack.Length() && ent->IsType(idActor::Type)) { + ent->Damage(this, this, vel, attack, 1.0f, INVALID_JOINT); + } + else { + ent->GetPhysics()->SetLinearVelocity(100.0f * vel, touchList[i].touchedClipModel->GetId()); } } } @@ -4458,18 +4573,19 @@ void idAI::PushWithAF( void ) { idAI::GetMuzzle ================ */ -void idAI::GetMuzzle( const char *jointname, idVec3 &muzzle, idMat3 &axis ) { +void idAI::GetMuzzle(const char* jointname, idVec3& muzzle, idMat3& axis) { jointHandle_t joint; - if ( !jointname || !jointname[ 0 ] ) { - muzzle = physicsObj.GetOrigin() + viewAxis[ 0 ] * physicsObj.GetGravityAxis() * 14; - muzzle -= physicsObj.GetGravityNormal() * physicsObj.GetBounds()[ 1 ].z * 0.5f; - } else { - joint = animator.GetJointHandle( jointname ); - if ( joint == INVALID_JOINT ) { - gameLocal.Error( "Unknown joint '%s' on %s", jointname, GetEntityDefName() ); + if (!jointname || !jointname[0]) { + muzzle = physicsObj.GetOrigin() + viewAxis[0] * physicsObj.GetGravityAxis() * 14; + muzzle -= physicsObj.GetGravityNormal() * physicsObj.GetBounds()[1].z * 0.5f; + } + else { + joint = animator.GetJointHandle(jointname); + if (joint == INVALID_JOINT) { + gameLocal.Error("Unknown joint '%s' on %s", jointname, GetEntityDefName()); } - GetJointWorldTransform( joint, gameLocal.time, muzzle, axis ); + GetJointWorldTransform(joint, gameLocal.time, muzzle, axis); } } @@ -4478,34 +4594,73 @@ void idAI::GetMuzzle( const char *jointname, idVec3 &muzzle, idMat3 &axis ) { idAI::TriggerWeaponEffects ================ */ -void idAI::TriggerWeaponEffects( const idVec3 &muzzle ) { +void idAI::TriggerWeaponEffects(const idVec3& muzzle) { idVec3 org; idMat3 axis; - if ( !g_muzzleFlash.GetBool() ) { + if (!g_muzzleFlash.GetBool()) { return; } - // muzzle flash - // offset the shader parms so muzzle flashes show up - renderEntity.shaderParms[SHADERPARM_TIMEOFFSET] = -MS2SEC( gameLocal.time ); - renderEntity.shaderParms[ SHADERPARM_DIVERSITY ] = gameLocal.random.CRandomFloat(); + // Keep the model/material flash behavior exactly as before. + renderEntity.shaderParms[SHADERPARM_TIMEOFFSET] = -MS2SEC(gameLocal.time); + renderEntity.shaderParms[SHADERPARM_DIVERSITY] = gameLocal.random.CRandomFloat(); - if ( flashJointWorld != INVALID_JOINT ) { - GetJointWorldTransform( flashJointWorld, gameLocal.time, org, axis ); + // Reset the light back to full strength every time the AI fires. The update + // path fades it down; reloading the spawn args here prevents a faded value + // from becoming the new base color on rapid-fire monsters. + idVec3 flashColor; + spawnArgs.GetVector("flashColor", "1 0.82 0.45", flashColor); + if (flashColor.LengthSqr() <= 0.0001f) { + flashColor.Set(1.0f, 0.82f, 0.45f); + } - if ( worldMuzzleFlash.lightRadius.x > 0.0f ) { - worldMuzzleFlash.axis = axis; - worldMuzzleFlash.shaderParms[SHADERPARM_TIMEOFFSET] = -MS2SEC( gameLocal.time ); - if ( worldMuzzleFlashHandle != - 1 ) { - gameRenderWorld->UpdateLightDef( worldMuzzleFlashHandle, &worldMuzzleFlash ); - } else { - worldMuzzleFlashHandle = gameRenderWorld->AddLightDef( &worldMuzzleFlash ); - } - muzzleFlashEnd = gameLocal.time + flashTime; - UpdateVisuals(); + float flashRadius = spawnArgs.GetFloat("flashRadius", "0"); + if (flashRadius <= 0.0f) { + flashRadius = spawnArgs.GetFloat("muzzleLightRadius", "150"); + } + if (flashRadius <= 0.0f) { + flashRadius = 150.0f; + } + + if (flashTime <= 0) { + flashTime = SEC2MS(spawnArgs.GetFloat("flashTime", "0.12")); + if (flashTime <= 0) { + flashTime = 120; } } + + if (flashJointWorld != INVALID_JOINT) { + GetJointWorldTransform(flashJointWorld, gameLocal.time, org, axis); + } + else { + org = muzzle; + axis = viewAxis * physicsObj.GetGravityAxis(); + } + + worldMuzzleFlash.origin = org; + worldMuzzleFlash.axis = axis; + worldMuzzleFlash.noShadows = true; + worldMuzzleFlash.pointLight = true; + worldMuzzleFlash.shaderParms[SHADERPARM_TIMEOFFSET] = -MS2SEC(gameLocal.time); + worldMuzzleFlash.shaderParms[SHADERPARM_RED] = flashColor.x; + worldMuzzleFlash.shaderParms[SHADERPARM_GREEN] = flashColor.y; + worldMuzzleFlash.shaderParms[SHADERPARM_BLUE] = flashColor.z; + worldMuzzleFlash.shaderParms[SHADERPARM_ALPHA] = 1.0f; + worldMuzzleFlash.lightRadius[0] = flashRadius; + worldMuzzleFlash.lightRadius[1] = flashRadius; + worldMuzzleFlash.lightRadius[2] = flashRadius; + + muzzleFlashEnd = gameLocal.time + flashTime; + + if (worldMuzzleFlashHandle != -1) { + gameRenderWorld->UpdateLightDef(worldMuzzleFlashHandle, &worldMuzzleFlash); + } + else { + worldMuzzleFlashHandle = gameRenderWorld->AddLightDef(&worldMuzzleFlash); + } + + UpdateVisuals(); } /* @@ -4513,20 +4668,52 @@ void idAI::TriggerWeaponEffects( const idVec3 &muzzle ) { idAI::UpdateMuzzleFlash ================ */ -void idAI::UpdateMuzzleFlash( void ) { - if ( worldMuzzleFlashHandle != -1 ) { - if ( gameLocal.time >= muzzleFlashEnd ) { - gameRenderWorld->FreeLightDef( worldMuzzleFlashHandle ); - worldMuzzleFlashHandle = -1; - } else { - idVec3 muzzle; - animator.GetJointTransform( flashJointWorld, gameLocal.time, muzzle, worldMuzzleFlash.axis ); - animator.GetJointTransform( flashJointWorld, gameLocal.time, muzzle, worldMuzzleFlash.axis ); - muzzle = physicsObj.GetOrigin() + ( muzzle + modelOffset ) * viewAxis * physicsObj.GetGravityAxis(); - worldMuzzleFlash.origin = muzzle; - gameRenderWorld->UpdateLightDef( worldMuzzleFlashHandle, &worldMuzzleFlash ); - } +void idAI::UpdateMuzzleFlash(void) { + if (worldMuzzleFlashHandle == -1) { + return; } + + if (IsHidden() || gameLocal.time >= muzzleFlashEnd) { + gameRenderWorld->FreeLightDef(worldMuzzleFlashHandle); + worldMuzzleFlashHandle = -1; + muzzleFlashEnd = 0; + return; + } + + // Follow the muzzle joint while the flash is alive. + if (flashJointWorld != INVALID_JOINT) { + GetJointWorldTransform(flashJointWorld, gameLocal.time, worldMuzzleFlash.origin, worldMuzzleFlash.axis); + } + + // Fade the actual light, not just the material time parm. This gives the AI + // muzzle flash the same behavior as the idWeapon weapon-fire light: bright at + // the shot, then quickly decays while staying attached to the joint. + float fade = 1.0f; + if (flashTime > 0) { + fade = (float)(muzzleFlashEnd - gameLocal.time) / (float)flashTime; + } + if (fade < 0.0f) { + fade = 0.0f; + } + else if (fade > 1.0f) { + fade = 1.0f; + } + + // Smooth the fade so it starts hot and falls off faster near the end. + fade = fade * fade; + + idVec3 flashColor; + spawnArgs.GetVector("flashColor", "1 0.82 0.45", flashColor); + if (flashColor.LengthSqr() <= 0.0001f) { + flashColor.Set(1.0f, 0.82f, 0.45f); + } + + worldMuzzleFlash.shaderParms[SHADERPARM_RED] = flashColor.x * fade; + worldMuzzleFlash.shaderParms[SHADERPARM_GREEN] = flashColor.y * fade; + worldMuzzleFlash.shaderParms[SHADERPARM_BLUE] = flashColor.z * fade; + worldMuzzleFlash.shaderParms[SHADERPARM_ALPHA] = fade; + + gameRenderWorld->UpdateLightDef(worldMuzzleFlashHandle, &worldMuzzleFlash); } /* @@ -4534,17 +4721,23 @@ void idAI::UpdateMuzzleFlash( void ) { idAI::Hide ================ */ -void idAI::Hide( void ) { +void idAI::Hide(void) { + if (worldMuzzleFlashHandle != -1) { + gameRenderWorld->FreeLightDef(worldMuzzleFlashHandle); + worldMuzzleFlashHandle = -1; + } + muzzleFlashEnd = 0; + idActor::Hide(); fl.takedamage = false; - physicsObj.SetContents( 0 ); + physicsObj.SetContents(0); physicsObj.GetClipModel()->Unlink(); - StopSound( SND_CHANNEL_AMBIENT, false ); + StopSound(SND_CHANNEL_AMBIENT, false); SetChatSound(); - AI_ENEMY_IN_FOV = false; - AI_ENEMY_VISIBLE = false; - StopMove( MOVE_STATUS_DONE ); + AI_ENEMY_IN_FOV = false; + AI_ENEMY_VISIBLE = false; + StopMove(MOVE_STATUS_DONE); } /* @@ -4552,19 +4745,21 @@ void idAI::Hide( void ) { idAI::Show ================ */ -void idAI::Show( void ) { +void idAI::Show(void) { idActor::Show(); - if ( spawnArgs.GetBool( "big_monster" ) ) { - physicsObj.SetContents( 0 ); - } else if ( use_combat_bbox ) { - physicsObj.SetContents( CONTENTS_BODY|CONTENTS_SOLID ); - } else { - physicsObj.SetContents( CONTENTS_BODY ); + if (spawnArgs.GetBool("big_monster")) { + physicsObj.SetContents(0); } - physicsObj.GetClipModel()->Link( gameLocal.clip ); - fl.takedamage = !spawnArgs.GetBool( "noDamage" ); + else if (use_combat_bbox) { + physicsObj.SetContents(CONTENTS_BODY | CONTENTS_SOLID); + } + else { + physicsObj.SetContents(CONTENTS_BODY); + } + physicsObj.GetClipModel()->Link(gameLocal.clip); + fl.takedamage = !spawnArgs.GetBool("noDamage"); SetChatSound(); - StartSound( "snd_ambient", SND_CHANNEL_AMBIENT, 0, false, NULL ); + StartSound("snd_ambient", SND_CHANNEL_AMBIENT, 0, false, NULL); } /* @@ -4572,29 +4767,33 @@ void idAI::Show( void ) { idAI::SetChatSound ===================== */ -void idAI::SetChatSound( void ) { - const char *snd; +void idAI::SetChatSound(void) { + const char* snd; - if ( IsHidden() ) { + if (IsHidden()) { snd = NULL; - } else if ( enemy.GetEntity() ) { - snd = spawnArgs.GetString( "snd_chatter_combat", NULL ); - chat_min = SEC2MS( spawnArgs.GetFloat( "chatter_combat_min", "5" ) ); - chat_max = SEC2MS( spawnArgs.GetFloat( "chatter_combat_max", "10" ) ); - } else if ( !spawnArgs.GetBool( "no_idle_chatter" ) ) { - snd = spawnArgs.GetString( "snd_chatter", NULL ); - chat_min = SEC2MS( spawnArgs.GetFloat( "chatter_min", "5" ) ); - chat_max = SEC2MS( spawnArgs.GetFloat( "chatter_max", "10" ) ); - } else { + } + else if (enemy.GetEntity()) { + snd = spawnArgs.GetString("snd_chatter_combat", NULL); + chat_min = SEC2MS(spawnArgs.GetFloat("chatter_combat_min", "5")); + chat_max = SEC2MS(spawnArgs.GetFloat("chatter_combat_max", "10")); + } + else if (!spawnArgs.GetBool("no_idle_chatter")) { + snd = spawnArgs.GetString("snd_chatter", NULL); + chat_min = SEC2MS(spawnArgs.GetFloat("chatter_min", "5")); + chat_max = SEC2MS(spawnArgs.GetFloat("chatter_max", "10")); + } + else { snd = NULL; } - if ( snd && *snd ) { - chat_snd = declManager->FindSound( snd ); + if (snd && *snd) { + chat_snd = declManager->FindSound(snd); // set the next chat time - chat_time = gameLocal.time + chat_min + gameLocal.random.RandomFloat() * ( chat_max - chat_min ); - } else { + chat_time = gameLocal.time + chat_min + gameLocal.random.RandomFloat() * (chat_max - chat_min); + } + else { chat_snd = NULL; } } @@ -4606,20 +4805,20 @@ idAI::CanPlayChatterSounds Used for playing chatter sounds on monsters. ================ */ -bool idAI::CanPlayChatterSounds( void ) const { - if ( AI_DEAD ) { +bool idAI::CanPlayChatterSounds(void) const { + if (AI_DEAD) { return false; } - if ( IsHidden() ) { + if (IsHidden()) { return false; } - if ( enemy.GetEntity() ) { + if (enemy.GetEntity()) { return true; } - if ( spawnArgs.GetBool( "no_idle_chatter" ) ) { + if (spawnArgs.GetBool("no_idle_chatter")) { return false; } @@ -4631,16 +4830,16 @@ bool idAI::CanPlayChatterSounds( void ) const { idAI::PlayChatter ===================== */ -void idAI::PlayChatter( void ) { +void idAI::PlayChatter(void) { // check if it's time to play a chat sound - if ( AI_DEAD || !chat_snd || ( chat_time > gameLocal.time ) ) { + if (AI_DEAD || !chat_snd || (chat_time > gameLocal.time)) { return; } - StartSoundShader( chat_snd, SND_CHANNEL_VOICE, 0, false, NULL ); + StartSoundShader(chat_snd, SND_CHANNEL_VOICE, 0, false, NULL); // set the next chat time - chat_time = gameLocal.time + chat_min + gameLocal.random.RandomFloat() * ( chat_max - chat_min ); + chat_time = gameLocal.time + chat_min + gameLocal.random.RandomFloat() * (chat_max - chat_min); } /* @@ -4648,36 +4847,38 @@ void idAI::PlayChatter( void ) { idAI::UpdateParticles ===================== */ -void idAI::UpdateParticles( void ) { - if ( ( thinkFlags & TH_UPDATEPARTICLES) && !IsHidden() ) { +void idAI::UpdateParticles(void) { + if ((thinkFlags & TH_UPDATEPARTICLES) && !IsHidden()) { idVec3 realVector; idMat3 realAxis; int particlesAlive = 0; - for ( int i = 0; i < particles.Num(); i++ ) { - if ( particles[i].particle && particles[i].time ) { + for (int i = 0; i < particles.Num(); i++) { + if (particles[i].particle && particles[i].time) { particlesAlive++; if (af.IsActive()) { realAxis = mat3_identity; realVector = GetPhysics()->GetOrigin(); - } else { - animator.GetJointTransform( particles[i].joint, gameLocal.time, realVector, realAxis ); + } + else { + animator.GetJointTransform(particles[i].joint, gameLocal.time, realVector, realAxis); realAxis *= renderEntity.axis; - realVector = physicsObj.GetOrigin() + ( realVector + modelOffset ) * ( viewAxis * physicsObj.GetGravityAxis() ); + realVector = physicsObj.GetOrigin() + (realVector + modelOffset) * (viewAxis * physicsObj.GetGravityAxis()); } - if ( !gameLocal.smokeParticles->EmitSmoke( particles[i].particle, particles[i].time, gameLocal.random.CRandomFloat(), realVector, realAxis )) { - if ( restartParticles ) { + if (!gameLocal.smokeParticles->EmitSmoke(particles[i].particle, particles[i].time, gameLocal.random.CRandomFloat(), realVector, realAxis)) { + if (restartParticles) { particles[i].time = gameLocal.time; - } else { + } + else { particles[i].time = 0; particlesAlive--; } } } } - if ( particlesAlive == 0 ) { - BecomeInactive( TH_UPDATEPARTICLES ); + if (particlesAlive == 0) { + BecomeInactive(TH_UPDATEPARTICLES); } } } @@ -4687,14 +4888,14 @@ void idAI::UpdateParticles( void ) { idAI::TriggerParticles ===================== */ -void idAI::TriggerParticles( const char *jointName ) { +void idAI::TriggerParticles(const char* jointName) { jointHandle_t jointNum; - jointNum = animator.GetJointHandle( jointName ); - for ( int i = 0; i < particles.Num(); i++ ) { - if ( particles[i].joint == jointNum ) { + jointNum = animator.GetJointHandle(jointName); + for (int i = 0; i < particles.Num(); i++) { + if (particles[i].joint == jointNum) { particles[i].time = gameLocal.time; - BecomeActive( TH_UPDATEPARTICLES ); + BecomeActive(TH_UPDATEPARTICLES); } } } @@ -4711,7 +4912,7 @@ void idAI::TriggerParticles( const char *jointName ) { idAI::UpdateAnimationControllers ================ */ -bool idAI::UpdateAnimationControllers( void ) { +bool idAI::UpdateAnimationControllers(void) { idVec3 local; idVec3 focusPos; idQuat jawQuat; @@ -4724,42 +4925,45 @@ bool idAI::UpdateAnimationControllers( void ) { idMat3 mat; idMat3 axis; idMat3 orientationJointAxis; - idAFAttachment *headEnt = head.GetEntity(); + idAFAttachment* headEnt = head.GetEntity(); idVec3 eyepos; idVec3 pos; int i; idAngles jointAng; float orientationJointYaw; - if ( AI_DEAD ) { + if (AI_DEAD) { return idActor::UpdateAnimationControllers(); } - if ( orientationJoint == INVALID_JOINT ) { + if (orientationJoint == INVALID_JOINT) { orientationJointAxis = viewAxis; orientationJointPos = physicsObj.GetOrigin(); orientationJointYaw = current_yaw; - } else { - GetJointWorldTransform( orientationJoint, gameLocal.time, orientationJointPos, orientationJointAxis ); - orientationJointYaw = orientationJointAxis[ 2 ].ToYaw(); - orientationJointAxis = idAngles( 0.0f, orientationJointYaw, 0.0f ).ToMat3(); + } + else { + GetJointWorldTransform(orientationJoint, gameLocal.time, orientationJointPos, orientationJointAxis); + orientationJointYaw = orientationJointAxis[2].ToYaw(); + orientationJointAxis = idAngles(0.0f, orientationJointYaw, 0.0f).ToMat3(); } - if ( focusJoint != INVALID_JOINT ) { - if ( headEnt ) { - headEnt->GetJointWorldTransform( focusJoint, gameLocal.time, eyepos, axis ); - } else { - GetJointWorldTransform( focusJoint, gameLocal.time, eyepos, axis ); + if (focusJoint != INVALID_JOINT) { + if (headEnt) { + headEnt->GetJointWorldTransform(focusJoint, gameLocal.time, eyepos, axis); + } + else { + GetJointWorldTransform(focusJoint, gameLocal.time, eyepos, axis); } eyeOffset.z = eyepos.z - physicsObj.GetOrigin().z; - if ( ai_debugMove.GetBool() ) { - gameRenderWorld->DebugLine( colorRed, eyepos, eyepos + orientationJointAxis[ 0 ] * 32.0f, gameLocal.msec ); + if (ai_debugMove.GetBool()) { + gameRenderWorld->DebugLine(colorRed, eyepos, eyepos + orientationJointAxis[0] * 32.0f, gameLocal.msec); } - } else { + } + else { eyepos = GetEyePosition(); } - if ( headEnt ) { + if (headEnt) { CopyJointsFromBodyToHead(); } @@ -4772,74 +4976,80 @@ bool idAI::UpdateAnimationControllers( void ) { // in order to see how many times an entity transforms the joints per frame. idActor::UpdateAnimationControllers(); - idEntity *focusEnt = focusEntity.GetEntity(); - if ( !allowJointMod || !allowEyeFocus || ( gameLocal.time >= focusTime ) ) { - focusPos = GetEyePosition() + orientationJointAxis[ 0 ] * 512.0f; - } else if ( focusEnt == NULL ) { + idEntity* focusEnt = focusEntity.GetEntity(); + if (!allowJointMod || !allowEyeFocus || (gameLocal.time >= focusTime)) { + focusPos = GetEyePosition() + orientationJointAxis[0] * 512.0f; + } + else if (focusEnt == NULL) { // keep looking at last position until focusTime is up focusPos = currentFocusPos; - } else if ( focusEnt == enemy.GetEntity() ) { + } + else if (focusEnt == enemy.GetEntity()) { focusPos = lastVisibleEnemyPos + lastVisibleEnemyEyeOffset - eyeVerticalOffset * enemy.GetEntity()->GetPhysics()->GetGravityNormal(); - } else if ( focusEnt->IsType( idActor::Type ) ) { - focusPos = static_cast( focusEnt )->GetEyePosition() - eyeVerticalOffset * focusEnt->GetPhysics()->GetGravityNormal(); - } else { + } + else if (focusEnt->IsType(idActor::Type)) { + focusPos = static_cast(focusEnt)->GetEyePosition() - eyeVerticalOffset * focusEnt->GetPhysics()->GetGravityNormal(); + } + else { focusPos = focusEnt->GetPhysics()->GetOrigin(); } - currentFocusPos = currentFocusPos + ( focusPos - currentFocusPos ) * eyeFocusRate; + currentFocusPos = currentFocusPos + (focusPos - currentFocusPos) * eyeFocusRate; // determine yaw from origin instead of from focus joint since joint may be offset, which can cause us to bounce between two angles dir = focusPos - orientationJointPos; - newLookAng.yaw = idMath::AngleNormalize180( dir.ToYaw() - orientationJointYaw ); + newLookAng.yaw = idMath::AngleNormalize180(dir.ToYaw() - orientationJointYaw); newLookAng.roll = 0.0f; newLookAng.pitch = 0.0f; #if 0 - gameRenderWorld->DebugLine( colorRed, orientationJointPos, focusPos, gameLocal.msec ); - gameRenderWorld->DebugLine( colorYellow, orientationJointPos, orientationJointPos + orientationJointAxis[ 0 ] * 32.0f, gameLocal.msec ); - gameRenderWorld->DebugLine( colorGreen, orientationJointPos, orientationJointPos + newLookAng.ToForward() * 48.0f, gameLocal.msec ); + gameRenderWorld->DebugLine(colorRed, orientationJointPos, focusPos, gameLocal.msec); + gameRenderWorld->DebugLine(colorYellow, orientationJointPos, orientationJointPos + orientationJointAxis[0] * 32.0f, gameLocal.msec); + gameRenderWorld->DebugLine(colorGreen, orientationJointPos, orientationJointPos + newLookAng.ToForward() * 48.0f, gameLocal.msec); #endif // determine pitch from joint position dir = focusPos - eyepos; dir.NormalizeFast(); - orientationJointAxis.ProjectVector( dir, localDir ); - newLookAng.pitch = -idMath::AngleNormalize180( localDir.ToPitch() ); - newLookAng.roll = 0.0f; + orientationJointAxis.ProjectVector(dir, localDir); + newLookAng.pitch = -idMath::AngleNormalize180(localDir.ToPitch()); + newLookAng.roll = 0.0f; diff = newLookAng - lookAng; - - if ( eyeAng != diff ) { + + if (eyeAng != diff) { eyeAng = diff; - eyeAng.Clamp( eyeMin, eyeMax ); + eyeAng.Clamp(eyeMin, eyeMax); idAngles angDelta = diff - eyeAng; - if ( !angDelta.Compare( ang_zero, 0.1f ) ) { + if (!angDelta.Compare(ang_zero, 0.1f)) { alignHeadTime = gameLocal.time; - } else { - alignHeadTime = gameLocal.time + ( 0.5f + 0.5f * gameLocal.random.RandomFloat() ) * focusAlignTime; + } + else { + alignHeadTime = gameLocal.time + (0.5f + 0.5f * gameLocal.random.RandomFloat()) * focusAlignTime; } } - if ( idMath::Fabs( newLookAng.yaw ) < 0.1f ) { + if (idMath::Fabs(newLookAng.yaw) < 0.1f) { alignHeadTime = gameLocal.time; } - if ( ( gameLocal.time >= alignHeadTime ) || ( gameLocal.time < forceAlignHeadTime ) ) { - alignHeadTime = gameLocal.time + ( 0.5f + 0.5f * gameLocal.random.RandomFloat() ) * focusAlignTime; + if ((gameLocal.time >= alignHeadTime) || (gameLocal.time < forceAlignHeadTime)) { + alignHeadTime = gameLocal.time + (0.5f + 0.5f * gameLocal.random.RandomFloat()) * focusAlignTime; destLookAng = newLookAng; - destLookAng.Clamp( lookMin, lookMax ); + destLookAng.Clamp(lookMin, lookMax); } diff = destLookAng - lookAng; - if ( ( lookMin.pitch == -180.0f ) && ( lookMax.pitch == 180.0f ) ) { - if ( ( diff.pitch > 180.0f ) || ( diff.pitch <= -180.0f ) ) { + if ((lookMin.pitch == -180.0f) && (lookMax.pitch == 180.0f)) { + if ((diff.pitch > 180.0f) || (diff.pitch <= -180.0f)) { diff.pitch = 360.0f - diff.pitch; } } - if ( ( lookMin.yaw == -180.0f ) && ( lookMax.yaw == 180.0f ) ) { - if ( diff.yaw > 180.0f ) { + if ((lookMin.yaw == -180.0f) && (lookMax.yaw == 180.0f)) { + if (diff.yaw > 180.0f) { diff.yaw -= 360.0f; - } else if ( diff.yaw <= -180.0f ) { + } + else if (diff.yaw <= -180.0f) { diff.yaw += 360.0f; } } @@ -4847,42 +5057,45 @@ bool idAI::UpdateAnimationControllers( void ) { lookAng.Normalize180(); jointAng.roll = 0.0f; - for( i = 0; i < lookJoints.Num(); i++ ) { - jointAng.pitch = lookAng.pitch * lookJointAngles[ i ].pitch; - jointAng.yaw = lookAng.yaw * lookJointAngles[ i ].yaw; - animator.SetJointAxis( lookJoints[ i ], JOINTMOD_WORLD, jointAng.ToMat3() ); + for (i = 0; i < lookJoints.Num(); i++) { + jointAng.pitch = lookAng.pitch * lookJointAngles[i].pitch; + jointAng.yaw = lookAng.yaw * lookJointAngles[i].yaw; + animator.SetJointAxis(lookJoints[i], JOINTMOD_WORLD, jointAng.ToMat3()); } - if ( move.moveType == MOVETYPE_FLY ) { + if (move.moveType == MOVETYPE_FLY) { // lean into turns AdjustFlyingAngles(); } - - if ( headEnt ) { - idAnimator *headAnimator = headEnt->GetAnimator(); - if ( allowEyeFocus ) { - idMat3 eyeAxis = ( lookAng + eyeAng ).ToMat3(); idMat3 headTranspose = headEnt->GetPhysics()->GetAxis().Transpose(); - axis = eyeAxis * orientationJointAxis; - left = axis[ 1 ] * eyeHorizontalOffset; + if (headEnt) { + idAnimator* headAnimator = headEnt->GetAnimator(); + + if (allowEyeFocus) { + idMat3 eyeAxis = (lookAng + eyeAng).ToMat3(); idMat3 headTranspose = headEnt->GetPhysics()->GetAxis().Transpose(); + axis = eyeAxis * orientationJointAxis; + left = axis[1] * eyeHorizontalOffset; eyepos -= headEnt->GetPhysics()->GetOrigin(); - headAnimator->SetJointPos( leftEyeJoint, JOINTMOD_WORLD_OVERRIDE, eyepos + ( axis[ 0 ] * 64.0f + left ) * headTranspose ); - headAnimator->SetJointPos( rightEyeJoint, JOINTMOD_WORLD_OVERRIDE, eyepos + ( axis[ 0 ] * 64.0f - left ) * headTranspose ); - } else { - headAnimator->ClearJoint( leftEyeJoint ); - headAnimator->ClearJoint( rightEyeJoint ); + headAnimator->SetJointPos(leftEyeJoint, JOINTMOD_WORLD_OVERRIDE, eyepos + (axis[0] * 64.0f + left) * headTranspose); + headAnimator->SetJointPos(rightEyeJoint, JOINTMOD_WORLD_OVERRIDE, eyepos + (axis[0] * 64.0f - left) * headTranspose); } - } else { - if ( allowEyeFocus ) { - idMat3 eyeAxis = ( lookAng + eyeAng ).ToMat3(); - axis = eyeAxis * orientationJointAxis; - left = axis[ 1 ] * eyeHorizontalOffset; - eyepos += axis[ 0 ] * 64.0f - physicsObj.GetOrigin(); - animator.SetJointPos( leftEyeJoint, JOINTMOD_WORLD_OVERRIDE, eyepos + left ); - animator.SetJointPos( rightEyeJoint, JOINTMOD_WORLD_OVERRIDE, eyepos - left ); - } else { - animator.ClearJoint( leftEyeJoint ); - animator.ClearJoint( rightEyeJoint ); + else { + headAnimator->ClearJoint(leftEyeJoint); + headAnimator->ClearJoint(rightEyeJoint); + } + } + else { + if (allowEyeFocus) { + idMat3 eyeAxis = (lookAng + eyeAng).ToMat3(); + axis = eyeAxis * orientationJointAxis; + left = axis[1] * eyeHorizontalOffset; + eyepos += axis[0] * 64.0f - physicsObj.GetOrigin(); + animator.SetJointPos(leftEyeJoint, JOINTMOD_WORLD_OVERRIDE, eyepos + left); + animator.SetJointPos(rightEyeJoint, JOINTMOD_WORLD_OVERRIDE, eyepos - left); + } + else { + animator.ClearJoint(leftEyeJoint); + animator.ClearJoint(rightEyeJoint); } } @@ -4895,11 +5108,11 @@ idCombatNode ***********************************************************************/ -const idEventDef EV_CombatNode_MarkUsed( "markUsed" ); +const idEventDef EV_CombatNode_MarkUsed("markUsed"); -CLASS_DECLARATION( idEntity, idCombatNode ) - EVENT( EV_CombatNode_MarkUsed, idCombatNode::Event_MarkUsed ) - EVENT( EV_Activate, idCombatNode::Event_Activate ) +CLASS_DECLARATION(idEntity, idCombatNode) +EVENT(EV_CombatNode_MarkUsed, idCombatNode::Event_MarkUsed) +EVENT(EV_Activate, idCombatNode::Event_Activate) END_CLASS /* @@ -4907,7 +5120,7 @@ END_CLASS idCombatNode::idCombatNode ===================== */ -idCombatNode::idCombatNode( void ) { +idCombatNode::idCombatNode(void) { min_dist = 0.0f; max_dist = 0.0f; cone_dist = 0.0f; @@ -4924,16 +5137,16 @@ idCombatNode::idCombatNode( void ) { idCombatNode::Save ===================== */ -void idCombatNode::Save( idSaveGame *savefile ) const { - savefile->WriteFloat( min_dist ); - savefile->WriteFloat( max_dist ); - savefile->WriteFloat( cone_dist ); - savefile->WriteFloat( min_height ); - savefile->WriteFloat( max_height ); - savefile->WriteVec3( cone_left ); - savefile->WriteVec3( cone_right ); - savefile->WriteVec3( offset ); - savefile->WriteBool( disabled ); +void idCombatNode::Save(idSaveGame* savefile) const { + savefile->WriteFloat(min_dist); + savefile->WriteFloat(max_dist); + savefile->WriteFloat(cone_dist); + savefile->WriteFloat(min_height); + savefile->WriteFloat(max_height); + savefile->WriteVec3(cone_left); + savefile->WriteVec3(cone_right); + savefile->WriteVec3(offset); + savefile->WriteBool(disabled); } /* @@ -4941,16 +5154,16 @@ void idCombatNode::Save( idSaveGame *savefile ) const { idCombatNode::Restore ===================== */ -void idCombatNode::Restore( idRestoreGame *savefile ) { - savefile->ReadFloat( min_dist ); - savefile->ReadFloat( max_dist ); - savefile->ReadFloat( cone_dist ); - savefile->ReadFloat( min_height ); - savefile->ReadFloat( max_height ); - savefile->ReadVec3( cone_left ); - savefile->ReadVec3( cone_right ); - savefile->ReadVec3( offset ); - savefile->ReadBool( disabled ); +void idCombatNode::Restore(idRestoreGame* savefile) { + savefile->ReadFloat(min_dist); + savefile->ReadFloat(max_dist); + savefile->ReadFloat(cone_dist); + savefile->ReadFloat(min_height); + savefile->ReadFloat(max_height); + savefile->ReadVec3(cone_left); + savefile->ReadVec3(cone_right); + savefile->ReadVec3(offset); + savefile->ReadBool(disabled); } /* @@ -4958,31 +5171,31 @@ void idCombatNode::Restore( idRestoreGame *savefile ) { idCombatNode::Spawn ===================== */ -void idCombatNode::Spawn( void ) { +void idCombatNode::Spawn(void) { float fov; float yaw; float height; - min_dist = spawnArgs.GetFloat( "min" ); - max_dist = spawnArgs.GetFloat( "max" ); - height = spawnArgs.GetFloat( "height" ); - fov = spawnArgs.GetFloat( "fov", "60" ); - offset = spawnArgs.GetVector( "offset" ); + min_dist = spawnArgs.GetFloat("min"); + max_dist = spawnArgs.GetFloat("max"); + height = spawnArgs.GetFloat("height"); + fov = spawnArgs.GetFloat("fov", "60"); + offset = spawnArgs.GetVector("offset"); - const idVec3 &org = GetPhysics()->GetOrigin() + offset; + const idVec3& org = GetPhysics()->GetOrigin() + offset; min_height = org.z - height * 0.5f; max_height = min_height + height; - const idMat3 &axis = GetPhysics()->GetAxis(); - yaw = axis[ 0 ].ToYaw(); + const idMat3& axis = GetPhysics()->GetAxis(); + yaw = axis[0].ToYaw(); - idAngles leftang( 0.0f, yaw + fov * 0.5f - 90.0f, 0.0f ); + idAngles leftang(0.0f, yaw + fov * 0.5f - 90.0f, 0.0f); cone_left = leftang.ToForward(); - idAngles rightang( 0.0f, yaw - fov * 0.5f + 90.0f, 0.0f ); + idAngles rightang(0.0f, yaw - fov * 0.5f + 90.0f, 0.0f); cone_right = rightang.ToForward(); - disabled = spawnArgs.GetBool( "start_off" ); + disabled = spawnArgs.GetBool("start_off"); } /* @@ -4990,7 +5203,7 @@ void idCombatNode::Spawn( void ) { idCombatNode::IsDisabled ===================== */ -bool idCombatNode::IsDisabled( void ) const { +bool idCombatNode::IsDisabled(void) const { return disabled; } @@ -4999,51 +5212,53 @@ bool idCombatNode::IsDisabled( void ) const { idCombatNode::DrawDebugInfo ===================== */ -void idCombatNode::DrawDebugInfo( void ) { - idEntity *ent; - idCombatNode *node; - idPlayer *player = gameLocal.GetLocalPlayer(); +void idCombatNode::DrawDebugInfo(void) { + idEntity* ent; + idCombatNode* node; + idPlayer* player = gameLocal.GetLocalPlayer(); idVec4 color; - idBounds bounds( idVec3( -16, -16, 0 ), idVec3( 16, 16, 0 ) ); - - for( ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) { - if ( !ent->IsType( idCombatNode::Type ) ) { + idBounds bounds(idVec3(-16, -16, 0), idVec3(16, 16, 0)); + + for (ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next()) { + if (!ent->IsType(idCombatNode::Type)) { continue; } - node = static_cast( ent ); - if ( node->disabled ) { + node = static_cast(ent); + if (node->disabled) { color = colorMdGrey; - } else if ( player && node->EntityInView( player, player->GetPhysics()->GetOrigin() ) ) { + } + else if (player && node->EntityInView(player, player->GetPhysics()->GetOrigin())) { color = colorYellow; - } else { + } + else { color = colorRed; } - idVec3 leftDir( -node->cone_left.y, node->cone_left.x, 0.0f ); - idVec3 rightDir( node->cone_right.y, -node->cone_right.x, 0.0f ); + idVec3 leftDir(-node->cone_left.y, node->cone_left.x, 0.0f); + idVec3 rightDir(node->cone_right.y, -node->cone_right.x, 0.0f); idVec3 org = node->GetPhysics()->GetOrigin() + node->offset; - bounds[ 1 ].z = node->max_height; + bounds[1].z = node->max_height; leftDir.NormalizeFast(); rightDir.NormalizeFast(); - const idMat3 &axis = node->GetPhysics()->GetAxis(); - float cone_dot = node->cone_right * axis[ 1 ]; - if ( idMath::Fabs( cone_dot ) > 0.1 ) { + const idMat3& axis = node->GetPhysics()->GetAxis(); + float cone_dot = node->cone_right * axis[1]; + if (idMath::Fabs(cone_dot) > 0.1) { float cone_dist = node->max_dist / cone_dot; idVec3 pos1 = org + leftDir * node->min_dist; idVec3 pos2 = org + leftDir * cone_dist; idVec3 pos3 = org + rightDir * node->min_dist; idVec3 pos4 = org + rightDir * cone_dist; - gameRenderWorld->DebugLine( color, node->GetPhysics()->GetOrigin(), ( pos1 + pos3 ) * 0.5f, gameLocal.msec ); - gameRenderWorld->DebugLine( color, pos1, pos2, gameLocal.msec ); - gameRenderWorld->DebugLine( color, pos1, pos3, gameLocal.msec ); - gameRenderWorld->DebugLine( color, pos3, pos4, gameLocal.msec ); - gameRenderWorld->DebugLine( color, pos2, pos4, gameLocal.msec ); - gameRenderWorld->DebugBounds( color, bounds, org, gameLocal.msec ); + gameRenderWorld->DebugLine(color, node->GetPhysics()->GetOrigin(), (pos1 + pos3) * 0.5f, gameLocal.msec); + gameRenderWorld->DebugLine(color, pos1, pos2, gameLocal.msec); + gameRenderWorld->DebugLine(color, pos1, pos3, gameLocal.msec); + gameRenderWorld->DebugLine(color, pos3, pos4, gameLocal.msec); + gameRenderWorld->DebugLine(color, pos2, pos4, gameLocal.msec); + gameRenderWorld->DebugBounds(color, bounds, org, gameLocal.msec); } } } @@ -5053,32 +5268,32 @@ void idCombatNode::DrawDebugInfo( void ) { idCombatNode::EntityInView ===================== */ -bool idCombatNode::EntityInView( idActor *actor, const idVec3 &pos ) { - if ( !actor || ( actor->health <= 0 ) ) { +bool idCombatNode::EntityInView(idActor* actor, const idVec3& pos) { + if (!actor || (actor->health <= 0)) { return false; } - const idBounds &bounds = actor->GetPhysics()->GetBounds(); - if ( ( pos.z + bounds[ 1 ].z < min_height ) || ( pos.z + bounds[ 0 ].z >= max_height ) ) { + const idBounds& bounds = actor->GetPhysics()->GetBounds(); + if ((pos.z + bounds[1].z < min_height) || (pos.z + bounds[0].z >= max_height)) { return false; } - const idVec3 &org = GetPhysics()->GetOrigin() + offset; - const idMat3 &axis = GetPhysics()->GetAxis(); + const idVec3& org = GetPhysics()->GetOrigin() + offset; + const idMat3& axis = GetPhysics()->GetAxis(); idVec3 dir = pos - org; - float dist = dir * axis[ 0 ]; - - if ( ( dist < min_dist ) || ( dist > max_dist ) ) { + float dist = dir * axis[0]; + + if ((dist < min_dist) || (dist > max_dist)) { return false; } float left_dot = dir * cone_left; - if ( left_dot < 0.0f ) { + if (left_dot < 0.0f) { return false; } float right_dot = dir * cone_right; - if ( right_dot < 0.0f ) { + if (right_dot < 0.0f) { return false; } @@ -5090,7 +5305,7 @@ bool idCombatNode::EntityInView( idActor *actor, const idVec3 &pos ) { idCombatNode::Event_Activate ===================== */ -void idCombatNode::Event_Activate( idEntity *activator ) { +void idCombatNode::Event_Activate(idEntity* activator) { disabled = !disabled; } @@ -5099,8 +5314,8 @@ void idCombatNode::Event_Activate( idEntity *activator ) { idCombatNode::Event_MarkUsed ===================== */ -void idCombatNode::Event_MarkUsed( void ) { - if ( spawnArgs.GetBool( "use_once" ) ) { +void idCombatNode::Event_MarkUsed(void) { + if (spawnArgs.GetBool("use_once")) { disabled = true; } } diff --git a/neo/doom3/game/ai/AI_events.cpp b/neo/doom3/game/ai/AI_events.cpp index 2eff6d32..97ed5f78 100644 --- a/neo/doom3/game/ai/AI_events.cpp +++ b/neo/doom3/game/ai/AI_events.cpp @@ -519,6 +519,15 @@ void idAI::MuzzleFlash(const char* jointname) { idVec3 muzzle; idMat3 axis; + // Match the idWeapon behavior: the short-lived muzzle light should attach + // to the same joint the script fired from, not blindly to a hardcoded joint. + if (jointname && jointname[0]) { + jointHandle_t joint = animator.GetJointHandle(jointname); + if (joint != INVALID_JOINT) { + flashJointWorld = joint; + } + } + GetMuzzle(jointname, muzzle, axis); TriggerWeaponEffects(muzzle); } diff --git a/neo/engine/opengl/gl_d3d12shim.cpp b/neo/engine/opengl/gl_d3d12shim.cpp index c3737808..d2074db3 100644 --- a/neo/engine/opengl/gl_d3d12shim.cpp +++ b/neo/engine/opengl/gl_d3d12shim.cpp @@ -2308,7 +2308,12 @@ cbuffer DrawCB : register(b0) // Full object-space displacement amplitude for the tessellation domain shader. // The CPU side keeps this conservative, but clamp here too so a bad material // strength cannot explode the mesh. -#define gTessellationDisplacement clamp(gMaterialMapPad.w, 0.0, 0.35) +// Raised from the old 0.35 cap so stronger materials can push deeper, while +// the hull shader below uses shared-edge tess factors to prevent crack artifacts. +#define gTessellationDisplacement clamp(gMaterialMapPad.w, 0.0, 0.50) +#define QD3D12_TESS_MIN_FACTOR 2.0 +#define QD3D12_TESS_MAX_FACTOR 15.0 +#define QD3D12_TESS_TARGET_EDGE_PIXELS 28.0 Texture2D gTex0 : register(t0); Texture2D gTex1 : register(t1); @@ -2565,6 +2570,38 @@ float QD3D12_GetHeightFromNormalMapLOD(float2 uv, float lod) return QD3D12_HeightFromNormalSample(gNormalMap.SampleLevel(gSamp2, uv, lod)); } +float2 QD3D12_NormalMapTexelSize() +{ + uint w = 1; + uint h = 1; + gNormalMap.GetDimensions(w, h); + return rcp(max(float2((float)w, (float)h), float2(1.0, 1.0))); +} + +float QD3D12_GetFilteredTessHeight(float2 uv) +{ + // Hardware tessellation magnifies tiny normal-map compression errors. + // A light cross filter keeps the deeper displacement stable without + // blurring the color/normal sampling path used by the pixel shader. + float2 texel = QD3D12_NormalMapTexelSize(); + float center = QD3D12_GetHeightFromNormalMapLOD(uv, 0.0); + float hx0 = QD3D12_GetHeightFromNormalMapLOD(uv - float2(texel.x, 0.0), 0.0); + float hx1 = QD3D12_GetHeightFromNormalMapLOD(uv + float2(texel.x, 0.0), 0.0); + float hy0 = QD3D12_GetHeightFromNormalMapLOD(uv - float2(0.0, texel.y), 0.0); + float hy1 = QD3D12_GetHeightFromNormalMapLOD(uv + float2(0.0, texel.y), 0.0); + return saturate(center * 0.50 + (hx0 + hx1 + hy0 + hy1) * 0.125); +} + +float QD3D12_CleanCenteredTessHeight(float height) +{ + // Suppress barely-visible single-texel noise before applying the now deeper + // displacement. This removes acne-like spikes while preserving real relief. + float centered = (height - 0.5) * 2.0; + float s = (centered < 0.0) ? -1.0 : 1.0; + float a = saturate((abs(centered) - 0.015) * (1.0 / 0.985)); + return s * a; +} + float3 QD3D12_BuildFallbackTangent(float3 n) { float3 up = (abs(n.z) < 0.999) ? float3(0.0, 0.0, 1.0) : float3(0.0, 1.0, 0.0); @@ -2721,7 +2758,8 @@ float4 BuildGlowEmission(VSOut i) { return QD3D12_SampleGlow(i); } - +)HLSL" +R"HLSL( float4 BuildSpecularAlbedo(VSOut i) { if (gUseSpecularMap <= 0.0) @@ -2838,29 +2876,68 @@ TessCP QD3D12_MakeTessCP(VSOut i) return o; } -float QD3D12_ComputeNormalMapTessFactor(InputPatch patch) +float2 QD3D12_ClipXYToNdc(float4 clipPos) { - float h0 = QD3D12_GetHeightFromNormalMapLOD(patch[0].uv0, 0.0); - float h1 = QD3D12_GetHeightFromNormalMapLOD(patch[1].uv0, 0.0); - float h2 = QD3D12_GetHeightFromNormalMapLOD(patch[2].uv0, 0.0); - float heightRange = max(abs(h0 - h1), max(abs(h1 - h2), abs(h2 - h0))); + return clipPos.xy / max(abs(clipPos.w), 1.0e-6); +} + +float QD3D12_EdgeLengthPixels(float4 clipA, float4 clipB) +{ + float2 ndcA = QD3D12_ClipXYToNdc(clipA); + float2 ndcB = QD3D12_ClipXYToNdc(clipB); + return length((ndcA - ndcB) * max(gRenderSize, float2(1.0, 1.0)) * 0.5); +} + +float QD3D12_ComputeNormalMapTessEdgeFactor(VSOut a, VSOut b) +{ + if (gUseNormalMap <= 0.5) + return 1.0; + + float ha = QD3D12_GetFilteredTessHeight(a.uv0); + float hb = QD3D12_GetFilteredTessHeight(b.uv0); + float hm = QD3D12_GetFilteredTessHeight((a.uv0 + b.uv0) * 0.5); + + // This edge-only factor is the crack fix: neighboring triangles that share + // this edge compute the same tessellation factor because they use only the + // two shared vertices and the same midpoint sample. + float heightRange = max(abs(ha - hb), abs(hm - (ha + hb) * 0.5) * 2.0); + float edgePixels = QD3D12_EdgeLengthPixels(a.currClip, b.currClip); + float uvSpan = length(a.uv0 - b.uv0); - // Give displaced normal-mapped surfaces enough subdivision to show the larger - // height push. fractional_odd will quantize these into stable odd partitions, - // so 3/5/7 are the practical quality tiers for default/strong materials. float strength = clamp(max(gNormalMapStrength, 0.0), 0.0, 4.0); - float factor = 2.0 + strength * 1.0 + heightRange * 8.0; - return (gUseNormalMap > 0.5) ? clamp(factor, 2.0, 7.0) : 1.0; + float screenTerm = sqrt(max(edgePixels, 1.0) / QD3D12_TESS_TARGET_EDGE_PIXELS); + float heightTerm = heightRange * (10.0 + strength * 4.0); + float uvTerm = saturate(uvSpan * 4.0) * 2.0; + float displacementTerm = saturate(gTessellationDisplacement * 6.0) * 2.0; + + float factor = 1.0 + strength * 0.75 + screenTerm * 3.0 + heightTerm + uvTerm + displacementTerm; + return clamp(factor, QD3D12_TESS_MIN_FACTOR, QD3D12_TESS_MAX_FACTOR); } HSConstOut HSMainConstants(InputPatch patch) { HSConstOut o; - float factor = QD3D12_ComputeNormalMapTessFactor(patch); - o.edge[0] = factor; - o.edge[1] = factor; - o.edge[2] = factor; - o.inside = factor; + + if (gUseNormalMap <= 0.5) + { + o.edge[0] = 1.0; + o.edge[1] = 1.0; + o.edge[2] = 1.0; + o.inside = 1.0; + return o; + } + + // D3D tri patch edge order is opposite the named control point: + // edge 0 = CP1-CP2, edge 1 = CP2-CP0, edge 2 = CP0-CP1. + float e0 = QD3D12_ComputeNormalMapTessEdgeFactor(patch[1], patch[2]); + float e1 = QD3D12_ComputeNormalMapTessEdgeFactor(patch[2], patch[0]); + float e2 = QD3D12_ComputeNormalMapTessEdgeFactor(patch[0], patch[1]); + float maxEdge = max(e0, max(e1, e2)); + + o.edge[0] = e0; + o.edge[1] = e1; + o.edge[2] = e2; + o.inside = clamp((e0 + e1 + e2 + maxEdge) * 0.25, QD3D12_TESS_MIN_FACTOR, QD3D12_TESS_MAX_FACTOR); return o; } @@ -2869,6 +2946,7 @@ HSConstOut HSMainConstants(InputPatch patch) [outputtopology("triangle_ccw")] [outputcontrolpoints(3)] [patchconstantfunc("HSMainConstants")] +[maxtessfactor(15.0)] TessCP HSMain(InputPatch patch, uint cpId : SV_OutputControlPointID) { return QD3D12_MakeTessCP(patch[cpId]); @@ -2911,8 +2989,8 @@ VSOut DSMain(HSConstOut tessFactors, float3 bary : SV_DomainLocation, const Outp VSOut o; float3 objNormal = QD3D12_SafeNormalize(i.objNormal, float3(0.0, 0.0, 1.0)); - float height = QD3D12_GetHeightFromNormalMapLOD(i.uv0, 0.0); - float centeredHeight = (height - 0.5) * 2.0; + float height = QD3D12_GetFilteredTessHeight(i.uv0); + float centeredHeight = QD3D12_CleanCenteredTessHeight(height); float displacement = centeredHeight * gTessellationDisplacement; float3 displacedObjPos = i.objPos + objNormal * displacement; @@ -7629,7 +7707,7 @@ static void QD3D12_FilterMipPixelGammaAware( center[1] /= centerA; center[2] /= centerA; - const float sharpen = 0.22f; + const float sharpen = 1.0f; filtered[0] = ClampValue(filtered[0] + (center[0] - filtered[0]) * sharpen, 0.0f, 1.0f); filtered[1] = ClampValue(filtered[1] + (center[1] - filtered[1]) * sharpen, 0.0f, 1.0f); filtered[2] = ClampValue(filtered[2] + (center[2] - filtered[2]) * sharpen, 0.0f, 1.0f); @@ -8935,14 +9013,15 @@ static void QD3D12_FlushQueuedBatches() dc->materialMapPad[1] = batch.key.specularMapStrength; dc->materialMapPad[2] = QD3D12_PipelineUsesAlphaBlend(batch.key.pipeline) ? 1.0f : 0.0f; // Normal-map strength now drives a visibly stronger object-space displacement. - // Keep a hard upper bound because old RGB-only normal maps are often noisy and - // are not authored as true height maps. Default strength 1.0 gives about - // +/-0.08 object units for authored alpha-height maps and outward lift for - // RGB-only bump detail; glNormalMapStrengthf() can push it higher. + // The hull shader can now subdivide much deeper, so the CPU side permits a + // deeper push too while the shader filters/suppresses tiny bump-map noise. + // Default strength 1.0 gives about +/-0.12 object units for authored alpha + // height maps and outward lift for RGB-only bump detail; glNormalMapStrengthf() + // can push it higher up to the hard 0.50 object-unit safety cap. const float tessStrength = ClampValue(batch.key.normalMapStrength, 0.0f, 4.0f); - const float tessDisplacementScale = 0.08f; + const float tessDisplacementScale = 0.12f; dc->materialMapPad[3] = QD3D12_UseNormalMapTessellationPSO(batch.key, nativeColorOnly) ? - ClampValue(tessStrength * tessDisplacementScale, 0.0f, 0.35f) : 0.0f; + ClampValue(tessStrength * tessDisplacementScale, 0.0f, 0.50f) : 0.0f; if (batch.key.useARBPrograms) { diff --git a/neo/engine/renderer/draw_dx.cpp b/neo/engine/renderer/draw_dx.cpp index f64008e7..d0af3dd9 100644 --- a/neo/engine/renderer/draw_dx.cpp +++ b/neo/engine/renderer/draw_dx.cpp @@ -176,7 +176,7 @@ void RB_DXDrawInteractions(void) const float r = srcLight.shaderParms[SHADERPARM_RED]; const float g = srcLight.shaderParms[SHADERPARM_GREEN]; const float b = srcLight.shaderParms[SHADERPARM_BLUE]; - const float intensity = 6.0f; + const float intensity = 4.0f; glRaytracingLight_t light = {}; bool supported = true; @@ -187,8 +187,8 @@ void RB_DXDrawInteractions(void) vLight->globalLightOrigin.x, vLight->globalLightOrigin.y, vLight->globalLightOrigin.z, - srcLight.lightRadius[0] * 1.4f, - srcLight.lightRadius[1] * 1.4f, + srcLight.lightRadius[0] * 1.25f, + srcLight.lightRadius[1] * 1.25f, srcLight.lightRadius[2] * 1.4f, r, g, b, intensity);