Move navigational helper functions into ncNavInfo
This commit is contained in:
parent
fd90be879c
commit
6867396b09
8 changed files with 15 additions and 308 deletions
|
@ -19,3 +19,4 @@
|
|||
#include "route.h"
|
||||
#include "node_edit.h"
|
||||
#include "way_convert.h"
|
||||
#include "NavInfo.h"
|
||||
|
|
|
@ -3,4 +3,5 @@ nodes.qc
|
|||
route.qc
|
||||
node_edit.qc
|
||||
way_convert.qc
|
||||
NavInfo.qc
|
||||
#endlist
|
||||
|
|
|
@ -47,63 +47,4 @@ void Nodes_Flush(void);
|
|||
void Nodes_Init(void);
|
||||
bool Nodes_Available(void);
|
||||
|
||||
vector Nodes_PositionOfClosestNode(vector);
|
||||
|
||||
/** Returns the position of a spot that'll provide cover from the specified enemy.
|
||||
|
||||
@param targetEnemy The enemy to hide from.
|
||||
@return Absolute position of a valid cover spot. */
|
||||
vector Nodes_FindCoverFromEnemy(ncActor targetEnemy);
|
||||
|
||||
/** Returns the position of a spot that'll be behind where you're currently standing
|
||||
|
||||
@param targetPosition The position to back away from.
|
||||
@param eulerDirection The direction we're looking in, in euler-angles.
|
||||
@return Absolute position of a valid cover spot. */
|
||||
vector Nodes_FindBackFromPosition(vector targetPosition, vector eulerDirection);
|
||||
|
||||
|
||||
/** Returns the position of a spot that'll provide cover from the specified enemy, closest to a specified node.
|
||||
|
||||
@param targetEnemy The enemy to hide from.
|
||||
@param nodePosition The position we should get closest to.
|
||||
@return Absolute position of a valid cover spot. */
|
||||
vector Nodes_FindCoverFromEnemyNearNode(ncActor targetEnemy, vector nodePosition);
|
||||
|
||||
|
||||
/** Returns the position of a spot that'll provide cover from the specified enemy, furthest from a specified node.
|
||||
|
||||
@param targetEnemy The enemy to hide from.
|
||||
@param nodePosition The position we should get as far away from as possible from.
|
||||
@return Absolute position of a valid cover spot. */
|
||||
vector Nodes_FindCoverFromEnemyFarNode(ncActor targetEnemy, vector nodePosition);
|
||||
|
||||
|
||||
/** Returns the position of a spot that'll provide cover from the specified enemy.
|
||||
|
||||
@param traceEntity The entity which will be testing for collisions.
|
||||
@param targetOrigin The spot to hide from.
|
||||
@return Absolute position of a valid cover spot. */
|
||||
vector Nodes_FindCoverFromPosition(entity traceEntity, vector targetOrigin);
|
||||
|
||||
|
||||
/** Returns the position of a spot that is accessible within a specified position.
|
||||
|
||||
@param traceEntity The entity which will be testing for collisions.
|
||||
@param targetOrigin The spot to be near.
|
||||
@param minRadius The mininum distance / search radius from the targetOrigin.
|
||||
@param maxRadius The maximum Radius in which we'll look for a free spot.
|
||||
@return Absolute position of a valid cover spot. */
|
||||
vector Nodes_FindEmptySpotNearPosition(entity traceEntity, vector position, float minRadius, float maxRadius);
|
||||
|
||||
|
||||
/** Returns the position of a spot that is far away within a specified position.
|
||||
|
||||
@param traceEntity The entity which will be testing for collisions.
|
||||
@param targetOrigin The spot to be near.
|
||||
@param minRadius The mininum distance / search radius from the targetOrigin.
|
||||
@param maxRadius The maximum Radius in which we'll look for a free spot.
|
||||
@return Absolute position of a valid cover spot. */
|
||||
vector Nodes_FindEmptySpotAwayFromPosition(entity traceEntity, vector position, float minRadius, float maxRadius);
|
||||
|
||||
/** @} */ // end of nav
|
||||
|
|
232
src/nav/nodes.qc
232
src/nav/nodes.qc
|
@ -187,235 +187,3 @@ Nodes_Flush(void)
|
|||
{
|
||||
NodeEdit_Flush();
|
||||
}
|
||||
|
||||
/* Helper functions for tasks/nav */
|
||||
vector
|
||||
Nodes_PositionOfClosestNode(vector pointOrigin)
|
||||
{
|
||||
float bestDistance = COST_INFINITE;
|
||||
int bestNodeID = -1;
|
||||
|
||||
for (int i = 0; i < g_iNodes; i++) {
|
||||
vector nodePosition = g_pNodes[i].m_vecOrigin;
|
||||
float nodeDistance = distanceSquared(nodePosition, pointOrigin);
|
||||
|
||||
if (nodeDistance < bestDistance) {
|
||||
bestDistance = nodeDistance;
|
||||
bestNodeID = i;
|
||||
}
|
||||
}
|
||||
|
||||
return (g_pNodes[bestNodeID].m_vecOrigin);
|
||||
}
|
||||
|
||||
vector
|
||||
Nodes_FindCoverFromEnemy(ncActor targetEnemy)
|
||||
{
|
||||
float bestDistance = COST_INFINITE;
|
||||
int bestNodeID = -1i;
|
||||
|
||||
for (int i = 0; i < g_iNodes; i++) {
|
||||
vector nodePosition = g_pNodes[i].m_vecOrigin;
|
||||
float nodeRadius = g_pNodes[i].m_flRadius;
|
||||
float nodeDistance = distanceSquared(nodePosition, targetEnemy.origin);
|
||||
traceline(targetEnemy.origin, nodePosition, MOVE_NORMAL, targetEnemy);
|
||||
|
||||
if (trace_fraction < 1.0 && nodeDistance < bestDistance) {
|
||||
bestDistance = nodeDistance;
|
||||
bestNodeID = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (bestNodeID != -1i) {
|
||||
return g_vec_null;
|
||||
}
|
||||
|
||||
return (g_pNodes[bestNodeID].m_vecOrigin);
|
||||
}
|
||||
|
||||
vector
|
||||
Nodes_FindBackFromPosition(vector targetPosition, vector eulerDirection)
|
||||
{
|
||||
float bestDistance = COST_INFINITE;
|
||||
int bestNodeID = -1;
|
||||
vector forwardDir = anglesToForward(eulerDirection);
|
||||
|
||||
for (int i = 0; i < g_iNodes; i++) {
|
||||
vector nodePosition = g_pNodes[i].m_vecOrigin;
|
||||
float nodeRadius = g_pNodes[i].m_flRadius;
|
||||
float nodeDistance = distanceSquared(nodePosition, targetPosition);
|
||||
traceline(targetPosition, nodePosition, MOVE_NORMAL, world);
|
||||
|
||||
if (trace_fraction < 1.0 && nodeDistance < bestDistance) {
|
||||
bestDistance = nodeDistance;
|
||||
bestNodeID = i;
|
||||
}
|
||||
}
|
||||
|
||||
return (g_pNodes[bestNodeID].m_vecOrigin);
|
||||
}
|
||||
|
||||
vector
|
||||
Nodes_FindCoverFromEnemyNearNode(ncActor targetEnemy, vector targetNode)
|
||||
{
|
||||
float bestDistance = COST_INFINITE;
|
||||
int bestNodeID = -1;
|
||||
|
||||
for (int i = 0; i < g_iNodes; i++) {
|
||||
vector nodePosition = g_pNodes[i].m_vecOrigin;
|
||||
float nodeDistance = distanceSquared(nodePosition, targetNode);
|
||||
|
||||
traceline(targetEnemy.origin, nodePosition, MOVE_NORMAL, targetEnemy);
|
||||
|
||||
if (trace_fraction < 1.0 && nodeDistance < bestDistance) {
|
||||
bestDistance = nodeDistance;
|
||||
bestNodeID = i;
|
||||
}
|
||||
}
|
||||
|
||||
return (g_pNodes[bestNodeID].m_vecOrigin);
|
||||
}
|
||||
|
||||
vector
|
||||
Nodes_FindCoverFromEnemyFarNode(ncActor targetEnemy, vector targetNode)
|
||||
{
|
||||
float bestDistance = 0;
|
||||
int bestNodeID = -1;
|
||||
|
||||
for (int i = 0; i < g_iNodes; i++) {
|
||||
vector nodePosition = g_pNodes[i].m_vecOrigin;
|
||||
float nodeDistance = distanceSquared(nodePosition, targetNode);
|
||||
|
||||
traceline(targetEnemy.origin, nodePosition, MOVE_NORMAL, targetEnemy);
|
||||
|
||||
if (trace_fraction < 1.0 && nodeDistance > bestDistance) {
|
||||
bestDistance = nodeDistance;
|
||||
bestNodeID = i;
|
||||
}
|
||||
}
|
||||
|
||||
return (g_pNodes[bestNodeID].m_vecOrigin);
|
||||
}
|
||||
|
||||
vector
|
||||
Nodes_FindCoverFromPosition(entity traceEntity, vector targetOrigin)
|
||||
{
|
||||
float bestDistance = COST_INFINITE;
|
||||
int bestNodeID = -1i;
|
||||
|
||||
#if 0
|
||||
if (g_iNodes <= 0i) {
|
||||
return Nodes_FindEmptySpotNearPosition(world, targetOrigin, 512.0, 4096.0f);
|
||||
}
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < g_iNodes; i++) {
|
||||
vector nodePosition = g_pNodes[i].m_vecOrigin;
|
||||
float nodeDistance = distanceSquared(nodePosition, traceEntity.origin);
|
||||
|
||||
traceline(nodePosition, targetOrigin, MOVE_NORMAL, traceEntity);
|
||||
|
||||
if ((trace_ent == world || trace_fraction < 1.0) && nodeDistance < bestDistance) {
|
||||
bestDistance = nodeDistance;
|
||||
bestNodeID = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (bestNodeID) {
|
||||
return (g_vec_null);
|
||||
}
|
||||
|
||||
NSError("%v", (g_pNodes[bestNodeID].m_vecOrigin));
|
||||
return (g_pNodes[bestNodeID].m_vecOrigin);
|
||||
}
|
||||
|
||||
vector
|
||||
Nodes_FindEmptySpotNearPosition(entity traceEntity, vector position, float minRadius, float maxRadius)
|
||||
{
|
||||
float bestYaw = 0.0f;
|
||||
float bestDist = 0.0f;
|
||||
vector testAngle = g_vec_null;
|
||||
vector testPos = g_vec_null;
|
||||
|
||||
for (float yawTest = 0.0f; yawTest < 360.0f; yawTest += 10.0f) {
|
||||
vector testPos;
|
||||
float distSquared;
|
||||
vector testAngle = traceEntity.angles = [0, yawTest, 0];
|
||||
testAngle[0] = testAngle[2] = 0.0f;
|
||||
makevectors(testAngle);
|
||||
testPos = position + (v_forward * 2048.0f);
|
||||
tracebox(position, traceEntity.mins, traceEntity.maxs, testPos, MOVE_NORMAL, traceEntity);
|
||||
distSquared = distance(position, trace_endpos);
|
||||
|
||||
if (distSquared > bestDist) {
|
||||
bestYaw = yawTest;
|
||||
bestDist = distSquared;
|
||||
}
|
||||
}
|
||||
|
||||
/* cancel early */
|
||||
if (bestDist <= minRadius) {
|
||||
return (g_vec_null);
|
||||
}
|
||||
|
||||
for (float dist = minRadius; dist < maxRadius; dist += ((maxRadius - minRadius) / 16.0f)) {
|
||||
vector testAngle = [0, bestYaw, 0];
|
||||
testAngle[0] = testAngle[2] = 0.0f;
|
||||
makevectors(testAngle);
|
||||
vector testPos = position + (v_forward * dist);
|
||||
tracebox(testPos, traceEntity.mins, traceEntity.maxs, testPos, MOVE_NORMAL, traceEntity);
|
||||
|
||||
if (!trace_startsolid) {
|
||||
return (testPos);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return (g_vec_null);
|
||||
}
|
||||
|
||||
vector
|
||||
Nodes_FindEmptySpotAwayFromPosition(entity traceEntity, vector position, float minRadius, float maxRadius)
|
||||
{
|
||||
float bestYaw = 0.0f;
|
||||
float bestDist = 0.0f;
|
||||
vector testAngle = g_vec_null;
|
||||
vector testPos = g_vec_null;
|
||||
|
||||
for (float yawTest = 0.0f; yawTest < 360.0f; yawTest += 10.0f) {
|
||||
vector testPos;
|
||||
float distSquared;
|
||||
vector testAngle = traceEntity.angles = [0, yawTest, 0];
|
||||
testAngle[0] = testAngle[2] = 0.0f;
|
||||
makevectors(testAngle);
|
||||
testPos = position + (v_forward * 2048.0f);
|
||||
tracebox(position, traceEntity.mins, traceEntity.maxs, testPos, MOVE_NORMAL, traceEntity);
|
||||
distSquared = distance(position, trace_endpos);
|
||||
|
||||
if (distSquared > bestDist) {
|
||||
bestYaw = yawTest;
|
||||
bestDist = distSquared;
|
||||
}
|
||||
}
|
||||
|
||||
/* cancel early */
|
||||
if (bestDist <= minRadius) {
|
||||
return (g_vec_null);
|
||||
}
|
||||
|
||||
for (float dist = maxRadius; dist > minRadius; dist -= ((maxRadius - minRadius) / 16.0f)) {
|
||||
vector testAngle = [0, bestYaw, 0];
|
||||
testAngle[0] = testAngle[2] = 0.0f;
|
||||
makevectors(testAngle);
|
||||
vector testPos = position + (v_forward * dist);
|
||||
tracebox(testPos, traceEntity.mins, traceEntity.maxs, testPos, MOVE_NORMAL, traceEntity);
|
||||
|
||||
if (!trace_startsolid) {
|
||||
return (testPos);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return (g_vec_null);
|
||||
}
|
||||
|
||||
|
|
|
@ -147,10 +147,6 @@ ncSchedule::Think(void)
|
|||
if (!m_controllingActor) {
|
||||
shouldCancel = true;
|
||||
} else {
|
||||
if (m_controllingActor.IsAlive() == false) {
|
||||
shouldCancel = true;
|
||||
}
|
||||
|
||||
if (m_controllingActor.m_activeSchedule != this) {
|
||||
shouldCancel = true;
|
||||
}
|
||||
|
|
|
@ -167,17 +167,16 @@ Spawn_TeleportToSpawn(entity targetEnt)
|
|||
}
|
||||
|
||||
/* if not set, don't bother teleporting */
|
||||
if (!STRING_SET(desiredSpawn)) {
|
||||
return;
|
||||
}
|
||||
if (STRING_SET(desiredSpawn)) {
|
||||
|
||||
entity spawnPoint = Spawn_SelectRandom(desiredSpawn);
|
||||
entity spawnPoint = Spawn_SelectRandom(desiredSpawn);
|
||||
|
||||
if (spawnPoint) {
|
||||
targetEnt.origin = spawnPoint.origin;
|
||||
targetEnt.angles = spawnPoint.angles;
|
||||
setorigin_safe(targetEnt, targetEnt.origin);
|
||||
return;
|
||||
if (spawnPoint) {
|
||||
targetEnt.origin = spawnPoint.origin;
|
||||
targetEnt.angles = spawnPoint.angles;
|
||||
setorigin_safe(targetEnt, targetEnt.origin);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
spawnPoint = Spawn_SelectRandom("info_player_start");
|
||||
|
|
|
@ -478,7 +478,7 @@ ncActor::Input(entity eAct, string strInput, string strData)
|
|||
// NSWarning("Task %S unimplemented", strInput);
|
||||
break;
|
||||
case "GoToCover":
|
||||
vector coverPos = Nodes_FindCoverFromPosition(this, GetOrigin());
|
||||
vector coverPos = ncNavInfo::FindCoverFromPosition(this, GetOrigin());
|
||||
|
||||
if (vlen(coverPos) > 0.0f) {
|
||||
RouteToPosition(coverPos);
|
||||
|
@ -487,7 +487,7 @@ ncActor::Input(entity eAct, string strInput, string strData)
|
|||
}
|
||||
break;
|
||||
case "GoToSpotInRadius":
|
||||
vector t = Nodes_FindEmptySpotNearPosition(this, GetOrigin(), 128.0f, stof(strData));
|
||||
vector t = ncNavInfo::FindEmptySpotNearPosition(this, GetOrigin(), 128.0f, stof(strData));
|
||||
|
||||
if (vlen(t) > 0.0f) {
|
||||
RouteToPosition(t);
|
||||
|
@ -496,7 +496,7 @@ ncActor::Input(entity eAct, string strInput, string strData)
|
|||
}
|
||||
break;
|
||||
case "AvoidSpotInRadius":
|
||||
vector t = Nodes_FindEmptySpotAwayFromPosition(this, GetOrigin(), 0.0f, stof(strData));
|
||||
vector t = ncNavInfo::FindEmptySpotAwayFromPosition(this, GetOrigin(), 0.0f, stof(strData));
|
||||
|
||||
if (vlen(t) > 0.0f) {
|
||||
RouteToPosition(t);
|
||||
|
|
|
@ -1969,6 +1969,7 @@ ncMonster::Death(entity inflictor, entity attacker, int damage, vector dir, vect
|
|||
}
|
||||
|
||||
m_iFlags = 0x0;
|
||||
CancelSchedule();
|
||||
|
||||
switch (hitBody) {
|
||||
case BODY_HEAD:
|
||||
|
@ -2265,7 +2266,7 @@ ncMonster::Input( entity entityActivator, string inputName, string dataField )
|
|||
}
|
||||
break;
|
||||
case "FindCoverFromEnemy":
|
||||
vector coverPos = Nodes_FindCoverFromEnemy(this);
|
||||
vector coverPos = ncNavInfo::FindCoverFromEnemy(this);
|
||||
|
||||
if (vlen(coverPos) > 0.0f) {
|
||||
RouteToPosition(coverPos);
|
||||
|
|
Loading…
Reference in a new issue