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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
void BotUpdateDesiredViewRotation(AvHAIPlayer* pBot)
|
||||
|
@ -1646,11 +1670,6 @@ void UpdateAIPlayerDMRole(AvHAIPlayer* pBot)
|
|||
|
||||
}
|
||||
|
||||
void UpdateAIAlienPlayerNSRole(AvHAIPlayer* pBot)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool ShouldAIPlayerTakeCommand(AvHAIPlayer* pBot)
|
||||
{
|
||||
AvHAICommanderMode CurrentCommanderMode = AIMGR_GetCommanderMode();
|
||||
|
@ -1700,6 +1719,34 @@ bool ShouldAIPlayerTakeCommand(AvHAIPlayer* pBot)
|
|||
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)
|
||||
{
|
||||
AvHTeamNumber BotTeamNumber = pBot->Player->GetTeam();
|
||||
|
@ -1857,11 +1904,6 @@ void AIPlayerNSMarineThink(AvHAIPlayer* pBot)
|
|||
{
|
||||
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)
|
||||
|
|
|
@ -142,6 +142,16 @@ void AIMGR_UpdateAIPlayerCounts()
|
|||
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()
|
||||
{
|
||||
AvHTeamNumber teamA = GetGameRules()->GetTeamANumber();
|
||||
|
|
|
@ -38,7 +38,9 @@ void AIMGR_UpdateFillTeams();
|
|||
|
||||
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();
|
||||
// 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);
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "AvHAIHelper.h"
|
||||
#include "AvHAIConstants.h"
|
||||
#include "AvHAIPlayerManager.h"
|
||||
#include "AvHAIConfig.h"
|
||||
|
||||
#include "../AvHGamerules.h"
|
||||
#include "../AvHServerUtil.h"
|
||||
|
@ -3300,3 +3301,55 @@ bool AITAC_AnyPlayerOnTeamWithLOS(AvHTeamNumber Team, const Vector& Location, fl
|
|||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
BotAlienHealTarget(pBot, Task->TaskTarget);
|
||||
}
|
||||
|
||||
void AlienProgressBuildHiveTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
||||
|
@ -2214,9 +2196,6 @@ void BotAlienBuildResTower(AvHAIPlayer* pBot, const AvHAIResourceNode* NodeToCap
|
|||
RegisterBotAlienBuildAttempt(pBot, NodeToCap->Location, STRUCTURE_ALIEN_RESTOWER);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
pBot->ActiveBuildInfo.AttemptedLocation = PlacementLocation;
|
||||
|
|
|
@ -112,6 +112,7 @@ void UTIL_ClearGuardInfo(AvHAIPlayer* pBot);
|
|||
void BotAlienPlaceChamber(AvHAIPlayer* pBot, Vector Location, AvHAIDeployableStructureType DesiredStructure);
|
||||
void BotAlienBuildHive(AvHAIPlayer* pBot, const AvHAIHiveDefinition* HiveToBuild);
|
||||
void BotAlienBuildResTower(AvHAIPlayer* pBot, const AvHAIResourceNode* NodeToCap);
|
||||
void BotAlienHealTarget(AvHAIPlayer* pBot, edict_t* HealTarget);
|
||||
|
||||
void RegisterBotAlienBuildAttempt(AvHAIPlayer* pBot, Vector PlacementLocation, AvHAIDeployableStructureType DesiredStructure);
|
||||
|
||||
|
|
|
@ -399,7 +399,7 @@ float GetMaxIdealWeaponRange(const AvHAIWeapon Weapon)
|
|||
case WEAPON_LERK_BITE:
|
||||
return BALANCE_VAR(kBite2Range);
|
||||
case WEAPON_GORGE_HEALINGSPRAY:
|
||||
return BALANCE_VAR(kHealingSprayRange);
|
||||
return BALANCE_VAR(kHealingSprayRange) * 0.5f;
|
||||
case WEAPON_MARINE_WELDER:
|
||||
return BALANCE_VAR(kWelderRange);
|
||||
default:
|
||||
|
|
Loading…
Reference in a new issue