Refactoring (#246)
add: yb_chat_percent, yb_camping_time_[min/max], yb_danger_factor[min/max], yb_chat_percent cvars fix: possible crash with difficulty 0 fix: debug_goal should not be used as last history fix: startup on old hlds, because of missing pfnGetFileSize fix: crash with out-bounds read change: again tweaked some aiming code change: player avoidance code so bots will jump less when stuck change: max followers is just /4 of max players refactor: redone distance between vectors refactor: remove magic numbers in graph.add function
This commit is contained in:
parent
6e83258c7d
commit
6f912eb056
10 changed files with 214 additions and 177 deletions
116
src/graph.cpp
116
src/graph.cpp
|
|
@ -386,6 +386,15 @@ int BotGraph::clearConnections (int index) {
|
|||
return numFixedLinks;
|
||||
}
|
||||
|
||||
int BotGraph::getBspSize () {
|
||||
MemFile file (strings.format ("maps/%s.bsp", game.getMapName ()));
|
||||
|
||||
if (file) {
|
||||
return static_cast <int> (file.length ());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void BotGraph::addPath (int addIndex, int pathIndex, float distance) {
|
||||
if (!exists (addIndex) || !exists (pathIndex)) {
|
||||
return;
|
||||
|
|
@ -437,7 +446,7 @@ int BotGraph::getFarest (const Vector &origin, float maxDistance) {
|
|||
maxDistance = cr::square (maxDistance);
|
||||
|
||||
for (const auto &path : m_paths) {
|
||||
float distance = (path.origin - origin).lengthSq ();
|
||||
float distance = path.origin.distanceSq (origin);
|
||||
|
||||
if (distance > maxDistance) {
|
||||
index = path.number;
|
||||
|
|
@ -458,7 +467,7 @@ int BotGraph::getNearestNoBuckets (const Vector &origin, float minDistance, int
|
|||
if (flags != -1 && !(path.flags & flags)) {
|
||||
continue; // if flag not -1 and node has no this flag, skip node
|
||||
}
|
||||
float distance = (path.origin - origin).lengthSq ();
|
||||
float distance = path.origin.distanceSq (origin);
|
||||
|
||||
if (distance < minDistance) {
|
||||
index = path.number;
|
||||
|
|
@ -491,7 +500,7 @@ int BotGraph::getNearest (const Vector &origin, float minDistance, int flags) {
|
|||
if (flags != -1 && !(m_paths[at].flags & flags)) {
|
||||
continue; // if flag not -1 and node has no this flag, skip node
|
||||
}
|
||||
float distance = (m_paths[at].origin - origin).lengthSq ();
|
||||
float distance = origin.distanceSq (m_paths[at].origin);
|
||||
|
||||
if (distance < minDistanceSq) {
|
||||
index = at;
|
||||
|
|
@ -523,7 +532,7 @@ IntArray BotGraph::searchRadius (float radius, const Vector &origin, int maxCoun
|
|||
break;
|
||||
}
|
||||
|
||||
if ((m_paths[at].origin - origin).lengthSq () < radius) {
|
||||
if (origin.distanceSq (m_paths[at].origin) < radius) {
|
||||
result.push (at);
|
||||
}
|
||||
}
|
||||
|
|
@ -548,7 +557,7 @@ void BotGraph::add (int type, const Vector &pos) {
|
|||
m_hasChanged = true;
|
||||
|
||||
switch (type) {
|
||||
case 5:
|
||||
case NodeAddFlag::Camp:
|
||||
index = getEditorNeareset ();
|
||||
|
||||
if (index != kInvalidNodeIndex) {
|
||||
|
|
@ -564,7 +573,7 @@ void BotGraph::add (int type, const Vector &pos) {
|
|||
}
|
||||
break;
|
||||
|
||||
case 6:
|
||||
case NodeAddFlag::CampEnd:
|
||||
index = getEditorNeareset ();
|
||||
|
||||
if (index != kInvalidNodeIndex) {
|
||||
|
|
@ -581,11 +590,11 @@ void BotGraph::add (int type, const Vector &pos) {
|
|||
}
|
||||
return;
|
||||
|
||||
case 9:
|
||||
case NodeAddFlag::JumpStart:
|
||||
index = getEditorNeareset ();
|
||||
|
||||
if (index != kInvalidNodeIndex && m_paths[index].number >= 0) {
|
||||
float distance = (m_paths[index].origin - m_editor->v.origin).length ();
|
||||
float distance = m_editor->v.origin.distance (m_paths[index].origin);
|
||||
|
||||
if (distance < 50.0f) {
|
||||
addNewNode = false;
|
||||
|
|
@ -599,11 +608,11 @@ void BotGraph::add (int type, const Vector &pos) {
|
|||
}
|
||||
break;
|
||||
|
||||
case 10:
|
||||
case NodeAddFlag::JumpEnd:
|
||||
index = getEditorNeareset ();
|
||||
|
||||
if (index != kInvalidNodeIndex && m_paths[index].number >= 0) {
|
||||
float distance = (m_paths[index].origin - m_editor->v.origin).length ();
|
||||
float distance = m_editor->v.origin.distance (m_paths[index].origin);
|
||||
|
||||
if (distance < 50.0f) {
|
||||
addNewNode = false;
|
||||
|
|
@ -627,7 +636,7 @@ void BotGraph::add (int type, const Vector &pos) {
|
|||
auto nearest = getEditorNeareset ();
|
||||
|
||||
// do not allow to place waypoints "inside" waypoints, make at leat 10 units range
|
||||
if (exists (nearest) && (m_paths[nearest].origin - newOrigin).lengthSq () < cr::square (10.0f)) {
|
||||
if (exists (nearest) && newOrigin.distanceSq (m_paths[nearest].origin) < cr::square (10.0f)) {
|
||||
ctrl.msg ("Can't add node. It's way to near to %d node. Please move some units anywhere.", nearest);
|
||||
return;
|
||||
}
|
||||
|
|
@ -666,11 +675,11 @@ void BotGraph::add (int type, const Vector &pos) {
|
|||
m_lastNode = m_editor->v.origin;
|
||||
}
|
||||
|
||||
if (type == 9) {
|
||||
if (type == NodeAddFlag::JumpStart) {
|
||||
m_lastJumpNode = index;
|
||||
}
|
||||
else if (type == 10) {
|
||||
float distance = (m_paths[m_lastJumpNode].origin - m_editor->v.origin).length ();
|
||||
else if (type == NodeAddFlag::JumpEnd) {
|
||||
float distance = m_paths[m_lastJumpNode].origin.distance (m_editor->v.origin);
|
||||
addPath (m_lastJumpNode, index, distance);
|
||||
|
||||
for (auto &link : m_paths[m_lastJumpNode].links) {
|
||||
|
|
@ -701,32 +710,32 @@ void BotGraph::add (int type, const Vector &pos) {
|
|||
}
|
||||
|
||||
switch (type) {
|
||||
case 1:
|
||||
case NodeAddFlag::TOnly:
|
||||
path->flags |= NodeFlag::Crossing;
|
||||
path->flags |= NodeFlag::TerroristOnly;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
case NodeAddFlag::CTOnly:
|
||||
path->flags |= NodeFlag::Crossing;
|
||||
path->flags |= NodeFlag::CTOnly;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
case NodeAddFlag::NoHostage:
|
||||
path->flags |= NodeFlag::NoHostage;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
case NodeAddFlag::Rescue:
|
||||
path->flags |= NodeFlag::Rescue;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
case NodeAddFlag::Camp:
|
||||
path->flags |= NodeFlag::Crossing;
|
||||
path->flags |= NodeFlag::Camp;
|
||||
|
||||
path->start = m_editor->v.v_angle;
|
||||
break;
|
||||
|
||||
case 100:
|
||||
case NodeAddFlag::Goal:
|
||||
path->flags |= NodeFlag::Goal;
|
||||
break;
|
||||
}
|
||||
|
|
@ -750,7 +759,7 @@ void BotGraph::add (int type, const Vector &pos) {
|
|||
game.testLine (newOrigin, calc.origin, TraceIgnore::Monsters, m_editor, &tr);
|
||||
|
||||
if (cr::fequal (tr.flFraction, 1.0f) && cr::abs (newOrigin.x - calc.origin.x) < 64.0f && cr::abs (newOrigin.y - calc.origin.y) < 64.0f && cr::abs (newOrigin.z - calc.origin.z) < m_autoPathDistance) {
|
||||
float distance = (calc.origin - newOrigin).length ();
|
||||
float distance = newOrigin.distance (calc.origin);
|
||||
|
||||
addPath (index, calc.number, distance);
|
||||
addPath (calc.number, index, distance);
|
||||
|
|
@ -759,7 +768,7 @@ void BotGraph::add (int type, const Vector &pos) {
|
|||
else {
|
||||
// check if the node is reachable from the new one
|
||||
if (isNodeReacheable (newOrigin, calc.origin) || isNodeReacheable (calc.origin, newOrigin)) {
|
||||
float distance = (calc.origin - newOrigin).length ();
|
||||
float distance = newOrigin.distance (calc.origin);
|
||||
|
||||
if (distance < minDistance) {
|
||||
destIndex = calc.number;
|
||||
|
|
@ -772,12 +781,12 @@ void BotGraph::add (int type, const Vector &pos) {
|
|||
if (exists (destIndex)) {
|
||||
// check if the node is reachable from the new one (one-way)
|
||||
if (isNodeReacheable (newOrigin, m_paths[destIndex].origin)) {
|
||||
addPath (index, destIndex, (m_paths[destIndex].origin - newOrigin).length ());
|
||||
addPath (index, destIndex, newOrigin.distance (m_paths[destIndex].origin));
|
||||
}
|
||||
|
||||
// check if the new one is reachable from the node (other way)
|
||||
if (isNodeReacheable (m_paths[destIndex].origin, newOrigin)) {
|
||||
addPath (destIndex, index, (m_paths[destIndex].origin - newOrigin).length ());
|
||||
addPath (destIndex, index, newOrigin.distance (m_paths[destIndex].origin));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -790,12 +799,12 @@ void BotGraph::add (int type, const Vector &pos) {
|
|||
|
||||
// check if the node is reachable from the new one (one-way)
|
||||
if (isNodeReacheable (newOrigin, calc.origin)) {
|
||||
addPath (index, calc.number, (calc.origin - newOrigin).length ());
|
||||
addPath (index, calc.number, calc.origin.distance (newOrigin));
|
||||
}
|
||||
|
||||
// check if the new one is reachable from the node (other way)
|
||||
if (isNodeReacheable (calc.origin, newOrigin)) {
|
||||
addPath (calc.number, index, (calc.origin - newOrigin).length ());
|
||||
addPath (calc.number, index, calc.origin.distance (newOrigin));
|
||||
}
|
||||
}
|
||||
clearConnections (index);
|
||||
|
|
@ -975,7 +984,7 @@ void BotGraph::pathCreate (char dir) {
|
|||
return;
|
||||
}
|
||||
|
||||
float distance = (m_paths[nodeTo].origin - m_paths[nodeFrom].origin).length ();
|
||||
float distance = m_paths[nodeFrom].origin.distance (m_paths[nodeTo].origin);
|
||||
|
||||
if (dir == PathConnection::Outgoing) {
|
||||
addPath (nodeFrom, nodeTo, distance);
|
||||
|
|
@ -1787,7 +1796,7 @@ bool BotGraph::loadGraphData () {
|
|||
loadPractice ();
|
||||
|
||||
if (exten.mapSize > 0) {
|
||||
int mapSize = engfuncs.pfnGetFileSize (strings.format ("maps/%s.bsp", game.getMapName ()));
|
||||
int mapSize = getBspSize ();
|
||||
|
||||
if (mapSize != exten.mapSize) {
|
||||
ctrl.msg ("Warning: Graph data is probably not for this map. Please check bots behaviour.");
|
||||
|
|
@ -1829,7 +1838,7 @@ bool BotGraph::saveGraphData () {
|
|||
|
||||
ExtenHeader exten {};
|
||||
strings.copy (exten.author, author.chars (), cr::bufsize (exten.author));
|
||||
exten.mapSize = engfuncs.pfnGetFileSize (strings.format ("maps/%s.bsp", game.getMapName ()));
|
||||
exten.mapSize = getBspSize ();
|
||||
|
||||
// ensure narrow places saved into file
|
||||
m_narrowChecked = false;
|
||||
|
|
@ -1883,13 +1892,13 @@ const char *BotGraph::getOldFormatGraphName (bool isMemoryFile) {
|
|||
float BotGraph::calculateTravelTime (float maxSpeed, const Vector &src, const Vector &origin) {
|
||||
// this function returns 2D traveltime to a position
|
||||
|
||||
return (origin - src).length2d () / maxSpeed;
|
||||
return origin.distance2d (src) / maxSpeed;
|
||||
}
|
||||
|
||||
bool BotGraph::isNodeReacheable (const Vector &src, const Vector &destination) {
|
||||
TraceResult tr {};
|
||||
|
||||
float distance = (destination - src).length ();
|
||||
float distance = destination.distance (src);
|
||||
|
||||
// is the destination not close enough?
|
||||
if (distance > m_autoPathDistance) {
|
||||
|
|
@ -1945,7 +1954,7 @@ bool BotGraph::isNodeReacheable (const Vector &src, const Vector &destination) {
|
|||
game.testLine (check, down, TraceIgnore::Monsters, m_editor, &tr);
|
||||
|
||||
float lastHeight = tr.flFraction * 1000.0f; // height from ground
|
||||
distance = (destination - check).length (); // distance from goal
|
||||
distance = destination.distance (check); // distance from goal
|
||||
|
||||
while (distance > 10.0f) {
|
||||
// move 10 units closer to the goal...
|
||||
|
|
@ -1963,7 +1972,7 @@ bool BotGraph::isNodeReacheable (const Vector &src, const Vector &destination) {
|
|||
return false; // can't get there without jumping...
|
||||
}
|
||||
lastHeight = height;
|
||||
distance = (destination - check).length (); // distance from goal
|
||||
distance = destination.distance (check); // distance from goal
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
@ -2115,7 +2124,7 @@ void BotGraph::frame () {
|
|||
if (m_jumpLearnNode) {
|
||||
if (!m_endJumpPoint) {
|
||||
if (m_editor->v.button & IN_JUMP) {
|
||||
add (9);
|
||||
add (NodeAddFlag::JumpStart);
|
||||
|
||||
m_timeJumpStarted = game.time ();
|
||||
m_endJumpPoint = true;
|
||||
|
|
@ -2126,7 +2135,7 @@ void BotGraph::frame () {
|
|||
}
|
||||
}
|
||||
else if (((m_editor->v.flags & FL_ONGROUND) || m_editor->v.movetype == MOVETYPE_FLY) && m_timeJumpStarted + 0.1f < game.time () && m_endJumpPoint) {
|
||||
add (10);
|
||||
add (NodeAddFlag::JumpEnd);
|
||||
|
||||
m_jumpLearnNode = false;
|
||||
m_endJumpPoint = false;
|
||||
|
|
@ -2136,13 +2145,13 @@ void BotGraph::frame () {
|
|||
// check if it's a auto-add-node mode enabled
|
||||
if (hasEditFlag (GraphEdit::Auto) && (m_editor->v.flags & (FL_ONGROUND | FL_PARTIALGROUND))) {
|
||||
// find the distance from the last used node
|
||||
float distance = (m_lastNode - m_editor->v.origin).lengthSq ();
|
||||
float distance = m_lastNode.distanceSq (m_editor->v.origin);
|
||||
|
||||
if (distance > cr::square (128.0f)) {
|
||||
// check that no other reachable nodes are nearby...
|
||||
for (const auto &path : m_paths) {
|
||||
if (isNodeReacheable (m_editor->v.origin, path.origin)) {
|
||||
distance = (path.origin - m_editor->v.origin).lengthSq ();
|
||||
distance = path.origin.distanceSq (m_editor->v.origin);
|
||||
|
||||
if (distance < nearestDistance) {
|
||||
nearestDistance = distance;
|
||||
|
|
@ -2152,7 +2161,7 @@ void BotGraph::frame () {
|
|||
|
||||
// make sure nearest node is far enough away...
|
||||
if (nearestDistance >= cr::square (128.0f)) {
|
||||
add (GraphAdd::Normal); // place a node here
|
||||
add (NodeAddFlag::Normal); // place a node here
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2163,7 +2172,7 @@ void BotGraph::frame () {
|
|||
|
||||
// now iterate through all nodes in a map, and draw required ones
|
||||
for (auto &path : m_paths) {
|
||||
float distance = (path.origin - m_editor->v.origin).length ();
|
||||
float distance = path.origin.distance (m_editor->v.origin);
|
||||
|
||||
// check if node is whitin a distance, and is visible
|
||||
if (distance < 512.0f && ((util.isVisible (path.origin, m_editor) && util.isInViewCone (path.origin, m_editor)) || !util.isAlive (m_editor) || distance < 128.0f)) {
|
||||
|
|
@ -2705,7 +2714,7 @@ void BotGraph::addBasic () {
|
|||
|
||||
do {
|
||||
if (getNearestNoBuckets (point, 50.0f) == kInvalidNodeIndex) {
|
||||
add (3, point);
|
||||
add (NodeAddFlag::NoHostage, point);
|
||||
}
|
||||
point.z += 160;
|
||||
} while (point.z < down.z - 40.0f);
|
||||
|
|
@ -2713,7 +2722,7 @@ void BotGraph::addBasic () {
|
|||
point = down + Vector (0.0f, 0.0f, 38.0f);
|
||||
|
||||
if (getNearestNoBuckets (point, 50.0f) == kInvalidNodeIndex) {
|
||||
add (3, point);
|
||||
add (NodeAddFlag::NoHostage, point);
|
||||
}
|
||||
m_isOnLadder = false;
|
||||
|
||||
|
|
@ -2731,31 +2740,30 @@ void BotGraph::addBasic () {
|
|||
});
|
||||
};
|
||||
|
||||
autoCreateForEntity (0, "info_player_deathmatch"); // then terrortist spawnpoints
|
||||
autoCreateForEntity (0, "info_player_start"); // then add ct spawnpoints
|
||||
autoCreateForEntity (0, "info_vip_start"); // then vip spawnpoint
|
||||
autoCreateForEntity (0, "armoury_entity"); // weapons on the map ?
|
||||
autoCreateForEntity (NodeAddFlag::Normal, "info_player_deathmatch"); // then terrortist spawnpoints
|
||||
autoCreateForEntity (NodeAddFlag::Normal, "info_player_start"); // then add ct spawnpoints
|
||||
autoCreateForEntity (NodeAddFlag::Normal, "info_vip_start"); // then vip spawnpoint
|
||||
autoCreateForEntity (NodeAddFlag::Normal, "armoury_entity"); // weapons on the map ?
|
||||
|
||||
autoCreateForEntity (4, "func_hostage_rescue"); // hostage rescue zone
|
||||
autoCreateForEntity (4, "info_hostage_rescue"); // hostage rescue zone (same as above)
|
||||
autoCreateForEntity (NodeAddFlag::Rescue, "func_hostage_rescue"); // hostage rescue zone
|
||||
autoCreateForEntity (NodeAddFlag::Rescue, "info_hostage_rescue"); // hostage rescue zone (same as above)
|
||||
|
||||
autoCreateForEntity (100, "func_bomb_target"); // bombspot zone
|
||||
autoCreateForEntity (100, "info_bomb_target"); // bombspot zone (same as above)
|
||||
autoCreateForEntity (100, "hostage_entity"); // hostage entities
|
||||
autoCreateForEntity (100, "func_vip_safetyzone"); // vip rescue (safety) zone
|
||||
autoCreateForEntity (100, "func_escapezone"); // terrorist escape zone
|
||||
autoCreateForEntity (NodeAddFlag::Goal, "func_bomb_target"); // bombspot zone
|
||||
autoCreateForEntity (NodeAddFlag::Goal, "info_bomb_target"); // bombspot zone (same as above)
|
||||
autoCreateForEntity (NodeAddFlag::Goal, "hostage_entity"); // hostage entities
|
||||
autoCreateForEntity (NodeAddFlag::Goal, "func_vip_safetyzone"); // vip rescue (safety) zone
|
||||
autoCreateForEntity (NodeAddFlag::Goal, "func_escapezone"); // terrorist escape zone
|
||||
}
|
||||
|
||||
void BotGraph::eraseFromDisk () {
|
||||
// this function removes graph file from the hard disk
|
||||
|
||||
StringArray forErase;
|
||||
bots.kickEveryone (true);
|
||||
|
||||
auto map = game.getMapName ();
|
||||
auto data = getDataDirectory ();
|
||||
|
||||
bots.kickEveryone (true);
|
||||
|
||||
// if we're delete graph, delete all corresponding to it files
|
||||
forErase.push (strings.format ("%spwf/%s.pwf", data, map)); // graph itself
|
||||
forErase.push (strings.format ("%strain/%s.prc", data, map)); // corresponding to practice
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue