mirror of
https://github.com/ENSL/NS.git
synced 2025-04-20 16:30:56 +00:00
Improved skulk ladder usage and lerk lift usage
This commit is contained in:
parent
81320dd2dc
commit
72f48fe4ee
2 changed files with 85 additions and 16 deletions
|
@ -1329,7 +1329,15 @@ dtStatus FindFlightPathToPoint(const nav_profile &NavProfile, Vector FromLocatio
|
|||
|
||||
bot_path_node NextPathNode;
|
||||
|
||||
NextPathNode.flag = SAMPLE_POLYFLAGS_WALK;
|
||||
if (CurrFlags == SAMPLE_POLYFLAGS_LIFT)
|
||||
{
|
||||
NextPathNode.flag = CurrFlags;
|
||||
}
|
||||
else
|
||||
{
|
||||
NextPathNode.flag = SAMPLE_POLYFLAGS_WALK;
|
||||
}
|
||||
|
||||
NextPathNode.area = CurrArea;
|
||||
NextPathNode.poly = StraightPolyPath[nVert];
|
||||
|
||||
|
@ -1755,20 +1763,21 @@ dtStatus FindPathClosestToPoint(AvHAIPlayer* pBot, const BotMoveStyle MoveStyle,
|
|||
NextPathNode.requiredZ += 5.0f;
|
||||
}
|
||||
|
||||
if (IsPlayerSkulk(pBot->Edict))
|
||||
if (IsPlayerSkulk(pBot->Edict) && CurrFlags == SAMPLE_POLYFLAGS_LADDER)
|
||||
{
|
||||
Vector NearestLadderTopPoint = UTIL_GetNearestLadderTopPoint(NextPathNode.Location);
|
||||
NearestLadderTopPoint.z = NewRequiredZ;
|
||||
|
||||
Vector CurrMoveDest = NextPathNode.Location;
|
||||
|
||||
NextPathNode.flag = SAMPLE_POLYFLAGS_WALLCLIMB;
|
||||
|
||||
Vector ThisMoveDest = Vector(NodeFromLocation.x, NodeFromLocation.y, NextPathNode.Location.z);
|
||||
|
||||
NextPathNode.Location = ThisMoveDest;
|
||||
NextPathNode.Location = NearestLadderTopPoint;
|
||||
|
||||
path.push_back(NextPathNode);
|
||||
|
||||
NextPathNode.Location = CurrMoveDest;
|
||||
NextPathNode.FromLocation = ThisMoveDest;
|
||||
NextPathNode.FromLocation = NearestLadderTopPoint;
|
||||
|
||||
CurrFlags = SAMPLE_POLYFLAGS_WALLCLIMB;
|
||||
}
|
||||
|
@ -2680,7 +2689,7 @@ void CheckAndHandleBreakableObstruction(AvHAIPlayer* pBot, const Vector MoveFrom
|
|||
{
|
||||
if (IsPlayerSkulk(pBot->Edict))
|
||||
{
|
||||
DesiredWeapon = (BlockingBreakableEdict->v.health <= 20) ? WEAPON_SKULK_PARASITE : WEAPON_SKULK_BITE;
|
||||
DesiredWeapon = (BlockingBreakableEdict->v.health <= 10) ? WEAPON_SKULK_PARASITE : WEAPON_SKULK_BITE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3409,7 +3418,6 @@ void LiftMove(AvHAIPlayer* pBot, const Vector StartPoint, const Vector EndPoint)
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
Vector LiftPosition = UTIL_GetCentreOfEntity(NearestLift->DoorEdict);
|
||||
|
||||
pBot->desiredMovementDir = ZERO_VECTOR;
|
||||
|
@ -3552,7 +3560,8 @@ void LiftMove(AvHAIPlayer* pBot, const Vector StartPoint, const Vector EndPoint)
|
|||
|
||||
if (NearestLiftTrigger)
|
||||
{
|
||||
if (gpGlobals->time < NearestLiftTrigger->NextActivationTime || !(NearestLift->DoorEdict->v.spawnflags & SF_TRAIN_WAIT_RETRIGGER) || (NearestLift->DoorEntity && NearestLift->DoorEntity->m_flWait > 0.0f))
|
||||
// If the trigger is on cooldown, or the door/train is designed to automatically return without being summoned, then just wait for it to come back
|
||||
if (gpGlobals->time < NearestLiftTrigger->NextActivationTime || (NearestLift->DoorType == DOORTYPE_TRAIN && !(NearestLift->DoorEdict->v.spawnflags & SF_TRAIN_WAIT_RETRIGGER)) || (NearestLift->DoorType == DOORTYPE_DOOR && NearestLift->DoorEntity && NearestLift->DoorEntity->GetToggleState() == TS_AT_TOP && NearestLift->DoorEntity->m_flWait > 0.0f && !(NearestLift->DoorEdict->v.spawnflags & SF_DOOR_NO_AUTO_RETURN)))
|
||||
{
|
||||
if (!bIsOnLift && !bIsLiftAtOrNearStart)
|
||||
{
|
||||
|
@ -3595,14 +3604,21 @@ void LiftMove(AvHAIPlayer* pBot, const Vector StartPoint, const Vector EndPoint)
|
|||
|
||||
Vector NearestPointOnLiftToButton = UTIL_GetClosestPointOnEntityToLocation(ButtonFloorLocation, NearestLift->DoorEdict);
|
||||
|
||||
bool ButtonReachableFromLift = !vIsZero(ButtonFloorLocation) && (vDist2DSq(ButtonFloorLocation, NearestPointOnLiftToButton) <= sqrf(64.0f));
|
||||
bool ButtonReachableFromLift = (NearestLiftTrigger->TriggerType == DOOR_TRIGGER) ? vBBOverlaps2D(NearestLiftTrigger->Edict->v.absmin, NearestLiftTrigger->Edict->v.absmax, NearestLift->DoorEdict->v.absmin, NearestLift->DoorEdict->v.absmax) : (!vIsZero(ButtonFloorLocation) && (vDist2DSq(ButtonFloorLocation, NearestPointOnLiftToButton) <= sqrf(64.0f)));
|
||||
|
||||
if (ButtonReachableFromLift)
|
||||
{
|
||||
if (IsPlayerInUseRange(pBot->Edict, NearestLiftTrigger->Edict))
|
||||
if (NearestLiftTrigger->TriggerType == DOOR_BUTTON)
|
||||
{
|
||||
BotUseObject(pBot, NearestLiftTrigger->Edict, false);
|
||||
return;
|
||||
if (IsPlayerInUseRange(pBot->Edict, NearestLiftTrigger->Edict))
|
||||
{
|
||||
BotUseObject(pBot, NearestLiftTrigger->Edict, false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pBot->desiredMovementDir = UTIL_GetVectorNormal2D(NearestLiftTrigger->Edict->v.origin - pBot->Edict->v.origin);
|
||||
}
|
||||
|
||||
if (!bIsOnLift)
|
||||
|
@ -3743,8 +3759,6 @@ bool IsBotOffPath(const AvHAIPlayer* pBot)
|
|||
// Give us a chance to land before deciding we're off the path
|
||||
if (!pBot->BotNavInfo.IsOnGround) { return false; }
|
||||
|
||||
|
||||
// TODO: This sucks
|
||||
if (pBot->BotNavInfo.CurrentPathPoint->flag == SAMPLE_POLYFLAGS_WALK)
|
||||
{
|
||||
|
||||
|
@ -5534,6 +5548,12 @@ void BotFollowFlightPath(AvHAIPlayer* pBot)
|
|||
}
|
||||
}
|
||||
|
||||
if (BotNavInfo->CurrentPathPoint->flag == SAMPLE_POLYFLAGS_LIFT)
|
||||
{
|
||||
LiftMove(pBot, BotNavInfo->CurrentPathPoint->FromLocation, CurrentMoveDest);
|
||||
return;
|
||||
}
|
||||
|
||||
if (BotNavInfo->CurrentPathPoint->area != SAMPLE_POLYAREA_CROUCH && next(BotNavInfo->CurrentPathPoint) != BotNavInfo->CurrentPath.end() && next(BotNavInfo->CurrentPathPoint)->area != SAMPLE_POLYAREA_CROUCH)
|
||||
{
|
||||
SkipAheadInFlightPath(pBot);
|
||||
|
@ -6370,6 +6390,43 @@ Vector UTIL_GetNearestLadderBottomPoint(edict_t* pEdict)
|
|||
return pEdict->v.origin;
|
||||
}
|
||||
|
||||
Vector UTIL_GetNearestLadderTopPoint(const Vector SearchLocation)
|
||||
{
|
||||
TraceResult result;
|
||||
CBaseEntity* entity = NULL;
|
||||
|
||||
entity = UTIL_FindEntityByClassname(entity, "func_ladder");
|
||||
|
||||
CBaseEntity* closestLadderRef = entity;
|
||||
float lowestDist = 999999.0f;
|
||||
|
||||
while (entity)
|
||||
{
|
||||
Vector LadderMin = entity->pev->absmin;
|
||||
Vector LadderMax = entity->pev->absmax;
|
||||
|
||||
float dist = vDistanceFromLine3D(LadderMin, LadderMax, SearchLocation);
|
||||
|
||||
if (dist < lowestDist)
|
||||
{
|
||||
closestLadderRef = entity;
|
||||
lowestDist = dist;
|
||||
}
|
||||
|
||||
entity = UTIL_FindEntityByClassname(entity, "func_ladder");
|
||||
}
|
||||
|
||||
if (closestLadderRef)
|
||||
{
|
||||
Vector Centre = (closestLadderRef->pev->absmin + ((closestLadderRef->pev->absmax - closestLadderRef->pev->absmin) * 0.5f));
|
||||
Centre.z = closestLadderRef->pev->absmax.z;
|
||||
return Centre;
|
||||
|
||||
}
|
||||
|
||||
return SearchLocation;
|
||||
}
|
||||
|
||||
Vector UTIL_GetNearestLadderTopPoint(edict_t* pEdict)
|
||||
{
|
||||
TraceResult result;
|
||||
|
@ -7689,10 +7746,12 @@ void UTIL_PopulateDoors()
|
|||
|
||||
if (TrainRef)
|
||||
{
|
||||
NewDoor.DoorType = DOORTYPE_TRAIN;
|
||||
UTIL_PopulateTrainStopPoints(&NewDoor);
|
||||
}
|
||||
else
|
||||
{
|
||||
NewDoor.DoorType = DOORTYPE_DOOR;
|
||||
if (NewDoor.DoorEdict->v.spawnflags & DOOR_START_OPEN)
|
||||
{
|
||||
NewDoor.StopPoints.push_back(UTIL_GetCentreOfEntity(NewDoor.DoorEdict) + ToggleRef->m_vecPosition2);
|
||||
|
|
|
@ -81,6 +81,14 @@ enum DoorActivationType
|
|||
DOOR_BREAK // Door activated by breaking something
|
||||
};
|
||||
|
||||
// Door type. Not currently used, future feature so bots know how to open a door
|
||||
enum NavDoorType
|
||||
{
|
||||
DOORTYPE_DOOR, // No type, cannot be activated (permanently open/shut)
|
||||
DOORTYPE_PLAT, // Door activated by using it directly
|
||||
DOORTYPE_TRAIN // Door activated by touching a trigger_once or trigger_multiple
|
||||
};
|
||||
|
||||
typedef struct _DOOR_TRIGGER
|
||||
{
|
||||
CBaseEntity* Entity = nullptr;
|
||||
|
@ -101,13 +109,14 @@ typedef struct _NAV_DOOR
|
|||
{
|
||||
CBaseToggle* DoorEntity = nullptr;
|
||||
edict_t* DoorEdict = nullptr; // Reference to the func_door
|
||||
unsigned int ObstacleRefs[32][MAX_NAV_MESHES]; // Dynamic obstacle ref. Used to add/remove the obstacle as the door is opened/closed
|
||||
unsigned int ObstacleRefs[32][MAX_NAV_MESHES] = {}; // Dynamic obstacle ref. Used to add/remove the obstacle as the door is opened/closed
|
||||
int NumObstacles = 0;
|
||||
vector<DoorTrigger> TriggerEnts; // Reference to the trigger edicts (e.g. func_trigger, func_button etc.)
|
||||
DoorActivationType ActivationType = DOOR_NONE; // How the door should be opened
|
||||
TOGGLE_STATE CurrentState = TS_AT_BOTTOM;
|
||||
float OpenDelay = 0.0f; // How long the door takes to start opening after activation
|
||||
vector<Vector> StopPoints; // Where does this door/platform stop when triggered?
|
||||
NavDoorType DoorType = DOORTYPE_DOOR;
|
||||
} nav_door;
|
||||
|
||||
typedef struct _NAV_WELDABLE
|
||||
|
@ -439,6 +448,7 @@ const char* UTIL_NavmeshAreaToChar(const unsigned char Area);
|
|||
Vector UTIL_GetNearestLadderNormal(edict_t* pEdict);
|
||||
Vector UTIL_GetNearestLadderCentrePoint(edict_t* pEdict);
|
||||
Vector UTIL_GetNearestLadderTopPoint(edict_t* pEdict);
|
||||
Vector UTIL_GetNearestLadderTopPoint(const Vector SearchLocation);
|
||||
Vector UTIL_GetNearestLadderBottomPoint(edict_t* pEdict);
|
||||
|
||||
// From the given start point, determine how high up the bot needs to climb to get to climb end. Will allow the bot to climb over railings
|
||||
|
|
Loading…
Reference in a new issue