fix: use clamped health value to avoid overflows.
crlib: do not shutdown wsa, it's cleaned upon server exit anyway.
This commit is contained in:
parent
3afd03c12c
commit
1263a1a439
11 changed files with 109 additions and 126 deletions
|
|
@ -628,7 +628,7 @@ void Bot::updatePickups () {
|
|||
else if (m_isVIP || !rateGroundWeapon (ent)) {
|
||||
allowPickup = false;
|
||||
}
|
||||
else if (strcmp (model, "medkit.mdl") == 0 && pev->health >= 100.0f) {
|
||||
else if (strcmp (model, "medkit.mdl") == 0 && m_healthValue >= 100.0f) {
|
||||
allowPickup = false;
|
||||
}
|
||||
else if ((strcmp (model, "kevlar.mdl") == 0 || strcmp (model, "battery.mdl") == 0) && pev->armorvalue >= 100.0f) {
|
||||
|
|
@ -792,7 +792,7 @@ void Bot::updatePickups () {
|
|||
m_itemIgnore = ent;
|
||||
allowPickup = false;
|
||||
|
||||
if (!m_defendedBomb && m_difficulty >= Difficulty::Normal && rg.chance (75) && pev->health < 60) {
|
||||
if (!m_defendedBomb && m_difficulty >= Difficulty::Normal && rg.chance (75) && m_healthValue < 60) {
|
||||
int index = findDefendNode (origin);
|
||||
|
||||
startTask (Task::Camp, TaskPri::Camp, kInvalidNodeIndex, game.time () + rg.float_ (30.0f, 70.0f), true); // push camp task on to stack
|
||||
|
|
@ -1931,7 +1931,7 @@ void Bot::filterTasks () {
|
|||
|
||||
// calculate desires to seek cover or hunt
|
||||
if (util.isPlayer (m_lastEnemy) && !m_lastEnemyOrigin.empty () && !m_hasC4) {
|
||||
float retreatLevel = (100.0f - (pev->health > 50.0f ? 100.0f : pev->health)) * tempFear; // retreat level depends on bot health
|
||||
float retreatLevel = (100.0f - (m_healthValue > 50.0f ? 100.0f : m_healthValue)) * tempFear; // retreat level depends on bot health
|
||||
|
||||
if (m_numEnemiesLeft > m_numFriendsLeft / 2 && m_retreatTime < game.time () && m_seeEnemyTime - rg.float_ (2.0f, 4.0f) < game.time ()) {
|
||||
|
||||
|
|
@ -2958,6 +2958,7 @@ void Bot::update () {
|
|||
m_canChooseAimDirection = true;
|
||||
m_notKilled = util.isAlive (ent ());
|
||||
m_team = game.getTeam (ent ());
|
||||
m_healthValue = cr::clamp (pev->health, 0.0f, 100.0f);
|
||||
|
||||
if (game.mapIs (MapFlags::Assassination) && !m_isVIP) {
|
||||
m_isVIP = util.isPlayerVIP (ent ());
|
||||
|
|
@ -5033,7 +5034,7 @@ void Bot::showDebugOverlay () {
|
|||
auto weapon = util.weaponIdToAlias (m_currentWeapon);
|
||||
|
||||
String debugData;
|
||||
debugData.assignf ("\n\n\n\n\n%s (H:%.1f/A:%.1f)- Task: %d=%s Desire:%.02f\nItem: %s Clip: %d Ammo: %d%s Money: %d AimFlags: %s\nSP=%.02f SSP=%.02f I=%d PG=%d G=%d T: %.02f MT: %d\nEnemy=%s Pickup=%s Type=%s\n", pev->netname.chars (), pev->health, pev->armorvalue, taskID, tasks[taskID], getTask ()->desire, weapon, getAmmoInClip (), getAmmo (), m_isReloading ? " (R)" : "", m_moneyAmount, aimFlags.trim (), m_moveSpeed, m_strafeSpeed, index, m_prevGoalIndex, goal, m_navTimeset - game.time (), pev->movetype, enemy, pickup, personalities[m_personality]);
|
||||
debugData.assignf ("\n\n\n\n\n%s (H:%.1f/A:%.1f)- Task: %d=%s Desire:%.02f\nItem: %s Clip: %d Ammo: %d%s Money: %d AimFlags: %s\nSP=%.02f SSP=%.02f I=%d PG=%d G=%d T: %.02f MT: %d\nEnemy=%s Pickup=%s Type=%s\n", pev->netname.chars (), m_healthValue, pev->armorvalue, taskID, tasks[taskID], getTask ()->desire, weapon, getAmmoInClip (), getAmmo (), m_isReloading ? " (R)" : "", m_moneyAmount, aimFlags.trim (), m_moveSpeed, m_strafeSpeed, index, m_prevGoalIndex, goal, m_navTimeset - game.time (), pev->movetype, enemy, pickup, personalities[m_personality]);
|
||||
|
||||
MessageWriter (MSG_ONE_UNRELIABLE, SVC_TEMPENTITY, nullptr, game.getLocalEntity ())
|
||||
.writeByte (TE_TEXTMESSAGE)
|
||||
|
|
@ -5117,7 +5118,7 @@ void Bot::takeDamage (edict_t *inflictor, int damage, int armor, int bits) {
|
|||
}
|
||||
else {
|
||||
// attacked by an enemy
|
||||
if (pev->health > 60.0f) {
|
||||
if (m_healthValue > 60.0f) {
|
||||
m_agressionLevel += 0.1f;
|
||||
|
||||
if (m_agressionLevel > 1.0f) {
|
||||
|
|
@ -5186,7 +5187,7 @@ void Bot::takeBlind (int alpha) {
|
|||
m_blindSidemoveSpeed = -pev->maxspeed;
|
||||
}
|
||||
|
||||
if (pev->health < 85.0f) {
|
||||
if (m_healthValue < 85.0f) {
|
||||
m_blindMoveSpeed = -pev->maxspeed;
|
||||
}
|
||||
else if (m_personality == Personality::Careful) {
|
||||
|
|
@ -5208,8 +5209,8 @@ void Bot::updatePracticeValue (int damage) {
|
|||
|
||||
// only rate goal waypoint if bot died because of the damage
|
||||
// FIXME: could be done a lot better, however this cares most about damage done by sniping or really deadly weapons
|
||||
if (pev->health - damage <= 0) {
|
||||
graph.setDangerValue (m_team, m_chosenGoalIndex, m_prevGoalIndex, cr::clamp (graph.getDangerValue (m_team, m_chosenGoalIndex, m_prevGoalIndex) - static_cast <int> (pev->health / 20), -kMaxPracticeGoalValue, kMaxPracticeGoalValue));
|
||||
if (m_healthValue - damage <= 0) {
|
||||
graph.setDangerValue (m_team, m_chosenGoalIndex, m_prevGoalIndex, cr::clamp (graph.getDangerValue (m_team, m_chosenGoalIndex, m_prevGoalIndex) - static_cast <int> (m_healthValue / 20), -kMaxPracticeGoalValue, kMaxPracticeGoalValue));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -5245,7 +5246,7 @@ void Bot::updatePracticeDamage (edict_t *attacker, int damage) {
|
|||
victimIndex = findNearestNode ();
|
||||
}
|
||||
|
||||
if (pev->health > 20.0f) {
|
||||
if (m_healthValue > 20.0f) {
|
||||
if (victimTeam == Team::Terrorist || victimTeam == Team::CT) {
|
||||
graph.setDangerDamage (victimIndex, victimIndex, victimIndex, cr::clamp (graph.getDangerDamage (victimTeam, victimIndex, victimIndex), 0, kMaxPracticeDamageValue));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -883,7 +883,7 @@ void Bot::fireWeapons () {
|
|||
}
|
||||
|
||||
// use knife if near and good difficulty (l33t dude!)
|
||||
if (cv_stab_close_enemies.bool_ () && m_difficulty >= Difficulty::Hard && pev->health > 80.0f && !game.isNullEntity (enemy) && pev->health >= enemy->v.health && distance < 100.0f && !isOnLadder () && !isGroupOfEnemies (pev->origin)) {
|
||||
if (cv_stab_close_enemies.bool_ () && m_difficulty >= Difficulty::Hard && m_healthValue > 80.0f && !game.isNullEntity (enemy) && m_healthValue >= enemy->v.health && distance < 100.0f && !isOnLadder () && !isGroupOfEnemies (pev->origin)) {
|
||||
selectWeapons (distance, selectIndex, selectId, choosenWeapon);
|
||||
return;
|
||||
}
|
||||
|
|
@ -1039,7 +1039,7 @@ void Bot::attackMovement () {
|
|||
approach = 29;
|
||||
}
|
||||
else {
|
||||
approach = static_cast <int> (pev->health * m_agressionLevel);
|
||||
approach = static_cast <int> (m_healthValue * m_agressionLevel);
|
||||
|
||||
if (usesSniper () && approach > 49) {
|
||||
approach = 49;
|
||||
|
|
|
|||
|
|
@ -754,9 +754,6 @@ int BotControl::cmdNodeUpload () {
|
|||
msg ("you may notice the game freezes a bit during upload and issue request creation. Please, be patient.");
|
||||
msg ("\n");
|
||||
|
||||
// six seconds is enough?
|
||||
http.setTimeout (6);
|
||||
|
||||
// try to upload the file
|
||||
if (http.uploadFile (strings.format ("http://%s/graph", product.download), strings.format ("%sgraph/%s.graph", graph.getDataDirectory (false), game.getMapName ()))) {
|
||||
msg ("Graph file was successfully validated and uploaded to the YaPB Graph DB (%s).", product.download);
|
||||
|
|
|
|||
|
|
@ -448,7 +448,7 @@ void Game::prepareBotArgs (edict_t *ent, String str) {
|
|||
}
|
||||
|
||||
// helper to parse single (not multi) command
|
||||
auto parsePartArgs = [&] (String &args) {
|
||||
auto parsePartArgs = [& ] (String &args) {
|
||||
args.trim ("\r\n\t\" "); // trim new lines
|
||||
|
||||
// we're have empty commands?
|
||||
|
|
@ -465,17 +465,17 @@ void Game::prepareBotArgs (edict_t *ent, String str) {
|
|||
|
||||
// check if we're got a quoted string
|
||||
if (quote < args.length () && args[quote] == '\"') {
|
||||
m_botArgs.push (cr::move (args.substr (0, space))); // add command
|
||||
m_botArgs.push (cr::move (args.substr (quote, args.length () - 1).trim ("\""))); // add string with trimmed quotes
|
||||
m_botArgs.emplace (args.substr (0, space)); // add command
|
||||
m_botArgs.emplace (args.substr (quote, args.length () - 1).trim ("\"")); // add string with trimmed quotes
|
||||
}
|
||||
else {
|
||||
for (auto &&arg : args.split (" ")) {
|
||||
m_botArgs.push (cr::move (arg));
|
||||
m_botArgs.emplace (arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
m_botArgs.push (cr::move (args)); // move all the part to args
|
||||
m_botArgs.emplace (args); // move all the part to args
|
||||
}
|
||||
MDLL_ClientCommand (ent);
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
ConVar cv_graph_fixcamp ("yb_graph_fixcamp", "1", "Specifies whether bot should not 'fix' camp directions of camp waypoints when loading old PWF format.");
|
||||
ConVar cv_graph_url ("yb_graph_url", product.download.chars (), "Specifies the URL from bots will be able to download graph in case of missing local one. Set to empty, if no downloads needed.", false, 0.0f, 0.0f);
|
||||
|
||||
void BotGraph::initGraph () {
|
||||
void BotGraph::reset () {
|
||||
// this function initialize the graph structures..
|
||||
|
||||
m_loadAttempts = 0;
|
||||
|
|
@ -1515,7 +1515,7 @@ bool BotGraph::convertOldFormat () {
|
|||
if (header.pointNumber == 0 || header.pointNumber > kMaxNodes) {
|
||||
return false;
|
||||
}
|
||||
initGraph ();
|
||||
reset ();
|
||||
m_paths.clear ();
|
||||
|
||||
for (int i = 0; i < header.pointNumber; ++i) {
|
||||
|
|
@ -1578,8 +1578,6 @@ template <typename U> bool BotGraph::saveStorage (StringRef ext, StringRef name,
|
|||
// no open no fun
|
||||
if (!file) {
|
||||
logger.error ("Unable to open %s file for writing (filename: '%s').", name, filename);
|
||||
file.close ();
|
||||
|
||||
return false;
|
||||
}
|
||||
int32 rawLength = data.template length <int32> () * sizeof (U);
|
||||
|
|
@ -1609,11 +1607,8 @@ template <typename U> bool BotGraph::saveStorage (StringRef ext, StringRef name,
|
|||
}
|
||||
else {
|
||||
logger.error ("Unable to compress %s data (filename: '%s').", name, filename);
|
||||
file.close ();
|
||||
|
||||
return false;
|
||||
}
|
||||
file.close ();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -1758,7 +1753,7 @@ template <typename U> bool BotGraph::loadStorage (StringRef ext, StringRef name,
|
|||
if ((hdr.options & StorageOption::Exten) && exten != nullptr) {
|
||||
file.read (exten, sizeof (ExtenHeader));
|
||||
}
|
||||
game.print ("Successfully loaded Bots %s data v%d.0 (%d/%.2fMB).", name, hdr.version, m_paths.length (), static_cast <float> (data.capacity () * sizeof (U)) / 1024.0f / 1024.0f);
|
||||
game.print ("Successfully loaded Bots %s data v%d (%d/%.2fMB).", name, hdr.version, m_paths.length (), static_cast <float> (data.capacity () * sizeof (U)) / 1024.0f / 1024.0f);
|
||||
file.close ();
|
||||
|
||||
return true;
|
||||
|
|
@ -1779,7 +1774,7 @@ bool BotGraph::loadGraphData () {
|
|||
bool dataLoaded = loadStorage <Path> ("graph", "Graph", StorageOption::Graph, StorageVersion::Graph, m_paths, &exten, &outOptions);
|
||||
|
||||
if (dataLoaded) {
|
||||
initGraph ();
|
||||
reset ();
|
||||
initBuckets ();
|
||||
|
||||
// add data to buckets
|
||||
|
|
@ -2783,7 +2778,7 @@ void BotGraph::eraseFromDisk () {
|
|||
logger.error ("Unable to open %s", item);
|
||||
}
|
||||
}
|
||||
initGraph (); // reintialize points
|
||||
reset (); // reintialize points
|
||||
m_paths.clear ();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ namespace variadic {
|
|||
vsnprintf (buffer, StringBuffer::StaticBufferSize, format, ap);
|
||||
va_end (ap);
|
||||
|
||||
if (ent && (ent->v.flags & (FL_FAKECLIENT | FL_DORMANT))) {
|
||||
if (util.isFakeClient (ent)) {
|
||||
auto bot = bots[ent];
|
||||
|
||||
if (bot) {
|
||||
|
|
@ -359,7 +359,7 @@ CR_EXPORT int GetEntityAPI (gamefuncs_t *table, int) {
|
|||
if (game.is (GameFlags::Xash3D)) {
|
||||
bots.kickEveryone (true, false);
|
||||
}
|
||||
graph.initGraph ();
|
||||
graph.reset ();
|
||||
|
||||
// clear all the bots
|
||||
bots.destroy ();
|
||||
|
|
|
|||
|
|
@ -1035,6 +1035,7 @@ Bot::Bot (edict_t *bot, int difficulty, int personality, int team, int member) {
|
|||
m_agressionLevel = m_baseAgressionLevel;
|
||||
m_fearLevel = m_baseFearLevel;
|
||||
m_nextEmotionUpdate = game.time () + 0.5f;
|
||||
m_healthValue = bot->v.health;
|
||||
|
||||
// just to be sure
|
||||
m_msgQueue.clear ();
|
||||
|
|
|
|||
|
|
@ -820,7 +820,7 @@ bool Bot::updateNavigation () {
|
|||
|
||||
// add goal values
|
||||
int goalValue = graph.getDangerValue (m_team, m_chosenGoalIndex, m_currentNodeIndex);
|
||||
int addedValue = static_cast <int> (pev->health * 0.5f + m_goalValue * 0.5f);
|
||||
int addedValue = static_cast <int> (m_healthValue * 0.5f + m_goalValue * 0.5f);
|
||||
|
||||
goalValue = cr::clamp (goalValue + addedValue, -kMaxPracticeGoalValue, kMaxPracticeGoalValue);
|
||||
|
||||
|
|
@ -1416,8 +1416,7 @@ void Bot::findPath (int srcIndex, int destIndex, FindPath pathType /*= FindPath:
|
|||
if (m_routeQue.length () >= kMaxRouteLength - 1) {
|
||||
logger.error ("A* Search for bot \"%s\" has tried to build path with at least %d nodes. Seems to be graph is broken.", pev->netname.chars (), m_routeQue.length ());
|
||||
|
||||
// bail out to shortest path
|
||||
findShortestPath (srcIndex, destIndex);
|
||||
kick (); // kick the bot off...
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue