Added more commander requests

Armouries, Heavy armour and jetpacks can be requested
This commit is contained in:
RGreenlees 2024-04-02 12:14:10 +01:00 committed by pierow
parent 44a1072fb3
commit 349cf7240f
4 changed files with 216 additions and 10 deletions

View file

@ -940,6 +940,12 @@ bool AICOMM_IsRequestValid(ai_commander_request* Request)
case BUILD_HMG: case BUILD_HMG:
return !PlayerHasWeapon(PlayerRef, WEAPON_MARINE_HMG) return !PlayerHasWeapon(PlayerRef, WEAPON_MARINE_HMG)
&& !AITAC_ItemExistsInLocation(Requestor->v.origin, DEPLOYABLE_ITEM_HMG, RequestorTeam, AI_REACHABILITY_MARINE, 0.0f, UTIL_MetresToGoldSrcUnits(5.0f), false); && !AITAC_ItemExistsInLocation(Requestor->v.origin, DEPLOYABLE_ITEM_HMG, RequestorTeam, AI_REACHABILITY_MARINE, 0.0f, UTIL_MetresToGoldSrcUnits(5.0f), false);
case BUILD_HEAVY:
return !PlayerHasEquipment(Requestor)
&& !AITAC_ItemExistsInLocation(Requestor->v.origin, DEPLOYABLE_ITEM_HEAVYARMOUR, RequestorTeam, AI_REACHABILITY_MARINE, 0.0f, UTIL_MetresToGoldSrcUnits(5.0f), false);
case BUILD_JETPACK:
return !PlayerHasEquipment(Requestor)
&& !AITAC_ItemExistsInLocation(Requestor->v.origin, DEPLOYABLE_ITEM_JETPACK, RequestorTeam, AI_REACHABILITY_MARINE, 0.0f, UTIL_MetresToGoldSrcUnits(5.0f), false);
case BUILD_GRENADE_GUN: case BUILD_GRENADE_GUN:
return !PlayerHasWeapon(PlayerRef, WEAPON_MARINE_GL) return !PlayerHasWeapon(PlayerRef, WEAPON_MARINE_GL)
&& !AITAC_ItemExistsInLocation(Requestor->v.origin, DEPLOYABLE_ITEM_GRENADELAUNCHER, RequestorTeam, AI_REACHABILITY_MARINE, 0.0f, UTIL_MetresToGoldSrcUnits(5.0f), false); && !AITAC_ItemExistsInLocation(Requestor->v.origin, DEPLOYABLE_ITEM_GRENADELAUNCHER, RequestorTeam, AI_REACHABILITY_MARINE, 0.0f, UTIL_MetresToGoldSrcUnits(5.0f), false);
@ -2669,6 +2675,89 @@ bool AICOMM_CheckForNextSupportAction(AvHAIPlayer* pBot)
} }
if (NextRequest->RequestType == BUILD_HEAVY || NextRequest->RequestType == BUILD_JETPACK)
{
AvHAIDeployableItemType ItemToDrop = (NextRequest->RequestType == BUILD_HEAVY) ? DEPLOYABLE_ITEM_HEAVYARMOUR : DEPLOYABLE_ITEM_JETPACK;
float Cost = (NextRequest->RequestType == BUILD_HEAVY) ? BALANCE_VAR(kHeavyArmorCost) : BALANCE_VAR(kJetpackCost);
AvHTechID TechNeeded = (NextRequest->RequestType == BUILD_HEAVY) ? TECH_RESEARCH_HEAVYARMOR : TECH_RESEARCH_JETPACKS;
if (!AITAC_ResearchIsComplete(CommanderTeam, TechNeeded))
{
char msg[128];
sprintf(msg, "We haven't researched it yet, %s. Ask again later.", STRING(Requestor->v.netname));
BotSay(pBot, true, 0.5f, msg);
NextRequest->bResponded = true;
return false;
}
DeployableSearchFilter PrototypeLabFilter;
PrototypeLabFilter.DeployableTeam = CommanderTeam;
PrototypeLabFilter.DeployableTypes = STRUCTURE_MARINE_PROTOTYPELAB;
PrototypeLabFilter.IncludeStatusFlags = STRUCTURE_STATUS_COMPLETED;
PrototypeLabFilter.ExcludeStatusFlags = STRUCTURE_STATUS_RECYCLING;
AvHAIBuildableStructure NearestPL = AITAC_FindClosestDeployableToLocation(Requestor->v.origin, &PrototypeLabFilter);
if (!NearestPL.IsValid())
{
char msg[128];
sprintf(msg, "We don't have a prototype lab %s, ask again later.", STRING(Requestor->v.netname));
BotSay(pBot, true, 0.5f, msg);
NextRequest->bResponded = true;
return false;
}
if (vDist2DSq(Requestor->v.origin, NearestPL.Location) > sqrf(BALANCE_VAR(kArmoryBuildDistance)))
{
if (!NextRequest->bAcknowledged)
{
char msg[128];
sprintf(msg, "Get near the prototype lab %s, and I will drop it for you.", STRING(Requestor->v.netname));
BotSay(pBot, true, 0.5f, msg);
NextRequest->bAcknowledged = true;
}
return false;
}
Vector IdealDeployLocation = Requestor->v.origin + (UTIL_GetForwardVector2D(Requestor->v.angles) * 75.0f);
Vector ProjectedDeployLocation = AdjustPointForPathfinding(IdealDeployLocation);
if (vDist2DSq(ProjectedDeployLocation, NearestPL.Location) < BALANCE_VAR(kArmoryBuildDistance))
{
bool bSuccess = AICOMM_DeployItem(pBot, ItemToDrop, ProjectedDeployLocation);
if (bSuccess)
{
NextRequest->bResponded = bSuccess;
return true;
}
}
Vector DeployLocation = UTIL_GetRandomPointOnNavmeshInRadius(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), NearestPL.Location, UTIL_MetresToGoldSrcUnits(4.0f));
if (vIsZero(DeployLocation))
{
DeployLocation = UTIL_GetRandomPointOnNavmeshInRadius(GetBaseNavProfile(MARINE_BASE_NAV_PROFILE), NearestPL.Location, UTIL_MetresToGoldSrcUnits(4.0f));
}
if (vIsZero(DeployLocation))
{
char msg[128];
sprintf(msg, "I can't find a drop location, %s. Try asking again elsewhere.", STRING(Requestor->v.netname));
BotSay(pBot, true, 0.5f, msg);
NextRequest->bResponded = true;
return false;
}
bool bSuccess = AICOMM_DeployItem(pBot, ItemToDrop, DeployLocation);
NextRequest->ResponseAttempts++;
NextRequest->bResponded = bSuccess;
return true;
}
if (NextRequest->RequestType == BUILD_HMG || NextRequest->RequestType == BUILD_GRENADE_GUN) if (NextRequest->RequestType == BUILD_HMG || NextRequest->RequestType == BUILD_GRENADE_GUN)
{ {
AvHAIDeployableItemType ItemToDrop = (NextRequest->RequestType == BUILD_HMG) ? DEPLOYABLE_ITEM_HMG : DEPLOYABLE_ITEM_GRENADELAUNCHER; AvHAIDeployableItemType ItemToDrop = (NextRequest->RequestType == BUILD_HMG) ? DEPLOYABLE_ITEM_HMG : DEPLOYABLE_ITEM_GRENADELAUNCHER;
@ -2838,6 +2927,81 @@ bool AICOMM_CheckForNextSupportAction(AvHAIPlayer* pBot)
} }
if (NextRequest->RequestType == BUILD_ARMORY)
{
if (pBot->Player->GetResources() < BALANCE_VAR(kArmoryCost))
{
if (!NextRequest->bAcknowledged)
{
char msg[128];
sprintf(msg, "Just waiting on resources, %s. Will drop asap.", STRING(Requestor->v.netname));
BotSay(pBot, true, 0.5f, msg);
NextRequest->bAcknowledged = true;
return false;
}
return false;
}
Vector IdealDeployLocation = Requestor->v.origin + (UTIL_GetForwardVector2D(Requestor->v.angles) * 75.0f);
Vector ProjectedDeployLocation = AdjustPointForPathfinding(IdealDeployLocation, GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE));
if (!vIsZero(ProjectedDeployLocation))
{
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_ARMOURY, ProjectedDeployLocation, STRUCTURE_PURPOSE_NONE);
if (bSuccess)
{
NextRequest->bResponded = true;
return true;
}
}
Vector DeployLocation = UTIL_GetRandomPointOnNavmeshInRadius(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), Requestor->v.origin, UTIL_MetresToGoldSrcUnits(5.0f));
if (!vIsZero(DeployLocation))
{
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_ARMOURY, DeployLocation, STRUCTURE_PURPOSE_NONE);
if (bSuccess)
{
NextRequest->bResponded = true;
return true;
}
}
DeployLocation = UTIL_GetRandomPointOnNavmeshInRadiusIgnoreReachability(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), Requestor->v.origin, UTIL_MetresToGoldSrcUnits(5.0f));
if (!vIsZero(DeployLocation))
{
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_ARMOURY, DeployLocation, STRUCTURE_PURPOSE_NONE);
if (bSuccess)
{
NextRequest->bResponded = true;
return true;
}
else
{
char msg[128];
sprintf(msg, "I can't find a good deploy spot, %s. Try again elsewhere.", STRING(Requestor->v.netname));
BotSay(pBot, true, 0.5f, msg);
NextRequest->bResponded = true;
return false;
}
}
else
{
char msg[128];
sprintf(msg, "I can't find a good deploy spot, %s. Try again elsewhere.", STRING(Requestor->v.netname));
BotSay(pBot, true, 0.5f, msg);
NextRequest->bResponded = true;
return false;
}
return false;
}
if (NextRequest->RequestType == BUILD_TURRET_FACTORY) if (NextRequest->RequestType == BUILD_TURRET_FACTORY)
{ {
if (pBot->Player->GetResources() < BALANCE_VAR(kTurretFactoryCost)) if (pBot->Player->GetResources() < BALANCE_VAR(kTurretFactoryCost))
@ -3391,6 +3555,14 @@ void AICOMM_ReceiveChatRequest(AvHAIPlayer* Commander, edict_t* Requestor, const
{ {
NewRequestType = BUILD_MINES; NewRequestType = BUILD_MINES;
} }
else if (!stricmp(Request, "ha") || !stricmp(Request, "heavy") || !stricmp(Request, "heavyarmor") || !stricmp(Request, "heavy armor"))
{
NewRequestType = BUILD_HEAVY;
}
else if (!stricmp(Request, "jp") || !stricmp(Request, "jetpack") || !stricmp(Request, "jet pack"))
{
NewRequestType = BUILD_JETPACK;
}
else if (!stricmp(Request, "cat") || !stricmp(Request, "cats") || !stricmp(Request, "catalysts")) else if (!stricmp(Request, "cat") || !stricmp(Request, "cats") || !stricmp(Request, "catalysts"))
{ {
NewRequestType = BUILD_CAT; NewRequestType = BUILD_CAT;
@ -3411,6 +3583,14 @@ void AICOMM_ReceiveChatRequest(AvHAIPlayer* Commander, edict_t* Requestor, const
{ {
NewRequestType = BUILD_ARMORY; NewRequestType = BUILD_ARMORY;
} }
else if (!stricmp(Request, "scan"))
{
NewRequestType = BUILD_SCAN;
}
else if (!stricmp(Request, "cc") || !stricmp(Request, "chair") || !stricmp(Request, "command chair"))
{
NewRequestType = BUILD_COMMANDSTATION;
}
if (NewRequestType == MESSAGE_NULL) { return; } if (NewRequestType == MESSAGE_NULL) { return; }

View file

@ -4012,19 +4012,20 @@ void LiftMove(AvHAIPlayer* pBot, const Vector StartPoint, const Vector EndPoint)
bool bIsOnLift = (pBot->Edict->v.groundentity == NearestLift->DoorEdict); bool bIsOnLift = (pBot->Edict->v.groundentity == NearestLift->DoorEdict);
bool bWaitingToEmbark = (!bIsOnLift && vDist3DSq(pBot->Edict->v.origin, StartPoint) < vDist3DSq(pBot->Edict->v.origin, EndPoint)) || (bIsOnLift && !bIsLiftMoving && bIsLiftAtOrNearStart); bool bWaitingToEmbark = (!bIsOnLift && vDist3DSq(pBot->Edict->v.origin, StartPoint) < vDist3DSq(pBot->Edict->v.origin, EndPoint)) || (bIsOnLift && !bIsLiftMoving && bIsLiftAtOrNearStart);
// Do nothing if we're on a moving lift // Do nothing if we're on a moving lift
if (bIsLiftMoving && bIsOnLift) if (bIsLiftMoving && bIsOnLift)
{ {
Vector LiftEdge = UTIL_GetClosestPointOnEntityToLocation(StartPoint, NearestLift->DoorEdict); Vector LiftEdge = UTIL_GetClosestPointOnEntityToLocation(StartPoint, NearestLift->DoorEdict);
bool bFullyOnLift = vDist2DSq(pBot->Edict->v.origin, LiftEdge) > (sqrf(GetPlayerRadius(pBot->Player) * 1.1f)); bool bFullyOnLift = vDist2DSq(pBot->Edict->v.origin, LiftEdge) > sqrf(GetPlayerRadius(pBot->Player) * 2.0f);
if (!bFullyOnLift) if (!bFullyOnLift)
{ {
pBot->desiredMovementDir = UTIL_GetVectorNormal2D(LiftPosition - pBot->Edict->v.origin); pBot->desiredMovementDir = UTIL_GetVectorNormal2D(LiftPosition - pBot->Edict->v.origin);
} }
if (!UTIL_QuickTrace(pBot->Edict, pBot->CollisionHullTopLocation, pBot->CollisionHullTopLocation + Vector(0.0f, 0.0f, 64.0f))) if (!UTIL_QuickHullTrace(pBot->Edict, pBot->Edict->v.origin, pBot->CollisionHullTopLocation + Vector(0.0f, 0.0f, 64.0f)))
{ {
pBot->desiredMovementDir = UTIL_GetVectorNormal2D(LiftPosition - pBot->Edict->v.origin); pBot->desiredMovementDir = UTIL_GetVectorNormal2D(LiftPosition - pBot->Edict->v.origin);
} }
@ -5460,6 +5461,8 @@ bool AbortCurrentMove(AvHAIPlayer* pBot, const Vector NewDestination)
{ {
if (pBot->BotNavInfo.CurrentPath.size() == 0 || pBot->BotNavInfo.CurrentPathPoint >= pBot->BotNavInfo.CurrentPath.size() || pBot->BotNavInfo.NavProfile.bFlyingProfile) { return true; } if (pBot->BotNavInfo.CurrentPath.size() == 0 || pBot->BotNavInfo.CurrentPathPoint >= pBot->BotNavInfo.CurrentPath.size() || pBot->BotNavInfo.NavProfile.bFlyingProfile) { return true; }
if (IsBotOffPath(pBot) || HasBotReachedPathPoint(pBot)) { return true; }
bot_path_node CurrentPathNode = pBot->BotNavInfo.CurrentPath[pBot->BotNavInfo.CurrentPathPoint]; bot_path_node CurrentPathNode = pBot->BotNavInfo.CurrentPath[pBot->BotNavInfo.CurrentPathPoint];
Vector MoveFrom = CurrentPathNode.FromLocation; Vector MoveFrom = CurrentPathNode.FromLocation;
@ -5927,6 +5930,13 @@ void OnosUpdateBotMoveProfile(AvHAIPlayer* pBot, BotMoveStyle MoveStyle)
bool MoveTo(AvHAIPlayer* pBot, const Vector Destination, const BotMoveStyle MoveStyle, const float MaxAcceptableDist) bool MoveTo(AvHAIPlayer* pBot, const Vector Destination, const BotMoveStyle MoveStyle, const float MaxAcceptableDist)
{ {
#ifdef DEBUG
if (pBot == AIMGR_GetDebugAIPlayer())
{
bool bBreak = true; // Add a break point here if you want to debug a specific bot
}
#endif
if (vIsZero(Destination) || (vDist2D(pBot->Edict->v.origin, Destination) <= 6.0f && (fabs(pBot->CollisionHullBottomLocation.z - Destination.z) < 50.0f))) if (vIsZero(Destination) || (vDist2D(pBot->Edict->v.origin, Destination) <= 6.0f && (fabs(pBot->CollisionHullBottomLocation.z - Destination.z) < 50.0f)))
{ {
pBot->BotNavInfo.StuckInfo.bPathFollowFailed = false; pBot->BotNavInfo.StuckInfo.bPathFollowFailed = false;
@ -8710,7 +8720,8 @@ bool NAV_IsMovementTaskStillValid(AvHAIPlayer* pBot)
if (MoveTask->TaskType == MOVE_TASK_MOVE) if (MoveTask->TaskType == MOVE_TASK_MOVE)
{ {
return (vDist2DSq(pBot->Edict->v.origin, MoveTask->TaskLocation) > sqrf(GetPlayerRadius(pBot->Player)) || fabsf(pBot->Edict->v.origin.z - MoveTask->TaskLocation.z) > 50.0f); return (vDist2DSq(pBot->Edict->v.origin, MoveTask->TaskLocation) > sqrf(GetPlayerRadius(pBot->Player)) || fabsf(pBot->Edict->v.origin.z - MoveTask->TaskLocation.z) > 50.0f)
&& UTIL_PointIsReachable(pBot->BotNavInfo.NavProfile, pBot->CurrentFloorPosition, MoveTask->TaskLocation, GetPlayerRadius(pBot->Edict));
} }
if (MoveTask->TaskType == MOVE_TASK_USE) if (MoveTask->TaskType == MOVE_TASK_USE)

View file

@ -492,6 +492,8 @@ void AIMGR_AddAIPlayerToTeam(int Team)
BotEnt->v.pitch_speed = 270; // slightly faster than HLDM of 225 BotEnt->v.pitch_speed = 270; // slightly faster than HLDM of 225
BotEnt->v.yaw_speed = 250; // slightly faster than HLDM of 210 BotEnt->v.yaw_speed = 250; // slightly faster than HLDM of 210
BotEnt->v.modelindex = 0;
AvHPlayer* theNewAIPlayer = GetClassPtr((AvHPlayer*)&BotEnt->v); AvHPlayer* theNewAIPlayer = GetClassPtr((AvHPlayer*)&BotEnt->v);
if (theNewAIPlayer) if (theNewAIPlayer)
@ -631,7 +633,7 @@ void AIMGR_UpdateAIPlayers()
int NumBotsThinkThisFrame = 0; int NumBotsThinkThisFrame = 0;
int BotsPerFrame = max(1.0f, round(BOT_THINK_RATE_HZ * NumRegularBots * FrameDelta)); int BotsPerFrame = max(1, (int)round(BOT_THINK_RATE_HZ * NumRegularBots * FrameDelta));
int BotIndex = 0; int BotIndex = 0;

View file

@ -1772,16 +1772,29 @@ void BotProgressDefendTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
AvHAIBuildableStructure StructureRef = AITAC_GetDeployableFromEdict(Task->TaskTarget); AvHAIBuildableStructure StructureRef = AITAC_GetDeployableFromEdict(Task->TaskTarget);
if (!StructureRef.IsValid()) { return; } if (StructureRef.IsValid())
// If the structure we're defending was damaged just now, look at it so we can see who is attacking
if (gpGlobals->time - StructureRef.lastDamagedTime < 5.0f)
{ {
if (UTIL_QuickTrace(pBot->Edict, pBot->CurrentEyePosition, UTIL_GetCentreOfEntity(Task->TaskTarget))) // If the structure we're defending was damaged just now, look at it so we can see who is attacking
if (gpGlobals->time - StructureRef.lastDamagedTime < 5.0f)
{ {
BotLookAt(pBot, Task->TaskTarget); if (UTIL_QuickTrace(pBot->Edict, pBot->CurrentEyePosition, UTIL_GetCentreOfEntity(Task->TaskTarget)))
{
BotLookAt(pBot, Task->TaskTarget);
}
} }
} }
else
{
AvHAIHiveDefinition* Hive = AITAC_GetHiveFromEdict(Task->TaskTarget);
if (Hive && Hive->bIsUnderAttack)
{
if (UTIL_QuickTrace(pBot->Edict, pBot->CurrentEyePosition, Hive->Location))
{
BotLookAt(pBot, Task->TaskTarget);
}
}
}
} }
BotProgressGuardTask(pBot, Task); BotProgressGuardTask(pBot, Task);