conf: get decal indices during config load
combat: do not init hitbox aiming if disabled nav: reverted some last changes nav: fixed check fall on ladders chat: added %g keyword that is replaced with graph author
This commit is contained in:
parent
7157cf1b2f
commit
ecb1f20303
12 changed files with 79 additions and 106 deletions
11
inc/config.h
11
inc/config.h
|
|
@ -48,7 +48,7 @@ private:
|
||||||
SmallArray <WeaponInfo> m_weapons {};
|
SmallArray <WeaponInfo> m_weapons {};
|
||||||
SmallArray <WeaponProp> m_weaponProps {};
|
SmallArray <WeaponProp> m_weaponProps {};
|
||||||
|
|
||||||
StringArray m_logos {};
|
IntArray m_logosIndices {};
|
||||||
StringArray m_avatars {};
|
StringArray m_avatars {};
|
||||||
|
|
||||||
HashMap <uint32_t, String, Hash <int32_t>> m_language {};
|
HashMap <uint32_t, String, Hash <int32_t>> m_language {};
|
||||||
|
|
@ -244,13 +244,8 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// get's random logo index
|
// get's random logo index
|
||||||
int32_t getRandomLogoIndex () const {
|
int32_t getRandomLogoDecalIndex () const {
|
||||||
return static_cast <int32_t> (m_logos.index (m_logos.random ()));
|
return static_cast <int32_t> (m_logosIndices.random ());
|
||||||
}
|
|
||||||
|
|
||||||
// get random name by index
|
|
||||||
StringRef getLogoName (int index) {
|
|
||||||
return m_logos[index];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// get custom value
|
// get custom value
|
||||||
|
|
|
||||||
|
|
@ -439,12 +439,12 @@ constexpr auto kSprayDistanceX2 = kSprayDistance * 2;
|
||||||
constexpr auto kMaxChatterRepeatInterval = 99.0f;
|
constexpr auto kMaxChatterRepeatInterval = 99.0f;
|
||||||
constexpr auto kViewFrameUpdate = 1.0f / 25.0f;
|
constexpr auto kViewFrameUpdate = 1.0f / 25.0f;
|
||||||
constexpr auto kGrenadeDamageRadius = 385.0f;
|
constexpr auto kGrenadeDamageRadius = 385.0f;
|
||||||
constexpr auto kMinMovedDistance = 2.0f;
|
constexpr auto kMinMovedDistance = 3.0f;
|
||||||
|
|
||||||
constexpr auto kInfiniteDistanceLong = static_cast <int> (kInfiniteDistance);
|
constexpr auto kInfiniteDistanceLong = static_cast <int> (kInfiniteDistance);
|
||||||
constexpr auto kMaxWeapons = 32;
|
constexpr auto kMaxWeapons = 32;
|
||||||
constexpr auto kNumWeapons = 26;
|
constexpr auto kNumWeapons = 26;
|
||||||
constexpr auto kMaxCollideMoves = 3;
|
constexpr auto kMaxCollideMoves = 4;
|
||||||
constexpr auto kGameMaxPlayers = 32;
|
constexpr auto kGameMaxPlayers = 32;
|
||||||
constexpr auto kGameTeamNum = 2;
|
constexpr auto kGameTeamNum = 2;
|
||||||
constexpr auto kInvalidNodeIndex = -1;
|
constexpr auto kInvalidNodeIndex = -1;
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ public:
|
||||||
bool findNearestPlayer (void **holder, edict_t *to, float searchDistance = 4096.0, bool sameTeam = false, bool needBot = false, bool needAlive = false, bool needDrawn = false, bool needBotWithC4 = false);
|
bool findNearestPlayer (void **holder, edict_t *to, float searchDistance = 4096.0, bool sameTeam = false, bool needBot = false, bool needAlive = false, bool needDrawn = false, bool needBotWithC4 = false);
|
||||||
|
|
||||||
// tracing decals for bots spraying logos
|
// tracing decals for bots spraying logos
|
||||||
void decalTrace (entvars_t *pev, TraceResult *trace, int logotypeIndex);
|
void decalTrace (TraceResult *trace, int decalIndex);
|
||||||
|
|
||||||
// update stats on clients
|
// update stats on clients
|
||||||
void updateClients ();
|
void updateClients ();
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,7 @@ struct WeaponInfo {
|
||||||
int id {}; // the weapon id value
|
int id {}; // the weapon id value
|
||||||
StringRef name {}; // name of the weapon when selecting it
|
StringRef name {}; // name of the weapon when selecting it
|
||||||
StringRef model {}; // model name to separate cs weapons
|
StringRef model {}; // model name to separate cs weapons
|
||||||
|
StringRef alias {}; // alias name for weapon
|
||||||
int price {}; // price when buying
|
int price {}; // price when buying
|
||||||
int minPrimaryAmmo {}; // minimum primary ammo
|
int minPrimaryAmmo {}; // minimum primary ammo
|
||||||
int teamStandard {}; // used by team (number) (standard map)
|
int teamStandard {}; // used by team (number) (standard map)
|
||||||
|
|
@ -235,7 +236,6 @@ private:
|
||||||
float m_prevTime {}; // time previously checked movement speed
|
float m_prevTime {}; // time previously checked movement speed
|
||||||
float m_heavyTimestamp {}; // is it time to execute heavy-weight functions
|
float m_heavyTimestamp {}; // is it time to execute heavy-weight functions
|
||||||
float m_prevSpeed {}; // speed some frames before
|
float m_prevSpeed {}; // speed some frames before
|
||||||
float m_prevVelocity {}; // velocity some frames before
|
|
||||||
float m_timeDoorOpen {}; // time to next door open check
|
float m_timeDoorOpen {}; // time to next door open check
|
||||||
float m_timeHitDoor {}; // specific time after hitting the door
|
float m_timeHitDoor {}; // specific time after hitting the door
|
||||||
float m_lastChatTime {}; // time bot last chatted
|
float m_lastChatTime {}; // time bot last chatted
|
||||||
|
|
@ -315,7 +315,6 @@ private:
|
||||||
|
|
||||||
PathWalk m_pathWalk {}; // pointer to current node from path
|
PathWalk m_pathWalk {}; // pointer to current node from path
|
||||||
Dodge m_dodgeStrafeDir {}; // direction to strafe
|
Dodge m_dodgeStrafeDir {}; // direction to strafe
|
||||||
Dodge m_avoidAction {}; // player avoid action
|
|
||||||
Fight m_fightStyle {}; // combat style to use
|
Fight m_fightStyle {}; // combat style to use
|
||||||
CollisionState m_collisionState {}; // collision State
|
CollisionState m_collisionState {}; // collision State
|
||||||
FindPath m_pathType {}; // which pathfinder to use
|
FindPath m_pathType {}; // which pathfinder to use
|
||||||
|
|
@ -351,6 +350,7 @@ private:
|
||||||
Vector m_breakableOrigin {}; // origin of breakable
|
Vector m_breakableOrigin {}; // origin of breakable
|
||||||
Vector m_rightRef {}; // right referential vector
|
Vector m_rightRef {}; // right referential vector
|
||||||
Vector m_checkFallPoint[2] {}; // check fall point
|
Vector m_checkFallPoint[2] {}; // check fall point
|
||||||
|
Vector m_prevVelocity {}; // velocity some frames before
|
||||||
|
|
||||||
Array <edict_t *> m_ignoredBreakable {}; // list of ignored breakables
|
Array <edict_t *> m_ignoredBreakable {}; // list of ignored breakables
|
||||||
Array <edict_t *> m_ignoredItems {}; // list of pointers to entity to ignore for pickup
|
Array <edict_t *> m_ignoredItems {}; // list of pointers to entity to ignore for pickup
|
||||||
|
|
@ -651,7 +651,7 @@ public:
|
||||||
int m_voteKickIndex {}; // index of player to vote against
|
int m_voteKickIndex {}; // index of player to vote against
|
||||||
int m_lastVoteKick {}; // last index
|
int m_lastVoteKick {}; // last index
|
||||||
int m_voteMap {}; // number of map to vote for
|
int m_voteMap {}; // number of map to vote for
|
||||||
int m_logotypeIndex {}; // index for logotype
|
int m_logoDecalIndex {}; // index for logotype
|
||||||
int m_buyState {}; // current count in buying
|
int m_buyState {}; // current count in buying
|
||||||
int m_blindButton {}; // buttons bot press, when blind
|
int m_blindButton {}; // buttons bot press, when blind
|
||||||
int m_radioOrder {}; // actual command
|
int m_radioOrder {}; // actual command
|
||||||
|
|
@ -930,6 +930,7 @@ extern ConVar cv_camping_time_min;
|
||||||
extern ConVar cv_camping_time_max;
|
extern ConVar cv_camping_time_max;
|
||||||
extern ConVar cv_smoke_grenade_checks;
|
extern ConVar cv_smoke_grenade_checks;
|
||||||
extern ConVar cv_check_darkness;
|
extern ConVar cv_check_darkness;
|
||||||
|
extern ConVar cv_use_hitbox_enemy_targeting;
|
||||||
|
|
||||||
extern ConVar mp_freezetime;
|
extern ConVar mp_freezetime;
|
||||||
extern ConVar mp_roundtime;
|
extern ConVar mp_roundtime;
|
||||||
|
|
|
||||||
|
|
@ -180,6 +180,7 @@ void Bot::checkBreakablesAround () {
|
||||||
|| !cv_destroy_breakables_around
|
|| !cv_destroy_breakables_around
|
||||||
|| usesKnife ()
|
|| usesKnife ()
|
||||||
|| usesSniper ()
|
|| usesSniper ()
|
||||||
|
|| isOnLadder ()
|
||||||
|| rg.chance (25)
|
|| rg.chance (25)
|
||||||
|| !game.hasBreakables ()
|
|| !game.hasBreakables ()
|
||||||
|| m_seeEnemyTime + 4.0f > game.time ()
|
|| m_seeEnemyTime + 4.0f > game.time ()
|
||||||
|
|
@ -3161,7 +3162,7 @@ void Bot::checkSpawnConditions () {
|
||||||
|
|
||||||
// switch to knife if time to do this
|
// switch to knife if time to do this
|
||||||
if (m_checkKnifeSwitch && m_buyingFinished && m_spawnTime + rg (5.0f, 7.5f) < game.time ()) {
|
if (m_checkKnifeSwitch && m_buyingFinished && m_spawnTime + rg (5.0f, 7.5f) < game.time ()) {
|
||||||
if (!game.is (GameFlags::Xash3D) && rg (1, 100) < 2 && cv_spraypaints) {
|
if (rg (1, 100) < 30 && cv_spraypaints) {
|
||||||
startTask (Task::Spraypaint, TaskPri::Spraypaint, kInvalidNodeIndex, game.time () + 1.0f, false);
|
startTask (Task::Spraypaint, TaskPri::Spraypaint, kInvalidNodeIndex, game.time () + 1.0f, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3397,7 +3398,8 @@ void Bot::logic () {
|
||||||
|
|
||||||
// save the previous speed (for checking if stuck)
|
// save the previous speed (for checking if stuck)
|
||||||
m_prevSpeed = cr::abs (m_moveSpeed);
|
m_prevSpeed = cr::abs (m_moveSpeed);
|
||||||
m_prevVelocity = cr::abs (pev->velocity.length2d ());
|
m_prevVelocity = pev->velocity;
|
||||||
|
|
||||||
m_lastDamageType = -1; // reset damage
|
m_lastDamageType = -1; // reset damage
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -235,12 +235,13 @@ void Bot::prepareChatMessage (StringRef message) {
|
||||||
if (!(client.flags & ClientFlags::Used) || !(client.flags & ClientFlags::Alive) || client.ent == ent ()) {
|
if (!(client.flags & ClientFlags::Used) || !(client.flags & ClientFlags::Alive) || client.ent == ent ()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
const auto playerIndex = game.indexOfPlayer (client.ent);
|
||||||
|
|
||||||
if (needsEnemy && m_team != client.team) {
|
if (needsEnemy && m_team != client.team) {
|
||||||
return humanizedName (game.indexOfPlayer (client.ent));
|
return humanizedName (playerIndex);
|
||||||
}
|
}
|
||||||
else if (!needsEnemy && m_team == client.team) {
|
else if (!needsEnemy && m_team == client.team) {
|
||||||
return humanizedName (game.indexOfPlayer (client.ent));
|
return humanizedName (playerIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return getHighfragPlayer ();
|
return getHighfragPlayer ();
|
||||||
|
|
@ -290,6 +291,9 @@ void Bot::prepareChatMessage (StringRef message) {
|
||||||
case 'e':
|
case 'e':
|
||||||
m_chatBuffer.replace ("%e", getPlayerAlive (true));
|
m_chatBuffer.replace ("%e", getPlayerAlive (true));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'g':
|
||||||
|
m_chatBuffer.replace ("%g", graph.getAuthor ());
|
||||||
};
|
};
|
||||||
++replaceCounter;
|
++replaceCounter;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -180,7 +180,7 @@ bool Bot::checkBodyParts (edict_t *target) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// hitboxes requested ?
|
// hitboxes requested ?
|
||||||
if (game.is (GameFlags::HasStudioModels) && cv_use_hitbox_enemy_targeting) {
|
if (game.is (GameFlags::HasStudioModels) && cv_use_hitbox_enemy_targeting && m_hitboxEnumerator) {
|
||||||
return checkBodyPartsWithHitboxes (target);
|
return checkBodyPartsWithHitboxes (target);
|
||||||
}
|
}
|
||||||
return checkBodyPartsWithOffsets (target);
|
return checkBodyPartsWithOffsets (target);
|
||||||
|
|
|
||||||
|
|
@ -735,19 +735,32 @@ void BotConfig::loadLogosConfig () {
|
||||||
String line {};
|
String line {};
|
||||||
MemFile file {};
|
MemFile file {};
|
||||||
|
|
||||||
|
auto addLogoIndex = [&] (StringRef logo) {
|
||||||
|
const auto index = engfuncs.pfnDecalIndex (logo.chars ());
|
||||||
|
|
||||||
|
if (index > 0) {
|
||||||
|
m_logosIndices.push (index);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
m_logosIndices.clear ();
|
||||||
|
|
||||||
// logos initialization
|
// logos initialization
|
||||||
if (openConfig ("logos", "Logos config file not found. Loading defaults.", &file)) {
|
if (openConfig ("logos", "Logos config file not found. Loading defaults.", &file)) {
|
||||||
m_logos.clear ();
|
|
||||||
|
|
||||||
while (file.getLine (line)) {
|
while (file.getLine (line)) {
|
||||||
if (isCommentLine (line)) {
|
if (isCommentLine (line)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
m_logos.push (cr::move (line.trim ()));
|
addLogoIndex (line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
m_logos = cr::move (String { "{biohaz;{graf003;{graf004;{graf005;{lambda06;{target;{hand1;{spit2;{bloodhand6;{foot_l;{foot_r" }.split (";"));
|
// use defaults
|
||||||
|
if (m_logosIndices.empty ()) {
|
||||||
|
auto defaults = String { "{biohaz;{graf003;{graf004;{graf005;{lambda06;{target;{hand1;{spit2;{bloodhand6;{foot_l;{foot_r" }.split (";");
|
||||||
|
|
||||||
|
for (const auto &logo : defaults) {
|
||||||
|
addLogoIndex (logo);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1157,7 +1157,7 @@ Bot::Bot (edict_t *bot, int difficulty, int personality, int team, int skin) {
|
||||||
m_startAction = BotMsg::None;
|
m_startAction = BotMsg::None;
|
||||||
m_retryJoin = 0;
|
m_retryJoin = 0;
|
||||||
m_moneyAmount = 0;
|
m_moneyAmount = 0;
|
||||||
m_logotypeIndex = conf.getRandomLogoIndex ();
|
m_logoDecalIndex = conf.getRandomLogoDecalIndex ();
|
||||||
|
|
||||||
if (cv_rotate_bots) {
|
if (cv_rotate_bots) {
|
||||||
m_stayTime = game.time () + rg (cv_rotate_stay_min.as <float> (), cv_rotate_stay_max.as <float> ());
|
m_stayTime = game.time () + rg (cv_rotate_stay_min.as <float> (), cv_rotate_stay_max.as <float> ());
|
||||||
|
|
@ -1496,7 +1496,6 @@ void Bot::newRound () {
|
||||||
m_askCheckTime = rg (30.0f, 90.0f);
|
m_askCheckTime = rg (30.0f, 90.0f);
|
||||||
m_minSpeed = 260.0f;
|
m_minSpeed = 260.0f;
|
||||||
m_prevSpeed = 0.0f;
|
m_prevSpeed = 0.0f;
|
||||||
m_prevVelocity = 0.0f;
|
|
||||||
m_prevOrigin = Vector (kInfiniteDistance, kInfiniteDistance, kInfiniteDistance);
|
m_prevOrigin = Vector (kInfiniteDistance, kInfiniteDistance, kInfiniteDistance);
|
||||||
m_prevTime = game.time ();
|
m_prevTime = game.time ();
|
||||||
m_lookUpdateTime = game.time ();
|
m_lookUpdateTime = game.time ();
|
||||||
|
|
@ -1630,7 +1629,6 @@ void Bot::newRound () {
|
||||||
m_zoomCheckTime = 0.0f;
|
m_zoomCheckTime = 0.0f;
|
||||||
m_strafeSetTime = 0.0f;
|
m_strafeSetTime = 0.0f;
|
||||||
m_dodgeStrafeDir = Dodge::None;
|
m_dodgeStrafeDir = Dodge::None;
|
||||||
m_avoidAction = Dodge::None;
|
|
||||||
m_fightStyle = Fight::None;
|
m_fightStyle = Fight::None;
|
||||||
m_lastFightStyleCheck = 0.0f;
|
m_lastFightStyleCheck = 0.0f;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -530,23 +530,8 @@ void Bot::doPlayerAvoidance (const Vector &normal) {
|
||||||
|
|
||||||
// found somebody?
|
// found somebody?
|
||||||
if (game.isNullEntity (m_hindrance)) {
|
if (game.isNullEntity (m_hindrance)) {
|
||||||
m_avoidAction = Dodge::None;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
if (util.getConeDeviation (ent (), m_hindrance->v.origin) < 0.8f) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_avoidAction != Dodge::None) {
|
|
||||||
if (m_avoidAction == Dodge::Left) {
|
|
||||||
setStrafeSpeed (normal, pev->maxspeed);
|
|
||||||
}
|
|
||||||
else if (m_avoidAction == Dodge::Right) {
|
|
||||||
setStrafeSpeed (normal, -pev->maxspeed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const float interval = m_frameInterval * (!isDucking () && pev->velocity.lengthSq2d () > 0.0f ? 6.0f : 2.0f);
|
const float interval = m_frameInterval * (!isDucking () && pev->velocity.lengthSq2d () > 0.0f ? 6.0f : 2.0f);
|
||||||
|
|
||||||
// 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
|
||||||
|
|
@ -566,31 +551,20 @@ void Bot::doPlayerAvoidance (const Vector &normal) {
|
||||||
const auto &dir = (pev->origin - m_hindrance->v.origin).normalize2d_apx ();
|
const auto &dir = (pev->origin - m_hindrance->v.origin).normalize2d_apx ();
|
||||||
|
|
||||||
// to start strafing, we have to first figure out if the target is on the left side or right side
|
// to start strafing, we have to first figure out if the target is on the left side or right side
|
||||||
if ((m_avoidAction == Dodge::None
|
|
||||||
&& m_path->radius > 16.0f
|
|
||||||
&& !isInNarrowPlace ())
|
|
||||||
|| m_moveSpeed < 0.0f) {
|
|
||||||
if ((dir | right.normalize2d_apx ()) > 0.0f) {
|
if ((dir | right.normalize2d_apx ()) > 0.0f) {
|
||||||
m_avoidAction = Dodge::Left;
|
|
||||||
|
|
||||||
// start strafing
|
// start strafing
|
||||||
setStrafeSpeed (normal, pev->maxspeed);
|
setStrafeSpeed (normal, pev->maxspeed);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
m_avoidAction = Dodge::Right;
|
|
||||||
|
|
||||||
// start strafing
|
// start strafing
|
||||||
setStrafeSpeed (normal, -pev->maxspeed);
|
setStrafeSpeed (normal, -pev->maxspeed);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
m_navTimeset = game.time ();
|
|
||||||
|
|
||||||
if (distanceSq < cr::sqrf (96.0f)) {
|
if (distanceSq < cr::sqrf (96.0f)) {
|
||||||
if ((dir | forward.normalize2d_apx ()) < 0.0f) {
|
if ((dir | forward.normalize2d_apx ()) < 0.0f) {
|
||||||
m_moveSpeed = -pev->maxspeed;
|
m_moveSpeed = -pev->maxspeed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ignoreCollision ();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -600,10 +574,12 @@ void Bot::checkTerrain (float movedDistance, const Vector &dirNormal) {
|
||||||
TraceResult tr {};
|
TraceResult tr {};
|
||||||
m_isStuck = false;
|
m_isStuck = false;
|
||||||
|
|
||||||
|
const auto tid = getCurrentTaskId ();
|
||||||
|
|
||||||
// standing still, no need to check?
|
// standing still, no need to check?
|
||||||
if (m_lastCollTime < game.time () && getCurrentTaskId () != Task::Attack) {
|
if (m_lastCollTime < game.time () && tid != Task::Attack && tid != Task::Camp) {
|
||||||
// didn't we move enough previously?
|
// didn't we move enough previously?
|
||||||
if (movedDistance < kMinMovedDistance && (m_prevSpeed > 20.0f || m_prevVelocity < m_moveSpeed / 2)) {
|
if (movedDistance < kMinMovedDistance && m_prevSpeed > 20.0f) {
|
||||||
m_prevTime = game.time (); // then consider being stuck
|
m_prevTime = game.time (); // then consider being stuck
|
||||||
m_isStuck = true;
|
m_isStuck = true;
|
||||||
|
|
||||||
|
|
@ -881,6 +857,14 @@ void Bot::checkTerrain (float movedDistance, const Vector &dirNormal) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bot::checkFall () {
|
void Bot::checkFall () {
|
||||||
|
if (isPreviousLadder ()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (graph.exists (m_currentNodeIndex)) {
|
||||||
|
if (graph[m_currentNodeIndex].flags & NodeFlag::Ladder) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!m_checkFall) {
|
if (!m_checkFall) {
|
||||||
if (isOnFloor ()) {
|
if (isOnFloor ()) {
|
||||||
|
|
|
||||||
|
|
@ -103,24 +103,13 @@ bool BotSupport::isVisible (const Vector &origin, edict_t *ent) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BotSupport::decalTrace (entvars_t *pev, TraceResult *trace, int logotypeIndex) {
|
void BotSupport::decalTrace (TraceResult *trace, int decalIndex) {
|
||||||
// this function draw spraypaint depending on the tracing results.
|
// this function draw spraypaint depending on the tracing results.
|
||||||
|
|
||||||
if (cr::fequal (trace->flFraction, 1.0f)) {
|
if (cr::fequal (trace->flFraction, 1.0f) || decalIndex <= 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto logo = conf.getLogoName (logotypeIndex);
|
|
||||||
|
|
||||||
int entityIndex = -1, message = TE_DECAL;
|
int entityIndex = -1, message = TE_DECAL;
|
||||||
int decalIndex = engfuncs.pfnDecalIndex (logo.chars ());
|
|
||||||
|
|
||||||
if (decalIndex <= 0) {
|
|
||||||
decalIndex = engfuncs.pfnDecalIndex ("{lambda06");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (decalIndex <= 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!game.isNullEntity (trace->pHit)) {
|
if (!game.isNullEntity (trace->pHit)) {
|
||||||
if (trace->pHit->v.solid == SOLID_BSP || trace->pHit->v.movetype == MOVETYPE_PUSHSTEP) {
|
if (trace->pHit->v.solid == SOLID_BSP || trace->pHit->v.movetype == MOVETYPE_PUSHSTEP) {
|
||||||
|
|
@ -148,18 +137,6 @@ void BotSupport::decalTrace (entvars_t *pev, TraceResult *trace, int logotypeInd
|
||||||
decalIndex -= 256;
|
decalIndex -= 256;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (logo.startsWith ("{")) {
|
|
||||||
MessageWriter (MSG_BROADCAST, SVC_TEMPENTITY)
|
|
||||||
.writeByte (TE_PLAYERDECAL)
|
|
||||||
.writeByte (game.indexOfEntity (pev->pContainingEntity))
|
|
||||||
.writeCoord (trace->vecEndPos.x)
|
|
||||||
.writeCoord (trace->vecEndPos.y)
|
|
||||||
.writeCoord (trace->vecEndPos.z)
|
|
||||||
.writeShort (static_cast <short> (game.indexOfEntity (trace->pHit)))
|
|
||||||
.writeByte (decalIndex);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
MessageWriter msg {};
|
MessageWriter msg {};
|
||||||
|
|
||||||
msg.start (MSG_BROADCAST, SVC_TEMPENTITY)
|
msg.start (MSG_BROADCAST, SVC_TEMPENTITY)
|
||||||
|
|
@ -174,7 +151,6 @@ void BotSupport::decalTrace (entvars_t *pev, TraceResult *trace, int logotypeInd
|
||||||
}
|
}
|
||||||
msg.end ();
|
msg.end ();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
bool BotSupport::isPlayer (edict_t *ent) {
|
bool BotSupport::isPlayer (edict_t *ent) {
|
||||||
if (game.isNullEntity (ent)) {
|
if (game.isNullEntity (ent)) {
|
||||||
|
|
|
||||||
|
|
@ -99,11 +99,10 @@ void Bot::normal_ () {
|
||||||
// spray logo sometimes if allowed to do so
|
// spray logo sometimes if allowed to do so
|
||||||
if (!(m_states & (Sense::SeeingEnemy | Sense::SuspectEnemy))
|
if (!(m_states & (Sense::SeeingEnemy | Sense::SuspectEnemy))
|
||||||
&& m_seeEnemyTime + 5.0f < game.time ()
|
&& m_seeEnemyTime + 5.0f < game.time ()
|
||||||
&& !m_reloadState && m_timeLogoSpray < game.time ()
|
&& m_reloadState == Reload::None
|
||||||
&& !game.is (GameFlags::Xash3D)
|
&& m_timeLogoSpray < game.time ()
|
||||||
&& cv_spraypaints
|
&& cv_spraypaints
|
||||||
&& rg.chance (50)
|
&& m_moveSpeed >= getShiftSpeed ()
|
||||||
&& m_moveSpeed > getShiftSpeed ()
|
|
||||||
&& game.isNullEntity (m_pickupItem)) {
|
&& 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)) {
|
||||||
|
|
@ -316,7 +315,7 @@ void Bot::spraypaint_ () {
|
||||||
m_aimFlags |= AimFlags::Entity;
|
m_aimFlags |= AimFlags::Entity;
|
||||||
|
|
||||||
// bot didn't spray this round?
|
// bot didn't spray this round?
|
||||||
if (m_timeLogoSpray < game.time () && getTask ()->time > game.time ()) {
|
if (m_timeLogoSpray <= game.time () && getTask ()->time > game.time ()) {
|
||||||
const auto &forward = pev->v_angle.forward ();
|
const auto &forward = pev->v_angle.forward ();
|
||||||
Vector sprayOrigin = getEyesPos () + forward * 128.0f;
|
Vector sprayOrigin = getEyesPos () + forward * 128.0f;
|
||||||
|
|
||||||
|
|
@ -331,11 +330,12 @@ void Bot::spraypaint_ () {
|
||||||
|
|
||||||
if (getTask ()->time - 0.5f < game.time ()) {
|
if (getTask ()->time - 0.5f < game.time ()) {
|
||||||
// emit spray can sound
|
// emit spray can sound
|
||||||
engfuncs.pfnEmitSound (ent (), CHAN_VOICE, "player/sprayer.wav", 1.0f, ATTN_NORM, 0, 100);
|
engfuncs.pfnEmitSound (pev->pContainingEntity, CHAN_VOICE, "player/sprayer.wav", 1.0f, ATTN_NORM, 0, 100);
|
||||||
|
|
||||||
game.testLine (getEyesPos (), getEyesPos () + forward * 128.0f, TraceIgnore::Monsters, ent (), &tr);
|
game.testLine (getEyesPos (), getEyesPos () + forward * 128.0f, TraceIgnore::Monsters, ent (), &tr);
|
||||||
|
|
||||||
// paint the actual logo decal
|
// paint the actual logo decal
|
||||||
util.decalTrace (pev, &tr, m_logotypeIndex);
|
util.decalTrace (&tr, m_logoDecalIndex);
|
||||||
m_timeLogoSpray = game.time () + rg (60.0f, 90.0f);
|
m_timeLogoSpray = game.time () + rg (60.0f, 90.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue