mirror of
https://github.com/s1lentq/ReGameDLL_CS.git
synced 2024-12-27 07:05:38 +03:00
Cleanup code
Fixed a bug after killing czbot by headshot, angles turn at 180 degrees. Fixed some bugs with mp_nadedrops
This commit is contained in:
parent
9dcab4bd49
commit
0eed08c133
@ -1,6 +1,6 @@
|
||||
#include "precompiled.h"
|
||||
|
||||
// BModelOrigin - calculates origin of a bmodel from absmin/size because all bmodel origins are 0 0 0
|
||||
// Calculates origin of a bmodel from absmin/size because all bmodel origins are 0 0 0
|
||||
Vector VecBModelOrigin(entvars_t *pevBModel)
|
||||
{
|
||||
return pevBModel->absmin + (pevBModel->size * 0.5f);
|
||||
@ -477,7 +477,7 @@ void CFuncRotating::Precache()
|
||||
}
|
||||
}
|
||||
|
||||
// Touch - will hurt others based on how fast the brush is spinning
|
||||
// Will hurt others based on how fast the brush is spinning
|
||||
void CFuncRotating::HurtTouch(CBaseEntity *pOther)
|
||||
{
|
||||
entvars_t *pevOther = pOther->pev;
|
||||
@ -494,7 +494,7 @@ void CFuncRotating::HurtTouch(CBaseEntity *pOther)
|
||||
pevOther->velocity = (pevOther->origin - VecBModelOrigin(pev)).Normalize() * pev->dmg;
|
||||
}
|
||||
|
||||
// RampPitchVol - ramp pitch and volume up to final values, based on difference
|
||||
// Ramp pitch and volume up to final values, based on difference
|
||||
// between how fast we're going vs how fast we plan to go
|
||||
void CFuncRotating::RampPitchVol(BOOL fUp)
|
||||
{
|
||||
@ -540,7 +540,7 @@ void CFuncRotating::RampPitchVol(BOOL fUp)
|
||||
EMIT_SOUND_DYN(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noiseRunning), fvol, m_flAttenuation, (SND_CHANGE_PITCH | SND_CHANGE_VOL), pitch);
|
||||
}
|
||||
|
||||
// SpinUp - accelerates a non-moving func_rotating up to it's speed
|
||||
// Accelerates a non-moving func_rotating up to it's speed
|
||||
void CFuncRotating::SpinUp()
|
||||
{
|
||||
// rotational velocity
|
||||
@ -616,7 +616,7 @@ void CFuncRotating::Rotate()
|
||||
pev->nextthink = pev->ltime + 10;
|
||||
}
|
||||
|
||||
// Rotating Use - when a rotating brush is triggered
|
||||
// When a rotating brush is triggered
|
||||
void CFuncRotating::RotatingUse(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value)
|
||||
{
|
||||
// is this a brush that should accelerate and decelerate when turned on/off (fan)?
|
||||
@ -662,7 +662,7 @@ void CFuncRotating::RotatingUse(CBaseEntity *pActivator, CBaseEntity *pCaller, U
|
||||
}
|
||||
}
|
||||
|
||||
// RotatingBlocked - An entity has blocked the brush
|
||||
// An entity has blocked the brush
|
||||
void CFuncRotating::Blocked(CBaseEntity *pOther)
|
||||
{
|
||||
pOther->TakeDamage(pev, pev, pev->dmg, DMG_CRUSH);
|
||||
|
@ -729,7 +729,7 @@ private:
|
||||
float m_jumpCrouchTimestamp;
|
||||
|
||||
// path navigation data
|
||||
enum { MAX_PATH_LENGTH = 256 };
|
||||
enum { MAX_PATH_LENGTH = 256 };
|
||||
struct ConnectInfo
|
||||
{
|
||||
CNavArea *area; // the area along the path
|
||||
@ -1643,6 +1643,15 @@ public:
|
||||
cost += crouchPenalty * dist;
|
||||
}
|
||||
|
||||
// if this is a "walk" area, add penalty
|
||||
if (area->GetAttributes() & NAV_WALK)
|
||||
{
|
||||
// these areas are kinda slow to move through
|
||||
float_precision walkPenalty = (m_route == FASTEST_ROUTE) ? 2.5f : 1.5f;
|
||||
|
||||
cost += walkPenalty * dist;
|
||||
}
|
||||
|
||||
// if this is a "jump" area, add penalty
|
||||
if (area->GetAttributes() & NAV_JUMP)
|
||||
{
|
||||
|
@ -838,24 +838,24 @@ bool BotStatement::IsValid() const
|
||||
{
|
||||
switch (m_condition[i])
|
||||
{
|
||||
case IS_IN_COMBAT:
|
||||
{
|
||||
if (!GetOwner()->IsAttacking())
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
/*case RADIO_SILENCE:
|
||||
{
|
||||
if (GetOwner()->GetChatter()->GetRadioSilenceDuration() < 10.0f)
|
||||
return false;
|
||||
break;
|
||||
}*/
|
||||
case ENEMIES_REMAINING:
|
||||
{
|
||||
if (GetOwner()->GetEnemiesRemaining() == 0)
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
case IS_IN_COMBAT:
|
||||
{
|
||||
if (!GetOwner()->IsAttacking())
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
/*case RADIO_SILENCE:
|
||||
{
|
||||
if (GetOwner()->GetChatter()->GetRadioSilenceDuration() < 10.0f)
|
||||
return false;
|
||||
break;
|
||||
}*/
|
||||
case ENEMIES_REMAINING:
|
||||
{
|
||||
if (GetOwner()->GetEnemiesRemaining() == 0)
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -270,6 +270,7 @@ void CCSBotManager::AddServerCommands()
|
||||
AddServerCommand("bot_nav_crouch");
|
||||
AddServerCommand("bot_nav_jump");
|
||||
AddServerCommand("bot_nav_precise");
|
||||
AddServerCommand("bot_nav_walk");
|
||||
AddServerCommand("bot_nav_no_jump");
|
||||
AddServerCommand("bot_nav_analyze");
|
||||
AddServerCommand("bot_nav_strip");
|
||||
@ -525,6 +526,10 @@ void CCSBotManager::ServerCommand(const char *pcmd)
|
||||
{
|
||||
m_editCmd = EDIT_ATTRIB_PRECISE;
|
||||
}
|
||||
else if (FStrEq(pcmd, "bot_nav_walk"))
|
||||
{
|
||||
m_editCmd = EDIT_ATTRIB_WALK;
|
||||
}
|
||||
else if (FStrEq(pcmd, "bot_nav_no_jump"))
|
||||
{
|
||||
m_editCmd = EDIT_ATTRIB_NO_JUMP;
|
||||
|
@ -288,23 +288,23 @@ bool CCSBot::UpdateLadderMovement()
|
||||
// check if somehow we totally missed the ladder
|
||||
switch (m_pathLadderState)
|
||||
{
|
||||
case MOUNT_ASCENDING_LADDER:
|
||||
case MOUNT_DESCENDING_LADDER:
|
||||
case ASCEND_LADDER:
|
||||
case DESCEND_LADDER:
|
||||
case MOUNT_ASCENDING_LADDER:
|
||||
case MOUNT_DESCENDING_LADDER:
|
||||
case ASCEND_LADDER:
|
||||
case DESCEND_LADDER:
|
||||
{
|
||||
const float farAway = 200.0f;
|
||||
Vector2D d = (m_pathLadder->m_top - pev->origin).Make2D();
|
||||
if (d.IsLengthGreaterThan(farAway))
|
||||
{
|
||||
const float farAway = 200.0f;
|
||||
Vector2D d = (m_pathLadder->m_top - pev->origin).Make2D();
|
||||
if (d.IsLengthGreaterThan(farAway))
|
||||
{
|
||||
PrintIfWatched("Missed ladder\n");
|
||||
Jump(MUST_JUMP);
|
||||
DestroyPath();
|
||||
Run();
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
PrintIfWatched("Missed ladder\n");
|
||||
Jump(MUST_JUMP);
|
||||
DestroyPath();
|
||||
Run();
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_areaEnteredTimestamp = gpGlobals->time;
|
||||
@ -314,12 +314,68 @@ bool CCSBot::UpdateLadderMovement()
|
||||
|
||||
switch (m_pathLadderState)
|
||||
{
|
||||
case APPROACH_ASCENDING_LADDER:
|
||||
case APPROACH_ASCENDING_LADDER:
|
||||
{
|
||||
bool approached = false;
|
||||
Vector2D d(pev->origin.x - m_goalPosition.x, pev->origin.y - m_goalPosition.y);
|
||||
|
||||
if (d.x * m_pathLadder->m_dirVector.x + d.y * m_pathLadder->m_dirVector.y < 0.0f)
|
||||
{
|
||||
Vector2D perp(-m_pathLadder->m_dirVector.y, m_pathLadder->m_dirVector.x);
|
||||
|
||||
if (Q_abs(int64(d.x * perp.x + d.y * perp.y)) < tolerance && d.Length() < closeToGoal)
|
||||
approached = true;
|
||||
}
|
||||
|
||||
// small radius will just slow them down a little for more accuracy in hitting their spot
|
||||
const float walkRange = 50.0f;
|
||||
if (d.IsLengthLessThan(walkRange))
|
||||
{
|
||||
Walk();
|
||||
StandUp();
|
||||
}
|
||||
|
||||
// TODO: Check that we are on the ladder we think we are
|
||||
if (IsOnLadder())
|
||||
{
|
||||
m_pathLadderState = ASCEND_LADDER;
|
||||
PrintIfWatched("ASCEND_LADDER\n");
|
||||
|
||||
// find actual top in case m_pathLadder penetrates the ceiling
|
||||
ComputeLadderEndpoint(true);
|
||||
}
|
||||
else if (approached)
|
||||
{
|
||||
// face the m_pathLadder
|
||||
m_pathLadderState = FACE_ASCENDING_LADDER;
|
||||
PrintIfWatched("FACE_ASCENDING_LADDER\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
// move toward ladder mount point
|
||||
MoveTowardsPosition(&m_goalPosition);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case APPROACH_DESCENDING_LADDER:
|
||||
{
|
||||
// fall check
|
||||
if (GetFeetZ() <= m_pathLadder->m_bottom.z + HalfHumanHeight)
|
||||
{
|
||||
PrintIfWatched("Fell from ladder.\n");
|
||||
|
||||
m_pathLadderState = MOVE_TO_DESTINATION;
|
||||
m_path[m_pathIndex].area->GetClosestPointOnArea(&m_pathLadder->m_bottom, &m_goalPosition);
|
||||
|
||||
AddDirectionVector(&m_goalPosition, m_pathLadder->m_dir, HalfHumanWidth);
|
||||
PrintIfWatched("MOVE_TO_DESTINATION\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
bool approached = false;
|
||||
Vector2D d(pev->origin.x - m_goalPosition.x, pev->origin.y - m_goalPosition.y);
|
||||
|
||||
if (d.x * m_pathLadder->m_dirVector.x + d.y * m_pathLadder->m_dirVector.y < 0.0f)
|
||||
if (d.x * m_pathLadder->m_dirVector.x + d.y * m_pathLadder->m_dirVector.y > 0.0f)
|
||||
{
|
||||
Vector2D perp(-m_pathLadder->m_dirVector.y, m_pathLadder->m_dirVector.x);
|
||||
|
||||
@ -327,274 +383,218 @@ bool CCSBot::UpdateLadderMovement()
|
||||
approached = true;
|
||||
}
|
||||
|
||||
// small radius will just slow them down a little for more accuracy in hitting their spot
|
||||
const float walkRange = 50.0f;
|
||||
if (d.IsLengthLessThan(walkRange))
|
||||
// if approaching ladder from the side or "ahead", walk
|
||||
if (m_pathLadder->m_topBehindArea != m_lastKnownArea)
|
||||
{
|
||||
Walk();
|
||||
StandUp();
|
||||
const float walkRange = 150.0f;
|
||||
if (!IsCrouching() && d.IsLengthLessThan(walkRange))
|
||||
Walk();
|
||||
}
|
||||
|
||||
// TODO: Check that we are on the ladder we think we are
|
||||
if (IsOnLadder())
|
||||
{
|
||||
m_pathLadderState = ASCEND_LADDER;
|
||||
PrintIfWatched("ASCEND_LADDER\n");
|
||||
// we slipped onto the ladder - climb it
|
||||
m_pathLadderState = DESCEND_LADDER;
|
||||
Run();
|
||||
PrintIfWatched("DESCEND_LADDER\n");
|
||||
|
||||
// find actual top in case m_pathLadder penetrates the ceiling
|
||||
ComputeLadderEndpoint(true);
|
||||
// find actual bottom in case m_pathLadder penetrates the floor
|
||||
ComputeLadderEndpoint(false);
|
||||
}
|
||||
else if (approached)
|
||||
{
|
||||
// face the m_pathLadder
|
||||
m_pathLadderState = FACE_ASCENDING_LADDER;
|
||||
PrintIfWatched("FACE_ASCENDING_LADDER\n");
|
||||
// face the ladder
|
||||
m_pathLadderState = FACE_DESCENDING_LADDER;
|
||||
PrintIfWatched("FACE_DESCENDING_LADDER\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
// move toward ladder mount point
|
||||
MoveTowardsPosition(&m_goalPosition);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case APPROACH_DESCENDING_LADDER:
|
||||
break;
|
||||
}
|
||||
case FACE_ASCENDING_LADDER:
|
||||
{
|
||||
// find yaw to directly aim at ladder
|
||||
Vector to = m_pathLadder->m_bottom - pev->origin;
|
||||
Vector idealAngle = UTIL_VecToAngles(to);
|
||||
|
||||
const float angleTolerance = 5.0f;
|
||||
if (AnglesAreEqual(pev->v_angle.y, idealAngle.y, angleTolerance))
|
||||
{
|
||||
// fall check
|
||||
if (GetFeetZ() <= m_pathLadder->m_bottom.z + HalfHumanHeight)
|
||||
{
|
||||
PrintIfWatched("Fell from ladder.\n");
|
||||
|
||||
m_pathLadderState = MOVE_TO_DESTINATION;
|
||||
m_path[m_pathIndex].area->GetClosestPointOnArea(&m_pathLadder->m_bottom, &m_goalPosition);
|
||||
|
||||
AddDirectionVector(&m_goalPosition, m_pathLadder->m_dir, HalfHumanWidth);
|
||||
PrintIfWatched("MOVE_TO_DESTINATION\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
bool approached = false;
|
||||
Vector2D d(pev->origin.x - m_goalPosition.x, pev->origin.y - m_goalPosition.y);
|
||||
|
||||
if (d.x * m_pathLadder->m_dirVector.x + d.y * m_pathLadder->m_dirVector.y > 0.0f)
|
||||
{
|
||||
Vector2D perp(-m_pathLadder->m_dirVector.y, m_pathLadder->m_dirVector.x);
|
||||
|
||||
if (Q_abs(int64(d.x * perp.x + d.y * perp.y)) < tolerance && d.Length() < closeToGoal)
|
||||
approached = true;
|
||||
}
|
||||
|
||||
// if approaching ladder from the side or "ahead", walk
|
||||
if (m_pathLadder->m_topBehindArea != m_lastKnownArea)
|
||||
{
|
||||
const float walkRange = 150.0f;
|
||||
if (!IsCrouching() && d.IsLengthLessThan(walkRange))
|
||||
Walk();
|
||||
}
|
||||
|
||||
// TODO: Check that we are on the ladder we think we are
|
||||
if (IsOnLadder())
|
||||
{
|
||||
// we slipped onto the ladder - climb it
|
||||
m_pathLadderState = DESCEND_LADDER;
|
||||
Run();
|
||||
PrintIfWatched("DESCEND_LADDER\n");
|
||||
|
||||
// find actual bottom in case m_pathLadder penetrates the floor
|
||||
ComputeLadderEndpoint(false);
|
||||
}
|
||||
else if (approached)
|
||||
{
|
||||
// face the ladder
|
||||
m_pathLadderState = FACE_DESCENDING_LADDER;
|
||||
PrintIfWatched("FACE_DESCENDING_LADDER\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
// move toward ladder mount point
|
||||
MoveTowardsPosition(&m_goalPosition);
|
||||
}
|
||||
}
|
||||
break;
|
||||
// move toward ladder until we become "on" it
|
||||
Run();
|
||||
ResetStuckMonitor();
|
||||
m_pathLadderState = MOUNT_ASCENDING_LADDER;
|
||||
PrintIfWatched("MOUNT_ASCENDING_LADDER\n");
|
||||
}
|
||||
case FACE_ASCENDING_LADDER:
|
||||
break;
|
||||
}
|
||||
case FACE_DESCENDING_LADDER:
|
||||
{
|
||||
// find yaw to directly aim at ladder
|
||||
Vector to = m_pathLadder->m_top - pev->origin;
|
||||
Vector idealAngle = UTIL_VecToAngles(to);
|
||||
|
||||
const float angleTolerance = 5.0f;
|
||||
if (AnglesAreEqual(pev->v_angle.y, idealAngle.y, angleTolerance))
|
||||
{
|
||||
// find yaw to directly aim at ladder
|
||||
Vector to = m_pathLadder->m_bottom - pev->origin;
|
||||
Vector idealAngle = UTIL_VecToAngles(to);
|
||||
|
||||
const float angleTolerance = 5.0f;
|
||||
if (AnglesAreEqual(pev->v_angle.y, idealAngle.y, angleTolerance))
|
||||
{
|
||||
// move toward ladder until we become "on" it
|
||||
Run();
|
||||
ResetStuckMonitor();
|
||||
m_pathLadderState = MOUNT_ASCENDING_LADDER;
|
||||
PrintIfWatched("MOUNT_ASCENDING_LADDER\n");
|
||||
}
|
||||
break;
|
||||
// move toward ladder until we become "on" it
|
||||
m_pathLadderState = MOUNT_DESCENDING_LADDER;
|
||||
ResetStuckMonitor();
|
||||
PrintIfWatched("MOUNT_DESCENDING_LADDER\n");
|
||||
}
|
||||
case FACE_DESCENDING_LADDER:
|
||||
break;
|
||||
}
|
||||
case MOUNT_ASCENDING_LADDER:
|
||||
{
|
||||
if (IsOnLadder())
|
||||
{
|
||||
// find yaw to directly aim at ladder
|
||||
Vector to = m_pathLadder->m_top - pev->origin;
|
||||
Vector idealAngle = UTIL_VecToAngles(to);
|
||||
m_pathLadderState = ASCEND_LADDER;
|
||||
PrintIfWatched("ASCEND_LADDER\n");
|
||||
|
||||
const float angleTolerance = 5.0f;
|
||||
if (AnglesAreEqual(pev->v_angle.y, idealAngle.y, angleTolerance))
|
||||
{
|
||||
// move toward ladder until we become "on" it
|
||||
m_pathLadderState = MOUNT_DESCENDING_LADDER;
|
||||
ResetStuckMonitor();
|
||||
PrintIfWatched("MOUNT_DESCENDING_LADDER\n");
|
||||
}
|
||||
break;
|
||||
// find actual top in case m_pathLadder penetrates the ceiling
|
||||
ComputeLadderEndpoint(true);
|
||||
}
|
||||
case MOUNT_ASCENDING_LADDER:
|
||||
|
||||
MoveForward();
|
||||
break;
|
||||
}
|
||||
case MOUNT_DESCENDING_LADDER:
|
||||
{
|
||||
// fall check
|
||||
if (GetFeetZ() <= m_pathLadder->m_bottom.z + HalfHumanHeight)
|
||||
{
|
||||
PrintIfWatched("Fell from ladder.\n");
|
||||
|
||||
m_pathLadderState = MOVE_TO_DESTINATION;
|
||||
m_path[m_pathIndex].area->GetClosestPointOnArea(&m_pathLadder->m_bottom, &m_goalPosition);
|
||||
|
||||
AddDirectionVector(&m_goalPosition, m_pathLadder->m_dir, HalfHumanWidth);
|
||||
PrintIfWatched("MOVE_TO_DESTINATION\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsOnLadder())
|
||||
{
|
||||
m_pathLadderState = ASCEND_LADDER;
|
||||
PrintIfWatched("ASCEND_LADDER\n");
|
||||
m_pathLadderState = DESCEND_LADDER;
|
||||
PrintIfWatched("DESCEND_LADDER\n");
|
||||
|
||||
// find actual top in case m_pathLadder penetrates the ceiling
|
||||
ComputeLadderEndpoint(true);
|
||||
// find actual bottom in case m_pathLadder penetrates the floor
|
||||
ComputeLadderEndpoint(false);
|
||||
}
|
||||
|
||||
// move toward ladder mount point
|
||||
MoveForward();
|
||||
break;
|
||||
}
|
||||
case MOUNT_DESCENDING_LADDER:
|
||||
break;
|
||||
}
|
||||
case ASCEND_LADDER:
|
||||
{
|
||||
// run, so we can make our dismount jump to the side, if necessary
|
||||
Run();
|
||||
|
||||
// if our destination area requires us to crouch, do it
|
||||
if (m_path[m_pathIndex].area->GetAttributes() & NAV_CROUCH)
|
||||
Crouch();
|
||||
|
||||
// did we reach the top?
|
||||
if (GetFeetZ() >= m_pathLadderEnd)
|
||||
{
|
||||
// fall check
|
||||
if (GetFeetZ() <= m_pathLadder->m_bottom.z + HalfHumanHeight)
|
||||
{
|
||||
PrintIfWatched("Fell from ladder.\n");
|
||||
// we reached the top - dismount
|
||||
m_pathLadderState = DISMOUNT_ASCENDING_LADDER;
|
||||
PrintIfWatched("DISMOUNT_ASCENDING_LADDER\n");
|
||||
|
||||
m_pathLadderState = MOVE_TO_DESTINATION;
|
||||
m_path[m_pathIndex].area->GetClosestPointOnArea(&m_pathLadder->m_bottom, &m_goalPosition);
|
||||
if (m_path[m_pathIndex].area == m_pathLadder->m_topForwardArea)
|
||||
m_pathLadderDismountDir = FORWARD;
|
||||
else if (m_path[m_pathIndex].area == m_pathLadder->m_topLeftArea)
|
||||
m_pathLadderDismountDir = LEFT;
|
||||
else if (m_path[m_pathIndex].area == m_pathLadder->m_topRightArea)
|
||||
m_pathLadderDismountDir = RIGHT;
|
||||
|
||||
AddDirectionVector(&m_goalPosition, m_pathLadder->m_dir, HalfHumanWidth);
|
||||
PrintIfWatched("MOVE_TO_DESTINATION\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsOnLadder())
|
||||
{
|
||||
m_pathLadderState = DESCEND_LADDER;
|
||||
PrintIfWatched("DESCEND_LADDER\n");
|
||||
|
||||
// find actual bottom in case m_pathLadder penetrates the floor
|
||||
ComputeLadderEndpoint(false);
|
||||
}
|
||||
|
||||
// move toward ladder mount point
|
||||
MoveForward();
|
||||
}
|
||||
break;
|
||||
m_pathLadderDismountTimestamp = gpGlobals->time;
|
||||
}
|
||||
case ASCEND_LADDER:
|
||||
else if (!IsOnLadder())
|
||||
{
|
||||
// run, so we can make our dismount jump to the side, if necessary
|
||||
Run();
|
||||
|
||||
// if our destination area requires us to crouch, do it
|
||||
if (m_path[m_pathIndex].area->GetAttributes() & NAV_CROUCH)
|
||||
Crouch();
|
||||
|
||||
// did we reach the top?
|
||||
if (GetFeetZ() >= m_pathLadderEnd)
|
||||
{
|
||||
// we reached the top - dismount
|
||||
m_pathLadderState = DISMOUNT_ASCENDING_LADDER;
|
||||
PrintIfWatched("DISMOUNT_ASCENDING_LADDER\n");
|
||||
|
||||
if (m_path[m_pathIndex].area == m_pathLadder->m_topForwardArea)
|
||||
m_pathLadderDismountDir = FORWARD;
|
||||
else if (m_path[m_pathIndex].area == m_pathLadder->m_topLeftArea)
|
||||
m_pathLadderDismountDir = LEFT;
|
||||
else if (m_path[m_pathIndex].area == m_pathLadder->m_topRightArea)
|
||||
m_pathLadderDismountDir = RIGHT;
|
||||
|
||||
m_pathLadderDismountTimestamp = gpGlobals->time;
|
||||
}
|
||||
else if (!IsOnLadder())
|
||||
{
|
||||
// we fall off the ladder, repath
|
||||
DestroyPath();
|
||||
return false;
|
||||
}
|
||||
|
||||
// move up ladder
|
||||
MoveForward();
|
||||
break;
|
||||
// we fall off the ladder, repath
|
||||
DestroyPath();
|
||||
return false;
|
||||
}
|
||||
case DESCEND_LADDER:
|
||||
|
||||
// move up ladder
|
||||
MoveForward();
|
||||
break;
|
||||
}
|
||||
case DESCEND_LADDER:
|
||||
{
|
||||
Run();
|
||||
|
||||
float destHeight = m_pathLadderEnd + HalfHumanHeight;
|
||||
if (!IsOnLadder() || GetFeetZ() <= destHeight)
|
||||
{
|
||||
Run();
|
||||
// we reached the bottom, or we fell off - dismount
|
||||
m_pathLadderState = MOVE_TO_DESTINATION;
|
||||
m_path[m_pathIndex].area->GetClosestPointOnArea(&m_pathLadder->m_bottom, &m_goalPosition);
|
||||
|
||||
float destHeight = m_pathLadderEnd + HalfHumanHeight;
|
||||
if (!IsOnLadder() || GetFeetZ() <= destHeight)
|
||||
{
|
||||
// we reached the bottom, or we fell off - dismount
|
||||
m_pathLadderState = MOVE_TO_DESTINATION;
|
||||
m_path[m_pathIndex].area->GetClosestPointOnArea(&m_pathLadder->m_bottom, &m_goalPosition);
|
||||
|
||||
AddDirectionVector(&m_goalPosition, m_pathLadder->m_dir, HalfHumanWidth);
|
||||
PrintIfWatched("MOVE_TO_DESTINATION\n");
|
||||
}
|
||||
|
||||
// Move down ladder
|
||||
MoveForward();
|
||||
break;
|
||||
AddDirectionVector(&m_goalPosition, m_pathLadder->m_dir, HalfHumanWidth);
|
||||
PrintIfWatched("MOVE_TO_DESTINATION\n");
|
||||
}
|
||||
case DISMOUNT_ASCENDING_LADDER:
|
||||
|
||||
// Move down ladder
|
||||
MoveForward();
|
||||
break;
|
||||
}
|
||||
case DISMOUNT_ASCENDING_LADDER:
|
||||
{
|
||||
if (gpGlobals->time - m_pathLadderDismountTimestamp >= 0.4f)
|
||||
{
|
||||
if (gpGlobals->time - m_pathLadderDismountTimestamp >= 0.4f)
|
||||
{
|
||||
m_pathLadderState = MOVE_TO_DESTINATION;
|
||||
m_path[m_pathIndex].area->GetClosestPointOnArea(&pev->origin, &m_goalPosition);
|
||||
PrintIfWatched("MOVE_TO_DESTINATION\n");
|
||||
}
|
||||
|
||||
// We should already be facing the dismount point
|
||||
if (m_pathLadderFaceIn)
|
||||
{
|
||||
switch (m_pathLadderDismountDir)
|
||||
{
|
||||
case LEFT: StrafeLeft(); break;
|
||||
case RIGHT: StrafeRight(); break;
|
||||
case FORWARD: MoveForward(); break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (m_pathLadderDismountDir)
|
||||
{
|
||||
case LEFT: StrafeRight(); break;
|
||||
case RIGHT: StrafeLeft(); break;
|
||||
case FORWARD: MoveBackward(); break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
m_pathLadderState = MOVE_TO_DESTINATION;
|
||||
m_path[m_pathIndex].area->GetClosestPointOnArea(&pev->origin, &m_goalPosition);
|
||||
PrintIfWatched("MOVE_TO_DESTINATION\n");
|
||||
}
|
||||
case MOVE_TO_DESTINATION:
|
||||
|
||||
// We should already be facing the dismount point
|
||||
if (m_pathLadderFaceIn)
|
||||
{
|
||||
if (m_path[m_pathIndex].area->Contains(&pev->origin))
|
||||
switch (m_pathLadderDismountDir)
|
||||
{
|
||||
// successfully traversed ladder and reached destination area
|
||||
// exit ladder state machine
|
||||
PrintIfWatched("Ladder traversed.\n");
|
||||
m_pathLadder = nullptr;
|
||||
|
||||
// incrememnt path index to next step beyond this ladder
|
||||
SetPathIndex(m_pathIndex + 1);
|
||||
|
||||
return false;
|
||||
case LEFT: StrafeLeft(); break;
|
||||
case RIGHT: StrafeRight(); break;
|
||||
case FORWARD: MoveForward(); break;
|
||||
}
|
||||
|
||||
MoveTowardsPosition(&m_goalPosition);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (m_pathLadderDismountDir)
|
||||
{
|
||||
case LEFT: StrafeRight(); break;
|
||||
case RIGHT: StrafeLeft(); break;
|
||||
case FORWARD: MoveBackward(); break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MOVE_TO_DESTINATION:
|
||||
{
|
||||
if (m_path[m_pathIndex].area->Contains(&pev->origin))
|
||||
{
|
||||
// successfully traversed ladder and reached destination area
|
||||
// exit ladder state machine
|
||||
PrintIfWatched("Ladder traversed.\n");
|
||||
m_pathLadder = nullptr;
|
||||
|
||||
// incrememnt path index to next step beyond this ladder
|
||||
SetPathIndex(m_pathIndex + 1);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
MoveTowardsPosition(&m_goalPosition);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -1352,9 +1352,10 @@ CCSBot::PathResult CCSBot::UpdatePathMovement(bool allowSpeedChange)
|
||||
SetPathIndex(newIndex);
|
||||
}
|
||||
|
||||
// Crouching
|
||||
if (!IsUsingLadder())
|
||||
{
|
||||
// Crouching
|
||||
|
||||
// if we are approaching a crouch area, crouch
|
||||
// if there are no crouch areas coming up, stand
|
||||
const float crouchRange = 50.0f;
|
||||
@ -1388,6 +1389,29 @@ CCSBot::PathResult CCSBot::UpdatePathMovement(bool allowSpeedChange)
|
||||
StandUp();
|
||||
}
|
||||
// end crouching logic
|
||||
|
||||
// Walking
|
||||
bool didWalk = false;
|
||||
for (int i = prevIndex; i < m_pathLength; ++i)
|
||||
{
|
||||
const CNavArea *to = m_path[i].area;
|
||||
|
||||
Vector close;
|
||||
to->GetClosestPointOnArea(&pev->origin, &close);
|
||||
|
||||
if ((close - pev->origin).Make2D().IsLengthGreaterThan(crouchRange))
|
||||
break;
|
||||
|
||||
if (to->GetAttributes() & NAV_WALK)
|
||||
{
|
||||
Walk();
|
||||
didWalk = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!didWalk)
|
||||
Run();
|
||||
}
|
||||
|
||||
// compute our forward facing angle
|
||||
|
@ -106,98 +106,98 @@ void CCSBot::RespondToRadioCommands()
|
||||
const float inhibitAutoFollowDuration = 60.0f;
|
||||
switch (m_lastRadioCommand)
|
||||
{
|
||||
case EVENT_RADIO_REPORT_IN_TEAM:
|
||||
case EVENT_RADIO_REPORT_IN_TEAM:
|
||||
{
|
||||
GetChatter()->ReportingIn();
|
||||
break;
|
||||
}
|
||||
case EVENT_RADIO_FOLLOW_ME:
|
||||
case EVENT_RADIO_COVER_ME:
|
||||
case EVENT_RADIO_STICK_TOGETHER_TEAM:
|
||||
case EVENT_RADIO_REGROUP_TEAM:
|
||||
{
|
||||
if (!IsFollowing())
|
||||
{
|
||||
GetChatter()->ReportingIn();
|
||||
break;
|
||||
}
|
||||
case EVENT_RADIO_FOLLOW_ME:
|
||||
case EVENT_RADIO_COVER_ME:
|
||||
case EVENT_RADIO_STICK_TOGETHER_TEAM:
|
||||
case EVENT_RADIO_REGROUP_TEAM:
|
||||
{
|
||||
if (!IsFollowing())
|
||||
{
|
||||
Follow(m_radioSubject);
|
||||
m_radioSubject->AllowAutoFollow();
|
||||
canDo = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EVENT_RADIO_ENEMY_SPOTTED:
|
||||
case EVENT_RADIO_NEED_BACKUP:
|
||||
case EVENT_RADIO_TAKING_FIRE:
|
||||
{
|
||||
if (!IsFollowing())
|
||||
{
|
||||
Follow(m_radioSubject);
|
||||
GetChatter()->Say("OnMyWay");
|
||||
m_radioSubject->AllowAutoFollow();
|
||||
canDo = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EVENT_RADIO_TEAM_FALL_BACK:
|
||||
{
|
||||
if (TryToRetreat())
|
||||
canDo = true;
|
||||
break;
|
||||
}
|
||||
case EVENT_RADIO_HOLD_THIS_POSITION:
|
||||
{
|
||||
// find the leader's area
|
||||
SetTask(HOLD_POSITION);
|
||||
StopFollowing();
|
||||
m_radioSubject->InhibitAutoFollow(inhibitAutoFollowDuration);
|
||||
Hide(TheNavAreaGrid.GetNearestNavArea(&m_radioPosition));
|
||||
Follow(m_radioSubject);
|
||||
m_radioSubject->AllowAutoFollow();
|
||||
canDo = true;
|
||||
break;
|
||||
}
|
||||
case EVENT_RADIO_GO_GO_GO:
|
||||
case EVENT_RADIO_STORM_THE_FRONT:
|
||||
break;
|
||||
}
|
||||
case EVENT_RADIO_ENEMY_SPOTTED:
|
||||
case EVENT_RADIO_NEED_BACKUP:
|
||||
case EVENT_RADIO_TAKING_FIRE:
|
||||
{
|
||||
if (!IsFollowing())
|
||||
{
|
||||
StopFollowing();
|
||||
Hunt();
|
||||
Follow(m_radioSubject);
|
||||
GetChatter()->Say("OnMyWay");
|
||||
m_radioSubject->AllowAutoFollow();
|
||||
canDo = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EVENT_RADIO_TEAM_FALL_BACK:
|
||||
{
|
||||
if (TryToRetreat())
|
||||
canDo = true;
|
||||
break;
|
||||
}
|
||||
case EVENT_RADIO_HOLD_THIS_POSITION:
|
||||
{
|
||||
// find the leader's area
|
||||
SetTask(HOLD_POSITION);
|
||||
StopFollowing();
|
||||
m_radioSubject->InhibitAutoFollow(inhibitAutoFollowDuration);
|
||||
Hide(TheNavAreaGrid.GetNearestNavArea(&m_radioPosition));
|
||||
canDo = true;
|
||||
break;
|
||||
}
|
||||
case EVENT_RADIO_GO_GO_GO:
|
||||
case EVENT_RADIO_STORM_THE_FRONT:
|
||||
{
|
||||
StopFollowing();
|
||||
Hunt();
|
||||
canDo = true;
|
||||
m_radioSubject->InhibitAutoFollow(inhibitAutoFollowDuration);
|
||||
break;
|
||||
}
|
||||
case EVENT_RADIO_GET_OUT_OF_THERE:
|
||||
{
|
||||
if (TheCSBots()->IsBombPlanted())
|
||||
{
|
||||
EscapeFromBomb();
|
||||
m_radioSubject->InhibitAutoFollow(inhibitAutoFollowDuration);
|
||||
break;
|
||||
canDo = true;
|
||||
}
|
||||
case EVENT_RADIO_GET_OUT_OF_THERE:
|
||||
break;
|
||||
}
|
||||
case EVENT_RADIO_SECTOR_CLEAR:
|
||||
{
|
||||
// if this is a defusal scenario, and the bomb is planted,
|
||||
// and a human player cleared a bombsite, check it off our list too
|
||||
if (TheCSBots()->GetScenario() == CCSBotManager::SCENARIO_DEFUSE_BOMB)
|
||||
{
|
||||
if (TheCSBots()->IsBombPlanted())
|
||||
if (m_iTeam == CT && TheCSBots()->IsBombPlanted())
|
||||
{
|
||||
EscapeFromBomb();
|
||||
m_radioSubject->InhibitAutoFollow(inhibitAutoFollowDuration);
|
||||
canDo = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EVENT_RADIO_SECTOR_CLEAR:
|
||||
{
|
||||
// if this is a defusal scenario, and the bomb is planted,
|
||||
// and a human player cleared a bombsite, check it off our list too
|
||||
if (TheCSBots()->GetScenario() == CCSBotManager::SCENARIO_DEFUSE_BOMB)
|
||||
{
|
||||
if (m_iTeam == CT && TheCSBots()->IsBombPlanted())
|
||||
const CCSBotManager::Zone *zone = TheCSBots()->GetClosestZone(m_radioSubject);
|
||||
if (zone)
|
||||
{
|
||||
const CCSBotManager::Zone *zone = TheCSBots()->GetClosestZone(m_radioSubject);
|
||||
if (zone)
|
||||
{
|
||||
GetGameState()->ClearBombsite(zone->m_index);
|
||||
GetGameState()->ClearBombsite(zone->m_index);
|
||||
|
||||
// if we are huting for the planted bomb, re-select bombsite
|
||||
if (GetTask() == FIND_TICKING_BOMB)
|
||||
Idle();
|
||||
// if we are huting for the planted bomb, re-select bombsite
|
||||
if (GetTask() == FIND_TICKING_BOMB)
|
||||
Idle();
|
||||
|
||||
canDo = true;
|
||||
}
|
||||
canDo = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// ignore all other radio commands for now
|
||||
return;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// ignore all other radio commands for now
|
||||
return;
|
||||
}
|
||||
|
||||
if (canDo)
|
||||
|
@ -132,34 +132,34 @@ void CCSBot::Upkeep()
|
||||
|
||||
switch (m_lookAtSpotState)
|
||||
{
|
||||
case NOT_LOOKING_AT_SPOT:
|
||||
{
|
||||
// look ahead
|
||||
SetLookAngles(m_lookAheadAngle, 0);
|
||||
break;
|
||||
}
|
||||
case LOOK_TOWARDS_SPOT:
|
||||
{
|
||||
UpdateLookAt();
|
||||
case NOT_LOOKING_AT_SPOT:
|
||||
{
|
||||
// look ahead
|
||||
SetLookAngles(m_lookAheadAngle, 0);
|
||||
break;
|
||||
}
|
||||
case LOOK_TOWARDS_SPOT:
|
||||
{
|
||||
UpdateLookAt();
|
||||
|
||||
if (IsLookingAtPosition(&m_lookAtSpot, m_lookAtSpotAngleTolerance))
|
||||
{
|
||||
m_lookAtSpotState = LOOK_AT_SPOT;
|
||||
m_lookAtSpotTimestamp = gpGlobals->time;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case LOOK_AT_SPOT:
|
||||
if (IsLookingAtPosition(&m_lookAtSpot, m_lookAtSpotAngleTolerance))
|
||||
{
|
||||
UpdateLookAt();
|
||||
|
||||
if (m_lookAtSpotDuration >= 0.0f && gpGlobals->time - m_lookAtSpotTimestamp > m_lookAtSpotDuration)
|
||||
{
|
||||
m_lookAtSpotState = NOT_LOOKING_AT_SPOT;
|
||||
m_lookAtSpotDuration = 0.0f;
|
||||
}
|
||||
break;
|
||||
m_lookAtSpotState = LOOK_AT_SPOT;
|
||||
m_lookAtSpotTimestamp = gpGlobals->time;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case LOOK_AT_SPOT:
|
||||
{
|
||||
UpdateLookAt();
|
||||
|
||||
if (m_lookAtSpotDuration >= 0.0f && gpGlobals->time - m_lookAtSpotTimestamp > m_lookAtSpotDuration)
|
||||
{
|
||||
m_lookAtSpotState = NOT_LOOKING_AT_SPOT;
|
||||
m_lookAtSpotDuration = 0.0f;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
float driftAmplitude = 2.0f;
|
||||
@ -189,10 +189,10 @@ void CCSBot::Update()
|
||||
|
||||
switch (m_processMode)
|
||||
{
|
||||
case PROCESS_LEARN: UpdateLearnProcess(); return;
|
||||
case PROCESS_ANALYZE_ALPHA: UpdateAnalyzeAlphaProcess(); return;
|
||||
case PROCESS_ANALYZE_BETA: UpdateAnalyzeBetaProcess(); return;
|
||||
case PROCESS_SAVE: UpdateSaveProcess(); return;
|
||||
case PROCESS_LEARN: UpdateLearnProcess(); return;
|
||||
case PROCESS_ANALYZE_ALPHA: UpdateAnalyzeAlphaProcess(); return;
|
||||
case PROCESS_ANALYZE_BETA: UpdateAnalyzeBetaProcess(); return;
|
||||
case PROCESS_SAVE: UpdateSaveProcess(); return;
|
||||
}
|
||||
|
||||
// update our radio chatter
|
||||
@ -312,11 +312,11 @@ void CCSBot::Update()
|
||||
{
|
||||
switch (m_blindMoveDir)
|
||||
{
|
||||
case FORWARD: MoveForward(); break;
|
||||
case RIGHT: StrafeRight(); break;
|
||||
case BACKWARD: MoveBackward(); break;
|
||||
case LEFT: StrafeLeft(); break;
|
||||
default: Crouch(); break;
|
||||
case FORWARD: MoveForward(); break;
|
||||
case RIGHT: StrafeRight(); break;
|
||||
case BACKWARD: MoveBackward(); break;
|
||||
case LEFT: StrafeLeft(); break;
|
||||
default: Crouch(); break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -349,32 +349,32 @@ void CCSBot::Update()
|
||||
bool doAttack = false;
|
||||
switch (GetDisposition())
|
||||
{
|
||||
case IGNORE_ENEMIES:
|
||||
{
|
||||
// never attack
|
||||
doAttack = false;
|
||||
break;
|
||||
}
|
||||
case SELF_DEFENSE:
|
||||
{
|
||||
// attack if fired on
|
||||
doAttack = IsPlayerLookingAtMe(threat);
|
||||
case IGNORE_ENEMIES:
|
||||
{
|
||||
// never attack
|
||||
doAttack = false;
|
||||
break;
|
||||
}
|
||||
case SELF_DEFENSE:
|
||||
{
|
||||
// attack if fired on
|
||||
doAttack = IsPlayerLookingAtMe(threat);
|
||||
|
||||
// attack if enemy very close
|
||||
if (!doAttack)
|
||||
{
|
||||
const float selfDefenseRange = 750.0f;
|
||||
doAttack = (pev->origin - threat->pev->origin).IsLengthLessThan(selfDefenseRange);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ENGAGE_AND_INVESTIGATE:
|
||||
case OPPORTUNITY_FIRE:
|
||||
// attack if enemy very close
|
||||
if (!doAttack)
|
||||
{
|
||||
// normal combat range
|
||||
doAttack = true;
|
||||
break;
|
||||
const float selfDefenseRange = 750.0f;
|
||||
doAttack = (pev->origin - threat->pev->origin).IsLengthLessThan(selfDefenseRange);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ENGAGE_AND_INVESTIGATE:
|
||||
case OPPORTUNITY_FIRE:
|
||||
{
|
||||
// normal combat range
|
||||
doAttack = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (doAttack)
|
||||
@ -596,52 +596,52 @@ void CCSBot::Update()
|
||||
// Scenario interrupts
|
||||
switch (TheCSBots()->GetScenario())
|
||||
{
|
||||
case CCSBotManager::SCENARIO_DEFUSE_BOMB:
|
||||
case CCSBotManager::SCENARIO_DEFUSE_BOMB:
|
||||
{
|
||||
// flee if the bomb is ready to blow and we aren't defusing it or attacking and we know where the bomb is
|
||||
// (aggressive players wait until its almost too late)
|
||||
float gonnaBlowTime = 8.0f - (2.0f * GetProfile()->GetAggression());
|
||||
|
||||
// if we have a defuse kit, can wait longer
|
||||
if (m_bHasDefuser)
|
||||
gonnaBlowTime *= 0.66f;
|
||||
|
||||
if (!IsEscapingFromBomb() // we aren't already escaping the bomb
|
||||
&& TheCSBots()->IsBombPlanted() // is the bomb planted
|
||||
&& GetGameState()->IsPlantedBombLocationKnown() // we know where the bomb is
|
||||
&& TheCSBots()->GetBombTimeLeft() < gonnaBlowTime // is the bomb about to explode
|
||||
&& !IsDefusingBomb() // we aren't defusing the bomb
|
||||
&& !IsAttacking()) // we aren't in the midst of a firefight
|
||||
{
|
||||
// flee if the bomb is ready to blow and we aren't defusing it or attacking and we know where the bomb is
|
||||
// (aggressive players wait until its almost too late)
|
||||
float gonnaBlowTime = 8.0f - (2.0f * GetProfile()->GetAggression());
|
||||
|
||||
// if we have a defuse kit, can wait longer
|
||||
if (m_bHasDefuser)
|
||||
gonnaBlowTime *= 0.66f;
|
||||
|
||||
if (!IsEscapingFromBomb() // we aren't already escaping the bomb
|
||||
&& TheCSBots()->IsBombPlanted() // is the bomb planted
|
||||
&& GetGameState()->IsPlantedBombLocationKnown() // we know where the bomb is
|
||||
&& TheCSBots()->GetBombTimeLeft() < gonnaBlowTime // is the bomb about to explode
|
||||
&& !IsDefusingBomb() // we aren't defusing the bomb
|
||||
&& !IsAttacking()) // we aren't in the midst of a firefight
|
||||
{
|
||||
EscapeFromBomb();
|
||||
break;
|
||||
}
|
||||
EscapeFromBomb();
|
||||
break;
|
||||
}
|
||||
case CCSBotManager::SCENARIO_RESCUE_HOSTAGES:
|
||||
break;
|
||||
}
|
||||
case CCSBotManager::SCENARIO_RESCUE_HOSTAGES:
|
||||
{
|
||||
if (m_iTeam == CT)
|
||||
{
|
||||
if (m_iTeam == CT)
|
||||
{
|
||||
UpdateHostageEscortCount();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Terrorists have imperfect information on status of hostages
|
||||
CSGameState::ValidateStatusType status = GetGameState()->ValidateHostagePositions();
|
||||
|
||||
if (status & CSGameState::HOSTAGES_ALL_GONE)
|
||||
{
|
||||
GetChatter()->HostagesTaken();
|
||||
Idle();
|
||||
}
|
||||
else if (status & CSGameState::HOSTAGE_GONE)
|
||||
{
|
||||
GetGameState()->HostageWasTaken();
|
||||
Idle();
|
||||
}
|
||||
}
|
||||
break;
|
||||
UpdateHostageEscortCount();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Terrorists have imperfect information on status of hostages
|
||||
CSGameState::ValidateStatusType status = GetGameState()->ValidateHostagePositions();
|
||||
|
||||
if (status & CSGameState::HOSTAGES_ALL_GONE)
|
||||
{
|
||||
GetChatter()->HostagesTaken();
|
||||
Idle();
|
||||
}
|
||||
else if (status & CSGameState::HOSTAGE_GONE)
|
||||
{
|
||||
GetGameState()->HostageWasTaken();
|
||||
Idle();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Follow nearby humans if our co-op is high and we have nothing else to do
|
||||
|
@ -103,56 +103,56 @@ void CCSBot::UpdateLookAngles()
|
||||
// adjust pitch to look up/down ladder as we ascend/descend
|
||||
switch (m_pathLadderState)
|
||||
{
|
||||
case APPROACH_ASCENDING_LADDER:
|
||||
{
|
||||
Vector to = m_goalPosition - pev->origin;
|
||||
useYaw = idealYaw;
|
||||
case APPROACH_ASCENDING_LADDER:
|
||||
{
|
||||
Vector to = m_goalPosition - pev->origin;
|
||||
useYaw = idealYaw;
|
||||
|
||||
if (to.IsLengthLessThan(lookAlongLadderRange))
|
||||
usePitch = -ladderPitch;
|
||||
break;
|
||||
}
|
||||
case APPROACH_DESCENDING_LADDER:
|
||||
{
|
||||
Vector to = m_goalPosition - pev->origin;
|
||||
useYaw = idealYaw;
|
||||
if (to.IsLengthLessThan(lookAlongLadderRange))
|
||||
usePitch = -ladderPitch;
|
||||
break;
|
||||
}
|
||||
case APPROACH_DESCENDING_LADDER:
|
||||
{
|
||||
Vector to = m_goalPosition - pev->origin;
|
||||
useYaw = idealYaw;
|
||||
|
||||
if (to.IsLengthLessThan(lookAlongLadderRange))
|
||||
usePitch = ladderPitch;
|
||||
break;
|
||||
}
|
||||
case FACE_ASCENDING_LADDER:
|
||||
{
|
||||
useYaw = idealYaw;
|
||||
usePitch = -ladderPitch;
|
||||
break;
|
||||
}
|
||||
case FACE_DESCENDING_LADDER:
|
||||
{
|
||||
useYaw = idealYaw;
|
||||
if (to.IsLengthLessThan(lookAlongLadderRange))
|
||||
usePitch = ladderPitch;
|
||||
break;
|
||||
}
|
||||
case MOUNT_ASCENDING_LADDER:
|
||||
case ASCEND_LADDER:
|
||||
{
|
||||
useYaw = DirectionToAngle(faceDir) + StayOnLadderLine(this, m_pathLadder);
|
||||
usePitch = -ladderPitch;
|
||||
break;
|
||||
}
|
||||
case MOUNT_DESCENDING_LADDER:
|
||||
case DESCEND_LADDER:
|
||||
{
|
||||
useYaw = DirectionToAngle(faceDir) + StayOnLadderLine(this, m_pathLadder);
|
||||
usePitch = ladderPitch;
|
||||
break;
|
||||
}
|
||||
case DISMOUNT_ASCENDING_LADDER:
|
||||
case DISMOUNT_DESCENDING_LADDER:
|
||||
{
|
||||
useYaw = DirectionToAngle(faceDir);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FACE_ASCENDING_LADDER:
|
||||
{
|
||||
useYaw = idealYaw;
|
||||
usePitch = -ladderPitch;
|
||||
break;
|
||||
}
|
||||
case FACE_DESCENDING_LADDER:
|
||||
{
|
||||
useYaw = idealYaw;
|
||||
usePitch = ladderPitch;
|
||||
break;
|
||||
}
|
||||
case MOUNT_ASCENDING_LADDER:
|
||||
case ASCEND_LADDER:
|
||||
{
|
||||
useYaw = DirectionToAngle(faceDir) + StayOnLadderLine(this, m_pathLadder);
|
||||
usePitch = -ladderPitch;
|
||||
break;
|
||||
}
|
||||
case MOUNT_DESCENDING_LADDER:
|
||||
case DESCEND_LADDER:
|
||||
{
|
||||
useYaw = DirectionToAngle(faceDir) + StayOnLadderLine(this, m_pathLadder);
|
||||
usePitch = ladderPitch;
|
||||
break;
|
||||
}
|
||||
case DISMOUNT_ASCENDING_LADDER:
|
||||
case DISMOUNT_DESCENDING_LADDER:
|
||||
{
|
||||
useYaw = DirectionToAngle(faceDir);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -246,27 +246,27 @@ const Vector *CSGameState::GetBombPosition() const
|
||||
{
|
||||
switch (m_bombState)
|
||||
{
|
||||
case MOVING:
|
||||
{
|
||||
if (!m_lastSawBomber.HasStarted())
|
||||
return nullptr;
|
||||
|
||||
return &m_bomberPos;
|
||||
}
|
||||
case LOOSE:
|
||||
{
|
||||
if (IsLooseBombLocationKnown())
|
||||
return &m_looseBombPos;
|
||||
|
||||
case MOVING:
|
||||
{
|
||||
if (!m_lastSawBomber.HasStarted())
|
||||
return nullptr;
|
||||
}
|
||||
case PLANTED:
|
||||
{
|
||||
if (IsPlantedBombLocationKnown())
|
||||
return &m_plantedBombPos;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
return &m_bomberPos;
|
||||
}
|
||||
case LOOSE:
|
||||
{
|
||||
if (IsLooseBombLocationKnown())
|
||||
return &m_looseBombPos;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
case PLANTED:
|
||||
{
|
||||
if (IsPlantedBombLocationKnown())
|
||||
return &m_plantedBombPos;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
@ -477,7 +477,7 @@ CSGameState::ValidateStatusType CSGameState::ValidateHostagePositions()
|
||||
{
|
||||
HostageInfo *info = &m_hostage[i];
|
||||
|
||||
if (!info->hostage)
|
||||
if (!info->hostage)
|
||||
continue;
|
||||
|
||||
// if we can see a hostage, update our knowledge of it
|
||||
|
@ -39,7 +39,7 @@ void FetchBombState::OnUpdate(CCSBot *me)
|
||||
{
|
||||
if (me->IsCarryingBomb())
|
||||
{
|
||||
me->PrintIfWatched( "I picked up the bomb\n" );
|
||||
me->PrintIfWatched("I picked up the bomb\n");
|
||||
me->Idle();
|
||||
return;
|
||||
}
|
||||
|
@ -141,106 +141,106 @@ void HideState::OnUpdate(CCSBot *me)
|
||||
// Scenario logic
|
||||
switch (TheCSBots()->GetScenario())
|
||||
{
|
||||
case CCSBotManager::SCENARIO_DEFUSE_BOMB:
|
||||
case CCSBotManager::SCENARIO_DEFUSE_BOMB:
|
||||
{
|
||||
if (me->m_iTeam == CT)
|
||||
{
|
||||
if (me->m_iTeam == CT)
|
||||
// if we are just holding position (due to a radio order) and the bomb has just planted, go defuse it
|
||||
if (me->GetTask() == CCSBot::HOLD_POSITION &&
|
||||
TheCSBots()->IsBombPlanted() &&
|
||||
TheCSBots()->GetBombPlantTimestamp() > me->GetStateTimestamp())
|
||||
{
|
||||
// if we are just holding position (due to a radio order) and the bomb has just planted, go defuse it
|
||||
if (me->GetTask() == CCSBot::HOLD_POSITION &&
|
||||
TheCSBots()->IsBombPlanted() &&
|
||||
TheCSBots()->GetBombPlantTimestamp() > me->GetStateTimestamp())
|
||||
{
|
||||
me->Idle();
|
||||
return;
|
||||
}
|
||||
|
||||
// if we are guarding the defuser and he dies/gives up, stop hiding (to choose another defuser)
|
||||
if (me->GetTask() == CCSBot::GUARD_BOMB_DEFUSER && !TheCSBots()->GetBombDefuser())
|
||||
{
|
||||
me->Idle();
|
||||
return;
|
||||
}
|
||||
|
||||
// if we are guarding the loose bomb and it is picked up, stop hiding
|
||||
if (me->GetTask() == CCSBot::GUARD_LOOSE_BOMB && !TheCSBots()->GetLooseBomb())
|
||||
{
|
||||
me->GetChatter()->TheyPickedUpTheBomb();
|
||||
me->Idle();
|
||||
return;
|
||||
}
|
||||
|
||||
// if we are guarding a bombsite and the bomb is dropped and we hear about it, stop guarding
|
||||
if (me->GetTask() == CCSBot::GUARD_BOMB_ZONE && me->GetGameState()->IsLooseBombLocationKnown())
|
||||
{
|
||||
me->Idle();
|
||||
return;
|
||||
}
|
||||
|
||||
// if we are guarding (bombsite, initial encounter, etc) and the bomb is planted, go defuse it
|
||||
if (me->IsDoingScenario() && me->GetTask() == CCSBot::GUARD_BOMB_ZONE && TheCSBots()->IsBombPlanted())
|
||||
{
|
||||
me->Idle();
|
||||
return;
|
||||
}
|
||||
|
||||
me->Idle();
|
||||
return;
|
||||
}
|
||||
// TERRORIST
|
||||
else
|
||||
|
||||
// if we are guarding the defuser and he dies/gives up, stop hiding (to choose another defuser)
|
||||
if (me->GetTask() == CCSBot::GUARD_BOMB_DEFUSER && !TheCSBots()->GetBombDefuser())
|
||||
{
|
||||
// if we are near the ticking bomb and someone starts defusing it, attack!
|
||||
if (TheCSBots()->GetBombDefuser())
|
||||
{
|
||||
Vector toDefuser = TheCSBots()->GetBombDefuser()->pev->origin;
|
||||
const float hearDefuseRange = 2000.0f;
|
||||
if ((toDefuser - me->pev->origin).IsLengthLessThan(hearDefuseRange))
|
||||
{
|
||||
// if we are nearby, attack, otherwise move to the bomb (which will cause us to attack when we see defuser)
|
||||
if (me->CanSeePlantedBomb())
|
||||
{
|
||||
me->Attack(TheCSBots()->GetBombDefuser());
|
||||
}
|
||||
else
|
||||
{
|
||||
me->MoveTo(&toDefuser, FASTEST_ROUTE);
|
||||
me->InhibitLookAround(10.0f);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
me->Idle();
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
// if we are guarding the loose bomb and it is picked up, stop hiding
|
||||
if (me->GetTask() == CCSBot::GUARD_LOOSE_BOMB && !TheCSBots()->GetLooseBomb())
|
||||
{
|
||||
me->GetChatter()->TheyPickedUpTheBomb();
|
||||
me->Idle();
|
||||
return;
|
||||
}
|
||||
|
||||
// if we are guarding a bombsite and the bomb is dropped and we hear about it, stop guarding
|
||||
if (me->GetTask() == CCSBot::GUARD_BOMB_ZONE && me->GetGameState()->IsLooseBombLocationKnown())
|
||||
{
|
||||
me->Idle();
|
||||
return;
|
||||
}
|
||||
|
||||
// if we are guarding (bombsite, initial encounter, etc) and the bomb is planted, go defuse it
|
||||
if (me->IsDoingScenario() && me->GetTask() == CCSBot::GUARD_BOMB_ZONE && TheCSBots()->IsBombPlanted())
|
||||
{
|
||||
me->Idle();
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
case CCSBotManager::SCENARIO_RESCUE_HOSTAGES:
|
||||
// TERRORIST
|
||||
else
|
||||
{
|
||||
// if we're guarding the hostages and they all die or are taken, do something else
|
||||
if (me->GetTask() == CCSBot::GUARD_HOSTAGES)
|
||||
// if we are near the ticking bomb and someone starts defusing it, attack!
|
||||
if (TheCSBots()->GetBombDefuser())
|
||||
{
|
||||
if (me->GetGameState()->AreAllHostagesBeingRescued() || me->GetGameState()->AreAllHostagesGone())
|
||||
Vector toDefuser = TheCSBots()->GetBombDefuser()->pev->origin;
|
||||
const float hearDefuseRange = 2000.0f;
|
||||
if ((toDefuser - me->pev->origin).IsLengthLessThan(hearDefuseRange))
|
||||
{
|
||||
me->Idle();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (me->GetTask() == CCSBot::GUARD_HOSTAGE_RESCUE_ZONE)
|
||||
{
|
||||
// if we stumble across a hostage, guard it
|
||||
CHostage *pHostage = me->GetGameState()->GetNearestVisibleFreeHostage();
|
||||
if (pHostage)
|
||||
{
|
||||
// we see a free hostage, guard it
|
||||
CNavArea *area = TheNavAreaGrid.GetNearestNavArea(&pHostage->pev->origin);
|
||||
if (area)
|
||||
// if we are nearby, attack, otherwise move to the bomb (which will cause us to attack when we see defuser)
|
||||
if (me->CanSeePlantedBomb())
|
||||
{
|
||||
me->SetTask(CCSBot::GUARD_HOSTAGES);
|
||||
me->Hide(area);
|
||||
me->PrintIfWatched("I'm guarding hostages I found\n");
|
||||
// don't chatter here - he'll tell us when he's in his hiding spot
|
||||
return;
|
||||
me->Attack(TheCSBots()->GetBombDefuser());
|
||||
}
|
||||
else
|
||||
{
|
||||
me->MoveTo(&toDefuser, FASTEST_ROUTE);
|
||||
me->InhibitLookAround(10.0f);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CCSBotManager::SCENARIO_RESCUE_HOSTAGES:
|
||||
{
|
||||
// if we're guarding the hostages and they all die or are taken, do something else
|
||||
if (me->GetTask() == CCSBot::GUARD_HOSTAGES)
|
||||
{
|
||||
if (me->GetGameState()->AreAllHostagesBeingRescued() || me->GetGameState()->AreAllHostagesGone())
|
||||
{
|
||||
me->Idle();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (me->GetTask() == CCSBot::GUARD_HOSTAGE_RESCUE_ZONE)
|
||||
{
|
||||
// if we stumble across a hostage, guard it
|
||||
CHostage *pHostage = me->GetGameState()->GetNearestVisibleFreeHostage();
|
||||
if (pHostage)
|
||||
{
|
||||
// we see a free hostage, guard it
|
||||
CNavArea *area = TheNavAreaGrid.GetNearestNavArea(&pHostage->pev->origin);
|
||||
if (area)
|
||||
{
|
||||
me->SetTask(CCSBot::GUARD_HOSTAGES);
|
||||
me->Hide(area);
|
||||
me->PrintIfWatched("I'm guarding hostages I found\n");
|
||||
// don't chatter here - he'll tell us when he's in his hiding spot
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool isSettledInSniper = (me->IsSniper() && m_isAtSpot) ? true : false;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -44,15 +44,15 @@ void MoveToState::OnEnter(CCSBot *me)
|
||||
RouteType route;
|
||||
switch (me->GetTask())
|
||||
{
|
||||
case CCSBot::FIND_TICKING_BOMB:
|
||||
case CCSBot::DEFUSE_BOMB:
|
||||
case CCSBot::MOVE_TO_LAST_KNOWN_ENEMY_POSITION:
|
||||
route = FASTEST_ROUTE;
|
||||
break;
|
||||
case CCSBot::FIND_TICKING_BOMB:
|
||||
case CCSBot::DEFUSE_BOMB:
|
||||
case CCSBot::MOVE_TO_LAST_KNOWN_ENEMY_POSITION:
|
||||
route = FASTEST_ROUTE;
|
||||
break;
|
||||
|
||||
default:
|
||||
route = SAFEST_ROUTE;
|
||||
break;
|
||||
default:
|
||||
route = SAFEST_ROUTE;
|
||||
break;
|
||||
}
|
||||
|
||||
// build path to, or nearly to, goal position
|
||||
@ -84,181 +84,180 @@ void MoveToState::OnUpdate(CCSBot *me)
|
||||
// Scenario logic
|
||||
switch (TheCSBots()->GetScenario())
|
||||
{
|
||||
case CCSBotManager::SCENARIO_DEFUSE_BOMB:
|
||||
case CCSBotManager::SCENARIO_DEFUSE_BOMB:
|
||||
{
|
||||
// if the bomb has been planted, find it
|
||||
// NOTE: This task is used by both CT and T's to find the bomb
|
||||
if (me->GetTask() == CCSBot::FIND_TICKING_BOMB)
|
||||
{
|
||||
// if the bomb has been planted, find it
|
||||
// NOTE: This task is used by both CT and T's to find the bomb
|
||||
if (me->GetTask() == CCSBot::FIND_TICKING_BOMB)
|
||||
if (!me->GetGameState()->IsBombPlanted())
|
||||
{
|
||||
if (!me->GetGameState()->IsBombPlanted())
|
||||
{
|
||||
// the bomb is not planted - give up this task
|
||||
me->Idle();
|
||||
return;
|
||||
}
|
||||
// the bomb is not planted - give up this task
|
||||
me->Idle();
|
||||
return;
|
||||
}
|
||||
|
||||
if (me->GetGameState()->GetPlantedBombsite() != CSGameState::UNKNOWN)
|
||||
{
|
||||
// we know where the bomb is planted, stop searching
|
||||
me->Idle();
|
||||
return;
|
||||
}
|
||||
if (me->GetGameState()->GetPlantedBombsite() != CSGameState::UNKNOWN)
|
||||
{
|
||||
// we know where the bomb is planted, stop searching
|
||||
me->Idle();
|
||||
return;
|
||||
}
|
||||
|
||||
// check off bombsites that we explore or happen to stumble into
|
||||
for (int z = 0; z < TheCSBots()->GetZoneCount(); z++)
|
||||
{
|
||||
// don't re-check zones
|
||||
if (me->GetGameState()->IsBombsiteClear(z))
|
||||
continue;
|
||||
// check off bombsites that we explore or happen to stumble into
|
||||
for (int z = 0; z < TheCSBots()->GetZoneCount(); z++)
|
||||
{
|
||||
// don't re-check zones
|
||||
if (me->GetGameState()->IsBombsiteClear(z))
|
||||
continue;
|
||||
|
||||
if (TheCSBots()->GetZone(z)->m_extent.Contains(&me->pev->origin))
|
||||
if (TheCSBots()->GetZone(z)->m_extent.Contains(&me->pev->origin))
|
||||
{
|
||||
// note this bombsite is clear
|
||||
me->GetGameState()->ClearBombsite(z);
|
||||
|
||||
if (me->m_iTeam == CT)
|
||||
{
|
||||
// note this bombsite is clear
|
||||
me->GetGameState()->ClearBombsite(z);
|
||||
// tell teammates this bombsite is clear
|
||||
me->GetChatter()->BombsiteClear(z);
|
||||
}
|
||||
|
||||
if (me->m_iTeam == CT)
|
||||
{
|
||||
// tell teammates this bombsite is clear
|
||||
me->GetChatter()->BombsiteClear(z);
|
||||
}
|
||||
// find another zone to check
|
||||
me->Idle();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// find another zone to check
|
||||
// move to a bombsite
|
||||
break;
|
||||
}
|
||||
else if (me->m_iTeam == CT)
|
||||
{
|
||||
if (me->GetGameState()->IsBombPlanted())
|
||||
{
|
||||
switch (me->GetTask())
|
||||
{
|
||||
case CCSBot::DEFUSE_BOMB:
|
||||
{
|
||||
// if we are trying to defuse the bomb, and someone has started defusing, guard them instead
|
||||
if (me->CanSeePlantedBomb() && TheCSBots()->GetBombDefuser())
|
||||
{
|
||||
me->GetChatter()->Say("CoveringFriend");
|
||||
me->Idle();
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// move to a bombsite
|
||||
break;
|
||||
}
|
||||
else if (me->m_iTeam == CT)
|
||||
{
|
||||
if (me->GetGameState()->IsBombPlanted())
|
||||
default:
|
||||
{
|
||||
switch (me->GetTask())
|
||||
{
|
||||
case CCSBot::DEFUSE_BOMB:
|
||||
{
|
||||
// if we are trying to defuse the bomb, and someone has started defusing, guard them instead
|
||||
if (me->CanSeePlantedBomb() && TheCSBots()->GetBombDefuser())
|
||||
{
|
||||
me->GetChatter()->Say("CoveringFriend");
|
||||
me->Idle();
|
||||
return;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
// we need to find the bomb
|
||||
me->Idle();
|
||||
return;
|
||||
}
|
||||
}
|
||||
// we need to find the bomb
|
||||
me->Idle();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
// TERRORIST
|
||||
else
|
||||
{
|
||||
if (me->GetTask() == CCSBot::PLANT_BOMB)
|
||||
{
|
||||
if (me->GetFriendsRemaining())
|
||||
{
|
||||
// if we are about to plant, radio for cover
|
||||
if (!m_askedForCover)
|
||||
{
|
||||
const float nearPlantSite = 50.0f;
|
||||
if (me->IsAtBombsite() && me->GetPathDistanceRemaining() < nearPlantSite)
|
||||
{
|
||||
// radio to the team
|
||||
me->GetChatter()->PlantingTheBomb(me->GetPlace());
|
||||
m_askedForCover = true;
|
||||
}
|
||||
|
||||
// after we have started to move to the bombsite, tell team we're going to plant, and where
|
||||
// don't do this if we have already radioed that we are starting to plant
|
||||
if (!m_radioedPlan)
|
||||
{
|
||||
const float radioTime = 2.0f;
|
||||
if (gpGlobals->time - me->GetStateTimestamp() > radioTime)
|
||||
{
|
||||
me->GetChatter()->GoingToPlantTheBomb(TheNavAreaGrid.GetPlace(&m_goalPosition));
|
||||
m_radioedPlan = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CCSBotManager::SCENARIO_RESCUE_HOSTAGES:
|
||||
// TERRORIST
|
||||
else
|
||||
{
|
||||
if (me->GetTask() == CCSBot::COLLECT_HOSTAGES)
|
||||
if (me->GetTask() == CCSBot::PLANT_BOMB)
|
||||
{
|
||||
// Since CT's have a radar, they can directly look at the actual hostage state
|
||||
// check if someone else collected our hostage, or the hostage died or was rescued
|
||||
CHostage *pHostage = me->GetGoalEntity<CHostage>();
|
||||
if (!pHostage || !pHostage->IsAlive() || pHostage->IsFollowingSomeone())
|
||||
if (me->GetFriendsRemaining())
|
||||
{
|
||||
me->Idle();
|
||||
return;
|
||||
}
|
||||
|
||||
// if our hostage has moved, repath
|
||||
const float repathToleranceSq = 75.0f * 75.0f;
|
||||
float error = (pHostage->pev->origin - m_goalPosition).LengthSquared();
|
||||
if (error > repathToleranceSq)
|
||||
{
|
||||
m_goalPosition = pHostage->pev->origin;
|
||||
me->ComputePath(TheNavAreaGrid.GetNavArea(&m_goalPosition), &m_goalPosition, SAFEST_ROUTE);
|
||||
}
|
||||
|
||||
// TODO: Generalize ladder priorities over other tasks
|
||||
if (!me->IsUsingLadder())
|
||||
{
|
||||
Vector pos = pHostage->pev->origin + Vector(0, 0, HumanHeight * 0.75f);
|
||||
Vector to = pos - me->pev->origin;
|
||||
|
||||
// look at the hostage as we approach
|
||||
const float watchHostageRange = 100.0f;
|
||||
if (to.IsLengthLessThan(watchHostageRange))
|
||||
// if we are about to plant, radio for cover
|
||||
if (!m_askedForCover)
|
||||
{
|
||||
me->SetLookAt("Hostage", &pos, PRIORITY_LOW, 0.5f);
|
||||
|
||||
// randomly move just a bit to avoid infinite use loops from bad hostage placement
|
||||
NavRelativeDirType dir = (NavRelativeDirType)RANDOM_LONG(0, 3);
|
||||
switch (dir)
|
||||
const float nearPlantSite = 50.0f;
|
||||
if (me->IsAtBombsite() && me->GetPathDistanceRemaining() < nearPlantSite)
|
||||
{
|
||||
case LEFT: me->StrafeLeft(); break;
|
||||
case RIGHT: me->StrafeRight(); break;
|
||||
case FORWARD: me->MoveForward(); break;
|
||||
case BACKWARD: me->MoveBackward(); break;
|
||||
// radio to the team
|
||||
me->GetChatter()->PlantingTheBomb(me->GetPlace());
|
||||
m_askedForCover = true;
|
||||
}
|
||||
|
||||
// check if we are close enough to the hostage to talk to him
|
||||
const float useRange = MAX_PLAYER_USE_RADIUS - 14.0f; // shave off a fudge factor to make sure we're within range
|
||||
if (to.IsLengthLessThan(useRange))
|
||||
// after we have started to move to the bombsite, tell team we're going to plant, and where
|
||||
// don't do this if we have already radioed that we are starting to plant
|
||||
if (!m_radioedPlan)
|
||||
{
|
||||
me->UseEntity(me->GetGoalEntity());
|
||||
return;
|
||||
const float radioTime = 2.0f;
|
||||
if (gpGlobals->time - me->GetStateTimestamp() > radioTime)
|
||||
{
|
||||
me->GetChatter()->GoingToPlantTheBomb(TheNavAreaGrid.GetPlace(&m_goalPosition));
|
||||
m_radioedPlan = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (me->GetTask() == CCSBot::RESCUE_HOSTAGES)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CCSBotManager::SCENARIO_RESCUE_HOSTAGES:
|
||||
{
|
||||
if (me->GetTask() == CCSBot::COLLECT_HOSTAGES)
|
||||
{
|
||||
// Since CT's have a radar, they can directly look at the actual hostage state
|
||||
// check if someone else collected our hostage, or the hostage died or was rescued
|
||||
CHostage *pHostage = me->GetGoalEntity<CHostage>();
|
||||
if (!pHostage || !pHostage->IsAlive() || pHostage->IsFollowingSomeone())
|
||||
{
|
||||
// periodically check if we lost all our hostages
|
||||
if (me->GetHostageEscortCount() == 0)
|
||||
me->Idle();
|
||||
return;
|
||||
}
|
||||
|
||||
// if our hostage has moved, repath
|
||||
const float repathToleranceSq = 75.0f * 75.0f;
|
||||
float error = (pHostage->pev->origin - m_goalPosition).LengthSquared();
|
||||
if (error > repathToleranceSq)
|
||||
{
|
||||
m_goalPosition = pHostage->pev->origin;
|
||||
me->ComputePath(TheNavAreaGrid.GetNavArea(&m_goalPosition), &m_goalPosition, SAFEST_ROUTE);
|
||||
}
|
||||
|
||||
// TODO: Generalize ladder priorities over other tasks
|
||||
if (!me->IsUsingLadder())
|
||||
{
|
||||
Vector pos = pHostage->pev->origin + Vector(0, 0, HumanHeight * 0.75f);
|
||||
Vector to = pos - me->pev->origin;
|
||||
|
||||
// look at the hostage as we approach
|
||||
const float watchHostageRange = 100.0f;
|
||||
if (to.IsLengthLessThan(watchHostageRange))
|
||||
{
|
||||
// lost our hostages - go get 'em
|
||||
me->Idle();
|
||||
return;
|
||||
me->SetLookAt("Hostage", &pos, PRIORITY_LOW, 0.5f);
|
||||
|
||||
// randomly move just a bit to avoid infinite use loops from bad hostage placement
|
||||
NavRelativeDirType dir = (NavRelativeDirType)RANDOM_LONG(0, 3);
|
||||
switch (dir)
|
||||
{
|
||||
case LEFT: me->StrafeLeft(); break;
|
||||
case RIGHT: me->StrafeRight(); break;
|
||||
case FORWARD: me->MoveForward(); break;
|
||||
case BACKWARD: me->MoveBackward(); break;
|
||||
}
|
||||
|
||||
// check if we are close enough to the hostage to talk to him
|
||||
const float useRange = MAX_PLAYER_USE_RADIUS - 14.0f; // shave off a fudge factor to make sure we're within range
|
||||
if (to.IsLengthLessThan(useRange))
|
||||
{
|
||||
me->UseEntity(me->GetGoalEntity());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if (me->GetTask() == CCSBot::RESCUE_HOSTAGES)
|
||||
{
|
||||
// periodically check if we lost all our hostages
|
||||
if (me->GetHostageEscortCount() == 0)
|
||||
{
|
||||
// lost our hostages - go get 'em
|
||||
me->Idle();
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (me->UpdatePathMovement() != CCSBot::PROGRESSING)
|
||||
@ -266,47 +265,47 @@ void MoveToState::OnUpdate(CCSBot *me)
|
||||
// reached destination
|
||||
switch (me->GetTask())
|
||||
{
|
||||
case CCSBot::PLANT_BOMB:
|
||||
case CCSBot::PLANT_BOMB:
|
||||
{
|
||||
// if we are at bombsite with the bomb, plant it
|
||||
if (me->IsAtBombsite() && me->IsCarryingBomb())
|
||||
{
|
||||
// if we are at bombsite with the bomb, plant it
|
||||
if (me->IsAtBombsite() && me->IsCarryingBomb())
|
||||
{
|
||||
me->PlantBomb();
|
||||
return;
|
||||
}
|
||||
break;
|
||||
me->PlantBomb();
|
||||
return;
|
||||
}
|
||||
case CCSBot::DEFUSE_BOMB:
|
||||
break;
|
||||
}
|
||||
case CCSBot::DEFUSE_BOMB:
|
||||
{
|
||||
if (!me->IsActiveWeaponReloading())
|
||||
{
|
||||
if (!me->IsActiveWeaponReloading())
|
||||
// if we are near the bomb, defuse it (if we are reloading, don't try to defuse until we finish)
|
||||
const Vector *bombPos = me->GetGameState()->GetBombPosition();
|
||||
if (bombPos)
|
||||
{
|
||||
// if we are near the bomb, defuse it (if we are reloading, don't try to defuse until we finish)
|
||||
const Vector *bombPos = me->GetGameState()->GetBombPosition();
|
||||
if (bombPos)
|
||||
{
|
||||
const float defuseRange = 100.0f;
|
||||
Vector toBomb = *bombPos - me->pev->origin;
|
||||
toBomb.z = bombPos->z - me->GetFeetZ();
|
||||
const float defuseRange = 100.0f;
|
||||
Vector toBomb = *bombPos - me->pev->origin;
|
||||
toBomb.z = bombPos->z - me->GetFeetZ();
|
||||
|
||||
if (toBomb.IsLengthLessThan(defuseRange))
|
||||
{
|
||||
me->DefuseBomb();
|
||||
return;
|
||||
}
|
||||
if (toBomb.IsLengthLessThan(defuseRange))
|
||||
{
|
||||
me->DefuseBomb();
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CCSBot::MOVE_TO_LAST_KNOWN_ENEMY_POSITION:
|
||||
break;
|
||||
}
|
||||
case CCSBot::MOVE_TO_LAST_KNOWN_ENEMY_POSITION:
|
||||
{
|
||||
CBaseEntity *pVictim = me->GetTaskEntity();
|
||||
if (pVictim && pVictim->IsAlive())
|
||||
{
|
||||
CBaseEntity *pVictim = me->GetTaskEntity();
|
||||
if (pVictim && pVictim->IsAlive())
|
||||
{
|
||||
// if we got here and haven't re-acquired the enemy, we lost him
|
||||
me->GetChatter()->Say("LostEnemy");
|
||||
}
|
||||
break;
|
||||
// if we got here and haven't re-acquired the enemy, we lost him
|
||||
me->GetChatter()->Say("LostEnemy");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// default behavior when destination is reached
|
||||
|
@ -293,7 +293,7 @@ void RadiusDamage(Vector vecSrc, entvars_t *pevInflictor, entvars_t *pevAttacker
|
||||
if (flAdjustedDamage < 0)
|
||||
flAdjustedDamage = 0;
|
||||
#endif
|
||||
pEntity->TakeDamage(pevInflictor, pevAttacker, flAdjustedDamage, bitsDamageType);
|
||||
pEntity->TakeDamage(pevInflictor, pevAttacker, flAdjustedDamage, bitsDamageType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -969,7 +969,7 @@ void CMomentaryDoor::Spawn()
|
||||
if (pev->dmg == 0)
|
||||
pev->dmg = 2;
|
||||
|
||||
m_vecPosition1 = pev->origin;
|
||||
m_vecPosition1 = pev->origin;
|
||||
|
||||
// Subtract 2 from size because the engine expands bboxes by 1 in all directions making the size too big
|
||||
m_vecPosition2 = m_vecPosition1 + (pev->movedir * (Q_fabs(float_precision(pev->movedir.x * (pev->size.x - 2))) + Q_fabs(float_precision(pev->movedir.y * (pev->size.y - 2))) + Q_fabs(float_precision(pev->movedir.z * (pev->size.z - 2))) - m_flLip));
|
||||
|
@ -1003,7 +1003,7 @@ void CGlow::Spawn()
|
||||
|
||||
if (m_maxFrame > 1.0f && pev->framerate != 0.0f)
|
||||
{
|
||||
pev->nextthink = gpGlobals->time + 0.1f;
|
||||
pev->nextthink = gpGlobals->time + 0.1f;
|
||||
}
|
||||
|
||||
m_lastTime = gpGlobals->time;
|
||||
|
@ -103,7 +103,7 @@ void CEnvExplosion::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE
|
||||
|
||||
vecSpot = pev->origin + Vector(0, 0, 8);
|
||||
|
||||
UTIL_TraceLine(vecSpot, vecSpot + Vector (0, 0, -40), ignore_monsters, ENT(pev), & tr);
|
||||
UTIL_TraceLine(vecSpot, vecSpot + Vector(0, 0, -40), ignore_monsters, ENT(pev), &tr);
|
||||
|
||||
// Pull out of the wall a bit
|
||||
if (tr.flFraction != 1.0f)
|
||||
@ -112,7 +112,7 @@ void CEnvExplosion::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE
|
||||
}
|
||||
|
||||
// draw decal
|
||||
if (! (pev->spawnflags & SF_ENVEXPLOSION_NODECAL))
|
||||
if (!(pev->spawnflags & SF_ENVEXPLOSION_NODECAL))
|
||||
{
|
||||
if (RANDOM_FLOAT(0, 1) < 0.5f)
|
||||
{
|
||||
|
@ -94,9 +94,9 @@ void CBreakable::Spawn()
|
||||
Precache();
|
||||
|
||||
if (pev->spawnflags & SF_BREAK_TRIGGER_ONLY)
|
||||
pev->takedamage = DAMAGE_NO;
|
||||
pev->takedamage = DAMAGE_NO;
|
||||
else
|
||||
pev->takedamage = DAMAGE_YES;
|
||||
pev->takedamage = DAMAGE_YES;
|
||||
|
||||
m_flHealth = pev->health;
|
||||
pev->solid = SOLID_BSP;
|
||||
@ -541,26 +541,25 @@ void CBreakable::TraceAttack(entvars_t *pevAttacker, float flDamage, Vector vecD
|
||||
{
|
||||
switch (m_Material)
|
||||
{
|
||||
case matComputer:
|
||||
case matComputer:
|
||||
{
|
||||
UTIL_Sparks(ptr->vecEndPos);
|
||||
|
||||
//random volume range
|
||||
float flVolume = RANDOM_FLOAT(0.7 , 1.0);
|
||||
switch (RANDOM_LONG(0, 1))
|
||||
{
|
||||
UTIL_Sparks(ptr->vecEndPos);
|
||||
|
||||
//random volume range
|
||||
float flVolume = RANDOM_FLOAT(0.7 , 1.0);
|
||||
switch (RANDOM_LONG(0, 1))
|
||||
{
|
||||
case 0: EMIT_SOUND(ENT(pev), CHAN_VOICE, "buttons/spark5.wav", flVolume, ATTN_NORM); break;
|
||||
case 1: EMIT_SOUND(ENT(pev), CHAN_VOICE, "buttons/spark6.wav", flVolume, ATTN_NORM); break;
|
||||
}
|
||||
|
||||
break;
|
||||
case 0: EMIT_SOUND(ENT(pev), CHAN_VOICE, "buttons/spark5.wav", flVolume, ATTN_NORM); break;
|
||||
case 1: EMIT_SOUND(ENT(pev), CHAN_VOICE, "buttons/spark6.wav", flVolume, ATTN_NORM); break;
|
||||
}
|
||||
|
||||
case matUnbreakableGlass:
|
||||
{
|
||||
UTIL_Ricochet(ptr->vecEndPos, RANDOM_FLOAT(0.5, 1.5));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case matUnbreakableGlass:
|
||||
{
|
||||
UTIL_Ricochet(ptr->vecEndPos, RANDOM_FLOAT(0.5, 1.5));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,7 +57,7 @@ enum HostageChatterType
|
||||
HOSTAGE_CHATTER_PLEASE_RESCUE_ME,
|
||||
HOSTAGE_CHATTER_SEE_RESCUE_ZONE,
|
||||
HOSTAGE_CHATTER_IMPATIENT_FOR_RESCUE,
|
||||
HOSTAGE_CHATTER_CTS_WIN ,
|
||||
HOSTAGE_CHATTER_CTS_WIN,
|
||||
HOSTAGE_CHATTER_TERRORISTS_WIN,
|
||||
HOSTAGE_CHATTER_RESCUED,
|
||||
HOSTAGE_CHATTER_WARN_NEARBY,
|
||||
|
@ -155,7 +155,7 @@ void CHostageImprov::MoveTowards(const Vector &pos, float deltaT)
|
||||
Vector stepAhead = GetFeet() + farLookAheadRange * aheadRay;
|
||||
stepAhead.z += HumanHeight;
|
||||
|
||||
if (GetSimpleGroundHeightWithFloor(&stepAhead, &ground, &normal ))
|
||||
if (GetSimpleGroundHeightWithFloor(&stepAhead, &ground, &normal))
|
||||
{
|
||||
if (normal.z > 0.9f)
|
||||
jumped = DiscontinuityJump(ground, HOSTAGE_ONLY_JUMP_DOWN);
|
||||
|
@ -247,7 +247,7 @@ BOOL CItemBattery::MyTouch(CBasePlayer *pPlayer)
|
||||
pct--;
|
||||
|
||||
char szcharge[64];
|
||||
Q_sprintf(szcharge,"!HEV_%1dP", pct);
|
||||
Q_sprintf(szcharge, "!HEV_%1dP", pct);
|
||||
pPlayer->SetSuitUpdate(szcharge, SUIT_SENTENCE, SUIT_NEXT_IN_30SEC);
|
||||
|
||||
return TRUE;
|
||||
|
@ -262,7 +262,7 @@ CPathTrack *CPathTrack::LookAhead(Vector *origin, float dist, int move)
|
||||
Vector dir = pcurrent->GetNext()->pev->origin - currentPos;
|
||||
float_precision length = dir.Length();
|
||||
|
||||
if (!length && !ValidPath(pcurrent->GetNext()->GetNext(), move))
|
||||
if (!length && !ValidPath(pcurrent->GetNext()->GetNext(), move))
|
||||
{
|
||||
// HACK: up against a dead end
|
||||
if (dist == originalDist)
|
||||
|
@ -474,7 +474,7 @@ void CFuncPlatRot::SetupRotation()
|
||||
if (m_vecFinalAngle.x != 0)
|
||||
{
|
||||
CBaseToggle::AxisDir(pev);
|
||||
m_start = pev->angles;
|
||||
m_start = pev->angles;
|
||||
m_end = pev->angles + pev->movedir * m_vecFinalAngle.x;
|
||||
}
|
||||
else
|
||||
@ -1328,9 +1328,15 @@ BOOL CFuncTrackTrain::OnControls(entvars_t *pevTest)
|
||||
local.y = -DotProduct(offset, gpGlobals->v_right);
|
||||
local.z = DotProduct(offset, gpGlobals->v_up);
|
||||
|
||||
if (local.x >= m_controlMins.x && local.y >= m_controlMins.y && local.z >= m_controlMins.z &&
|
||||
local.x <= m_controlMaxs.x && local.y <= m_controlMaxs.y && local.z <= m_controlMaxs.z)
|
||||
if (local.x >= m_controlMins.x
|
||||
&& local.y >= m_controlMins.y
|
||||
&& local.z >= m_controlMins.z
|
||||
&& local.x <= m_controlMaxs.x
|
||||
&& local.y <= m_controlMaxs.y
|
||||
&& local.z <= m_controlMaxs.z)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
@ -1718,8 +1724,9 @@ TRAIN_CODE CFuncTrackChange::EvaluateTrain(CPathTrack *pcurrent)
|
||||
if (!pcurrent || !m_train)
|
||||
return TRAIN_SAFE;
|
||||
|
||||
if (m_train->m_ppath == pcurrent || (pcurrent->m_pprevious && m_train->m_ppath == pcurrent->m_pprevious) ||
|
||||
(pcurrent->m_pnext && m_train->m_ppath == pcurrent->m_pnext))
|
||||
if (m_train->m_ppath == pcurrent
|
||||
|| (pcurrent->m_pprevious && m_train->m_ppath == pcurrent->m_pprevious)
|
||||
|| (pcurrent->m_pnext && m_train->m_ppath == pcurrent->m_pnext))
|
||||
{
|
||||
if (m_train->pev->speed != 0)
|
||||
return TRAIN_BLOCKING;
|
||||
|
@ -110,7 +110,7 @@ const char *GetCSModelName(int item_id)
|
||||
case WEAPON_SCOUT: modelName = "models/w_scout.mdl"; break;
|
||||
case WEAPON_HEGRENADE: modelName = "models/w_hegrenade.mdl"; break;
|
||||
case WEAPON_XM1014: modelName = "models/w_xm1014.mdl"; break;
|
||||
case WEAPON_C4: modelName = "models/w_backpack.mdl"; break;
|
||||
case WEAPON_C4: modelName = "models/w_backpack.mdl"; break;
|
||||
case WEAPON_MAC10: modelName = "models/w_mac10.mdl"; break;
|
||||
case WEAPON_AUG: modelName = "models/w_aug.mdl"; break;
|
||||
case WEAPON_SMOKEGRENADE: modelName = "models/w_smokegrenade.mdl"; break;
|
||||
@ -547,7 +547,7 @@ bool CBasePlayer::IsHittingShield(Vector &vecDirection, TraceResult *ptr)
|
||||
return false;
|
||||
|
||||
if (ptr->iHitgroup == HITGROUP_SHIELD)
|
||||
return true;
|
||||
return true;
|
||||
|
||||
if (m_bShieldDrawn)
|
||||
UTIL_MakeVectors(pev->angles);
|
||||
@ -1228,7 +1228,7 @@ BOOL EXT_FUNC CBasePlayer::__API_HOOK(TakeDamage)(entvars_t *pevInflictor, entva
|
||||
return bTookDamage;
|
||||
}
|
||||
|
||||
void packPlayerItem(CBasePlayer *pPlayer, CBasePlayerItem *pItem, bool packAmmo)
|
||||
void PackPlayerItem(CBasePlayer *pPlayer, CBasePlayerItem *pItem, bool packAmmo)
|
||||
{
|
||||
if (!pItem)
|
||||
return;
|
||||
@ -1260,7 +1260,7 @@ void packPlayerItem(CBasePlayer *pPlayer, CBasePlayerItem *pItem, bool packAmmo)
|
||||
}
|
||||
|
||||
#ifdef REGAMEDLL_ADD
|
||||
void packPlayerNade(CBasePlayer *pPlayer, CBasePlayerItem *pItem, bool packAmmo)
|
||||
void PackPlayerNade(CBasePlayer *pPlayer, CBasePlayerItem *pItem, bool packAmmo)
|
||||
{
|
||||
if (!pItem)
|
||||
return;
|
||||
@ -1282,16 +1282,9 @@ void packPlayerNade(CBasePlayer *pPlayer, CBasePlayerItem *pItem, bool packAmmo)
|
||||
break;
|
||||
}
|
||||
|
||||
auto& ammoNades = pPlayer->m_rgAmmo[pItem->PrimaryAmmoIndex()];
|
||||
if (pItem->m_flStartThrow != 0)
|
||||
{
|
||||
if (ammoNades < 2)
|
||||
return;
|
||||
|
||||
ammoNades--;
|
||||
}
|
||||
else if (pItem->m_flReleaseThrow > 0 && ammoNades < 1)
|
||||
if ((pPlayer->pev->button & IN_ATTACK) && pPlayer->m_rgAmmo[pItem->PrimaryAmmoIndex()] <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
Vector vecAngles = pPlayer->pev->angles;
|
||||
Vector dir(Q_cos(vecAngles.y) * flOffset, Q_sin(vecAngles.y) * flOffset, 0.0f);
|
||||
@ -1367,19 +1360,19 @@ void CBasePlayer::PackDeadPlayerItems()
|
||||
else if (pPlayerItem->iItemSlot() == GRENADE_SLOT)
|
||||
{
|
||||
if (AreRunningCZero())
|
||||
packPlayerItem(this, pPlayerItem, true);
|
||||
PackPlayerItem(this, pPlayerItem, true);
|
||||
#ifdef REGAMEDLL_ADD
|
||||
else
|
||||
{
|
||||
switch ((int)nadedrops.value)
|
||||
{
|
||||
case 1:
|
||||
packPlayerNade(this, pPlayerItem, true);
|
||||
PackPlayerNade(this, pPlayerItem, true);
|
||||
break;
|
||||
case 2:
|
||||
{
|
||||
CBasePlayerItem *pNext = pPlayerItem->m_pNext;
|
||||
packPlayerNade(this, pPlayerItem, true);
|
||||
PackPlayerNade(this, pPlayerItem, true);
|
||||
pPlayerItem = pNext;
|
||||
continue;
|
||||
}
|
||||
@ -1392,7 +1385,7 @@ void CBasePlayer::PackDeadPlayerItems()
|
||||
}
|
||||
}
|
||||
|
||||
packPlayerItem(this, pBestItem, bPackAmmo);
|
||||
PackPlayerItem(this, pBestItem, bPackAmmo);
|
||||
}
|
||||
|
||||
RemoveAllItems(TRUE);
|
||||
@ -1950,6 +1943,10 @@ void EXT_FUNC CBasePlayer::__API_HOOK(Killed)(entvars_t *pevAttacker, int iGib)
|
||||
if ((pev->button & IN_ATTACK) && m_rgAmmo[pHEGrenade->m_iPrimaryAmmoType])
|
||||
{
|
||||
CGrenade::ShootTimed2(pev, (pev->origin + pev->view_ofs), pev->angles, 1.5, m_iTeam, pHEGrenade->m_usCreateExplosion);
|
||||
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
m_rgAmmo[m_pActiveItem->PrimaryAmmoIndex()]--;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1958,6 +1955,10 @@ void EXT_FUNC CBasePlayer::__API_HOOK(Killed)(entvars_t *pevAttacker, int iGib)
|
||||
if ((pev->button & IN_ATTACK) && m_rgAmmo[((CBasePlayerWeapon *)m_pActiveItem)->m_iPrimaryAmmoType])
|
||||
{
|
||||
CGrenade::ShootTimed(pev, (pev->origin + pev->view_ofs), pev->angles, 1.5);
|
||||
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
m_rgAmmo[m_pActiveItem->PrimaryAmmoIndex()]--;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1967,6 +1968,10 @@ void EXT_FUNC CBasePlayer::__API_HOOK(Killed)(entvars_t *pevAttacker, int iGib)
|
||||
if ((pev->button & IN_ATTACK) && m_rgAmmo[pSmoke->m_iPrimaryAmmoType])
|
||||
{
|
||||
CGrenade::ShootSmokeGrenade(pev, (pev->origin + pev->view_ofs), pev->angles, 1.5, pSmoke->m_usCreateSmoke);
|
||||
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
m_rgAmmo[m_pActiveItem->PrimaryAmmoIndex()]--;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1997,7 +2002,9 @@ void EXT_FUNC CBasePlayer::__API_HOOK(Killed)(entvars_t *pevAttacker, int iGib)
|
||||
MESSAGE_END();
|
||||
}
|
||||
else
|
||||
{
|
||||
UTIL_ScreenFade(this, Vector(0, 0, 0), 3, 3, 255, (FFADE_OUT | FFADE_STAYOUT));
|
||||
}
|
||||
|
||||
SetScoreboardAttributes();
|
||||
|
||||
@ -2056,7 +2063,12 @@ void EXT_FUNC CBasePlayer::__API_HOOK(Killed)(entvars_t *pevAttacker, int iGib)
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
pev->angles.y = UTIL_VecToAngles(pev->velocity).y;
|
||||
#else
|
||||
pev->angles.y = UTIL_VecToAngles(-pev->velocity).y;
|
||||
#endif
|
||||
|
||||
pev->v_angle.y = pev->angles.y;
|
||||
|
||||
m_iThrowDirection = THROW_NONE;
|
||||
@ -4728,6 +4740,7 @@ void EXT_FUNC CBasePlayer::__API_HOOK(PostThink)()
|
||||
// NOTE: play on item channel because we play footstep landing on body channel
|
||||
EMIT_SOUND(ENT(pev), CHAN_ITEM, "common/bodysplat.wav", VOL_NORM, ATTN_NORM);
|
||||
}
|
||||
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
if (flFallDamage >= 1.0f)
|
||||
#else
|
||||
|
@ -939,7 +939,6 @@ Vector VecVelocityForDamage(float flDamage);
|
||||
int TrainSpeed(int iSpeed, int iMax);
|
||||
const char *GetWeaponName(entvars_t *pevInflictor, entvars_t *pKiller);
|
||||
void LogAttack(CBasePlayer *pAttacker, CBasePlayer *pVictim, int teamAttack, int healthHit, int armorHit, int newHealth, int newArmor, const char *killer_weapon_name);
|
||||
void packPlayerItem(CBasePlayer *pPlayer, CBasePlayerItem *pItem, bool packAmmo);
|
||||
bool CanSeeUseable(CBasePlayer *me, CBaseEntity *entity);
|
||||
void FixPlayerCrouchStuck(edict_t *pPlayer);
|
||||
BOOL IsSpawnPointValid(CBaseEntity *pPlayer, CBaseEntity *pSpot);
|
||||
|
@ -148,7 +148,7 @@ edict_t *CHalfLifeRules::GetPlayerSpawnSpot(CBasePlayer *pPlayer)
|
||||
}
|
||||
|
||||
pPlayer->pev->origin = pSpot->pev->origin + Vector(0, 0, 1);
|
||||
pPlayer->pev->v_angle = g_vecZero;
|
||||
pPlayer->pev->v_angle = g_vecZero;
|
||||
pPlayer->pev->velocity = g_vecZero;
|
||||
pPlayer->pev->angles = pSpot->pev->angles;
|
||||
pPlayer->pev->punchangle = g_vecZero;
|
||||
|
@ -15,7 +15,7 @@ NOXREF float GetSkillCvar(char *pName)
|
||||
|
||||
if (flValue <= 0.0f)
|
||||
{
|
||||
ALERT(at_console, "\n\n** GetSkillCVar Got a zero for %s **\n\n",szBuffer);
|
||||
ALERT(at_console, "\n\n** GetSkillCVar Got a zero for %s **\n\n", szBuffer);
|
||||
}
|
||||
|
||||
return flValue;
|
||||
|
@ -1788,7 +1788,7 @@ float TEXTURETYPE_PlaySound(TraceResult *ptr, Vector vecSrc, Vector vecEnd, int
|
||||
{
|
||||
UTIL_Sparks(ptr->vecEndPos);
|
||||
|
||||
//random volume range
|
||||
// random volume range
|
||||
float flVolume = RANDOM_FLOAT(0.7 , 1.0);
|
||||
|
||||
switch (RANDOM_LONG(0, 1))
|
||||
|
@ -1127,8 +1127,8 @@ public:
|
||||
void EXPORT Smack();
|
||||
|
||||
void WeaponAnimation(int iAnimation);
|
||||
int Stab(int fFirst);
|
||||
int Swing(int fFirst);
|
||||
BOOL Stab(BOOL fFirst);
|
||||
BOOL Swing(BOOL fFirst);
|
||||
|
||||
public:
|
||||
bool ShieldSecondaryFire(int iUpAnim, int iDownAnim);
|
||||
|
@ -248,9 +248,9 @@ void CKnife::WeaponIdle()
|
||||
SendWeaponAnim(KNIFE_IDLE, UseDecrement() != FALSE);
|
||||
}
|
||||
|
||||
int CKnife::Swing(int fFirst)
|
||||
BOOL CKnife::Swing(BOOL fFirst)
|
||||
{
|
||||
int fDidHit = FALSE;
|
||||
BOOL fDidHit = FALSE;
|
||||
TraceResult tr;
|
||||
Vector vecSrc, vecEnd;
|
||||
|
||||
@ -422,9 +422,9 @@ int CKnife::Swing(int fFirst)
|
||||
return fDidHit;
|
||||
}
|
||||
|
||||
int CKnife::Stab(int fFirst)
|
||||
BOOL CKnife::Stab(BOOL fFirst)
|
||||
{
|
||||
int fDidHit = FALSE;
|
||||
BOOL fDidHit = FALSE;
|
||||
TraceResult tr;
|
||||
Vector vecSrc, vecEnd;
|
||||
|
||||
|
@ -69,6 +69,7 @@ enum NavAttributeType
|
||||
NAV_JUMP = 0x02, // must jump to traverse this area
|
||||
NAV_PRECISE = 0x04, // do not adjust for obstacles, just move along area
|
||||
NAV_NO_JUMP = 0x08, // inhibit discontinuity jumping
|
||||
NAV_WALK = 0x10, // must not run through this area
|
||||
};
|
||||
|
||||
enum NavDirType
|
||||
|
@ -2338,6 +2338,7 @@ void CNavArea::Draw(byte red, byte green, byte blue, int duration)
|
||||
UTIL_DrawBeamPoints(nw, se, duration, red, green, blue);
|
||||
UTIL_DrawBeamPoints(ne, sw, duration, red, green, blue);
|
||||
}
|
||||
|
||||
if (GetAttributes() & NAV_PRECISE)
|
||||
{
|
||||
float size = 8.0f;
|
||||
@ -2349,6 +2350,7 @@ void CNavArea::Draw(byte red, byte green, byte blue, int duration)
|
||||
Vector right(m_center.x + size, m_center.y, m_center.z + cv_bot_nav_zdraw.value);
|
||||
UTIL_DrawBeamPoints(left, right, duration, red, green, blue);
|
||||
}
|
||||
|
||||
if (GetAttributes() & NAV_NO_JUMP)
|
||||
{
|
||||
float size = 8.0f;
|
||||
@ -2361,6 +2363,19 @@ void CNavArea::Draw(byte red, byte green, byte blue, int duration)
|
||||
UTIL_DrawBeamPoints(down, left, duration, red, green, blue);
|
||||
UTIL_DrawBeamPoints(left, up, duration, red, green, blue);
|
||||
}
|
||||
|
||||
if (GetAttributes() & NAV_WALK)
|
||||
{
|
||||
float size = 8.0f;
|
||||
Vector up(m_center.x - size, m_center.y - size, m_center.z + cv_bot_nav_zdraw.value);
|
||||
Vector down(m_center.x + size, m_center.y + size, m_center.z + cv_bot_nav_zdraw.value);
|
||||
Vector left(m_center.x - size, m_center.y + size, m_center.z + cv_bot_nav_zdraw.value);
|
||||
Vector right(m_center.x + size, m_center.y - size, m_center.z + cv_bot_nav_zdraw.value);
|
||||
UTIL_DrawBeamPoints(up, right, duration, red, green, blue);
|
||||
UTIL_DrawBeamPoints(right, down, duration, red, green, blue);
|
||||
UTIL_DrawBeamPoints(down, left, duration, red, green, blue);
|
||||
UTIL_DrawBeamPoints(left, up, duration, red, green, blue);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw selected corner for debugging
|
||||
@ -3826,11 +3841,12 @@ void EditNavAreas(NavEditCmdType cmd)
|
||||
}
|
||||
else
|
||||
{
|
||||
Q_sprintf(attrib, "%s%s%s%s",
|
||||
Q_sprintf(attrib, "%s%s%s%s%s",
|
||||
(area->GetAttributes() & NAV_CROUCH) ? "CROUCH " : "",
|
||||
(area->GetAttributes() & NAV_JUMP) ? "JUMP " : "",
|
||||
(area->GetAttributes() & NAV_PRECISE) ? "PRECISE " : "",
|
||||
(area->GetAttributes() & NAV_NO_JUMP) ? "NO_JUMP " : "");
|
||||
(area->GetAttributes() & NAV_NO_JUMP) ? "NO_JUMP " : "",
|
||||
(area->GetAttributes() & NAV_WALK) ? "WALK " : "");
|
||||
}
|
||||
|
||||
Q_sprintf(buffer, "Area #%d %s %s\n", area->GetID(), locName, attrib);
|
||||
@ -3853,36 +3869,36 @@ void EditNavAreas(NavEditCmdType cmd)
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case EDIT_TOGGLE_PLACE_MODE:
|
||||
EMIT_SOUND_DYN(ENT(pLocalPlayer->pev), CHAN_ITEM, "buttons/blip1.wav", 1, ATTN_NORM, 0, 100);
|
||||
isPlaceMode = false;
|
||||
return;
|
||||
case EDIT_TOGGLE_PLACE_MODE:
|
||||
EMIT_SOUND_DYN(ENT(pLocalPlayer->pev), CHAN_ITEM, "buttons/blip1.wav", 1, ATTN_NORM, 0, 100);
|
||||
isPlaceMode = false;
|
||||
return;
|
||||
|
||||
case EDIT_TOGGLE_PLACE_PAINTING:
|
||||
case EDIT_TOGGLE_PLACE_PAINTING:
|
||||
{
|
||||
if (isPlacePainting)
|
||||
{
|
||||
if (isPlacePainting)
|
||||
{
|
||||
isPlacePainting = false;
|
||||
EMIT_SOUND_DYN(ENT(pLocalPlayer->pev), CHAN_ITEM, "buttons/latchunlocked2.wav", 1, ATTN_NORM, 0, 100);
|
||||
}
|
||||
else
|
||||
{
|
||||
isPlacePainting = true;
|
||||
EMIT_SOUND_DYN(ENT(pLocalPlayer->pev), CHAN_ITEM, "buttons/lightswitch2.wav", 1, ATTN_NORM, 0, 100);
|
||||
|
||||
// paint the initial area
|
||||
area->SetPlace(TheCSBots()->GetNavPlace());
|
||||
}
|
||||
break;
|
||||
isPlacePainting = false;
|
||||
EMIT_SOUND_DYN(ENT(pLocalPlayer->pev), CHAN_ITEM, "buttons/latchunlocked2.wav", 1, ATTN_NORM, 0, 100);
|
||||
}
|
||||
case EDIT_PLACE_PICK:
|
||||
EMIT_SOUND_DYN(ENT(pLocalPlayer->pev), CHAN_ITEM, "buttons/blip1.wav", 1, ATTN_NORM, 0, 100);
|
||||
TheCSBots()->SetNavPlace(area->GetPlace());
|
||||
break;
|
||||
case EDIT_PLACE_FLOODFILL:
|
||||
PlaceFloodFillFunctor pff(area);
|
||||
SearchSurroundingAreas(area, area->GetCenter(), pff);
|
||||
break;
|
||||
else
|
||||
{
|
||||
isPlacePainting = true;
|
||||
EMIT_SOUND_DYN(ENT(pLocalPlayer->pev), CHAN_ITEM, "buttons/lightswitch2.wav", 1, ATTN_NORM, 0, 100);
|
||||
|
||||
// paint the initial area
|
||||
area->SetPlace(TheCSBots()->GetNavPlace());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EDIT_PLACE_PICK:
|
||||
EMIT_SOUND_DYN(ENT(pLocalPlayer->pev), CHAN_ITEM, "buttons/blip1.wav", 1, ATTN_NORM, 0, 100);
|
||||
TheCSBots()->SetNavPlace(area->GetPlace());
|
||||
break;
|
||||
case EDIT_PLACE_FLOODFILL:
|
||||
PlaceFloodFillFunctor pff(area);
|
||||
SearchSurroundingAreas(area, area->GetCenter(), pff);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else // normal editing mode
|
||||
@ -3974,6 +3990,10 @@ void EditNavAreas(NavEditCmdType cmd)
|
||||
EMIT_SOUND_DYN(ENT(pLocalPlayer->pev), CHAN_ITEM, "buttons/bell1.wav", 1, ATTN_NORM, 0, 100);
|
||||
area->SetAttributes(area->GetAttributes() ^ NAV_PRECISE);
|
||||
break;
|
||||
case EDIT_ATTRIB_WALK:
|
||||
EMIT_SOUND_DYN(ENT(UTIL_GetLocalPlayer()->pev), CHAN_ITEM, "buttons/bell1.wav", 1, ATTN_NORM, 0, 100);
|
||||
area->SetAttributes(area->GetAttributes() ^ NAV_WALK);
|
||||
break;
|
||||
case EDIT_ATTRIB_NO_JUMP:
|
||||
EMIT_SOUND_DYN(ENT(pLocalPlayer->pev), CHAN_ITEM, "buttons/bell1.wav", 1, ATTN_NORM, 0, 100);
|
||||
area->SetAttributes(area->GetAttributes() ^ NAV_NO_JUMP);
|
||||
|
@ -50,6 +50,7 @@ enum NavEditCmdType
|
||||
EDIT_ATTRIB_CROUCH, // toggle crouch attribute on current area
|
||||
EDIT_ATTRIB_JUMP, // toggle jump attribute on current area
|
||||
EDIT_ATTRIB_PRECISE, // toggle precise attribute on current area
|
||||
EDIT_ATTRIB_WALK, // toggle walk attribute on current area
|
||||
EDIT_ATTRIB_NO_JUMP, // toggle inhibiting discontinuity jumping in current area
|
||||
EDIT_BEGIN_AREA, // begin creating a new nav area
|
||||
EDIT_END_AREA, // end creation of the new nav area
|
||||
|
@ -130,12 +130,13 @@ void CNavArea::Save(FILE *fp) const
|
||||
fprintf(fp, "v %f %f %f\n", m_extent.lo.x, m_extent.hi.y, m_swZ);
|
||||
|
||||
static int base = 1;
|
||||
fprintf(fp, "\n\ng %04dArea%s%s%s%s\n", m_id,
|
||||
fprintf(fp, "\n\ng %04dArea%s%s%s%s%s\n", m_id,
|
||||
(GetAttributes() & NAV_CROUCH) ? "CROUCH" : "", (GetAttributes() & NAV_JUMP) ? "JUMP" : "",
|
||||
(GetAttributes() & NAV_PRECISE) ? "PRECISE" : "", (GetAttributes() & NAV_NO_JUMP) ? "NO_JUMP" : "");
|
||||
(GetAttributes() & NAV_PRECISE) ? "PRECISE" : "", (GetAttributes() & NAV_NO_JUMP) ? "NO_JUMP" : "",
|
||||
(GetAttributes() & NAV_WALK) ? "NAV_WALK" : "");
|
||||
|
||||
fprintf(fp, "f %d %d %d %d\n\n", base, base + 1, base + 2, base + 3);
|
||||
base += 4;
|
||||
fprintf(fp, "f %d %d %d %d %d\n\n", base, base + 1, base + 2, base + 3, base + 4);
|
||||
base += 5;
|
||||
}
|
||||
|
||||
void CNavArea::Save(int fd, unsigned int version)
|
||||
|
Loading…
Reference in New Issue
Block a user