mirror of
https://github.com/ENSL/NS.git
synced 2025-02-16 09:01:56 +00:00
commit
c710fa347a
26 changed files with 688 additions and 222 deletions
Binary file not shown.
|
@ -30,7 +30,7 @@ MarineReactionTime=0.4
|
|||
MarineAimSkill=0.1
|
||||
MarineMovementTracking=0.1
|
||||
MarineViewSpeed=0.5
|
||||
AlienReactionTime=0.4
|
||||
AlienReactionTime=0.5
|
||||
AlienAimSkill=0.2
|
||||
AlienMovementTracking=0.2
|
||||
AlienViewSpeed=0.75
|
||||
|
@ -89,4 +89,4 @@ TeamSize=co_kestrel:5/5
|
|||
# ChamberSequence:movement/?/?
|
||||
# Or if you want sensory always last, but movement and defence random, use
|
||||
# ChamberSequence=?/?/sensory
|
||||
ChamberSequence=defense/movement/sensory
|
||||
ChamberSequence=?/?/?
|
||||
|
|
|
@ -256,6 +256,7 @@
|
|||
<ClCompile Include="..\mod\AvHAIPlayer.cpp" />
|
||||
<ClCompile Include="..\mod\AvHAIPlayerManager.cpp" />
|
||||
<ClCompile Include="..\mod\AvHAIPlayerUtil.cpp" />
|
||||
<ClCompile Include="..\mod\AvHAISoundQueue.cpp" />
|
||||
<ClCompile Include="..\mod\AvHAITactical.cpp" />
|
||||
<ClCompile Include="..\mod\AvHAITask.cpp" />
|
||||
<ClCompile Include="..\mod\AvHAIWeaponHelper.cpp" />
|
||||
|
@ -1390,6 +1391,7 @@
|
|||
<ClInclude Include="..\mod\AvHAIPlayer.h" />
|
||||
<ClInclude Include="..\mod\AvHAIPlayerManager.h" />
|
||||
<ClInclude Include="..\mod\AvHAIPlayerUtil.h" />
|
||||
<ClInclude Include="..\mod\AvHAISoundQueue.h" />
|
||||
<ClInclude Include="..\mod\AvHAITactical.h" />
|
||||
<ClInclude Include="..\mod\AvHAITask.h" />
|
||||
<ClInclude Include="..\mod\AvHAIWeaponHelper.h" />
|
||||
|
|
|
@ -545,6 +545,9 @@
|
|||
<ClCompile Include="..\mod\AvHAIPlayer.cpp">
|
||||
<Filter>mod\bots</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\mod\AvHAISoundQueue.cpp">
|
||||
<Filter>mod\bots</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="activity.h">
|
||||
|
@ -967,5 +970,8 @@
|
|||
<ClInclude Include="..\mod\AvHAIPlayer.h">
|
||||
<Filter>mod\bots</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\mod\AvHAISoundQueue.h">
|
||||
<Filter>mod\bots</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -25,6 +25,10 @@
|
|||
#include "gamerules.h"
|
||||
#include "../mod/AvHSpecials.h"
|
||||
|
||||
#ifdef AVH_SERVER
|
||||
#include "../mod/AvHAIPlayerManager.h"
|
||||
#endif
|
||||
|
||||
static char *memfgets( byte *pMemFile, int fileSize, int &filePos, char *pBuffer, int bufferSize );
|
||||
|
||||
|
||||
|
@ -1429,7 +1433,9 @@ void EMIT_SOUND_DYN(edict_t *entity, int channel, const char *sample, float volu
|
|||
ALERT( at_aiconsole, "Unable to find %s in sentences.txt\n", sample );
|
||||
}
|
||||
else
|
||||
{
|
||||
EMIT_SOUND_DYN2(entity, channel, sample, volume, attenuation, flags, pitch);
|
||||
}
|
||||
}
|
||||
|
||||
// play a specific sentence over the HEV suit speaker - just pass player entity, and !sentencename
|
||||
|
|
|
@ -718,7 +718,7 @@ void CONFIG_RegenerateIniFile()
|
|||
fprintf(NewConfigFile, "# ChamberSequence:movement/?/?\n");
|
||||
fprintf(NewConfigFile, "# Or if you want sensory always last, but movement and defence random, use\n");
|
||||
fprintf(NewConfigFile, "# ChamberSequence=?/?/sensory\n");
|
||||
fprintf(NewConfigFile, "ChamberSequence=defense/movement/sensory\n");
|
||||
fprintf(NewConfigFile, "ChamberSequence=?/?/?\n");
|
||||
|
||||
fflush(NewConfigFile);
|
||||
fclose(NewConfigFile);
|
||||
|
|
|
@ -497,6 +497,7 @@ typedef struct _ENEMY_STATUS
|
|||
float NextUpdateTime = 0.0f; // When the bot can next react to a change in target's state
|
||||
float NextVelocityUpdateTime = 0.0f; // When the bot can next react to a change in target's state
|
||||
float EndTrackingTime = 0.0f; // When to stop "sensing" enemy movement after losing LOS
|
||||
float CertaintyOfLocation = 0.0f; // How sure the bot is where the enemy is if they're cloaked
|
||||
|
||||
} enemy_status;
|
||||
|
||||
|
@ -804,6 +805,8 @@ typedef struct AVH_AI_PLAYER
|
|||
float ServerUpdateDelta = 0.0f; // How long since we last called RunPlayerMove
|
||||
float LastServerUpdateTime = 0.0f; // When we last called RunPlayerMove
|
||||
|
||||
float HearingThreshold = 0.0f; // How loud does a sound need to be before the bot detects it? This is set when hearing a sound so that louder sounds drown out quieter ones, and decrements quickly
|
||||
|
||||
} AvHAIPlayer;
|
||||
|
||||
|
||||
|
|
|
@ -2059,7 +2059,7 @@ dtStatus FindPathClosestToPoint(AvHAIPlayer* pBot, const BotMoveStyle MoveStyle,
|
|||
|
||||
Vector FromFloorLocation = AdjustPointForPathfinding(FromLocation);
|
||||
|
||||
nav_door* LiftReference = UTIL_GetNavDoorByEdict(pBot->Edict->v.groundentity);
|
||||
nav_door* LiftReference = UTIL_GetLiftReferenceByEdict(pBot->Edict->v.groundentity);
|
||||
bool bMustDisembarkLiftFirst = false;
|
||||
Vector LiftStart = ZERO_VECTOR;
|
||||
Vector LiftEnd = ZERO_VECTOR;
|
||||
|
@ -3691,11 +3691,16 @@ void StructureBlockedMove(AvHAIPlayer* pBot, const Vector StartPoint, const Vect
|
|||
|
||||
void BlockedMove(AvHAIPlayer* pBot, const Vector StartPoint, const Vector EndPoint)
|
||||
{
|
||||
Vector vForward = UTIL_GetVectorNormal2D(EndPoint - StartPoint);
|
||||
Vector vForward = UTIL_GetVectorNormal2D(EndPoint - pBot->Edict->v.origin);
|
||||
|
||||
if (vIsZero(vForward))
|
||||
{
|
||||
vForward = UTIL_GetForwardVector2D(pBot->Edict->v.angles);
|
||||
vForward = UTIL_GetVectorNormal2D(EndPoint - StartPoint);
|
||||
|
||||
if (vIsZero(vForward))
|
||||
{
|
||||
vForward = UTIL_GetForwardVector2D(pBot->Edict->v.angles);
|
||||
}
|
||||
}
|
||||
|
||||
pBot->desiredMovementDir = vForward;
|
||||
|
@ -3713,6 +3718,10 @@ void BlockedMove(AvHAIPlayer* pBot, const Vector StartPoint, const Vector EndPoi
|
|||
if (FaceDot < 0.95f)
|
||||
{
|
||||
float MoveSpeed = vSize2D(pBot->Edict->v.velocity);
|
||||
if (MoveSpeed < 20.0f)
|
||||
{
|
||||
MoveSpeed = 100.0f;
|
||||
}
|
||||
Vector NewVelocity = vForward * MoveSpeed;
|
||||
NewVelocity.z = pBot->Edict->v.velocity.z;
|
||||
|
||||
|
@ -3729,6 +3738,11 @@ void JumpMove(AvHAIPlayer* pBot, const Vector StartPoint, const Vector EndPoint)
|
|||
if (vIsZero(vForward))
|
||||
{
|
||||
vForward = UTIL_GetVectorNormal2D(EndPoint - StartPoint);
|
||||
|
||||
if (vIsZero(vForward))
|
||||
{
|
||||
vForward = UTIL_GetForwardVector2D(pBot->Edict->v.angles);
|
||||
}
|
||||
}
|
||||
|
||||
pBot->desiredMovementDir = vForward;
|
||||
|
@ -3746,6 +3760,10 @@ void JumpMove(AvHAIPlayer* pBot, const Vector StartPoint, const Vector EndPoint)
|
|||
if (FaceDot < 0.95f)
|
||||
{
|
||||
float MoveSpeed = vSize2D(pBot->Edict->v.velocity);
|
||||
if (MoveSpeed < 20.0f)
|
||||
{
|
||||
MoveSpeed = 100.0f;
|
||||
}
|
||||
Vector NewVelocity = vForward * MoveSpeed;
|
||||
NewVelocity.z = pBot->Edict->v.velocity.z;
|
||||
|
||||
|
@ -4729,7 +4747,7 @@ void BlinkClimbMove(AvHAIPlayer* pBot, const Vector StartPoint, const Vector End
|
|||
if (GetPlayerCurrentWeapon(pBot->Player) != WEAPON_FADE_BLINK) { return; }
|
||||
|
||||
// Only blink if we're below the target climb height
|
||||
if (pEdict->v.origin.z < RequiredClimbHeight + 32.0f)
|
||||
if (pEdict->v.origin.z < RequiredClimbHeight + 4.0f)
|
||||
{
|
||||
float HeightToClimb = (fabsf(pEdict->v.origin.z - RequiredClimbHeight));
|
||||
|
||||
|
@ -4746,6 +4764,12 @@ void BlinkClimbMove(AvHAIPlayer* pBot, const Vector StartPoint, const Vector End
|
|||
if (FaceDot < 0.95f)
|
||||
{
|
||||
float MoveSpeed = vSize2D(pBot->Edict->v.velocity);
|
||||
|
||||
if (MoveSpeed < 20.0f)
|
||||
{
|
||||
MoveSpeed = 100.0f;
|
||||
}
|
||||
|
||||
Vector NewVelocity = MoveDir * MoveSpeed;
|
||||
NewVelocity.z = pBot->Edict->v.velocity.z;
|
||||
|
||||
|
@ -6365,6 +6389,7 @@ bool MoveTo(AvHAIPlayer* pBot, const Vector Destination, const BotMoveStyle Move
|
|||
{
|
||||
pBot->BotNavInfo.StuckInfo.bPathFollowFailed = false;
|
||||
ClearBotMovement(pBot);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -6811,6 +6836,7 @@ void BotFollowSwimPath(AvHAIPlayer* pBot)
|
|||
if (pBot->BotNavInfo.CurrentPath.size() == 0 || pBot->BotNavInfo.CurrentPathPoint >= pBot->BotNavInfo.CurrentPath.size())
|
||||
{
|
||||
ClearBotPath(pBot);
|
||||
NAV_ClearMovementTask(pBot);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -6964,6 +6990,7 @@ void BotFollowPath(AvHAIPlayer* pBot)
|
|||
MoveToWithoutNav(pBot, CurrentNode.Location);
|
||||
pBot->BotNavInfo.StuckInfo.bPathFollowFailed = true;
|
||||
ClearBotPath(pBot);
|
||||
NAV_ClearMovementTask(pBot);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -7408,6 +7435,7 @@ void ClearBotStuck(AvHAIPlayer* pBot)
|
|||
bool BotRecalcPath(AvHAIPlayer* pBot, const Vector Destination)
|
||||
{
|
||||
ClearBotPath(pBot);
|
||||
NAV_ClearMovementTask(pBot);
|
||||
|
||||
Vector ValidNavmeshPoint = UTIL_ProjectPointToNavmesh(Destination, Vector(max_ai_use_reach, max_ai_use_reach, max_ai_use_reach), pBot->BotNavInfo.NavProfile);
|
||||
|
||||
|
@ -8772,6 +8800,18 @@ void UTIL_PopulateDoors()
|
|||
NavDoors.push_back(NewDoor);
|
||||
}
|
||||
|
||||
for (auto it = BaseMapConnections.begin(); it != BaseMapConnections.end(); it++)
|
||||
{
|
||||
if (!(it->ConnectionFlags & SAMPLE_POLYFLAGS_LIFT)) { continue; }
|
||||
|
||||
nav_door* CorrespondingLift = UTIL_GetClosestLiftToPoints(it->FromLocation, it->ToLocation);
|
||||
|
||||
if (CorrespondingLift)
|
||||
{
|
||||
it->TargetObject = CorrespondingLift->DoorEdict;
|
||||
}
|
||||
}
|
||||
|
||||
UTIL_UpdateDoors(true);
|
||||
}
|
||||
|
||||
|
@ -8790,6 +8830,28 @@ nav_door* UTIL_GetNavDoorByEdict(const edict_t* DoorEdict)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
nav_door* UTIL_GetLiftReferenceByEdict(const edict_t* DoorEdict)
|
||||
{
|
||||
if (FNullEnt(DoorEdict)) { return nullptr; }
|
||||
|
||||
for (auto it = NavDoors.begin(); it != NavDoors.end(); it++)
|
||||
{
|
||||
if (it->DoorEdict == DoorEdict)
|
||||
{
|
||||
if (UTIL_GetOffMeshConnectionForLift(&(*it)) != nullptr)
|
||||
{
|
||||
return &(*it);
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
AvHAIOffMeshConnection* UTIL_GetOffMeshConnectionForLift(nav_door* LiftRef)
|
||||
{
|
||||
if (!LiftRef) { return nullptr; }
|
||||
|
@ -8801,15 +8863,20 @@ AvHAIOffMeshConnection* UTIL_GetOffMeshConnectionForLift(nav_door* LiftRef)
|
|||
{
|
||||
if (!(it->ConnectionFlags & SAMPLE_POLYFLAGS_LIFT)) { continue; }
|
||||
|
||||
Vector LiftLocation = UTIL_GetCentreOfEntity(LiftRef->DoorEdict);
|
||||
|
||||
float ThisDist = fminf(vDist3DSq(it->FromLocation, LiftLocation), vDist3DSq(it->ToLocation, LiftLocation));
|
||||
|
||||
if (!NearestConnection || ThisDist < MinDist)
|
||||
if (it->TargetObject == LiftRef->DoorEdict)
|
||||
{
|
||||
NearestConnection = &(*it);
|
||||
MinDist = ThisDist;
|
||||
return &(*it);
|
||||
}
|
||||
|
||||
//Vector LiftLocation = UTIL_GetCentreOfEntity(LiftRef->DoorEdict);
|
||||
|
||||
//float ThisDist = fminf(vDist3DSq(it->FromLocation, LiftLocation), vDist3DSq(it->ToLocation, LiftLocation));
|
||||
|
||||
//if (!NearestConnection || ThisDist < MinDist)
|
||||
//{
|
||||
// NearestConnection = &(*it);
|
||||
// MinDist = ThisDist;
|
||||
//}
|
||||
}
|
||||
|
||||
return NearestConnection;
|
||||
|
|
|
@ -482,6 +482,7 @@ void UTIL_PopulateWeldableObstacles();
|
|||
|
||||
void UTIL_ApplyTempObstaclesToDoor(nav_door* DoorRef, const int Area);
|
||||
|
||||
nav_door* UTIL_GetLiftReferenceByEdict(const edict_t* DoorEdict);
|
||||
nav_door* UTIL_GetNavDoorByEdict(const edict_t* DoorEdict);
|
||||
nav_door* UTIL_GetClosestLiftToPoints(const Vector StartPoint, const Vector EndPoint);
|
||||
AvHAIOffMeshConnection* UTIL_GetOffMeshConnectionForLift(nav_door* LiftRef);
|
||||
|
|
|
@ -1353,6 +1353,9 @@ void BotUpdateView(AvHAIPlayer* pBot)
|
|||
|
||||
UpdateAIPlayerViewFrustum(pBot);
|
||||
|
||||
float ViewUpdateDelta = gpGlobals->time - pBot->LastViewUpdateTime;
|
||||
ViewUpdateDelta = clampf(ViewUpdateDelta, 0.0f, 0.2f);
|
||||
|
||||
// Update list of currently visible players
|
||||
for (int i = 1; i <= gpGlobals->maxClients; i++)
|
||||
{
|
||||
|
@ -1378,6 +1381,10 @@ void BotUpdateView(AvHAIPlayer* pBot)
|
|||
|
||||
enemy_status* TrackingInfo = &pBot->TrackedEnemies[EnemyIndex];
|
||||
|
||||
|
||||
TrackingInfo->CertaintyOfLocation -= (ViewUpdateDelta * 0.15f);
|
||||
TrackingInfo->CertaintyOfLocation = clampf(TrackingInfo->CertaintyOfLocation, 0.0f, 1.0f);
|
||||
|
||||
if (gpGlobals->time < TrackingInfo->NextUpdateTime)
|
||||
{
|
||||
continue;
|
||||
|
@ -1434,6 +1441,7 @@ void BotUpdateView(AvHAIPlayer* pBot)
|
|||
|
||||
if (bInFOV && (bCanSeeEnemy || bIsTracked))
|
||||
{
|
||||
TrackingInfo->CertaintyOfLocation = 1.0f;
|
||||
Vector FloorLocation = UTIL_GetEntityGroundLocation(Enemy);
|
||||
Vector BotVelocity = Enemy->v.velocity;
|
||||
|
||||
|
@ -1486,7 +1494,7 @@ void BotUpdateView(AvHAIPlayer* pBot)
|
|||
}
|
||||
}
|
||||
|
||||
if (bHasLOS)
|
||||
if (bHasLOS && bCanSeeEnemy)
|
||||
{
|
||||
TrackingInfo->LastLOSPosition = pBot->CurrentFloorPosition + Vector(0.0f, 0.0f, 5.0f);
|
||||
|
||||
|
@ -1554,6 +1562,8 @@ void BotUpdateView(AvHAIPlayer* pBot)
|
|||
{
|
||||
pBot->LastSafeLocation = pBot->Edict->v.origin;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool UTIL_IsCloakedPlayerInvisible(edict_t* Observer, AvHPlayer* Player)
|
||||
|
@ -1595,6 +1605,7 @@ void BotClearEnemyTrackingInfo(enemy_status* TrackingInfo)
|
|||
TrackingInfo->LastSeenTime = 0.0f;
|
||||
TrackingInfo->LastLOSPosition = ZERO_VECTOR;
|
||||
TrackingInfo->LastHiddenPosition = ZERO_VECTOR;
|
||||
TrackingInfo->CertaintyOfLocation = 0.0f;
|
||||
}
|
||||
|
||||
void UpdateAIPlayerViewFrustum(AvHAIPlayer* pBot)
|
||||
|
@ -1895,23 +1906,25 @@ void EndBotFrame(AvHAIPlayer* pBot)
|
|||
|
||||
void CustomThink(AvHAIPlayer* pBot)
|
||||
{
|
||||
if (IsPlayerMarine(pBot->Edict)) { return; }
|
||||
|
||||
if (!PlayerHasAlienUpgradeOfType(pBot->Edict, HIVE_TECH_SENSORY))
|
||||
{
|
||||
BotEvolveUpgrade(pBot, pBot->CurrentFloorPosition, ALIEN_EVOLUTION_TEN);
|
||||
return;
|
||||
}
|
||||
|
||||
pBot->CurrentEnemy = BotGetNextEnemyTarget(pBot);
|
||||
|
||||
if (pBot->CurrentEnemy < 0)
|
||||
if (pBot->CurrentEnemy >= 0)
|
||||
{
|
||||
MoveTo(pBot, AITAC_GetTeamStartingLocation(AIMGR_GetEnemyTeam(pBot->Player->GetTeam())), MOVESTYLE_NORMAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
AlienCombatThink(pBot);
|
||||
enemy_status* TrackingInfo = &pBot->TrackedEnemies[pBot->CurrentEnemy];
|
||||
|
||||
char msg[32];
|
||||
sprintf(msg, "%.2f\n", TrackingInfo->CertaintyOfLocation);
|
||||
UTIL_SayText(msg, CBaseEntity::Instance(INDEXENT(1)));
|
||||
|
||||
if (IsPlayerMarine(pBot->Edict))
|
||||
{
|
||||
MarineCombatThink(pBot);
|
||||
}
|
||||
else
|
||||
{
|
||||
AlienCombatThink(pBot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2005,11 +2018,41 @@ void UpdateAIPlayerDMRole(AvHAIPlayer* pBot)
|
|||
|
||||
}
|
||||
|
||||
void AIPlayerHearEnemy(AvHAIPlayer* pBot, edict_t* HeardEnemy, float SoundVolume)
|
||||
{
|
||||
int heardIndex = ENTINDEX(HeardEnemy) - 1;
|
||||
|
||||
if (heardIndex < 0 || heardIndex >= 32 || HeardEnemy->v.team == pBot->Edict->v.team) { return; }
|
||||
|
||||
enemy_status* HeardEnemyStatus = &pBot->TrackedEnemies[heardIndex];
|
||||
|
||||
HeardEnemyStatus->LastSeenTime = gpGlobals->time;
|
||||
HeardEnemyStatus->CertaintyOfLocation += SoundVolume;
|
||||
HeardEnemyStatus->CertaintyOfLocation = clampf(HeardEnemyStatus->CertaintyOfLocation, 0.0f, 1.0f);
|
||||
|
||||
if (HeardEnemyStatus->CertaintyOfLocation < 0.15f) { return; }
|
||||
|
||||
// If the bot can't see the enemy (bCurrentlyVisible is false) then set the last seen location to a random point in the vicinity so the bot doesn't immediately know where they are
|
||||
if (HeardEnemyStatus->bIsVisible || HeardEnemyStatus->CertaintyOfLocation > 0.75f || vDist2DSq(HeardEnemyStatus->EnemyEdict->v.origin, pBot->Edict->v.origin) < sqrf(UTIL_MetresToGoldSrcUnits(3.0f)))
|
||||
{
|
||||
HeardEnemyStatus->LastSeenLocation = HeardEnemy->v.origin;
|
||||
}
|
||||
else
|
||||
{
|
||||
// The further the enemy is, the more inaccurate the bot's guess will be where they are
|
||||
HeardEnemyStatus->LastSeenLocation = UTIL_GetRandomPointOnNavmeshInRadius(GetBaseNavProfile(SKULK_BASE_NAV_PROFILE), HeardEnemy->v.origin, UTIL_MetresToGoldSrcUnits(5.0f));
|
||||
}
|
||||
|
||||
HeardEnemyStatus->bIsAwareOfPlayer = true;
|
||||
}
|
||||
|
||||
void AIPlayerTakeDamage(AvHAIPlayer* pBot, int damageTaken, edict_t* aggressor)
|
||||
{
|
||||
int aggressorIndex = ENTINDEX(aggressor) - 1;
|
||||
|
||||
if (aggressorIndex > -1 && aggressor->v.team != pBot->Edict->v.team && IsPlayerActiveInGame(aggressor))
|
||||
if (aggressorIndex < 0 || aggressorIndex >= 32) { return; }
|
||||
|
||||
if (aggressor->v.team != pBot->Edict->v.team && IsPlayerActiveInGame(aggressor))
|
||||
{
|
||||
pBot->TrackedEnemies[aggressorIndex].LastSeenTime = gpGlobals->time;
|
||||
|
||||
|
@ -2575,7 +2618,7 @@ AvHAICombatStrategy GetFadeCombatStrategyForTarget(AvHAIPlayer* pBot, enemy_stat
|
|||
{
|
||||
if (DistToEnemy > sqrf(UTIL_MetresToGoldSrcUnits(5.0f)))
|
||||
{
|
||||
if ((bEnemyHasDeadlyWeapon && (FacingDot > 0.5f || NumAllies > 0)) || NumAllies > 2)
|
||||
if ((bEnemyHasDeadlyWeapon && (FacingDot > 0.5f || NumAllies > 0)) || NumAllies > 1)
|
||||
{
|
||||
return COMBAT_STRATEGY_SKIRMISH;
|
||||
}
|
||||
|
@ -2583,7 +2626,7 @@ AvHAICombatStrategy GetFadeCombatStrategyForTarget(AvHAIPlayer* pBot, enemy_stat
|
|||
}
|
||||
else
|
||||
{
|
||||
if ((bEnemyHasDeadlyWeapon && (FacingDot > 0.5f || NumAllies > 0)) || NumAllies > 2)
|
||||
if ((bEnemyHasDeadlyWeapon && (FacingDot > 0.5f || NumAllies > 0)) || NumAllies > 1)
|
||||
{
|
||||
Vector EnemyVelocity = UTIL_GetVectorNormal2D(CurrentEnemy->LastSeenVelocity);
|
||||
|
||||
|
@ -2683,7 +2726,7 @@ AvHAICombatStrategy GetMarineCombatStrategyForTarget(AvHAIPlayer* pBot, enemy_st
|
|||
|
||||
float DistToEnemy = vDist2DSq(pBot->Edict->v.origin, CurrentEnemy->LastSeenLocation);
|
||||
|
||||
bool bCanRetreat = AITAC_IsCompletedStructureOfTypeNearLocation(BotTeam, (STRUCTURE_MARINE_COMMCHAIR | STRUCTURE_MARINE_ARMOURY | STRUCTURE_MARINE_ADVARMOURY), ZERO_VECTOR, 0.0f);
|
||||
bool bCanRetreat = AITAC_IsCompletedStructureOfTypeNearLocation(BotTeam, (STRUCTURE_MARINE_ARMOURY | STRUCTURE_MARINE_ADVARMOURY), ZERO_VECTOR, 0.0f);
|
||||
|
||||
// If we are doing something important, don't get distracted by enemies that aren't an immediate threat
|
||||
if (pBot->CurrentTask && (pBot->CurrentTask->TaskType == TASK_DEFEND || pBot->CommanderTask.TaskType != TASK_NONE))
|
||||
|
@ -2712,6 +2755,11 @@ AvHAICombatStrategy GetMarineCombatStrategyForTarget(AvHAIPlayer* pBot, enemy_st
|
|||
return COMBAT_STRATEGY_RETREAT;
|
||||
}
|
||||
|
||||
if (UTIL_GetPlayerPrimaryWeaponClipAmmo(pBot->Player) == 0 && UTIL_GetPlayerPrimaryAmmoReserve(pBot->Player) == 0 && UTIL_GetPlayerSecondaryWeaponClipAmmo(pBot->Player) == 0 && UTIL_GetPlayerSecondaryAmmoReserve(pBot->Player) == 0)
|
||||
{
|
||||
return COMBAT_STRATEGY_ATTACK;
|
||||
}
|
||||
|
||||
// Shotty users should attack, can't really skirmish with a shotgun
|
||||
if (PlayerHasWeapon(pBot->Player, WEAPON_MARINE_SHOTGUN) && (UTIL_GetPlayerPrimaryAmmoReserve(pBot->Player) > 0 || UTIL_GetPlayerPrimaryWeaponClipAmmo(pBot->Player) > 0))
|
||||
{
|
||||
|
@ -2899,6 +2947,7 @@ void BotThrowGrenadeAtTarget(AvHAIPlayer* pBot, const Vector TargetPoint)
|
|||
|
||||
BotShootLocation(pBot, GetPlayerCurrentWeapon(pBot->Player), ThrowTargetLocation);
|
||||
}
|
||||
|
||||
bool BombardierCombatThink(AvHAIPlayer* pBot)
|
||||
{
|
||||
return false;
|
||||
|
@ -2921,11 +2970,12 @@ bool RegularMarineCombatThink(AvHAIPlayer* pBot)
|
|||
|
||||
bool bBotIsGrenadier = (DesiredCombatWeapon == WEAPON_MARINE_GL);
|
||||
|
||||
float DistToEnemy = vDist2DSq(pBot->Edict->v.origin, CurrentEnemy->v.origin);
|
||||
float DistToEnemy = vDist2DSq(pBot->Edict->v.origin, TrackedEnemyRef->LastSeenLocation);
|
||||
|
||||
bool bEnemyIsRanged = IsPlayerMarine(TrackedEnemyRef->EnemyPlayer) || ((GetPlayerCurrentWeapon(TrackedEnemyRef->EnemyPlayer) == WEAPON_FADE_ACIDROCKET) && DistToEnemy > sqrf(UTIL_MetresToGoldSrcUnits(5.0f)));
|
||||
|
||||
float LastEnemySeenTime = (TrackedEnemyRef->LastTrackedTime > 0.0f) ? TrackedEnemyRef->LastTrackedTime : TrackedEnemyRef->LastSeenTime;
|
||||
float TimeSinceLastEnemySighting = gpGlobals->time - LastEnemySeenTime;
|
||||
Vector LastEnemySeenLocation = TrackedEnemyRef->LastSeenLocation;
|
||||
|
||||
// Run away and restock
|
||||
|
@ -3017,15 +3067,29 @@ bool RegularMarineCombatThink(AvHAIPlayer* pBot)
|
|||
// Maintain distance, pop and shoot
|
||||
if (pBot->CurrentCombatStrategy == COMBAT_STRATEGY_SKIRMISH || pBot->CurrentCombatStrategy == COMBAT_STRATEGY_AMBUSH)
|
||||
{
|
||||
pBot->DesiredCombatWeapon = DesiredCombatWeapon;
|
||||
|
||||
if (GetPlayerCurrentWeapon(pBot->Player) != DesiredCombatWeapon)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (vIsZero(pBot->LastSafeLocation))
|
||||
{
|
||||
pBot->LastSafeLocation = AITAC_GetTeamStartingLocation(BotTeam);
|
||||
}
|
||||
|
||||
if (TrackedEnemyRef->bHasLOS)
|
||||
float DesiredDistance = GetMinIdealWeaponRange(DesiredCombatWeapon) + ((GetMaxIdealWeaponRange(DesiredCombatWeapon) - GetMinIdealWeaponRange(DesiredCombatWeapon)) * 0.5f);
|
||||
|
||||
bool bCanReloadCurrentWeapon = (WeaponCanBeReloaded(DesiredCombatWeapon) && GetPlayerCurrentWeaponClipAmmo(pBot->Player) < GetPlayerCurrentWeaponMaxClipAmmo(pBot->Player) && GetPlayerCurrentWeaponReserveAmmo(pBot->Player) > 0);
|
||||
bool bMustReloadCurrentWeapon = bCanReloadCurrentWeapon && GetPlayerCurrentWeaponClipAmmo(pBot->Player) == 0;
|
||||
bool bCanReloadAnyWeapon = BotAnyWeaponNeedsReloading(pBot);
|
||||
|
||||
if (TrackedEnemyRef->bHasLOS && (TrackedEnemyRef->bIsVisible || TrackedEnemyRef->CertaintyOfLocation >= 0.8f))
|
||||
{
|
||||
if (GetPlayerCurrentWeaponClipAmmo(pBot->Player) == 0)
|
||||
if (bMustReloadCurrentWeapon)
|
||||
{
|
||||
BotLookAt(pBot, TrackedEnemyRef->LastSeenLocation);
|
||||
MoveTo(pBot, pBot->LastSafeLocation, MOVESTYLE_NORMAL);
|
||||
BotReloadWeapons(pBot);
|
||||
return true;
|
||||
|
@ -3033,7 +3097,9 @@ bool RegularMarineCombatThink(AvHAIPlayer* pBot)
|
|||
|
||||
if (vDist2DSq(pBot->Edict->v.origin, pBot->LastSafeLocation) > sqrf(UTIL_MetresToGoldSrcUnits(3.0f)))
|
||||
{
|
||||
BotLookAt(pBot, TrackedEnemyRef->LastSeenLocation);
|
||||
MoveTo(pBot, pBot->LastSafeLocation, MOVESTYLE_NORMAL);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -3099,6 +3165,7 @@ bool RegularMarineCombatThink(AvHAIPlayer* pBot)
|
|||
|
||||
if (BotReloadWeapons(pBot)) { return true; }
|
||||
|
||||
BotLookAt(pBot, LastEnemySeenLocation);
|
||||
MoveTo(pBot, LastEnemySeenLocation, MOVESTYLE_NORMAL);
|
||||
}
|
||||
|
||||
|
@ -3108,19 +3175,43 @@ bool RegularMarineCombatThink(AvHAIPlayer* pBot)
|
|||
// Go for the kill. Maintain desired distance and pursue when needed
|
||||
if (pBot->CurrentCombatStrategy == COMBAT_STRATEGY_ATTACK)
|
||||
{
|
||||
AvHAIWeapon IdealAttackWeapon = (UTIL_GetPlayerPrimaryAmmoReserve(pBot->Player) > 0 || UTIL_GetPlayerPrimaryWeaponClipAmmo(pBot->Player) > 0) ? UTIL_GetPlayerPrimaryWeapon(pBot->Player) : DesiredCombatWeapon;
|
||||
pBot->DesiredCombatWeapon = DesiredCombatWeapon;
|
||||
|
||||
float DesiredDistance = GetMinIdealWeaponRange(IdealAttackWeapon) + ((GetMaxIdealWeaponRange(IdealAttackWeapon) - GetMinIdealWeaponRange(IdealAttackWeapon)) * 0.5f);
|
||||
|
||||
bool bCanReloadCurrentWeapon = (WeaponCanBeReloaded(DesiredCombatWeapon) && GetPlayerCurrentWeaponClipAmmo(pBot->Player) < GetPlayerCurrentWeaponMaxClipAmmo(pBot->Player) && GetPlayerCurrentWeaponReserveAmmo(pBot->Player) > 0);
|
||||
bool bMustReloadCurrentWeapon = bCanReloadCurrentWeapon && GetPlayerCurrentWeaponClipAmmo(pBot->Player) == 0;
|
||||
if (GetPlayerCurrentWeapon(pBot->Player) != DesiredCombatWeapon)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (vIsZero(pBot->LastSafeLocation))
|
||||
{
|
||||
pBot->LastSafeLocation = AITAC_GetTeamStartingLocation(BotTeam);
|
||||
}
|
||||
|
||||
if (!TrackedEnemyRef->bHasLOS)
|
||||
float DesiredDistance = GetMinIdealWeaponRange(DesiredCombatWeapon) + ((GetMaxIdealWeaponRange(DesiredCombatWeapon) - GetMinIdealWeaponRange(DesiredCombatWeapon)) * 0.5f);
|
||||
|
||||
bool bCanReloadCurrentWeapon = (WeaponCanBeReloaded(DesiredCombatWeapon) && GetPlayerCurrentWeaponClipAmmo(pBot->Player) < GetPlayerCurrentWeaponMaxClipAmmo(pBot->Player) && GetPlayerCurrentWeaponReserveAmmo(pBot->Player) > 0);
|
||||
bool bMustReloadCurrentWeapon = bCanReloadCurrentWeapon && GetPlayerCurrentWeaponClipAmmo(pBot->Player) == 0;
|
||||
bool bCanReloadAnyWeapon = BotAnyWeaponNeedsReloading(pBot);
|
||||
|
||||
if (bMustReloadCurrentWeapon)
|
||||
{
|
||||
BotReloadWeapons(pBot);
|
||||
BotLookAt(pBot, TrackedEnemyRef->LastSeenLocation);
|
||||
|
||||
if (TrackedEnemyRef->bHasLOS || DistToEnemy < sqrf(UTIL_MetresToGoldSrcUnits(5.0f)))
|
||||
{
|
||||
MoveTo(pBot, pBot->LastSafeLocation, MOVESTYLE_NORMAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
BotGuardLocation(pBot, pBot->Edict->v.origin);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
if (!TrackedEnemyRef->bHasLOS || (!TrackedEnemyRef->bIsVisible && TrackedEnemyRef->CertaintyOfLocation < 0.8f))
|
||||
{
|
||||
if (PlayerHasWeapon(pBot->Player, WEAPON_MARINE_GRENADE) || (PlayerHasWeapon(pBot->Player, WEAPON_MARINE_GL) && UTIL_GetPlayerPrimaryWeaponClipAmmo(pBot->Player) > 0))
|
||||
{
|
||||
|
@ -3133,103 +3224,100 @@ bool RegularMarineCombatThink(AvHAIPlayer* pBot)
|
|||
}
|
||||
}
|
||||
|
||||
if ((IdealAttackWeapon != DesiredCombatWeapon || bCanReloadCurrentWeapon) && gpGlobals->time - TrackedEnemyRef->LastSeenTime > 3.0f)
|
||||
if (bCanReloadAnyWeapon && gpGlobals->time - TrackedEnemyRef->LastSeenTime > 3.0f)
|
||||
{
|
||||
BotReloadWeapons(pBot);
|
||||
if (vDist2DSq(pBot->Edict->v.origin, TrackedEnemyRef->LastVisibleLocation) < sqrf(UTIL_MetresToGoldSrcUnits(5.0f)))
|
||||
{
|
||||
BotLookAt(pBot, TrackedEnemyRef->LastSeenLocation);
|
||||
|
||||
if (DistToEnemy < sqrf(UTIL_MetresToGoldSrcUnits(5.0f)))
|
||||
{
|
||||
MoveTo(pBot, AITAC_GetTeamStartingLocation(BotTeam), MOVESTYLE_NORMAL);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
MoveTo(pBot, TrackedEnemyRef->LastSeenLocation, MOVESTYLE_NORMAL);
|
||||
BotGuardLocation(pBot, LastEnemySeenLocation);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (bCanReloadCurrentWeapon && DistToEnemy > sqrf(DesiredDistance))
|
||||
{
|
||||
BotReloadWeapons(pBot);
|
||||
}
|
||||
|
||||
BotAttackResult LOSCheck = PerformAttackLOSCheck(pBot, DesiredCombatWeapon, CurrentEnemy);
|
||||
|
||||
if (bMustReloadCurrentWeapon)
|
||||
if (LOSCheck != ATTACK_SUCCESS)
|
||||
{
|
||||
MoveTo(pBot, pBot->LastSafeLocation, MOVESTYLE_NORMAL);
|
||||
BotReloadWeapons(pBot);
|
||||
MoveTo(pBot, TrackedEnemyRef->LastSeenLocation, MOVESTYLE_NORMAL);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (DistToEnemy > sqrf(DesiredDistance))
|
||||
if (bEnemyIsRanged)
|
||||
{
|
||||
if (IdealAttackWeapon != DesiredCombatWeapon)
|
||||
Vector EnemyOrientation = UTIL_GetVectorNormal2D(CurrentEnemy->v.origin - pBot->Edict->v.origin);
|
||||
|
||||
Vector RightDir = UTIL_GetCrossProduct(EnemyOrientation, UP_VECTOR);
|
||||
|
||||
pBot->desiredMovementDir = (pBot->BotNavInfo.bZig) ? UTIL_GetVectorNormal2D(RightDir) : UTIL_GetVectorNormal2D(-RightDir);
|
||||
|
||||
// Let's get ziggy with it
|
||||
if (gpGlobals->time > pBot->BotNavInfo.NextZigTime)
|
||||
{
|
||||
BotReloadWeapons(pBot);
|
||||
MoveTo(pBot, pBot->LastSafeLocation, MOVESTYLE_NORMAL);
|
||||
return true;
|
||||
pBot->BotNavInfo.bZig = !pBot->BotNavInfo.bZig;
|
||||
pBot->BotNavInfo.NextZigTime = gpGlobals->time + frandrange(0.5f, 1.0f);
|
||||
}
|
||||
|
||||
MoveTo(pBot, LastEnemySeenLocation, MOVESTYLE_NORMAL);
|
||||
|
||||
BotMovementInputs(pBot);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
if (bEnemyIsRanged)
|
||||
float MinDesiredDist = GetMinIdealWeaponRange(DesiredCombatWeapon);
|
||||
Vector Orientation = UTIL_GetVectorNormal2D(CurrentEnemy->v.origin - pBot->Edict->v.origin);
|
||||
|
||||
float EnemyMoveDot = UTIL_GetDotProduct2D(UTIL_GetVectorNormal2D(CurrentEnemy->v.velocity), -Orientation);
|
||||
|
||||
// Enemy is too close for comfort, or is moving towards us. Back up
|
||||
if (DistToEnemy < MinDesiredDist || EnemyMoveDot > 0.7f)
|
||||
{
|
||||
Vector EnemyOrientation = UTIL_GetVectorNormal2D(CurrentEnemy->v.origin - pBot->Edict->v.origin);
|
||||
Vector RetreatLocation = pBot->CurrentFloorPosition - (Orientation * 50.0f);
|
||||
|
||||
Vector RightDir = UTIL_GetCrossProduct(EnemyOrientation, UP_VECTOR);
|
||||
|
||||
pBot->desiredMovementDir = (pBot->BotNavInfo.bZig) ? UTIL_GetVectorNormal2D(RightDir) : UTIL_GetVectorNormal2D(-RightDir);
|
||||
|
||||
// Let's get ziggy with it
|
||||
if (gpGlobals->time > pBot->BotNavInfo.NextZigTime)
|
||||
if (UTIL_PointIsDirectlyReachable(pBot->CurrentFloorPosition, RetreatLocation))
|
||||
{
|
||||
pBot->BotNavInfo.bZig = !pBot->BotNavInfo.bZig;
|
||||
pBot->BotNavInfo.NextZigTime = gpGlobals->time + frandrange(0.5f, 1.0f);
|
||||
MoveDirectlyTo(pBot, RetreatLocation);
|
||||
}
|
||||
|
||||
if (DesiredCombatWeapon != WEAPON_MARINE_KNIFE)
|
||||
{
|
||||
if (DistToEnemy < sqrf(100.0f))
|
||||
{
|
||||
if (IsPlayerReloading(pBot->Player) && CanInterruptWeaponReload(GetPlayerCurrentWeapon(pBot->Player)) && GetPlayerCurrentWeaponClipAmmo(pBot->Player) > 0)
|
||||
{
|
||||
InterruptReload(pBot);
|
||||
return true;
|
||||
}
|
||||
BotJump(pBot);
|
||||
}
|
||||
}
|
||||
|
||||
BotMovementInputs(pBot);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
float MinDesiredDist = GetMinIdealWeaponRange(DesiredCombatWeapon);
|
||||
Vector Orientation = UTIL_GetVectorNormal2D(CurrentEnemy->v.origin - pBot->Edict->v.origin);
|
||||
|
||||
float EnemyMoveDot = UTIL_GetDotProduct2D(UTIL_GetVectorNormal2D(CurrentEnemy->v.velocity), -Orientation);
|
||||
|
||||
// Enemy is too close for comfort, or is moving towards us. Back up
|
||||
if (DistToEnemy < MinDesiredDist || EnemyMoveDot > 0.7f)
|
||||
{
|
||||
Vector RetreatLocation = pBot->CurrentFloorPosition - (Orientation * 50.0f);
|
||||
|
||||
if (UTIL_PointIsDirectlyReachable(pBot->CurrentFloorPosition, RetreatLocation))
|
||||
{
|
||||
MoveDirectlyTo(pBot, RetreatLocation);
|
||||
}
|
||||
|
||||
if (DesiredCombatWeapon != WEAPON_MARINE_KNIFE)
|
||||
{
|
||||
if (DistToEnemy < sqrf(100.0f))
|
||||
{
|
||||
if (IsPlayerReloading(pBot->Player) && CanInterruptWeaponReload(GetPlayerCurrentWeapon(pBot->Player)) && GetPlayerCurrentWeaponClipAmmo(pBot->Player) > 0)
|
||||
{
|
||||
InterruptReload(pBot);
|
||||
return true;
|
||||
}
|
||||
BotJump(pBot);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
if (!UTIL_PlayerHasLOSToLocation(pBot->Edict, TrackedEnemyRef->LastSeenLocation, UTIL_MetresToGoldSrcUnits(5.0f)))
|
||||
{
|
||||
MoveTo(pBot, TrackedEnemyRef->LastSeenLocation, MOVESTYLE_NORMAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
BotGuardLocation(pBot, TrackedEnemyRef->LastSeenLocation);
|
||||
}
|
||||
}
|
||||
|
||||
BotShootTarget(pBot, DesiredCombatWeapon, CurrentEnemy);
|
||||
}
|
||||
|
||||
BotShootTarget(pBot, DesiredCombatWeapon, CurrentEnemy);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -153,6 +153,7 @@ void UpdateAIPlayerDMRole(AvHAIPlayer* pBot);
|
|||
bool ShouldAIPlayerTakeCommand(AvHAIPlayer* pBot);
|
||||
|
||||
void AIPlayerTakeDamage(AvHAIPlayer* pBot, int damageTaken, edict_t* aggressor);
|
||||
void AIPlayerHearEnemy(AvHAIPlayer* pBot, edict_t* HeardEnemy, float SoundVolume);
|
||||
|
||||
int BotGetNextEnemyTarget(AvHAIPlayer* pBot);
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "AvHAIHelper.h"
|
||||
#include "AvHAICommander.h"
|
||||
#include "AvHAIPlayerUtil.h"
|
||||
#include "AvHAISoundQueue.h"
|
||||
#include "AvHGamerules.h"
|
||||
#include "../dlls/client.h"
|
||||
#include <time.h>
|
||||
|
@ -51,6 +52,8 @@ float CountdownStartedTime = 0.0f;
|
|||
|
||||
bool bBotsEnabled = false;
|
||||
|
||||
float CurrentFrameDelta = 0.01f;
|
||||
|
||||
AvHAICommanderMode AIMGR_GetCommanderMode()
|
||||
{
|
||||
if (avh_botcommandermode.value == 1)
|
||||
|
@ -560,6 +563,8 @@ void AIMGR_UpdateAIPlayers()
|
|||
|
||||
float FrameDelta = CurrTime - PrevTime;
|
||||
|
||||
AIMGR_SetFrameDelta(FrameDelta);
|
||||
|
||||
int cvarBotSkill = clampi((int)avh_botskill.value, 0, 3);
|
||||
|
||||
bool bSkillChanged = (cvarBotSkill != CurrentBotSkill);
|
||||
|
@ -592,6 +597,8 @@ void AIMGR_UpdateAIPlayers()
|
|||
AIMGR_SetCommanderAllowedTime(TeamBNumber, gpGlobals->time + 15.0f);
|
||||
}
|
||||
}
|
||||
|
||||
AIMGR_ProcessPendingSounds();
|
||||
}
|
||||
|
||||
int NumCommanders = AIMGR_GetNumAICommanders();
|
||||
|
@ -709,7 +716,7 @@ AvHTeamNumber AIMGR_GetTeamANumber()
|
|||
|
||||
AvHTeamNumber AIMGR_GetTeamBNumber()
|
||||
{
|
||||
return GetGameRules()->GetTeamANumber();
|
||||
return GetGameRules()->GetTeamBNumber();
|
||||
}
|
||||
|
||||
AvHTeam* AIMGR_GetTeamRef(const AvHTeamNumber Team)
|
||||
|
@ -1450,4 +1457,100 @@ bool AIMGR_IsMatchPracticallyOver()
|
|||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void AIMGR_ProcessPendingSounds()
|
||||
{
|
||||
float FrameDelta = AIMGR_GetFrameDelta();
|
||||
|
||||
for (auto it = ActiveAIPlayers.begin(); it != ActiveAIPlayers.end(); it++)
|
||||
{
|
||||
it->HearingThreshold -= FrameDelta;
|
||||
it->HearingThreshold = clampf(it->HearingThreshold, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
AvHAISound Sound = AISND_PopSound();
|
||||
|
||||
AvHTeamNumber TeamANumber = AIMGR_GetTeamANumber();
|
||||
AvHTeamNumber TeamBNumber = AIMGR_GetTeamBNumber();
|
||||
|
||||
while (Sound.SoundType != AI_SOUND_NONE)
|
||||
{
|
||||
edict_t* EmittingEntity = INDEXENT(Sound.EntIndex);
|
||||
//string SoundType = "Unknown";
|
||||
|
||||
float MaxDist = 0.0f;
|
||||
|
||||
switch (Sound.SoundType)
|
||||
{
|
||||
case AI_SOUND_FOOTSTEP:
|
||||
MaxDist = UTIL_MetresToGoldSrcUnits(20.0f);
|
||||
//SoundType = "Footstep";
|
||||
break;
|
||||
case AI_SOUND_SHOOT:
|
||||
MaxDist = UTIL_MetresToGoldSrcUnits(30.0f);
|
||||
//SoundType = "Shoot";
|
||||
break;
|
||||
case AI_SOUND_VOICELINE:
|
||||
MaxDist = UTIL_MetresToGoldSrcUnits(20.0f);
|
||||
//SoundType = "Voiceline";
|
||||
break;
|
||||
case AI_SOUND_LANDING:
|
||||
MaxDist = UTIL_MetresToGoldSrcUnits(20.0f);
|
||||
//SoundType = "Landing";
|
||||
break;
|
||||
case AI_SOUND_OTHER:
|
||||
default:
|
||||
MaxDist = UTIL_MetresToGoldSrcUnits(20.0f);
|
||||
//SoundType = "Other";
|
||||
break;
|
||||
}
|
||||
|
||||
MaxDist = sqrf(MaxDist);
|
||||
|
||||
if (!FNullEnt(EmittingEntity) && EmittingEntity->v.team != 0 && IsEdictPlayer(EmittingEntity) && IsPlayerActiveInGame(EmittingEntity))
|
||||
{
|
||||
AvHTeamNumber EmitterTeam = (AvHTeamNumber)EmittingEntity->v.team;
|
||||
|
||||
for (auto it = ActiveAIPlayers.begin(); it != ActiveAIPlayers.end(); it++)
|
||||
{
|
||||
AvHTeamNumber ThisTeam = it->Player->GetTeam();
|
||||
float Volume = Sound.Volume;
|
||||
float HearingThresholdScalar = (ThisTeam != EmitterTeam || EmittingEntity == it->Edict) ? 1.0f : 0.5f;
|
||||
|
||||
if (EmitterTeam != ThisTeam)
|
||||
{
|
||||
float DistFromSound = vDist3DSq(Sound.SoundLocation, it->Edict->v.origin);
|
||||
|
||||
if (DistFromSound > MaxDist) { continue; }
|
||||
|
||||
Volume = Sound.Volume - (Sound.Volume * clampf((DistFromSound / MaxDist), 0.0f, 1.0f));
|
||||
}
|
||||
|
||||
Volume = Volume * HearingThresholdScalar;
|
||||
|
||||
if (Volume > it->HearingThreshold)
|
||||
{
|
||||
it->HearingThreshold = Volume;
|
||||
|
||||
if (EmitterTeam != ThisTeam)
|
||||
{
|
||||
AIPlayerHearEnemy(&(*it), EmittingEntity, Volume);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Sound = AISND_PopSound();
|
||||
}
|
||||
}
|
||||
|
||||
void AIMGR_SetFrameDelta(float NewValue)
|
||||
{
|
||||
CurrentFrameDelta = NewValue;
|
||||
}
|
||||
|
||||
float AIMGR_GetFrameDelta()
|
||||
{
|
||||
return CurrentFrameDelta;
|
||||
}
|
|
@ -126,4 +126,9 @@ bool AIMGR_HasMatchEnded();
|
|||
|
||||
bool AIMGR_IsMatchPracticallyOver();
|
||||
|
||||
void AIMGR_ProcessPendingSounds();
|
||||
|
||||
void AIMGR_SetFrameDelta(float NewValue);
|
||||
float AIMGR_GetFrameDelta();
|
||||
|
||||
#endif
|
35
main/source/mod/AvHAISoundQueue.cpp
Normal file
35
main/source/mod/AvHAISoundQueue.cpp
Normal file
|
@ -0,0 +1,35 @@
|
|||
#include "AvHAISoundQueue.h"
|
||||
#include "AvHAIPlayerManager.h"
|
||||
|
||||
std::vector<AvHAISound> PendingSounds;
|
||||
|
||||
void AISND_RegisterNewSound(int EntIndex, float* NewLocation, AvHAISoundType NewSoundType, float Volume)
|
||||
{
|
||||
if (!AIMGR_IsBotEnabled() || Volume < 0.01f) { return; }
|
||||
|
||||
AvHAISound NewSound;
|
||||
NewSound.EntIndex = EntIndex;
|
||||
NewSound.SoundLocation[0] = NewLocation[0];
|
||||
NewSound.SoundLocation[1] = NewLocation[1];
|
||||
NewSound.SoundLocation[2] = NewLocation[2];
|
||||
NewSound.Volume = Volume;
|
||||
NewSound.SoundType = NewSoundType;
|
||||
|
||||
PendingSounds.push_back(NewSound);
|
||||
}
|
||||
|
||||
AvHAISound AISND_PopSound()
|
||||
{
|
||||
if (PendingSounds.size() == 0) { return AvHAISound(); }
|
||||
|
||||
AvHAISound Result = PendingSounds.back();
|
||||
|
||||
PendingSounds.pop_back();
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
void AISND_ClearSounds()
|
||||
{
|
||||
PendingSounds.clear();
|
||||
}
|
35
main/source/mod/AvHAISoundQueue.h
Normal file
35
main/source/mod/AvHAISoundQueue.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
#ifndef AVH_AI_SOUND_QUEUE
|
||||
#define AVH_AI_SOUND_QUEUE
|
||||
|
||||
|
||||
#include <vector>
|
||||
|
||||
// Sound types affect how audible they are to bots, how easy it is to pinpoint the location of the sound etc
|
||||
typedef enum _AVHAISOUNDTYPE
|
||||
{
|
||||
AI_SOUND_NONE = 0, // Blank sound
|
||||
AI_SOUND_FOOTSTEP, // Footstep sound
|
||||
AI_SOUND_LANDING, // Landing sound, THUD
|
||||
AI_SOUND_SHOOT, // Pew pew
|
||||
AI_SOUND_VOICELINE, // Player played a voice line (e.g. "Need a medpack")
|
||||
AI_SOUND_OTHER // Miscellaneous sound e.g. building
|
||||
} AvHAISoundType;
|
||||
|
||||
typedef struct _AVHAISOUND
|
||||
{
|
||||
int EntIndex = 0;
|
||||
float SoundLocation[3] = {0.0f, 0.0f, 0.0f};
|
||||
float Volume = 1.0f;
|
||||
AvHAISoundType SoundType = AI_SOUND_NONE;
|
||||
|
||||
} AvHAISound;
|
||||
|
||||
|
||||
void AISND_RegisterNewSound(int EntIndex, float* NewLocation, AvHAISoundType NewSoundType, float Volume = 1.0f);
|
||||
|
||||
AvHAISound AISND_PopSound();
|
||||
|
||||
void AISND_ClearSounds();
|
||||
|
||||
|
||||
#endif
|
|
@ -1931,7 +1931,7 @@ void BotProgressEvolveTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
{
|
||||
if ((gpGlobals->time - Task->TaskStartedTime) > 1.0f)
|
||||
{
|
||||
Task->TaskLocation = UTIL_GetRandomPointOnNavmeshInRadiusIgnoreReachability(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), pBot->Edict->v.origin, UTIL_MetresToGoldSrcUnits(5.0f));
|
||||
Task->TaskLocation = UTIL_GetRandomPointOnNavmeshInRadius(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), pBot->Edict->v.origin, UTIL_MetresToGoldSrcUnits(5.0f));
|
||||
|
||||
if (vIsZero(Task->TaskLocation))
|
||||
{
|
||||
|
|
|
@ -562,128 +562,12 @@ AvHAIWeapon BotMarineChooseBestWeapon(AvHAIPlayer* pBot, edict_t* target)
|
|||
{
|
||||
return GetBotMarineSecondaryWeapon(pBot);
|
||||
}
|
||||
else
|
||||
{
|
||||
return UTIL_GetPlayerPrimaryWeapon(pBot->Player);
|
||||
}
|
||||
return UTIL_GetPlayerPrimaryWeapon(pBot->Player);
|
||||
}
|
||||
|
||||
if (IsEdictPlayer(target))
|
||||
{
|
||||
float DistFromEnemy = vDist2DSq(pBot->Edict->v.origin, target->v.origin);
|
||||
|
||||
if (UTIL_GetPlayerPrimaryWeapon(pBot->Player) == WEAPON_MARINE_GL)
|
||||
{
|
||||
if (UTIL_GetPlayerPrimaryWeaponClipAmmo(pBot->Player) > 0 && DistFromEnemy > sqrf(UTIL_MetresToGoldSrcUnits(5.0f)))
|
||||
{
|
||||
return WEAPON_MARINE_GL;
|
||||
}
|
||||
|
||||
if (BotGetSecondaryWeaponClipAmmo(pBot) > 0)
|
||||
{
|
||||
return GetBotMarineSecondaryWeapon(pBot);
|
||||
}
|
||||
|
||||
return WEAPON_MARINE_KNIFE;
|
||||
}
|
||||
|
||||
if (DistFromEnemy <= sqrf(UTIL_MetresToGoldSrcUnits(2.0f)))
|
||||
{
|
||||
if (UTIL_GetPlayerPrimaryWeaponClipAmmo(pBot->Player) == 0)
|
||||
{
|
||||
if (BotGetSecondaryWeaponClipAmmo(pBot) > 0)
|
||||
{
|
||||
return GetBotMarineSecondaryWeapon(pBot);
|
||||
}
|
||||
else
|
||||
{
|
||||
return WEAPON_MARINE_KNIFE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return UTIL_GetPlayerPrimaryWeapon(pBot->Player);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AvHAIWeapon PrimaryWeapon = UTIL_GetPlayerPrimaryWeapon(pBot->Player);
|
||||
|
||||
if (PrimaryWeapon == WEAPON_MARINE_SHOTGUN)
|
||||
{
|
||||
if (DistFromEnemy > sqrf(UTIL_MetresToGoldSrcUnits(10.0f)))
|
||||
{
|
||||
if (BotGetSecondaryWeaponClipAmmo(pBot) > 0 || BotGetSecondaryWeaponAmmoReserve(pBot) > 0)
|
||||
{
|
||||
return GetBotMarineSecondaryWeapon(pBot);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (UTIL_GetPlayerPrimaryWeaponClipAmmo(pBot->Player) > 0 || UTIL_GetPlayerPrimaryAmmoReserve(pBot->Player) > 0)
|
||||
{
|
||||
return PrimaryWeapon;
|
||||
}
|
||||
else
|
||||
{
|
||||
return WEAPON_MARINE_KNIFE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (UTIL_GetPlayerPrimaryWeaponClipAmmo(pBot->Player) > 0 || UTIL_GetPlayerPrimaryAmmoReserve(pBot->Player) > 0)
|
||||
{
|
||||
return PrimaryWeapon;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (BotGetSecondaryWeaponClipAmmo(pBot) > 0)
|
||||
{
|
||||
return GetBotMarineSecondaryWeapon(pBot);
|
||||
}
|
||||
else
|
||||
{
|
||||
return WEAPON_MARINE_KNIFE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (DistFromEnemy > sqrf(UTIL_MetresToGoldSrcUnits(5.0f)))
|
||||
{
|
||||
if (UTIL_GetPlayerPrimaryWeaponClipAmmo(pBot->Player) > 0 || UTIL_GetPlayerPrimaryAmmoReserve(pBot->Player) > 0)
|
||||
{
|
||||
return PrimaryWeapon;
|
||||
}
|
||||
|
||||
if (BotGetSecondaryWeaponClipAmmo(pBot) > 0 || BotGetSecondaryWeaponAmmoReserve(pBot) > 0)
|
||||
{
|
||||
return GetBotMarineSecondaryWeapon(pBot);
|
||||
}
|
||||
|
||||
return WEAPON_MARINE_KNIFE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (UTIL_GetPlayerPrimaryWeaponClipAmmo(pBot->Player) > 0 || (DistFromEnemy > sqrf(UTIL_MetresToGoldSrcUnits(5.0f)) && UTIL_GetPlayerPrimaryAmmoReserve(pBot->Player) > 0))
|
||||
{
|
||||
return PrimaryWeapon;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (BotGetSecondaryWeaponClipAmmo(pBot) > 0)
|
||||
{
|
||||
return GetBotMarineSecondaryWeapon(pBot);
|
||||
}
|
||||
else
|
||||
{
|
||||
return WEAPON_MARINE_KNIFE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return MarineGetBestWeaponForPlayerTarget(pBot, dynamic_cast<AvHPlayer*>(CBaseEntity::Instance(target)));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -691,6 +575,14 @@ AvHAIWeapon BotMarineChooseBestWeapon(AvHAIPlayer* pBot, edict_t* target)
|
|||
}
|
||||
}
|
||||
|
||||
bool BotAnyWeaponNeedsReloading(AvHAIPlayer* pBot)
|
||||
{
|
||||
if (UTIL_GetPlayerPrimaryWeaponClipAmmo(pBot->Player) < UTIL_GetPlayerPrimaryWeaponMaxClipSize(pBot->Player) && UTIL_GetPlayerPrimaryAmmoReserve(pBot->Player) > 0) { return true; }
|
||||
if (UTIL_GetPlayerSecondaryWeaponClipAmmo(pBot->Player) < UTIL_GetPlayerSecondaryWeaponMaxClipSize(pBot->Player) && UTIL_GetPlayerSecondaryAmmoReserve(pBot->Player) > 0) { return true; }
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
AvHAIWeapon BotAlienChooseBestWeaponForStructure(AvHAIPlayer* pBot, edict_t* target)
|
||||
{
|
||||
AvHAIDeployableStructureType StructureType = GetStructureTypeFromEdict(target);
|
||||
|
@ -772,6 +664,114 @@ AvHAIWeapon BotMarineChooseBestWeaponForStructure(AvHAIPlayer* pBot, edict_t* ta
|
|||
return WEAPON_MARINE_KNIFE;
|
||||
}
|
||||
|
||||
AvHAIWeapon MarineGetBestWeaponForPlayerTarget(AvHAIPlayer* pBot, AvHPlayer* Target)
|
||||
{
|
||||
AvHAIWeapon PrimaryWeapon = UTIL_GetPlayerPrimaryWeapon(pBot->Player);
|
||||
AvHAIWeapon SecondaryWeapon = UTIL_GetPlayerSecondaryWeapon(pBot->Player);
|
||||
AvHAIWeapon CurrentWeapon = GetPlayerCurrentWeapon(pBot->Player);
|
||||
|
||||
float DistToEnemy = vDist2DSq(pBot->Edict->v.origin, Target->pev->origin);
|
||||
|
||||
bool bHasAmmoForPrimary = (PrimaryWeapon != WEAPON_INVALID && UTIL_GetPlayerPrimaryWeaponClipAmmo(pBot->Player) > 0 || UTIL_GetPlayerPrimaryAmmoReserve(pBot->Player) > 0);
|
||||
bool bHasAmmoForSecondary = (SecondaryWeapon != WEAPON_INVALID && UTIL_GetPlayerSecondaryWeaponClipAmmo(pBot->Player) > 0 || UTIL_GetPlayerSecondaryAmmoReserve(pBot->Player) > 0);
|
||||
|
||||
if (PrimaryWeapon != WEAPON_INVALID && UTIL_GetPlayerPrimaryWeaponClipAmmo(pBot->Player) > 0)
|
||||
{
|
||||
if (PrimaryWeapon == WEAPON_MARINE_GL)
|
||||
{
|
||||
if (DistToEnemy > sqrf(BALANCE_VAR(kGrenadeRadius)) || !bHasAmmoForSecondary)
|
||||
{
|
||||
return PrimaryWeapon;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bHasAmmoForSecondary)
|
||||
{
|
||||
return SecondaryWeapon;
|
||||
}
|
||||
else
|
||||
{
|
||||
return WEAPON_MARINE_KNIFE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (PrimaryWeapon == WEAPON_MARINE_SHOTGUN)
|
||||
{
|
||||
float MaxDist = (IsPlayerMarine(Target) || Target->GetUser3() > AVH_USER3_ALIEN_PLAYER3) ? UTIL_MetresToGoldSrcUnits(15.0f) : UTIL_MetresToGoldSrcUnits(8.0f);
|
||||
|
||||
// Give a little extra leeway if the bot is currently holding a shotgun. Helps prevent rapid switching if the enemy is right on the edge of the max distance
|
||||
if (CurrentWeapon == PrimaryWeapon)
|
||||
{
|
||||
MaxDist *= 1.25f;
|
||||
}
|
||||
|
||||
if (DistToEnemy < sqrf(MaxDist) || !bHasAmmoForSecondary)
|
||||
{
|
||||
return PrimaryWeapon;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bHasAmmoForSecondary)
|
||||
{
|
||||
return SecondaryWeapon;
|
||||
}
|
||||
else
|
||||
{
|
||||
return WEAPON_MARINE_KNIFE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return PrimaryWeapon;
|
||||
}
|
||||
}
|
||||
|
||||
bool bEnemyIsRanged = IsPlayerMarine(Target) || ((GetPlayerCurrentWeapon(Target) == WEAPON_FADE_ACIDROCKET || GetPlayerCurrentWeapon(Target) == WEAPON_LERK_SPORES) && DistToEnemy > sqrf(UTIL_MetresToGoldSrcUnits(5.0f)));
|
||||
|
||||
if (bEnemyIsRanged)
|
||||
{
|
||||
if (bHasAmmoForSecondary)
|
||||
{
|
||||
return SecondaryWeapon;
|
||||
}
|
||||
else
|
||||
{
|
||||
return WEAPON_MARINE_KNIFE;
|
||||
}
|
||||
}
|
||||
|
||||
if (DistToEnemy > sqrf(UTIL_MetresToGoldSrcUnits(5.0f)))
|
||||
{
|
||||
if (bHasAmmoForPrimary)
|
||||
{
|
||||
return PrimaryWeapon;
|
||||
}
|
||||
else if (bHasAmmoForSecondary)
|
||||
{
|
||||
return SecondaryWeapon;
|
||||
}
|
||||
else
|
||||
{
|
||||
return WEAPON_MARINE_KNIFE;
|
||||
}
|
||||
}
|
||||
|
||||
if (UTIL_GetPlayerPrimaryWeaponClipAmmo(pBot->Player) > 0)
|
||||
{
|
||||
return PrimaryWeapon;
|
||||
}
|
||||
else if (UTIL_GetPlayerSecondaryWeaponClipAmmo(pBot->Player) > 0)
|
||||
{
|
||||
return SecondaryWeapon;
|
||||
}
|
||||
else
|
||||
{
|
||||
return WEAPON_MARINE_KNIFE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
AvHAIWeapon GorgeGetBestWeaponForCombatTarget(AvHAIPlayer* pBot, edict_t* Target)
|
||||
{
|
||||
// Apparently I only imagined bile bomb doing damage to marine armour. Leaving it commented out in case we want to enable it again in future
|
||||
|
|
|
@ -43,8 +43,11 @@ bool IsMeleeWeapon(const AvHAIWeapon Weapon);
|
|||
Vector UTIL_GetGrenadeThrowTarget(edict_t* Player, const Vector TargetLocation, const float ExplosionRadius, bool bPrecise);
|
||||
|
||||
AvHAIWeapon BotMarineChooseBestWeaponForStructure(AvHAIPlayer* pBot, edict_t* target);
|
||||
AvHAIWeapon MarineGetBestWeaponForPlayerTarget(AvHAIPlayer* pBot, AvHPlayer* Target);
|
||||
AvHAIWeapon BotAlienChooseBestWeaponForStructure(AvHAIPlayer* pBot, edict_t* target);
|
||||
|
||||
bool BotAnyWeaponNeedsReloading(AvHAIPlayer* pBot);
|
||||
|
||||
// Helper function to pick the best weapon for any given situation and target type.
|
||||
AvHAIWeapon BotMarineChooseBestWeapon(AvHAIPlayer* pBot, edict_t* target);
|
||||
AvHAIWeapon BotAlienChooseBestWeapon(AvHAIPlayer* pBot, edict_t* target);
|
||||
|
|
|
@ -86,7 +86,7 @@ extern int g_runfuncs;
|
|||
#ifdef AVH_SERVER
|
||||
#include "AvHServerUtil.h"
|
||||
#include "AvHGamerules.h"
|
||||
|
||||
#include "AvHAISoundQueue.h"
|
||||
extern int gWelderConstEventID;
|
||||
#endif
|
||||
|
||||
|
@ -1048,11 +1048,32 @@ void AvHBasePlayerWeapon::PrimaryAttack(void)
|
|||
|
||||
this->PlaybackEvent(this->mEvent, this->GetShootAnimation());
|
||||
this->SetAnimationAndSound();
|
||||
|
||||
|
||||
|
||||
// If player is too close to a wall, don't actually fire the projectile
|
||||
if(this->GetIsGunPositionValid())
|
||||
{
|
||||
this->FireProjectiles();
|
||||
#ifdef AVH_SERVER
|
||||
|
||||
float SoundVolume = 1.0f;
|
||||
|
||||
int theSilenceLevel = AvHGetAlienUpgradeLevel(this->m_pPlayer->pev->iuser4, MASK_UPGRADE_6);
|
||||
switch (theSilenceLevel)
|
||||
{
|
||||
case 1:
|
||||
SoundVolume = (float)BALANCE_VAR(kSilenceLevel1Volume);
|
||||
break;
|
||||
case 2:
|
||||
SoundVolume = (float)BALANCE_VAR(kSilenceLevel2Volume);
|
||||
break;
|
||||
case 3:
|
||||
SoundVolume = (float)BALANCE_VAR(kSilenceLevel3Volume);
|
||||
break;
|
||||
}
|
||||
AISND_RegisterNewSound(this->m_pPlayer->entindex(), this->m_pPlayer->pev->origin, AI_SOUND_SHOOT, SoundVolume);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -64,6 +64,7 @@
|
|||
#ifdef AVH_SERVER
|
||||
#include "AvHGamerules.h"
|
||||
#include "AvHServerUtil.h"
|
||||
#include "AvHAISoundQueue.h"
|
||||
#endif
|
||||
|
||||
#include "AvHSharedUtil.h"
|
||||
|
@ -221,6 +222,8 @@ void AvHBite::FireProjectiles(void)
|
|||
{
|
||||
theSoundToPlay = kBiteKillSound;
|
||||
}
|
||||
|
||||
AISND_RegisterNewSound(this->m_pPlayer->entindex(), this->m_pPlayer->pev->origin, AI_SOUND_LANDING, 1.0f);
|
||||
|
||||
EMIT_SOUND(ENT(pev), CHAN_WEAPON, theSoundToPlay, 1.0, ATTN_NORM);
|
||||
}
|
||||
|
|
|
@ -70,6 +70,7 @@
|
|||
#ifdef AVH_SERVER
|
||||
#include "AvHGamerules.h"
|
||||
#include "AvHServerUtil.h"
|
||||
#include "AvHAISoundQueue.h"
|
||||
#endif
|
||||
|
||||
#include "AvHSharedUtil.h"
|
||||
|
@ -235,6 +236,8 @@ void AvHClaws::FireProjectiles(void)
|
|||
float theForceScalar = theDamage*.2f;
|
||||
CBaseEntity* theAttacker = this->m_pPlayer;
|
||||
AvHSUExplosiveForce(pHurt->pev->origin, 100, theForceScalar, theAttacker, theAttacker);
|
||||
|
||||
AISND_RegisterNewSound(pHurt->entindex(), this->m_pPlayer->pev->origin, AI_SOUND_LANDING, 1.0f);
|
||||
|
||||
// Played in event now
|
||||
//EMIT_SOUND_DYN(ENT(pev), CHAN_WEAPON, theSoundToPlay, 1.0, ATTN_NORM, 0, 100 + theAdrenalineFactor*30 + RANDOM_LONG(-3,3) );
|
||||
|
|
|
@ -146,7 +146,10 @@
|
|||
#include "AvHSiegeTurret.h"
|
||||
#include "AvHHulls.h"
|
||||
|
||||
#ifdef AVH_SERVER
|
||||
#include "AvHAIPlayerManager.h"
|
||||
#include "AvHAISoundQueue.h"
|
||||
#endif
|
||||
|
||||
//LINK_ENTITY_TO_CLASS(kwMine, AvHMine);
|
||||
//LINK_ENTITY_TO_CLASS(kwDeployedTurret, AvHDeployedTurret);
|
||||
|
@ -1286,6 +1289,10 @@ void AvHPhaseGate::TeleportUse(CBaseEntity *pActivator, CBaseEntity *pCaller, US
|
|||
this->SetTimeOfLastDeparture(gpGlobals->time);
|
||||
AvHSUPlayPhaseInEffect(theFlags, this, thePlayer);
|
||||
|
||||
#ifdef AVH_SERVER
|
||||
AISND_RegisterNewSound(thePlayer->entindex(), theOrigin, AI_SOUND_OTHER, 1.0f);
|
||||
#endif
|
||||
|
||||
// AvHSUKillPlayersTouchingPlayer(thePlayer, this->pev);
|
||||
AvHSUPushbackPlayersTouchingPlayer(thePlayer, this->pev);
|
||||
KillBuildablesTouchingPlayer(thePlayer, this->pev);
|
||||
|
@ -1978,11 +1985,13 @@ void AvHCommandStation::CommandUse( CBaseEntity* pActivator, CBaseEntity* pCalle
|
|||
|
||||
GetGameRules()->MarkDramaticEvent(kCCNewCommanderPriority, thePlayer, this);
|
||||
|
||||
#ifdef AVH_SERVER
|
||||
// A human used the comm chair, let the AI know to keep away
|
||||
if (!(thePlayer->pev->flags & FL_FAKECLIENT))
|
||||
{
|
||||
AIMGR_SetCommanderAllowedTime(theStationTeamNumber, gpGlobals->time + 20.0f);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -255,7 +255,10 @@
|
|||
#include "AvHNetworkMessages.h"
|
||||
#include "AvHNexusServer.h"
|
||||
|
||||
#ifdef AVH_SERVER
|
||||
#include "AvHAIPlayerManager.h"
|
||||
#include "AvHAISoundQueue.h"
|
||||
#endif
|
||||
|
||||
std::string GetLogStringForPlayer( edict_t *pEntity );
|
||||
|
||||
|
@ -2309,6 +2312,26 @@ void AvHPlayer::StartLeap()
|
|||
// Make sure player has leap
|
||||
if(this->pev->iuser3 == AVH_USER3_ALIEN_PLAYER1)
|
||||
{
|
||||
#ifdef AVH_SERVER
|
||||
|
||||
float SoundVolume = 1.0f;
|
||||
|
||||
int theSilenceLevel = AvHGetAlienUpgradeLevel(this->pev->iuser4, MASK_UPGRADE_6);
|
||||
switch (theSilenceLevel)
|
||||
{
|
||||
case 1:
|
||||
SoundVolume = (float)BALANCE_VAR(kSilenceLevel1Volume);
|
||||
break;
|
||||
case 2:
|
||||
SoundVolume = (float)BALANCE_VAR(kSilenceLevel2Volume);
|
||||
break;
|
||||
case 3:
|
||||
SoundVolume = (float)BALANCE_VAR(kSilenceLevel3Volume);
|
||||
break;
|
||||
}
|
||||
|
||||
AISND_RegisterNewSound(this->entindex(), this->pev->origin, AI_SOUND_SHOOT, SoundVolume);
|
||||
#endif
|
||||
this->mTimeLeapEnd = gpGlobals->time + kLeapDuration;
|
||||
}
|
||||
}
|
||||
|
@ -4973,6 +4996,11 @@ bool AvHPlayer::PlaySaying(AvHMessageID inMessageID)
|
|||
//int pitch = 95;// + RANDOM_LONG(0,29);
|
||||
//EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, theSaying, 1, ATTN_NORM, 0, pitch);
|
||||
gSoundListManager.PlaySoundInList(theSoundList, this, CHAN_VOICE, 1.0f);
|
||||
|
||||
#ifdef AVH_SERVER
|
||||
AISND_RegisterNewSound(this->entindex(), this->pev->origin, AI_SOUND_VOICELINE, 1.0f);
|
||||
#endif
|
||||
|
||||
|
||||
thePlayedSaying = true;
|
||||
}
|
||||
|
@ -7034,6 +7062,28 @@ void AvHPlayer::InternalMovementThink()
|
|||
}
|
||||
}
|
||||
else {
|
||||
|
||||
#ifdef AVH_SERVER
|
||||
|
||||
float SoundVolume = 1.0f;
|
||||
|
||||
int theSilenceLevel = AvHGetAlienUpgradeLevel(this->pev->iuser4, MASK_UPGRADE_6);
|
||||
switch (theSilenceLevel)
|
||||
{
|
||||
case 1:
|
||||
SoundVolume = (float)BALANCE_VAR(kSilenceLevel1Volume);
|
||||
break;
|
||||
case 2:
|
||||
SoundVolume = (float)BALANCE_VAR(kSilenceLevel2Volume);
|
||||
break;
|
||||
case 3:
|
||||
SoundVolume = (float)BALANCE_VAR(kSilenceLevel3Volume);
|
||||
break;
|
||||
}
|
||||
|
||||
AISND_RegisterNewSound(this->entindex(), this->pev->origin, AI_SOUND_SHOOT, SoundVolume);
|
||||
#endif
|
||||
|
||||
EMIT_SOUND_DYN(ENT(this->pev), CHAN_WEAPON, theSoundToPlay, theVolumeScalar, ATTN_NORM, 0, 100);
|
||||
this->mTimeOfLastMovementSound = gpGlobals->time;
|
||||
}
|
||||
|
@ -8753,6 +8803,10 @@ bool AvHPlayer::Heal(float inAmount, bool inPlaySound, bool dcHealing)
|
|||
{
|
||||
// Play regeneration event
|
||||
PLAYBACK_EVENT_FULL(0, this->edict(), gRegenerationEventID, 0, this->pev->origin, (float *)&g_vecZero, this->GetAlienAdjustedEventVolume(), 0.0, /*theWeaponIndex*/ 0, 0, 0, 0 );
|
||||
#ifdef AVH_SERVER
|
||||
// Heartbeat sound is a little loud, so reduce it for the AI so bots don't instantly spot your location with a single regen tic
|
||||
AISND_RegisterNewSound(this->entindex(), this->pev->origin, AI_SOUND_OTHER, this->GetAlienAdjustedEventVolume() * 0.25f);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9177,7 +9231,8 @@ int AvHPlayer::TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, floa
|
|||
{
|
||||
CBasePlayer* inAttackingPlayer = dynamic_cast<CBasePlayer*>(CBaseEntity::Instance(ENT(pevAttacker)));
|
||||
|
||||
if (inAttackingPlayer)
|
||||
#ifdef AVH_SERVER
|
||||
if (inAttackingPlayer && AIMGR_IsBotEnabled())
|
||||
{
|
||||
AvHAIPlayer* VictimBot = AIMGR_GetBotRefFromPlayer(this);
|
||||
|
||||
|
@ -9186,7 +9241,7 @@ int AvHPlayer::TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, floa
|
|||
AIPlayerTakeDamage(VictimBot, flDamage, inAttackingPlayer->edict());
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
const char* inWeaponName = STRING(pevInflictor->classname);
|
||||
if(inAttackingPlayer && inWeaponName)
|
||||
{
|
||||
|
|
|
@ -123,6 +123,8 @@
|
|||
#include "AvHHulls.h"
|
||||
#include "AnimationUtil.h"
|
||||
|
||||
#include "AvHAISoundQueue.h"
|
||||
|
||||
int NS_PointContents(const hull_t *hull, int num, float p[3]);
|
||||
float NS_TraceLineAgainstEntity(int inEntityIndex, float inTime, const float inRayOrigin[3], const float inRayDirection[3]);
|
||||
|
||||
|
@ -573,6 +575,8 @@ void AvHSUPlayRandomConstructionEffect(AvHPlayer* inPlayer, CBaseEntity* inConst
|
|||
{
|
||||
gSoundListManager.PlaySoundInList(kMarineConstructionSoundList, inConstructee, CHAN_BODY, theVolume);
|
||||
|
||||
AISND_RegisterNewSound(inPlayer->entindex(), inPlayer->pev->origin, AI_SOUND_OTHER, theVolume);
|
||||
|
||||
// Play sparks every other time
|
||||
if(RANDOM_LONG(0, 1) == 1)
|
||||
{
|
||||
|
|
|
@ -67,6 +67,7 @@
|
|||
#ifdef AVH_SERVER
|
||||
#include "AvHGamerules.h"
|
||||
#include "AvHServerUtil.h"
|
||||
#include "AvHAISoundQueue.h"
|
||||
#endif
|
||||
|
||||
#include "AvHSharedUtil.h"
|
||||
|
@ -254,6 +255,8 @@ void AvHSwipe::FireProjectiles(void)
|
|||
ASSERT(theSoundToPlay);
|
||||
|
||||
EMIT_SOUND(ENT(pev), CHAN_WEAPON, theSoundToPlay, 1.0, ATTN_NORM);
|
||||
|
||||
AISND_RegisterNewSound(pHurt->entindex(), this->m_pPlayer->pev->origin, AI_SOUND_LANDING, 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -107,6 +107,9 @@
|
|||
#include "../mod/CollisionUtil.h"
|
||||
#include "../engine/studio.h"
|
||||
|
||||
#ifdef AVH_SERVER
|
||||
#include "../mod/AvHAISoundQueue.h"
|
||||
#endif
|
||||
|
||||
//#ifdef AVH_SERVER
|
||||
#include "../engine/edict.h"
|
||||
|
@ -2008,6 +2011,9 @@ void NS_PlayStepSound(int inMaterialType, int inSoundNumber, float inVolume)
|
|||
|
||||
// Play it at the specified volume
|
||||
PM_NSPlaySound(CHAN_BODY, theFinalName, inVolume, theNorm, 0, PITCH_NORM);
|
||||
#ifdef AVH_SERVER
|
||||
AISND_RegisterNewSound(pmove->player_index + 1, pmove->origin, AI_SOUND_FOOTSTEP, inVolume);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -4613,6 +4619,10 @@ bool PM_FlapMove()
|
|||
theVolumeScalar = min(max(theVolumeScalar, 0.0f), 1.0f);
|
||||
|
||||
PM_NSPlaySound(CHAN_BODY, theSoundToPlay, theVolumeScalar, ATTN_NORM, 0, PITCH_NORM);
|
||||
|
||||
#ifdef AVH_SERVER
|
||||
AISND_RegisterNewSound(pmove->player_index + 1, pmove->origin, AI_SOUND_FOOTSTEP, theVolumeScalar);
|
||||
#endif
|
||||
}
|
||||
|
||||
pmove->oldbuttons |= IN_JUMP; // don't jump again until released
|
||||
|
@ -5700,6 +5710,9 @@ void PM_CheckFalling( void )
|
|||
//break;
|
||||
//case 1:
|
||||
PM_NSPlaySound( CHAN_VOICE, theFallPainSound, theFallPainVolume, ATTN_NORM, 0, PITCH_NORM );
|
||||
#ifdef AVH_SERVER
|
||||
AISND_RegisterNewSound(pmove->player_index + 1, pmove->origin, AI_SOUND_LANDING, theFallPainVolume);
|
||||
#endif
|
||||
// break;
|
||||
//}
|
||||
fvol = 1.0;
|
||||
|
|
Loading…
Reference in a new issue