Module dpmod: Change committed
havoc at icculus.org
havoc at icculus.org
Thu Feb 20 04:04:55 EST 2003
Commiter : havoc
CVSROOT : /cvs/cvsroot/twilight
Module : dpmod
Commit time: 2003-02-20 09:04:55 UTC
Log message:
limited monster AI and creaturecode to only executing FindTarget and creaturecode and such on 200 creatures per frame
this massively sped up helm18
optimized monster AI a lot, merged functions, etc
Modified files:
qc/ai.qc qc/fight.qc qc/world.qc
------=MIME.79f9c30afa7e6234c8ee365c2c102d81
Content-Type: text/plain; name="dpmod.20030220.090455.havoc.diff"
Content-Disposition: attachment; filename="dpmod.20030220.090455.havoc.diff"
Content-Transfer-Encoding: 8bit
Index: dpmod/qc/ai.qc
diff -u dpmod/qc/ai.qc:1.1.1.1 dpmod/qc/ai.qc:1.2
--- dpmod/qc/ai.qc:1.1.1.1 Thu Sep 19 15:06:58 2002
+++ dpmod/qc/ai.qc Thu Feb 20 04:04:45 2003
@@ -260,14 +260,14 @@
*/
float(entity targ) range =
{
-local float r;
- r = vlen ((self.origin + self.view_ofs) - (targ.origin + targ.view_ofs));
+ local float r;
+ r = vlen ((self.origin + self.view_ofs) - (targ.origin + targ.view_ofs));
if (r < 120)
return RANGE_MELEE;
if (r < 500)
return RANGE_NEAR;
- if (r < 2000) // increased from 1000 for DP
- return RANGE_MID;
+ if (r < 2000) // increased from 1000 for DP
+ return RANGE_MID;
return RANGE_FAR;
};
@@ -380,8 +380,6 @@
void() HuntTarget =
{
- if (self.health < 1)
- return;
self.goalentity = self.enemy;
self.think = self.th_run;
self.ideal_yaw = vectoyaw(self.enemy.origin - self.origin);
@@ -419,13 +417,14 @@
float checkplayertime;
entity lastcheckplayer;
-.float isbot;
+entity havocbot_list;
+
entity() checkplayer =
{
local entity check;
// we can just fallback on checkclient if there are no bots
- if (!findfloat(world, isbot, TRUE))
+ if (!havocbot_list)
return checkclient();
if (time < checkplayertime)
{
@@ -468,16 +467,17 @@
slower noticing monsters.
============
*/
+.float findtarget;
float() FindTarget =
{
- local entity client;
- local float r;
+ local entity client;
+ local float r;
if (self.health < 1)
return FALSE;
- // if the first or second spawnflag bit is set, the monster will only wake
- // up onreally seeing the player, not another monster getting angry
+ // if the first or second spawnflag bit is set, the monster will only
+ // wake up on really seeing the player, not another monster getting angry
if (self.spawnflags & 3)
{
@@ -511,7 +511,7 @@
if (client.items & IT_INVISIBILITY)
return FALSE;
- r = range (client);
+ r = range(client);
if (r == RANGE_FAR)
return FALSE;
@@ -651,8 +651,9 @@
self.enemy = world;
}
- if (FindTarget ())
- return;
+ self.findtarget = TRUE;
+ //if (FindTarget ())
+ // return;
movetogoal (dist);
};
@@ -668,16 +669,32 @@
void() ai_stand =
{
if (self.health < 1)
- return;
- if (FindTarget ())
return;
-
+ if (self.enemy)
+ {
+ if (self.enemy.takedamage)
+ {
+ if (self.enemy.health >= 1)
+ {
+ FoundTarget();
+ return;
+ }
+ else
+ self.enemy = world;
+ }
+ else
+ self.enemy = world;
+ }
+ self.findtarget = TRUE;
+ //if (FindTarget ())
+ // return;
+
if (time > self.pausetime)
{
self.th_walk ();
return;
}
-
+
// change angle slightly
};
@@ -691,9 +708,25 @@
*/
void() ai_turn =
{
- if (FindTarget ())
- return;
-
+ if (self.enemy)
+ {
+ if (self.enemy.takedamage)
+ {
+ if (self.enemy.health >= 1)
+ {
+ FoundTarget();
+ return;
+ }
+ else
+ self.enemy = world;
+ }
+ else
+ self.enemy = world;
+ }
+ self.findtarget = TRUE;
+ //if (FindTarget ())
+ // return;
+
ChangeYaw ();
};
@@ -749,90 +782,11 @@
//=============================================================================
.float() th_checkattack;
-float() CheckAnyAttack =
-{
- if (self.health < 1)
- return FALSE;
- if (!enemy_vis)
- return FALSE;
- return self.th_checkattack();
-};
-/*
-=============
-ai_run_melee
-Turn and close until within an angle to launch a melee attack
-=============
-*/
-void() ai_run_melee =
-{
- if (self.health < 1)
- return;
- self.ideal_yaw = enemy_yaw;
- ChangeYaw ();
-
- if (FacingIdeal())
- {
- self.th_melee ();
- self.attack_state = AS_STRAIGHT;
- }
-};
-
-
/*
=============
-ai_run_missile
-
-Turn in place until within an angle to launch a missile attack
-=============
-*/
-void() ai_run_missile =
-{
- if (self.health < 1)
- return;
- self.ideal_yaw = enemy_yaw;
- ChangeYaw ();
- if (FacingIdeal())
- {
- if (self.th_missile ())
- self.attack_state = AS_STRAIGHT;
- }
-};
-
-
-/*
-=============
-ai_run_slide
-
-Strafe sideways, but stay at aproximately the same range
-=============
-*/
-void() ai_run_slide =
-{
- local float ofs;
-
- if (self.health < 1)
- return;
- self.ideal_yaw = enemy_yaw;
- ChangeYaw ();
- if (self.lefty)
- ofs = 90;
- else
- ofs = -90;
-
- if (walkmove (self.ideal_yaw + ofs, movedist))
- return;
-
- self.lefty = !self.lefty;
-
- walkmove (self.ideal_yaw - ofs, movedist);
-};
-
-
-/*
-=============
ai_run
The monster has an enemy it is trying to kill
@@ -840,14 +794,15 @@
*/
void(float dist) ai_run =
{
+ local float ofs;
if (self.health < 1)
return;
movedist = dist;
-// see if the enemy is dead
+ // see if the enemy is dead
if (self.enemy.health < 1 || self.enemy.takedamage == DAMAGE_NO)
{
self.enemy = world;
- // FIXME: look all around for other targets
+ // FIXME: look all around for other targets
if (self.oldenemy.health >= 1 && self.oldenemy.takedamage)
{
self.enemy = self.oldenemy;
@@ -864,47 +819,71 @@
}
}
- self.show_hostile = time + 1; // wake up other monsters
+ // wake up other monsters
+ self.show_hostile = time + 1;
-// check knowledge of enemy
- enemy_vis = visible(self.enemy);
- if (enemy_vis)
- self.search_time = time + 5;
-
-// look for other coop players
- if (coop && (self.search_time < time))
- {
- if (FindTarget ())
- return;
- }
-
- enemy_infront = infront(self.enemy);
+ // check knowledge of enemy
enemy_range = range(self.enemy);
- enemy_yaw = vectoyaw(self.enemy.origin - self.origin);
+
+ self.ideal_yaw = vectoyaw(self.enemy.origin - self.origin);
+ ChangeYaw ();
- if (self.attack_state == AS_MISSILE)
+ if (self.attack_state == AS_MELEE)
{
-//dprint ("ai_run_missile\n");
- ai_run_missile ();
+ //dprint ("ai_run_melee\n");
+ //Turn and close until within an angle to launch a melee attack
+ if (FacingIdeal())
+ {
+ self.th_melee ();
+ self.attack_state = AS_STRAIGHT;
+ }
return;
}
- if (self.attack_state == AS_MELEE)
+ else if (self.attack_state == AS_MISSILE)
{
-//dprint ("ai_run_melee\n");
- ai_run_melee ();
+ //dprint ("ai_run_missile\n");
+ //Turn in place until within an angle to launch a missile attack
+ if (FacingIdeal())
+ if (self.th_missile ())
+ self.attack_state = AS_STRAIGHT;
return;
}
- if (CheckAnyAttack ())
- return; // beginning an attack
-
+ if (visible(self.enemy))
+ {
+ self.search_time = time + 5;
+ if (self.th_checkattack())
+ return; // beginning an attack
+ }
+ else if (coop)
+ {
+ // look for other coop players
+ if (self.search_time < time)
+ {
+ self.findtarget = TRUE;
+ //if (FindTarget ())
+ // return;
+ }
+ }
+
if (self.attack_state == AS_SLIDING)
{
- ai_run_slide ();
- return;
+ //dprint ("ai_run_slide\n");
+ //Strafe sideways, but stay at aproximately the same range
+ if (self.lefty)
+ ofs = 90;
+ else
+ ofs = -90;
+
+ if (walkmove (self.ideal_yaw + ofs, movedist))
+ return;
+
+ self.lefty = !self.lefty;
+
+ walkmove (self.ideal_yaw - ofs, movedist);
}
-
-// head straight in
+
+ // head straight in
movetogoal (dist); // done in C code...
};
Index: dpmod/qc/fight.qc
diff -u dpmod/qc/fight.qc:1.1.1.1 dpmod/qc/fight.qc:1.2
--- dpmod/qc/fight.qc:1.1.1.1 Thu Sep 19 15:07:08 2002
+++ dpmod/qc/fight.qc Thu Feb 20 04:04:45 2003
@@ -26,8 +26,7 @@
void() ai_face;
-float enemy_vis, enemy_infront, enemy_range;
-float enemy_yaw;
+float enemy_range;
//=============================================================================
Index: dpmod/qc/world.qc
diff -u dpmod/qc/world.qc:1.1.1.1 dpmod/qc/world.qc:1.2
--- dpmod/qc/world.qc:1.1.1.1 Thu Sep 19 15:08:22 2002
+++ dpmod/qc/world.qc Thu Feb 20 04:04:45 2003
@@ -739,111 +739,129 @@
// 20% is normal
};
+.float findtarget;
+entity creaturetocheck;
void() startframe_creaturecode =
{
- local entity e;
+ local entity oldself;
local vector b, v, vel;
- local float c, f, monster_count;
- e = findfloat(world, iscreature, TRUE);
- while (e)
+ local float c, f, monster_count, iterations;
+ oldself = self;
+ self = creaturetocheck;
+ if (self == world)
+ self = findfloat(world, iscreature, TRUE);
+ // only process up to 200 creatures per frame
+ iterations = 0;
+ while (self && iterations < 200)
{
- if (e.takedamage) //e.health >= 1 || e.bodyhealth >= 1)
+ iterations = iterations + 1;
+ if (self.iscreature)
{
- /*
- if (e.bleedcount > 0)
- if (time >= e.nextbleed)
- if (e.velocity != '0 0 0')
+ if (self.takedamage) //self.health >= 1 || self.bodyhealth >= 1)
{
- e.nextbleed = time + 0.2;
- e.bleedcount = e.bleedcount - 5;
- v = (e.absmin + e.absmax) * 0.5 + randomvec() * 8;
- vel = randomvec() * 20;
- SpawnMeatSpray(v, vel);
- }
- */
- if (e.watertype >= CONTENT_EMPTY)
- {
- if (e.flags & FL_INWATER)
+ if (self.findtarget)
{
- // play leave water sound, but only if not an observer
- if (e.solid)
- sound (e, CHAN_BODY, "misc/outwater.wav", 1, ATTN_NORM);
- e.flags = e.flags - FL_INWATER;
+ self.findtarget = FALSE;
+ FindTarget();
}
- }
- else
- {
- //if (e.watertype == CONTENT_WATER || e.watertype == CONTENT_SLIME)
- // e.flamecount = 0;
- if (e.movetype != MOVETYPE_NOCLIP)
- WaterMove(e);
- }
- if (e.bubble_count)
- if (time > e.bubble_time)
- {
- e.bubble_time = time + 0.1;
- v = randomvec2() * 5;
- makebubble(e.origin + '0 0 18', '0 0 15' + v, 0);
- e.bubble_count = self.bubble_count - 1;
- if (e.bubble_count < 1)
- e.bubble_count = 0;
- }
- if (e.jump_flag < -200)
- if (e.flags & FL_ONGROUND)
- if (e.solid) // ignore observers
- {
- if (e.watertype == CONTENT_WATER)
- sound (e, CHAN_BODY, "player/h2ojump.wav", 1, ATTN_NORM);
- else if (e.jump_flag < -650 && world.worldtype < 3)
- {
- // normal quake maps
- b = e.origin;
- b_z = e.absmin_z;
- //T_Damage (e, world, world, (-650 - e.jump_flag) * 0.1, (-650 - e.jump_flag) * 0.1, " met a flat world", DT_FALL, b, '0 0 20', Obituary_Generic);
- T_Damage (e, world, world, 5, 5, " met a flat world", DT_FALL, b, '0 0 20', Obituary_Generic);
- if (!e.deadflag)
- sound (e, CHAN_VOICE, "player/land2.wav", 1, ATTN_NORM);
- }
- else if (e.jump_flag < -500 && world.worldtype >= 3)
- {
- // Dark Places maps
- b = e.origin;
- b_z = e.absmin_z;
- T_Damage (e, world, world, (-500 - e.jump_flag) * 0.3, (-500 - e.jump_flag) * 0.3, " met a flat world", DT_FALL, b, '0 0 20', Obituary_Generic);
- if (!e.deadflag)
- sound (e, CHAN_VOICE, "player/land2.wav", 1, ATTN_NORM);
+ /*
+ if (self.bleedcount > 0)
+ if (time >= self.nextbleed)
+ if (self.velocity != '0 0 0')
+ {
+ self.nextbleed = time + 0.2;
+ self.bleedcount = self.bleedcount - 5;
+ v = (self.absmin + self.absmax) * 0.5 + randomvec() * 8;
+ vel = randomvec() * 20;
+ SpawnMeatSpray(v, vel);
+ }
+ */
+ if (self.watertype >= CONTENT_EMPTY)
+ {
+ if (self.flags & FL_INWATER)
+ {
+ // play leave water sound, but only if not an observer
+ if (self.solid)
+ sound (self, CHAN_BODY, "misc/outwater.wav", 1, ATTN_NORM);
+ self.flags = self.flags - FL_INWATER;
+ }
}
else
- sound (e, CHAN_VOICE, "player/land.wav", 1, ATTN_NORM);
- }
- e.jump_flag = e.velocity_z;
- /*
- if (e.flamecount > 0)
- {
- e.effects = e.effects | EF_FLAME;
- if (time > e.flametime)
+ {
+ //if (self.watertype == CONTENT_WATER || self.watertype == CONTENT_SLIME)
+ // self.flamecount = 0;
+ if (self.movetype != MOVETYPE_NOCLIP)
+ WaterMove(self);
+ }
+ if (self.bubble_count)
+ if (time > self.bubble_time)
{
- e.flametime = time + 0.1;
- if (time > e.flamesoundtime)
+ self.bubble_time = time + 0.1;
+ v = randomvec2() * 5;
+ makebubble(self.origin + '0 0 18', '0 0 15' + v, 0);
+ self.bubble_count = self.bubble_count - 1;
+ if (self.bubble_count < 1)
+ self.bubble_count = 0;
+ }
+ if (self.jump_flag < -200)
+ if (self.flags & FL_ONGROUND)
+ if (self.solid) // ignore observers
+ {
+ if (self.watertype == CONTENT_WATER)
+ sound (self, CHAN_BODY, "player/h2ojump.wav", 1, ATTN_NORM);
+ else if (self.jump_flag < -650 && world.worldtype < 3)
{
- sound (e, CHAN_AUTO, "fire/burn.wav", 1, ATTN_NORM);
- e.flamesoundtime = time + 0.5;
+ // normal quake maps
+ b = self.origin;
+ b_z = self.absmin_z;
+ //T_Damage (self, world, world, (-650 - self.jump_flag) * 0.1, (-650 - self.jump_flag) * 0.1, " met a flat world", DT_FALL, b, '0 0 20', Obituary_Generic);
+ T_Damage (self, world, world, 5, 5, " met a flat world", DT_FALL, b, '0 0 20', Obituary_Generic);
+ if (!self.deadflag)
+ sound (self, CHAN_VOICE, "player/land2.wav", 1, ATTN_NORM);
}
- f = e.flamecount;
- if (f > 5)
- f = 5;
- e.flamecount = e.flamecount - f;
- T_Damage(e, e.flameowner, e.flameowner, f, f, "FIRE", DT_FIRE, e.origin, '0 0 0', Obituary_Fire);
+ else if (self.jump_flag < -500 && world.worldtype >= 3)
+ {
+ // Dark Places maps
+ b = self.origin;
+ b_z = self.absmin_z;
+ T_Damage (self, world, world, (-500 - self.jump_flag) * 0.3, (-500 - self.jump_flag) * 0.3, " met a flat world", DT_FALL, b, '0 0 20', Obituary_Generic);
+ if (!self.deadflag)
+ sound (self, CHAN_VOICE, "player/land2.wav", 1, ATTN_NORM);
+ }
+ else
+ sound (self, CHAN_VOICE, "player/land.wav", 1, ATTN_NORM);
+ }
+ self.jump_flag = self.velocity_z;
+ /*
+ if (self.flamecount > 0)
+ {
+ self.effects = self.effects | EF_FLAME;
+ if (time > self.flametime)
+ {
+ self.flametime = time + 0.1;
+ if (time > self.flamesoundtime)
+ {
+ sound (self, CHAN_AUTO, "fire/burn.wav", 1, ATTN_NORM);
+ self.flamesoundtime = time + 0.5;
+ }
+ f = self.flamecount;
+ if (f > 5)
+ f = 5;
+ self.flamecount = self.flamecount - f;
+ T_Damage(self, self.flameowner, self.flameowner, f, f, "FIRE", DT_FIRE, self.origin, '0 0 0', Obituary_Fire);
+ }
}
+ else if (self.effects & EF_FLAME)
+ self.effects = self.effects - EF_FLAME;
+ */
}
- else if (e.effects & EF_FLAME)
- e.effects = e.effects - EF_FLAME;
- */
+ else
+ self.iscreature = FALSE;
}
- else
- e.iscreature = FALSE;
- e = findfloat(e, iscreature, TRUE);
+ self = findfloat(self, iscreature, TRUE);
}
+ creaturetocheck = self;
+ self = oldself;
};
void() StartFrame =
More information about the twilight-commits
mailing list