mirror of
https://github.com/ENSL/NS.git
synced 2024-11-24 21:41:17 +00:00
Bot Relocation
* Marine bots can now relocate their base to a nearby hive * If the chance to relocate is above 0 (configurable in nsbots.ini) then the bots will relocate at the start of a match based on the percentage set, or if the current base is overrun and about to be lost * The bot will recycle the old comm chair * The bot will abandon the relocation attempt if unsuccessful 90 seconds into a match
This commit is contained in:
parent
91231ac069
commit
e17fba76ea
9 changed files with 65 additions and 12 deletions
|
@ -14,6 +14,9 @@ MaxAIMatchTime=90
|
||||||
# 2 = When the round has started (after countdown)
|
# 2 = When the round has started (after countdown)
|
||||||
BotFillTiming=1
|
BotFillTiming=1
|
||||||
|
|
||||||
|
# Chance the AI commander will try to relocate to an empty hive at match start
|
||||||
|
# Value is a decimal between 0.0 and 1.0, with 0 being never and 1 being always
|
||||||
|
RelocationChance=0.1
|
||||||
|
|
||||||
### Skill Settings ###
|
### Skill Settings ###
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "AvHAITask.h"
|
#include "AvHAITask.h"
|
||||||
#include "AvHAIHelper.h"
|
#include "AvHAIHelper.h"
|
||||||
#include "AvHAIPlayerManager.h"
|
#include "AvHAIPlayerManager.h"
|
||||||
|
#include "AvHAIConfig.h"
|
||||||
|
|
||||||
#include "AvHSharedUtil.h"
|
#include "AvHSharedUtil.h"
|
||||||
#include "AvHServerUtil.h"
|
#include "AvHServerUtil.h"
|
||||||
|
@ -3701,6 +3702,8 @@ void AICOMM_ReceiveChatRequest(AvHAIPlayer* Commander, edict_t* Requestor, const
|
||||||
|
|
||||||
bool AICOMM_ShouldCommanderRelocate(AvHAIPlayer* pBot)
|
bool AICOMM_ShouldCommanderRelocate(AvHAIPlayer* pBot)
|
||||||
{
|
{
|
||||||
|
if (!CONFIG_IsRelocationAllowed()) { return false; }
|
||||||
|
|
||||||
AvHTeamNumber Team = pBot->Player->GetTeam();
|
AvHTeamNumber Team = pBot->Player->GetTeam();
|
||||||
AvHTeamNumber EnemyTeam = AIMGR_GetEnemyTeam(Team);
|
AvHTeamNumber EnemyTeam = AIMGR_GetEnemyTeam(Team);
|
||||||
|
|
||||||
|
@ -3818,13 +3821,13 @@ bool AICOMM_ShouldCommanderRelocate(AvHAIPlayer* pBot)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the match has been going on for a minute and we haven't made any progress in relocation then give up, or we risk losing everything
|
// If the match has been going on for a minute and we haven't made any progress in relocation then give up, or we risk losing everything
|
||||||
if (AIMGR_GetMatchLength() > 60.0f)
|
if (AIMGR_GetMatchLength() > 90.0f)
|
||||||
{
|
{
|
||||||
return AITAC_GetNumPlayersOfTeamInArea(Team, pBot->RelocationSpot, UTIL_MetresToGoldSrcUnits(10.0f), false, nullptr, AVH_USER3_COMMANDER_PLAYER) > 0;
|
return AITAC_GetNumPlayersOfTeamInArea(Team, pBot->RelocationSpot, UTIL_MetresToGoldSrcUnits(10.0f), false, nullptr, AVH_USER3_COMMANDER_PLAYER) > 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return AITAC_IsRelocationEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AICOMM_CheckForNextRelocationAction(AvHAIPlayer* pBot)
|
bool AICOMM_CheckForNextRelocationAction(AvHAIPlayer* pBot)
|
||||||
|
@ -3877,7 +3880,12 @@ bool AICOMM_CheckForNextRelocationAction(AvHAIPlayer* pBot)
|
||||||
|
|
||||||
if (!RelocationCommChair.IsValid())
|
if (!RelocationCommChair.IsValid())
|
||||||
{
|
{
|
||||||
Vector BuildPoint = UTIL_GetRandomPointOnNavmeshInRadius(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), RelocationPoint, UTIL_MetresToGoldSrcUnits(2.0f));
|
Vector BuildPoint = AITAC_GetRandomBuildHintInLocation(STRUCTURE_MARINE_COMMCHAIR, pBot->RelocationSpot, UTIL_MetresToGoldSrcUnits(10.0f));
|
||||||
|
|
||||||
|
if (vIsZero(BuildPoint))
|
||||||
|
{
|
||||||
|
BuildPoint = UTIL_GetRandomPointOnNavmeshInRadius(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), RelocationPoint, UTIL_MetresToGoldSrcUnits(2.0f));
|
||||||
|
}
|
||||||
|
|
||||||
if (vIsZero(BuildPoint))
|
if (vIsZero(BuildPoint))
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,7 +12,7 @@ BotFillTiming CurrentBotFillTiming = FILLTIMING_ALLHUMANS;
|
||||||
|
|
||||||
float MaxAIMatchTimeMinutes = 90.0f;
|
float MaxAIMatchTimeMinutes = 90.0f;
|
||||||
|
|
||||||
bool bRelocationAllowed = false;
|
float RelocationChance = 0.1f;
|
||||||
|
|
||||||
std::unordered_map<std::string, TeamSizeDefinitions> TeamSizeMap;
|
std::unordered_map<std::string, TeamSizeDefinitions> TeamSizeMap;
|
||||||
|
|
||||||
|
@ -94,7 +94,12 @@ bool CONFIG_IsOnosAllowed()
|
||||||
|
|
||||||
bool CONFIG_IsRelocationAllowed()
|
bool CONFIG_IsRelocationAllowed()
|
||||||
{
|
{
|
||||||
return bRelocationAllowed;
|
return RelocationChance > 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float CONFIG_GetRelocationChance()
|
||||||
|
{
|
||||||
|
return RelocationChance;
|
||||||
}
|
}
|
||||||
|
|
||||||
float CONFIG_GetMaxStuckTime()
|
float CONFIG_GetMaxStuckTime()
|
||||||
|
@ -335,10 +340,10 @@ void CONFIG_ParseConfigFile()
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!stricmp(keyChar, "AllowRelocation"))
|
if (!stricmp(keyChar, "RelocationChance"))
|
||||||
{
|
{
|
||||||
const char* ValueChar = value.c_str();
|
float RelocationValue = std::stof(value.c_str());
|
||||||
bRelocationAllowed = (!stricmp(ValueChar, "True") || !stricmp(ValueChar, "T"));
|
RelocationChance = RelocationValue;
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -656,7 +661,11 @@ void CONFIG_RegenerateIniFile()
|
||||||
fprintf(NewConfigFile, "# 0 = On map load (after 5 second grace period)\n");
|
fprintf(NewConfigFile, "# 0 = On map load (after 5 second grace period)\n");
|
||||||
fprintf(NewConfigFile, "# 1 = When all humans have joined a team (i.e. no more humans left in ready room)\n");
|
fprintf(NewConfigFile, "# 1 = When all humans have joined a team (i.e. no more humans left in ready room)\n");
|
||||||
fprintf(NewConfigFile, "# 2 = When the round has started (after countdown)\n");
|
fprintf(NewConfigFile, "# 2 = When the round has started (after countdown)\n");
|
||||||
fprintf(NewConfigFile, "BotFillTiming=1\n\n\n");
|
fprintf(NewConfigFile, "BotFillTiming=1\n\n");
|
||||||
|
|
||||||
|
fprintf(NewConfigFile, "# Chance the AI Commander will try to relocate at the beginning of the game\n");
|
||||||
|
fprintf(NewConfigFile, "# Value is a decimal between 0.0 and 1.0, with 0 being never and 1 being always\n");
|
||||||
|
fprintf(NewConfigFile, "RelocationChance=0.1\n\n\n");
|
||||||
|
|
||||||
|
|
||||||
fprintf(NewConfigFile, "### Skill Settings ###\n\n");
|
fprintf(NewConfigFile, "### Skill Settings ###\n\n");
|
||||||
|
|
|
@ -44,6 +44,7 @@ bool CONFIG_IsFadeAllowed();
|
||||||
bool CONFIG_IsOnosAllowed();
|
bool CONFIG_IsOnosAllowed();
|
||||||
|
|
||||||
bool CONFIG_IsRelocationAllowed();
|
bool CONFIG_IsRelocationAllowed();
|
||||||
|
float CONFIG_GetRelocationChance();
|
||||||
|
|
||||||
// Returns the max time a bot is allowed to be stuck before suiciding (0 means forever)
|
// Returns the max time a bot is allowed to be stuck before suiciding (0 means forever)
|
||||||
float CONFIG_GetMaxStuckTime();
|
float CONFIG_GetMaxStuckTime();
|
||||||
|
|
|
@ -930,6 +930,8 @@ void AIMGR_ResetRound()
|
||||||
bMapDataInitialised = true;
|
bMapDataInitialised = true;
|
||||||
|
|
||||||
CountdownStartedTime = 0.0f;
|
CountdownStartedTime = 0.0f;
|
||||||
|
|
||||||
|
AITAC_DetermineRelocationEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AIMGR_ReloadNavigationData()
|
void AIMGR_ReloadNavigationData()
|
||||||
|
|
|
@ -73,6 +73,7 @@ bool IsPlayerClimbingWall(const edict_t* Player)
|
||||||
|
|
||||||
bool IsPlayerInReadyRoom(const edict_t* Player)
|
bool IsPlayerInReadyRoom(const edict_t* Player)
|
||||||
{
|
{
|
||||||
|
if (FNullEnt(Player)) { return false; }
|
||||||
return Player->v.playerclass == PLAYMODE_READYROOM;
|
return Player->v.playerclass == PLAYMODE_READYROOM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,8 @@ Vector TeamBStartingLocation = ZERO_VECTOR;
|
||||||
Vector TeamARelocationPoint = ZERO_VECTOR;
|
Vector TeamARelocationPoint = ZERO_VECTOR;
|
||||||
Vector TeamBRelocationPoint = ZERO_VECTOR;
|
Vector TeamBRelocationPoint = ZERO_VECTOR;
|
||||||
|
|
||||||
|
bool bEnableRelocation = false; // For this round, should the AI commander try relocating (if appropriate)?
|
||||||
|
|
||||||
extern nav_mesh NavMeshes[MAX_NAV_MESHES]; // Array of nav meshes. Currently only 3 are used (building, onos, and regular)
|
extern nav_mesh NavMeshes[MAX_NAV_MESHES]; // Array of nav meshes. Currently only 3 are used (building, onos, and regular)
|
||||||
extern nav_profile BaseNavProfiles[MAX_NAV_PROFILES]; // Array of nav profiles
|
extern nav_profile BaseNavProfiles[MAX_NAV_PROFILES]; // Array of nav profiles
|
||||||
|
|
||||||
|
@ -5559,7 +5561,7 @@ void AITAC_ManageSquads()
|
||||||
for (auto pIt = it->SquadMembers.begin(); pIt != it->SquadMembers.end();)
|
for (auto pIt = it->SquadMembers.begin(); pIt != it->SquadMembers.end();)
|
||||||
{
|
{
|
||||||
AvHAIPlayer* ThisPlayer = (*pIt);
|
AvHAIPlayer* ThisPlayer = (*pIt);
|
||||||
if (!AITAC_IsBotPursuingSquadObjective(ThisPlayer, &(*it)))
|
if (!ThisPlayer || FNullEnt(ThisPlayer->Edict) || !AITAC_IsBotPursuingSquadObjective(ThisPlayer, &(*it)))
|
||||||
{
|
{
|
||||||
pIt = it->SquadMembers.erase(pIt);
|
pIt = it->SquadMembers.erase(pIt);
|
||||||
}
|
}
|
||||||
|
@ -5780,8 +5782,6 @@ Vector AITAC_GetGatherLocationForSquad(AvHAISquad* Squad)
|
||||||
|
|
||||||
Vector AITAC_FindNewTeamRelocationPoint(AvHTeamNumber Team)
|
Vector AITAC_FindNewTeamRelocationPoint(AvHTeamNumber Team)
|
||||||
{
|
{
|
||||||
if (!CONFIG_IsRelocationAllowed()) { return ZERO_VECTOR; }
|
|
||||||
|
|
||||||
AvHTeamNumber EnemyTeam = AIMGR_GetEnemyTeam(Team);
|
AvHTeamNumber EnemyTeam = AIMGR_GetEnemyTeam(Team);
|
||||||
|
|
||||||
// Only relocate if:
|
// Only relocate if:
|
||||||
|
@ -5929,4 +5929,21 @@ bool AITAC_IsRelocationCompleted(AvHTeamNumber RelocationTeam, Vector Relocation
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AITAC_IsRelocationEnabled()
|
||||||
|
{
|
||||||
|
return bEnableRelocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AITAC_DetermineRelocationEnabled()
|
||||||
|
{
|
||||||
|
bEnableRelocation = false;
|
||||||
|
|
||||||
|
if (CONFIG_IsRelocationAllowed())
|
||||||
|
{
|
||||||
|
float RandomRoll = frandrange(0.0f, 1.0f);
|
||||||
|
|
||||||
|
bEnableRelocation = (RandomRoll <= CONFIG_GetRelocationChance());
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -216,4 +216,8 @@ Vector AITAC_FindNewTeamRelocationPoint(AvHTeamNumber Team);
|
||||||
bool AITAC_IsRelocationPointStillValid(AvHTeamNumber RelocationTeam, Vector RelocationPoint);
|
bool AITAC_IsRelocationPointStillValid(AvHTeamNumber RelocationTeam, Vector RelocationPoint);
|
||||||
bool AITAC_IsRelocationCompleted(AvHTeamNumber RelocationTeam, Vector RelocationPoint);
|
bool AITAC_IsRelocationCompleted(AvHTeamNumber RelocationTeam, Vector RelocationPoint);
|
||||||
|
|
||||||
|
bool AITAC_IsRelocationEnabled();
|
||||||
|
|
||||||
|
void AITAC_DetermineRelocationEnabled();
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -987,6 +987,8 @@ bool AITASK_IsMarineSecureHiveTaskStillValid(AvHAIPlayer* pBot, AvHAIPlayerTask*
|
||||||
|
|
||||||
if (!HiveToSecure || HiveToSecure->Status != HIVE_STATUS_UNBUILT) { return false; }
|
if (!HiveToSecure || HiveToSecure->Status != HIVE_STATUS_UNBUILT) { return false; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// A marine bot will consider their "secure hive" task completed if the following structures have been fully built:
|
// A marine bot will consider their "secure hive" task completed if the following structures have been fully built:
|
||||||
// Phase gate (only if tech available)
|
// Phase gate (only if tech available)
|
||||||
// Turret factory (regular or advanced)
|
// Turret factory (regular or advanced)
|
||||||
|
@ -995,6 +997,12 @@ bool AITASK_IsMarineSecureHiveTaskStillValid(AvHAIPlayer* pBot, AvHAIPlayerTask*
|
||||||
|
|
||||||
AvHTeamNumber BotTeam = pBot->Player->GetTeam();
|
AvHTeamNumber BotTeam = pBot->Player->GetTeam();
|
||||||
|
|
||||||
|
// We've relocated to this hive, no need to secure now
|
||||||
|
if (vDist2DSq(AITAC_GetTeamStartingLocation(BotTeam), HiveToSecure->FloorLocation) < sqrf(UTIL_MetresToGoldSrcUnits(10.0f)))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool bPhaseGatesAvailable = AITAC_PhaseGatesAvailable(BotTeam);
|
bool bPhaseGatesAvailable = AITAC_PhaseGatesAvailable(BotTeam);
|
||||||
|
|
||||||
bool bHasPhaseGate = false;
|
bool bHasPhaseGate = false;
|
||||||
|
|
Loading…
Reference in a new issue