fix: code formatting
This commit is contained in:
parent
290681d2d8
commit
2718adbb8f
13 changed files with 206 additions and 208 deletions
|
|
@ -14,7 +14,7 @@ struct BotName {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BotName () = default;
|
BotName () = default;
|
||||||
BotName (StringRef name, int usedBy) : name (name), usedBy (usedBy) { }
|
BotName (StringRef name, int usedBy) : name (name), usedBy (usedBy) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// voice config structure definition
|
// voice config structure definition
|
||||||
|
|
@ -24,7 +24,7 @@ struct ChatterItem {
|
||||||
float duration;
|
float duration;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ChatterItem (StringRef name, float repeat, float duration) : name (name), repeat (repeat), duration (duration) { }
|
ChatterItem (StringRef name, float repeat, float duration) : name (name), repeat (repeat), duration (duration) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// mostly config stuff, and some stuff dealing with menus
|
// mostly config stuff, and some stuff dealing with menus
|
||||||
|
|
@ -112,7 +112,7 @@ public:
|
||||||
void clearUsedName (Bot *bot);
|
void clearUsedName (Bot *bot);
|
||||||
|
|
||||||
// set the bot names as used
|
// set the bot names as used
|
||||||
void setBotNameUsed(const int index, StringRef name);
|
void setBotNameUsed (const int index, StringRef name);
|
||||||
|
|
||||||
// initialize weapon info
|
// initialize weapon info
|
||||||
void initWeapons ();
|
void initWeapons ();
|
||||||
|
|
|
||||||
|
|
@ -576,7 +576,7 @@ void Bot::updatePickups () {
|
||||||
|
|
||||||
// get the entity origin
|
// get the entity origin
|
||||||
const auto &origin = game.getEntityOrigin (ent);
|
const auto &origin = game.getEntityOrigin (ent);
|
||||||
|
|
||||||
if ((ent->v.effects & EF_NODRAW) || ent == m_itemIgnore || cr::abs (origin.z - pev->origin.z) > 96.0f) {
|
if ((ent->v.effects & EF_NODRAW) || ent == m_itemIgnore || cr::abs (origin.z - pev->origin.z) > 96.0f) {
|
||||||
continue; // someone owns this weapon or it hasn't respawned yet
|
continue; // someone owns this weapon or it hasn't respawned yet
|
||||||
}
|
}
|
||||||
|
|
@ -620,7 +620,7 @@ void Bot::updatePickups () {
|
||||||
pickupType = Pickup::None;
|
pickupType = Pickup::None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the bot found something it can pickup...
|
// if the bot found something it can pickup...
|
||||||
if (allowPickup) {
|
if (allowPickup) {
|
||||||
|
|
||||||
|
|
@ -640,7 +640,7 @@ void Bot::updatePickups () {
|
||||||
}
|
}
|
||||||
else if (!m_isVIP && primaryWeaponCarried >= 7 && (m_ammo[primary.id] > 0.3 * primaryProp.ammo1Max) && strncmp (model, "w_", 2) == 0) {
|
else if (!m_isVIP && primaryWeaponCarried >= 7 && (m_ammo[primary.id] > 0.3 * primaryProp.ammo1Max) && strncmp (model, "w_", 2) == 0) {
|
||||||
auto weaponType = conf.getWeaponType (primaryWeaponCarried);
|
auto weaponType = conf.getWeaponType (primaryWeaponCarried);
|
||||||
|
|
||||||
const bool isSniperRifle = weaponType == WeaponType::Sniper;
|
const bool isSniperRifle = weaponType == WeaponType::Sniper;
|
||||||
const bool isSubmachine = weaponType == WeaponType::SMG;
|
const bool isSubmachine = weaponType == WeaponType::SMG;
|
||||||
const bool isShotgun = weaponType == WeaponType::Shotgun;
|
const bool isShotgun = weaponType == WeaponType::Shotgun;
|
||||||
|
|
@ -826,7 +826,7 @@ void Bot::updatePickups () {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pev->origin.distanceSq (origin) > cr::square (60.0f)) {
|
if (pev->origin.distanceSq (origin) > cr::square (60.0f)) {
|
||||||
|
|
||||||
if (!graph.isNodeReacheable (pev->origin, origin)) {
|
if (!graph.isNodeReacheable (pev->origin, origin)) {
|
||||||
allowPickup = false;
|
allowPickup = false;
|
||||||
}
|
}
|
||||||
|
|
@ -946,7 +946,7 @@ void Bot::showChaterIcon (bool show) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto sendBotVoice = [](bool show, edict_t *ent, int ownId) {
|
auto sendBotVoice = [] (bool show, edict_t *ent, int ownId) {
|
||||||
MessageWriter (MSG_ONE, msgs.id (NetMsg::BotVoice), nullptr, ent) // begin message
|
MessageWriter (MSG_ONE, msgs.id (NetMsg::BotVoice), nullptr, ent) // begin message
|
||||||
.writeByte (show) // switch on/off
|
.writeByte (show) // switch on/off
|
||||||
.writeByte (ownId);
|
.writeByte (ownId);
|
||||||
|
|
@ -1181,12 +1181,12 @@ void Bot::checkMsgQueue () {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// team independent saytext
|
// team independent saytext
|
||||||
case BotMsg::Say:
|
case BotMsg::Say:
|
||||||
sendToChat (m_chatBuffer, false);
|
sendToChat (m_chatBuffer, false);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// team dependent saytext
|
// team dependent saytext
|
||||||
case BotMsg::SayTeam:
|
case BotMsg::SayTeam:
|
||||||
sendToChat (m_chatBuffer, true);
|
sendToChat (m_chatBuffer, true);
|
||||||
break;
|
break;
|
||||||
|
|
@ -1229,7 +1229,7 @@ bool Bot::isWeaponRestrictedAMX (int weaponIndex) {
|
||||||
if (restrictedWeapons.empty ()) {
|
if (restrictedWeapons.empty ()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
constexpr int indices[] = {4, 25, 20, -1, 8, -1, 12, 19, -1, 5, 6, 13, 23, 17, 18, 1, 2, 21, 9, 24, 7, 16, 10, 22, -1, 3, 15, 14, 0, 11};
|
constexpr int indices[] = { 4, 25, 20, -1, 8, -1, 12, 19, -1, 5, 6, 13, 23, 17, 18, 1, 2, 21, 9, 24, 7, 16, 10, 22, -1, 3, 15, 14, 0, 11 };
|
||||||
|
|
||||||
// find the weapon index
|
// find the weapon index
|
||||||
int index = indices[weaponIndex - 1];
|
int index = indices[weaponIndex - 1];
|
||||||
|
|
@ -1248,7 +1248,7 @@ bool Bot::isWeaponRestrictedAMX (int weaponIndex) {
|
||||||
if (restrictedEquipment.empty ()) {
|
if (restrictedEquipment.empty ()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
constexpr int indices[] = {-1, -1, -1, 3, -1, -1, -1, -1, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, -1, -1, -1, -1, -1, 0, 1, 5};
|
constexpr int indices[] = { -1, -1, -1, 3, -1, -1, -1, -1, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, -1, -1, -1, -1, -1, 0, 1, 5 };
|
||||||
|
|
||||||
// find the weapon index
|
// find the weapon index
|
||||||
int index = indices[weaponIndex - 1];
|
int index = indices[weaponIndex - 1];
|
||||||
|
|
@ -1775,7 +1775,7 @@ void Bot::overrideConditions () {
|
||||||
}
|
}
|
||||||
|
|
||||||
// special handling for reloading
|
// special handling for reloading
|
||||||
if (m_reloadState != Reload::None && m_isReloading && ((pev->button | m_oldButtons) & IN_RELOAD)) {
|
if (m_reloadState != Reload::None && m_isReloading && ((pev->button | m_oldButtons) & IN_RELOAD)) {
|
||||||
if (m_seeEnemyTime + 4.0f < game.time () && (m_states & Sense::SuspectEnemy)) {
|
if (m_seeEnemyTime + 4.0f < game.time () && (m_states & Sense::SuspectEnemy)) {
|
||||||
m_moveSpeed = 0.0f;
|
m_moveSpeed = 0.0f;
|
||||||
m_strafeSpeed = 0.0f;
|
m_strafeSpeed = 0.0f;
|
||||||
|
|
@ -2001,7 +2001,7 @@ void Bot::filterTasks () {
|
||||||
else {
|
else {
|
||||||
seekCoverDesire = 0.0f;
|
seekCoverDesire = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if half of the round is over, allow hunting
|
// if half of the round is over, allow hunting
|
||||||
if (getCurrentTaskId () != Task::EscapeFromBomb && game.isNullEntity (m_enemy) && !m_isVIP && bots.getRoundMidTime () < game.time () && !hasHostage () && !m_isUsingGrenade && m_currentNodeIndex != graph.getNearest (m_lastEnemyOrigin) && m_personality != Personality::Careful && !cv_ignore_enemies.bool_ ()) {
|
if (getCurrentTaskId () != Task::EscapeFromBomb && game.isNullEntity (m_enemy) && !m_isVIP && bots.getRoundMidTime () < game.time () && !hasHostage () && !m_isUsingGrenade && m_currentNodeIndex != graph.getNearest (m_lastEnemyOrigin) && m_personality != Personality::Careful && !cv_ignore_enemies.bool_ ()) {
|
||||||
float desireLevel = 4096.0f - ((1.0f - tempAgression) * m_lastEnemyOrigin.distance (pev->origin));
|
float desireLevel = 4096.0f - ((1.0f - tempAgression) * m_lastEnemyOrigin.distance (pev->origin));
|
||||||
|
|
@ -2765,7 +2765,7 @@ void Bot::updateAimDir () {
|
||||||
m_canChooseAimDirection = false;
|
m_canChooseAimDirection = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & AimFlags::Override) {
|
if (flags & AimFlags::Override) {
|
||||||
m_lookAt = m_camp;
|
m_lookAt = m_camp;
|
||||||
}
|
}
|
||||||
|
|
@ -2813,7 +2813,7 @@ void Bot::updateAimDir () {
|
||||||
}
|
}
|
||||||
else if (flags & AimFlags::PredictPath) {
|
else if (flags & AimFlags::PredictPath) {
|
||||||
bool changePredictedEnemy = true;
|
bool changePredictedEnemy = true;
|
||||||
|
|
||||||
if (m_timeNextTracking > game.time () && m_trackingEdict == m_lastEnemy && util.isAlive (m_lastEnemy)) {
|
if (m_timeNextTracking > game.time () && m_trackingEdict == m_lastEnemy && util.isAlive (m_lastEnemy)) {
|
||||||
changePredictedEnemy = false;
|
changePredictedEnemy = false;
|
||||||
}
|
}
|
||||||
|
|
@ -2920,7 +2920,7 @@ void Bot::checkDarkness () {
|
||||||
else if (!m_usesNVG && ((skyColor > 50.0f && m_path->light < 15.0f) || (skyColor <= 50.0f && m_path->light < 40.0f))) {
|
else if (!m_usesNVG && ((skyColor > 50.0f && m_path->light < 15.0f) || (skyColor <= 50.0f && m_path->light < 40.0f))) {
|
||||||
issueCommand ("nightvision");
|
issueCommand ("nightvision");
|
||||||
}
|
}
|
||||||
else if (m_usesNVG && ((m_path->light > 20.0f && skyColor > 50.0f) || (m_path->light > 45.0f && skyColor <= 50.0f))) {
|
else if (m_usesNVG && ((m_path->light > 20.0f && skyColor > 50.0f) || (m_path->light > 45.0f && skyColor <= 50.0f))) {
|
||||||
issueCommand ("nightvision");
|
issueCommand ("nightvision");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3017,7 +3017,7 @@ void Bot::update () {
|
||||||
updateTeamJoin (); // select team & class
|
updateTeamJoin (); // select team & class
|
||||||
}
|
}
|
||||||
else if (!m_notKilled) {
|
else if (!m_notKilled) {
|
||||||
// we got a teamkiller? vote him away...
|
// we got a teamkiller? vote him away...
|
||||||
if (m_voteKickIndex != m_lastVoteKick && cv_tkpunish.bool_ ()) {
|
if (m_voteKickIndex != m_lastVoteKick && cv_tkpunish.bool_ ()) {
|
||||||
issueCommand ("vote %d", m_voteKickIndex);
|
issueCommand ("vote %d", m_voteKickIndex);
|
||||||
m_lastVoteKick = m_voteKickIndex;
|
m_lastVoteKick = m_voteKickIndex;
|
||||||
|
|
@ -3123,10 +3123,10 @@ void Bot::normal_ () {
|
||||||
if (!bots.isBombPlanted () && m_currentNodeIndex != kInvalidNodeIndex && (m_path->flags & NodeFlag::Goal) && rg.chance (15) && numEnemiesNear (pev->origin, 650.0f) == 0) {
|
if (!bots.isBombPlanted () && m_currentNodeIndex != kInvalidNodeIndex && (m_path->flags & NodeFlag::Goal) && rg.chance (15) && numEnemiesNear (pev->origin, 650.0f) == 0) {
|
||||||
pushRadioMessage (Radio::SectorClear);
|
pushRadioMessage (Radio::SectorClear);
|
||||||
}
|
}
|
||||||
|
|
||||||
completeTask ();
|
completeTask ();
|
||||||
m_prevGoalIndex = kInvalidNodeIndex;
|
m_prevGoalIndex = kInvalidNodeIndex;
|
||||||
|
|
||||||
// spray logo sometimes if allowed to do so
|
// spray logo sometimes if allowed to do so
|
||||||
if (!(m_states & (Sense::SeeingEnemy | Sense::SuspectEnemy)) && m_seeEnemyTime + 5.0f < game.time () && !m_reloadState && m_timeLogoSpray < game.time () && cv_spraypaints.bool_ () && rg.chance (50) && m_moveSpeed > getShiftSpeed () && game.isNullEntity (m_pickupItem)) {
|
if (!(m_states & (Sense::SeeingEnemy | Sense::SuspectEnemy)) && m_seeEnemyTime + 5.0f < game.time () && !m_reloadState && m_timeLogoSpray < game.time () && cv_spraypaints.bool_ () && rg.chance (50) && m_moveSpeed > getShiftSpeed () && game.isNullEntity (m_pickupItem)) {
|
||||||
if (!(game.mapIs (MapFlags::Demolition) && bots.isBombPlanted () && m_team == Team::CT)) {
|
if (!(game.mapIs (MapFlags::Demolition) && bots.isBombPlanted () && m_team == Team::CT)) {
|
||||||
|
|
@ -3268,7 +3268,7 @@ void Bot::normal_ () {
|
||||||
// no more nodes to follow - search new ones (or we have a bomb)
|
// no more nodes to follow - search new ones (or we have a bomb)
|
||||||
else if (!hasActiveGoal ()) {
|
else if (!hasActiveGoal ()) {
|
||||||
m_moveSpeed = pev->maxspeed;
|
m_moveSpeed = pev->maxspeed;
|
||||||
|
|
||||||
clearSearchNodes ();
|
clearSearchNodes ();
|
||||||
ignoreCollision ();
|
ignoreCollision ();
|
||||||
|
|
||||||
|
|
@ -3369,7 +3369,7 @@ void Bot::spraypaint_ () {
|
||||||
|
|
||||||
void Bot::huntEnemy_ () {
|
void Bot::huntEnemy_ () {
|
||||||
m_aimFlags |= AimFlags::Nav;
|
m_aimFlags |= AimFlags::Nav;
|
||||||
|
|
||||||
// if we've got new enemy...
|
// if we've got new enemy...
|
||||||
if (!game.isNullEntity (m_enemy) || game.isNullEntity (m_lastEnemy)) {
|
if (!game.isNullEntity (m_enemy) || game.isNullEntity (m_lastEnemy)) {
|
||||||
|
|
||||||
|
|
@ -3395,7 +3395,7 @@ void Bot::huntEnemy_ () {
|
||||||
}
|
}
|
||||||
|
|
||||||
// do we need to calculate a new path?
|
// do we need to calculate a new path?
|
||||||
else if (!hasActiveGoal ()) {
|
else if (!hasActiveGoal ()) {
|
||||||
clearSearchNodes ();
|
clearSearchNodes ();
|
||||||
|
|
||||||
int destIndex = kInvalidNodeIndex;
|
int destIndex = kInvalidNodeIndex;
|
||||||
|
|
@ -4250,7 +4250,7 @@ void Bot::throwFlashbang_ () {
|
||||||
auto grenade = correctGrenadeVelocity ("flashbang.mdl");
|
auto grenade = correctGrenadeVelocity ("flashbang.mdl");
|
||||||
|
|
||||||
if (game.isNullEntity (grenade)) {
|
if (game.isNullEntity (grenade)) {
|
||||||
if (m_currentWeapon != Weapon::Flashbang && !m_grenadeRequested) {
|
if (m_currentWeapon != Weapon::Flashbang && !m_grenadeRequested) {
|
||||||
if (pev->weapons & cr::bit (Weapon::Flashbang)) {
|
if (pev->weapons & cr::bit (Weapon::Flashbang)) {
|
||||||
m_grenadeRequested = true;
|
m_grenadeRequested = true;
|
||||||
selectWeaponByName ("weapon_flashbang");
|
selectWeaponByName ("weapon_flashbang");
|
||||||
|
|
@ -4371,7 +4371,7 @@ void Bot::doublejump_ () {
|
||||||
}
|
}
|
||||||
|
|
||||||
// didn't choose goal waypoint yet?
|
// didn't choose goal waypoint yet?
|
||||||
if (!hasActiveGoal ()) {
|
if (!hasActiveGoal ()) {
|
||||||
clearSearchNodes ();
|
clearSearchNodes ();
|
||||||
|
|
||||||
int destIndex = graph.getNearest (m_doubleJumpOrigin);
|
int destIndex = graph.getNearest (m_doubleJumpOrigin);
|
||||||
|
|
@ -4381,7 +4381,7 @@ void Bot::doublejump_ () {
|
||||||
m_travelStartIndex = m_currentNodeIndex;
|
m_travelStartIndex = m_currentNodeIndex;
|
||||||
|
|
||||||
getTask ()->data = destIndex;
|
getTask ()->data = destIndex;
|
||||||
|
|
||||||
// always take the shortest path
|
// always take the shortest path
|
||||||
findPath (m_currentNodeIndex, destIndex, FindPath::Fast);
|
findPath (m_currentNodeIndex, destIndex, FindPath::Fast);
|
||||||
|
|
||||||
|
|
@ -4553,7 +4553,7 @@ void Bot::pickupItem_ () {
|
||||||
// primary weapon
|
// primary weapon
|
||||||
int wid = bestWeaponCarried ();
|
int wid = bestWeaponCarried ();
|
||||||
bool niceWeapon = rateGroundWeapon (m_pickupItem);
|
bool niceWeapon = rateGroundWeapon (m_pickupItem);
|
||||||
|
|
||||||
if ((wid == Weapon::Shield || wid > 6 || hasShield ()) && niceWeapon) {
|
if ((wid == Weapon::Shield || wid > 6 || hasShield ()) && niceWeapon) {
|
||||||
selectWeaponById (wid);
|
selectWeaponById (wid);
|
||||||
issueCommand ("drop");
|
issueCommand ("drop");
|
||||||
|
|
@ -4689,8 +4689,8 @@ void Bot::pickupItem_ () {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (nearestHostageNodeIndex != kInvalidNodeIndex) {
|
if (nearestHostageNodeIndex != kInvalidNodeIndex) {
|
||||||
clearTask (Task::MoveToPosition); // remove any move tasks
|
clearTask (Task::MoveToPosition); // remove any move tasks
|
||||||
startTask (Task::MoveToPosition, TaskPri::MoveToPosition, nearestHostageNodeIndex, 0.0f, true);
|
startTask (Task::MoveToPosition, TaskPri::MoveToPosition, nearestHostageNodeIndex, 0.0f, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ignoreCollision (); // also don't consider being stuck
|
ignoreCollision (); // also don't consider being stuck
|
||||||
|
|
@ -4936,7 +4936,7 @@ void Bot::logic () {
|
||||||
prevLadder = true;
|
prevLadder = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// press duck button if we need to
|
// press duck button if we need to
|
||||||
if ((m_path->flags & NodeFlag::Crouch) && !(m_path->flags & (NodeFlag::Camp | NodeFlag::Goal))) {
|
if ((m_path->flags & NodeFlag::Crouch) && !(m_path->flags & (NodeFlag::Camp | NodeFlag::Goal))) {
|
||||||
pev->button |= IN_DUCK;
|
pev->button |= IN_DUCK;
|
||||||
|
|
@ -4948,7 +4948,7 @@ void Bot::logic () {
|
||||||
pev->button |= IN_JUMP;
|
pev->button |= IN_JUMP;
|
||||||
m_jumpTime = game.time () + 1.0f;
|
m_jumpTime = game.time () + 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_path->flags & NodeFlag::Ladder) {
|
if (m_path->flags & NodeFlag::Ladder) {
|
||||||
if (m_pathOrigin.z < pev->origin.z + 16.0f && !isOnLadder () && isOnFloor () && !(pev->flags & FL_DUCKING)) {
|
if (m_pathOrigin.z < pev->origin.z + 16.0f && !isOnLadder () && isOnFloor () && !(pev->flags & FL_DUCKING)) {
|
||||||
if (!prevLadder) {
|
if (!prevLadder) {
|
||||||
|
|
@ -4965,7 +4965,7 @@ void Bot::logic () {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// special movement for swimming here
|
// special movement for swimming here
|
||||||
if (isInWater ()) {
|
if (isInWater ()) {
|
||||||
// check if we need to go forward or back press the correct buttons
|
// check if we need to go forward or back press the correct buttons
|
||||||
|
|
@ -5196,7 +5196,7 @@ void Bot::showDebugOverlay () {
|
||||||
// red = view angles
|
// red = view angles
|
||||||
game.drawLine (game.getLocalEntity (), getEyesPos (), m_destOrigin, 10, 0, { 0, 255, 0 }, 250, 5, 1, DrawLine::Arrow);
|
game.drawLine (game.getLocalEntity (), getEyesPos (), m_destOrigin, 10, 0, { 0, 255, 0 }, 250, 5, 1, DrawLine::Arrow);
|
||||||
game.drawLine (game.getLocalEntity (), getEyesPos () - Vector (0.0f, 0.0f, 16.0f), getEyesPos () + m_idealAngles.forward () * 300.0f, 10, 0, { 0, 0, 255 }, 250, 5, 1, DrawLine::Arrow);
|
game.drawLine (game.getLocalEntity (), getEyesPos () - Vector (0.0f, 0.0f, 16.0f), getEyesPos () + m_idealAngles.forward () * 300.0f, 10, 0, { 0, 0, 255 }, 250, 5, 1, DrawLine::Arrow);
|
||||||
game.drawLine (game.getLocalEntity (), getEyesPos () - Vector (0.0f, 0.0f, 32.0f), getEyesPos () + pev->v_angle.forward () * 300.0f, 10, 0, {255, 0, 0}, 250, 5, 1, DrawLine::Arrow);
|
game.drawLine (game.getLocalEntity (), getEyesPos () - Vector (0.0f, 0.0f, 32.0f), getEyesPos () + pev->v_angle.forward () * 300.0f, 10, 0, { 255, 0, 0 }, 250, 5, 1, DrawLine::Arrow);
|
||||||
|
|
||||||
// now draw line from source to destination
|
// now draw line from source to destination
|
||||||
for (size_t i = 0; i < m_pathWalk.length () && i + 1 < m_pathWalk.length (); ++i) {
|
for (size_t i = 0; i < m_pathWalk.length () && i + 1 < m_pathWalk.length (); ++i) {
|
||||||
|
|
@ -5868,7 +5868,7 @@ void Bot::updateHearing () {
|
||||||
}
|
}
|
||||||
|
|
||||||
// bot had an enemy, check if it's the heard one
|
// bot had an enemy, check if it's the heard one
|
||||||
else {
|
else {
|
||||||
if (player == m_lastEnemy) {
|
if (player == m_lastEnemy) {
|
||||||
// bot sees enemy ? then bail out !
|
// bot sees enemy ? then bail out !
|
||||||
if (m_states & Sense::SeeingEnemy) {
|
if (m_states & Sense::SeeingEnemy) {
|
||||||
|
|
@ -5955,7 +5955,7 @@ bool Bot::isBombDefusing (const Vector &bombOrigin) {
|
||||||
if (m_team != bot->m_team || bot->getCurrentTaskId () == Task::EscapeFromBomb) {
|
if (m_team != bot->m_team || bot->getCurrentTaskId () == Task::EscapeFromBomb) {
|
||||||
continue; // skip other mess
|
continue; // skip other mess
|
||||||
}
|
}
|
||||||
|
|
||||||
// if close enough, mark as progressing
|
// if close enough, mark as progressing
|
||||||
if (bombDistance < distanceToBomb && (bot->getCurrentTaskId () == Task::DefuseBomb || bot->m_hasProgressBar)) {
|
if (bombDistance < distanceToBomb && (bot->getCurrentTaskId () == Task::DefuseBomb || bot->m_hasProgressBar)) {
|
||||||
defusingInProgress = true;
|
defusingInProgress = true;
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,7 @@ bool BotSupport::checkKeywords (StringRef line, String &reply) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// reply not used, so use it
|
// reply not used, so use it
|
||||||
if (!replyUsed) {
|
if (!replyUsed) {
|
||||||
reply.assign (choosenReply); // update final buffer
|
reply.assign (choosenReply); // update final buffer
|
||||||
|
|
@ -181,7 +181,7 @@ void Bot::prepareChatMessage (StringRef message) {
|
||||||
// get roundtime
|
// get roundtime
|
||||||
auto getRoundTime = [] () -> String {
|
auto getRoundTime = [] () -> String {
|
||||||
auto roundTimeSecs = static_cast <int> (bots.getRoundEndTime () - game.time ());
|
auto roundTimeSecs = static_cast <int> (bots.getRoundEndTime () - game.time ());
|
||||||
|
|
||||||
String roundTime;
|
String roundTime;
|
||||||
roundTime.assignf ("%02d:%02d", cr::clamp (roundTimeSecs / 60, 0, 59), cr::clamp (cr::abs (roundTimeSecs % 60), 0, 59));
|
roundTime.assignf ("%02d:%02d", cr::clamp (roundTimeSecs / 60, 0, 59), cr::clamp (cr::abs (roundTimeSecs % 60), 0, 59));
|
||||||
|
|
||||||
|
|
@ -190,7 +190,7 @@ void Bot::prepareChatMessage (StringRef message) {
|
||||||
|
|
||||||
// get bot's victim
|
// get bot's victim
|
||||||
auto getMyVictim = [&] () -> String {;
|
auto getMyVictim = [&] () -> String {;
|
||||||
return humanizedName (game.indexOfPlayer (m_lastVictim));
|
return humanizedName (game.indexOfPlayer (m_lastVictim));
|
||||||
};
|
};
|
||||||
|
|
||||||
// get the game name alias
|
// get the game name alias
|
||||||
|
|
@ -300,7 +300,7 @@ bool Bot::isReplyingToChat () {
|
||||||
if (rg.chance (m_sayTextBuffer.chatProbability + rg.get (40, 70)) && checkChatKeywords (replyText)) {
|
if (rg.chance (m_sayTextBuffer.chatProbability + rg.get (40, 70)) && checkChatKeywords (replyText)) {
|
||||||
prepareChatMessage (replyText);
|
prepareChatMessage (replyText);
|
||||||
pushMsgQueue (BotMsg::Say);
|
pushMsgQueue (BotMsg::Say);
|
||||||
|
|
||||||
m_sayTextBuffer.entityIndex = -1;
|
m_sayTextBuffer.entityIndex = -1;
|
||||||
m_sayTextBuffer.timeNextChat = game.time () + m_sayTextBuffer.chatDelay;
|
m_sayTextBuffer.timeNextChat = game.time () + m_sayTextBuffer.chatDelay;
|
||||||
m_sayTextBuffer.sayText.clear ();
|
m_sayTextBuffer.sayText.clear ();
|
||||||
|
|
@ -338,7 +338,7 @@ void Bot::checkForChat () {
|
||||||
if (!sayBufferExists) {
|
if (!sayBufferExists) {
|
||||||
prepareChatMessage (phrase);
|
prepareChatMessage (phrase);
|
||||||
pushMsgQueue (BotMsg::Say);
|
pushMsgQueue (BotMsg::Say);
|
||||||
|
|
||||||
m_lastChatTime = game.time ();
|
m_lastChatTime = game.time ();
|
||||||
bots.setLastChatTimestamp (game.time ());
|
bots.setLastChatTimestamp (game.time ());
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -326,7 +326,7 @@ bool Bot::lookupEnemies () {
|
||||||
newEnemy = shieldEnemy;
|
newEnemy = shieldEnemy;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newEnemy != nullptr && (util.isPlayer (newEnemy) || (cv_attack_monsters.bool_ () && util.isMonster (newEnemy)))) {
|
if (newEnemy != nullptr && (util.isPlayer (newEnemy) || (cv_attack_monsters.bool_ () && util.isMonster (newEnemy)))) {
|
||||||
bots.setCanPause (true);
|
bots.setCanPause (true);
|
||||||
|
|
||||||
|
|
@ -411,7 +411,7 @@ bool Bot::lookupEnemies () {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (m_shootAtDeadTime > game.time ()) {
|
else if (m_shootAtDeadTime > game.time ()) {
|
||||||
m_actualReactionTime = 0.0f;
|
m_actualReactionTime = 0.0f;
|
||||||
m_states |= Sense::SuspectEnemy;
|
m_states |= Sense::SuspectEnemy;
|
||||||
|
|
@ -791,7 +791,7 @@ void Bot::selectWeapons (float distance, int index, int id, int choosen) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// is the bot holding a sniper rifle?
|
// is the bot holding a sniper rifle?
|
||||||
if (usesSniper () && m_zoomCheckTime < game.time ()) {
|
if (usesSniper () && m_zoomCheckTime < game.time ()) {
|
||||||
// should the bot switch to the long-range zoom?
|
// should the bot switch to the long-range zoom?
|
||||||
if (distance > 1500.0f && pev->fov >= 40.0f) {
|
if (distance > 1500.0f && pev->fov >= 40.0f) {
|
||||||
pev->button |= IN_ATTACK2;
|
pev->button |= IN_ATTACK2;
|
||||||
|
|
@ -810,7 +810,7 @@ void Bot::selectWeapons (float distance, int index, int id, int choosen) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// else is the bot holding a zoomable rifle?
|
// else is the bot holding a zoomable rifle?
|
||||||
else if (m_difficulty < Difficulty::Hard && usesZoomableRifle () && m_zoomCheckTime < game.time ()) {
|
else if (m_difficulty < Difficulty::Hard && usesZoomableRifle () && m_zoomCheckTime < game.time ()) {
|
||||||
// should the bot switch to zoomed mode?
|
// should the bot switch to zoomed mode?
|
||||||
if (distance > 800.0f && pev->fov >= 90.0f) {
|
if (distance > 800.0f && pev->fov >= 90.0f) {
|
||||||
pev->button |= IN_ATTACK2;
|
pev->button |= IN_ATTACK2;
|
||||||
|
|
@ -1019,7 +1019,7 @@ void Bot::focusEnemy () {
|
||||||
|
|
||||||
if (m_enemySurpriseTime > game.time ()) {
|
if (m_enemySurpriseTime > game.time ()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
float distance = m_lookAt.distance2d (getEyesPos ()); // how far away is the enemy scum?
|
float distance = m_lookAt.distance2d (getEyesPos ()); // how far away is the enemy scum?
|
||||||
|
|
||||||
if (distance < 128.0f && !usesSniper ()) {
|
if (distance < 128.0f && !usesSniper ()) {
|
||||||
|
|
@ -1303,7 +1303,7 @@ bool Bot::usesCampGun () {
|
||||||
return usesSubmachine () || usesRifle () || usesSniper () || usesHeavy ();
|
return usesSubmachine () || usesRifle () || usesSniper () || usesHeavy ();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Bot::usesKnife (){
|
bool Bot::usesKnife () {
|
||||||
return m_weaponType == WeaponType::Melee;
|
return m_weaponType == WeaponType::Melee;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1311,7 +1311,7 @@ int Bot::bestPrimaryCarried () {
|
||||||
// this function returns the best weapon of this bot (based on personality prefs)
|
// this function returns the best weapon of this bot (based on personality prefs)
|
||||||
|
|
||||||
const int *pref = conf.getWeaponPrefs (m_personality);
|
const int *pref = conf.getWeaponPrefs (m_personality);
|
||||||
|
|
||||||
int weaponIndex = 0;
|
int weaponIndex = 0;
|
||||||
int weapons = pev->weapons;
|
int weapons = pev->weapons;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ void BotConfig::loadMainConfig (bool isFirstLoad) {
|
||||||
}
|
}
|
||||||
setupMemoryFiles ();
|
setupMemoryFiles ();
|
||||||
|
|
||||||
auto needsToIgnoreVar = [](StringArray &list, const char *needle) {
|
auto needsToIgnoreVar = [] (StringArray &list, const char *needle) {
|
||||||
for (const auto &var : list) {
|
for (const auto &var : list) {
|
||||||
if (var == needle) {
|
if (var == needle) {
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -136,7 +136,7 @@ void BotConfig::loadNamesConfig () {
|
||||||
void BotConfig::loadWeaponsConfig () {
|
void BotConfig::loadWeaponsConfig () {
|
||||||
setupMemoryFiles ();
|
setupMemoryFiles ();
|
||||||
|
|
||||||
auto addWeaponEntries = [](SmallArray <WeaponInfo> &weapons, bool as, StringRef name, const StringArray &data) {
|
auto addWeaponEntries = [] (SmallArray <WeaponInfo> &weapons, bool as, StringRef name, const StringArray &data) {
|
||||||
|
|
||||||
// we're have null terminator element in weapons array...
|
// we're have null terminator element in weapons array...
|
||||||
if (data.length () + 1 != weapons.length ()) {
|
if (data.length () + 1 != weapons.length ()) {
|
||||||
|
|
@ -155,7 +155,7 @@ void BotConfig::loadWeaponsConfig () {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
auto addIntEntries = [](SmallArray <int32> &to, StringRef name, const StringArray &data) {
|
auto addIntEntries = [] (SmallArray <int32> &to, StringRef name, const StringArray &data) {
|
||||||
if (data.length () != to.length ()) {
|
if (data.length () != to.length ()) {
|
||||||
logger.error ("%s entry in weapons config is not valid or malformed (%d/%d).", name, data.length (), to.length ());
|
logger.error ("%s entry in weapons config is not valid or malformed (%d/%d).", name, data.length (), to.length ());
|
||||||
return;
|
return;
|
||||||
|
|
@ -711,7 +711,7 @@ void BotConfig::clearUsedName (Bot *bot) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BotConfig::setBotNameUsed(const int index, StringRef name) {
|
void BotConfig::setBotNameUsed (const int index, StringRef name) {
|
||||||
for (auto &bn : m_botNames) {
|
for (auto &bn : m_botNames) {
|
||||||
if (bn.name == name) {
|
if (bn.name == name) {
|
||||||
bn.usedBy = index;
|
bn.usedBy = index;
|
||||||
|
|
@ -795,7 +795,7 @@ const char *BotConfig::translate (StringRef input) {
|
||||||
void BotConfig::showCustomValues () {
|
void BotConfig::showCustomValues () {
|
||||||
game.print ("Current values for custom config items:");
|
game.print ("Current values for custom config items:");
|
||||||
|
|
||||||
m_custom.foreach ([&](const String &key, const String &val) {
|
m_custom.foreach ([&] (const String &key, const String &val) {
|
||||||
game.print (" %s = %s", key, val);
|
game.print (" %s = %s", key, val);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -868,7 +868,7 @@ int BotControl::cmdNodeFileInfo () {
|
||||||
return BotCommandResult::Handled;
|
return BotCommandResult::Handled;
|
||||||
}
|
}
|
||||||
|
|
||||||
int BotControl::cmdAdjustHeight() {
|
int BotControl::cmdAdjustHeight () {
|
||||||
enum args { graph_cmd = 1, cmd, offset };
|
enum args { graph_cmd = 1, cmd, offset };
|
||||||
|
|
||||||
if (!hasArg (offset)) {
|
if (!hasArg (offset)) {
|
||||||
|
|
@ -1481,12 +1481,12 @@ int BotControl::menuGraphFlag (int item) {
|
||||||
graph.toggleFlags (NodeFlag::Sniper);
|
graph.toggleFlags (NodeFlag::Sniper);
|
||||||
showMenu (Menu::NodeFlag);
|
showMenu (Menu::NodeFlag);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 6:
|
case 6:
|
||||||
graph.toggleFlags (NodeFlag::Goal);
|
graph.toggleFlags (NodeFlag::Goal);
|
||||||
showMenu (Menu::NodeFlag);
|
showMenu (Menu::NodeFlag);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 7:
|
case 7:
|
||||||
graph.toggleFlags (NodeFlag::Rescue);
|
graph.toggleFlags (NodeFlag::Rescue);
|
||||||
showMenu (Menu::NodeFlag);
|
showMenu (Menu::NodeFlag);
|
||||||
|
|
@ -1501,10 +1501,10 @@ int BotControl::menuGraphFlag (int item) {
|
||||||
graph.toggleFlags (NodeFlag::Crouch);
|
graph.toggleFlags (NodeFlag::Crouch);
|
||||||
graph[nearest].origin.z += 18.0f;
|
graph[nearest].origin.z += 18.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
showMenu (Menu::NodeFlag);
|
showMenu (Menu::NodeFlag);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 9:
|
case 9:
|
||||||
// if the node doesn't have a camp flag, set it and open the camp directions selection menu
|
// if the node doesn't have a camp flag, set it and open the camp directions selection menu
|
||||||
if (!(graph[nearest].flags & NodeFlag::Camp)) {
|
if (!(graph[nearest].flags & NodeFlag::Camp)) {
|
||||||
|
|
@ -1852,7 +1852,7 @@ void BotControl::showMenu (int id) {
|
||||||
}
|
}
|
||||||
auto &client = util.getClient (game.indexOfPlayer (m_ent));
|
auto &client = util.getClient (game.indexOfPlayer (m_ent));
|
||||||
|
|
||||||
auto sendMenu = [&](int32 slots, bool last, StringRef text) {
|
auto sendMenu = [&] (int32 slots, bool last, StringRef text) {
|
||||||
MessageWriter (MSG_ONE, msgs.id (NetMsg::ShowMenu), nullptr, m_ent)
|
MessageWriter (MSG_ONE, msgs.id (NetMsg::ShowMenu), nullptr, m_ent)
|
||||||
.writeShort (slots)
|
.writeShort (slots)
|
||||||
.writeChar (-1)
|
.writeChar (-1)
|
||||||
|
|
@ -2098,7 +2098,7 @@ void BotControl::enableDrawModels (bool enable) {
|
||||||
ent->v.effects |= EF_NODRAW;
|
ent->v.effects |= EF_NODRAW;
|
||||||
}
|
}
|
||||||
return EntitySearchResult::Continue;
|
return EntitySearchResult::Continue;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2321,7 +2321,7 @@ void BotControl::createMenus () {
|
||||||
"\\w9. Jump\n\n"
|
"\\w9. Jump\n\n"
|
||||||
"0. Exit",
|
"0. Exit",
|
||||||
&BotControl::menuGraphType);
|
&BotControl::menuGraphType);
|
||||||
|
|
||||||
// debug goal menu
|
// debug goal menu
|
||||||
m_menus.emplace (
|
m_menus.emplace (
|
||||||
Menu::NodeDebug, keys (3),
|
Menu::NodeDebug, keys (3),
|
||||||
|
|
@ -2347,7 +2347,7 @@ void BotControl::createMenus () {
|
||||||
"9. Camp Point\n\n"
|
"9. Camp Point\n\n"
|
||||||
"0. Exit",
|
"0. Exit",
|
||||||
&BotControl::menuGraphFlag);
|
&BotControl::menuGraphFlag);
|
||||||
|
|
||||||
// set camp directions menu
|
// set camp directions menu
|
||||||
m_menus.emplace (
|
m_menus.emplace (
|
||||||
Menu::CampDirections, keys (2),
|
Menu::CampDirections, keys (2),
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ void Game::levelInitialize (edict_t *entities, int max) {
|
||||||
m_breakables.clear ();
|
m_breakables.clear ();
|
||||||
|
|
||||||
// initialize all config files
|
// initialize all config files
|
||||||
conf.loadConfigs ();
|
conf.loadConfigs ();
|
||||||
|
|
||||||
// update worldmodel
|
// update worldmodel
|
||||||
illum.resetWorldModel ();
|
illum.resetWorldModel ();
|
||||||
|
|
@ -87,7 +87,7 @@ void Game::levelInitialize (edict_t *entities, int max) {
|
||||||
|
|
||||||
// flush any print queue
|
// flush any print queue
|
||||||
ctrl.resetFlushTimestamp ();
|
ctrl.resetFlushTimestamp ();
|
||||||
|
|
||||||
// go thru the all entities on map, and do whatever we're want
|
// go thru the all entities on map, and do whatever we're want
|
||||||
for (int i = 0; i < max; ++i) {
|
for (int i = 0; i < max; ++i) {
|
||||||
auto ent = entities + i;
|
auto ent = entities + i;
|
||||||
|
|
@ -480,14 +480,14 @@ void Game::sendClientMessage (bool console, edict_t *ent, StringRef message) {
|
||||||
.writeByte (console ? HUD_PRINTCONSOLE : HUD_PRINTCENTER)
|
.writeByte (console ? HUD_PRINTCONSOLE : HUD_PRINTCENTER)
|
||||||
.writeString (text.chars ());
|
.writeString (text.chars ());
|
||||||
};
|
};
|
||||||
|
|
||||||
// do not excess limit
|
// do not excess limit
|
||||||
constexpr size_t maxSendLength = 125;
|
constexpr size_t maxSendLength = 125;
|
||||||
|
|
||||||
// split up the string into chunks if needed (maybe check if it's multibyte?)
|
// split up the string into chunks if needed (maybe check if it's multibyte?)
|
||||||
if (buffer.length () > maxSendLength) {
|
if (buffer.length () > maxSendLength) {
|
||||||
auto chunks = buffer.split (maxSendLength);
|
auto chunks = buffer.split (maxSendLength);
|
||||||
|
|
||||||
// send in chunks
|
// send in chunks
|
||||||
for (size_t i = 0; i < chunks.length (); ++i) {
|
for (size_t i = 0; i < chunks.length (); ++i) {
|
||||||
sendTextMsg (chunks[i]);
|
sendTextMsg (chunks[i]);
|
||||||
|
|
@ -530,7 +530,7 @@ void Game::prepareBotArgs (edict_t *ent, String str) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// helper to parse single (not multi) command
|
// helper to parse single (not multi) command
|
||||||
auto parsePartArgs = [& ] (String &args) {
|
auto parsePartArgs = [&] (String &args) {
|
||||||
args.trim ("\r\n\t\" "); // trim new lines
|
args.trim ("\r\n\t\" "); // trim new lines
|
||||||
|
|
||||||
// we're have empty commands?
|
// we're have empty commands?
|
||||||
|
|
@ -763,7 +763,7 @@ bool Game::loadCSBinary () {
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
// search the libraries inside game dlls directory
|
// search the libraries inside game dlls directory
|
||||||
for (const auto &lib : libs) {
|
for (const auto &lib : libs) {
|
||||||
auto path = strings.format ("%s/dlls/%s", modname, lib);
|
auto path = strings.format ("%s/dlls/%s", modname, lib);
|
||||||
|
|
@ -772,7 +772,7 @@ bool Game::loadCSBinary () {
|
||||||
if (!File::exists (path)) {
|
if (!File::exists (path)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// special case, czero is always detected first, as it's has custom directory
|
// special case, czero is always detected first, as it's has custom directory
|
||||||
if (strcmp (modname, "czero") == 0) {
|
if (strcmp (modname, "czero") == 0) {
|
||||||
m_gameFlags |= (GameFlags::ConditionZero | GameFlags::HasBotVoice | GameFlags::HasFakePings);
|
m_gameFlags |= (GameFlags::ConditionZero | GameFlags::HasBotVoice | GameFlags::HasFakePings);
|
||||||
|
|
@ -809,7 +809,7 @@ bool Game::loadCSBinary () {
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entity != nullptr) {
|
if (entity != nullptr) {
|
||||||
m_gameFlags |= (GameFlags::Modern | GameFlags::HasBotVoice | GameFlags::HasFakePings);
|
m_gameFlags |= (GameFlags::Modern | GameFlags::HasBotVoice | GameFlags::HasFakePings);
|
||||||
}
|
}
|
||||||
|
|
@ -908,18 +908,18 @@ void Game::applyGameModes () {
|
||||||
case 0:
|
case 0:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// force CSDM mode
|
// force CSDM mode
|
||||||
case 1:
|
case 1:
|
||||||
m_gameFlags |= GameFlags::CSDM;
|
m_gameFlags |= GameFlags::CSDM;
|
||||||
m_gameFlags &= ~GameFlags::FreeForAll;
|
m_gameFlags &= ~GameFlags::FreeForAll;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// force CSDM FFA mode
|
// force CSDM FFA mode
|
||||||
case 2:
|
case 2:
|
||||||
m_gameFlags |= GameFlags::CSDM | GameFlags::FreeForAll;
|
m_gameFlags |= GameFlags::CSDM | GameFlags::FreeForAll;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// force disable everything
|
// force disable everything
|
||||||
case 3:
|
case 3:
|
||||||
m_gameFlags &= ~(GameFlags::CSDM | GameFlags::FreeForAll);
|
m_gameFlags &= ~(GameFlags::CSDM | GameFlags::FreeForAll);
|
||||||
return;
|
return;
|
||||||
|
|
@ -973,7 +973,7 @@ void Game::slowFrame () {
|
||||||
// check if we're need to autokill bots
|
// check if we're need to autokill bots
|
||||||
bots.maintainAutoKill ();
|
bots.maintainAutoKill ();
|
||||||
|
|
||||||
// update client pings
|
// update client pings
|
||||||
util.calculatePings ();
|
util.calculatePings ();
|
||||||
|
|
||||||
// maintain leaders selection upon round start
|
// maintain leaders selection upon round start
|
||||||
|
|
@ -1124,7 +1124,7 @@ void LightMeasure::updateLight (int style, char *value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strings.isEmpty (value)){
|
if (strings.isEmpty (value)) {
|
||||||
m_lightstyle[style].length = 0u;
|
m_lightstyle[style].length = 0u;
|
||||||
m_lightstyle[style].map[0] = kNullChar;
|
m_lightstyle[style].map[0] = kNullChar;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -209,7 +209,7 @@ int BotGraph::clearConnections (int index) {
|
||||||
|
|
||||||
|
|
||||||
for (int i = 2; i < kMaxNodeLinks; ++i) {
|
for (int i = 2; i < kMaxNodeLinks; ++i) {
|
||||||
while (inspect_p0 (i)) { }
|
while (inspect_p0 (i)) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// check pass 1
|
// check pass 1
|
||||||
|
|
@ -332,7 +332,7 @@ int BotGraph::clearConnections (int index) {
|
||||||
};
|
};
|
||||||
|
|
||||||
for (int i = 1; i < kMaxNodeLinks; ++i) {
|
for (int i = 1; i < kMaxNodeLinks; ++i) {
|
||||||
while (inspect_p2 (i)) { }
|
while (inspect_p2 (i)) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// check pass 3
|
// check pass 3
|
||||||
|
|
@ -663,7 +663,7 @@ void BotGraph::add (int type, const Vector &pos) {
|
||||||
path->origin = newOrigin;
|
path->origin = newOrigin;
|
||||||
path->start = nullptr;
|
path->start = nullptr;
|
||||||
path->end = nullptr;
|
path->end = nullptr;
|
||||||
|
|
||||||
path->display = 0.0f;
|
path->display = 0.0f;
|
||||||
path->light = 0.0f;
|
path->light = 0.0f;
|
||||||
|
|
||||||
|
|
@ -684,7 +684,7 @@ void BotGraph::add (int type, const Vector &pos) {
|
||||||
}
|
}
|
||||||
m_autoSaveCount = 0;
|
m_autoSaveCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// store the last used node for the auto node code...
|
// store the last used node for the auto node code...
|
||||||
m_lastNode = m_editor->v.origin;
|
m_lastNode = m_editor->v.origin;
|
||||||
}
|
}
|
||||||
|
|
@ -949,7 +949,7 @@ int BotGraph::getFacingIndex () {
|
||||||
if (to.lengthSq () > cr::square (500.0f) || cr::abs (angles.y) > result.second) {
|
if (to.lengthSq () > cr::square (500.0f) || cr::abs (angles.y) > result.second) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if visible, (we're not using visiblity tables here, as they not valid at time of waypoint editing)
|
// 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);
|
game.testLine (editorEyes, path.origin, TraceIgnore::Everything, m_editor, &tr);
|
||||||
|
|
@ -1253,7 +1253,7 @@ void BotGraph::loadPractice () {
|
||||||
if (m_paths.empty ()) {
|
if (m_paths.empty ()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// reset highest recorded damage
|
// reset highest recorded damage
|
||||||
for (int team = Team::Terrorist; team < kGameTeamNum; ++team) {
|
for (int team = Team::Terrorist; team < kGameTeamNum; ++team) {
|
||||||
m_highestDamage[team] = 1;
|
m_highestDamage[team] = 1;
|
||||||
|
|
@ -1522,7 +1522,7 @@ void BotGraph::initNodesTypes () {
|
||||||
|
|
||||||
bool BotGraph::convertOldFormat () {
|
bool BotGraph::convertOldFormat () {
|
||||||
MemFile fp (getOldFormatGraphName (true));
|
MemFile fp (getOldFormatGraphName (true));
|
||||||
|
|
||||||
PODGraphHeader header {};
|
PODGraphHeader header {};
|
||||||
plat.bzero (&header, sizeof (header));
|
plat.bzero (&header, sizeof (header));
|
||||||
|
|
||||||
|
|
@ -1557,7 +1557,7 @@ bool BotGraph::convertOldFormat () {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
convertFromPOD (path, podpath);
|
convertFromPOD (path, podpath);
|
||||||
|
|
||||||
// more checks of node quality
|
// more checks of node quality
|
||||||
if (path.number < 0 || path.number > header.pointNumber) {
|
if (path.number < 0 || path.number > header.pointNumber) {
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -1565,11 +1565,11 @@ bool BotGraph::convertOldFormat () {
|
||||||
// add to node array
|
// add to node array
|
||||||
m_paths.push (cr::move (path));
|
m_paths.push (cr::move (path));
|
||||||
}
|
}
|
||||||
fp.close();
|
fp.close ();
|
||||||
|
|
||||||
// save new format in case loaded older one
|
// save new format in case loaded older one
|
||||||
if (!m_paths.empty()) {
|
if (!m_paths.empty ()) {
|
||||||
ctrl.msg("Converting old PWF to new format Graph.");
|
ctrl.msg ("Converting old PWF to new format Graph.");
|
||||||
|
|
||||||
m_graphAuthor = header.author;
|
m_graphAuthor = header.author;
|
||||||
|
|
||||||
|
|
@ -1577,7 +1577,7 @@ bool BotGraph::convertOldFormat () {
|
||||||
auto editor = m_editor;
|
auto editor = m_editor;
|
||||||
m_editor = nullptr;
|
m_editor = nullptr;
|
||||||
|
|
||||||
auto result = saveGraphData();
|
auto result = saveGraphData ();
|
||||||
m_editor = editor;
|
m_editor = editor;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -1634,7 +1634,7 @@ template <typename U> bool BotGraph::saveStorage (StringRef ext, StringRef name,
|
||||||
hdr.length = length ();
|
hdr.length = length ();
|
||||||
hdr.compressed = compressedLength;
|
hdr.compressed = compressedLength;
|
||||||
hdr.uncompressed = rawLength;
|
hdr.uncompressed = rawLength;
|
||||||
|
|
||||||
file.write (&hdr, sizeof (StorageHeader));
|
file.write (&hdr, sizeof (StorageHeader));
|
||||||
file.write (compressed.data (), sizeof (uint8), compressedLength);
|
file.write (compressed.data (), sizeof (uint8), compressedLength);
|
||||||
|
|
||||||
|
|
@ -1693,7 +1693,7 @@ template <typename U> bool BotGraph::loadStorage (StringRef ext, StringRef name,
|
||||||
auto fromDownload = strings.format ("http://%s/graph/%s", downloadAddress, filename);
|
auto fromDownload = strings.format ("http://%s/graph/%s", downloadAddress, filename);
|
||||||
|
|
||||||
// try to download
|
// try to download
|
||||||
if (http.downloadFile (fromDownload, toDownload)) {
|
if (http.downloadFile (fromDownload, toDownload)) {
|
||||||
ctrl.msg ("%s file '%s' successfully downloaded. Processing...", name, filename);
|
ctrl.msg ("%s file '%s' successfully downloaded. Processing...", name, filename);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -1714,7 +1714,7 @@ template <typename U> bool BotGraph::loadStorage (StringRef ext, StringRef name,
|
||||||
if (download ()) {
|
if (download ()) {
|
||||||
return loadStorage <U> (ext, name, options, version, data, exten, outOptions);
|
return loadStorage <U> (ext, name, options, version, data, exten, outOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (convertOldFormat ()) {
|
if (convertOldFormat ()) {
|
||||||
return loadStorage <U> (ext, name, options, version, data, exten, outOptions);
|
return loadStorage <U> (ext, name, options, version, data, exten, outOptions);
|
||||||
}
|
}
|
||||||
|
|
@ -1756,7 +1756,7 @@ template <typename U> bool BotGraph::loadStorage (StringRef ext, StringRef name,
|
||||||
|
|
||||||
// check the version
|
// check the version
|
||||||
if (hdr.version > version && isGraph) {
|
if (hdr.version > version && isGraph) {
|
||||||
ctrl.msg ("Graph version mismatch %s (filename: '%s'). Version number differs (got: '%d', need: '%d') Please, upgrade %s.", name, filename, hdr.version, version, product.name);
|
ctrl.msg ("Graph version mismatch %s (filename: '%s'). Version number differs (got: '%d', need: '%d') Please, upgrade %s.", name, filename, hdr.version, version, product.name);
|
||||||
}
|
}
|
||||||
else if (hdr.version > version && !isGraph) {
|
else if (hdr.version > version && !isGraph) {
|
||||||
return raiseLoadingError (isGraph, file, "Damaged %s (filename: '%s'). Version number differs (got: '%d', need: '%d').", name, filename, hdr.version, version);
|
return raiseLoadingError (isGraph, file, "Damaged %s (filename: '%s'). Version number differs (got: '%d', need: '%d').", name, filename, hdr.version, version);
|
||||||
|
|
@ -1786,7 +1786,7 @@ template <typename U> bool BotGraph::loadStorage (StringRef ext, StringRef name,
|
||||||
return raiseLoadingError (isGraph, file, "Unable to decompress ULZ data for %s (filename: '%s').", name, filename);
|
return raiseLoadingError (isGraph, file, "Unable to decompress ULZ data for %s (filename: '%s').", name, filename);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
if (outOptions) {
|
if (outOptions) {
|
||||||
outOptions = &hdr.options;
|
outOptions = &hdr.options;
|
||||||
}
|
}
|
||||||
|
|
@ -2199,7 +2199,7 @@ void BotGraph::frame () {
|
||||||
if (!m_endJumpPoint) {
|
if (!m_endJumpPoint) {
|
||||||
if (m_editor->v.button & IN_JUMP) {
|
if (m_editor->v.button & IN_JUMP) {
|
||||||
add (NodeAddFlag::JumpStart);
|
add (NodeAddFlag::JumpStart);
|
||||||
|
|
||||||
m_timeJumpStarted = game.time ();
|
m_timeJumpStarted = game.time ();
|
||||||
m_endJumpPoint = true;
|
m_endJumpPoint = true;
|
||||||
}
|
}
|
||||||
|
|
@ -2300,7 +2300,7 @@ void BotGraph::frame () {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
nodeColor = { 0, 255, 0 };
|
nodeColor = { 0, 255, 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
// colorize additional flags
|
// colorize additional flags
|
||||||
Color nodeFlagColor { -1, -1, -1 };
|
Color nodeFlagColor { -1, -1, -1 };
|
||||||
|
|
@ -2325,7 +2325,7 @@ void BotGraph::frame () {
|
||||||
if (nodeFlagColor.red == -1) {
|
if (nodeFlagColor.red == -1) {
|
||||||
game.drawLine (m_editor, path.origin - Vector (0, 0, nodeHalfHeight), path.origin + Vector (0, 0, nodeHalfHeight), nodeWidth + 1, 0, nodeColor, 250, 0, 10);
|
game.drawLine (m_editor, path.origin - Vector (0, 0, nodeHalfHeight), path.origin + Vector (0, 0, nodeHalfHeight), nodeWidth + 1, 0, nodeColor, 250, 0, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
// draw node with flags
|
// draw node with flags
|
||||||
else {
|
else {
|
||||||
game.drawLine (m_editor, path.origin - Vector (0, 0, nodeHalfHeight), path.origin - Vector (0, 0, nodeHalfHeight - nodeHeight * 0.75f), nodeWidth, 0, nodeColor, 250, 0, 10); // draw basic path
|
game.drawLine (m_editor, path.origin - Vector (0, 0, nodeHalfHeight), path.origin - Vector (0, 0, nodeHalfHeight - nodeHeight * 0.75f), nodeWidth, 0, nodeColor, 250, 0, 10); // draw basic path
|
||||||
|
|
@ -2381,7 +2381,7 @@ void BotGraph::frame () {
|
||||||
const auto &source = Vector (path.origin.x, path.origin.y, path.origin.z + height); // source
|
const auto &source = Vector (path.origin.x, path.origin.y, path.origin.z + height); // source
|
||||||
const auto &start = path.origin + Vector (path.start.x, path.start.y, 0.0f).forward () * 500.0f; // camp start
|
const auto &start = path.origin + Vector (path.start.x, path.start.y, 0.0f).forward () * 500.0f; // camp start
|
||||||
const auto &end = path.origin + Vector (path.end.x, path.end.y, 0.0f).forward () * 500.0f; // camp end
|
const auto &end = path.origin + Vector (path.end.x, path.end.y, 0.0f).forward () * 500.0f; // camp end
|
||||||
|
|
||||||
// draw it now
|
// draw it now
|
||||||
game.drawLine (m_editor, source, start, 10, 0, { 255, 0, 0 }, 200, 0, 10);
|
game.drawLine (m_editor, source, start, 10, 0, { 255, 0, 0 }, 200, 0, 10);
|
||||||
game.drawLine (m_editor, source, end, 10, 0, { 255, 0, 0 }, 200, 0, 10);
|
game.drawLine (m_editor, source, end, 10, 0, { 255, 0, 0 }, 200, 0, 10);
|
||||||
|
|
@ -2418,7 +2418,7 @@ void BotGraph::frame () {
|
||||||
// if radius is nonzero, draw a full circle
|
// if radius is nonzero, draw a full circle
|
||||||
if (path.radius > 0.0f) {
|
if (path.radius > 0.0f) {
|
||||||
float sqr = cr::sqrtf (cr::square (path.radius) * 0.5f);
|
float sqr = cr::sqrtf (cr::square (path.radius) * 0.5f);
|
||||||
|
|
||||||
game.drawLine (m_editor, origin + Vector (path.radius, 0.0f, 0.0f), origin + Vector (sqr, -sqr, 0.0f), 5, 0, radiusColor, 200, 0, 10);
|
game.drawLine (m_editor, origin + Vector (path.radius, 0.0f, 0.0f), origin + Vector (sqr, -sqr, 0.0f), 5, 0, radiusColor, 200, 0, 10);
|
||||||
game.drawLine (m_editor, origin + Vector (sqr, -sqr, 0.0f), origin + Vector (0.0f, -path.radius, 0.0f), 5, 0, radiusColor, 200, 0, 10);
|
game.drawLine (m_editor, origin + Vector (sqr, -sqr, 0.0f), origin + Vector (0.0f, -path.radius, 0.0f), 5, 0, radiusColor, 200, 0, 10);
|
||||||
|
|
||||||
|
|
@ -2527,8 +2527,8 @@ void BotGraph::frame () {
|
||||||
|
|
||||||
String practice;
|
String practice;
|
||||||
practice.assignf (" Node practice data (index / damage):\n"
|
practice.assignf (" Node practice data (index / damage):\n"
|
||||||
" CT: %d / %d\n"
|
" CT: %d / %d\n"
|
||||||
" T: %d / %d\n\n", dangerIndexCT, dangerIndexCT != kInvalidNodeIndex ? getDangerDamage (Team::CT, nearestIndex, dangerIndexCT) : 0, dangerIndexT, dangerIndexT != kInvalidNodeIndex ? getDangerDamage (Team::Terrorist, nearestIndex, dangerIndexT) : 0);
|
" T: %d / %d\n\n", dangerIndexCT, dangerIndexCT != kInvalidNodeIndex ? getDangerDamage (Team::CT, nearestIndex, dangerIndexCT) : 0, dangerIndexT, dangerIndexT != kInvalidNodeIndex ? getDangerDamage (Team::Terrorist, nearestIndex, dangerIndexT) : 0);
|
||||||
|
|
||||||
sendHudMessage ({ 255, 255, 255 }, 0.0f, 0.16f, m_editor, practice + timeMessage);
|
sendHudMessage ({ 255, 255, 255 }, 0.0f, 0.16f, m_editor, practice + timeMessage);
|
||||||
}
|
}
|
||||||
|
|
@ -2695,7 +2695,7 @@ bool BotGraph::checkNodes (bool teleportPlayer) {
|
||||||
Array <IntArray> outgoingPaths; // store incoming paths for speedup
|
Array <IntArray> outgoingPaths; // store incoming paths for speedup
|
||||||
outgoingPaths.resize (m_paths.length ());
|
outgoingPaths.resize (m_paths.length ());
|
||||||
|
|
||||||
for (const auto &path: m_paths) {
|
for (const auto &path : m_paths) {
|
||||||
outgoingPaths[path.number].resize (m_paths.length () + 1);
|
outgoingPaths[path.number].resize (m_paths.length () + 1);
|
||||||
|
|
||||||
for (const auto &link : path.links) {
|
for (const auto &link : path.links) {
|
||||||
|
|
@ -2724,7 +2724,7 @@ bool BotGraph::checkNodes (bool teleportPlayer) {
|
||||||
walk.add (outgoing);
|
walk.add (outgoing);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto &path : m_paths) {
|
for (const auto &path : m_paths) {
|
||||||
if (!visited[path.number]) {
|
if (!visited[path.number]) {
|
||||||
ctrl.msg ("Path broken from node %d to node 0.", path.number);
|
ctrl.msg ("Path broken from node %d to node 0.", path.number);
|
||||||
|
|
@ -2905,7 +2905,7 @@ void BotGraph::setBombOrigin (bool reset, const Vector &pos) {
|
||||||
}
|
}
|
||||||
bool wasFound = false;
|
bool wasFound = false;
|
||||||
auto bombModel = conf.getBombModelName ();
|
auto bombModel = conf.getBombModelName ();
|
||||||
|
|
||||||
game.searchEntities ("classname", "grenade", [&] (edict_t *ent) {
|
game.searchEntities ("classname", "grenade", [&] (edict_t *ent) {
|
||||||
if (util.isModel (ent, bombModel)) {
|
if (util.isModel (ent, bombModel)) {
|
||||||
m_bombOrigin = game.getEntityOrigin (ent);
|
m_bombOrigin = game.getEntityOrigin (ent);
|
||||||
|
|
@ -3028,7 +3028,7 @@ void BotGraph::updateGlobalPractice () {
|
||||||
// get the most dangerous node for this position for both teams
|
// get the most dangerous node for this position for both teams
|
||||||
for (int team = Team::Terrorist; team < kGameTeamNum; ++team) {
|
for (int team = Team::Terrorist; team < kGameTeamNum; ++team) {
|
||||||
int bestIndex = kInvalidNodeIndex; // best index to store
|
int bestIndex = kInvalidNodeIndex; // best index to store
|
||||||
|
|
||||||
for (int i = 0; i < length (); ++i) {
|
for (int i = 0; i < length (); ++i) {
|
||||||
int maxDamage = 0;
|
int maxDamage = 0;
|
||||||
bestIndex = kInvalidNodeIndex;
|
bestIndex = kInvalidNodeIndex;
|
||||||
|
|
@ -3068,7 +3068,7 @@ void BotGraph::updateGlobalPractice () {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int team = Team::Terrorist; team < kGameTeamNum; ++team) {
|
for (int team = Team::Terrorist; team < kGameTeamNum; ++team) {
|
||||||
m_highestDamage[team] = cr::clamp (m_highestDamage [team] - kHalfDamageVal, 1, kMaxPracticeDamageValue);
|
m_highestDamage[team] = cr::clamp (m_highestDamage[team] - kHalfDamageVal, 1, kMaxPracticeDamageValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,54 +32,52 @@ plugin_info_t Plugin_info = {
|
||||||
PT_ANYTIME, // when unloadable
|
PT_ANYTIME, // when unloadable
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace variadic {
|
void hook_ClientCommand (edict_t *ent, char const *format, ...) {
|
||||||
void clientCommand (edict_t *ent, char const *format, ...) {
|
// this function forces the client whose player entity is ent to issue a client command.
|
||||||
// this function forces the client whose player entity is ent to issue a client command.
|
// How it works is that clients all have a argv global string in their client DLL that
|
||||||
// How it works is that clients all have a argv global string in their client DLL that
|
// stores the command string; if ever that string is filled with characters, the client DLL
|
||||||
// stores the command string; if ever that string is filled with characters, the client DLL
|
// sends it to the engine as a command to be executed. When the engine has executed that
|
||||||
// sends it to the engine as a command to be executed. When the engine has executed that
|
// command, this argv string is reset to zero. Here is somehow a curious implementation of
|
||||||
// command, this argv string is reset to zero. Here is somehow a curious implementation of
|
// ClientCommand: the engine sets the command it wants the client to issue in his argv, then
|
||||||
// ClientCommand: the engine sets the command it wants the client to issue in his argv, then
|
// the client DLL sends it back to the engine, the engine receives it then executes the
|
||||||
// the client DLL sends it back to the engine, the engine receives it then executes the
|
// command therein. Don't ask me why we need all this complicated crap. Anyhow since bots have
|
||||||
// command therein. Don't ask me why we need all this complicated crap. Anyhow since bots have
|
// no client DLL, be certain never to call this function upon a bot entity, else it will just
|
||||||
// no client DLL, be certain never to call this function upon a bot entity, else it will just
|
// make the server crash. Since hordes of uncautious, not to say stupid, programmers don't
|
||||||
// make the server crash. Since hordes of uncautious, not to say stupid, programmers don't
|
// even imagine some players on their servers could be bots, this check is performed less than
|
||||||
// even imagine some players on their servers could be bots, this check is performed less than
|
// sometimes actually by their side, that's why we strongly recommend to check it here too. In
|
||||||
// sometimes actually by their side, that's why we strongly recommend to check it here too. In
|
// case it's a bot asking for a client command, we handle it like we do for bot commands
|
||||||
// case it's a bot asking for a client command, we handle it like we do for bot commands
|
|
||||||
|
|
||||||
if (game.isNullEntity (ent)) {
|
if (game.isNullEntity (ent)) {
|
||||||
if (game.is (GameFlags::Metamod)) {
|
if (game.is (GameFlags::Metamod)) {
|
||||||
RETURN_META (MRES_SUPERCEDE);
|
RETURN_META (MRES_SUPERCEDE);
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
va_list ap;
|
va_list ap;
|
||||||
auto buffer = strings.chars ();
|
auto buffer = strings.chars ();
|
||||||
|
|
||||||
va_start (ap, format);
|
va_start (ap, format);
|
||||||
vsnprintf (buffer, StringBuffer::StaticBufferSize, format, ap);
|
vsnprintf (buffer, StringBuffer::StaticBufferSize, format, ap);
|
||||||
va_end (ap);
|
va_end (ap);
|
||||||
|
|
||||||
if (util.isFakeClient (ent) || (ent->v.flags & FL_DORMANT)) {
|
if (util.isFakeClient (ent) || (ent->v.flags & FL_DORMANT)) {
|
||||||
auto bot = bots[ent];
|
auto bot = bots[ent];
|
||||||
|
|
||||||
if (bot) {
|
if (bot) {
|
||||||
bot->issueCommand (buffer);
|
bot->issueCommand (buffer);
|
||||||
}
|
|
||||||
|
|
||||||
if (game.is (GameFlags::Metamod)) {
|
|
||||||
RETURN_META (MRES_SUPERCEDE); // prevent bots to be forced to issue client commands
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (game.is (GameFlags::Metamod)) {
|
if (game.is (GameFlags::Metamod)) {
|
||||||
RETURN_META (MRES_IGNORED);
|
RETURN_META (MRES_SUPERCEDE); // prevent bots to be forced to issue client commands
|
||||||
}
|
}
|
||||||
engfuncs.pfnClientCommand (ent, buffer);
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (game.is (GameFlags::Metamod)) {
|
||||||
|
RETURN_META (MRES_IGNORED);
|
||||||
|
}
|
||||||
|
engfuncs.pfnClientCommand (ent, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
CR_EXPORT int GetEntityAPI (gamefuncs_t *table, int) {
|
CR_EXPORT int GetEntityAPI (gamefuncs_t *table, int) {
|
||||||
|
|
@ -255,7 +253,7 @@ CR_EXPORT int GetEntityAPI (gamefuncs_t *table, int) {
|
||||||
dllapi.pfnClientDisconnect (ent);
|
dllapi.pfnClientDisconnect (ent);
|
||||||
};
|
};
|
||||||
|
|
||||||
table->pfnClientUserInfoChanged = [] (edict_t *ent, char *infobuffer) {
|
table->pfnClientUserInfoChanged = [] (edict_t *ent, char *infobuffer) {
|
||||||
// this function is called when a player changes model, or changes team. Occasionally it
|
// this function is called when a player changes model, or changes team. Occasionally it
|
||||||
// enforces rules on these changes (for example, some MODs don't want to allow players to
|
// enforces rules on these changes (for example, some MODs don't want to allow players to
|
||||||
// change their player model). But most commonly, this function is in charge of handling
|
// change their player model). But most commonly, this function is in charge of handling
|
||||||
|
|
@ -402,7 +400,7 @@ CR_EXPORT int GetEntityAPI (gamefuncs_t *table, int) {
|
||||||
|
|
||||||
// flush print queue to users
|
// flush print queue to users
|
||||||
ctrl.flushPrintQueue ();
|
ctrl.flushPrintQueue ();
|
||||||
|
|
||||||
if (game.is (GameFlags::Metamod)) {
|
if (game.is (GameFlags::Metamod)) {
|
||||||
RETURN_META (MRES_IGNORED);
|
RETURN_META (MRES_IGNORED);
|
||||||
}
|
}
|
||||||
|
|
@ -414,7 +412,7 @@ CR_EXPORT int GetEntityAPI (gamefuncs_t *table, int) {
|
||||||
|
|
||||||
table->pfnCmdStart = [] (const edict_t *player, usercmd_t *cmd, unsigned int random_seed) {
|
table->pfnCmdStart = [] (const edict_t *player, usercmd_t *cmd, unsigned int random_seed) {
|
||||||
auto ent = const_cast <edict_t *> (player);
|
auto ent = const_cast <edict_t *> (player);
|
||||||
|
|
||||||
// if we're handle pings for bots and clients, clear IN_SCORE button so SV_ShouldUpdatePing engine function return false, and SV_EmitPings will not overwrite our results
|
// if we're handle pings for bots and clients, clear IN_SCORE button so SV_ShouldUpdatePing engine function return false, and SV_EmitPings will not overwrite our results
|
||||||
if (game.is (GameFlags::HasFakePings) && cv_show_latency.int_ () == 2) {
|
if (game.is (GameFlags::HasFakePings) && cv_show_latency.int_ () == 2) {
|
||||||
if (!util.isFakeClient (ent) && (ent->v.oldbuttons | ent->v.button | cmd->buttons) & IN_SCORE) {
|
if (!util.isFakeClient (ent) && (ent->v.oldbuttons | ent->v.button | cmd->buttons) & IN_SCORE) {
|
||||||
|
|
@ -422,7 +420,7 @@ CR_EXPORT int GetEntityAPI (gamefuncs_t *table, int) {
|
||||||
util.emitPings (ent);
|
util.emitPings (ent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (game.is (GameFlags::Metamod)) {
|
if (game.is (GameFlags::Metamod)) {
|
||||||
RETURN_META (MRES_IGNORED);
|
RETURN_META (MRES_IGNORED);
|
||||||
}
|
}
|
||||||
|
|
@ -509,7 +507,7 @@ CR_LINKAGE_C int GetEngineFunctions (enginefuncs_t *table, int *) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ents.needsBypass () && !game.is (GameFlags::Metamod)) {
|
if (ents.needsBypass () && !game.is (GameFlags::Metamod)) {
|
||||||
table->pfnCreateNamedEntity = [] (int classname) -> edict_t * {
|
table->pfnCreateNamedEntity = [] (int classname) -> edict_t *{
|
||||||
|
|
||||||
if (ents.isPaused ()) {
|
if (ents.isPaused ()) {
|
||||||
ents.enable ();
|
ents.enable ();
|
||||||
|
|
@ -779,7 +777,7 @@ CR_LINKAGE_C int GetEngineFunctions (enginefuncs_t *table, int *) {
|
||||||
engfuncs.pfnSetClientMaxspeed (ent, newMaxspeed);
|
engfuncs.pfnSetClientMaxspeed (ent, newMaxspeed);
|
||||||
};
|
};
|
||||||
|
|
||||||
table->pfnClientCommand = variadic::clientCommand;
|
table->pfnClientCommand = hook_ClientCommand;
|
||||||
|
|
||||||
return HLTrue;
|
return HLTrue;
|
||||||
}
|
}
|
||||||
|
|
@ -830,7 +828,7 @@ CR_LINKAGE_C int GetEngineFunctions_Post (enginefuncs_t *table, int *) {
|
||||||
|
|
||||||
RETURN_META (MRES_IGNORED);
|
RETURN_META (MRES_IGNORED);
|
||||||
};
|
};
|
||||||
|
|
||||||
table->pfnRegUserMsg = [] (const char *name, int) {
|
table->pfnRegUserMsg = [] (const char *name, int) {
|
||||||
// this function registers a "user message" by the engine side. User messages are network
|
// this function registers a "user message" by the engine side. User messages are network
|
||||||
// messages the game DLL asks the engine to send to clients. Since many MODs have completely
|
// messages the game DLL asks the engine to send to clients. Since many MODs have completely
|
||||||
|
|
@ -989,7 +987,7 @@ CR_EXPORT int Server_GetPhysicsInterface (int version, server_physics_api_t *phy
|
||||||
// this function handle the custom xash3d physics interface, that we're uses just for resolving
|
// this function handle the custom xash3d physics interface, that we're uses just for resolving
|
||||||
// entities between game and engine.
|
// entities between game and engine.
|
||||||
|
|
||||||
if (!table || !physics_api || version != SV_PHYSICS_INTERFACE_VERSION) {
|
if (!table || !physics_api || version != SV_PHYSICS_INTERFACE_VERSION) {
|
||||||
return HLFalse;
|
return HLFalse;
|
||||||
}
|
}
|
||||||
table->version = SV_PHYSICS_INTERFACE_VERSION;
|
table->version = SV_PHYSICS_INTERFACE_VERSION;
|
||||||
|
|
@ -1061,7 +1059,7 @@ void EntityLinkage::callPlayerFunction (edict_t *ent) {
|
||||||
else {
|
else {
|
||||||
playerFunction = reinterpret_cast <EntityFunction> (lookup (game.lib ().handle (), "player"));
|
playerFunction = reinterpret_cast <EntityFunction> (lookup (game.lib ().handle (), "player"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!playerFunction) {
|
if (!playerFunction) {
|
||||||
logger.fatal ("Cannot resolve player () function in gamedll.");
|
logger.fatal ("Cannot resolve player () function in gamedll.");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -163,7 +163,7 @@ BotCreateResult BotManager::create (StringRef name, int difficulty, int personal
|
||||||
}
|
}
|
||||||
|
|
||||||
// don't allow creating bots with changed graph (distance tables are messed up)
|
// don't allow creating bots with changed graph (distance tables are messed up)
|
||||||
else if (graph.hasChanged ()) {
|
else if (graph.hasChanged ()) {
|
||||||
ctrl.msg ("Graph has been changed. Load graph again...");
|
ctrl.msg ("Graph has been changed. Load graph again...");
|
||||||
return BotCreateResult::GraphError;
|
return BotCreateResult::GraphError;
|
||||||
}
|
}
|
||||||
|
|
@ -237,7 +237,7 @@ BotCreateResult BotManager::create (StringRef name, int difficulty, int personal
|
||||||
botName->usedBy = index; // save by who name is used
|
botName->usedBy = index; // save by who name is used
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
conf.setBotNameUsed(index, resultName);
|
conf.setBotNameUsed (index, resultName);
|
||||||
}
|
}
|
||||||
m_bots.push (cr::move (object));
|
m_bots.push (cr::move (object));
|
||||||
|
|
||||||
|
|
@ -473,7 +473,7 @@ void BotManager::maintainAutoKill () {
|
||||||
if (!totalHumans) {
|
if (!totalHumans) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto &bot : m_bots) {
|
for (const auto &bot : m_bots) {
|
||||||
if (bot->m_notKilled) {
|
if (bot->m_notKilled) {
|
||||||
++aliveBots;
|
++aliveBots;
|
||||||
|
|
@ -566,7 +566,7 @@ void BotManager::serverFill (int selection, int personality, int difficulty, int
|
||||||
else {
|
else {
|
||||||
selection = 5;
|
selection = 5;
|
||||||
}
|
}
|
||||||
char teams[6][12] = {"", {"Terrorists"}, {"CTs"}, "", "", {"Random"}, };
|
char teams[6][12] = { "", {"Terrorists"}, {"CTs"}, "", "", {"Random"}, };
|
||||||
auto toAdd = numToAdd == -1 ? maxClients - (getHumansCount () + getBotCount ()) : numToAdd;
|
auto toAdd = numToAdd == -1 ? maxClients - (getHumansCount () + getBotCount ()) : numToAdd;
|
||||||
|
|
||||||
for (int i = 0; i <= toAdd; ++i) {
|
for (int i = 0; i <= toAdd; ++i) {
|
||||||
|
|
@ -703,7 +703,7 @@ bool BotManager::kickRandom (bool decQuota, Team fromTeam) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BotManager::setLastWinner (int winner) {
|
void BotManager::setLastWinner (int winner) {
|
||||||
m_lastWinner = winner;
|
m_lastWinner = winner;
|
||||||
m_roundOver = true;
|
m_roundOver = true;
|
||||||
|
|
||||||
|
|
@ -748,8 +748,8 @@ void BotManager::setWeaponMode (int selection) {
|
||||||
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, -1, 1, -1, -1}, // Snipers only
|
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, -1, 1, -1, -1}, // Snipers only
|
||||||
{-1, -1, -1, 2, 2, 0, 1, 1, 1, 1, 1, 1, 0, 2, 0, -1, 1, 0, 1, 1, 0, 0, -1, 1, 1, 1} // Standard
|
{-1, -1, -1, 2, 2, 0, 1, 1, 1, 1, 1, 1, 0, 2, 0, -1, 1, 0, 1, 1, 0, 0, -1, 1, 1, 1} // Standard
|
||||||
};
|
};
|
||||||
constexpr char modes[7][12] = {{"Knife"}, {"Pistol"}, {"Shotgun"}, {"Machine Gun"}, {"Rifle"}, {"Sniper"}, {"Standard"}};
|
constexpr char modes[7][12] = { {"Knife"}, {"Pistol"}, {"Shotgun"}, {"Machine Gun"}, {"Rifle"}, {"Sniper"}, {"Standard"} };
|
||||||
|
|
||||||
// get the raw weapons array
|
// get the raw weapons array
|
||||||
auto tab = conf.getRawWeapons ();
|
auto tab = conf.getRawWeapons ();
|
||||||
|
|
||||||
|
|
@ -768,7 +768,8 @@ void BotManager::listBots () {
|
||||||
|
|
||||||
ctrl.msg ("%-3.5s\t%-19.16s\t%-10.12s\t%-3.4s\t%-3.4s\t%-3.4s\t%-3.5s", "index", "name", "personality", "team", "difficulty", "frags", "alive");
|
ctrl.msg ("%-3.5s\t%-19.16s\t%-10.12s\t%-3.4s\t%-3.4s\t%-3.4s\t%-3.5s", "index", "name", "personality", "team", "difficulty", "frags", "alive");
|
||||||
|
|
||||||
for (const auto &bot : bots) {;
|
for (const auto &bot : bots) {
|
||||||
|
;
|
||||||
ctrl.msg ("[%-3.1d]\t%-19.16s\t%-10.12s\t%-3.4s\t%-3.1d\t%-3.1d\t%-3.4s", bot->index (), bot->pev->netname.chars (), bot->m_personality == Personality::Rusher ? "rusher" : bot->m_personality == Personality::Normal ? "normal" : "careful", bot->m_team == Team::CT ? "CT" : "T", bot->m_difficulty, static_cast <int> (bot->pev->frags), bot->m_notKilled ? "yes" : "no");
|
ctrl.msg ("[%-3.1d]\t%-19.16s\t%-10.12s\t%-3.4s\t%-3.1d\t%-3.1d\t%-3.4s", bot->index (), bot->pev->netname.chars (), bot->m_personality == Personality::Rusher ? "rusher" : bot->m_personality == Personality::Normal ? "normal" : "careful", bot->m_team == Team::CT ? "CT" : "T", bot->m_difficulty, static_cast <int> (bot->pev->frags), bot->m_notKilled ? "yes" : "no");
|
||||||
}
|
}
|
||||||
ctrl.msg ("%d bots", m_bots.length ());
|
ctrl.msg ("%d bots", m_bots.length ());
|
||||||
|
|
@ -966,7 +967,7 @@ Bot::Bot (edict_t *bot, int difficulty, int personality, int team, int skin) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char reject[256] = {0, };
|
char reject[256] = { 0, };
|
||||||
MDLL_ClientConnect (bot, bot->v.netname.chars (), strings.format ("127.0.0.%d", clientIndex + 100), reject);
|
MDLL_ClientConnect (bot, bot->v.netname.chars (), strings.format ("127.0.0.%d", clientIndex + 100), reject);
|
||||||
|
|
||||||
if (!strings.isEmpty (reject)) {
|
if (!strings.isEmpty (reject)) {
|
||||||
|
|
@ -1146,7 +1147,7 @@ void BotManager::erase (Bot *bot) {
|
||||||
m_bots.erase (index, 1); // remove from bots array
|
m_bots.erase (index, 1); // remove from bots array
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BotManager::handleDeath (edict_t *killer, edict_t *victim) {
|
void BotManager::handleDeath (edict_t *killer, edict_t *victim) {
|
||||||
|
|
@ -1194,13 +1195,13 @@ void BotManager::handleDeath (edict_t *killer, edict_t *victim) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// did a human kill a bot on his team?
|
// did a human kill a bot on his team?
|
||||||
else {
|
else {
|
||||||
if (victimBot != nullptr) {
|
if (victimBot != nullptr) {
|
||||||
if (killerTeam == victimBot->m_team) {
|
if (killerTeam == victimBot->m_team) {
|
||||||
victimBot->m_voteKickIndex = game.indexOfEntity (killer);
|
victimBot->m_voteKickIndex = game.indexOfEntity (killer);
|
||||||
for (const auto ¬ify : bots) {
|
for (const auto ¬ify : bots) {
|
||||||
if (notify->seesEntity (victim->v.origin)) {
|
if (notify->seesEntity (victim->v.origin)) {
|
||||||
notify->pushChatterMessage (Chatter::TeamKill);
|
notify->pushChatterMessage (Chatter::TeamKill);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1221,7 +1222,7 @@ void Bot::newRound () {
|
||||||
|
|
||||||
m_path = nullptr;
|
m_path = nullptr;
|
||||||
m_currentTravelFlags = 0;
|
m_currentTravelFlags = 0;
|
||||||
m_desiredVelocity= nullptr;
|
m_desiredVelocity = nullptr;
|
||||||
m_currentNodeIndex = kInvalidNodeIndex;
|
m_currentNodeIndex = kInvalidNodeIndex;
|
||||||
m_prevGoalIndex = kInvalidNodeIndex;
|
m_prevGoalIndex = kInvalidNodeIndex;
|
||||||
m_chosenGoalIndex = kInvalidNodeIndex;
|
m_chosenGoalIndex = kInvalidNodeIndex;
|
||||||
|
|
@ -1310,7 +1311,7 @@ void Bot::newRound () {
|
||||||
m_aimFlags = 0;
|
m_aimFlags = 0;
|
||||||
m_liftState = 0;
|
m_liftState = 0;
|
||||||
|
|
||||||
m_aimLastError= nullptr;
|
m_aimLastError = nullptr;
|
||||||
m_position = nullptr;
|
m_position = nullptr;
|
||||||
m_liftTravelPos = nullptr;
|
m_liftTravelPos = nullptr;
|
||||||
|
|
||||||
|
|
@ -1414,7 +1415,7 @@ void Bot::newRound () {
|
||||||
m_lastTrace[i] = {};
|
m_lastTrace[i] = {};
|
||||||
m_traceSkip[i] = 0;
|
m_traceSkip[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// and put buying into its message queue
|
// and put buying into its message queue
|
||||||
pushMsgQueue (BotMsg::Buy);
|
pushMsgQueue (BotMsg::Buy);
|
||||||
startTask (Task::Normal, TaskPri::Normal, kInvalidNodeIndex, 0.0f, true);
|
startTask (Task::Normal, TaskPri::Normal, kInvalidNodeIndex, 0.0f, true);
|
||||||
|
|
@ -1457,7 +1458,7 @@ void Bot::kill () {
|
||||||
void Bot::kick () {
|
void Bot::kick () {
|
||||||
// this function kick off one bot from the server.
|
// this function kick off one bot from the server.
|
||||||
auto username = pev->netname.chars ();
|
auto username = pev->netname.chars ();
|
||||||
|
|
||||||
if (!(pev->flags & FL_CLIENT) || strings.isEmpty (username)) {
|
if (!(pev->flags & FL_CLIENT) || strings.isEmpty (username)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -1471,7 +1472,7 @@ void Bot::markStale () {
|
||||||
showChaterIcon (false);
|
showChaterIcon (false);
|
||||||
|
|
||||||
// clear the bot name
|
// clear the bot name
|
||||||
conf.clearUsedName (this);
|
conf.clearUsedName (this);
|
||||||
|
|
||||||
// clear fakeclient bit
|
// clear fakeclient bit
|
||||||
pev->flags &= ~FL_FAKECLIENT;
|
pev->flags &= ~FL_FAKECLIENT;
|
||||||
|
|
@ -1602,10 +1603,10 @@ void BotManager::captureChatRadio (const char *cmd, const char *arg, edict_t *en
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
auto target = bots[client.ent];
|
auto target = bots[client.ent];
|
||||||
|
|
||||||
if (target != nullptr) {
|
if (target != nullptr) {
|
||||||
target->m_sayTextBuffer.entityIndex = game.indexOfPlayer (ent);
|
target->m_sayTextBuffer.entityIndex = game.indexOfPlayer (ent);
|
||||||
|
|
||||||
if (strings.isEmpty (engfuncs.pfnCmd_Args ())) {
|
if (strings.isEmpty (engfuncs.pfnCmd_Args ())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -1690,7 +1691,7 @@ void BotManager::updateIntrestingEntities () {
|
||||||
// search the map for any type of grenade
|
// search the map for any type of grenade
|
||||||
game.searchEntities (nullptr, kInfiniteDistance, [&] (edict_t *e) {
|
game.searchEntities (nullptr, kInfiniteDistance, [&] (edict_t *e) {
|
||||||
auto classname = e->v.classname.chars ();
|
auto classname = e->v.classname.chars ();
|
||||||
|
|
||||||
// search for grenades, weaponboxes, weapons, items and armoury entities
|
// search for grenades, weaponboxes, weapons, items and armoury entities
|
||||||
if (strncmp ("weaponbox", classname, 9) == 0 || strncmp ("grenade", classname, 7) == 0 || util.isItem (e) || strncmp ("armoury", classname, 7) == 0) {
|
if (strncmp ("weaponbox", classname, 9) == 0 || strncmp ("grenade", classname, 7) == 0 || util.isItem (e) || strncmp ("armoury", classname, 7) == 0) {
|
||||||
m_intrestingEntities.push (e);
|
m_intrestingEntities.push (e);
|
||||||
|
|
|
||||||
|
|
@ -206,7 +206,7 @@ void MessageDispatcher::netMsgDamage () {
|
||||||
if (m_args.length () < min || !m_bot) {
|
if (m_args.length () < min || !m_bot) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle damage if any
|
// handle damage if any
|
||||||
if (m_args[armor].long_ > 0 || m_args[health].long_) {
|
if (m_args[armor].long_ > 0 || m_args[health].long_) {
|
||||||
m_bot->takeDamage (m_bot->pev->dmg_inflictor, m_args[health].long_, m_args[armor].long_, m_args[bits].long_);
|
m_bot->takeDamage (m_bot->pev->dmg_inflictor, m_args[health].long_, m_args[armor].long_, m_args[bits].long_);
|
||||||
|
|
@ -283,7 +283,7 @@ void MessageDispatcher::netMsgScreenFade () {
|
||||||
if (m_args.length () < min || !m_bot) {
|
if (m_args.length () < min || !m_bot) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// screen completely faded ?
|
// screen completely faded ?
|
||||||
if (m_args[r].long_ >= 255 && m_args[g].long_ >= 255 && m_args[b].long_ >= 255 && m_args[alpha].long_ > 170) {
|
if (m_args[r].long_ >= 255 && m_args[g].long_ >= 255 && m_args[b].long_ >= 255 && m_args[alpha].long_ > 170) {
|
||||||
m_bot->takeBlind (m_args[alpha].long_);
|
m_bot->takeBlind (m_args[alpha].long_);
|
||||||
|
|
|
||||||
|
|
@ -237,7 +237,7 @@ int Bot::findGoalPost (int tactic, IntArray *defensive, IntArray *offsensive) {
|
||||||
|
|
||||||
for (auto &choice : goalChoices) {
|
for (auto &choice : goalChoices) {
|
||||||
if (choice == kInvalidNodeIndex) {
|
if (choice == kInvalidNodeIndex) {
|
||||||
choice = graph.m_rescuePoints.random ();
|
choice = graph.m_rescuePoints.random ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -369,7 +369,7 @@ bool Bot::doPlayerAvoidance (const Vector &normal) {
|
||||||
// use our movement angles, try to predict where we should be next frame
|
// use our movement angles, try to predict where we should be next frame
|
||||||
Vector right, forward;
|
Vector right, forward;
|
||||||
m_moveAngles.angleVectors (&forward, &right, nullptr);
|
m_moveAngles.angleVectors (&forward, &right, nullptr);
|
||||||
|
|
||||||
Vector predict = pev->origin + forward * m_moveSpeed * interval;
|
Vector predict = pev->origin + forward * m_moveSpeed * interval;
|
||||||
|
|
||||||
predict += right * m_strafeSpeed * interval;
|
predict += right * m_strafeSpeed * interval;
|
||||||
|
|
@ -597,8 +597,7 @@ void Bot::checkTerrain (float movedDistance, const Vector &dirNormal) {
|
||||||
++i;
|
++i;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
if (bits & CollisionProbe::Duck)
|
if (bits & CollisionProbe::Duck) {
|
||||||
{
|
|
||||||
state[i] = 0;
|
state[i] = 0;
|
||||||
|
|
||||||
if (canDuckUnder (dirNormal)) {
|
if (canDuckUnder (dirNormal)) {
|
||||||
|
|
@ -611,7 +610,7 @@ void Bot::checkTerrain (float movedDistance, const Vector &dirNormal) {
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
state[i] = 0;
|
state[i] = 0;
|
||||||
++i;
|
++i;
|
||||||
|
|
||||||
// weighted all possible moves, now sort them to start with most probable
|
// weighted all possible moves, now sort them to start with most probable
|
||||||
|
|
@ -687,7 +686,7 @@ bool Bot::updateNavigation () {
|
||||||
if (m_currentNodeIndex == kInvalidNodeIndex) {
|
if (m_currentNodeIndex == kInvalidNodeIndex) {
|
||||||
findValidNode ();
|
findValidNode ();
|
||||||
m_pathOrigin = m_path->origin;
|
m_pathOrigin = m_path->origin;
|
||||||
|
|
||||||
// if graph node radius non zero vary origin a bit depending on the body angles
|
// if graph node radius non zero vary origin a bit depending on the body angles
|
||||||
if (m_path->radius > 0.0f) {
|
if (m_path->radius > 0.0f) {
|
||||||
m_pathOrigin += Vector (pev->angles.x, cr::normalizeAngles (pev->angles.y + rg.get (-90.0f, 90.0f)), 0.0f).forward () * rg.get (0.0f, m_path->radius);
|
m_pathOrigin += Vector (pev->angles.x, cr::normalizeAngles (pev->angles.y + rg.get (-90.0f, 90.0f)), 0.0f).forward () * rg.get (0.0f, m_path->radius);
|
||||||
|
|
@ -728,8 +727,8 @@ bool Bot::updateNavigation () {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(graph[m_previousNodes[0]].flags & NodeFlag::Ladder)) {
|
if (!(graph[m_previousNodes[0]].flags & NodeFlag::Ladder)) {
|
||||||
if (cr::abs (m_pathOrigin.z - pev->origin.z) > 5.0f) {
|
if (cr::abs (m_pathOrigin.z - pev->origin.z) > 5.0f) {
|
||||||
m_pathOrigin.z += pev->origin.z - m_pathOrigin.z;
|
m_pathOrigin.z += pev->origin.z - m_pathOrigin.z;
|
||||||
}
|
}
|
||||||
|
|
@ -741,7 +740,7 @@ bool Bot::updateNavigation () {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_destOrigin = m_pathOrigin;
|
m_destOrigin = m_pathOrigin;
|
||||||
|
|
||||||
// special detection if someone is using the ladder (to prevent to have bots-towers on ladders)
|
// special detection if someone is using the ladder (to prevent to have bots-towers on ladders)
|
||||||
for (const auto &client : util.getClients ()) {
|
for (const auto &client : util.getClients ()) {
|
||||||
if (!(client.flags & ClientFlags::Used) || !(client.flags & ClientFlags::Alive) || (client.ent->v.movetype != MOVETYPE_FLY) || client.ent == nullptr || client.ent == ent ()) {
|
if (!(client.flags & ClientFlags::Used) || !(client.flags & ClientFlags::Alive) || (client.ent->v.movetype != MOVETYPE_FLY) || client.ent == nullptr || client.ent == ent ()) {
|
||||||
|
|
@ -764,7 +763,7 @@ bool Bot::updateNavigation () {
|
||||||
|
|
||||||
m_enemyParts = Visibility::None;
|
m_enemyParts = Visibility::None;
|
||||||
m_enemyParts |= (Visibility::Head | Visibility::Body);
|
m_enemyParts |= (Visibility::Head | Visibility::Body);
|
||||||
|
|
||||||
m_states |= Sense::SeeingEnemy;
|
m_states |= Sense::SeeingEnemy;
|
||||||
m_seeEnemyTime = game.time ();
|
m_seeEnemyTime = game.time ();
|
||||||
break;
|
break;
|
||||||
|
|
@ -809,7 +808,7 @@ bool Bot::updateNavigation () {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -914,7 +913,7 @@ bool Bot::updateNavigation () {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// needs precise placement - check if we get past the point
|
// needs precise placement - check if we get past the point
|
||||||
if (desiredDistance < 22.0f && nodeDistance < 30.0f && m_pathOrigin.distanceSq (pev->origin + pev->velocity * getFrameInterval ()) >= cr::square (nodeDistance)) {
|
if (desiredDistance < 22.0f && nodeDistance < 30.0f && m_pathOrigin.distanceSq (pev->origin + pev->velocity * getFrameInterval ()) >= cr::square (nodeDistance)) {
|
||||||
desiredDistance = nodeDistance + 1.0f;
|
desiredDistance = nodeDistance + 1.0f;
|
||||||
|
|
@ -1168,7 +1167,7 @@ bool Bot::updateLiftHandling () {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!game.isNullEntity (m_liftEntity)) {
|
else if (!game.isNullEntity (m_liftEntity)) {
|
||||||
auto button = lookupButton (m_liftEntity->v.targetname.chars ());
|
auto button = lookupButton (m_liftEntity->v.targetname.chars ());
|
||||||
|
|
||||||
// if we got a valid button entity
|
// if we got a valid button entity
|
||||||
if (!game.isNullEntity (button)) {
|
if (!game.isNullEntity (button)) {
|
||||||
|
|
@ -1294,7 +1293,7 @@ bool Bot::updateLiftStates () {
|
||||||
void Bot::findShortestPath (int srcIndex, int destIndex) {
|
void Bot::findShortestPath (int srcIndex, int destIndex) {
|
||||||
// this function finds the shortest path from source index to destination index
|
// this function finds the shortest path from source index to destination index
|
||||||
|
|
||||||
if (!graph.exists (srcIndex)){
|
if (!graph.exists (srcIndex)) {
|
||||||
logger.error ("%s source path index not valid (%d).", __FUNCTION__, srcIndex);
|
logger.error ("%s source path index not valid (%d).", __FUNCTION__, srcIndex);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -1634,7 +1633,7 @@ int Bot::findAimingNode (const Vector &to) {
|
||||||
if (destIndex == kInvalidNodeIndex) {
|
if (destIndex == kInvalidNodeIndex) {
|
||||||
return kInvalidNodeIndex;
|
return kInvalidNodeIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (destIndex != m_currentNodeIndex) {
|
while (destIndex != m_currentNodeIndex) {
|
||||||
destIndex = (graph.m_matrix.data () + (destIndex * graph.length ()) + m_currentNodeIndex)->index;
|
destIndex = (graph.m_matrix.data () + (destIndex * graph.length ()) + m_currentNodeIndex)->index;
|
||||||
|
|
||||||
|
|
@ -1692,7 +1691,7 @@ bool Bot::findBestNearestNode () {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check we're have link to it
|
// check we're have link to it
|
||||||
if (m_currentNodeIndex != kInvalidNodeIndex && !graph.isConnected (m_currentNodeIndex, at)) {
|
if (m_currentNodeIndex != kInvalidNodeIndex && !graph.isConnected (m_currentNodeIndex, at)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -1767,7 +1766,7 @@ bool Bot::findBestNearestNode () {
|
||||||
|
|
||||||
float Bot::getReachTime () {
|
float Bot::getReachTime () {
|
||||||
auto task = getCurrentTaskId ();
|
auto task = getCurrentTaskId ();
|
||||||
float estimatedTime = 0.0f;
|
float estimatedTime = 0.0f;
|
||||||
|
|
||||||
switch (task) {
|
switch (task) {
|
||||||
case Task::Pause:
|
case Task::Pause:
|
||||||
|
|
@ -2036,7 +2035,7 @@ int Bot::findDefendNode (const Vector &origin) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nodeIndex[rg.get (0, (index -1) / 2)];
|
return nodeIndex[rg.get (0, (index - 1) / 2)];
|
||||||
}
|
}
|
||||||
|
|
||||||
int Bot::findCoverNode (float maxDistance) {
|
int Bot::findCoverNode (float maxDistance) {
|
||||||
|
|
@ -2194,16 +2193,16 @@ bool Bot::advanceMovement () {
|
||||||
// advances in our pathfinding list and sets the appropiate destination origins for this bot
|
// advances in our pathfinding list and sets the appropiate destination origins for this bot
|
||||||
|
|
||||||
findValidNode (); // check if old nodes is still reliable
|
findValidNode (); // check if old nodes is still reliable
|
||||||
|
|
||||||
// no nodes from pathfinding?
|
// no nodes from pathfinding?
|
||||||
if (m_pathWalk.empty ()) {
|
if (m_pathWalk.empty ()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
TraceResult tr {};
|
TraceResult tr {};
|
||||||
|
|
||||||
m_pathWalk.shift (); // advance in list
|
m_pathWalk.shift (); // advance in list
|
||||||
m_currentTravelFlags = 0; // reset travel flags (jumping etc)
|
m_currentTravelFlags = 0; // reset travel flags (jumping etc)
|
||||||
|
|
||||||
// helper to change bot's goal
|
// helper to change bot's goal
|
||||||
auto changeNextGoal = [&] {
|
auto changeNextGoal = [&] {
|
||||||
int newGoal = findBestGoal ();
|
int newGoal = findBestGoal ();
|
||||||
|
|
@ -2807,7 +2806,7 @@ bool Bot::isDeadlyMove (const Vector &to) {
|
||||||
game.testHull (check, down, TraceIgnore::Monsters, head_hull, ent (), &tr);
|
game.testHull (check, down, TraceIgnore::Monsters, head_hull, ent (), &tr);
|
||||||
|
|
||||||
// wall blocking?
|
// wall blocking?
|
||||||
if (tr.fStartSolid) {
|
if (tr.fStartSolid) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
float height = tr.flFraction * 1000.0f; // height from ground
|
float height = tr.flFraction * 1000.0f; // height from ground
|
||||||
|
|
@ -2946,7 +2945,7 @@ void Bot::updateBodyAngles () {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bot::updateLookAngles () {
|
void Bot::updateLookAngles () {
|
||||||
|
|
||||||
const float delta = cr::clamp (game.time () - m_lookUpdateTime, cr::kFloatEqualEpsilon, 1.0f / 30.0f);
|
const float delta = cr::clamp (game.time () - m_lookUpdateTime, cr::kFloatEqualEpsilon, 1.0f / 30.0f);
|
||||||
m_lookUpdateTime = game.time ();
|
m_lookUpdateTime = game.time ();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -177,11 +177,11 @@ void BotSupport::traceDecals (entvars_t *pev, TraceResult *trace, int logotypeIn
|
||||||
MessageWriter msg;
|
MessageWriter msg;
|
||||||
|
|
||||||
msg.start (MSG_BROADCAST, SVC_TEMPENTITY)
|
msg.start (MSG_BROADCAST, SVC_TEMPENTITY)
|
||||||
.writeByte (message)
|
.writeByte (message)
|
||||||
.writeCoord (trace->vecEndPos.x)
|
.writeCoord (trace->vecEndPos.x)
|
||||||
.writeCoord (trace->vecEndPos.y)
|
.writeCoord (trace->vecEndPos.y)
|
||||||
.writeCoord (trace->vecEndPos.z)
|
.writeCoord (trace->vecEndPos.z)
|
||||||
.writeByte (decalIndex);
|
.writeByte (decalIndex);
|
||||||
|
|
||||||
if (entityIndex) {
|
if (entityIndex) {
|
||||||
msg.writeShort (entityIndex);
|
msg.writeShort (entityIndex);
|
||||||
|
|
@ -222,7 +222,7 @@ bool BotSupport::isMonster (edict_t *ent) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BotSupport::isItem (edict_t *ent) {
|
bool BotSupport::isItem (edict_t *ent) {
|
||||||
return !!(strstr (ent->v.classname.chars(), "item_"));
|
return !!(strstr (ent->v.classname.chars (), "item_"));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BotSupport::isPlayerVIP (edict_t *ent) {
|
bool BotSupport::isPlayerVIP (edict_t *ent) {
|
||||||
|
|
@ -489,7 +489,7 @@ void BotSupport::simulateNoise (int playerIndex) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// pressed reload button?
|
// pressed reload button?
|
||||||
else if (buttons & IN_RELOAD) {
|
else if (buttons & IN_RELOAD) {
|
||||||
noise.dist = 512.0f;
|
noise.dist = 512.0f;
|
||||||
noise.last = game.time () + 0.5f;
|
noise.last = game.time () + 0.5f;
|
||||||
}
|
}
|
||||||
|
|
@ -637,7 +637,7 @@ void BotSupport::emitPings (edict_t *to) {
|
||||||
auto isThirdpartyBot = [] (edict_t *ent) {
|
auto isThirdpartyBot = [] (edict_t *ent) {
|
||||||
return !bots[ent] && (ent->v.flags & FL_FAKECLIENT);
|
return !bots[ent] && (ent->v.flags & FL_FAKECLIENT);
|
||||||
};
|
};
|
||||||
|
|
||||||
for (auto &client : m_clients) {
|
for (auto &client : m_clients) {
|
||||||
if (!(client.flags & ClientFlags::Used) || client.ent == game.getLocalEntity () || isThirdpartyBot (client.ent)) {
|
if (!(client.flags & ClientFlags::Used) || client.ent == game.getLocalEntity () || isThirdpartyBot (client.ent)) {
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -647,7 +647,7 @@ void BotSupport::emitPings (edict_t *to) {
|
||||||
if (!client.ping) {
|
if (!client.ping) {
|
||||||
client.ping = getPingBitmask (client.ent, rg.get (5, 10), rg.get (15, 40));
|
client.ping = getPingBitmask (client.ent, rg.get (5, 10), rg.get (15, 40));
|
||||||
}
|
}
|
||||||
|
|
||||||
msg.start (MSG_ONE_UNRELIABLE, kGamePingSVC, nullptr, to)
|
msg.start (MSG_ONE_UNRELIABLE, kGamePingSVC, nullptr, to)
|
||||||
.writeLong (client.ping)
|
.writeLong (client.ping)
|
||||||
.end ();
|
.end ();
|
||||||
|
|
@ -676,7 +676,7 @@ void BotSupport::installSendTo () {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BotSupport::isObjectInsidePlane (FrustumPlane &plane, const Vector ¢er, float height, float radius) {
|
bool BotSupport::isObjectInsidePlane (FrustumPlane &plane, const Vector ¢er, float height, float radius) {
|
||||||
auto isPointInsidePlane = [&](const Vector &point) -> bool {
|
auto isPointInsidePlane = [&] (const Vector &point) -> bool {
|
||||||
return plane.result + (plane.normal | point) >= 0.0f;
|
return plane.result + (plane.normal | point) >= 0.0f;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -707,12 +707,12 @@ int32 BotSupport::sendTo (int socket, const void *message, size_t length, int fl
|
||||||
const auto send = [&] (const Twin <const uint8 *, size_t> &msg) -> int32 {
|
const auto send = [&] (const Twin <const uint8 *, size_t> &msg) -> int32 {
|
||||||
return Socket::sendto (socket, msg.first, msg.second, flags, dest, destLength);
|
return Socket::sendto (socket, msg.first, msg.second, flags, dest, destLength);
|
||||||
};
|
};
|
||||||
|
|
||||||
auto packet = reinterpret_cast <const uint8 *> (message);
|
auto packet = reinterpret_cast <const uint8 *> (message);
|
||||||
|
|
||||||
// player replies response
|
// player replies response
|
||||||
if (length > 5 && packet[0] == 0xff && packet[1] == 0xff && packet[2] == 0xff && packet[3] == 0xff) {
|
if (length > 5 && packet[0] == 0xff && packet[1] == 0xff && packet[2] == 0xff && packet[3] == 0xff) {
|
||||||
|
|
||||||
if (packet[4] == 'D') {
|
if (packet[4] == 'D') {
|
||||||
QueryBuffer buffer (packet, length, 5);
|
QueryBuffer buffer (packet, length, 5);
|
||||||
auto count = buffer.read <uint8> ();
|
auto count = buffer.read <uint8> ();
|
||||||
|
|
@ -730,7 +730,7 @@ int32 BotSupport::sendTo (int socket, const void *message, size_t length, int fl
|
||||||
else if (packet[4] == 'I') {
|
else if (packet[4] == 'I') {
|
||||||
QueryBuffer buffer (packet, length, 5);
|
QueryBuffer buffer (packet, length, 5);
|
||||||
buffer.skip <uint8> (); // protocol
|
buffer.skip <uint8> (); // protocol
|
||||||
|
|
||||||
// skip server name, folder, map game
|
// skip server name, folder, map game
|
||||||
for (size_t i = 0; i < 4; ++i) {
|
for (size_t i = 0; i < 4; ++i) {
|
||||||
buffer.skipString ();
|
buffer.skipString ();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue