mirror of
https://github.com/ENSL/NS.git
synced 2024-11-21 12:11:04 +00:00
Ladder fix + relocation fixes
* Improved ladder climbing, especially for skulks * Fixed issues with bots getting confused when switching commanders during a relocation
This commit is contained in:
parent
9a4a6b3660
commit
36318cd1d4
8 changed files with 359 additions and 108 deletions
|
@ -3239,7 +3239,7 @@ bool AICOMM_CheckForNextSupportAction(AvHAIPlayer* pBot)
|
|||
}
|
||||
}
|
||||
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, StructureToDeploy, ProjectedDeployLocation, STRUCTURE_PURPOSE_NONE);
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, StructureToDeploy, ProjectedDeployLocation, STRUCTURE_PURPOSE_GENERAL);
|
||||
|
||||
if (bSuccess)
|
||||
{
|
||||
|
@ -3252,7 +3252,7 @@ bool AICOMM_CheckForNextSupportAction(AvHAIPlayer* pBot)
|
|||
|
||||
if (!vIsZero(DeployLocation))
|
||||
{
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, StructureToDeploy, DeployLocation, STRUCTURE_PURPOSE_NONE);
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, StructureToDeploy, DeployLocation, STRUCTURE_PURPOSE_GENERAL);
|
||||
|
||||
if (bSuccess)
|
||||
{
|
||||
|
@ -3265,7 +3265,7 @@ bool AICOMM_CheckForNextSupportAction(AvHAIPlayer* pBot)
|
|||
|
||||
if (!vIsZero(DeployLocation))
|
||||
{
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, StructureToDeploy, DeployLocation, STRUCTURE_PURPOSE_NONE);
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, StructureToDeploy, DeployLocation, STRUCTURE_PURPOSE_GENERAL);
|
||||
|
||||
if (bSuccess)
|
||||
{
|
||||
|
@ -3399,6 +3399,13 @@ void AICOMM_CommanderThink(AvHAIPlayer* pBot)
|
|||
|
||||
if (!vIsZero(pBot->RelocationSpot))
|
||||
{
|
||||
vector<AvHAIPlayer*> AllMarineBots = AIMGR_GetAIPlayersOnTeam(pBot->Player->GetTeam());
|
||||
|
||||
for (auto it = AllMarineBots.begin(); it != AllMarineBots.end(); it++)
|
||||
{
|
||||
(*it)->RelocationSpot = pBot->RelocationSpot;
|
||||
}
|
||||
|
||||
const AvHAIHiveDefinition* RelocationHive = AITAC_GetHiveNearestLocation(pBot->RelocationSpot);
|
||||
|
||||
if (RelocationHive)
|
||||
|
@ -4026,19 +4033,29 @@ bool AICOMM_CheckForNextRelocationAction(AvHAIPlayer* pBot)
|
|||
{
|
||||
Vector BuildPoint = AITAC_GetRandomBuildHintInLocation(STRUCTURE_MARINE_COMMCHAIR, pBot->RelocationSpot, UTIL_MetresToGoldSrcUnits(10.0f));
|
||||
|
||||
if (vIsZero(BuildPoint))
|
||||
if (!vIsZero(BuildPoint))
|
||||
{
|
||||
BuildPoint = UTIL_GetRandomPointOnNavmeshInRadius(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), RelocationPoint, UTIL_MetresToGoldSrcUnits(2.0f));
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_COMMCHAIR, BuildPoint, STRUCTURE_PURPOSE_BASE);
|
||||
|
||||
if (bSuccess) { return true; }
|
||||
}
|
||||
|
||||
if (vIsZero(BuildPoint))
|
||||
{
|
||||
BuildPoint = UTIL_ProjectPointToNavmesh(RelocationPoint, Vector(500.0f, 500.0f, 500.0f), GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE));
|
||||
}
|
||||
BuildPoint = UTIL_GetRandomPointOnNavmeshInRadius(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), pBot->RelocationSpot, UTIL_MetresToGoldSrcUnits(2.0f));
|
||||
|
||||
if (!vIsZero(BuildPoint))
|
||||
{
|
||||
return AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_COMMCHAIR, BuildPoint, STRUCTURE_PURPOSE_BASE);
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_COMMCHAIR, BuildPoint, STRUCTURE_PURPOSE_BASE);
|
||||
|
||||
if (bSuccess) { return true; }
|
||||
}
|
||||
|
||||
BuildPoint = UTIL_GetRandomPointOnNavmeshInRadius(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), pBot->RelocationSpot, UTIL_MetresToGoldSrcUnits(10.0f));
|
||||
|
||||
if (!vIsZero(BuildPoint))
|
||||
{
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_COMMCHAIR, BuildPoint, STRUCTURE_PURPOSE_BASE);
|
||||
|
||||
if (bSuccess) { return true; }
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
@ -3848,7 +3848,34 @@ void JumpMove(AvHAIPlayer* pBot, const Vector StartPoint, const Vector EndPoint)
|
|||
}
|
||||
}
|
||||
|
||||
void LadderMove(AvHAIPlayer* pBot, const Vector StartPoint, const Vector EndPoint, float RequiredClimbHeight, unsigned char NextArea)
|
||||
void MountLadderMove(AvHAIPlayer* pBot, edict_t* LadderToMount)
|
||||
{
|
||||
Vector LadderNormal = UTIL_GetLadderNormal(pBot->Edict->v.origin, LadderToMount);
|
||||
LadderNormal = UTIL_GetVectorNormal2D(LadderNormal);
|
||||
|
||||
Vector NearestPointOnLadder = UTIL_GetClosestPointOnEntityToLocation(pBot->Edict->v.origin, LadderToMount);
|
||||
|
||||
Vector OrientationToLadder = UTIL_GetVectorNormal2D(pBot->Edict->v.origin - NearestPointOnLadder);
|
||||
|
||||
if (UTIL_GetDotProduct2D(LadderNormal, OrientationToLadder) < 0.8f)
|
||||
{
|
||||
Vector MovePoint = NearestPointOnLadder + (LadderNormal * 32.0f);
|
||||
pBot->desiredMovementDir = UTIL_GetVectorNormal2D(MovePoint - pBot->Edict->v.origin);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Vector nearestLadderPoint = UTIL_GetCentreOfEntity(LadderToMount);
|
||||
nearestLadderPoint.z = pBot->Edict->v.origin.z;
|
||||
pBot->desiredMovementDir = UTIL_GetVectorNormal2D(NearestPointOnLadder - pBot->Edict->v.origin);
|
||||
}
|
||||
|
||||
Vector LookPoint = NearestPointOnLadder;
|
||||
|
||||
BotLookAt(pBot, LookPoint, true);
|
||||
}
|
||||
|
||||
void SkulkLadderMove(AvHAIPlayer* pBot, const Vector StartPoint, const Vector EndPoint, float RequiredClimbHeight, unsigned char NextArea)
|
||||
{
|
||||
edict_t* pEdict = pBot->Edict;
|
||||
AvHPlayer* AIPlayer = pBot->Player;
|
||||
|
@ -3857,48 +3884,173 @@ void LadderMove(AvHAIPlayer* pBot, const Vector StartPoint, const Vector EndPoin
|
|||
|
||||
bool bIsGoingUpLadder = (EndPoint.z > StartPoint.z);
|
||||
|
||||
// Stop holding crouch if we're a skulk so we can climb up/down
|
||||
if (IsPlayerSkulk(pBot->Edict))
|
||||
edict_t* Ladder = UTIL_GetNearestLadderAtPoint(StartPoint);
|
||||
|
||||
if (!FNullEnt(Ladder))
|
||||
{
|
||||
pBot->Button &= ~IN_DUCK;
|
||||
Vector LadderStart = Ladder->v.absmin;
|
||||
Vector LadderEnd = Ladder->v.absmax;
|
||||
LadderEnd.z = LadderStart.z;
|
||||
|
||||
edict_t* Ladder = UTIL_GetNearestLadderAtPoint(StartPoint);
|
||||
|
||||
if (!FNullEnt(Ladder))
|
||||
// The below test will be false if the ladder is to one side, hence do not try to climb it like a wall
|
||||
if (vIntersects2D(StartPoint, EndPoint, LadderStart, LadderEnd))
|
||||
{
|
||||
Vector LadderStart = Ladder->v.absmin;
|
||||
Vector LadderEnd = Ladder->v.absmax;
|
||||
LadderEnd.z = LadderStart.z;
|
||||
|
||||
// Basically, if we're directly climbing up or down the ladder, treat it like a wall. The below test will be false if the ladder is to one side
|
||||
if (vIntersects2D(StartPoint, EndPoint, LadderStart, LadderEnd))
|
||||
if (bIsGoingUpLadder)
|
||||
{
|
||||
if (bIsGoingUpLadder)
|
||||
{
|
||||
WallClimbMove(pBot, StartPoint, EndPoint, RequiredClimbHeight);
|
||||
}
|
||||
else
|
||||
{
|
||||
FallMove(pBot, StartPoint, EndPoint);
|
||||
}
|
||||
return;
|
||||
WallClimbMove(pBot, StartPoint, EndPoint, RequiredClimbHeight);
|
||||
}
|
||||
else
|
||||
{
|
||||
FallMove(pBot, StartPoint, EndPoint);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Stop holding crouch so we can wall-climb
|
||||
pBot->Button &= ~IN_DUCK;
|
||||
|
||||
if (pBot->Edict->v.origin.z > RequiredClimbHeight)
|
||||
{
|
||||
if (UTIL_QuickHullTrace(pBot->Edict, pBot->Edict->v.origin, EndPoint + Vector(0.0f, 0.0f, 16.0f)))
|
||||
{
|
||||
pBot->desiredMovementDir = vForward;
|
||||
BotLookAt(pBot, EndPoint + Vector(0.0f, 0.0f, 50.0f));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (pBot->Edict->v.origin.z > Ladder->v.absmax.z)
|
||||
{
|
||||
WallClimbMove(pBot, StartPoint, EndPoint, RequiredClimbHeight);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IsPlayerOnLadder(pBot->Edict))
|
||||
{
|
||||
MountLadderMove(pBot, Ladder);
|
||||
return;
|
||||
}
|
||||
|
||||
pBot->Button |= IN_WALK;
|
||||
|
||||
Vector CurrentLadderNormal = UTIL_GetNearestSurfaceNormal(pBot->Edict->v.origin);
|
||||
Vector LadderRightNormal = UTIL_GetVectorNormal(UTIL_GetCrossProduct(CurrentLadderNormal, UP_VECTOR));
|
||||
|
||||
Vector ClimbRightNormal = LadderRightNormal;
|
||||
|
||||
if (bIsGoingUpLadder)
|
||||
{
|
||||
ClimbRightNormal = -LadderRightNormal;
|
||||
}
|
||||
|
||||
if (IsPlayerClimbingWall(pBot->Edict))
|
||||
{
|
||||
Vector StartLeftTrace = pBot->CollisionHullTopLocation - (ClimbRightNormal * GetPlayerRadius(pBot->Player));
|
||||
Vector StartRightTrace = pBot->CollisionHullTopLocation + (ClimbRightNormal * GetPlayerRadius(pBot->Player));
|
||||
|
||||
Vector EndLeftTrace = (bIsGoingUpLadder) ? StartLeftTrace + Vector(0.0f, 0.0f, 32.0f) : StartLeftTrace - Vector(0.0f, 0.0f, 32.0f);
|
||||
Vector EndRightTrace = (bIsGoingUpLadder) ? StartRightTrace + Vector(0.0f, 0.0f, 32.0f) : StartRightTrace - Vector(0.0f, 0.0f, 32.0f);
|
||||
|
||||
bool bBlockedLeft = !UTIL_QuickHullTrace(pEdict, StartLeftTrace, EndLeftTrace, head_hull);
|
||||
bool bBlockedRight = !UTIL_QuickHullTrace(pEdict, StartRightTrace, EndRightTrace, head_hull);
|
||||
|
||||
if (bBlockedLeft && bBlockedRight)
|
||||
{
|
||||
Vector LadderCentre = UTIL_GetCentreOfEntity(Ladder);
|
||||
int Side = vPointOnLine(LadderCentre, LadderCentre + CurrentLadderNormal, pBot->Edict->v.origin);
|
||||
|
||||
if (Side > 0)
|
||||
{
|
||||
pBot->desiredMovementDir = -LadderRightNormal;
|
||||
}
|
||||
else
|
||||
{
|
||||
pBot->desiredMovementDir = LadderRightNormal;
|
||||
}
|
||||
|
||||
Vector LookLocation = pBot->Edict->v.origin - (CurrentLadderNormal * 50.0f);
|
||||
LookLocation.z = RequiredClimbHeight + 100.0f;
|
||||
BotMoveLookAt(pBot, LookLocation, true);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// If we are blocked going up the ladder, face the ladder and slide left/right to avoid blockage
|
||||
if (bBlockedLeft)
|
||||
{
|
||||
Vector LookLocation = pBot->Edict->v.origin - (CurrentLadderNormal * 50.0f);
|
||||
LookLocation.z = RequiredClimbHeight + 100.0f;
|
||||
BotMoveLookAt(pBot, LookLocation, true);
|
||||
|
||||
pBot->desiredMovementDir = ClimbRightNormal;
|
||||
return;
|
||||
}
|
||||
|
||||
if (bBlockedRight)
|
||||
{
|
||||
Vector LookLocation = pBot->Edict->v.origin - (CurrentLadderNormal * 50.0f);
|
||||
LookLocation.z = RequiredClimbHeight + 100.0f;
|
||||
BotMoveLookAt(pBot, LookLocation, true);
|
||||
|
||||
pBot->desiredMovementDir = -ClimbRightNormal;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Vector LookLocation = pBot->Edict->v.origin - (CurrentLadderNormal * 50.0f);
|
||||
LookLocation.z = (bIsGoingUpLadder) ? RequiredClimbHeight + 100.0f : Ladder->v.absmin.z;
|
||||
BotMoveLookAt(pBot, LookLocation, true);
|
||||
|
||||
pBot->desiredMovementDir = -CurrentLadderNormal;
|
||||
|
||||
Vector CurrentVelocity = UTIL_GetVectorNormal2D(pBot->Edict->v.velocity);
|
||||
|
||||
if (UTIL_GetDotProduct2D(pBot->desiredMovementDir, CurrentVelocity) < 0.5f)
|
||||
{
|
||||
float ZVelocity = pBot->Edict->v.velocity.z;
|
||||
float SpeedXY = pBot->Edict->v.velocity.Length2D();
|
||||
|
||||
pBot->Edict->v.velocity = pBot->desiredMovementDir * SpeedXY;
|
||||
pBot->Edict->v.velocity.z = ZVelocity;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void LadderMove(AvHAIPlayer* pBot, const Vector StartPoint, const Vector EndPoint, float RequiredClimbHeight, unsigned char NextArea)
|
||||
{
|
||||
// Basically, if we're a skulk and are directly climbing up or down the ladder, treat it like a basic wall climb
|
||||
if (IsPlayerSkulk(pBot->Edict))
|
||||
{
|
||||
SkulkLadderMove(pBot, StartPoint, EndPoint, RequiredClimbHeight, NextArea);
|
||||
return;
|
||||
}
|
||||
|
||||
edict_t* Ladder = UTIL_GetNearestLadderAtPoint(pBot->Edict->v.origin);
|
||||
|
||||
if (FNullEnt(Ladder)) { return; }
|
||||
|
||||
edict_t* pEdict = pBot->Edict;
|
||||
AvHPlayer* AIPlayer = pBot->Player;
|
||||
|
||||
const Vector vForward = UTIL_GetVectorNormal2D(EndPoint - StartPoint);
|
||||
|
||||
bool bIsGoingUpLadder = (EndPoint.z > StartPoint.z);
|
||||
|
||||
if (IsPlayerOnLadder(pBot->Edict))
|
||||
{
|
||||
// We're on the ladder and actively climbing
|
||||
Vector CurrentLadderNormal;
|
||||
|
||||
if (IsPlayerSkulk(pBot->Edict))
|
||||
if (pBot->Edict->v.origin.z > UTIL_GetNearestLadderTopPoint(pEdict).z)
|
||||
{
|
||||
CurrentLadderNormal = UTIL_GetNearestSurfaceNormal(pBot->Edict->v.origin);
|
||||
CurrentLadderNormal = UTIL_GetNearestLadderNormal(pBot->CollisionHullBottomLocation + Vector(0.0f, 0.0f, 5.0f));
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentLadderNormal = UTIL_GetNearestLadderNormal(pBot->CollisionHullBottomLocation + Vector(0.0f, 0.0f, 5.0f));
|
||||
}
|
||||
CurrentLadderNormal = UTIL_GetNearestLadderNormal(pBot->Edict->v.origin);
|
||||
}
|
||||
|
||||
CurrentLadderNormal = UTIL_GetVectorNormal2D(CurrentLadderNormal);
|
||||
|
||||
|
@ -3948,7 +4100,7 @@ void LadderMove(AvHAIPlayer* pBot, const Vector StartPoint, const Vector EndPoin
|
|||
Vector LookLocation = EndPoint;
|
||||
LookLocation.z = pBot->CurrentEyePosition.z + 64.0f;
|
||||
|
||||
BotMoveLookAt(pBot, LookLocation);
|
||||
BotMoveLookAt(pBot, LookLocation, true);
|
||||
|
||||
// If the get-off point is opposite the ladder, then jump to get to it
|
||||
if (UTIL_GetDotProduct(CurrentLadderNormal, vForward) > 0.75f)
|
||||
|
@ -3956,17 +4108,14 @@ void LadderMove(AvHAIPlayer* pBot, const Vector StartPoint, const Vector EndPoin
|
|||
BotJump(pBot);
|
||||
}
|
||||
|
||||
if (!IsPlayerGorge(pEdict) && !IsPlayerLerk(pEdict) && !IsPlayerSkulk(pEdict))
|
||||
if (!IsPlayerGorge(pEdict) && !IsPlayerLerk(pEdict))
|
||||
{
|
||||
Vector HeadTraceLocation = GetPlayerTopOfCollisionHull(pEdict, false);
|
||||
|
||||
bool bHittingHead = !UTIL_QuickTrace(pBot->Edict, HeadTraceLocation, HeadTraceLocation + Vector(0.0f, 0.0f, 10.0f));
|
||||
bool bClimbIntoVent = (NextArea == SAMPLE_POLYAREA_CROUCH);
|
||||
|
||||
if (!IsPlayerSkulk(pBot->Edict) && (bHittingHead || bClimbIntoVent))
|
||||
{
|
||||
pBot->Button |= IN_DUCK;
|
||||
}
|
||||
pBot->Button |= IN_DUCK;
|
||||
}
|
||||
|
||||
return;
|
||||
|
@ -3978,7 +4127,7 @@ void LadderMove(AvHAIPlayer* pBot, const Vector StartPoint, const Vector EndPoin
|
|||
{
|
||||
pBot->desiredMovementDir = vForward;
|
||||
// We look up really far to get maximum launch
|
||||
BotMoveLookAt(pBot, EndPoint + Vector(0.0f, 0.0f, 100.0f));
|
||||
BotMoveLookAt(pBot, EndPoint + Vector(0.0f, 0.0f, 100.0f), true);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -3987,36 +4136,79 @@ void LadderMove(AvHAIPlayer* pBot, const Vector StartPoint, const Vector EndPoin
|
|||
Vector StartLeftTrace = pBot->CollisionHullTopLocation - (ClimbRightNormal * GetPlayerRadius(pBot->Player));
|
||||
Vector StartRightTrace = pBot->CollisionHullTopLocation + (ClimbRightNormal * GetPlayerRadius(pBot->Player));
|
||||
|
||||
bool bBlockedLeft = !UTIL_QuickTrace(pEdict, StartLeftTrace, StartLeftTrace + Vector(0.0f, 0.0f, 32.0f));
|
||||
bool bBlockedRight = !UTIL_QuickTrace(pEdict, StartRightTrace, StartRightTrace + Vector(0.0f, 0.0f, 32.0f));
|
||||
Vector EndLeftTrace = (bIsGoingUpLadder) ? StartLeftTrace + Vector(0.0f, 0.0f, 32.0f) : StartLeftTrace - Vector(0.0f, 0.0f, 32.0f);
|
||||
Vector EndRightTrace = (bIsGoingUpLadder) ? StartRightTrace + Vector(0.0f, 0.0f, 32.0f) : StartRightTrace - Vector(0.0f, 0.0f, 32.0f);
|
||||
|
||||
// Look up at the top of the ladder
|
||||
bool bBlockedLeft = !UTIL_QuickTrace(pEdict, StartLeftTrace, EndLeftTrace);
|
||||
bool bBlockedRight = !UTIL_QuickTrace(pEdict, StartRightTrace, EndRightTrace);
|
||||
|
||||
if (bBlockedLeft && bBlockedRight)
|
||||
{
|
||||
Vector LadderCentre = UTIL_GetCentreOfEntity(Ladder);
|
||||
int Side = vPointOnLine(LadderCentre, LadderCentre + CurrentLadderNormal, pBot->Edict->v.origin);
|
||||
|
||||
if (Side > 0)
|
||||
{
|
||||
pBot->desiredMovementDir = -LadderRightNormal;
|
||||
}
|
||||
else
|
||||
{
|
||||
pBot->desiredMovementDir = LadderRightNormal;
|
||||
}
|
||||
|
||||
Vector LookLocation = pBot->Edict->v.origin - (CurrentLadderNormal * 50.0f);
|
||||
LookLocation.z = RequiredClimbHeight + 100.0f;
|
||||
BotMoveLookAt(pBot, LookLocation, true);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// If we are blocked going up the ladder, face the ladder and slide left/right to avoid blockage
|
||||
if (bBlockedLeft && !bBlockedRight)
|
||||
if (bBlockedLeft)
|
||||
{
|
||||
Vector LookLocation = pBot->Edict->v.origin - (CurrentLadderNormal * 50.0f);
|
||||
LookLocation.z = RequiredClimbHeight + 100.0f;
|
||||
BotMoveLookAt(pBot, LookLocation);
|
||||
BotMoveLookAt(pBot, LookLocation, true);
|
||||
|
||||
pBot->desiredMovementDir = ClimbRightNormal;
|
||||
return;
|
||||
}
|
||||
|
||||
if (bBlockedRight && !bBlockedLeft)
|
||||
if (bBlockedRight)
|
||||
{
|
||||
Vector LookLocation = pBot->Edict->v.origin - (CurrentLadderNormal * 50.0f);
|
||||
LookLocation.z = RequiredClimbHeight + 100.0f;
|
||||
BotMoveLookAt(pBot, LookLocation);
|
||||
BotMoveLookAt(pBot, LookLocation, true);
|
||||
|
||||
pBot->desiredMovementDir = -ClimbRightNormal;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!UTIL_QuickHullTrace(pBot->Edict, pBot->CurrentEyePosition, pBot->CurrentEyePosition + Vector(0.0f, 0.0f, 32.0f)))
|
||||
{
|
||||
Vector LadderCentre = UTIL_GetCentreOfEntity(Ladder);
|
||||
int Side = vPointOnLine(LadderCentre, LadderCentre + CurrentLadderNormal, pBot->Edict->v.origin);
|
||||
|
||||
if (Side > 0)
|
||||
{
|
||||
pBot->desiredMovementDir = -LadderRightNormal;
|
||||
}
|
||||
else
|
||||
{
|
||||
pBot->desiredMovementDir = LadderRightNormal;
|
||||
}
|
||||
|
||||
Vector LookLocation = pBot->Edict->v.origin - (CurrentLadderNormal * 50.0f);
|
||||
LookLocation.z = RequiredClimbHeight + 100.0f;
|
||||
BotMoveLookAt(pBot, LookLocation, true);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Crouch if we're hitting our head on a ceiling
|
||||
|
||||
|
||||
if (!IsPlayerGorge(pEdict) && !IsPlayerLerk(pEdict) && !IsPlayerSkulk(pEdict))
|
||||
if (!IsPlayerGorge(pEdict) && !IsPlayerLerk(pEdict))
|
||||
{
|
||||
Vector HeadTraceLocation = GetPlayerTopOfCollisionHull(pEdict, false);
|
||||
|
||||
|
@ -4034,39 +4226,30 @@ void LadderMove(AvHAIPlayer* pBot, const Vector StartPoint, const Vector EndPoin
|
|||
|
||||
Vector LookLocation = EndPoint;
|
||||
|
||||
if (!IsPlayerSkulk(pBot->Edict))
|
||||
float dot = UTIL_GetDotProduct2D(vForward, LadderRightNormal);
|
||||
|
||||
// Get-off point is to the side of the ladder rather than right at the top
|
||||
if (fabsf(dot) > 0.5f)
|
||||
{
|
||||
float dot = UTIL_GetDotProduct2D(vForward, LadderRightNormal);
|
||||
|
||||
// Get-off point is to the side of the ladder rather than right at the top
|
||||
if (fabsf(dot) > 0.5f)
|
||||
if (dot > 0.0f)
|
||||
{
|
||||
if (dot > 0.0f)
|
||||
{
|
||||
LookLocation = pBot->Edict->v.origin + (LadderRightNormal * 50.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
LookLocation = pBot->Edict->v.origin - (LadderRightNormal * 50.0f);
|
||||
}
|
||||
|
||||
LookLocation = pBot->Edict->v.origin + (LadderRightNormal * 50.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get-off point is at the top of the ladder, so face the ladder
|
||||
LookLocation = EndPoint - (CurrentLadderNormal * 50.0f);
|
||||
LookLocation = pBot->Edict->v.origin - (LadderRightNormal * 50.0f);
|
||||
}
|
||||
|
||||
LookLocation.z += 100.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get-off point is at the top of the ladder, so face the ladder
|
||||
LookLocation = UTIL_GetNearestLadderTopPoint(pBot->Edict->v.origin) - (CurrentLadderNormal * 50.0f);
|
||||
LookLocation.z += 100.0f;
|
||||
LookLocation = EndPoint - (CurrentLadderNormal * 50.0f);
|
||||
}
|
||||
|
||||
BotMoveLookAt(pBot, LookLocation);
|
||||
LookLocation.z += 100.0f;
|
||||
|
||||
BotMoveLookAt(pBot, LookLocation, true);
|
||||
|
||||
if (RequiredClimbHeight > pBot->Edict->v.origin.z || IsPlayerSkulk(pBot->Edict))
|
||||
{
|
||||
|
@ -4116,28 +4299,20 @@ void LadderMove(AvHAIPlayer* pBot, const Vector StartPoint, const Vector EndPoin
|
|||
|
||||
Vector LookLocation = EndPoint;
|
||||
|
||||
if (!IsPlayerSkulk(pBot->Edict))
|
||||
{
|
||||
Vector FurthestView = UTIL_GetFurthestVisiblePointOnPath(pBot);
|
||||
Vector FurthestView = UTIL_GetFurthestVisiblePointOnPath(pBot);
|
||||
|
||||
if (vIsZero(FurthestView))
|
||||
{
|
||||
LookLocation = EndPoint + (CurrentLadderNormal * 100.0f);
|
||||
}
|
||||
|
||||
// We're close enough to the end that we can jump off the ladder
|
||||
if (UTIL_QuickTrace(pBot->Edict, pBot->Edict->v.origin, EndPoint) && (pBot->CollisionHullBottomLocation.z - EndPoint.z < 100.0f))
|
||||
{
|
||||
BotJump(pBot);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (vIsZero(FurthestView))
|
||||
{
|
||||
LookLocation = pBot->CurrentEyePosition - (CurrentLadderNormal * 50.0f);
|
||||
LookLocation.z -= 100.0f;
|
||||
LookLocation = EndPoint + (CurrentLadderNormal * 100.0f);
|
||||
}
|
||||
|
||||
BotMoveLookAt(pBot, LookLocation);
|
||||
// We're close enough to the end that we can jump off the ladder
|
||||
if (UTIL_QuickTrace(pBot->Edict, pBot->Edict->v.origin, EndPoint) && (pBot->CollisionHullBottomLocation.z - EndPoint.z < 100.0f))
|
||||
{
|
||||
BotJump(pBot);
|
||||
}
|
||||
|
||||
BotMoveLookAt(pBot, LookLocation, true);
|
||||
}
|
||||
|
||||
return;
|
||||
|
@ -4154,7 +4329,7 @@ void LadderMove(AvHAIPlayer* pBot, const Vector StartPoint, const Vector EndPoin
|
|||
pBot->desiredMovementDir = UTIL_GetVectorNormal2D(TargetPoint - pBot->Edict->v.origin);
|
||||
Vector LookPoint = TargetPoint + Vector(0.0f, 0.0f, 100.0f);
|
||||
|
||||
BotMoveLookAt(pBot, LookPoint);
|
||||
BotMoveLookAt(pBot, LookPoint, true);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -4169,7 +4344,7 @@ void LadderMove(AvHAIPlayer* pBot, const Vector StartPoint, const Vector EndPoin
|
|||
}
|
||||
|
||||
// If we're going down the ladder and are approaching it, just keep moving towards it
|
||||
if ((pBot->BotNavInfo.IsOnGround || IsPlayerSkulk(pBot->Edict)) && !bIsGoingUpLadder)
|
||||
if (pBot->BotNavInfo.IsOnGround && !bIsGoingUpLadder)
|
||||
{
|
||||
if (vDist2DSq(pEdict->v.origin, StartPoint) < sqrf(32.0f))
|
||||
{
|
||||
|
@ -4221,12 +4396,29 @@ void LadderMove(AvHAIPlayer* pBot, const Vector StartPoint, const Vector EndPoin
|
|||
|
||||
if (pBot->Edict->v.origin.z < nearestLadderTop.z)
|
||||
{
|
||||
Vector LadderNormal = UTIL_GetNearestLadderNormal(StartPoint);
|
||||
LadderNormal = UTIL_GetVectorNormal2D(LadderNormal);
|
||||
|
||||
Vector nearestLadderPoint = UTIL_GetNearestLadderCentrePoint(pEdict);
|
||||
nearestLadderPoint.z = pEdict->v.origin.z;
|
||||
pBot->desiredMovementDir = UTIL_GetVectorNormal2D(nearestLadderPoint - pEdict->v.origin);
|
||||
edict_t* NearestLadder = UTIL_GetNearestLadderAtPoint(StartPoint);
|
||||
|
||||
Vector LookPoint = nearestLadderPoint + Vector(0.0f, 0.0f, 20.0f);
|
||||
Vector NearestPointOnLadder = UTIL_GetClosestPointOnEntityToLocation(pBot->Edict->v.origin, NearestLadder);
|
||||
|
||||
Vector OrientationToLadder = UTIL_GetVectorNormal2D(pBot->Edict->v.origin - NearestPointOnLadder);
|
||||
|
||||
Vector LookPoint = NearestPointOnLadder + Vector(0.0f, 0.0f, 20.0f);
|
||||
|
||||
if (UTIL_GetDotProduct2D(LadderNormal, OrientationToLadder) < 0.8f)
|
||||
{
|
||||
Vector MovePoint = NearestPointOnLadder + (LadderNormal * 32.0f);
|
||||
pBot->desiredMovementDir = UTIL_GetVectorNormal2D(MovePoint - pBot->Edict->v.origin);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Vector nearestLadderPoint = UTIL_GetNearestLadderCentrePoint(pEdict);
|
||||
nearestLadderPoint.z = pEdict->v.origin.z;
|
||||
pBot->desiredMovementDir = UTIL_GetVectorNormal2D(NearestPointOnLadder - pEdict->v.origin);
|
||||
}
|
||||
|
||||
BotMoveLookAt(pBot, LookPoint);
|
||||
}
|
||||
|
|
|
@ -2420,14 +2420,34 @@ AvHAICombatStrategy GetBotCombatStrategyForTarget(AvHAIPlayer* pBot, enemy_statu
|
|||
{
|
||||
if (FNullEnt(CurrentEnemy->PlayerEdict) || !IsPlayerActiveInGame(CurrentEnemy->PlayerEdict)) { return COMBAT_STRATEGY_IGNORE; }
|
||||
|
||||
AvHAICombatStrategy IdealStrategy;
|
||||
|
||||
if (IsPlayerAlien(pBot->Edict))
|
||||
{
|
||||
return GetAlienCombatStrategyForTarget(pBot, CurrentEnemy);
|
||||
IdealStrategy = GetAlienCombatStrategyForTarget(pBot, CurrentEnemy);
|
||||
}
|
||||
else
|
||||
{
|
||||
return GetMarineCombatStrategyForTarget(pBot, CurrentEnemy);
|
||||
IdealStrategy = GetMarineCombatStrategyForTarget(pBot, CurrentEnemy);
|
||||
}
|
||||
|
||||
if (IdealStrategy == COMBAT_STRATEGY_ATTACK)
|
||||
{
|
||||
// If we want to attack, but we can't reach the enemy and don't have a ranged weapon then ignore them entirely. Otherwise, skirmish instead
|
||||
if (!UTIL_PointIsReachable(pBot->BotNavInfo.NavProfile, pBot->CurrentFloorPosition, UTIL_GetFloorUnderEntity(CurrentEnemy->PlayerEdict), max_ai_use_reach))
|
||||
{
|
||||
if (IsPlayerOnos(pBot->Edict) || IsPlayerSkulk(pBot->Edict) || (IsPlayerFade(pBot->Edict) && !PlayerHasWeapon(pBot->Player, WEAPON_FADE_ACIDROCKET)))
|
||||
{
|
||||
return COMBAT_STRATEGY_IGNORE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return COMBAT_STRATEGY_SKIRMISH;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return IdealStrategy;
|
||||
}
|
||||
|
||||
AvHAICombatStrategy GetAlienCombatStrategyForTarget(AvHAIPlayer* pBot, enemy_status* CurrentEnemy)
|
||||
|
@ -4091,7 +4111,7 @@ void AIPlayerSetWantsAndNeedsMarineTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task
|
|||
AvHTeamNumber BotTeam = pBot->Player->GetTeam();
|
||||
|
||||
bool bNeedsHealth = pBot->Edict->v.health < (pBot->Edict->v.max_health * 0.9f);
|
||||
bool bNeedsAmmo = UTIL_GetPlayerPrimaryAmmoReserve(pBot->Player) < (UTIL_GetPlayerPrimaryMaxAmmoReserve(pBot->Player) * 0.9f);
|
||||
bool bNeedsAmmo = UTIL_GetPlayerPrimaryAmmoReserve(pBot->Player) < (UTIL_GetPlayerPrimaryMaxAmmoReserve(pBot->Player) * 0.75f);
|
||||
|
||||
if (bNeedsHealth || bNeedsAmmo)
|
||||
{
|
||||
|
@ -4121,7 +4141,7 @@ void AIPlayerSetWantsAndNeedsMarineTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task
|
|||
NearestArmouryFilter.ReachabilityFlags = pBot->BotNavInfo.NavProfile.ReachabilityFlag;
|
||||
NearestArmouryFilter.IncludeStatusFlags = STRUCTURE_STATUS_COMPLETED;
|
||||
NearestArmouryFilter.ExcludeStatusFlags = STRUCTURE_STATUS_RECYCLING;
|
||||
NearestArmouryFilter.MaxSearchRadius = (bTaskIsUrgent) ? UTIL_MetresToGoldSrcUnits(20.0f) : UTIL_MetresToGoldSrcUnits(5.0f);
|
||||
NearestArmouryFilter.MaxSearchRadius = (bTaskIsUrgent) ? UTIL_MetresToGoldSrcUnits(20.0f) : UTIL_MetresToGoldSrcUnits(3.0f);
|
||||
|
||||
AvHAIBuildableStructure NearestArmoury = AITAC_FindClosestDeployableToLocation(pBot->Edict->v.origin, &NearestArmouryFilter);
|
||||
|
||||
|
|
|
@ -839,7 +839,7 @@ int AIMGR_GetNumAIPlayersWithRoleOnTeam(AvHTeamNumber Team, AvHAIBotRole Role, A
|
|||
{
|
||||
if (&(*it) == IgnoreAIPlayer) { continue; }
|
||||
|
||||
if (it->Player->GetTeam() == Team)
|
||||
if (it->Player->GetTeam() == Team && IsPlayerActiveInGame((*it).Edict))
|
||||
{
|
||||
if (it->BotRole == Role)
|
||||
{
|
||||
|
|
|
@ -153,7 +153,7 @@ bool IsPlayerOnLadder(const edict_t* Player)
|
|||
Vector NearestPointOnLadder = UTIL_GetClosestPointOnEntityToLocation(Player->v.origin, NearestLadder);
|
||||
Vector NearestPointOnPlayer = UTIL_GetClosestPointOnEntityToLocation(NearestPointOnLadder, Player);
|
||||
|
||||
return (vDist2DSq(NearestPointOnLadder, NearestPointOnPlayer) <= sqrf(4.0f));
|
||||
return (vDist3DSq(NearestPointOnLadder, NearestPointOnPlayer) <= sqrf(2.0f));
|
||||
}
|
||||
|
||||
return (Player->v.movetype == MOVETYPE_FLY);
|
||||
|
@ -992,6 +992,31 @@ Vector UTIL_GetNearestSurfaceNormal(Vector SearchLocation)
|
|||
return ClosestNormal;
|
||||
}
|
||||
|
||||
Vector UTIL_GetLadderNormal(Vector SearchLocation, edict_t* Ladder)
|
||||
{
|
||||
if (FNullEnt(Ladder)) { return ZERO_VECTOR; }
|
||||
|
||||
if (vPointOverlaps3D(SearchLocation, Ladder->v.absmin, Ladder->v.absmax))
|
||||
{
|
||||
return UTIL_GetNearestSurfaceNormal(SearchLocation);
|
||||
}
|
||||
else
|
||||
{
|
||||
Vector CentrePoint = Ladder->v.absmin + (Ladder->v.size * 0.5f);
|
||||
CentrePoint.z = SearchLocation.z;
|
||||
|
||||
trace_t TraceResult;
|
||||
NS_TraceLine(SearchLocation, CentrePoint, 1, PM_WORLD_ONLY, -1, true, TraceResult);
|
||||
|
||||
if (TraceResult.fraction < 1.0f)
|
||||
{
|
||||
return TraceResult.plane.normal;
|
||||
}
|
||||
}
|
||||
|
||||
return ZERO_VECTOR;
|
||||
}
|
||||
|
||||
Vector UTIL_GetNearestLadderNormal(Vector SearchLocation)
|
||||
{
|
||||
TraceResult result;
|
||||
|
|
|
@ -172,6 +172,8 @@ Vector UTIL_GetNearestLadderTopPoint(edict_t* pEdict);
|
|||
Vector UTIL_GetNearestLadderTopPoint(const Vector SearchLocation);
|
||||
Vector UTIL_GetNearestLadderBottomPoint(edict_t* pEdict);
|
||||
|
||||
Vector UTIL_GetLadderNormal(Vector SearchLocation, edict_t* Ladder);
|
||||
|
||||
Vector UTIL_GetNearestSurfaceNormal(Vector SearchLocation);
|
||||
|
||||
#endif
|
|
@ -5843,11 +5843,6 @@ Vector AITAC_FindNewTeamRelocationPoint(AvHTeamNumber Team)
|
|||
MinDist = ThisDist;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
// No hives to relocate to
|
||||
|
|
|
@ -1272,9 +1272,9 @@ void BotProgressMineStructureTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
}
|
||||
}
|
||||
|
||||
float DistToPlaceLocation = vDist2DSq(pBot->Edict->v.origin, Task->TaskLocation);
|
||||
float DistToPlaceLocation = vDist3DSq(pBot->Edict->v.origin, Task->TaskLocation);
|
||||
|
||||
if (DistToPlaceLocation < sqrf(UTIL_MetresToGoldSrcUnits(5.0f)))
|
||||
if (DistToPlaceLocation < sqrf(50.0f))
|
||||
{
|
||||
pBot->DesiredCombatWeapon = WEAPON_MARINE_MINES;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue