Improved pathfinding by skipping unnecessary node-walking passes.

This commit is contained in:
Marco Cawthorne 2020-03-30 13:51:48 +02:00
parent 8bf96e425a
commit d7fdabbd60
19 changed files with 171 additions and 86 deletions

View File

@ -102,8 +102,32 @@ class CBaseMonster:CBaseEntity
virtual void() CheckRoute;
virtual void() WalkRoute;
virtual void(vector) NewRoute;
/* animation cycles */
float m_flAnimTime;
virtual int() AnimIdle;
virtual int() AnimWalk;
virtual int() AnimRun;
};
int
CBaseMonster::AnimIdle(void)
{
return 0;
}
int
CBaseMonster::AnimWalk(void)
{
return 0;
}
int
CBaseMonster::AnimRun(void)
{
return 0;
}
void CBaseMonster::Sound(string msg)
{
sound(this, CHAN_VOICE, msg, 1.0, ATTN_NORM);
@ -280,6 +304,13 @@ void CBaseMonster::NewRoute(vector destination)
p.m_iNodes = numnodes;
p.m_iCurNode = numnodes - 1;
p.m_pRoute = nodelist;
/* we can walk there directly */
tracebox(p.origin, p.mins, p.maxs, dest, TRUE, this);
if (trace_fraction == 1.0) {
print("^2CBaseMonster::NewRoute^7: Walking directly to last node\n");
p.m_iCurNode = -1;
}
}
ClearRoute();
@ -309,6 +340,22 @@ void CBaseMonster::Physics(void)
runstandardplayerphysics(this);
movetype = MOVETYPE_NONE;
IdleNoise();
if (style != MONSTER_DEAD) {
if (m_flAnimTime > time) {
input_movevalues = [0,0,0];
} else {
float spvel = vlen(velocity);
if (spvel < 5) {
frame = AnimIdle();
} else if (spvel <= 140) {
frame = AnimWalk();
} else if (spvel <= 240) {
frame = AnimRun();
}
}
}
}
/* support for think/nextthink */
@ -322,6 +369,10 @@ void CBaseMonster::Physics(void)
void CBaseMonster::touch(void)
{
if (movetype != MOVETYPE_WALK) {
return;
}
if (other.movetype == MOVETYPE_WALK) {
velocity = normalize(other.origin - origin) * -128;
}

View File

@ -42,9 +42,6 @@ class CBaseNPC:CBaseMonster
float m_flChangePath;
float m_flTraceTime;
/* damage/combat related */
float m_flPainTime;
/* sentences identifiers */
string m_talkAnswer; /* random answer to whenever a question is asked */
string m_talkAsk; /* asks a random generic question */
@ -75,9 +72,6 @@ class CBaseNPC:CBaseMonster
virtual void() FollowPlayer;
virtual void() FollowChain;
virtual void() Physics;
virtual int() AnimIdle;
virtual int() AnimWalk;
virtual int() AnimRun;
virtual void() PlayerUse;
virtual void() PanicFrame;
virtual void() Hide;
@ -103,24 +97,6 @@ class CBaseNPC:CBaseMonster
virtual void() TalkStopFollow;
};
int
CBaseNPC::AnimIdle(void)
{
return 0;
}
int
CBaseNPC::AnimWalk(void)
{
return 0;
}
int
CBaseNPC::AnimRun(void)
{
return 0;
}
void
CBaseNPC::WarnAllies(void)
{
@ -490,7 +466,7 @@ CBaseNPC::Physics(void)
}
}
if (m_flPainTime > time) {
if (m_flAnimTime > time) {
input_movevalues = [0,0,0];
} else {
spvel = vlen(velocity);

View File

@ -186,5 +186,6 @@ monster_alien_grunt::monster_alien_grunt(void)
model = "models/agrunt.mdl";
base_mins = [-32,-32,0];
base_maxs = [32,32,64];
base_health = Skill_GetValue("agrunt_health");
CBaseMonster::CBaseMonster();
}

View File

@ -41,5 +41,6 @@ void monster_apache::monster_apache(void)
model = "models/apache.mdl";
base_mins = [-16,-16,0];
base_maxs = [16,16,72];
base_health = Skill_GetValue("apache_health");
CBaseMonster::CBaseMonster();
}

View File

@ -100,7 +100,7 @@ monster_barney::Pain(int iHitBody)
{
WarnAllies();
if (m_flPainTime > time) {
if (m_flAnimTime > time) {
return;
}
@ -113,7 +113,7 @@ monster_barney::Pain(int iHitBody)
frame = BA_FLINCH_LA + floor(random(0, 5));
m_iFlags |= MONSTER_FEAR;
m_flPainTime = time + 0.25f;
m_flAnimTime = time + 0.25f;
}
void
@ -176,7 +176,7 @@ monster_barney::monster_barney(void)
model = "models/barney.mdl";
netname = "Barney";
base_health = 50;
base_health = Skill_GetValue("barney_health");
base_mins = [-16,-16,0];
base_maxs = [16,16,72];
CBaseNPC::CBaseNPC();

View File

@ -92,7 +92,6 @@ string gon_sndstep[] = {
class monster_bigmomma:CBaseMonster
{
float m_flIdleTime;
float m_flPainTime;
void() monster_bigmomma;
@ -125,7 +124,7 @@ monster_bigmomma::Pain(int iHitBody)
{
CBaseMonster::Pain(iHitBody);
if (m_flPainTime > time) {
if (m_flAnimTime > time) {
return;
}
@ -136,7 +135,7 @@ monster_bigmomma::Pain(int iHitBody)
int rand = floor(random(0,gon_sndpain.length));
Sound(gon_sndpain[rand]);
frame = GON_FLINCH;
m_flPainTime = time + 0.25f;
m_flAnimTime = time + 0.25f;
}
void

View File

@ -94,16 +94,35 @@ string bull_sndpain[] = {
class monster_bullchicken:CBaseMonster
{
float m_flIdleTime;
float m_flPainTime;
void() monster_bullchicken;
virtual void(int) Death;
virtual void(int) Pain;
virtual void(void) IdleNoise;
virtual void(void) Respawn;
virtual void() IdleNoise;
virtual int() AnimIdle;
virtual int() AnimWalk;
virtual int() AnimRun;
};
int
monster_bullchicken::AnimIdle(void)
{
return BULL_IDLE;
}
int
monster_bullchicken::AnimWalk(void)
{
return BULL_WALK;
}
int
monster_bullchicken::AnimRun(void)
{
return BULL_RUN;
}
void
monster_bullchicken::IdleNoise(void)
{
@ -127,7 +146,7 @@ monster_bullchicken::Pain(int iHitBody)
{
CBaseMonster::Pain(iHitBody);
if (m_flPainTime > time) {
if (m_flAnimTime > time) {
return;
}
@ -138,7 +157,7 @@ monster_bullchicken::Pain(int iHitBody)
int rand = floor(random(0,bull_sndpain.length));
Sound(bull_sndpain[rand]);
frame = (random() < 0.5) ? BULL_FLINCH : BULL_FLINCH2;
m_flPainTime = time + 0.25f;
m_flAnimTime = time + 0.25f;
}
void
@ -159,13 +178,6 @@ monster_bullchicken::Death(int iHitBody)
CBaseMonster::Death(iHitBody);
}
void
monster_bullchicken::Respawn(void)
{
CBaseMonster::Respawn();
frame = BULL_IDLE;
}
void monster_bullchicken::monster_bullchicken(void)
{
for (int i = 0; i <bull_sndattack.length; i++) {

View File

@ -96,7 +96,6 @@ string garg_sndpain[] = {
class monster_gargantua:CBaseMonster
{
float m_flIdleTime;
float m_flPainTime;
void() monster_gargantua;
@ -129,7 +128,7 @@ monster_gargantua::Pain(int iHitBody)
{
CBaseMonster::Pain(iHitBody);
if (m_flPainTime > time) {
if (m_flAnimTime > time) {
return;
}
@ -140,7 +139,7 @@ monster_gargantua::Pain(int iHitBody)
int rand = floor(random(0,garg_sndpain.length));
Sound(garg_sndpain[rand]);
frame = (random() < 0.5) ? GARG_FLINCH : GARG_FLINCH2;
m_flPainTime = time + 0.25f;
m_flAnimTime = time + 0.25f;
}
void

View File

@ -40,9 +40,31 @@ enum {
class monster_gman:CBaseMonster
{
void() monster_gman;
virtual void() Respawn;
virtual int() AnimIdle;
virtual int() AnimWalk;
virtual int() AnimRun;
};
int
monster_gman::AnimIdle(void)
{
return GMAN_IDLE;
}
int
monster_gman::AnimWalk(void)
{
return GMAN_WALK;
}
int
monster_gman::AnimRun(void)
{
return GMAN_WALK;
}
void monster_gman::Respawn(void)
{
/* he can't die, he's the G-Man! */

View File

@ -81,22 +81,41 @@ string hc_sndsee[] = {
class monster_headcrab:CBaseMonster
{
float m_flIdleTime;
float m_flPainTime;
void() monster_headcrab;
virtual void(int) Pain;
virtual void(int) Death;
virtual void(void) IdleNoise;
virtual void(void) Respawn;
virtual int() AnimIdle;
virtual int() AnimWalk;
virtual int() AnimRun;
};
int
monster_headcrab::AnimIdle(void)
{
return HC_IDLE1;
}
int
monster_headcrab::AnimWalk(void)
{
return HC_WALK;
}
int
monster_headcrab::AnimRun(void)
{
return HC_RUN;
}
void
monster_headcrab::Pain(int iHitBody)
{
CBaseMonster::Pain(iHitBody);
if (m_flPainTime > time) {
if (m_flAnimTime > time) {
return;
}
@ -107,7 +126,7 @@ monster_headcrab::Pain(int iHitBody)
int rand = floor(random(0,hc_sndpain.length));
Sound(hc_sndpain[rand]);
frame = HC_FLINCH;
m_flPainTime = time + 0.25f;
m_flAnimTime = time + 0.25f;
}
void
@ -143,13 +162,6 @@ monster_headcrab::IdleNoise(void)
Sound(hc_sndidle[rand]);
}
void
monster_headcrab::Respawn(void)
{
CBaseMonster::Respawn();
frame = HC_IDLE1;
}
void
monster_headcrab::monster_headcrab(void)
{

View File

@ -95,7 +95,6 @@ string he_sndsee[] = {
class monster_houndeye:CBaseMonster
{
float m_flIdleTime;
float m_flPainTime;
void() monster_houndeye;
@ -110,7 +109,7 @@ monster_houndeye::Pain(int iHitBody)
{
CBaseMonster::Pain(iHitBody);
if (m_flPainTime > time) {
if (m_flAnimTime > time) {
return;
}
@ -121,7 +120,7 @@ monster_houndeye::Pain(int iHitBody)
int rand = floor(random(0,he_sndpain.length));
Sound(he_sndpain[rand]);
frame = HE_FLINCH + floor(random(0, 2));
m_flPainTime = time + 0.25f;
m_flAnimTime = time + 0.25f;
}
void

View File

@ -125,7 +125,6 @@ string gr_sndpain[] = {
class monster_human_grunt:CBaseNPC
{
float m_flIdleTime;
float m_flPainTime;
void() monster_human_grunt;
@ -134,9 +133,29 @@ class monster_human_grunt:CBaseNPC
virtual void() Respawn;
virtual void(int) Pain;
virtual void(int) Death;
virtual int() AnimIdle;
virtual int() AnimWalk;
virtual int() AnimRun;
};
int
monster_human_grunt::AnimIdle(void)
{
return GR_IDLE;
}
int
monster_human_grunt::AnimWalk(void)
{
return GR_WALK;
}
int
monster_human_grunt::AnimRun(void)
{
return GR_RUN;
}
void monster_human_grunt::Scream(void)
{
if (m_flIdleTime > time) {
@ -168,7 +187,7 @@ monster_human_grunt::Pain(int iHitBody)
{
CBaseMonster::Pain(iHitBody);
if (m_flPainTime > time) {
if (m_flAnimTime > time) {
return;
}
@ -179,7 +198,7 @@ monster_human_grunt::Pain(int iHitBody)
int rand = floor(random(0,gr_sndpain.length));
Sound(gr_sndpain[rand]);
frame = GR_FLINCH;
m_flPainTime = time + 0.25f;
m_flAnimTime = time + 0.25f;
}
void

View File

@ -69,7 +69,6 @@ string ichy_sndsee[] = {
class monster_ichthyosaur:CBaseMonster
{
float m_flIdleTime;
float m_flPainTime;
void() monster_ichthyosaur;
@ -84,7 +83,7 @@ monster_ichthyosaur::Pain(int iHitBody)
{
CBaseMonster::Pain(iHitBody);
if (m_flPainTime > time) {
if (m_flAnimTime > time) {
return;
}
@ -95,7 +94,7 @@ monster_ichthyosaur::Pain(int iHitBody)
int rand = floor(random(0,ichy_sndpain.length));
Sound(ichy_sndpain[rand]);
frame = ICHY_FLINCH + floor(random(0, 2));
m_flPainTime = time + 0.25f;
m_flAnimTime = time + 0.25f;
}
void

View File

@ -45,7 +45,6 @@ string leech_sndsee[] = {
class monster_leech:CBaseMonster
{
float m_flIdleTime;
float m_flPainTime;
void() monster_leech;

View File

@ -77,7 +77,6 @@ string nil_sndrecharge[] = {
class monster_nihilanth:CBaseMonster
{
float m_flIdleTime;
float m_flPainTime;
void() monster_nihilanth;
@ -110,7 +109,7 @@ monster_nihilanth::Pain(int iHitBody)
{
CBaseMonster::Pain(iHitBody);
if (m_flPainTime > time) {
if (m_flAnimTime > time) {
return;
}
@ -122,7 +121,7 @@ monster_nihilanth::Pain(int iHitBody)
Sound(nil_sndpain[rand]);
frame = (random() < 0.5) ? NIL_FLINCH : NIL_FLINCH2;
m_flPainTime = time + 0.25f;
m_flAnimTime = time + 0.25f;
}
void

View File

@ -133,7 +133,7 @@ monster_scientist::Pain(int iHitBody)
{
WarnAllies();
if (m_flPainTime > time) {
if (m_flAnimTime > time) {
return;
}
@ -146,7 +146,7 @@ monster_scientist::Pain(int iHitBody)
frame = SCIA_FLINCH + floor(random(0, 6));
m_iFlags |= MONSTER_FEAR;
m_flPainTime = time + 0.25f;
m_flAnimTime = time + 0.25f;
}
void
@ -228,6 +228,7 @@ monster_scientist::monster_scientist(void)
model = "models/scientist.mdl";
base_mins = [-16,-16,0];
base_maxs = [16,16,72];
base_health = Skill_GetValue("scientist_health");
/* has the body not been overriden, etc. choose a character for us */
if (body == -1) {

View File

@ -41,7 +41,6 @@ string sent_snddie[] = {
class monster_sentry:CBaseMonster
{
void() monster_sentry;
virtual void(int) Death;

View File

@ -104,7 +104,6 @@ string zo_sndsee[] = {
class monster_zombie:CBaseMonster
{
float m_flIdleTime;
float m_flPainTime;
void() monster_zombie;
@ -119,7 +118,7 @@ monster_zombie::Pain(int iHitBody)
{
CBaseMonster::Pain(iHitBody);
if (m_flPainTime > time) {
if (m_flAnimTime > time) {
return;
}
@ -130,7 +129,7 @@ monster_zombie::Pain(int iHitBody)
int rand = floor(random(0,zo_sndpain.length));
Sound(zo_sndpain[rand]);
frame = ZO_FLINCH + floor(random(0, 2));
m_flPainTime = time + 0.25f;
m_flAnimTime = time + 0.25f;
}
void

View File

@ -366,8 +366,8 @@ void Effect_BreakModel(int count, vector vMins, vector vMaxs, vector vVel, float
msg_entity = self;
vector vWorldPos;
vWorldPos[0] = vMins[0] + (0.5 * (vMaxs[0] - vMins[0]));
vWorldPos[1] = vMins[1] + (0.5 * (vMaxs[1] - vMins[1]));
vWorldPos[0] = vMins[0] + (0.5 * (vMaxs[0] - vMins[0]));
vWorldPos[1] = vMins[1] + (0.5 * (vMaxs[1] - vMins[1]));
vWorldPos[2] = vMins[2] + (0.5 * (vMaxs[2] - vMins[2]));
multicast(vWorldPos, MULTICAST_PVS);
#else
@ -376,8 +376,7 @@ void Effect_BreakModel(int count, vector vMins, vector vMaxs, vector vVel, float
float fModelCount;
vector vPos;
string sModel = "";
float fCount = 20;
switch (fStyle) {
case GSMATERIAL_GLASS:
case GSMATERIAL_GLASS_UNBREAKABLE:
@ -416,8 +415,8 @@ void Effect_BreakModel(int count, vector vMins, vector vMaxs, vector vVel, float
}
vector vWorldPos;
vWorldPos[0] = vMins[0] + (0.5 * (vMaxs[0] - vMins[0]));
vWorldPos[1] = vMins[1] + (0.5 * (vMaxs[1] - vMins[1]));
vWorldPos[0] = vMins[0] + (0.5 * (vMaxs[0] - vMins[0]));
vWorldPos[1] = vMins[1] + (0.5 * (vMaxs[1] - vMins[1]));
vWorldPos[2] = vMins[2] + (0.5 * (vMaxs[2] - vMins[2]));
switch (fStyle) {
@ -443,7 +442,7 @@ void Effect_BreakModel(int count, vector vMins, vector vMaxs, vector vVel, float
break;
}
while (fCount > 0) {
for (int i = 0; i < count; i++) {
entity eGib = spawn();
eGib.classname = "gib";
@ -466,8 +465,7 @@ void Effect_BreakModel(int count, vector vMins, vector vMaxs, vector vVel, float
if ((fStyle == GSMATERIAL_GLASS) || (fStyle == GSMATERIAL_GLASS_UNBREAKABLE)) {
eGib.effects = EF_ADDITIVE;
}
fCount--;
eGib.drawmask = MASK_ENGINE;
}
#endif