mirror of
https://github.com/ENSL/NS.git
synced 2024-11-10 15:21:54 +00:00
Start alien tactical decisioning
This commit is contained in:
parent
07f488af9a
commit
d3e1d18e11
7 changed files with 150 additions and 36 deletions
|
@ -1001,7 +1001,31 @@ void BotEvolveLifeform(AvHAIPlayer* pBot, Vector DesiredEvolveLocation, AvHMessa
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float EvolveCost = 0.0f;
|
||||||
|
|
||||||
|
switch (TargetLifeform)
|
||||||
|
{
|
||||||
|
case ALIEN_LIFEFORM_TWO:
|
||||||
|
EvolveCost = BALANCE_VAR(kGorgeCost);
|
||||||
|
break;
|
||||||
|
case ALIEN_LIFEFORM_THREE:
|
||||||
|
EvolveCost = BALANCE_VAR(kLerkCost);
|
||||||
|
break;
|
||||||
|
case ALIEN_LIFEFORM_FOUR:
|
||||||
|
EvolveCost = BALANCE_VAR(kFadeCost);
|
||||||
|
break;
|
||||||
|
case ALIEN_LIFEFORM_FIVE:
|
||||||
|
EvolveCost = BALANCE_VAR(kOnosCost);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
EvolveCost = 0.0f;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pBot->Player->GetResources() >= EvolveCost)
|
||||||
|
{
|
||||||
pBot->Impulse = TargetLifeform;
|
pBot->Impulse = TargetLifeform;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BotUpdateDesiredViewRotation(AvHAIPlayer* pBot)
|
void BotUpdateDesiredViewRotation(AvHAIPlayer* pBot)
|
||||||
|
@ -1646,11 +1670,6 @@ void UpdateAIPlayerDMRole(AvHAIPlayer* pBot)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateAIAlienPlayerNSRole(AvHAIPlayer* pBot)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ShouldAIPlayerTakeCommand(AvHAIPlayer* pBot)
|
bool ShouldAIPlayerTakeCommand(AvHAIPlayer* pBot)
|
||||||
{
|
{
|
||||||
AvHAICommanderMode CurrentCommanderMode = AIMGR_GetCommanderMode();
|
AvHAICommanderMode CurrentCommanderMode = AIMGR_GetCommanderMode();
|
||||||
|
@ -1700,6 +1719,34 @@ bool ShouldAIPlayerTakeCommand(AvHAIPlayer* pBot)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UpdateAIAlienPlayerNSRole(AvHAIPlayer* pBot)
|
||||||
|
{
|
||||||
|
AvHTeamNumber BotTeamNumber = pBot->Player->GetTeam();
|
||||||
|
|
||||||
|
if (BotTeamNumber == TEAM_IND)
|
||||||
|
{
|
||||||
|
SetNewAIPlayerRole(pBot, BOT_ROLE_NONE);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't switch roles if already fade/onos or those resources are potentially wasted
|
||||||
|
if (IsPlayerFade(pBot->Edict) || IsPlayerOnos(pBot->Edict))
|
||||||
|
{
|
||||||
|
SetNewAIPlayerRole(pBot, BOT_ROLE_ASSAULT);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Likewise for lerks
|
||||||
|
if (IsPlayerLerk(pBot->Edict))
|
||||||
|
{
|
||||||
|
SetNewAIPlayerRole(pBot, BOT_ROLE_HARASS);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void UpdateAIMarinePlayerNSRole(AvHAIPlayer* pBot)
|
void UpdateAIMarinePlayerNSRole(AvHAIPlayer* pBot)
|
||||||
{
|
{
|
||||||
AvHTeamNumber BotTeamNumber = pBot->Player->GetTeam();
|
AvHTeamNumber BotTeamNumber = pBot->Player->GetTeam();
|
||||||
|
@ -1857,11 +1904,6 @@ void AIPlayerNSMarineThink(AvHAIPlayer* pBot)
|
||||||
{
|
{
|
||||||
pBot->DesiredCombatWeapon = BotMarineChooseBestWeapon(pBot, nullptr);
|
pBot->DesiredCombatWeapon = BotMarineChooseBestWeapon(pBot, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pBot->CommanderTask.TaskType != TASK_NONE)
|
|
||||||
{
|
|
||||||
UTIL_DrawLine(INDEXENT(1), pBot->Edict->v.origin, pBot->CommanderTask.TaskLocation);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AIPlayerSetPrimaryMarineTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
void AIPlayerSetPrimaryMarineTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
||||||
|
|
|
@ -142,6 +142,16 @@ void AIMGR_UpdateAIPlayerCounts()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int AIMGR_GetNumPlayersOnTeam(AvHTeamNumber Team)
|
||||||
|
{
|
||||||
|
AvHTeamNumber teamA = GetGameRules()->GetTeamANumber();
|
||||||
|
AvHTeamNumber teamB = GetGameRules()->GetTeamBNumber();
|
||||||
|
|
||||||
|
if (Team != teamA && Team != teamB) { return 0; }
|
||||||
|
|
||||||
|
return (Team == teamA) ? GetGameRules()->GetTeamAPlayerCount() : GetGameRules()->GetTeamBPlayerCount();
|
||||||
|
}
|
||||||
|
|
||||||
void AIMGR_UpdateTeamBalance()
|
void AIMGR_UpdateTeamBalance()
|
||||||
{
|
{
|
||||||
AvHTeamNumber teamA = GetGameRules()->GetTeamANumber();
|
AvHTeamNumber teamA = GetGameRules()->GetTeamANumber();
|
||||||
|
|
|
@ -38,7 +38,9 @@ void AIMGR_UpdateFillTeams();
|
||||||
|
|
||||||
vector<AvHPlayer*> AIMGR_GetAllPlayersOnTeam(AvHTeamNumber Team);
|
vector<AvHPlayer*> AIMGR_GetAllPlayersOnTeam(AvHTeamNumber Team);
|
||||||
|
|
||||||
// How many AI players are in the game (does not include third-party bots like RCBot/Whichbot)
|
// Convenient helper function to get total number of players (human and AI) on a team
|
||||||
|
int AIMGR_GetNumPlayersOnTeam(AvHTeamNumber Team);
|
||||||
|
// How many AI players are in the game (does NOT include third-party bots like RCBot/Whichbot)
|
||||||
int AIMGR_GetNumAIPlayers();
|
int AIMGR_GetNumAIPlayers();
|
||||||
// Returns true if an AI player is on the requested team (does NOT include third-party bots like RCBot/Whichbot)
|
// Returns true if an AI player is on the requested team (does NOT include third-party bots like RCBot/Whichbot)
|
||||||
int AIMGR_AIPlayerExistsOnTeam(AvHTeamNumber Team);
|
int AIMGR_AIPlayerExistsOnTeam(AvHTeamNumber Team);
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include "AvHAIHelper.h"
|
#include "AvHAIHelper.h"
|
||||||
#include "AvHAIConstants.h"
|
#include "AvHAIConstants.h"
|
||||||
#include "AvHAIPlayerManager.h"
|
#include "AvHAIPlayerManager.h"
|
||||||
|
#include "AvHAIConfig.h"
|
||||||
|
|
||||||
#include "../AvHGamerules.h"
|
#include "../AvHGamerules.h"
|
||||||
#include "../AvHServerUtil.h"
|
#include "../AvHServerUtil.h"
|
||||||
|
@ -3300,3 +3301,55 @@ bool AITAC_AnyPlayerOnTeamWithLOS(AvHTeamNumber Team, const Vector& Location, fl
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AITAC_IsAlienBuilderNeeded(AvHAIPlayer* pBot)
|
||||||
|
{
|
||||||
|
AvHTeamNumber BotTeam = pBot->Player->GetTeam();
|
||||||
|
|
||||||
|
AvHMessageID HiveTechOne = CONFIG_GetHiveTechAtIndex(0);
|
||||||
|
AvHMessageID HiveTechTwo = CONFIG_GetHiveTechAtIndex(1);
|
||||||
|
AvHMessageID HiveTechThree = CONFIG_GetHiveTechAtIndex(2);
|
||||||
|
|
||||||
|
AvHAIDeployableStructureType ChamberTypeOne = UTIL_GetChamberTypeForHiveTech(HiveTechOne);
|
||||||
|
AvHAIDeployableStructureType ChamberTypeTwo = UTIL_GetChamberTypeForHiveTech(HiveTechTwo);
|
||||||
|
AvHAIDeployableStructureType ChamberTypeThree = UTIL_GetChamberTypeForHiveTech(HiveTechThree);
|
||||||
|
|
||||||
|
DeployableSearchFilter StructureFilter;
|
||||||
|
StructureFilter.DeployableTeam = BotTeam;
|
||||||
|
|
||||||
|
int NumTeamPlayers = AIMGR_GetNumPlayersOnTeam(BotTeam);
|
||||||
|
int MaxBuilders = imini(2, (int)floorf((float)NumTeamPlayers * 0.5f));
|
||||||
|
int NumCurrentBuilders = AIMGR_GetNumAIPlayersWithRoleOnTeam(BotTeam, BOT_ROLE_BUILDER, pBot);
|
||||||
|
|
||||||
|
if (MaxBuilders == 0) { return false; }
|
||||||
|
|
||||||
|
// We have a hive without any associated chambers yet
|
||||||
|
if (AITAC_TeamHiveWithTechExists(BotTeam, MESSAGE_NULL))
|
||||||
|
{
|
||||||
|
return NumCurrentBuilders < MaxBuilders;
|
||||||
|
}
|
||||||
|
|
||||||
|
StructureFilter.DeployableTypes = ChamberTypeOne;
|
||||||
|
if (AITAC_TeamHiveWithTechExists(BotTeam, HiveTechOne) && AITAC_GetNumDeployablesNearLocation(pBot->Edict->v.origin, &StructureFilter) < 3) { return NumBuilders < 1; }
|
||||||
|
|
||||||
|
StructureFilter.DeployableTypes = ChamberTypeTwo;
|
||||||
|
if (AITAC_TeamHiveWithTechExists(BotTeam, HiveTechTwo) && AITAC_GetNumDeployablesNearLocation(pBot->Edict->v.origin, &StructureFilter) < 3) { return NumBuilders < 1; }
|
||||||
|
|
||||||
|
StructureFilter.DeployableTypes = ChamberTypeThree;
|
||||||
|
if (AITAC_TeamHiveWithTechExists(BotTeam, HiveTechThree) && AITAC_GetNumDeployablesNearLocation(pBot->Edict->v.origin, &StructureFilter) < 3) { return NumBuilders < 1; }
|
||||||
|
|
||||||
|
DeployableSearchFilter ResNodeFilter;
|
||||||
|
ResNodeFilter.DeployableTeam = BotTeam;
|
||||||
|
ResNodeFilter.ReachabilityTeam = BotTeam;
|
||||||
|
ResNodeFilter.ReachabilityFlags = pBot->BotNavInfo.NavProfile.ReachabilityFlag;
|
||||||
|
|
||||||
|
vector <AvHAIResourceNode*> OwnedNodes = AITAC_GetAllMatchingResourceNodes(pBot->Edict->v.origin, &ResNodeFilter);
|
||||||
|
|
||||||
|
for (auto it = OwnedNodes.begin(); it != OwnedNodes.end(); it++)
|
||||||
|
{
|
||||||
|
AvHAIResourceNode* ThisNode = (*it);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1999,27 +1999,9 @@ void AlienProgressGetHealthTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
||||||
|
|
||||||
void AlienProgressHealTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
void AlienProgressHealTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
||||||
{
|
{
|
||||||
if (!IsPlayerGorge(pBot->Edict) || FNullEnt(Task->TaskTarget) || IsPlayerDead(Task->TaskTarget)) { return; }
|
if (FNullEnt(Task->TaskTarget) || IsPlayerDead(Task->TaskTarget)) { return; }
|
||||||
|
|
||||||
float DesiredDist = (IsEdictStructure(Task->TaskTarget)) ? kHealingSprayRange : (kHealingSprayRange * 0.5f);
|
BotAlienHealTarget(pBot, Task->TaskTarget);
|
||||||
|
|
||||||
BotAttackResult LOSCheck = PerformAttackLOSCheck(pBot, WEAPON_GORGE_HEALINGSPRAY, Task->TaskTarget);
|
|
||||||
|
|
||||||
if (LOSCheck == ATTACK_SUCCESS)
|
|
||||||
{
|
|
||||||
pBot->DesiredCombatWeapon = WEAPON_GORGE_HEALINGSPRAY;
|
|
||||||
BotLookAt(pBot, UTIL_GetCentreOfEntity(Task->TaskTarget));
|
|
||||||
if (GetPlayerCurrentWeapon(pBot->Player) == WEAPON_GORGE_HEALINGSPRAY)
|
|
||||||
{
|
|
||||||
pBot->Button |= IN_ATTACK;
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MoveTo(pBot, UTIL_GetEntityGroundLocation(Task->TaskTarget), MOVESTYLE_NORMAL, kHealingSprayRange);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AlienProgressBuildHiveTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
void AlienProgressBuildHiveTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
||||||
|
@ -2214,9 +2196,6 @@ void BotAlienBuildResTower(AvHAIPlayer* pBot, const AvHAIResourceNode* NodeToCap
|
||||||
RegisterBotAlienBuildAttempt(pBot, NodeToCap->Location, STRUCTURE_ALIEN_RESTOWER);
|
RegisterBotAlienBuildAttempt(pBot, NodeToCap->Location, STRUCTURE_ALIEN_RESTOWER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BotAlienBuildHive(AvHAIPlayer* pBot, const AvHAIHiveDefinition* HiveToBuild)
|
void BotAlienBuildHive(AvHAIPlayer* pBot, const AvHAIHiveDefinition* HiveToBuild)
|
||||||
|
@ -2267,6 +2246,33 @@ void BotAlienBuildHive(AvHAIPlayer* pBot, const AvHAIHiveDefinition* HiveToBuild
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BotAlienHealTarget(AvHAIPlayer* pBot, edict_t* HealTarget)
|
||||||
|
{
|
||||||
|
float MaxHealRange = GetMaxIdealWeaponRange(WEAPON_GORGE_HEALINGSPRAY);
|
||||||
|
float TargetHealRange = MaxHealRange * 0.5f;
|
||||||
|
|
||||||
|
BotAttackResult HitCheck = PerformAttackLOSCheck(pBot, WEAPON_GORGE_HEALINGSPRAY, HealTarget);
|
||||||
|
|
||||||
|
if (HitCheck == ATTACK_SUCCESS)
|
||||||
|
{
|
||||||
|
if (IsPlayerGorge(pBot->Edict))
|
||||||
|
{
|
||||||
|
BotShootTarget(pBot, WEAPON_GORGE_HEALINGSPRAY, HealTarget);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BotEvolveLifeform(pBot, pBot->Edict->v.origin, ALIEN_LIFEFORM_TWO);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MoveTo(pBot, UTIL_GetEntityGroundLocation(HealTarget), MOVESTYLE_NORMAL, MaxHealRange);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void RegisterBotAlienBuildAttempt(AvHAIPlayer* pBot, Vector PlacementLocation, AvHAIDeployableStructureType DesiredStructure)
|
void RegisterBotAlienBuildAttempt(AvHAIPlayer* pBot, Vector PlacementLocation, AvHAIDeployableStructureType DesiredStructure)
|
||||||
{
|
{
|
||||||
pBot->ActiveBuildInfo.AttemptedLocation = PlacementLocation;
|
pBot->ActiveBuildInfo.AttemptedLocation = PlacementLocation;
|
||||||
|
|
|
@ -112,6 +112,7 @@ void UTIL_ClearGuardInfo(AvHAIPlayer* pBot);
|
||||||
void BotAlienPlaceChamber(AvHAIPlayer* pBot, Vector Location, AvHAIDeployableStructureType DesiredStructure);
|
void BotAlienPlaceChamber(AvHAIPlayer* pBot, Vector Location, AvHAIDeployableStructureType DesiredStructure);
|
||||||
void BotAlienBuildHive(AvHAIPlayer* pBot, const AvHAIHiveDefinition* HiveToBuild);
|
void BotAlienBuildHive(AvHAIPlayer* pBot, const AvHAIHiveDefinition* HiveToBuild);
|
||||||
void BotAlienBuildResTower(AvHAIPlayer* pBot, const AvHAIResourceNode* NodeToCap);
|
void BotAlienBuildResTower(AvHAIPlayer* pBot, const AvHAIResourceNode* NodeToCap);
|
||||||
|
void BotAlienHealTarget(AvHAIPlayer* pBot, edict_t* HealTarget);
|
||||||
|
|
||||||
void RegisterBotAlienBuildAttempt(AvHAIPlayer* pBot, Vector PlacementLocation, AvHAIDeployableStructureType DesiredStructure);
|
void RegisterBotAlienBuildAttempt(AvHAIPlayer* pBot, Vector PlacementLocation, AvHAIDeployableStructureType DesiredStructure);
|
||||||
|
|
||||||
|
|
|
@ -399,7 +399,7 @@ float GetMaxIdealWeaponRange(const AvHAIWeapon Weapon)
|
||||||
case WEAPON_LERK_BITE:
|
case WEAPON_LERK_BITE:
|
||||||
return BALANCE_VAR(kBite2Range);
|
return BALANCE_VAR(kBite2Range);
|
||||||
case WEAPON_GORGE_HEALINGSPRAY:
|
case WEAPON_GORGE_HEALINGSPRAY:
|
||||||
return BALANCE_VAR(kHealingSprayRange);
|
return BALANCE_VAR(kHealingSprayRange) * 0.5f;
|
||||||
case WEAPON_MARINE_WELDER:
|
case WEAPON_MARINE_WELDER:
|
||||||
return BALANCE_VAR(kWelderRange);
|
return BALANCE_VAR(kWelderRange);
|
||||||
default:
|
default:
|
||||||
|
|
Loading…
Reference in a new issue