Get rid of Visual Studio warnings.
Relicensed under the MIT license. Added safety checks here and there.
This commit is contained in:
parent
bee9653a71
commit
61fad287e7
48 changed files with 517 additions and 554 deletions
|
|
@ -1,10 +1,9 @@
|
|||
//
|
||||
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
|
||||
// Copyright (c) YaPB Development Team.
|
||||
// Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
|
||||
//
|
||||
// This software is licensed under the BSD-style license.
|
||||
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
|
||||
// https://yapb.ru/license
|
||||
// This software is licensed under the MIT license.
|
||||
// Additional exceptions apply. For full license details, see LICENSE.txt
|
||||
//
|
||||
|
||||
#include <yapb.h>
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
//
|
||||
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
|
||||
// Copyright (c) YaPB Development Team.
|
||||
// Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
|
||||
//
|
||||
// This software is licensed under the BSD-style license.
|
||||
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
|
||||
// https://yapb.ru/license
|
||||
// This software is licensed under the MIT license.
|
||||
// Additional exceptions apply. For full license details, see LICENSE.txt
|
||||
//
|
||||
|
||||
#include <yapb.h>
|
||||
|
|
@ -93,20 +92,20 @@ bool Bot::isInViewCone (const Vector &origin) {
|
|||
}
|
||||
|
||||
bool Bot::seesItem (const Vector &destination, const char *itemName) {
|
||||
TraceResult tr;
|
||||
TraceResult tr {};
|
||||
|
||||
// trace a line from bot's eyes to destination..
|
||||
game.testLine (getEyesPos (), destination, TraceIgnore::Monsters, ent (), &tr);
|
||||
|
||||
// check if line of sight to object is not blocked (i.e. visible)
|
||||
if (tr.flFraction != 1.0f) {
|
||||
if (tr.flFraction != 1.0f && tr.pHit) {
|
||||
return strcmp (tr.pHit->v.classname.chars (), itemName) == 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Bot::seesEntity (const Vector &dest, bool fromBody) {
|
||||
TraceResult tr;
|
||||
TraceResult tr {};
|
||||
|
||||
// trace a line from bot's eyes to destination...
|
||||
game.testLine (fromBody ? pev->origin : getEyesPos (), dest, TraceIgnore::Everything, ent (), &tr);
|
||||
|
|
@ -330,7 +329,7 @@ void Bot::avoidGrenades () {
|
|||
if (!seesEntity (pent->v.origin) && isInFOV (pent->v.origin - getEyesPos ()) > pev->fov * 0.5f) {
|
||||
continue;
|
||||
}
|
||||
auto model = pent->v.model.chars () + 9;
|
||||
auto model = pent->v.model.chars (9);
|
||||
|
||||
if (m_preventFlashing < game.time () && m_personality == Personality::Rusher && m_difficulty == 4 && strcmp (model, "flashbang.mdl") == 0) {
|
||||
// don't look at flash bang
|
||||
|
|
@ -428,7 +427,7 @@ void Bot::checkBreakablesAround () {
|
|||
edict_t *Bot::lookupBreakable () {
|
||||
// this function checks if bot is blocked by a shoot able breakable in his moving direction
|
||||
|
||||
TraceResult tr;
|
||||
TraceResult tr {};
|
||||
game.testLine (pev->origin, pev->origin + (m_destOrigin - pev->origin).normalize () * 72.0f, TraceIgnore::None, ent (), &tr);
|
||||
|
||||
if (tr.flFraction != 1.0f) {
|
||||
|
|
@ -539,7 +538,7 @@ void Bot::updatePickups () {
|
|||
}
|
||||
|
||||
auto classname = ent->v.classname.chars ();
|
||||
auto model = ent->v.model.chars () + 9;
|
||||
auto model = ent->v.model.chars (9);
|
||||
|
||||
// check if line of sight to object is not blocked (i.e. visible)
|
||||
if (seesItem (origin, classname)) {
|
||||
|
|
@ -830,7 +829,7 @@ void Bot::getCampDirection (Vector *dest) {
|
|||
// this function check if view on last enemy position is blocked - replace with better vector then
|
||||
// mostly used for getting a good camping direction vector if not camping on a camp waypoint
|
||||
|
||||
TraceResult tr;
|
||||
TraceResult tr {};
|
||||
const Vector &src = getEyesPos ();
|
||||
|
||||
game.testLine (src, *dest, TraceIgnore::Monsters, ent (), &tr);
|
||||
|
|
@ -1484,7 +1483,7 @@ void Bot::buyStuff () {
|
|||
break;
|
||||
|
||||
case BuyState::SecondaryWeapon: // if bot has still some money, buy a better secondary weapon
|
||||
if (isPistolMode || (isFirstRound && hasDefaultPistols) || (hasDefaultPistols && bots.getLastWinner () == m_team && m_moneyAmount > rg.int_ (3500, 4500)) || (hasPrimaryWeapon () && hasDefaultPistols && m_moneyAmount > rg.int_ (7500, 9000))) {
|
||||
if (isPistolMode || (isFirstRound && hasDefaultPistols) || (hasDefaultPistols && bots.getLastWinner () == m_team && m_moneyAmount > rg.int_ (2000, 3000)) || (hasPrimaryWeapon () && hasDefaultPistols && m_moneyAmount > rg.int_ (7500, 9000))) {
|
||||
do {
|
||||
pref--;
|
||||
|
||||
|
|
@ -2031,6 +2030,8 @@ void Bot::clearTasks () {
|
|||
}
|
||||
|
||||
void Bot::startTask (Task id, float desire, int data, float time, bool resume) {
|
||||
static const auto &filter = bots.getFilters ();
|
||||
|
||||
for (auto &task : m_tasks) {
|
||||
if (task.id == id) {
|
||||
if (!cr::fequal (task.desire, desire)) {
|
||||
|
|
@ -2039,7 +2040,7 @@ void Bot::startTask (Task id, float desire, int data, float time, bool resume) {
|
|||
return;
|
||||
}
|
||||
}
|
||||
m_tasks.emplace (id, desire, data, time, resume);
|
||||
m_tasks.emplace (filter[id].func, id, desire, data, time, resume);
|
||||
|
||||
clearSearchNodes ();
|
||||
ignoreCollision ();
|
||||
|
|
@ -2056,21 +2057,27 @@ void Bot::startTask (Task id, float desire, int data, float time, bool resume) {
|
|||
}
|
||||
|
||||
// this is best place to handle some voice commands report team some info
|
||||
if (rg.chance (90)) {
|
||||
if (tid == Task::Blind) {
|
||||
pushChatterMessage (Chatter::Blind);
|
||||
if (yb_radio_mode.int_ () > 1) {
|
||||
if (rg.chance (90)) {
|
||||
if (tid == Task::Blind) {
|
||||
pushChatterMessage (Chatter::Blind);
|
||||
}
|
||||
else if (tid == Task::PlantBomb) {
|
||||
pushChatterMessage (Chatter::PlantingBomb);
|
||||
}
|
||||
}
|
||||
else if (tid == Task::PlantBomb) {
|
||||
pushChatterMessage (Chatter::PlantingBomb);
|
||||
}
|
||||
}
|
||||
|
||||
if (rg.chance (25) && tid == Task::Camp) {
|
||||
if (game.mapIs (MapFlags::Demolition) && bots.isBombPlanted ()) {
|
||||
pushChatterMessage (Chatter::GuardingDroppedC4);
|
||||
if (rg.chance (25) && tid == Task::Camp) {
|
||||
if (game.mapIs (MapFlags::Demolition) && bots.isBombPlanted ()) {
|
||||
pushChatterMessage (Chatter::GuardingDroppedC4);
|
||||
}
|
||||
else {
|
||||
pushChatterMessage (Chatter::GoingToCamp);
|
||||
}
|
||||
}
|
||||
else {
|
||||
pushChatterMessage (Chatter::GoingToCamp);
|
||||
|
||||
if (rg.chance (75) && tid == Task::Camp && m_team == Team::Terrorist && m_inVIPZone) {
|
||||
pushChatterMessage (Chatter::GoingToGuardVIPSafety);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2080,15 +2087,11 @@ void Bot::startTask (Task id, float desire, int data, float time, bool resume) {
|
|||
else {
|
||||
m_chosenGoalIndex = getTask ()->data;
|
||||
}
|
||||
|
||||
if (rg.chance (75) && tid == Task::Camp && m_team == Team::Terrorist && m_inVIPZone) {
|
||||
pushChatterMessage (Chatter::GoingToGuardVIPSafety);
|
||||
}
|
||||
}
|
||||
|
||||
BotTask *Bot::getTask () {
|
||||
if (m_tasks.empty ()) {
|
||||
m_tasks.emplace (Task::Normal, TaskPri::Normal, kInvalidNodeIndex, 0.0f, true);
|
||||
startTask (Task::Normal, TaskPri::Normal, kInvalidNodeIndex, 0.0f, true);
|
||||
}
|
||||
return &m_tasks.last ();
|
||||
}
|
||||
|
|
@ -3200,7 +3203,7 @@ void Bot::spraypaint_ () {
|
|||
const auto &forward = pev->v_angle.forward ();
|
||||
Vector sprayOrigin = getEyesPos () + forward * 128.0f;
|
||||
|
||||
TraceResult tr;
|
||||
TraceResult tr {};
|
||||
game.testLine (getEyesPos (), sprayOrigin, TraceIgnore::Monsters, ent (), &tr);
|
||||
|
||||
// no wall in front?
|
||||
|
|
@ -3732,7 +3735,7 @@ void Bot::plantBomb_ () {
|
|||
}
|
||||
}
|
||||
|
||||
void Bot::bombDefuse_ () {
|
||||
void Bot::defuseBomb_ () {
|
||||
float fullDefuseTime = m_hasDefuser ? 7.0f : 12.0f;
|
||||
float timeToBlowUp = getBombTimeleft ();
|
||||
float defuseRemainingTime = fullDefuseTime;
|
||||
|
|
@ -3908,7 +3911,7 @@ void Bot::followUser_ () {
|
|||
}
|
||||
|
||||
if (m_targetEntity->v.button & IN_ATTACK) {
|
||||
TraceResult tr;
|
||||
TraceResult tr {};
|
||||
game.testLine (m_targetEntity->v.origin + m_targetEntity->v.view_ofs, m_targetEntity->v.v_angle.forward () * 500.0f, TraceIgnore::Everything, ent (), &tr);
|
||||
|
||||
if (!game.isNullEntity (tr.pHit) && util.isPlayer (tr.pHit) && game.getTeam (tr.pHit) != m_team) {
|
||||
|
|
@ -4201,7 +4204,7 @@ void Bot::doublejump_ () {
|
|||
const auto &src = pev->origin + Vector (0.0f, 0.0f, 45.0f);
|
||||
const auto &dest = src + Vector (0.0f, pev->angles.y, 0.0f).upward () * 256.0f;
|
||||
|
||||
TraceResult tr;
|
||||
TraceResult tr {};
|
||||
game.testLine (src, dest, TraceIgnore::None, ent (), &tr);
|
||||
|
||||
if (tr.flFraction < 1.0f && tr.pHit == m_doubleJumpEntity && inJump) {
|
||||
|
|
@ -4373,7 +4376,7 @@ void Bot::pickupItem_ () {
|
|||
auto &info = conf.getWeapons ();
|
||||
|
||||
for (index = 0; index < 7; ++index) {
|
||||
if (strcmp (info[index].model, m_pickupItem->v.model.chars () + 9) == 0) {
|
||||
if (strcmp (info[index].model, m_pickupItem->v.model.chars (9)) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -4536,108 +4539,15 @@ void Bot::pickupItem_ () {
|
|||
void Bot::executeTasks () {
|
||||
// this is core function that handle task execution
|
||||
|
||||
switch (getCurrentTaskId ()) {
|
||||
// normal task
|
||||
default:
|
||||
case Task::Normal:
|
||||
normal_ ();
|
||||
break;
|
||||
auto func = getTask ()->func;
|
||||
|
||||
// bot sprays messy logos all over the place...
|
||||
case Task::Spraypaint:
|
||||
spraypaint_ ();
|
||||
break;
|
||||
|
||||
// hunt down enemy
|
||||
case Task::Hunt:
|
||||
huntEnemy_ ();
|
||||
break;
|
||||
|
||||
// bot seeks cover from enemy
|
||||
case Task::SeekCover:
|
||||
seekCover_ ();
|
||||
break;
|
||||
|
||||
// plain attacking
|
||||
case Task::Attack:
|
||||
attackEnemy_ ();
|
||||
break;
|
||||
|
||||
// Bot is pausing
|
||||
case Task::Pause:
|
||||
pause_ ();
|
||||
break;
|
||||
|
||||
// blinded (flashbanged) behaviour
|
||||
case Task::Blind:
|
||||
blind_ ();
|
||||
break;
|
||||
|
||||
// camping behaviour
|
||||
case Task::Camp:
|
||||
camp_ ();
|
||||
break;
|
||||
|
||||
// hiding behaviour
|
||||
case Task::Hide:
|
||||
hide_ ();
|
||||
break;
|
||||
|
||||
// moves to a position specified in position has a higher priority than task_normal
|
||||
case Task::MoveToPosition:
|
||||
moveToPos_ ();
|
||||
break;
|
||||
|
||||
// planting the bomb right now
|
||||
case Task::PlantBomb:
|
||||
plantBomb_ ();
|
||||
break;
|
||||
|
||||
// bomb defusing behaviour
|
||||
case Task::DefuseBomb:
|
||||
bombDefuse_ ();
|
||||
break;
|
||||
|
||||
// follow user behaviour
|
||||
case Task::FollowUser:
|
||||
followUser_ ();
|
||||
break;
|
||||
|
||||
// HE grenade throw behaviour
|
||||
case Task::ThrowExplosive:
|
||||
throwExplosive_ ();
|
||||
break;
|
||||
|
||||
// flashbang throw behavior (basically the same code like for HE's)
|
||||
case Task::ThrowFlashbang:
|
||||
throwFlashbang_ ();
|
||||
break;
|
||||
|
||||
// smoke grenade throw behavior
|
||||
// a bit different to the others because it mostly tries to throw the sg on the ground
|
||||
case Task::ThrowSmoke:
|
||||
throwSmoke_ ();
|
||||
break;
|
||||
|
||||
// bot helps human player (or other bot) to get somewhere
|
||||
case Task::DoubleJump:
|
||||
doublejump_ ();
|
||||
break;
|
||||
|
||||
// escape from bomb behaviour
|
||||
case Task::EscapeFromBomb:
|
||||
escapeFromBomb_ ();
|
||||
break;
|
||||
|
||||
// shooting breakables in the way action
|
||||
case Task::ShootBreakable:
|
||||
shootBreakable_ ();
|
||||
break;
|
||||
|
||||
// picking up items and stuff behaviour
|
||||
case Task::PickupItem:
|
||||
pickupItem_ ();
|
||||
break;
|
||||
// run the current task
|
||||
if (func != nullptr) {
|
||||
(this->*func) ();
|
||||
}
|
||||
else {
|
||||
logger.error ("Missing callback function of Task %d.", getCurrentTaskId ());
|
||||
kick (); // drop the player, as it's fatal for bot
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -4737,6 +4647,9 @@ void Bot::logic () {
|
|||
if (canRunHeavyWeight ()) {
|
||||
setConditions ();
|
||||
}
|
||||
else if (!game.isNullEntity (m_enemy)) {
|
||||
trackEnemies ();
|
||||
}
|
||||
|
||||
// some stuff required by by chatter engine
|
||||
if (yb_radio_mode.int_ () == 2) {
|
||||
|
|
@ -5086,7 +4999,6 @@ void Bot::takeDamage (edict_t *inflictor, int damage, int armor, int bits) {
|
|||
m_enemyOrigin = m_enemy->v.origin;
|
||||
|
||||
pushChatMessage (Chat::TeamAttack);
|
||||
handleChatter ("#Bot_TeamAttack");
|
||||
pushChatterMessage (Chatter::FriendlyFire);
|
||||
}
|
||||
else {
|
||||
|
|
@ -5235,29 +5147,6 @@ void Bot::updatePracticeDamage (edict_t *attacker, int damage) {
|
|||
graph.setDangerDamage (m_team, victimIndex, attackerIndex, damageValue);
|
||||
}
|
||||
|
||||
void Bot::handleChatter (const char *tempMessage) {
|
||||
// this function is added to prevent engine crashes with: 'Message XX started, before message XX ended', or something.
|
||||
|
||||
if ((m_team == Team::CT && strcmp (tempMessage, "#CTs_Win") == 0) || (m_team == Team::Terrorist && strcmp (tempMessage, "#Terrorists_Win") == 0)) {
|
||||
if (bots.getRoundMidTime () > game.time ()) {
|
||||
pushChatterMessage (Chatter::QuickWonRound);
|
||||
}
|
||||
else {
|
||||
pushChatterMessage (Chatter::WonTheRound);
|
||||
}
|
||||
}
|
||||
|
||||
else if (strcmp (tempMessage, "#Bot_TeamAttack") == 0) {
|
||||
pushChatterMessage (Chatter::FriendlyFire);
|
||||
}
|
||||
else if (strcmp (tempMessage, "#Bot_NiceShotCommander") == 0) {
|
||||
pushChatterMessage (Chatter::NiceShotCommander);
|
||||
}
|
||||
else if (strcmp (tempMessage, "#Bot_NiceShotPall") == 0) {
|
||||
pushChatterMessage (Chatter::NiceShotPall);
|
||||
}
|
||||
}
|
||||
|
||||
void Bot::pushChatMessage (int type, bool isTeamSay) {
|
||||
if (!conf.hasChatBank (type) || !yb_chat.bool_ ()) {
|
||||
return;
|
||||
|
|
@ -5352,7 +5241,7 @@ Vector Bot::calcToss (const Vector &start, const Vector &stop) {
|
|||
// this function returns the velocity at which an object should looped from start to land near end.
|
||||
// returns null vector if toss is not feasible.
|
||||
|
||||
TraceResult tr;
|
||||
TraceResult tr {};
|
||||
float gravity = sv_gravity.float_ () * 0.55f;
|
||||
|
||||
Vector end = stop - pev->velocity;
|
||||
|
|
@ -5364,7 +5253,7 @@ Vector Bot::calcToss (const Vector &start, const Vector &stop) {
|
|||
Vector midPoint = start + (end - start) * 0.5f;
|
||||
game.testHull (midPoint, midPoint + Vector (0.0f, 0.0f, 500.0f), TraceIgnore::Monsters, head_hull, ent (), &tr);
|
||||
|
||||
if (tr.flFraction < 1.0f) {
|
||||
if (tr.flFraction < 1.0f && tr.pHit) {
|
||||
midPoint = tr.vecEndPos;
|
||||
midPoint.z = tr.pHit->v.absmin.z - 1.0f;
|
||||
}
|
||||
|
|
@ -5406,7 +5295,7 @@ Vector Bot::calcThrow (const Vector &start, const Vector &stop) {
|
|||
// returns null vector if throw is not feasible.
|
||||
|
||||
Vector velocity = stop - start;
|
||||
TraceResult tr;
|
||||
TraceResult tr {};
|
||||
|
||||
float gravity = sv_gravity.float_ () * 0.55f;
|
||||
float time = velocity.length () / 195.0f;
|
||||
|
|
@ -5444,7 +5333,7 @@ edict_t *Bot::correctGrenadeVelocity (const char *model) {
|
|||
edict_t *result = nullptr;
|
||||
|
||||
game.searchEntities ("classname", "grenade", [&] (edict_t *ent) {
|
||||
if (ent->v.owner == this->ent () && strcmp (ent->v.model.chars () + 9, model) == 0) {
|
||||
if (ent->v.owner == this->ent () && strcmp (ent->v.model.chars (9), model) == 0) {
|
||||
result = ent;
|
||||
|
||||
// set the correct velocity for the grenade
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
//
|
||||
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
|
||||
// Copyright (c) YaPB Development Team.
|
||||
// Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
|
||||
//
|
||||
// This software is licensed under the BSD-style license.
|
||||
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
|
||||
// https://yapb.ru/license
|
||||
// This software is licensed under the MIT license.
|
||||
// Additional exceptions apply. For full license details, see LICENSE.txt
|
||||
//
|
||||
|
||||
#include <yapb.h>
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
//
|
||||
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
|
||||
// Copyright (c) YaPB Development Team.
|
||||
// Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
|
||||
//
|
||||
// This software is licensed under the BSD-style license.
|
||||
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
|
||||
// https://yapb.ru/license
|
||||
// This software is licensed under the MIT license.
|
||||
// Additional exceptions apply. For full license details, see LICENSE.txt
|
||||
//
|
||||
|
||||
#include <yapb.h>
|
||||
|
|
@ -97,7 +96,7 @@ bool Bot::checkBodyParts (edict_t *target) {
|
|||
return false;
|
||||
}
|
||||
|
||||
TraceResult result;
|
||||
TraceResult result {};
|
||||
auto eyes = getEyesPos ();
|
||||
|
||||
auto spot = target->v.origin;
|
||||
|
|
@ -539,7 +538,7 @@ bool Bot::isFriendInLineOfFire (float distance) {
|
|||
return false;
|
||||
}
|
||||
|
||||
TraceResult tr;
|
||||
TraceResult tr {};
|
||||
game.testLine (getEyesPos (), getEyesPos () + distance * pev->v_angle.normalize (), TraceIgnore::None, ent (), &tr);
|
||||
|
||||
// check if we hit something
|
||||
|
|
@ -582,7 +581,7 @@ bool Bot::isPenetrableObstacle (const Vector &dest) {
|
|||
if (penetratePower == 0) {
|
||||
return false;
|
||||
}
|
||||
TraceResult tr;
|
||||
TraceResult tr {};
|
||||
|
||||
float obstacleDistance = 0.0f;
|
||||
game.testLine (getEyesPos (), dest, TraceIgnore::Monsters, ent (), &tr);
|
||||
|
|
@ -632,7 +631,7 @@ bool Bot::isPenetrableObstacle2 (const Vector &dest) {
|
|||
int numHits = 0;
|
||||
|
||||
Vector point;
|
||||
TraceResult tr;
|
||||
TraceResult tr {};
|
||||
|
||||
game.testLine (source, dest, TraceIgnore::Everything, ent (), &tr);
|
||||
|
||||
|
|
@ -1197,7 +1196,7 @@ bool Bot::hasSecondaryWeapon () {
|
|||
bool Bot::hasShield () {
|
||||
// this function returns true, if bot has a tactical shield
|
||||
|
||||
return strncmp (pev->viewmodel.chars (), "models/shield/v_shield_", 23) == 0;
|
||||
return strncmp (pev->viewmodel.chars (14), "v_shield_", 9) == 0;
|
||||
}
|
||||
|
||||
bool Bot::isShieldDrawn () {
|
||||
|
|
@ -1217,7 +1216,7 @@ bool Bot::isEnemyBehindShield (edict_t *enemy) {
|
|||
}
|
||||
|
||||
// check if enemy has shield and this shield is drawn
|
||||
if ((enemy->v.weaponanim == 6 || enemy->v.weaponanim == 7) && strncmp (enemy->v.viewmodel.chars (), "models/shield/v_shield_", 23) == 0) {
|
||||
if ((enemy->v.weaponanim == 6 || enemy->v.weaponanim == 7) && strncmp (enemy->v.viewmodel.chars (14), "v_shield_", 9) == 0) {
|
||||
if (util.isInViewCone (pev->origin, enemy)) {
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1356,7 +1355,7 @@ bool Bot::rateGroundWeapon (edict_t *ent) {
|
|||
auto tab = conf.getRawWeapons ();
|
||||
|
||||
for (int i = 0; i < kNumWeapons; ++i) {
|
||||
if (strcmp (tab[*pref].model, ent->v.model.chars () + 9) == 0) {
|
||||
if (strcmp (tab[*pref].model, ent->v.model.chars (9)) == 0) {
|
||||
groundIndex = i;
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
//
|
||||
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
|
||||
// Copyright (c) YaPB Development Team.
|
||||
// Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
|
||||
//
|
||||
// This software is licensed under the BSD-style license.
|
||||
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
|
||||
// https://yapb.ru/license
|
||||
// This software is licensed under the MIT license.
|
||||
// Additional exceptions apply. For full license details, see LICENSE.txt
|
||||
//
|
||||
|
||||
#include <yapb.h>
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
//
|
||||
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
|
||||
// Copyright (c) YaPB Development Team.
|
||||
// Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
|
||||
//
|
||||
// This software is licensed under the BSD-style license.
|
||||
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
|
||||
// https://yapb.ru/license
|
||||
// This software is licensed under the MIT license.
|
||||
// Additional exceptions apply. For full license details, see LICENSE.txt
|
||||
//
|
||||
|
||||
#include <yapb.h>
|
||||
|
|
@ -22,8 +21,8 @@ Game::Game () {
|
|||
m_precached = false;
|
||||
m_isBotCommand = false;
|
||||
|
||||
memset (m_drawModels, 0, sizeof (m_drawModels));
|
||||
memset (m_spawnCount, 0, sizeof (m_spawnCount));
|
||||
plat.bzero (m_drawModels, sizeof (m_drawModels));
|
||||
plat.bzero (m_spawnCount, sizeof (m_spawnCount));
|
||||
|
||||
m_gameFlags = 0;
|
||||
m_mapFlags = 0;
|
||||
|
|
@ -88,7 +87,7 @@ void Game::levelInitialize (edict_t *entities, int max) {
|
|||
util.installSendTo ();
|
||||
}
|
||||
else if (strcmp (classname, "player_weaponstrip") == 0) {
|
||||
if (is (GameFlags::Legacy) && ent->v.target.chars ()[0] == '\0') {
|
||||
if (is (GameFlags::Legacy) && strings.isEmpty (ent->v.target.chars ())) {
|
||||
ent->v.target = ent->v.targetname = engfuncs.pfnAllocString ("fake");
|
||||
}
|
||||
else {
|
||||
|
|
@ -256,7 +255,7 @@ float Game::getWaveLen (const char *fileName) {
|
|||
unsigned long dataChunkLength;
|
||||
} waveHdr;
|
||||
|
||||
memset (&waveHdr, 0, sizeof (waveHdr));
|
||||
plat.bzero (&waveHdr, sizeof (waveHdr));
|
||||
|
||||
if (fp.read (&waveHdr, sizeof (WavHeader)) == 0) {
|
||||
logger.error ("Wave File %s - has wrong or unsupported format", filePath);
|
||||
|
|
@ -465,6 +464,20 @@ bool Game::isSoftwareRenderer () {
|
|||
if (isDedicated ()) {
|
||||
return true;
|
||||
}
|
||||
auto model = illum.getWorldModel ();
|
||||
|
||||
if (model->nodes[0].parent != nullptr) {
|
||||
return false;
|
||||
}
|
||||
const auto child = model->nodes[0].children[0];
|
||||
|
||||
if (child < model->nodes || child > model->nodes + model->numnodes) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (child->parent != &model->nodes[0]) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// and on only windows version you can use software-render game. Linux, OSX always defaults to OpenGL
|
||||
if (plat.win32) {
|
||||
|
|
@ -476,7 +489,7 @@ bool Game::isSoftwareRenderer () {
|
|||
void Game::addNewCvar (const char *name, const char *value, const char *info, bool bounded, float min, float max, Var varType, bool missingAction, const char *regval, ConVar *self) {
|
||||
// this function adds globally defined variable to registration stack
|
||||
|
||||
VarPair pair;
|
||||
VarPair pair {};
|
||||
|
||||
pair.reg.name = const_cast <char *> (name);
|
||||
pair.reg.string = const_cast <char *> (value);
|
||||
|
|
@ -747,7 +760,7 @@ bool Game::postload () {
|
|||
if (is (GameFlags::Metamod)) {
|
||||
return true; // we should stop the attempt for loading the real gamedll, since metamod handle this for us
|
||||
}
|
||||
auto gamedll = strings.format ("%s/%s", getenv ("XASH3D_GAMELIBDIR"), plat.hfp ? "libserver_hardfp.so" : "libserver.so");
|
||||
auto gamedll = strings.format ("%s/%s", plat.env ("XASH3D_GAMELIBDIR"), plat.hfp ? "libserver_hardfp.so" : "libserver.so");
|
||||
|
||||
if (!m_gameLib.load (gamedll)) {
|
||||
logger.fatal ("Unable to load gamedll \"%s\". Exiting... (gamedir: %s)", gamedll, getModName ());
|
||||
|
|
@ -938,7 +951,7 @@ void LightMeasure::updateLight (int style, char *value) {
|
|||
return;
|
||||
}
|
||||
const auto copyLimit = sizeof (m_lightstyle[style].map) - sizeof ('\0');
|
||||
strncpy (m_lightstyle[style].map, value, copyLimit);
|
||||
strings.copy (m_lightstyle[style].map, value, copyLimit);
|
||||
|
||||
m_lightstyle[style].map[copyLimit] = '\0';
|
||||
m_lightstyle[style].length = strlen (m_lightstyle[style].map);
|
||||
|
|
@ -1072,7 +1085,7 @@ DynamicEntityLink::Handle DynamicEntityLink::search (Handle module, Name functio
|
|||
Handle ret = nullptr;
|
||||
|
||||
if (m_dlsym.disable ()) {
|
||||
ret = LookupSymbol (reinterpret_cast <CastType> (handle), function);
|
||||
ret = MODULE_SYMBOL (reinterpret_cast <MODULE_HANDLE> (handle), function);
|
||||
m_dlsym.enable ();
|
||||
}
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
//
|
||||
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
|
||||
// Copyright (c) YaPB Development Team.
|
||||
// Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
|
||||
//
|
||||
// This software is licensed under the BSD-style license.
|
||||
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
|
||||
// https://yapb.ru/license
|
||||
// This software is licensed under the MIT license.
|
||||
// Additional exceptions apply. For full license details, see LICENSE.txt
|
||||
//
|
||||
|
||||
#include <yapb.h>
|
||||
|
|
@ -637,7 +636,7 @@ void BotGraph::add (int type, const Vector &pos) {
|
|||
if (m_paths.length () >= kMaxNodes) {
|
||||
return;
|
||||
}
|
||||
m_paths.push (Path ());
|
||||
m_paths.push (Path {});
|
||||
|
||||
index = m_paths.length () - 1;
|
||||
path = &m_paths[index];
|
||||
|
|
@ -737,7 +736,7 @@ void BotGraph::add (int type, const Vector &pos) {
|
|||
float minDistance = kInfiniteDistance;
|
||||
int destIndex = kInvalidNodeIndex;
|
||||
|
||||
TraceResult tr;
|
||||
TraceResult tr {};
|
||||
|
||||
// calculate all the paths to this new node
|
||||
for (const auto &calc : m_paths) {
|
||||
|
|
@ -929,7 +928,7 @@ int BotGraph::getFacingIndex () {
|
|||
}
|
||||
|
||||
// check if visible, (we're not using visiblity tables here, as they not valid at time of waypoint editing)
|
||||
TraceResult tr;
|
||||
TraceResult tr {};
|
||||
game.testLine (editorEyes, path.origin, TraceIgnore::Everything, m_editor, &tr);
|
||||
|
||||
if (!cr::fequal (tr.flFraction, 1.0f)) {
|
||||
|
|
@ -1076,7 +1075,7 @@ void BotGraph::calculatePathRadius (int index) {
|
|||
return;
|
||||
}
|
||||
}
|
||||
TraceResult tr;
|
||||
TraceResult tr {};
|
||||
bool wayBlocked = false;
|
||||
|
||||
for (float scanDistance = 32.0f; scanDistance < 128.0f; scanDistance += 16.0f) {
|
||||
|
|
@ -1098,7 +1097,7 @@ void BotGraph::calculatePathRadius (int index) {
|
|||
if (tr.flFraction < 1.0f) {
|
||||
game.testLine (radiusStart, radiusEnd, TraceIgnore::Monsters, nullptr, &tr);
|
||||
|
||||
if (strncmp ("func_door", tr.pHit->v.classname.chars (), 9) == 0) {
|
||||
if (tr.pHit && strncmp ("func_door", tr.pHit->v.classname.chars (), 9) == 0) {
|
||||
path.radius = 0.0f;
|
||||
wayBlocked = true;
|
||||
|
||||
|
|
@ -1336,7 +1335,7 @@ bool BotGraph::convertOldFormat () {
|
|||
MemFile fp (getOldFormatGraphName (true));
|
||||
|
||||
PODGraphHeader header;
|
||||
memset (&header, 0, sizeof (header));
|
||||
plat.bzero (&header, sizeof (header));
|
||||
|
||||
// save for faster access
|
||||
const char *map = game.getMapName ();
|
||||
|
|
@ -1350,7 +1349,7 @@ bool BotGraph::convertOldFormat () {
|
|||
if (header.fileVersion != StorageVersion::Podbot) {
|
||||
return false;
|
||||
}
|
||||
else if (!plat.caseStrMatch (header.mapName, map)) {
|
||||
else if (!strings.matches (header.mapName, map)) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
|
|
@ -1693,9 +1692,9 @@ bool BotGraph::saveGraphData () {
|
|||
void BotGraph::saveOldFormat () {
|
||||
PODGraphHeader header {};
|
||||
|
||||
strcpy (header.header, kPodbotMagic);
|
||||
strncpy (header.author, m_editor->v.netname.chars (), cr::bufsize (header.author));
|
||||
strncpy (header.mapName, game.getMapName (), cr::bufsize (header.mapName));
|
||||
strings.copy (header.header, kPodbotMagic, sizeof (kPodbotMagic));
|
||||
strings.copy (header.author, m_editor->v.netname.chars (), cr::bufsize (header.author));
|
||||
strings.copy (header.mapName, game.getMapName (), cr::bufsize (header.mapName));
|
||||
|
||||
header.mapName[31] = 0;
|
||||
header.fileVersion = StorageVersion::Podbot;
|
||||
|
|
@ -1739,7 +1738,7 @@ float BotGraph::calculateTravelTime (float maxSpeed, const Vector &src, const Ve
|
|||
}
|
||||
|
||||
bool BotGraph::isNodeReacheable (const Vector &src, const Vector &destination) {
|
||||
TraceResult tr;
|
||||
TraceResult tr {};
|
||||
|
||||
float distance = (destination - src).length ();
|
||||
|
||||
|
|
@ -1751,7 +1750,7 @@ bool BotGraph::isNodeReacheable (const Vector &src, const Vector &destination) {
|
|||
// check if we go through a func_illusionary, in which case return false
|
||||
game.testHull (src, destination, TraceIgnore::Monsters, head_hull, m_editor, &tr);
|
||||
|
||||
if (!game.isNullEntity (tr.pHit) && strcmp ("func_illusionary", tr.pHit->v.classname.chars ()) == 0) {
|
||||
if (tr.pHit && strcmp ("func_illusionary", tr.pHit->v.classname.chars ()) == 0) {
|
||||
return false; // don't add pathnodes through func_illusionaries
|
||||
}
|
||||
|
||||
|
|
@ -1759,7 +1758,7 @@ bool BotGraph::isNodeReacheable (const Vector &src, const Vector &destination) {
|
|||
game.testLine (src, destination, TraceIgnore::Monsters, m_editor, &tr);
|
||||
|
||||
// if node is visible from current position (even behind head)...
|
||||
if (tr.flFraction >= 1.0f || strncmp ("func_door", tr.pHit->v.classname.chars (), 9) == 0) {
|
||||
if (tr.flFraction >= 1.0f || (tr.pHit && strncmp ("func_door", tr.pHit->v.classname.chars (), 9) == 0)) {
|
||||
// if it's a door check if nothing blocks behind
|
||||
if (strncmp ("func_door", tr.pHit->v.classname.chars (), 9) == 0) {
|
||||
game.testLine (tr.vecEndPos, destination, TraceIgnore::Monsters, tr.pHit, &tr);
|
||||
|
|
@ -1827,7 +1826,7 @@ void BotGraph::rebuildVisibility () {
|
|||
return;
|
||||
}
|
||||
|
||||
TraceResult tr;
|
||||
TraceResult tr {};
|
||||
uint8 res, shift;
|
||||
|
||||
for (const auto &vis : m_paths) {
|
||||
|
|
@ -2525,7 +2524,7 @@ void BotGraph::addBasic () {
|
|||
Vector ladderRight = ent->v.absmax;
|
||||
ladderLeft.z = ladderRight.z;
|
||||
|
||||
TraceResult tr;
|
||||
TraceResult tr {};
|
||||
Vector up, down, front, back;
|
||||
|
||||
const Vector &diff = ((ladderLeft - ladderRight) ^ Vector (0.0f, 0.0f, 0.0f)).normalize () * 15.0f;
|
||||
|
|
@ -2650,7 +2649,7 @@ void BotGraph::setBombOrigin (bool reset, const Vector &pos) {
|
|||
}
|
||||
|
||||
game.searchEntities ("classname", "grenade", [&] (edict_t *ent) {
|
||||
if (strcmp (ent->v.model.chars () + 9, "c4.mdl") == 0) {
|
||||
if (strcmp (ent->v.model.chars (9), "c4.mdl") == 0) {
|
||||
m_bombOrigin = game.getEntityWorldOrigin (ent);
|
||||
return EntitySearchResult::Break;
|
||||
}
|
||||
|
|
@ -2674,7 +2673,7 @@ void BotGraph::setSearchIndex (int index) {
|
|||
}
|
||||
|
||||
BotGraph::BotGraph () {
|
||||
memset (m_highestDamage, 0, sizeof (m_highestDamage));
|
||||
plat.bzero (m_highestDamage, sizeof (m_highestDamage));
|
||||
|
||||
m_endJumpPoint = false;
|
||||
m_needsVisRebuild = false;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
//
|
||||
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
|
||||
// Copyright (c) YaPB Development Team.
|
||||
//
|
||||
// This software is licensed under the BSD-style license.
|
||||
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
|
||||
// https://yapb.ru/license
|
||||
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
|
||||
// Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
|
||||
//
|
||||
// This software is licensed under the MIT license.
|
||||
// Additional exceptions apply. For full license details, see LICENSE.txt
|
||||
//
|
||||
|
||||
#include <yapb.h>
|
||||
|
|
@ -87,7 +86,7 @@ CR_EXPORT int GetEntityAPI2 (gamefuncs_t *table, int *) {
|
|||
// engine, and then calls the MOD DLL's version of GetEntityAPI to get the REAL gamedll
|
||||
// functions this time (to use in the bot code).
|
||||
|
||||
memset (table, 0, sizeof (gamefuncs_t));
|
||||
plat.bzero (table, sizeof (gamefuncs_t));
|
||||
|
||||
if (!(game.is (GameFlags::Metamod))) {
|
||||
auto api_GetEntityAPI = game.lib ().resolve <int (*) (gamefuncs_t *, int)> ("GetEntityAPI");
|
||||
|
|
@ -457,7 +456,7 @@ CR_LINKAGE_C int GetEntityAPI2_Post (gamefuncs_t *table, int *) {
|
|||
// engine, and then calls the MOD DLL's version of GetEntityAPI to get the REAL gamedll
|
||||
// functions this time (to use in the bot code). Post version, called only by metamod.
|
||||
|
||||
memset (table, 0, sizeof (gamefuncs_t));
|
||||
plat.bzero (table, sizeof (gamefuncs_t));
|
||||
|
||||
table->pfnSpawn = [] (edict_t *ent) {
|
||||
// this function asks the game DLL to spawn (i.e, give a physical existence in the virtual
|
||||
|
|
@ -505,7 +504,7 @@ CR_LINKAGE_C int GetEntityAPI2_Post (gamefuncs_t *table, int *) {
|
|||
|
||||
CR_LINKAGE_C int GetEngineFunctions (enginefuncs_t *table, int *) {
|
||||
if (game.is (GameFlags::Metamod)) {
|
||||
memset (table, 0, sizeof (enginefuncs_t));
|
||||
plat.bzero (table, sizeof (enginefuncs_t));
|
||||
}
|
||||
|
||||
table->pfnChangeLevel = [] (char *s1, char *s2) {
|
||||
|
|
@ -811,7 +810,7 @@ CR_EXPORT int GetNewDLLFunctions (newgamefuncs_t *table, int *interfaceVersion)
|
|||
}
|
||||
|
||||
CR_LINKAGE_C int GetEngineFunctions_Post (enginefuncs_t *table, int *) {
|
||||
memset (table, 0, sizeof (enginefuncs_t));
|
||||
plat.bzero (table, sizeof (enginefuncs_t));
|
||||
|
||||
table->pfnMessageEnd = [] () {
|
||||
msgs.stop (); // this allows us to send messages right in handler code
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
//
|
||||
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
|
||||
// Copyright (c) YaPB Development Team.
|
||||
// Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
|
||||
//
|
||||
// This software is licensed under the BSD-style license.
|
||||
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
|
||||
// https://yapb.ru/license
|
||||
// This software is licensed under the MIT license.
|
||||
// Additional exceptions apply. For full license details, see LICENSE.txt
|
||||
//
|
||||
|
||||
#include <yapb.h>
|
||||
|
|
@ -273,7 +272,7 @@ void BotManager::frame () {
|
|||
void BotManager::addbot (const String &name, int difficulty, int personality, int team, int member, bool manual) {
|
||||
// this function putting bot creation process to queue to prevent engine crashes
|
||||
|
||||
CreateQueue create;
|
||||
CreateQueue create {};
|
||||
|
||||
// fill the holder
|
||||
create.name = name;
|
||||
|
|
@ -290,7 +289,7 @@ void BotManager::addbot (const String &name, int difficulty, int personality, in
|
|||
void BotManager::addbot (const String &name, const String &difficulty, const String &personality, const String &team, const String &member, bool manual) {
|
||||
// this function is same as the function above, but accept as parameters string instead of integers
|
||||
|
||||
CreateQueue create;
|
||||
CreateQueue create {};
|
||||
const String &any = "*";
|
||||
|
||||
create.name = (name.empty () || name == any) ? String ("\0") : name;
|
||||
|
|
@ -358,10 +357,10 @@ void BotManager::maintainQuota () {
|
|||
int desiredBotCount = yb_quota.int_ ();
|
||||
int botsInGame = getBotCount ();
|
||||
|
||||
if (plat.caseStrMatch (yb_quota_mode.str (), "fill")) {
|
||||
if (strings.matches (yb_quota_mode.str (), "fill")) {
|
||||
botsInGame += humanPlayersInGame;
|
||||
}
|
||||
else if (plat.caseStrMatch (yb_quota_mode.str (), "match")) {
|
||||
else if (strings.matches (yb_quota_mode.str (), "match")) {
|
||||
int detectQuotaMatch = yb_quota_match.int_ () == 0 ? yb_quota.int_ () : yb_quota_match.int_ ();
|
||||
|
||||
desiredBotCount = cr::max <int> (0, detectQuotaMatch * humanPlayersInGame);
|
||||
|
|
@ -427,26 +426,26 @@ void BotManager::reset () {
|
|||
void BotManager::initFilters () {
|
||||
// table with all available actions for the bots (filtered in & out in bot::setconditions) some of them have subactions included
|
||||
|
||||
m_filters.emplace (Task::Normal, 0.0f, kInvalidNodeIndex, 0.0f, true);
|
||||
m_filters.emplace (Task::Pause, 0.0f, kInvalidNodeIndex, 0.0f, false);
|
||||
m_filters.emplace (Task::MoveToPosition, 0.0f, kInvalidNodeIndex, 0.0f, true);
|
||||
m_filters.emplace (Task::FollowUser, 0.0f, kInvalidNodeIndex, 0.0f, true);
|
||||
m_filters.emplace (Task::PickupItem, 0.0f, kInvalidNodeIndex, 0.0f, true);
|
||||
m_filters.emplace (Task::Camp, 0.0f, kInvalidNodeIndex, 0.0f, true);
|
||||
m_filters.emplace (Task::PlantBomb, 0.0f, kInvalidNodeIndex, 0.0f, false);
|
||||
m_filters.emplace (Task::DefuseBomb, 0.0f, kInvalidNodeIndex, 0.0f, false);
|
||||
m_filters.emplace (Task::Attack, 0.0f, kInvalidNodeIndex, 0.0f, false);
|
||||
m_filters.emplace (Task::Hunt, 0.0f, kInvalidNodeIndex, 0.0f, false);
|
||||
m_filters.emplace (Task::SeekCover, 0.0f, kInvalidNodeIndex, 0.0f, false);
|
||||
m_filters.emplace (Task::ThrowExplosive, 0.0f, kInvalidNodeIndex, 0.0f, false);
|
||||
m_filters.emplace (Task::ThrowFlashbang, 0.0f, kInvalidNodeIndex, 0.0f, false);
|
||||
m_filters.emplace (Task::ThrowSmoke, 0.0f, kInvalidNodeIndex, 0.0f, false);
|
||||
m_filters.emplace (Task::DoubleJump, 0.0f, kInvalidNodeIndex, 0.0f, false);
|
||||
m_filters.emplace (Task::EscapeFromBomb, 0.0f, kInvalidNodeIndex, 0.0f, false);
|
||||
m_filters.emplace (Task::ShootBreakable, 0.0f, kInvalidNodeIndex, 0.0f, false);
|
||||
m_filters.emplace (Task::Hide, 0.0f, kInvalidNodeIndex, 0.0f, false);
|
||||
m_filters.emplace (Task::Blind, 0.0f, kInvalidNodeIndex, 0.0f, false);
|
||||
m_filters.emplace (Task::Spraypaint, 0.0f, kInvalidNodeIndex, 0.0f, false);
|
||||
m_filters.emplace (&Bot::normal_, Task::Normal, 0.0f, kInvalidNodeIndex, 0.0f, true);
|
||||
m_filters.emplace (&Bot::pause_, Task::Pause, 0.0f, kInvalidNodeIndex, 0.0f, false);
|
||||
m_filters.emplace (&Bot::moveToPos_, Task::MoveToPosition, 0.0f, kInvalidNodeIndex, 0.0f, true);
|
||||
m_filters.emplace (&Bot::followUser_, Task::FollowUser, 0.0f, kInvalidNodeIndex, 0.0f, true);
|
||||
m_filters.emplace (&Bot::pickupItem_, Task::PickupItem, 0.0f, kInvalidNodeIndex, 0.0f, true);
|
||||
m_filters.emplace (&Bot::camp_, Task::Camp, 0.0f, kInvalidNodeIndex, 0.0f, true);
|
||||
m_filters.emplace (&Bot::plantBomb_, Task::PlantBomb, 0.0f, kInvalidNodeIndex, 0.0f, false);
|
||||
m_filters.emplace (&Bot::defuseBomb_, Task::DefuseBomb, 0.0f, kInvalidNodeIndex, 0.0f, false);
|
||||
m_filters.emplace (&Bot::attackEnemy_, Task::Attack, 0.0f, kInvalidNodeIndex, 0.0f, false);
|
||||
m_filters.emplace (&Bot::huntEnemy_, Task::Hunt, 0.0f, kInvalidNodeIndex, 0.0f, false);
|
||||
m_filters.emplace (&Bot::seekCover_, Task::SeekCover, 0.0f, kInvalidNodeIndex, 0.0f, false);
|
||||
m_filters.emplace (&Bot::throwExplosive_, Task::ThrowExplosive, 0.0f, kInvalidNodeIndex, 0.0f, false);
|
||||
m_filters.emplace (&Bot::throwFlashbang_, Task::ThrowFlashbang, 0.0f, kInvalidNodeIndex, 0.0f, false);
|
||||
m_filters.emplace (&Bot::throwSmoke_, Task::ThrowSmoke, 0.0f, kInvalidNodeIndex, 0.0f, false);
|
||||
m_filters.emplace (&Bot::doublejump_, Task::DoubleJump, 0.0f, kInvalidNodeIndex, 0.0f, false);
|
||||
m_filters.emplace (&Bot::escapeFromBomb_, Task::EscapeFromBomb, 0.0f, kInvalidNodeIndex, 0.0f, false);
|
||||
m_filters.emplace (&Bot::shootBreakable_, Task::ShootBreakable, 0.0f, kInvalidNodeIndex, 0.0f, false);
|
||||
m_filters.emplace (&Bot::hide_, Task::Hide, 0.0f, kInvalidNodeIndex, 0.0f, false);
|
||||
m_filters.emplace (&Bot::blind_, Task::Blind, 0.0f, kInvalidNodeIndex, 0.0f, false);
|
||||
m_filters.emplace (&Bot::spraypaint_, Task::Spraypaint, 0.0f, kInvalidNodeIndex, 0.0f, false);
|
||||
}
|
||||
|
||||
void BotManager::resetFilters () {
|
||||
|
|
@ -619,6 +618,26 @@ bool BotManager::kickRandom (bool decQuota, Team fromTeam) {
|
|||
return false;
|
||||
}
|
||||
|
||||
void BotManager::setLastWinner (int winner) {
|
||||
m_lastWinner = winner;
|
||||
|
||||
if (yb_radio_mode.int_ () != 2) {
|
||||
return;
|
||||
}
|
||||
auto notify = findAliveBot ();
|
||||
|
||||
if (notify) {
|
||||
if (notify->m_team == winner) {
|
||||
if (getRoundMidTime () > game.time ()) {
|
||||
notify->pushChatterMessage (Chatter::QuickWonRound);
|
||||
}
|
||||
else {
|
||||
notify->pushChatterMessage (Chatter::WonTheRound);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BotManager::setWeaponMode (int selection) {
|
||||
// this function sets bots weapon mode
|
||||
|
||||
|
|
@ -785,12 +804,13 @@ void BotManager::destroy () {
|
|||
}
|
||||
|
||||
Bot::Bot (edict_t *bot, int difficulty, int personality, int team, int member) {
|
||||
// this function does core operation of creating bot, it's called by CreateBot (),
|
||||
// this function does core operation of creating bot, it's called by addbot (),
|
||||
// when bot setup completed, (this is a bot class constructor)
|
||||
|
||||
int clientIndex = game.indexOfEntity (bot);
|
||||
// we're not initializing all the variables in bot class, so do an ugly thing... memset this
|
||||
plat.bzero (this, sizeof (*this));
|
||||
|
||||
memset (reinterpret_cast <void *> (this), 0, sizeof (*this));
|
||||
int clientIndex = game.indexOfEntity (bot);
|
||||
pev = &bot->v;
|
||||
|
||||
if (bot->pvPrivateData != nullptr) {
|
||||
|
|
@ -881,8 +901,8 @@ Bot::Bot (edict_t *bot, int difficulty, int personality, int team, int member) {
|
|||
break;
|
||||
}
|
||||
|
||||
memset (&m_ammoInClip, 0, sizeof (m_ammoInClip));
|
||||
memset (&m_ammo, 0, sizeof (m_ammo));
|
||||
plat.bzero (&m_ammoInClip, sizeof (m_ammoInClip));
|
||||
plat.bzero (&m_ammo, sizeof (m_ammo));
|
||||
|
||||
m_currentWeapon = 0; // current weapon is not assigned at start
|
||||
m_voicePitch = rg.int_ (80, 115); // assign voice pitch
|
||||
|
|
@ -975,10 +995,10 @@ void BotManager::handleDeath (edict_t *killer, edict_t *victim) {
|
|||
for (const auto ¬ify : bots) {
|
||||
if (notify->m_notKilled && killerTeam == notify->m_team && killerTeam != victimTeam && killer != notify->ent () && notify->seesEntity (victim->v.origin)) {
|
||||
if (!(killer->v.flags & FL_FAKECLIENT)) {
|
||||
notify->handleChatter ("#Bot_NiceShotCommander");
|
||||
notify->pushChatterMessage (Chatter::NiceShotCommander);
|
||||
}
|
||||
else {
|
||||
notify->handleChatter ("#Bot_NiceShotPall");
|
||||
notify->pushChatterMessage (Chatter::NiceShotPall);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -1179,8 +1199,8 @@ void Bot::newRound () {
|
|||
|
||||
// if bot died, clear all weapon stuff and force buying again
|
||||
if (!m_notKilled) {
|
||||
memset (&m_ammoInClip, 0, sizeof (m_ammoInClip));
|
||||
memset (&m_ammo, 0, sizeof (m_ammo));
|
||||
plat.bzero (&m_ammoInClip, sizeof (m_ammoInClip));
|
||||
plat.bzero (&m_ammo, sizeof (m_ammo));
|
||||
|
||||
m_currentWeapon = 0;
|
||||
}
|
||||
|
|
@ -1339,7 +1359,7 @@ void BotManager::captureChatRadio (const char *cmd, const char *arg, edict_t *en
|
|||
return;
|
||||
}
|
||||
|
||||
if (plat.caseStrMatch (cmd, "say") || plat.caseStrMatch (cmd, "say_team")) {
|
||||
if (strings.matches (cmd, "say") || strings.matches (cmd, "say_team")) {
|
||||
bool alive = util.isAlive (ent);
|
||||
int team = -1;
|
||||
|
||||
|
|
@ -1414,7 +1434,7 @@ void BotManager::updateActiveGrenade () {
|
|||
// search the map for any type of grenade
|
||||
game.searchEntities ("classname", "grenade", [&] (edict_t *e) {
|
||||
// do not count c4 as a grenade
|
||||
if (strcmp (e->v.model.chars () + 9, "c4.mdl") == 0) {
|
||||
if (strcmp (e->v.model.chars (9), "c4.mdl") == 0) {
|
||||
return EntitySearchResult::Continue;
|
||||
}
|
||||
m_activeGrenades.push (e);
|
||||
|
|
@ -1668,10 +1688,10 @@ void BotConfig::loadMainConfig () {
|
|||
if (cvar != nullptr) {
|
||||
auto value = const_cast <char *> (keyval[1].trim ().trim ("\"").trim ().chars ());
|
||||
|
||||
if (needsToIgnoreVar (ignore, key) && !plat.caseStrMatch (value, cvar->string)) {
|
||||
if (needsToIgnoreVar (ignore, key) && !strings.matches (value, cvar->string)) {
|
||||
|
||||
// preserve quota number if it's zero
|
||||
if (plat.caseStrMatch (cvar->name, "yb_quota") && yb_quota.int_ () <= 0) {
|
||||
if (strings.matches (cvar->name, "yb_quota") && yb_quota.int_ () <= 0) {
|
||||
engfuncs.pfnCvar_DirectSet (cvar, value);
|
||||
continue;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
//
|
||||
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
|
||||
// Copyright (c) YaPB Development Team.
|
||||
// Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
|
||||
//
|
||||
// This software is licensed under the BSD-style license.
|
||||
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
|
||||
// https://yapb.ru/license
|
||||
// This software is licensed under the MIT license.
|
||||
// Additional exceptions apply. For full license details, see LICENSE.txt
|
||||
//
|
||||
|
||||
#include <yapb.h>
|
||||
|
|
@ -17,18 +16,6 @@ void MessageDispatcher::netMsgTextMsg () {
|
|||
return;
|
||||
}
|
||||
|
||||
// bots chatter notification
|
||||
const auto dispatchChatterMessage = [&] () -> void {
|
||||
if (yb_radio_mode.int_ () == 2) {
|
||||
auto notify = bots.findAliveBot ();
|
||||
|
||||
if (notify && notify->m_notKilled) {
|
||||
notify->handleChatter (m_args[msg].chars_);
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// lookup cached message
|
||||
auto cached = m_textMsgCache[m_args[msg].chars_];
|
||||
|
||||
|
|
@ -50,8 +37,6 @@ void MessageDispatcher::netMsgTextMsg () {
|
|||
}
|
||||
else if (cached & TextMsgCache::CounterWin) {
|
||||
bots.setLastWinner (Team::CT); // update last winner for economics
|
||||
dispatchChatterMessage ();
|
||||
|
||||
resetBombPosition ();
|
||||
}
|
||||
else if (cached & TextMsgCache::RestartRound) {
|
||||
|
|
@ -70,8 +55,6 @@ void MessageDispatcher::netMsgTextMsg () {
|
|||
}
|
||||
else if (cached & TextMsgCache::TerroristWin) {
|
||||
bots.setLastWinner (Team::Terrorist); // update last winner for economics
|
||||
dispatchChatterMessage ();
|
||||
|
||||
resetBombPosition ();
|
||||
}
|
||||
else if ((cached & TextMsgCache::BombPlanted) && !bots.isBombPlanted ()) {
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
//
|
||||
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
|
||||
// Copyright (c) YaPB Development Team.
|
||||
//
|
||||
// This software is licensed under the BSD-style license.
|
||||
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
|
||||
// https://yapb.ru/license
|
||||
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
|
||||
// Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
|
||||
//
|
||||
// This software is licensed under the MIT license.
|
||||
// Additional exceptions apply. For full license details, see LICENSE.txt
|
||||
//
|
||||
|
||||
#include <yapb.h>
|
||||
|
|
@ -19,7 +18,7 @@ int Bot::findBestGoal () {
|
|||
int result = kInvalidNodeIndex;
|
||||
|
||||
game.searchEntities ("classname", "weaponbox", [&] (edict_t *ent) {
|
||||
if (strcmp (ent->v.model.chars () + 9, "backpack.mdl") == 0) {
|
||||
if (strcmp (ent->v.model.chars (9), "backpack.mdl") == 0) {
|
||||
result = graph.getNearest (game.getEntityWorldOrigin (ent));
|
||||
|
||||
if (graph.exists (result)) {
|
||||
|
|
@ -361,7 +360,7 @@ void Bot::checkTerrain (float movedDistance, const Vector &dirNormal) {
|
|||
m_isStuck = false;
|
||||
|
||||
// if avoiding someone do not consider stuck
|
||||
TraceResult tr;
|
||||
TraceResult tr {};
|
||||
doPlayerAvoidance (dirNormal);
|
||||
|
||||
// Standing still, no need to check?
|
||||
|
|
@ -702,7 +701,7 @@ bool Bot::updateNavigation () {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
TraceResult tr;
|
||||
TraceResult tr {};
|
||||
|
||||
// check if we are going through a door...
|
||||
if (game.mapIs (MapFlags::HasDoors)) {
|
||||
|
|
@ -849,7 +848,7 @@ bool Bot::updateLiftHandling () {
|
|||
// update node time set
|
||||
m_navTimeset = game.time ();
|
||||
|
||||
TraceResult tr;
|
||||
TraceResult tr {};
|
||||
|
||||
// wait for something about for lift
|
||||
auto wait = [&] () {
|
||||
|
|
@ -867,7 +866,7 @@ bool Bot::updateLiftHandling () {
|
|||
// trace line to door
|
||||
game.testLine (pev->origin, m_path->origin, TraceIgnore::Everything, ent (), &tr);
|
||||
|
||||
if (tr.flFraction < 1.0f && strcmp (tr.pHit->v.classname.chars (), "func_door") == 0 && (m_liftState == LiftState::None || m_liftState == LiftState::WaitingFor || m_liftState == LiftState::LookingButtonOutside) && pev->groundentity != tr.pHit) {
|
||||
if (tr.flFraction < 1.0f && tr.pHit && strcmp (tr.pHit->v.classname.chars (), "func_door") == 0 && (m_liftState == LiftState::None || m_liftState == LiftState::WaitingFor || m_liftState == LiftState::LookingButtonOutside) && pev->groundentity != tr.pHit) {
|
||||
if (m_liftState == LiftState::None) {
|
||||
m_liftState = LiftState::LookingButtonOutside;
|
||||
m_liftUsageTime = game.time () + 7.0f;
|
||||
|
|
@ -1817,7 +1816,7 @@ int Bot::findDefendNode (const Vector &origin) {
|
|||
if (m_currentNodeIndex == kInvalidNodeIndex) {
|
||||
m_currentNodeIndex = changePointIndex (findNearestNode ());
|
||||
}
|
||||
TraceResult tr;
|
||||
TraceResult tr {};
|
||||
|
||||
int nodeIndex[kMaxNodeLinks];
|
||||
int minDistance[kMaxNodeLinks];
|
||||
|
|
@ -2016,7 +2015,7 @@ int Bot::findCoverNode (float maxDistance) {
|
|||
}
|
||||
} while (sorting);
|
||||
|
||||
TraceResult tr;
|
||||
TraceResult tr {};
|
||||
|
||||
// take the first one which isn't spotted by the enemy
|
||||
for (const auto &index : nodeIndex) {
|
||||
|
|
@ -2073,7 +2072,7 @@ bool Bot::advanceMovement () {
|
|||
if (m_pathWalk.empty ()) {
|
||||
return false;
|
||||
}
|
||||
TraceResult tr;
|
||||
TraceResult tr {};
|
||||
|
||||
m_pathWalk.shift (); // advance in list
|
||||
m_currentTravelFlags = 0; // reset travel flags (jumping etc)
|
||||
|
|
@ -2392,7 +2391,7 @@ bool Bot::canStrafeRight (TraceResult *tr) {
|
|||
bool Bot::canJumpUp (const Vector &normal) {
|
||||
// this function check if bot can jump over some obstacle
|
||||
|
||||
TraceResult tr;
|
||||
TraceResult tr {};
|
||||
|
||||
// can't jump if not on ground and not on ladder/swimming
|
||||
if (!isOnFloor () && (isOnLadder () || !isInWater ())) {
|
||||
|
|
@ -2472,7 +2471,7 @@ bool Bot::doneCanJumpUp (const Vector &normal, const Vector &right) {
|
|||
Vector src = pev->origin + Vector (0.0f, 0.0f, -36.0f + 63.0f);
|
||||
Vector dest = src + normal * 32.0f;
|
||||
|
||||
TraceResult tr;
|
||||
TraceResult tr {};
|
||||
|
||||
// trace a line forward at maximum jump height...
|
||||
game.testLine (src, dest, TraceIgnore::Monsters, ent (), &tr);
|
||||
|
|
@ -2541,7 +2540,7 @@ bool Bot::doneCanJumpUp (const Vector &normal, const Vector &right) {
|
|||
bool Bot::canDuckUnder (const Vector &normal) {
|
||||
// this function check if bot can duck under obstacle
|
||||
|
||||
TraceResult tr;
|
||||
TraceResult tr {};
|
||||
Vector baseHeight;
|
||||
|
||||
// use center of the body first...
|
||||
|
|
@ -2590,7 +2589,7 @@ bool Bot::canDuckUnder (const Vector &normal) {
|
|||
}
|
||||
|
||||
bool Bot::isBlockedLeft () {
|
||||
TraceResult tr;
|
||||
TraceResult tr {};
|
||||
float direction = 48.0f;
|
||||
|
||||
if (m_moveSpeed < 0.0f) {
|
||||
|
|
@ -2603,14 +2602,14 @@ bool Bot::isBlockedLeft () {
|
|||
game.testLine (pev->origin, forward * direction - right * 48.0f, TraceIgnore::Monsters, ent (), &tr);
|
||||
|
||||
// check if the trace hit something...
|
||||
if (game.mapIs (MapFlags::HasDoors) && tr.flFraction < 1.0f && strncmp ("func_door", tr.pHit->v.classname.chars (), 9) != 0) {
|
||||
if (game.mapIs (MapFlags::HasDoors) && tr.flFraction < 1.0f && tr.pHit && strncmp ("func_door", tr.pHit->v.classname.chars (), 9) != 0) {
|
||||
return true; // bot's body will hit something
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Bot::isBlockedRight () {
|
||||
TraceResult tr;
|
||||
TraceResult tr {};
|
||||
float direction = 48.0f;
|
||||
|
||||
if (m_moveSpeed < 0.0f) {
|
||||
|
|
@ -2623,14 +2622,14 @@ bool Bot::isBlockedRight () {
|
|||
game.testLine (pev->origin, pev->origin + forward * direction + right * 48.0f, TraceIgnore::Monsters, ent (), &tr);
|
||||
|
||||
// check if the trace hit something...
|
||||
if (game.mapIs (MapFlags::HasDoors) && tr.flFraction < 1.0f && (strncmp ("func_door", tr.pHit->v.classname.chars (), 9) != 0)) {
|
||||
if (game.mapIs (MapFlags::HasDoors) && tr.flFraction < 1.0f && tr.pHit && strncmp ("func_door", tr.pHit->v.classname.chars (), 9) != 0) {
|
||||
return true; // bot's body will hit something
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Bot::checkWallOnLeft () {
|
||||
TraceResult tr;
|
||||
TraceResult tr {};
|
||||
game.testLine (pev->origin, pev->origin - pev->angles.right () * 40.0f, TraceIgnore::Monsters, ent (), &tr);
|
||||
|
||||
// check if the trace hit something...
|
||||
|
|
@ -2641,7 +2640,7 @@ bool Bot::checkWallOnLeft () {
|
|||
}
|
||||
|
||||
bool Bot::checkWallOnRight () {
|
||||
TraceResult tr;
|
||||
TraceResult tr {};
|
||||
|
||||
// do a trace to the right...
|
||||
game.testLine (pev->origin, pev->origin + pev->angles.right () * 40.0f, TraceIgnore::Monsters, ent (), &tr);
|
||||
|
|
@ -2656,7 +2655,7 @@ bool Bot::checkWallOnRight () {
|
|||
bool Bot::isDeadlyMove (const Vector &to) {
|
||||
// this function eturns if given location would hurt Bot with falling damage
|
||||
|
||||
TraceResult tr;
|
||||
TraceResult tr {};
|
||||
const auto &direction = (to - pev->origin).normalize (); // 1 unit long
|
||||
|
||||
Vector check = to, down = to;
|
||||
|
|
@ -2984,7 +2983,7 @@ int Bot::getNearestToPlantedBomb () {
|
|||
|
||||
// search the bomb on the map
|
||||
game.searchEntities ("classname", "grenade", [&result] (edict_t *ent) {
|
||||
if (strcmp (ent->v.model.chars () + 9, "c4.mdl") == 0) {
|
||||
if (strcmp (ent->v.model.chars (9), "c4.mdl") == 0) {
|
||||
result = graph.getNearest (game.getEntityWorldOrigin (ent));
|
||||
|
||||
if (graph.exists (result)) {
|
||||
|
|
@ -3077,7 +3076,7 @@ bool Bot::isReachableNode (int index) {
|
|||
}
|
||||
float ladderDist = (dst - src).length2d ();
|
||||
|
||||
TraceResult tr;
|
||||
TraceResult tr {};
|
||||
game.testLine (src, dst, TraceIgnore::Monsters, ent (), &tr);
|
||||
|
||||
// if node is visible from current position (even behind head)...
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
|
||||
// Copyright (c) YaPB Development Team.
|
||||
//
|
||||
// This software is licensed under the BSD-style license.
|
||||
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
|
||||
// https://yapb.ru/license
|
||||
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
|
||||
// Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
|
||||
//
|
||||
// This software is licensed under the MIT license.
|
||||
// Additional exceptions apply. For full license details, see LICENSE.txt
|
||||
//
|
||||
|
||||
#include <yapb.h>
|
||||
|
|
@ -115,7 +115,7 @@ bool BotUtils::isVisible (const Vector &origin, edict_t *ent) {
|
|||
if (game.isNullEntity (ent)) {
|
||||
return false;
|
||||
}
|
||||
TraceResult tr;
|
||||
TraceResult tr {};
|
||||
game.testLine (ent->v.origin + ent->v.view_ofs, origin, TraceIgnore::Everything, ent, &tr);
|
||||
|
||||
if (tr.flFraction != 1.0f) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue