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
|
|
@ -180,6 +180,7 @@ void Bot::checkBreakablesAround () {
|
|||
|| !cv_destroy_breakables_around
|
||||
|| usesKnife ()
|
||||
|| usesSniper ()
|
||||
|| isOnLadder ()
|
||||
|| rg.chance (25)
|
||||
|| !game.hasBreakables ()
|
||||
|| m_seeEnemyTime + 4.0f > game.time ()
|
||||
|
|
@ -3161,7 +3162,7 @@ void Bot::checkSpawnConditions () {
|
|||
|
||||
// switch to knife if time to do this
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
@ -3397,7 +3398,8 @@ void Bot::logic () {
|
|||
|
||||
// save the previous speed (for checking if stuck)
|
||||
m_prevSpeed = cr::abs (m_moveSpeed);
|
||||
m_prevVelocity = cr::abs (pev->velocity.length2d ());
|
||||
m_prevVelocity = pev->velocity;
|
||||
|
||||
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 ()) {
|
||||
continue;
|
||||
}
|
||||
const auto playerIndex = game.indexOfPlayer (client.ent);
|
||||
|
||||
if (needsEnemy && m_team != client.team) {
|
||||
return humanizedName (game.indexOfPlayer (client.ent));
|
||||
return humanizedName (playerIndex);
|
||||
}
|
||||
else if (!needsEnemy && m_team == client.team) {
|
||||
return humanizedName (game.indexOfPlayer (client.ent));
|
||||
return humanizedName (playerIndex);
|
||||
}
|
||||
}
|
||||
return getHighfragPlayer ();
|
||||
|
|
@ -290,6 +291,9 @@ void Bot::prepareChatMessage (StringRef message) {
|
|||
case 'e':
|
||||
m_chatBuffer.replace ("%e", getPlayerAlive (true));
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
m_chatBuffer.replace ("%g", graph.getAuthor ());
|
||||
};
|
||||
++replaceCounter;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -180,7 +180,7 @@ bool Bot::checkBodyParts (edict_t *target) {
|
|||
}
|
||||
|
||||
// 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 checkBodyPartsWithOffsets (target);
|
||||
|
|
|
|||
|
|
@ -735,19 +735,32 @@ void BotConfig::loadLogosConfig () {
|
|||
String line {};
|
||||
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
|
||||
if (openConfig ("logos", "Logos config file not found. Loading defaults.", &file)) {
|
||||
m_logos.clear ();
|
||||
|
||||
while (file.getLine (line)) {
|
||||
if (isCommentLine (line)) {
|
||||
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_retryJoin = 0;
|
||||
m_moneyAmount = 0;
|
||||
m_logotypeIndex = conf.getRandomLogoIndex ();
|
||||
m_logoDecalIndex = conf.getRandomLogoDecalIndex ();
|
||||
|
||||
if (cv_rotate_bots) {
|
||||
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_minSpeed = 260.0f;
|
||||
m_prevSpeed = 0.0f;
|
||||
m_prevVelocity = 0.0f;
|
||||
m_prevOrigin = Vector (kInfiniteDistance, kInfiniteDistance, kInfiniteDistance);
|
||||
m_prevTime = game.time ();
|
||||
m_lookUpdateTime = game.time ();
|
||||
|
|
@ -1630,7 +1629,6 @@ void Bot::newRound () {
|
|||
m_zoomCheckTime = 0.0f;
|
||||
m_strafeSetTime = 0.0f;
|
||||
m_dodgeStrafeDir = Dodge::None;
|
||||
m_avoidAction = Dodge::None;
|
||||
m_fightStyle = Fight::None;
|
||||
m_lastFightStyleCheck = 0.0f;
|
||||
|
||||
|
|
|
|||
|
|
@ -530,23 +530,8 @@ void Bot::doPlayerAvoidance (const Vector &normal) {
|
|||
|
||||
// found somebody?
|
||||
if (game.isNullEntity (m_hindrance)) {
|
||||
m_avoidAction = Dodge::None;
|
||||
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);
|
||||
|
||||
// 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 ();
|
||||
|
||||
// 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) {
|
||||
m_avoidAction = Dodge::Left;
|
||||
|
||||
// start strafing
|
||||
setStrafeSpeed (normal, pev->maxspeed);
|
||||
}
|
||||
else {
|
||||
m_avoidAction = Dodge::Right;
|
||||
|
||||
// start strafing
|
||||
setStrafeSpeed (normal, -pev->maxspeed);
|
||||
}
|
||||
if ((dir | right.normalize2d_apx ()) > 0.0f) {
|
||||
// start strafing
|
||||
setStrafeSpeed (normal, pev->maxspeed);
|
||||
}
|
||||
else {
|
||||
// start strafing
|
||||
setStrafeSpeed (normal, -pev->maxspeed);
|
||||
}
|
||||
m_navTimeset = game.time ();
|
||||
|
||||
if (distanceSq < cr::sqrf (96.0f)) {
|
||||
if ((dir | forward.normalize2d_apx ()) < 0.0f) {
|
||||
m_moveSpeed = -pev->maxspeed;
|
||||
}
|
||||
}
|
||||
ignoreCollision ();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -600,10 +574,12 @@ void Bot::checkTerrain (float movedDistance, const Vector &dirNormal) {
|
|||
TraceResult tr {};
|
||||
m_isStuck = false;
|
||||
|
||||
const auto tid = getCurrentTaskId ();
|
||||
|
||||
// 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?
|
||||
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_isStuck = true;
|
||||
|
||||
|
|
@ -881,6 +857,14 @@ void Bot::checkTerrain (float movedDistance, const Vector &dirNormal) {
|
|||
}
|
||||
|
||||
void Bot::checkFall () {
|
||||
if (isPreviousLadder ()) {
|
||||
return;
|
||||
}
|
||||
else if (graph.exists (m_currentNodeIndex)) {
|
||||
if (graph[m_currentNodeIndex].flags & NodeFlag::Ladder) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_checkFall) {
|
||||
if (isOnFloor ()) {
|
||||
|
|
|
|||
|
|
@ -103,24 +103,13 @@ bool BotSupport::isVisible (const Vector &origin, edict_t *ent) {
|
|||
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.
|
||||
|
||||
if (cr::fequal (trace->flFraction, 1.0f)) {
|
||||
if (cr::fequal (trace->flFraction, 1.0f) || decalIndex <= 0) {
|
||||
return;
|
||||
}
|
||||
auto logo = conf.getLogoName (logotypeIndex);
|
||||
|
||||
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 (trace->pHit->v.solid == SOLID_BSP || trace->pHit->v.movetype == MOVETYPE_PUSHSTEP) {
|
||||
|
|
@ -148,32 +137,19 @@ void BotSupport::decalTrace (entvars_t *pev, TraceResult *trace, int logotypeInd
|
|||
decalIndex -= 256;
|
||||
}
|
||||
}
|
||||
MessageWriter msg {};
|
||||
|
||||
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 {};
|
||||
|
||||
msg.start (MSG_BROADCAST, SVC_TEMPENTITY)
|
||||
.writeByte (message)
|
||||
.writeCoord (trace->vecEndPos.x)
|
||||
.writeCoord (trace->vecEndPos.y)
|
||||
.writeCoord (trace->vecEndPos.z)
|
||||
.writeByte (decalIndex);
|
||||
|
||||
if (entityIndex) {
|
||||
msg.writeShort (entityIndex);
|
||||
}
|
||||
msg.end ();
|
||||
msg.start (MSG_BROADCAST, SVC_TEMPENTITY)
|
||||
.writeByte (message)
|
||||
.writeCoord (trace->vecEndPos.x)
|
||||
.writeCoord (trace->vecEndPos.y)
|
||||
.writeCoord (trace->vecEndPos.z)
|
||||
.writeByte (decalIndex);
|
||||
|
||||
if (entityIndex) {
|
||||
msg.writeShort (entityIndex);
|
||||
}
|
||||
msg.end ();
|
||||
}
|
||||
|
||||
bool BotSupport::isPlayer (edict_t *ent) {
|
||||
|
|
|
|||
|
|
@ -99,11 +99,10 @@ void Bot::normal_ () {
|
|||
// 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 ()
|
||||
&& !game.is (GameFlags::Xash3D)
|
||||
&& m_reloadState == Reload::None
|
||||
&& m_timeLogoSpray < game.time ()
|
||||
&& cv_spraypaints
|
||||
&& rg.chance (50)
|
||||
&& m_moveSpeed > getShiftSpeed ()
|
||||
&& m_moveSpeed >= getShiftSpeed ()
|
||||
&& game.isNullEntity (m_pickupItem)) {
|
||||
|
||||
if (!(game.mapIs (MapFlags::Demolition) && bots.isBombPlanted () && m_team == Team::CT)) {
|
||||
|
|
@ -316,7 +315,7 @@ void Bot::spraypaint_ () {
|
|||
m_aimFlags |= AimFlags::Entity;
|
||||
|
||||
// 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 ();
|
||||
Vector sprayOrigin = getEyesPos () + forward * 128.0f;
|
||||
|
||||
|
|
@ -331,11 +330,12 @@ void Bot::spraypaint_ () {
|
|||
|
||||
if (getTask ()->time - 0.5f < game.time ()) {
|
||||
// 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);
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue