AI: add ai_debugNav, and ai_debugLogic cvars. Add cooldown timer for targets
This commit is contained in:
parent
3bbeea3343
commit
bd7cb44784
6 changed files with 125 additions and 33 deletions
|
@ -14,6 +14,15 @@
|
|||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
var bool autocvar_ai_debugLogic = false;
|
||||
void
|
||||
_NSMonster_Log(string msg)
|
||||
{
|
||||
if (autocvar_ai_debugLogic == true)
|
||||
print(sprintf("%f %s\n", time, msg));
|
||||
}
|
||||
#define NSMonster_Log(...) _NSMonster_Log(sprintf(__VA_ARGS__))
|
||||
|
||||
/**
|
||||
Bitfield enumeration for NSMonster its SendFlags field.
|
||||
|
||||
|
@ -32,7 +41,7 @@ typedef enumflags
|
|||
MONFL_CHANGED_FLAGS,
|
||||
MONFL_CHANGED_SOLID,
|
||||
MONFL_CHANGED_FRAME,
|
||||
MONFL_CHANGED_SKIN,
|
||||
MONFL_CHANGED_SKINHEALTH,
|
||||
MONFL_CHANGED_MOVETYPE,
|
||||
MONFL_CHANGED_EFFECTS,
|
||||
MONFL_CHANGED_BODY,
|
||||
|
@ -261,6 +270,9 @@ private:
|
|||
/* animation cycles */
|
||||
float m_flAnimTime;
|
||||
|
||||
/* timer for keeping track of the target */
|
||||
float m_flTrackingTime;
|
||||
|
||||
PREDICTED_VECTOR_N(view_ofs)
|
||||
|
||||
nonvirtual void _LerpTurnToEnemy(float);
|
||||
|
|
|
@ -23,6 +23,33 @@ NSMonster::NSMonster(void)
|
|||
remove(this);
|
||||
return;
|
||||
}
|
||||
|
||||
m_ssLast = __NULL__;
|
||||
oldnet_velocity = g_vec_null;
|
||||
m_flPitch = 1.0f;
|
||||
m_iFlags = 0i;
|
||||
base_mins = g_vec_null;
|
||||
base_maxs = g_vec_null;
|
||||
base_health = 100;
|
||||
m_strRouteEnded = __NULL__;
|
||||
m_iSequenceRemove = 0i;
|
||||
m_iSequenceState = 0i;
|
||||
m_flSequenceEnd = 0.0f;
|
||||
m_flSequenceSpeed = 0.0f;
|
||||
m_vecSequenceAngle = g_vec_null;
|
||||
m_iSequenceFlags = 0i;
|
||||
m_iMoveState = 0i;
|
||||
m_iTriggerCondition = 0i;
|
||||
m_strTriggerTarget = __NULL__;
|
||||
m_flBaseTime = 0.0f;
|
||||
m_eEnemy = __NULL__;
|
||||
m_flAttackThink = 0.0f;
|
||||
m_iMState = 0i;
|
||||
m_iOldMState = 0i;
|
||||
m_vecLKPos = g_vec_null;
|
||||
m_flSeeTime = 0.0f;
|
||||
m_flAnimTime = 0.0f;
|
||||
m_flTrackingTime = 0.0f;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -266,7 +293,7 @@ NSMonster::AlertNearby(void)
|
|||
if (vlen(origin - w.origin) > 512)
|
||||
continue;
|
||||
|
||||
//NSLog("Alert! %s get %s", w.classname, m_eEnemy.classname);
|
||||
//NSMonster_Log("Alert! %s get %s", w.classname, m_eEnemy.classname);
|
||||
NSMonster f = (NSMonster)w;
|
||||
|
||||
/* we shouldn't override this when they already got a target */
|
||||
|
@ -302,15 +329,42 @@ NSMonster::IsValidEnemy(entity enny)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static bool
|
||||
NSMonster_TraceAgainsTarget(NSMonster monster, NSEntity target)
|
||||
{
|
||||
traceline(monster.GetEyePos(), target.GetOrigin(), MOVE_NORMAL, monster);
|
||||
|
||||
/* we have line of sight with the player */
|
||||
if (trace_fraction == 1.0f || trace_ent == target) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
NSMonster::SeeThink(void)
|
||||
{
|
||||
if (m_flAttackThink < time)
|
||||
if (m_eEnemy) {
|
||||
/* check if we should invalidate current enemy */
|
||||
if (IsValidEnemy(m_eEnemy))
|
||||
if (IsValidEnemy(m_eEnemy)) {
|
||||
/* only update 1/4th of a second */
|
||||
if (m_flSeeTime > time)
|
||||
return;
|
||||
|
||||
m_flSeeTime = time + 0.25f;
|
||||
|
||||
/* see if we can trace our target, if yes, update our timestamp */
|
||||
if (NSMonster_TraceAgainsTarget(this, (NSEntity) m_eEnemy) == true) {
|
||||
m_flTrackingTime = time;
|
||||
}
|
||||
|
||||
/* if we haven't gotten a trace in 5 seconds, give up. */
|
||||
if ((m_flTrackingTime + 5.0) > time)
|
||||
return;
|
||||
}
|
||||
|
||||
/* enemy is not valid anymore, reset it, clear route and search for new enemy */
|
||||
RouteClear();
|
||||
|
||||
|
@ -350,15 +404,13 @@ NSMonster::SeeThink(void)
|
|||
if (flDot < SeeFOV()/180)
|
||||
continue;
|
||||
|
||||
traceline(GetEyePos(), w.origin, MOVE_EVERYTHING, this);
|
||||
|
||||
/* we have line of sight with the player */
|
||||
if (trace_fraction == 1.0f || trace_ent == w) {
|
||||
if (NSMonster_TraceAgainsTarget(this, (NSEntity)w) == true) {
|
||||
if (m_eEnemy != w) {
|
||||
m_eEnemy = w;
|
||||
m_flTrackingTime = time;
|
||||
AlertNearby();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -386,7 +438,10 @@ NSMonster::GetRunSpeed(void)
|
|||
void
|
||||
NSMonster::_LerpTurnToEnemy(float flSpeed)
|
||||
{
|
||||
/* only continue if we're in one of the three states. */
|
||||
if (GetState() != MONSTER_AIMING)
|
||||
if (GetState() != MONSTER_CHASING)
|
||||
if (GetState() != MONSTER_FOLLOWING)
|
||||
return;
|
||||
|
||||
if (!m_eEnemy)
|
||||
|
@ -451,7 +506,7 @@ NSMonster::AttackThink(void)
|
|||
if (GetState() == MONSTER_AIMING) {
|
||||
int m;
|
||||
|
||||
_LerpTurnToEnemy(1000);
|
||||
_LerpTurnToEnemy(30);
|
||||
|
||||
if (MeleeCondition() == TRUE)
|
||||
m = AttackMelee();
|
||||
|
@ -482,14 +537,14 @@ NSMonster::AttackRanged(void)
|
|||
void
|
||||
NSMonster::AttackDraw(void)
|
||||
{
|
||||
NSLog("^1%s::AttackDraw: Not defined!", classname);
|
||||
NSMonster_Log("^1%s::AttackDraw: Not defined!", classname);
|
||||
m_flAttackThink = time + 0.5f;
|
||||
}
|
||||
|
||||
void
|
||||
NSMonster::AttackHolster(void)
|
||||
{
|
||||
NSLog("^1%s::AttackHolster: Not defined!", classname);
|
||||
NSMonster_Log("^1%s::AttackHolster: Not defined!", classname);
|
||||
m_flAttackThink = time + 0.5f;
|
||||
}
|
||||
|
||||
|
@ -526,7 +581,7 @@ NSMonster::FreeState(void)
|
|||
if (m_iSequenceRemove) {
|
||||
Hide();
|
||||
}
|
||||
NSLog("^2%s::^3FreeState^7: (%i, %S)", classname, m_iSequenceRemove, to_trigger);
|
||||
NSMonster_Log("^2%s::^3FreeState^7: (%i, %S)", classname, m_iSequenceRemove, to_trigger);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -534,7 +589,7 @@ NSMonster::FreeStateMoved(void)
|
|||
{
|
||||
vector new_origin;
|
||||
new_origin = gettaginfo(this, 1);
|
||||
NSLog("^2%s::^3FreeStateMoved^7: moved to %v", classname, new_origin);
|
||||
NSMonster_Log("^2%s::^3FreeStateMoved^7: moved to %v", classname, new_origin);
|
||||
SetOrigin(new_origin);
|
||||
DropToFloor();
|
||||
FreeState();
|
||||
|
@ -554,13 +609,13 @@ NSMonster::RouteEnded(void)
|
|||
m_iSequenceState = SEQUENCESTATE_ENDING;
|
||||
think = (m_iSequenceFlags & SSFL_NOSCRIPTMOVE) ? FreeState : FreeStateMoved;
|
||||
nextthink = time + duration;
|
||||
NSLog("^2%s::^3CheckRoute^7: %s overriding anim for %f seconds (modelindex %d, frame %d)", \
|
||||
NSMonster_Log("^2%s::^3CheckRoute^7: %s overriding anim for %f seconds (modelindex %d, frame %d)", \
|
||||
classname, this.targetname, duration, modelindex, m_flSequenceEnd);
|
||||
} else {
|
||||
/* we still need to trigger targets */
|
||||
think = (m_iSequenceFlags & SSFL_NOSCRIPTMOVE) ? FreeState : FreeStateMoved;
|
||||
nextthink = time;
|
||||
NSLog("^2%s::^3CheckRoute^7: %s has no anim, finished sequence", \
|
||||
NSMonster_Log("^2%s::^3CheckRoute^7: %s has no anim, finished sequence", \
|
||||
classname, this.targetname);
|
||||
}
|
||||
}
|
||||
|
@ -674,7 +729,7 @@ NSMonster::IsAlive(void)
|
|||
void
|
||||
NSMonster::StateChanged(monsterState_t oldState, monsterState_t newState)
|
||||
{
|
||||
NSLog("^2%s::^3StateChanged^7: state changed from %d to %d", \
|
||||
NSMonster_Log("^2%s::^3StateChanged^7: state changed from %d to %d", \
|
||||
classname, oldState, newState);
|
||||
}
|
||||
|
||||
|
@ -823,6 +878,9 @@ NSMonster::Pain(void)
|
|||
m_eEnemy = g_dmg_eAttacker;
|
||||
|
||||
/* an alert monster will take a while to calm back down */
|
||||
if (GetState() != MONSTER_ALERT)
|
||||
if (GetState() != MONSTER_FOLLOWING)
|
||||
if (GetState() != MONSTER_CHASING)
|
||||
SetState(MONSTER_ALERT);
|
||||
|
||||
/* alert all nearby friendlies */
|
||||
|
@ -937,7 +995,8 @@ NSMonster::EvaluateEntity(void)
|
|||
EVALUATE_VECTOR(maxs, 1, MONFL_CHANGED_SIZE)
|
||||
EVALUATE_VECTOR(maxs, 2, MONFL_CHANGED_SIZE)
|
||||
EVALUATE_FIELD(frame, MONFL_CHANGED_FRAME)
|
||||
EVALUATE_FIELD(skin, MONFL_CHANGED_SKIN)
|
||||
EVALUATE_FIELD(skin, MONFL_CHANGED_SKINHEALTH)
|
||||
EVALUATE_FIELD(health, MONFL_CHANGED_SKINHEALTH)
|
||||
EVALUATE_FIELD(effects, MONFL_CHANGED_EFFECTS)
|
||||
EVALUATE_FIELD(m_iBody, MONFL_CHANGED_BODY)
|
||||
EVALUATE_FIELD(scale, MONFL_CHANGED_SCALE)
|
||||
|
@ -985,7 +1044,8 @@ NSMonster::SendEntity(entity ePEnt, float flChanged)
|
|||
SENDENTITY_COORD(maxs[1], MONFL_CHANGED_SIZE)
|
||||
SENDENTITY_COORD(maxs[2], MONFL_CHANGED_SIZE)
|
||||
SENDENTITY_BYTE(frame, MONFL_CHANGED_FRAME)
|
||||
SENDENTITY_FLOAT(skin, MONFL_CHANGED_SKIN)
|
||||
SENDENTITY_FLOAT(skin, MONFL_CHANGED_SKINHEALTH)
|
||||
SENDENTITY_FLOAT(health, MONFL_CHANGED_SKINHEALTH)
|
||||
SENDENTITY_FLOAT(effects, MONFL_CHANGED_EFFECTS)
|
||||
SENDENTITY_BYTE(m_iBody, MONFL_CHANGED_BODY)
|
||||
SENDENTITY_FLOAT(scale, MONFL_CHANGED_SCALE)
|
||||
|
@ -1060,7 +1120,8 @@ NSMonster::ReceiveEntity(float flNew, float flChanged)
|
|||
READENTITY_COORD(maxs[1], MONFL_CHANGED_SIZE)
|
||||
READENTITY_COORD(maxs[2], MONFL_CHANGED_SIZE)
|
||||
READENTITY_BYTE(frame, MONFL_CHANGED_FRAME)
|
||||
READENTITY_FLOAT(skin, MONFL_CHANGED_SKIN)
|
||||
READENTITY_FLOAT(skin, MONFL_CHANGED_SKINHEALTH)
|
||||
READENTITY_FLOAT(health, MONFL_CHANGED_SKINHEALTH)
|
||||
READENTITY_FLOAT(effects, MONFL_CHANGED_EFFECTS)
|
||||
READENTITY_BYTE(m_iBody, MONFL_CHANGED_BODY)
|
||||
READENTITY_FLOAT(scale, MONFL_CHANGED_SCALE)
|
||||
|
@ -1094,6 +1155,9 @@ NSMonster::_RenderDebugViewCone(void)
|
|||
float flDot;
|
||||
vector testOrg;
|
||||
|
||||
if (health <= 0 || solid == SOLID_CORPSE)
|
||||
return;
|
||||
|
||||
if (autocvar(r_showViewCone, 0) == 0)
|
||||
return;
|
||||
|
||||
|
|
|
@ -14,6 +14,15 @@
|
|||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
var bool autocvar_ai_debugNav = false;
|
||||
void
|
||||
_NSNavAI_Log(string msg)
|
||||
{
|
||||
if (autocvar_ai_debugNav == true)
|
||||
print(sprintf("%f %s\n", time, msg));
|
||||
}
|
||||
#define NSNavAI_Log(...) _NSNavAI_Log(sprintf(__VA_ARGS__))
|
||||
|
||||
#ifndef MAX_AMMO_TYPES
|
||||
#define MAX_AMMO_TYPES 16
|
||||
#endif
|
||||
|
|
|
@ -107,7 +107,7 @@ NSNavAI::CheckRoute(void)
|
|||
flDist = floor(vlen(evenpos - origin));
|
||||
|
||||
if (flDist < 8) {
|
||||
NSLog("^2%s::^3CheckRoute^7: " \
|
||||
NSNavAI_Log("^2%s::^3CheckRoute^7: " \
|
||||
"%s reached node", classname, targetname);
|
||||
m_iCurNode--;
|
||||
velocity = [0,0,0]; /* clamp friction */
|
||||
|
@ -119,7 +119,7 @@ NSNavAI::CheckRoute(void)
|
|||
|
||||
/* can we walk directly to our target destination? */
|
||||
if (trace_fraction == 1.0) {
|
||||
NSLog("^2%s::^3CheckRoute^7: Walking directly to last node at '%v'", \
|
||||
NSNavAI_Log("^2%s::^3CheckRoute^7: Walking directly to last node at '%v'", \
|
||||
classname, m_vecLastNode);
|
||||
m_iCurNode = -1;
|
||||
}
|
||||
|
@ -137,7 +137,7 @@ NSNavAI::CheckRoute(void)
|
|||
if (!trace_startsolid && trace_fraction == 1.0f) {
|
||||
evenpos = vecNextNode;
|
||||
m_iCurNode = iNextNode;
|
||||
NSLog("^2%s::^3CheckRoute^7: skipping to next node %i at '%v'", \
|
||||
NSNavAI_Log("^2%s::^3CheckRoute^7: skipping to next node %i at '%v'", \
|
||||
classname, iNextNode, vecNextNode);
|
||||
}
|
||||
}
|
||||
|
@ -146,7 +146,7 @@ NSNavAI::CheckRoute(void)
|
|||
if (m_iCurNode < -1) {
|
||||
RouteClear();
|
||||
RouteEnded();
|
||||
NSLog("^2%s::^3CheckRoute^7: %s reached end", classname, targetname);
|
||||
NSNavAI_Log("^2%s::^3CheckRoute^7: %s reached end", classname, targetname);
|
||||
}
|
||||
|
||||
/* crouch attempt */
|
||||
|
@ -234,11 +234,11 @@ NSNavAI::RouteToPosition(vector destination)
|
|||
|
||||
/* can we walk directly to our target destination? */
|
||||
if (trace_fraction == 1.0) {
|
||||
NSLog("^2%s::^3RouteToPosition^7: " \
|
||||
NSNavAI_Log("^2%s::^3RouteToPosition^7: " \
|
||||
"Walking directly to last node", classname);
|
||||
p.m_iCurNode = -1;
|
||||
} else {
|
||||
NSLog("^2%s::^3RouteToPosition^7: " \
|
||||
NSNavAI_Log("^2%s::^3RouteToPosition^7: " \
|
||||
"Path obstructed, calculating route", classname);
|
||||
|
||||
/* run through all nodes, mark the closest direct path possible */
|
||||
|
|
|
@ -14,6 +14,10 @@
|
|||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef CLIENT
|
||||
noref .float health;
|
||||
#endif
|
||||
|
||||
typedef enumflags
|
||||
{
|
||||
SRFENT_CHANGED_ORIGIN_X,
|
||||
|
@ -47,6 +51,7 @@ private:
|
|||
float m_flBurnNext;
|
||||
|
||||
PREDICTED_FLOAT(armor)
|
||||
PREDICTED_FLOAT_N(health)
|
||||
|
||||
#ifdef SERVER
|
||||
/* fire/burning */
|
||||
|
|
|
@ -680,7 +680,8 @@ NSTalkMonster::SendEntity(entity ePEnt, float flChanged)
|
|||
SENDENTITY_COORD(maxs[1], MONFL_CHANGED_SIZE)
|
||||
SENDENTITY_COORD(maxs[2], MONFL_CHANGED_SIZE)
|
||||
SENDENTITY_BYTE(frame, MONFL_CHANGED_FRAME)
|
||||
SENDENTITY_FLOAT(skin, MONFL_CHANGED_SKIN)
|
||||
SENDENTITY_FLOAT(skin, MONFL_CHANGED_SKINHEALTH)
|
||||
SENDENTITY_FLOAT(health, MONFL_CHANGED_SKINHEALTH)
|
||||
SENDENTITY_FLOAT(effects, MONFL_CHANGED_EFFECTS)
|
||||
SENDENTITY_BYTE(m_iBody, MONFL_CHANGED_BODY)
|
||||
SENDENTITY_FLOAT(scale, MONFL_CHANGED_SCALE)
|
||||
|
@ -732,7 +733,7 @@ NSTalkMonster::ProcessWordQue(void)
|
|||
|
||||
SentenceSample(m_pSentenceQue[m_iSentencePos].m_strSnd);
|
||||
|
||||
NSLog("^2NSEntity::^3ProcessWordQue^7: Speaking %s", m_pSentenceQue[m_iSentencePos].m_strSnd);
|
||||
NSMonster_Log("^2NSEntity::^3ProcessWordQue^7: Speaking %s", m_pSentenceQue[m_iSentencePos].m_strSnd);
|
||||
m_iSentencePos++;
|
||||
|
||||
if (m_iSentencePos == m_iSentenceCount) {
|
||||
|
@ -856,7 +857,8 @@ NSTalkMonster::ReceiveEntity(float flNew, float flChanged)
|
|||
READENTITY_COORD(maxs[1], MONFL_CHANGED_SIZE)
|
||||
READENTITY_COORD(maxs[2], MONFL_CHANGED_SIZE)
|
||||
READENTITY_BYTE(frame, MONFL_CHANGED_FRAME)
|
||||
READENTITY_FLOAT(skin, MONFL_CHANGED_SKIN)
|
||||
READENTITY_FLOAT(skin, MONFL_CHANGED_SKINHEALTH)
|
||||
READENTITY_FLOAT(health, MONFL_CHANGED_SKINHEALTH)
|
||||
READENTITY_FLOAT(effects, MONFL_CHANGED_EFFECTS)
|
||||
READENTITY_BYTE(m_iBody, MONFL_CHANGED_BODY)
|
||||
READENTITY_FLOAT(scale, MONFL_CHANGED_SCALE)
|
||||
|
@ -899,14 +901,14 @@ NSTalkMonster_ParseSentence(void)
|
|||
|
||||
if (ent) {
|
||||
if (ent.classname != "NSTalkMonster" && ent.classname != "ambient_generic")
|
||||
NSLog("^3 NSTalkMonster_ParseSentence ^7: Entity %d not a NSTalkMonster!", e);
|
||||
NSMonster_Log("^3 NSTalkMonster_ParseSentence ^7: Entity %d not a NSTalkMonster!", e);
|
||||
else {
|
||||
targ = (NSTalkMonster)ent;
|
||||
targ.Sentence(sentence);
|
||||
NSLog("^3 NSTalkMonster_ParseSentence ^7: Entity %d saying %s", e, sentence);
|
||||
NSMonster_Log("^3 NSTalkMonster_ParseSentence ^7: Entity %d saying %s", e, sentence);
|
||||
}
|
||||
} else {
|
||||
NSLog("^3 NSTalkMonster_ParseSentence ^7: Entity %d not in PVS", e);
|
||||
NSMonster_Log("^3 NSTalkMonster_ParseSentence ^7: Entity %d not in PVS", e);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue