Git Repos / fte_dogmode / commit dcb9d64
Commit: dcb9d642dd88b7f9ab33596a717431f332cdbb16
Parent: f83788e50d28c91b0501ee6251a9b6c523c204ea
Author: Cameron Vanderzanden, 2024-01-31 01:26
Committer: Cameron Vanderzanden, 2024-01-31 01:26
Commit Message
Class based monster refactor & start projectiles Big commit. The main attraction is that the monsters have all been refactored and the associated functions (in ai.qc, fight.qc, monster.qc) have been refactored / rewritten (see base_monster.qc). This appears to all work but has not been extensively tested. There will be bugs. I've also started on projectiles & weapon firing code. That work is/will be in projects/*.qc . (Ended up having to do monsters first before projectiles). There have been a handful of bugs fixed and new bugs introduced. Much testing is needed. Next step: projectiles, weapons code, player entity code & client code.
Change List
Diff qc/ai.qc
diff --git a/qc/ai.qc b/qc/ai.qc
index 73ee26d..776c1a1 100644
--- a/qc/ai.qc
+++ b/qc/ai.qc
@@ -1,12 +1,9 @@
-void() movetarget_f;
-void() t_movetarget;
-void() knight_walk1;
-void() knight_bow6;
-void() knight_bow1;
-void(entity etemp, entity stemp, entity stemp, float dmg) T_Damage;
+/*
float NO_SIGHT_SOUND = 32;
float PASSIVE_UNTIL_ATTACKED = 64;
float PASSIVE_ALWAYS = 128;
+*/
+
/*
.enemy
@@ -43,17 +40,10 @@ walkmove(angle, speed) primitive is all or nothing
// as the sight target the next frame so that monsters near that one
// will wake up even if they wouldn't have noticed the player
//
+/*
entity sight_entity;
float sight_entity_time;
-
-float(float v) anglemod =
-{
- while (v >= 360)
- v = v - 360;
- while (v < 0)
- v = v + 360;
- return v;
-};
+*/
/*
==============================================================================
@@ -139,12 +129,10 @@ returns the range catagorization of an entity reletive to self
*/
float(entity targ) range =
{
-local vector spot1, spot2;
-local float r;
- spot1 = self.origin + self.view_ofs;
- spot2 = targ.origin + targ.view_ofs;
+ local vector spot1 = self.origin + self.view_ofs;
+ local vector spot2 = targ.origin + targ.view_ofs;
+ local float r = vlen (spot1 - spot2);
- r = vlen (spot1 - spot2);
if (r < 120)
return RANGE_MELEE;
if (r < 500)
@@ -163,7 +151,7 @@ returns 1 if the entity is visible to self, even if not infront ()
*/
float (entity targ) visible =
{
- local vector spot1, spot2;
+ local vector spot1, spot2;
spot1 = self.origin + self.view_ofs;
spot2 = targ.origin + targ.view_ofs;
@@ -260,6 +248,7 @@ void() ChangeYaw =
//============================================================================
+/*
void() HuntTarget =
{
self.goalentity = self.enemy;
@@ -344,6 +333,7 @@ void() FoundTarget =
SUB_UseAndForgetTargets ();
}
};
+*/
/*
===========
@@ -364,16 +354,17 @@ slower noticing monsters.
*/
float() FindTarget =
{
- local entity client;
- local float r;
+ local entity client;
+ local float r;
-// if the first spawnflag bit is set, the monster will only wake up on
-// really seeing the player, not another monster getting angry
+ // if the first spawnflag bit is set, the monster will only
+ // wake up on really seeing the player, not another monster
+ // getting angry
-// spawnflags & 3 is a big hack, because zombie crucified used the first
-// spawn flag prior to the ambush flag, and I forgot about it, so the second
-// spawn flag works as well
- if (sight_entity_time >= time - 0.1 && !(self.spawnflags & 3) )
+ // spawnflags & 3 is a big hack, because zombie crucified
+ // used the first spawn flag prior to the ambush flag, and
+ // I forgot about it, so the second spawn flag works as well
+ if (sight_entity_time >= time - 0.1 && !(self.spawnflags & 3))
{
client = sight_entity;
if (client.enemy == self.enemy)
@@ -383,13 +374,18 @@ float() FindTarget =
{
client = checkclient ();
if (!client)
- return FALSE; // current check entity isn't in PVS
+ // current check entity isn't in PVS
+ return FALSE;
}
- if ((self.spawnflags & PASSIVE_UNTIL_ATTACKED) || (self.spawnflags & PASSIVE_ALWAYS))
+ if ((self.spawnflags & PASSIVE_UNTIL_ATTACKED) ||
+ (self.spawnflags & PASSIVE_ALWAYS))
+ {
return FALSE;
+ }
- if (client.flags & FL_NOTARGET || client.movetype == MOVETYPE_NOCLIP) // from Copper -- dumptruck_ds
+ // from Copper -- dumptruck_ds
+ if (client.flags & FL_NOTARGET || client.movetype == MOVETYPE_NOCLIP)
return FALSE;
if (client.health <= 0)
@@ -425,9 +421,7 @@ float() FindTarget =
return FALSE;
}
-//
-// got one
-//
+ // got one
self.enemy = client;
if (self.enemy.classname != "player")
{
@@ -456,7 +450,7 @@ void(float dist) ai_forward =
void(float dist) ai_back =
{
// dprint("ai_back\n");
- walkmove ( (self.angles_y+180), dist);
+ walkmove ((self.angles_y + 180), dist);
};
@@ -607,9 +601,6 @@ float() FacingIdeal =
//=============================================================================
-float() WizardCheckAttack;
-float() DogCheckAttack;
-
float() CheckAnyAttack =
{
if (cutscene) // Drake devkit -- dumptruck_ds
@@ -618,10 +609,13 @@ float() CheckAnyAttack =
if (!enemy_vis)
return FALSE;
+ /*
if (self.classname == "monster_army")
return SoldierCheckAttack ();
+ */
if ((self.classname == "monster_ogre") || (self.classname == "monster_ogre_marksman"))
return OgreCheckAttack ();
+ /*
if (self.classname == "monster_shambler")
return ShamCheckAttack ();
if (self.classname == "monster_demon1")
@@ -630,6 +624,7 @@ float() CheckAnyAttack =
return DogCheckAttack ();
if (self.classname == "monster_wizard")
return WizardCheckAttack ();
+ */
return CheckAttack ();
};
@@ -825,28 +820,19 @@ if !(self.spawnflags & I_AM_TURRET) // keeps monster from moving to player - dum
// head straight in
movetogoal (dist); // done in C code...
};
-/*
-=============
-visibleToOther
-returns 1 if the entity is visible to other, even if not infront ()
-=============
-*/
-float (entity targ) visibleToOther =
-{
- local vector spot1, spot2;
- spot1 = other.origin + other.view_ofs;
- spot2 = targ.origin + targ.view_ofs;
- traceline(spot1, spot2, TRUE, other); // see through other monsters
- if (trace_inopen && trace_inwater)
- return FALSE; // sight line crossed contents
- if (trace_fraction == 1)
- return TRUE;
- return FALSE;
-};
-//----------------------------------------------------------------------------
+
+
+
+
+
+
+
+
+
+
Return to the top of this page or return to the overview of this repo.
Diff qc/base_entities.qc
diff --git a/qc/base_entities.qc b/qc/base_entities.qc
index ca52a0b..8209813 100644
--- a/qc/base_entities.qc
+++ b/qc/base_entities.qc
@@ -6,6 +6,8 @@
enumflags
{
DISABLE_BLOCKED,
+ DISABLE_DAMAGE,
+ DISABLE_DESTROY,
DISABLE_THINK,
DISABLE_TOUCH,
DISABLE_USE
@@ -60,7 +62,7 @@ class base_entity: entity
// undefined here & defined later in the base_func class -- CEV
//--------------------------------------------------------------
- virtual void(entity caller) do_think = { };
+ virtual void() do_think = { };
//--------------------------------------------------------------
virtual void() think =
@@ -69,45 +71,33 @@ class base_entity: entity
if (this.interaction_flags & DISABLE_THINK)
return;
- do_think (other);
+ do_think ();
};
//--------------------------------------------------------------
virtual void(entity toucher) do_touch = { };
//--------------------------------------------------------------
- virtual void(entity toucher) handle_touch =
+ virtual void() touch =
{
// has touch been disabled? -- CEV
if (this.interaction_flags & DISABLE_TOUCH)
return;
- do_touch (toucher);
- };
-
- //--------------------------------------------------------------
- virtual void() touch =
- {
- handle_touch (other);
+ do_touch (other);
};
//--------------------------------------------------------------
virtual void(entity caller) do_use = { };
//--------------------------------------------------------------
- virtual void(entity caller) handle_use =
+ virtual void() use =
{
// has use been disabled? -- CEV
if (this.interaction_flags & DISABLE_USE)
return;
- do_use (caller);
- };
-
- //--------------------------------------------------------------
- virtual void() use =
- {
- handle_use (other);
+ do_use (other);
};
//==============================================================
@@ -143,7 +133,8 @@ class temp_delayed_use: base_tempentity
{
activator = this.enemy;
base_mapentity::sub_usetargets ();
- remove (this);
+ if (this)
+ remove (this);
};
//--------------------------------------------------------------
@@ -161,6 +152,9 @@ class temp_delayed_use: base_tempentity
//------------------------------------------------------------------------------
class base_mapentity: base_entity
{
+ //--------------------------------------------------------------
+ virtual void(entity attacker, float damage) do_damage = { };
+
//==============================================================
// Subs
//==============================================================
@@ -171,6 +165,7 @@ class base_mapentity: base_entity
if (this.estate != STATE_ACTIVE)
return;
+ local entity otemp = other;
local entity t;
local string match = "";
@@ -207,7 +202,6 @@ class base_mapentity: base_entity
CT_PLAYER);
}
}
-
else if (activator.classtype == CT_PLAYER)
{
centerprint (activator, this.message);
@@ -234,7 +228,8 @@ class base_mapentity: base_entity
{
if (t.switchshadstyle)
lightstyle (t.switchshadstyle, "m");
- remove (t);
+ if (t)
+ remove (t);
t = find (t, ::targetname, match);
}
@@ -243,7 +238,8 @@ class base_mapentity: base_entity
{
if (t.switchshadstyle)
lightstyle (t.switchshadstyle, "m");
- remove (t);
+ if (t)
+ remove (t);
t = find (t, ::targetname2, match);
}
@@ -252,7 +248,8 @@ class base_mapentity: base_entity
{
if (t.switchshadstyle)
lightstyle (t.switchshadstyle, "m");
- remove (t);
+ if (t)
+ remove (t);
t = find (t, ::targetname3, match);
}
@@ -261,12 +258,16 @@ class base_mapentity: base_entity
{
if (t.switchshadstyle)
lightstyle (t.switchshadstyle, "m");
- remove (t);
+ if (t)
+ remove (t);
t = find (t, ::targetname4, match);
}
match = "";
}
+ // for the use calls below
+ other = this;
+
// regular targets
for (float i = 0; i < 4; i++)
{
@@ -292,10 +293,10 @@ class base_mapentity: base_entity
t = find (world, ::targetname, match);
while (t != world)
{
+ // TODO CEV
if (t.classgroup & CG_MAPENTITY)
- ((base_mapentity)t).handle_use (this);
+ ((base_mapentity)t).use ();
else
- // TODO CEV
SUB_UseAsSelf (t, match);
t = find (t, ::targetname, match);
}
@@ -303,10 +304,10 @@ class base_mapentity: base_entity
t = find (world, ::targetname2, match);
while (t != world)
{
+ // TODO CEV
if (t.classgroup & CG_MAPENTITY)
- ((base_mapentity)t).handle_use (this);
+ ((base_mapentity)t).use ();
else
- // TODO CEV
SUB_UseAsSelf (t, match);
t = find (t, ::targetname2, match);
}
@@ -314,10 +315,10 @@ class base_mapentity: base_entity
t = find (world, ::targetname3, match);
while (t != world)
{
+ // TODO CEV
if (t.classgroup & CG_MAPENTITY)
- ((base_mapentity)t).handle_use (this);
+ ((base_mapentity)t).use ();
else
- // TODO CEV
SUB_UseAsSelf (t, match);
t = find (t, ::targetname3, match);
}
@@ -325,14 +326,17 @@ class base_mapentity: base_entity
t = find (world, ::targetname4, match);
while (t != world)
{
+ // TODO CEV
if (t.classgroup & CG_MAPENTITY)
- ((base_mapentity)t).handle_use (this);
+ ((base_mapentity)t).use ();
else
- // TODO CEV
SUB_UseAsSelf (t, match);
t = find (t, ::targetname4, match);
}
}
+
+ // reverse the 'other' global before finishing
+ other = otemp;
};
//--------------------------------------------------------------
@@ -341,18 +345,22 @@ class base_mapentity: base_entity
if (matchstring == __NULL__ || matchstring == "")
return;
+ local entity otemp = other;
local entity t;
+ other = this;
t = find (world, ::matchfield, matchstring);
while (t != world)
{
+ // TODO CEV
if (t.classgroup & CG_MAPENTITY)
- ((base_mapentity)t).handle_use (this);
+ ((base_mapentity)t).use ();
else
- // TODO CEV
SUB_UseAsSelf (t, matchstring);
t = find (t, ::matchfield, matchstring);
}
+
+ other = otemp;
};
//--------------------------------------------------------------
Return to the top of this page or return to the overview of this repo.
Diff qc/base_func.qc
diff --git a/qc/base_func.qc b/qc/base_func.qc
index 20ae4e0..c1c64f0 100644
--- a/qc/base_func.qc
+++ b/qc/base_func.qc
@@ -15,6 +15,10 @@ const float FUNC_STATE_DOWN = 3;
//------------------------------------------------------------------------------
class base_func: base_mapentity
{
+ //==============================================================
+ // class fields
+ //==============================================================
+ float aflag;
float calc_move_done;
//==============================================================
@@ -64,13 +68,13 @@ class base_func: base_mapentity
this.nextthink = localtime + 0.1;
return;
}
-
+
// set destdelta to the vector needed to move
vdestdelta = tdest - this.origin;
-
+
// calculate length of vector
len = vlen (vdestdelta);
-
+
// divide by speed to get time to reach tdest
traveltime = len / tspeed;
@@ -80,13 +84,13 @@ class base_func: base_mapentity
this.nextthink = localtime + 0.1;
return;
}
-
+
// set nextthink to trigger a think when d is reached
this.nextthink = localtime + traveltime;
// scale the destdelta vector by the time spent traveling
// to get velocity
- // qcc won't take vec/float
+ // qcc won't take vec/float
this.velocity = vdestdelta * (1 / traveltime);
};
@@ -116,7 +120,7 @@ class base_func: base_mapentity
}
else
{
- do_think (other);
+ do_think ();
}
};
Return to the top of this page or return to the overview of this repo.
Diff qc/base_item.qc
diff --git a/qc/base_item.qc b/qc/base_item.qc
index 334b9f9..9a27a02 100644
--- a/qc/base_item.qc
+++ b/qc/base_item.qc
@@ -30,7 +30,22 @@ enumflags
//------------------------------------------------------------------------------
class base_item: base_mapentity
{
+ //==============================================================
+ // class fields
+ //==============================================================
+ float aflag;
float item_flags; // internal think & use state flags
+ vector pos1;
+ vector pos2;
+
+ // Supa, Quoth respawning items support
+ //
+ // Respawn item like in DM if 'ritem' TRUE, override respawn time
+ // with 'respawndelay' if set, inc 'cnt' with each respawn and if
+ // 'respawncount' is set we'll remove the item if cnt > respawncount
+ // remember that SUB_Regen is already set on every item that can
+ // respawn, all we need to do is give a nextthink time in order
+ // to trigger it
float ritem; // legacy singleplayer item respawn flag
float respawndelay; // legacy singleplayer respawn delay
@@ -271,7 +286,7 @@ class base_item: base_mapentity
// from the RMQ code, and was here when the
// func_mapjamx maps were created. It would have been
// nice to remove this code entirely, because progs_dump
- // doesn't need it, and it breaks item_health's
+ // doesn't need it, and it breaks item_health's
// collision with entities that have MOVETYPE_PUSH.
// However, removing this code would cause some of the
// item_health entities in some of the func_mapjamx
@@ -352,7 +367,7 @@ class base_item: base_mapentity
//==============================================================
//--------------------------------------------------------------
- virtual void(entity caller) do_think =
+ virtual void() do_think =
{
if (this.item_flags & ITEM_FLAG_SPAWN)
{
@@ -385,16 +400,16 @@ class base_item: base_mapentity
};
//--------------------------------------------------------------
- virtual void(entity toucher) handle_touch =
+ virtual void() touch =
{
// has touch been disabled? -- CEV
if (this.interaction_flags & DISABLE_TOUCH)
return;
- if (sub_checkvalidtouch(toucher) == FALSE)
+ if (sub_checkvalidtouch(other) == FALSE)
return;
- do_touch (toucher);
+ do_touch (other);
};
//--------------------------------------------------------------
Return to the top of this page or return to the overview of this repo.
Diff qc/base_monster.qc
diff --git a/qc/base_monster.qc b/qc/base_monster.qc
index 9521644..3e8f2fa 100644
--- a/qc/base_monster.qc
+++ b/qc/base_monster.qc
@@ -2,11 +2,1513 @@
// base_monster.qc -- base monster class, monster logic
//==============================================================================
+// constants -- any states should start at -1 and decrement because
+// subclasses will start at 0 and work up -- CEV
+const float MONSTER_THINK_START = -1;
+const float MONSTER_THINK_FOUNDTARGET = -2;
+
+const float MONSTER_USE_MAKEANGRY = -1;
+const float MONSTER_USE_TELEDELAY = -2;
+
+const float NO_SIGHT_SOUND = 32;
+const float PASSIVE_UNTIL_ATTACKED = 64;
+const float PASSIVE_ALWAYS = 128;
+
+// globals
+entity sight_entity; // was in ai.qc
+float sight_entity_time; // was in ai.qc
+float enemy_vis; // was in fight.qc
+float enemy_infront; // was in fight.qc
+float enemy_range; // was in fight.qc
+float enemy_yaw; // was in fight.qc
+
+// fields -- define Preach's new fields dumptruck_ds
+.string tele_model;
+.vector tele_mins;
+.vector tele_maxs;
+.float tele_solid;
+.float tele_movetype;
+
+//======================================================================
+// .enemy
+// Will be world if not currently angry at anyone.
+//
+// .movetarget
+// The next path spot to walk toward. If .enemy, ignore .movetarget.
+// When an enemy is killed, the monster will try to return to it's path.
+//
+// .huntt_ime
+// Set to time + something when the player is in sight, but movement
+// straight for him is blocked. This causes the monster to use wall
+// following code for movement direction instead of sighting on the
+// player.
+//
+// .ideal_yaw
+// A yaw angle of the intended direction, which will be turned towards
+// at up to 45 deg / state. If the enemy is in view and hunt_time is not
+// active, this will be the exact line towards the enemy.
+//
+// .pausetime
+// A monster will leave it's stand state and head towards it's .movetarget
+// when time > .pausetime.
+//
+// walkmove(angle, speed) primitive is all or nothing
+//======================================================================
+
+//----------------------------------------------------------------------
+// monster_update_total
+//
+// Call this function to safely update total_monsters when the game is
+// in progress. It adds "n" to total_monsters, then notifies all clients
+// of the change. -- iw
+//----------------------------------------------------------------------
+void(float n) monster_update_total =
+{
+ total_monsters = total_monsters + n;
+
+ WriteByte (MSG_ALL, SVC_UPDATESTAT);
+ WriteByte (MSG_ALL, STAT_TOTALMONSTERS);
+ WriteLong (MSG_ALL, total_monsters);
+};
+
//------------------------------------------------------------------------------
class base_monster: base_mapentity
{
+ float use_flag;
+
+ // the typical th_ monster think functions -- CEV
+ virtual void() think_stand = {};
+ virtual void() think_walk = {};
+ virtual void() think_run = {};
+ virtual void() think_missile = {};
+ virtual void() think_melee = {};
+ virtual void() think_turret = {};
+
+ //==============================================================
+ // Monster AI
+ //==============================================================
+
+ //--------------------------------------------------------------
+ // ai_checkattack - MonsterCheckAttack & CheckAttack
+ // override in monster code if other behavior is desired
+ //
+ // The player is in view, so decide to move or launch an attack
+ // Returns FALSE if movement should continue
+ //--------------------------------------------------------------
+ virtual float() ai_checkattack =
+ {
+ local vector spot1 = '0 0 0';
+ local vector spot2 = '0 0 0';
+ local entity targ;
+ local float chance;
+
+ // TODO CEV: fix these classname checks, generalize
+ // calls to knight_attack
+
+ // dumptruck_ds
+ if (this.spawnflags & I_AM_TURRET)
+ {
+ // dprint ("CheckAttack...\n");
+ if (this.classname == "monster_enforcer")
+ {
+ if (this.style == 4)
+ {
+ // lightning can only go so far
+ if (vlen(spot1 - spot2) > 900)
+ return FALSE;
+ }
+ this.attack_state = AS_MISSILE;
+ }
+ else if (this.classname == "monster_hell_knight")
+ {
+ if (this.style == 1)
+ {
+ // lightning can only go so far
+ if (vlen(spot1 - spot2) > 900)
+ return FALSE;
+ }
+ // this.attack_state = AS_MISSILE;
+ this.think_turret ();
+ }
+ else if (this.classname == "monster_shalrath")
+ {
+ this.think_turret ();
+ }
+ else if (this.classname == "monster_zombie")
+ {
+ // dprint ("CheckAttack...\n");
+ // zombie_turret_missile ();
+ this.think_turret ();
+ }
+ sub_attackfinished (2 * random());
+ return TRUE;
+ }
+
+ targ = this.enemy;
+
+ // see if any entities are in the way of the shot
+ spot1 = this.origin + this.view_ofs;
+ spot2 = targ.origin + targ.view_ofs;
+
+ traceline (spot1, spot2, FALSE, this);
+
+ if ((this.spawnflags & I_AM_TURRET) && (trace_ent != targ))
+ {
+ // dprint ("trace_ent...\n");
+ this.attack_state = AS_TURRET;
+ return FALSE;
+ }
+
+ if (trace_inopen && trace_inwater)
+ // sight line crossed contents
+ return FALSE;
+
+ if (trace_ent != targ)
+ // don't have a clear shot
+ return FALSE;
+
+ if (enemy_range == RANGE_MELEE)
+ {
+ // melee attack
+ if (this.classtype == CT_MONSTER_KNIGHT)
+ ((monster_knight)this).knight_attack ();
+ else
+ this.think_melee ();
+ return TRUE;
+ }
+
+ // missile attack
+ if (!this.think_missile)
+ return FALSE;
+
+ if (time < this.attack_finished)
+ return FALSE;
+
+ if (enemy_range == RANGE_FAR)
+ return FALSE;
+
+ if (enemy_range == RANGE_MELEE)
+ {
+ chance = 0.9;
+ this.attack_finished = 0;
+ }
+ else if (enemy_range == RANGE_NEAR)
+ {
+ if (this.think_melee)
+ chance = 0.2;
+ else
+ chance = 0.4;
+ }
+ else if (enemy_range == RANGE_MID)
+ {
+ if (this.think_melee)
+ chance = 0.05;
+ else
+ chance = 0.1;
+ }
+ else
+ {
+ chance = 0;
+ }
+
+ if (random() < chance)
+ {
+ this.think_missile ();
+ sub_attackfinished (2 * random());
+ return TRUE;
+ }
+
+ return FALSE;
+ };
+
+ //--------------------------------------------------------------
+ // infront -- returns 1 if the entity is in front (in sight) of self
+ //--------------------------------------------------------------
+ nonvirtual float(entity targ) ai_infront =
+ {
+ local vector vec;
+ local float dot;
+
+ makevectors (this.angles);
+ vec = normalize (targ.origin - this.origin);
+ dot = vec * v_forward;
+
+ if (dot > 0.3)
+ {
+ return TRUE;
+ }
+ return FALSE;
+ };
+
+ //--------------------------------------------------------------
+ // range
+ //
+ // returns the range catagorization of an entity reletive to self
+ // 0 melee range, will become hostile even if back is turned
+ // 1 visibility and infront, or visibility and show hostile
+ // 2 infront and show hostile
+ // 3 only triggered by damage
+ //--------------------------------------------------------------
+ nonvirtual float(entity targ) ai_range =
+ {
+ local vector spot1 = this.origin + this.view_ofs;
+ local vector spot2 = targ.origin + targ.view_ofs;
+ local float r = vlen (spot1 - spot2);
+
+ if (r < 120)
+ return RANGE_MELEE;
+ if (r < 500)
+ return RANGE_NEAR;
+ if (r < 1000)
+ return RANGE_MID;
+ return RANGE_FAR;
+ };
+
+ //--------------------------------------------------------------
+ // visible - returns 1 if the entity is visible to self, even
+ // if not infront ()
+ //--------------------------------------------------------------
+ nonvirtual float (entity targ) ai_visible =
+ {
+ local vector spot1, spot2;
+
+ spot1 = this.origin + this.view_ofs;
+ spot2 = targ.origin + targ.view_ofs;
+ // see through other monsters
+ traceline (spot1, spot2, TRUE, this);
+
+ if (trace_inopen && trace_inwater)
+ // sight line crossed contents
+ return FALSE;
+
+ if (trace_fraction == 1)
+ return TRUE;
+ return FALSE;
+ };
+
+ //--------------------------------------------------------------
+ // SightSound -- was in ai.qc -- implement in subclasses -- CEV
+ //--------------------------------------------------------------
+ virtual void() ai_sightsound = { };
+
+ //--------------------------------------------------------------
+ // HuntTarget -- was in ai.qc -- CEV
+ //--------------------------------------------------------------
+ nonvirtual void() ai_hunttarget =
+ {
+ this.goalentity = this.enemy;
+ this.think = this.think_run;
+ this.ideal_yaw = vectoyaw (this.enemy.origin - this.origin);
+ this.nextthink = time + 0.1;
+ // wait a while before first attack
+ sub_attackfinished (1);
+ };
+
+ //--------------------------------------------------------------
+ // FoundTarget -- was in ai.qc -- CEV
+ //--------------------------------------------------------------
+ nonvirtual void() ai_foundtarget =
+ {
+ if (this.enemy.classtype == CT_PLAYER)
+ {
+ // let other monsters see this monster for a while
+ sight_entity = this;
+ sight_entity_time = time;
+ }
+
+ // wake up other monsters
+ this.show_hostile = time + 1;
+
+ if !(this.spawnflags & NO_SIGHT_SOUND ||
+ this.spawnflags & PASSIVE_ALWAYS ||
+ this.spawnflags & PASSIVE_UNTIL_ATTACKED)
+ {
+ ai_sightsound ();
+ }
+
+ ai_hunttarget ();
+
+ // thanks RennyC -- dumptruck_ds
+ if (this.sight_trigger == 1)
+ {
+ activator = this.enemy;
+ sub_useandforgettargets ();
+ }
+ };
+
+ //--------------------------------------------------------------
+ // FindTarget
+ //
+ // Self is currently not attacking anything, so try to find a target
+ //
+ // Returns TRUE if an enemy was sighted
+ //
+ // When a player fires a missile, the point of impact becomes a
+ // fakeplayer so that monsters that see the impact will respond as
+ // if they had seen the player.
+ //
+ // To avoid spending too much time, only a single client (or
+ // fakeclient) is checked each frame. This means multi player games
+ // will have slightly slower noticing monsters.
+ //--------------------------------------------------------------
+ nonvirtual float() ai_findtarget =
+ {
+ local entity client;
+ local float r;
+
+ // if the first spawnflag bit is set, the monster will only
+ // wake up on really seeing the player, not another monster
+ // getting angry
+
+ // spawnflags & 3 is a big hack, because zombie crucified
+ // used the first spawn flag prior to the ambush flag, and
+ // I forgot about it, so the second spawn flag works as well
+ if (sight_entity_time >= time - 0.1 && !(this.spawnflags & 3))
+ {
+ client = sight_entity;
+ if (client.enemy == this.enemy)
+ return TRUE;
+ }
+ else
+ {
+ client = checkclient ();
+ if (!client)
+ // current check entity isn't in PVS
+ return FALSE;
+ }
+
+ if ((this.spawnflags & PASSIVE_UNTIL_ATTACKED) ||
+ (this.spawnflags & PASSIVE_ALWAYS))
+ {
+ return FALSE;
+ }
+
+ // from Copper -- dumptruck_ds
+ if (client.flags & FL_NOTARGET ||
+ client.movetype == MOVETYPE_NOCLIP)
+ {
+ return FALSE;
+ }
+
+ if (client.health <= 0)
+ return FALSE;
+
+ if (client.classtype != CT_PLAYER)
+ if (client.enemy.health <= 0)
+ return FALSE;
+
+ if (client == this.enemy)
+ return FALSE;
+
+ if (client.flags & FL_NOTARGET)
+ return FALSE;
+ if (client.items & IT_INVISIBILITY)
+ return FALSE;
+
+ r = ai_range (client);
+ if (r == RANGE_FAR)
+ return FALSE;
+
+ if (!ai_visible(client))
+ return FALSE;
+
+ if (r == RANGE_NEAR)
+ {
+ if (client.show_hostile < time && !ai_infront
+ (client))
+ return FALSE;
+ }
+ else if (r == RANGE_MID)
+ {
+ /*
+ if (client.show_hostile < time || !ai_infront (client))
+ */
+ if (!ai_infront(client))
+ return FALSE;
+ }
+
+ // got one
+ this.enemy = client;
+ if (this.enemy.classtype != CT_PLAYER)
+ {
+ this.enemy = this.enemy.enemy;
+ if (this.enemy.classtype != CT_PLAYER)
+ {
+ this.enemy = world;
+ return FALSE;
+ }
+ }
+
+ ai_foundtarget ();
+
+ return TRUE;
+ };
+
+ //--------------------------------------------------------------
+ // ai_face Stay facing the enemy
+ //--------------------------------------------------------------
+ nonvirtual void() ai_face =
+ {
+ this.ideal_yaw = vectoyaw (this.enemy.origin - this.origin);
+ ChangeYaw ();
+ };
+
+ //--------------------------------------------------------------
+ // FacingIdeal
//--------------------------------------------------------------
- virtual void() customphysics =
+ nonvirtual float() ai_facing_ideal =
{
+ local float delta;
+
+ delta = anglemod (this.angles_y - this.ideal_yaw);
+ if (delta > 45 && delta < 315)
+ return FALSE;
+ return TRUE;
+ };
+
+ //--------------------------------------------------------------
+ nonvirtual void(float dist) ai_forward =
+ {
+ // dprint ("ai_forward\n");
+ walkmove (this.angles_y, dist);
+ };
+
+ //--------------------------------------------------------------
+ nonvirtual void(float dist) ai_back =
+ {
+ // dprint ("ai_back\n");
+ walkmove ((this.angles_y + 180), dist);
+ };
+
+ //--------------------------------------------------------------
+ // ai_pain -- stagger back a bit
+ //--------------------------------------------------------------
+ nonvirtual void(float dist) ai_pain =
+ {
+ ai_back (dist);
+ /*
+ local float away;
+
+ away = anglemod (vectoyaw (this.origin - this.enemy.origin)
+ + 180 * (random() - 0.5));
+
+ walkmove (away, dist);
+ */
+ };
+
+ //--------------------------------------------------------------
+ // ai_painforward -- stagger back a bit
+ //--------------------------------------------------------------
+ nonvirtual void(float dist) ai_painforward =
+ {
+ // dprint ("ai_painforward\n");
+ walkmove (this.ideal_yaw, dist);
+ };
+
+ //--------------------------------------------------------------
+ // ai_walk -- The monster is walking it's beat
+ //--------------------------------------------------------------
+ nonvirtual void(float dist) ai_walk =
+ {
+ movedist = dist;
+
+ if (this.classname == "monster_dragon")
+ {
+ movetogoal (dist);
+ return;
+ }
+
+ // check for noticing a player
+ if (ai_findtarget())
+ return;
+
+ movetogoal (dist);
+ };
+
+ //--------------------------------------------------------------
+ // ai_stand -- The monster is staying in one place for a while,
+ // with slight angle turns
+ //--------------------------------------------------------------
+ nonvirtual void() ai_stand =
+ {
+ if (ai_findtarget())
+ return;
+
+ if (time > this.pausetime)
+ {
+ this.think_walk ();
+ return;
+ }
+ // change angle slightly -- TODO CEV ???
+ };
+
+ //--------------------------------------------------------------
+ // ai_turn -- don't move, but turn towards ideal_yaw
+ //--------------------------------------------------------------
+ nonvirtual void() ai_turn =
+ {
+ if (ai_findtarget())
+ return;
+
+ ChangeYaw ();
+ };
+
+ //--------------------------------------------------------------
+ // ai_run_melee
+ // Turn and close until within an angle to launch a melee attack
+ //--------------------------------------------------------------
+ nonvirtual void() ai_run_melee =
+ {
+ this.ideal_yaw = enemy_yaw;
+ ChangeYaw ();
+
+ if (ai_facing_ideal())
+ {
+ this.think_melee ();
+ this.attack_state = AS_STRAIGHT;
+ }
+ };
+
+ //--------------------------------------------------------------
+ // ai_run_missile
+ // Turn in place until within an angle to launch a missile attack
+ //--------------------------------------------------------------
+ nonvirtual void() ai_run_missile =
+ {
+ this.ideal_yaw = enemy_yaw;
+ // dprint ("ai_run_missile GO\n");
+ ChangeYaw ();
+ if (this.ai_facing_ideal())
+ {
+ if (this.spawnflags & I_AM_TURRET)
+ {
+ this.think_turret ();
+ // dprint ("th_turret...\n");
+ }
+ else
+ {
+ this.think_missile ();
+ // dprint ("th_missile\n");
+ }
+ this.attack_state = AS_STRAIGHT;
+ }
+ };
+
+ //--------------------------------------------------------------
+ // ai_run_slide
+ // Strafe sideways, but stay at approximately the same range
+ //--------------------------------------------------------------
+ nonvirtual void() ai_run_slide =
+ {
+ local float ofs;
+
+ this.ideal_yaw = enemy_yaw;
+ ChangeYaw ();
+ if (this.lefty)
+ ofs = 90;
+ else
+ ofs = -90;
+
+ if (walkmove(this.ideal_yaw + ofs, movedist))
+ return;
+
+ this.lefty = 1 - this.lefty;
+
+ walkmove (this.ideal_yaw - ofs, movedist);
+ };
+
+ //--------------------------------------------------------------
+ // ai_run -- The monster has an enemy it is trying to kill
+ //--------------------------------------------------------------
+ nonvirtual void(float dist) ai_run =
+ {
+ // dprint ("ai_run\n");
+ movedist = dist;
+ // see if the enemy is dead
+ if ((this.enemy.health <= 0) ||
+ (this.spawnflags & PASSIVE_ALWAYS))
+ {
+ this.enemy = world;
+ // FIXME: look all around for other targets
+ if (this.oldenemy.health > 0)
+ {
+ this.enemy = this.oldenemy;
+ ai_hunttarget ();
+ }
+ else
+ {
+ if (this.spawnflags & I_AM_TURRET)
+ this.think_stand ();
+ else if (this.movetarget)
+ this.think_walk ();
+ else
+ this.think_stand ();
+ return;
+ }
+ }
+
+ // wake up other monsters
+ this.show_hostile = time + 1;
+
+ // check knowledge of enemy
+ enemy_vis = ai_visible (this.enemy);
+ if (enemy_vis)
+ this.search_time = time + 5;
+
+ // look for other coop players
+ if (coop && this.search_time < time)
+ {
+ if (ai_findtarget())
+ return;
+ }
+
+ enemy_infront = ai_infront (this.enemy);
+ enemy_range = ai_range (this.enemy);
+ enemy_yaw = vectoyaw (this.enemy.origin - this.origin);
+
+ if (this.spawnflags & I_AM_TURRET)
+ {
+ ai_face ();
+ }
+
+ // if ((this.attack_state == AS_MISSILE) ||
+ // !(this.spawnflags & I_AM_TURRET))
+ if (this.attack_state == AS_MISSILE)
+ {
+ // dprint ("ai_run_missile... from ai_run\n");
+ ai_run_missile ();
+ return;
+ }
+ // if ((this.attack_state == AS_MELEE) ||
+ // !(this.spawnflags & I_AM_TURRET))
+ if (this.attack_state == AS_MELEE)
+ {
+ // dprint ("ai_run_melee\n");
+ ai_run_melee ();
+ return;
+ }
+
+ if (ai_checkattack())
+ // beginning an attack
+ return;
+
+ // if ((this.attack_state == AS_SLIDING) ||
+ // !(this.spawnflags & I_AM_TURRET))
+ if (this.attack_state == AS_SLIDING)
+ {
+ ai_run_slide ();
+ return;
+ }
+ // part of monster face from TheSolipsist
+ // urged to change positions
+ if (time < this.t_length)
+ {
+ // if orientation is forced
+ ChangeYaw ();
+
+ if (walkmove(this.ideal_yaw, dist))
+ return;
+
+ // dodge left
+ this.ideal_yaw += 30;
+ ChangeYaw ();
+
+ if (walkmove(this.ideal_yaw, dist))
+ return;
+
+ // dodge right
+ this.ideal_yaw -= 60;
+ ChangeYaw ();
+ ChangeYaw ();
+
+ if (walkmove(this.ideal_yaw, dist))
+ return;
+
+ // give up
+ this.ideal_yaw += 30;
+ ChangeYaw();
+ // lose patience
+ this.touch_time = this.touch_time - 0.1;
+
+ return;
+ }
+
+ if !(this.spawnflags & I_AM_TURRET)
+ // keeps monster from moving to player - dumptruck_ds
+ // head straight in -- done in C code...
+ movetogoal (dist);
+ };
+
+ //--------------------------------------------------------------
+ // ai_charge -- The monster is in a melee attack, so get as close
+ // as possible to .enemy
+ //--------------------------------------------------------------
+ nonvirtual void(float d) ai_charge =
+ {
+ ai_face ();
+ // done in C code...
+ movetogoal (d);
+ };
+
+ //--------------------------------------------------------------
+ nonvirtual void() ai_charge_side =
+ {
+ local vector dtemp;
+ local float heading;
+
+ // aim to the left of the enemy for a flyby
+ this.ideal_yaw = vectoyaw (this.enemy.origin - this.origin);
+ ChangeYaw ();
+
+ makevectors (this.angles);
+ dtemp = this.enemy.origin - 30 * v_right;
+ heading = vectoyaw (dtemp - this.origin);
+
+ walkmove (heading, 20);
+ };
+
+ //--------------------------------------------------------------
+ // ai_melee
+ //--------------------------------------------------------------
+ nonvirtual void() ai_melee =
+ {
+ local vector delta;
+ local float ldmg;
+
+ if (!this.enemy)
+ // removed before stroke
+ return;
+
+ delta = this.enemy.origin - this.origin;
+
+ if (vlen(delta) > 60)
+ return;
+
+ ldmg = (random() + random() + random()) * 3;
+ T_Damage (this.enemy, this, this, ldmg);
+ };
+
+ //--------------------------------------------------------------
+ nonvirtual void() ai_melee_side =
+ {
+ local vector delta;
+ local float ldmg;
+
+ if (!this.enemy)
+ // removed before stroke
+ return;
+
+ ai_charge_side ();
+
+ delta = this.enemy.origin - this.origin;
+
+ if (vlen(delta) > 60)
+ return;
+
+ if (!CanDamage(this.enemy, this))
+ return;
+
+ ldmg = (random() + random() + random()) * 3;
+ T_Damage (this.enemy, this, this, ldmg);
+ };
+
+ //==============================================================
+ // SUBS
+ //==============================================================
+
+ //--------------------------------------------------------------
+ // SUB_AttackFinished
+ // in nightmare mode, all attack_finished times become 0
+ // some monsters refire twice automatically
+ //--------------------------------------------------------------
+ nonvirtual void(float normal) sub_attackfinished =
+ {
+ // refire count for nightmare
+ this.cnt = 0;
+ if (skill != 3)
+ this.attack_finished = time + normal;
+ };
+
+ //--------------------------------------------------------------
+ nonvirtual void(void() nextfunc) sub_checkrefire =
+ {
+ if (skill != 3)
+ return;
+ if (this.cnt == 1)
+ return;
+ if (!ai_visible(this.enemy))
+ return;
+
+ this.cnt = 1;
+ this.think = nextfunc;
+ };
+
+ //--------------------------------------------------------------
+ // SUB_FieldIsTargeted
+ //
+ // Return TRUE if the "fld" field of this entity is non-empty and
+ // matches the target (or target2/3/4 or pain_target) field of
+ // any other entity, otherwise return FALSE. -- iw
+ //--------------------------------------------------------------
+ nonvirtual float(.string fld) sub_fieldistargeted =
+ {
+ if (this.fld == "")
+ return FALSE;
+
+ // the following function calls are staggered to avoid
+ // the silly "return value conflict" problem with
+ // traditional compilers -- iw
+
+ if (find (world, ::target, this.fld) != world)
+ return TRUE;
+
+ if (find (world, ::target2, this.fld) != world)
+ return TRUE;
+
+ if (find (world, ::target3, this.fld) != world)
+ return TRUE;
+
+ if (find (world, ::target4, this.fld) != world)
+ return TRUE;
+
+ if (find (world, ::pain_target, this.fld) != world)
+ return TRUE;
+
+ return FALSE;
+ };
+
+ //--------------------------------------------------------------
+ // SUB_IsTargeted
+ //
+ // Return TRUE if the targetname (or targetname2/3/4) field of
+ // this entity is non-empty and matches the target (or target2/3/4
+ // or pain_target) field of any other entity, otherwise return
+ // FALSE. -- iw
+ //--------------------------------------------------------------
+ nonvirtual float() sub_istargeted =
+ {
+ // the following function calls are staggered to avoid
+ // the silly "return value conflict" problem with
+ // traditional compilers -- iw
+ if (sub_fieldistargeted(::targetname))
+ return TRUE;
+
+ if (sub_fieldistargeted(::targetname2))
+ return TRUE;
+
+ if (sub_fieldistargeted(::targetname3))
+ return TRUE;
+
+ if (sub_fieldistargeted(::targetname4))
+ return TRUE;
+
+ return FALSE;
+ };
+
+ //--------------------------------------------------------------
+ // monster_death_use
+ //
+ // When a mosnter dies, it fires all of its targets with the
+ // current enemy as activator.
+ //--------------------------------------------------------------
+ nonvirtual void() sub_death_use =
+ {
+ // fall to ground
+ if (this.flags & FL_FLY)
+ this.flags = this.flags - FL_FLY;
+ if (this.flags & FL_SWIM)
+ this.flags = this.flags - FL_SWIM;
+
+ if (!this.target)
+ return;
+
+ if (this.infight_activator)
+ {
+ activator = this.infight_activator;
+ }
+ else
+ {
+ activator = this.enemy;
+ }
+
+ sub_usetargets ();
+ };
+
+ //--------------------------------------------------------------
+ // monster_pain_use -- dumptruck_ds
+ //
+ // When a monster reaches pain_threshold, it fires all of its
+ // pain_targets with the current enemy as activator.
+ //--------------------------------------------------------------
+ nonvirtual void() sub_pain_use =
+ {
+ if (!this.pain_target)
+ return;
+
+ activator = this.enemy;
+ // SUB_UsePain ();
+ if (this.pain_target != "")
+ {
+ sub_usetarget (this.pain_target, ::targetname);
+ sub_usetarget (this.pain_target, ::targetname2);
+ sub_usetarget (this.pain_target, ::targetname3);
+ sub_usetarget (this.pain_target, ::targetname4);
+ }
+ // dumptruck_ds via Discord - thanks Spike, Snaut and QueenJazz
+ this.pain_target = "";
+ };
+
+ //==============================================================
+ // Interaction
+ //==============================================================
+
+ //--------------------------------------------------------------
+ // think is reassigned in subclasses & so isn't defined here
+ //--------------------------------------------------------------
+ /*
+ virtual void() think = { };
+ */
+
+ //--------------------------------------------------------------
+ virtual void() think_start = { };
+
+ //--------------------------------------------------------------
+ nonvirtual void() think_teleport_go =
+ {
+ this.solid = this.tele_solid;
+ this.movetype = this.tele_movetype;
+ setmodel (this, this.tele_model);
+ setsize (this, this.tele_mins, this.tele_maxs);
+
+ // fix for cumulative delays for counters etc. -- dumptruck_ds
+ this.delay = 0;
+
+ this.use_flag = MONSTER_USE_MAKEANGRY;
+
+ // was a call to think1 -- CEV
+ this.think_start ();
+
+ // override the random delay some go functions apply
+ this.nextthink = time + 0.1;
+ {
+ if !(this.spawnflags & SPAWN_SILENTLY)
+ {
+ // dumptruck_ds: if wait value is > 0
+ // spawn silently or use a spawnflag
+ if (this.wait == 0)
+ spawn_tfog (this.origin);
+ spawn_tdeath (this.origin, this);
+ }
+ }
+ };
+
+ //--------------------------------------------------------------
+ // monster_touch -- was in monsters.qc -- CEV
+ //--------------------------------------------------------------
+ virtual void() touch =
+ {
+ // has touch been disabled? -- CEV
+ if (this.interaction_flags & DISABLE_TOUCH)
+ return;
+
+ // 1998-09-16 Sliding/not-jumping on monsters/boxes/players
+ // fix by Maddes/Kryten start
+
+ // by: Philip Martin aka: Kryten
+ // When on top of monsters or players you slide. This is a
+ // QuakeC problem. The function below fixes that problem.
+ // based on code given to Kryten by: Michael Turitzin (MaNiAc)
+
+ // can cause problems for monsters on top of a player,
+ // so only players
+ if (other.classtype != CT_PLAYER)
+ return;
+
+ if (other.health <= 0)
+ return;
+
+ if ((!(other.flags & FL_ONGROUND)) &&
+ ((other.absmin_z >= this.absmax_z - 2)))
+ {
+ other.flags = other.flags + FL_ONGROUND;
+ }
+
+ // you can add other stuff like pushable players/monsters here
+
+ // 1998-09-16 Sliding/not-jumping on monsters/boxes/players
+ // fix by Maddes/Kryten end
+ };
+
+ //--------------------------------------------------------------
+ // monster_use -- Using a monster makes it angry at the activator
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_use =
+ {
+ if (this.use_flag == MONSTER_USE_MAKEANGRY)
+ {
+ if (this.enemy)
+ return;
+ if (this.health <= 0)
+ return;
+ if (activator.items & IT_INVISIBILITY)
+ return;
+ if (activator.flags & FL_NOTARGET)
+ return;
+ if (activator.movetype == MOVETYPE_NOCLIP)
+ // Copper -- dumptruck_ds
+ return FALSE;
+
+ if (activator.classtype != CT_PLAYER)
+ return;
+
+ // delay reaction so if the monster is teleported,
+ // its sound is still heard
+ this.enemy = activator;
+ this.think = ai_foundtarget;
+ this.nextthink = time + 0.1;
+ }
+ else if (this.use_flag == MONSTER_USE_TELEDELAY)
+ {
+ // monster_teleport_delay
+ // new from Qmaster func coding help thread
+ this.think = this.think_teleport_go;
+ if (this.delay == -1)
+ {
+ // if delay is set to -1 random delay
+ // from 0.1 to 1 second - dumptruck_ds
+ this.nextthink = time + 0.1 + random();
+ return;
+ }
+ this.nextthink = time + 0.1 + this.delay;
+ }
+ };
+
+ //==============================================================
+ // Initialization
+ //==============================================================
+
+ //--------------------------------------------------------------
+ // monster_teleport_check
+ //
+ // This detects and eliminates a common map bug: a trigger-spawned
+ // monster which can't be activated either because it has no
+ // targetname or because its targetname isn't targeted by any
+ // other entity. (This map bug would otherwise make it impossible
+ // for the player to get 100% kills.) -- iw
+ //--------------------------------------------------------------
+ nonvirtual void() init_teleport_check =
+ {
+ if (!sub_istargeted())
+ {
+ dprint (sprintf("base_monster::init_teleport_check: "
+ "WARNING: removed untargeted trigger-spawned "
+ "%s at %v\n", this.classname, this.origin));
+
+ remove (this);
+ return;
+ }
+
+ // the targetname appears to be OK, so let's finish
+ // setting up the trigger-spawned monster -- iw
+ // qmaster
+ // this.use = monster_teleport_delay;
+ this.use_flag = MONSTER_USE_TELEDELAY;
+ monster_update_total (1);
+ };
+
+ //--------------------------------------------------------------
+ nonvirtual float () init_teleport =
+ {
+ if(!(this.spawnflags & 8))
+ return FALSE;
+
+ // PREACH: This monster is to be teleported in, so hide it
+ this.tele_model= this.model;
+ this.tele_mins = this.mins;
+ this.tele_maxs = this.maxs;
+ this.tele_solid = this.solid;
+ this.tele_movetype = this.movetype;
+
+ this.model = "";
+ this.modelindex = 0;
+ this.solid = SOLID_NOT;
+ this.movetype = MOVETYPE_NONE;
+
+ // wait for other entities to finish spawning, then check that
+ // something targets this -- iw
+ this.think = init_teleport_check;
+ this.nextthink = time + 0.1;
+
+ return TRUE;
+ };
+
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
+ {
+ this.use_flag = MONSTER_USE_MAKEANGRY;
+ };
+
+ //--------------------------------------------------------------
+ void() base_monster =
+ {
+ this.classgroup |= CG_MONSTER;
+ };
+};
+
+//------------------------------------------------------------------------------
+class base_flymonster: base_monster
+{
+ //==============================================================
+ // Interaction
+ //==============================================================
+
+ //--------------------------------------------------------------
+ // flymonster_start_go
+ //--------------------------------------------------------------
+ virtual void() think_start =
+ {
+ this.takedamage = DAMAGE_AIM;
+
+ this.ideal_yaw = this.angles * '0 1 0';
+ if (!this.yaw_speed)
+ this.yaw_speed = 10;
+ this.view_ofs = '0 0 25';
+
+ this.flags = this.flags | FL_FLY;
+ this.flags = this.flags | FL_MONSTER;
+
+ if (!walkmove(0,0))
+ dprint (sprintf("base_flymonster::think_start: "
+ "monster in awll at %v\n", this.origin));
+
+ if (this.target != "")
+ {
+ this.goalentity = this.movetarget = find (world,
+ ::targetname, this.target);
+ if (!this.movetarget)
+ dprint (sprintf("base_flymonster::monster_think"
+ "_start: monster can't find target at "
+ "%v\n", this.origin));
+
+ // this used to be an objerror
+ if (this.movetarget.classtype == CT_PATH_CORNER)
+ {
+ this.think_walk ();
+ }
+ else
+ {
+ this.pausetime = 99999999;
+ this.think_stand ();
+ }
+ }
+ else
+ {
+ this.pausetime = 99999999;
+ this.think_stand ();
+ }
+
+ // 1998-08-14 Monsters sometimes don't move fix by Lord Sméagol
+ this.nextthink = time + 0.1 + random() * 0.5;
+
+ // dumptruck_ds -- using spawn_angry set to 1 in order to spawn
+ // in "angry" monsters
+ // if ((this.spawnflags & 8) && this.spawn_angry == 1)
+ // {
+ // monster_use ();
+ // }
+
+ // dumptruck_ds -- this is Shamblernaut's method
+ local entity pl;
+
+ pl = findfloat (world, ::classtype, CT_PLAYER);
+
+ if (this.spawn_angry == 1)
+ {
+ activator = pl;
+ this.use ();
+ }
+ };
+
+ //==============================================================
+ // Initialization
+ //==============================================================
+
+ //--------------------------------------------------------------
+ // flymonster_start
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
+ {
+ if (cvar("nomonsters"))
+ {
+ remove (this);
+ return;
+ }
+
+ super::init_spawned ();
+
+ // Preach's tutorial
+ if (init_teleport())
+ return;
+
+ // 1998-08-14 Monsters sometimes don't move fix by Lord Sméagol
+ this.flags = this.flags | FL_FLY;
+
+ total_monsters = total_monsters + 1;
+ this.think = this.think_start;
+ // spread think times so they don't all happen at same time
+ // 1998-08-14 Monsters sometimes don't move fix by
+ // Lord Sméagol start
+ // this.nextthink = this.nextthink + random() * 0.5;
+ this.nextthink = time + 0.1 + random() * 0.5;
+ // 1998-08-14 Monsters sometimes don't move fix by
+ // Lord Sméagol end
+ };
+};
+
+//------------------------------------------------------------------------------
+class base_swimmonster: base_monster
+{
+ //==============================================================
+ // Interaction
+ //==============================================================
+
+ //--------------------------------------------------------------
+ // swimmonster_start_go
+ //--------------------------------------------------------------
+ virtual void() think_start =
+ {
+ if (deathmatch)
+ {
+ remove (this);
+ return;
+ }
+
+ this.takedamage = DAMAGE_AIM;
+
+ this.ideal_yaw = this.angles * '0 1 0';
+ if (!this.yaw_speed)
+ this.yaw_speed = 10;
+ this.view_ofs = '0 0 10';
+
+ this.flags = this.flags | FL_SWIM;
+ this.flags = this.flags | FL_MONSTER;
+
+ if (this.target != "")
+ {
+ this.goalentity = this.movetarget = find (world,
+ ::targetname, this.target);
+ if (!this.movetarget)
+ {
+ dprint ("Monster can't find target at ");
+ dprint (vtos(this.origin));
+ dprint ("\n");
+ }
+ // this used to be an objerror
+ this.ideal_yaw = vectoyaw (
+ this.goalentity.origin - this.origin);
+ this.think_walk ();
+ }
+ else
+ {
+ this.pausetime = 99999999;
+ this.think_stand ();
+ }
+
+ // spread think times so they don't all happen at same time
+ // 1998-08-14 Monsters sometimes do not move fix
+ // by Lord Sméagol start
+ // this.nextthink = this.nextthink + random()*0.5;
+ this.nextthink = time + 0.1 + random() * 0.5;
+ // 1998-08-14 Monsters sometimes do not move fix
+ // by Lord Sméagol end
+
+ // dumptruck_ds -- using spawn_angry set to 1 in order to
+ // spawn in "angry" monsters
+ // if ((this.spawnflags & 8) && this.spawn_angry == 1)
+ // {
+ // monster_use ();
+ // }
+
+ // dumptruck_ds -- this is Shamblernaut's method
+ local entity pl;
+
+ pl = findfloat (world, ::classtype, CT_PLAYER);
+
+ if (this.spawn_angry == 1)
+ {
+ activator = pl;
+ this.use ();
+ }
+ };
+
+ //==============================================================
+ // Initialization
+ //==============================================================
+
+ //--------------------------------------------------------------
+ // swimmonster_start
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
+ {
+ if (cvar("nomonsters"))
+ {
+ remove (this);
+ return;
+ }
+
+ // 1998-08-14 Monsters sometimes don't move fix by Lord Sméagol
+ this.flags = this.flags | FL_SWIM;
+
+ super::init_spawned ();
+
+ // Preach's tutorial
+ if (init_teleport())
+ return;
+
+ total_monsters = total_monsters + 1;
+ this.think = this.think_start;
+ // spread think times so they don't all happen at same time
+ // 1998-08-14 Monsters sometimes do not move fix
+ // by Lord Sméagol start
+ // this.nextthink = this.nextthink + random() * 0.5;
+ this.nextthink = time + 0.1 + random() * 0.5;
+ // 1998-08-14 Monsters sometimes do not move fix
+ // by Lord Sméagol end
+ };
+};
+
+//------------------------------------------------------------------------------
+class base_walkmonster: base_monster
+{
+ //==============================================================
+ // Interaction
+ //==============================================================
+
+ //--------------------------------------------------------------
+ // walkmonster_start_go
+ //--------------------------------------------------------------
+ virtual void() think_start =
+ {
+ // raise off floor a bit
+ this.origin_z = this.origin_z + 1;
+
+ // Preach's "check" here
+
+ // if(time <= 0.5)
+ if(!(this.spawnflags & 8))
+ {
+ droptofloorwrapper (this);
+ if !(this.spawnflags & I_AM_TURRET)
+ {
+ // fixes an incorrect dprint
+ // -- dumptruck_ds
+ if (!walkmove(0,0))
+ {
+ dprint (sprintf("\n\n%s "
+ "in wall at: %v\n\n",
+ this.classname,
+ this.origin));
+ }
+ }
+ }
+
+ this.takedamage = DAMAGE_AIM;
+ this.ideal_yaw = this.angles * '0 1 0';
+ if (!this.yaw_speed)
+ this.yaw_speed = 20;
+ this.view_ofs = '0 0 25';
+ this.flags |= FL_MONSTER;
+
+ if (this.target != "")
+ {
+ this.goalentity = this.movetarget = find (
+ world, ::targetname, this.target);
+ this.ideal_yaw = vectoyaw (
+ this.goalentity.origin - this.origin);
+ if (!this.movetarget)
+ {
+ dprint (sprintf("base_walkmonster::"
+ "think: Monster can't find "
+ "target at %v\n", this.origin));
+ }
+
+ // this used to be an objerror
+ if (this.movetarget.classtype == CT_PATH_CORNER)
+ {
+ this.think_walk ();
+ }
+ else
+ {
+ this.pausetime = 99999999;
+ this.think_stand ();
+ }
+ }
+ else
+ {
+ this.pausetime = 99999999;
+ this.think_stand ();
+ }
+
+ // spread think times so they don't all happen at once
+ // 1998-08-14 Monsters sometimes do not move fix
+ // by Lord Sméagol start
+ // this.nextthink = this.nextthink + random() * 0.5;
+ this.nextthink = time + 0.1 + random() * 0.5;
+ // 1998-08-14 Monsters sometimes do not move fixx
+ // by Lord Sméagol end
+ // dumptruck_ds -- using spawn_angry set to 1 in
+ // order to spawn in "angry" monsters
+ // if ((this.spawnflags & 8) && this.spawn_angry == 1)
+ // {
+ // monster_use ();
+ // }
+
+ // dumptruck_ds -- this is Shamblernaut's method
+ local entity pl;
+
+ pl = findfloat (world, ::classtype, CT_PLAYER);
+
+ if (this.spawn_angry == 1)
+ {
+ activator = pl;
+ this.use ();
+ }
+ };
+
+ //==============================================================
+ // Initialization
+ //==============================================================
+
+ //--------------------------------------------------------------
+ // walkmonster_start
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
+ {
+ // Preach's tutorial
+ if (cvar("nomonsters"))
+ {
+ remove (this);
+ return;
+ }
+
+ super::init_spawned ();
+
+ // Preach's tutorial
+ if (init_teleport())
+ return;
+
+ // delay drop to floor to make sure all doors have been
+ // spawned spread think times so they don't all happen
+ // at same time
+
+ total_monsters = total_monsters + 1;
+ // not real keen on assigning & reassigning think -- CEV
+ this.think = this.think_start;
+ // 1998-08-14 Monsters sometimes do not move fix
+ // by Lord Sméagol start
+ // this.nextthink = this.nextthink + random() * 0.5;
+ this.nextthink = time + 0.1 + random() * 0.5;
+ // 1998-08-14 Monsters sometimes do not move fix
+ // by Lord Sméagol end
};
};
Return to the top of this page or return to the overview of this repo.
Diff qc/base_projectile.qc
diff --git a/qc/base_projectile.qc b/qc/base_projectile.qc
new file mode 100644
index 0000000..9553708
--- /dev/null
+++ b/qc/base_projectile.qc
@@ -0,0 +1,68 @@
+//==============================================================================
+// base_projectile.qc -- generated projectile entities
+//==============================================================================
+
+enum
+{
+ EXPLOSION_THINK_1, // explosion frame/think tracking
+ EXPLOSION_THINK_2,
+ EXPLOSION_THINK_3,
+ EXPLOSION_THINK_4,
+ EXPLOSION_THINK_5,
+ EXPLOSION_THINK_6,
+ EXPLOSION_THINK_REMOVE
+};
+
+//------------------------------------------------------------------------------
+class base_projectile: base_tempentity
+{
+ //--------------------------------------------------------------
+ void() base_projectile =
+ {
+ this.classgroup |= CG_PROJECTILE;
+ };
+};
+
+class base_explosion: base_tempentity
+{
+ float explosion_think_state;
+
+ //--------------------------------------------------------------
+ virtual void() think =
+ {
+ if (this.explosion_think_state == EXPLOSION_THINK_REMOVE)
+ {
+ remove (this);
+ return;
+ }
+
+ if (this.explosion_think_state == EXPLOSION_THINK_1)
+ this.frame = 0;
+ else
+ this.frame += 1;
+
+ this.explosion_think_state += 1;
+ this.nextthink = time + 0.1;
+ };
+
+ //--------------------------------------------------------------
+ virtual void() touch =
+ {
+ // sub_null - no-op
+ };
+
+ //--------------------------------------------------------------
+ void() base_explosion =
+ {
+ this.classtype = CT_TEMP_EXPLOSION;
+ this.movetype = MOVETYPE_NONE;
+ this.solid = SOLID_NOT;
+ if (this.origin == '0 0 0')
+ dprint ("base_explosion: spawned at zero origin\n");
+ setorigin (this, this.origin);
+ this.velocity = '0 0 0';
+ setmodel (this, "progs/s_explod.spr");
+ this.explosion_think_state = EXPLOSION_THINK_1;
+ this.think ();
+ };
+};
Return to the top of this page or return to the overview of this repo.
Diff qc/base_trigger.qc
diff --git a/qc/base_trigger.qc b/qc/base_trigger.qc
index 4b50ecb..774440f 100644
--- a/qc/base_trigger.qc
+++ b/qc/base_trigger.qc
@@ -5,10 +5,32 @@
//------------------------------------------------------------------------------
class base_trigger: base_mapentity
{
+ //==============================================================
+ // class fields
+ //==============================================================
+ float aflag;
+ float count;
+
// Supa, triggers, wait until activated before we can trigger?
float is_waiting;
float endwaiting;
+ //--------------------------------------------------------------
+ virtual void(string fieldname, string fieldvalue) init_field =
+ {
+ switch (fieldname)
+ {
+ case "count":
+ count = stof (fieldvalue);
+ break;
+ case "is_waiting":
+ is_waiting = stof (fieldvalue);
+ break;
+ default:
+ super::init_field (fieldname, fieldvalue);
+ }
+ };
+
//==============================================================
// Subs
//==============================================================
@@ -40,7 +62,7 @@ class base_trigger: base_mapentity
};
//--------------------------------------------------------------
- virtual void(entity caller) handle_use =
+ virtual void() use =
{
// SUB_EndWaiting -- CEV
if (this.is_waiting == TRUE && this.endwaiting == TRUE)
@@ -49,7 +71,7 @@ class base_trigger: base_mapentity
}
else
{
- super::handle_use (caller);
+ super::use ();
}
};
@@ -57,19 +79,6 @@ class base_trigger: base_mapentity
// Constructor & Spawn Functions
//==============================================================
- //--------------------------------------------------------------
- virtual void(string fieldname, string fieldvalue) init_field =
- {
- switch (fieldname)
- {
- case "is_waiting":
- is_waiting = stof (fieldvalue);
- break;
- default:
- super::init_field (fieldname, fieldvalue);
- }
- };
-
//--------------------------------------------------------------
// InitTrigger
//--------------------------------------------------------------
Return to the top of this page or return to the overview of this repo.
Diff qc/client/obituary.qc
diff --git a/qc/client/obituary.qc b/qc/client/obituary.qc
index 3a5ff7e..346b5e6 100644
--- a/qc/client/obituary.qc
+++ b/qc/client/obituary.qc
@@ -240,7 +240,7 @@ void(entity targ, entity inflictor, entity attacker) ClientObituary =
bprint (attacker.obit_method);
bprint (" by ");
// a bad monster
- bprint (attacker.obit_name);
+ bprint (attacker.obit_name);
bprint ("\n");
return;
}
Return to the top of this page or return to the overview of this repo.
Diff qc/client/playerspawn.qc
diff --git a/qc/client/playerspawn.qc b/qc/client/playerspawn.qc
index 9087969..fa73970 100644
--- a/qc/client/playerspawn.qc
+++ b/qc/client/playerspawn.qc
@@ -9,8 +9,34 @@ float modelindex_eyes, modelindex_player;
void() set_suicide_frame;
void() DecodeLevelParms;
void() PlayerDie;
-// 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten
-void() monster_touch;
+
+// 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten start
+/*
+================
+by: Philip Martin aka: Kryten
+When on top of monsters or players you slide. This is a QuakeC problem.
+The function below fixes that problem.
+based on code given to Kryten by: Michael Turitzin (MaNiAc)
+================
+*/
+void() monster_touch =
+{
+ //can cause problems for monsters on top of a player, so only players
+ if (other.classname != "player")
+ return;
+ if (other.health <= 0)
+ return;
+
+ if ((!(other.flags & FL_ONGROUND)) &&
+ ((other.absmin_z >= self.absmax_z - 2)))
+ {
+ other.flags = other.flags + FL_ONGROUND;
+ }
+
+ // you can add other stuff like pushable players/monsters here
+};
+// 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten end
+
//----------------------------------------------------------------------
// respawn -- called by ClientKill and DeadThink
@@ -148,6 +174,7 @@ float(entity to, float fl) SendPlayer =
WriteShort (MSG_ENTITY, self.velocity_x);
WriteShort (MSG_ENTITY, self.velocity_y);
WriteShort (MSG_ENTITY, self.velocity_z);
+ WriteFloat (MSG_ENTITY, self.effects);
WriteFloat (MSG_ENTITY, self.flags);
WriteFloat (MSG_ENTITY, self.pmove_flags);
WriteFloat (MSG_ENTITY, self.doublejump_timer);
Return to the top of this page or return to the overview of this repo.
Diff qc/combat.qc
diff --git a/qc/combat.qc b/qc/combat.qc
index 9606069..3ea5650 100644
--- a/qc/combat.qc
+++ b/qc/combat.qc
@@ -1,5 +1,9 @@
//==============================================================================
+// CEV: Contains the functions:
+//
+// CanDamage, Killed, T_Damage, T_RadiusDamage, T_BeamDamage
+
/*
============
CanDamage
@@ -88,7 +92,13 @@ void(entity targ, entity inflictor, entity attacker) Killed =
self.takedamage = DAMAGE_NO;
self.touch = sub_null;
- monster_death_use ();
+ // TODO CEV
+ if (targ.classgroup & CG_MONSTER)
+ {
+ ((base_monster)targ).sub_death_use ();
+ // monster_death_use ();
+ }
+
self.th_die ();
self = oself;
@@ -247,10 +257,17 @@ void(entity targ, entity inflictor, entity attacker, float damage) T_Damage=
targ.pain_target != "" &&
targ.health <= targ.pain_threshold)
{
+ // TODO CEV
+ /*
oldself = self;
self = targ;
monster_pain_use ();
self = oldself;
+ */
+ if (targ.classgroup & CG_MONSTER)
+ {
+ ((base_monster)targ).sub_pain_use ();
+ }
}
if (targ.health <= 0)
@@ -292,7 +309,21 @@ void(entity targ, entity inflictor, entity attacker, float damage) T_Damage=
if (self.enemy.classname == "player")
self.oldenemy = self.enemy;
self.enemy = attacker;
- FoundTarget ();
+ // TODO CEV
+ if (self.classgroup & CG_MONSTER)
+ {
+ local base_monster m =
+ (base_monster)self;
+ dprint ("T_Damage: calling ai_foundtarget\n");
+ m.ai_foundtarget ();
+ }
+ /*
+ else
+ {
+ // TODO CEV
+ FoundTarget ();
+ }
+ */
}
}
else if ((self.classname != attacker.classname) ||
@@ -310,17 +341,44 @@ void(entity targ, entity inflictor, entity attacker, float damage) T_Damage=
if (self.enemy.classname == "player")
self.oldenemy = self.enemy;
self.enemy = attacker;
- FoundTarget ();
+ // TODO CEV
+ if (self.classgroup & CG_MONSTER)
+ {
+ local base_monster m1 =
+ (base_monster)self;
+ dprint ("T_Damage: calling ai_foundtarget\n");
+ m1.ai_foundtarget ();
+ }
+ /*
+ else
+ {
+ // TODO CEV
+ FoundTarget ();
+ }
+ */
}
}
}
- if (self.th_pain)
+ // TODO CEV
+ if (self.classgroup & CG_MAPENTITY)
{
- self.th_pain (attacker, take);
- // nightmare mode monsters don't go into pain frames often
- if (skill == 3)
- self.pain_finished = time + 5;
+ // cast to base_mapentity -- CEV
+ // dprint (sprintf("T_Damage: calling do_damage on "
+ // "mapentity %s\n", self.classname));
+ local base_mapentity bme = (base_mapentity)self;
+ bme.do_damage (attacker, take);
+ }
+ else
+ {
+ if (self.th_pain)
+ {
+ self.th_pain (attacker, take);
+ // nightmare mode monsters don't go into pain
+ // frames often
+ if (skill == 3)
+ self.pain_finished = time + 5;
+ }
}
self = oldself;
Return to the top of this page or return to the overview of this repo.
Diff qc/cshift.qc
diff --git a/qc/cshift.qc b/qc/cshift.qc
index 86cd34f..527471a 100644
--- a/qc/cshift.qc
+++ b/qc/cshift.qc
@@ -37,11 +37,10 @@ void() csfcontroller_think =
if (self.pain_finished > time && e.csf_density != self.csf_density)
{
-
local float density, fraction;
local vector color;
- // wat
+ // wat
fraction = 1 - (self.pain_finished - time) / self.speed;
density = lerpHermite (e.csf_density, self.csf_density,
Return to the top of this page or return to the overview of this repo.
Diff qc/csqc/csqc_defsbuiltins.qc
diff --git a/qc/csqc/csqc_defsbuiltins.qc b/qc/csqc/csqc_defsbuiltins.qc
index 18eb713..8ac0e23 100644
--- a/qc/csqc/csqc_defsbuiltins.qc
+++ b/qc/csqc/csqc_defsbuiltins.qc
@@ -97,7 +97,7 @@ void(string var, string val) cvar_set = #72;
// Returns the angles (+x=UP) required to orient an entity to look in the
// given direction. The 'up' argument is required if you wish to set a roll
// angle, otherwise it will be limited to just monster-style turning.
-vector(vector fwd, optional vector up) vectoangles2 = #51;
+vector(vector fwd, optional vector up) vectoangles2 = #51;
float(float angle) sin = #60;
float(float angle) cos = #61;
float(float value) sqrt = #62;
@@ -107,7 +107,7 @@ string(entity ent) etos = #65;
// localinfo. If e is a player, returns the value of 'key' from the player's
// userinfo string. There are a few special exceptions, like 'ip' which is not
// technically part of the userinfo.
-string(entity e, string key) infokey = #80;
+string(entity e, string key) infokey = #80;
float(string) stof = #81;
#define unicast(pl,reli) do{msg_entity = pl; multicast('0 0 0', reli?MULITCAST_ONE_R:MULTICAST_ONE);}while(0)
// Once the MSG_MULTICAST network message buffer has been filled with data,
@@ -356,14 +356,14 @@ float(string name) checkcommand = #294;
// dpextensions+csprogsdefs from SVN ICCULUS site (DP trunk)
// fteexentions from triptohell website
// qsextensions from QSS devkit on triptohell website
-//
+//
// CSQC range #300-#399
//======================================================================
//----------------------------------------------------------------------
// DP/FTE extensions ONLY
//----------------------------------------------------------------------
-// Forgets all rentities, polygons, and temporary dlights.
+// Forgets all rentities, polygons, and temporary dlights.
// Resets all view properties to their default values.
void() clearscene = #300;
void(float mask) addentities = #301;
@@ -399,7 +399,7 @@ void(string texturename, float flag, ...) R_BeginPolygon = #306;
// Specifies a polygon vertex with its various properties
void(vector org, vector texcoords, vector rgb,
float alpha) R_PolygonVertex = #307;
-// Ends the current polygon. At least 3 verticies must have been
+// Ends the current polygon. At least 3 verticies must have been
// specified. You do not need to call beginpolygon if you wish to
// draw another polygon with the same shader
void() R_EndPolygon = #308;
@@ -421,14 +421,14 @@ vector (vector v) cs_project = #311;
// Draws a 2d line between the two 2d points
void(float width, vector pos1, vector pos2, vector rgb, float alpha,
float flag) drawline = #315;
-// Tells the engine that the image is no longer needed.
+// Tells the engine that the image is no longer needed.
// The image will appear to be new the next time its needed
void(string name) freepic = #319;
-// Draws the specified string without using any markup at all,
+// Draws the specified string without using any markup at all,
// even in engines that support it.
// If UTF-8 is globally enabled in the engine, then that encoding
// is used (without additional markup), otherwise it is raw quake chars.
-// Software engines may assume a size of '8 8 0', rgb='1 1 1',
+// Software engines may assume a size of '8 8 0', rgb='1 1 1',
// alpha=1, flag&3=0, but it is not an error to draw out of the screen.
float(vector position, string text, vector scale, vector rgb,
float alpha, float flag) drawstring = #321;
@@ -449,7 +449,7 @@ float loadfont(string fontname, string fontmaps, string sizes, float slot, float
//----------------------------------------------------------------------
// QSS (CSQC Lit) + DP/FTE extensions
//----------------------------------------------------------------------
-// Checks to see if the image is currently loaded.
+// Checks to see if the image is currently loaded.
// Engines might lie, or cache between maps.
float(string name) iscachedpic = #316;
// Forces the engine to load the named image. If trywad is specified,
@@ -459,15 +459,15 @@ string(string name, optional float trywad) precache_pic = #317;
// with .lmp should give the original .lmp's dimensions even if
// texture replacements use a different resolution.
// define = FTE version of DP version
-#define drawgetimagesize draw_getimagesize
+#define drawgetimagesize draw_getimagesize
vector(string picname) draw_getimagesize = #318;
// Draw the given quake character at the given position.
-// If flag&4, the function will consider the char to be a unicode
+// If flag&4, the function will consider the char to be a unicode
// char instead (or display as a ? if outside the 32-127 range).
// size should normally be something like '8 8 0'.
// rgb should normally be '1 1 1' and alpha normally 1.
// Software engines may assume the named defaults.
-// Note that ALL text may be rescaled on the X axis due to
+// Note that ALL text may be rescaled on the X axis due to
// variable width fonts. The X axis may even be ignored completely.
float(vector position, float character, vector scale, vector rgb,
float alpha, float flag) drawcharacter = #320;
@@ -477,14 +477,14 @@ float(vector position, float character, vector scale, vector rgb,
// flag = draw method; 0=normal, 1=additive, 2=modulate, 3=modulate2
float(vector position, string pic, vector size, vector rgb,
float alpha, float flag) drawpic = #322;
-// Draws a solid block over the given 2d box, with given colour,
+// Draws a solid block over the given 2d box, with given colour,
// alpha, and blend mode (specified via flags).
// flags&3=0 simple blend flags&3=1 additive blend
float(vector position, vector size, vector rgb,
float alpha, float flag) drawfill = #323;
// Specifies a 2d clipping region (aka: scissor test).
// 2d draw calls will all be clipped to this 2d box,
-// the area outside will not be modified by any
+// the area outside will not be modified by any
// 2d draw call (even 2d polygons).
void(float x, float y, float width, float height) drawsetcliparea = #324;
// Reverts the scissor/clip area to the whole screen
@@ -553,7 +553,7 @@ float(float stnum, optional float firstbit,
//----------------------------------------------------------------------
// QSS (CSQC Lit) + DP/FTE extensions
//----------------------------------------------------------------------
-// Sets a model by precache index instead of by name.
+// Sets a model by precache index instead of by name.
// Otherwise identical to setmodel.
void(entity e, float mdlindex) setmodelindex = #333;
// Part of DP_ENT_TRAILEFFECTNUM, FTE_SV_POINTPARTICLES
@@ -573,7 +573,7 @@ void(float effectnum, entity ent, vector start, vector end)
// Spawn a load of particles from the given effect at the given
// point traveling or aiming along the direction specified.
// The number of particles are scaled by the count argument.
-// For regular particles, the dir vector is multiplied by the
+// For regular particles, the dir vector is multiplied by the
// 'veladd' property (while orgadd will push the particles along it).
// Decals will use it as a hint to align to the correct surface.
// In both cases, it should normally be a unit vector, but other
@@ -587,7 +587,7 @@ void(string s, ...) csqc_centerprint = #338;
// Print into the center of the screen just as ssqc's centerprint
// would appear
void(string s, ...) cprint = #338;
-// This is identical to dprint except that it always prints
+// This is identical to dprint except that it always prints
// regardless of the developer cvar. Same number as in EXT_CSQC
// Unconditionally print on the local system's console, even in
// ssqc (doesn't care about the value of the developer cvar)
@@ -597,7 +597,7 @@ string(float keynum) keynumtostring = #340;
// Looks up the key name in the same way that the bind command would,
// returning the keycode for that key
float(string keyname) stringtokeynum = #341;
-// Returns the current binding for the given key (returning only the
+// Returns the current binding for the given key (returning only the
// command executed when no modifiers are pressed)
string(float key, float bindmap) getkeybind_bindmap = #342;
string(float keynum) getkeybind = #342;
@@ -661,7 +661,7 @@ float() readentitynum = #368;
// interchangable with readlong.
int() ReadInt = #0:readint;
-// Replaces the title of the game window, as seen when
+// Replaces the title of the game window, as seen when
// task switching or just running in windowed mode
void(string newcaption) setwindowcaption = #0;
Return to the top of this page or return to the overview of this repo.
Diff qc/csqc/csqc_defsclient.qc
diff --git a/qc/csqc/csqc_defsclient.qc b/qc/csqc/csqc_defsclient.qc
index 273784c..eab38d3 100644
--- a/qc/csqc/csqc_defsclient.qc
+++ b/qc/csqc/csqc_defsclient.qc
@@ -213,7 +213,7 @@ const float FL_ONGROUND = 512; // standing on something
const float FL_PARTIALGROUND = 1024; // not all corners are valid
const float FL_WATERJUMP = 2048; // player jumping out of water
const float FL_JUMPRELEASED = 4096; // for jump debouncing
-const float FL_DOUBLEJUMPED = 8192; // player has doublejumped
+const float FL_DOUBLEJUMPED = 8192; // player has doublejumped
const float FL_WALLJUMP = 16384; // player has jumped off a wall
const float FL_NOCENTERPRINT = 65536; // don't centerprint entity's message
// field when its targets are used
@@ -244,7 +244,7 @@ const float SOLID_CORPSE = 5; // supported extension
const float CONTENT_EMPTY = -1;
const float CONTENT_SOLID = -2;
const float CONTENT_WATER = -3;
-const float CONTENT_SLIME = -4;
+const float CONTENT_SLIME = -4;
const float CONTENT_LAVA = -5;
const float CONTENT_SKY = -6;
Return to the top of this page or return to the overview of this repo.
Diff qc/csqc/csqc_entrypoints.qc
diff --git a/qc/csqc/csqc_entrypoints.qc b/qc/csqc/csqc_entrypoints.qc
index cd40038..3b67765 100644
--- a/qc/csqc/csqc_entrypoints.qc
+++ b/qc/csqc/csqc_entrypoints.qc
@@ -58,7 +58,7 @@ void(string str) SV_ParseClientCommand =
// Search for tokens in string
tokenize_console (str);
// Find the first argument of the command
- cmd = argv (0);
+ cmd = argv (0);
// Is this my (AD CSQC) command?
if (cmd == CSQC_PING)
self.ext_csqc = TRUE;
@@ -107,7 +107,7 @@ void(float vwidth, float vheight, float notmenu) CSQC_UpdateView =
ssize_x = vwidth;
ssize_y = vheight;
ssize_z = 0;
-
+
// Is the CSQC functionality enabled/disabled?
nocsqc = cvar ("cl_nocsqc");
@@ -162,7 +162,7 @@ void(float vwidth, float vheight, float notmenu) CSQC_UpdateView =
// Revert back to using engine HUD?
if (nocsqc > 0)
return;
-
+
// Used on intermission screen later
if (!intermission)
intermission_time = time;
@@ -171,7 +171,7 @@ void(float vwidth, float vheight, float notmenu) CSQC_UpdateView =
// csprogs has no knowledge of the coop variable
deathmatch = stof (serverkey("deathmatch"));
coop = !deathmatch && maxclients > 1;
-
+
// Draw the HUDs and scoreboards
CSQC_DrawHud (ssize, sb_showscores);
CSQC_DrawScores (ssize, sb_showscores);
@@ -243,7 +243,7 @@ void(float isnew) CSQC_Ent_Update =
void(float apilevel, string enginename, float engineversion) CSQC_Init =
{
local float i, wadonly;
-
+
// Is the CSQC functionality enabled/disabled?
nocsqc = cvar ("cl_nocsqc");
// Revert back to using engine HUD?
@@ -252,12 +252,12 @@ void(float apilevel, string enginename, float engineversion) CSQC_Init =
// Send ping back to server that CSQC client is alive
// This can be used on the server side to detect CSQC
- // and change functions for new features
+ // and change functions for new features
localcmd (strcat("cmd ", CSQC_PING, "\n"));
-
+
// precache from gfx.wad ONLY!?!
wadonly = TRUE;
-
+
// Cache all string tables
for (i = 0; i < 14; i++)
{
@@ -312,7 +312,7 @@ __wrap void(float apilevel, string enginename, float engineversion) CSQC_Init =
{
// Execute previous CSQC_Init function
prior (apilevel, enginename, engineversion);
-
+
registercommand ("+showscores");
registercommand ("+showscores");
registercommand ("+showteamscores");
Return to the top of this page or return to the overview of this repo.
Diff qc/csqc/csqc_hudvanilla.qc
diff --git a/qc/csqc/csqc_hudvanilla.qc b/qc/csqc/csqc_hudvanilla.qc
index aea1207..cf4692d 100644
--- a/qc/csqc/csqc_hudvanilla.qc
+++ b/qc/csqc/csqc_hudvanilla.qc
@@ -4,14 +4,14 @@
/*======================================================================
All CSQC functions (Vanilla ONLY version)
-
+
* This file is heavily influenced by QSS devkit (credit=spike)
* re-written some functions to make better sense to me
* Contains all HUD elements for full quake interface (SP/Coop/Dm)
* Sripped out the experimental stuff included in devkit
* Converted most of the hardcoded values into constants
* Added loads of extra comments to show what is going on
-
+
======================================================================*/
// Default sizes for HUD elements
@@ -91,7 +91,7 @@ string ibrunes[4] =
//----------------------------------------------------------------------
// Special constants for weapons
float WPN_ICONS = 7; // Total weapons to precache pics + flash timers
-float WPN_WIDTHLG = 6; // Odd weapon gfx width (48) default (24)
+float WPN_WIDTHLG = 6; // Odd weapon gfx width (48) default (24)
// Record when weapons have been added (flash mechanic)
float flashtime[WPN_ICONS];
@@ -115,7 +115,7 @@ string wpnflash[5] =
//----------------------------------------------------------------------
// Frame 00-04 : Regular HP 100/80/60/40/20
// Frame 05-09 : InPain HP 100/80/60/40/20
-// Frame 10 : Invisibility Ring + Pentagram!
+// Frame 10 : Invisibility Ring + Pentagram!
// Frame 11 : Quad Damage
// Frame 12 : Invisibility Ring
// Frame 13 : Pentagram (invulnerability)
@@ -153,7 +153,7 @@ void(vector pos, float value, float threshhold) Hud_DrawNoFont24 =
// Work out which number colour to use
if (value <= threshhold)
disp_col = TRUE;
-
+
while (disp_len > 0)
{
// Countdown early (range is 0-2, strlen returns 1-3)
@@ -176,8 +176,8 @@ void(vector pos, float value, float threshhold) Hud_DrawNoFont24 =
disp_str = number[disp_no];
// Draw number in correct (right-justified) position
- drawpic (pos, disp_str, HUDSIZE_24, HUDRGB_DEF, hudalpha, 0);
- }
+ drawpic (pos, disp_str, HUDSIZE_24, HUDRGB_DEF, hudalpha, 0);
+ }
};
//----------------------------------------------------------------------
@@ -236,11 +236,11 @@ void(vector pos, float value, float digit, float zerofill, float fontcol)
value = 99;
else if (value > 9 && digit <= 1)
value = 9;
-
+
// Round number down (floor) and work out length
val_str = ftos (floor(value));
disp_len = strlen (val_str);
-
+
// Zero fill number?
if (zerofill)
{
@@ -255,7 +255,7 @@ void(vector pos, float value, float digit, float zerofill, float fontcol)
// Move to the lowest digit position first
pos_x = pos_x + (digit * HUDSIZE_8_x);
-
+
while (disp_len > 0)
{
// Countdown first (digit positions = 0-2)
@@ -270,8 +270,8 @@ void(vector pos, float value, float digit, float zerofill, float fontcol)
disp_no = disp_no + 128;
// Draw character from ascii font table (right-justified)
drawcharacter (pos, disp_no, HUDSIZE_8, HUDRGB_DEF,
- hudalpha, 0);
- }
+ hudalpha, 0);
+ }
};
//----------------------------------------------------------------------
@@ -281,7 +281,7 @@ void(vector pos) Hud_DrawFace =
{
string face;
local float hpframe;
-
+
// Start with InvRing as it has two states
if (sitems & CSQC_INVISIBILITY)
{
@@ -321,7 +321,7 @@ void(vector pos) Hud_DrawFace =
// Final HP face
face = facetab[hpframe];
}
-
+
// Draw face - always 24x24 size, full rgb/alpha
drawpic (pos, face, HUDSIZE_24, HUDRGB_DEF, hudalpha, 0);
};
@@ -334,13 +334,13 @@ static void(float num, vector pos) Hud_DrawWeapon =
local string prefix, file_str;
local vector gfx_size;
local float flash;
-
+
// The weapon flash is done every 0.1s and repeated twice!
// When the player gets a new weapon the time is reset
// This function will count the time difference for flashing
// Convert the flash time to a 0-10+ range
flash = (time - flashtime[num]) * 10;
-
+
// Has the flash happened twice? (finished)
if (flash >= 10)
{
@@ -369,7 +369,7 @@ static void(float num, vector pos) Hud_DrawWeapon =
// This sorta assumes that CSQC is running on an advanced engine
// QSS/FTE/DP all support FTE_STRINGS extra str functions
file_str = strcat (prefix, wpnnames[num]);
-
+
// Most weapons are 24 pixels wide (half of ammo above)
// As always there is an exception (lightning gun)
if (num == WPN_WIDTHLG)
@@ -419,7 +419,7 @@ void (vector pos, vector virtsize) Hud_DrawSBar =
// Only update ammo type/quantity if not using axe!
if (sweapon != CSQC_AXE)
- {
+ {
Hud_DrawNoFont24 (pos + [248, 0], getstatf(CLIENT_AMMO), 10);
if (sitems & CSQC_SHELLS)
drawpic (pos + [224, 0], sbitems[0], HUDSIZE_24,
@@ -443,7 +443,7 @@ void (vector pos, vector br) Hud_DrawIBar =
{
local vector topcol, botcol;
local string player_frags;
-
+
// Draw background bar using scr_sbaralpha default
drawpic (pos, backgrd[1], HUDSIZE_320, HUDRGB_DEF, baralpha, 0);
@@ -512,7 +512,7 @@ void (vector pos, vector br) Hud_DrawIBar =
{
// Move to space above powerups
pos_x += 194;
-
+
// Loop through 4 players
for (float i = -1; i >= -4; i--)
{
@@ -539,7 +539,7 @@ void (vector pos, vector br) Hud_DrawIBar =
if (player_localentnum == stof(getplayerkeyvalue(
i, "viewentity")))
{
- // special characters = []
+ // special characters = []
drawcharacter (pos + [-4, 0], 0xe010,
HUDSIZE_8, HUDRGB_DEF, hudalpha, 0);
drawcharacter (pos + [24, 0], 0xe011,
@@ -560,7 +560,7 @@ void(vector pos, float bx, float by, float bwidth, float bheight,
{
local float str_width, str_double, str_speed;
local string wide_str;
-
+
// draw debug visual box to show area on screen
//drawfill (pos + [bx, by], [bwidth, bheight], HUDRGB_DEF, 0.1, 0);
@@ -605,7 +605,7 @@ void(vector pos) Hud_QSScores_SBar =
{
local string skill_str, map_str;
local float digit;
-
+
// Clear status bar ready for map info/scores
drawpic (pos, backgrd[2], HUDSIZE_320, HUDRGB_DEF, baralpha, 0);
@@ -638,7 +638,7 @@ void(vector pos) Hud_QSScores_SBar =
// Display map skill level
skill_str = autocvar (skill, "1");
drawstring (pos + [180, 12], skill_str, HUDSIZE_8, HUDRGB_DEF,
- hudalpha, 0);
+ hudalpha, 0);
// Level designers Map name + File name
map_str = strcat (world.message, " (", mapname, ")");
@@ -651,7 +651,7 @@ void(vector pos) Hud_QSScores_SBar =
void(vector pos) Hud_IDScores_SBar =
{
local float nsecs, nmins;
-
+
// Clear status bar ready for map info/scores
drawpic (pos, backgrd[2], HUDSIZE_320, HUDRGB_DEF, baralpha, 0);
// Display headings
@@ -701,13 +701,13 @@ void(string picname, float scrwidth, vector pos, float height) Hud_CentrePic =
//----------------------------------------------------------------------
void(vector virtmin, vector virtsize) Hud_DMScoreboard =
{
- local float isspec;
+ local float isspec;
local vector pos, topcol, botcol;
string player_name, player_frags, player_ping;
-
+
// Working copy
pos = virtmin;
-
+
// Check for 16 players?
player_name = getplayerkeyvalue (-16, "name");
if (player_name == "")
@@ -716,7 +716,7 @@ void(vector virtmin, vector virtsize) Hud_DMScoreboard =
// Only draw the header when its not a really big game
player_name = getplayerkeyvalue (-24, "name");
if (player_name == "")
- {
+ {
pos_y += 8;
// Display header (ranking.lmp) gfx for DM scoreboard
Hud_CentrePic (backlmp[0], virtsize_x, pos, 24);
@@ -737,7 +737,7 @@ void(vector virtmin, vector virtsize) Hud_DMScoreboard =
// No more in list, end loop
if (player_name == "")
break;
-
+
// Read player stats (frag/ping)
isspec = stof (getplayerkeyvalue(i, "*spectator"));
player_frags = getplayerkeyvalue (i, "frags");
@@ -745,13 +745,13 @@ void(vector virtmin, vector virtsize) Hud_DMScoreboard =
// Read deathmatch player top/bottom skin colours
topcol = stov (getplayerkeyvalue(i, "topcolor_rgb"));
botcol = stov (getplayerkeyvalue(i, "bottomcolor_rgb"));
-
+
// Re-format the player name (no case conversion, force red)
player_name = strconv (0,2,2, player_name);
// Draw frag score (New global small font function)
Hud_DrawNoFont8 (pos - [8 * 5, 0], stof(player_ping), 3,
FALSE, HUDFONT_WHITE);
-
+
// Which type of player? Spectator or Active?
if (isspec)
{
@@ -763,7 +763,7 @@ void(vector virtmin, vector virtsize) Hud_DMScoreboard =
// Draw skin colours (alpha was 0.75 hardcoded)
drawfill (pos + [0, 0], [40, 4], topcol, 0.75, 0);
drawfill (pos + [0, 4], [40, 4], botcol, 0.75, 0);
-
+
// Draw frag score (New global small font function)
Hud_DrawNoFont8 (pos + [8, 0], stof(player_frags), 3,
FALSE, HUDFONT_WHITE);
@@ -771,7 +771,7 @@ void(vector virtmin, vector virtsize) Hud_DMScoreboard =
if (player_localentnum == stof(getplayerkeyvalue(i,
"viewentity")))
{
- // special characters = []
+ // special characters = []
drawcharacter (pos + [0, 0], 0xe010,
HUDSIZE_8, HUDRGB_DEF, hudalpha, 0);
drawcharacter (pos + [32, 0], 0xe011,
@@ -796,7 +796,7 @@ void(vector virtmin, vector virtsize) Hud_Intermission =
// Draw Intermission title and table info (Time/secret/kill)
Hud_CentrePic (backlmp[1], 320, pos + [0, 24], 24);
drawpic (pos + [0,56], backlmp[2], [160,144], HUDRGB_DEF, hudalpha, 0);
-
+
// Generate complete string and then draw 1 character at time
// Uses Sprintf function to feed values into final string
// This function should be supported by Advanced engines
@@ -849,7 +849,7 @@ void(vector virtsize, float showscores) CSQC_DrawHud =
// The downside to this bitswapping mess is that the serverflags
// is not passed to CSQC completely, only the first 4bits (runes)
//------------------------------------------------------------------
- sitems = getstatbits (CLIENT_ITEMS, 0, 23);
+ sitems = getstatbits (CLIENT_ITEMS, 0, 23);
sitems2 = getstatbits (CLIENT_ITEMS, 23, 9);
sweapon = getstatf (CLIENT_ACTIVEWEAPON);
shealth = getstatf (CLIENT_HEALTH);
@@ -857,7 +857,7 @@ void(vector virtsize, float showscores) CSQC_DrawHud =
// Don't show HUD, intermission or dead
if (intermission || shealth <= 0)
return;
-
+
//--------------------------------------------------------------
// Read console variable for background HUD alpha
baralpha = cvar ("scr_sbaralpha");
Return to the top of this page or return to the overview of this repo.
Diff qc/csqc/csqc_player.qc
diff --git a/qc/csqc/csqc_player.qc b/qc/csqc/csqc_player.qc
index f8cb736..e40527f 100644
--- a/qc/csqc/csqc_player.qc
+++ b/qc/csqc/csqc_player.qc
@@ -223,6 +223,7 @@ void(float isnew) PlayerUpdate =
self.velocity_x = ReadShort ();
self.velocity_y = ReadShort ();
self.velocity_z = ReadShort ();
+ self.effects = ReadFloat ();
self.flags = ReadFloat ();
self.pmove_flags = ReadFloat ();
self.doublejump_timer = ReadFloat ();
Return to the top of this page or return to the overview of this repo.
Diff qc/csqc/csqc_progs.src
diff --git a/qc/csqc/csqc_progs.src b/qc/csqc/csqc_progs.src
index 9417653..e17ac97 100644
--- a/qc/csqc/csqc_progs.src
+++ b/qc/csqc/csqc_progs.src
@@ -22,5 +22,5 @@ csqc_defs.qc // from Sock's AD CSQC
../player/pmove.qc // player movement code
csqc_player.qc // player handling
csqc_hudvanilla.qc // HUD
-csqc_entrypoints.qc //
+csqc_entrypoints.qc //
#endlist
Return to the top of this page or return to the overview of this repo.
Diff qc/defs_builtins.qc
diff --git a/qc/defs_builtins.qc b/qc/defs_builtins.qc
index 9b00489..bb03db5 100644
--- a/qc/defs_builtins.qc
+++ b/qc/defs_builtins.qc
@@ -7,7 +7,7 @@ void(entity e, vector o) setorigin = #2;
void(entity e, string m) setmodel = #3; // set movetype and solid first
void(entity e, vector min, vector max) setsize = #4;
// #5 was removed
-void() break = #6;
+void() breakpoint = #6;
float() random = #7; // returns 0 - 1
void(entity e, float chan, string samp, float vol, float atten) sound = #8;
vector(vector v) normalize = #9;
@@ -190,7 +190,7 @@ float(float value, float exp) pow = #97;
// Part of DP_QC_FINDFLOAT
// Equivelent to the find builtin, but instead of comparing strings contents,
-// this builtin compares the raw values. This builtin requires multiple calls
+// this builtin compares the raw values. This builtin requires multiple calls
// in order to scan all entities - set start to the previous call's return
// value. world is returned when there are no more entities.
entity(entity start, .__variant fld, __variant match) findfloat = #98;
@@ -217,7 +217,7 @@ void(string s, ...) print = #339;
// Perform the engine's standard player movement prediction upon the given
// entity using the input_* globals to describe movement.
void(entity ent) runstandardplayerphysics = #347;
-
+
// Look up a key in the server's public serverinfo string
string(string key) serverkey = #354;
@@ -231,7 +231,7 @@ float(float s) asin = #471;
float(float c) acos = #472;
float(float t) atan = #473;
float(float c, float s) atan2 = #474;
-// float(float a) tan = #475;
+float(float a) tan = #475;
// Part of DP_QC_SPRINTF
string(string fmt, ...) sprintf = #627;
Return to the top of this page or return to the overview of this repo.
Diff qc/defs_classtype.qc
diff --git a/qc/defs_classtype.qc b/qc/defs_classtype.qc
index eb0e508..1e4cbcf 100644
--- a/qc/defs_classtype.qc
+++ b/qc/defs_classtype.qc
@@ -1,5 +1,5 @@
//=============================================================================
-// CLASSTYPES
+// CLASSTYPES -- inspired by the system used in Arcane Dimensions -- CEV
//=============================================================================
// fields
@@ -54,7 +54,7 @@ enum
CT_FUNC_ROTATE_ENTITY, // Hipnotic rotation
CT_FUNC_ROTATE_TRAIN, // Hipnotic rotation
CT_FUNC_SHADOW, // pd3 func_shadow
- CT_FUNC_TOGGLEVISIBLEWALL, // pd3(?) togglevisiblewall
+ CT_FUNC_TOGGLEVISIBLEWALL, // pd3(?) togglevisiblewall
CT_FUNC_TOGGLEWALL, // Hipnotic func_togglewall
CT_FUNC_TRAIN, // id1 train
CT_FUNC_WALL, // func_wall
@@ -166,6 +166,25 @@ enum
CT_MISC_TELE_FOG, // pd3 play
CT_MISC_TELEPORTTRAIN, // id1 teleport train
+ // monsters
+ CT_MONSTER_BOSS_CHTHON, // id1 chthon
+ CT_MONSTER_BOSS_CHTHON2, // pd3 killable chthon
+ CT_MONSTER_BOSS_OLDONE, // id1 shub
+ CT_MONSTER_BOSS_OLDONE2, // pd3 killable shub
+ CT_MONSTER_DEATHKNIGHT, // id1 hell knight / death knight
+ CT_MONSTER_DOG, // id1 dog / pupper
+ CT_MONSTER_ENFORCER, // id1 enforcer
+ CT_MONSTER_FIEND, // id1 demon1 / fiend / jumpy friend
+ CT_MONSTER_FISH, // id1 fishies
+ CT_MONSTER_GRUNT, // id1 army / grunt / soldier
+ CT_MONSTER_KNIGHT, // id1 knights
+ CT_MONSTER_OGRE, // id1 ogres
+ CT_MONSTER_OGRE_MARKSMAN, // id1 ogre marksman
+ CT_MONSTER_SCRAG, // id1 wizard / scrag
+ CT_MONSTER_SHAMBLER, // id1 shambler
+ CT_MONSTER_VORE, // id1 shalrath / vore
+ CT_MONSTER_ZOMBIE, // id1 zombie
+
// paths
CT_PATH_CORNER, // id1 path_corner
CT_PATH_ROTATE, // Hipnotic rotation
@@ -173,8 +192,8 @@ enum
// targets
CT_TARGET_AUTOSAVE, // target_autosave from copper
CT_TARGET_FOGBLEND, // fog
- CT_TARGET_SETCOUNT, //
- CT_TARGET_SETSTATE, //
+ CT_TARGET_SETCOUNT, //
+ CT_TARGET_SETSTATE, //
CT_TARGET_TEXTSTORY, // progs_dump textstory
CT_TARGET_TEXTSTORY_HELPER, // textstory helper subclass
@@ -218,6 +237,7 @@ enum
CT_TEMP_BUBBLES, // air bubble
CT_TEMP_DELAYEDUSE, // delayed sub_usetargets
CT_TEMP_DOOR_TRIGGER, // id1 doors
+ CT_TEMP_EXPLOSION, // id1 explosions (BecomeExplosion)
CT_TEMP_FALL2_HELPER, // RennyC & whirledtsar fall2
CT_TEMP_FIREBALL, // created by misc_fireball
CT_TEMP_FOG_CONTROLLER, // pd3 fog
@@ -236,6 +256,7 @@ enum
//----------------------------------------------------------------------
// classgroups, defined as needed; I did not want to do this -- CEV
// go no higher than 24 bits (according to the FTEQCC manual) -- CEV
+// current count: 18 -- CEV
//----------------------------------------------------------------------
enumflags
{
Return to the top of this page or return to the overview of this repo.
Diff qc/defs_misc.qc
diff --git a/qc/defs_misc.qc b/qc/defs_misc.qc
index 8c590f7..ff1db1d 100644
--- a/qc/defs_misc.qc
+++ b/qc/defs_misc.qc
@@ -326,9 +326,8 @@ float AS_TURRET = 5;
//======================================================================
.float wait; // time from firing to restarting
.float delay; // time from activation to firing
-.entity trigger_field; // door's trigger entity
+.entity trigger_field; // TODO CEV: cutscene, shambler
.string noise4;
-.float aflag;
.float dmg; // damage done by door when hit
//======================================================================
@@ -361,12 +360,7 @@ float AS_TURRET = 5;
//======================================================================
// plats / doors / buttons
//======================================================================
-.float lip;
.float state;
-.vector pos1, pos2; // top and bottom positions
-
-// TODO CEV
-.float height;
//======================================================================
// fog // progs_dump
@@ -420,29 +414,28 @@ string lastnameused; // the targetname that was last used
// .float is_waiting; // Supa, triggers, wait until activated
// before we can trigger?
.float gravity; // from custdefs.qc by way of Hipnotic
-float STAT_TOTALMONSTERS = 12; // required by Hipnotic code
+const float STAT_TOTALMONSTERS = 12; // required by Hipnotic code
// dumptruck_ds from Rogue eod defs
/*============================================================================
johnfitz new defs from Rubicon2
============================================================================*/
-float BREAKABLE_NO_MONSTERS = 1;
+const float BREAKABLE_NO_MONSTERS = 1;
.float wantedgravity; // thanks Spike!
// .float ladder_step_finished; // footsteps on ladder -- dumptruck_ds
// TODO CEV keep these
.float alpha; // translucency in supported engines
-.vector colormod; // Provides a colour tint for the entity
-.vector glowmod; // make 'em glow
+.vector pos1; // used by some func_ classes; vector
+.vector pos2; // fields seem to cause problems.
// TODO CEV check these
.float pain_threshold; // dumptruck_ds
.string pain_target; // dumptruck_ds
.float color; // Hipnotic
.float megahealth_rottime; // dumptruck_ds
-.float style2; // c0burn's switchable lights
.float sight_trigger; // dumptruck_ds
.float keep_ammo; // dumptruck_ds
.float berserk; // dumptruck_ds
@@ -497,8 +490,8 @@ float mindex_inviso; // Invisible (null sprite)
.float drop_item; // key DropStuff
-float SPAWN_SILENTLY = 2097152;
-float TRIGGER_CENTERPRINTALL = 1048576;
+const float SPAWN_SILENTLY = 2097152;
+const float TRIGGER_CENTERPRINTALL = 1048576;
// entity state
.float estate;
@@ -513,7 +506,7 @@ nosave float gamestarted;
.float last_setstate_frame = light_lev;
.entity last_setstate = aiment;
-float I_AM_TURRET = 262144; // dumptruck_ds
+const float I_AM_TURRET = 262144; // dumptruck_ds
.void() th_turret;
// TODO CEV
@@ -531,7 +524,7 @@ float I_AM_TURRET = 262144; // dumptruck_ds
// TODO CEV shadows
.float switchshadstyle;
.float shadowoff;
-.entity shadowcontroller;
+// .entity shadowcontroller;
// worldspawn default mdls
.string h_vial_mdl;
Return to the top of this page or return to the overview of this repo.
Diff qc/fight.qc
diff --git a/qc/fight.qc b/qc/fight.qc
index ad9f9bd..b86bfd1 100644
--- a/qc/fight.qc
+++ b/qc/fight.qc
@@ -1,46 +1,93 @@
/*
-
A monster is in fight mode if it thinks it can effectively attack its
enemy.
When it decides it can't attack, it goes into hunt mode.
+*/
+
+float enemy_vis, enemy_infront, enemy_range, enemy_yaw;
+
+//============================================================================
+
+/*
+===========
+OgreCheckAttack
+The player is in view, so decide to move or launch an attack
+Returns FALSE if movement should continue
+============
*/
+float() OgreCheckAttack =
+{
+ local vector spot1, spot2;
+ local entity targ;
+ local float chance;
-float(float v) anglemod;
+ // dprint("OgreCheckAttack\n");
+ // dumptruck_ds
+ if (self.spawnflags & I_AM_TURRET)
+ {
+ self.attack_state = AS_MISSILE;
+ SUB_AttackFinished (2 + 2 * random());
+ return TRUE;
+ }
-void() knight_atk1;
-void() knight_runatk1;
-void() ogre_smash1;
-void() ogre_swing1;
+ if (enemy_range == RANGE_MELEE)
+ {
+ if (CanDamage (self.enemy, self))
+ {
+ self.attack_state = AS_MELEE;
+ return TRUE;
+ }
+ }
-void() sham_smash1;
-void() sham_swingr1;
-void() sham_swingl1;
+ if (time < self.attack_finished)
+ return FALSE;
-float() DemonCheckAttack;
-void(float side) Demon_Melee;
+ if (!enemy_vis)
+ return FALSE;
-void(vector dest) ChooseTurn;
+ targ = self.enemy;
-void() ai_face;
+ // see if any entities are in the way of the shot
+ spot1 = self.origin + self.view_ofs;
+ spot2 = targ.origin + targ.view_ofs;
+ traceline (spot1, spot2, FALSE, self);
-float enemy_vis, enemy_infront, enemy_range;
-float enemy_yaw;
-void() zombie_turret_missile;
+ if (trace_inopen && trace_inwater)
+ // sight line crossed contents
+ return FALSE;
-void() knight_attack =
-{
- local float len;
+ if ((self.spawnflags & I_AM_TURRET) && (trace_ent != targ))
+ {
+ // dprint("trace_ent...\n");
+ self.attack_state = AS_TURRET;
+ return FALSE;
+ }
+
+ if (trace_ent != targ)
+ // don't have a clear shot
+ return FALSE;
-// decide if now is a good swing time
- len = vlen(self.enemy.origin+self.enemy.view_ofs - (self.origin+self.view_ofs));
- if (len<80)
- knight_atk1 ();
+ // missile attack
+ if (time < self.attack_finished)
+ return FALSE;
+
+ if (enemy_range == RANGE_FAR)
+ return FALSE;
+
+ else if (enemy_range == RANGE_NEAR)
+ chance = 0.10;
+ else if (enemy_range == RANGE_MID)
+ chance = 0.05;
else
- knight_runatk1 ();
+ chance = 0;
+
+ self.attack_state = AS_MISSILE;
+ SUB_AttackFinished (1 + 2 * random());
+ return TRUE;
};
//=============================================================================
@@ -55,55 +102,55 @@ Returns FALSE if movement should continue
*/
float() CheckAttack =
{
- local vector spot1, spot2;
+ local vector spot1 = '0 0 0';
+ local vector spot2 = '0 0 0';
local entity targ;
local float chance;
- // silence a compiler warning -- CEV
- spot1 = spot2 = '0 0 0';
-
- if (self.spawnflags & I_AM_TURRET) //dumptruck_ds
+ // dumptruck_ds
+ if (self.spawnflags & I_AM_TURRET)
+ {
+ // dprint("CheckAttack...\n");
+ if (self.classname == "monster_enforcer")
+ {
+ if (self.style == 4)
+ {
+ // lightning can only go so far
+ if (vlen(spot1 - spot2) > 900)
+ return FALSE;
+ }
+ self.attack_state = AS_MISSILE;
+ }
+ else if (self.classname == "monster_hell_knight")
+ {
+ if (self.style == 1)
+ {
+ // lightning can only go so far
+ if (vlen(spot1 - spot2) > 900)
+ return FALSE;
+ }
+ // self.attack_state = AS_MISSILE;
+ self.th_turret ();
+ }
+ else if (self.classname == "monster_shalrath")
+ {
+ self.th_turret ();
+ }
+ /*
+ else if (self.classname == "monster_zombie")
{
// dprint("CheckAttack...\n");
- if ((self.classname) == ("monster_enforcer"))
- {
- if (self.style == 4) // lightning can only go so far
- {
- if (vlen(spot1 - spot2) > 900)
- {
- return FALSE;
- }
- }
- self.attack_state = AS_MISSILE;
- }
- else if ((self.classname) == ("monster_hell_knight"))
- {
- if (self.style == 1) // lightning can only go so far
- {
- if (vlen(spot1 - spot2) > 900)
- {
- return FALSE;
- }
- }
- // self.attack_state = AS_MISSILE;
- self.th_turret ();
- }
- else if ((self.classname) == ("monster_shalrath"))
- {
- self.th_turret ();
- }
- else if ((self.classname) == ("monster_zombie"))
- {
- // dprint("CheckAttack...\n");
- zombie_turret_missile();
- }
- SUB_AttackFinished (2*random());
- return TRUE;
+ // TODO CEV commented this out; this file to be deleted
+ // zombie_turret_missile ();
}
+ */
+ SUB_AttackFinished (2 * random());
+ return TRUE;
+ }
targ = self.enemy;
-// see if any entities are in the way of the shot
+ // see if any entities are in the way of the shot
spot1 = self.origin + self.view_ofs;
spot2 = targ.origin + targ.view_ofs;
@@ -117,24 +164,30 @@ float() CheckAttack =
}
if (trace_inopen && trace_inwater)
- return FALSE; // sight line crossed contents
+ // sight line crossed contents
+ return FALSE;
if (trace_ent != targ)
- return FALSE; // don't have a clear shot
+ // don't have a clear shot
+ return FALSE;
if (enemy_range == RANGE_MELEE)
- { // melee attack
+ {
+ // melee attack
if (self.th_melee)
{
+ // TODO CEV
+ /*
if (self.classname == "monster_knight")
knight_attack ();
else
+ */
self.th_melee ();
return TRUE;
}
}
-// missile attack
+ // missile attack
if (!self.th_missile)
return FALSE;
@@ -164,19 +217,20 @@ float() CheckAttack =
chance = 0.1;
}
else
+ {
chance = 0;
+ }
- if (random () < chance)
+ if (random() < chance)
{
self.th_missile ();
- SUB_AttackFinished (2*random());
+ SUB_AttackFinished (2 * random());
return TRUE;
}
return FALSE;
};
-
/*
=============
ai_face
@@ -186,7 +240,7 @@ Stay facing the enemy
*/
void() ai_face =
{
- self.ideal_yaw = vectoyaw(self.enemy.origin - self.origin);
+ self.ideal_yaw = vectoyaw (self.enemy.origin - self.origin);
ChangeYaw ();
};
@@ -197,31 +251,27 @@ ai_charge
The monster is in a melee attack, so get as close as possible to .enemy
=============
*/
-float (entity targ) visible;
-float(entity targ) infront;
-float(entity targ) range;
-
void(float d) ai_charge =
{
ai_face ();
- movetogoal (d); // done in C code...
+ // done in C code...
+ movetogoal (d);
};
void() ai_charge_side =
{
- local vector dtemp;
- local float heading;
+ local vector dtemp;
+ local float heading;
-// aim to the left of the enemy for a flyby
-
- self.ideal_yaw = vectoyaw(self.enemy.origin - self.origin);
+ // aim to the left of the enemy for a flyby
+ self.ideal_yaw = vectoyaw (self.enemy.origin - self.origin);
ChangeYaw ();
makevectors (self.angles);
- dtemp = self.enemy.origin - 30*v_right;
- heading = vectoyaw(dtemp - self.origin);
+ dtemp = self.enemy.origin - 30 * v_right;
+ heading = vectoyaw (dtemp - self.origin);
- walkmove(heading, 20);
+ walkmove (heading, 20);
};
@@ -233,11 +283,12 @@ ai_melee
*/
void() ai_melee =
{
- local vector delta;
- local float ldmg;
+ local vector delta;
+ local float ldmg;
if (!self.enemy)
- return; // removed before stroke
+ // removed before stroke
+ return;
delta = self.enemy.origin - self.origin;
@@ -248,264 +299,25 @@ void() ai_melee =
T_Damage (self.enemy, self, self, ldmg);
};
-
void() ai_melee_side =
{
- local vector delta;
- local float ldmg;
+ local vector delta;
+ local float ldmg;
if (!self.enemy)
- return; // removed before stroke
+ // removed before stroke
+ return;
- ai_charge_side();
+ ai_charge_side ();
delta = self.enemy.origin - self.origin;
if (vlen(delta) > 60)
return;
- if (!CanDamage (self.enemy, self))
+
+ if (!CanDamage(self.enemy, self))
return;
+
ldmg = (random() + random() + random()) * 3;
T_Damage (self.enemy, self, self, ldmg);
};
-
-
-//=============================================================================
-
-/*
-===========
-SoldierCheckAttack
-
-The player is in view, so decide to move or launch an attack
-Returns FALSE if movement should continue
-============
-*/
-float() SoldierCheckAttack =
-{
- local vector spot1, spot2;
- local entity targ;
- local float chance;
-
- // dprint("SoldierAttack\n");
- if (self.spawnflags & I_AM_TURRET) //dumptruck_ds
- {
- // self.th_turret ();
- self.attack_state = AS_MISSILE;
- SUB_AttackFinished (1 + random());
- if (random() < 0.3)
- self.lefty = !self.lefty;
- return TRUE;
- }
-
- targ = self.enemy;
-
-// see if any entities are in the way of the shot
- spot1 = self.origin + self.view_ofs;
- spot2 = targ.origin + targ.view_ofs;
-
- traceline (spot1, spot2, FALSE, self);
-
- if (trace_inopen && trace_inwater)
- return FALSE; // sight line crossed contents
-
- if ((self.spawnflags & I_AM_TURRET) && (trace_ent != targ))
- {
- // dprint("trace_ent...\n");
- self.attack_state = AS_TURRET;
- return FALSE;
- }
-
- if (trace_ent != targ)
- return FALSE; // don't have a clear shot
-
-// missile attack
- if (time < self.attack_finished)
- return FALSE;
-
- if (enemy_range == RANGE_FAR)
- return FALSE;
-
- if (enemy_range == RANGE_MELEE)
- chance = 0.9;
- else if (enemy_range == RANGE_NEAR)
- chance = 0.4;
- else if (enemy_range == RANGE_MID)
- chance = 0.05;
- else
- chance = 0;
-
- if (random () < chance)
- {
- self.th_missile ();
- SUB_AttackFinished (1 + random());
- if (random() < 0.3)
- self.lefty = !self.lefty;
-
- return TRUE;
- }
-
- return FALSE;
-};
-//=============================================================================
-
-/*
-===========
-ShamCheckAttack
-
-The player is in view, so decide to move or launch an attack
-Returns FALSE if movement should continue
-============
-*/
-float() ShamCheckAttack =
-{
- local vector spot1, spot2;
- local entity targ;
-
- if (enemy_range == RANGE_MELEE)
- {
- if (CanDamage (self.enemy, self))
- {
- self.attack_state = AS_MELEE;
- return TRUE;
- }
- }
-
- if (self.spawnflags & I_AM_TURRET)
- {
- self.attack_state = AS_MISSILE;
- SUB_AttackFinished (2 + 2*random());
- return TRUE;
- }
-
- if (time < self.attack_finished)
- return FALSE;
-
- if (!enemy_vis)
- return FALSE;
-
- targ = self.enemy;
-
-// see if any entities are in the way of the shot
- spot1 = self.origin + self.view_ofs;
- spot2 = targ.origin + targ.view_ofs;
-
-
- if (self.style == 0)
- {
- if (vlen(spot1 - spot2) > 600)
- return FALSE;
- }
- if (self.spawnflags & I_AM_TURRET)
- {
- if (vlen(spot1 - spot2) > 900)
- return FALSE;
- }
-
- // return FALSE;
-
- traceline (spot1, spot2, FALSE, self);
-
- if (trace_inopen && trace_inwater)
- return FALSE; // sight line crossed contents
-
- if ((self.spawnflags & I_AM_TURRET) && (trace_ent != targ))
- {
- // dprint("trace_ent...\n");
- self.attack_state = AS_TURRET;
- return FALSE;
- }
- if (trace_ent != targ)
- {
- return FALSE; // don't have a clear shot
- }
-
-// missile attack
- if (self.style == 0 && enemy_range == RANGE_FAR)
- return FALSE;
-
- self.attack_state = AS_MISSILE;
- SUB_AttackFinished (2 + 2*random());
- return TRUE;
-};
-
-//============================================================================
-
-/*
-===========
-OgreCheckAttack
-
-The player is in view, so decide to move or launch an attack
-Returns FALSE if movement should continue
-============
-*/
-float() OgreCheckAttack =
-{
- local vector spot1, spot2;
- local entity targ;
- local float chance;
-
- // dprint("OgreCheckAttack\n");
- if (self.spawnflags & I_AM_TURRET) //dumptruck_ds
- {
- self.attack_state = AS_MISSILE;
- SUB_AttackFinished (2 + 2*random());
- return TRUE;
- }
-
- if (enemy_range == RANGE_MELEE)
- {
- if (CanDamage (self.enemy, self))
- {
- self.attack_state = AS_MELEE;
- return TRUE;
- }
- }
-
- if (time < self.attack_finished)
- return FALSE;
-
- if (!enemy_vis)
- return FALSE;
-
- targ = self.enemy;
-
-// see if any entities are in the way of the shot
- spot1 = self.origin + self.view_ofs;
- spot2 = targ.origin + targ.view_ofs;
-
- traceline (spot1, spot2, FALSE, self);
-
- if (trace_inopen && trace_inwater)
- return FALSE; // sight line crossed contents
-
- if ((self.spawnflags & I_AM_TURRET) && (trace_ent != targ))
- {
- // dprint("trace_ent...\n");
- self.attack_state = AS_TURRET;
- return FALSE;
- }
-
- if (trace_ent != targ)
- {
- return FALSE; // don't have a clear shot
- }
-
-
-// missile attack
- if (time < self.attack_finished)
- return FALSE;
-
- if (enemy_range == RANGE_FAR)
- return FALSE;
-
- else if (enemy_range == RANGE_NEAR)
- chance = 0.10;
- else if (enemy_range == RANGE_MID)
- chance = 0.05;
- else
- chance = 0;
-
- self.attack_state = AS_MISSILE;
- SUB_AttackFinished (1 + 2*random());
- return TRUE;
-};
Return to the top of this page or return to the overview of this repo.
Diff qc/fteqcc.ini
diff --git a/qc/fteqcc.ini b/qc/fteqcc.ini
index a002034..9c62c09 100644
--- a/qc/fteqcc.ini
+++ b/qc/fteqcc.ini
@@ -189,7 +189,7 @@ flag debugmacros false # Print out the contents of macros that
# look inside macros that are expanded and is especially handy if
# people are using preprocessor hacks.
flag filetimes false # Recompiles the progs only if the file times are modified.
-flag fastarrays false # Generates extra instructions inside array handling functions to
+flag fastarrays true # Generates extra instructions inside array handling functions to
# detect engine and use extension opcodes only in supporting engines.
# Adds a global which is set by the engine if the engine supports
# the extra opcodes. Note that this applies to all arrays or none.
@@ -224,7 +224,7 @@ log off # Write out a compile log
enginebinary d:\Quakec\fteqw64.exe # Location of the engine binary to run. Change this to something
# else to run a different engine, but not all support debugging.
basedir d:\Quakec # The base directory of the game that contains your sub directory
-engineargs "-game progs_dump +exec fte.cfg"
+engineargs "-game progs_dump +exec fte.cfg"
# The engine commandline to use when debugging. You'll likely want
# to ensure this contains -window as well as the appropriate -game
# argument.
Return to the top of this page or return to the overview of this repo.
Diff qc/func/bob.qc
diff --git a/qc/func/bob.qc b/qc/func/bob.qc
index c9ccb3f..451c64b 100644
--- a/qc/func/bob.qc
+++ b/qc/func/bob.qc
@@ -13,7 +13,9 @@ class base_func_bob: base_func
// class fields
float attack_timer;
float bsporigin; // All bmodel origins are 0,0,0 check this first
+ float count;
float distance;
+ float height;
float waitmin2;
//--------------------------------------------------------------
@@ -27,9 +29,15 @@ class base_func_bob: base_func
case "bsporigin":
bsporigin = stof (fieldvalue);
break;
+ case "count":
+ count = stof (fieldvalue);
+ break;
case "distance":
distance = stof (fieldvalue);
break;
+ case "height":
+ height = stof (fieldvalue);
+ break;
case "waitmin2":
waitmin2 = stof (fieldvalue);
break;
@@ -95,7 +103,7 @@ class base_func_bob: base_func
//--------------------------------------------------------------
// was bob_timer -- CEV
//--------------------------------------------------------------
- virtual void(entity caller) do_think =
+ virtual void() do_think =
{
if (this.bsporigin)
this.nextthink = this.ltime + 0.1;
@@ -221,7 +229,7 @@ class func_bob: base_func_bob
{
bob_init ();
};
-
+
//--------------------------------------------------------------
void() func_bob =
{
Return to the top of this page or return to the overview of this repo.
Diff qc/func/breakable.qc
diff --git a/qc/func/breakable.qc b/qc/func/breakable.qc
index 3dfa51d..ba662a6 100644
--- a/qc/func/breakable.qc
+++ b/qc/func/breakable.qc
@@ -116,7 +116,7 @@ class base_breakable: base_func
};
//--------------------------------------------------------------
- virtual void() single_debris =
+ virtual void() single_debris =
{
local entity new;
@@ -278,7 +278,9 @@ class base_breakable: base_func
// this is broken as of 1.1.0 no custom explosion
// sound for now -- dumptruck_ds
// sound (this, CHAN_VOICE, this.noise2, 1, ATTN_NORM);
- remove (this);
+ // explode_silent removes (this) already -- CEV
+ if (this)
+ remove (this);
}
else
{
@@ -290,14 +292,16 @@ class base_breakable: base_func
if (this.switchshadstyle)
lightstyle(this.switchshadstyle, "m");
make_breakable_templates_debris ();
- remove (this);
+ if (this)
+ remove (this);
}
else
{
if (this.switchshadstyle)
lightstyle(this.switchshadstyle, "m");
make_breakable_debris ();
- remove (this);
+ if (this)
+ remove (this);
}
}
};
Return to the top of this page or return to the overview of this repo.
Diff qc/func/button.qc
diff --git a/qc/func/button.qc b/qc/func/button.qc
index c2a8829..ba03a5a 100644
--- a/qc/func/button.qc
+++ b/qc/func/button.qc
@@ -19,6 +19,25 @@ When a button is touched, it moves some distance in the direction of it's angle,
*/
class func_button: base_func
{
+ float lip;
+ /*
+ vector pos1;
+ vector pos2;
+ */
+
+ //--------------------------------------------------------------
+ virtual void(string fieldname, string fieldvalue) init_field =
+ {
+ switch (fieldname)
+ {
+ case "lip":
+ lip = stof (fieldvalue);
+ break;
+ default:
+ super::init_field (fieldname, fieldvalue);
+ }
+ };
+
//--------------------------------------------------------------
nonvirtual void() button_wait =
{
@@ -58,7 +77,7 @@ class func_button: base_func
//--------------------------------------------------------------
// was button_return -- CEV
//--------------------------------------------------------------
- virtual void(entity caller) do_think =
+ virtual void() do_think =
{
if (this.estate != STATE_ACTIVE)
return;
@@ -117,12 +136,12 @@ class func_button: base_func
if (b.state == FUNC_STATE_UP || b.state == FUNC_STATE_TOP)
b.prevstate = FUNC_STATE_TOP;
- else
+ else
b.prevstate = FUNC_STATE_BOTTOM;
if (b.max_health)
b.takedamage = DAMAGE_NO;
-
+
b.state = FUNC_STATE_UP;
b.calc_move (b.pos2, b.speed, b.button_wait);
b.estate = STATE_INACTIVE;
Return to the top of this page or return to the overview of this repo.
Diff qc/func/counter.qc
diff --git a/qc/func/counter.qc b/qc/func/counter.qc
index 6fcafa1..21ee4d4 100644
--- a/qc/func/counter.qc
+++ b/qc/func/counter.qc
@@ -46,12 +46,26 @@ it specifies how high to count before reseting to zero. Default is 10.
*/
class func_counter: base_func
{
+ float count;
float counter_on;
//--------------------------------------------------------------
- virtual void(entity caller) do_think =
+ virtual void(string fieldname, string fieldvalue) init_field =
{
- if (this.spawnflags & COUNTER_START_ON && caller != this)
+ switch (fieldname)
+ {
+ case "count":
+ count = stof (fieldvalue);
+ break;
+ default:
+ super::init_field (fieldname, fieldvalue);
+ }
+ };
+
+ //--------------------------------------------------------------
+ virtual void() do_think =
+ {
+ if (this.spawnflags & COUNTER_START_ON && other != this)
{
// was counter_start_on_think -- CEV
// fix func_counter and func_oncount handling of
@@ -141,7 +155,7 @@ class func_counter: base_func
}
else
{
- this.do_think (this);
+ this.do_think ();
}
};
@@ -208,6 +222,21 @@ reaches the value set by count, func_oncount triggers its targets.
*/
class func_oncount: base_func
{
+ float count;
+
+ //--------------------------------------------------------------
+ virtual void(string fieldname, string fieldvalue) init_field =
+ {
+ switch (fieldname)
+ {
+ case "count":
+ count = stof (fieldvalue);
+ break;
+ default:
+ super::init_field (fieldname, fieldvalue);
+ }
+ };
+
//--------------------------------------------------------------
virtual void(entity caller) do_use =
{
Return to the top of this page or return to the overview of this repo.
Diff qc/func/door.qc
diff --git a/qc/func/door.qc b/qc/func/door.qc
index 14fdb7c..bcee8f7 100644
--- a/qc/func/door.qc
+++ b/qc/func/door.qc
@@ -6,7 +6,7 @@
// Doors are similar to buttons, but can spawn a fat trigger field around
// them to open without a touch, and they link together to form simultaneous
// double/quad doors.
-//
+//
// Linked doors are a chain with prev_door and next_door being the previous
// and next links in that chain respectively. The chain is terminated when
// prev/next link connects to __NULL__ or back to self/this.
@@ -87,12 +87,30 @@ Key doors are always wait -1.
class func_door: base_func
{
float is_primary;
+ float lip;
float need_link;
+ /*
+ vector pos1;
+ vector pos2;
+ */
temp_door_trigger area_trig;
func_door prev_door;
func_door next_door;
misc_shadowcontroller shadow;
+ //--------------------------------------------------------------
+ virtual void(string fieldname, string fieldvalue) init_field =
+ {
+ switch (fieldname)
+ {
+ case "lip":
+ lip = stof (fieldvalue);
+ break;
+ default:
+ super::init_field (fieldname, fieldvalue);
+ }
+ };
+
//--------------------------------------------------------------
static float (entity e1, entity e2) entities_touching =
{
@@ -163,7 +181,7 @@ class func_door: base_func
this.state = FUNC_STATE_DOWN;
calc_move (this.pos1, this.speed, door_hit_bottom);
-
+
if (this.switchshadstyle && this.shadow)
{
if (this.spawnflags & DOOR_START_OPEN)
@@ -198,7 +216,7 @@ class func_door: base_func
calc_move (this.pos2, this.speed, door_hit_top);
sub_usetargets ();
-
+
if (this.switchshadstyle && this.shadow)
{
if (this.spawnflags & DOOR_START_OPEN)
@@ -244,7 +262,7 @@ class func_door: base_func
if (d.is_primary == FALSE)
objerror ("door_fire: called on non-primary door\n");
- if (d.estate != STATE_ACTIVE)
+ if (d.estate != STATE_ACTIVE)
return;
// noise4 is now played in keylock_try_to_unlock -- iw
@@ -267,7 +285,7 @@ class func_door: base_func
};
//--------------------------------------------------------------
- virtual void(entity caller) do_think =
+ virtual void() do_think =
{
if (this.need_link == TRUE)
this.link_doors ();
@@ -319,10 +337,10 @@ class func_door: base_func
//--------------------------------------------------------------
// door_unlock
- //
+ //
// Perform the actions which should be performed when this is
// successfully unlocked with a key.
- //
+ //
// This function exists so that it can be passed as an argument
// to the new keylock_try_to_unlock function. This code was
// previously part of the door_touch function. -- iw
@@ -452,7 +470,7 @@ class func_door: base_func
}
local func_door next;
-
+
if (d.estate == STATE_ACTIVE)
return;
@@ -679,7 +697,7 @@ class func_door: base_func
if (this.spawnflags & DOOR_SILVER_KEY)
{
keylock_set_silver_key ();
-
+
if (this.keyname != "")
{
this.netname = this.keyname;
Return to the top of this page or return to the overview of this repo.
Diff qc/func/door_secret.qc
diff --git a/qc/func/door_secret.qc b/qc/func/door_secret.qc
index 3f517a6..ab3df3f 100644
--- a/qc/func/door_secret.qc
+++ b/qc/func/door_secret.qc
@@ -43,7 +43,14 @@ class func_door_secret: base_func
};
//--------------------------------------------------------------
- virtual void(entity caller) do_think =
+ virtual void(entity attacker, float damage) do_damage =
+ {
+ if (this.takedamage == DAMAGE_YES)
+ this.do_use (other);
+ };
+
+ //--------------------------------------------------------------
+ virtual void() do_think =
{
switch (this.door_state)
{
@@ -92,7 +99,6 @@ class func_door_secret: base_func
{
this.health = 10000;
this.takedamage = DAMAGE_YES;
- this.th_pain = fd_secret_pain;
}
sound (this, CHAN_VOICE, this.noise3,
@@ -104,7 +110,7 @@ class func_door_secret: base_func
this.door_state));
}
- if (this.door_state < 4 ||
+ if (this.door_state < 4 ||
!(this.spawnflags & SECRET_OPEN_ONCE))
{
this.door_state++;
@@ -150,10 +156,7 @@ class func_door_secret: base_func
sub_usetargets ();
if (!(this.spawnflags & SECRET_NO_SHOOT))
- {
- this.th_pain = sub_nullpain;
this.takedamage = DAMAGE_NO;
- }
this.velocity = '0 0 0';
@@ -189,12 +192,6 @@ class func_door_secret: base_func
};
//--------------------------------------------------------------
- nonvirtual void(entity attacker, float damage) fd_secret_pain =
- {
- this.do_use (other);
- };
-
- //--------------------------------------------------------------
virtual void() init_spawned =
{
if (this.sounds == 0)
@@ -244,8 +241,6 @@ class func_door_secret: base_func
{
this.health = 10000;
this.takedamage = DAMAGE_YES;
- // TODO CEV
- this.th_pain = fd_secret_pain;
this.th_die = this.use;
}
Return to the top of this page or return to the overview of this repo.
Diff qc/func/elvtr_button.qc
diff --git a/qc/func/elvtr_button.qc b/qc/func/elvtr_button.qc
index ef8e3d5..10662ee 100644
--- a/qc/func/elvtr_button.qc
+++ b/qc/func/elvtr_button.qc
@@ -35,6 +35,25 @@ When a button is touched, it moves some distance in the direction of it's angle,
*/
class func_elvtr_button: base_func
{
+ float lip;
+ /*
+ vector pos1;
+ vector pos2;
+ */
+
+ //--------------------------------------------------------------
+ virtual void(string fieldname, string fieldvalue) init_field =
+ {
+ switch (fieldname)
+ {
+ case "lip":
+ lip = stof (fieldvalue);
+ break;
+ default:
+ super::init_field (fieldname, fieldvalue);
+ }
+ };
+
//--------------------------------------------------------------
nonvirtual void() elvtr_button_wait =
{
@@ -79,7 +98,7 @@ class func_elvtr_button: base_func
//--------------------------------------------------------------
// was elvtr_button_return -- CEV
//--------------------------------------------------------------
- virtual void(entity caller) do_think =
+ virtual void() do_think =
{
this.state = FUNC_STATE_DOWN;
calc_move (this.pos1, this.speed, elvtr_button_done);
Return to the top of this page or return to the overview of this repo.
Diff qc/func/explobox.qc
diff --git a/qc/func/explobox.qc b/qc/func/explobox.qc
index 85d2e75..33f0fae 100644
--- a/qc/func/explobox.qc
+++ b/qc/func/explobox.qc
@@ -27,7 +27,10 @@ class func_explobox: base_func
WriteCoord (MSG_BROADCAST, this.origin_x);
WriteCoord (MSG_BROADCAST, this.origin_y);
WriteCoord (MSG_BROADCAST, this.origin_z);
- BecomeExplosion ();
+ // BecomeExplosion
+ spawn (base_explosion, origin: this.origin);
+ if (this)
+ remove (this);
};
//--------------------------------------------------------------
@@ -38,7 +41,7 @@ class func_explobox: base_func
};
//--------------------------------------------------------------
- virtual void(entity caller) do_think =
+ virtual void() do_think =
{
// sound (this, CHAN_VOICE, "weapons/r_exp3.wav", 1, ATTN_NORM);
this.explode_silent ();
Return to the top of this page or return to the overview of this repo.
Diff qc/func/fall.qc
diff --git a/qc/func/fall.qc b/qc/func/fall.qc
index d924511..ba934c8 100644
--- a/qc/func/fall.qc
+++ b/qc/func/fall.qc
@@ -26,7 +26,7 @@ Falling brush upon touch
class func_fall: base_func
{
//--------------------------------------------------------------
- virtual void(entity caller) do_think =
+ virtual void() do_think =
{
if (this.cnt == TRUE && this.attack_finished < time)
{
Return to the top of this page or return to the overview of this repo.
Diff qc/func/fall2.qc
diff --git a/qc/func/fall2.qc b/qc/func/fall2.qc
index 17d8be0..80b1f4e 100644
--- a/qc/func/fall2.qc
+++ b/qc/func/fall2.qc
@@ -62,16 +62,40 @@ Able to .target other entities, including other func_fall2s
*/
class func_fall2: base_breakable
{
+ // class fields
+ float count;
+ float lip;
+ float thinkuse;
+ /*
+ vector pos1;
+ vector pos2;
+ */
+
// class fields: linker entity
temp_fall2_helper fall2_helper;
- float thinkuse;
//--------------------------------------------------------------
- virtual void(entity caller) do_think =
+ virtual void(string fieldname, string fieldvalue) init_field =
+ {
+ switch (fieldname)
+ {
+ case "count":
+ count = stof (fieldvalue);
+ break;
+ case "lip":
+ lip = stof (fieldvalue);
+ break;
+ default:
+ super::init_field (fieldname, fieldvalue);
+ }
+ };
+
+ //--------------------------------------------------------------
+ virtual void() do_think =
{
if (this.thinkuse == TRUE)
{
- this.do_use (caller);
+ this.do_use (other);
return;
}
// turn off quake engine splash sound
Return to the top of this page or return to the overview of this repo.
Diff qc/func/laser.qc
diff --git a/qc/func/laser.qc b/qc/func/laser.qc
index 325c169..5b76cc7 100644
--- a/qc/func/laser.qc
+++ b/qc/func/laser.qc
@@ -10,7 +10,7 @@ const float LASER_SOLID = 2;
class temp_laser_helper: base_tempentity
{
//--------------------------------------------------------------
- virtual void(entity caller) do_think =
+ virtual void() do_think =
{
if (!this.owner || this.owner.classtype != CT_FUNC_LASER)
{
Return to the top of this page or return to the overview of this repo.
Diff qc/func/monster_spawner.qc
diff --git a/qc/func/monster_spawner.qc b/qc/func/monster_spawner.qc
index 2e48b52..39c06c0 100644
--- a/qc/func/monster_spawner.qc
+++ b/qc/func/monster_spawner.qc
@@ -44,6 +44,24 @@ Can only use default health, models and sounds.
*/
class func_monster_spawner: base_func
{
+ float count;
+ float style2;
+
+ //--------------------------------------------------------------
+ virtual void(string fieldname, string fieldvalue) init_field =
+ {
+ switch (fieldname)
+ {
+ case "count":
+ count = stof (fieldvalue);
+ break;
+ case "style2":
+ style2 = stof (fieldvalue);
+ break;
+ default:
+ super::init_field (fieldname, fieldvalue);
+ }
+ };
//--------------------------------------------------------------
// find_spawnpoint -- Returns the entity to spawn at; was named
@@ -85,6 +103,8 @@ class func_monster_spawner: base_func
if (this.style == 1)
{
+ // TODO CEV
+ /*
// spawn a Doggo
// set size and shape
bot.solid = SOLID_SLIDEBOX;
@@ -115,10 +135,13 @@ class func_monster_spawner: base_func
bot.ideal_yaw = bot.angles * '0 1 0';
bot.yaw_speed = 120;
bot.view_ofs = '0 0 22';
+ */
}
if (this.style == 2)
{
+ // TODO CEV
+ /*
// spawn a Grunt
// set size and shape
bot.solid = SOLID_SLIDEBOX;
@@ -149,10 +172,13 @@ class func_monster_spawner: base_func
bot.ideal_yaw = bot.angles * '0 1 0';
bot.yaw_speed = 120;
bot.view_ofs = '0 0 22';
+ */
}
if (this.style == 3)
{
+ // TODO CEV
+ /*
// spawn an Enforcer
// set size and shape
bot.solid = SOLID_SLIDEBOX;
@@ -183,10 +209,13 @@ class func_monster_spawner: base_func
bot.ideal_yaw = bot.angles * '0 1 0';
bot.yaw_speed = 120;
bot.view_ofs = '0 0 22';
+ */
}
if (this.style == 4)
{
+ // TODO CEV
+ /*
// spawn an Ogre
// set size and shape
bot.solid = SOLID_SLIDEBOX;
@@ -217,10 +246,13 @@ class func_monster_spawner: base_func
bot.ideal_yaw = bot.angles * '0 1 0';
bot.yaw_speed = 120;
bot.view_ofs = '0 0 22';
+ */
}
if (this.style == 5)
{
+ // TODO CEV
+ /*
// spawn an Fiend
// set size and shape
bot.solid = SOLID_SLIDEBOX;
@@ -253,10 +285,13 @@ class func_monster_spawner: base_func
bot.ideal_yaw = bot.angles * '0 1 0';
bot.yaw_speed = 120;
bot.view_ofs = '0 0 22';
+ */
}
if (this.style == 6)
{
+ // TODO CEV
+ /*
// spawn a Wizard / Scrag
// set size and shape
bot.solid = SOLID_SLIDEBOX;
@@ -288,10 +323,13 @@ class func_monster_spawner: base_func
bot.yaw_speed = 120;
bot.view_ofs = '0 0 22';
bot.mdl_proj = "progs/w_spike.mdl";
+ */
}
if (this.style == 7)
{
+ // TODO CEV
+ /*
// spawn a Shambler
// set size and shape
bot.solid = SOLID_SLIDEBOX;
@@ -323,10 +361,13 @@ class func_monster_spawner: base_func
bot.yaw_speed = 120;
bot.view_ofs = '0 0 2';
// bot.view_ofs = '0 0 22';
+ */
}
if (this.style == 8)
{
+ // TODO CEV
+ /*
// spawn a Knight
// set size and shape
bot.solid = SOLID_SLIDEBOX;
@@ -357,10 +398,13 @@ class func_monster_spawner: base_func
bot.ideal_yaw = bot.angles * '0 1 0';
bot.yaw_speed = 120;
bot.view_ofs = '0 0 22';
+ */
}
if (this.style == 9)
{
+ // TODO CEV
+ /*
// spawn a HellKnight
// set size and shape
bot.solid = SOLID_SLIDEBOX;
@@ -391,10 +435,13 @@ class func_monster_spawner: base_func
bot.ideal_yaw = bot.angles * '0 1 0';
bot.yaw_speed = 120;
bot.view_ofs = '0 0 22';
+ */
}
if (this.style == 11)
{
+ // TODO CEV
+ /*
// spawn a Zombie
// set size and shape
bot.solid = SOLID_SLIDEBOX;
@@ -419,10 +466,13 @@ class func_monster_spawner: base_func
bot.yaw_speed = 120;
bot.view_ofs = '0 0 2';
// bot.view_ofs = '0 0 22';
+ */
}
if (this.style == 12)
{
+ // TODO CEV
+ /*
// spawn a Shalrath
// set size and shape
bot.solid = SOLID_SLIDEBOX;
@@ -455,8 +505,12 @@ class func_monster_spawner: base_func
bot.ideal_yaw = bot.angles * '0 1 0';
bot.yaw_speed = 120;
bot.view_ofs = '0 0 22';
+ */
}
+ // TODO CEV
+
+ /*
// begin his thinking
// this seems better with monster_use -- dumptruck_ds
bot.nextthink = time + 0.2;
@@ -473,16 +527,17 @@ class func_monster_spawner: base_func
{
bot.think = walkmonster_start_go;
}
+ */
if (!(this.spawnflags & MOBOT_DONT_ADD_KILL_COUNT))
{
- // repacement function from iw -- dumptruck_ds
+ // replacement function from iw -- dumptruck_ds
monster_update_total (1);
}
};
//--------------------------------------------------------------
- virtual void(entity caller) do_think =
+ virtual void() do_think =
{
dprint ("mobot thinking\n");
// telefrag check thanks to ryanscissorhands for this code!
@@ -544,7 +599,7 @@ class func_monster_spawner: base_func
//--------------------------------------------------------------
virtual void(entity caller) do_use =
{
- this.do_think (caller);
+ this.do_think ();
};
//--------------------------------------------------------------
Return to the top of this page or return to the overview of this repo.
Diff qc/func/new_plat.qc
diff --git a/qc/func/new_plat.qc b/qc/func/new_plat.qc
index 4974ad6..b07221e 100644
--- a/qc/func/new_plat.qc
+++ b/qc/func/new_plat.qc
@@ -29,7 +29,7 @@ class temp_newplat_trigger: base_tempentity
if (this.enemy.classtype != CT_FUNC_NEW_PLAT)
return;
-
+
// at this point "this" is the trigger, "this.enemy" is
// the plat, and "toucher" is the player.
@@ -140,6 +140,7 @@ Set "sounds" to one of the following:
class func_new_plat: base_func
{
// class fields for progs_dump plat2 (& Rogue multifloor elevator)
+ float height;
float plat2Called;
float plat2LastMove;
float plat2GoTime;
@@ -148,6 +149,10 @@ class func_new_plat: base_func
float elevatorOnFloor;
float elevatorToFloor;
+ /*
+ vector pos1;
+ vector pos2;
+ */
vector pos_top;
vector pos_bottom;
@@ -155,6 +160,9 @@ class func_new_plat: base_func
{
switch (fieldname)
{
+ case "height":
+ this.height = stof (fieldvalue);
+ break;
default:
super::init_field (fieldname, fieldvalue);
}
@@ -541,7 +549,7 @@ class func_new_plat: base_func
};
//--------------------------------------------------------------
- virtual void(entity caller) do_think =
+ virtual void() do_think =
{
if (this.spawnflags & NEWPLAT_DN_N_WAIT)
{
@@ -643,8 +651,7 @@ class func_new_plat: base_func
this.mangle = this.angles;
this.angles = '0 0 0';
- // commented out the classname assignment -- CEV
- // this.classname = "plat";
+ this.classname = "plat";
this.solid = SOLID_BSP;
this.movetype = MOVETYPE_PUSH;
setorigin (this, this.origin);
@@ -655,8 +662,8 @@ class func_new_plat: base_func
this.speed = 150;
// pos1 is the top position, pos2 is the bottom
- pos1 = this.origin;
- pos2 = this.origin;
+ this.pos1 = this.origin;
+ this.pos2 = this.origin;
if (this.height < 0)
{
@@ -666,13 +673,13 @@ class func_new_plat: base_func
if (this.height)
{
- pos2_z = this.origin_z - this.height;
+ this.pos2_z = this.origin_z - this.height;
}
else
{
negativeHeight = 1;
- height = this.size_z - 8;
- pos2_z = this.origin_z - this.height;
+ this.height = this.size_z - 8;
+ this.pos2_z = this.origin_z - this.height;
}
if (this.spawnflags & NEWPLAT_DN_N_WAIT)
Return to the top of this page or return to the overview of this repo.
Diff qc/func/particlefield.qc
diff --git a/qc/func/particlefield.qc b/qc/func/particlefield.qc
index 3b64cba..49ded3f 100644
--- a/qc/func/particlefield.qc
+++ b/qc/func/particlefield.qc
@@ -33,8 +33,22 @@ class func_particlefield: base_func
vector dest1;
vector dest2;
+ float count;
float field_direction;
+ //--------------------------------------------------------------
+ virtual void(string fieldname, string fieldvalue) init_field =
+ {
+ switch (fieldname)
+ {
+ case "count":
+ count = stof (fieldvalue);
+ break;
+ default:
+ super::init_field (fieldname, fieldvalue);
+ }
+ };
+
//--------------------------------------------------------------
nonvirtual void() particlefield_xz =
{
Return to the top of this page or return to the overview of this repo.
Diff qc/func/plat.qc
diff --git a/qc/func/plat.qc b/qc/func/plat.qc
index 6866717..b6593d2 100644
--- a/qc/func/plat.qc
+++ b/qc/func/plat.qc
@@ -57,6 +57,43 @@ class temp_plat_trigger: base_tempentity
this.classtype = CT_TEMP_PLAT_TRIGGER;
this.movetype = MOVETYPE_NONE;
this.solid = SOLID_TRIGGER;
+
+ if (!this.enemy)
+ objerror ("temp_plat_trigger has no linked plat!\n");
+
+ if (this.enemy.classtype != CT_FUNC_PLAT)
+ return;
+
+ // cast to func_plat -- CEV
+ local func_plat fp = (func_plat)this.enemy;
+
+ // local vector tmin = fp.mins + '25 25 0';
+ // local vector tmax = fp.maxs - '25 25 -8';
+ local vector tmax = [fp.maxs_x - 25, fp.maxs_y - 25,
+ fp.maxs_z - -8];
+ local vector tmin = [fp.mins_x + 25, fp.mins_y + 25,
+ tmax_z - (fp.pos1_z - fp.pos2_z + 8)];
+ // tmin_z = tmax_z - (fp.pos1_z - fp.pos2_z + 8);
+ if (fp.spawnflags & PLAT_LOW_TRIGGER)
+ tmax_z = tmin_z + 8;
+
+ if (fp.size_x <= 50)
+ {
+ tmin_x = (fp.mins_x + fp.maxs_x) / 2;
+ tmax_x = tmin_x + 1;
+ }
+
+ if (fp.size_y <= 50)
+ {
+ tmin_y = (fp.mins_y + fp.maxs_y) / 2;
+ tmax_y = tmin_y + 1;
+ }
+
+ setsize (this, tmin, tmax);
+
+ // TODO CEV this next line is here because class field
+ // vectors are busted (why?)
+ // setorigin (this, fp.pos2);
};
};
@@ -75,7 +112,28 @@ Set "sounds" to one of the following:
*/
class func_plat: base_func
{
+ // class fields
+ float height;
+ /*
+ vector pos1; // top position
+ vector pos2; // bottom position
+ */
+
+ //--------------------------------------------------------------
+ virtual void(string fieldname, string fieldvalue) init_field =
+ {
+ switch (fieldname)
+ {
+ case "height":
+ this.height = stof (fieldvalue);
+ break;
+ default:
+ super::init_field (fieldname, fieldvalue);
+ }
+ };
+
//--------------------------------------------------------------
+ /*
nonvirtual void() plat_spawn_inside_trigger =
{
local entity trigger;
@@ -84,26 +142,27 @@ class func_plat: base_func
// middle trigger
trigger = spawn (temp_plat_trigger, enemy: this);
- tmin = this.mins + '25 25 0';
tmax = this.maxs - '25 25 -8';
- tmin_z = tmax_z - (this.pos1_z - this.pos2_z + 8);
+ tmin = this.mins + '25 25 0';
+ tmin.z = tmax.z - (this.pos1.z - this.pos2.z + 8);
if (this.spawnflags & PLAT_LOW_TRIGGER)
- tmax_z = tmin_z + 8;
+ tmax = [tmax_x, tmax_y, tmin_z + 8];
if (this.size_x <= 50)
{
- tmin_x = (this.mins_x + this.maxs_x) / 2;
- tmax_x = tmin_x + 1;
+ tmin.x = (this.mins.x + this.maxs.x) / 2;
+ tmax.x = tmin.x + 1;
}
if (this.size_y <= 50)
{
- tmin_y = (this.mins_y + this.maxs_y) / 2;
- tmax_y = tmin_y + 1;
+ tmin.y = (this.mins.y + this.maxs.y) / 2;
+ tmax.y = tmin.y + 1;
}
setsize (trigger, tmin, tmax);
};
+ */
//--------------------------------------------------------------
nonvirtual void() plat_hit_top =
@@ -150,7 +209,7 @@ class func_plat: base_func
};
//--------------------------------------------------------------
- virtual void(entity caller) do_think =
+ virtual void() do_think =
{
if (this.state == FUNC_STATE_TOP)
this.plat_go_down ();
@@ -223,15 +282,20 @@ class func_plat: base_func
this.speed = 150;
// pos1 is the top position, pos2 is the bottom
- this.pos1 = this.origin;
- this.pos2 = this.origin;
+ this.pos1 = [this.origin_x, this.origin_y, this.origin_z];
if (this.height)
- this.pos2_z = this.origin_z - this.height;
+ this.pos2 = [this.origin_x, this.origin_y,
+ this.origin_z - this.height];
else
- this.pos2_z = this.origin_z - this.size_z + 8;
+ this.pos2 = [this.origin_x, this.origin_y,
+ this.origin_z - this.size_z + 8];
+
+ dprint (sprintf("func_plat::init_spawned: pos1 %v, pos2 %v, "
+ "origin %v\n", this.pos1, this.pos2, this.origin));
// the "start moving" trigger
- plat_spawn_inside_trigger ();
+ // plat_spawn_inside_trigger ();
+ spawn (temp_plat_trigger, enemy: this);
if (this.targetname != "")
{
Return to the top of this page or return to the overview of this repo.
Diff qc/func/rotate.qc
diff --git a/qc/func/rotate.qc b/qc/func/rotate.qc
index 2e7df47..5739eb8 100644
--- a/qc/func/rotate.qc
+++ b/qc/func/rotate.qc
@@ -380,10 +380,24 @@ If "deathtype" is set with a string, this is the message that will appear when a
*/
class func_rotate_entity: base_rotate
{
+ float count;
float firstthink;
+ //--------------------------------------------------------------
+ virtual void(string fieldname, string fieldvalue) init_field =
+ {
+ switch (fieldname)
+ {
+ case "count":
+ count = stof (fieldvalue);
+ break;
+ default:
+ super::init_field (fieldname, fieldvalue);
+ }
+ };
+
//--------------------------------------------------------------
- virtual void(entity caller) do_think =
+ virtual void() do_think =
{
if (this.firstthink)
{
@@ -633,7 +647,7 @@ class func_rotate_train: base_rotate
if (this.goal_rotate.noise != "")
{
- sound (this, CHAN_VOICE, this.goal_rotate.noise,
+ sound (this, CHAN_VOICE, this.goal_rotate.noise,
1, ATTN_NORM);
}
else
@@ -883,7 +897,7 @@ class func_rotate_train: base_rotate
//--------------------------------------------------------------
// was rotate_train_think
//--------------------------------------------------------------
- virtual void(entity caller) do_think =
+ virtual void() do_think =
{
local float t, timeelapsed;
@@ -1083,7 +1097,7 @@ class func_movewall: base_rotate
};
//--------------------------------------------------------------
- virtual void(entity caller) do_think =
+ virtual void() do_think =
{
this.ltime = time;
this.nextthink = time + 0.02;
@@ -1202,7 +1216,7 @@ class func_rotate_door: base_rotate
};
//--------------------------------------------------------------
- virtual void(entity caller) do_think =
+ virtual void() do_think =
{
local float t;
Return to the top of this page or return to the overview of this repo.
Diff qc/func/shadow.qc
diff --git a/qc/func/shadow.qc b/qc/func/shadow.qc
index e3028f2..30981c7 100644
--- a/qc/func/shadow.qc
+++ b/qc/func/shadow.qc
@@ -16,10 +16,10 @@ const float SHADOWCONTROLLER_STARTOFF = 1;
//------------------------------------------------------------------------------
// misc_shadowcontroller
-//
+//
// Controls switchable shadows on any bmodel entity (except doors).
// Target entity must have set _switchableshadow set to 1.
-//
+//
// speed: Controls the time in seconds it takes to fade the shadow in.
// Default is 0.5, and setting it to -1 disables fading.
// speed2: Same as 'speed' but for the fade out animation. If unset it's
@@ -28,6 +28,7 @@ const float SHADOWCONTROLLER_STARTOFF = 1;
//------------------------------------------------------------------------------
class misc_shadowcontroller: base_mapentity
{
+ float count;
float fading;
float speed2;
@@ -127,7 +128,7 @@ class misc_shadowcontroller: base_mapentity
};
//--------------------------------------------------------------
- virtual void(entity caller) do_think =
+ virtual void() do_think =
{
if (this.fading < 0)
this.fade_out ();
Return to the top of this page or return to the overview of this repo.
Diff qc/func/togglevisiblewall.qc
diff --git a/qc/func/togglevisiblewall.qc b/qc/func/togglevisiblewall.qc
index d483970..d29c6e6 100644
--- a/qc/func/togglevisiblewall.qc
+++ b/qc/func/togglevisiblewall.qc
@@ -1,11 +1,11 @@
//==============================================================================
// func_togglevisiblewall
-//
+//
// A bmodel which you can toggle its visibility. Behaves much like a
// traditional func_wall in any other way, but you can target it to
// toggle visible/invisible. If the entity has a switchable shadow it
// also toggles.
-//
+//
// spawnflag 1: starts invisible
// spawnflag 2: set brush as non-solid
//==============================================================================
Return to the top of this page or return to the overview of this repo.
Diff qc/func/train.qc
diff --git a/qc/func/train.qc b/qc/func/train.qc
index 81fb00b..6c52389 100644
--- a/qc/func/train.qc
+++ b/qc/func/train.qc
@@ -4,7 +4,7 @@
// constants
const float TRAIN_RETRIGGER = 1;
-const float TRAIN_MOVEONTRIGGER = 2;
+const float TRAIN_MOVEONTRIGGER = 2;
const float TRAIN_STOPONTRIGGER = 4;
const float TRAIN_NONSOLID = 8;
const float TRAIN_NOROTATE = 16;
@@ -47,7 +47,7 @@ class base_func_train: base_func
};
//--------------------------------------------------------------
- virtual void(entity caller) do_think =
+ virtual void() do_think =
{
if (find_think == TRUE)
{
@@ -85,7 +85,7 @@ class base_func_train: base_func
this.train_next ();
return;
}
-
+
// Train has already moved after startup, and has no
// "stop on trigger" flag, so ignore activation.
if (!this.find_think && this.cnt != TRAIN_NEXT_STOP)
@@ -175,7 +175,7 @@ class base_func_train: base_func
1, ATTN_NORM);
else
sound (this, CHAN_VOICE, this.noise,
- 1, ATTN_NORM);
+ 1, ATTN_NORM);
}
// train is moving normally and path_corner has no wait time,
// or has been forced to move instantly through a triggering.
@@ -214,7 +214,7 @@ class base_func_train: base_func
1, ATTN_NORM);
else
sound (this, CHAN_VOICE, this.noise,
- 1, ATTN_NORM);
+ 1, ATTN_NORM);
// state: stopped
this.state = 0;
@@ -244,7 +244,7 @@ class base_func_train: base_func
objerror ("train_next: no next target");
this.target = targ.target;
-
+
if (targ.wait)
{
// get the wait time from the upcoming path_corner
@@ -264,9 +264,9 @@ class base_func_train: base_func
}
this.enemy = targ;
-
+
sound (this, CHAN_VOICE, this.noise1, 1, ATTN_NORM);
-
+
if (!(!this.wait && this.cnt == TRAIN_NEXT_CONTINUE))
this.cnt = TRAIN_NEXT_WAIT;
@@ -289,10 +289,10 @@ class base_func_train: base_func
doDisplace = 0.0;
else
doDisplace = 1.0;
-
+
if (this.classtype != CT_MISC_MODELTRAIN)
displ = this.mins;
-
+
calc_move (targ.origin - (displ * doDisplace),
this.speed2, train_wait);
};
@@ -320,7 +320,7 @@ class base_func_train: base_func
doDisplace = 0.0;
else
doDisplace = 1.0;
-
+
if (this.classtype != CT_MISC_MODELTRAIN)
displ = this.mins;
@@ -390,7 +390,7 @@ class base_func_train: base_func
precache_sound (this.noise2);
this.cnt = TRAIN_NEXT_WAIT;
-
+
if (this.spawnflags & TRAIN_NONSOLID)
{
this.solid = SOLID_NOT;
Return to the top of this page or return to the overview of this repo.
Diff qc/hazards/ltrail.qc
diff --git a/qc/hazards/ltrail.qc b/qc/hazards/ltrail.qc
index 80d0355..9062fb1 100644
--- a/qc/hazards/ltrail.qc
+++ b/qc/hazards/ltrail.qc
@@ -68,7 +68,7 @@ class base_hazard_ltrail: base_mapentity
};
//--------------------------------------------------------------
- virtual void(entity caller) do_think =
+ virtual void() do_think =
{
switch (this.think_state)
{
Return to the top of this page or return to the overview of this repo.
Diff qc/hazards/shooter.qc
diff --git a/qc/hazards/shooter.qc b/qc/hazards/shooter.qc
index 4e709c5..8c13b7e 100644
--- a/qc/hazards/shooter.qc
+++ b/qc/hazards/shooter.qc
@@ -39,13 +39,9 @@ void() ShalMissileTouch =
WriteCoord (MSG_BROADCAST, self.origin_y);
WriteCoord (MSG_BROADCAST, self.origin_z);
- BecomeExplosion ();
-
- // self.velocity = '0 0 0';
- // self.touch = sub_null;
- // setmodel (self, "progs/s_explod.spr");
- // self.solid = SOLID_NOT;
- // s_explode1 ();
+ // BecomeExplosion
+ spawn (base_explosion, origin: self.origin);
+ remove (self);
};
//----------------------------------------------------------------------
@@ -78,7 +74,7 @@ class base_hazard_shooter: base_mapentity
//--------------------------------------------------------------
// shooter_think -- MED 11/01/96 added state capability
//--------------------------------------------------------------
- virtual void(entity caller) do_think =
+ virtual void() do_think =
{
if (this.state)
this.do_use (other);
@@ -172,7 +168,14 @@ class base_hazard_shooter: base_mapentity
if (!(this.spawnflags & SHOOTER_SPAWNFLAG_SILENT))
sound (this, CHAN_VOICE, "weapons/grenade.wav",
1, ATTN_NORM);
- gnade = spawn ();
+ local vector gnade_velocity = this.movedir * 600 +
+ v_up * 200 + crandom() * v_right * 10 +
+ crandom() * v_up * 10;
+ gnade = spawn (projectile_grenade,
+ owner: this,
+ origin: this.origin,
+ velocity: gnade_velocity);
+ /*
gnade.movetype = MOVETYPE_BOUNCE;
// gnade.movetype = MOVETYPE_FLYMISSILE;
gnade.solid = SOLID_BBOX;
@@ -190,6 +193,7 @@ class base_hazard_shooter: base_mapentity
gnade.avelocity = '300 300 300';
gnade.nextthink = time + 2.5;
gnade.think = GrenadeExplode;
+ */
}
else if (this.spawnflags & SHOOTER_SPAWNFLAG_GIBS)
{
@@ -215,8 +219,9 @@ class base_hazard_shooter: base_mapentity
else
{
if (!(this.spawnflags & SHOOTER_SPAWNFLAG_SILENT))
+ // changed vol fromt 1 to 0.666 -- CEV
sound (this, CHAN_VOICE, "weapons/spike2.wav",
- 1, ATTN_NORM);
+ 0.666, ATTN_NORM);
launch_spike (this.origin, this.movedir);
newmis.velocity = this.movedir * 500;
if (this.spawnflags & SHOOTER_SPAWNFLAG_SUPERSPIKE)
Return to the top of this page or return to the overview of this repo.
Diff qc/info/camera.qc
diff --git a/qc/info/camera.qc b/qc/info/camera.qc
index a612f12..94d8f54 100644
--- a/qc/info/camera.qc
+++ b/qc/info/camera.qc
@@ -9,7 +9,7 @@ field with the same value as a camera-trigger's "target" field.
class info_movie_camera: base_mapentity
{
//--------------------------------------------------------------
- virtual void(entity caller) do_think =
+ virtual void() do_think =
{
remove (this);
};
Return to the top of this page or return to the overview of this repo.
Diff qc/info/path_corner.qc
diff --git a/qc/info/path_corner.qc b/qc/info/path_corner.qc
index 4534386..28dcbc5 100644
--- a/qc/info/path_corner.qc
+++ b/qc/info/path_corner.qc
@@ -2,6 +2,70 @@
// path_corner
//==============================================================================
+//----------------------------------------------------------------------
+// MOVETARGET CODE
+//
+// The angle of the movetarget effects standing and bowing direction, but
+// has no effect on movement, which always heads to the next target.
+//
+// targetname
+// must be present. The name of this movetarget.
+//
+// target
+// the next spot to move to. If not present, stop here for good.
+//
+// pausetime
+// The number of seconds to spend standing or bowing for path_stand or
+// path_bow
+//----------------------------------------------------------------------
+void() movetarget_f =
+{
+ if (!self.targetname)
+ objerror ("monster_movetarget: no targetname");
+
+ self.solid = SOLID_TRIGGER;
+ self.touch = t_movetarget;
+ setsize (self, '-8 -8 -8', '8 8 8');
+
+};
+
+//----------------------------------------------------------------------
+// t_movetarget
+//
+// Something has bumped into a movetarget. If it is a monster moving
+// towards it, change the next destination and continue.
+//----------------------------------------------------------------------
+void() t_movetarget =
+{
+ local entity temp;
+
+ if (other.movetarget != self)
+ return;
+
+ if (other.enemy)
+ // fighting, not following a path
+ return;
+
+ temp = self;
+ self = other;
+ other = temp;
+
+ if (self.classname == "monster_ogre")
+ // play chainsaw drag sound -- sound_custom -- dumptruck_ds
+ sound_misc (self, CHAN_VOICE, "ogre/ogdrag.wav", 1, ATTN_IDLE);
+
+ // dprint ("t_movetarget\n");
+ self.goalentity = self.movetarget = find (world, targetname,
+ other.target);
+ self.ideal_yaw = vectoyaw (self.goalentity.origin - self.origin);
+ if (!self.movetarget)
+ {
+ self.pausetime = time + 999999;
+ self.th_stand ();
+ return;
+ }
+};
+
/*QUAKED path_corner (0.5 0.3 0) (-8 -8 -8) (8 8 8)
Monsters will continue walking towards the next target corner.
*/
Return to the top of this page or return to the overview of this repo.
Diff qc/info/rotate.qc
diff --git a/qc/info/rotate.qc b/qc/info/rotate.qc
index 227709b..b0b0c54 100644
--- a/qc/info/rotate.qc
+++ b/qc/info/rotate.qc
@@ -16,7 +16,7 @@ Used as the point of rotation for rotatable objects.
class info_rotate: base_mapentity
{
//--------------------------------------------------------------
- virtual void(entity caller) do_think =
+ virtual void() do_think =
{
remove (this);
};
Return to the top of this page or return to the overview of this repo.
Diff qc/info/teleport_changedest.qc
diff --git a/qc/info/teleport_changedest.qc b/qc/info/teleport_changedest.qc
index 01852d2..8727b01 100644
--- a/qc/info/teleport_changedest.qc
+++ b/qc/info/teleport_changedest.qc
@@ -52,8 +52,11 @@ class info_teleport_changedest: base_mapentity
makevectors (trig.goalentity.mangle);
trig.goalentity.movedir = v_forward;
+ // TODO CEV pos1
+ /*
trig.goalentity.pos1 = trig.goalentity.origin + 32 *
trig.goalentity.movedir;
+ */
// dumptruck_ds see comment above
trig.target = this.message;
@@ -90,5 +93,3 @@ class info_teleport_changedest: base_mapentity
this.classtype = CT_INFO_TELEPORT_CHANGEDEST;
};
};
-
-
Return to the top of this page or return to the overview of this repo.
Diff qc/info/teleport_destination.qc
diff --git a/qc/info/teleport_destination.qc b/qc/info/teleport_destination.qc
index 57e63b5..0f09f2e 100644
--- a/qc/info/teleport_destination.qc
+++ b/qc/info/teleport_destination.qc
@@ -41,7 +41,7 @@ class info_teleport_destination: base_mapentity
// instead apply the standard fixed Z offset -- CEV
this.origin = this.origin + '0 0 27';
}
-
+
if (!this.targetname)
if (this.target != __NULL__ && this.target != "")
// quake 3 compat -- CEV
Return to the top of this page or return to the overview of this repo.
Diff qc/items/ammo.qc
diff --git a/qc/items/ammo.qc b/qc/items/ammo.qc
index 15a6509..f9665bd 100644
--- a/qc/items/ammo.qc
+++ b/qc/items/ammo.qc
@@ -82,7 +82,7 @@ class base_item_ammo: base_item
{
if (toucher.ammo_nails >= AMMO_NAILS_MAX)
return;
- toucher.ammo_nails =+ this.aflag;
+ toucher.ammo_nails += this.aflag;
}
// rockets
Return to the top of this page or return to the overview of this repo.
Diff qc/items/backpacks.qc
diff --git a/qc/items/backpacks.qc b/qc/items/backpacks.qc
index 49f652a..041e45d 100644
--- a/qc/items/backpacks.qc
+++ b/qc/items/backpacks.qc
@@ -8,7 +8,7 @@ const float BACKPACK_SHELLS = 2;
const float BACKPACK_NAILS = 4;
const float BACKPACK_ROCKETS = 8;
const float BACKPACK_CELLS = 16;
-const float BACKPACK_CUSTOM = 32;
+const float BACKPACK_DROPPED = 32;
// Some of this text is from Drake -- dumptruck_ds
@@ -44,21 +44,26 @@ class item_backpack: base_item
//--------------------------------------------------------------
// DropBackpack
//--------------------------------------------------------------
- static void(entity source) drop_backpack =
+ static void(vector org, float in_weapon, float in_shells,
+ float in_nails, float in_rockets, float in_cells) drop_backpack =
{
local item_backpack pack;
- if (!(source.ammo_shells + source.ammo_nails +
- source.ammo_rockets + source.ammo_cells))
+ if (!(in_shells + in_nails + in_rockets + in_cells))
{
// nothing in it
+ dprint ("item_backpack::drop_backpack: empty pack!\n");
return;
}
- pack = spawn (item_backpack, spawnflags: BACKPACK_CUSTOM);
- pack.origin = source.origin - '0 0 24';
-
- pack.items = source.weapon;
+ pack = spawn (item_backpack,
+ spawnflags: BACKPACK_DROPPED,
+ origin: org - '0 0 24',
+ items: in_weapon,
+ ammo_shells: in_shells,
+ ammo_nails: in_nails,
+ ammo_rockets: in_rockets,
+ ammo_cells: in_cells);
if (pack.items == IT_AXE)
pack.netname = "Axe";
@@ -79,31 +84,15 @@ class item_backpack: base_item
else
pack.netname = "";
- pack.ammo_shells = source.ammo_shells;
- pack.ammo_nails = source.ammo_nails;
- pack.ammo_rockets = source.ammo_rockets;
- pack.ammo_cells = source.ammo_cells;
-
pack.velocity_z = 300;
pack.velocity_x = -100 + (random() * 200);
pack.velocity_y = -100 + (random() * 200);
-
- pack.flags = FL_ITEM;
- pack.solid = SOLID_TRIGGER;
- pack.movetype = MOVETYPE_TOSS;
- precache_body_model ("progs/backpack.mdl");
- setmodel (pack, "progs/backpack.mdl");
- setsize (pack, '-16 -16 0', '16 16 56');
-
- // remove after 2 minutes
- pack.nextthink = time + 120;
- pack.item_flags = ITEM_FLAG_REMOVE;
};
//--------------------------------------------------------------
virtual void(entity toucher) do_touch =
{
- if (this.spawnflags & BACKPACK_CUSTOM)
+ if (this.spawnflags & BACKPACK_DROPPED)
{
local string s;
local float acount, best, old, new;
@@ -111,8 +100,8 @@ class item_backpack: base_item
// from Copper -- dumptruck_ds
if (other.movetype == MOVETYPE_NOCLIP)
- return;
- if (other.classname != "player")
+ return;
+ if (other.classtype != CT_PLAYER)
return;
if (other.health <= 0)
return;
@@ -218,6 +207,8 @@ class item_backpack: base_item
Deathmatch_Weapon (old, new);
PlayerSetCurrentAmmo ();
*/
+ REMOVEME_CallAsSelf (other,
+ PlayerSetCurrentAmmo);
}
// remove the backpack, change this to the player
@@ -273,7 +264,6 @@ class item_backpack: base_item
this.flags = FL_ITEM;
this.solid = SOLID_TRIGGER;
this.movetype = MOVETYPE_TOSS;
- // this.netname = this.netname;
if !(this.spawnflags)
{
@@ -314,14 +304,35 @@ class item_backpack: base_item
if !(this.snd_misc)
this.snd_misc = "weapons/lock4.wav";
precache_sound_misc (this.snd_misc);
- precache_body_model ("progs/pd_bpack.mdl");
- body_model ("progs/pd_bpack.mdl");
+
+ if (this.spawnflags & BACKPACK_DROPPED)
+ {
+ precache_body_model ("progs/backpack.mdl");
+ // setmodel (this, "progs/backpack.mdl");
+ body_model ("progs/backpack.mdl");
+ }
+ else
+ {
+ precache_body_model ("progs/pd_bpack.mdl");
+ body_model ("progs/pd_bpack.mdl");
+ }
+
// setmodel (this, "progs/backpack.mdl");
this.size_min = '-16 -16 0';
this.size_max = '16 16 56';
// StartItem
- super::init_spawned ();
+ if (this.spawnflags & BACKPACK_DROPPED)
+ {
+ // don't delay, spawn immediately -- CEV
+ setsize (this, this.size_min, this.size_max);
+ this.item_flags = ITEM_FLAG_REMOVE;
+ this.nextthink = time + 120;
+ }
+ else
+ {
+ super::init_spawned ();
+ }
};
//--------------------------------------------------------------
@@ -336,7 +347,7 @@ class item_backpack: base_item
//======================================================================
// DropStuff -- dumptruck_ds
// set drops_item on a monster to a number:
-//
+//
// 1 = Silver Key
// 2 = Gold Key
// 3 = Health Vial
Return to the top of this page or return to the overview of this repo.
Diff qc/items/keys.qc
diff --git a/qc/items/keys.qc b/qc/items/keys.qc
index 5a2f660..04285cc 100644
--- a/qc/items/keys.qc
+++ b/qc/items/keys.qc
@@ -43,7 +43,7 @@ class base_item_key: base_item
//--------------------------------------------------------------
// SilverKeyName
- //
+ //
// Return the name that should be used for the silver key as per
// world.worldtype. -- iw
//--------------------------------------------------------------
@@ -58,7 +58,7 @@ class base_item_key: base_item
//--------------------------------------------------------------
// GoldKeyName
- //
+ //
// Return the name that should be used for the gold key as per
// world.worldtype. -- iw
//--------------------------------------------------------------
@@ -73,10 +73,10 @@ class base_item_key: base_item
//--------------------------------------------------------------
// FindCustomKeyDef
- //
+ //
// If a custom_key_def entity exists which defines the custom key
// named key_name, then find and return it, otherwise return world.
- //
+ //
// If a custom_key_def entity is returned, then the value of its
// customkeys field will be the bitflag that should be used to
// represent the custom key named key_name. -- iw
@@ -97,10 +97,10 @@ class base_item_key: base_item
//--------------------------------------------------------------
// SpawnCustomKeyDef
- //
+ //
// Spawn and return a new custom_key_def entity which will define
// the custom key named key_name.
- //
+ //
// The value of the entity's customkeys field will be a bitflag
// which has not yet been used to represent a custom key. -- iw
//--------------------------------------------------------------
@@ -125,10 +125,10 @@ class base_item_key: base_item
//--------------------------------------------------------------
// CustomKeyFlag
- //
+ //
// Return the bitflag that should be used to represent the custom
// key named key_name.
- //
+ //
// More specifically, if this is the first time that this function
// has been called for the specified key_name, then return a bitflag
// which has not previously been returned by this function for
@@ -147,7 +147,7 @@ class base_item_key: base_item
//--------------------------------------------------------------
// HasKeys
- //
+ //
// Return TRUE if the specified client has all of the non-custom
// keys represented by the flags and all of the custom keys
// represented by the custom_flags, otherwise return FALSE. -- iw
@@ -160,7 +160,7 @@ class base_item_key: base_item
//--------------------------------------------------------------
// GiveKeys
- //
+ //
// Give the specified client all of the non-custom keys represented
// by the item_flags and all of the custom keys represented by the
// customkey_flags. -- iw
@@ -173,7 +173,7 @@ class base_item_key: base_item
//--------------------------------------------------------------
// GiveAllKeys
- //
+ //
// Give the specified client the silver key, the gold key, and
// all of the custom keys that have been defined for the current
// map. -- iw
@@ -186,7 +186,7 @@ class base_item_key: base_item
//--------------------------------------------------------------
// RemoveKeys
- //
+ //
// Remove all of the non-custom keys represented by the item_flags
// and all of the custom keys represented by the customkey_flags
// from the specified client's inventory. -- iw
Return to the top of this page or return to the overview of this repo.
Diff qc/items/runes.qc
diff --git a/qc/items/runes.qc b/qc/items/runes.qc
index 49cbbf3..050ebbd 100644
--- a/qc/items/runes.qc
+++ b/qc/items/runes.qc
@@ -28,7 +28,7 @@ class base_item_rune: base_item
activator = toucher;
// fire all targets / killtargets
- // SUB_UseTargets ();
+ // sub_usetargets ();
};
//--------------------------------------------------------------
Return to the top of this page or return to the overview of this repo.
Diff qc/items/weapons.qc
diff --git a/qc/items/weapons.qc b/qc/items/weapons.qc
index 05ba4de..544fa84 100644
--- a/qc/items/weapons.qc
+++ b/qc/items/weapons.qc
@@ -528,6 +528,9 @@ Thunderbolt
class weapon_lightning: base_item_weapon
{
//--------------------------------------------------------------
+
+
+ //--------------------------------------------------------------
virtual void() init_spawned =
{
precache_model ("progs/g_light.mdl");
Return to the top of this page or return to the overview of this repo.
Diff qc/keylock.qc
diff --git a/qc/keylock.qc b/qc/keylock.qc
index 6f7db28..d39243a 100644
--- a/qc/keylock.qc
+++ b/qc/keylock.qc
@@ -84,7 +84,7 @@ void() keylock_init =
//----------------------------------------------------------------------
// keylock_set_silver_key
-//
+//
// Make it so that the player will need to use the silver key in order to
// unlock self. -- iw
//----------------------------------------------------------------------
@@ -97,7 +97,7 @@ void() keylock_set_silver_key =
//----------------------------------------------------------------------
// keylock_set_gold_key
-//
+//
// Make it so that the player will need to use the gold key in order to
// unlock self. -- iw
//----------------------------------------------------------------------
@@ -114,7 +114,7 @@ void() keylock_set_gold_key =
//
// Make it so that the player will need to use the custom key named
// key_name in order to unlock self. -- iw
-//
+//
// support for item_key_custom -- iw
//----------------------------------------------------------------------
void(string key_name) keylock_set_custom_key =
@@ -126,7 +126,7 @@ void(string key_name) keylock_set_custom_key =
//----------------------------------------------------------------------
// keylock_has_key_set
-//
+//
// Return TRUE if one of the keylock_set_*_key functions has been called
// for entity e, otherwise return FALSE. -- iw
//----------------------------------------------------------------------
Return to the top of this page or return to the overview of this repo.
Diff qc/math.qc
diff --git a/qc/math.qc b/qc/math.qc
index 3803c1b..4404b8c 100644
--- a/qc/math.qc
+++ b/qc/math.qc
@@ -35,7 +35,7 @@ float(float value, float minValue, float maxValue) clamp =
//----------------------------------------------------------------------
// mod
-//
+//
// Returns the remainder after the division of a by n
// a: The dividend
// b: The divisor
@@ -48,7 +48,7 @@ float(float a, float n) mod =
//----------------------------------------------------------------------
// sign
-//
+//
// Returns an indication of the sign of the given number.
// x: A number
// Returns: -1 if x < 0, 0 if x == 0, 1 if x > 0.
@@ -69,10 +69,10 @@ float(float x) sign =
//----------------------------------------------------------------------
// wrap
-//
+//
// Limits the given value to the given range and will wrap the value to the
// the other end of the range if exceeded.
-//
+//
// value: A number
// minValue: The minimum value of the range
// maxValue: The maximum value of the range
@@ -185,3 +185,94 @@ vector(vector ang) normalizeAngles180 =
return ang;
};
+
+//======================================================================
+// Below are various math functions copied from elsewhere in the program
+// (i.e., the following were not originally in math.qc) -- CEV
+//======================================================================
+
+//----------------------------------------------------------------------
+// was in weapons.qc -- CEV
+//----------------------------------------------------------------------
+float() crandom =
+{
+ return 2 * (random() - 0.5);
+};
+
+//----------------------------------------------------------------------
+// was in ai.qc -- CEV
+//----------------------------------------------------------------------
+float(float v) anglemod =
+{
+ while (v >= 360)
+ v = v - 360;
+ while (v < 0)
+ v = v + 360;
+ return v;
+};
+
+//----------------------------------------------------------------------
+// the next two functions were in ogre.qc -- CEV
+//----------------------------------------------------------------------
+
+//////////////////////////////////////////////////////////////
+// start Preach Ogre Marksman tutorial here -- dumptruck_ds //
+//////////////////////////////////////////////////////////////
+
+// uses QuakeC builtins to calculate tan of angle
+// WARNING: uses makevectors! This overwrites the v_forward... globals
+float(float theta) newtan =
+{
+ local vector ang = '0 0 0'; // temp used to calculate trig values
+
+ // assign theta to the yaw to simplify reasoning
+ ang_y = theta;
+ makevectors (ang);
+ return v_forward_y / v_forward_x;
+};
+
+float(float theta, vector source, vector dest) IterateElevation =
+{
+ // constants in the equation to be solved
+ local float a, b, c;
+ // displacement we wish the projectile to travel
+ local vector ofs;
+ // horizontal and vertical components of ofs
+ local float y, z;
+ // trig values of the angle theta
+ local float tan_theta;
+ local float tan_test;
+
+ // calculate how far we are firing
+ ofs = dest - source;
+ z = ofs_z;
+ ofs_z = 0;
+ y = vlen (ofs);
+
+ // find the coefficients of the quadratic in tan(theta)
+ a = 0.5 * pgrav * y * y / (OGRE_G_VEL * OGRE_G_VEL);
+ b = -y;
+ c = a + z;
+
+ // check if the destination is too far to reach
+ if (b * b < 4 * a * c)
+ return OGRE_DEFAULT_ELEVATION;
+
+ // calculate the tan value of the given theta
+ tan_theta = newtan (theta);
+ tan_test = tan (theta);
+
+ // TODO CEV
+ dprint (sprintf("IterateElevation: tan: %f, newtan: %f\n",
+ tan_test, tan_theta));
+
+ // reuse ang to create the improved firing direction
+ theta = atan2 (a * tan_theta * tan_theta - c, 2 * a * tan_theta + b);
+
+ // constrain the values to stop anything too mad happening
+ while (theta > 90)
+ theta = theta - 180;
+ return theta;
+};
+
+// end Preach tutorial
Return to the top of this page or return to the overview of this repo.
Diff qc/misc/air_bubbles.qc
diff --git a/qc/misc/air_bubbles.qc b/qc/misc/air_bubbles.qc
index 94eb74f..428c060 100644
--- a/qc/misc/air_bubbles.qc
+++ b/qc/misc/air_bubbles.qc
@@ -2,6 +2,7 @@
// air_bubbles
//==============================================================================
+//------------------------------------------------------------------------------
class temp_bubbles: base_tempentity
{
float in_water;
@@ -9,7 +10,7 @@ class temp_bubbles: base_tempentity
//--------------------------------------------------------------
// was bubble_bob -- CEV
//--------------------------------------------------------------
- virtual void(entity caller) do_think =
+ virtual void() do_think =
{
local float rnd1, rnd2, rnd3;
@@ -108,7 +109,7 @@ class air_bubbles: base_mapentity
//--------------------------------------------------------------
// was make_bubbles -- CEV
//--------------------------------------------------------------
- virtual void(entity caller) do_think =
+ virtual void() do_think =
{
local temp_bubbles bubble;
Return to the top of this page or return to the overview of this repo.
Diff qc/misc/ambient_sound.qc
diff --git a/qc/misc/ambient_sound.qc b/qc/misc/ambient_sound.qc
index b42706f..070c118 100644
--- a/qc/misc/ambient_sound.qc
+++ b/qc/misc/ambient_sound.qc
@@ -391,7 +391,7 @@ only need one of these in your level. It will play everywhere.
class ambient_thunder: base_ambient_sound
{
//--------------------------------------------------------------
- virtual void(entity caller) do_think =
+ virtual void() do_think =
{
if (random() < 0.5)
sound (this, CHAN_AUTO, SND_AMBIENTHUNDER,
Return to the top of this page or return to the overview of this repo.
Diff qc/misc/deadstuff.qc
diff --git a/qc/misc/deadstuff.qc b/qc/misc/deadstuff.qc
index a261637..0fcd5f7 100644
--- a/qc/misc/deadstuff.qc
+++ b/qc/misc/deadstuff.qc
@@ -75,7 +75,7 @@ class gib_head_dog: base_mapentity
model ("progs/h_guard.mdl");
}
*/
-class gib_head_army: base_mapentity
+class gib_head_army: base_mapentity
{
//--------------------------------------------------------------
virtual void() init_spawned =
@@ -83,7 +83,7 @@ class gib_head_army: base_mapentity
precache_model ("progs/h_guard.mdl");
setmodel (this, "progs/h_guard.mdl");
this.frame = 0;
-
+
if (this.spawnflags & 1)
{
this.solid = SOLID_BBOX;
Return to the top of this page or return to the overview of this repo.
Diff qc/misc/explobox.qc
diff --git a/qc/misc/explobox.qc b/qc/misc/explobox.qc
index b643d39..9d27622 100644
--- a/qc/misc/explobox.qc
+++ b/qc/misc/explobox.qc
@@ -15,7 +15,9 @@ class base_explobox: base_mapentity
particle (this.origin, '0 0 0', 75, 255);
this.origin_z = this.origin_z + 32;
- BecomeExplosion ();
+ // BecomeExplosion
+ spawn (base_explosion, origin: this.origin);
+ remove (this);
};
};
Return to the top of this page or return to the overview of this repo.
Diff qc/misc/fireball.qc
diff --git a/qc/misc/fireball.qc b/qc/misc/fireball.qc
index e892288..8b6a202 100644
--- a/qc/misc/fireball.qc
+++ b/qc/misc/fireball.qc
@@ -6,7 +6,7 @@
class temp_fireball: base_tempentity
{
//--------------------------------------------------------------
- virtual void(entity caller) do_think =
+ virtual void() do_think =
{
remove (this);
};
@@ -42,7 +42,7 @@ class misc_fireball: base_mapentity
//--------------------------------------------------------------
// was fire_fly -- CEV
//--------------------------------------------------------------
- virtual void(entity caller) do_think =
+ virtual void() do_think =
{
local temp_fireball fireball;
Return to the top of this page or return to the overview of this repo.
Diff qc/misc/infight.qc
diff --git a/qc/misc/infight.qc b/qc/misc/infight.qc
index 07c4978..bfc2117 100644
--- a/qc/misc/infight.qc
+++ b/qc/misc/infight.qc
@@ -4,10 +4,10 @@
//======================================================================
// misc_infight
-//
+//
// target = monster that gets mad
// target2 = who target1 will be angry at
-//
+//
// spawnflag 1 = mutual hate, both targets get angry at each other instantly
// spawnflag 2 = maintain activator, makes it so the player that triggers
// the infighting sees centerprints triggered by it
@@ -31,7 +31,17 @@ class misc_infight: base_mapentity
// TODO CEV need to rework; this/self/FoundTarget
// FoundTarget () only acts on self
- FoundTargetForEntity (t1);
+ // FoundTargetForEntity (t1);
+ if (t1.classgroup & CG_MONSTER)
+ {
+ ((base_monster)t1).ai_findtarget ();
+ }
+ else
+ {
+ objerror (sprintf("misc_infight: tried to "
+ "make a %s fight a %s!",
+ t1.classname, t2.classname));
+ }
}
};
Return to the top of this page or return to the overview of this repo.
Diff qc/misc/light_candle.qc
diff --git a/qc/misc/light_candle.qc b/qc/misc/light_candle.qc
index 0e74565..40c5180 100644
--- a/qc/misc/light_candle.qc
+++ b/qc/misc/light_candle.qc
@@ -137,7 +137,7 @@ class model_candle: base_mapentity
//--------------------------------------------------------------
// was model_candle_think
//--------------------------------------------------------------
- virtual void(entity caller) do_think =
+ virtual void() do_think =
{
this.frame = this.frame + 1;
if (this.frame > 3)
Return to the top of this page or return to the overview of this repo.
Diff qc/misc/lights.qc
diff --git a/qc/misc/lights.qc b/qc/misc/lights.qc
index cf59cf2..1edf676 100644
--- a/qc/misc/lights.qc
+++ b/qc/misc/lights.qc
@@ -121,9 +121,28 @@ string(float num) lightstyle_fade_lookup =
//------------------------------------------------------------------------------
class base_light: base_mapentity
{
+ float count;
+ float style2;
float think_state;
- virtual void(entity caller) do_think =
+ //--------------------------------------------------------------
+ virtual void(string fieldname, string fieldvalue) init_field =
+ {
+ switch (fieldname)
+ {
+ case "count":
+ count = stof (fieldvalue);
+ break;
+ case "style2":
+ style2 = stof (fieldvalue);
+ break;
+ default:
+ super::init_field (fieldname, fieldvalue);
+ }
+ };
+
+ //--------------------------------------------------------------
+ virtual void() do_think =
{
if (this.think_state == LIGHT_THINK_FADE_IN)
{
@@ -177,7 +196,7 @@ class base_light: base_mapentity
if (this.spawnflags & LIGHT_FADE_IN_OUT && !this.style2)
{
this.think_state = LIGHT_THINK_FADE_IN;
- this.do_think (other);
+ this.do_think ();
}
else
{
@@ -191,7 +210,7 @@ class base_light: base_mapentity
if (this.spawnflags & LIGHT_FADE_IN_OUT && !this.style2)
{
this.think_state = LIGHT_THINK_FADE_OUT;
- this.do_think (other);
+ this.do_think ();
}
else
{
@@ -345,7 +364,7 @@ _color => _sunlight_color
_dirt => _sunlight_dirt
_anglescale => _anglescale
*/
-class light: base_light
+class light: base_light
{
//--------------------------------------------------------------
virtual void() init_spawned =
Return to the top of this page or return to the overview of this repo.
Diff qc/misc/model.qc
diff --git a/qc/misc/model.qc b/qc/misc/model.qc
index 975188f..18a8982 100644
--- a/qc/misc/model.qc
+++ b/qc/misc/model.qc
@@ -18,6 +18,7 @@ const float MISC_MODEL_STARTOFF = 32;
class base_misc_model: base_mapentity
{
// class fields
+ float count;
float first_frame; // The starting frame of the animation
float last_frame; // The ending frame of the animation
@@ -26,6 +27,9 @@ class base_misc_model: base_mapentity
{
switch (fieldname)
{
+ case "count":
+ count = stof (fieldvalue);
+ break;
case "first_frame":
first_frame = stof (fieldvalue);
break;
@@ -40,7 +44,7 @@ class base_misc_model: base_mapentity
//--------------------------------------------------------------
// misc_model_think -- Handles animation for misc_model entity.
//--------------------------------------------------------------
- virtual void(entity caller) do_think =
+ virtual void() do_think =
{
this.nextthink = time + fabs (this.speed);
if (this.estate != STATE_ACTIVE)
Return to the top of this page or return to the overview of this repo.
Diff qc/misc/modeltrain.qc
diff --git a/qc/misc/modeltrain.qc b/qc/misc/modeltrain.qc
index ff3cb10..2f9bd00 100644
--- a/qc/misc/modeltrain.qc
+++ b/qc/misc/modeltrain.qc
@@ -79,7 +79,7 @@ class temp_anim_controller: base_tempentity
base_misc_modeltrain tr;
//--------------------------------------------------------------
- virtual void(entity caller) do_think =
+ virtual void() do_think =
{
local float first, last, step, atype, dir, nextframe;
@@ -126,7 +126,7 @@ class temp_anim_controller: base_tempentity
// the step's signal
if (tr.distance < 0)
step = step * (-1);
-
+
nextframe = tr.frame + step;
if (atype == TRAIN_ANIMTYPE_BACKFORTH)
@@ -173,7 +173,7 @@ class temp_rotate_controller: base_tempentity
// SUB_CalcAngleMoveDoneController
// After rotating, set angle to exact final angle
//--------------------------------------------------------------
- virtual void(entity caller) do_think =
+ virtual void() do_think =
{
tr.angles = this.finalangle;
tr.avelocity = '0 0 0';
@@ -192,7 +192,7 @@ class temp_rotate_controller: base_tempentity
if (!tspeed)
objerror("No speed is defined!");
-
+
// set destdelta to the vector needed to move
destdelta = normalizeAngles180 (destangle - tr.angles);
@@ -214,7 +214,7 @@ class temp_rotate_controller: base_tempentity
// scale the destdelta vector by the time spent traveling to
// get velocity
tr.avelocity = destdelta * (1 / traveltime);
-
+
// Makes sure controller.owner points to self so it can be
// referenced later in the think function
this.finalangle = destangle;
@@ -266,13 +266,13 @@ class misc_modeltrain: base_misc_modeltrain
//--------------------------------------------------------------
virtual void() train_wait_handlepause =
{
- animcontroller.do_think (other);
+ animcontroller.do_think ();
};
//--------------------------------------------------------------
virtual void() train_wait_handlestop =
{
- animcontroller.do_think (other);
+ animcontroller.do_think ();
};
//--------------------------------------------------------------
@@ -301,7 +301,7 @@ class misc_modeltrain: base_misc_modeltrain
{
this.state = 1;
if (this.style != TRAIN_STYLE_SINGLEANIM)
- animcontroller.do_think (other);
+ animcontroller.do_think ();
}
};
@@ -316,7 +316,7 @@ class misc_modeltrain: base_misc_modeltrain
this.solid = SOLID_NOT;
}
else
- {
+ {
this.solid = SOLID_BBOX;
if (this.cmins == VEC_ORIGIN)
this.cmins = '-8 -8 -8';
@@ -345,7 +345,7 @@ class misc_modeltrain: base_misc_modeltrain
this.last_frame = this.first_frame;
else if (!this.first_frame && this.last_frame)
this.first_frame = this.last_frame;
-
+
if (this.first_frame2 && !this.last_frame2)
this.last_frame2 = this.first_frame2;
else if (!this.first_frame2 && this.last_frame2)
Return to the top of this page or return to the overview of this repo.
Diff qc/misc/noisemaker.qc
diff --git a/qc/misc/noisemaker.qc b/qc/misc/noisemaker.qc
index 8f2660c..d252583 100644
--- a/qc/misc/noisemaker.qc
+++ b/qc/misc/noisemaker.qc
@@ -9,7 +9,7 @@ For optimzation testing, starts a lot of sounds.
class misc_noisemaker: base_mapentity
{
//--------------------------------------------------------------
- virtual void(entity caller) do_think =
+ virtual void() do_think =
{
this.nextthink = time + 0.5;
sound (this, 1, "enforcer/enfire.wav", 1, ATTN_NORM);
Return to the top of this page or return to the overview of this repo.
Diff qc/misc/particle_stream.qc
diff --git a/qc/misc/particle_stream.qc b/qc/misc/particle_stream.qc
index fb684bb..70e13ee 100644
--- a/qc/misc/particle_stream.qc
+++ b/qc/misc/particle_stream.qc
@@ -46,7 +46,7 @@ class misc_particle_stream: base_mapentity
//--------------------------------------------------------------
// was particle_stream_start -- CEV
//--------------------------------------------------------------
- virtual void(entity caller) do_think =
+ virtual void() do_think =
{
local entity pspot;
Return to the top of this page or return to the overview of this repo.
Diff qc/misc/particles.qc
diff --git a/qc/misc/particles.qc b/qc/misc/particles.qc
index e888516..d02a5cf 100644
--- a/qc/misc/particles.qc
+++ b/qc/misc/particles.qc
@@ -24,7 +24,7 @@ class misc_particles: base_mapentity
//--------------------------------------------------------------
// was splash_think -- CEV
//--------------------------------------------------------------
- virtual void(entity caller) do_think =
+ virtual void() do_think =
{
local vector vec;
local float variance;
Return to the top of this page or return to the overview of this repo.
Diff qc/misc/particlespray.qc
diff --git a/qc/misc/particlespray.qc b/qc/misc/particlespray.qc
index 08bae28..cf64807 100644
--- a/qc/misc/particlespray.qc
+++ b/qc/misc/particlespray.qc
@@ -38,7 +38,7 @@ class misc_particlespray: base_mapentity
};
//--------------------------------------------------------------
- virtual void(entity caller) do_think =
+ virtual void() do_think =
{
particle (this.origin, this.movedir, this.color, this.count);
@@ -58,7 +58,7 @@ class misc_particlespray: base_mapentity
return;
this.endtime = time + this.duration;
- this.do_think (caller);
+ this.do_think ();
};
//--------------------------------------------------------------
Return to the top of this page or return to the overview of this repo.
Diff qc/misc/play.qc
diff --git a/qc/misc/play.qc b/qc/misc/play.qc
index 919d729..ad74851 100644
--- a/qc/misc/play.qc
+++ b/qc/misc/play.qc
@@ -14,7 +14,7 @@ class base_play_sound: base_mapentity
//--------------------------------------------------------------
// was play_sound_think -- CEV
//--------------------------------------------------------------
- virtual void(entity caller) do_think =
+ virtual void() do_think =
{
local float t;
t = this.wait * random ();
Return to the top of this page or return to the overview of this repo.
Diff qc/misc/sparks.qc
diff --git a/qc/misc/sparks.qc b/qc/misc/sparks.qc
index 2c49622..43335b4 100644
--- a/qc/misc/sparks.qc
+++ b/qc/misc/sparks.qc
@@ -26,7 +26,7 @@ class temp_spark: base_tempentity
float think_state;
//--------------------------------------------------------------
- virtual void(entity caller) do_think =
+ virtual void() do_think =
{
if (this.think_state == TEMP_SPARK_REMOVE)
{
@@ -98,7 +98,7 @@ class misc_sparks: base_mapentity
float think_state;
//--------------------------------------------------------------
- virtual void(entity caller) do_think =
+ virtual void() do_think =
{
if (this.think_state == MISC_SPARKS_OFFLIGHT)
{
Return to the top of this page or return to the overview of this repo.
Diff qc/misc/target_autosave.qc
diff --git a/qc/misc/target_autosave.qc b/qc/misc/target_autosave.qc
index 2dd841e..bf46132 100644
--- a/qc/misc/target_autosave.qc
+++ b/qc/misc/target_autosave.qc
@@ -66,9 +66,9 @@ class target_autosave: base_mapentity
//--------------------------------------------------------------
// was target_autosave_delaythink
//--------------------------------------------------------------
- virtual void(entity caller) do_think =
+ virtual void() do_think =
{
- this.do_use (caller);
+ this.do_use (other);
};
//--------------------------------------------------------------
Return to the top of this page or return to the overview of this repo.
Diff qc/misc/teleporttrain.qc
diff --git a/qc/misc/teleporttrain.qc b/qc/misc/teleporttrain.qc
index aa80bb9..a47f301 100644
--- a/qc/misc/teleporttrain.qc
+++ b/qc/misc/teleporttrain.qc
@@ -147,7 +147,7 @@ class misc_teleporttrain: base_mapentity
};
//--------------------------------------------------------------
- virtual void(entity caller) do_think =
+ virtual void() do_think =
{
switch (this.think_state)
{
@@ -213,11 +213,9 @@ class misc_teleporttrain: base_mapentity
// spawner -- dumptruck_ds
this.avelocity = '40 80 120';
- /*
- precache_sound ("misc/null.wav");
- this.noise = "misc/null.wav";
- this.noise1 = "misc/null.wav";
- */
+ // precache_sound ("misc/null.wav");
+ // this.noise = "misc/null.wav";
+ // this.noise1 = "misc/null.wav";
this.think_state = TELEPORTTRAIN_FIND;
if (this.ltime)
Return to the top of this page or return to the overview of this repo.
Diff qc/monsters.qc
diff --git a/qc/monsters.qc b/qc/monsters.qc
index 1576acf..8d9af8e 100644
--- a/qc/monsters.qc
+++ b/qc/monsters.qc
@@ -30,6 +30,7 @@ void(float n) monster_update_total =
/* From Preach's tutorial here: https://tomeofpreach.wordpress.com/2017/10/08/teleporting-monsters-flag/#more-2281 */
+/*
//define Preach's new fields dumptruck_ds
.string tele_model;
@@ -37,6 +38,7 @@ void(float n) monster_update_total =
.vector tele_maxs;
.float tele_solid;
.float tele_movetype;
+*/
void() monster_teleport_go =
{
@@ -73,7 +75,7 @@ void() monster_teleport_delay =
// if delay is set to -1 random delay from 0.1 to 1
// second - dumptruck_ds
self.nextthink = time + 0.1 + random();
- return;
+ return;
}
self.nextthink = time + 0.1 + self.delay;
};
@@ -217,7 +219,7 @@ void() monster_death_use =
if(self.infight_activator)
{
activator = self.infight_activator;
- }
+ }
else
{
activator = self.enemy;
Return to the top of this page or return to the overview of this repo.
Diff qc/monsters/boss.qc
diff --git a/qc/monsters/boss.qc b/qc/monsters/boss.qc
index 5c49e77..07c9b94 100644
--- a/qc/monsters/boss.qc
+++ b/qc/monsters/boss.qc
@@ -1,10 +1,10 @@
-/*
-==============================================================================
+//==============================================================================
+// BOSS-ONE
+//==============================================================================
-BOSS-ONE
-
-==============================================================================
-*/
+//======================================================================
+// frame macros
+//======================================================================
$cd id1/models/boss1
$origin 0 0 -15
$base base
@@ -34,296 +34,355 @@ $frame shockb1 shockb2 shockb3 shockb4 shockb5 shockb6
$frame shockc1 shockc2 shockc3 shockc4 shockc5 shockc6 shockc7 shockc8
$frame shockc9 shockc10
-
-void(vector p) boss_missile;
-
-void() boss_face =
+/*QUAKED monster_boss (1 0 0) (-128 -128 -24) (128 128 256)
+*/
+class monster_boss: base_monster
{
-
-// go for another player if multi player
- if (self.enemy.health <= 0 || random() < 0.02)
+ //--------------------------------------------------------------
+ nonvirtual void() boss_face =
{
- self.enemy = find(self.enemy, classname, "player");
- if (!self.enemy)
- self.enemy = find(self.enemy, classname, "player");
- }
- ai_face();
-};
-
-void() boss_rise1 =[ $rise1, boss_rise2 ] {
-sound_move (self, CHAN_WEAPON, "boss1/out1.wav", 1, ATTN_NORM);
-};
-void() boss_rise2 =[ $rise2, boss_rise3 ] {
-sound_sight (self, CHAN_VOICE, "boss1/sight1.wav", 1, ATTN_NORM);
-};
-void() boss_rise3 =[ $rise3, boss_rise4 ] {};
-void() boss_rise4 =[ $rise4, boss_rise5 ] {};
-void() boss_rise5 =[ $rise5, boss_rise6 ] {};
-void() boss_rise6 =[ $rise6, boss_rise7 ] {};
-void() boss_rise7 =[ $rise7, boss_rise8 ] {};
-void() boss_rise8 =[ $rise8, boss_rise9 ] {};
-void() boss_rise9 =[ $rise9, boss_rise10 ] {};
-void() boss_rise10 =[ $rise10, boss_rise11 ] {};
-void() boss_rise11 =[ $rise11, boss_rise12 ] {};
-void() boss_rise12 =[ $rise12, boss_rise13 ] {};
-void() boss_rise13 =[ $rise13, boss_rise14 ] {};
-void() boss_rise14 =[ $rise14, boss_rise15 ] {};
-void() boss_rise15 =[ $rise15, boss_rise16 ] {};
-void() boss_rise16 =[ $rise16, boss_rise17 ] {};
-void() boss_rise17 =[ $rise17, boss_missile1 ] {};
-
-void() boss_idle1 =[ $walk1, boss_idle2 ]
-{
-// look for other players
-};
-void() boss_idle2 =[ $walk2, boss_idle3 ] {boss_face();};
-void() boss_idle3 =[ $walk3, boss_idle4 ] {boss_face();};
-void() boss_idle4 =[ $walk4, boss_idle5 ] {boss_face();};
-void() boss_idle5 =[ $walk5, boss_idle6 ] {boss_face();};
-void() boss_idle6 =[ $walk6, boss_idle7 ] {boss_face();};
-void() boss_idle7 =[ $walk7, boss_idle8 ] {boss_face();};
-void() boss_idle8 =[ $walk8, boss_idle9 ] {boss_face();};
-void() boss_idle9 =[ $walk9, boss_idle10 ] {boss_face();};
-void() boss_idle10 =[ $walk10, boss_idle11 ] {boss_face();};
-void() boss_idle11 =[ $walk11, boss_idle12 ] {boss_face();};
-void() boss_idle12 =[ $walk12, boss_idle13 ] {boss_face();};
-void() boss_idle13 =[ $walk13, boss_idle14 ] {boss_face();};
-void() boss_idle14 =[ $walk14, boss_idle15 ] {boss_face();};
-void() boss_idle15 =[ $walk15, boss_idle16 ] {boss_face();};
-void() boss_idle16 =[ $walk16, boss_idle17 ] {boss_face();};
-void() boss_idle17 =[ $walk17, boss_idle18 ] {boss_face();};
-void() boss_idle18 =[ $walk18, boss_idle19 ] {boss_face();};
-void() boss_idle19 =[ $walk19, boss_idle20 ] {boss_face();};
-void() boss_idle20 =[ $walk20, boss_idle21 ] {boss_face();};
-void() boss_idle21 =[ $walk21, boss_idle22 ] {boss_face();};
-void() boss_idle22 =[ $walk22, boss_idle23 ] {boss_face();};
-void() boss_idle23 =[ $walk23, boss_idle24 ] {boss_face();};
-void() boss_idle24 =[ $walk24, boss_idle25 ] {boss_face();};
-void() boss_idle25 =[ $walk25, boss_idle26 ] {boss_face();};
-void() boss_idle26 =[ $walk26, boss_idle27 ] {boss_face();};
-void() boss_idle27 =[ $walk27, boss_idle28 ] {boss_face();};
-void() boss_idle28 =[ $walk28, boss_idle29 ] {boss_face();};
-void() boss_idle29 =[ $walk29, boss_idle30 ] {boss_face();};
-void() boss_idle30 =[ $walk30, boss_idle31 ] {boss_face();};
-void() boss_idle31 =[ $walk31, boss_idle1 ] {boss_face();};
-
-void() boss_missile1 =[ $attack1, boss_missile2 ] {boss_face();};
-void() boss_missile2 =[ $attack2, boss_missile3 ] {boss_face();};
-void() boss_missile3 =[ $attack3, boss_missile4 ] {boss_face();};
-void() boss_missile4 =[ $attack4, boss_missile5 ] {boss_face();};
-void() boss_missile5 =[ $attack5, boss_missile6 ] {boss_face();};
-void() boss_missile6 =[ $attack6, boss_missile7 ] {boss_face();};
-void() boss_missile7 =[ $attack7, boss_missile8 ] {boss_face();};
-void() boss_missile8 =[ $attack8, boss_missile9 ] {boss_face();};
-void() boss_missile9 =[ $attack9, boss_missile10 ] {boss_missile('100 100 200');};
-void() boss_missile10 =[ $attack10, boss_missile11 ] {boss_face();};
-void() boss_missile11 =[ $attack11, boss_missile12 ] {boss_face();};
-void() boss_missile12 =[ $attack12, boss_missile13 ] {boss_face();};
-void() boss_missile13 =[ $attack13, boss_missile14 ] {boss_face();};
-void() boss_missile14 =[ $attack14, boss_missile15 ] {boss_face();};
-void() boss_missile15 =[ $attack15, boss_missile16 ] {boss_face();};
-void() boss_missile16 =[ $attack16, boss_missile17 ] {boss_face();};
-void() boss_missile17 =[ $attack17, boss_missile18 ] {boss_face();};
-void() boss_missile18 =[ $attack18, boss_missile19 ] {boss_face();};
-void() boss_missile19 =[ $attack19, boss_missile20 ] {boss_face();};
-void() boss_missile20 =[ $attack20, boss_missile21 ] {boss_missile('100 -100 200');};
-void() boss_missile21 =[ $attack21, boss_missile22 ] {boss_face();};
-void() boss_missile22 =[ $attack22, boss_missile23 ] {boss_face();};
-void() boss_missile23 =[ $attack23, boss_missile1 ] {boss_face();};
-
-void() boss_shocka1 =[ $shocka1, boss_shocka2 ] {};
-void() boss_shocka2 =[ $shocka2, boss_shocka3 ] {};
-void() boss_shocka3 =[ $shocka3, boss_shocka4 ] {};
-void() boss_shocka4 =[ $shocka4, boss_shocka5 ] {};
-void() boss_shocka5 =[ $shocka5, boss_shocka6 ] {};
-void() boss_shocka6 =[ $shocka6, boss_shocka7 ] {};
-void() boss_shocka7 =[ $shocka7, boss_shocka8 ] {};
-void() boss_shocka8 =[ $shocka8, boss_shocka9 ] {};
-void() boss_shocka9 =[ $shocka9, boss_shocka10 ] {};
-void() boss_shocka10 =[ $shocka10, boss_missile1 ] {};
-
-void() boss_shockb1 =[ $shockb1, boss_shockb2 ] {};
-void() boss_shockb2 =[ $shockb2, boss_shockb3 ] {};
-void() boss_shockb3 =[ $shockb3, boss_shockb4 ] {};
-void() boss_shockb4 =[ $shockb4, boss_shockb5 ] {};
-void() boss_shockb5 =[ $shockb5, boss_shockb6 ] {};
-void() boss_shockb6 =[ $shockb6, boss_shockb7 ] {};
-void() boss_shockb7 =[ $shockb1, boss_shockb8 ] {};
-void() boss_shockb8 =[ $shockb2, boss_shockb9 ] {};
-void() boss_shockb9 =[ $shockb3, boss_shockb10 ] {};
-void() boss_shockb10 =[ $shockb4, boss_missile1 ] {};
-
-void() boss_shockc1 =[ $shockc1, boss_shockc2 ] {};
-void() boss_shockc2 =[ $shockc2, boss_shockc3 ] {};
-void() boss_shockc3 =[ $shockc3, boss_shockc4 ] {};
-void() boss_shockc4 =[ $shockc4, boss_shockc5 ] {};
-void() boss_shockc5 =[ $shockc5, boss_shockc6 ] {};
-void() boss_shockc6 =[ $shockc6, boss_shockc7 ] {};
-void() boss_shockc7 =[ $shockc7, boss_shockc8 ] {};
-void() boss_shockc8 =[ $shockc8, boss_shockc9 ] {};
-void() boss_shockc9 =[ $shockc9, boss_shockc10 ] {};
-void() boss_shockc10 =[ $shockc10, boss_death1 ] {};
-
-void() boss_death1 = [$death1, boss_death2] {
-sound_death (self, CHAN_VOICE, "boss1/death.wav", 1, ATTN_NORM);
-};
-void() boss_death2 = [$death2, boss_death3] {};
-void() boss_death3 = [$death3, boss_death4] {};
-void() boss_death4 = [$death4, boss_death5] {};
-void() boss_death5 = [$death5, boss_death6] {};
-void() boss_death6 = [$death6, boss_death7] {};
-void() boss_death7 = [$death7, boss_death8] {};
-void() boss_death8 = [$death8, boss_death9] {};
-void() boss_death9 = [$death9, boss_death10]
-{
- sound_move (self, CHAN_BODY, "boss1/out1.wav", 1, ATTN_NORM);
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_LAVASPLASH);
- WriteCoord (MSG_BROADCAST, self.origin_x);
- WriteCoord (MSG_BROADCAST, self.origin_y);
- WriteCoord (MSG_BROADCAST, self.origin_z);
-};
+ // go for another player if multi player
+ if (this.enemy.health <= 0 || random() < 0.02)
+ {
+ this.enemy = findfloat (this.enemy, ::classtype,
+ CT_PLAYER);
+ if (!this.enemy)
+ this.enemy = findfloat (this.enemy, ::classtype,
+ CT_PLAYER);
+ }
-void() boss_death10 = [$death9, boss_death10]
-{
- killed_monsters = killed_monsters + 1;
- WriteByte (MSG_ALL, SVC_KILLEDMONSTER); // FIXME: reliable broadcast
- SUB_UseTargets ();
- remove (self);
-};
+ ai_face();
+ };
-void(vector p) boss_missile =
-{
- local vector offang;
- local vector org, vec, d;
- local float t;
+ //--------------------------------------------------------------
+ // boss_missile
+ //--------------------------------------------------------------
+ nonvirtual void(vector p) attack_missile =
+ {
+ local vector offang;
+ local vector org, vec, d;
+ local float t;
- offang = vectoangles (self.enemy.origin - self.origin);
- makevectors (offang);
+ offang = vectoangles (this.enemy.origin - this.origin);
+ makevectors (offang);
- org = self.origin + p_x*v_forward + p_y*v_right + p_z*'0 0 1';
+ org = this.origin + p_x*v_forward + p_y*v_right + p_z*'0 0 1';
-// lead the player on hard mode
- if (skill > 1)
- {
- t = vlen(self.enemy.origin - org) / 300;
- vec = self.enemy.velocity;
- vec_z = 0;
- d = self.enemy.origin + t * vec;
- }
- else
- {
- d = self.enemy.origin;
- }
+ // lead the player on hard mode
+ if (skill > 1)
+ {
+ t = vlen(this.enemy.origin - org) / 300;
+ vec = this.enemy.velocity;
+ vec_z = 0;
+ d = this.enemy.origin + t * vec;
+ }
+ else
+ {
+ d = this.enemy.origin;
+ }
- vec = normalize (d - org);
+ vec = normalize (d - org);
- launch_spike2 (org, vec, 300);
- // setmodel (newmis, "progs/lavaball.mdl");
- if (self.mdl_proj != "") // dumptruck_ds custom_mdls
- {
- setmodel (newmis, self.mdl_proj);
+ launch_spike2 (org, vec, 300);
+ // setmodel (newmis, "progs/lavaball.mdl");
+ if (this.mdl_proj != "") // dumptruck_ds custom_mdls
+ {
+ setmodel (newmis, this.mdl_proj);
}
else
{
setmodel (newmis, "progs/lavaball.mdl");
- }
+ }
- if (!newmis.skin_proj) // dumptruck_ds
- {
- newmis.skin = self.skin_proj;
+ // dumptruck_ds
+ if (!newmis.skin_proj)
+ {
+ newmis.skin = this.skin_proj;
}
else
{
newmis.skin = 0;
- }
-
- newmis.avelocity = '200 100 300';
- setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
- newmis.touch = T_MissileTouch; // rocket explosion
- sound_attack (self, CHAN_WEAPON, "boss1/throw.wav", 1, ATTN_NORM);
-
-// check for dead enemy
- if (self.enemy.health <= 0)
- boss_idle1 ();
-};
+ }
+ newmis.avelocity = '200 100 300';
+ setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
+ // rocket explosion
+ newmis.touch = T_MissileTouch;
+ sound_attack (this, CHAN_WEAPON, "boss1/throw.wav",
+ 1, ATTN_NORM);
+
+ // check for dead enemy
+ if (this.enemy.health <= 0)
+ this.idle1 ();
+ };
+
+ //--------------------------------------------------------------
+ // Chthon Idle functions
+ //--------------------------------------------------------------
+ nonvirtual void() idle1 = [$walk1, idle2]
+ {
+ // look for other players
+ };
+ nonvirtual void() idle2 = [$walk2, idle3] { boss_face (); };
+ nonvirtual void() idle3 = [$walk3, idle4] { boss_face (); };
+ nonvirtual void() idle4 = [$walk4, idle5] { boss_face (); };
+ nonvirtual void() idle5 = [$walk5, idle6] { boss_face (); };
+ nonvirtual void() idle6 = [$walk6, idle7] { boss_face (); };
+ nonvirtual void() idle7 = [$walk7, idle8] { boss_face (); };
+ nonvirtual void() idle8 = [$walk8, idle9] { boss_face (); };
+ nonvirtual void() idle9 = [$walk9, idle10] { boss_face (); };
+ nonvirtual void() idle10 = [$walk10, idle11] { boss_face (); };
+ nonvirtual void() idle11 = [$walk11, idle12] { boss_face (); };
+ nonvirtual void() idle12 = [$walk12, idle13] { boss_face (); };
+ nonvirtual void() idle13 = [$walk13, idle14] { boss_face (); };
+ nonvirtual void() idle14 = [$walk14, idle15] { boss_face (); };
+ nonvirtual void() idle15 = [$walk15, idle16] { boss_face (); };
+ nonvirtual void() idle16 = [$walk16, idle17] { boss_face (); };
+ nonvirtual void() idle17 = [$walk17, idle18] { boss_face (); };
+ nonvirtual void() idle18 = [$walk18, idle19] { boss_face (); };
+ nonvirtual void() idle19 = [$walk19, idle20] { boss_face (); };
+ nonvirtual void() idle20 = [$walk20, idle21] { boss_face (); };
+ nonvirtual void() idle21 = [$walk21, idle22] { boss_face (); };
+ nonvirtual void() idle22 = [$walk22, idle23] { boss_face (); };
+ nonvirtual void() idle23 = [$walk23, idle24] { boss_face (); };
+ nonvirtual void() idle24 = [$walk24, idle25] { boss_face (); };
+ nonvirtual void() idle25 = [$walk25, idle26] { boss_face (); };
+ nonvirtual void() idle26 = [$walk26, idle27] { boss_face (); };
+ nonvirtual void() idle27 = [$walk27, idle28] { boss_face (); };
+ nonvirtual void() idle28 = [$walk28, idle29] { boss_face (); };
+ nonvirtual void() idle29 = [$walk29, idle30] { boss_face (); };
+ nonvirtual void() idle30 = [$walk30, idle31] { boss_face (); };
+ nonvirtual void() idle31 = [$walk31, idle1] { boss_face (); };
+
+ //--------------------------------------------------------------
+ // Chthon Rises
+ //--------------------------------------------------------------
+ nonvirtual void() rise1 = [$rise1, rise2]
+ {
+ sound_move (this, CHAN_WEAPON, "boss1/out1.wav", 1, ATTN_NORM);
+ };
+ nonvirtual void() rise2 = [$rise2, rise3]
+ {
+ sound_sight (this, CHAN_VOICE, "boss1/sight1.wav", 1, ATTN_NORM);
+ };
+ nonvirtual void() rise3 = [$rise3, rise4] { };
+ nonvirtual void() rise4 = [$rise4, rise5] { };
+ nonvirtual void() rise5 = [$rise5, rise6] { };
+ nonvirtual void() rise6 = [$rise6, rise7] { };
+ nonvirtual void() rise7 = [$rise7, rise8] { };
+ nonvirtual void() rise8 = [$rise8, rise9] { };
+ nonvirtual void() rise9 = [$rise9, rise10] { };
+ nonvirtual void() rise10 = [$rise10, rise11] { };
+ nonvirtual void() rise11 = [$rise11, rise12] { };
+ nonvirtual void() rise12 = [$rise12, rise13] { };
+ nonvirtual void() rise13 = [$rise13, rise14] { };
+ nonvirtual void() rise14 = [$rise14, rise15] { };
+ nonvirtual void() rise15 = [$rise15, rise16] { };
+ nonvirtual void() rise16 = [$rise16, rise17] { };
+ nonvirtual void() rise17 = [$rise17, missile1] { };
+
+ //--------------------------------------------------------------
+ // Chthon Attack Lavaball
+ //--------------------------------------------------------------
+ nonvirtual void() missile1 = [$attack1, missile2] { boss_face (); };
+ nonvirtual void() missile2 = [$attack2, missile3] { boss_face (); };
+ nonvirtual void() missile3 = [$attack3, missile4] { boss_face (); };
+ nonvirtual void() missile4 = [$attack4, missile5] { boss_face (); };
+ nonvirtual void() missile5 = [$attack5, missile6] { boss_face (); };
+ nonvirtual void() missile6 = [$attack6, missile7] { boss_face (); };
+ nonvirtual void() missile7 = [$attack7, missile8] { boss_face (); };
+ nonvirtual void() missile8 = [$attack8, missile9] { boss_face (); };
+ nonvirtual void() missile9 = [$attack9, missile10]
+ {
+ attack_missile ('100 100 200');
+ };
+ nonvirtual void() missile10 = [$attack10, missile11] { boss_face (); };
+ nonvirtual void() missile11 = [$attack11, missile12] { boss_face (); };
+ nonvirtual void() missile12 = [$attack12, missile13] { boss_face (); };
+ nonvirtual void() missile13 = [$attack13, missile14] { boss_face (); };
+ nonvirtual void() missile14 = [$attack14, missile15] { boss_face (); };
+ nonvirtual void() missile15 = [$attack15, missile16] { boss_face (); };
+ nonvirtual void() missile16 = [$attack16, missile17] { boss_face (); };
+ nonvirtual void() missile17 = [$attack17, missile18] { boss_face (); };
+ nonvirtual void() missile18 = [$attack18, missile19] { boss_face (); };
+ nonvirtual void() missile19 = [$attack19, missile20] { boss_face (); };
+ nonvirtual void() missile20 = [$attack20, missile21]
+ {
+ attack_missile ('100 -100 200');
+ };
+ nonvirtual void() missile21 = [$attack21, missile22] { boss_face (); };
+ nonvirtual void() missile22 = [$attack22, missile23] { boss_face (); };
+ nonvirtual void() missile23 = [$attack23, missile1] { boss_face (); };
+
+ //--------------------------------------------------------------
+ // Chthon Shock! A
+ //--------------------------------------------------------------
+ nonvirtual void() shocka1 = [$shocka1, shocka2] { };
+ nonvirtual void() shocka2 = [$shocka2, shocka3] { };
+ nonvirtual void() shocka3 = [$shocka3, shocka4] { };
+ nonvirtual void() shocka4 = [$shocka4, shocka5] { };
+ nonvirtual void() shocka5 = [$shocka5, shocka6] { };
+ nonvirtual void() shocka6 = [$shocka6, shocka7] { };
+ nonvirtual void() shocka7 = [$shocka7, shocka8] { };
+ nonvirtual void() shocka8 = [$shocka8, shocka9] { };
+ nonvirtual void() shocka9 = [$shocka9, shocka10] { };
+ nonvirtual void() shocka10 = [$shocka10, missile1] { };
+
+ //--------------------------------------------------------------
+ // Chthon Shock! B
+ //--------------------------------------------------------------
+ nonvirtual void() shockb1 = [$shockb1, shockb2] { };
+ nonvirtual void() shockb2 = [$shockb2, shockb3] { };
+ nonvirtual void() shockb3 = [$shockb3, shockb4] { };
+ nonvirtual void() shockb4 = [$shockb4, shockb5] { };
+ nonvirtual void() shockb5 = [$shockb5, shockb6] { };
+ nonvirtual void() shockb6 = [$shockb6, shockb7] { };
+ nonvirtual void() shockb7 = [$shockb1, shockb8] { };
+ nonvirtual void() shockb8 = [$shockb2, shockb9] { };
+ nonvirtual void() shockb9 = [$shockb3, shockb10] { };
+ nonvirtual void() shockb10 = [$shockb4, missile1] { };
+
+ //--------------------------------------------------------------
+ // Chthon Shock! C
+ //--------------------------------------------------------------
+ nonvirtual void() shockc1 = [$shockc1, shockc2] { };
+ nonvirtual void() shockc2 = [$shockc2, shockc3] { };
+ nonvirtual void() shockc3 = [$shockc3, shockc4] { };
+ nonvirtual void() shockc4 = [$shockc4, shockc5] { };
+ nonvirtual void() shockc5 = [$shockc5, shockc6] { };
+ nonvirtual void() shockc6 = [$shockc6, shockc7] { };
+ nonvirtual void() shockc7 = [$shockc7, shockc8] { };
+ nonvirtual void() shockc8 = [$shockc8, shockc9] { };
+ nonvirtual void() shockc9 = [$shockc9, shockc10] { };
+ nonvirtual void() shockc10 = [$shockc10, death1] { };
+
+ //--------------------------------------------------------------
+ // Chthon Death state
+ //--------------------------------------------------------------
+ nonvirtual void() death1 = [$death1, death2]
+ {
+ sound_death (this, CHAN_VOICE, "boss1/death.wav", 1, ATTN_NORM);
+ };
+ nonvirtual void() death2 = [$death2, death3] { };
+ nonvirtual void() death3 = [$death3, death4] { };
+ nonvirtual void() death4 = [$death4, death5] { };
+ nonvirtual void() death5 = [$death5, death6] { };
+ nonvirtual void() death6 = [$death6, death7] { };
+ nonvirtual void() death7 = [$death7, death8] { };
+ nonvirtual void() death8 = [$death8, death9] { };
+ nonvirtual void() death9 = [$death9, death10]
+ {
+ sound_move (this, CHAN_BODY, "boss1/out1.wav", 1, ATTN_NORM);
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_LAVASPLASH);
+ WriteCoord (MSG_BROADCAST, this.origin_x);
+ WriteCoord (MSG_BROADCAST, this.origin_y);
+ WriteCoord (MSG_BROADCAST, this.origin_z);
+ };
+ nonvirtual void() death10 = [$death9, death10]
+ {
+ killed_monsters = killed_monsters + 1;
+ // FIXME: reliable broadcast
+ WriteByte (MSG_ALL, SVC_KILLEDMONSTER);
+ sub_usetargets ();
+ remove (this);
+ };
+
+ //==============================================================
+ // Interaction
+ //==============================================================
+
+ //--------------------------------------------------------------
+ // boss_awake
+ //--------------------------------------------------------------
+ virtual void() use =
+ {
+ this.solid = SOLID_SLIDEBOX;
+ this.movetype = MOVETYPE_STEP;
+ this.takedamage = DAMAGE_NO;
-void() boss_awake =
-{
- self.solid = SOLID_SLIDEBOX;
- self.movetype = MOVETYPE_STEP;
- self.takedamage = DAMAGE_NO;
+ body_model ("progs/boss.mdl");
+ // custom_mdl -- dumptruck_ds
+ // setmodel (this, "progs/boss.mdl");
+ setsize (this, '-128 -128 -24', '128 128 256');
- body_model ("progs/boss.mdl");
- // setmodel (self, "progs/boss.mdl"); //custom_mdl -- dumptruck_ds
- setsize (self, '-128 -128 -24', '128 128 256');
+ if (skill == 0)
+ this.health = 1;
+ else
+ this.health = 3;
- if (skill == 0)
- self.health = 1;
- else
- self.health = 3;
+ this.enemy = activator;
- self.enemy = activator;
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_LAVASPLASH);
+ WriteCoord (MSG_BROADCAST, this.origin_x);
+ WriteCoord (MSG_BROADCAST, this.origin_y);
+ WriteCoord (MSG_BROADCAST, this.origin_z);
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_LAVASPLASH);
- WriteCoord (MSG_BROADCAST, self.origin_x);
- WriteCoord (MSG_BROADCAST, self.origin_y);
- WriteCoord (MSG_BROADCAST, self.origin_z);
+ this.yaw_speed = 20;
+ this.rise1 ();
+ };
- self.yaw_speed = 20;
- boss_rise1 ();
-};
+ //==============================================================
+ // Initialization
+ //==============================================================
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
+ {
+ if (this.spawnflags & I_AM_TURRET)
+ objerror ("Incompatible spawnflag: TURRET_MODE\n");
-/*QUAKED monster_boss (1 0 0) (-128 -128 -24) (128 128 256)
-*/
-void() monster_boss =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
+ if (deathmatch)
+ {
+ remove (this);
+ return;
+ }
- if (self.spawnflags & I_AM_TURRET)
- objerror("Incompatible spawnflag: TURRET_MODE\n");
+ // precache_model ("progs/boss.mdl");
+ precache_body_model ("progs/boss.mdl");
+ precache_head_model ("progs/h_boss.mdl");
- if (deathmatch)
- {
- remove(self);
- return;
- }
- // precache_model ("progs/boss.mdl");
- precache_body_model ("progs/boss.mdl");
- precache_head_model ("progs/h_boss.mdl");
+ precache_model ("progs/lavaball.mdl");
- precache_model ("progs/lavaball.mdl");
+ precache_sound ("weapons/rocket1i.wav");
+ precache_sound_move ("boss1/out1.wav");
+ precache_sound_sight ("boss1/sight1.wav");
+ precache_sound ("misc/power.wav");
+ precache_sound_attack ("boss1/throw.wav");
+ precache_sound_pain ("boss1/pain.wav");
+ precache_sound_death ("boss1/death.wav");
- precache_sound ("weapons/rocket1i.wav");
- precache_sound_move ("boss1/out1.wav");
- precache_sound_sight ("boss1/sight1.wav");
- precache_sound ("misc/power.wav");
- precache_sound_attack ("boss1/throw.wav");
- precache_sound_pain ("boss1/pain.wav");
- precache_sound_death ("boss1/death.wav");
+ total_monsters = total_monsters + 1;
- total_monsters = total_monsters + 1;
+ this.flags = FL_MONSTER;
+ };
- self.flags = FL_MONSTER;
- self.touch = monster_touch; // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten
- self.use = boss_awake;
+ //--------------------------------------------------------------
+ void() monster_boss =
+ {
+ this.classtype = CT_MONSTER_BOSS_CHTHON;
+ };
};
-//===========================================================================
+//==============================================================================
+// Event Lightning
+//==============================================================================
-entity le1, le2;
-float lightning_end;
+//======================================================================
+// globals
+//======================================================================
+entity le1, le2;
+float lightning_end;
+//----------------------------------------------------------------------
void() lightning_fire =
{
local vector p1, p2;
if (time >= lightning_end)
- { // done here, put the terminals back up
+ {
+ // done here, put the terminals back up
((func_door)le1).door_go_down ();
((func_door)le2).door_go_down ();
return;
@@ -336,7 +395,7 @@ void() lightning_fire =
p2_z = le2.absmin_z - 16;
// compensate for length of bolt
- p2 = p2 - normalize(p2-p1)*100;
+ p2 = p2 - normalize(p2-p1) * 100;
self.nextthink = time + 0.1;
self.think = lightning_fire;
@@ -352,29 +411,29 @@ void() lightning_fire =
WriteCoord (MSG_ALL, p2_z);
};
+//----------------------------------------------------------------------
void() lightning_use =
{
if (lightning_end >= time + 1)
return;
- le1 = find( world, target, "lightning");
- le2 = find( le1, target, "lightning");
+ le1 = find (world, target, "lightning");
+ le2 = find (le1, target, "lightning");
if (!le1 || !le2)
{
dprint ("missing lightning targets\n");
return;
}
- if (
- (le1.state != FUNC_STATE_TOP && le1.state != FUNC_STATE_BOTTOM)
- || (le2.state != FUNC_STATE_TOP && le2.state != FUNC_STATE_BOTTOM)
- || (le1.state != le2.state) )
+ if ((le1.state != FUNC_STATE_TOP && le1.state != FUNC_STATE_BOTTOM) ||
+ (le2.state != FUNC_STATE_TOP && le2.state != FUNC_STATE_BOTTOM)
+ || (le1.state != le2.state))
{
-// dprint ("not aligned\n");
+ // dprint ("not aligned\n");
return;
}
-// don't let the electrodes go back up until the bolt is done
+ // don't let the electrodes go back up until the bolt is done
le1.nextthink = -1;
le2.nextthink = -1;
lightning_end = time + 1;
@@ -382,31 +441,33 @@ void() lightning_use =
sound (self, CHAN_VOICE, "misc/power.wav", 1, ATTN_NORM);
lightning_fire ();
-// advance the boss pain if down
- self = find (world, classname, "monster_boss");
- if (!self)
+ // advance the boss pain if down
+ local entity e;
+ e = findfloat (world, classtype, CT_MONSTER_BOSS_CHTHON);
+ if (!e)
return;
- self.enemy = activator;
- if (le1.state == FUNC_STATE_TOP && self.health > 0)
+ local monster_boss boss = (monster_boss)e;
+ boss.enemy = activator;
+ if (le1.state == FUNC_STATE_TOP && boss.health > 0)
{
- sound_pain (self, CHAN_VOICE, "boss1/pain.wav", 1, ATTN_NORM);
- self.health = self.health - 1;
- if (self.health >= 2)
- boss_shocka1();
- else if (self.health == 1)
- boss_shockb1();
- else if (self.health == 0)
- boss_shockc1();
+ sound_pain (boss, CHAN_VOICE, "boss1/pain.wav", 1, ATTN_NORM);
+ boss.health = boss.health - 1;
+ if (boss.health >= 2)
+ boss.shocka1 ();
+ else if (boss.health == 1)
+ boss.shockb1 ();
+ else if (boss.health == 0)
+ boss.shockc1 ();
}
};
-
/*QUAKED event_lightning (0 1 1) (-16 -16 -16) (16 16 16) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
Just for boss level.
*/
void() event_lightning =
{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
return;
self.use = lightning_use;
Return to the top of this page or return to the overview of this repo.
Diff qc/monsters/boss2.qc
diff --git a/qc/monsters/boss2.qc b/qc/monsters/boss2.qc
index e58227b..0a315ed 100644
--- a/qc/monsters/boss2.qc
+++ b/qc/monsters/boss2.qc
@@ -1,10 +1,17 @@
-/*
-==============================================================================
+//==============================================================================
+// BOSS-ONE
+//==============================================================================
-BOSS-ONE
+//======================================================================
+// constants
+//======================================================================
-==============================================================================
-*/
+// supress lava splash effect when raising, lowering or gibbing - dumptruck_ds
+const float NO_LAVASPLASH = 2;
+
+//======================================================================
+// frame macros
+//======================================================================
$cd id1/models/boss1
$origin 0 0 -15
$base base
@@ -34,458 +41,548 @@ $frame shockb1 shockb2 shockb3 shockb4 shockb5 shockb6
$frame shockc1 shockc2 shockc3 shockc4 shockc5 shockc6 shockc7 shockc8
$frame shockc9 shockc10
-float NO_LAVASPLASH = 2; //supress lava splash effect when raising, lowering or gibbing - dumptruck_ds
-
-void(vector p) boss2_missile;
-
-void() boss2_face =
+/*QUAKED monster_boss2 (1 0 0) (-128 -128 -24) (128 128 256)
+*/
+class monster_boss2: base_monster
{
-// go for another player if multi player
- if (self.enemy.health <= 0 || random() < 0.02)
+ //--------------------------------------------------------------
+ nonvirtual void() boss2_face =
{
- self.enemy = find(self.enemy, classname, "player");
- if (!self.enemy)
- self.enemy = find(self.enemy, classname, "player");
- }
- ai_face();
-};
+ // go for another player if multi player
+ if (this.enemy.health <= 0 || random() < 0.02)
+ {
+ this.enemy = findfloat (this.enemy, ::classtype,
+ CT_PLAYER);
+ if (!this.enemy)
+ this.enemy = findfloat (this.enemy, ::classtype,
+ CT_PLAYER);
+ }
+ ai_face ();
+ };
-void() boss2_rise1 =[ $rise1, boss2_rise2 ] {
- sound_move (self, CHAN_AUTO, "boss1/out1.wav", 1, ATTN_NORM);
-};
-void() boss2_rise2 =[ $rise2, boss2_rise3 ] {
- sound_sight (self, CHAN_AUTO, "boss1/sight1.wav", 1, ATTN_NORM);
-};
-void() boss2_rise3 =[ $rise3, boss2_rise4 ] {};
-void() boss2_rise4 =[ $rise4, boss2_rise5 ] {};
-void() boss2_rise5 =[ $rise5, boss2_rise6 ] {};
-void() boss2_rise6 =[ $rise6, boss2_rise7 ] {};
-void() boss2_rise7 =[ $rise7, boss2_rise8 ] {};
-void() boss2_rise8 =[ $rise8, boss2_rise9 ] {};
-void() boss2_rise9 =[ $rise9, boss2_rise10 ] {};
-void() boss2_rise10 =[ $rise10, boss2_rise11 ] {};
-void() boss2_rise11 =[ $rise11, boss2_rise12 ] {};
-void() boss2_rise12 =[ $rise12, boss2_rise13 ] {};
-void() boss2_rise13 =[ $rise13, boss2_rise14 ] {};
-void() boss2_rise14 =[ $rise14, boss2_rise15 ] {};
-void() boss2_rise15 =[ $rise15, boss2_rise16 ] {};
-void() boss2_rise16 =[ $rise16, boss2_rise17 ] {};
-void() boss2_rise17 =[ $rise17, boss2_missile1 ] {};
-
-void() boss2_idle1 =[ $walk1, boss2_idle2 ]
-{
-// look for other players
-};
-void() boss2_idle2 =[ $walk2, boss2_idle3 ] {boss2_face();};
-void() boss2_idle3 =[ $walk3, boss2_idle4 ] {boss2_face();};
-void() boss2_idle4 =[ $walk4, boss2_idle5 ] {boss2_face();};
-void() boss2_idle5 =[ $walk5, boss2_idle6 ] {boss2_face();};
-void() boss2_idle6 =[ $walk6, boss2_idle7 ] {boss2_face();};
-void() boss2_idle7 =[ $walk7, boss2_idle8 ] {boss2_face();};
-void() boss2_idle8 =[ $walk8, boss2_idle9 ] {boss2_face();};
-void() boss2_idle9 =[ $walk9, boss2_idle10 ] {boss2_face();};
-void() boss2_idle10 =[ $walk10, boss2_idle11 ] {boss2_face();};
-void() boss2_idle11 =[ $walk11, boss2_idle12 ] {boss2_face();};
-void() boss2_idle12 =[ $walk12, boss2_idle13 ] {boss2_face();};
-void() boss2_idle13 =[ $walk13, boss2_idle14 ] {boss2_face();};
-void() boss2_idle14 =[ $walk14, boss2_idle15 ] {boss2_face();};
-void() boss2_idle15 =[ $walk15, boss2_idle16 ] {boss2_face();};
-void() boss2_idle16 =[ $walk16, boss2_idle17 ] {boss2_face();};
-void() boss2_idle17 =[ $walk17, boss2_idle18 ] {boss2_face();};
-void() boss2_idle18 =[ $walk18, boss2_idle19 ] {boss2_face();};
-void() boss2_idle19 =[ $walk19, boss2_idle20 ] {boss2_face();};
-void() boss2_idle20 =[ $walk20, boss2_idle21 ] {boss2_face();};
-void() boss2_idle21 =[ $walk21, boss2_idle22 ] {boss2_face();};
-void() boss2_idle22 =[ $walk22, boss2_idle23 ] {boss2_face();};
-void() boss2_idle23 =[ $walk23, boss2_idle24 ] {boss2_face();};
-void() boss2_idle24 =[ $walk24, boss2_idle25 ] {boss2_face();};
-void() boss2_idle25 =[ $walk25, boss2_idle26 ] {boss2_face();};
-void() boss2_idle26 =[ $walk26, boss2_idle27 ] {boss2_face();};
-void() boss2_idle27 =[ $walk27, boss2_idle28 ] {boss2_face();};
-void() boss2_idle28 =[ $walk28, boss2_idle29 ] {boss2_face();};
-void() boss2_idle29 =[ $walk29, boss2_idle30 ] {boss2_face();};
-void() boss2_idle30 =[ $walk30, boss2_idle31 ] {boss2_face();};
-void() boss2_idle31 =[ $walk31, boss2_idle1 ] {boss2_face();};
-
-void() boss2_missile1 =[ $attack1, boss2_missile2 ] {boss2_face();};
-void() boss2_missile2 =[ $attack2, boss2_missile3 ] {boss2_face();};
-void() boss2_missile3 =[ $attack3, boss2_missile4 ] {boss2_face();};
-void() boss2_missile4 =[ $attack4, boss2_missile5 ] {boss2_face();};
-void() boss2_missile5 =[ $attack5, boss2_missile6 ] {boss2_face();};
-void() boss2_missile6 =[ $attack6, boss2_missile7 ] {boss2_face();};
-void() boss2_missile7 =[ $attack7, boss2_missile8 ] {boss2_face();};
-void() boss2_missile8 =[ $attack8, boss2_missile9 ] {boss2_face();};
-void() boss2_missile9 =[ $attack9, boss2_missile10 ] {boss2_missile('100 100 200');};
-void() boss2_missile10 =[ $attack10, boss2_missile11 ] {boss2_face();};
-void() boss2_missile11 =[ $attack11, boss2_missile12 ] {boss2_face();};
-void() boss2_missile12 =[ $attack12, boss2_missile13 ] {boss2_face();};
-void() boss2_missile13 =[ $attack13, boss2_missile14 ] {boss2_face();};
-void() boss2_missile14 =[ $attack14, boss2_missile15 ] {boss2_face();};
-void() boss2_missile15 =[ $attack15, boss2_missile16 ] {boss2_face();};
-void() boss2_missile16 =[ $attack16, boss2_missile17 ] {boss2_face();};
-void() boss2_missile17 =[ $attack17, boss2_missile18 ] {boss2_face();};
-void() boss2_missile18 =[ $attack18, boss2_missile19 ] {boss2_face();};
-void() boss2_missile19 =[ $attack19, boss2_missile20 ] {boss2_face();};
-void() boss2_missile20 =[ $attack20, boss2_missile21 ] {boss2_missile('100 -100 200');};
-void() boss2_missile21 =[ $attack21, boss2_missile22 ] {boss2_face();};
-void() boss2_missile22 =[ $attack22, boss2_missile23 ] {boss2_face();};
-void() boss2_missile23 =[ $attack23, boss2_missile1 ] {boss2_face();};
-
-void() boss2_shocka1 =[ $shocka1, boss2_shocka2 ] {};
-void() boss2_shocka2 =[ $shocka2, boss2_shocka3 ] {};
-void() boss2_shocka3 =[ $shocka3, boss2_shocka4 ] {};
-void() boss2_shocka4 =[ $shocka4, boss2_shocka5 ] {};
-void() boss2_shocka5 =[ $shocka5, boss2_shocka6 ] {};
-void() boss2_shocka6 =[ $shocka6, boss2_shocka7 ] {};
-void() boss2_shocka7 =[ $shocka7, boss2_shocka8 ] {};
-void() boss2_shocka8 =[ $shocka8, boss2_shocka9 ] {};
-void() boss2_shocka9 =[ $shocka9, boss2_shocka10 ] {};
-void() boss2_shocka10 =[ $shocka10, boss2_missile1 ] {};
-
-void() boss2_shockb1 =[ $shockb1, boss2_shockb2 ] {};
-void() boss2_shockb2 =[ $shockb2, boss2_shockb3 ] {};
-void() boss2_shockb3 =[ $shockb3, boss2_shockb4 ] {};
-void() boss2_shockb4 =[ $shockb4, boss2_shockb5 ] {};
-void() boss2_shockb5 =[ $shockb5, boss2_shockb6 ] {};
-void() boss2_shockb6 =[ $shockb6, boss2_shockb7 ] {};
-void() boss2_shockb7 =[ $shockb1, boss2_shockb8 ] {};
-void() boss2_shockb8 =[ $shockb2, boss2_shockb9 ] {};
-void() boss2_shockb9 =[ $shockb3, boss2_shockb10 ] {};
-void() boss2_shockb10 =[ $shockb4, boss2_missile1 ] {};
-
-void() boss2_shockc1 =[ $shockc1, boss2_shockc2 ] {};
-void() boss2_shockc2 =[ $shockc2, boss2_shockc3 ] {};
-void() boss2_shockc3 =[ $shockc3, boss2_shockc4 ] {};
-void() boss2_shockc4 =[ $shockc4, boss2_shockc5 ] {};
-void() boss2_shockc5 =[ $shockc5, boss2_shockc6 ] {};
-void() boss2_shockc6 =[ $shockc6, boss2_shockc7 ] {};
-void() boss2_shockc7 =[ $shockc7, boss2_shockc8 ] {};
-void() boss2_shockc8 =[ $shockc8, boss2_shockc9 ] {};
-void() boss2_shockc9 =[ $shockc9, boss2_shockc10 ] {};
-void() boss2_shockc10 =[ $shockc10, boss2_death1 ] {};
-
-void() boss2_pain1 =[ $shocka1, boss2_pain2 ] {};
-void() boss2_pain2 =[ $shocka2, boss2_pain3 ] {};
-void() boss2_pain3 =[ $shocka3, boss2_pain4 ] {};
-void() boss2_pain4 =[ $shocka4, boss2_pain5 ] {
- sound_pain (self, CHAN_VOICE, "boss1/pain.wav", 1, ATTN_NORM); // pain noise
-};
-void() boss2_pain5 =[ $shocka5, boss2_pain6 ] {};
-void() boss2_pain6 =[ $shocka6, bos2s_pain7 ] {};
-void() bos2s_pain7 =[ $shocka7, boss2_pain8 ] {};
-void() boss2_pain8 =[ $shocka8, boss2_pain9 ] {};
-void() boss2_pain9 =[ $shocka9, boss2_missile1 ] {}; // auto shoot a lavaball
+ //--------------------------------------------------------------
+ // boss2_missile
+ //--------------------------------------------------------------
+ nonvirtual void(vector p) attack_missile =
+ {
+ local vector offang;
+ local vector org, vec, d;
+ local float t;
+ offang = vectoangles (this.enemy.origin - this.origin);
+ makevectors (offang);
-void() GibBoss2 =
-{
- sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
- // throw tons of meat chunks
+ org = this.origin + p_x * v_forward + p_y * v_right +
+ p_z * '0 0 1';
- local vector boss;
- local float x, y, z;
- local float r;
- // local entity n;
+ // lead the player on hard mode
+ if (skill > 1)
+ {
+ t = vlen (this.enemy.origin - org) / 300;
+ vec = this.enemy.velocity;
+ vec_z = 0;
+ d = this.enemy.origin + t * vec;
+ }
+ else
+ {
+ d = this.enemy.origin;
+ }
- boss = self.origin;
- z = 16;
- while (z <= 144)
+ vec = normalize (d - org);
+
+ launch_spike2 (org, vec, 300);
+ // setmodel (newmis, "progs/lavaball.mdl");
+ // dumptruck_ds custom_mdls
+ if (this.mdl_proj != "")
+ {
+ setmodel (newmis, this.mdl_proj);
+ }
+ else
+ {
+ setmodel (newmis, "progs/lavaball.mdl");
+ }
+
+ // dumptruck_ds
+ if (!newmis.skin_proj)
+ {
+ newmis.skin = this.skin_proj;
+ }
+ else
+ {
+ newmis.skin = 0;
+ }
+
+ newmis.avelocity = '200 100 300';
+ setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
+ // rocket explosion
+ newmis.touch = T_MissileTouch;
+ sound_attack (this, CHAN_WEAPON, "boss1/throw.wav",
+ 1, ATTN_NORM);
+
+ // check for dead enemy
+ if (this.enemy.health <= 0)
+ this.idle1 ();
+ };
+
+ //--------------------------------------------------------------
+ // GibBoss2
+ //--------------------------------------------------------------
+ nonvirtual void() gib_boss2 =
{
- x = -64;
- while (x <= 64)
+ sound (this, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
+ // throw tons of meat chunks
+
+ local vector boss;
+ local float x, y, z;
+ local float r;
+ // local entity n;
+
+ boss = this.origin;
+ z = 16;
+ while (z <= 144)
{
- y = -64;
- while (y <= 64)
+ x = -64;
+ while (x <= 64)
{
- self.origin_x = boss_x + x;
- self.origin_y = boss_y + y;
- self.origin_z = boss_z + z;
-
- r = random();
- if (r < 0.3)
- // ThrowGib ("progs/gib1.mdl", -120);
- if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
- {
- ThrowGib (self.mdl_gib1, -120);
- }
- else
- {
- ThrowGib ("progs/gib1.mdl", -120);
- }
- else if (r < 0.5)
- // ThrowGib ("progs/gib2.mdl", -120);
- if (self.mdl_gib2 != "") // custom models -- dumptruck_ds
+ y = -64;
+ while (y <= 64)
+ {
+ this.origin_x = boss_x + x;
+ this.origin_y = boss_y + y;
+ this.origin_z = boss_z + z;
+
+ r = random ();
+ if (r < 0.3)
{
- ThrowGib (self.mdl_gib2, -120);
+ // custom models -- dumptruck_ds
+ if (this.mdl_gib1 != "")
+ {
+ ThrowGib (this.mdl_gib1,
+ -120);
+ }
+ else
+ {
+ ThrowGib ("progs/gib1."
+ "mdl", -120);
+ }
}
- else
+ else if (r < 0.5)
{
- ThrowGib ("progs/gib2.mdl", -120);
+ // custom models -- dumptruck_ds
+ if (this.mdl_gib2 != "")
+ {
+ ThrowGib (this.mdl_gib2,
+ -120);
+ }
+ else
+ {
+ ThrowGib ("progs/gib2."
+ "mdl", -120);
+ }
}
- else if (r < 0.7)
- ThrowGib ("progs/lavaball.mdl", -120);
- else
- // ThrowGib ("progs/gib3.mdl", -120);
- if (self.mdl_gib3 != "") // custom models -- dumptruck_ds
+ else if (r < 0.7)
{
- ThrowGib (self.mdl_gib3, -120);
+ ThrowGib ("progs/lavaball.mdl",
+ -120);
}
else
{
- ThrowGib ("progs/gib3.mdl", -120);
+ // custom models -- dumptruck_ds
+ if (this.mdl_gib3 != "")
+ {
+ ThrowGib (this.mdl_gib3,
+ -120);
+ }
+ else
+ {
+ ThrowGib ("progs/gib3."
+ "mdl", -120);
+ }
}
- y = y + 32;
+ y = y + 32;
+ }
+ x = x + 32;
}
- x = x + 32;
+ z = z + 96;
}
- z = z + 96;
- }
-
- local entity head;
-
- head = spawn();
- head.origin = self.origin + '0 0 128';
- head.velocity_z = 600; + (random() * 200);
- head.velocity_x = -300 + (random() * 600);
- head.velocity_y = -200 + (random() * 600);
- head.avelocity_x = random()*120;
- head.avelocity_y = random()*120;
- head.avelocity_z = random()*120;
- head.flags = self.flags - (self.flags & FL_ONGROUND);
- head.solid = SOLID_NOT;
- head.movetype = MOVETYPE_BOUNCE;
- head.takedamage = DAMAGE_NO;
- if (self.mdl_head != "") // dumptruck_ds custom_mdls
- {
- setmodel (head, self.mdl_head);
+
+ local entity head;
+
+ head = spawn ();
+ head.origin = this.origin + '0 0 128';
+ head.velocity_z = 600; + (random() * 200);
+ head.velocity_x = -300 + (random() * 600);
+ head.velocity_y = -200 + (random() * 600);
+ head.avelocity_x = random() * 120;
+ head.avelocity_y = random() * 120;
+ head.avelocity_z = random() * 120;
+ head.flags = this.flags - (this.flags & FL_ONGROUND);
+ head.solid = SOLID_NOT;
+ head.movetype = MOVETYPE_BOUNCE;
+ head.takedamage = DAMAGE_NO;
+ // dumptruck_ds custom_mdls
+ if (this.mdl_head != "")
+ {
+ setmodel (head, this.mdl_head);
}
else
{
setmodel (head, "progs/h_boss.mdl");
- }
+ }
- if (!self.skin_head) // dumptruck_ds
- {
- head.skin = self.skin_proj;
+ // dumptruck_ds
+ if (!this.skin_head)
+ {
+ head.skin = this.skin_proj;
}
else
{
head.skin = 0;
- }
- setsize (head, '-67 -60 -6', '62 52 88');
- // setsize (head, '-16 -16 0', '16 16 56');
- head.touch = sub_null;
- head.think = sub_remove;
- head.nextthink = time + 120;
- if !(self.spawnflags & NO_LAVASPLASH)
- {
- // killed_monsters = killed_monsters + 1; //already done in combat.qc since this is now FL_MONSTER
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_LAVASPLASH);
- // WriteByte (MSG_ALL, SVC_KILLEDMONSTER); //already done in combat.qc since this is now FL_MONSTER -- dumptruck_ds
- WriteCoord (MSG_BROADCAST, self.origin_x);
- WriteCoord (MSG_BROADCAST, self.origin_y);
- WriteCoord (MSG_BROADCAST, self.origin_z);
- }
- remove (self);
-};
+ }
+ setsize (head, '-67 -60 -6', '62 52 88');
+ // setsize (head, '-16 -16 0', '16 16 56');
+ head.touch = sub_null;
+ head.think = sub_remove;
+ head.nextthink = time + 120;
+ if !(this.spawnflags & NO_LAVASPLASH)
+ {
+ // done in combat.qc since this is now FL_MONSTER
+ // killed_monsters = killed_monsters + 1;
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_LAVASPLASH);
+ // done in combat.qc since this is now FL_MONSTER
+ // -- dumptruck_ds
+ // WriteByte (MSG_ALL, SVC_KILLEDMONSTER);
+ WriteCoord (MSG_BROADCAST, this.origin_x);
+ WriteCoord (MSG_BROADCAST, this.origin_y);
+ WriteCoord (MSG_BROADCAST, this.origin_z);
+ }
+ remove (this);
+ };
-void() boss2_die =
-{
- if (self.health < -50) // if health under -15
+ //--------------------------------------------------------------
+ // Chthon Idle State
+ //--------------------------------------------------------------
+ nonvirtual void() idle1 = [$walk1, idle2]
{
- GibBoss2 ();
- return;
- }
- else // otherwise
+ // look for other players
+ };
+ nonvirtual void() idle2 = [$walk2, idle3] { boss2_face (); };
+ nonvirtual void() idle3 = [$walk3, idle4] { boss2_face (); };
+ nonvirtual void() idle4 = [$walk4, idle5] { boss2_face (); };
+ nonvirtual void() idle5 = [$walk5, idle6] { boss2_face (); };
+ nonvirtual void() idle6 = [$walk6, idle7] { boss2_face (); };
+ nonvirtual void() idle7 = [$walk7, idle8] { boss2_face (); };
+ nonvirtual void() idle8 = [$walk8, idle9] { boss2_face (); };
+ nonvirtual void() idle9 = [$walk9, idle10] { boss2_face (); };
+ nonvirtual void() idle10 = [$walk10, idle11] { boss2_face (); };
+ nonvirtual void() idle11 = [$walk11, idle12] { boss2_face (); };
+ nonvirtual void() idle12 = [$walk12, idle13] { boss2_face (); };
+ nonvirtual void() idle13 = [$walk13, idle14] { boss2_face (); };
+ nonvirtual void() idle14 = [$walk14, idle15] { boss2_face (); };
+ nonvirtual void() idle15 = [$walk15, idle16] { boss2_face (); };
+ nonvirtual void() idle16 = [$walk16, idle17] { boss2_face (); };
+ nonvirtual void() idle17 = [$walk17, idle18] { boss2_face (); };
+ nonvirtual void() idle18 = [$walk18, idle19] { boss2_face (); };
+ nonvirtual void() idle19 = [$walk19, idle20] { boss2_face (); };
+ nonvirtual void() idle20 = [$walk20, idle21] { boss2_face (); };
+ nonvirtual void() idle21 = [$walk21, idle22] { boss2_face (); };
+ nonvirtual void() idle22 = [$walk22, idle23] { boss2_face (); };
+ nonvirtual void() idle23 = [$walk23, idle24] { boss2_face (); };
+ nonvirtual void() idle24 = [$walk24, idle25] { boss2_face (); };
+ nonvirtual void() idle25 = [$walk25, idle26] { boss2_face (); };
+ nonvirtual void() idle26 = [$walk26, idle27] { boss2_face (); };
+ nonvirtual void() idle27 = [$walk27, idle28] { boss2_face (); };
+ nonvirtual void() idle28 = [$walk28, idle29] { boss2_face (); };
+ nonvirtual void() idle29 = [$walk29, idle30] { boss2_face (); };
+ nonvirtual void() idle30 = [$walk30, idle31] { boss2_face (); };
+ nonvirtual void() idle31 = [$walk31, idle1] { boss2_face (); };
+
+ //--------------------------------------------------------------
+ // Chthon Rises
+ //--------------------------------------------------------------
+ nonvirtual void() rise1 = [$rise1, rise2]
{
- boss2_death1 (); // normal death
- return;
- }
-};
-
-void() boss2_death1 = [$death1, boss2_death2] {
- sound_death (self, CHAN_VOICE, "boss1/death.wav", 1, ATTN_NORM);
-};
-void() boss2_death2 = [$death2, boss2_death3] {};
-void() boss2_death3 = [$death3, boss2_death4] {};
-void() boss2_death4 = [$death4, boss2_death5] {};
-void() boss2_death5 = [$death5, boss2_death6] {};
-void() boss2_death6 = [$death6, boss2_death7] {};
-void() boss2_death7 = [$death7, boss2_death8] {};
-void() boss2_death8 = [$death8, boss2_death9] {};
-void() boss2_death9 = [$death9, boss2_death10]
-{
- sound_move (self, CHAN_BODY, "boss1/out1.wav", 1, ATTN_NORM);
- if !(self.spawnflags & NO_LAVASPLASH)
+ sound_move (this, CHAN_AUTO, "boss1/out1.wav", 1, ATTN_NORM);
+ };
+ nonvirtual void() rise2 = [$rise2, rise3]
{
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_LAVASPLASH);
- WriteCoord (MSG_BROADCAST, self.origin_x);
- WriteCoord (MSG_BROADCAST, self.origin_y);
- WriteCoord (MSG_BROADCAST, self.origin_z);
- }
-};
-
-void(entity attacker, float damage) boss2_pain_go =
-{
- if (self.pain_finished > time)
- return;
-
- boss2_pain1();
- self.pain_finished = time + 4;
-};
-
-void() boss2_death10 = [$death9, boss2_death10]
-{
-// unlike the code for the original monster_boss, this function doesn't
-// need to increment killed_monsters or call SUB_UseTargets(); this
-// entity gets killed by regular damage and has FL_MONSTER, so the
-// Killed() function (in combat.qc) will already have taken care of
-// those things -- iw
-
- remove (self);
-};
-
-void(vector p) boss2_missile =
-{
- local vector offang;
- local vector org, vec, d;
- local float t;
-
- offang = vectoangles (self.enemy.origin - self.origin);
- makevectors (offang);
-
- org = self.origin + p_x*v_forward + p_y*v_right + p_z*'0 0 1';
-
-// lead the player on hard mode
- if (skill > 1)
+ sound_sight (this, CHAN_AUTO, "boss1/sight1.wav", 1, ATTN_NORM);
+ };
+ nonvirtual void() rise3 = [$rise3, rise4] { };
+ nonvirtual void() rise4 = [$rise4, rise5] { };
+ nonvirtual void() rise5 = [$rise5, rise6] { };
+ nonvirtual void() rise6 = [$rise6, rise7] { };
+ nonvirtual void() rise7 = [$rise7, rise8] { };
+ nonvirtual void() rise8 = [$rise8, rise9] { };
+ nonvirtual void() rise9 = [$rise9, rise10] { };
+ nonvirtual void() rise10 = [$rise10, rise11] { };
+ nonvirtual void() rise11 = [$rise11, rise12] { };
+ nonvirtual void() rise12 = [$rise12, rise13] { };
+ nonvirtual void() rise13 = [$rise13, rise14] { };
+ nonvirtual void() rise14 = [$rise14, rise15] { };
+ nonvirtual void() rise15 = [$rise15, rise16] { };
+ nonvirtual void() rise16 = [$rise16, rise17] { };
+ nonvirtual void() rise17 = [$rise17, missile1] { };
+
+ //--------------------------------------------------------------
+ // Chthon Attack Lavaball
+ //--------------------------------------------------------------
+ nonvirtual void() missile1 = [$attack1, missile2] { boss2_face (); };
+ nonvirtual void() missile2 = [$attack2, missile3] { boss2_face (); };
+ nonvirtual void() missile3 = [$attack3, missile4] { boss2_face (); };
+ nonvirtual void() missile4 = [$attack4, missile5] { boss2_face (); };
+ nonvirtual void() missile5 = [$attack5, missile6] { boss2_face (); };
+ nonvirtual void() missile6 = [$attack6, missile7] { boss2_face (); };
+ nonvirtual void() missile7 = [$attack7, missile8] { boss2_face (); };
+ nonvirtual void() missile8 = [$attack8, missile9] { boss2_face (); };
+ nonvirtual void() missile9 = [$attack9, missile10]
{
- t = vlen(self.enemy.origin - org) / 300;
- vec = self.enemy.velocity;
- vec_z = 0;
- d = self.enemy.origin + t * vec;
- }
- else
+ this.attack_missile ('100 100 200');
+ };
+ nonvirtual void() missile10 = [$attack10, missile11] { boss2_face (); };
+ nonvirtual void() missile11 = [$attack11, missile12] { boss2_face (); };
+ nonvirtual void() missile12 = [$attack12, missile13] { boss2_face (); };
+ nonvirtual void() missile13 = [$attack13, missile14] { boss2_face (); };
+ nonvirtual void() missile14 = [$attack14, missile15] { boss2_face (); };
+ nonvirtual void() missile15 = [$attack15, missile16] { boss2_face (); };
+ nonvirtual void() missile16 = [$attack16, missile17] { boss2_face (); };
+ nonvirtual void() missile17 = [$attack17, missile18] { boss2_face (); };
+ nonvirtual void() missile18 = [$attack18, missile19] { boss2_face (); };
+ nonvirtual void() missile19 = [$attack19, missile20] { boss2_face (); };
+ nonvirtual void() missile20 = [$attack20, missile21]
{
- d = self.enemy.origin;
- }
-
- vec = normalize (d - org);
+ attack_missile ('100 -100 200');
+ };
+ nonvirtual void() missile21 = [$attack21, missile22] { boss2_face (); };
+ nonvirtual void() missile22 = [$attack22, missile23] { boss2_face (); };
+ nonvirtual void() missile23 = [$attack23, missile1] { boss2_face (); };
+
+ //--------------------------------------------------------------
+ // Chthon Shock! A
+ //--------------------------------------------------------------
+ nonvirtual void() shocka1 = [$shocka1, shocka2] { };
+ nonvirtual void() shocka2 = [$shocka2, shocka3] { };
+ nonvirtual void() shocka3 = [$shocka3, shocka4] { };
+ nonvirtual void() shocka4 = [$shocka4, shocka5] { };
+ nonvirtual void() shocka5 = [$shocka5, shocka6] { };
+ nonvirtual void() shocka6 = [$shocka6, shocka7] { };
+ nonvirtual void() shocka7 = [$shocka7, shocka8] { };
+ nonvirtual void() shocka8 = [$shocka8, shocka9] { };
+ nonvirtual void() shocka9 = [$shocka9, shocka10] { };
+ nonvirtual void() shocka10 = [$shocka10, missile1] { };
+
+ //--------------------------------------------------------------
+ // Chthon Shock! B
+ //--------------------------------------------------------------
+ nonvirtual void() shockb1 = [$shockb1, shockb2] { };
+ nonvirtual void() shockb2 = [$shockb2, shockb3] { };
+ nonvirtual void() shockb3 = [$shockb3, shockb4] { };
+ nonvirtual void() shockb4 = [$shockb4, shockb5] { };
+ nonvirtual void() shockb5 = [$shockb5, shockb6] { };
+ nonvirtual void() shockb6 = [$shockb6, shockb7] { };
+ nonvirtual void() shockb7 = [$shockb1, shockb8] { };
+ nonvirtual void() shockb8 = [$shockb2, shockb9] { };
+ nonvirtual void() shockb9 = [$shockb3, shockb10] { };
+ nonvirtual void() shockb10 = [$shockb4, missile1] { };
+
+ //--------------------------------------------------------------
+ // Chthon Shock! C
+ //--------------------------------------------------------------
+ nonvirtual void() shockc1 = [$shockc1, shockc2] { };
+ nonvirtual void() shockc2 = [$shockc2, shockc3] { };
+ nonvirtual void() shockc3 = [$shockc3, shockc4] { };
+ nonvirtual void() shockc4 = [$shockc4, shockc5] { };
+ nonvirtual void() shockc5 = [$shockc5, shockc6] { };
+ nonvirtual void() shockc6 = [$shockc6, shockc7] { };
+ nonvirtual void() shockc7 = [$shockc7, shockc8] { };
+ nonvirtual void() shockc8 = [$shockc8, shockc9] { };
+ nonvirtual void() shockc9 = [$shockc9, shockc10] { };
+ nonvirtual void() shockc10 = [$shockc10, death1] { };
+
+ //--------------------------------------------------------------
+ // Chthon Pain state
+ //--------------------------------------------------------------
+ nonvirtual void() pain1 = [$shocka1, pain2] { };
+ nonvirtual void() pain2 = [$shocka2, pain3] { };
+ nonvirtual void() pain3 = [$shocka3, pain4] { };
+ nonvirtual void() pain4 = [$shocka4, pain5]
+ {
+ // pain noise
+ sound_pain (this, CHAN_VOICE, "boss1/pain.wav", 1, ATTN_NORM);
+ };
+ nonvirtual void() pain5 = [$shocka5, pain6] { };
+ nonvirtual void() pain6 = [$shocka6, pain7] { };
+ nonvirtual void() pain7 = [$shocka7, pain8] { };
+ nonvirtual void() pain8 = [$shocka8, pain9] { };
+ nonvirtual void() pain9 = [$shocka9, missile1]
+ {
+ // auto shoot a lavaball (by advancing to next think state)
+ };
- launch_spike2 (org, vec, 300);
- // setmodel (newmis, "progs/lavaball.mdl");
- if (self.mdl_proj != "") // dumptruck_ds custom_mdls
+ //--------------------------------------------------------------
+ // Chthon Death state
+ //--------------------------------------------------------------
+ nonvirtual void() death1 = [$death1, death2]
{
- setmodel (newmis, self.mdl_proj);
- }
- else
+ sound_death (this, CHAN_VOICE, "boss1/death.wav", 1, ATTN_NORM);
+ };
+ nonvirtual void() death2 = [$death2, death3] { };
+ nonvirtual void() death3 = [$death3, death4] { };
+ nonvirtual void() death4 = [$death4, death5] { };
+ nonvirtual void() death5 = [$death5, death6] { };
+ nonvirtual void() death6 = [$death6, death7] { };
+ nonvirtual void() death7 = [$death7, death8] { };
+ nonvirtual void() death8 = [$death8, death9] { };
+ nonvirtual void() death9 = [$death9, death10]
+ {
+ sound_move (this, CHAN_BODY, "boss1/out1.wav", 1, ATTN_NORM);
+ if !(this.spawnflags & NO_LAVASPLASH)
{
- setmodel (newmis, "progs/lavaball.mdl");
- }
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_LAVASPLASH);
+ WriteCoord (MSG_BROADCAST, this.origin_x);
+ WriteCoord (MSG_BROADCAST, this.origin_y);
+ WriteCoord (MSG_BROADCAST, this.origin_z);
+ }
+ };
+ nonvirtual void() death10 = [$death9, death10]
+ {
+ // unlike the code for the original monster_boss, this
+ // function doesn't need to increment killed_monsters
+ // or call SUB_UseTargets(); this entity gets killed
+ // by regular damage and has FL_MONSTER, so the Killed()
+ // function (in combat.qc) will already have taken care
+ // of those things -- iw
+ remove (this);
+ };
+
+ //==============================================================
+ // Interaction
+ //==============================================================
+
+ //--------------------------------------------------------------
+ // boss2_pain_go
+ //--------------------------------------------------------------
+ virtual void(entity attacker, float damage) do_damage =
+ {
+ if (this.pain_finished > time)
+ return;
+
+ this.pain1 ();
+ this.pain_finished = time + 4;
+ };
- if (!newmis.skin_proj) // dumptruck_ds
+ //--------------------------------------------------------------
+ // boss2_die
+ //--------------------------------------------------------------
+ virtual void() do_destroy =
{
- newmis.skin = self.skin_proj;
+ if (this.health < -50)
+ {
+ // if health under -15
+ this.gib_boss2 ();
+ return;
}
else
{
- newmis.skin = 0;
- }
+ // otherwise normal death
+ this.death1 ();
+ return;
+ }
+ };
- newmis.avelocity = '200 100 300';
- setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
- newmis.touch = T_MissileTouch; // rocket explosion
- sound_attack (self, CHAN_WEAPON, "boss1/throw.wav", 1, ATTN_NORM);
+ //--------------------------------------------------------------
+ // boss2_awake
+ //--------------------------------------------------------------
+ virtual void() use =
+ {
+ this.solid = SOLID_SLIDEBOX;
+ this.movetype = MOVETYPE_STEP;
+ this.takedamage = DAMAGE_AIM;
-// check for dead enemy
- if (self.enemy.health <= 0)
- boss2_idle1 ();
-};
+ body_model ("progs/boss.mdl");
+ // setmodel (this, "progs/boss.mdl");
+ setsize (this, '-128 -128 -24', '128 128 256');
+ if (!this.health)
+ {
+ if (skill == 0)
+ this.health = 1000;
+ else
+ this.health = 3000;
+ }
-void() boss2_awake =
-{
- self.solid = SOLID_SLIDEBOX;
- self.movetype = MOVETYPE_STEP;
- self.takedamage = DAMAGE_AIM;
+ // note that this.th_run has to be set in order to avoid a
+ // "NULL function" Host_Error in the case where T_Damage()
+ // calls FoundTarget(), which calls HuntTarget(), which
+ // uses this.th_run as the next this.think -- iw
+ this.think_run = this.missile1;
- body_model ("progs/boss.mdl");
- // setmodel (self, "progs/boss.mdl");
- setsize (self, '-128 -128 -24', '128 128 256');
+ this.th_pain = this.do_damage;
+ this.th_die = this.do_destroy;
- if (!self.health)
- {
- if (skill == 0)
- self.health = 1000;
- else
- self.health = 3000;
- }
+ // give the boss a couple of seconds to finish rising
+ // before allowing it to go into its pain animation -- iw
+ this.pain_finished = time + 2;
-// note that self.th_run has to be set in order to avoid a "NULL
-// function" Host_Error in the case where T_Damage() calls
-// FoundTarget(), which calls HuntTarget(), which uses self.th_run as
-// the next self.think -- iw
- self.th_run = boss2_missile1;
+ this.enemy = activator;
- self.th_pain = boss2_pain_go;
- self.th_die = boss2_die;
+ if !(this.spawnflags & NO_LAVASPLASH)
+ {
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_LAVASPLASH);
+ WriteCoord (MSG_BROADCAST, this.origin_x);
+ WriteCoord (MSG_BROADCAST, this.origin_y);
+ WriteCoord (MSG_BROADCAST, this.origin_z);
+ }
-// give the boss a couple of seconds to finish rising before allowing it
-// to go into its pain animation -- iw
- self.pain_finished = time + 2;
+ this.yaw_speed = 20;
+ this.rise1 ();
+ };
- self.enemy = activator;
+ //==============================================================
+ // Initialization
+ //==============================================================
- if !(self.spawnflags & NO_LAVASPLASH)
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
{
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_LAVASPLASH);
- WriteCoord (MSG_BROADCAST, self.origin_x);
- WriteCoord (MSG_BROADCAST, self.origin_y);
- WriteCoord (MSG_BROADCAST, self.origin_z);
- }
-
- self.yaw_speed = 20;
- boss2_rise1 ();
-};
-
+ if (this.spawnflags & I_AM_TURRET)
+ objerror ("Incompatible spawnflag: TURRET_MODE\n");
-/*QUAKED monster_boss2 (1 0 0) (-128 -128 -24) (128 128 256)
-*/
-void() monster_boss2 =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (self.spawnflags & I_AM_TURRET)
- objerror("Incompatible spawnflag: TURRET_MODE\n");
+ if (deathmatch)
+ {
+ remove (this);
+ return;
+ }
- if (deathmatch)
+ // custom sounds and models -- dumptruck_ds
+ precache_body_model ("progs/boss.mdl");
+ precache_head_model ("progs/h_boss.mdl");
+ precache_model ("progs/lavaball.mdl");
+ // precache_model ("progs/boss.mdl");
+ precache_model ("progs/h_boss.mdl");
+
+ precache_sound ("weapons/rocket1i.wav");
+ precache_sound_move ("boss1/out1.wav");
+ precache_sound_sight ("boss1/sight1.wav");
+ precache_sound ("misc/power.wav");
+ precache_sound_attack ("boss1/throw.wav");
+ precache_sound_pain ("boss1/pain.wav");
+ precache_sound_death ("boss1/death.wav");
+
+ precache_gib1 ("progs/gib1.mdl");
+ precache_gib2 ("progs/gib2.mdl");
+ precache_gib3 ("progs/gib3.mdl");
+
+ total_monsters = total_monsters + 1;
+ this.flags = FL_MONSTER;
+ };
+
+ //--------------------------------------------------------------
+ void() monster_boss2 =
{
- remove(self);
- return;
- } //custom sounds and models -- dumptruck_ds
- precache_body_model ("progs/boss.mdl");
- precache_head_model ("progs/h_boss.mdl");
- precache_model ("progs/lavaball.mdl");
- // precache_model ("progs/boss.mdl");
- precache_model ("progs/h_boss.mdl");
-
- precache_sound ("weapons/rocket1i.wav");
- precache_sound_move ("boss1/out1.wav");
- precache_sound_sight ("boss1/sight1.wav");
- precache_sound ("misc/power.wav");
- precache_sound_attack ("boss1/throw.wav");
- precache_sound_pain ("boss1/pain.wav");
- precache_sound_death ("boss1/death.wav");
-
- precache_gib1 ("progs/gib1.mdl");
- precache_gib2 ("progs/gib2.mdl");
- precache_gib3 ("progs/gib3.mdl");
-
- total_monsters = total_monsters + 1;
- self.flags = FL_MONSTER;
- self.touch = monster_touch; // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten
- self.use = boss2_awake;
+ this.classtype = CT_MONSTER_BOSS_CHTHON2;
+ };
};
Return to the top of this page or return to the overview of this repo.
Diff qc/monsters/demon.qc
diff --git a/qc/monsters/demon.qc b/qc/monsters/demon.qc
index 3b62ff5..c468300 100644
--- a/qc/monsters/demon.qc
+++ b/qc/monsters/demon.qc
@@ -1,11 +1,19 @@
-/*
-==============================================================================
-
-DEMON
-
-==============================================================================
-*/
+//==============================================================================
+// DEMON
+//==============================================================================
+
+//======================================================================
+// constants -- demon touch states
+//======================================================================
+enum
+{
+ DEMON_TOUCH_DEFAULT,
+ DEMON_TOUCH_JUMP
+};
+//======================================================================
+// frame macros
+//======================================================================
$cd id1/models/demon3
$scale 0.8
$origin 0 0 24
@@ -29,186 +37,6 @@ $frame death1 death2 death3 death4 death5 death6 death7 death8 death9
$frame attacka1 attacka2 attacka3 attacka4 attacka5 attacka6 attacka7 attacka8
$frame attacka9 attacka10 attacka11 attacka12 attacka13 attacka14 attacka15
-//============================================================================
-
-void() Demon_JumpTouch;
-
-void() demon1_stand1 =[ $stand1, demon1_stand2 ] {ai_stand();};
-void() demon1_stand2 =[ $stand2, demon1_stand3 ] {ai_stand();};
-void() demon1_stand3 =[ $stand3, demon1_stand4 ] {ai_stand();};
-void() demon1_stand4 =[ $stand4, demon1_stand5 ] {ai_stand();};
-void() demon1_stand5 =[ $stand5, demon1_stand6 ] {ai_stand();};
-void() demon1_stand6 =[ $stand6, demon1_stand7 ] {ai_stand();};
-void() demon1_stand7 =[ $stand7, demon1_stand8 ] {ai_stand();};
-void() demon1_stand8 =[ $stand8, demon1_stand9 ] {ai_stand();};
-void() demon1_stand9 =[ $stand9, demon1_stand10 ] {ai_stand();};
-void() demon1_stand10 =[ $stand10, demon1_stand11 ] {ai_stand();};
-void() demon1_stand11 =[ $stand11, demon1_stand12 ] {ai_stand();};
-void() demon1_stand12 =[ $stand12, demon1_stand13 ] {ai_stand();};
-void() demon1_stand13 =[ $stand13, demon1_stand1 ] {ai_stand();};
-
-void() demon1_walk1 =[ $walk1, demon1_walk2 ] {
-if (random() < 0.2)
- sound_idle (self, CHAN_VOICE, "demon/idle1.wav", 1, ATTN_IDLE);
-ai_walk(8);
-};
-void() demon1_walk2 =[ $walk2, demon1_walk3 ] {ai_walk(6);};
-void() demon1_walk3 =[ $walk3, demon1_walk4 ] {ai_walk(6);};
-void() demon1_walk4 =[ $walk4, demon1_walk5 ] {ai_walk(7);};
-void() demon1_walk5 =[ $walk5, demon1_walk6 ] {ai_walk(4);};
-void() demon1_walk6 =[ $walk6, demon1_walk7 ] {ai_walk(6);};
-void() demon1_walk7 =[ $walk7, demon1_walk8 ] {ai_walk(10);};
-void() demon1_walk8 =[ $walk8, demon1_walk1 ] {ai_walk(10);};
-
-void() demon1_run1 =[ $run1, demon1_run2 ] {
-if (random() < 0.2)
- sound_idle (self, CHAN_VOICE, "demon/idle1.wav", 1, ATTN_IDLE);
-ai_run(20);};
-void() demon1_run2 =[ $run2, demon1_run3 ] {ai_run(15);};
-void() demon1_run3 =[ $run3, demon1_run4 ] {ai_run(36);};
-void() demon1_run4 =[ $run4, demon1_run5 ] {ai_run(20);};
-void() demon1_run5 =[ $run5, demon1_run6 ] {ai_run(15);};
-void() demon1_run6 =[ $run6, demon1_run1 ] {ai_run(36);};
-
-void() demon1_jump1 =[ $leap1, demon1_jump2 ] {ai_face();};
-void() demon1_jump2 =[ $leap2, demon1_jump3 ] {ai_face();};
-void() demon1_jump3 =[ $leap3, demon1_jump4 ] {ai_face();};
-void() demon1_jump4 =[ $leap4, demon1_jump5 ]
-{
- ai_face();
- self.worldtype = 0; //fix for instakill bug -- dumptruck_ds
- self.touch = Demon_JumpTouch;
- makevectors (self.angles);
- self.origin_z = self.origin_z + 1;
- self.velocity = v_forward * 600 + '0 0 250';
- if (self.flags & FL_ONGROUND)
- self.flags = self.flags - FL_ONGROUND;
-};
-void() demon1_jump5 =[ $leap5, demon1_jump6 ] {};
-void() demon1_jump6 =[ $leap6, demon1_jump7 ] {};
-void() demon1_jump7 =[ $leap7, demon1_jump8 ] {};
-void() demon1_jump8 =[ $leap8, demon1_jump9 ] {};
-void() demon1_jump9 =[ $leap9, demon1_jump10 ] {};
-void() demon1_jump10 =[ $leap10, demon1_jump1 ] {
-self.nextthink = time + 3;
-// if three seconds pass, assume demon is stuck and jump again
-};
-
-void() demon1_jump11 =[ $leap11, demon1_jump12 ] {};
-void() demon1_jump12 =[ $leap12, demon1_run1 ] {};
-
-
-void() demon1_atta1 =[ $attacka1, demon1_atta2 ] {ai_charge(4);};
-void() demon1_atta2 =[ $attacka2, demon1_atta3 ] {ai_charge(0);};
-void() demon1_atta3 =[ $attacka3, demon1_atta4 ] {ai_charge(0);};
-void() demon1_atta4 =[ $attacka4, demon1_atta5 ] {ai_charge(1);};
-void() demon1_atta5 =[ $attacka5, demon1_atta6 ] {ai_charge(2); Demon_Melee(200);};
-void() demon1_atta6 =[ $attacka6, demon1_atta7 ] {ai_charge(1);};
-void() demon1_atta7 =[ $attacka7, demon1_atta8 ] {ai_charge(6);};
-void() demon1_atta8 =[ $attacka8, demon1_atta9 ] {ai_charge(8);};
-void() demon1_atta9 =[ $attacka9, demon1_atta10] {ai_charge(4);};
-void() demon1_atta10 =[ $attacka10, demon1_atta11] {ai_charge(2);};
-void() demon1_atta11 =[ $attacka11, demon1_atta12] {Demon_Melee(-200);};
-void() demon1_atta12 =[ $attacka12, demon1_atta13] {ai_charge(5);};
-void() demon1_atta13 =[ $attacka13, demon1_atta14] {ai_charge(8);};
-void() demon1_atta14 =[ $attacka14, demon1_atta15] {ai_charge(4);};
-void() demon1_atta15 =[ $attacka15, demon1_run1] {ai_charge(4);};
-
-void() demon1_pain1 =[ $pain1, demon1_pain2 ] {};
-void() demon1_pain2 =[ $pain2, demon1_pain3 ] {};
-void() demon1_pain3 =[ $pain3, demon1_pain4 ] {};
-void() demon1_pain4 =[ $pain4, demon1_pain5 ] {};
-void() demon1_pain5 =[ $pain5, demon1_pain6 ] {};
-void() demon1_pain6 =[ $pain6, demon1_run1 ] {};
-
-void(entity attacker, float damage) demon1_pain =
-{
- if (self.touch == Demon_JumpTouch)
- return;
-
- if (self.pain_finished > time)
- return;
-
- self.pain_finished = time + 1;
- sound_pain (self, CHAN_VOICE, "demon/dpain1.wav", 1, ATTN_NORM);
-
- if (random()*200 > damage)
- return; // didn't flinch
-
- demon1_pain1 ();
-};
-
-void() demon1_die1 =[ $death1, demon1_die2 ] {
-sound_death (self, CHAN_VOICE, "demon/ddeath.wav", 1, ATTN_NORM);};
-void() demon1_die2 =[ $death2, demon1_die3 ] {};
-void() demon1_die3 =[ $death3, demon1_die4 ] {};
-void() demon1_die4 =[ $death4, demon1_die5 ] {};
-void() demon1_die5 =[ $death5, demon1_die6 ] {};
-void() demon1_die6 =[ $death6, demon1_die7 ]
-{self.solid = SOLID_NOT;};
-void() demon1_die7 =[ $death7, demon1_die8 ] {};
-void() demon1_die8 =[ $death8, demon1_die9 ] {};
-void() demon1_die9 =[ $death9, demon1_die9 ] {};
-
-void() demon_die =
-{
-// check for gib
- if (self.health < -80)
- {
- sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
- if (self.mdl_head != "")
- {
- ThrowHead (self.mdl_head, self.health);
- }
- else
- {
- ThrowHead ("progs/h_demon.mdl", self.health);
- }
- // ThrowHead ("progs/h_demon.mdl", self.health);
- // ThrowGib ("progs/gib1.mdl", self.health);
- // ThrowGib ("progs/gib1.mdl", self.health);
- // ThrowGib ("progs/gib1.mdl", self.health);
- if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
- {
- ThrowGib (self.mdl_gib1, self.health);
- }
- else
- {
- ThrowGib ("progs/gib1.mdl", self.health);
- }
- if (self.mdl_gib2 != "")
- {
- ThrowGib (self.mdl_gib2, self.health);
- }
- else
- {
- ThrowGib ("progs/gib1.mdl", self.health);
- }
- if (self.mdl_gib3 != "")
- {
- ThrowGib (self.mdl_gib3, self.health);
- }
- else
- {
- ThrowGib ("progs/gib1.mdl", self.health);
- }
- base_item::drop_stuff (self);
-
- return;
- }
-
-// regular death
-base_item::drop_stuff (self);
- demon1_die1 ();
-};
-
-
-void() Demon_MeleeAttack =
-{
- demon1_atta1 ();
-};
-
-
/*QUAKED monster_demon1 (1 0 0) (-32 -32 -24) (32 32 64) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
{
model ("progs/demon.mdl");
@@ -265,218 +93,478 @@ obit_method(string) : "When used with obit_name, will set part of the text for a
damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
*/
-void() monster_demon1 =
+class monster_demon1: base_walkmonster
{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (self.spawnflags & I_AM_TURRET)
- objerror("Incompatible spawnflag: TURRET_MODE\n");
+ float touch_state;
+
+ //--------------------------------------------------------------
+ // CheckDemonMelee
+ // Returns TRUE if a melee attack would hit right now
+ //--------------------------------------------------------------
+ /*
+ float() CheckDemonMelee =
+ {
+ if (enemy_range == RANGE_MELEE)
+ {
+ // FIXME: check canreach
+ this.attack_state = AS_MELEE;
+ return TRUE;
+ }
+ return FALSE;
+ };
+ */
- if (deathmatch)
+ //--------------------------------------------------------------
+ // CheckDemonJump
+ //--------------------------------------------------------------
+ nonvirtual float() check_jump =
{
- remove(self);
- return;
- }
- //dumptruck_ds custom_mdls
- precache_body_model ("progs/demon.mdl");
- precache_head_model ("progs/h_demon.mdl");
-
- precache_sound_death ("demon/ddeath.wav");
- precache_sound_hit ("demon/dhit2.wav");
- precache_sound_attack ("demon/djump.wav");
- precache_sound_pain ("demon/dpain1.wav");
- precache_sound_idle ("demon/idle1.wav");
- precache_sound_sight ("demon/sight2.wav");
-
- precache_gib1 ("progs/gib1.mdl");
- // precache_gib2 ("progs/gib2.mdl");
- // precache_gib3 ("progs/gib3.mdl");
-
- self.solid = SOLID_SLIDEBOX;
- self.movetype = MOVETYPE_STEP;
-
- body_model ("progs/demon.mdl");
- // setmodel (self, "progs/demon.mdl");
-
- setsize (self, VEC_HULL2_MIN, VEC_HULL2_MAX);
-
- if (!self.health) //thanks RennyC -- dumptruck_ds
- self.health = 300;
-
- self.th_stand = demon1_stand1;
- self.th_walk = demon1_walk1;
- self.th_run = demon1_run1;
- self.th_die = demon_die;
- self.th_melee = Demon_MeleeAttack; // one of two attacks
- self.th_missile = demon1_jump1; // jump attack
- if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
- self.th_pain = demon1_pain;
- else
- self.th_pain = sub_nullpain;
-
- walkmonster_start();
-};
+ local vector dist;
+ local float d;
+
+ if (this.origin_z + this.mins_z >
+ this.enemy.origin_z + this.enemy.mins_z +
+ 0.75 * this.enemy.size_z)
+ {
+ return FALSE;
+ }
+ if (this.origin_z + this.maxs_z <
+ this.enemy.origin_z + this.enemy.mins_z +
+ 0.25 * this.enemy.size_z)
+ {
+ return FALSE;
+ }
-/*
-==============================================================================
+ dist = this.enemy.origin - this.origin;
+ dist_z = 0;
-DEMON
+ d = vlen (dist);
-==============================================================================
-*/
+ if (d < 100)
+ return FALSE;
-/*
-==============
-CheckDemonMelee
+ if (d > 200)
+ {
+ if (random() < 0.9)
+ return FALSE;
+ }
-Returns TRUE if a melee attack would hit right now
-==============
-*/
-float() CheckDemonMelee =
-{
- if (enemy_range == RANGE_MELEE)
- { // FIXME: check canreach
- self.attack_state = AS_MELEE;
return TRUE;
- }
- return FALSE;
-};
+ };
-/*
-==============
-CheckDemonJump
+ //--------------------------------------------------------------
+ // DemonCheckAttack
+ //--------------------------------------------------------------
+ virtual float() ai_checkattack =
+ {
+ // if close enough for slashing, go for it
+ // if (CheckDemonMelee())
+ if (enemy_range == RANGE_MELEE)
+ {
+ this.attack_state = AS_MELEE;
+ return TRUE;
+ }
-==============
-*/
-float() CheckDemonJump =
-{
- local vector dist;
- local float d;
+ if (this.check_jump())
+ {
+ this.attack_state = AS_MISSILE;
+ sound_attack (this, CHAN_VOICE, "demon/djump.wav",
+ 1, ATTN_NORM);
+ return TRUE;
+ }
- if (self.origin_z + self.mins_z > self.enemy.origin_z + self.enemy.mins_z
- + 0.75 * self.enemy.size_z)
return FALSE;
+ };
- if (self.origin_z + self.maxs_z < self.enemy.origin_z + self.enemy.mins_z
- + 0.25 * self.enemy.size_z)
- return FALSE;
+ //--------------------------------------------------------------
+ virtual void() ai_sightsound =
+ {
+ sound_sight (this, CHAN_VOICE, "demon/sight2.wav",
+ 1, ATTN_NORM);
+ };
- dist = self.enemy.origin - self.origin;
- dist_z = 0;
+ //--------------------------------------------------------------
+ virtual void(entity attacker, float damage) do_damage =
+ {
+ if (this.touch_state == DEMON_TOUCH_JUMP)
+ return;
- d = vlen(dist);
+ if (this.pain_finished > time)
+ return;
- if (d < 100)
- return FALSE;
+ this.pain_finished = time + 1;
+ sound_pain (this, CHAN_VOICE, "demon/dpain1.wav", 1, ATTN_NORM);
- if (d > 200)
- {
- if (random() < 0.9)
- return FALSE;
- }
+ if (random() * 200 > damage)
+ // didn't flinch
+ return;
- return TRUE;
-};
+ this.pain1 ();
+ };
-float() DemonCheckAttack =
-{
+ //--------------------------------------------------------------
+ nonvirtual void() do_destroy =
+ {
+ // check for gib
+ if (this.health < -80)
+ {
+ sound (this, CHAN_VOICE, "player/udeath.wav",
+ 1, ATTN_NORM);
+ if (this.mdl_head != "")
+ {
+ ThrowHead (this.mdl_head, this.health);
+ }
+ else
+ {
+ ThrowHead ("progs/h_demon.mdl", this.health);
+ }
+ // ThrowHead ("progs/h_demon.mdl", this.health);
+ // ThrowGib ("progs/gib1.mdl", this.health);
+ // ThrowGib ("progs/gib1.mdl", this.health);
+ // ThrowGib ("progs/gib1.mdl", this.health);
+ if (this.mdl_gib1 != "")
+ {
+ // custom models -- dumptruck_ds
+ ThrowGib (this.mdl_gib1, this.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib1.mdl", this.health);
+ }
+ if (this.mdl_gib2 != "")
+ {
+ ThrowGib (this.mdl_gib2, this.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib1.mdl", this.health);
+ }
+ if (this.mdl_gib3 != "")
+ {
+ ThrowGib (this.mdl_gib3, this.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib1.mdl", this.health);
+ }
+ base_item::drop_stuff (this);
+ return;
+ }
+
+ // regular death
+ base_item::drop_stuff (this);
+ this.die1 ();
+ };
-// if close enough for slashing, go for it
- if (CheckDemonMelee ())
+ //--------------------------------------------------------------
+ nonvirtual void(float side) melee =
{
- self.attack_state = AS_MELEE;
- return TRUE;
- }
+ local float ldmg;
+ local vector delta;
+
+ ai_face ();
+ // allow a little closing
+ walkmove (this.ideal_yaw, 12);
+
+ delta = this.enemy.origin - this.origin;
+
+ if (vlen(delta) > 100)
+ return;
+ if (!CanDamage (this.enemy, this))
+ return;
+
+ sound_hit (this, CHAN_WEAPON, "demon/dhit2.wav", 1, ATTN_NORM);
+ ldmg = 10 + 5 * random ();
+ T_Damage (this.enemy, this, this, ldmg);
+
+ makevectors (this.angles);
+ SpawnMeatSpray (this.origin + v_forward * 16, side * v_right);
+ };
+
+ //--------------------------------------------------------------
+ // Fiend stand functions
+ //--------------------------------------------------------------
+ nonvirtual void() stand1 = [$stand1, stand2] { ai_stand (); };
+ nonvirtual void() stand2 = [$stand2, stand3] { ai_stand (); };
+ nonvirtual void() stand3 = [$stand3, stand4] { ai_stand (); };
+ nonvirtual void() stand4 = [$stand4, stand5] { ai_stand (); };
+ nonvirtual void() stand5 = [$stand5, stand6] { ai_stand (); };
+ nonvirtual void() stand6 = [$stand6, stand7] { ai_stand (); };
+ nonvirtual void() stand7 = [$stand7, stand8] { ai_stand (); };
+ nonvirtual void() stand8 = [$stand8, stand9] { ai_stand (); };
+ nonvirtual void() stand9 = [$stand9, stand10] { ai_stand (); };
+ nonvirtual void() stand10 = [$stand10, stand11] { ai_stand (); };
+ nonvirtual void() stand11 = [$stand11, stand12] { ai_stand (); };
+ nonvirtual void() stand12 = [$stand12, stand13] { ai_stand (); };
+ nonvirtual void() stand13 = [$stand13, stand1] { ai_stand (); };
+
+ //--------------------------------------------------------------
+ // Fiend walk functions
+ //--------------------------------------------------------------
+ nonvirtual void() walk1 = [$walk1, walk2]
+ {
+ if (random() < 0.2)
+ sound_idle (this, CHAN_VOICE, "demon/idle1.wav",
+ 1, ATTN_IDLE);
+ ai_walk (8);
+ };
+ nonvirtual void() walk2 = [$walk2, walk3] { ai_walk (6); };
+ nonvirtual void() walk3 = [$walk3, walk4] { ai_walk (6); };
+ nonvirtual void() walk4 = [$walk4, walk5] { ai_walk (7); };
+ nonvirtual void() walk5 = [$walk5, walk6] { ai_walk (4); };
+ nonvirtual void() walk6 = [$walk6, walk7] { ai_walk (6); };
+ nonvirtual void() walk7 = [$walk7, walk8] { ai_walk (10); };
+ nonvirtual void() walk8 = [$walk8, walk1] { ai_walk (10); };
+
+ //--------------------------------------------------------------
+ // Fiend run functions
+ //--------------------------------------------------------------
+ nonvirtual void() run1 = [$run1, run2]
+ {
+ if (random() < 0.2)
+ sound_idle (this, CHAN_VOICE, "demon/idle1.wav",
+ 1, ATTN_IDLE);
+ ai_run (20);
+ };
+ nonvirtual void() run2 = [$run2, run3] { ai_run (15); };
+ nonvirtual void() run3 = [$run3, run4] { ai_run (36); };
+ nonvirtual void() run4 = [$run4, run5] { ai_run (20); };
+ nonvirtual void() run5 = [$run5, run6] { ai_run (15); };
+ nonvirtual void() run6 = [$run6, run1] { ai_run (36); };
+
+ //--------------------------------------------------------------
+ // Fiend jump functions
+ //--------------------------------------------------------------
+ nonvirtual void() jump1 = [$leap1, jump2] { ai_face (); };
+ nonvirtual void() jump2 = [$leap2, jump3] { ai_face (); };
+ nonvirtual void() jump3 = [$leap3, jump4] { ai_face (); };
+ nonvirtual void() jump4 = [$leap4, jump5]
+ {
+ ai_face ();
+ // fix for instakill bug -- dumptruck_ds
+ this.worldtype = 0;
+ this.touch_state = DEMON_TOUCH_JUMP;
+ makevectors (this.angles);
+ this.origin_z = this.origin_z + 1;
+ this.velocity = v_forward * 600 + '0 0 250';
+ if (this.flags & FL_ONGROUND)
+ this.flags = this.flags - FL_ONGROUND;
+ };
+ nonvirtual void() jump5 = [$leap5, jump6] {};
+ nonvirtual void() jump6 = [$leap6, jump7] {};
+ nonvirtual void() jump7 = [$leap7, jump8] {};
+ nonvirtual void() jump8 = [$leap8, jump9] {};
+ nonvirtual void() jump9 = [$leap9, jump10] {};
+ nonvirtual void() jump10 = [$leap10, jump1]
+ {
+ // if three seconds pass, assume demon is stuck and jump again
+ this.nextthink = time + 3;
+ };
+ nonvirtual void() jump11 = [$leap11, jump12] {};
+ nonvirtual void() jump12 = [$leap12, run1] {};
+
+ //--------------------------------------------------------------
+ // Fiend attack functions
+ //--------------------------------------------------------------
+ nonvirtual void() atta1 = [$attacka1, atta2] { ai_charge (4); };
+ nonvirtual void() atta2 = [$attacka2, atta3] { ai_charge (0); };
+ nonvirtual void() atta3 = [$attacka3, atta4] { ai_charge (0); };
+ nonvirtual void() atta4 = [$attacka4, atta5] { ai_charge (1); };
+ nonvirtual void() atta5 = [$attacka5, atta6]
+ {
+ ai_charge (2);
+ this.melee (200);
+ };
+ nonvirtual void() atta6 = [$attacka6, atta7] { ai_charge (1); };
+ nonvirtual void() atta7 = [$attacka7, atta8] { ai_charge (6); };
+ nonvirtual void() atta8 = [$attacka8, atta9] { ai_charge (8); };
+ nonvirtual void() atta9 = [$attacka9, atta10] { ai_charge (4); };
+ nonvirtual void() atta10 = [$attacka10, atta11] { ai_charge (2); };
+ nonvirtual void() atta11 = [$attacka11, atta12] { this.melee (-200); };
+ nonvirtual void() atta12 = [$attacka12, atta13] { ai_charge (5); };
+ nonvirtual void() atta13 = [$attacka13, atta14] { ai_charge (8); };
+ nonvirtual void() atta14 = [$attacka14, atta15] { ai_charge (4); };
+ nonvirtual void() atta15 = [$attacka15, run1] { ai_charge (4); };
+
+ //--------------------------------------------------------------
+ // Fiend pain states
+ //--------------------------------------------------------------
+ nonvirtual void() pain1 = [$pain1, pain2] { };
+ nonvirtual void() pain2 = [$pain2, pain3] { };
+ nonvirtual void() pain3 = [$pain3, pain4] { };
+ nonvirtual void() pain4 = [$pain4, pain5] { };
+ nonvirtual void() pain5 = [$pain5, pain6] { };
+ nonvirtual void() pain6 = [$pain6, run1] { };
+
+ //--------------------------------------------------------------
+ // Fiend death states
+ //--------------------------------------------------------------
+ nonvirtual void() die1 = [$death1, die2]
+ {
+ sound_death (this, CHAN_VOICE, "demon/ddeath.wav",
+ 1, ATTN_NORM);
+ };
+ nonvirtual void() die2 = [$death2, die3] { };
+ nonvirtual void() die3 = [$death3, die4] { };
+ nonvirtual void() die4 = [$death4, die5] { };
+ nonvirtual void() die5 = [$death5, die6] { };
+ nonvirtual void() die6 = [$death6, die7]
+ {
+ this.solid = SOLID_NOT;
+ };
+ nonvirtual void() die7 = [$death7, die8] { };
+ nonvirtual void() die8 = [$death8, die9] { };
+ nonvirtual void() die9 = [$death9, die9] { };
+
+ //==============================================================
+ // Interaction
+ //==============================================================
+
+ //--------------------------------------------------------------
+ // Demon_JumpTouch
+ //--------------------------------------------------------------
+ virtual void() touch =
+ {
+ if (this.touch_state == DEMON_TOUCH_DEFAULT)
+ {
+ super::touch ();
+ return;
+ }
+
+ // there's only two states (right now) so we're clear to
+ // do Demon_JumpTouch now -- CEV
+ local float ldmg;
+
+ if (this.health <= 0)
+ return;
+
+ if (other.takedamage)
+ {
+ if (vlen(this.velocity) > 400)
+ {
+ if !(this.worldtype)
+ {
+ ldmg = 40 + 10 * random();
+ T_Damage (other, this, this, ldmg);
+ // is the player still alive?
+ // Preach's instakill bug check
+ // - dumptruck_ds
+ if (other.health > 0)
+ this.worldtype = 1;
+ }
+ }
+ }
- if (CheckDemonJump ())
+ if (!checkbottom(this))
+ {
+ if (this.flags & FL_ONGROUND)
+ {
+ // jump randomly to not get hung up
+ // dprint ("popjump\n");
+ // 1998-09-16 Sliding/not-jumping on monsters/
+ // boxes/players fix by Maddes/Kryten start
+ this.touch_state = DEMON_TOUCH_DEFAULT;
+ // 1998-09-16 Sliding/not-jumping on monsters/
+ // boxes/players fix by Maddes/Kryten end
+ this.think = this.jump1;
+ this.nextthink = time + 0.1;
+
+ // this.velocity_x = (random() - 0.5) * 600;
+ // this.velocity_y = (random() - 0.5) * 600;
+ // this.velocity_z = 200;
+ // this.flags = this.flags - FL_ONGROUND;
+ }
+ // not on ground yet
+ return;
+ }
+
+ // 1998-09-16 Sliding/not-jumping on monsters/boxes/players
+ // fix by Maddes/Kryten start
+ this.touch_state = DEMON_TOUCH_DEFAULT;
+ // 1998-09-16 Sliding/not-jumping on monsters/boxes/players
+ // fix by Maddes/Kryten end
+ this.think = jump11;
+ this.nextthink = time + 0.1;
+ };
+
+ //==============================================================
+ // Initialization
+ //==============================================================
+
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
{
- self.attack_state = AS_MISSILE;
- sound_attack (self, CHAN_VOICE, "demon/djump.wav", 1, ATTN_NORM);
- return TRUE;
- }
+ if (this.spawnflags & I_AM_TURRET)
+ objerror ("Incompatible spawnflag: TURRET_MODE\n");
- return FALSE;
-};
+ if (deathmatch)
+ {
+ remove (this);
+ return;
+ }
+ // dumptruck_ds custom_mdls
+ precache_body_model ("progs/demon.mdl");
+ precache_head_model ("progs/h_demon.mdl");
-//===========================================================================
+ precache_sound_death ("demon/ddeath.wav");
+ precache_sound_hit ("demon/dhit2.wav");
+ precache_sound_attack ("demon/djump.wav");
+ precache_sound_pain ("demon/dpain1.wav");
+ precache_sound_idle ("demon/idle1.wav");
+ precache_sound_sight ("demon/sight2.wav");
-void(float side) Demon_Melee =
-{
- local float ldmg;
- local vector delta;
+ precache_gib1 ("progs/gib1.mdl");
+ // precache_gib2 ("progs/gib2.mdl");
+ // precache_gib3 ("progs/gib3.mdl");
- ai_face ();
- walkmove (self.ideal_yaw, 12); // allow a little closing
+ this.solid = SOLID_SLIDEBOX;
+ this.movetype = MOVETYPE_STEP;
- delta = self.enemy.origin - self.origin;
+ body_model ("progs/demon.mdl");
+ // setmodel (this, "progs/demon.mdl");
- if (vlen(delta) > 100)
- return;
- if (!CanDamage (self.enemy, self))
- return;
+ setsize (this, VEC_HULL2_MIN, VEC_HULL2_MAX);
- sound_hit (self, CHAN_WEAPON, "demon/dhit2.wav", 1, ATTN_NORM);
- ldmg = 10 + 5*random();
- T_Damage (self.enemy, self, self, ldmg);
+ if (!this.health)
+ // thanks RennyC -- dumptruck_ds
+ this.health = 300;
- makevectors (self.angles);
- SpawnMeatSpray (self.origin + v_forward*16, side * v_right);
-};
+ this.touch_state = DEMON_TOUCH_DEFAULT;
+ this.think_stand = this.stand1;
+ this.think_walk = this.walk1;
+ this.think_run = this.run1;
+ // two attacks: melee, jump
+ // this.think_melee = Demon_MeleeAttack;
+ this.think_melee = this.atta1;
+ this.think_missile = this.jump1;
-void() Demon_JumpTouch =
-{
- local float ldmg;
+ // Berserk test from
+ // http://celephais.net/board/view_thread.php?id=4&start=3465
+ // -- dumptruck_ds
+ if !(this.berserk)
+ this.th_pain = this.do_damage;
+ else
+ this.th_pain = sub_nullpain;
- if (self.health <= 0)
- return;
+ this.th_die = do_destroy;
- if (other.takedamage)
- {
- if ( vlen(self.velocity) > 400 )
- {
- if !(self.worldtype)
- {
- ldmg = 40 + 10*random();
- T_Damage (other, self, self, ldmg);
- if (other.health > 0) // is the player still alive? Preach's instakill bug check - dumptruck_ds
- self.worldtype = 1;
- }
- }
- }
+ // walkmonster_start
+ super::init_spawned ();
+ };
- if (!checkbottom(self))
+ //--------------------------------------------------------------
+ void() monster_demon1 =
{
- if (self.flags & FL_ONGROUND)
- { // jump randomly to not get hung up
-//dprint ("popjump\n");
-// 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten start
-// self.touch = sub_null;
- self.touch = monster_touch;
-// 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten end
- self.think = demon1_jump1;
- self.nextthink = time + 0.1;
-
-// self.velocity_x = (random() - 0.5) * 600;
-// self.velocity_y = (random() - 0.5) * 600;
-// self.velocity_z = 200;
-// self.flags = self.flags - FL_ONGROUND;
- }
- return; // not on ground yet
- }
-
- // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten start
- // self.touch = sub_null;
- self.touch = monster_touch;
- // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten end
- self.think = demon1_jump11;
- self.nextthink = time + 0.1;
+ this.classtype = CT_MONSTER_FIEND;
+ };
};
-/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
+//==============================================================================
+// Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds
+//==============================================================================
/*QUAKED monster_dead_demon (0 0.5 0.8) (-32 -32 -24) (32 32 64) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
{
@@ -485,16 +573,17 @@ void() Demon_JumpTouch =
*/
void() monster_dead_demon =
{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ // new spawnflags for all entities -- iw
return;
- precache_model("progs/demon.mdl");
- setmodel(self, "progs/demon.mdl");
+ precache_model ("progs/demon.mdl");
+ setmodel (self, "progs/demon.mdl");
self.frame = $death9;
- if (self.spawnflags & 1)
+ if (self.spawnflags & 1)
{
self.solid = SOLID_BBOX;
- setsize(self,'-43.63 -47.26 -50.53','32.48 24.65 30');
+ setsize (self,'-43.63 -47.26 -50.53','32.48 24.65 30');
}
else
{
Return to the top of this page or return to the overview of this repo.
Diff qc/monsters/dog.qc
diff --git a/qc/monsters/dog.qc b/qc/monsters/dog.qc
index 4f6a71a..ce061e5 100644
--- a/qc/monsters/dog.qc
+++ b/qc/monsters/dog.qc
@@ -1,10 +1,19 @@
-/*
-==============================================================================
-
-DOG
+//==============================================================================
+// DOG
+//==============================================================================
+
+//======================================================================
+// constants -- dog touch states
+//======================================================================
+enum
+{
+ DOG_TOUCH_DEFAULT,
+ DOG_TOUCH_JUMP
+};
-==============================================================================
-*/
+//======================================================================
+// frame macros
+//======================================================================
$cd id1/models/dog
$origin 0 0 24
$base base
@@ -30,342 +39,6 @@ $frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9
$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8
-
-void() dog_leap1;
-void() dog_run1;
-
-/*
-================
-dog_bite
-
-================
-*/
-void() dog_bite =
-{
-local vector delta;
-local float ldmg;
-
- if (!self.enemy)
- return;
-
- ai_charge(10);
-
- if (!CanDamage (self.enemy, self))
- return;
-
- delta = self.enemy.origin - self.origin;
-
- if (vlen(delta) > 100)
- return;
-
- ldmg = (random() + random() + random()) * 8;
- T_Damage (self.enemy, self, self, ldmg);
-};
-
-void() Dog_JumpTouch =
-{
- local float ldmg;
-
- if (self.health <= 0)
- return;
-
- if (other.takedamage)
- {
- if ( vlen(self.velocity) > 300 )
- {
- if !(self.worldtype)
- {
- ldmg = 10 + 10*random();
- T_Damage (other, self, self, ldmg);
- if (other.health > 0) // is the player still alive? Preach's instakill bug check - dumptruck_ds
- self.worldtype = 1;
- }
- }
- }
-
- if (!checkbottom(self))
- {
- if (self.flags & FL_ONGROUND)
- { // jump randomly to not get hung up
-//dprint ("popjump\n");
-// 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten start
-// self.touch = sub_null;
- self.touch = monster_touch;
-// 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten end
- self.think = dog_leap1;
- self.nextthink = time + 0.1;
-
-// self.velocity_x = (random() - 0.5) * 600;
-// self.velocity_y = (random() - 0.5) * 600;
-// self.velocity_z = 200;
-// self.flags = self.flags - FL_ONGROUND;
- }
- return; // not on ground yet
- }
-
- // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten start
- // self.touch = sub_null;
- self.touch = monster_touch;
- // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten end
- self.think = dog_run1;
- self.nextthink = time + 0.1;
-};
-
-
-void() dog_stand1 =[ $stand1, dog_stand2 ] {ai_stand();};
-void() dog_stand2 =[ $stand2, dog_stand3 ] {ai_stand();};
-void() dog_stand3 =[ $stand3, dog_stand4 ] {ai_stand();};
-void() dog_stand4 =[ $stand4, dog_stand5 ] {ai_stand();};
-void() dog_stand5 =[ $stand5, dog_stand6 ] {ai_stand();};
-void() dog_stand6 =[ $stand6, dog_stand7 ] {ai_stand();};
-void() dog_stand7 =[ $stand7, dog_stand8 ] {ai_stand();};
-void() dog_stand8 =[ $stand8, dog_stand9 ] {ai_stand();};
-void() dog_stand9 =[ $stand9, dog_stand1 ] {ai_stand();};
-
-void() dog_walk1 =[ $walk1 , dog_walk2 ] {
-if (random() < 0.2)
- sound_idle (self, CHAN_VOICE, "dog/idle.wav", 1, ATTN_IDLE); //dumptruck_ds
-ai_walk(8);};
-void() dog_walk2 =[ $walk2 , dog_walk3 ] {ai_walk(8);};
-void() dog_walk3 =[ $walk3 , dog_walk4 ] {ai_walk(8);};
-void() dog_walk4 =[ $walk4 , dog_walk5 ] {ai_walk(8);};
-void() dog_walk5 =[ $walk5 , dog_walk6 ] {ai_walk(8);};
-void() dog_walk6 =[ $walk6 , dog_walk7 ] {ai_walk(8);};
-void() dog_walk7 =[ $walk7 , dog_walk8 ] {ai_walk(8);};
-void() dog_walk8 =[ $walk8 , dog_walk1 ] {ai_walk(8);};
-
-void() dog_run1 =[ $run1 , dog_run2 ] {
-if (random() < 0.2)
- sound_idle (self, CHAN_VOICE, "dog/idle.wav", 1, ATTN_IDLE); //dumptruck_ds
-ai_run(16);};
-void() dog_run2 =[ $run2 , dog_run3 ] {ai_run(32);};
-void() dog_run3 =[ $run3 , dog_run4 ] {ai_run(32);};
-void() dog_run4 =[ $run4 , dog_run5 ] {ai_run(20);};
-void() dog_run5 =[ $run5 , dog_run6 ] {ai_run(64);};
-void() dog_run6 =[ $run6 , dog_run7 ] {ai_run(32);};
-void() dog_run7 =[ $run7 , dog_run8 ] {ai_run(16);};
-void() dog_run8 =[ $run8 , dog_run9 ] {ai_run(32);};
-void() dog_run9 =[ $run9 , dog_run10 ] {ai_run(32);};
-void() dog_run10 =[ $run10 , dog_run11 ] {ai_run(20);};
-void() dog_run11 =[ $run11 , dog_run12 ] {ai_run(64);};
-void() dog_run12 =[ $run12 , dog_run1 ] {ai_run(32);};
-
-void() dog_atta1 =[ $attack1, dog_atta2 ] {ai_charge(10);};
-void() dog_atta2 =[ $attack2, dog_atta3 ] {ai_charge(10);};
-void() dog_atta3 =[ $attack3, dog_atta4 ] {ai_charge(10);};
-void() dog_atta4 =[ $attack4, dog_atta5 ] {
-sound_attack (self, CHAN_VOICE, "dog/dattack1.wav", 1, ATTN_NORM); //dumptruck_ds
-dog_bite();};
-void() dog_atta5 =[ $attack5, dog_atta6 ] {ai_charge(10);};
-void() dog_atta6 =[ $attack6, dog_atta7 ] {ai_charge(10);};
-void() dog_atta7 =[ $attack7, dog_atta8 ] {ai_charge(10);};
-void() dog_atta8 =[ $attack8, dog_run1 ] {ai_charge(10);};
-
-void() dog_leap1 =[ $leap1, dog_leap2 ] {ai_face();};
-void() dog_leap2 =[ $leap2, dog_leap3 ]
-{
- ai_face();
- self.worldtype = 0; //fix for instakill bug -- dumptruck_ds
- self.touch = Dog_JumpTouch;
- makevectors (self.angles);
- self.origin_z = self.origin_z + 1;
- self.velocity = v_forward * 300 + '0 0 200';
- if (self.flags & FL_ONGROUND)
- self.flags = self.flags - FL_ONGROUND;
-};
-
-void() dog_leap3 =[ $leap3, dog_leap4 ] {};
-void() dog_leap4 =[ $leap4, dog_leap5 ] {};
-void() dog_leap5 =[ $leap5, dog_leap6 ] {};
-void() dog_leap6 =[ $leap6, dog_leap7 ] {};
-void() dog_leap7 =[ $leap7, dog_leap8 ] {};
-void() dog_leap8 =[ $leap8, dog_leap9 ] {};
-void() dog_leap9 =[ $leap9, dog_leap9 ] {};
-
-void() dog_pain1 =[ $pain1 , dog_pain2 ] {};
-void() dog_pain2 =[ $pain2 , dog_pain3 ] {};
-void() dog_pain3 =[ $pain3 , dog_pain4 ] {};
-void() dog_pain4 =[ $pain4 , dog_pain5 ] {};
-void() dog_pain5 =[ $pain5 , dog_pain6 ] {};
-void() dog_pain6 =[ $pain6 , dog_run1 ] {};
-
-void() dog_painb1 =[ $painb1 , dog_painb2 ] {};
-void() dog_painb2 =[ $painb2 , dog_painb3 ] {};
-void() dog_painb3 =[ $painb3 , dog_painb4 ] {ai_pain(4);};
-void() dog_painb4 =[ $painb4 , dog_painb5 ] {ai_pain(12);};
-void() dog_painb5 =[ $painb5 , dog_painb6 ] {ai_pain(12);};
-void() dog_painb6 =[ $painb6 , dog_painb7 ] {ai_pain(2);};
-void() dog_painb7 =[ $painb7 , dog_painb8 ] {};
-void() dog_painb8 =[ $painb8 , dog_painb9 ] {ai_pain(4);};
-void() dog_painb9 =[ $painb9 , dog_painb10 ] {};
-void() dog_painb10 =[ $painb10 , dog_painb11 ] {ai_pain(10);};
-void() dog_painb11 =[ $painb11 , dog_painb12 ] {};
-void() dog_painb12 =[ $painb12 , dog_painb13 ] {};
-void() dog_painb13 =[ $painb13 , dog_painb14 ] {};
-void() dog_painb14 =[ $painb14 , dog_painb15 ] {};
-void() dog_painb15 =[ $painb15 , dog_painb16 ] {};
-void() dog_painb16 =[ $painb16 , dog_run1 ] {};
-
-void(entity attacker, float damage) dog_pain =
-{
- sound_pain (self, CHAN_VOICE, "dog/dpain1.wav", 1, ATTN_NORM); //dumptruck_ds
-
- if (random() > 0.5)
- dog_pain1 ();
- else
- dog_painb1 ();
-};
-
-void() dog_die1 =[ $death1, dog_die2 ] {};
-void() dog_die2 =[ $death2, dog_die3 ] {};
-void() dog_die3 =[ $death3, dog_die4 ] {};
-void() dog_die4 =[ $death4, dog_die5 ] {};
-void() dog_die5 =[ $death5, dog_die6 ] {};
-void() dog_die6 =[ $death6, dog_die7 ] {};
-void() dog_die7 =[ $death7, dog_die8 ] {};
-void() dog_die8 =[ $death8, dog_die9 ] {};
-void() dog_die9 =[ $death9, dog_die9 ] {};
-
-void() dog_dieb1 =[ $deathb1, dog_dieb2 ] {};
-void() dog_dieb2 =[ $deathb2, dog_dieb3 ] {};
-void() dog_dieb3 =[ $deathb3, dog_dieb4 ] {};
-void() dog_dieb4 =[ $deathb4, dog_dieb5 ] {};
-void() dog_dieb5 =[ $deathb5, dog_dieb6 ] {};
-void() dog_dieb6 =[ $deathb6, dog_dieb7 ] {};
-void() dog_dieb7 =[ $deathb7, dog_dieb8 ] {};
-void() dog_dieb8 =[ $deathb8, dog_dieb9 ] {};
-void() dog_dieb9 =[ $deathb9, dog_dieb9 ] {};
-
-
-void() dog_die =
-{
-// check for gib
- if (self.health < -35)
- {
- sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
-
- if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
- {
- ThrowGib (self.mdl_gib1, self.health);
- }
- else
- {
- ThrowGib ("progs/gib3.mdl", self.health);
- }
- if (self.mdl_gib2 != "")
- {
- ThrowGib (self.mdl_gib2, self.health);
- }
- else
- {
- ThrowGib ("progs/gib3.mdl", self.health);
- }
- if (self.mdl_gib3 != "")
- {
- ThrowGib (self.mdl_gib3, self.health);
- }
- else
- {
- ThrowGib ("progs/gib3.mdl", self.health);
- }
- if (self.mdl_head != "")
- {
- ThrowHead (self.mdl_head, self.health);
- }
- else
- {
- ThrowHead ("progs/h_dog.mdl", self.health);
- }
- base_item::drop_stuff (self);
- return;
- }
-
-// regular death
- sound_death (self, CHAN_VOICE, "dog/ddeath.wav", 1, ATTN_NORM); //dumptruck_ds
- self.solid = SOLID_NOT;
-
- base_item::drop_stuff (self);
-
- if (random() > 0.5)
- dog_die1 ();
- else
- dog_dieb1 ();
-};
-
-//============================================================================
-
-/*
-==============
-CheckDogMelee
-
-Returns TRUE if a melee attack would hit right now
-==============
-*/
-float() CheckDogMelee =
-{
- if (enemy_range == RANGE_MELEE)
- { // FIXME: check canreach
- self.attack_state = AS_MELEE;
- return TRUE;
- }
- return FALSE;
-};
-
-/*
-==============
-CheckDogJump
-
-==============
-*/
-float() CheckDogJump =
-{
- local vector dist;
- local float d;
-
- if (self.origin_z + self.mins_z > self.enemy.origin_z + self.enemy.mins_z
- + 0.75 * self.enemy.size_z)
- return FALSE;
-
- if (self.origin_z + self.maxs_z < self.enemy.origin_z + self.enemy.mins_z
- + 0.25 * self.enemy.size_z)
- return FALSE;
-
- dist = self.enemy.origin - self.origin;
- dist_z = 0;
-
- d = vlen(dist);
-
- if (d < 80)
- return FALSE;
-
- if (d > 150)
- return FALSE;
-
- return TRUE;
-};
-
-float() DogCheckAttack =
-{
-
-// if close enough for slashing, go for it
- if (CheckDogMelee ())
- {
- self.attack_state = AS_MELEE;
- return TRUE;
- }
-
- if (CheckDogJump ())
- {
- self.attack_state = AS_MISSILE;
- return TRUE;
- }
-
- return FALSE;
-};
-
-
-//===========================================================================
-
/*QUAKED monster_dog (1 0 0) (-32 -32 -24) (32 32 40) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
{
model ("progs/dog.mdl");
@@ -423,59 +96,482 @@ obit_method(string) : "When used with obit_name, will set part of the text for a
damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
*/
-void() monster_dog =
+class monster_dog: base_walkmonster
{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
+ float touch_state;
+
+ //--------------------------------------------------------------
+ // CheckDogMelee
+ // Returns TRUE if a melee attack would hit right now
+ //--------------------------------------------------------------
+ /*
+ nonvirtual float() check_melee =
+ {
+ if (enemy_range == RANGE_MELEE)
+ {
+ // FIXME: check canreach
+ this.attack_state = AS_MELEE;
+ return TRUE;
+ }
+ return FALSE;
+ };
+ */
+
+ //--------------------------------------------------------------
+ // CheckDogJump
+ //--------------------------------------------------------------
+ nonvirtual float() check_jump =
+ {
+ local vector dist;
+ local float d;
+
+ if (this.origin_z + this.mins_z >
+ this.enemy.origin_z + this.enemy.mins_z +
+ 0.75 * this.enemy.size_z)
+ {
+ return FALSE;
+ }
+
+ if (this.origin_z + this.maxs_z <
+ this.enemy.origin_z + this.enemy.mins_z +
+ 0.25 * this.enemy.size_z)
+ {
+ return FALSE;
+ }
+
+ dist = this.enemy.origin - this.origin;
+ dist_z = 0;
+
+ d = vlen (dist);
- if (self.spawnflags & I_AM_TURRET)
- objerror("Incompatible spawnflag: TURRET_MODE\n");
+ if (d < 80)
+ return FALSE;
- if (deathmatch)
+ if (d > 150)
+ return FALSE;
+
+ return TRUE;
+ };
+
+ //--------------------------------------------------------------
+ virtual float() ai_checkattack =
{
- remove(self);
- return;
- }
- //dumptruck_ds -- model_custom and sounds changes
- precache_head_model ("progs/h_dog.mdl");
- precache_body_model ("progs/dog.mdl");
- precache_sound_attack ("dog/dattack1.wav");
- precache_sound_death ("dog/ddeath.wav");
- precache_sound_pain ("dog/dpain1.wav");
- precache_sound_sight ("dog/dsight.wav");
- precache_sound_idle ("dog/idle.wav");
+ // if close enough for slashing, go for it
+ /*
+ if (this.check_melee())
+ */
+ if (enemy_range == RANGE_MELEE)
+ {
+ this.attack_state = AS_MELEE;
+ return TRUE;
+ }
- precache_gib1 ("progs/gib1.mdl");
- precache_gib2 ("progs/gib2.mdl");
- precache_gib3 ("progs/gib3.mdl");
+ if (this.check_jump())
+ {
+ this.attack_state = AS_MISSILE;
+ return TRUE;
+ }
- // dumptruck_ds
+ return FALSE;
+ };
- self.solid = SOLID_SLIDEBOX;
- self.movetype = MOVETYPE_STEP;
+ //--------------------------------------------------------------
+ virtual void() ai_sightsound =
+ {
+ // dumptruck_ds
+ sound_sight (this, CHAN_VOICE, "dog/dsight.wav", 1, ATTN_NORM);
+ };
+
+ //--------------------------------------------------------------
+ // dog_bite
+ //--------------------------------------------------------------
+ nonvirtual void() bite =
+ {
+ local vector delta;
+ local float ldmg;
+
+ if (!this.enemy)
+ return;
+
+ ai_charge (10);
+
+ if (!CanDamage (this.enemy, this))
+ return;
+
+ delta = this.enemy.origin - this.origin;
+
+ if (vlen(delta) > 100)
+ return;
+
+ ldmg = (random() + random() + random()) * 8;
+ T_Damage (this.enemy, this, this, ldmg);
+ };
+
+ //--------------------------------------------------------------
+ // Dog standing state
+ //--------------------------------------------------------------
+ nonvirtual void() stand1 = [$stand1, stand2] { ai_stand (); };
+ nonvirtual void() stand2 = [$stand2, stand3] { ai_stand (); };
+ nonvirtual void() stand3 = [$stand3, stand4] { ai_stand (); };
+ nonvirtual void() stand4 = [$stand4, stand5] { ai_stand (); };
+ nonvirtual void() stand5 = [$stand5, stand6] { ai_stand (); };
+ nonvirtual void() stand6 = [$stand6, stand7] { ai_stand (); };
+ nonvirtual void() stand7 = [$stand7, stand8] { ai_stand (); };
+ nonvirtual void() stand8 = [$stand8, stand9] { ai_stand (); };
+ nonvirtual void() stand9 = [$stand9, stand1] { ai_stand (); };
+
+ //--------------------------------------------------------------
+ // Dog walking state
+ //--------------------------------------------------------------
+ nonvirtual void() walk1 = [$walk1, walk2]
+ {
+ if (random() < 0.2)
+ // dumptruck_ds
+ sound_idle (this, CHAN_VOICE, "dog/idle.wav",
+ 1, ATTN_IDLE);
+ ai_walk (8);
+ };
+ nonvirtual void() walk2 = [$walk2, walk3] { ai_walk (8); };
+ nonvirtual void() walk3 = [$walk3, walk4] { ai_walk (8); };
+ nonvirtual void() walk4 = [$walk4, walk5] { ai_walk (8); };
+ nonvirtual void() walk5 = [$walk5, walk6] { ai_walk (8); };
+ nonvirtual void() walk6 = [$walk6, walk7] { ai_walk (8); };
+ nonvirtual void() walk7 = [$walk7, walk8] { ai_walk (8); };
+ nonvirtual void() walk8 = [$walk8, walk1] { ai_walk (8); };
+
+ //--------------------------------------------------------------
+ // Dog running state
+ //--------------------------------------------------------------
+ nonvirtual void() run1 = [$run1, run2]
+ {
+ if (random() < 0.2)
+ // dumptruck_ds
+ sound_idle (this, CHAN_VOICE, "dog/idle.wav",
+ 1, ATTN_IDLE);
+ ai_run (16);
+ };
+ nonvirtual void() run2 = [$run2, run3] { ai_run (32); };
+ nonvirtual void() run3 = [$run3, run4] { ai_run (32); };
+ nonvirtual void() run4 = [$run4, run5] { ai_run (20); };
+ nonvirtual void() run5 = [$run5, run6] { ai_run (64); };
+ nonvirtual void() run6 = [$run6, run7] { ai_run (32); };
+ nonvirtual void() run7 = [$run7, run8] { ai_run (16); };
+ nonvirtual void() run8 = [$run8, run9] { ai_run (32); };
+ nonvirtual void() run9 = [$run9, run10] { ai_run (32); };
+ nonvirtual void() run10 = [$run10, run11] { ai_run (20); };
+ nonvirtual void() run11 = [$run11, run12] { ai_run (64); };
+ nonvirtual void() run12 = [$run12, run1] { ai_run (32); };
+
+ //--------------------------------------------------------------
+ // Dog attack state
+ //--------------------------------------------------------------
+ nonvirtual void() atta1 = [$attack1, atta2] { ai_charge (10); };
+ nonvirtual void() atta2 = [$attack2, atta3] { ai_charge (10); };
+ nonvirtual void() atta3 = [$attack3, atta4] { ai_charge (10); };
+ nonvirtual void() atta4 = [$attack4, atta5]
+ {
+ // dumptruck_ds
+ sound_attack (this, CHAN_VOICE, "dog/dattack1.wav",
+ 1, ATTN_NORM);
+ this.bite ();
+ };
+ nonvirtual void() atta5 = [$attack5, atta6] { ai_charge (10); };
+ nonvirtual void() atta6 = [$attack6, atta7] { ai_charge (10); };
+ nonvirtual void() atta7 = [$attack7, atta8] { ai_charge (10); };
+ nonvirtual void() atta8 = [$attack8, run1] { ai_charge (10); };
+
+ //--------------------------------------------------------------
+ // Dog jumping (leaping) state
+ //--------------------------------------------------------------
+ nonvirtual void() leap1 = [$leap1, leap2] { ai_face (); };
+ nonvirtual void() leap2 = [$leap2, leap3]
+ {
+ ai_face ();
+ // fix for instakill bug -- dumptruck_ds
+ this.worldtype = 0;
+ this.touch_state = DOG_TOUCH_JUMP;
+ makevectors (this.angles);
+ this.origin_z = this.origin_z + 1;
+ this.velocity = v_forward * 300 + '0 0 200';
+ if (this.flags & FL_ONGROUND)
+ this.flags = this.flags - FL_ONGROUND;
+ };
+ nonvirtual void() leap3 = [$leap3, leap4] { };
+ nonvirtual void() leap4 = [$leap4, leap5] { };
+ nonvirtual void() leap5 = [$leap5, leap6] { };
+ nonvirtual void() leap6 = [$leap6, leap7] { };
+ nonvirtual void() leap7 = [$leap7, leap8] { };
+ nonvirtual void() leap8 = [$leap8, leap9] { };
+ nonvirtual void() leap9 = [$leap9, leap9] { };
+
+ //--------------------------------------------------------------
+ // Dog pain state A
+ //--------------------------------------------------------------
+ nonvirtual void() pain1 = [$pain1, pain2] { };
+ nonvirtual void() pain2 = [$pain2, pain3] { };
+ nonvirtual void() pain3 = [$pain3, pain4] { };
+ nonvirtual void() pain4 = [$pain4, pain5] { };
+ nonvirtual void() pain5 = [$pain5, pain6] { };
+ nonvirtual void() pain6 = [$pain6, run1] { };
+
+ //--------------------------------------------------------------
+ // Dog pain state B
+ //--------------------------------------------------------------
+ nonvirtual void() painb1 = [$painb1, painb2] { };
+ nonvirtual void() painb2 = [$painb2, painb3] { };
+ nonvirtual void() painb3 = [$painb3, painb4] { ai_pain (4); };
+ nonvirtual void() painb4 = [$painb4, painb5] { ai_pain (12); };
+ nonvirtual void() painb5 = [$painb5, painb6] { ai_pain (12); };
+ nonvirtual void() painb6 = [$painb6, painb7] { ai_pain (2); };
+ nonvirtual void() painb7 = [$painb7, painb8] { };
+ nonvirtual void() painb8 = [$painb8, painb9] { ai_pain (4); };
+ nonvirtual void() painb9 = [$painb9, painb10] { };
+ nonvirtual void() painb10 = [$painb10, painb11] { ai_pain (10); };
+ nonvirtual void() painb11 = [$painb11, painb12] { };
+ nonvirtual void() painb12 = [$painb12, painb13] { };
+ nonvirtual void() painb13 = [$painb13, painb14] { };
+ nonvirtual void() painb14 = [$painb14, painb15] { };
+ nonvirtual void() painb15 = [$painb15, painb16] { };
+ nonvirtual void() painb16 = [$painb16, run1] { };
+
+ //--------------------------------------------------------------
+ // Dog death state A
+ //--------------------------------------------------------------
+ nonvirtual void() die1 = [$death1, die2] { };
+ nonvirtual void() die2 = [$death2, die3] { };
+ nonvirtual void() die3 = [$death3, die4] { };
+ nonvirtual void() die4 = [$death4, die5] { };
+ nonvirtual void() die5 = [$death5, die6] { };
+ nonvirtual void() die6 = [$death6, die7] { };
+ nonvirtual void() die7 = [$death7, die8] { };
+ nonvirtual void() die8 = [$death8, die9] { };
+ nonvirtual void() die9 = [$death9, die9] { };
+
+ //--------------------------------------------------------------
+ // Dog death state B
+ //--------------------------------------------------------------
+ nonvirtual void() dieb1 = [$deathb1, dieb2] { };
+ nonvirtual void() dieb2 = [$deathb2, dieb3] { };
+ nonvirtual void() dieb3 = [$deathb3, dieb4] { };
+ nonvirtual void() dieb4 = [$deathb4, dieb5] { };
+ nonvirtual void() dieb5 = [$deathb5, dieb6] { };
+ nonvirtual void() dieb6 = [$deathb6, dieb7] { };
+ nonvirtual void() dieb7 = [$deathb7, dieb8] { };
+ nonvirtual void() dieb8 = [$deathb8, dieb9] { };
+ nonvirtual void() dieb9 = [$deathb9, dieb9] { };
+
+ //==============================================================
+ // Interaction
+ //==============================================================
+
+ //--------------------------------------------------------------
+ virtual void(entity attacker, float damage) do_damage =
+ {
+ // dumptruck_ds
+ sound_pain (this, CHAN_VOICE, "dog/dpain1.wav", 1, ATTN_NORM);
- body_model ("progs/dog.mdl"); //dumptruck_ds
- // setmodel (self, "progs/dog.mdl");
+ if (random() > 0.5)
+ this.pain1 ();
+ else
+ this.painb1 ();
+ };
+
+ //--------------------------------------------------------------
+ virtual void() do_destroy =
+ {
+ // check for gib
+ if (this.health < -35)
+ {
+ sound (this, CHAN_VOICE, "player/udeath.wav",
+ 1, ATTN_NORM);
+
+ // custom models -- dumptruck_ds
+ if (this.mdl_gib1 != "")
+ {
+ ThrowGib (this.mdl_gib1, this.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib3.mdl", this.health);
+ }
+ if (this.mdl_gib2 != "")
+ {
+ ThrowGib (this.mdl_gib2, this.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib3.mdl", this.health);
+ }
+ if (this.mdl_gib3 != "")
+ {
+ ThrowGib (this.mdl_gib3, this.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib3.mdl", this.health);
+ }
+ if (this.mdl_head != "")
+ {
+ ThrowHead (this.mdl_head, this.health);
+ }
+ else
+ {
+ ThrowHead ("progs/h_dog.mdl", this.health);
+ }
+ base_item::drop_stuff (this);
+ return;
+ }
- setsize (self, '-32 -32 -24', '32 32 40');
+ // regular death
+ sound_death (this, CHAN_VOICE, "dog/ddeath.wav",
+ 1, ATTN_NORM); //dumptruck_ds
+ this.solid = SOLID_NOT;
- if (!self.health) //thanks RennyC -- dumptruck_ds
- self.health = 25;
+ base_item::drop_stuff (this);
- self.th_stand = dog_stand1;
- self.th_walk = dog_walk1;
- self.th_run = dog_run1;
- if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
- self.th_pain = dog_pain;
- else
- self.th_pain = sub_nullpain;
- self.th_die = dog_die;
- self.th_melee = dog_atta1;
- self.th_missile = dog_leap1;
+ if (random() > 0.5)
+ this.die1 ();
+ else
+ this.dieb1 ();
+ };
+
+ //--------------------------------------------------------------
+ virtual void() touch =
+ {
+ if (this.touch_state == DOG_TOUCH_DEFAULT)
+ {
+ super::touch ();
+ return;
+ }
+
+ // clear to do Dog_JumpTouch now
+ local float ldmg;
+
+ if (this.health <= 0)
+ return;
+
+ if (other.takedamage)
+ {
+ if (vlen(this.velocity) > 300)
+ {
+ if !(this.worldtype)
+ {
+ ldmg = 10 + 10*random();
+ T_Damage (other, this, this, ldmg);
+ if (other.health > 0)
+ // is the player still alive?
+ // Preach's instakill bug check
+ // - dumptruck_ds
+ this.worldtype = 1;
+ }
+ }
+ }
+
+ if (!checkbottom(this))
+ {
+ if (this.flags & FL_ONGROUND)
+ {
+ // jump randomly to not get hung up
+ // dprint ("popjump\n");
+ // 1998-09-16 Sliding/not-jumping on monsters/
+ // boxes/players fix by Maddes/Kryten start
+ this.touch_state = DOG_TOUCH_DEFAULT;
+ // 1998-09-16 Sliding/not-jumping on monsters/
+ // boxes/players fix by Maddes/Kryten end
+ this.think = leap1;
+ this.nextthink = time + 0.1;
+
+ // this.velocity_x = (random() - 0.5) * 600;
+ // this.velocity_y = (random() - 0.5) * 600;
+ // this.velocity_z = 200;
+ // this.flags = this.flags - FL_ONGROUND;
+ }
+ // not on ground yet
+ return;
+ }
+
+ // 1998-09-16 Sliding/not-jumping on monsters/boxes/players
+ // fix by Maddes/Kryten start
+ this.touch_state = DOG_TOUCH_DEFAULT;
+ // 1998-09-16 Sliding/not-jumping on monsters/boxes/players
+ // fix by Maddes/Kryten end
+ this.think = run1;
+ this.nextthink = time + 0.1;
+ };
+
+ //==============================================================
+ // Initialization
+ //==============================================================
+
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
+ {
+ if (this.spawnflags & I_AM_TURRET)
+ objerror ("Incompatible spawnflag: TURRET_MODE\n");
+
+ if (deathmatch)
+ {
+ remove (this);
+ return;
+ }
+
+ // dumptruck_ds -- model_custom and sounds changes
+ precache_head_model ("progs/h_dog.mdl");
+ precache_body_model ("progs/dog.mdl");
+ precache_sound_attack ("dog/dattack1.wav");
+ precache_sound_death ("dog/ddeath.wav");
+ precache_sound_pain ("dog/dpain1.wav");
+ precache_sound_sight ("dog/dsight.wav");
+ precache_sound_idle ("dog/idle.wav");
+
+ precache_gib1 ("progs/gib1.mdl");
+ precache_gib2 ("progs/gib2.mdl");
+ precache_gib3 ("progs/gib3.mdl");
+
+ // dumptruck_ds
- walkmonster_start();
+ this.solid = SOLID_SLIDEBOX;
+ this.movetype = MOVETYPE_STEP;
+
+ body_model ("progs/dog.mdl"); //dumptruck_ds
+ // setmodel (this, "progs/dog.mdl");
+
+ setsize (this, '-32 -32 -24', '32 32 40');
+
+ if (!this.health)
+ //thanks RennyC -- dumptruck_ds
+ this.health = 25;
+
+ this.touch_state = DOG_TOUCH_DEFAULT;
+
+ this.think_stand = this.stand1;
+ this.think_walk = this.walk1;
+ this.think_run = this.run1;
+ this.think_melee = this.atta1;
+ this.think_missile = this.leap1;
+
+ // Berserk test from
+ // http://celephais.net/board/view_thread.php?id=4&start=3465
+ // -- dumptruck_ds
+ if !(this.berserk)
+ this.th_pain = this.do_damage;
+ else
+ this.th_pain = sub_nullpain;
+ this.th_die = this.do_destroy;
+
+ // walkmonster_start
+ super::init_spawned ();
+ };
+
+ //--------------------------------------------------------------
+ void() monster_dog =
+ {
+ this.classtype = CT_MONSTER_DOG;
+ };
};
+//==============================================================================
+
/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
/*QUAKED monster_dead_dog (0 0.5 0.8) (-32 -32 -24) (32 32 64) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
Return to the top of this page or return to the overview of this repo.
Diff qc/monsters/enforcer.qc
diff --git a/qc/monsters/enforcer.qc b/qc/monsters/enforcer.qc
index e3de581..8b07a07 100644
--- a/qc/monsters/enforcer.qc
+++ b/qc/monsters/enforcer.qc
@@ -1,11 +1,10 @@
-/*
-==============================================================================
-
-SOLDIER / PLAYER
-
-==============================================================================
-*/
+//==============================================================================
+// ENFORCER
+//==============================================================================
+//======================================================================
+// frame macros
+//======================================================================
$cd id1/models/enforcer
$origin 0 -6 24
$base base
@@ -37,94 +36,862 @@ $frame paind1 paind2 paind3 paind4 paind5 paind6 paind7 paind8
$frame paind9 paind10 paind11 paind12 paind13 paind14 paind15 paind16
$frame paind17 paind18 paind19
-
-void() Laser_Touch =
+/*QUAKED monster_enforcer (1 0 0) (-16 -16 -24) (16 16 40) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
{
- local vector org;
+ model ("progs/enforcer.mdl");
+}
+Enforcer.
- if (other == self.owner)
- return; // don't explode on owner
+Default health = 80
- if (pointcontents(self.origin) == CONTENT_SKY)
- {
- remove(self);
- return;
- }
+keep_ammo(integer) : "1 = Don't drop backpack upon death"
- sound_hit (self, CHAN_WEAPON, "enforcer/enfstop.wav", 1, ATTN_STATIC); //dumptruck_ds
- org = self.origin - 8*normalize(self.velocity);
+style(Choices) : "Attack type"
+0 : "Default (lasers)"
+1 : "rockets"
+2 : "grenades"
+3 : "nails"
- if (other.health)
+snd_death(string) : Path to custom death sound"
+snd_pain(string) : "Path to 1st custom pain sound"
+snd_sight(string) : "Path to custom sight sound for STOP!"
+snd_attack(string) : Path to custom attack sound e.g laser firing"
+snd_hit(string) : "Path to custom hit sound e.g. laser hits wall"
+snd_idle(string) : "Path to custom idle sound"
+snd_misc(string) : "Path to custom sight sound for FREEZE!"
+snd_misc1(string) : "Path to custom sight sound for YOU THERE!"
+snd_misc2(string) : "Path to custom sight sound for HALT!"
+snd_misc3(string) : "Path to 2nd custom pain sound"
+
+mdl_head(string) : "Path to custom head model"
+mdl_body(string) : "Path to custom body model"
+mdl_proj(string) : "Path to custom projectile model"
+skin_head(float) : "Skin index of custom head model"
+skin_proj(float) : "Skin index of custom projectile model"
+mdl_gib1(string) : "Path to custom 1st gib model"
+mdl_gib2(string) : "Path to custom 2nd gib model"
+mdl_gib3(string) : "Path to custom 3rd gib model"
+
+effects(choices) : "Add a visual effect to an entity"
+0 : "None (Default)"
+1 : "Brightfield (yellow particles)"
+4 : "Bright light"
+8 : "Dim light"
+
+berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
+0 : "Off (Default)"
+1 : "Berserk (skip pain animations)"
+
+delay(float) : "Delay spawn in for this amount of time"
+
+wait(choices) : "Play an effect when trigger spawned?"
+0 : "Teleport Effects (Default)"
+1 : "Spawn Silently"
+
+spawn_angry(Choices)
+0 : "Only when trigger spawned, default behavior - not angry"
+1 : "Only when trigger spawned, set to 1 to spawn angry at player"
+
+infight_mode(Choices)
+0 : "Default behavior, only with different classnames"
+1 : "Infight with monsters with the same classname but a different mdl_body"
+2 : "Infight with monsters with the same classname and model but a different skin"
+3 : "Infight no matter what"
+
+health(integer) : "Set this to a custom health amount"
+pain_target(string) : "Fire this target when pain_threshold is reached"
+pain_threshold(integer) : "Fire pain_target when health drops below this amount"
+sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
+skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
+obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
+obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
+damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
+
+*/
+class monster_enforcer: base_walkmonster
+{
+ float attack_elevation;
+
+ //--------------------------------------------------------------
+ virtual void() ai_sightsound =
{
- SpawnBlood (org, self.velocity*0.2, 15);
- T_Damage (other, self, self.owner, 15);
- }
- else
+ local float rsnd;
+
+ rsnd = rint (random() * 3);
+ if (rsnd == 1)
+ // dumptruck_ds
+ sound_sight (this, CHAN_VOICE, "enforcer/sight1.wav",
+ 1, ATTN_NORM);
+ else if (rsnd == 2)
+ sound_misc (this, CHAN_VOICE, "enforcer/sight2.wav",
+ 1, ATTN_NORM);
+ else if (rsnd == 0)
+ sound_misc1 (this, CHAN_VOICE, "enforcer/sight3.wav",
+ 1, ATTN_NORM);
+ else
+ sound_misc2 (this, CHAN_VOICE, "enforcer/sight4.wav",
+ 1, ATTN_NORM);
+ };
+
+ //--------------------------------------------------------------
+ // enf_lightning -- TODO CEV
+ //--------------------------------------------------------------
+ nonvirtual void() atk_lightning =
{
+ local vector org, dir;
+
+ this.effects = this.effects | EF_MUZZLEFLASH;
+ sound_attack (this, CHAN_WEAPON, "weapons/lstart.wav",
+ 1, ATTN_NORM);
+ ai_face ();
+ makevectors (this.angles);
+ org = this.origin + v_forward * 30 + v_right * 8.5 + '0 0 16';
+
+ dir = this.enemy.origin - this.enemy.velocity * 0.075;
+ dir = normalize (dir - org + '0 0 16');
+
+ if (this.spawnflags & I_AM_TURRET)
+ {
+ traceline (org, this.origin + dir * 900, TRUE, this);
+ }
+ else
+ {
+ traceline (org, this.origin + dir * 600, TRUE, this);
+ }
+
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_GUNSHOT);
+ WriteByte (MSG_BROADCAST, TE_LIGHTNING2);
+ WriteEntity (MSG_BROADCAST, this);
WriteCoord (MSG_BROADCAST, org_x);
WriteCoord (MSG_BROADCAST, org_y);
WriteCoord (MSG_BROADCAST, org_z);
- }
+ WriteCoord (MSG_BROADCAST, trace_endpos_x);
+ WriteCoord (MSG_BROADCAST, trace_endpos_y);
+ WriteCoord (MSG_BROADCAST, trace_endpos_z);
- remove(self);
-};
+ LightningDamage (org, trace_endpos, this, 4);
+ };
-void(vector org, vector vec) LaunchLaser =
-{
+ //--------------------------------------------------------------
+ nonvirtual void() atk_laser =
+ {
+ // style stuff -- dumptruck_ds
+ if (this.style == 1)
+ {
+ this.effects = this.effects | EF_MUZZLEFLASH;
+ ai_face ();
+ sound_attack (this, CHAN_WEAPON, "enforcer/enfire.wav",
+ 1, ATTN_NORM);
+ EnfRocket ();
+ return;
+ }
+ else if (this.style == 2)
+ {
+ this.effects = this.effects | EF_MUZZLEFLASH;
+ ai_face ();
+ if (this.spawnflags & I_AM_TURRET)
+ // TODO CEV
+ // PreachFireGrenade (this.attack_elevation);
+ dprint ("monster_enforcer::atk_laser: need to "
+ "implement PreachFireGrenade ()\n");
+ else
+ EnfFireGrenade ();
+ return;
+ }
+ else if (this.style == 3 || this.style ==5)
+ {
+ local vector foo;
- local float projspeed = self.proj_speed_mod * 600;
+ this.effects = this.effects | EF_MUZZLEFLASH;
+ makevectors (this.angles);
- if (self.classname == "monster_enforcer" || self.classname == "monster_army")
- sound_attack (self, CHAN_WEAPON, "enforcer/enfire.wav", 1, ATTN_NORM);
+ foo = this.origin + v_forward * 30 +
+ v_right * 8.5 + '0 0 16';
- vec = normalize(vec);
+ EnfLaunchSpike (foo, this.enemy.origin - this.origin);
+ return;
+ }
+ else
+ {
+ local vector org;
- newmis = spawn();
- newmis.snd_hit = self.snd_hit; // dumptruck_ds
- newmis.owner = self;
- newmis.movetype = MOVETYPE_FLY;
- newmis.solid = SOLID_BBOX;
- newmis.effects = EF_DIMLIGHT;
- newmis.skin = self.skin_proj; //dumptruck_ds
+ this.effects = this.effects | EF_MUZZLEFLASH;
+ makevectors (this.angles);
- if (self.mdl_proj != "") // dumptruck_ds
+ org = this.origin + v_forward * 30 +
+ v_right * 8.5 + '0 0 16';
+
+ LaunchLaser (org, this.enemy.origin - this.origin);
+ }
+ };
+
+ //--------------------------------------------------------------
+ // Enforcer stand functions
+ //--------------------------------------------------------------
+ nonvirtual void() stand1 = [$stand1, stand2] { ai_stand (); };
+ nonvirtual void() stand2 = [$stand2, stand3] { ai_stand (); };
+ nonvirtual void() stand3 = [$stand3, stand4] { ai_stand (); };
+ nonvirtual void() stand4 = [$stand4, stand5] { ai_stand (); };
+ nonvirtual void() stand5 = [$stand5, stand6] { ai_stand (); };
+ nonvirtual void() stand6 = [$stand6, stand7] { ai_stand (); };
+ nonvirtual void() stand7 = [$stand7, stand1] { ai_stand (); };
+
+ //--------------------------------------------------------------
+ // Enforcer walk functions
+ //--------------------------------------------------------------
+ nonvirtual void() walk1 = [$walk1, walk2]
+ {
+ if (random() < 0.2)
+ // dumptruck_ds
+ sound_idle (this, CHAN_VOICE, "enforcer/idle1.wav",
+ 1, ATTN_IDLE);
+ ai_walk (2);
+ };
+ nonvirtual void() walk2 = [$walk2, walk3] { ai_walk (4); };
+ nonvirtual void() walk3 = [$walk3, walk4] { ai_walk (4); };
+ nonvirtual void() walk4 = [$walk4, walk5] { ai_walk (3); };
+ nonvirtual void() walk5 = [$walk5, walk6] { ai_walk (1); };
+ nonvirtual void() walk6 = [$walk6, walk7] { ai_walk (2); };
+ nonvirtual void() walk7 = [$walk7, walk8] { ai_walk (2); };
+ nonvirtual void() walk8 = [$walk8, walk9] { ai_walk (1); };
+ nonvirtual void() walk9 = [$walk9, walk10] { ai_walk (2); };
+ nonvirtual void() walk10 = [$walk10, walk11] { ai_walk (4); };
+ nonvirtual void() walk11 = [$walk11, walk12] { ai_walk (4); };
+ nonvirtual void() walk12 = [$walk12, walk13] { ai_walk (1); };
+ nonvirtual void() walk13 = [$walk13, walk14] { ai_walk (2); };
+ nonvirtual void() walk14 = [$walk14, walk15] { ai_walk (3); };
+ nonvirtual void() walk15 = [$walk15, walk16] { ai_walk (4); };
+ nonvirtual void() walk16 = [$walk16, walk1] { ai_walk (2); };
+
+ //--------------------------------------------------------------
+ // Enforcer run functions
+ //--------------------------------------------------------------
+ nonvirtual void() run1 = [$run1, run2]
+ {
+ if (random() < 0.2)
+ // dumptruck_ds
+ sound_idle (this, CHAN_VOICE, "enforcer/idle1.wav",
+ 1, ATTN_IDLE);
+ ai_run (18);
+ };
+ nonvirtual void() run2 = [$run2, run3] { ai_run (14); };
+ nonvirtual void() run3 = [$run3, run4] { ai_run (7); };
+ nonvirtual void() run4 = [$run4, run5] { ai_run (12); };
+ nonvirtual void() run5 = [$run5, run6] { ai_run (14); };
+ nonvirtual void() run6 = [$run6, run7] { ai_run (14); };
+ nonvirtual void() run7 = [$run7, run8] { ai_run (7); };
+ nonvirtual void() run8 = [$run8, run1] { ai_run (11); };
+
+ //--------------------------------------------------------------
+ // Enforcer attack functions
+ //--------------------------------------------------------------
+ nonvirtual void() atk1 = [$attack1, atk2] { ai_face (); };
+ nonvirtual void() atk2 = [$attack2, atk3] { ai_face (); };
+ nonvirtual void() atk3 = [$attack3, atk4] { ai_face (); };
+ nonvirtual void() atk4 = [$attack4, atk5] { ai_face (); };
+ nonvirtual void() atk5 = [$attack5, atk6] { ai_face (); };
+ nonvirtual void() atk6 = [$attack6, atk7] { atk_laser (); };
+ nonvirtual void() atk7 = [$attack7, atk8] { ai_face (); };
+ nonvirtual void() atk8 = [$attack8, atk9] { ai_face (); };
+ nonvirtual void() atk9 = [$attack5, atk10] { ai_face (); };
+ nonvirtual void() atk10 = [$attack6, atk11] { atk_laser (); };
+ nonvirtual void() atk11 = [$attack7, atk12] { ai_face (); };
+ nonvirtual void() atk12 = [$attack8, atk13] { ai_face (); };
+ nonvirtual void() atk13 = [$attack9, atk14] { ai_face (); };
+ nonvirtual void() atk14 = [$attack10, run1]
+ {
+ ai_face ();
+ sub_checkrefire (this.atk1);
+ };
+
+ //--------------------------------------------------------------
+ // Enforcer attack functions 2
+ // modified animation frames for style Enforcers -- dumptruck_ds
+ //--------------------------------------------------------------
+ nonvirtual void() enf2atk1 = [$attack1, enf2atk2]
+ {
+ ai_face ();
+ this.count = 0;
+ this.t_length = 8 + floor (random() * 6);
+ };
+ nonvirtual void() enf2atk2 = [$attack2, enf2atk3] { ai_face (); };
+ nonvirtual void() enf2atk3 = [$attack3, enf2atk4] { ai_face (); };
+ nonvirtual void() enf2atk4 = [$attack4, enf2atk5] { ai_face (); };
+ nonvirtual void() enf2atk5 = [$attack5, enf2atk6] { ai_face (); };
+ nonvirtual void() enf2atk6 =
{
- setmodel (newmis, self.mdl_proj);
+ this.frame = $attack6;
+ this.nextthink = time + 0.1;
+ if (this.style == 5 && this.count < this.t_length)
+ {
+ this.count += 1;
}
else
{
- setmodel (newmis, "progs/laser.mdl");
- }
+ this.think = this.enf2atk7;
+ }
+ ai_face ();
+ atk_laser ();
+ };
+ nonvirtual void() enf2atk7 = [$attack7, enf2atk8] { ai_face (); };
+ nonvirtual void() enf2atk8 = [$attack8, enf2atk9] { ai_face (); };
+ nonvirtual void() enf2atk9 = [$attack9, enf2atk10] { ai_face (); };
+ nonvirtual void() enf2atk10 = [$attack10, run1]
+ {
+ ai_face ();
+ sub_checkrefire (this.enf2atk1);
+ };
+
+ //--------------------------------------------------------------
+ // Enforcer attack functions 4
+ //--------------------------------------------------------------
+ nonvirtual void() enf4atk1 = [$attack1, enf4atk2] { ai_face (); };
+ nonvirtual void() enf4atk2 = [$attack2, enf4atk3] { ai_face (); };
+ nonvirtual void() enf4atk3 = [$attack3, enf4atk4] { ai_face (); };
+ nonvirtual void() enf4atk4 = [$attack4, enf4atk5] { ai_face (); };
+ nonvirtual void() enf4atk5 = [$attack5, enf4atk6] { ai_face (); };
+ nonvirtual void() enf4atk6 = [$attack6, enf4atk7] { atk_lightning (); };
+ nonvirtual void() enf4atk7 = [$attack6, enf4atk8] { atk_lightning (); };
+ nonvirtual void() enf4atk8 = [$attack6, enf4atk9] { atk_lightning (); };
+ nonvirtual void() enf4atk9 = [$attack7, enf4atk10] { ai_face (); };
+ nonvirtual void() enf4atk10 = [$attack8, enf4atk11] { ai_face (); };
+ nonvirtual void() enf4atk11 = [$attack9, enf4atk12] { ai_face (); };
+ nonvirtual void() enf4atk12 = [$attack10, run1]
+ {
+ ai_face ();
+ sub_checkrefire (enf2atk1);
+ };
+
+ //////////////////////////////////////
+ // new frames for turret mode START //
+ //////////////////////////////////////
+
+ //--------------------------------------------------------------
+ // Enforcer turret attack 1
+ //--------------------------------------------------------------
+ nonvirtual void() turret_atk1 = [$attack1, turret_atk2] { ai_face (); };
+ nonvirtual void() turret_atk2 = [$attack2, turret_atk3] { ai_face (); };
+ nonvirtual void() turret_atk3 = [$attack3, turret_atk4]
+ {
+ ai_face ();
+ this.attack_elevation = IterateElevation (
+ OGRE_DEFAULT_ELEVATION, this.origin, this.enemy.origin);
+ };
+ nonvirtual void() turret_atk4 = [$attack4, turret_atk5]
+ {
+ ai_face ();
+ this.attack_elevation = IterateElevation (
+ this.attack_elevation, this.origin, this.enemy.origin);
+ };
+ nonvirtual void() turret_atk5 = [$attack5, turret_atk6]
+ {
+ ai_face ();
+ this.attack_elevation = IterateElevation (
+ this.attack_elevation, this.origin, this.enemy.origin);
+ };
+ nonvirtual void() turret_atk6 = [$attack6, turret_atk7]
+ {
+ atk_laser ();
+ };
+ nonvirtual void() turret_atk7 = [$attack7, turret_atk8]
+ {
+ ai_face ();
+ this.attack_elevation = IterateElevation (
+ OGRE_DEFAULT_ELEVATION, this.origin, this.enemy.origin);
+ };
+ nonvirtual void() turret_atk8 = [$attack8, turret_atk9]
+ {
+ ai_face ();
+ this.attack_elevation = IterateElevation (
+ this.attack_elevation, this.origin, this.enemy.origin);
+ };
+ nonvirtual void() turret_atk9 = [$attack5, turret_atk10]
+ {
+ ai_face ();
+ this.attack_elevation = IterateElevation (
+ this.attack_elevation, this.origin, this.enemy.origin);
+ };
+ nonvirtual void() turret_atk10 = [$attack6, turret_atk11]
+ {
+ atk_laser ();
+ };
+ nonvirtual void() turret_atk11 = [$attack7, turret_atk12] { ai_face ();};
+ nonvirtual void() turret_atk12 = [$attack8, turret_atk13] { ai_face ();};
+ nonvirtual void() turret_atk13 = [$attack9, turret_atk14] { ai_face ();};
+ nonvirtual void() turret_atk14 = [$attack10, seek_stand1]
+ {
+ ai_face ();
+ sub_checkrefire (turret_atk1);
+ };
+
+ //--------------------------------------------------------------
+ // Enforcer turret seek
+ //--------------------------------------------------------------
+ nonvirtual void() seek_stand1 = [$stand1, seek_stand2] { ai_run (0); };
+ nonvirtual void() seek_stand2 = [$stand2, seek_stand3] { ai_run (0); };
+ nonvirtual void() seek_stand3 = [$stand3, seek_stand4] { ai_run (0); };
+ nonvirtual void() seek_stand4 = [$stand4, seek_stand5] { ai_run (0); };
+ nonvirtual void() seek_stand5 = [$stand5, seek_stand6] { ai_run (0); };
+ nonvirtual void() seek_stand6 = [$stand6, seek_stand7] { ai_run (0); };
+ nonvirtual void() seek_stand7 = [$stand7, seek_stand1] { ai_run (0); };
+
+ //--------------------------------------------------------------
+ // Enforcer turret attack 2 (?)
+ //--------------------------------------------------------------
+ nonvirtual void() enf2turret_atk1 = [$attack1, enf2turret_atk2]
+ {
+ ai_face ();
+ this.count = 0;
+ this.t_length = 4 + floor (random() * 4);
+ };
+ nonvirtual void() enf2turret_atk2 = [$attack2, enf2turret_atk3] {ai_face ();};
+ nonvirtual void() enf2turret_atk3 = [$attack3, enf2turret_atk4] {ai_face ();};
+ nonvirtual void() enf2turret_atk4 = [$attack4, enf2turret_atk5] {ai_face ();};
+ nonvirtual void() enf2turret_atk5 = [$attack5, enf2turret_atk6] {ai_face ();};
+ nonvirtual void() enf2turret_atk6 =
+ {
+ this.frame = $attack6;
+ this.nextthink = time + 0.1;
+ if (this.style == 5 && this.count < this.t_length)
+ {
+ this.count += 1;
+ }
+ else
+ {
+ this.think = this.enf2turret_atk7;
+ }
+ ai_face ();
+ atk_laser ();
+ };
+ nonvirtual void() enf2turret_atk7 = [$attack7, enf2turret_atk8] {ai_face ();};
+ nonvirtual void() enf2turret_atk8 = [$attack8, enf2turret_atk9] {ai_face ();};
+ nonvirtual void() enf2turret_atk9 = [$attack9, enf2turret_atk10] {ai_face();};
+ nonvirtual void() enf2turret_atk10 = [$attack10, enf2stand1]
+ {
+ ai_face ();
+ sub_checkrefire (enf2turret_atk1);
+ };
+
+ //--------------------------------------------------------------
+ // Enforcer turret attack 4 (?)
+ //--------------------------------------------------------------
+ nonvirtual void() enf4turret_atk1 = [$attack1, enf4turret_atk2] {ai_face ();};
+ nonvirtual void() enf4turret_atk2 = [$attack2, enf4turret_atk3] {ai_face ();};
+ nonvirtual void() enf4turret_atk3 = [$attack3, enf4turret_atk4] {ai_face ();};
+ nonvirtual void() enf4turret_atk4 = [$attack4, enf4turret_atk5] {ai_face ();};
+ nonvirtual void() enf4turret_atk5 = [$attack5, enf4turret_atk6] {ai_face ();};
+ nonvirtual void() enf4turret_atk6 = [$attack6, enf4turret_atk7]
+ {
+ atk_lightning ();
+ };
+ nonvirtual void() enf4turret_atk7 = [$attack6, enf4turret_atk8]
+ {
+ atk_lightning ();
+ };
+ nonvirtual void() enf4turret_atk8 = [$attack6, enf4turret_atk9]
+ {
+ atk_lightning ();
+ };
+ nonvirtual void() enf4turret_atk9 = [$attack7, enf4turret_atk10] {ai_face();};
+ nonvirtual void() enf4turret_atk10 = [$attack8, enf4turret_atk11] {ai_face();};
+ nonvirtual void() enf4turret_atk11 = [$attack9, enf4turret_atk12] {ai_face();};
+ nonvirtual void() enf4turret_atk12 = [$attack10, enf2stand1]
+ {
+ ai_face ();
+ sub_checkrefire (enf2turret_atk1);
+ };
+
+ //--------------------------------------------------------------
+ // Enforcer turret stand 2 (?)
+ //--------------------------------------------------------------
+ nonvirtual void() enf2stand1 = [$stand1, enf2stand2] { ai_run (0); };
+ nonvirtual void() enf2stand2 = [$stand2, enf2stand3] { ai_run (0); };
+ nonvirtual void() enf2stand3 = [$stand3, enf2stand4] { ai_run (0); };
+ nonvirtual void() enf2stand4 = [$stand4, enf2stand5] { ai_run (0); };
+ nonvirtual void() enf2stand5 = [$stand5, enf2stand6] { ai_run (0); };
+ nonvirtual void() enf2stand6 = [$stand6, enf2stand7] { ai_run (0); };
+ nonvirtual void() enf2stand7 = [$stand7, enf2stand1] { ai_run (0); };
+
+ //////////////////////////////////////
+ // new frames for turret mode END //
+ //////////////////////////////////////
+
+ //--------------------------------------------------------------
+ // Enforcer pain state A
+ //--------------------------------------------------------------
+ nonvirtual void() paina1 = [$paina1, paina2] { };
+ nonvirtual void() paina2 = [$paina2, paina3] { };
+ nonvirtual void() paina3 = [$paina3, paina4] { };
+ nonvirtual void() paina4 = [$paina4, run1] { };
+
+ //--------------------------------------------------------------
+ // Enforcer pain state B
+ //--------------------------------------------------------------
+ nonvirtual void() painb1 = [$painb1, painb2] { };
+ nonvirtual void() painb2 = [$painb2, painb3] { };
+ nonvirtual void() painb3 = [$painb3, painb4] { };
+ nonvirtual void() painb4 = [$painb4, painb5] { };
+ nonvirtual void() painb5 = [$painb5, run1] { };
+
+ //--------------------------------------------------------------
+ // Enforcer pain state C
+ //--------------------------------------------------------------
+ nonvirtual void() painc1 = [$painc1, painc2] { };
+ nonvirtual void() painc2 = [$painc2, painc3] { };
+ nonvirtual void() painc3 = [$painc3, painc4] { };
+ nonvirtual void() painc4 = [$painc4, painc5] { };
+ nonvirtual void() painc5 = [$painc5, painc6] { };
+ nonvirtual void() painc6 = [$painc6, painc7] { };
+ nonvirtual void() painc7 = [$painc7, painc8] { };
+ nonvirtual void() painc8 = [$painc8, run1] { };
+
+ //--------------------------------------------------------------
+ // Enforcer pain state D
+ //--------------------------------------------------------------
+ nonvirtual void() paind1 = [$paind1, paind2] { };
+ nonvirtual void() paind2 = [$paind2, paind3] { };
+ nonvirtual void() paind3 = [$paind3, paind4] { };
+ nonvirtual void() paind4 = [$paind4, paind5] { ai_painforward (2); };
+ nonvirtual void() paind5 = [$paind5, paind6] { ai_painforward (1); };
+ nonvirtual void() paind6 = [$paind6, paind7] { };
+ nonvirtual void() paind7 = [$paind7, paind8] { };
+ nonvirtual void() paind8 = [$paind8, paind9] { };
+ nonvirtual void() paind9 = [$paind9, paind10] { };
+ nonvirtual void() paind10 = [$paind10, paind11] { };
+ nonvirtual void() paind11 = [$paind11, paind12] { ai_painforward (1); };
+ nonvirtual void() paind12 = [$paind12, paind13] { ai_painforward (1); };
+ nonvirtual void() paind13 = [$paind13, paind14] { ai_painforward (1); };
+ nonvirtual void() paind14 = [$paind14, paind15] { };
+ nonvirtual void() paind15 = [$paind15, paind16] { };
+ nonvirtual void() paind16 = [$paind16, paind17] { ai_pain (1); };
+ nonvirtual void() paind17 = [$paind17, paind18] { ai_pain (1); };
+ nonvirtual void() paind18 = [$paind18, paind19] { };
+ nonvirtual void() paind19 = [$paind19, run1] { };
+
+ //--------------------------------------------------------------
+ // Enforcer death state A
+ //--------------------------------------------------------------
+ nonvirtual void() die1 = [$death1, die2] { };
+ nonvirtual void() die2 = [$death2, die3] { };
+ nonvirtual void() die3 = [$death3, die4]
+ {
+ this.solid = SOLID_NOT;
+
+ // style ammotype check -- dumptruck_ds
+ if (this.style == 1)
+ {
+ this.ammo_rockets = 2;
+ }
+ // style ammotype check -- dumptruck_ds
+ if (this.style == 2)
+ {
+ this.ammo_rockets = 2;
+ }
+ // style ammotype check -- dumptruck_ds
+ if (this.style == 3 || this.style == 5)
+ {
+ this.ammo_nails = 5;
+ }
+ // style ammotype check -- dumptruck_ds
+ if (this.style == 0 || this.style == 4)
+ {
+ this.ammo_cells = 5;
+ }
+ if (!this.keep_ammo)
+ item_backpack::drop_backpack (this.origin, this.weapon,
+ this.ammo_shells, this.ammo_nails,
+ this.ammo_rockets, this.ammo_cells);
+ };
+ nonvirtual void() die4 = [$death4, die5] { ai_forward (14); };
+ nonvirtual void() die5 = [$death5, die6] { ai_forward (2); };
+ nonvirtual void() die6 = [$death6, die7] { };
+ nonvirtual void() die7 = [$death7, die8] { };
+ nonvirtual void() die8 = [$death8, die9] { };
+ nonvirtual void() die9 = [$death9, die10] { ai_forward (3); };
+ nonvirtual void() die10 = [$death10, die11] { ai_forward (5); };
+ nonvirtual void() die11 = [$death11, die12] { ai_forward (5); };
+ nonvirtual void() die12 = [$death12, die13] { ai_forward (5); };
+ nonvirtual void() die13 = [$death13, die14] { };
+ nonvirtual void() die14 = [$death14, die14] { };
+
+ //--------------------------------------------------------------
+ // Enforcer death state F
+ //--------------------------------------------------------------
+ nonvirtual void() fdie1 = [$fdeath1, fdie2] { };
+ nonvirtual void() fdie2 = [$fdeath2, fdie3] { };
+ nonvirtual void() fdie3 = [$fdeath3, fdie4]
+ {
+ this.solid = SOLID_NOT;
- if (!newmis.skin_proj) // dumptruck_ds
+ // style ammotype check -- dumptruck_ds
+ if (this.style == 1)
+ {
+ this.ammo_rockets = 2;
+ }
+ // style ammotype check -- dumptruck_ds
+ if (this.style == 2)
+ {
+ this.ammo_rockets = 2;
+ }
+ // style ammotype check -- dumptruck_ds
+ if (this.style == 3 || this.style == 5)
+ {
+ this.ammo_nails = 5;
+ }
+ // style ammotype check -- dumptruck_ds
+ if (this.style == 0 || this.style == 4)
+ {
+ this.ammo_cells = 5;
+ }
+ if (!this.keep_ammo)
+ item_backpack::drop_backpack (this.origin, this.weapon,
+ this.ammo_shells, this.ammo_nails,
+ this.ammo_rockets, this.ammo_cells);
+ };
+ nonvirtual void() fdie4 = [$fdeath4, fdie5] { };
+ nonvirtual void() fdie5 = [$fdeath5, fdie6] { };
+ nonvirtual void() fdie6 = [$fdeath6, fdie7] { };
+ nonvirtual void() fdie7 = [$fdeath7, fdie8] { };
+ nonvirtual void() fdie8 = [$fdeath8, fdie9] { };
+ nonvirtual void() fdie9 = [$fdeath9, fdie10] { };
+ nonvirtual void() fdie10 = [$fdeath10, fdie11] { };
+ nonvirtual void() fdie11 = [$fdeath11, fdie11] { };
+
+ //==============================================================
+ // Interaction
+ //==============================================================
+
+ //--------------------------------------------------------------
+ // enf_pain
+ //--------------------------------------------------------------
+ virtual void(entity attacker, float damage) do_damage =
{
- newmis.skin = self.skin_proj;
+ local float r;
+
+ r = random ();
+
+ if (this.pain_finished > time)
+ return;
+
+ if (r < 0.5)
+ // dumptruck_ds
+ sound_pain (this, CHAN_VOICE, "enforcer/pain1.wav",
+ 1, ATTN_NORM);
+ else
+ // dumptruck_ds
+ sound_misc3 (this, CHAN_VOICE, "enforcer/pain2.wav",
+ 1, ATTN_NORM);
+
+ if (r < 0.2)
+ {
+ this.pain_finished = time + 1;
+ // moved these here to avoid spamming pain sounds
+ // -- dumptruck_ds
+ if (this.spawnflags & I_AM_TURRET)
+ return;
+ else
+ this.paina1 ();
+ }
+ else if (r < 0.4)
+ {
+ this.pain_finished = time + 1;
+ if (this.spawnflags & I_AM_TURRET)
+ return;
+ else
+ this.painb1 ();
+ }
+ else if (r < 0.7)
+ {
+ this.pain_finished = time + 1;
+ if (this.spawnflags & I_AM_TURRET)
+ return;
+ else
+ this.painc1 ();
}
else
{
- newmis.skin = 0;
- }
- // setmodel (newmis, "progs/laser.mdl");
- setsize (newmis, '0 0 0', '0 0 0');
+ this.pain_finished = time + 2;
+ if (this.spawnflags & I_AM_TURRET)
+ return;
+ else
+ this.paind1 ();
+ }
+ };
- setorigin (newmis, org);
+ //--------------------------------------------------------------
+ // enf_die
+ //--------------------------------------------------------------
+ virtual void() do_destroy =
+ {
+ // check for gib
+ if (this.health < -35)
+ {
+ sound (this, CHAN_VOICE, "player/udeath.wav",
+ 1, ATTN_NORM);
+ // dumptruck_ds custom_mdls
+ if (this.mdl_head != "")
+ {
+ ThrowHead (this.mdl_head, this.health);
+ }
+ else
+ {
+ ThrowHead ("progs/h_mega.mdl", this.health);
+ }
+ // ThrowGib ("progs/gib1.mdl", this.health);
+ // ThrowGib ("progs/gib2.mdl", this.health);
+ // ThrowGib ("progs/gib3.mdl", this.health);
+ // custom models -- dumptruck_ds
+ if (this.mdl_gib1 != "")
+ {
+ ThrowGib (this.mdl_gib1, this.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib1.mdl", this.health);
+ }
+ if (this.mdl_gib2 != "")
+ {
+ ThrowGib (this.mdl_gib2, this.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib2.mdl", this.health);
+ }
+ if (this.mdl_gib3 != "")
+ {
+ ThrowGib (this.mdl_gib3, this.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib3.mdl", this.health);
+ }
+ base_item::drop_stuff (this);
+ return;
+ }
- SetSpeed(newmis, vec, projspeed);
- newmis.angles = vectoangles(newmis.velocity);
- if (self.homing > 0)
+ // regular death
+ // dumptruck_ds
+ sound_death (this, CHAN_VOICE, "enforcer/death1.wav",
+ 1, ATTN_NORM);
+ base_item::drop_stuff (this);
+ if (random() > 0.5)
+ this.die1 ();
+ else
+ this.fdie1 ();
+ };
+
+ //==============================================================
+ // Initialization
+ //==============================================================
+
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
{
- SetupHoming(newmis, projspeed);
- }
- else
+ if (deathmatch)
+ {
+ remove (this);
+ return;
+ }
+
+ if (this.style >= 6)
+ objerror ("style key set too high\n");
+
+ // custom_mdls function -- dumptruck_ds
+ precache_body_model2 ("progs/enforcer.mdl");
+ precache_head_model2 ("progs/h_mega.mdl");
+ precache_proj_model2 ("progs/laser.mdl");
+ precache_proj_model2 ("progs/s_spike.mdl");
+ precache_proj_model2 ("progs/missile.mdl");
+ // dumptruck_ds
+ precache_sound2_death ("enforcer/death1.wav");
+ precache_sound2_attack ("enforcer/enfire.wav");
+ precache_sound2_hit ("enforcer/enfstop.wav");
+ precache_sound2_idle ("enforcer/idle1.wav");
+ precache_sound2_pain ("enforcer/pain1.wav");
+ precache_sound2_misc3 ("enforcer/pain2.wav");
+ precache_sound2_sight ("enforcer/sight1.wav");
+ // these will be replaced with custom noise fields eventually
+ // -- dumptruck_ds
+ precache_sound2_misc ("enforcer/sight2.wav");
+ precache_sound2_misc1 ("enforcer/sight3.wav");
+ precache_sound2_misc2 ("enforcer/sight4.wav");
+
+ precache_gib1 ("progs/gib1.mdl");
+ precache_gib2 ("progs/gib2.mdl");
+ precache_gib3 ("progs/gib3.mdl");
+
+ this.solid = SOLID_SLIDEBOX;
+ this.movetype = MOVETYPE_STEP;
+
+ // SPIKE to the RESCUE!!!! - got this fixed. -- dumptruck_ds
+ body_model ("progs/enforcer.mdl");
+ // orginal dumptruck_ds
+ // setmodel (this, "progs/enforcer.mdl");
+
+ setsize (this, '-16 -16 -24', '16 16 40');
+
+ if (!this.proj_speed_mod)
+ this.proj_speed_mod = 1;
+
+ if (!this.health)
+ // thanks RennyC -- dumptruck_ds
+ this.health = 80;
+
+ this.think_stand = this.stand1;
+ this.think_walk = this.walk1;
+ if (this.spawnflags & I_AM_TURRET)
+ this.think_run = this.enf2stand1;
+ else
+ this.think_run = this.run1;
+ // Berserk test from
+ // http://celephais.net/board/view_thread.php?id=4&start=3465
+ // -- dumptruck_ds
+ if !(this.berserk)
+ this.th_pain = this.do_damage;
+ else
+ this.th_pain = sub_nullpain;
+ this.th_die = this.do_destroy;
+ // new animation frame check -- dumptruck_ds
+ if (this.style == 1 || this.style == 2 || this.style == 5)
+ {
+ if (this.spawnflags & I_AM_TURRET)
+ {
+ this.think_turret = this.enf2turret_atk1;
+ }
+ this.think_missile = this.enf2atk1;
+ }
+ else if (this.style == 0 || this.style == 3 )
+ {
+ if (this.spawnflags & I_AM_TURRET)
+ {
+ this.think_turret = this.turret_atk1;
+ }
+ this.think_missile = this.atk1;
+ }
+ else if (this.style == 4)
+ {
+ if (this.spawnflags & I_AM_TURRET)
+ {
+ this.think_turret = this.enf4turret_atk1;
+ }
+ this.think_missile = this.enf4atk1;
+ }
+
+ // walkmonster_start
+ super::init_spawned ();
+ };
+
+ //--------------------------------------------------------------
+ void() monster_enforcer =
{
- newmis.nextthink = time + 5;
- newmis.think = sub_remove;
- }
- newmis.touch = Laser_Touch;
+ this.classtype = CT_MONSTER_ENFORCER;
+ };
};
+//==============================================================================
+// TODO CEV: rework the enforcer attack / projectile functions below
+//==============================================================================
+
void(vector org, vector vec) EnfLaunchSpike =
{
@@ -132,44 +899,48 @@ void(vector org, vector vec) EnfLaunchSpike =
sound_attack (self, CHAN_WEAPON, "weapons/spike2.wav", 1, ATTN_NORM);
- vec = normalize(vec);
+ vec = normalize (vec);
- newmis = spawn();
+ newmis = spawn ();
newmis.owner = self;
newmis.movetype = MOVETYPE_FLY;
newmis.solid = SOLID_BBOX;
// newmis.effects = EF_DIMLIGHT;
- newmis.skin = self.skin_proj; //dumptruck_ds
+ // dumptruck_ds
+ newmis.skin = self.skin_proj;
// setmodel (newmis, "progs/s_spike.mdl");
- if (self.mdl_proj != "") // dumptruck_ds
+ // dumptruck_ds
+ if (self.mdl_proj != "")
{
- setmodel (newmis, self.mdl_proj);
- }
- else
- {
- setmodel (newmis, "progs/s_spike.mdl");
+ setmodel (newmis, self.mdl_proj);
+ }
+ else
+ {
+ setmodel (newmis, "progs/s_spike.mdl");
}
- if (!newmis.skin_proj) // dumptruck_ds
+ // dumptruck_ds
+ if (!newmis.skin_proj)
{
- newmis.skin = self.skin_proj;
- }
- else
- {
- newmis.skin = 0;
+ newmis.skin = self.skin_proj;
+ }
+ else
+ {
+ newmis.skin = 0;
}
-// dumptruck_ds - end
+ // dumptruck_ds - end
+
setsize (newmis, '0 0 0', '0 0 0');
setorigin (newmis, org);
- SetSpeed(newmis, vec, projspeed);
- newmis.angles = vectoangles(newmis.velocity);
+ SetSpeed (newmis, vec, projspeed);
+ newmis.angles = vectoangles (newmis.velocity);
if (self.homing > 0)
{
- SetupHoming(newmis, projspeed);
+ SetupHoming (newmis, projspeed);
}
else
{
@@ -179,36 +950,40 @@ void(vector org, vector vec) EnfLaunchSpike =
newmis.touch = superspike_touch;
};
-//dumptruck_ds start -- from inside qc tut http://www.insideqc.com/qctut/lesson-32.shtml
-
+// dumptruck_ds start
+// from inside qc tut http://www.insideqc.com/qctut/lesson-32.shtml
void() EnfMisTouch =
{
- local float damg;
+ local float damg;
if (other == self.owner)
- return; // don't explode on owner
+ // don't explode on owner
+ return;
if (pointcontents(self.origin) == CONTENT_SKY)
{
- remove(self);
+ remove (self);
return;
}
- damg = 30 + random()*2; //dumptruck_ds
+ // dumptruck_ds
+ damg = 30 + random() * 2;
if (other.health)
{
if (other.classname == "monster_shambler")
- damg = damg * 0.5; // mostly immune
+ // mostly immune
+ damg = damg * 0.5;
T_Damage (other, self, self.owner, damg );
}
// don't do radius damage to the other, because all the damage
// was done in the impact
- T_RadiusDamage (self, self.owner, 40, other); //dumptruck_ds
+ // dumptruck_ds
+ T_RadiusDamage (self, self.owner, 40, other);
-// sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM);
- self.origin = self.origin - 8*normalize(self.velocity);
+ // sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM);
+ self.origin = self.origin - 8 * normalize(self.velocity);
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_EXPLOSION);
@@ -216,19 +991,22 @@ void() EnfMisTouch =
WriteCoord (MSG_BROADCAST, self.origin_y);
WriteCoord (MSG_BROADCAST, self.origin_z);
- BecomeExplosion ();
+ // BecomeExplosion
+ spawn (base_explosion, origin: self.origin);
+ remove (self);
};
-/*
-================
-EnfRocket //dumptruck_ds start -- from inside qc tut http://www.insideqc.com/qctut/lesson-32.shtml
-================
-*/
+//----------------------------------------------------------------------
+// EnfRocket
+// dumptruck_ds start -- from inside qc tut
+// http://www.insideqc.com/qctut/lesson-32.shtml
+//----------------------------------------------------------------------
void() EnfRocket =
{
- local entity missile;
+ local entity missile;
local float projspeed = 900 * self.proj_speed_mod;
- // self.currentammo = self.ammo_rockets = self.ammo_rockets - 1; dumptruck_ds
+ // dumptruck_ds
+ // self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
sound_attack (self, CHAN_WEAPON, "weapons/sgun1.wav", 1, ATTN_NORM);
@@ -240,11 +1018,12 @@ void() EnfRocket =
missile.solid = SOLID_BBOX;
missile.classname = "missile";
-// set missile speed -- dumptruck_ds below
+ // set missile speed -- dumptruck_ds below
- SetSpeed(missile, normalize(self.enemy.origin - self.origin), projspeed);
- missile.angles = vectoangles(missile.velocity);
- missile.touch = EnfMisTouch;
+ SetSpeed (missile, normalize(self.enemy.origin - self.origin),
+ projspeed);
+ missile.angles = vectoangles (missile.velocity);
+ missile.touch = EnfMisTouch;
// makevectors (self.v_angle);
// missile.velocity = aim(self, 1000);
@@ -253,51 +1032,57 @@ void() EnfRocket =
// missile.touch = T_MissileTouch;
-// set missile duration
+ // set missile duration
if (self.homing > 0)
{
- SetupHoming(missile, projspeed);
+ SetupHoming (missile, projspeed);
}
else
{
missile.nextthink = time + 5;
missile.think = sub_remove;
}
- missile.skin = self.skin_proj; //dumptruck_ds
+ // dumptruck_ds
+ missile.skin = self.skin_proj;
- if (self.mdl_proj != "") // dumptruck_ds
+ // dumptruck_ds
+ if (self.mdl_proj != "")
{
- setmodel (missile, self.mdl_proj);
- }
- else
- {
- setmodel (missile, "progs/missile.mdl");
+ setmodel (missile, self.mdl_proj);
+ }
+ else
+ {
+ setmodel (missile, "progs/missile.mdl");
}
- if (!missile.skin_proj) // dumptruck_ds
+ // dumptruck_ds
+ if (!missile.skin_proj)
{
- missile.skin = self.skin_proj;
- }
- else
- {
- missile.skin = 0;
+ missile.skin = self.skin_proj;
+ }
+ else
+ {
+ missile.skin = 0;
}
-// dumptruck_ds - end
+ // dumptruck_ds - end
+
// setmodel (missile, "progs/missile.mdl");
setsize (missile, '0 0 0', '0 0 0');
- makevectors (self.angles); //thanks Voidforce -- dumptruck_ds
- setorigin (missile, self.origin + v_forward * 30 + v_right * 8.5 + '0 0 12'); //last number was 16 - dumptruck_ds
+ // thanks Voidforce -- dumptruck_ds
+ makevectors (self.angles);
+ // last number was 16 - dumptruck_ds
+ setorigin (missile, self.origin + v_forward * 30 +
+ v_right * 8.5 + '0 0 12');
// setorigin (missile, self.origin + v_forward*8 + '0 0 16');
};
-//end dumptruck_ds grunt missle end
-/*
-================
-EnfFireGrenade
-================
-*/
+// end dumptruck_ds grunt missle end
+
+//----------------------------------------------------------------------
+// EnfFireGrenade
+//----------------------------------------------------------------------
void() EnfFireGrenade =
{
- local entity missile;
+ local entity missile;
self.effects = self.effects | EF_MUZZLEFLASH;
@@ -308,700 +1093,155 @@ void() EnfFireGrenade =
missile.movetype = MOVETYPE_BOUNCE;
missile.solid = SOLID_BBOX;
-// set missile speed
-
+ // set missile speed
makevectors (self.angles);
- missile.velocity = normalize(self.enemy.origin - self.origin);
+ missile.velocity = normalize (self.enemy.origin - self.origin);
missile.velocity = missile.velocity * 600;
missile.velocity_z = 200;
missile.avelocity = '300 300 300';
- missile.angles = vectoangles(missile.velocity);
+ missile.angles = vectoangles (missile.velocity);
missile.touch = OgreGrenadeTouch;
-// set missile duration
+ // set missile duration
missile.nextthink = time + 2.5;
missile.think = OgreGrenadeExplode;
- missile.skin = self.skin_proj; //dumptruck_ds
+ // dumptruck_ds
+ missile.skin = self.skin_proj;
- if (self.mdl_proj != "") // dumptruck_ds
+ // dumptruck_ds
+ if (self.mdl_proj != "")
{
- setmodel (missile, self.mdl_proj);
- }
- else
- {
- setmodel (missile, "progs/grenade.mdl");
+ setmodel (missile, self.mdl_proj);
+ }
+ else
+ {
+ setmodel (missile, "progs/grenade.mdl");
}
- if (!missile.skin_proj) // dumptruck_ds
+ // dumptruck_ds
+ if (!missile.skin_proj)
{
- missile.skin = self.skin_proj;
- }
- else
- {
- missile.skin = 0;
+ missile.skin = self.skin_proj;
+ }
+ else
+ {
+ missile.skin = 0;
}
-// dumptruck_ds - end
+ // dumptruck_ds - end
// setmodel (missile, "progs/grenade.mdl");
setsize (missile, '0 0 0', '0 0 0');
- setorigin (missile, self.origin + v_forward * 30 + v_right * 8.5 + '0 0 16');
+ setorigin (missile, self.origin + v_forward * 30 +
+ v_right * 8.5 + '0 0 16');
// setorigin (missile, self.origin);
};
-void() EnfLightning =
-{
- local vector org, dir;
-
- self.effects = self.effects | EF_MUZZLEFLASH;
- sound_attack(self, CHAN_WEAPON, "weapons/lstart.wav", 1, ATTN_NORM);
- ai_face ();
- makevectors (self.angles);
- org = self.origin + v_forward * 30 + v_right * 8.5 + '0 0 16';
-
- dir = self.enemy.origin - self.enemy.velocity * 0.075;
- dir = normalize (dir - org + '0 0 16');
-
- if (self.spawnflags & I_AM_TURRET)
- {
- traceline (org, self.origin + dir*900, TRUE, self);
- }
- else
- {
- traceline (org, self.origin + dir*600, TRUE, self);
- }
-
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_LIGHTNING2);
- WriteEntity (MSG_BROADCAST, self);
- WriteCoord (MSG_BROADCAST, org_x);
- WriteCoord (MSG_BROADCAST, org_y);
- WriteCoord (MSG_BROADCAST, org_z);
- WriteCoord (MSG_BROADCAST, trace_endpos_x);
- WriteCoord (MSG_BROADCAST, trace_endpos_y);
- WriteCoord (MSG_BROADCAST, trace_endpos_z);
-
- LightningDamage (org, trace_endpos, self, 4);
-};
-
+//==============================================================================
-// style stuff -- dumptruck_ds
-void() enforcer_fire =
+void() Laser_Touch =
{
+ local vector org;
-if (self.style == 1)
+ // don't explode on owner
+ if (other == self.owner)
+ return;
+ if (pointcontents(self.origin) == CONTENT_SKY)
{
- self.effects = self.effects | EF_MUZZLEFLASH;
- ai_face();
- sound_attack (self, CHAN_WEAPON, "enforcer/enfire.wav", 1, ATTN_NORM);
-
- EnfRocket();
+ remove (self);
return;
}
-else if (self.style == 2)
+ // dumptruck_ds
+ sound_hit (self, CHAN_WEAPON, "enforcer/enfstop.wav", 1, ATTN_STATIC);
+ org = self.origin - 8 * normalize (self.velocity);
+ if (other.health)
{
- self.effects = self.effects | EF_MUZZLEFLASH;
- ai_face();
- if (self.spawnflags & I_AM_TURRET)
- {
- PreachFireGrenade(self.attack_elevation);
- }
- else
- EnfFireGrenade();
- return;
+ SpawnBlood (org, self.velocity * 0.2, 15);
+ T_Damage (other, self, self.owner, 15);
}
-
-else if (self.style == 3 || self.style ==5)
-
+ else
{
- local vector foo;
-
- self.effects = self.effects | EF_MUZZLEFLASH;
- makevectors (self.angles);
-
- foo = self.origin + v_forward * 30 + v_right * 8.5 + '0 0 16';
-
- EnfLaunchSpike(foo, self.enemy.origin - self.origin);
- return;
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_GUNSHOT);
+ WriteCoord (MSG_BROADCAST, org_x);
+ WriteCoord (MSG_BROADCAST, org_y);
+ WriteCoord (MSG_BROADCAST, org_z);
}
-else
-
- local vector org;
-
- self.effects = self.effects | EF_MUZZLEFLASH;
- makevectors (self.angles);
-
- org = self.origin + v_forward * 30 + v_right * 8.5 + '0 0 16';
-
- LaunchLaser(org, self.enemy.origin - self.origin);
+ remove (self);
};
-//============================================================================
-
-void() enf_stand1 =[ $stand1, enf_stand2 ] {ai_stand();};
-void() enf_stand2 =[ $stand2, enf_stand3 ] {ai_stand();};
-void() enf_stand3 =[ $stand3, enf_stand4 ] {ai_stand();};
-void() enf_stand4 =[ $stand4, enf_stand5 ] {ai_stand();};
-void() enf_stand5 =[ $stand5, enf_stand6 ] {ai_stand();};
-void() enf_stand6 =[ $stand6, enf_stand7 ] {ai_stand();};
-void() enf_stand7 =[ $stand7, enf_stand1 ] {ai_stand();};
-
-void() enf_walk1 =[ $walk1 , enf_walk2 ] {
-if (random() < 0.2)
- sound_idle (self, CHAN_VOICE, "enforcer/idle1.wav", 1, ATTN_IDLE); //dumptruck_ds
-ai_walk(2);};
-void() enf_walk2 =[ $walk2 , enf_walk3 ] {ai_walk(4);};
-void() enf_walk3 =[ $walk3 , enf_walk4 ] {ai_walk(4);};
-void() enf_walk4 =[ $walk4 , enf_walk5 ] {ai_walk(3);};
-void() enf_walk5 =[ $walk5 , enf_walk6 ] {ai_walk(1);};
-void() enf_walk6 =[ $walk6 , enf_walk7 ] {ai_walk(2);};
-void() enf_walk7 =[ $walk7 , enf_walk8 ] {ai_walk(2);};
-void() enf_walk8 =[ $walk8 , enf_walk9 ] {ai_walk(1);};
-void() enf_walk9 =[ $walk9 , enf_walk10 ] {ai_walk(2);};
-void() enf_walk10 =[ $walk10, enf_walk11 ] {ai_walk(4);};
-void() enf_walk11 =[ $walk11, enf_walk12 ] {ai_walk(4);};
-void() enf_walk12 =[ $walk12, enf_walk13 ] {ai_walk(1);};
-void() enf_walk13 =[ $walk13, enf_walk14 ] {ai_walk(2);};
-void() enf_walk14 =[ $walk14, enf_walk15 ] {ai_walk(3);};
-void() enf_walk15 =[ $walk15, enf_walk16 ] {ai_walk(4);};
-void() enf_walk16 =[ $walk16, enf_walk1 ] {ai_walk(2);};
-
-void() enf_run1 =[ $run1 , enf_run2 ] {
-if (random() < 0.2)
- sound_idle (self, CHAN_VOICE, "enforcer/idle1.wav", 1, ATTN_IDLE); //dumptruck_ds
-ai_run(18);};
-void() enf_run2 =[ $run2 , enf_run3 ] {ai_run(14);};
-void() enf_run3 =[ $run3 , enf_run4 ] {ai_run(7);};
-void() enf_run4 =[ $run4 , enf_run5 ] {ai_run(12);};
-void() enf_run5 =[ $run5 , enf_run6 ] {ai_run(14);};
-void() enf_run6 =[ $run6 , enf_run7 ] {ai_run(14);};
-void() enf_run7 =[ $run7 , enf_run8 ] {ai_run(7);};
-void() enf_run8 =[ $run8 , enf_run1 ] {ai_run(11);};
-
-void() enf_atk1 =[ $attack1, enf_atk2 ] {ai_face();};
-void() enf_atk2 =[ $attack2, enf_atk3 ] {ai_face();};
-void() enf_atk3 =[ $attack3, enf_atk4 ] {ai_face();};
-void() enf_atk4 =[ $attack4, enf_atk5 ] {ai_face();};
-void() enf_atk5 =[ $attack5, enf_atk6 ] {ai_face();};
-void() enf_atk6 =[ $attack6, enf_atk7 ] {enforcer_fire();};
-void() enf_atk7 =[ $attack7, enf_atk8 ] {ai_face();};
-void() enf_atk8 =[ $attack8, enf_atk9 ] {ai_face();};
-void() enf_atk9 =[ $attack5, enf_atk10 ] {ai_face();};
-void() enf_atk10 =[ $attack6, enf_atk11 ] {enforcer_fire();};
-void() enf_atk11 =[ $attack7, enf_atk12 ] {ai_face();};
-void() enf_atk12 =[ $attack8, enf_atk13 ] {ai_face();};
-void() enf_atk13 =[ $attack9, enf_atk14 ] {ai_face();};
-void() enf_atk14 =[ $attack10, enf_run1 ] {ai_face();SUB_CheckRefire (enf_atk1);
-};
-/* modified animation frames for style Enforcers */ // dumptruck_ds
-void() enf_2atk7;
-void() enf_2atk1 =[ $attack1, enf_2atk2 ] {ai_face();self.count = 0;self.t_length= 8 + floor(random()*6);};
-void() enf_2atk2 =[ $attack2, enf_2atk3 ] {ai_face();};
-void() enf_2atk3 =[ $attack3, enf_2atk4 ] {ai_face();};
-void() enf_2atk4 =[ $attack4, enf_2atk5 ] {ai_face();};
-void() enf_2atk5 =[ $attack5, enf_2atk6 ] {ai_face();};
-
-void() enf_2atk6 ={
-self.frame = $attack6;
-self.nextthink = time + .1;
-if (self.style == 5 && self.count < self.t_length)
-{
- self.count +=1;
-}
-else
+void(vector org, vector vec) LaunchLaser =
{
- self.think = enf_2atk7;
-}
-ai_face();
-enforcer_fire();};
-void() enf_2atk7 =[ $attack7, enf_2atk8 ] {ai_face();};
-void() enf_2atk8 =[ $attack8, enf_2atk9 ] {ai_face();};
-void() enf_2atk9 =[ $attack9, enf_2atk10 ] {ai_face();};
-void() enf_2atk10 =[ $attack10, enf_run1 ] {ai_face();SUB_CheckRefire (enf_2atk1);
-};
-void() enf_4atk1 =[ $attack1, enf_4atk2 ] {ai_face();};
-void() enf_4atk2 =[ $attack2, enf_4atk3 ] {ai_face();};
-void() enf_4atk3 =[ $attack3, enf_4atk4 ] {ai_face();};
-void() enf_4atk4 =[ $attack4, enf_4atk5 ] {ai_face();};
-void() enf_4atk5 =[ $attack5, enf_4atk6 ] {ai_face();};
-void() enf_4atk6 =[ $attack6, enf_4atk7 ] {EnfLightning();};
-void() enf_4atk7 =[ $attack6, enf_4atk8 ] {EnfLightning();};
-void() enf_4atk8 =[ $attack6, enf_4atk9 ] {EnfLightning();};
-void() enf_4atk9 =[ $attack7, enf_4atk10 ] {ai_face();};
-void() enf_4atk10 =[ $attack8, enf_4atk11 ] {ai_face();};
-void() enf_4atk11 =[ $attack9, enf_4atk12 ] {ai_face();};
-void() enf_4atk12 =[ $attack10, enf_run1 ] {ai_face();SUB_CheckRefire (enf_2atk1);
-};
-////////////////////////////
-// new frames for turret mode START
-////////////////////////////
-
-void() enf_turret_atk1 =[ $attack1, enf_turret_atk2 ] {ai_face();};
-void() enf_turret_atk2 =[ $attack2, enf_turret_atk3 ] {ai_face();};
-void() enf_turret_atk3 =[ $attack3, enf_turret_atk4 ] {ai_face();self.attack_elevation = IterateElevation(OGRE_DEFAULT_ELEVATION, self.enemy.origin);};
-void() enf_turret_atk4 =[ $attack4, enf_turret_atk5 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
-void() enf_turret_atk5 =[ $attack5, enf_turret_atk6 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
-void() enf_turret_atk6 =[ $attack6, enf_turret_atk7 ] {enforcer_fire();};
-void() enf_turret_atk7 =[ $attack7, enf_turret_atk8 ] {ai_face();self.attack_elevation = IterateElevation(OGRE_DEFAULT_ELEVATION, self.enemy.origin);};
-void() enf_turret_atk8 =[ $attack8, enf_turret_atk9 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
-void() enf_turret_atk9 =[ $attack5, enf_turret_atk10 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
-void() enf_turret_atk10 =[ $attack6, enf_turret_atk11 ] {enforcer_fire();};
-void() enf_turret_atk11 =[ $attack7, enf_turret_atk12 ] {ai_face();};
-void() enf_turret_atk12 =[ $attack8, enf_turret_atk13 ] {ai_face();};
-void() enf_turret_atk13 =[ $attack9, enf_turret_atk14 ] {ai_face();};
-void() enf_turret_atk14 =[ $attack10, enf_seek_stand1 ] {ai_face();SUB_CheckRefire (enf_turret_atk1);
-};
-void() enf_seek_stand1 =[ $stand1, enf_seek_stand2 ] {ai_run(0);};
-void() enf_seek_stand2 =[ $stand2, enf_seek_stand3 ] {ai_run(0);};
-void() enf_seek_stand3 =[ $stand3, enf_seek_stand4 ] {ai_run(0);};
-void() enf_seek_stand4 =[ $stand4, enf_seek_stand5 ] {ai_run(0);};
-void() enf_seek_stand5 =[ $stand5, enf_seek_stand6 ] {ai_run(0);};
-void() enf_seek_stand6 =[ $stand6, enf_seek_stand7 ] {ai_run(0);};
-void() enf_seek_stand7 =[ $stand7, enf_seek_stand1 ] {ai_run(0);};
-
-void() enf_2turret_atk7;
-void() enf_2turret_atk1 =[ $attack1, enf_2turret_atk2 ] {ai_face();self.count = 0;self.t_length= 4 + floor(random()*4);};
-void() enf_2turret_atk2 =[ $attack2, enf_2turret_atk3 ] {ai_face();};
-void() enf_2turret_atk3 =[ $attack3, enf_2turret_atk4 ] {ai_face();};
-void() enf_2turret_atk4 =[ $attack4, enf_2turret_atk5 ] {ai_face();};
-void() enf_2turret_atk5 =[ $attack5, enf_2turret_atk6 ] {ai_face();};
-
-void() enf_2turret_atk6 ={
-self.frame = $attack6;
-self.nextthink = time + .1;
-if (self.style == 5 && self.count < self.t_length)
-{
- self.count +=1;
-}
-else
-{
- self.think = enf_2turret_atk7;
-}
-ai_face();
-enforcer_fire();};
-void() enf_2turret_atk7 =[ $attack7, enf_2turret_atk8 ] {ai_face();};
-void() enf_2turret_atk8 =[ $attack8, enf_2turret_atk9 ] {ai_face();};
-void() enf_2turret_atk9 =[ $attack9, enf_2turret_atk10 ] {ai_face();};
-void() enf_2turret_atk10 =[ $attack10, enf_2stand1 ] {ai_face();SUB_CheckRefire (enf_2turret_atk1);
-};
-void() enf_4turret_atk1 =[ $attack1, enf_4turret_atk2 ] {ai_face();};
-void() enf_4turret_atk2 =[ $attack2, enf_4turret_atk3 ] {ai_face();};
-void() enf_4turret_atk3 =[ $attack3, enf_4turret_atk4 ] {ai_face();};
-void() enf_4turret_atk4 =[ $attack4, enf_4turret_atk5 ] {ai_face();};
-void() enf_4turret_atk5 =[ $attack5, enf_4turret_atk6 ] {ai_face();};
-void() enf_4turret_atk6 =[ $attack6, enf_4turret_atk7 ] {EnfLightning();};
-void() enf_4turret_atk7 =[ $attack6, enf_4turret_atk8 ] {EnfLightning();};
-void() enf_4turret_atk8 =[ $attack6, enf_4turret_atk9 ] {EnfLightning();};
-void() enf_4turret_atk9 =[ $attack7, enf_4turret_atk10 ] {ai_face();};
-void() enf_4turret_atk10 =[ $attack8, enf_4turret_atk11 ] {ai_face();};
-void() enf_4turret_atk11 =[ $attack9, enf_4turret_atk12 ] {ai_face();};
-void() enf_4turret_atk12 =[ $attack10, enf_2stand1 ] {ai_face();SUB_CheckRefire (enf_2turret_atk1);
-};
-void() enf_2stand1 =[ $stand1, enf_2stand2 ] {ai_run(0);};
-void() enf_2stand2 =[ $stand2, enf_2stand3 ] {ai_run(0);};
-void() enf_2stand3 =[ $stand3, enf_2stand4 ] {ai_run(0);};
-void() enf_2stand4 =[ $stand4, enf_2stand5 ] {ai_run(0);};
-void() enf_2stand5 =[ $stand5, enf_2stand6 ] {ai_run(0);};
-void() enf_2stand6 =[ $stand6, enf_2stand7 ] {ai_run(0);};
-void() enf_2stand7 =[ $stand7, enf_2stand1 ] {ai_run(0);};
-////////////////////////////
-// new frames for turret mode END
-////////////////////////////
-void() enf_paina1 =[ $paina1, enf_paina2 ] {};
-void() enf_paina2 =[ $paina2, enf_paina3 ] {};
-void() enf_paina3 =[ $paina3, enf_paina4 ] {};
-void() enf_paina4 =[ $paina4, enf_run1 ] {};
-
-void() enf_painb1 =[ $painb1, enf_painb2 ] {};
-void() enf_painb2 =[ $painb2, enf_painb3 ] {};
-void() enf_painb3 =[ $painb3, enf_painb4 ] {};
-void() enf_painb4 =[ $painb4, enf_painb5 ] {};
-void() enf_painb5 =[ $painb5, enf_run1 ] {};
-
-void() enf_painc1 =[ $painc1, enf_painc2 ] {};
-void() enf_painc2 =[ $painc2, enf_painc3 ] {};
-void() enf_painc3 =[ $painc3, enf_painc4 ] {};
-void() enf_painc4 =[ $painc4, enf_painc5 ] {};
-void() enf_painc5 =[ $painc5, enf_painc6 ] {};
-void() enf_painc6 =[ $painc6, enf_painc7 ] {};
-void() enf_painc7 =[ $painc7, enf_painc8 ] {};
-void() enf_painc8 =[ $painc8, enf_run1 ] {};
-
-void() enf_paind1 =[ $paind1, enf_paind2 ] {};
-void() enf_paind2 =[ $paind2, enf_paind3 ] {};
-void() enf_paind3 =[ $paind3, enf_paind4 ] {};
-void() enf_paind4 =[ $paind4, enf_paind5 ] {ai_painforward(2);};
-void() enf_paind5 =[ $paind5, enf_paind6 ] {ai_painforward(1);};
-void() enf_paind6 =[ $paind6, enf_paind7 ] {};
-void() enf_paind7 =[ $paind7, enf_paind8 ] {};
-void() enf_paind8 =[ $paind8, enf_paind9 ] {};
-void() enf_paind9 =[ $paind9, enf_paind10 ] {};
-void() enf_paind10 =[ $paind10, enf_paind11 ] {};
-void() enf_paind11 =[ $paind11, enf_paind12 ] {ai_painforward(1);};
-void() enf_paind12 =[ $paind12, enf_paind13 ] {ai_painforward(1);};
-void() enf_paind13 =[ $paind13, enf_paind14 ] {ai_painforward(1);};
-void() enf_paind14 =[ $paind14, enf_paind15 ] {};
-void() enf_paind15 =[ $paind15, enf_paind16 ] {};
-void() enf_paind16 =[ $paind16, enf_paind17 ] {ai_pain(1);};
-void() enf_paind17 =[ $paind17, enf_paind18 ] {ai_pain(1);};
-void() enf_paind18 =[ $paind18, enf_paind19 ] {};
-void() enf_paind19 =[ $paind19, enf_run1 ] {};
-
-void(entity attacker, float damage) enf_pain =
-{
- local float r;
+ local float projspeed = self.proj_speed_mod * 600;
- r = random ();
+ if (self.classname == "monster_enforcer" ||
+ self.classname == "monster_army")
+ {
+ sound_attack (self, CHAN_WEAPON, "enforcer/enfire.wav",
+ 1, ATTN_NORM);
+ }
- if (self.pain_finished > time)
- return;
+ vec = normalize (vec);
- if (r < 0.5)
- sound_pain (self, CHAN_VOICE, "enforcer/pain1.wav", 1, ATTN_NORM); //dumptruck_ds
- else
- sound_misc3 (self, CHAN_VOICE, "enforcer/pain2.wav", 1, ATTN_NORM); // dumptruck_ds
+ newmis = spawn ();
+ // dumptruck_ds
+ newmis.snd_hit = self.snd_hit;
+ newmis.owner = self;
+ newmis.movetype = MOVETYPE_FLY;
+ newmis.solid = SOLID_BBOX;
+ newmis.effects = EF_DIMLIGHT;
+ // dumptruck_ds
+ newmis.skin = self.skin_proj;
- if (r < 0.2)
- {
- self.pain_finished = time + 1;
- // moved these here to avoid spamming pain sounds - dumptruck_ds
- if (self.spawnflags & I_AM_TURRET)
- return;
- else
- enf_paina1 ();
- }
- else if (r < 0.4)
+ // dumptruck_ds
+ if (self.mdl_proj != "")
{
- self.pain_finished = time + 1;
- if (self.spawnflags & I_AM_TURRET)
- return;
- else
- enf_painb1 ();
- }
- else if (r < 0.7)
- {
- self.pain_finished = time + 1;
- if (self.spawnflags & I_AM_TURRET)
- return;
- else
- enf_painc1 ();
+ setmodel (newmis, self.mdl_proj);
}
else
{
- self.pain_finished = time + 2;
- if (self.spawnflags & I_AM_TURRET)
- return;
- else
- enf_paind1 ();
+ setmodel (newmis, "progs/laser.mdl");
}
-};
-
-//============================================================================
-
-
-
-
-void() enf_die1 =[ $death1, enf_die2 ] {};
-void() enf_die2 =[ $death2, enf_die3 ] {};
-void() enf_die3 =[ $death3, enf_die4 ]
-{
- self.solid = SOLID_NOT;
-
- if (self.style == 1) // style ammotype check -- dumptruck_ds
- {
- self.ammo_rockets = 2;
- }
- if (self.style == 2) // style ammotype check -- dumptruck_ds
- {
- self.ammo_rockets = 2;
- }
- if (self.style == 3 || self.style == 5) // style ammotype check -- dumptruck_ds
- {
- self.ammo_nails = 5;
- }
- if (self.style == 0 || self.style == 4) // style ammotype check -- dumptruck_ds
- {
- self.ammo_cells = 5;
- }
- if(!self.keep_ammo)
- item_backpack::drop_backpack (self);
-};
-void() enf_die4 =[ $death4, enf_die5 ] {ai_forward(14);};
-void() enf_die5 =[ $death5, enf_die6 ] {ai_forward(2);};
-void() enf_die6 =[ $death6, enf_die7 ] {};
-void() enf_die7 =[ $death7, enf_die8 ] {};
-void() enf_die8 =[ $death8, enf_die9 ] {};
-void() enf_die9 =[ $death9, enf_die10 ] {ai_forward(3);};
-void() enf_die10 =[ $death10, enf_die11 ] {ai_forward(5);};
-void() enf_die11 =[ $death11, enf_die12 ] {ai_forward(5);};
-void() enf_die12 =[ $death12, enf_die13 ] {ai_forward(5);};
-void() enf_die13 =[ $death13, enf_die14 ] {};
-void() enf_die14 =[ $death14, enf_die14 ] {};
-
-void() enf_fdie1 =[ $fdeath1, enf_fdie2 ] {
-
-};
-void() enf_fdie2 =[ $fdeath2, enf_fdie3 ] {};
-void() enf_fdie3 =[ $fdeath3, enf_fdie4 ]
-{
- self.solid = SOLID_NOT;
-
- if (self.style == 1) // style ammotype check -- dumptruck_ds
- {
- self.ammo_rockets = 2;
- }
- if (self.style == 2) // style ammotype check -- dumptruck_ds
- {
- self.ammo_rockets = 2;
- }
- if (self.style == 3 || self.style == 5) // style ammotype check -- dumptruck_ds
- {
- self.ammo_nails = 5;
- }
- if (self.style == 0 || self.style == 4) // style ammotype check -- dumptruck_ds
- {
- self.ammo_cells = 5;
- }
- if(!self.keep_ammo)
- item_backpack::drop_backpack (self);
-};
-void() enf_fdie4 =[ $fdeath4, enf_fdie5 ] {};
-void() enf_fdie5 =[ $fdeath5, enf_fdie6 ] {};
-void() enf_fdie6 =[ $fdeath6, enf_fdie7 ] {};
-void() enf_fdie7 =[ $fdeath7, enf_fdie8 ] {};
-void() enf_fdie8 =[ $fdeath8, enf_fdie9 ] {};
-void() enf_fdie9 =[ $fdeath9, enf_fdie10 ] {};
-void() enf_fdie10 =[ $fdeath10, enf_fdie11 ] {};
-void() enf_fdie11 =[ $fdeath11, enf_fdie11 ] {};
-
-void() enf_die =
-{
-// check for gib
- if (self.health < -35)
+ // dumptruck_ds
+ if (!newmis.skin_proj)
{
- sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
- if (self.mdl_head != "") //dumptruck_ds custom_mdls
- {
- ThrowHead (self.mdl_head, self.health);
- }
- else
- {
- ThrowHead ("progs/h_mega.mdl", self.health);
- }
- // ThrowGib ("progs/gib1.mdl", self.health);
- // ThrowGib ("progs/gib2.mdl", self.health);
- // ThrowGib ("progs/gib3.mdl", self.health);
- if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
- {
- ThrowGib (self.mdl_gib1, self.health);
- }
- else
- {
- ThrowGib ("progs/gib1.mdl", self.health);
- }
- if (self.mdl_gib2 != "")
- {
- ThrowGib (self.mdl_gib2, self.health);
- }
- else
- {
- ThrowGib ("progs/gib2.mdl", self.health);
- }
- if (self.mdl_gib3 != "")
- {
- ThrowGib (self.mdl_gib3, self.health);
- }
- else
- {
- ThrowGib ("progs/gib3.mdl", self.health);
- }
- base_item::drop_stuff (self);
- return;
+ newmis.skin = self.skin_proj;
}
-
-// regular death
- sound_death (self, CHAN_VOICE, "enforcer/death1.wav", 1, ATTN_NORM); //dumptruck_ds
- base_item::drop_stuff (self);
- if (random() > 0.5)
- enf_die1 ();
else
- enf_fdie1 ();
-};
-
-
-/*QUAKED monster_enforcer (1 0 0) (-16 -16 -24) (16 16 40) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ("progs/enforcer.mdl");
-}
-Enforcer.
-
-Default health = 80
-
-keep_ammo(integer) : "1 = Don't drop backpack upon death"
-
-style(Choices) : "Attack type"
-0 : "Default (lasers)"
-1 : "rockets"
-2 : "grenades"
-3 : "nails"
-
-snd_death(string) : Path to custom death sound"
-snd_pain(string) : "Path to 1st custom pain sound"
-snd_sight(string) : "Path to custom sight sound for STOP!"
-snd_attack(string) : Path to custom attack sound e.g laser firing"
-snd_hit(string) : "Path to custom hit sound e.g. laser hits wall"
-snd_idle(string) : "Path to custom idle sound"
-snd_misc(string) : "Path to custom sight sound for FREEZE!"
-snd_misc1(string) : "Path to custom sight sound for YOU THERE!"
-snd_misc2(string) : "Path to custom sight sound for HALT!"
-snd_misc3(string) : "Path to 2nd custom pain sound"
-
-mdl_head(string) : "Path to custom head model"
-mdl_body(string) : "Path to custom body model"
-mdl_proj(string) : "Path to custom projectile model"
-skin_head(float) : "Skin index of custom head model"
-skin_proj(float) : "Skin index of custom projectile model"
-mdl_gib1(string) : "Path to custom 1st gib model"
-mdl_gib2(string) : "Path to custom 2nd gib model"
-mdl_gib3(string) : "Path to custom 3rd gib model"
-
-effects(choices) : "Add a visual effect to an entity"
-0 : "None (Default)"
-1 : "Brightfield (yellow particles)"
-4 : "Bright light"
-8 : "Dim light"
-
-berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
-0 : "Off (Default)"
-1 : "Berserk (skip pain animations)"
-
-delay(float) : "Delay spawn in for this amount of time"
-
-wait(choices) : "Play an effect when trigger spawned?"
-0 : "Teleport Effects (Default)"
-1 : "Spawn Silently"
-
-spawn_angry(Choices)
-0 : "Only when trigger spawned, default behavior - not angry"
-1 : "Only when trigger spawned, set to 1 to spawn angry at player"
-
-infight_mode(Choices)
-0 : "Default behavior, only with different classnames"
-1 : "Infight with monsters with the same classname but a different mdl_body"
-2 : "Infight with monsters with the same classname and model but a different skin"
-3 : "Infight no matter what"
-
-health(integer) : "Set this to a custom health amount"
-pain_target(string) : "Fire this target when pain_threshold is reached"
-pain_threshold(integer) : "Fire pain_target when health drops below this amount"
-sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
-skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
-obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
-obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
-damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
-
-*/
-void() monster_enforcer =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (deathmatch)
{
- remove(self);
- return;
- }
- if (self.style >= 6)
- objerror("style key set too high\n");
-
- precache_body_model2 ("progs/enforcer.mdl"); // custom_mdls function -- dumptruck_ds
- precache_head_model2 ("progs/h_mega.mdl");
- precache_proj_model2 ("progs/laser.mdl");
- precache_proj_model2 ("progs/s_spike.mdl");
- precache_proj_model2 ("progs/missile.mdl");
- //dumptruck_ds
- precache_sound2_death ("enforcer/death1.wav");
- precache_sound2_attack ("enforcer/enfire.wav");
- precache_sound2_hit ("enforcer/enfstop.wav");
- precache_sound2_idle ("enforcer/idle1.wav");
- precache_sound2_pain ("enforcer/pain1.wav");
- precache_sound2_misc3 ("enforcer/pain2.wav");
- precache_sound2_sight ("enforcer/sight1.wav");
- precache_sound2_misc ("enforcer/sight2.wav"); // these will be replaced with custom noise fields eventually - dumptruck_ds
- precache_sound2_misc1 ("enforcer/sight3.wav");
- precache_sound2_misc2 ("enforcer/sight4.wav");
-
- precache_gib1 ("progs/gib1.mdl");
- precache_gib2 ("progs/gib2.mdl");
- precache_gib3 ("progs/gib3.mdl");
-
- self.solid = SOLID_SLIDEBOX;
- self.movetype = MOVETYPE_STEP;
-
- body_model ("progs/enforcer.mdl"); // SPIKE to the RESCUE!!!! - got this fixed. -- dumptruck_ds
- // // setmodel (self, "progs/enforcer.mdl"); //orginal dumptruck_ds
-
- setsize (self, '-16 -16 -24', '16 16 40');
-
- if (!self.proj_speed_mod)
- {
- self.proj_speed_mod = 1;
+ newmis.skin = 0;
}
- if (!self.health) //thanks RennyC -- dumptruck_ds
- self.health = 80;
+ // setmodel (newmis, "progs/laser.mdl");
+ setsize (newmis, '0 0 0', '0 0 0');
+
+ setorigin (newmis, org);
- self.th_stand = enf_stand1;
- self.th_walk = enf_walk1;
- if (self.spawnflags & I_AM_TURRET)
+ SetSpeed (newmis, vec, projspeed);
+ newmis.angles = vectoangles (newmis.velocity);
+ if (self.homing > 0)
{
- self.th_run = enf_2stand1;
+ SetupHoming (newmis, projspeed);
}
else
{
- self.th_run = enf_run1;
+ newmis.nextthink = time + 5;
+ newmis.think = sub_remove;
}
- if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
- self.th_pain = enf_pain;
- else
- self.th_pain = sub_nullpain;
- self.th_die = enf_die;
- if (self.style == 1 || self.style == 2 || self.style == 5) // new animation frame check -- dumptruck_ds
- {
- if (self.spawnflags & I_AM_TURRET)
- {
- self.th_turret = enf_2turret_atk1;
- }
- self.th_missile = enf_2atk1;
- }
- else if (self.style == 0 || self.style == 3 ) // new animation frame check -- dumptruck_ds
- {
- if (self.spawnflags & I_AM_TURRET)
- {
- self.th_turret = enf_turret_atk1;
- }
- self.th_missile = enf_atk1;
- }
- else if (self.style == 4) // new animation frame check -- dumptruck_ds
- {
- if (self.spawnflags & I_AM_TURRET)
- {
- self.th_turret = enf_4turret_atk1;
- }
- self.th_missile = enf_4atk1;
- }
- walkmonster_start();
+ newmis.touch = Laser_Touch;
};
+//==============================================================================
+
/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
/*QUAKED monster_dead_enforcer (0 0.5 0.8) (-16 -16 -24) (16 16 32) SOLID FACE_UP X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
@@ -1033,6 +1273,7 @@ void() monster_dead_enforcer =
else
{
self.frame = $death14;
+
if (self.spawnflags & 1)
{
self.solid = SOLID_BBOX;
Return to the top of this page or return to the overview of this repo.
Diff qc/monsters/fish.qc
diff --git a/qc/monsters/fish.qc b/qc/monsters/fish.qc
index e348590..1c6a780 100644
--- a/qc/monsters/fish.qc
+++ b/qc/monsters/fish.qc
@@ -1,3 +1,10 @@
+//==============================================================================
+// FISHIES
+//==============================================================================
+
+//======================================================================
+// frame macros
+//======================================================================
$cd id1/models/fish
$origin 0 0 24
$base base
@@ -18,191 +25,6 @@ $frame swim18
$frame pain1 pain2 pain3 pain4 pain5 pain6 pain7 pain8
$frame pain9
-void() swimmonster_start;
-
-void() f_stand1 =[ $swim1, f_stand2 ] {ai_stand();};
-void() f_stand2 =[ $swim2, f_stand3 ] {ai_stand();};
-void() f_stand3 =[ $swim3, f_stand4 ] {ai_stand();};
-void() f_stand4 =[ $swim4, f_stand5 ] {ai_stand();};
-void() f_stand5 =[ $swim5, f_stand6 ] {ai_stand();};
-void() f_stand6 =[ $swim6, f_stand7 ] {ai_stand();};
-void() f_stand7 =[ $swim7, f_stand8 ] {ai_stand();};
-void() f_stand8 =[ $swim8, f_stand9 ] {ai_stand();};
-void() f_stand9 =[ $swim9, f_stand10 ] {ai_stand();};
-void() f_stand10 =[ $swim10, f_stand11 ] {ai_stand();};
-void() f_stand11 =[ $swim11, f_stand12 ] {ai_stand();};
-void() f_stand12 =[ $swim12, f_stand13 ] {ai_stand();};
-void() f_stand13 =[ $swim13, f_stand14 ] {ai_stand();};
-void() f_stand14 =[ $swim14, f_stand15 ] {ai_stand();};
-void() f_stand15 =[ $swim15, f_stand16 ] {ai_stand();};
-void() f_stand16 =[ $swim16, f_stand17 ] {ai_stand();};
-void() f_stand17 =[ $swim17, f_stand18 ] {ai_stand();};
-void() f_stand18 =[ $swim18, f_stand1 ] {ai_stand();};
-
-void() f_walk1 =[ $swim1, f_walk2 ] {ai_walk(8);};
-void() f_walk2 =[ $swim2, f_walk3 ] {ai_walk(8);};
-void() f_walk3 =[ $swim3, f_walk4 ] {ai_walk(8);};
-void() f_walk4 =[ $swim4, f_walk5 ] {ai_walk(8);};
-void() f_walk5 =[ $swim5, f_walk6 ] {ai_walk(8);};
-void() f_walk6 =[ $swim6, f_walk7 ] {ai_walk(8);};
-void() f_walk7 =[ $swim7, f_walk8 ] {ai_walk(8);};
-void() f_walk8 =[ $swim8, f_walk9 ] {ai_walk(8);};
-void() f_walk9 =[ $swim9, f_walk10 ] {ai_walk(8);};
-void() f_walk10 =[ $swim10, f_walk11 ] {ai_walk(8);};
-void() f_walk11 =[ $swim11, f_walk12 ] {ai_walk(8);};
-void() f_walk12 =[ $swim12, f_walk13 ] {ai_walk(8);};
-void() f_walk13 =[ $swim13, f_walk14 ] {ai_walk(8);};
-void() f_walk14 =[ $swim14, f_walk15 ] {ai_walk(8);};
-void() f_walk15 =[ $swim15, f_walk16 ] {ai_walk(8);};
-void() f_walk16 =[ $swim16, f_walk17 ] {ai_walk(8);};
-void() f_walk17 =[ $swim17, f_walk18 ] {ai_walk(8);};
-void() f_walk18 =[ $swim18, f_walk1 ] {ai_walk(8);};
-
-void() f_run1 =[ $swim1, f_run2 ] {ai_run(12);
- if (random() < 0.5)
- sound_idle (self, CHAN_VOICE, "fish/idle.wav", 1, ATTN_NORM);
-};
-void() f_run2 =[ $swim3, f_run3 ] {ai_run(12);};
-void() f_run3 =[ $swim5, f_run4 ] {ai_run(12);};
-void() f_run4 =[ $swim7, f_run5 ] {ai_run(12);};
-void() f_run5 =[ $swim9, f_run6 ] {ai_run(12);};
-void() f_run6 =[ $swim11, f_run7 ] {ai_run(12);};
-void() f_run7 =[ $swim13, f_run8 ] {ai_run(12);};
-void() f_run8 =[ $swim15, f_run9 ] {ai_run(12);};
-void() f_run9 =[ $swim17, f_run1 ] {ai_run(12);};
-
-void() fish_melee =
-{
- local vector delta;
- local float ldmg;
-
- if (!self.enemy)
- return; // removed before stroke
-
- delta = self.enemy.origin - self.origin;
-
- if (vlen(delta) > 60)
- return;
-
- sound_attack (self, CHAN_VOICE, "fish/bite.wav", 1, ATTN_NORM);
- ldmg = (random() + random()) * 3;
- T_Damage (self.enemy, self, self, ldmg);
-};
-
-void() f_attack1 =[ $attack1, f_attack2 ] {ai_charge(10);};
-void() f_attack2 =[ $attack2, f_attack3 ] {ai_charge(10);};
-void() f_attack3 =[ $attack3, f_attack4 ] {fish_melee();};
-void() f_attack4 =[ $attack4, f_attack5 ] {ai_charge(10);};
-void() f_attack5 =[ $attack5, f_attack6 ] {ai_charge(10);};
-void() f_attack6 =[ $attack6, f_attack7 ] {ai_charge(10);};
-void() f_attack7 =[ $attack7, f_attack8 ] {ai_charge(10);};
-void() f_attack8 =[ $attack8, f_attack9 ] {ai_charge(10);};
-void() f_attack9 =[ $attack9, f_attack10] {fish_melee();};
-void() f_attack10 =[ $attack10, f_attack11] {ai_charge(10);};
-void() f_attack11 =[ $attack11, f_attack12] {ai_charge(10);};
-void() f_attack12 =[ $attack12, f_attack13] {ai_charge(10);};
-void() f_attack13 =[ $attack13, f_attack14] {ai_charge(10);};
-void() f_attack14 =[ $attack14, f_attack15] {ai_charge(10);};
-void() f_attack15 =[ $attack15, f_attack16] {fish_melee();};
-void() f_attack16 =[ $attack16, f_attack17] {ai_charge(10);};
-void() f_attack17 =[ $attack17, f_attack18] {ai_charge(10);};
-void() f_attack18 =[ $attack18, f_run1 ] {ai_charge(10);};
-
-void() f_death1 =[ $death1, f_death2 ]
- {
- self.solid = SOLID_NOT;
- sound_death (self, CHAN_VOICE, "fish/death.wav", 1, ATTN_NORM);
- };
-void() f_death2 =[ $death2, f_death3 ] {};
-void() f_death3 =[ $death3, f_death4 ] {};
-void() f_death4 =[ $death4, f_death5 ] {};
-void() f_death5 =[ $death5, f_death6 ] {};
-void() f_death6 =[ $death6, f_death7 ] {};
-void() f_death7 =[ $death7, f_death8 ] {};
-void() f_death8 =[ $death8, f_death9 ] {};
-void() f_death9 =[ $death9, f_death10 ] {};
-void() f_death10 =[ $death10, f_death11 ] {};
-void() f_death11 =[ $death11, f_death12 ] {};
-void() f_death12 =[ $death12, f_death13 ] {};
-void() f_death13 =[ $death13, f_death14 ] {};
-void() f_death14 =[ $death14, f_death15 ] {};
-void() f_death15 =[ $death15, f_death16 ] {};
-void() f_death16 =[ $death16, f_death17 ] {};
-void() f_death17 =[ $death17, f_death18 ] {};
-void() f_death18 =[ $death18, f_death19 ] {};
-void() f_death19 =[ $death19, f_death20 ] {};
-void() f_death20 =[ $death20, f_death21 ] {};
-void() f_death21 =[ $death21, f_death21 ] {};
-
-void() fish_die =
-{
- if (self.health < -35) //fish gibs -- dumptruck_ds
- {
- sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
- // ThrowGib ("progs/gib3.mdl", self.health);
- // ThrowGib ("progs/gib1.mdl", self.health);
- // ThrowGib ("progs/gib3.mdl", self.health);
- if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
- {
- ThrowGib (self.mdl_gib1, self.health);
- }
- else
- {
- ThrowGib ("progs/gib3.mdl", self.health);
- }
- if (self.mdl_gib2 != "")
- {
- ThrowGib (self.mdl_gib2, self.health);
- }
- else
- {
- ThrowGib ("progs/gib3.mdl", self.health);
- }
- if (self.mdl_gib3 != "")
- {
- ThrowGib (self.mdl_gib3, self.health);
- }
- else
- {
- ThrowGib ("progs/gib3.mdl", self.health);
- }
- if (self.mdl_head != "")
- {
- ThrowHead (self.mdl_head, self.health);
- }
- else
- {
- ThrowHead ("progs/h_dog.mdl", self.health);
- }
- base_item::drop_stuff (self);
- sub_remove();
- }
- // regular death
- else
- {
- base_item::drop_stuff (self);
- f_death1();
- }
-};
-
-void() f_pain1 =[ $pain1, f_pain2 ] {};
-void() f_pain2 =[ $pain2, f_pain3 ] {ai_pain(6);};
-void() f_pain3 =[ $pain3, f_pain4 ] {ai_pain(6);};
-void() f_pain4 =[ $pain4, f_pain5 ] {ai_pain(6);};
-void() f_pain5 =[ $pain5, f_pain6 ] {ai_pain(6);};
-void() f_pain6 =[ $pain6, f_pain7 ] {ai_pain(6);};
-void() f_pain7 =[ $pain7, f_pain8 ] {ai_pain(6);};
-void() f_pain8 =[ $pain8, f_pain9 ] {ai_pain(6);};
-void() f_pain9 =[ $pain9, f_run1 ] {ai_pain(6);};
-
-void(entity attacker, float damage) fish_pain =
-{
-// fish always do pain frames
- f_pain1 ();
-};
-
-
-
/*QUAKED monster_fish (1 0 0) (-16 -16 -24) (16 16 24) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
{
model ("progs/fish.mdl");
@@ -256,51 +78,284 @@ obit_method(string) : "When used with obit_name, will set part of the text for a
damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
*/
-void() monster_fish =
+class monster_fish: base_swimmonster
{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
+ //--------------------------------------------------------------
+ nonvirtual void() melee =
+ {
+ local vector delta;
+ local float ldmg;
+
+ if (!this.enemy)
+ // removed before stroke
+ return;
+
+ delta = this.enemy.origin - this.origin;
+
+ if (vlen(delta) > 60)
+ return;
- if (self.spawnflags & I_AM_TURRET)
- objerror("Incompatible spawnflag: TURRET_MODE\n");
+ sound_attack (this, CHAN_VOICE, "fish/bite.wav", 1, ATTN_NORM);
+ ldmg = (random() + random()) * 3;
+ T_Damage (this.enemy, this, this, ldmg);
+ };
+
+ //--------------------------------------------------------------
+ // Fish stand (resting?) functions
+ //--------------------------------------------------------------
+ nonvirtual void() stand1 = [$swim1, stand2] { ai_stand (); };
+ nonvirtual void() stand2 = [$swim2, stand3] { ai_stand (); };
+ nonvirtual void() stand3 = [$swim3, stand4] { ai_stand (); };
+ nonvirtual void() stand4 = [$swim4, stand5] { ai_stand (); };
+ nonvirtual void() stand5 = [$swim5, stand6] { ai_stand (); };
+ nonvirtual void() stand6 = [$swim6, stand7] { ai_stand (); };
+ nonvirtual void() stand7 = [$swim7, stand8] { ai_stand (); };
+ nonvirtual void() stand8 = [$swim8, stand9] { ai_stand (); };
+ nonvirtual void() stand9 = [$swim9, stand10 ] { ai_stand (); };
+ nonvirtual void() stand10 = [$swim10, stand11] { ai_stand (); };
+ nonvirtual void() stand11 = [$swim11, stand12] { ai_stand (); };
+ nonvirtual void() stand12 = [$swim12, stand13] { ai_stand (); };
+ nonvirtual void() stand13 = [$swim13, stand14] { ai_stand (); };
+ nonvirtual void() stand14 = [$swim14, stand15] { ai_stand (); };
+ nonvirtual void() stand15 = [$swim15, stand16] { ai_stand (); };
+ nonvirtual void() stand16 = [$swim16, stand17] { ai_stand (); };
+ nonvirtual void() stand17 = [$swim17, stand18] { ai_stand (); };
+ nonvirtual void() stand18 = [$swim18, stand1] { ai_stand (); };
+
+ //--------------------------------------------------------------
+ // Fish walking functions (ever seen a fish walk?)
+ //--------------------------------------------------------------
+ nonvirtual void() walk1 = [$swim1, walk2] { ai_walk (8); };
+ nonvirtual void() walk2 = [$swim2, walk3] { ai_walk (8); };
+ nonvirtual void() walk3 = [$swim3, walk4] { ai_walk (8); };
+ nonvirtual void() walk4 = [$swim4, walk5] { ai_walk (8); };
+ nonvirtual void() walk5 = [$swim5, walk6] { ai_walk (8); };
+ nonvirtual void() walk6 = [$swim6, walk7] { ai_walk (8); };
+ nonvirtual void() walk7 = [$swim7, walk8] { ai_walk (8); };
+ nonvirtual void() walk8 = [$swim8, walk9] { ai_walk (8); };
+ nonvirtual void() walk9 = [$swim9, walk10] { ai_walk (8); };
+ nonvirtual void() walk10 = [$swim10, walk11] { ai_walk (8); };
+ nonvirtual void() walk11 = [$swim11, walk12] { ai_walk (8); };
+ nonvirtual void() walk12 = [$swim12, walk13] { ai_walk (8); };
+ nonvirtual void() walk13 = [$swim13, walk14] { ai_walk (8); };
+ nonvirtual void() walk14 = [$swim14, walk15] { ai_walk (8); };
+ nonvirtual void() walk15 = [$swim15, walk16] { ai_walk (8); };
+ nonvirtual void() walk16 = [$swim16, walk17] { ai_walk (8); };
+ nonvirtual void() walk17 = [$swim17, walk18] { ai_walk (8); };
+ nonvirtual void() walk18 = [$swim18, walk1] { ai_walk (8); };
+
+ //--------------------------------------------------------------
+ // Fish run functions
+ //--------------------------------------------------------------
+ nonvirtual void() run1 = [$swim1, run2]
+ {
+ ai_run (12);
+ if (random() < 0.5)
+ sound_idle (this, CHAN_VOICE, "fish/idle.wav",
+ 1, ATTN_NORM);
+ };
+ nonvirtual void() run2 = [$swim3, run3] { ai_run (12); };
+ nonvirtual void() run3 = [$swim5, run4] { ai_run (12); };
+ nonvirtual void() run4 = [$swim7, run5] { ai_run (12); };
+ nonvirtual void() run5 = [$swim9, run6] { ai_run (12); };
+ nonvirtual void() run6 = [$swim11, run7] { ai_run (12); };
+ nonvirtual void() run7 = [$swim13, run8] { ai_run (12); };
+ nonvirtual void() run8 = [$swim15, run9] { ai_run (12); };
+ nonvirtual void() run9 = [$swim17, run1] { ai_run (12); };
+
+ //--------------------------------------------------------------
+ // Fish attack functions
+ //--------------------------------------------------------------
+ nonvirtual void() attack1 = [$attack1, attack2] { ai_charge (10); };
+ nonvirtual void() attack2 = [$attack2, attack3] { ai_charge (10); };
+ nonvirtual void() attack3 = [$attack3, attack4] { this.melee (); };
+ nonvirtual void() attack4 = [$attack4, attack5] { ai_charge (10); };
+ nonvirtual void() attack5 = [$attack5, attack6] { ai_charge (10); };
+ nonvirtual void() attack6 = [$attack6, attack7] { ai_charge (10); };
+ nonvirtual void() attack7 = [$attack7, attack8] { ai_charge (10); };
+ nonvirtual void() attack8 = [$attack8, attack9] { ai_charge (10); };
+ nonvirtual void() attack9 = [$attack9, attack10] { this.melee (); };
+ nonvirtual void() attack10 = [$attack10, attack11] { ai_charge (10); };
+ nonvirtual void() attack11 = [$attack11, attack12] { ai_charge (10); };
+ nonvirtual void() attack12 = [$attack12, attack13] { ai_charge (10); };
+ nonvirtual void() attack13 = [$attack13, attack14] { ai_charge (10); };
+ nonvirtual void() attack14 = [$attack14, attack15] { ai_charge (10); };
+ nonvirtual void() attack15 = [$attack15, attack16] { this.melee (); };
+ nonvirtual void() attack16 = [$attack16, attack17] { ai_charge (10); };
+ nonvirtual void() attack17 = [$attack17, attack18] { ai_charge (10); };
+ nonvirtual void() attack18 = [$attack18, run1] { ai_charge (10); };
+
+ //--------------------------------------------------------------
+ // Fish pain states (please don't hurt the fish)
+ //--------------------------------------------------------------
+ nonvirtual void() pain1 = [$pain1, pain2] { };
+ nonvirtual void() pain2 = [$pain2, pain3] { ai_pain (6); };
+ nonvirtual void() pain3 = [$pain3, pain4] { ai_pain (6); };
+ nonvirtual void() pain4 = [$pain4, pain5] { ai_pain (6); };
+ nonvirtual void() pain5 = [$pain5, pain6] { ai_pain (6); };
+ nonvirtual void() pain6 = [$pain6, pain7] { ai_pain (6); };
+ nonvirtual void() pain7 = [$pain7, pain8] { ai_pain (6); };
+ nonvirtual void() pain8 = [$pain8, pain9] { ai_pain (6); };
+ nonvirtual void() pain9 = [$pain9, run1] { ai_pain (6); };
+
+ //--------------------------------------------------------------
+ // Fish death states (RIP fish)
+ //--------------------------------------------------------------
+ nonvirtual void() death1 = [$death1, death2]
+ {
+ this.solid = SOLID_NOT;
+ sound_death (this, CHAN_VOICE, "fish/death.wav", 1, ATTN_NORM);
+ };
+ nonvirtual void() death2 = [$death2, death3] { };
+ nonvirtual void() death3 = [$death3, death4] { };
+ nonvirtual void() death4 = [$death4, death5] { };
+ nonvirtual void() death5 = [$death5, death6] { };
+ nonvirtual void() death6 = [$death6, death7] { };
+ nonvirtual void() death7 = [$death7, death8] { };
+ nonvirtual void() death8 = [$death8, death9] { };
+ nonvirtual void() death9 = [$death9, death10] { };
+ nonvirtual void() death10 = [$death10, death11] { };
+ nonvirtual void() death11 = [$death11, death12] { };
+ nonvirtual void() death12 = [$death12, death13] { };
+ nonvirtual void() death13 = [$death13, death14] { };
+ nonvirtual void() death14 = [$death14, death15] { };
+ nonvirtual void() death15 = [$death15, death16] { };
+ nonvirtual void() death16 = [$death16, death17] { };
+ nonvirtual void() death17 = [$death17, death18] { };
+ nonvirtual void() death18 = [$death18, death19] { };
+ nonvirtual void() death19 = [$death19, death20] { };
+ nonvirtual void() death20 = [$death20, death21] { };
+ nonvirtual void() death21 = [$death21, death21] { };
+
+ //==============================================================
+ // Interaction
+ //==============================================================
+
+ //--------------------------------------------------------------
+ // fish_pain
+ //--------------------------------------------------------------
+ virtual void(entity attacker, float damage) do_damage =
+ {
+ // fish always do pain frames
+ this.pain1 ();
+ };
- if (deathmatch)
+ //--------------------------------------------------------------
+ // fish_die
+ //--------------------------------------------------------------
+ virtual void() do_destroy =
{
- remove(self);
- return;
- }
- precache_body_model2 ("progs/fish.mdl");
- // precache_model2 ("progs/fish.mdl");
-
- precache_sound2_death ("fish/death.wav");
- precache_sound2_attack ("fish/bite.wav");
- precache_sound2_idle ("fish/idle.wav");
-
- precache_gib1 ("progs/gib1.mdl");
- precache_gib2 ("progs/gib2.mdl");
- precache_gib3 ("progs/gib3.mdl");
-
- self.solid = SOLID_SLIDEBOX;
- self.movetype = MOVETYPE_STEP;
-
- body_model ("progs/fish.mdl");
- // setmodel (self, "progs/fish.mdl");
-
- setsize (self, '-16 -16 -24', '16 16 24');
-
- if (!self.health) //thanks RennyC -- dumptruck_ds
- self.health = 25;
-
- self.th_stand = f_stand1;
- self.th_walk = f_walk1;
- self.th_run = f_run1;
- // self.th_die = f_death1;
- self.th_die = fish_die;
- if !(self.berserk) //Berserk from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
- self.th_pain = fish_pain;
- else
- self.th_pain = sub_nullpain;
- self.th_melee = f_attack1;
-
- swimmonster_start ();
+ if (this.health < -35)
+ {
+ // fish gibs -- dumptruck_ds
+ sound (this, CHAN_VOICE, "player/udeath.wav",
+ 1, ATTN_NORM);
+ // ThrowGib ("progs/gib3.mdl", this.health);
+ // ThrowGib ("progs/gib1.mdl", this.health);
+ // ThrowGib ("progs/gib3.mdl", this.health);
+ // custom models -- dumptruck_ds
+ if (this.mdl_gib1 != "")
+ {
+ ThrowGib (this.mdl_gib1, this.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib3.mdl", this.health);
+ }
+ if (this.mdl_gib2 != "")
+ {
+ ThrowGib (this.mdl_gib2, this.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib3.mdl", this.health);
+ }
+ if (this.mdl_gib3 != "")
+ {
+ ThrowGib (this.mdl_gib3, this.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib3.mdl", this.health);
+ }
+ if (this.mdl_head != "")
+ {
+ ThrowHead (this.mdl_head, this.health);
+ }
+ else
+ {
+ ThrowHead ("progs/h_dog.mdl", this.health);
+ }
+ base_item::drop_stuff (this);
+ sub_remove ();
+ }
+ // regular death
+ else
+ {
+ base_item::drop_stuff (this);
+ this.death1 ();
+ }
+ };
+
+ //==============================================================
+ // Initialization
+ //==============================================================
+
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
+ {
+ if (this.spawnflags & I_AM_TURRET)
+ objerror ("Incompatible spawnflag: TURRET_MODE\n");
+
+ if (deathmatch)
+ {
+ remove (this);
+ return;
+ }
+
+ precache_body_model2 ("progs/fish.mdl");
+ // precache_model2 ("progs/fish.mdl");
+
+ precache_sound2_death ("fish/death.wav");
+ precache_sound2_attack ("fish/bite.wav");
+ precache_sound2_idle ("fish/idle.wav");
+
+ precache_gib1 ("progs/gib1.mdl");
+ precache_gib2 ("progs/gib2.mdl");
+ precache_gib3 ("progs/gib3.mdl");
+
+ this.solid = SOLID_SLIDEBOX;
+ this.movetype = MOVETYPE_STEP;
+
+ body_model ("progs/fish.mdl");
+ // setmodel (this, "progs/fish.mdl");
+
+ setsize (this, '-16 -16 -24', '16 16 24');
+
+ if (!this.health)
+ // thanks RennyC -- dumptruck_ds
+ this.health = 25;
+
+ this.think_stand = this.stand1;
+ this.think_walk = this.walk1;
+ this.think_run = this.run1;
+ this.th_die = this.do_destroy;
+ // Berserk from
+ // http://celephais.net/board/view_thread.php?id=4&start=3465
+ // -- dumptruck_ds
+ if !(this.berserk)
+ this.th_pain = this.do_damage;
+ else
+ this.th_pain = sub_nullpain;
+ this.think_melee = this.attack1;
+
+ // swimmonster_start
+ super::init_spawned ();
+ };
+
+ //--------------------------------------------------------------
+ void() monster_fish =
+ {
+ this.classtype = CT_MONSTER_FISH;
+ };
};
Return to the top of this page or return to the overview of this repo.
Diff qc/monsters/hknight.qc
diff --git a/qc/monsters/hknight.qc b/qc/monsters/hknight.qc
index c59446f..462aa2a 100644
--- a/qc/monsters/hknight.qc
+++ b/qc/monsters/hknight.qc
@@ -1,11 +1,10 @@
-/*
-==============================================================================
-
-KNIGHT
-
-==============================================================================
-*/
+//==============================================================================
+// DEATH KNIGHT / HELL KNIGHT
+//==============================================================================
+//======================================================================
+// frame macros
+//======================================================================
$cd id1/models/knight2
$origin 0 0 24
$base base
@@ -51,514 +50,6 @@ $frame w_attack21 w_attack22
$frame magicc1 magicc2 magicc3 magicc4 magicc5 magicc6 magicc7 magicc8
$frame magicc9 magicc10 magicc11
-
-void() hknight_char_a1;
-void() hknight_run1;
-void() hk_idle_sound;
-
-void(float offset) hknight_shot =
-{
- local vector offang;
- local vector org, vec;
- local float exploding = self.projexpl == 1 || (self.projexpl == 2 && offset % 2 == 0) || (self.projexpl == 3 && random()*2 < 1);
- offang = vectoangles (self.enemy.origin - self.origin);
- offang_y = offang_y + offset * 6;
-
- makevectors (offang);
-
- org = self.origin + self.mins + self.size*0.5 + v_forward * 20;
-
-// set missile speed
- vec = normalize (v_forward);
- vec_z = 0 - vec_z + (random() - 0.5)*0.1;
-
- launch_spike2 (org, vec, 300);
- newmis.classname = "knightspike";
- // setmodel (newmis, "progs/k_spike.mdl");
- if (exploding)
- {
- newmis.touch = T_HellKnightMisTouch;
- if (self.mdl_exproj != "") // dumptruck_ds custom_mdls
- {
- setmodel (newmis, self.mdl_exproj);
- }
- else
- {
- setmodel (newmis, "progs/k_spike2.mdl");
- }
-
- if (self.skin_exproj) // dumptruck_ds
- {
- newmis.skin = self.skin_exproj;
- }
- else
- {
- newmis.skin = 0;
- }
- }
- else
- {
- if (self.mdl_proj != "") // dumptruck_ds custom_mdls
- {
- setmodel (newmis, self.mdl_proj);
- }
- else
- {
- setmodel (newmis, "progs/k_spike.mdl");
- }
-
- if (self.skin_proj) // dumptruck_ds
- {
- newmis.skin = self.skin_proj;
- }
- else
- {
- newmis.skin = 0;
- }
- }
- setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
- sound_attack (self, CHAN_WEAPON, "hknight/attack1.wav", 1, ATTN_NORM);
-};
-
-void() CheckForCharge =
-{
-// check for mad charge
-if (!enemy_vis)
- return;
-if (time < self.attack_finished)
- return;
-if ( fabs(self.origin_z - self.enemy.origin_z) > 20)
- return; // too much height change
-if ( vlen (self.origin - self.enemy.origin) < 80)
- return; // use regular attack
-
-// charge
- SUB_AttackFinished (2);
- hknight_char_a1 ();
-
-};
-
-void() CheckContinueCharge =
-{
- if (time > self.attack_finished)
- {
- SUB_AttackFinished (3);
- hknight_run1 ();
- return; // done charging
- }
- if (random() > 0.5)
- sound (self, CHAN_WEAPON, "knight/sword2.wav", 1, ATTN_NORM);
- else
- sound (self, CHAN_WEAPON, "knight/sword1.wav", 1, ATTN_NORM);
-};
-
-//===========================================================================
-
-void() hknight_stand1 =[ $stand1, hknight_stand2 ] {ai_stand();};
-void() hknight_stand2 =[ $stand2, hknight_stand3 ] {ai_stand();};
-void() hknight_stand3 =[ $stand3, hknight_stand4 ] {ai_stand();};
-void() hknight_stand4 =[ $stand4, hknight_stand5 ] {ai_stand();};
-void() hknight_stand5 =[ $stand5, hknight_stand6 ] {ai_stand();};
-void() hknight_stand6 =[ $stand6, hknight_stand7 ] {ai_stand();};
-void() hknight_stand7 =[ $stand7, hknight_stand8 ] {ai_stand();};
-void() hknight_stand8 =[ $stand8, hknight_stand9 ] {ai_stand();};
-void() hknight_stand9 =[ $stand9, hknight_stand1 ] {ai_stand();};
-
-//===========================================================================
-
-void() hknight_walk1 =[ $walk1, hknight_walk2 ] {
-hk_idle_sound();
-ai_walk(2);};
-void() hknight_walk2 =[ $walk2, hknight_walk3 ] {ai_walk(5);};
-void() hknight_walk3 =[ $walk3, hknight_walk4 ] {ai_walk(5);};
-void() hknight_walk4 =[ $walk4, hknight_walk5 ] {ai_walk(4);};
-void() hknight_walk5 =[ $walk5, hknight_walk6 ] {ai_walk(4);};
-void() hknight_walk6 =[ $walk6, hknight_walk7 ] {ai_walk(2);};
-void() hknight_walk7 =[ $walk7, hknight_walk8 ] {ai_walk(2);};
-void() hknight_walk8 =[ $walk8, hknight_walk9 ] {ai_walk(3);};
-void() hknight_walk9 =[ $walk9, hknight_walk10 ] {ai_walk(3);};
-void() hknight_walk10 =[ $walk10, hknight_walk11 ] {ai_walk(4);};
-void() hknight_walk11 =[ $walk11, hknight_walk12 ] {ai_walk(3);};
-void() hknight_walk12 =[ $walk12, hknight_walk13 ] {ai_walk(4);};
-void() hknight_walk13 =[ $walk13, hknight_walk14 ] {ai_walk(6);};
-void() hknight_walk14 =[ $walk14, hknight_walk15 ] {ai_walk(2);};
-void() hknight_walk15 =[ $walk15, hknight_walk16 ] {ai_walk(2);};
-void() hknight_walk16 =[ $walk16, hknight_walk17 ] {ai_walk(4);};
-void() hknight_walk17 =[ $walk17, hknight_walk18 ] {ai_walk(3);};
-void() hknight_walk18 =[ $walk18, hknight_walk19 ] {ai_walk(3);};
-void() hknight_walk19 =[ $walk19, hknight_walk20 ] {ai_walk(3);};
-void() hknight_walk20 =[ $walk20, hknight_walk1 ] {ai_walk(2);};
-
-//===========================================================================
-
-void() hknight_run1 =[ $run1, hknight_run2 ] {
-hk_idle_sound();
-ai_run (20); CheckForCharge (); };
-void() hknight_run2 =[ $run2, hknight_run3 ] {ai_run(25);};
-void() hknight_run3 =[ $run3, hknight_run4 ] {ai_run(18);};
-void() hknight_run4 =[ $run4, hknight_run5 ] {ai_run(16);};
-void() hknight_run5 =[ $run5, hknight_run6 ] {ai_run(14);};
-void() hknight_run6 =[ $run6, hknight_run7 ] {ai_run(25);};
-void() hknight_run7 =[ $run7, hknight_run8 ] {ai_run(21);};
-void() hknight_run8 =[ $run8, hknight_run1 ] {ai_run(13);};
-
-//============================================================================
-
-void() hknight_pain1 =[ $pain1, hknight_pain2 ] {sound_pain (self, CHAN_VOICE, "hknight/pain1.wav", 1, ATTN_NORM);};
-void() hknight_pain2 =[ $pain2, hknight_pain3 ] {};
-void() hknight_pain3 =[ $pain3, hknight_pain4 ] {};
-void() hknight_pain4 =[ $pain4, hknight_pain5 ] {};
-void() hknight_pain5 =[ $pain5, hknight_run1 ] {};
-
-//============================================================================
-
-void() hknight_die1 =[ $death1, hknight_die2 ] {ai_forward(10);};
-void() hknight_die2 =[ $death2, hknight_die3 ] {ai_forward(8);};
-void() hknight_die3 =[ $death3, hknight_die4 ]{self.solid = SOLID_NOT;ai_forward(7);};
-void() hknight_die4 =[ $death4, hknight_die5 ] {};
-void() hknight_die5 =[ $death5, hknight_die6 ] {};
-void() hknight_die6 =[ $death6, hknight_die7 ] {};
-void() hknight_die7 =[ $death7, hknight_die8 ] {};
-void() hknight_die8 =[ $death8, hknight_die9 ] {ai_forward(10);};
-void() hknight_die9 =[ $death9, hknight_die10 ] {ai_forward(11);};
-void() hknight_die10 =[ $death10, hknight_die11 ] {};
-void() hknight_die11 =[ $death11, hknight_die12 ] {};
-void() hknight_die12 =[ $death12, hknight_die12 ] {};
-
-void() hknight_dieb1 =[ $deathb1, hknight_dieb2 ] {};
-void() hknight_dieb2 =[ $deathb2, hknight_dieb3 ] {};
-void() hknight_dieb3 =[ $deathb3, hknight_dieb4 ] {self.solid = SOLID_NOT;};
-void() hknight_dieb4 =[ $deathb4, hknight_dieb5 ] {};
-void() hknight_dieb5 =[ $deathb5, hknight_dieb6 ] {};
-void() hknight_dieb6 =[ $deathb6, hknight_dieb7 ] {};
-void() hknight_dieb7 =[ $deathb7, hknight_dieb8 ] {};
-void() hknight_dieb8 =[ $deathb8, hknight_dieb9 ] {};
-void() hknight_dieb9 =[ $deathb9, hknight_dieb9 ] {};
-
-void() hknight_die =
-{
-// check for gib
- if (self.health < -40)
- {
- sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
- if (self.mdl_head != "") //dumptruck_ds custom_mdls
- {
- ThrowHead (self.mdl_head, self.health);
- }
- else
- {
- ThrowHead ("progs/h_hellkn.mdl", self.health);
- }
- // ThrowGib ("progs/gib1.mdl", self.health);
- // ThrowGib ("progs/gib2.mdl", self.health);
- // ThrowGib ("progs/gib3.mdl", self.health);
- if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
- {
- ThrowGib (self.mdl_gib1, self.health);
- }
- else
- {
- ThrowGib ("progs/gib1.mdl", self.health);
- }
- if (self.mdl_gib2 != "")
- {
- ThrowGib (self.mdl_gib2, self.health);
- }
- else
- {
- ThrowGib ("progs/gib2.mdl", self.health);
- }
- if (self.mdl_gib3 != "")
- {
- ThrowGib (self.mdl_gib3, self.health);
- }
- else
- {
- ThrowGib ("progs/gib3.mdl", self.health);
- }
- base_item::drop_stuff (self);
- return;
- }
-
-// regular death
- sound_death (self, CHAN_VOICE, "hknight/death1.wav", 1, ATTN_NORM);
- base_item::drop_stuff (self);
- if (random() > 0.5)
- hknight_die1 ();
- else
- hknight_dieb1 ();
-};
-
-
-//============================================================================
-
-void() hknight_magica1 =[ $magica1, hknight_magica2 ] {ai_face();};
-void() hknight_magica2 =[ $magica2, hknight_magica3 ] {ai_face();};
-void() hknight_magica3 =[ $magica3, hknight_magica4 ] {ai_face();};
-void() hknight_magica4 =[ $magica4, hknight_magica5 ] {ai_face();};
-void() hknight_magica5 =[ $magica5, hknight_magica6 ] {ai_face();};
-void() hknight_magica6 =[ $magica6, hknight_magica7 ] {ai_face();};
-void() hknight_magica7 =[ $magica7, hknight_magica8 ] {hknight_shot(-2);};
-void() hknight_magica8 =[ $magica8, hknight_magica9 ] {hknight_shot(-1);};
-void() hknight_magica9 =[ $magica9, hknight_magica10] {hknight_shot(0);};
-void() hknight_magica10 =[ $magica10, hknight_magica11] {hknight_shot(1);};
-void() hknight_magica11 =[ $magica11, hknight_magica12] {hknight_shot(2);};
-void() hknight_magica12 =[ $magica12, hknight_magica13] {hknight_shot(3);};
-void() hknight_magica13 =[ $magica13, hknight_magica14] {ai_face();};
-void() hknight_magica14 =[ $magica14, hknight_run1 ] {ai_face();};
-
-//============================================================================
-
-void() HellKnightLightning =
-{
- local vector org, dir;
-
- self.effects = self.effects | EF_MUZZLEFLASH;
- sound_attack(self, CHAN_WEAPON, "weapons/lstart.wav", 1, ATTN_NORM);
- ai_face ();
- makevectors (self.angles);
- org = self.origin + v_forward * 50 + '0 0 20';
-
- dir = self.enemy.origin - self.enemy.velocity * 0.075;
- dir = normalize (dir - org + '0 0 16');
-
- if (self.spawnflags & I_AM_TURRET)
- {
- traceline (org, self.origin + dir*900, TRUE, self);
- }
- else
- {
- traceline (org, self.origin + dir*600, TRUE, self);
- }
-
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_LIGHTNING1);
- WriteEntity (MSG_BROADCAST, self);
- WriteCoord (MSG_BROADCAST, org_x);
- WriteCoord (MSG_BROADCAST, org_y);
- WriteCoord (MSG_BROADCAST, org_z);
- WriteCoord (MSG_BROADCAST, trace_endpos_x);
- WriteCoord (MSG_BROADCAST, trace_endpos_y);
- WriteCoord (MSG_BROADCAST, trace_endpos_z);
-
- LightningDamage (org, trace_endpos, self, 20);
-};
-void() hknight_magicb1 =[ $magicb1, hknight_magicb2 ] {ai_face();};
-void() hknight_magicb2 =[ $magicb2, hknight_magicb3 ] {ai_face();};
-void() hknight_magicb3 =[ $magicb3, hknight_magicb4 ] {ai_face();};
-void() hknight_magicb4 =[ $magicb4, hknight_magicb5 ] {ai_face();};
-void() hknight_magicb5 =[ $magicb5, hknight_magicb6 ] {ai_face();};
-void() hknight_magicb6 =[ $magicb6, hknight_magicb7 ] {ai_face();};
-void() hknight_magicb7 =[ $magicb7, hknight_magicb8 ] {ai_face();};
-void() hknight_magicb8 =[ $magicb8, hknight_magicb9 ] {ai_face();};
-void() hknight_magicb9 =[ $magicb9, hknight_magicb10] {ai_face();};
-void() hknight_magicb10 =[ $magicb10, hknight_magicb11] {ai_face();sound_misc2 (self, CHAN_WEAPON, "shambler/sboom.wav", 1, ATTN_NORM);HellKnightLightning();};
-void() hknight_magicb11 =[ $magicb11, hknight_magicb12] {ai_face();};
-void() hknight_magicb12 =[ $magicb12, hknight_magicb13] {ai_face();};
-void() hknight_magicb13 =[ $magicb13, hknight_run1] {ai_face();};
-
-//============================================================================
-
-void() hknight_magicc1 =[ $magicc1, hknight_magicc2 ] {ai_face();};
-void() hknight_magicc2 =[ $magicc2, hknight_magicc3 ] {ai_face();};
-void() hknight_magicc3 =[ $magicc3, hknight_magicc4 ] {ai_face();};
-void() hknight_magicc4 =[ $magicc4, hknight_magicc5 ] {ai_face();};
-void() hknight_magicc5 =[ $magicc5, hknight_magicc6 ] {ai_face();};
-void() hknight_magicc6 =[ $magicc6, hknight_magicc7 ] {hknight_shot(-2);};
-void() hknight_magicc7 =[ $magicc7, hknight_magicc8 ] {hknight_shot(-1);};
-void() hknight_magicc8 =[ $magicc8, hknight_magicc9 ] {hknight_shot(0);};
-void() hknight_magicc9 =[ $magicc9, hknight_magicc10] {hknight_shot(1);};
-void() hknight_magicc10 =[ $magicc10, hknight_magicc11] {hknight_shot(2);};
-void() hknight_magicc11 =[ $magicc11, hknight_run1] {hknight_shot(3);};
-
-//============================================================================
-///////////////////////////////////////
-////// turret frames START - revisions
-//////////////////////////////////////
-void() hknight_turret_magicc1 =[ $magicc1, hknight_turret_magicc2 ] {ai_face();};
-void() hknight_turret_magicc2 =[ $magicc2, hknight_turret_magicc3 ] {ai_face();};
-void() hknight_turret_magicc3 =[ $magicc3, hknight_turret_magicc4 ] {ai_face();};
-void() hknight_turret_magicc4 =[ $magicc4, hknight_turret_magicc5 ] {ai_face();};
-void() hknight_turret_magicc5 =[ $magicc5, hknight_turret_magicc6 ] {ai_face();};
-void() hknight_turret_magicc6 =[ $magicc6, hknight_turret_magicc7 ] {hknight_shot(-2);};
-void() hknight_turret_magicc7 =[ $magicc7, hknight_turret_magicc8 ] {hknight_shot(-1);};
-void() hknight_turret_magicc8 =[ $magicc8, hknight_turret_magicc9 ] {hknight_shot(0);};
-void() hknight_turret_magicc9 =[ $magicc9, hknight_turret_magicc10] {hknight_shot(1);};
-void() hknight_turret_magicc10 =[ $magicc10, hknight_turret_magicc11] {hknight_shot(2);};
-void() hknight_turret_magicc11 =[ $magicc11, hknight_turret_magicc12] {ai_face();};
-void() hknight_turret_magicc12 =[ $stand1, hknight_turret_magicc13 ] {ai_face();};
-void() hknight_turret_magicc13 =[ $stand2, hknight_turret_magicc14 ] {ai_face();};
-void() hknight_turret_magicc14 =[ $stand3, hknight_turret_magicc15 ] {ai_face();};
-void() hknight_turret_magicc15 =[ $stand4, hknight_seek_stand1 ] {ai_run(0);};
-void() hknight_seek_stand1 =[ $stand1, hknight_seek_stand2 ] {ai_run(0);};
-void() hknight_seek_stand2 =[ $stand2, hknight_seek_stand3 ] {ai_run(0);};
-void() hknight_seek_stand3 =[ $stand3, hknight_seek_stand4 ] {ai_run(0);};
-void() hknight_seek_stand4 =[ $stand4, hknight_seek_stand5 ] {ai_run(0);};
-void() hknight_seek_stand5 =[ $stand5, hknight_seek_stand6 ] {ai_run(0);};
-void() hknight_seek_stand6 =[ $stand6, hknight_seek_stand7 ] {ai_run(0);};
-void() hknight_seek_stand7 =[ $stand7, hknight_seek_stand8 ] {ai_run(0);};
-void() hknight_seek_stand8 =[ $stand8, hknight_seek_stand9 ] {ai_run(0);};
-void() hknight_seek_stand9 =[ $stand9, hknight_seek_stand1 ] {ai_run(0);};
-
-void() hknight_turret_magicb1 =[ $magicb1, hknight_turret_magicb2 ] {ai_face();};
-void() hknight_turret_magicb2 =[ $magicb2, hknight_turret_magicb3 ] {ai_face();};
-void() hknight_turret_magicb3 =[ $magicb3, hknight_turret_magicb4 ] {ai_face();};
-void() hknight_turret_magicb4 =[ $magicb4, hknight_turret_magicb5 ] {ai_face();};
-void() hknight_turret_magicb5 =[ $magicb5, hknight_turret_magicb6 ] {ai_face();};
-void() hknight_turret_magicb6 =[ $magicb6, hknight_turret_magicb7 ] {ai_face();};
-void() hknight_turret_magicb7 =[ $magicb7, hknight_turret_magicb8 ] {ai_face();};
-void() hknight_turret_magicb8 =[ $magicb8, hknight_turret_magicb9 ] {ai_face();};
-void() hknight_turret_magicb9 =[ $magicb9, hknight_turret_magicb10] {ai_face();};
-void() hknight_turret_magicb10 =[ $magicb10, hknight_turret_magicb11] {ai_face();sound_misc2 (self, CHAN_WEAPON, "shambler/sboom.wav", 1, ATTN_NORM);HellKnightLightning();};
-void() hknight_turret_magicb11 =[ $magicb11, hknight_turret_magicb12] {ai_face();};
-void() hknight_turret_magicb12 =[ $magicb12, hknight_turret_magicb13] {ai_face();};
-void() hknight_turret_magicb13 =[ $magicb13, hknight_seek_stand1] {ai_face();};
-/////////////////////////
-////// turret frames END
-/////////////////////////
-
-//===========================================================================
-
-void() hknight_char_a1 =[ $char_a1, hknight_char_a2 ] {ai_charge(20);};
-void() hknight_char_a2 =[ $char_a2, hknight_char_a3 ] {ai_charge(25);};
-void() hknight_char_a3 =[ $char_a3, hknight_char_a4 ] {ai_charge(18);};
-void() hknight_char_a4 =[ $char_a4, hknight_char_a5 ] {ai_charge(16);};
-void() hknight_char_a5 =[ $char_a5, hknight_char_a6 ] {ai_charge(14);};
-void() hknight_char_a6 =[ $char_a6, hknight_char_a7 ] {ai_charge(20); ai_melee();};
-void() hknight_char_a7 =[ $char_a7, hknight_char_a8 ] {ai_charge(21); ai_melee();};
-void() hknight_char_a8 =[ $char_a8, hknight_char_a9 ] {ai_charge(13); ai_melee();};
-void() hknight_char_a9 =[ $char_a9, hknight_char_a10 ] {ai_charge(20); ai_melee();};
-void() hknight_char_a10=[ $char_a10, hknight_char_a11 ] {ai_charge(20); ai_melee();};
-void() hknight_char_a11=[ $char_a11, hknight_char_a12 ] {ai_charge(18); ai_melee();};
-void() hknight_char_a12=[ $char_a12, hknight_char_a13 ] {ai_charge(16);};
-void() hknight_char_a13=[ $char_a13, hknight_char_a14 ] {ai_charge(14);};
-void() hknight_char_a14=[ $char_a14, hknight_char_a15 ] {ai_charge(25);};
-void() hknight_char_a15=[ $char_a15, hknight_char_a16 ] {ai_charge(21);};
-void() hknight_char_a16=[ $char_a16, hknight_run1 ] {ai_charge(13);};
-
-//===========================================================================
-
-void() hknight_char_b1 =[ $char_b1, hknight_char_b2 ]
-{CheckContinueCharge (); ai_charge(23); ai_melee();};
-void() hknight_char_b2 =[ $char_b2, hknight_char_b3 ] {ai_charge(17); ai_melee();};
-void() hknight_char_b3 =[ $char_b3, hknight_char_b4 ] {ai_charge(12); ai_melee();};
-void() hknight_char_b4 =[ $char_b4, hknight_char_b5 ] {ai_charge(22); ai_melee();};
-void() hknight_char_b5 =[ $char_b5, hknight_char_b6 ] {ai_charge(18); ai_melee();};
-void() hknight_char_b6 =[ $char_b6, hknight_char_b1 ] {ai_charge(8); ai_melee();};
-
-//===========================================================================
-
-void() hknight_slice1 =[ $slice1, hknight_slice2 ] {ai_charge(9);};
-void() hknight_slice2 =[ $slice2, hknight_slice3 ] {ai_charge(6);};
-void() hknight_slice3 =[ $slice3, hknight_slice4 ] {ai_charge(13);};
-void() hknight_slice4 =[ $slice4, hknight_slice5 ] {ai_charge(4);};
-void() hknight_slice5 =[ $slice5, hknight_slice6 ] {ai_charge(7); ai_melee();};
-void() hknight_slice6 =[ $slice6, hknight_slice7 ] {ai_charge(15); ai_melee();};
-void() hknight_slice7 =[ $slice7, hknight_slice8 ] {ai_charge(8); ai_melee();};
-void() hknight_slice8 =[ $slice8, hknight_slice9 ] {ai_charge(2); ai_melee();};
-void() hknight_slice9 =[ $slice9, hknight_slice10 ] {ai_melee();};
-void() hknight_slice10 =[ $slice10, hknight_run1 ] {ai_charge(3);};
-
-//===========================================================================
-
-void() hknight_smash1 =[ $smash1, hknight_smash2 ] {ai_charge(1);};
-void() hknight_smash2 =[ $smash2, hknight_smash3 ] {ai_charge(13);};
-void() hknight_smash3 =[ $smash3, hknight_smash4 ] {ai_charge(9);};
-void() hknight_smash4 =[ $smash4, hknight_smash5 ] {ai_charge(11);};
-void() hknight_smash5 =[ $smash5, hknight_smash6 ] {ai_charge(10); ai_melee();};
-void() hknight_smash6 =[ $smash6, hknight_smash7 ] {ai_charge(7); ai_melee();};
-void() hknight_smash7 =[ $smash7, hknight_smash8 ] {ai_charge(12); ai_melee();};
-void() hknight_smash8 =[ $smash8, hknight_smash9 ] {ai_charge(2); ai_melee();};
-void() hknight_smash9 =[ $smash9, hknight_smash10 ] {ai_charge(3); ai_melee();};
-void() hknight_smash10 =[ $smash10, hknight_smash11 ] {ai_charge(0);};
-void() hknight_smash11 =[ $smash11, hknight_run1 ] {ai_charge(0);};
-
-//============================================================================
-
-void() hknight_watk1 =[ $w_attack1, hknight_watk2 ] {ai_charge(2);};
-void() hknight_watk2 =[ $w_attack2, hknight_watk3 ] {ai_charge(0);};
-void() hknight_watk3 =[ $w_attack3, hknight_watk4 ] {ai_charge(0);};
-void() hknight_watk4 =[ $w_attack4, hknight_watk5 ] {ai_melee();};
-void() hknight_watk5 =[ $w_attack5, hknight_watk6 ] {ai_melee();};
-void() hknight_watk6 =[ $w_attack6, hknight_watk7 ] {ai_melee();};
-void() hknight_watk7 =[ $w_attack7, hknight_watk8 ] {ai_charge(1);};
-void() hknight_watk8 =[ $w_attack8, hknight_watk9 ] {ai_charge(4);};
-void() hknight_watk9 =[ $w_attack9, hknight_watk10 ] {ai_charge(5);};
-void() hknight_watk10 =[ $w_attack10, hknight_watk11 ] {ai_charge(3); ai_melee();};
-void() hknight_watk11 =[ $w_attack11, hknight_watk12 ] {ai_charge(2); ai_melee();};
-void() hknight_watk12 =[ $w_attack12, hknight_watk13 ] {ai_charge(2); ai_melee();};
-void() hknight_watk13 =[ $w_attack13, hknight_watk14 ] {ai_charge(0);};
-void() hknight_watk14 =[ $w_attack14, hknight_watk15 ] {ai_charge(0);};
-void() hknight_watk15 =[ $w_attack15, hknight_watk16 ] {ai_charge(0);};
-void() hknight_watk16 =[ $w_attack16, hknight_watk17 ] {ai_charge(1);};
-void() hknight_watk17 =[ $w_attack17, hknight_watk18 ] {ai_charge(1); ai_melee();};
-void() hknight_watk18 =[ $w_attack18, hknight_watk19 ] {ai_charge(3); ai_melee();};
-void() hknight_watk19 =[ $w_attack19, hknight_watk20 ] {ai_charge(4); ai_melee();};
-void() hknight_watk20 =[ $w_attack20, hknight_watk21 ] {ai_charge(6);};
-void() hknight_watk21 =[ $w_attack21, hknight_watk22 ] {ai_charge(7);};
-void() hknight_watk22 =[ $w_attack22, hknight_run1 ] {ai_charge(3);};
-
-//============================================================================
-
-void() hk_idle_sound =
-{
- if (random() < 0.2)
- sound_idle (self, CHAN_VOICE, "hknight/idle.wav", 1, ATTN_NORM);
-};
-
-void(entity attacker, float damage) hknight_pain =
-{
- local float r;
-
- r = random();
-
- if (self.pain_finished > time)
- return;
-
- if (self.spawnflags & I_AM_TURRET)
- {
- if (r < 0.5)
- {
- self.pain_finished = time + 1.5;
- sound_pain (self, CHAN_VOICE, "hknight/pain1.wav", 1, ATTN_NORM);
- }
- return;
- }
-
- sound_pain (self, CHAN_VOICE, "hknight/pain1.wav", 1, ATTN_NORM);
-
- if (time - self.pain_finished > 5)
- { // always go into pain frame if it has been a while
- hknight_pain1 ();
- self.pain_finished = time + 1;
- return;
- }
-
- if ((random()*30 > damage) )
- return; // didn't flinch
-
- self.pain_finished = time + 1;
- hknight_pain1 ();
-};
-
-float hknight_type;
-
-void() hknight_melee =
-{
- hknight_type = hknight_type + 1;
-
- sound_misc (self, CHAN_WEAPON, "hknight/slash1.wav", 1, ATTN_NORM);
- if (hknight_type == 1)
- hknight_slice1 ();
- else if (hknight_type == 2)
- hknight_smash1 ();
- else if (hknight_type == 3)
- {
- hknight_watk1 ();
- hknight_type = 0;
- }
-};
-
/*QUAKED monster_hell_knight (1 0 0) (-16 -16 -24) (16 16 40) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
{
model ("progs/hknight.mdl");
@@ -627,88 +118,820 @@ obit_method(string) : "When used with obit_name, will set part of the text for a
damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
*/
-void() monster_hell_knight =
+class monster_hell_knight: base_walkmonster
{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
+ float hknight_type; // this used to be a global -- CEV
- if (deathmatch)
+ //--------------------------------------------------------------
+ virtual void() ai_sightsound =
{
- remove(self);
- return;
- }
+ sound_sight (this, CHAN_VOICE, "hknight/sight1.wav",
+ 1, ATTN_NORM);
+ };
+
+ //--------------------------------------------------------------
+ // CheckForCharge
+ //--------------------------------------------------------------
+ nonvirtual void() check_for_charge =
+ {
+ // check for mad charge
+ if (!enemy_vis)
+ return;
+ if (time < this.attack_finished)
+ return;
+ if (fabs(this.origin_z - this.enemy.origin_z) > 20)
+ // too much height change
+ return;
+ if (vlen(this.origin - this.enemy.origin) < 80)
+ // use regular attack
+ return;
- precache_model2 ("progs/hknight.mdl");
- precache_model2 ("progs/k_spike.mdl");
- precache_model2 ("progs/k_spike2.mdl");
- precache_model2 ("progs/h_hellkn.mdl");
- //dumptruck_ds custom_mdls
- precache_body_model2 ("progs/hknight.mdl");
- precache_head_model2 ("progs/h_hellkn.mdl");
- precache_proj_model2 ("progs/k_spike.mdl");
- precache_exproj_model2 ("progs/k_spike2.mdl"); // this needed a unique name defiined in custom_mdls.qc -- dumptruck_ds
-// dumptruck_ds
+ // charge
+ sub_attackfinished (2);
+ this.char_a1 ();
+ };
- precache_sound2_attack ("hknight/attack1.wav");
- precache_sound2_death ("hknight/death1.wav");
- precache_sound2_pain ("hknight/pain1.wav");
- precache_sound2_sight ("hknight/sight1.wav");
- precache_sound ("hknight/hit.wav"); // used by C code, so don't sound2
- precache_sound2_misc ("hknight/slash1.wav");
- precache_sound2_idle ("hknight/idle.wav");
- precache_sound2 ("hknight/grunt.wav"); // what??? never knew about this! -- dumptruck_ds
+ //--------------------------------------------------------------
+ // CheckContinueCharge
+ //--------------------------------------------------------------
+ nonvirtual void() check_continue_charge =
+ {
+ if (time > this.attack_finished)
+ {
+ sub_attackfinished (3);
+ this.run1 ();
+ // done charging
+ return;
+ }
- precache_sound ("knight/sword1.wav");
- precache_sound ("knight/sword2.wav");
+ if (random() > 0.5)
+ sound (this, CHAN_WEAPON, "knight/sword2.wav",
+ 1, ATTN_NORM);
+ else
+ sound (this, CHAN_WEAPON, "knight/sword1.wav",
+ 1, ATTN_NORM);
+ };
+
+ //--------------------------------------------------------------
+ // HellKnightLightning
+ //--------------------------------------------------------------
+ nonvirtual void() attack_lightning =
+ {
+ local vector org, dir;
- precache_gib1 ("progs/gib1.mdl");
- precache_gib2 ("progs/gib2.mdl");
- precache_gib3 ("progs/gib3.mdl");
+ this.effects = this.effects | EF_MUZZLEFLASH;
+ sound_attack(this, CHAN_WEAPON, "weapons/lstart.wav",
+ 1, ATTN_NORM);
+ ai_face ();
+ makevectors (this.angles);
+ org = this.origin + v_forward * 50 + '0 0 20';
- self.solid = SOLID_SLIDEBOX;
- self.movetype = MOVETYPE_STEP;
+ dir = this.enemy.origin - this.enemy.velocity * 0.075;
+ dir = normalize (dir - org + '0 0 16');
- body_model ("progs/hknight.mdl"); // custom_mdls dumptruck_ds
- // setmodel (self, "progs/hknight.mdl");
+ if (this.spawnflags & I_AM_TURRET)
+ {
+ traceline (org, this.origin + dir * 900, TRUE, this);
+ }
+ else
+ {
+ traceline (org, this.origin + dir * 600, TRUE, this);
+ }
- setsize (self, '-16 -16 -24', '16 16 40');
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_LIGHTNING1);
+ WriteEntity (MSG_BROADCAST, this);
+ WriteCoord (MSG_BROADCAST, org_x);
+ WriteCoord (MSG_BROADCAST, org_y);
+ WriteCoord (MSG_BROADCAST, org_z);
+ WriteCoord (MSG_BROADCAST, trace_endpos_x);
+ WriteCoord (MSG_BROADCAST, trace_endpos_y);
+ WriteCoord (MSG_BROADCAST, trace_endpos_z);
+
+ LightningDamage (org, trace_endpos, this, 20);
+ };
+
+ //--------------------------------------------------------------
+ // hknight_melee
+ //--------------------------------------------------------------
+ nonvirtual void() attack_melee =
+ {
+ this.hknight_type = this.hknight_type + 1;
- if (!self.health) //thanks RennyC -- dumptruck_ds
- self.health = 250;
+ sound_misc (this, CHAN_WEAPON, "hknight/slash1.wav",
+ 1, ATTN_NORM);
+ if (this.hknight_type == 1)
+ {
+ this.slice1 ();
+ }
+ else if (this.hknight_type == 2)
+ {
+ this.smash1 ();
+ }
+ else if (this.hknight_type == 3)
+ {
+ this.watk1 ();
+ this.hknight_type = 0;
+ }
+ };
- if (!self.proj_speed_mod)
+ //--------------------------------------------------------------
+ // hknight_shot
+ //--------------------------------------------------------------
+ nonvirtual void(float offset) attack_shot =
{
- self.proj_speed_mod = 1;
- }
+ local vector offang, org, vec;
+
+ local float exploding = this.projexpl == 1 ||
+ (this.projexpl == 2 && offset % 2 == 0) ||
+ (this.projexpl == 3 && random()*2 < 1);
+
+ offang = vectoangles (this.enemy.origin - this.origin);
+ offang_y = offang_y + offset * 6;
+
+ makevectors (offang);
+
+ org = this.origin + this.mins + this.size * 0.5 +
+ v_forward * 20;
+
+ // set missile speed
+ vec = normalize (v_forward);
+ vec_z = 0 - vec_z + (random() - 0.5) * 0.1;
- self.th_stand = hknight_stand1;
- self.th_walk = hknight_walk1;
- if (self.spawnflags & I_AM_TURRET)
+ launch_spike2 (org, vec, 300);
+ newmis.classname = "knightspike";
+ // setmodel (newmis, "progs/k_spike.mdl");
+ if (exploding)
+ {
+ // TODO CEV
+ newmis.touch = T_HellKnightMisTouch;
+ // dumptruck_ds custom_mdls
+ if (this.mdl_exproj != "")
+ setmodel (newmis, this.mdl_exproj);
+ else
+ setmodel (newmis, "progs/k_spike2.mdl");
+
+ // dumptruck_ds
+ if (this.skin_exproj)
+ newmis.skin = this.skin_exproj;
+ else
+ newmis.skin = 0;
+ }
+ else
+ {
+ // dumptruck_ds custom_mdls
+ if (this.mdl_proj != "")
+ setmodel (newmis, this.mdl_proj);
+ else
+ setmodel (newmis, "progs/k_spike.mdl");
+
+ // dumptruck_ds
+ if (this.skin_proj)
+ newmis.skin = this.skin_proj;
+ else
+ newmis.skin = 0;
+ }
+
+ setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
+ sound_attack (this, CHAN_WEAPON, "hknight/attack1.wav",
+ 1, ATTN_NORM);
+ };
+
+ //--------------------------------------------------------------
+ // hk_idle_sound
+ //--------------------------------------------------------------
+ nonvirtual void() idle_sound =
{
- self.th_run = hknight_seek_stand1;
- }
- else
+ if (random() < 0.2)
+ sound_idle (this, CHAN_VOICE, "hknight/idle.wav",
+ 1, ATTN_NORM);
+ };
+
+ //--------------------------------------------------------------
+ // Death Knight Standing functions
+ //--------------------------------------------------------------
+ nonvirtual void() stand1 = [$stand1, stand2] { ai_stand (); };
+ nonvirtual void() stand2 = [$stand2, stand3] { ai_stand (); };
+ nonvirtual void() stand3 = [$stand3, stand4] { ai_stand (); };
+ nonvirtual void() stand4 = [$stand4, stand5] { ai_stand (); };
+ nonvirtual void() stand5 = [$stand5, stand6] { ai_stand (); };
+ nonvirtual void() stand6 = [$stand6, stand7] { ai_stand (); };
+ nonvirtual void() stand7 = [$stand7, stand8] { ai_stand (); };
+ nonvirtual void() stand8 = [$stand8, stand9] { ai_stand (); };
+ nonvirtual void() stand9 = [$stand9, stand1] { ai_stand (); };
+
+ //--------------------------------------------------------------
+ // Death Knight Walking functions
+ //--------------------------------------------------------------
+ nonvirtual void() walk1 = [$walk1, walk2]
{
- self.th_run = hknight_run1;
- }
- self.th_melee = hknight_melee;
- if (self.style == 1)
+ this.idle_sound ();
+ ai_walk (2);
+ };
+ nonvirtual void() walk2 = [$walk2, walk3] { ai_walk (5); };
+ nonvirtual void() walk3 = [$walk3, walk4] { ai_walk (5); };
+ nonvirtual void() walk4 = [$walk4, walk5] { ai_walk (4); };
+ nonvirtual void() walk5 = [$walk5, walk6] { ai_walk (4); };
+ nonvirtual void() walk6 = [$walk6, walk7] { ai_walk (2); };
+ nonvirtual void() walk7 = [$walk7, walk8] { ai_walk (2); };
+ nonvirtual void() walk8 = [$walk8, walk9] { ai_walk (3); };
+ nonvirtual void() walk9 = [$walk9, walk10] { ai_walk (3); };
+ nonvirtual void() walk10 = [$walk10, walk11] { ai_walk (4); };
+ nonvirtual void() walk11 = [$walk11, walk12] { ai_walk (3); };
+ nonvirtual void() walk12 = [$walk12, walk13] { ai_walk (4); };
+ nonvirtual void() walk13 = [$walk13, walk14] { ai_walk (6); };
+ nonvirtual void() walk14 = [$walk14, walk15] { ai_walk (2); };
+ nonvirtual void() walk15 = [$walk15, walk16] { ai_walk (2); };
+ nonvirtual void() walk16 = [$walk16, walk17] { ai_walk (4); };
+ nonvirtual void() walk17 = [$walk17, walk18] { ai_walk (3); };
+ nonvirtual void() walk18 = [$walk18, walk19] { ai_walk (3); };
+ nonvirtual void() walk19 = [$walk19, walk20] { ai_walk (3); };
+ nonvirtual void() walk20 = [$walk20, walk1] { ai_walk (2); };
+
+ //--------------------------------------------------------------
+ // Death Knight Running functions
+ //--------------------------------------------------------------
+ nonvirtual void() run1 = [$run1, run2]
{
- self.th_missile = hknight_magicb1;
- self.th_turret = hknight_turret_magicb1;
- }
- else
+ this.idle_sound ();
+ ai_run (20);
+ this.check_for_charge ();
+ };
+ nonvirtual void() run2 = [$run2, run3] { ai_run (25); };
+ nonvirtual void() run3 = [$run3, run4] { ai_run (18); };
+ nonvirtual void() run4 = [$run4, run5] { ai_run (16); };
+ nonvirtual void() run5 = [$run5, run6] { ai_run (14); };
+ nonvirtual void() run6 = [$run6, run7] { ai_run (25); };
+ nonvirtual void() run7 = [$run7, run8] { ai_run (21); };
+ nonvirtual void() run8 = [$run8, run1] { ai_run (13); };
+
+ //--------------------------------------------------------------
+ // Death Knight Charge A
+ //--------------------------------------------------------------
+ nonvirtual void() char_a1 = [$char_a1, char_a2] { ai_charge (20); };
+ nonvirtual void() char_a2 = [$char_a2, char_a3] { ai_charge (25); };
+ nonvirtual void() char_a3 = [$char_a3, char_a4] { ai_charge (18); };
+ nonvirtual void() char_a4 = [$char_a4, char_a5] { ai_charge (16); };
+ nonvirtual void() char_a5 = [$char_a5, char_a6] { ai_charge (14); };
+ nonvirtual void() char_a6 = [$char_a6, char_a7]
{
- self.th_missile = hknight_magicc1;
- self.th_turret = hknight_turret_magicc1;
- }
- if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
- self.th_pain = hknight_pain;
- else
- self.th_pain = sub_nullpain;
- self.th_die = hknight_die;
+ ai_charge (20);
+ ai_melee ();
+ };
+ nonvirtual void() char_a7 = [$char_a7, char_a8]
+ {
+ ai_charge (21);
+ ai_melee ();
+ };
+ nonvirtual void() char_a8 = [$char_a8, char_a9]
+ {
+ ai_charge (13);
+ ai_melee ();
+ };
+ nonvirtual void() char_a9 = [$char_a9, char_a10]
+ {
+ ai_charge (20);
+ ai_melee ();
+ };
+ nonvirtual void() char_a10 = [$char_a10, char_a11]
+ {
+ ai_charge (20);
+ ai_melee ();
+ };
+ nonvirtual void() char_a11 = [$char_a11, char_a12]
+ {
+ ai_charge (18);
+ ai_melee ();
+ };
+ nonvirtual void() char_a12 = [$char_a12, char_a13] { ai_charge (16); };
+ nonvirtual void() char_a13 = [$char_a13, char_a14] { ai_charge (14); };
+ nonvirtual void() char_a14 = [$char_a14, char_a15] { ai_charge (25); };
+ nonvirtual void() char_a15 = [$char_a15, char_a16] { ai_charge (21); };
+ nonvirtual void() char_a16 = [$char_a16, run1] { ai_charge (13); };
+
+ //--------------------------------------------------------------
+ // Death Knight Charge B
+ //--------------------------------------------------------------
+ nonvirtual void() char_b1 = [$char_b1, char_b2]
+ {
+ this.check_continue_charge ();
+ ai_charge (23);
+ ai_melee ();
+ };
+ nonvirtual void() char_b2 = [$char_b2, char_b3]
+ {
+ ai_charge (17);
+ ai_melee ();
+ };
+ nonvirtual void() char_b3 = [$char_b3, char_b4]
+ {
+ ai_charge (12);
+ ai_melee ();
+ };
+ nonvirtual void() char_b4 = [$char_b4, char_b5]
+ {
+ ai_charge (22);
+ ai_melee ();
+ };
+ nonvirtual void() char_b5 = [$char_b5, char_b6]
+ {
+ ai_charge (18);
+ ai_melee ();
+ };
+ nonvirtual void() char_b6 = [$char_b6, char_b1]
+ {
+ ai_charge (8);
+ ai_melee ();
+ };
+
+ //--------------------------------------------------------------
+ // Death Knight Slice Attack
+ //--------------------------------------------------------------
+ nonvirtual void() slice1 = [$slice1, slice2] { ai_charge (9); };
+ nonvirtual void() slice2 = [$slice2, slice3] { ai_charge (6); };
+ nonvirtual void() slice3 = [$slice3, slice4] { ai_charge (13); };
+ nonvirtual void() slice4 = [$slice4, slice5] { ai_charge (4); };
+ nonvirtual void() slice5 = [$slice5, slice6]
+ {
+ ai_charge (7);
+ ai_melee ();
+ };
+ nonvirtual void() slice6 = [$slice6, slice7]
+ {
+ ai_charge (15);
+ ai_melee ();
+ };
+ nonvirtual void() slice7 = [$slice7, slice8]
+ {
+ ai_charge (8);
+ ai_melee ();
+ };
+ nonvirtual void() slice8 = [$slice8, slice9]
+ {
+ ai_charge (2);
+ ai_melee ();
+ };
+ nonvirtual void() slice9 = [$slice9, slice10] { ai_melee (); };
+ nonvirtual void() slice10 = [$slice10, run1] { ai_charge (3); };
+
+ //--------------------------------------------------------------
+ // Death Knight Smash Attack
+ //--------------------------------------------------------------
+ nonvirtual void() smash1 = [$smash1, smash2] { ai_charge (1); };
+ nonvirtual void() smash2 = [$smash2, smash3] { ai_charge (13); };
+ nonvirtual void() smash3 = [$smash3, smash4] { ai_charge (9); };
+ nonvirtual void() smash4 = [$smash4, smash5] { ai_charge (11); };
+ nonvirtual void() smash5 = [$smash5, smash6]
+ {
+ ai_charge (10);
+ ai_melee ();
+ };
+ nonvirtual void() smash6 = [$smash6, smash7]
+ {
+ ai_charge (7);
+ ai_melee ();
+ };
+ nonvirtual void() smash7 = [$smash7, smash8]
+ {
+ ai_charge (12);
+ ai_melee ();
+ };
+ nonvirtual void() smash8 = [$smash8, smash9]
+ {
+ ai_charge (2);
+ ai_melee ();
+ };
+ nonvirtual void() smash9 = [$smash9, smash10]
+ {
+ ai_charge (3);
+ ai_melee ();
+ };
+ nonvirtual void() smash10 = [$smash10, smash11] { ai_charge (0); };
+ nonvirtual void() smash11 = [$smash11, run1] { ai_charge (0); };
+
+ //--------------------------------------------------------------
+ // Death Knight W (?) Attack
+ //--------------------------------------------------------------
+ nonvirtual void() watk1 = [$w_attack1, watk2] { ai_charge (2); };
+ nonvirtual void() watk2 = [$w_attack2, watk3] { ai_charge (0); };
+ nonvirtual void() watk3 = [$w_attack3, watk4] { ai_charge (0); };
+ nonvirtual void() watk4 = [$w_attack4, watk5] { ai_melee (); };
+ nonvirtual void() watk5 = [$w_attack5, watk6] { ai_melee (); };
+ nonvirtual void() watk6 = [$w_attack6, watk7] { ai_melee (); };
+ nonvirtual void() watk7 = [$w_attack7, watk8] { ai_charge (1); };
+ nonvirtual void() watk8 = [$w_attack8, watk9] { ai_charge (4); };
+ nonvirtual void() watk9 = [$w_attack9, watk10] { ai_charge (5); };
+ nonvirtual void() watk10 = [$w_attack10, watk11]
+ {
+ ai_charge (3);
+ ai_melee ();
+ };
+ nonvirtual void() watk11 = [$w_attack11, watk12]
+ {
+ ai_charge (2);
+ ai_melee ();
+ };
+ nonvirtual void() watk12 = [$w_attack12, watk13]
+ {
+ ai_charge (2);
+ ai_melee ();
+ };
+ nonvirtual void() watk13 = [$w_attack13, watk14] { ai_charge (0); };
+ nonvirtual void() watk14 = [$w_attack14, watk15] { ai_charge (0); };
+ nonvirtual void() watk15 = [$w_attack15, watk16] { ai_charge (0); };
+ nonvirtual void() watk16 = [$w_attack16, watk17] { ai_charge (1); };
+ nonvirtual void() watk17 = [$w_attack17, watk18]
+ {
+ ai_charge (1);
+ ai_melee ();
+ };
+ nonvirtual void() watk18 = [$w_attack18, watk19]
+ {
+ ai_charge (3);
+ ai_melee ();
+ };
+ nonvirtual void() watk19 = [$w_attack19, watk20]
+ {
+ ai_charge (4);
+ ai_melee ();
+ };
+ nonvirtual void() watk20 = [$w_attack20, watk21] { ai_charge (6); };
+ nonvirtual void() watk21 = [$w_attack21, watk22] { ai_charge (7); };
+ nonvirtual void() watk22 = [$w_attack22, run1] { ai_charge (3); };
+
+ //--------------------------------------------------------------
+ // Death Knight Magic A
+ //--------------------------------------------------------------
+ nonvirtual void() magica1 = [$magica1, magica2] { ai_face (); };
+ nonvirtual void() magica2 = [$magica2, magica3] { ai_face (); };
+ nonvirtual void() magica3 = [$magica3, magica4] { ai_face (); };
+ nonvirtual void() magica4 = [$magica4, magica5] { ai_face (); };
+ nonvirtual void() magica5 = [$magica5, magica6] { ai_face (); };
+ nonvirtual void() magica6 = [$magica6, magica7] { ai_face (); };
+ nonvirtual void() magica7 = [$magica7, magica8] { attack_shot (-2); };
+ nonvirtual void() magica8 = [$magica8, magica9] { attack_shot (-1); };
+ nonvirtual void() magica9 = [$magica9, magica10] { attack_shot (0); };
+ nonvirtual void() magica10 = [$magica10, magica11] { attack_shot(1);};
+ nonvirtual void() magica11 = [$magica11, magica12] { attack_shot(2);};
+ nonvirtual void() magica12 = [$magica12, magica13] { attack_shot(3);};
+ nonvirtual void() magica13 = [$magica13, magica14] { ai_face (); };
+ nonvirtual void() magica14 = [$magica14, run1] { ai_face (); };
+
+ //--------------------------------------------------------------
+ // Death Knight Magic B
+ //--------------------------------------------------------------
+ nonvirtual void() magicb1 = [$magicb1, magicb2] { ai_face (); };
+ nonvirtual void() magicb2 = [$magicb2, magicb3] { ai_face (); };
+ nonvirtual void() magicb3 = [$magicb3, magicb4] { ai_face (); };
+ nonvirtual void() magicb4 = [$magicb4, magicb5] { ai_face (); };
+ nonvirtual void() magicb5 = [$magicb5, magicb6] { ai_face (); };
+ nonvirtual void() magicb6 = [$magicb6, magicb7] { ai_face (); };
+ nonvirtual void() magicb7 = [$magicb7, magicb8] { ai_face (); };
+ nonvirtual void() magicb8 = [$magicb8, magicb9] { ai_face (); };
+ nonvirtual void() magicb9 = [$magicb9, magicb10] { ai_face (); };
+ nonvirtual void() magicb10 = [$magicb10, magicb11]
+ {
+ ai_face ();
+ sound_misc2 (this, CHAN_WEAPON, "shambler/sboom.wav",
+ 1, ATTN_NORM);
+ this.attack_lightning ();
+ };
+ nonvirtual void() magicb11 = [$magicb11, magicb12] { ai_face (); };
+ nonvirtual void() magicb12 = [$magicb12, magicb13] { ai_face (); };
+ nonvirtual void() magicb13 = [$magicb13, run1] { ai_face (); };
+
+ //--------------------------------------------------------------
+ // Death Knight Magic C
+ //--------------------------------------------------------------
+ nonvirtual void() magicc1 = [$magicc1, magicc2] { ai_face (); };
+ nonvirtual void() magicc2 = [$magicc2, magicc3] { ai_face (); };
+ nonvirtual void() magicc3 = [$magicc3, magicc4] { ai_face (); };
+ nonvirtual void() magicc4 = [$magicc4, magicc5] { ai_face (); };
+ nonvirtual void() magicc5 = [$magicc5, magicc6] { ai_face (); };
+ nonvirtual void() magicc6 = [$magicc6, magicc7] { attack_shot (-2); };
+ nonvirtual void() magicc7 = [$magicc7, magicc8] { attack_shot (-1); };
+ nonvirtual void() magicc8 = [$magicc8, magicc9] { attack_shot (0); };
+ nonvirtual void() magicc9 = [$magicc9, magicc10] { attack_shot (1); };
+ nonvirtual void() magicc10 = [$magicc10, magicc11] { attack_shot(2); };
+ nonvirtual void() magicc11 = [$magicc11, run1] { attack_shot (3); };
+
+ /////////////////////////////////////////////
+ ////// turret frames START - revisions //////
+ /////////////////////////////////////////////
+
+ //--------------------------------------------------------------
+ // Death Knight Seek / Standing Frames
+ //--------------------------------------------------------------
+ nonvirtual void() seek_stand1 = [$stand1, seek_stand2] { ai_run (0); };
+ nonvirtual void() seek_stand2 = [$stand2, seek_stand3] { ai_run (0); };
+ nonvirtual void() seek_stand3 = [$stand3, seek_stand4] { ai_run (0); };
+ nonvirtual void() seek_stand4 = [$stand4, seek_stand5] { ai_run (0); };
+ nonvirtual void() seek_stand5 = [$stand5, seek_stand6] { ai_run (0); };
+ nonvirtual void() seek_stand6 = [$stand6, seek_stand7] { ai_run (0); };
+ nonvirtual void() seek_stand7 = [$stand7, seek_stand8] { ai_run (0); };
+ nonvirtual void() seek_stand8 = [$stand8, seek_stand9] { ai_run (0); };
+ nonvirtual void() seek_stand9 = [$stand9, seek_stand1] { ai_run (0); };
+
+ //--------------------------------------------------------------
+ // Death Knight Turret Magic B (fnames shortened -- CEV)
+ //--------------------------------------------------------------
+ nonvirtual void() t_magb1 = [$magicb1, t_magb2] { ai_face (); };
+ nonvirtual void() t_magb2 = [$magicb2, t_magb3] { ai_face (); };
+ nonvirtual void() t_magb3 = [$magicb3, t_magb4] { ai_face (); };
+ nonvirtual void() t_magb4 = [$magicb4, t_magb5] { ai_face (); };
+ nonvirtual void() t_magb5 = [$magicb5, t_magb6] { ai_face (); };
+ nonvirtual void() t_magb6 = [$magicb6, t_magb7] { ai_face (); };
+ nonvirtual void() t_magb7 = [$magicb7, t_magb8] { ai_face (); };
+ nonvirtual void() t_magb8 = [$magicb8, t_magb9] { ai_face (); };
+ nonvirtual void() t_magb9 = [$magicb9, t_magb10] { ai_face (); };
+ nonvirtual void() t_magb10 = [$magicb10, t_magb11]
+ {
+ ai_face ();
+ sound_misc2 (this, CHAN_WEAPON, "shambler/sboom.wav",
+ 1, ATTN_NORM);
+ this.attack_lightning ();
+ };
+ nonvirtual void() t_magb11 = [$magicb11, t_magb12] { ai_face (); };
+ nonvirtual void() t_magb12 = [$magicb12, t_magb13] { ai_face (); };
+ nonvirtual void() t_magb13 = [$magicb13, seek_stand1] { ai_face (); };
+
+ //--------------------------------------------------------------
+ // Death Knight Turret Magic C (fnames shortened -- CEV)
+ //--------------------------------------------------------------
+ nonvirtual void() t_magc1 = [$magicc1, t_magc2] { ai_face (); };
+ nonvirtual void() t_magc2 = [$magicc2, t_magc3] { ai_face (); };
+ nonvirtual void() t_magc3 = [$magicc3, t_magc4] { ai_face (); };
+ nonvirtual void() t_magc4 = [$magicc4, t_magc5] { ai_face (); };
+ nonvirtual void() t_magc5 = [$magicc5, t_magc6] { ai_face (); };
+ nonvirtual void() t_magc6 = [$magicc6, t_magc7] { attack_shot (-2); };
+ nonvirtual void() t_magc7 = [$magicc7, t_magc8] { attack_shot (-1); };
+ nonvirtual void() t_magc8 = [$magicc8, t_magc9] { attack_shot (0); };
+ nonvirtual void() t_magc9 = [$magicc9, t_magc10] { attack_shot (1); };
+ nonvirtual void() t_magc10 = [$magicc10, t_magc11] { attack_shot (2);};
+ nonvirtual void() t_magc11 = [$magicc11, t_magc12] { ai_face (); };
+ nonvirtual void() t_magc12 = [$stand1, t_magc13] { ai_face (); };
+ nonvirtual void() t_magc13 = [$stand2, t_magc14] { ai_face (); };
+ nonvirtual void() t_magc14 = [$stand3, t_magc15] { ai_face (); };
+ nonvirtual void() t_magc15 = [$stand4, seek_stand1] { ai_run (0); };
+
+ /////////////////////////////////////////////
+ ////// turret frames END //////
+ /////////////////////////////////////////////
+
+ //--------------------------------------------------------------
+ // Death Knight pain state
+ //--------------------------------------------------------------
+ nonvirtual void() pain1 = [$pain1, pain2]
+ {
+ sound_pain (this, CHAN_VOICE, "hknight/pain1.wav",
+ 1, ATTN_NORM);
+ };
+ nonvirtual void() pain2 = [$pain2, pain3] { };
+ nonvirtual void() pain3 = [$pain3, pain4] { };
+ nonvirtual void() pain4 = [$pain4, pain5] { };
+ nonvirtual void() pain5 = [$pain5, run1] { };
+
+ //--------------------------------------------------------------
+ // Death Knight death state A
+ //--------------------------------------------------------------
+ nonvirtual void() die1 = [$death1, die2] { ai_forward (10); };
+ nonvirtual void() die2 = [$death2, die3] { ai_forward (8); };
+ nonvirtual void() die3 = [$death3, die4]
+ {
+ this.solid = SOLID_NOT;
+ ai_forward (7);
+ };
+ nonvirtual void() die4 = [$death4, die5] { };
+ nonvirtual void() die5 = [$death5, die6] { };
+ nonvirtual void() die6 = [$death6, die7] { };
+ nonvirtual void() die7 = [$death7, die8] { };
+ nonvirtual void() die8 = [$death8, die9] { ai_forward (10); };
+ nonvirtual void() die9 = [$death9, die10] { ai_forward (11); };
+ nonvirtual void() die10 = [$death10, die11] { };
+ nonvirtual void() die11 = [$death11, die12] { };
+ nonvirtual void() die12 = [$death12, die12] { };
+
+ //--------------------------------------------------------------
+ // Death Knight death state B
+ //--------------------------------------------------------------
+ nonvirtual void() dieb1 = [$deathb1, dieb2] { };
+ nonvirtual void() dieb2 = [$deathb2, dieb3] { };
+ nonvirtual void() dieb3 = [$deathb3, dieb4] { this.solid = SOLID_NOT; };
+ nonvirtual void() dieb4 = [$deathb4, dieb5] { };
+ nonvirtual void() dieb5 = [$deathb5, dieb6] { };
+ nonvirtual void() dieb6 = [$deathb6, dieb7] { };
+ nonvirtual void() dieb7 = [$deathb7, dieb8] { };
+ nonvirtual void() dieb8 = [$deathb8, dieb9] { };
+ nonvirtual void() dieb9 = [$deathb9, dieb9] { };
+
+ //==============================================================
+ // Interaction
+ //==============================================================
+
+ //--------------------------------------------------------------
+ // hknight_pain
+ //--------------------------------------------------------------
+ virtual void(entity attacker, float damage) do_damage =
+ {
+ local float r;
+
+ r = random ();
+
+ if (this.pain_finished > time)
+ return;
+
+ if (this.spawnflags & I_AM_TURRET)
+ {
+ if (r < 0.5)
+ {
+ this.pain_finished = time + 1.5;
+ sound_pain (this, CHAN_VOICE,
+ "hknight/pain1.wav", 1, ATTN_NORM);
+ }
+ return;
+ }
+
+ sound_pain (this, CHAN_VOICE, "hknight/pain1.wav",
+ 1, ATTN_NORM);
+
+ if (time - this.pain_finished > 5)
+ {
+ // always go into pain frame if it has been a while
+ this.pain1 ();
+ this.pain_finished = time + 1;
+ return;
+ }
+
+ if ((random()*30 > damage))
+ // didn't flinch
+ return;
+
+ this.pain_finished = time + 1;
+ this.pain1 ();
+ };
- walkmonster_start ();
+ //--------------------------------------------------------------
+ // hknight_die
+ //--------------------------------------------------------------
+ virtual void() do_destroy =
+ {
+ // check for gib
+ if (this.health < -40)
+ {
+ sound (this, CHAN_VOICE, "player/udeath.wav",
+ 1, ATTN_NORM);
+ // dumptruck_ds custom_mdls
+ if (this.mdl_head != "")
+ {
+ ThrowHead (this.mdl_head, this.health);
+ }
+ else
+ {
+ ThrowHead ("progs/h_hellkn.mdl", this.health);
+ }
+ // ThrowGib ("progs/gib1.mdl", this.health);
+ // ThrowGib ("progs/gib2.mdl", this.health);
+ // ThrowGib ("progs/gib3.mdl", this.health);
+ // custom models -- dumptruck_ds
+ if (this.mdl_gib1 != "")
+ {
+ ThrowGib (this.mdl_gib1, this.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib1.mdl", this.health);
+ }
+ if (this.mdl_gib2 != "")
+ {
+ ThrowGib (this.mdl_gib2, this.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib2.mdl", this.health);
+ }
+ if (this.mdl_gib3 != "")
+ {
+ ThrowGib (this.mdl_gib3, this.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib3.mdl", this.health);
+ }
+ base_item::drop_stuff (this);
+ return;
+ }
+
+ // regular death
+ sound_death (this, CHAN_VOICE, "hknight/death1.wav",
+ 1, ATTN_NORM);
+ base_item::drop_stuff (this);
+ if (random() > 0.5)
+ this.die1 ();
+ else
+ this.dieb1 ();
+ };
+
+ //==============================================================
+ // Initialization
+ //==============================================================
+
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
+ {
+ if (deathmatch)
+ {
+ remove (this);
+ return;
+ }
+
+ precache_model2 ("progs/hknight.mdl");
+ precache_model2 ("progs/k_spike.mdl");
+ precache_model2 ("progs/k_spike2.mdl");
+ precache_model2 ("progs/h_hellkn.mdl");
+ // dumptruck_ds custom_mdls
+ precache_body_model2 ("progs/hknight.mdl");
+ precache_head_model2 ("progs/h_hellkn.mdl");
+ precache_proj_model2 ("progs/k_spike.mdl");
+ // this needed a unique name defined in custom_mdls.qc
+ // -- dumptruck_ds
+ precache_exproj_model2 ("progs/k_spike2.mdl");
+ // dumptruck_ds
+
+ precache_sound2_attack ("hknight/attack1.wav");
+ precache_sound2_death ("hknight/death1.wav");
+ precache_sound2_pain ("hknight/pain1.wav");
+ precache_sound2_sight ("hknight/sight1.wav");
+ // used by C code, so don't sound2
+ precache_sound ("hknight/hit.wav");
+ precache_sound2_misc ("hknight/slash1.wav");
+ precache_sound2_idle ("hknight/idle.wav");
+ // what??? never knew about this! -- dumptruck_ds
+ precache_sound2 ("hknight/grunt.wav");
+
+ precache_sound ("knight/sword1.wav");
+ precache_sound ("knight/sword2.wav");
+
+ precache_gib1 ("progs/gib1.mdl");
+ precache_gib2 ("progs/gib2.mdl");
+ precache_gib3 ("progs/gib3.mdl");
+
+ this.solid = SOLID_SLIDEBOX;
+ this.movetype = MOVETYPE_STEP;
+
+ // custom_mdls dumptruck_ds
+ body_model ("progs/hknight.mdl");
+ // setmodel (this, "progs/hknight.mdl");
+
+ setsize (this, '-16 -16 -24', '16 16 40');
+
+ // thanks RennyC -- dumptruck_ds
+ if (!this.health)
+ this.health = 250;
+
+ if (!this.proj_speed_mod)
+ {
+ this.proj_speed_mod = 1;
+ }
+
+ this.think_stand = this.stand1;
+ this.think_walk = this.walk1;
+ if (this.spawnflags & I_AM_TURRET)
+ {
+ this.think_run = this.seek_stand1;
+ }
+ else
+ {
+ this.think_run = this.run1;
+ }
+ this.think_melee = this.attack_melee;
+ if (this.style == 1)
+ {
+ this.think_missile = this.magicb1;
+ this.think_turret = this.t_magb1;
+ }
+ else
+ {
+ this.think_missile = this.magicc1;
+ this.think_turret = this.t_magc1;
+ }
+ // Berserk test from
+ // http://celephais.net/board/view_thread.php?id=4&start=3465
+ // -- dumptruck_ds
+ if !(this.berserk)
+ this.th_pain = this.do_damage;
+ else
+ this.th_pain = sub_nullpain;
+ this.th_die = this.do_destroy;
+
+ // walkmonster_start
+ super::init_spawned ();
+ };
+
+ //--------------------------------------------------------------
+ void() monster_hell_knight =
+ {
+ this.classtype = CT_MONSTER_DEATHKNIGHT;
+ };
};
/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
Return to the top of this page or return to the overview of this repo.
Diff qc/monsters/knight.qc
diff --git a/qc/monsters/knight.qc b/qc/monsters/knight.qc
index c058a89..c0b4bbe 100644
--- a/qc/monsters/knight.qc
+++ b/qc/monsters/knight.qc
@@ -1,11 +1,10 @@
-/*
-==============================================================================
-
-KNIGHT
-
-==============================================================================
-*/
+//==============================================================================
+// KNIGHT
+//==============================================================================
+//======================================================================
+// frame macros
+//======================================================================
$cd id1/models/knight
$origin 0 0 24
$base base
@@ -15,7 +14,7 @@ $frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9
$frame runb1 runb2 runb3 runb4 runb5 runb6 runb7 runb8
-//frame runc1 runc2 runc3 runc4 runc5 runc6
+// frame runc1 runc2 runc3 runc4 runc5 runc6
$frame runattack1 runattack2 runattack3 runattack4 runattack5
$frame runattack6 runattack7 runattack8 runattack9 runattack10
@@ -26,8 +25,8 @@ $frame pain1 pain2 pain3
$frame painb1 painb2 painb3 painb4 painb5 painb6 painb7 painb8 painb9
$frame painb10 painb11
-//frame attack1 attack2 attack3 attack4 attack5 attack6 attack7
-//frame attack8 attack9 attack10 attack11
+// frame attack1 attack2 attack3 attack4 attack5 attack6 attack7
+// frame attack8 attack9 attack10 attack11
$frame attackdummy
$frame attackb1 attackb2 attackb3 attackb4 attackb5
@@ -46,224 +45,6 @@ $frame death9 death10
$frame deathb1 deathb2 deathb3 deathb4 deathb5 deathb6 deathb7 deathb8
$frame deathb9 deathb10 deathb11
-void() knight_stand1 =[ $stand1, knight_stand2 ] {ai_stand();};
-void() knight_stand2 =[ $stand2, knight_stand3 ] {ai_stand();};
-void() knight_stand3 =[ $stand3, knight_stand4 ] {ai_stand();};
-void() knight_stand4 =[ $stand4, knight_stand5 ] {ai_stand();};
-void() knight_stand5 =[ $stand5, knight_stand6 ] {ai_stand();};
-void() knight_stand6 =[ $stand6, knight_stand7 ] {ai_stand();};
-void() knight_stand7 =[ $stand7, knight_stand8 ] {ai_stand();};
-void() knight_stand8 =[ $stand8, knight_stand9 ] {ai_stand();};
-void() knight_stand9 =[ $stand9, knight_stand1 ] {ai_stand();};
-
-void() knight_walk1 =[ $walk1, knight_walk2 ] {
-if (random() < 0.2)
- sound_idle (self, CHAN_VOICE, "knight/idle.wav", 1, ATTN_IDLE);
-ai_walk(3);};
-void() knight_walk2 =[ $walk2, knight_walk3 ] {ai_walk(2);};
-void() knight_walk3 =[ $walk3, knight_walk4 ] {ai_walk(3);};
-void() knight_walk4 =[ $walk4, knight_walk5 ] {ai_walk(4);};
-void() knight_walk5 =[ $walk5, knight_walk6 ] {ai_walk(3);};
-void() knight_walk6 =[ $walk6, knight_walk7 ] {ai_walk(3);};
-void() knight_walk7 =[ $walk7, knight_walk8 ] {ai_walk(3);};
-void() knight_walk8 =[ $walk8, knight_walk9 ] {ai_walk(4);};
-void() knight_walk9 =[ $walk9, knight_walk10 ] {ai_walk(3);};
-void() knight_walk10 =[ $walk10, knight_walk11 ] {ai_walk(3);};
-void() knight_walk11 =[ $walk11, knight_walk12 ] {ai_walk(2);};
-void() knight_walk12 =[ $walk12, knight_walk13 ] {ai_walk(3);};
-void() knight_walk13 =[ $walk13, knight_walk14 ] {ai_walk(4);};
-void() knight_walk14 =[ $walk14, knight_walk1 ] {ai_walk(3);};
-
-
-void() knight_run1 =[ $runb1, knight_run2 ] {
-if (random() < 0.2)
- sound_idle (self, CHAN_VOICE, "knight/idle.wav", 1, ATTN_IDLE);
-ai_run(16);};
-void() knight_run2 =[ $runb2, knight_run3 ] {ai_run(20);};
-void() knight_run3 =[ $runb3, knight_run4 ] {ai_run(13);};
-void() knight_run4 =[ $runb4, knight_run5 ] {ai_run(7);};
-void() knight_run5 =[ $runb5, knight_run6 ] {ai_run(16);};
-void() knight_run6 =[ $runb6, knight_run7 ] {ai_run(20);};
-void() knight_run7 =[ $runb7, knight_run8 ] {ai_run(14);};
-void() knight_run8 =[ $runb8, knight_run1 ] {ai_run(6);};
-
-
-void() knight_runatk1 =[ $runattack1, knight_runatk2 ]
-{
-if (random() > 0.5)
- sound_misc (self, CHAN_WEAPON, "knight/sword2.wav", 1, ATTN_NORM);
-else
- sound_attack(self, CHAN_WEAPON, "knight/sword1.wav", 1, ATTN_NORM);
-ai_charge(20);
-};
-void() knight_runatk2 =[ $runattack2, knight_runatk3 ] {ai_charge_side();};
-void() knight_runatk3 =[ $runattack3, knight_runatk4 ] {ai_charge_side();};
-void() knight_runatk4 =[ $runattack4, knight_runatk5 ] {ai_charge_side();};
-void() knight_runatk5 =[ $runattack5, knight_runatk6 ] {ai_melee_side();};
-void() knight_runatk6 =[ $runattack6, knight_runatk7 ] {ai_melee_side();};
-void() knight_runatk7 =[ $runattack7, knight_runatk8 ] {ai_melee_side();};
-void() knight_runatk8 =[ $runattack8, knight_runatk9 ] {ai_melee_side();};
-void() knight_runatk9 =[ $runattack9, knight_runatk10 ] {ai_melee_side();};
-void() knight_runatk10 =[ $runattack10, knight_runatk11 ] {ai_charge_side();};
-void() knight_runatk11 =[ $runattack11, knight_run1 ] {ai_charge(10);};
-
-void() knight_atk1 =[ $attackb1, knight_atk2 ]
-{
-sound_attack(self, CHAN_WEAPON, "knight/sword1.wav", 1, ATTN_NORM);
-ai_charge(0);};
-void() knight_atk2 =[ $attackb2, knight_atk3 ] {ai_charge(7);};
-void() knight_atk3 =[ $attackb3, knight_atk4 ] {ai_charge(4);};
-void() knight_atk4 =[ $attackb4, knight_atk5 ] {ai_charge(0);};
-void() knight_atk5 =[ $attackb5, knight_atk6 ] {ai_charge(3);};
-void() knight_atk6 =[ $attackb6, knight_atk7 ] {ai_charge(4); ai_melee();};
-void() knight_atk7 =[ $attackb7, knight_atk8 ] {ai_charge(1); ai_melee();};
-void() knight_atk8 =[ $attackb8, knight_atk9 ] {ai_charge(3);
-ai_melee();};
-void() knight_atk9 =[ $attackb9, knight_atk10] {ai_charge(1);};
-void() knight_atk10=[ $attackb10, knight_run1 ] {ai_charge(5);};
-
-//void() knight_atk9 =[ $attack9, knight_atk10 ] {};
-//void() knight_atk10 =[ $attack10, knight_atk11 ] {};
-//void() knight_atk11 =[ $attack11, knight_run1 ] {};
-
-//===========================================================================
-
-void() knight_pain1 =[ $pain1, knight_pain2 ] {};
-void() knight_pain2 =[ $pain2, knight_pain3 ] {};
-void() knight_pain3 =[ $pain3, knight_run1 ] {};
-
-void() knight_painb1 =[ $painb1, knight_painb2 ] {ai_painforward(0);};
-void() knight_painb2 =[ $painb2, knight_painb3 ] {ai_painforward(3);};
-void() knight_painb3 =[ $painb3, knight_painb4 ] {};
-void() knight_painb4 =[ $painb4, knight_painb5 ] {};
-void() knight_painb5 =[ $painb5, knight_painb6 ] {ai_painforward(2);};
-void() knight_painb6 =[ $painb6, knight_painb7 ] {ai_painforward(4);};
-void() knight_painb7 =[ $painb7, knight_painb8 ] {ai_painforward(2);};
-void() knight_painb8 =[ $painb8, knight_painb9 ] {ai_painforward(5);};
-void() knight_painb9 =[ $painb9, knight_painb10 ] {ai_painforward(5);};
-void() knight_painb10 =[ $painb10, knight_painb11 ] {ai_painforward(0);};
-void() knight_painb11 =[ $painb11, knight_run1 ] {};
-
-void(entity attacker, float damage) knight_pain =
-{
- local float r;
-
- if (self.pain_finished > time)
- return;
-
- r = random();
-
- sound_pain (self, CHAN_VOICE, "knight/khurt.wav", 1, ATTN_NORM);
- if (r < 0.85)
- {
- knight_pain1 ();
- self.pain_finished = time + 1;
- }
- else
- {
- knight_painb1 ();
- self.pain_finished = time + 1;
- }
-
-};
-
-//===========================================================================
-
-void() knight_bow1 =[ $kneel1, knight_bow2 ] {ai_turn();};
-void() knight_bow2 =[ $kneel2, knight_bow3 ] {ai_turn();};
-void() knight_bow3 =[ $kneel3, knight_bow4 ] {ai_turn();};
-void() knight_bow4 =[ $kneel4, knight_bow5 ] {ai_turn();};
-
-void() knight_bow5 =[ $kneel5, knight_bow5 ] {ai_turn();};
-
-void() knight_bow6 =[ $kneel4, knight_bow7 ] {ai_turn();};
-void() knight_bow7 =[ $kneel3, knight_bow8 ] {ai_turn();};
-void() knight_bow8 =[ $kneel2, knight_bow9 ] {ai_turn();};
-void() knight_bow9 =[ $kneel1, knight_bow10 ] {ai_turn();};
-void() knight_bow10 =[ $walk1, knight_walk1 ] {ai_turn();};
-
-
-
-void() knight_die1 =[ $death1, knight_die2 ] {};
-void() knight_die2 =[ $death2, knight_die3 ] {};
-void() knight_die3 =[ $death3, knight_die4 ] {self.solid = SOLID_NOT;};
-void() knight_die4 =[ $death4, knight_die5 ] {};
-void() knight_die5 =[ $death5, knight_die6 ] {};
-void() knight_die6 =[ $death6, knight_die7 ] {};
-void() knight_die7 =[ $death7, knight_die8 ] {};
-void() knight_die8 =[ $death8, knight_die9 ] {};
-void() knight_die9 =[ $death9, knight_die10] {};
-void() knight_die10=[ $death10, knight_die10] {};
-
-
-void() knight_dieb1 =[ $deathb1, knight_dieb2 ] {};
-void() knight_dieb2 =[ $deathb2, knight_dieb3 ] {};
-void() knight_dieb3 =[ $deathb3, knight_dieb4 ] {self.solid = SOLID_NOT;};
-void() knight_dieb4 =[ $deathb4, knight_dieb5 ] {};
-void() knight_dieb5 =[ $deathb5, knight_dieb6 ] {};
-void() knight_dieb6 =[ $deathb6, knight_dieb7 ] {};
-void() knight_dieb7 =[ $deathb7, knight_dieb8 ] {};
-void() knight_dieb8 =[ $deathb8, knight_dieb9 ] {};
-void() knight_dieb9 =[ $deathb9, knight_dieb10] {};
-void() knight_dieb10 = [ $deathb10, knight_dieb11] {};
-void() knight_dieb11 = [ $deathb11, knight_dieb11] {};
-
-
-void() knight_die =
-{
-// check for gib
- if (self.health < -40)
- {
- sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
- if (self.mdl_head != "") //dumptruck_ds custom_mdls
- {
- ThrowHead (self.mdl_head, self.health);
- }
- else
- {
- ThrowHead ("progs/h_knight.mdl", self.health);
- }
- // ThrowGib ("progs/gib1.mdl", self.health);
- // ThrowGib ("progs/gib2.mdl", self.health);
- // ThrowGib ("progs/gib3.mdl", self.health);
- if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
- {
- ThrowGib (self.mdl_gib1, self.health);
- }
- else
- {
- ThrowGib ("progs/gib1.mdl", self.health);
- }
- if (self.mdl_gib2 != "")
- {
- ThrowGib (self.mdl_gib2, self.health);
- }
- else
- {
- ThrowGib ("progs/gib2.mdl", self.health);
- }
- if (self.mdl_gib3 != "")
- {
- ThrowGib (self.mdl_gib3, self.health);
- }
- else
- {
- ThrowGib ("progs/gib3.mdl", self.health);
- }
- base_item::drop_stuff (self);
- return;
- }
-
-// regular death
- sound_death (self, CHAN_VOICE, "knight/kdeath.wav", 1, ATTN_NORM);
- base_item::drop_stuff (self);
- if (random() < 0.5)
- knight_die1 ();
- else
- knight_dieb1 ();
-};
-
-
/*QUAKED monster_knight (1 0 0) (-16 -16 -24) (16 16 40) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
{
model ("progs/knight.mdl");
@@ -322,56 +103,369 @@ obit_method(string) : "When used with obit_name, will set part of the text for a
damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
*/
-void() monster_knight =
+class monster_knight: base_walkmonster
{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
+ //--------------------------------------------------------------
+ virtual void() ai_sightsound =
+ {
+ sound_sight (this, CHAN_VOICE, "knight/ksight.wav",
+ 1, ATTN_NORM);
+ };
+
+ //--------------------------------------------------------------
+ // knight_attack
+ //--------------------------------------------------------------
+ nonvirtual void() knight_attack =
+ {
+ local float len;
- if (self.spawnflags & I_AM_TURRET)
- objerror("Incompatible spawnflag: TURRET_MODE\n");
+ // decide if now is a good swing time
+ len = vlen (this.enemy.origin + this.enemy.view_ofs -
+ (this.origin + this.view_ofs));
- if (deathmatch)
+ if (len < 80)
+ this.atk1 ();
+ else
+ this.runatk1 ();
+ };
+
+ //--------------------------------------------------------------
+ // Knight Standing functions
+ //--------------------------------------------------------------
+ nonvirtual void() stand1 = [$stand1, stand2] { ai_stand (); };
+ nonvirtual void() stand2 = [$stand2, stand3] { ai_stand (); };
+ nonvirtual void() stand3 = [$stand3, stand4] { ai_stand (); };
+ nonvirtual void() stand4 = [$stand4, stand5] { ai_stand (); };
+ nonvirtual void() stand5 = [$stand5, stand6] { ai_stand (); };
+ nonvirtual void() stand6 = [$stand6, stand7] { ai_stand (); };
+ nonvirtual void() stand7 = [$stand7, stand8] { ai_stand (); };
+ nonvirtual void() stand8 = [$stand8, stand9] { ai_stand (); };
+ nonvirtual void() stand9 = [$stand9, stand1] { ai_stand (); };
+
+ //--------------------------------------------------------------
+ // Knight Walking functions
+ //--------------------------------------------------------------
+ nonvirtual void() walk1 = [$walk1, walk2]
{
- remove(self);
- return;
- }
- // dumptruck_ds custom_mdls
- precache_body_model ("progs/knight.mdl");
- precache_head_model ("progs/h_knight.mdl");
- //// dumptruck_ds
- precache_sound_death ("knight/kdeath.wav");
- precache_sound_pain ("knight/khurt.wav");
- precache_sound_sight ("knight/ksight.wav");
- precache_sound_attack ("knight/sword1.wav");
- precache_sound_misc ("knight/sword2.wav");
- precache_sound_idle ("knight/idle.wav");
-
- precache_gib1 ("progs/gib1.mdl");
- precache_gib2 ("progs/gib2.mdl");
- precache_gib3 ("progs/gib3.mdl");
-
- self.solid = SOLID_SLIDEBOX;
- self.movetype = MOVETYPE_STEP;
-
- body_model ("progs/knight.mdl"); // dumptruck_ds custom_mdls
- // setmodel (self, "progs/knight.mdl");
-
- setsize (self, '-16 -16 -24', '16 16 40');
-
- if (!self.health) //thanks RennyC -- dumptruck_ds
- self.health = 75;
-
- self.th_stand = knight_stand1;
- self.th_walk = knight_walk1;
- self.th_run = knight_run1;
- self.th_melee = knight_atk1;
- if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
- self.th_pain = knight_pain;
- else
- self.th_pain = sub_nullpain;
- self.th_die = knight_die;
+ if (random() < 0.2)
+ sound_idle (this, CHAN_VOICE, "knight/idle.wav",
+ 1, ATTN_IDLE);
+ ai_walk (3);
+ };
+ nonvirtual void() walk2 = [$walk2, walk3] { ai_walk (2); };
+ nonvirtual void() walk3 = [$walk3, walk4] { ai_walk (3); };
+ nonvirtual void() walk4 = [$walk4, walk5] { ai_walk (4); };
+ nonvirtual void() walk5 = [$walk5, walk6] { ai_walk (3); };
+ nonvirtual void() walk6 = [$walk6, walk7] { ai_walk (3); };
+ nonvirtual void() walk7 = [$walk7, walk8] { ai_walk (3); };
+ nonvirtual void() walk8 = [$walk8, walk9] { ai_walk (4); };
+ nonvirtual void() walk9 = [$walk9, walk10] { ai_walk (3); };
+ nonvirtual void() walk10 = [$walk10, walk11] { ai_walk (3); };
+ nonvirtual void() walk11 = [$walk11, walk12] { ai_walk (2); };
+ nonvirtual void() walk12 = [$walk12, walk13] { ai_walk (3); };
+ nonvirtual void() walk13 = [$walk13, walk14] { ai_walk (4); };
+ nonvirtual void() walk14 = [$walk14, walk1] { ai_walk (3); };
+
+ //--------------------------------------------------------------
+ // Knight Running functions
+ //--------------------------------------------------------------
+ nonvirtual void() run1 = [$runb1, run2]
+ {
+ if (random() < 0.2)
+ sound_idle (this, CHAN_VOICE, "knight/idle.wav",
+ 1, ATTN_IDLE);
+ ai_run (16);
+ };
+ nonvirtual void() run2 = [ $runb2, run3] { ai_run (20); };
+ nonvirtual void() run3 = [ $runb3, run4] { ai_run (13); };
+ nonvirtual void() run4 = [ $runb4, run5] { ai_run (7); };
+ nonvirtual void() run5 = [ $runb5, run6] { ai_run (16); };
+ nonvirtual void() run6 = [ $runb6, run7] { ai_run (20); };
+ nonvirtual void() run7 = [ $runb7, run8] { ai_run (14); };
+ nonvirtual void() run8 = [ $runb8, run1] { ai_run (6); };
+
+ //--------------------------------------------------------------
+ // Knight Running Attack
+ //--------------------------------------------------------------
+ nonvirtual void() runatk1 = [$runattack1, runatk2]
+ {
+ if (random() > 0.5)
+ sound_misc (this, CHAN_WEAPON, "knight/sword2.wav",
+ 1, ATTN_NORM);
+ else
+ sound_attack (this, CHAN_WEAPON, "knight/sword1.wav",
+ 1, ATTN_NORM);
+ ai_charge (20);
+ };
+ nonvirtual void() runatk2 = [$runattack2, runatk3] {ai_charge_side();};
+ nonvirtual void() runatk3 = [$runattack3, runatk4] {ai_charge_side();};
+ nonvirtual void() runatk4 = [$runattack4, runatk5] {ai_charge_side();};
+ nonvirtual void() runatk5 = [$runattack5, runatk6] {ai_melee_side();};
+ nonvirtual void() runatk6 = [$runattack6, runatk7] {ai_melee_side();};
+ nonvirtual void() runatk7 = [$runattack7, runatk8] {ai_melee_side();};
+ nonvirtual void() runatk8 = [$runattack8, runatk9] {ai_melee_side();};
+ nonvirtual void() runatk9 = [$runattack9, runatk10] {ai_melee_side();};
+ nonvirtual void() runatk10 = [$runattack10, runatk11] {ai_charge_side();};
+ nonvirtual void() runatk11 = [$runattack11, run1] { ai_charge (10); };
+
+ //--------------------------------------------------------------
+ // Knight Attack
+ //--------------------------------------------------------------
+ nonvirtual void() atk1 = [$attackb1, atk2]
+ {
+ sound_attack (this, CHAN_WEAPON, "knight/sword1.wav",
+ 1, ATTN_NORM);
+ ai_charge (0);
+ };
+ nonvirtual void() atk2 = [$attackb2, atk3] { ai_charge (7); };
+ nonvirtual void() atk3 = [$attackb3, atk4] { ai_charge (4); };
+ nonvirtual void() atk4 = [$attackb4, atk5] { ai_charge (0); };
+ nonvirtual void() atk5 = [$attackb5, atk6] { ai_charge (3); };
+ nonvirtual void() atk6 = [$attackb6, atk7]
+ {
+ ai_charge (4);
+ ai_melee ();
+ };
+ nonvirtual void() atk7 = [$attackb7, atk8]
+ {
+ ai_charge (1);
+ ai_melee ();
+ };
+ nonvirtual void() atk8 = [$attackb8, atk9]
+ {
+ ai_charge (3);
+ ai_melee ();
+ };
+ nonvirtual void() atk9 = [$attackb9, atk10] { ai_charge (1); };
+ nonvirtual void() atk10 = [$attackb10, run1] { ai_charge (5); };
+
+ // nonvirtual void() atk9 = [$attack9, atk10] { };
+ // nonvirtual void() atk10 = [$attack10, atk11] { };
+ // nonvirtual void() atk11 = [$attack11, run1] { };
+
+ //--------------------------------------------------------------
+ // Knight Bowing / Kneeling state
+ //--------------------------------------------------------------
+ nonvirtual void() bow1 = [$kneel1, bow2] { ai_turn (); };
+ nonvirtual void() bow2 = [$kneel2, bow3] { ai_turn (); };
+ nonvirtual void() bow3 = [$kneel3, bow4] { ai_turn (); };
+ nonvirtual void() bow4 = [$kneel4, bow5] { ai_turn (); };
+ nonvirtual void() bow5 = [$kneel5, bow5] { ai_turn (); };
+ nonvirtual void() bow6 = [$kneel4, bow7] { ai_turn (); };
+ nonvirtual void() bow7 = [$kneel3, bow8] { ai_turn (); };
+ nonvirtual void() bow8 = [$kneel2, bow9] { ai_turn (); };
+ nonvirtual void() bow9 = [$kneel1, bow10] { ai_turn (); };
+ nonvirtual void() bow10 = [$walk1, walk1] { ai_turn (); };
+
+ //--------------------------------------------------------------
+ // Knight Pain state A
+ //--------------------------------------------------------------
+ nonvirtual void() pain1 = [$pain1, pain2] { };
+ nonvirtual void() pain2 = [$pain2, pain3] { };
+ nonvirtual void() pain3 = [$pain3, run1] { };
+
+ //--------------------------------------------------------------
+ // Knight Pain state B
+ //--------------------------------------------------------------
+ nonvirtual void() painb1 = [$painb1, painb2] { ai_painforward (0); };
+ nonvirtual void() painb2 = [$painb2, painb3] { ai_painforward (3); };
+ nonvirtual void() painb3 = [$painb3, painb4] { };
+ nonvirtual void() painb4 = [$painb4, painb5] { };
+ nonvirtual void() painb5 = [$painb5, painb6] { ai_painforward (2); };
+ nonvirtual void() painb6 = [$painb6, painb7] { ai_painforward (4); };
+ nonvirtual void() painb7 = [$painb7, painb8] { ai_painforward (2); };
+ nonvirtual void() painb8 = [$painb8, painb9] { ai_painforward (5); };
+ nonvirtual void() painb9 = [$painb9, painb10] { ai_painforward (5); };
+ nonvirtual void() painb10 = [$painb10, painb11] { ai_painforward (0); };
+ nonvirtual void() painb11 = [$painb11, run1] { };
+
+ //--------------------------------------------------------------
+ // Knight Death state A
+ //--------------------------------------------------------------
+ nonvirtual void() die1 = [$death1, die2] { };
+ nonvirtual void() die2 = [$death2, die3] { };
+ nonvirtual void() die3 = [$death3, die4] { this.solid = SOLID_NOT;};
+ nonvirtual void() die4 = [$death4, die5] { };
+ nonvirtual void() die5 = [$death5, die6] { };
+ nonvirtual void() die6 = [$death6, die7] { };
+ nonvirtual void() die7 = [$death7, die8] { };
+ nonvirtual void() die8 = [$death8, die9] { };
+ nonvirtual void() die9 = [$death9, die10] { };
+ nonvirtual void() die10 = [$death10, die10] { };
+
+ //--------------------------------------------------------------
+ // Knight Death state B
+ //--------------------------------------------------------------
+ nonvirtual void() dieb1 = [$deathb1, dieb2 ] { };
+ nonvirtual void() dieb2 = [$deathb2, dieb3 ] { };
+ nonvirtual void() dieb3 = [$deathb3, dieb4 ] {this.solid = SOLID_NOT;};
+ nonvirtual void() dieb4 = [$deathb4, dieb5 ] { };
+ nonvirtual void() dieb5 = [$deathb5, dieb6 ] { };
+ nonvirtual void() dieb6 = [$deathb6, dieb7 ] { };
+ nonvirtual void() dieb7 = [$deathb7, dieb8 ] { };
+ nonvirtual void() dieb8 = [$deathb8, dieb9 ] { };
+ nonvirtual void() dieb9 = [$deathb9, dieb10] { };
+ nonvirtual void() dieb10 = [$deathb10, dieb11] { };
+ nonvirtual void() dieb11 = [$deathb11, dieb11] { };
+
+ //==============================================================
+ // Interaction
+ //==============================================================
+
+ //--------------------------------------------------------------
+ // knight_pain
+ //--------------------------------------------------------------
+ virtual void(entity attacker, float damage) do_damage =
+ {
+ if (this.pain_finished > time)
+ return;
- walkmonster_start ();
+ local float r = random ();
+
+ sound_pain (this, CHAN_VOICE, "knight/khurt.wav",
+ 1, ATTN_NORM);
+
+ if (r < 0.85)
+ {
+ this.pain1 ();
+ this.pain_finished = time + 1;
+ }
+ else
+ {
+ this.painb1 ();
+ this.pain_finished = time + 1;
+ }
+ };
+
+ //--------------------------------------------------------------
+ // knight_die
+ //--------------------------------------------------------------
+ virtual void() do_destroy =
+ {
+ // check for gib
+ if (this.health < -40)
+ {
+ sound (this, CHAN_VOICE, "player/udeath.wav",
+ 1, ATTN_NORM);
+
+ // dumptruck_ds custom_mdls
+ if (this.mdl_head != "")
+ {
+ ThrowHead (this.mdl_head, this.health);
+ }
+ else
+ {
+ ThrowHead ("progs/h_knight.mdl", this.health);
+ }
+
+ // ThrowGib ("progs/gib1.mdl", this.health);
+ // ThrowGib ("progs/gib2.mdl", this.health);
+ // ThrowGib ("progs/gib3.mdl", this.health);
+
+ // custom models -- dumptruck_ds
+ if (this.mdl_gib1 != "")
+ {
+ ThrowGib (this.mdl_gib1, this.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib1.mdl", this.health);
+ }
+ if (this.mdl_gib2 != "")
+ {
+ ThrowGib (this.mdl_gib2, this.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib2.mdl", this.health);
+ }
+ if (this.mdl_gib3 != "")
+ {
+ ThrowGib (this.mdl_gib3, this.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib3.mdl", this.health);
+ }
+ base_item::drop_stuff (this);
+ return;
+ }
+
+ // regular death
+ sound_death (this, CHAN_VOICE, "knight/kdeath.wav",
+ 1, ATTN_NORM);
+ base_item::drop_stuff (this);
+ if (random() < 0.5)
+ this.die1 ();
+ else
+ this.dieb1 ();
+ };
+
+ //==============================================================
+ // Initialization
+ //==============================================================
+
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
+ {
+ if (this.spawnflags & I_AM_TURRET)
+ objerror("Incompatible spawnflag: TURRET_MODE\n");
+
+ if (deathmatch)
+ {
+ remove (this);
+ return;
+ }
+
+ // dumptruck_ds custom_mdls
+ precache_body_model ("progs/knight.mdl");
+ precache_head_model ("progs/h_knight.mdl");
+ // dumptruck_ds
+ precache_sound_death ("knight/kdeath.wav");
+ precache_sound_pain ("knight/khurt.wav");
+ precache_sound_sight ("knight/ksight.wav");
+ precache_sound_attack ("knight/sword1.wav");
+ precache_sound_misc ("knight/sword2.wav");
+ precache_sound_idle ("knight/idle.wav");
+
+ precache_gib1 ("progs/gib1.mdl");
+ precache_gib2 ("progs/gib2.mdl");
+ precache_gib3 ("progs/gib3.mdl");
+
+ this.solid = SOLID_SLIDEBOX;
+ this.movetype = MOVETYPE_STEP;
+
+ body_model ("progs/knight.mdl"); // dumptruck_ds custom_mdls
+ // setmodel (this, "progs/knight.mdl");
+
+ setsize (this, '-16 -16 -24', '16 16 40');
+
+ if (!this.health)
+ // thanks RennyC -- dumptruck_ds
+ this.health = 75;
+
+ this.think_stand = this.stand1;
+ this.think_walk = this.walk1;
+ this.think_run = this.run1;
+ this.think_melee = this.atk1;
+ // Berserk test from
+ // http://celephais.net/board/view_thread.php?id=4&start=3465
+ // -- dumptruck_ds
+ if !(this.berserk)
+ this.th_pain = this.do_damage;
+ else
+ this.th_pain = sub_nullpain;
+ this.th_die = this.do_destroy;
+
+ // walkmonster_start
+ super::init_spawned ();
+ };
+
+ //--------------------------------------------------------------
+ void() monster_knight =
+ {
+ this.classtype = CT_MONSTER_KNIGHT;
+ };
};
/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
Return to the top of this page or return to the overview of this repo.
Diff qc/monsters/ogre.qc
diff --git a/qc/monsters/ogre.qc b/qc/monsters/ogre.qc
index 83998fc..cf1d10e 100644
--- a/qc/monsters/ogre.qc
+++ b/qc/monsters/ogre.qc
@@ -1,58 +1,28 @@
-float MONSTER_FLAK_OGRE = 4;
-float FL_NOSELECT = 8192; //ignored by entity selector
-.float spikecount; //bdw - saves up flak hits to do a single damage next frame - currently only used for flak ogre
+//==============================================================================
+// OGRE
+//==============================================================================
-/*
-==============================================================================
+//======================================================================
+// constants
+//======================================================================
+const float MONSTER_FLAK_OGRE = 4;
+const float FL_NOSELECT = 8192; // ignored by entity selector
-OGRE
+const float OGRE_G_VEL = 600; // speed an ogre grenade is fired at
+const float pgrav = 800; // TODO: get correct grav for level
+const float OGRE_DEFAULT_ELEVATION = 30;// angle to fire at if enemy too far
-==============================================================================
-*/
-
-$cd id1/models/ogre_c
-$origin 0 0 24
-$base base
-$skin base
-
-$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9
-
-$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7
-$frame walk8 walk9 walk10 walk11 walk12 walk13 walk14 walk15 walk16
-
-$frame run1 run2 run3 run4 run5 run6 run7 run8
-
-$frame swing1 swing2 swing3 swing4 swing5 swing6 swing7
-$frame swing8 swing9 swing10 swing11 swing12 swing13 swing14
-
-$frame smash1 smash2 smash3 smash4 smash5 smash6 smash7
-$frame smash8 smash9 smash10 smash11 smash12 smash13 smash14
-
-$frame shoot1 shoot2 shoot3 shoot4 shoot5 shoot6
-
-$frame pain1 pain2 pain3 pain4 pain5
-
-$frame painb1 painb2 painb3
-
-$frame painc1 painc2 painc3 painc4 painc5 painc6
-
-$frame paind1 paind2 paind3 paind4 paind5 paind6 paind7 paind8 paind9 paind10
-$frame paind11 paind12 paind13 paind14 paind15 paind16
-
-$frame paine1 paine2 paine3 paine4 paine5 paine6 paine7 paine8 paine9 paine10
-$frame paine11 paine12 paine13 paine14 paine15
+//======================================================================
+// fields
+//======================================================================
-$frame death1 death2 death3 death4 death5 death6
-$frame death7 death8 death9 death10 death11 death12
-$frame death13 death14
-
-$frame bdeath1 bdeath2 bdeath3 bdeath4 bdeath5 bdeath6
-$frame bdeath7 bdeath8 bdeath9 bdeath10
-
-$frame pull1 pull2 pull3 pull4 pull5 pull6 pull7 pull8 pull9 pull10 pull11
+// bdw - saves up flak hits to do a single damage next frame -
+// currently only used for flak ogre
+.float spikecount;
-//=============================================================================
+//======================================================================
+// TODO CEV generalize & rework projectiles
void() OgreGrenadeExplode =
{
@@ -65,38 +35,47 @@ void() OgreGrenadeExplode =
WriteCoord (MSG_BROADCAST, self.origin_y);
WriteCoord (MSG_BROADCAST, self.origin_z);
- self.velocity = '0 0 0';
- self.touch = sub_null;
- setmodel (self, "progs/s_explod.spr");
- self.solid = SOLID_NOT;
- s_explode1 ();
+ // BecomeExplosion
+ spawn (base_explosion, origin: self.origin);
+ remove (self);
};
void() OgreGrenadeTouch =
{
if (other == self.owner)
- return; // don't explode on owner
+ // don't explode on owner
+ return;
+
if (other.takedamage == DAMAGE_AIM)
{
- OgreGrenadeExplode();
+ OgreGrenadeExplode ();
return;
}
- if (self.count < time) {
- sound (self, CHAN_VOICE, "weapons/bounce.wav", 1, ATTN_NORM); // bounce sound
+
+ if (self.count < time)
+ {
+ // bounce sound
+ sound (self, CHAN_VOICE, "weapons/bounce.wav", 1, ATTN_NORM);
}
self.count = time + .02;
+
if (self.velocity == '0 0 0')
self.avelocity = '0 0 0';
};
-//BDW 31/08/00 - evil, nasty red-hot nail cluster-bomb attack... from Marcher -- dumptruck_ds
+//======================================================================
+// TODO CEV generalize & rework projectiles
+
+// BDW 31/08/00 - evil, nasty red-hot nail cluster-bomb attack...
+// from Marcher -- dumptruck_ds
void() FlakDoDamage =
{
- self.origin = self.oldenemy.origin + self.oldorigin; //get correct gib direction
- T_Damage(self.oldenemy, self, self.owner, self.oldenemy.spikecount);
+ // get correct gib direction
+ self.origin = self.oldenemy.origin + self.oldorigin;
+ T_Damage (self.oldenemy, self, self.owner, self.oldenemy.spikecount);
self.oldenemy.spikecount = 0;
- remove(self);
+ remove (self);
};
void() FlakTouch =
@@ -106,26 +85,26 @@ void() FlakTouch =
if (pointcontents(self.origin) == CONTENT_SKY)
{
- remove(self);
+ remove (self);
return;
}
-// hit something that bleeds
+ // hit something that bleeds
if (other.takedamage)
{
spawn_touchblood(self.dmg);
sound(self, CHAN_VOICE, "fish/bite.wav", 1, ATTN_NORM);
- if (other.spikecount) //not the first one
+ if (other.spikecount)
{
+ // not the first one
other.spikecount = other.spikecount + self.dmg;
remove(self);
return;
}
// the first one...
-
other.spikecount = self.dmg;
// stick around for a little while...
@@ -133,7 +112,8 @@ void() FlakTouch =
self.solid = SOLID_NOT;
self.touch = sub_null;
self.model = string_null;
- self.oldorigin = self.origin - other.origin; //displacement from enemy origin (its gonna move next frame)
+ // displacement from enemy origin (its gonna move next frame)
+ self.oldorigin = self.origin - other.origin;
self.oldenemy = other;
self.think = FlakDoDamage;
self.nextthink = time + 0.05;
@@ -146,428 +126,34 @@ void() FlakTouch =
WriteCoord (MSG_BROADCAST, self.origin_y);
WriteCoord (MSG_BROADCAST, self.origin_z);
- if (self.spawnflags & MONSTER_FLAK_OGRE) //bit of a hack
+ // bit of a hack
+ if (self.spawnflags & MONSTER_FLAK_OGRE)
{
- remove(self);
+ remove (self);
return;
}
- self.dmg = self.dmg - 5; //gets weaker with each bounce. also stops them getting stuck in world.
+ // gets weaker with each bounce. also stops them getting stuck in world.
+ self.dmg = self.dmg - 5;
if (self.dmg <= 0)
{
- remove(self);
+ remove (self);
return;
}
- self.velocity = self.velocity * 0.5; //reduce crazy ricochets
+ // reduce crazy ricochets
+ self.velocity = self.velocity * 0.5;
self.movetype = MOVETYPE_BOUNCE;
};
-void() BDW_OgreFireFlak =
-{
- local float flakcount;
- local vector dir, ang;
- local entity flak;
- local float projspeed = 800 * self.proj_speed_mod;
-
- flakcount = 8;
-
- self.effects = self.effects | EF_MUZZLEFLASH;
- sound(self, CHAN_WEAPON, "weapons/spike2.wav", 1, ATTN_NORM);
-
-// make angles out of the current displacement vector...
- ang = vectoangles(self.enemy.origin - self.origin);
-// then get the required components...
- makevectors(ang);
-
- while (flakcount > 0)
- {
- //tighter spread...
- dir = v_forward*10 + crandom()*v_right + crandom()*v_up;
- dir = normalize(dir);
- // f*cking hack...is this a v_forward problem?
- dir_z = dir_z * -1;
- //dir = dir*1000;
- //dir = dir*800;
-
-
- flak = spawn();
-
- flak.owner = self;
- //flymissile is a bit too all-seeing for this gun...
- flak.movetype = MOVETYPE_FLY;
- //flak.movetype = MOVETYPE_FLYMISSILE;
- flak.solid = SOLID_BBOX;
- flak.flags = FL_NOSELECT;
- flak.touch = FlakTouch;
- flak.angles = vectoangles(dir);
- SetSpeed(flak, dir, projspeed);
- if (self.homing > 0)
- {
- SetupHoming(flak, projspeed);
- }
- else
- {
- flak.nextthink = time + 6;
- flak.think = sub_remove;
- }
- flak.dmg = 4;
-
- flak.spawnflags = MONSTER_FLAK_OGRE; //this is a hack to tell FlakTouch that it came from an ogre
- // setmodel(flak, "progs/spike.mdl");
- flak.skin = self.skin_proj; //dumptruck_ds
-
- if (self.mdl_proj != "") // dumptruck_ds
- {
- setmodel (flak, self.mdl_proj);
- }
- else
- {
- setmodel (flak, "progs/spike.mdl");
- }
-
- if (!flak.skin_proj) // dumptruck_ds
- {
- flak.skin = self.skin_proj;
- }
- else
- {
- flak.skin = 0;
- }
- // dumptruck_ds - end
-
- setsize(flak, '0 0 0', '0 0 0');
- setorigin(flak, self.origin + '0 0 16');
-
- flakcount = flakcount - 1;
- }
-};
-/////////////////////////////////////////////////////////////
-/* start Preach Ogre Marksman tutorial here -- dumptruck_ds*/
-/////////////////////////////////////////////////////////////
-
-//speed an ogre grenade is fired at
-float OGRE_G_VEL = 600;
-
-//fixme: get the correct gravity strength for the level
-float pgrav = 800;
-
-//a default angle to fire at if the enemy is too far away
-float OGRE_DEFAULT_ELEVATION = 30;
-
-//uses QuakeC builtins to calculate tan of angle
-//WARNING: uses makevectors! This overwrites the v_forward... globals
-float(float theta) tan =
-{
- local vector ang; //temporary used to calculate trig values
- ang = '0 0 0';
- ang_y = theta; //assign theta to the yaw to simplify reasoning
- makevectors(ang);
- return v_forward_y / v_forward_x;
-}
-
-//inverse tan function
-//takes two parameters, numerator and denominator
-//this copes better with denominator 0 and gets quadrant correct
-/*
-float(float y, float x) atan2 =
-{
- local vector ang; //temporary used to calculate trig values
- ang = '0 0 0';
- ang_x = x;
- ang_y = y;
- return vectoyaw(ang);
-}
-*/
-
-float(float theta, vector dest) IterateElevation =
-{
- local float a, b, c; //constants in the equation to be solved
- local vector ofs; //displacement we wish the projectile to travel
- local float y, z; //horizontal and vertical components of ofs
- local float tan_theta; //trig values of the angle theta
-
- //calculate how far we are firing
- ofs = dest - self.origin;
- z = ofs_z;
- ofs_z = 0;
- y = vlen(ofs);
-
- //find the coefficients of the quadratic in tan(theta)
- a = 0.5 * pgrav * y * y / (OGRE_G_VEL * OGRE_G_VEL);
- b = -y;
- c = a + z;
-
- //check if the destination is too far to reach
- if(b*b < 4*a*c)
- return OGRE_DEFAULT_ELEVATION;
-
- //calculate the tan value of the given theta
- tan_theta = tan(theta);
-
- //reuse ang to create the improved firing direction
- theta = atan2(a*tan_theta*tan_theta - c,
- 2*a*tan_theta + b);
-
- //constrain the values to stop anything too mad happening
- while(theta > 90)
- theta = theta - 180;
- return theta;
-}
-/*
-================
-PreachFireGrenade
-================
-*/
-void(float elevation) PreachFireGrenade =
-{
- local entity missile;
- local vector ang;
-
- self.effects = self.effects | EF_MUZZLEFLASH;
-
- sound (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
-
- missile = spawn ();
- missile.owner = self;
- missile.movetype = MOVETYPE_BOUNCE;
- missile.solid = SOLID_BBOX;
-
-// set missile speed
- ang = self.angles;
- ang_x = -elevation;
- makevectors (ang);
-
- missile.velocity = v_forward * OGRE_G_VEL;
-
- missile.avelocity = '300 300 300';
-
- missile.angles = vectoangles(missile.velocity);
-
- missile.touch = OgreGrenadeTouch;
-
-// set missile duration
- missile.nextthink = time + 2.5;
- missile.think = OgreGrenadeExplode;
- // setmodel (missile, "progs/grenade.mdl");
- if (self.mdl_proj != "") // dumptruck_ds
- {
- setmodel (missile, self.mdl_proj);
- }
- else
- {
- setmodel (missile, "progs/grenade.mdl");
- }
-
- if (!missile.skin_proj) // dumptruck_ds
- {
- missile.skin = self.skin_proj;
- }
- else
- {
- missile.skin = 0;
- }
-
- setsize (missile, '0 0 0', '0 0 0');
- setorigin (missile, self.origin);
-};
-
-// end Preach tutorial
-
-/*
-================
-PreachFireZombie
-for Z-Aware Zombies in Turret Mode only
-================
-*/
-void(float elevation) PreachFireZombie =
-{
- local entity missile;
- local vector ang;
-
- // self.effects = self.effects | EF_MUZZLEFLASH;
-
- sound_attack (self, CHAN_WEAPON, "zombie/z_shot1.wav", 1, ATTN_NORM);
-
- missile = spawn ();
- missile.owner = self;
- missile.movetype = MOVETYPE_BOUNCE;
- missile.solid = SOLID_BBOX;
-
-// set missile speed
- ang = self.angles;
- ang_x = -elevation;
- makevectors (ang);
-
- missile.velocity = v_forward * OGRE_G_VEL;
-
- missile.avelocity = '3000 1000 2000';
-
- missile.angles = vectoangles(missile.velocity);
-
- missile.touch = ZombieGrenadeTouch;
-
-// set missile duration
- missile.nextthink = time + 2.5;
- missile.think = sub_remove;
- // setmodel (missile, "progs/grenade.mdl");
- if (self.mdl_proj != "") // dumptruck_ds
- {
- setmodel (missile, self.mdl_proj);
- }
- else
- {
- setmodel (missile, "progs/zom_gib.mdl");
- }
-
- if (!missile.skin_proj) // dumptruck_ds
- {
- missile.skin = self.skin_proj;
- }
- else
- {
- missile.skin = 0;
- }
-
- setsize (missile, '0 0 0', '0 0 0');
- setorigin (missile, self.origin);
-};
-
-// end Preach tutorial
-
-/*
-================
-OgreFireGrenade
-================
-*/
-void() MultiGrenadeTouch;
-void() MultiGrenadeExplode;
-
-void() OgreFireGrenade =
-{
- local entity missile;
-
- self.effects = self.effects | EF_MUZZLEFLASH;
-
- sound (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
-
- missile = spawn ();
- missile.owner = self;
- missile.movetype = MOVETYPE_BOUNCE;
- missile.solid = SOLID_BBOX;
- missile.skin = self.skin_proj; //dumptruck_ds
-
- if (self.mdl_proj != "") // dumptruck_ds
- {
- setmodel (missile, self.mdl_proj);
- }
- else
- {
- setmodel (missile, "progs/grenade.mdl");
- }
-
- if (!missile.skin_proj) // dumptruck_ds
- {
- missile.skin = self.skin_proj;
- }
- else
- {
- missile.skin = 0;
- }
-// dumptruck_ds - end
-// set missile speed
-
- makevectors (self.angles);
- missile.velocity = normalize(self.enemy.origin - self.origin);
- missile.velocity = missile.velocity * 600;
- missile.velocity_z = 200;
- missile.avelocity = '300 300 300';
- missile.angles = vectoangles(missile.velocity);
-
- // set missile duration
- if(self.style == 3)
- {
- missile.touch = MultiGrenadeTouch;
- missile.nextthink = time + 2.5;
- missile.think = MultiGrenadeExplode;
- setmodel (missile, "progs/mervup.mdl");
- setsize (missile, '0 0 0', '0 0 0');
- setorigin (missile, self.origin);
- missile.classname = "MultiGrenade";
- }
- else
- {
- missile.touch = OgreGrenadeTouch;
- missile.nextthink = time + 2.5;
- missile.think = OgreGrenadeExplode;
- // setmodel (missile, "progs/grenade.mdl");
- setsize (missile, '0 0 0', '0 0 0');
- setorigin (missile, self.origin);
- }
- };
-
- // missile.touch = OgreGrenadeTouch;
-
-// // set missile duration
-// missile.nextthink = time + 2.5;
-// missile.think = OgreGrenadeExplode;
-//
-// setmodel (missile, "progs/grenade.mdl");
-// setsize (missile, '0 0 0', '0 0 0');
-// setorigin (missile, self.origin);
-// };
-
-/*
-================
-OgreFireSpike from insideqc tutorial here: http://www.insideqc.com/qctut/lesson-33.shtml
-================
-*/
-void() OgreFireSpike =
-{
- local vector dir;
- // local entity old;
-
-
- sound (self, CHAN_WEAPON, "weapons/spike2.wav", 1, ATTN_NORM);
- self.attack_finished = time + .7;
- // self.attack_finished = time + 0.2;
- self.effects = self.effects | EF_MUZZLEFLASH; // -- dumptruck_ds
-
- dir = normalize (self.enemy.origin - self.origin);
+//======================================================================
- launch_spike (self.origin + v_right * 4 + '0 0 16', dir);
+// TODO CEV generalize & rework projectiles
- newmis.touch = superduperspike_touch; //dumptruck_ds found in client.qc
- // setmodel (newmis, "progs/lspike.mdl");
- newmis.skin = self.skin_proj; //dumptruck_ds
-
- if (self.mdl_proj != "") // dumptruck_ds
- {
- setmodel (newmis, self.mdl_proj);
- }
- else
- {
- setmodel (newmis, "progs/lspike.mdl");
- }
-
- if (!newmis.skin_proj) // dumptruck_ds
- {
- newmis.skin = self.skin_proj;
- }
- else
- {
- newmis.skin = 0;
- }
- // dumptruck_ds - end
-
- setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
-};
-//=============================================================================
+//----------------------------------------------------------------------
// Multi Grenade Code from doe progs MULT_WPN.QC -- dumptruck_ds
-//=============================================================================
-void() MultiGrenadeTouch;
+//----------------------------------------------------------------------
-//================================
-//================================
+//----------------------------------------------------------------------
void() MiniGrenadeExplode =
{
if ( self.owner.classname == "player")
@@ -580,18 +166,19 @@ void() MiniGrenadeExplode =
WriteCoord (MSG_BROADCAST, self.origin_x);
WriteCoord (MSG_BROADCAST, self.origin_y);
WriteCoord (MSG_BROADCAST, self.origin_z);
- WriteByte (MSG_BROADCAST, 230);
- WriteByte (MSG_BROADCAST, 5);
+ WriteByte (MSG_BROADCAST, 230);
+ WriteByte (MSG_BROADCAST, 5);
- BecomeExplosion ();
+ // BecomeExplosion
+ spawn (base_explosion, origin: self.origin);
+ remove (self);
};
-//================================
-//================================
+//----------------------------------------------------------------------
void(float offsetAngle) MiniGrenadeLaunch =
{
- local entity missile/*, mpuff*/;
- local float tempRand;
+ local entity missile/*, mpuff*/;
+ local float tempRand;
missile = spawn ();
missile.owner = self.owner;
@@ -599,61 +186,61 @@ void(float offsetAngle) MiniGrenadeLaunch =
missile.solid = SOLID_BBOX;
missile.classname = "MiniGrenade";
-// set missile speed
+ // set missile speed
missile.v_angle = self.v_angle;
missile.v_angle_y = missile.v_angle_y + offsetAngle;
makevectors (missile.v_angle);
- missile.velocity = v_forward*100 + v_up*400;
- tempRand = (crandom()*60) - 30;
- missile.velocity = missile.velocity + tempRand * v_forward;
- tempRand = (crandom()*40) - 20;
- missile.velocity = missile.velocity + tempRand * v_right;
- tempRand = (crandom()*60) - 30;
- missile.velocity = missile.velocity + tempRand * v_up;
+ missile.velocity = v_forward * 100 + v_up * 400;
+ tempRand = (crandom() * 60) - 30;
+ missile.velocity = missile.velocity + tempRand * v_forward;
+ tempRand = (crandom() * 40) - 20;
+ missile.velocity = missile.velocity + tempRand * v_right;
+ tempRand = (crandom() * 60) - 30;
+ missile.velocity = missile.velocity + tempRand * v_up;
missile.avelocity = '300 300 300';
- missile.angles = vectoangles(missile.velocity);
+ missile.angles = vectoangles (missile.velocity);
missile.touch = MultiGrenadeTouch;
setmodel (missile, "progs/mervup.mdl");
setsize (missile, '0 0 0', '0 0 0');
setorigin (missile, self.origin);
-// set missile duration
+ // set missile duration
missile.nextthink = time + 1 + (crandom() * 0.5);
missile.think = MiniGrenadeExplode;
};
-//================================
-//================================
+//----------------------------------------------------------------------
void() MultiGrenadeExplode =
{
- MiniGrenadeLaunch(0);
- MiniGrenadeLaunch(72);
- MiniGrenadeLaunch(144);
- MiniGrenadeLaunch(216);
- MiniGrenadeLaunch(288);
+ MiniGrenadeLaunch (0);
+ MiniGrenadeLaunch (72);
+ MiniGrenadeLaunch (144);
+ MiniGrenadeLaunch (216);
+ MiniGrenadeLaunch (288);
remove (self);
};
-//================================
-//================================
+//----------------------------------------------------------------------
void() MultiGrenadeTouch =
{
if (other == self.owner)
- return; // don't explode on owner
+ // don't explode on owner
+ return;
+
if (other.takedamage == DAMAGE_AIM)
{
if (self.classname == "MiniGrenade")
- MiniGrenadeExplode();
+ MiniGrenadeExplode ();
else
{
if (self.owner.classname == "player")
- GrenadeExplode();
+ GrenadeExplode ();
else
- MiniGrenadeExplode();
+ MiniGrenadeExplode ();
}
return;
}
@@ -663,619 +250,1283 @@ void() MultiGrenadeTouch =
self.avelocity = '0 0 0';
};
-//================================
-//================================
-void() W_FireMultiGrenade =
-{
- local entity missile/*, mpuff*/;
+//----------------------------------------------------------------------
+// end doe qc -- dumptruck_ds
+//----------------------------------------------------------------------
- // self.currentammo = self.ammo_multi_rockets = self.ammo_multi_rockets - 1;
- // UpdateAmmoCounts (self);
+//======================================================================
+// frame macros
+//======================================================================
+$cd id1/models/ogre_c
+$origin 0 0 24
+$base base
+$skin base
- sound (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
+$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9
- // self.punchangle_x = -2;
+$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7
+$frame walk8 walk9 walk10 walk11 walk12 walk13 walk14 walk15 walk16
- missile = spawn ();
- missile.owner = self;
- missile.movetype = MOVETYPE_BOUNCE;
- missile.solid = SOLID_BBOX;
- missile.classname = "MultiGrenade";
+$frame run1 run2 run3 run4 run5 run6 run7 run8
- makevectors (self.angles);
- missile.velocity = normalize(self.enemy.origin - self.origin);
- missile.velocity = missile.velocity * 600;
- missile.velocity_z = 200;
- missile.avelocity = '300 300 300';
- missile.angles = vectoangles(missile.velocity);
-
-
-// set missile speed
- // makevectors (self.v_angle);
- // if (self.v_angle_x)
- // missile.velocity = v_forward*600 + v_up * 200 + crandom()*v_right*10 + crandom()*v_up*10;
- // else
- // {
- // missile.velocity = aim(self, 10000);
- // missile.velocity = missile.velocity * 600;
- // missile.velocity_z = 200;
- // }
- //
- // missile.avelocity = '300 300 300';
- // missile.angles = vectoangles(missile.velocity);
- missile.touch = MultiGrenadeTouch;
+$frame swing1 swing2 swing3 swing4 swing5 swing6 swing7
+$frame swing8 swing9 swing10 swing11 swing12 swing13 swing14
-// set missile duration
- missile.nextthink = time + 1;
- missile.think = MultiGrenadeExplode;
- setmodel (missile, "progs/mervup.mdl");
- missile.skin = self.skin_proj; //dumptruck_ds
+$frame smash1 smash2 smash3 smash4 smash5 smash6 smash7
+$frame smash8 smash9 smash10 smash11 smash12 smash13 smash14
- setsize (missile, '0 0 0', '0 0 0');
- setorigin (missile, self.origin + '0 0 16');
-};
+$frame shoot1 shoot2 shoot3 shoot4 shoot5 shoot6
-//=============================================================================
-//end doe qc -- dumptruck_ds
-//=============================================================================
-/*
-================
-OgreFireLavaBall by jaycie erysdren 2021-09-14
-================
-*/
+$frame pain1 pain2 pain3 pain4 pain5
-void() OgreFireLavaBall =
-{
- local vector offang;
- local vector org, vec, d;
- // local float t;
-
- offang = vectoangles (self.enemy.origin - self.origin);
- makevectors (offang);
-
- org = self.origin; // + p_x*v_forward + p_y*v_right + p_z*'0 0 1';
-
-// lead the player on hard mode
- // if (skill > 1)
- // {
- // t = vlen(self.enemy.origin - org) / 300;
- // vec = self.enemy.velocity;
- // vec_z = 0;
- // d = self.enemy.origin + t * vec;
- // }
- // else
- // {
- d = self.enemy.origin;
- // }
-
- vec = normalize (d - org);
-
- // launch_spike (org, vec);
- launch_spike2 (self.origin + v_right * 4 + '0 0 16', vec, 600);
- self.effects = self.effects | EF_MUZZLEFLASH;
- if (self.mdl_proj != "") // dumptruck_ds custom_mdls
- {
- setmodel (newmis, self.mdl_proj);
- }
- else
- {
- setmodel (newmis, "progs/lavaball.mdl");
- }
+$frame painb1 painb2 painb3
+
+$frame painc1 painc2 painc3 painc4 painc5 painc6
+
+$frame paind1 paind2 paind3 paind4 paind5 paind6 paind7 paind8 paind9 paind10
+$frame paind11 paind12 paind13 paind14 paind15 paind16
+
+$frame paine1 paine2 paine3 paine4 paine5 paine6 paine7 paine8 paine9 paine10
+$frame paine11 paine12 paine13 paine14 paine15
+
+$frame death1 death2 death3 death4 death5 death6
+$frame death7 death8 death9 death10 death11 death12
+$frame death13 death14
+
+$frame bdeath1 bdeath2 bdeath3 bdeath4 bdeath5 bdeath6
+$frame bdeath7 bdeath8 bdeath9 bdeath10
+
+$frame pull1 pull2 pull3 pull4 pull5 pull6 pull7 pull8 pull9 pull10 pull11
+
+/*QUAKED monster_ogre (1 0 0) (-32 -32 -24) (32 32 64) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ("progs/ogre.mdl");
+}
+Ogre.
+
+Default health = 200"
+
+style(Choices) : "Attack type" =
+0 : "Default (grenade)"
+1 : "Flak Ogre (Marcher, Quoth)"
+2 : "sniper (shoots single, deadly lava round)"
+3 : "multi-grenade (Mission Pack 2)"
+
+keep_ammo(integer) : "1 = Don't drop backpack upon death"
+snd_death(string) : "Path to custom death sound"
+snd_pain(string) : "Path to custom pain sound"
+snd_sight(string) : "Path to custom sight sound"
+snd_attack(string) : "Path to custom attack sound (CHAINSAW)"
+snd_idle(string) : "Path to custom idle sound (IDLE)"
+snd_misc(string) : "Path to custom sound (IDLE CHAINSAW DRAG)"
+snd_misc1(string) : "Path to custom sound (ATTACK GRUNT)"
+
+mdl_head(string) : "Path to custom head model"
+mdl_body(string) : "Path to custom body model"
+mdl_proj(string) : "Path to custom projectile model"
+skin_head(float) : "Skin index of custom head model"
+skin_proj(float) : "Skin index of custom projectile model"
+mdl_gib1(string) : "Path to custom 1st gib model"
+mdl_gib2(string) : "Path to custom 2nd gib model"
+mdl_gib3(string) : "Path to custom 3rd gib model"
+
+effects(choices) : "Add a visual effect to an entity"
+0 : "None (Default)"
+1 : "Brightfield (yellow particles)"
+4 : "Bright light"
+8 : "Dim light"
+
+berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
+0 : "Off (Default)"
+1 : "Berserk (skip pain animations)"
+
+delay(float) : "Delay spawn in for this amount of time"
- if (!newmis.skin_proj) // dumptruck_ds
+wait(choices) : "Play an effect when trigger spawned?"
+0 : "Teleport Effects (Default)"
+1 : "Spawn Silently"
+
+spawn_angry(Choices)
+0 : "Only when trigger spawned, default behavior - not angry"
+1 : "Only when trigger spawned, set to 1 to spawn angry at player"
+
+infight_mode(Choices)
+0 : "Default behavior, only with different classnames"
+1 : "Infight with monsters with the same classname but a different mdl_body"
+2 : "Infight with monsters with the same classname and model but a different skin"
+3 : "Infight no matter what"
+
+health(integer) : "Set this to a custom health amount"
+pain_target(string) : "Fire this target when pain_threshold is reached"
+pain_threshold(integer) : "Fire pain_target when health drops below this amount"
+sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
+skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
+obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
+obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
+damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
+
+*/
+class monster_ogre: base_walkmonster
+{
+ float attack_elevation;
+
+ //--------------------------------------------------------------
+ virtual void() ai_sightsound =
{
- newmis.skin = self.skin_proj;
+ sound_sight (this, CHAN_VOICE, "ogre/ogwake.wav",
+ 1, ATTN_NORM);
+ };
+
+ //--------------------------------------------------------------
+ // OgreCheckAttack
+ // The player is in view, so decide to move or launch an attack
+ // Returns FALSE if movement should continue
+ //--------------------------------------------------------------
+ virtual float() ai_checkattack =
+ {
+ local vector spot1, spot2;
+ local entity targ;
+ local float chance;
+
+ // dprint("OgreCheckAttack\n");
+ // dumptruck_ds
+ if (this.spawnflags & I_AM_TURRET)
+ {
+ this.attack_state = AS_MISSILE;
+ sub_attackfinished (2 + 2 * random());
+ return TRUE;
}
+
+ if (enemy_range == RANGE_MELEE)
+ {
+ if (CanDamage (this.enemy, this))
+ {
+ this.attack_state = AS_MELEE;
+ return TRUE;
+ }
+ }
+
+ if (time < this.attack_finished)
+ return FALSE;
+
+ if (!enemy_vis)
+ return FALSE;
+
+ targ = this.enemy;
+
+ // see if any entities are in the way of the shot
+ spot1 = this.origin + this.view_ofs;
+ spot2 = targ.origin + targ.view_ofs;
+
+ traceline (spot1, spot2, FALSE, this);
+
+ if (trace_inopen && trace_inwater)
+ // sight line crossed contents
+ return FALSE;
+
+ if ((this.spawnflags & I_AM_TURRET) && (trace_ent != targ))
+ {
+ // dprint("trace_ent...\n");
+ this.attack_state = AS_TURRET;
+ return FALSE;
+ }
+
+ if (trace_ent != targ)
+ // don't have a clear shot
+ return FALSE;
+
+ // missile attack
+ if (time < this.attack_finished)
+ return FALSE;
+
+ if (enemy_range == RANGE_FAR)
+ return FALSE;
+ else if (enemy_range == RANGE_NEAR)
+ chance = 0.10;
+ else if (enemy_range == RANGE_MID)
+ chance = 0.05;
else
+ chance = 0;
+
+ this.attack_state = AS_MISSILE;
+ sub_attackfinished (1 + 2 * random());
+ return TRUE;
+ };
+
+ //--------------------------------------------------------------
+ // BDW_OgreFireFlak
+ //--------------------------------------------------------------
+ nonvirtual void() attack_flak =
+ {
+ local float flakcount;
+ local vector dir, ang;
+ local entity flak;
+ local float projspeed = 800 * this.proj_speed_mod;
+
+ flakcount = 8;
+
+ this.effects = this.effects | EF_MUZZLEFLASH;
+ sound (this, CHAN_WEAPON, "weapons/spike2.wav", 1, ATTN_NORM);
+
+ // make angles out of the current displacement vector...
+ ang = vectoangles (this.enemy.origin - this.origin);
+ // then get the required components...
+ makevectors (ang);
+
+ while (flakcount > 0)
{
- newmis.skin = 0;
- }
- newmis.avelocity = self.cust_avelocity;
- if !(newmis.avelocity)
- newmis.avelocity = '200 100 300';
- setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
- // newmis.touch = T_MissileTouch; // rocket explosion
- newmis.touch = OgreGrenadeExplode;
- sound_attack (self, CHAN_AUTO, "boss1/throw.wav", 1, ATTN_NORM);
+ //tighter spread...
+ dir = v_forward * 10 + crandom() *
+ v_right + crandom() * v_up;
+ dir = normalize (dir);
+ // f*cking hack...is this a v_forward problem?
+ dir_z = dir_z * -1;
+ // dir = dir * 1000;
+ // dir = dir * 800;
+
+ flak = spawn ();
+ flak.owner = this;
+ // flymissile is a bit too all-seeing for this gun...
+ flak.movetype = MOVETYPE_FLY;
+ // flak.movetype = MOVETYPE_FLYMISSILE;
+ flak.solid = SOLID_BBOX;
+ flak.flags = FL_NOSELECT;
+ flak.touch = FlakTouch;
+ flak.angles = vectoangles (dir);
+ SetSpeed (flak, dir, projspeed);
+ if (this.homing > 0)
+ {
+ SetupHoming (flak, projspeed);
+ }
+ else
+ {
+ flak.nextthink = time + 6;
+ flak.think = sub_remove;
+ }
+ flak.dmg = 4;
-};
+ // this is a hack to tell FlakTouch that it came
+ // from an ogre
+ flak.spawnflags = MONSTER_FLAK_OGRE;
+ // setmodel (flak, "progs/spike.mdl");
+ // dumptruck_ds
+ flak.skin = this.skin_proj;
-/*
-================
-chainsaw
+ // dumptruck_ds
+ if (this.mdl_proj != "")
+ {
+ setmodel (flak, this.mdl_proj);
+ }
+ else
+ {
+ setmodel (flak, "progs/spike.mdl");
+ }
-FIXME
-================
-*/
-void(float side) chainsaw =
-{
-local vector delta;
-local float ldmg;
+ // dumptruck_ds
+ if (!flak.skin_proj)
+ {
+ flak.skin = this.skin_proj;
+ }
+ else
+ {
+ flak.skin = 0;
+ }
+ // dumptruck_ds - end
- if (!self.enemy)
- return;
- if (!CanDamage (self.enemy, self))
- return;
+ setsize (flak, '0 0 0', '0 0 0');
+ setorigin (flak, this.origin + '0 0 16');
+
+ flakcount = flakcount - 1;
+ }
+ };
- ai_charge(10);
+ //--------------------------------------------------------------
+ // OgreFireGrenade
+ //--------------------------------------------------------------
+ nonvirtual void() attack_grenade =
+ {
+ local entity missile;
- delta = self.enemy.origin - self.origin;
+ this.effects = this.effects | EF_MUZZLEFLASH;
- if (vlen(delta) > 100)
- return;
+ sound (this, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
+
+ missile = spawn ();
+ missile.owner = this;
+ missile.movetype = MOVETYPE_BOUNCE;
+ missile.solid = SOLID_BBOX;
+ // dumptruck_ds
+ missile.skin = this.skin_proj;
+
+ // dumptruck_ds
+ if (this.mdl_proj != "")
+ {
+ setmodel (missile, this.mdl_proj);
+ }
+ else
+ {
+ setmodel (missile, "progs/grenade.mdl");
+ }
- ldmg = (random() + random() + random()) * 4;
- T_Damage (self.enemy, self, self, ldmg);
+ // dumptruck_ds
+ if (!missile.skin_proj)
+ {
+ missile.skin = this.skin_proj;
+ }
+ else
+ {
+ missile.skin = 0;
+ }
+ // dumptruck_ds - end
+
+ // set missile speed
+ makevectors (this.angles);
+ missile.velocity = normalize (this.enemy.origin - this.origin);
+ missile.velocity = missile.velocity * 600;
+ missile.velocity_z = 200;
+ missile.avelocity = '300 300 300';
+ missile.angles = vectoangles (missile.velocity);
+
+ // set missile duration
+ if (this.style == 3)
+ {
+ missile.touch = MultiGrenadeTouch;
+ missile.nextthink = time + 2.5;
+ missile.think = MultiGrenadeExplode;
+ setmodel (missile, "progs/mervup.mdl");
+ setsize (missile, '0 0 0', '0 0 0');
+ setorigin (missile, this.origin);
+ missile.classname = "MultiGrenade";
+ }
+ else
+ {
+ missile.touch = OgreGrenadeTouch;
+ missile.nextthink = time + 2.5;
+ missile.think = OgreGrenadeExplode;
+ // setmodel (missile, "progs/grenade.mdl");
+ setsize (missile, '0 0 0', '0 0 0');
+ setorigin (missile, this.origin);
+ }
+
+ // missile.touch = OgreGrenadeTouch;
- if (side)
+ // set missile duration
+ // missile.nextthink = time + 2.5;
+ // missile.think = OgreGrenadeExplode;
+ //
+ // setmodel (missile, "progs/grenade.mdl");
+ // setsize (missile, '0 0 0', '0 0 0');
+ // setorigin (missile, self.origin);
+ };
+
+ //--------------------------------------------------------------
+ // PreachFireGrenade
+ //--------------------------------------------------------------
+ nonvirtual void(float elevation) attack_preach_grenade =
{
- makevectors (self.angles);
- if (side == 1)
- SpawnMeatSpray (self.origin + v_forward*16, crandom() * 100 * v_right);
+ local entity missile;
+ local vector ang;
+
+ this.effects = this.effects | EF_MUZZLEFLASH;
+
+ sound (this, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
+
+ missile = spawn ();
+ missile.owner = this;
+ missile.movetype = MOVETYPE_BOUNCE;
+ missile.solid = SOLID_BBOX;
+
+ // set missile speed
+ ang = this.angles;
+ ang_x = -elevation;
+ makevectors (ang);
+
+ missile.velocity = v_forward * OGRE_G_VEL;
+ missile.avelocity = '300 300 300';
+ missile.angles = vectoangles(missile.velocity);
+ missile.touch = OgreGrenadeTouch;
+
+ // set missile duration
+ missile.nextthink = time + 2.5;
+ missile.think = OgreGrenadeExplode;
+ // setmodel (missile, "progs/grenade.mdl");
+ // dumptruck_ds
+ if (this.mdl_proj != "")
+ {
+ setmodel (missile, this.mdl_proj);
+ }
else
- SpawnMeatSpray (self.origin + v_forward*16, side * v_right);
- }
-};
+ {
+ setmodel (missile, "progs/grenade.mdl");
+ }
-void() ogre_stand1 =[ $stand1, ogre_stand2 ] {ai_stand();};
-void() ogre_stand2 =[ $stand2, ogre_stand3 ] {ai_stand();};
-void() ogre_stand3 =[ $stand3, ogre_stand4 ] {ai_stand();};
-void() ogre_stand4 =[ $stand4, ogre_stand5 ] {ai_stand();};
-void() ogre_stand5 =[ $stand5, ogre_stand6 ] {
-if (random() < 0.2)
- sound_idle (self, CHAN_VOICE, "ogre/ogidle.wav", 1, ATTN_IDLE);
-ai_stand();
-};
-void() ogre_stand6 =[ $stand6, ogre_stand7 ] {ai_stand();};
-void() ogre_stand7 =[ $stand7, ogre_stand8 ] {ai_stand();};
-void() ogre_stand8 =[ $stand8, ogre_stand9 ] {ai_stand();};
-void() ogre_stand9 =[ $stand9, ogre_stand1 ] {ai_stand();};
-
-void() ogre_walk1 =[ $walk1, ogre_walk2 ] {ai_walk(3);};
-void() ogre_walk2 =[ $walk2, ogre_walk3 ] {ai_walk(2);};
-void() ogre_walk3 =[ $walk3, ogre_walk4 ] {
-ai_walk(2);
-if (random() < 0.2)
- sound_idle (self, CHAN_VOICE, "ogre/ogidle.wav", 1, ATTN_IDLE);
-};
-void() ogre_walk4 =[ $walk4, ogre_walk5 ] {ai_walk(2);};
-void() ogre_walk5 =[ $walk5, ogre_walk6 ] {ai_walk(2);};
-void() ogre_walk6 =[ $walk6, ogre_walk7 ] {
-ai_walk(5);
-if (random() < 0.1)
- sound_misc (self, CHAN_VOICE, "ogre/ogdrag.wav", 1, ATTN_IDLE);
-};
-void() ogre_walk7 =[ $walk7, ogre_walk8 ] {ai_walk(3);};
-void() ogre_walk8 =[ $walk8, ogre_walk9 ] {ai_walk(2);};
-void() ogre_walk9 =[ $walk9, ogre_walk10 ] {ai_walk(3);};
-void() ogre_walk10 =[ $walk10, ogre_walk11 ] {ai_walk(1);};
-void() ogre_walk11 =[ $walk11, ogre_walk12 ] {ai_walk(2);};
-void() ogre_walk12 =[ $walk12, ogre_walk13 ] {ai_walk(3);};
-void() ogre_walk13 =[ $walk13, ogre_walk14 ] {ai_walk(3);};
-void() ogre_walk14 =[ $walk14, ogre_walk15 ] {ai_walk(3);};
-void() ogre_walk15 =[ $walk15, ogre_walk16 ] {ai_walk(3);};
-void() ogre_walk16 =[ $walk16, ogre_walk1 ] {ai_walk(4);};
-
-void() ogre_run1 =[ $run1, ogre_run2 ] {ai_run(9);
-if (random() < 0.2)
- sound_misc1 (self, CHAN_VOICE, "ogre/ogidle2.wav", 1, ATTN_IDLE);
-};
-void() ogre_run2 =[ $run2, ogre_run3 ] {ai_run(12);};
-void() ogre_run3 =[ $run3, ogre_run4 ] {ai_run(8);};
-void() ogre_run4 =[ $run4, ogre_run5 ] {ai_run(22);};
-void() ogre_run5 =[ $run5, ogre_run6 ] {ai_run(16);};
-void() ogre_run6 =[ $run6, ogre_run7 ] {ai_run(4);};
-void() ogre_run7 =[ $run7, ogre_run8 ] {ai_run(13);};
-void() ogre_run8 =[ $run8, ogre_run1 ] {ai_run(24);};
-
-void() ogre_swing1 =[ $swing1, ogre_swing2 ] {ai_charge(11);
-sound_attack (self, CHAN_WEAPON, "ogre/ogsawatk.wav", 1, ATTN_NORM);
-};
-void() ogre_swing2 =[ $swing2, ogre_swing3 ] {ai_charge(1);};
-void() ogre_swing3 =[ $swing3, ogre_swing4 ] {ai_charge(4);};
-void() ogre_swing4 =[ $swing4, ogre_swing5 ] {ai_charge(13);};
-void() ogre_swing5 =[ $swing5, ogre_swing6 ] {ai_charge(9); chainsaw(0);self.angles_y = self.angles_y + random()*25;};
-void() ogre_swing6 =[ $swing6, ogre_swing7 ] {chainsaw(200);self.angles_y = self.angles_y + random()* 25;};
-void() ogre_swing7 =[ $swing7, ogre_swing8 ] {chainsaw(0);self.angles_y = self.angles_y + random()* 25;};
-void() ogre_swing8 =[ $swing8, ogre_swing9 ] {chainsaw(0);self.angles_y = self.angles_y + random()* 25;};
-void() ogre_swing9 =[ $swing9, ogre_swing10 ] {chainsaw(0);self.angles_y = self.angles_y + random()* 25;};
-void() ogre_swing10 =[ $swing10, ogre_swing11 ] {chainsaw(-200);self.angles_y = self.angles_y + random()* 25;};
-void() ogre_swing11 =[ $swing11, ogre_swing12 ] {chainsaw(0);self.angles_y = self.angles_y + random()* 25;};
-void() ogre_swing12 =[ $swing12, ogre_swing13 ] {ai_charge(3);};
-void() ogre_swing13 =[ $swing13, ogre_swing14 ] {ai_charge(8);};
-void() ogre_swing14 =[ $swing14, ogre_run1 ] {ai_charge(9);};
-
-void() ogre_smash1 =[ $smash1, ogre_smash2 ] {ai_charge(6);
-sound_attack (self, CHAN_WEAPON, "ogre/ogsawatk.wav", 1, ATTN_NORM);
-};
-void() ogre_smash2 =[ $smash2, ogre_smash3 ] {ai_charge(0);};
-void() ogre_smash3 =[ $smash3, ogre_smash4 ] {ai_charge(0);};
-void() ogre_smash4 =[ $smash4, ogre_smash5 ] {ai_charge(1);};
-void() ogre_smash5 =[ $smash5, ogre_smash6 ] {ai_charge(4);};
-void() ogre_smash6 =[ $smash6, ogre_smash7 ] {ai_charge(4); chainsaw(0);};
-void() ogre_smash7 =[ $smash7, ogre_smash8 ] {ai_charge(4); chainsaw(0);};
-void() ogre_smash8 =[ $smash8, ogre_smash9 ] {ai_charge(10); chainsaw(0);};
-void() ogre_smash9 =[ $smash9, ogre_smash10 ] {ai_charge(13); chainsaw(0);};
-void() ogre_smash10 =[ $smash10, ogre_smash11 ] {chainsaw(1);};
-void() ogre_smash11 =[ $smash11, ogre_smash12 ] {ai_charge(2); chainsaw(0);
-// self.nextthink = self.nextthink + random()*0.2;}; // slight variation
-self.nextthink = time + 0.1 + random()*0.2;}; // 1998-08-14 Incorrect setting of nextthink fix by Maddes/Lord Sméagol
-void() ogre_smash12 =[ $smash12, ogre_smash13 ] {ai_charge(0);};
-void() ogre_smash13 =[ $smash13, ogre_smash14 ] {ai_charge(4);};
-void() ogre_smash14 =[ $smash14, ogre_run1 ] {ai_charge(12);};
-
-// Preach tutorial alternate animation frames for monster_ogre_marksman -- dumptruck_ds
-.float attack_elevation;
-void() ogre2_nail1 =[ $shoot1, ogre2_nail2 ] {ai_face();
-self.attack_elevation = IterateElevation(OGRE_DEFAULT_ELEVATION, self.enemy.origin);};
-void() ogre2_nail2 =[ $shoot2, ogre2_nail3 ] {ai_face();
-self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
-void() ogre2_nail3 =[ $shoot2, ogre2_nail4 ] {ai_face();
-self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
-void() ogre2_nail4 =[ $shoot3, ogre_nail5 ] {ai_face();
- PreachFireGrenade(self.attack_elevation);
-};
-// Preach tutorial alternate animation frames for monster_ogre_marksman -- dumptruck_ds
-// these are for the turret version of monster_ogre_marksman
-.float attack_elevation;
-void() ogre2_turret_attack1 =[ $shoot1, ogre2_turret_attack2 ] {ai_face();
-self.attack_elevation = IterateElevation(OGRE_DEFAULT_ELEVATION, self.enemy.origin);};
-void() ogre2_turret_attack2 =[ $shoot2, ogre2_turret_attack3 ] {ai_face();
-self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
-void() ogre2_turret_attack3 =[ $shoot2, ogre2_turret_attack4 ] {ai_face();
-self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
-void() ogre2_turret_attack4 =[ $shoot3, ogre2_turret_attack5 ] {ai_face();
- PreachFireGrenade(self.attack_elevation);};
-void() ogre2_turret_attack5 =[ $shoot4, ogre2_turret_attack6 ] {ai_face();};
-void() ogre2_turret_attack6 =[ $shoot5, ogre2_turret_attack7 ] {ai_face();};
-void() ogre2_turret_attack7 =[ $shoot5, ogre2_turret_attack8 ] {ai_face();};
-void() ogre2_turret_attack8 =[ $shoot6, ogre2_turret_attack9 ] {ai_face();};
-void() ogre2_turret_attack9 =[ $shoot6, ogre2_turret_seek1 ] {ai_face();};
-void() ogre2_turret_seek1 =[ $stand1, ogre2_turret_seek2 ] {ai_run(0);};
-void() ogre2_turret_seek2 =[ $stand2, ogre2_turret_seek3 ] {ai_run(0);};
-void() ogre2_turret_seek3 =[ $stand3, ogre2_turret_seek4 ] {ai_run(0);};
-void() ogre2_turret_seek4 =[ $stand4, ogre2_turret_seek5 ] {ai_run(0);};
-void() ogre2_turret_seek5 =[ $stand5, ogre2_turret_seek6 ] {
-if (random() < 0.2)
- sound_idle (self, CHAN_VOICE, "ogre/ogidle.wav", 1, ATTN_IDLE);
- ai_run(0);
-};
-void() ogre2_turret_seek6 =[ $stand6, ogre2_turret_seek7 ] {ai_run(0);};
-void() ogre2_turret_seek7 =[ $stand7, ogre2_turret_seek8 ] {ai_run(0);};
-void() ogre2_turret_seek8 =[ $stand8, ogre2_turret_seek9 ] {ai_run(0);};
-void() ogre2_turret_seek9 =[ $stand9, ogre2_turret_seek1 ] {ai_run(0);};
-
-//end Preach -- dumptruck_ds
-void() ogre_nail1 =[ $shoot1, ogre_nail2 ] {ai_face();};
-void() ogre_nail2 =[ $shoot2, ogre_nail3 ] {ai_face();};
-void() ogre_nail3 =[ $shoot2, ogre_nail4 ] {ai_face();};
-void() ogre_nail4 =[ $shoot3, ogre_nail5 ] {ai_face();
- if (self.style == 0)
+ // dumptruck_ds
+ if (!missile.skin_proj)
{
- OgreFireGrenade();
+ missile.skin = this.skin_proj;
}
- if (self.style == 1)
+ else
{
- BDW_OgreFireFlak();
- // OgreFireSpike();
+ missile.skin = 0;
}
- else if (self.style == 2)
+
+ setsize (missile, '0 0 0', '0 0 0');
+ setorigin (missile, this.origin);
+ };
+
+ //--------------------------------------------------------------
+ // OgreFireSpike from insideqc tutorial here:
+ // http://www.insideqc.com/qctut/lesson-33.shtml
+ //--------------------------------------------------------------
+ nonvirtual void() attack_spike =
+ {
+ local vector dir;
+ // local entity old;
+
+ sound (this, CHAN_WEAPON, "weapons/spike2.wav", 1, ATTN_NORM);
+ this.attack_finished = time + 0.7;
+ // this.attack_finished = time + 0.2;
+ // -- dumptruck_ds
+ this.effects = this.effects | EF_MUZZLEFLASH;
+
+ dir = normalize (this.enemy.origin - this.origin);
+
+ launch_spike (this.origin + v_right * 4 + '0 0 16', dir);
+
+ // dumptruck_ds found in client.qc
+ newmis.touch = superduperspike_touch;
+ // setmodel (newmis, "progs/lspike.mdl");
+ // dumptruck_ds
+ newmis.skin = this.skin_proj;
+
+ // dumptruck_ds
+ if (this.mdl_proj != "")
{
- OgreFireSpike();
+ setmodel (newmis, this.mdl_proj);
}
- if (self.style == 3)
+ else
{
- W_FireMultiGrenade();
+ setmodel (newmis, "progs/lspike.mdl");
}
- if (self.style == 4) // jaycie erysdren 2021-09-14
+
+ // dumptruck_ds
+ if (!newmis.skin_proj)
{
- OgreFireLavaBall();
- sound_misc2 (self, CHAN_WEAPON, "shalrath/attack2.wav", 1, ATTN_NORM); // used for initial attack sound dumptruck_ds
+ newmis.skin = this.skin_proj;
}
-};
-void() ogre_nail5 =[ $shoot4, ogre_nail6 ] {ai_face();};
-void() ogre_nail6 =[ $shoot5, ogre_nail7 ] {ai_face();};
-void() ogre_nail7 =[ $shoot6, ogre_run1 ] {ai_face();};
-//
-////////////////////////
-// turret frames START
-////////////////////////
-//
-void() ogre_turret_attack1 =[ $shoot1, ogre_turret_attack2 ] {ai_face();};
-void() ogre_turret_attack2 =[ $shoot2, ogre_turret_attack3 ] {ai_face();};
-void() ogre_turret_attack3 =[ $shoot2, ogre_turret_attack4 ] {ai_face();};
-void() ogre_turret_attack4 =[ $shoot3, ogre_turret_attack5 ] {ai_face();
- if (self.style == 0)
+ else
{
- OgreFireGrenade();
+ newmis.skin = 0;
}
- if (self.style == 1)
+ // dumptruck_ds - end
+
+ setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
+ };
+
+ //--------------------------------------------------------------
+ // W_FireMultiGrenade
+ //--------------------------------------------------------------
+ nonvirtual void() attack_multigrenade =
+ {
+ // local entity missile, mpuff;
+ local entity missile;
+
+ // this.currentammo = this.ammo_multi_rockets =
+ // this.ammo_multi_rockets - 1;
+ // UpdateAmmoCounts (this);
+
+ sound (this, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
+
+ // this.punchangle_x = -2;
+
+ missile = spawn ();
+ missile.owner = this;
+ missile.movetype = MOVETYPE_BOUNCE;
+ missile.solid = SOLID_BBOX;
+ missile.classname = "MultiGrenade";
+
+ makevectors (this.angles);
+ missile.velocity = normalize (this.enemy.origin - this.origin);
+ missile.velocity = missile.velocity * 600;
+ missile.velocity_z = 200;
+ missile.avelocity = '300 300 300';
+ missile.angles = vectoangles (missile.velocity);
+
+ // set missile speed
+ // makevectors (this.v_angle);
+ // if (this.v_angle_x)
+ // missile.velocity = v_forward * 600 + v_up * 200 +
+ // crandom() * v_right * 10 + crandom() * v_up * 10;
+ // else
+ // {
+ // missile.velocity = aim (this, 10000);
+ // missile.velocity = missile.velocity * 600;
+ // missile.velocity_z = 200;
+ // }
+ //
+ // missile.avelocity = '300 300 300';
+ // missile.angles = vectoangles (missile.velocity);
+
+ missile.touch = MultiGrenadeTouch;
+
+ // set missile duration
+ missile.nextthink = time + 1;
+ missile.think = MultiGrenadeExplode;
+ setmodel (missile, "progs/mervup.mdl");
+ // dumptruck_ds
+ missile.skin = this.skin_proj;
+
+ setsize (missile, '0 0 0', '0 0 0');
+ setorigin (missile, this.origin + '0 0 16');
+ };
+
+ //--------------------------------------------------------------
+ // OgreFireLavaBall by jaycie erysdren 2021-09-14
+ //--------------------------------------------------------------
+ nonvirtual void() attack_lavaball =
+ {
+ local vector offang;
+ local vector org, vec, d;
+ // local float t;
+
+ offang = vectoangles (this.enemy.origin - this.origin);
+ makevectors (offang);
+
+ org = this.origin;
+ // + p_x*v_forward + p_y*v_right + p_z*'0 0 1';
+
+ // lead the player on hard mode
+ // if (skill > 1)
+ // {
+ // t = vlen(this.enemy.origin - org) / 300;
+ // vec = this.enemy.velocity;
+ // vec_z = 0;
+ // d = this.enemy.origin + t * vec;
+ // }
+ // else
+ // {
+ d = this.enemy.origin;
+ // }
+
+ vec = normalize (d - org);
+
+ // launch_spike (org, vec);
+ launch_spike2 (this.origin + v_right * 4 + '0 0 16', vec, 600);
+ this.effects = this.effects | EF_MUZZLEFLASH;
+ // dumptruck_ds custom_mdls
+ if (this.mdl_proj != "")
{
- BDW_OgreFireFlak();
- // OgreFireSpike();
+ setmodel (newmis, this.mdl_proj);
}
- else if (self.style == 2)
+ else
{
- OgreFireSpike();
+ setmodel (newmis, "progs/lavaball.mdl");
}
- if (self.style == 3)
+
+ // dumptruck_ds
+ if (!newmis.skin_proj)
{
- W_FireMultiGrenade();
+ newmis.skin = this.skin_proj;
}
- if (self.style == 4) // jaycie erysdren 2021-09-14
+ else
{
- OgreFireLavaBall();
- sound_misc2 (self, CHAN_WEAPON, "shalrath/attack2.wav", 1, ATTN_NORM); // used for initial attack sound dumptruck_ds
+ newmis.skin = 0;
}
-};
-void() ogre_turret_attack5 =[ $shoot4, ogre_turret_attack6 ] {ai_face();};
-
-void() ogre_turret_attack6=[ $shoot5, ogre_turret_attack7 ] {ai_face();};
-void() ogre_turret_attack7=[ $shoot5, ogre_turret_attack8 ] {ai_face();};
-void() ogre_turret_attack8=[ $shoot6, ogre_turret_attack9 ] {ai_face();};
-void() ogre_turret_attack9=[ $shoot6, ogre_turret_seek1 ] {ai_face();};
-void() ogre_turret_seek1 =[ $stand1, ogre_turret_seek2 ] {ai_run(0);};
-void() ogre_turret_seek2 =[ $stand2, ogre_turret_seek3 ] {ai_run(0);};
-void() ogre_turret_seek3 =[ $stand3, ogre_turret_seek4 ] {ai_run(0);};
-void() ogre_turret_seek4 =[ $stand4, ogre_turret_seek5 ] {ai_run(0);};
-void() ogre_turret_seek5 =[ $stand5, ogre_turret_seek6 ] {
-if (random() < 0.2)
- sound_idle (self, CHAN_VOICE, "ogre/ogidle.wav", 1, ATTN_IDLE);
- ai_run(0);
-};
-void() ogre_turret_seek6 =[ $stand6, ogre_turret_seek7 ] {ai_run(0);};
-void() ogre_turret_seek7 =[ $stand7, ogre_turret_seek8 ] {ai_run(0);};
-void() ogre_turret_seek8 =[ $stand8, ogre_turret_seek9 ] {ai_run(0);};
-void() ogre_turret_seek9 =[ $stand9, ogre_turret_seek1 ] {ai_run(0);};
-////////////////////////
-//turret frames END
-///////////////////////
-void() ogre_pain1 =[ $pain1, ogre_pain2 ] {};
-void() ogre_pain2 =[ $pain2, ogre_pain3 ] {};
-void() ogre_pain3 =[ $pain3, ogre_pain4 ] {};
-void() ogre_pain4 =[ $pain4, ogre_pain5 ] {};
-void() ogre_pain5 =[ $pain5, ogre_run1 ] {};
-
-
-void() ogre_painb1 =[ $painb1, ogre_painb2 ] {};
-void() ogre_painb2 =[ $painb2, ogre_painb3 ] {};
-void() ogre_painb3 =[ $painb3, ogre_run1 ] {};
-
-
-void() ogre_painc1 =[ $painc1, ogre_painc2 ] {};
-void() ogre_painc2 =[ $painc2, ogre_painc3 ] {};
-void() ogre_painc3 =[ $painc3, ogre_painc4 ] {};
-void() ogre_painc4 =[ $painc4, ogre_painc5 ] {};
-void() ogre_painc5 =[ $painc5, ogre_painc6 ] {};
-void() ogre_painc6 =[ $painc6, ogre_run1 ] {};
-
-
-void() ogre_paind1 =[ $paind1, ogre_paind2 ] {};
-void() ogre_paind2 =[ $paind2, ogre_paind3 ] {ai_pain(10);};
-void() ogre_paind3 =[ $paind3, ogre_paind4 ] {ai_pain(9);};
-void() ogre_paind4 =[ $paind4, ogre_paind5 ] {ai_pain(4);};
-void() ogre_paind5 =[ $paind5, ogre_paind6 ] {};
-void() ogre_paind6 =[ $paind6, ogre_paind7 ] {};
-void() ogre_paind7 =[ $paind7, ogre_paind8 ] {};
-void() ogre_paind8 =[ $paind8, ogre_paind9 ] {};
-void() ogre_paind9 =[ $paind9, ogre_paind10 ] {};
-void() ogre_paind10=[ $paind10, ogre_paind11 ] {};
-void() ogre_paind11=[ $paind11, ogre_paind12 ] {};
-void() ogre_paind12=[ $paind12, ogre_paind13 ] {};
-void() ogre_paind13=[ $paind13, ogre_paind14 ] {};
-void() ogre_paind14=[ $paind14, ogre_paind15 ] {};
-void() ogre_paind15=[ $paind15, ogre_paind16 ] {};
-void() ogre_paind16=[ $paind16, ogre_run1 ] {};
-
-void() ogre_paine1 =[ $paine1, ogre_paine2 ] {};
-void() ogre_paine2 =[ $paine2, ogre_paine3 ] {ai_pain(10);};
-void() ogre_paine3 =[ $paine3, ogre_paine4 ] {ai_pain(9);};
-void() ogre_paine4 =[ $paine4, ogre_paine5 ] {ai_pain(4);};
-void() ogre_paine5 =[ $paine5, ogre_paine6 ] {};
-void() ogre_paine6 =[ $paine6, ogre_paine7 ] {};
-void() ogre_paine7 =[ $paine7, ogre_paine8 ] {};
-void() ogre_paine8 =[ $paine8, ogre_paine9 ] {};
-void() ogre_paine9 =[ $paine9, ogre_paine10 ] {};
-void() ogre_paine10=[ $paine10, ogre_paine11 ] {};
-void() ogre_paine11=[ $paine11, ogre_paine12 ] {};
-void() ogre_paine12=[ $paine12, ogre_paine13 ] {};
-void() ogre_paine13=[ $paine13, ogre_paine14 ] {};
-void() ogre_paine14=[ $paine14, ogre_paine15 ] {};
-void() ogre_paine15=[ $paine15, ogre_run1 ] {};
-
-
-void(entity attacker, float damage) ogre_pain =
-{
- local float r;
+ newmis.avelocity = this.cust_avelocity;
+ if !(newmis.avelocity)
+ newmis.avelocity = '200 100 300';
+ setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
+ // newmis.touch = T_MissileTouch; // rocket explosion
+ newmis.touch = OgreGrenadeExplode;
+ sound_attack (this, CHAN_AUTO, "boss1/throw.wav", 1, ATTN_NORM);
+ };
-// don't make multiple pain sounds right after each other
- if (self.pain_finished > time)
- return;
+ //--------------------------------------------------------------
+ // chainsaw -- FIXME
+ //--------------------------------------------------------------
+ nonvirtual void(float side) attack_chainsaw =
+ {
+ local vector delta;
+ local float ldmg;
- if (self.spawnflags & I_AM_TURRET)
- return;
+ if (!this.enemy)
+ return;
+ if (!CanDamage (this.enemy, this))
+ return;
+
+ ai_charge (10);
- sound_pain (self, CHAN_VOICE, "ogre/ogpain1.wav", 1, ATTN_NORM);
+ delta = this.enemy.origin - this.origin;
+
+ if (vlen(delta) > 100)
+ return;
- r = random();
+ ldmg = (random() + random() + random()) * 4;
+ T_Damage (this.enemy, this, this, ldmg);
- if (r < 0.25)
+ if (side)
+ {
+ makevectors (this.angles);
+ if (side == 1)
+ SpawnMeatSpray (this.origin + v_forward * 16,
+ crandom() * 100 * v_right);
+ else
+ SpawnMeatSpray (this.origin + v_forward * 16,
+ side * v_right);
+ }
+ };
+
+ //--------------------------------------------------------------
+ // ogre_melee
+ //--------------------------------------------------------------
+ nonvirtual void() attack_melee =
{
- ogre_pain1 ();
- self.pain_finished = time + 1;
- }
- else if (r < 0.5)
+ if (random() > 0.5)
+ this.smash1 ();
+ else
+ this.swing1 ();
+ };
+
+ //--------------------------------------------------------------
+ // Ogre Standing functions
+ //--------------------------------------------------------------
+ nonvirtual void() stand1 = [$stand1, stand2] { ai_stand (); };
+ nonvirtual void() stand2 = [$stand2, stand3] { ai_stand (); };
+ nonvirtual void() stand3 = [$stand3, stand4] { ai_stand (); };
+ nonvirtual void() stand4 = [$stand4, stand5] { ai_stand (); };
+ nonvirtual void() stand5 = [$stand5, stand6]
{
- ogre_painb1 ();
- self.pain_finished = time + 1;
- }
- else if (r < 0.75)
+ if (random() < 0.2)
+ sound_idle (this, CHAN_VOICE, "ogre/ogidle.wav",
+ 1, ATTN_IDLE);
+ ai_stand ();
+ };
+ nonvirtual void() stand6 = [$stand6, stand7] { ai_stand (); };
+ nonvirtual void() stand7 = [$stand7, stand8] { ai_stand (); };
+ nonvirtual void() stand8 = [$stand8, stand9] { ai_stand (); };
+ nonvirtual void() stand9 = [$stand9, stand1] { ai_stand (); };
+
+ //--------------------------------------------------------------
+ // Ogre Walking functions
+ //--------------------------------------------------------------
+ nonvirtual void() walk1 = [$walk1, walk2] { ai_walk (3); };
+ nonvirtual void() walk2 = [$walk2, walk3] { ai_walk (2); };
+ nonvirtual void() walk3 = [$walk3, walk4]
{
- ogre_painc1 ();
- self.pain_finished = time + 1;
- }
- else if (r < 0.88)
+ ai_walk (2);
+ if (random() < 0.2)
+ sound_idle (this, CHAN_VOICE, "ogre/ogidle.wav",
+ 1, ATTN_IDLE);
+ };
+ nonvirtual void() walk4 = [$walk4,walk5] { ai_walk (2); };
+ nonvirtual void() walk5 = [$walk5,walk6] { ai_walk (2); };
+ nonvirtual void() walk6 = [$walk6,walk7]
{
- ogre_paind1 ();
- self.pain_finished = time + 2;
- }
- else
+ ai_walk (5);
+ if (random() < 0.1)
+ sound_misc (this, CHAN_VOICE, "ogre/ogdrag.wav",
+ 1, ATTN_IDLE);
+ };
+ nonvirtual void() walk7 = [$walk7, walk8] { ai_walk (3); };
+ nonvirtual void() walk8 = [$walk8, walk9] { ai_walk (2); };
+ nonvirtual void() walk9 = [$walk9, walk10] { ai_walk (3); };
+ nonvirtual void() walk10 = [$walk10, walk11] { ai_walk (1); };
+ nonvirtual void() walk11 = [$walk11, walk12] { ai_walk (2); };
+ nonvirtual void() walk12 = [$walk12, walk13] { ai_walk (3); };
+ nonvirtual void() walk13 = [$walk13, walk14] { ai_walk (3); };
+ nonvirtual void() walk14 = [$walk14, walk15] { ai_walk (3); };
+ nonvirtual void() walk15 = [$walk15, walk16] { ai_walk (3); };
+ nonvirtual void() walk16 = [$walk16, walk1] { ai_walk (4); };
+
+ //--------------------------------------------------------------
+ // Ogre Running functions
+ //--------------------------------------------------------------
+ nonvirtual void() run1 = [$run1, run2]
{
- ogre_paine1 ();
- self.pain_finished = time + 2;
- }
-};
-
-void() ogre_die1 =[ $death1, ogre_die2 ] {};
-void() ogre_die2 =[ $death2, ogre_die3 ] {};
-void() ogre_die3 =[ $death3, ogre_die4 ]
-{self.solid = SOLID_NOT;
- // style ammotype check -- dumptruck_ds
- if (self.style == 1) // flak style
+ ai_run (9);
+ if (random() < 0.2)
+ sound_misc1 (this, CHAN_VOICE, "ogre/ogidle2.wav",
+ 1, ATTN_IDLE);
+ };
+ nonvirtual void() run2 = [$run2, run3] { ai_run (12); };
+ nonvirtual void() run3 = [$run3, run4] { ai_run (8); };
+ nonvirtual void() run4 = [$run4, run5] { ai_run (22); };
+ nonvirtual void() run5 = [$run5, run6] { ai_run (16); };
+ nonvirtual void() run6 = [$run6, run7] { ai_run (4); };
+ nonvirtual void() run7 = [$run7, run8] { ai_run (13); };
+ nonvirtual void() run8 = [$run8, run1] { ai_run (24); };
+
+ //--------------------------------------------------------------
+ // Ogre Smash Attack
+ //--------------------------------------------------------------
+ nonvirtual void() smash1 = [$smash1, smash2]
+ {
+ ai_charge (6);
+ sound_attack (this, CHAN_WEAPON, "ogre/ogsawatk.wav",
+ 1, ATTN_NORM);
+ };
+ nonvirtual void() smash2 = [$smash2, smash3] { ai_charge (0); };
+ nonvirtual void() smash3 = [$smash3, smash4] { ai_charge (0); };
+ nonvirtual void() smash4 = [$smash4, smash5] { ai_charge (1); };
+ nonvirtual void() smash5 = [$smash5, smash6] { ai_charge (4); };
+ nonvirtual void() smash6 = [$smash6, smash7]
+ {
+ ai_charge (4);
+ attack_chainsaw (0);
+ };
+ nonvirtual void() smash7 = [$smash7, smash8]
+ {
+ ai_charge (4);
+ attack_chainsaw (0);
+ };
+ nonvirtual void() smash8 = [$smash8, smash9]
+ {
+ ai_charge (10);
+ attack_chainsaw (0);
+ };
+ nonvirtual void() smash9 = [$smash9,smash10]
+ {
+ ai_charge (13);
+ attack_chainsaw (0);
+ };
+ nonvirtual void() smash10 = [$smash10, smash11] { attack_chainsaw(1); };
+ nonvirtual void() smash11 = [$smash11, smash12]
+ {
+ ai_charge (2);
+ attack_chainsaw (0);
+ // slight variation
+ // this.nextthink = this.nextthink + random()*0.2;};
+ // 1998-08-14 Incorrect setting of nextthink fix
+ // by Maddes/Lord Sméagol
+ this.nextthink = time + 0.1 + random() * 0.2;
+ };
+ nonvirtual void() smash12 = [$smash12, smash13] { ai_charge (0); };
+ nonvirtual void() smash13 = [$smash13, smash14] { ai_charge (4); };
+ nonvirtual void() smash14 = [$smash14, run1] { ai_charge (12); };
+
+ //--------------------------------------------------------------
+ // Ogre Swing Attack
+ //--------------------------------------------------------------
+ nonvirtual void() swing1 = [$swing1, swing2]
+ {
+ ai_charge (11);
+ sound_attack (this, CHAN_WEAPON, "ogre/ogsawatk.wav",
+ 1, ATTN_NORM);
+ };
+ nonvirtual void() swing2 = [$swing2, swing3] { ai_charge (1); };
+ nonvirtual void() swing3 = [$swing3, swing4] { ai_charge (4); };
+ nonvirtual void() swing4 = [$swing4, swing5] { ai_charge (13); };
+ nonvirtual void() swing5 = [$swing5, swing6]
+ {
+ ai_charge (9);
+ attack_chainsaw (0);
+ this.angles_y = this.angles_y + random() * 25;
+ };
+ nonvirtual void() swing6 = [$swing6, swing7]
+ {
+ attack_chainsaw (200);
+ this.angles_y = this.angles_y + random() * 25;
+ };
+ nonvirtual void() swing7 = [$swing7,swing8]
+ {
+ attack_chainsaw (0);
+ this.angles_y = this.angles_y + random() * 25;
+ };
+ nonvirtual void() swing8 = [$swing8,swing9]
+ {
+ attack_chainsaw (0);
+ this.angles_y = this.angles_y + random() * 25;
+ };
+ nonvirtual void() swing9 = [$swing9,swing10]
+ {
+ attack_chainsaw (0);
+ this.angles_y = this.angles_y + random() * 25;
+ };
+ nonvirtual void() swing10 = [$swing10, swing11]
+ {
+ attack_chainsaw (-200);
+ this.angles_y = this.angles_y + random() * 25;
+ };
+ nonvirtual void() swing11 = [$swing11,swing12]
+ {
+ attack_chainsaw (0);
+ this.angles_y = this.angles_y + random() * 25;
+ };
+ nonvirtual void() swing12 = [$swing12, swing13] { ai_charge (3); };
+ nonvirtual void() swing13 = [$swing13, swing14] { ai_charge (8); };
+ nonvirtual void() swing14 = [$swing14, run1] { ai_charge (9); };
+
+ //--------------------------------------------------------------
+ // Ogre Projectile Attack
+ //--------------------------------------------------------------
+ nonvirtual void() nail1 = [$shoot1, nail2] { ai_face (); };
+ nonvirtual void() nail2 = [$shoot2, nail3] { ai_face (); };
+ nonvirtual void() nail3 = [$shoot2, nail4] { ai_face (); };
+ nonvirtual void() nail4 = [$shoot3, nail5]
+ {
+ ai_face ();
+ if (this.style == 0)
{
- self.ammo_nails = 5;
+ this.attack_grenade ();
}
- if (self.style == 2) // super nail style
+ if (this.style == 1)
{
- self.ammo_nails = 5;
+ this.attack_flak ();
}
- if (self.style == 3) //DOE multi-grenade
+ else if (this.style == 2)
{
- self.ammo_rockets = 2;
+ this.attack_spike ();
}
- else if (self.style == 0) //default Ogre
+ if (this.style == 3)
{
- self.ammo_rockets = 2;
+ this.attack_multigrenade ();
}
-if(!self.keep_ammo)
- item_backpack::drop_backpack (self);
-};
-
-void() ogre_die4 =[ $death4, ogre_die5 ] {};
-void() ogre_die5 =[ $death5, ogre_die6 ] {};
-void() ogre_die6 =[ $death6, ogre_die7 ] {};
-void() ogre_die7 =[ $death7, ogre_die8 ] {};
-void() ogre_die8 =[ $death8, ogre_die9 ] {};
-void() ogre_die9 =[ $death9, ogre_die10 ] {};
-void() ogre_die10 =[ $death10, ogre_die11 ] {};
-void() ogre_die11 =[ $death11, ogre_die12 ] {};
-void() ogre_die12 =[ $death12, ogre_die13 ] {};
-void() ogre_die13 =[ $death13, ogre_die14 ] {};
-void() ogre_die14 =[ $death14, ogre_die14 ] {};
-
-void() ogre_bdie1 =[ $bdeath1, ogre_bdie2 ] {};
-void() ogre_bdie2 =[ $bdeath2, ogre_bdie3 ] {ai_forward(5);};
-void() ogre_bdie3 =[ $bdeath3, ogre_bdie4 ]
-{self.solid = SOLID_NOT;
- // style ammotype check -- dumptruck_ds
- if (self.style == 1)
+ if (this.style == 4)
{
- self.ammo_nails = 5;
+ // jaycie erysdren 2021-09-14
+ this.attack_lavaball ();
+ // used for initial attack sound dumptruck_ds
+ sound_misc2 (this, CHAN_WEAPON, "shalrath/attack2.wav",
+ 1, ATTN_NORM);
}
- if (self.style == 2)
+ };
+ nonvirtual void() nail5 = [$shoot4, nail6] { ai_face (); };
+ nonvirtual void() nail6 = [$shoot5, nail7] { ai_face (); };
+ nonvirtual void() nail7 = [$shoot6, run1] { ai_face (); };
+
+ /////////////////////////
+ // turret frames START //
+ /////////////////////////
+
+ //--------------------------------------------------------------
+ // Ogre Turret Attack
+ //--------------------------------------------------------------
+ nonvirtual void() turret_atk1 = [$shoot1, turret_atk2] { ai_face (); };
+ nonvirtual void() turret_atk2 = [$shoot2, turret_atk3] { ai_face (); };
+ nonvirtual void() turret_atk3 = [$shoot2, turret_atk4] { ai_face (); };
+ nonvirtual void() turret_atk4 = [$shoot3, turret_atk5]
+ {
+ ai_face ();
+ if (this.style == 0)
{
- self.ammo_nails = 5;
+ this.attack_grenade ();
}
- if (self.style == 3) //DOE multi-grenade
+ if (this.style == 1)
{
- self.ammo_rockets = 2;
+ this.attack_flak ();
}
- if (self.style == 4) // lavaball ogre jaycie erysdren 2021-09-14
+ else if (this.style == 2)
{
- self.ammo_rockets = 2;
+ this.attack_spike ();
}
- else if (self.style == 0)
+ if (this.style == 3)
{
- self.ammo_rockets = 2;
+ this.attack_multigrenade ();
}
-if(!self.keep_ammo)
- item_backpack::drop_backpack (self);
-};
+ if (this.style == 4)
+ {
+ // jaycie erysdren 2021-09-14
+ this.attack_lavaball ();
+ // used for initial attack sound dumptruck_ds
+ sound_misc2 (this, CHAN_WEAPON, "shalrath/attack2.wav",
+ 1, ATTN_NORM);
+ }
+ };
+ nonvirtual void() turret_atk5 = [$shoot4, turret_atk6] { ai_face (); };
+ nonvirtual void() turret_atk6 = [$shoot5, turret_atk7] { ai_face (); };
+ nonvirtual void() turret_atk7 = [$shoot5, turret_atk8] { ai_face (); };
+ nonvirtual void() turret_atk8 = [$shoot6, turret_atk9] { ai_face (); };
+ nonvirtual void() turret_atk9 = [$shoot6, turret_seek1] { ai_face (); };
+
+ //--------------------------------------------------------------
+ // Ogre Turret Seek / Stand
+ //--------------------------------------------------------------
+ nonvirtual void() turret_seek1 = [$stand1, turret_seek2] { ai_run (0);};
+ nonvirtual void() turret_seek2 = [$stand2, turret_seek3] { ai_run (0);};
+ nonvirtual void() turret_seek3 = [$stand3, turret_seek4] { ai_run (0);};
+ nonvirtual void() turret_seek4 = [$stand4, turret_seek5] { ai_run (0);};
+ nonvirtual void() turret_seek5 = [$stand5, turret_seek6]
+ {
+ if (random() < 0.2)
+ sound_idle (this, CHAN_VOICE, "ogre/ogidle.wav",
+ 1, ATTN_IDLE);
+ ai_run (0);
+ };
+ nonvirtual void() turret_seek6 = [$stand6, turret_seek7] { ai_run (0);};
+ nonvirtual void() turret_seek7 = [$stand7, turret_seek8] { ai_run (0);};
+ nonvirtual void() turret_seek8 = [$stand8, turret_seek9] { ai_run (0);};
+ nonvirtual void() turret_seek9 = [$stand9, turret_seek1] { ai_run (0);};
+
+ /////////////////////////
+ // turret frames END //
+ /////////////////////////
+
+ //--------------------------------------------------------------
+ // Ogre Pain state A
+ //--------------------------------------------------------------
+ nonvirtual void() pain1 = [$pain1, pain2] { };
+ nonvirtual void() pain2 = [$pain2, pain3] { };
+ nonvirtual void() pain3 = [$pain3, pain4] { };
+ nonvirtual void() pain4 = [$pain4, pain5] { };
+ nonvirtual void() pain5 = [$pain5, run1] { };
+
+ //--------------------------------------------------------------
+ // Ogre Pain state B
+ //--------------------------------------------------------------
+ nonvirtual void() painb1 = [$painb1, painb2] { };
+ nonvirtual void() painb2 = [$painb2, painb3] { };
+ nonvirtual void() painb3 = [$painb3, run1] { };
+
+ //--------------------------------------------------------------
+ // Ogre Pain state C
+ //--------------------------------------------------------------
+ nonvirtual void() painc1 = [$painc1, painc2] { };
+ nonvirtual void() painc2 = [$painc2, painc3] { };
+ nonvirtual void() painc3 = [$painc3, painc4] { };
+ nonvirtual void() painc4 = [$painc4, painc5] { };
+ nonvirtual void() painc5 = [$painc5, painc6] { };
+ nonvirtual void() painc6 = [$painc6, run1] { };
+
+ //--------------------------------------------------------------
+ // Ogre Pain state D
+ //--------------------------------------------------------------
+ nonvirtual void() paind1 = [$paind1, paind2] { };
+ nonvirtual void() paind2 = [$paind2, paind3] { ai_pain (10); };
+ nonvirtual void() paind3 = [$paind3, paind4] { ai_pain (9); };
+ nonvirtual void() paind4 = [$paind4, paind5] { ai_pain (4); };
+ nonvirtual void() paind5 = [$paind5, paind6] { };
+ nonvirtual void() paind6 = [$paind6, paind7] { };
+ nonvirtual void() paind7 = [$paind7, paind8] { };
+ nonvirtual void() paind8 = [$paind8, paind9] { };
+ nonvirtual void() paind9 = [$paind9, paind10] { };
+ nonvirtual void() paind10 = [$paind10, paind11] { };
+ nonvirtual void() paind11 = [$paind11, paind12] { };
+ nonvirtual void() paind12 = [$paind12, paind13] { };
+ nonvirtual void() paind13 = [$paind13, paind14] { };
+ nonvirtual void() paind14 = [$paind14, paind15] { };
+ nonvirtual void() paind15 = [$paind15, paind16] { };
+ nonvirtual void() paind16 = [$paind16, run1] { };
+
+ //--------------------------------------------------------------
+ // Ogre Pain state E
+ //--------------------------------------------------------------
+ nonvirtual void() paine1 = [$paine1, paine2] { };
+ nonvirtual void() paine2 = [$paine2, paine3] { ai_pain (10); };
+ nonvirtual void() paine3 = [$paine3, paine4] { ai_pain (9); };
+ nonvirtual void() paine4 = [$paine4, paine5] { ai_pain (4); };
+ nonvirtual void() paine5 = [$paine5, paine6] { };
+ nonvirtual void() paine6 = [$paine6, paine7] { };
+ nonvirtual void() paine7 = [$paine7, paine8] { };
+ nonvirtual void() paine8 = [$paine8, paine9] { };
+ nonvirtual void() paine9 = [$paine9, paine10] { };
+ nonvirtual void() paine10 = [$paine10, paine11] { };
+ nonvirtual void() paine11 = [$paine11, paine12] { };
+ nonvirtual void() paine12 = [$paine12, paine13] { };
+ nonvirtual void() paine13 = [$paine13, paine14] { };
+ nonvirtual void() paine14 = [$paine14, paine15] { };
+ nonvirtual void() paine15 = [$paine15, run1] { };
+
+ //--------------------------------------------------------------
+ // Ogre Death state A
+ //--------------------------------------------------------------
+ nonvirtual void() die1 = [$death1, die2] { };
+ nonvirtual void() die2 = [$death2, die3] { };
+ nonvirtual void() die3 = [$death3, die4]
+ {
+ this.solid = SOLID_NOT;
+ // style ammotype check -- dumptruck_ds
+ if (this.style == 1)
+ {
+ // flak style
+ this.ammo_nails = 5;
+ }
+ if (this.style == 2)
+ {
+ // super nail style
+ this.ammo_nails = 5;
+ }
+ if (this.style == 3)
+ {
+ // DOE multi-grenade
+ this.ammo_rockets = 2;
+ }
+ else if (this.style == 0)
+ {
+ // default Ogre
+ this.ammo_rockets = 2;
+ }
+ if(!this.keep_ammo)
+ item_backpack::drop_backpack (this.origin, this.weapon,
+ this.ammo_shells, this.ammo_nails,
+ this.ammo_rockets, this.ammo_cells);
+ };
+ nonvirtual void() die4 = [$death4, die5] { };
+ nonvirtual void() die5 = [$death5, die6] { };
+ nonvirtual void() die6 = [$death6, die7] { };
+ nonvirtual void() die7 = [$death7, die8] { };
+ nonvirtual void() die8 = [$death8, die9] { };
+ nonvirtual void() die9 = [$death9, die10] { };
+ nonvirtual void() die10 = [$death10, die11] { };
+ nonvirtual void() die11 = [$death11, die12] { };
+ nonvirtual void() die12 = [$death12, die13] { };
+ nonvirtual void() die13 = [$death13, die14] { };
+ nonvirtual void() die14 = [$death14, die14] { };
+
+ //--------------------------------------------------------------
+ // Ogre Death state B
+ //--------------------------------------------------------------
+ nonvirtual void() bdie1 = [$bdeath1, bdie2] { };
+ nonvirtual void() bdie2 = [$bdeath2, bdie3] { ai_forward (5); };
+ nonvirtual void() bdie3 = [$bdeath3, bdie4]
+ {
+ this.solid = SOLID_NOT;
+ // style ammotype check -- dumptruck_ds
+ if (this.style == 1)
+ {
+ this.ammo_nails = 5;
+ }
+ if (this.style == 2)
+ {
+ this.ammo_nails = 5;
+ }
+ if (this.style == 3)
+ {
+ // DOE multi-grenade
+ this.ammo_rockets = 2;
+ }
+ if (this.style == 4)
+ {
+ // lavaball ogre jaycie erysdren 2021-09-14
+ this.ammo_rockets = 2;
+ }
+ else if (this.style == 0)
+ {
+ this.ammo_rockets = 2;
+ }
+ if(!this.keep_ammo)
+ item_backpack::drop_backpack (this.origin, this.weapon,
+ this.ammo_shells, this.ammo_nails,
+ this.ammo_rockets, this.ammo_cells);
+ };
+ nonvirtual void() bdie4 = [$bdeath4, bdie5] { ai_forward (1); };
+ nonvirtual void() bdie5 = [$bdeath5, bdie6] { ai_forward (3); };
+ nonvirtual void() bdie6 = [$bdeath6, bdie7] { ai_forward (7); };
+ nonvirtual void() bdie7 = [$bdeath7, bdie8] { ai_forward (25); };
+ nonvirtual void() bdie8 = [$bdeath8, bdie9] { };
+ nonvirtual void() bdie9 = [$bdeath9, bdie10] { };
+ nonvirtual void() bdie10 = [$bdeath10, bdie10] { };
+
+ //==============================================================
+ // Interaction
+ //==============================================================
+
+ //--------------------------------------------------------------
+ // ogre_pain
+ //--------------------------------------------------------------
+ virtual void(entity attacker, float damage) do_damage =
+ {
+ local float r;
-void() ogre_bdie4 =[ $bdeath4, ogre_bdie5 ] {ai_forward(1);};
-void() ogre_bdie5 =[ $bdeath5, ogre_bdie6 ] {ai_forward(3);};
-void() ogre_bdie6 =[ $bdeath6, ogre_bdie7 ] {ai_forward(7);};
-void() ogre_bdie7 =[ $bdeath7, ogre_bdie8 ] {ai_forward(25);};
-void() ogre_bdie8 =[ $bdeath8, ogre_bdie9 ] {};
-void() ogre_bdie9 =[ $bdeath9, ogre_bdie10 ] {};
-void() ogre_bdie10 =[ $bdeath10, ogre_bdie10 ] {};
+ // don't make multiple pain sounds right after each other
+ if (this.pain_finished > time)
+ return;
-void() ogre_die =
-{
-// check for gib
- if (self.health < -80)
- {
- sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
- if (self.mdl_head != "") //dumptruck_ds custom_mdls
+ if (this.spawnflags & I_AM_TURRET)
+ return;
+
+ sound_pain (this, CHAN_VOICE, "ogre/ogpain1.wav", 1, ATTN_NORM);
+
+ r = random();
+
+ if (r < 0.25)
{
- ThrowHead (self.mdl_head, self.health);
+ this.pain1 ();
+ this.pain_finished = time + 1;
}
- else
+ else if (r < 0.5)
+ {
+ this.painb1 ();
+ this.pain_finished = time + 1;
+ }
+ else if (r < 0.75)
{
- ThrowHead ("progs/h_ogre.mdl", self.health);
+ this.painc1 ();
+ this.pain_finished = time + 1;
}
- // ThrowGib ("progs/gib3.mdl", self.health);
- // ThrowGib ("progs/gib3.mdl", self.health);
- // ThrowGib ("progs/gib3.mdl", self.health);
- if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
+ else if (r < 0.88)
{
- ThrowGib (self.mdl_gib1, self.health);
+ this.paind1 ();
+ this.pain_finished = time + 2;
}
else
{
- ThrowGib ("progs/gib3.mdl", self.health);
+ this.paine1 ();
+ this.pain_finished = time + 2;
}
- if (self.mdl_gib2 != "")
+ };
+
+ //--------------------------------------------------------------
+ // ogre_die
+ //--------------------------------------------------------------
+ virtual void() do_destroy =
+ {
+ // check for gib
+ if (this.health < -80)
{
- ThrowGib (self.mdl_gib2, self.health);
+ sound (this, CHAN_VOICE, "player/udeath.wav",
+ 1, ATTN_NORM);
+
+ // dumptruck_ds custom_mdls
+ if (this.mdl_head != "")
+ {
+ ThrowHead (this.mdl_head, this.health);
+ }
+ else
+ {
+ ThrowHead ("progs/h_ogre.mdl", this.health);
+ }
+ // ThrowGib ("progs/gib3.mdl", this.health);
+ // ThrowGib ("progs/gib3.mdl", this.health);
+ // ThrowGib ("progs/gib3.mdl", this.health);
+ // custom models -- dumptruck_ds
+ if (this.mdl_gib1 != "")
+ {
+ ThrowGib (this.mdl_gib1, this.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib3.mdl", this.health);
+ }
+ if (this.mdl_gib2 != "")
+ {
+ ThrowGib (this.mdl_gib2, this.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib3.mdl", this.health);
+ }
+ if (this.mdl_gib3 != "")
+ {
+ ThrowGib (this.mdl_gib3, this.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib3.mdl", this.health);
+ }
+ base_item::drop_stuff (this);
+ return;
}
+
+ sound_death (this, CHAN_VOICE, "ogre/ogdth.wav", 1, ATTN_NORM);
+
+ base_item::drop_stuff (this);
+ if (random() < 0.5)
+ this.die1 ();
else
+ this.bdie1 ();
+ };
+
+ //==============================================================
+ // Initialization
+ //==============================================================
+
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
+ {
+ if (deathmatch)
{
- ThrowGib ("progs/gib3.mdl", self.health);
+ remove (this);
+ return;
}
- if (self.mdl_gib3 != "")
+
+ // custom_mdls dumptruck_ds
+ precache_body_model ("progs/ogre.mdl");
+ precache_head_model ("progs/h_ogre.mdl");
+ precache_proj_model ("progs/grenade.mdl");
+
+ // custom_mdls dumptruck_ds
+ // for style 3 Orge dumptruck_ds
+ precache_model ("progs/mervup.mdl");
+ // for style 2 Ogre dumptruck_ds
+ precache_model ("progs/lspike.mdl");
+ precache_sound_misc ("ogre/ogdrag.wav");
+ precache_sound_death ("ogre/ogdth.wav");
+ precache_sound_idle ("ogre/ogidle.wav");
+ precache_sound_misc1 ("ogre/ogidle2.wav");
+ precache_sound_pain ("ogre/ogpain1.wav");
+ precache_sound_attack ("ogre/ogsawatk.wav");
+ precache_sound_sight ("ogre/ogwake.wav");
+ precache_sound_misc2 ("shalrath/attack2.wav");
+ precache_sound ("fish/bite.wav");
+ // jaycie erysdren 2021-09-14
+ precache_sound ("boss1/throw.wav");
+
+ precache_gib1 ("progs/gib1.mdl");
+ precache_gib2 ("progs/gib2.mdl");
+ precache_gib3 ("progs/gib3.mdl");
+
+ this.solid = SOLID_SLIDEBOX;
+ this.movetype = MOVETYPE_STEP;
+
+ // custom_mdls dumptruck_ds
+ body_model ("progs/ogre.mdl");
+ // setmodel (this, "progs/ogre.mdl");
+
+ setsize (this, VEC_HULL2_MIN, VEC_HULL2_MAX);
+
+ if (!this.proj_speed_mod)
+ this.proj_speed_mod = 1;
+
+ // thanks RennyC -- dumptruck_ds
+ if (!this.health)
+ this.health = 200;
+
+ this.think_stand = this.stand1;
+ this.think_walk = this.walk1;
+ if (this.spawnflags & I_AM_TURRET)
{
- ThrowGib (self.mdl_gib3, self.health);
+ this.think_run = this.turret_seek1;
}
else
{
- ThrowGib ("progs/gib3.mdl", self.health);
+ this.think_run = this.run1;
}
- base_item::drop_stuff (self);
- return;
- }
-
- sound_death (self, CHAN_VOICE, "ogre/ogdth.wav", 1, ATTN_NORM);
+ this.th_die = this.do_destroy;
+ this.think_melee = this.attack_melee;
+ this.think_missile = this.nail1;
+ // dumptruck_ds
+ this.think_turret = this.turret_atk1;
+ // Berserk test from
+ // http://celephais.net/board/view_thread.php?id=4&start=3465
+ // -- dumptruck_ds
+ if !(this.berserk)
+ this.th_pain = this.do_damage;
+ else
+ this.th_pain = sub_nullpain;
- base_item::drop_stuff (self);
- if (random() < 0.5)
- ogre_die1 ();
- else
- ogre_bdie1 ();
-};
+ // walkmonster_start
+ super::init_spawned ();
+ };
-void() ogre_melee =
-{
- if (random() > 0.5)
- ogre_smash1 ();
- else
- ogre_swing1 ();
+ //--------------------------------------------------------------
+ void() monster_ogre =
+ {
+ // let subclasses override classtype -- CEV
+ if (!this.classtype)
+ this.classtype = CT_MONSTER_OGRE;
+ };
};
+//==============================================================================
+// OGRE MARKSMAN
+//==============================================================================
-/*QUAKED monster_ogre (1 0 0) (-32 -32 -24) (32 32 64) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+/*QUAKED monster_ogre_marksman (1 0 0) (-32 -32 -24) (32 32 64) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
{
- model ("progs/ogre.mdl");
+model ({ "path" : "progs/ogre.mdl", "frame": 63 });
}
-Ogre.
-
-Default health = 200"
-
-style(Choices) : "Attack type" =
-0 : "Default (grenade)"
-1 : "Flak Ogre (Marcher, Quoth)"
-2 : "sniper (shoots single, deadly lava round)"
-3 : "multi-grenade (Mission Pack 2)"
+Ogre Marksman.
+Unlike vanilla Quake, this is a slightly more accurate Orge.
keep_ammo(integer) : "1 = Don't drop backpack upon death"
snd_death(string) : "Path to custom death sound"
@@ -1331,208 +1582,174 @@ obit_method(string) : "When used with obit_name, will set part of the text for a
damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
*/
-void() monster_ogre =
+class monster_ogre_marksman: monster_ogre
{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
+ // Preach tutorial alternate animation frames for
+ // monster_ogre_marksman -- dumptruck_ds
- if (deathmatch)
+ //--------------------------------------------------------------
+ // Ogre2 Nail frames
+ //--------------------------------------------------------------
+ nonvirtual void() mm_nail1 = [$shoot1, mm_nail2]
{
- remove(self);
- return;
- }
- // custom_mdls dumptruck_ds
- precache_body_model ("progs/ogre.mdl");
- precache_head_model ("progs/h_ogre.mdl");
- precache_proj_model ("progs/grenade.mdl");
-
- // custom_mdls dumptruck_ds
- precache_model ("progs/mervup.mdl"); //for style 3 Orge dumptruck_ds
- precache_model ("progs/lspike.mdl"); //for style 2 Ogre dumptruck_ds
- precache_sound_misc ("ogre/ogdrag.wav");
- precache_sound_death ("ogre/ogdth.wav");
- precache_sound_idle ("ogre/ogidle.wav");
- precache_sound_misc1 ("ogre/ogidle2.wav");
- precache_sound_pain ("ogre/ogpain1.wav");
- precache_sound_attack ("ogre/ogsawatk.wav");
- precache_sound_sight ("ogre/ogwake.wav");
- precache_sound_misc2 ("shalrath/attack2.wav");
- precache_sound ("fish/bite.wav");
- precache_sound ("boss1/throw.wav"); // jaycie erysdren 2021-09-14
-
- precache_gib1 ("progs/gib1.mdl");
- precache_gib2 ("progs/gib2.mdl");
- precache_gib3 ("progs/gib3.mdl");
-
- self.solid = SOLID_SLIDEBOX;
- self.movetype = MOVETYPE_STEP;
-
- // custom_mdls dumptruck_ds
- body_model ("progs/ogre.mdl");
- // setmodel (self, "progs/ogre.mdl");
-
- setsize (self, VEC_HULL2_MIN, VEC_HULL2_MAX);
- if (!self.proj_speed_mod)
+ ai_face ();
+ this.attack_elevation = IterateElevation (
+ OGRE_DEFAULT_ELEVATION, this.origin, this.enemy.origin);
+ };
+ nonvirtual void() mm_nail2 = [$shoot2, mm_nail3]
{
- self.proj_speed_mod = 1;
- }
- if (!self.health) //thanks RennyC -- dumptruck_ds
- self.health = 200;
-
- self.th_stand = ogre_stand1;
- self.th_walk = ogre_walk1;
- if (self.spawnflags & I_AM_TURRET)
+ ai_face ();
+ this.attack_elevation = IterateElevation (
+ this.attack_elevation, this.origin, this.enemy.origin);
+ };
+ nonvirtual void() mm_nail3 = [$shoot2, mm_nail4]
{
- self.th_run = ogre_turret_seek1;
- }
- else
+ ai_face ();
+ this.attack_elevation = IterateElevation (
+ this.attack_elevation, this.origin, this.enemy.origin);
+ };
+ nonvirtual void() mm_nail4 = [$shoot3, nail5]
{
- self.th_run = ogre_run1;
- }
- self.th_die = ogre_die;
- self.th_melee = ogre_melee;
- self.th_missile = ogre_nail1;
- self.th_turret = ogre_turret_attack1; //dumptruck_ds
- if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
- self.th_pain = ogre_pain;
- else
- self.th_pain = sub_nullpain;
+ ai_face ();
+ attack_preach_grenade (this.attack_elevation);
+ };
- walkmonster_start();
-};
+ // these are for the turret version of monster_ogre_marksman
-/*QUAKED monster_ogre_marksman (1 0 0) (-32 -32 -24) (32 32 64) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
-model ({ "path" : "progs/ogre.mdl", "frame": 63 });
-}
-Ogre Marksman.
-Unlike vanilla Quake, this is a slightly more accurate Orge.
+ //--------------------------------------------------------------
+ // Ogre2 Turret Attack
+ //--------------------------------------------------------------
+ nonvirtual void() mm_t_atk1 = [$shoot1, mm_t_atk2]
+ {
+ ai_face ();
+ this.attack_elevation = IterateElevation (
+ OGRE_DEFAULT_ELEVATION, this.origin, this.enemy.origin);
+ };
+ nonvirtual void() mm_t_atk2 = [$shoot2, mm_t_atk3]
+ {
+ ai_face ();
+ this.attack_elevation = IterateElevation (
+ this.attack_elevation, this.origin, this.enemy.origin);
+ };
+ nonvirtual void() mm_t_atk3 = [$shoot2, mm_t_atk4]
+ {
+ ai_face ();
+ this.attack_elevation = IterateElevation (
+ this.attack_elevation, this.origin, this.enemy.origin);
+ };
+ nonvirtual void() mm_t_atk4 = [$shoot3, mm_t_atk5]
+ {
+ ai_face ();
+ attack_preach_grenade (this.attack_elevation);
+ };
+ nonvirtual void() mm_t_atk5 = [$shoot4, mm_t_atk6] { ai_face (); };
+ nonvirtual void() mm_t_atk6 = [$shoot5, mm_t_atk7] { ai_face (); };
+ nonvirtual void() mm_t_atk7 = [$shoot5, mm_t_atk8] { ai_face (); };
+ nonvirtual void() mm_t_atk8 = [$shoot6, mm_t_atk9] { ai_face (); };
+ nonvirtual void() mm_t_atk9 = [$shoot6, mm_t_seek1] { ai_face (); };
+
+ //--------------------------------------------------------------
+ // Ogre2 Turret Seek / Stand
+ //--------------------------------------------------------------
+ nonvirtual void() mm_t_seek1 = [$stand1, mm_t_seek2] { ai_run (0); };
+ nonvirtual void() mm_t_seek2 = [$stand2, mm_t_seek3] { ai_run (0); };
+ nonvirtual void() mm_t_seek3 = [$stand3, mm_t_seek4] { ai_run (0); };
+ nonvirtual void() mm_t_seek4 = [$stand4, mm_t_seek5] { ai_run (0); };
+ nonvirtual void() mm_t_seek5 = [$stand5, mm_t_seek6]
+ {
+ if (random() < 0.2)
+ sound_idle (this, CHAN_VOICE, "ogre/ogidle.wav",
+ 1, ATTN_IDLE);
+ ai_run (0);
+ };
+ nonvirtual void() mm_t_seek6 = [$stand6, mm_t_seek7] { ai_run (0); };
+ nonvirtual void() mm_t_seek7 = [$stand7, mm_t_seek8] { ai_run (0); };
+ nonvirtual void() mm_t_seek8 = [$stand8, mm_t_seek9] { ai_run (0); };
+ nonvirtual void() mm_t_seek9 = [$stand9, mm_t_seek1] { ai_run (0); };
-keep_ammo(integer) : "1 = Don't drop backpack upon death"
-snd_death(string) : "Path to custom death sound"
-snd_pain(string) : "Path to custom pain sound"
-snd_sight(string) : "Path to custom sight sound"
-snd_attack(string) : "Path to custom attack sound (CHAINSAW)"
-snd_idle(string) : "Path to custom idle sound (IDLE)"
-snd_misc(string) : "Path to custom sound (IDLE CHAINSAW DRAG)"
-snd_misc1(string) : "Path to custom sound (ATTACK GRUNT)"
+ // end Preach -- dumptruck_ds
-mdl_head(string) : "Path to custom head model"
-mdl_body(string) : "Path to custom body model"
-mdl_proj(string) : "Path to custom projectile model"
-skin_head(float) : "Skin index of custom head model"
-skin_proj(float) : "Skin index of custom projectile model"
-mdl_gib1(string) : "Path to custom 1st gib model"
-mdl_gib2(string) : "Path to custom 2nd gib model"
-mdl_gib3(string) : "Path to custom 3rd gib model"
+ //==============================================================
+ // Initialization
+ //==============================================================
-effects(choices) : "Add a visual effect to an entity"
-0 : "None (Default)"
-1 : "Brightfield (yellow particles)"
-4 : "Bright light"
-8 : "Dim light"
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
+ {
+ if (deathmatch)
+ {
+ remove (this);
+ return;
+ }
-berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
-0 : "Off (Default)"
-1 : "Berserk (skip pain animations)"
+ // custom_mdls dumptruck_ds
+ precache_body_model ("progs/ogre.mdl");
+ precache_head_model ("progs/h_ogre.mdl");
+ precache_proj_model ("progs/grenade.mdl");
-delay(float) : "Delay spawn in for this amount of time"
+ precache_sound_misc ("ogre/ogdrag.wav");
+ precache_sound_death ("ogre/ogdth.wav");
+ precache_sound_idle ("ogre/ogidle.wav");
+ precache_sound_misc1 ("ogre/ogidle2.wav");
+ precache_sound_pain ("ogre/ogpain1.wav");
+ precache_sound_attack ("ogre/ogsawatk.wav");
+ precache_sound_sight ("ogre/ogwake.wav");
-wait(choices) : "Play an effect when trigger spawned?"
-0 : "Teleport Effects (Default)"
-1 : "Spawn Silently"
+ precache_gib1 ("progs/gib1.mdl");
+ precache_gib2 ("progs/gib2.mdl");
+ precache_gib3 ("progs/gib3.mdl");
-spawn_angry(Choices)
-0 : "Only when trigger spawned, default behavior - not angry"
-1 : "Only when trigger spawned, set to 1 to spawn angry at player"
+ this.solid = SOLID_SLIDEBOX;
+ this.movetype = MOVETYPE_STEP;
-infight_mode(Choices)
-0 : "Default behavior, only with different classnames"
-1 : "Infight with monsters with the same classname but a different mdl_body"
-2 : "Infight with monsters with the same classname and model but a different skin"
-3 : "Infight no matter what"
+ // custom_mdls dumptruck_ds
+ body_model ("progs/ogre.mdl");
+ // setmodel (this, "progs/ogre.mdl");
-health(integer) : "Set this to a custom health amount"
-pain_target(string) : "Fire this target when pain_threshold is reached"
-pain_threshold(integer) : "Fire pain_target when health drops below this amount"
-sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
-skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
-obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
-obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
-damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
+ setsize (this, VEC_HULL2_MIN, VEC_HULL2_MAX);
+ if (!this.proj_speed_mod)
+ {
+ this.proj_speed_mod = 1;
+ }
-*/
-void() monster_ogre_marksman =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
+ // thanks RennyC -- dumptruck_ds
+ if (!this.health)
+ this.health = 200;
- if (deathmatch)
- {
- remove(self);
- return;
- }
- // custom_mdls dumptruck_ds
- precache_body_model ("progs/ogre.mdl");
- precache_head_model ("progs/h_ogre.mdl");
- precache_proj_model ("progs/grenade.mdl");
-
- precache_sound_misc ("ogre/ogdrag.wav");
- precache_sound_death ("ogre/ogdth.wav");
- precache_sound_idle ("ogre/ogidle.wav");
- precache_sound_misc1 ("ogre/ogidle2.wav");
- precache_sound_pain ("ogre/ogpain1.wav");
- precache_sound_attack ("ogre/ogsawatk.wav");
- precache_sound_sight ("ogre/ogwake.wav");
-
- precache_gib1 ("progs/gib1.mdl");
- precache_gib2 ("progs/gib2.mdl");
- precache_gib3 ("progs/gib3.mdl");
-
- self.solid = SOLID_SLIDEBOX;
- self.movetype = MOVETYPE_STEP;
-
- // custom_mdls dumptruck_ds
- body_model ("progs/ogre.mdl");
- // setmodel (self, "progs/ogre.mdl");
-
- setsize (self, VEC_HULL2_MIN, VEC_HULL2_MAX);
- if (!self.proj_speed_mod)
- {
- self.proj_speed_mod = 1;
- }
- if (!self.health) //thanks RennyC -- dumptruck_ds
- self.health = 200;
+ this.think_stand = this.stand1;
+ this.think_walk = this.walk1;
+ if (this.spawnflags & I_AM_TURRET)
+ {
+ this.think_run = this.mm_t_seek1;
+ }
+ else
+ {
+ this.think_run = this.run1;
+ }
+ this.th_die = this.do_destroy;
+ this.think_melee = this.attack_melee;
+ this.think_missile = this.mm_nail1;
+ // dumptruck_ds
+ this.think_turret = this.mm_t_atk1;
+ // Berserk test from
+ // http://celephais.net/board/view_thread.php?id=4&start=3465
+ // -- dumptruck_ds
+ if !(this.berserk)
+ this.th_pain = this.do_damage;
+ else
+ this.th_pain = sub_nullpain;
- self.th_stand = ogre_stand1;
- self.th_walk = ogre_walk1;
- if (self.spawnflags & I_AM_TURRET)
- {
- self.th_run = ogre2_turret_seek1;
- }
- else
- {
- self.th_run = ogre_run1;
- }
- self.th_die = ogre_die;
- self.th_melee = ogre_melee;
- self.th_missile = ogre2_nail1;
- self.th_turret = ogre2_turret_attack1; //dumptruck_ds
- if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
- self.th_pain = ogre_pain;
- else
- self.th_pain = sub_nullpain;
+ // walkmonster_start
+ super::init_spawned ();
+ };
- walkmonster_start();
+ //--------------------------------------------------------------
+ void() monster_ogre_marksman =
+ {
+ this.classtype = CT_MONSTER_OGRE_MARKSMAN;
+ };
};
-// {
-// if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
-// return;
-//
-// monster_ogre ();
-// };
-
/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
/*QUAKED monster_dead_ogre (0 0.5 0.8) (-32 -32 -24) (32 32 64) SOLID ON_SIDE X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
@@ -1554,7 +1771,7 @@ void() monster_dead_ogre =
if (self.spawnflags & 1)
{
self.solid = SOLID_BBOX;
- setsize(self,'-40.64 -54.06 -54.1','29.42 54.63 30');
+ setsize (self,'-40.64 -54.06 -54.1','29.42 54.63 30');
}
else
{
@@ -1567,7 +1784,7 @@ void() monster_dead_ogre =
if (self.spawnflags & 1)
{
self.solid = SOLID_BBOX;
- setsize(self,'-45.64 -29.46 -54.52','33.87 39.18 30');
+ setsize (self,'-45.64 -29.46 -54.52','33.87 39.18 30');
}
else
{
Return to the top of this page or return to the overview of this repo.
Diff qc/monsters/oldone.qc
diff --git a/qc/monsters/oldone.qc b/qc/monsters/oldone.qc
index 13731a2..f4b68b7 100644
--- a/qc/monsters/oldone.qc
+++ b/qc/monsters/oldone.qc
@@ -1,24 +1,21 @@
-/*
-==============================================================================
-
-OLD ONE
-
-==============================================================================
-*/
+//==============================================================================
+// OLD ONE
+//==============================================================================
+
+//======================================================================
+// globals
+//======================================================================
+entity shub;
+
+//======================================================================
+// frame macros
+//======================================================================
$cd id1/models/old_one
$origin 0 0 24
$base base
$skin skin
$scale 1
-void() finale_1;
-void() finale_2;
-void() finale_3;
-void() finale_4;
-
-
-entity shub;
-
$frame old1 old2 old3 old4 old5 old6 old7 old8 old9
$frame old10 old11 old12 old13 old14 old15 old16 old17 old18 old19
$frame old20 old21 old22 old23 old24 old25 old26 old27 old28 old29
@@ -29,336 +26,378 @@ $frame shake1 shake2 shake3 shake4 shake5 shake6 shake7 shake8
$frame shake9 shake10 shake11 shake12 shake13 shake14
$frame shake15 shake16 shake17 shake18 shake19 shake20
-//void() old_stand =[ $old1, old_stand ] {};
-
-void() old_idle1 =[ $old1, old_idle2 ] {};
-void() old_idle2 =[ $old2, old_idle3 ] {};
-void() old_idle3 =[ $old3, old_idle4 ] {};
-void() old_idle4 =[ $old4, old_idle5 ] {};
-void() old_idle5 =[ $old5, old_idle6 ] {};
-void() old_idle6 =[ $old6, old_idle7 ] {};
-void() old_idle7 =[ $old7, old_idle8 ] {};
-void() old_idle8 =[ $old8, old_idle9 ] {};
-void() old_idle9 =[ $old9, old_idle10 ] {};
-void() old_idle10 =[ $old10, old_idle11 ] {};
-void() old_idle11 =[ $old11, old_idle12 ] {};
-void() old_idle12 =[ $old12, old_idle13 ] {};
-void() old_idle13 =[ $old13, old_idle14 ] {};
-void() old_idle14 =[ $old14, old_idle15 ] {};
-void() old_idle15 =[ $old15, old_idle16 ] {};
-void() old_idle16 =[ $old16, old_idle17 ] {};
-void() old_idle17 =[ $old17, old_idle18 ] {};
-void() old_idle18 =[ $old18, old_idle19 ] {};
-void() old_idle19 =[ $old19, old_idle20 ] {};
-void() old_idle20 =[ $old20, old_idle21 ] {};
-void() old_idle21 =[ $old21, old_idle22 ] {};
-void() old_idle22 =[ $old22, old_idle23 ] {};
-void() old_idle23 =[ $old23, old_idle24 ] {};
-void() old_idle24 =[ $old24, old_idle25 ] {};
-void() old_idle25 =[ $old25, old_idle26 ] {};
-void() old_idle26 =[ $old26, old_idle27 ] {};
-void() old_idle27 =[ $old27, old_idle28 ] {};
-void() old_idle28 =[ $old28, old_idle29 ] {};
-void() old_idle29 =[ $old29, old_idle30 ] {};
-void() old_idle30 =[ $old30, old_idle31 ] {};
-void() old_idle31 =[ $old31, old_idle32 ] {};
-void() old_idle32 =[ $old32, old_idle33 ] {};
-void() old_idle33 =[ $old33, old_idle34 ] {};
-void() old_idle34 =[ $old34, old_idle35 ] {};
-void() old_idle35 =[ $old35, old_idle36 ] {};
-void() old_idle36 =[ $old36, old_idle37 ] {};
-void() old_idle37 =[ $old37, old_idle38 ] {};
-void() old_idle38 =[ $old38, old_idle39 ] {};
-void() old_idle39 =[ $old39, old_idle40 ] {};
-void() old_idle40 =[ $old40, old_idle41 ] {};
-void() old_idle41 =[ $old41, old_idle42 ] {};
-void() old_idle42 =[ $old42, old_idle43 ] {};
-void() old_idle43 =[ $old43, old_idle44 ] {};
-void() old_idle44 =[ $old44, old_idle45 ] {};
-void() old_idle45 =[ $old45, old_idle46 ] {};
-void() old_idle46 =[ $old46, old_idle1 ] {};
-
-
-void() old_thrash1 =[ $shake1, old_thrash2 ] {lightstyle(0, "m");};
-void() old_thrash2 =[ $shake2, old_thrash3 ] {lightstyle(0, "k");};
-void() old_thrash3 =[ $shake3, old_thrash4 ] {lightstyle(0, "k");};
-void() old_thrash4 =[ $shake4, old_thrash5 ] {lightstyle(0, "i");};
-void() old_thrash5 =[ $shake5, old_thrash6 ] {lightstyle(0, "g");};
-void() old_thrash6 =[ $shake6, old_thrash7 ] {lightstyle(0, "e");};
-void() old_thrash7 =[ $shake7, old_thrash8 ] {lightstyle(0, "c");};
-void() old_thrash8 =[ $shake8, old_thrash9 ] {lightstyle(0, "a");};
-void() old_thrash9 =[ $shake9, old_thrash10 ] {lightstyle(0, "c");};
-void() old_thrash10 =[ $shake10, old_thrash11 ] {lightstyle(0, "e");};
-void() old_thrash11 =[ $shake11, old_thrash12 ] {lightstyle(0, "g");};
-void() old_thrash12 =[ $shake12, old_thrash13 ] {lightstyle(0, "i");};
-void() old_thrash13 =[ $shake13, old_thrash14 ] {lightstyle(0, "k");};
-void() old_thrash14 =[ $shake14, old_thrash15 ] {lightstyle(0, "m");};
-void() old_thrash15 =[ $shake15, old_thrash16 ] {lightstyle(0, "m");
-self.cnt = self.cnt + 1;
-if (self.cnt != 3)
- self.think = old_thrash1;
-};
-void() old_thrash16 =[ $shake16, old_thrash17 ] {lightstyle(0, "g");};
-void() old_thrash17 =[ $shake17, old_thrash18 ] {lightstyle(0, "c");};
-void() old_thrash18 =[ $shake18, old_thrash19 ] {lightstyle(0, "b");};
-void() old_thrash19 =[ $shake19, old_thrash20 ] {lightstyle(0, "a");};
-void() old_thrash20 =[ $shake20, old_thrash20 ] {finale_4();};
-
-//============================================================================
-
-void() finale_1 =
+/*QUAKED monster_oldone (1 0 0) (-160 -128 -24) (160 128 256)
+*/
+class monster_oldone: base_walkmonster
{
- local entity pos, pl;
- local entity timer;
-
-// 1998-07-30 Shub kill count fix by Maddes start
- killed_monsters = killed_monsters + 1;
- WriteByte (MSG_ALL, SVC_KILLEDMONSTER); // FIXME: reliable broadcast
-// 1998-07-30 Shub kill count fix by Maddes end
-
- intermission_exittime = time + 10000000; // never allow exit
- intermission_running = 1;
-
- // find the intermission spot
- pos = find (world, classname, "info_intermission");
- if (!pos)
- error ("no info_intermission");
- pl = find (world, classname, "misc_teleporttrain");
- if (!pl)
- error ("no teleporttrain");
- remove (pl);
-
- WriteByte (MSG_ALL, SVC_FINALE);
- WriteString (MSG_ALL, "");
-
- pl = find (world, classname, "player");
- while (pl != world)
+ //--------------------------------------------------------------
+ nonvirtual void() finale_1 =
{
- pl.view_ofs = '0 0 0';
- pl.angles = other.v_angle = pos.mangle;
- pl.fixangle = TRUE; // turn this way immediately
- pl.map = self.map;
- pl.nextthink = time + 0.5;
- pl.takedamage = DAMAGE_NO;
- pl.solid = SOLID_NOT;
- pl.movetype = MOVETYPE_NONE;
- pl.modelindex = 0;
- setorigin (pl, pos.origin);
- pl = find (pl, classname, "player");
- }
-
- // make fake versions of all players as standins, and move the real
- // players to the intermission spot
-
- // wait for 1 second
- timer = spawn();
- timer.nextthink = time + 1;
- timer.think = finale_2;
-};
+ local entity pos, pl;
+ local entity timer;
+
+ // 1998-07-30 Shub kill count fix by Maddes start
+ killed_monsters = killed_monsters + 1;
+ // FIXME: reliable broadcast
+ WriteByte (MSG_ALL, SVC_KILLEDMONSTER);
+ // 1998-07-30 Shub kill count fix by Maddes end
+
+ // never allow exit
+ intermission_exittime = time + 10000000;
+ intermission_running = 1;
+
+ // find the intermission spot
+ pos = findfloat (world, ::classtype, CT_INFO_INTERMISSION);
+ if (!pos)
+ error ("no info_intermission");
+ pl = findfloat (world, ::classtype, CT_MISC_TELEPORTTRAIN);
+ if (!pl)
+ error ("no teleporttrain");
+ remove (pl);
+
+ WriteByte (MSG_ALL, SVC_FINALE);
+ WriteString (MSG_ALL, "");
+
+ pl = findfloat (world, ::classtype, CT_PLAYER);
+ while (pl != world)
+ {
+ pl.view_ofs = '0 0 0';
+ pl.angles = other.v_angle = pos.mangle;
+ // turn this way immediately
+ pl.fixangle = TRUE;
+ pl.map = this.map;
+ pl.nextthink = time + 0.5;
+ pl.takedamage = DAMAGE_NO;
+ pl.solid = SOLID_NOT;
+ pl.movetype = MOVETYPE_NONE;
+ pl.modelindex = 0;
+ setorigin (pl, pos.origin);
+ pl = findfloat (pl, ::classtype, CT_PLAYER);
+ }
-void() finale_2 =
-{
- local vector o;
+ // make fake versions of all players as standins, and
+ // move the real players to the intermission spot
- // start a teleport splash inside shub
+ // wait for 1 second
+ // TODO CEV rework into a class outside of moster_oldone
+ timer = spawn ();
+ timer.nextthink = time + 1;
+ timer.think = finale_2;
+ };
- o = shub.origin - '0 100 0';
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_TELEPORT);
- WriteCoord (MSG_BROADCAST, o_x);
- WriteCoord (MSG_BROADCAST, o_y);
- WriteCoord (MSG_BROADCAST, o_z);
+ //--------------------------------------------------------------
+ nonvirtual void() finale_2 =
+ {
+ local vector o;
- sound (shub, CHAN_VOICE, "misc/r_tele1.wav", 1, ATTN_NORM);
+ // start a teleport splash inside shub
- self.nextthink = time + 2;
- self.think = finale_3;
-};
+ o = shub.origin - '0 100 0';
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_TELEPORT);
+ WriteCoord (MSG_BROADCAST, o_x);
+ WriteCoord (MSG_BROADCAST, o_y);
+ WriteCoord (MSG_BROADCAST, o_z);
-void() finale_3 =
-{
- // start shub thrashing wildly
- shub.think = old_thrash1;
- sound_death (shub, CHAN_VOICE, "boss2/death.wav", 1, ATTN_NORM);
- lightstyle(0, "abcdefghijklmlkjihgfedcb");
-};
+ sound (shub, CHAN_VOICE, "misc/r_tele1.wav", 1, ATTN_NORM);
-void() finale_4 =
-{
- // throw tons of meat chunks
- local vector oldo;
- local float x, y, z;
- local float r;
- local entity n;
+ this.nextthink = time + 2;
+ this.think = finale_3;
+ };
- sound_misc (self, CHAN_VOICE, "boss2/pop2.wav", 1, ATTN_NORM);
+ //--------------------------------------------------------------
+ nonvirtual void() finale_3 =
+ {
+ // start shub thrashing wildly
+ shub.think = monster_oldone::thrash1;
+ sound_death (shub, CHAN_VOICE, "boss2/death.wav", 1, ATTN_NORM);
+ lightstyle (0, "abcdefghijklmlkjihgfedcb");
+ };
+
+ //--------------------------------------------------------------
+ nonvirtual void() finale_4 =
+ {
+ // throw tons of meat chunks
+ local vector oldo;
+ local float x, y, z;
+ local float r;
+ local entity n;
- oldo = self.origin;
+ sound_misc (this, CHAN_VOICE, "boss2/pop2.wav", 1, ATTN_NORM);
- z = 16;
- while (z <= 144)
- {
- x = -64;
- while (x <= 64)
+ oldo = this.origin;
+
+ z = 16;
+ while (z <= 144)
{
- y = -64;
- while (y <= 64)
+ x = -64;
+ while (x <= 64)
{
- self.origin_x = oldo_x + x;
- self.origin_y = oldo_y + y;
- self.origin_z = oldo_z + z;
-
- r = random();
- if (r < 0.3)
- ThrowGib ("progs/gib1.mdl", -999);
- else if (r < 0.6)
- ThrowGib ("progs/gib2.mdl", -999);
- else
- ThrowGib ("progs/gib3.mdl", -999);
- y = y + 32;
+ y = -64;
+ while (y <= 64)
+ {
+ this.origin_x = oldo_x + x;
+ this.origin_y = oldo_y + y;
+ this.origin_z = oldo_z + z;
+
+ r = random ();
+ if (r < 0.3)
+ ThrowGib ("progs/gib1.mdl",
+ -999);
+ else if (r < 0.6)
+ ThrowGib ("progs/gib2.mdl",
+ -999);
+ else
+ ThrowGib ("progs/gib3.mdl",
+ -999);
+ y = y + 32;
+ }
+ x = x + 32;
}
- x = x + 32;
+ z = z + 96;
}
- z = z + 96;
- }
- // start the end text
- WriteByte (MSG_ALL, SVC_FINALE);
- WriteString (MSG_ALL, "Congratulations and well done! You have\nbeaten the hideous Shub-Niggurath, and\nher hundreds of ugly changelings and\nmonsters. You have proven that your\nskill and your cunning are greater than\nall the powers of Quake. You are the\nmaster now. Id Software salutes you.");
-
-// put a player model down
- n = spawn();
- setmodel (n, "progs/player.mdl");
- oldo = oldo - '32 264 0';
- setorigin (n, oldo);
- n.angles = '0 290 0';
- n.frame = 1;
-
- remove (self);
-
-// switch cd track
- WriteByte (MSG_ALL, SVC_CDTRACK);
- WriteByte (MSG_ALL, 3);
- WriteByte (MSG_ALL, 3);
- lightstyle(0, "m");
-};
-
-//============================================================================
-
-void(entity attacker, float damage) nopain =
-{
- self.health = 40000;
-};
-
-//============================================================================
-
-// The next function is from Than's Deathmatch Dimensions; I've cut-and-pasted
-// it in here so I can play dmd8.bsp -- CEV
-
-// Shub death treated more like a standard monster death for Deathmatch
-// Dimension; Customised intermission message is handled in client.qc
-// -- comment from DMD's QC source
-void() shub_death =
-{
- self.solid = SOLID_NOT;
- killed_monsters = killed_monsters + 1;
- WriteByte (MSG_ALL, SVC_KILLEDMONSTER);
-
- // Remove any teleporttrain in the map (will need one for vanilla progs to avoid error)
- local entity tt;
- tt = find (world, classname, "misc_teleporttrain");
- if (tt)
- remove (tt);
-
- // throw tons of meat chunks
- local vector oldo;
- local float x, y, z;
- local float r;
- local float gibpow;
-
- sound (self, CHAN_VOICE, "boss2/pop2.wav", 1, ATTN_NORM);
-
- oldo = self.origin;
- gibpow = -160;
-
- z = 16;
- while (z <= 144)
+ // start the end text
+ WriteByte (MSG_ALL, SVC_FINALE);
+ WriteString (MSG_ALL, "Congratulations and well done! "
+ "You have\nbeaten the hideous Shub-Niggurath, and\n"
+ "her hundreds of ugly changelings and\n"
+ "monsters. You have proven that your\n"
+ "skill and your cunning are greater than\n"
+ "all the powers of Quake. You are the\n"
+ "master now. Id Software salutes you.");
+
+ // put a player model down
+ n = spawn ();
+ setmodel (n, "progs/player.mdl");
+ oldo = oldo - '32 264 0';
+ setorigin (n, oldo);
+ n.angles = '0 290 0';
+ n.frame = 1;
+
+ // switch cd track
+ WriteByte (MSG_ALL, SVC_CDTRACK);
+ WriteByte (MSG_ALL, 3);
+ WriteByte (MSG_ALL, 3);
+ lightstyle (0, "m");
+
+ remove (this);
+ };
+
+ //--------------------------------------------------------------
+ // Shub Stand function
+ //--------------------------------------------------------------
+ // nonvirtual void() stand = [$old1, stand] { };
+
+ //--------------------------------------------------------------
+ // Shub Idle functions
+ //--------------------------------------------------------------
+ nonvirtual void() idle1 = [$old1, idle2] { };
+ nonvirtual void() idle2 = [$old2, idle3] { };
+ nonvirtual void() idle3 = [$old3, idle4] { };
+ nonvirtual void() idle4 = [$old4, idle5] { };
+ nonvirtual void() idle5 = [$old5, idle6] { };
+ nonvirtual void() idle6 = [$old6, idle7] { };
+ nonvirtual void() idle7 = [$old7, idle8] { };
+ nonvirtual void() idle8 = [$old8, idle9] { };
+ nonvirtual void() idle9 = [$old9, idle10] { };
+ nonvirtual void() idle10 = [$old10, idle11] { };
+ nonvirtual void() idle11 = [$old11, idle12] { };
+ nonvirtual void() idle12 = [$old12, idle13] { };
+ nonvirtual void() idle13 = [$old13, idle14] { };
+ nonvirtual void() idle14 = [$old14, idle15] { };
+ nonvirtual void() idle15 = [$old15, idle16] { };
+ nonvirtual void() idle16 = [$old16, idle17] { };
+ nonvirtual void() idle17 = [$old17, idle18] { };
+ nonvirtual void() idle18 = [$old18, idle19] { };
+ nonvirtual void() idle19 = [$old19, idle20] { };
+ nonvirtual void() idle20 = [$old20, idle21] { };
+ nonvirtual void() idle21 = [$old21, idle22] { };
+ nonvirtual void() idle22 = [$old22, idle23] { };
+ nonvirtual void() idle23 = [$old23, idle24] { };
+ nonvirtual void() idle24 = [$old24, idle25] { };
+ nonvirtual void() idle25 = [$old25, idle26] { };
+ nonvirtual void() idle26 = [$old26, idle27] { };
+ nonvirtual void() idle27 = [$old27, idle28] { };
+ nonvirtual void() idle28 = [$old28, idle29] { };
+ nonvirtual void() idle29 = [$old29, idle30] { };
+ nonvirtual void() idle30 = [$old30, idle31] { };
+ nonvirtual void() idle31 = [$old31, idle32] { };
+ nonvirtual void() idle32 = [$old32, idle33] { };
+ nonvirtual void() idle33 = [$old33, idle34] { };
+ nonvirtual void() idle34 = [$old34, idle35] { };
+ nonvirtual void() idle35 = [$old35, idle36] { };
+ nonvirtual void() idle36 = [$old36, idle37] { };
+ nonvirtual void() idle37 = [$old37, idle38] { };
+ nonvirtual void() idle38 = [$old38, idle39] { };
+ nonvirtual void() idle39 = [$old39, idle40] { };
+ nonvirtual void() idle40 = [$old40, idle41] { };
+ nonvirtual void() idle41 = [$old41, idle42] { };
+ nonvirtual void() idle42 = [$old42, idle43] { };
+ nonvirtual void() idle43 = [$old43, idle44] { };
+ nonvirtual void() idle44 = [$old44, idle45] { };
+ nonvirtual void() idle45 = [$old45, idle46] { };
+ nonvirtual void() idle46 = [$old46, idle1] { };
+
+ //--------------------------------------------------------------
+ // Shub Thrashing
+ //--------------------------------------------------------------
+ nonvirtual void() thrash1 = [$shake1, thrash2] { lightstyle (0, "m"); };
+ nonvirtual void() thrash2 = [$shake2, thrash3] { lightstyle (0, "k"); };
+ nonvirtual void() thrash3 = [$shake3, thrash4] { lightstyle (0, "k"); };
+ nonvirtual void() thrash4 = [$shake4, thrash5] { lightstyle (0, "i"); };
+ nonvirtual void() thrash5 = [$shake5, thrash6] { lightstyle (0, "g"); };
+ nonvirtual void() thrash6 = [$shake6, thrash7] { lightstyle (0, "e"); };
+ nonvirtual void() thrash7 = [$shake7, thrash8] { lightstyle (0, "c"); };
+ nonvirtual void() thrash8 = [$shake8, thrash9] { lightstyle (0, "a"); };
+ nonvirtual void() thrash9 = [$shake9, thrash10] { lightstyle(0, "c"); };
+ nonvirtual void() thrash10 = [$shake10, thrash11] {lightstyle(0, "e");};
+ nonvirtual void() thrash11 = [$shake11, thrash12] {lightstyle(0, "g");};
+ nonvirtual void() thrash12 = [$shake12, thrash13] {lightstyle(0, "i");};
+ nonvirtual void() thrash13 = [$shake13, thrash14] {lightstyle(0, "k");};
+ nonvirtual void() thrash14 = [$shake14, thrash15] {lightstyle(0, "m");};
+ nonvirtual void() thrash15 = [$shake15, thrash16]
+ {
+ lightstyle (0, "m");
+ this.cnt = this.cnt + 1;
+ if (this.cnt != 3)
+ this.think = this.thrash1;
+ };
+ nonvirtual void() thrash16 = [$shake16, thrash17] {lightstyle(0, "g");};
+ nonvirtual void() thrash17 = [$shake17, thrash18] {lightstyle(0, "c");};
+ nonvirtual void() thrash18 = [$shake18, thrash19] {lightstyle(0, "b");};
+ nonvirtual void() thrash19 = [$shake19, thrash20] {lightstyle(0, "a");};
+ nonvirtual void() thrash20 = [$shake20, thrash20] { finale_4 (); };
+
+ //==============================================================
+ // Interaction
+ //==============================================================
+
+
+ //--------------------------------------------------------------
+ // nopain
+ //--------------------------------------------------------------
+ virtual void(entity attacker, float damage) do_damage =
{
- x = -64;
- while (x <= 64)
+ this.health = 40000;
+ };
+
+ //--------------------------------------------------------------
+ // shub_death
+ //
+ // The next function is from Than's Deathmatch Dimensions; I've
+ // cut-and-pasted it in here so I can play dmd8.bsp -- CEV
+ //
+ // Shub death treated more like a standard monster death for
+ // Deathmatch Dimension; Customised intermission message is
+ // handled in client.qc -- comment from DMD's QC source
+ //--------------------------------------------------------------
+ virtual void() do_destroy =
+ {
+ this.solid = SOLID_NOT;
+ killed_monsters = killed_monsters + 1;
+ WriteByte (MSG_ALL, SVC_KILLEDMONSTER);
+
+ // Remove any teleporttrain in the map (will need one for
+ // vanilla progs to avoid error)
+ local entity tt;
+ tt = findfloat (world, ::classtype, CT_MISC_TELEPORTTRAIN);
+ if (tt)
+ remove (tt);
+
+ // throw tons of meat chunks
+ local vector oldo;
+ local float x, y, z;
+ local float r;
+ local float gibpow;
+
+ sound (this, CHAN_VOICE, "boss2/pop2.wav", 1, ATTN_NORM);
+
+ oldo = this.origin;
+ gibpow = -160;
+
+ z = 16;
+ while (z <= 144)
{
- y = -64;
- while (y <= 64)
+ x = -64;
+ while (x <= 64)
{
- self.origin_x = oldo_x + x;
- self.origin_y = oldo_y + y;
- self.origin_z = oldo_z + z;
-
- r = random();
- if (r < 0.3)
- ThrowGib ("progs/gib1.mdl", gibpow);
- else if (r < 0.6)
- ThrowGib ("progs/gib2.mdl", gibpow);
- else
- ThrowGib ("progs/gib3.mdl", gibpow);
- y = y + 32;
+ y = -64;
+ while (y <= 64)
+ {
+ this.origin_x = oldo_x + x;
+ this.origin_y = oldo_y + y;
+ this.origin_z = oldo_z + z;
+
+ r = random ();
+ if (r < 0.3)
+ ThrowGib ("progs/gib1.mdl",
+ gibpow);
+ else if (r < 0.6)
+ ThrowGib ("progs/gib2.mdl",
+ gibpow);
+ else
+ ThrowGib ("progs/gib3.mdl",
+ gibpow);
+ y = y + 32;
+ }
+ x = x + 32;
}
- x = x + 32;
+ z = z + 96;
}
- z = z + 96;
- }
- remove (self);
-};
+ remove (this);
+ };
+ //==============================================================
+ // Initialization
+ //==============================================================
-/*QUAKED monster_oldone (1 0 0) (-160 -128 -24) (160 128 256)
-*/
-// TODO CEV
-void() monster_oldone =
-{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
+ {
+ if (this.spawnflags & I_AM_TURRET)
+ objerror ("Incompatible spawnflag: TURRET_MODE\n");
- if (self.spawnflags & I_AM_TURRET)
- objerror("Incompatible spawnflag: TURRET_MODE\n");
+ if (deathmatch)
+ {
+ remove (this);
+ return;
+ }
- if (deathmatch)
- {
- remove(self);
- return;
- }
-
- precache_body_model2 ("progs/oldone.mdl");
- // precache_model2 ("progs/oldone.mdl");
-
- precache_sound2_death ("boss2/death.wav");
- // precache_sound2_idle ("boss2/idle.wav");
- precache_sound2_sight ("boss2/sight.wav");
- precache_sound2_misc ("boss2/pop2.wav");
-
- self.solid = SOLID_SLIDEBOX;
- self.movetype = MOVETYPE_STEP;
-
- body_model ("progs/oldone.mdl"); //custom_mdls dumptruck_ds
- // setmodel (self, "progs/oldone.mdl");
- setsize (self, '-160 -128 -24', '160 128 256');
-
- self.health = 40000; // kill by telefrag
- self.think = old_idle1;
- self.nextthink = time + 0.1;
- self.takedamage = DAMAGE_YES;
- self.th_pain = nopain;
- if (self.spawnflags & 2)
+ precache_body_model2 ("progs/oldone.mdl");
+ // precache_model2 ("progs/oldone.mdl");
+
+ precache_sound2_death ("boss2/death.wav");
+ // precache_sound2_idle ("boss2/idle.wav");
+ precache_sound2_sight ("boss2/sight.wav");
+ precache_sound2_misc ("boss2/pop2.wav");
+
+ this.solid = SOLID_SLIDEBOX;
+ this.movetype = MOVETYPE_STEP;
+
+ // custom_mdls dumptruck_ds
+ body_model ("progs/oldone.mdl");
+ // setmodel (this, "progs/oldone.mdl");
+ setsize (this, '-160 -128 -24', '160 128 256');
+
+ // kill by telefrag
+ this.health = 40000;
+ this.takedamage = DAMAGE_YES;
+ this.th_pain = this.do_damage;
+ if (this.spawnflags & 2)
+ this.th_die = this.do_destroy;
+ else
+ this.th_die = finale_1;
+ shub = this;
+
+ total_monsters = total_monsters + 1;
+ this.think = this.idle1;
+ this.nextthink = time + 0.1;
+ };
+
+ //--------------------------------------------------------------
+ void() monster_oldone =
{
- self.th_die = shub_death;
- }
- else
- {
- self.th_die = finale_1;
- }
- self.touch = monster_touch; // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten
- shub = self;
-
- total_monsters = total_monsters + 1;
+ this.classtype = CT_MONSTER_BOSS_OLDONE;
+ };
};
Return to the top of this page or return to the overview of this repo.
Diff qc/monsters/oldone2.qc
diff --git a/qc/monsters/oldone2.qc b/qc/monsters/oldone2.qc
index 0cd4047..a2f0b7d 100644
--- a/qc/monsters/oldone2.qc
+++ b/qc/monsters/oldone2.qc
@@ -1,10 +1,10 @@
-/*
-==============================================================================
+//==============================================================================
+// OLD ONE 2 - killable variant -- dumptruck_ds
+//==============================================================================
-OLD ONE 2 - killable variant -- dumptruck_ds
-
-==============================================================================
-*/
+//======================================================================
+// frame macros
+//======================================================================
$cd id1/models/old2_one
$origin 0 0 24
$base base
@@ -21,347 +21,395 @@ $frame shake1 shake2 shake3 shake4 shake5 shake6 shake7 shake8
$frame shake9 shake10 shake11 shake12 shake13 shake14
$frame shake15 shake16 shake17 shake18 shake19 shake20
-void() shub_face =
+/*QUAKED monster_oldone2 (1 0 0) (-160 -128 -24) (160 128 256)
+*/
+class monster_oldone2: base_walkmonster
{
-// go for another player if multi player
- if (self.enemy.health <= 0 || random() < 0.02)
+ //--------------------------------------------------------------
+ virtual void() ai_sightsound =
{
- self.enemy = find(self.enemy, classname, "player");
- if (!self.enemy)
- self.enemy = find(self.enemy, classname, "player");
- }
- ai_face();
-};
-
+ sound_sight (this, CHAN_VOICE, "boss2/sight.wav", 1, ATTN_NORM);
+ };
-void() old2_stand =
-{
- FindTarget ();
-};
-
-void() old2_idle1 =[ $old1, old2_idle2 ] {old2_stand();};
-void() old2_idle2 =[ $old2, old2_idle3 ] {old2_stand();};
-void() old2_idle3 =[ $old3, old2_idle4 ] {old2_stand();};
-void() old2_idle4 =[ $old4, old2_idle5 ] {old2_stand();};
-void() old2_idle5 =[ $old5, old2_idle6 ] {old2_stand();};
-void() old2_idle6 =[ $old6, old2_idle7 ] {old2_stand();};
-void() old2_idle7 =[ $old7, old2_idle8 ] {old2_stand();};
-void() old2_idle8 =[ $old8, old2_idle9 ] {old2_stand();};
-void() old2_idle9 =[ $old9, old2_idle10 ] {old2_stand();};
-void() old2_idle10 =[ $old10, old2_idle11 ] {old2_stand();};
-void() old2_idle11 =[ $old11, old2_idle12 ] {old2_stand();};
-void() old2_idle12 =[ $old12, old2_idle13 ] {old2_stand();};
-void() old2_idle13 =[ $old13, old2_idle14 ] {old2_stand();};
-void() old2_idle14 =[ $old14, old2_idle15 ] {old2_stand();};
-void() old2_idle15 =[ $old15, old2_idle16 ] {old2_stand();};
-void() old2_idle16 =[ $old16, old2_idle17 ] {old2_stand();};
-void() old2_idle17 =[ $old17, old2_idle18 ] {old2_stand();};
-void() old2_idle18 =[ $old18, old2_idle19 ] {old2_stand();};
-void() old2_idle19 =[ $old19, old2_idle20 ] {old2_stand();};
-void() old2_idle20 =[ $old20, old2_idle21 ] {old2_stand();};
-void() old2_idle21 =[ $old21, old2_idle22 ] {old2_stand();};
-void() old2_idle22 =[ $old22, old2_idle23 ] {old2_stand();};
-void() old2_idle23 =[ $old23, old2_idle24 ] {old2_stand();};
-void() old2_idle24 =[ $old24, old2_idle25 ] {old2_stand();};
-void() old2_idle25 =[ $old25, old2_idle26 ] {old2_stand();};
-void() old2_idle26 =[ $old26, old2_idle27 ] {old2_stand();};
-void() old2_idle27 =[ $old27, old2_idle28 ] {old2_stand();};
-void() old2_idle28 =[ $old28, old2_idle29 ] {old2_stand();};
-void() old2_idle29 =[ $old29, old2_idle30 ] {old2_stand();};
-void() old2_idle30 =[ $old30, old2_idle31 ] {old2_stand();};
-void() old2_idle31 =[ $old31, old2_idle32 ] {old2_stand();};
-void() old2_idle32 =[ $old32, old2_idle33 ] {old2_stand();};
-void() old2_idle33 =[ $old33, old2_idle34 ] {old2_stand();};
-void() old2_idle34 =[ $old34, old2_idle35 ] {old2_stand();};
-void() old2_idle35 =[ $old35, old2_idle36 ] {old2_stand();};
-void() old2_idle36 =[ $old36, old2_idle37 ] {old2_stand();};
-void() old2_idle37 =[ $old37, old2_idle38 ] {old2_stand();};
-void() old2_idle38 =[ $old38, old2_idle39 ] {old2_stand();};
-void() old2_idle39 =[ $old39, old2_idle40 ] {old2_stand();};
-void() old2_idle40 =[ $old40, old2_idle41 ] {old2_stand();};
-void() old2_idle41 =[ $old41, old2_idle42 ] {old2_stand();};
-void() old2_idle42 =[ $old42, old2_idle43 ] {old2_stand();};
-void() old2_idle43 =[ $old43, old2_idle44 ] {old2_stand();};
-void() old2_idle44 =[ $old44, old2_idle45 ] {old2_stand();};
-void() old2_idle45 =[ $old45, old2_idle46 ] {old2_stand();};
-void() old2_idle46 =[ $old46, old2_idle1 ] {old2_stand();};
-
-void(vector p) shub_missile =
-{
- local vector offang;
- local vector org, vec, d;
- local float t;
+ //--------------------------------------------------------------
+ nonvirtual void(vector p) shub_missile =
+ {
+ local vector offang;
+ local vector org, vec, d;
+ local float t;
- offang = vectoangles (self.enemy.origin - self.origin);
- makevectors (offang);
+ offang = vectoangles (this.enemy.origin - this.origin);
+ makevectors (offang);
- org = self.origin + p_x*v_forward + p_y*v_right + p_z*'0 0 1';
+ org = this.origin + p_x * v_forward + p_y * v_right +
+ p_z * '0 0 1';
-// lead the player on hard mode
- if (skill > 1)
- {
- t = vlen(self.enemy.origin - org) / 300;
- vec = self.enemy.velocity;
- vec_z = 0;
- d = self.enemy.origin + t * vec;
- }
- else
- {
- d = self.enemy.origin;
- }
-
- vec = normalize (d - org);
+ // lead the player on hard mode
+ if (skill > 1)
+ {
+ t = vlen(this.enemy.origin - org) / 300;
+ vec = this.enemy.velocity;
+ vec_z = 0;
+ d = this.enemy.origin + t * vec;
+ }
+ else
+ {
+ d = this.enemy.origin;
+ }
- local entity puff; // added this to motivate fireballs dumptruck_ds
+ vec = normalize (d - org);
- puff = spawn ();
+ // added this to motivate fireballs dumptruck_ds
+ local entity puff;
- setmodel (puff, "progs/s_explod.spr");
- puff.origin = (org);
- puff.think = s_explode1;
- puff.nextthink = time;
+ puff = spawn (base_explosion, origin: org);
- launch_spike2 (org, vec, 300); // lavaball in your face!
- if (self.mdl_proj != "") // dumptruck_ds custom_mdls
- {
- setmodel (newmis, self.mdl_proj);
+ // lavaball in your face!
+ launch_spike2 (org, vec, 300);
+ // dumptruck_ds custom_mdls
+ if (this.mdl_proj != "")
+ {
+ setmodel (newmis, this.mdl_proj);
}
else
{
setmodel (newmis, "progs/lavaball.mdl");
- }
+ }
- if (!newmis.skin_proj) // dumptruck_ds
- {
- newmis.skin = self.skin_proj;
+ // dumptruck_ds
+ if (!newmis.skin_proj)
+ {
+ newmis.skin = this.skin_proj;
}
else
{
newmis.skin = 0;
- }
-
- // setmodel (newmis, "progs/lavaball.mdl");
- newmis.avelocity = '200 100 300';
- setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
- newmis.touch = T_MissileTouch; // rocket explosion
- sound_attack (self, CHAN_WEAPON, "boss1/throw.wav", 1, ATTN_NORM);
-
-// check for dead enemy
- if (self.enemy.health <= 0)
- old2_idle1 ();
-};
-
-void() old2_attk1 =[ $old1, old2_attk2 ] {shub_face();};
-void() old2_attk2 =[ $old2, old2_attk3 ] {shub_face();};
-void() old2_attk3 =[ $old3, old2_attk4 ] {shub_face();};
-void() old2_attk4 =[ $old4, old2_attk5 ] {shub_face();};
-void() old2_attk5 =[ $old5, old2_attk6 ] {shub_face();};
-void() old2_attk6 =[ $old6, old2_attk7 ] {shub_face();};
-void() old2_attk7 =[ $old7, old2_attk8 ] {shub_face();};
-void() old2_attk8 =[ $old8, old2_attk9 ] {shub_face();};
-void() old2_attk9 =[ $old9, old2_attk10 ] {shub_missile('0 -16 416');};
-void() old2_attk10 =[ $old10, old2_attk11 ] {shub_face();};
-void() old2_attk11 =[ $old11, old2_attk12 ] {shub_face();};
-void() old2_attk12 =[ $old12, old2_attk13 ] {shub_face();};
-void() old2_attk13 =[ $old13, old2_attk14 ] {shub_face();};
-void() old2_attk14 =[ $old14, old2_attk15 ] {shub_face();};
-void() old2_attk15 =[ $old15, old2_attk16 ] {shub_face();};
-void() old2_attk16 =[ $old16, old2_attk17 ] {shub_face();};
-void() old2_attk17 =[ $old17, old2_attk18 ] {shub_face();};
-void() old2_attk18 =[ $old18, old2_attk19 ] {shub_missile('0 -16 416');};
-void() old2_attk19 =[ $old19, old2_attk20 ] {shub_face();};
-void() old2_attk20 =[ $old20, old2_attk21 ] {shub_face();};
-void() old2_attk21 =[ $old21, old2_attk22 ] {shub_face();};
-void() old2_attk22 =[ $old22, old2_attk23 ] {shub_face();};
-void() old2_attk23 =[ $old23, old2_attk24 ] {shub_face();};
-void() old2_attk24 =[ $old24, old2_attk25 ] {shub_face();};
-void() old2_attk25 =[ $old25, old2_attk26 ] {shub_face();};
-void() old2_attk26 =[ $old26, old2_attk27 ] {shub_face();};
-void() old2_attk27 =[ $old27, old2_attk28 ] {shub_missile('0 -16 416');};
-void() old2_attk28 =[ $old28, old2_attk29 ] {shub_face();};
-void() old2_attk29 =[ $old29, old2_attk30 ] {shub_face();};
-void() old2_attk30 =[ $old30, old2_attk31 ] {shub_face();};
-void() old2_attk31 =[ $old31, old2_attk32 ] {shub_face();};
-void() old2_attk32 =[ $old32, old2_attk33 ] {shub_face();};
-void() old2_attk33 =[ $old33, old2_attk34 ] {shub_face();};
-void() old2_attk34 =[ $old34, old2_attk35 ] {shub_face();};
-void() old2_attk35 =[ $old35, old2_attk36 ] {shub_face();};
-void() old2_attk36 =[ $old36, old2_attk37 ] {shub_missile('0 -16 416');};
-void() old2_attk37 =[ $old37, old2_attk38 ] {shub_face();};
-void() old2_attk38 =[ $old38, old2_attk39 ] {shub_face();};
-void() old2_attk39 =[ $old39, old2_attk40 ] {shub_face();};
-void() old2_attk40 =[ $old40, old2_attk41 ] {shub_face();};
-void() old2_attk41 =[ $old41, old2_attk42 ] {shub_face();};
-void() old2_attk42 =[ $old42, old2_attk43 ] {shub_face();};
-void() old2_attk43 =[ $old43, old2_attk44 ] {shub_face();};
-void() old2_attk44 =[ $old44, old2_attk45 ] {shub_face();};
-void() old2_attk45 =[ $old45, old2_attk46 ] {shub_missile('0 -16 416');};
-void() old2_attk46 =[ $old46, old2_attk1 ] {shub_face();};
-//death twitch --dumptruck_ds
-void() old2_twitch1 =[ $shake1, old2_twitch2 ] {sound_misc (self, CHAN_VOICE, "boss2/pop2.wav", 1, ATTN_NONE);};
-void() old2_twitch2 =[ $shake2, old2_twitch3 ] {};
-void() old2_twitch3 =[ $shake3, old2_twitch4 ] {};
-void() old2_twitch4 =[ $shake4, old2_twitch5 ] {};
-void() old2_twitch5 =[ $shake5, old2_twitch6 ] {};
-void() old2_twitch6 =[ $shake6, old2_twitch7 ] {};
-void() old2_twitch7 =[ $shake7, old2_twitch8 ] {};
-void() old2_twitch8 =[ $shake8, old2_twitch9 ] {};
-void() old2_twitch9 =[ $shake9, old2_twitch10 ] {};
-void() old2_twitch10 =[ $shake10, old2_twitch11 ] {};
-void() old2_twitch11 =[ $shake11, old2_twitch12 ] {};
-void() old2_twitch12 =[ $shake12, old2_twitch13 ] {};
-void() old2_twitch13 =[ $shake13, old2_twitch14 ] {};
-void() old2_twitch14 =[ $shake14, old2_twitch15 ] {};
-void() old2_twitch15 =[ $shake15, old2_twitch16 ] {};
-void() old2_twitch16 =[ $shake16, old2_twitch17 ] {};
-void() old2_twitch17 =[ $shake17, old2_twitch18 ] {};
-void() old2_twitch18 =[ $shake18, old2_twitch19 ] {};
-void() old2_twitch19 =[ $shake19, old2_twitch20 ] {};
-void() old2_twitch20 =[ $shake20, old2_twitch21 ] {};
-void() old2_twitch21 =[ $shake17, old2_twitch22 ] {};
-void() old2_twitch22 =[ $shake18, old2_twitch23 ] {};
-void() old2_twitch23 =[ $shake19, old2_twitch24 ] {};
-void() old2_twitch24 =[ $shake20, old2_twitch25 ] {};
-void() old2_twitch25 =[ $shake17, old2_twitch26 ] {};
-void() old2_twitch26 =[ $shake18, old2_twitch27 ] {};
-void() old2_twitch27 =[ $shake19, old2_twitch28 ] {};
-void() old2_twitch28 =[ $shake20, oldone2_die ] {};
-
-void(entity attacker, float damage) oldone2_pain =
-{
- if (self.pain_finished > time)
- return;
+ }
- sound_pain (self, CHAN_AUTO, "oldone2/pd_pop2.wav", 1, ATTN_NORM); //new pain sound
- old2_attk1();
- self.pain_finished = time + 4;
-};
+ // setmodel (newmis, "progs/lavaball.mdl");
+ newmis.avelocity = '200 100 300';
+ setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
+ // rocket explosion
+ newmis.touch = T_MissileTouch;
+ sound_attack (this, CHAN_WEAPON, "boss1/throw.wav",
+ 1, ATTN_NORM);
+
+ // check for dead enemy
+ if (this.enemy.health <= 0)
+ this.idle1 ();
+ };
+
+ //--------------------------------------------------------------
+ nonvirtual void() shub_face =
+ {
+ // go for another player if multi player
+ if (this.enemy.health <= 0 || random() < 0.02)
+ {
+ this.enemy = findfloat (this.enemy, ::classtype,
+ CT_PLAYER);
+ if (!this.enemy)
+ this.enemy = findfloat (this.enemy, ::classtype,
+ CT_PLAYER);
+ }
+ ai_face ();
+ };
-void() oldone2_die =
-{
-// 1998-07-30 Shub kill count fix by Maddes start
- //killed_monsters = killed_monsters + 1;
- //WriteByte (MSG_ALL, SVC_KILLEDMONSTER); // Already done by FL_MONSTER
-// 1998-07-30 Shub kill count fix by Maddes end
- // throw tons of meat chunks
- local vector oldo;
- local float x, y, z;
- local float r;
-
- oldo = self.origin + '0 0 112';
-
- z = 16;
- while (z <= 144)
+ //--------------------------------------------------------------
+ nonvirtual void() stand =
+ {
+ ai_findtarget ();
+ };
+
+ //--------------------------------------------------------------
+ // Shub Idle functions
+ //--------------------------------------------------------------
+ nonvirtual void() idle1 = [$old1, idle2] { stand (); };
+ nonvirtual void() idle2 = [$old2, idle3] { stand (); };
+ nonvirtual void() idle3 = [$old3, idle4] { stand (); };
+ nonvirtual void() idle4 = [$old4, idle5] { stand (); };
+ nonvirtual void() idle5 = [$old5, idle6] { stand (); };
+ nonvirtual void() idle6 = [$old6, idle7] { stand (); };
+ nonvirtual void() idle7 = [$old7, idle8] { stand (); };
+ nonvirtual void() idle8 = [$old8, idle9] { stand (); };
+ nonvirtual void() idle9 = [$old9, idle10] { stand (); };
+ nonvirtual void() idle10 = [$old10, idle11] { stand (); };
+ nonvirtual void() idle11 = [$old11, idle12] { stand (); };
+ nonvirtual void() idle12 = [$old12, idle13] { stand (); };
+ nonvirtual void() idle13 = [$old13, idle14] { stand (); };
+ nonvirtual void() idle14 = [$old14, idle15] { stand (); };
+ nonvirtual void() idle15 = [$old15, idle16] { stand (); };
+ nonvirtual void() idle16 = [$old16, idle17] { stand (); };
+ nonvirtual void() idle17 = [$old17, idle18] { stand (); };
+ nonvirtual void() idle18 = [$old18, idle19] { stand (); };
+ nonvirtual void() idle19 = [$old19, idle20] { stand (); };
+ nonvirtual void() idle20 = [$old20, idle21] { stand (); };
+ nonvirtual void() idle21 = [$old21, idle22] { stand (); };
+ nonvirtual void() idle22 = [$old22, idle23] { stand (); };
+ nonvirtual void() idle23 = [$old23, idle24] { stand (); };
+ nonvirtual void() idle24 = [$old24, idle25] { stand (); };
+ nonvirtual void() idle25 = [$old25, idle26] { stand (); };
+ nonvirtual void() idle26 = [$old26, idle27] { stand (); };
+ nonvirtual void() idle27 = [$old27, idle28] { stand (); };
+ nonvirtual void() idle28 = [$old28, idle29] { stand (); };
+ nonvirtual void() idle29 = [$old29, idle30] { stand (); };
+ nonvirtual void() idle30 = [$old30, idle31] { stand (); };
+ nonvirtual void() idle31 = [$old31, idle32] { stand (); };
+ nonvirtual void() idle32 = [$old32, idle33] { stand (); };
+ nonvirtual void() idle33 = [$old33, idle34] { stand (); };
+ nonvirtual void() idle34 = [$old34, idle35] { stand (); };
+ nonvirtual void() idle35 = [$old35, idle36] { stand (); };
+ nonvirtual void() idle36 = [$old36, idle37] { stand (); };
+ nonvirtual void() idle37 = [$old37, idle38] { stand (); };
+ nonvirtual void() idle38 = [$old38, idle39] { stand (); };
+ nonvirtual void() idle39 = [$old39, idle40] { stand (); };
+ nonvirtual void() idle40 = [$old40, idle41] { stand (); };
+ nonvirtual void() idle41 = [$old41, idle42] { stand (); };
+ nonvirtual void() idle42 = [$old42, idle43] { stand (); };
+ nonvirtual void() idle43 = [$old43, idle44] { stand (); };
+ nonvirtual void() idle44 = [$old44, idle45] { stand (); };
+ nonvirtual void() idle45 = [$old45, idle46] { stand (); };
+ nonvirtual void() idle46 = [$old46, idle1] { stand (); };
+
+ //--------------------------------------------------------------
+ // Shub Attack!
+ //--------------------------------------------------------------
+ nonvirtual void() atk1 = [$old1, atk2] { shub_face (); };
+ nonvirtual void() atk2 = [$old2, atk3] { shub_face (); };
+ nonvirtual void() atk3 = [$old3, atk4] { shub_face (); };
+ nonvirtual void() atk4 = [$old4, atk5] { shub_face (); };
+ nonvirtual void() atk5 = [$old5, atk6] { shub_face (); };
+ nonvirtual void() atk6 = [$old6, atk7] { shub_face (); };
+ nonvirtual void() atk7 = [$old7, atk8] { shub_face (); };
+ nonvirtual void() atk8 = [$old8, atk9] { shub_face (); };
+ nonvirtual void() atk9 = [$old9, atk10] { shub_missile ('0 -16 416'); };
+ nonvirtual void() atk10 = [$old10, atk11] { shub_face (); };
+ nonvirtual void() atk11 = [$old11, atk12] { shub_face (); };
+ nonvirtual void() atk12 = [$old12, atk13] { shub_face (); };
+ nonvirtual void() atk13 = [$old13, atk14] { shub_face (); };
+ nonvirtual void() atk14 = [$old14, atk15] { shub_face (); };
+ nonvirtual void() atk15 = [$old15, atk16] { shub_face (); };
+ nonvirtual void() atk16 = [$old16, atk17] { shub_face (); };
+ nonvirtual void() atk17 = [$old17, atk18] { shub_face (); };
+ nonvirtual void() atk18 = [$old18, atk19] { shub_missile('0 -16 416');};
+ nonvirtual void() atk19 = [$old19, atk20] { shub_face (); };
+ nonvirtual void() atk20 = [$old20, atk21] { shub_face (); };
+ nonvirtual void() atk21 = [$old21, atk22] { shub_face (); };
+ nonvirtual void() atk22 = [$old22, atk23] { shub_face (); };
+ nonvirtual void() atk23 = [$old23, atk24] { shub_face (); };
+ nonvirtual void() atk24 = [$old24, atk25] { shub_face (); };
+ nonvirtual void() atk25 = [$old25, atk26] { shub_face (); };
+ nonvirtual void() atk26 = [$old26, atk27] { shub_face (); };
+ nonvirtual void() atk27 = [$old27, atk28] { shub_missile('0 -16 416');};
+ nonvirtual void() atk28 = [$old28, atk29] { shub_face (); };
+ nonvirtual void() atk29 = [$old29, atk30] { shub_face (); };
+ nonvirtual void() atk30 = [$old30, atk31] { shub_face (); };
+ nonvirtual void() atk31 = [$old31, atk32] { shub_face (); };
+ nonvirtual void() atk32 = [$old32, atk33] { shub_face (); };
+ nonvirtual void() atk33 = [$old33, atk34] { shub_face (); };
+ nonvirtual void() atk34 = [$old34, atk35] { shub_face (); };
+ nonvirtual void() atk35 = [$old35, atk36] { shub_face (); };
+ nonvirtual void() atk36 = [$old36, atk37] { shub_missile('0 -16 416');};
+ nonvirtual void() atk37 = [$old37, atk38] { shub_face (); };
+ nonvirtual void() atk38 = [$old38, atk39] { shub_face (); };
+ nonvirtual void() atk39 = [$old39, atk40] { shub_face (); };
+ nonvirtual void() atk40 = [$old40, atk41] { shub_face (); };
+ nonvirtual void() atk41 = [$old41, atk42] { shub_face (); };
+ nonvirtual void() atk42 = [$old42, atk43] { shub_face (); };
+ nonvirtual void() atk43 = [$old43, atk44] { shub_face (); };
+ nonvirtual void() atk44 = [$old44, atk45] { shub_face (); };
+ nonvirtual void() atk45 = [$old45, atk46] { shub_missile('0 -16 416');};
+ nonvirtual void() atk46 = [$old46, atk1] { shub_face (); };
+
+ //--------------------------------------------------------------
+ // Shub Twitch -- death twitch -- dumptruck_ds
+ //--------------------------------------------------------------
+ nonvirtual void() twitch1 = [$shake1, twitch2]
{
- x = -64;
- while (x <= 64)
+ sound_misc (this, CHAN_VOICE, "boss2/pop2.wav", 1, ATTN_NONE);
+ };
+ nonvirtual void() twitch2 = [$shake2, twitch3] { };
+ nonvirtual void() twitch3 = [$shake3, twitch4] { };
+ nonvirtual void() twitch4 = [$shake4, twitch5] { };
+ nonvirtual void() twitch5 = [$shake5, twitch6] { };
+ nonvirtual void() twitch6 = [$shake6, twitch7] { };
+ nonvirtual void() twitch7 = [$shake7, twitch8] { };
+ nonvirtual void() twitch8 = [$shake8, twitch9] { };
+ nonvirtual void() twitch9 = [$shake9, twitch10] { };
+ nonvirtual void() twitch10 = [$shake10, twitch11] { };
+ nonvirtual void() twitch11 = [$shake11, twitch12] { };
+ nonvirtual void() twitch12 = [$shake12, twitch13] { };
+ nonvirtual void() twitch13 = [$shake13, twitch14] { };
+ nonvirtual void() twitch14 = [$shake14, twitch15] { };
+ nonvirtual void() twitch15 = [$shake15, twitch16] { };
+ nonvirtual void() twitch16 = [$shake16, twitch17] { };
+ nonvirtual void() twitch17 = [$shake17, twitch18] { };
+ nonvirtual void() twitch18 = [$shake18, twitch19] { };
+ nonvirtual void() twitch19 = [$shake19, twitch20] { };
+ nonvirtual void() twitch20 = [$shake20, twitch21] { };
+ nonvirtual void() twitch21 = [$shake17, twitch22] { };
+ nonvirtual void() twitch22 = [$shake18, twitch23] { };
+ nonvirtual void() twitch23 = [$shake19, twitch24] { };
+ nonvirtual void() twitch24 = [$shake20, twitch25] { };
+ nonvirtual void() twitch25 = [$shake17, twitch26] { };
+ nonvirtual void() twitch26 = [$shake18, twitch27] { };
+ nonvirtual void() twitch27 = [$shake19, twitch28] { };
+ nonvirtual void() twitch28 = [$shake20, this.do_destroy] { };
+
+ //==============================================================
+ // Interaction
+ //==============================================================
+
+ //--------------------------------------------------------------
+ // oldone2_pain
+ //--------------------------------------------------------------
+ virtual void(entity attacker, float damage) do_damage =
+ {
+ if (this.pain_finished > time)
+ return;
+
+ // new pain sound
+ sound_pain (this, CHAN_AUTO, "oldone2/pd_pop2.wav",
+ 1, ATTN_NORM);
+ this.atk1 ();
+ this.pain_finished = time + 4;
+ };
+
+ //--------------------------------------------------------------
+ // oldone2_die
+ //--------------------------------------------------------------
+ virtual void() do_destroy =
+ {
+ // 1998-07-30 Shub kill count fix by Maddes start
+ // Already done by FL_MONSTER
+ // killed_monsters = killed_monsters + 1;
+ // WriteByte (MSG_ALL, SVC_KILLEDMONSTER);
+ // 1998-07-30 Shub kill count fix by Maddes end
+ // throw tons of meat chunks
+ local vector oldo;
+ local float x, y, z;
+ local float r;
+
+ oldo = this.origin + '0 0 112';
+
+ z = 16;
+ while (z <= 144)
{
- y = -64;
- while (y <= 64)
+ x = -64;
+ while (x <= 64)
{
- self.origin_x = oldo_x + x;
- self.origin_y = oldo_y + y;
- self.origin_z = oldo_z + z;
-
- r = random();
- if (r < 0.3)
- // ThrowGib ("progs/gib1.mdl", -120);
- if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
- {
- ThrowGib (self.mdl_gib1, -120);
- }
- else
- {
- ThrowGib ("progs/gib1.mdl", -120);
- }
- else if (r < 0.6)
- // ThrowGib ("progs/gib2.mdl", -120);
- if (self.mdl_gib2 != "") // custom models -- dumptruck_ds
+ y = -64;
+ while (y <= 64)
+ {
+ this.origin_x = oldo_x + x;
+ this.origin_y = oldo_y + y;
+ this.origin_z = oldo_z + z;
+
+ r = random ();
+ if (r < 0.3)
{
- ThrowGib (self.mdl_gib2, -120);
+ // custom models -- dumptruck_ds
+ if (this.mdl_gib1 != "")
+ ThrowGib (this.mdl_gib1,
+ -120);
+ else
+ ThrowGib ("progs/gib1."
+ "mdl", -120);
}
- else
- {
- ThrowGib ("progs/gib2.mdl", -120);
- }
- else
- // ThrowGib ("progs/gib3.mdl", -120);
- if (self.mdl_gib3 != "") // custom models -- dumptruck_ds
+ else if (r < 0.6)
{
- ThrowGib (self.mdl_gib3, -120);
+ // custom models -- dumptruck_ds
+ if (this.mdl_gib2 != "")
+ ThrowGib (this.mdl_gib2,
+ -120);
+ else
+ ThrowGib ("progs/gib2."
+ "mdl", -120);
}
else
{
- ThrowGib ("progs/gib3.mdl", -120);
+ // custom models -- dumptruck_ds
+ if (this.mdl_gib3 != "")
+ ThrowGib (this.mdl_gib3,
+ -120);
+ else
+ ThrowGib ("progs/gib3."
+ "mdl", -120);
}
- y = y + 32;
+ y = y + 32;
+ }
+ x = x + 32;
}
- x = x + 32;
+ z = z + 96;
}
- z = z + 96;
- }
- particle (oldo, '0 0 0', 0, 255);
- particle (oldo, '128 128 128', 0, 255);
- sound_death (self, CHAN_VOICE, "player/teledth1.wav", 1, ATTN_NONE);
-
- remove (self);
-}
-/*QUAKED monster_oldone2 (1 0 0) (-160 -128 -24) (160 128 256)
-*/
-void() monster_oldone2 =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
+ particle (oldo, '0 0 0', 0, 255);
+ particle (oldo, '128 128 128', 0, 255);
+ sound_death (this, CHAN_VOICE, "player/teledth1.wav",
+ 1, ATTN_NONE);
+ remove (this);
+ };
- if (self.spawnflags & I_AM_TURRET)
- objerror("Incompatible spawnflag: TURRET_MODE\n");
+ //==============================================================
+ // Initialization
+ //==============================================================
- if (deathmatch)
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
{
- remove(self);
- return;
- }
+ if (this.spawnflags & I_AM_TURRET)
+ objerror ("Incompatible spawnflag: TURRET_MODE\n");
- precache_body_model2 ("progs/oldone.mdl");
- // precache_model2 ("progs/oldone.mdl");
+ if (deathmatch)
+ {
+ remove (this);
+ return;
+ }
- precache_sound2_death ("boss2/death.wav");
- // precache_sound2_idle ("boss2/idle.wav");
- precache_sound2_sight ("boss2/sight.wav");
- precache_sound2_misc ("boss2/pop2.wav");
- precache_sound2_pain ("oldone2/pd_pop2.wav");
+ precache_body_model2 ("progs/oldone.mdl");
+ // precache_model2 ("progs/oldone.mdl");
- precache_model ("progs/lavaball.mdl");
- precache_sound ("boss1/throw.wav");
+ precache_sound2_death ("boss2/death.wav");
+ // precache_sound2_idle ("boss2/idle.wav");
+ precache_sound2_sight ("boss2/sight.wav");
+ precache_sound2_misc ("boss2/pop2.wav");
+ precache_sound2_pain ("oldone2/pd_pop2.wav");
- precache_gib1 ("progs/gib1.mdl");
- precache_gib2 ("progs/gib2.mdl");
- precache_gib3 ("progs/gib3.mdl");
+ precache_model ("progs/lavaball.mdl");
+ precache_sound ("boss1/throw.wav");
- self.solid = SOLID_SLIDEBOX;
- self.movetype = MOVETYPE_STEP;
+ precache_gib1 ("progs/gib1.mdl");
+ precache_gib2 ("progs/gib2.mdl");
+ precache_gib3 ("progs/gib3.mdl");
- body_model ("progs/oldone.mdl"); //custom_mdls dumptruck_ds
- // setmodel (self, "progs/oldone.mdl");
- setsize (self, '-160 -128 -24', '160 128 256');
+ this.solid = SOLID_SLIDEBOX;
+ this.movetype = MOVETYPE_STEP;
- if (!self.health)
+ // custom_mdls dumptruck_ds
+ body_model ("progs/oldone.mdl");
+ // setmodel (this, "progs/oldone.mdl");
+ setsize (this, '-160 -128 -24', '160 128 256');
+
+ if (!this.health)
+ {
+ if (skill == 0)
+ this.health = 1000;
+ else
+ this.health = 3000;
+ }
+
+ this.flags = FL_MONSTER;
+ this.takedamage = DAMAGE_AIM;
+ this.think_run = this.atk1;
+ this.th_pain = this.do_damage;
+ this.th_die = this.do_destroy;
+ total_monsters = total_monsters + 1;
+ this.think = this.idle1;
+ this.nextthink = time + 0.1;
+ };
+
+ //--------------------------------------------------------------
+ void() monster_oldone2 =
{
- if (skill == 0)
- self.health = 1000;
- else
- self.health = 3000;
- }
-
- self.flags = FL_MONSTER;
- self.think = old2_idle1;
- self.nextthink = time + 0.1;
- self.takedamage = DAMAGE_AIM;
- self.th_run = old2_attk1;
- self.th_pain = oldone2_pain;
- self.th_die = old2_twitch1;
- self.touch = monster_touch; // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten
-
- total_monsters = total_monsters + 1;
+ this.classtype = CT_MONSTER_BOSS_OLDONE2;
+ };
};
Return to the top of this page or return to the overview of this repo.
Diff qc/monsters/shalrath.qc
diff --git a/qc/monsters/shalrath.qc b/qc/monsters/shalrath.qc
index e27b3f7..76b9387 100644
--- a/qc/monsters/shalrath.qc
+++ b/qc/monsters/shalrath.qc
@@ -1,10 +1,10 @@
-/*
-==============================================================================
-
-SHAL-RATH
+//==============================================================================
+// SHAL-RATH
+//==============================================================================
-==============================================================================
-*/
+//======================================================================
+// frame macros
+//======================================================================
$cd id1/models/shalrath
$origin 0 0 24
$base base
@@ -18,257 +18,8 @@ $frame pain1 pain2 pain3 pain4 pain5
$frame death1 death2 death3 death4 death5 death6 death7
-$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 walk10
-$frame walk11 walk12
-
-void(entity attacker, float damage) shalrath_pain;
-void() ShalMissile;
-void() shal_stand =[ $walk1, shal_stand ] {ai_stand();};
-
-void() shal_walk1 =[ $walk2, shal_walk2 ] {
-if (random() < 0.2)
- sound_idle (self, CHAN_VOICE, "shalrath/idle.wav", 1, ATTN_IDLE);
-ai_walk(6);};
-void() shal_walk2 =[ $walk3, shal_walk3 ] {ai_walk(4);};
-void() shal_walk3 =[ $walk4, shal_walk4 ] {ai_walk(0);};
-void() shal_walk4 =[ $walk5, shal_walk5 ] {ai_walk(0);};
-void() shal_walk5 =[ $walk6, shal_walk6 ] {ai_walk(0);};
-void() shal_walk6 =[ $walk7, shal_walk7 ] {ai_walk(0);};
-void() shal_walk7 =[ $walk8, shal_walk8 ] {ai_walk(5);};
-void() shal_walk8 =[ $walk9, shal_walk9 ] {ai_walk(6);};
-void() shal_walk9 =[ $walk10, shal_walk10 ] {ai_walk(5);};
-void() shal_walk10 =[ $walk11, shal_walk11 ] {ai_walk(0);};
-void() shal_walk11 =[ $walk12, shal_walk12 ] {ai_walk(4);};
-void() shal_walk12 =[ $walk1, shal_walk1 ] {ai_walk(5);};
-
-void() shal_run1 =[ $walk2, shal_run2 ] {
-if (random() < 0.2)
- sound_idle (self, CHAN_VOICE, "shalrath/idle.wav", 1, ATTN_IDLE);
-ai_run(6);};
-void() shal_run2 =[ $walk3, shal_run3 ] {ai_run(4);};
-void() shal_run3 =[ $walk4, shal_run4 ] {ai_run(0);};
-void() shal_run4 =[ $walk5, shal_run5 ] {ai_run(0);};
-void() shal_run5 =[ $walk6, shal_run6 ] {ai_run(0);};
-void() shal_run6 =[ $walk7, shal_run7 ] {ai_run(0);};
-void() shal_run7 =[ $walk8, shal_run8 ] {ai_run(5);};
-void() shal_run8 =[ $walk9, shal_run9 ] {ai_run(6);};
-void() shal_run9 =[ $walk10, shal_run10 ] {ai_run(5);};
-void() shal_run10 =[ $walk11, shal_run11 ] {ai_run(0);};
-void() shal_run11 =[ $walk12, shal_run12 ] {ai_run(4);};
-void() shal_run12 =[ $walk1, shal_run1 ] {ai_run(5);};
-
-void() shal_attack1 =[ $attack1, shal_attack2 ] {
-sound_attack (self, CHAN_VOICE, "shalrath/attack.wav", 1, ATTN_NORM);
-ai_face();
-};
-void() shal_attack2 =[ $attack2, shal_attack3 ] {ai_face();};
-void() shal_attack3 =[ $attack3, shal_attack4 ] {ai_face();};
-void() shal_attack4 =[ $attack4, shal_attack5 ] {ai_face();};
-void() shal_attack5 =[ $attack5, shal_attack6 ] {ai_face();};
-void() shal_attack6 =[ $attack6, shal_attack7 ] {ai_face();};
-void() shal_attack7 =[ $attack7, shal_attack8 ] {ai_face();};
-void() shal_attack8 =[ $attack8, shal_attack9 ] {ai_face();};
-void() shal_attack9 =[ $attack9, shal_attack10 ] {ShalMissile();};
-void() shal_attack10 =[ $attack10, shal_attack11 ] {ai_face();};
-void() shal_attack11 =[ $attack11, shal_run1 ] {};
-//////////////////////////
-/// new frames for turret mode START
-//////////////////////////
-void() shal_turret_attack1 =[ $attack1, shal_turret_attack2 ] {
-sound_attack (self, CHAN_VOICE, "shalrath/attack.wav", 1, ATTN_NORM);
-ai_face();
-};
-void() shal_turret_attack2 =[ $attack2, shal_turret_attack3 ] {ai_face();};
-void() shal_turret_attack3 =[ $attack3, shal_turret_attack4 ] {ai_face();};
-void() shal_turret_attack4 =[ $attack4, shal_turret_attack5 ] {ai_face();};
-void() shal_turret_attack5 =[ $attack5, shal_turret_attack6 ] {ai_face();};
-void() shal_turret_attack6 =[ $attack6, shal_turret_attack7 ] {ai_face();};
-void() shal_turret_attack7 =[ $attack7, shal_turret_attack8 ] {ai_face();};
-void() shal_turret_attack8 =[ $attack8, shal_turret_attack9 ] {ai_face();};
-void() shal_turret_attack9 =[ $attack9, shal_turret_attack10 ] {ShalMissile();};
-void() shal_turret_attack10 =[ $attack10, shal_turret_attack11 ] {ai_face();};
-void() shal_turret_attack11 =[ $attack11, shal_turret_attack12 ] {ai_face();};
-void() shal_turret_attack12 =[ $walk1, shal_turret_attack13 ] {ai_face();};
-void() shal_turret_attack13 =[ $walk1, shal_turret_attack14 ] {ai_face();};
-void() shal_turret_attack14 =[ $walk1, shal_turret_attack15 ] {ai_face();};
-void() shal_turret_attack15 =[ $walk1, shal_seek_stand1 ] {ai_run(0);};
-void() shal_seek_stand1 =[ $walk1, shal_seek_stand2 ] {ai_run(0);};
-void() shal_seek_stand2 =[ $walk1, shal_seek_stand1 ] {ai_run(0);};
-//////////////////////////
-/// new frames for turret mode END
-//////////////////////////
-void() shal_pain1 =[ $pain1, shal_pain2 ] {};
-void() shal_pain2 =[ $pain2, shal_pain3 ] {};
-void() shal_pain3 =[ $pain3, shal_pain4 ] {};
-void() shal_pain4 =[ $pain4, shal_pain5 ] {};
-void() shal_pain5 =[ $pain5, shal_run1 ] {};
-
-void() shal_death1 =[ $death1, shal_death2 ] {};
-void() shal_death2 =[ $death2, shal_death3 ] {};
-void() shal_death3 =[ $death3, shal_death4 ] {};
-void() shal_death4 =[ $death4, shal_death5 ] {};
-void() shal_death5 =[ $death5, shal_death6 ] {};
-void() shal_death6 =[ $death6, shal_death7 ] {};
-void() shal_death7 =[ $death7, shal_death7 ] {};
-
-
-void(entity attacker, float damage) shalrath_pain =
-{
- if (self.pain_finished > time)
- return;
-
- sound_pain (self, CHAN_AUTO, "shalrath/pain.wav", 1, ATTN_NORM); //CHAN_AUTO was voice - dumptruck_ds
- self.pain_finished = time + 3;
- if (self.spawnflags & I_AM_TURRET)
- return;
- else
- shal_pain1();
-};
-
-void() shalrath_die =
-{
-// check for gib
- if (self.health < -90)
- {
- sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
- if (self.mdl_head != "") //dumptruck_ds custom_mdls
- {
- ThrowHead (self.mdl_head, self.health);
- }
- else
- {
- ThrowHead ("progs/h_shal.mdl", self.health);
- }
- // ThrowGib ("progs/gib1.mdl", self.health);
- // ThrowGib ("progs/gib2.mdl", self.health);
- // ThrowGib ("progs/gib3.mdl", self.health);
- if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
- {
- ThrowGib (self.mdl_gib1, self.health);
- }
- else
- {
- ThrowGib ("progs/gib1.mdl", self.health);
- }
- if (self.mdl_gib2 != "")
- {
- ThrowGib (self.mdl_gib2, self.health);
- }
- else
- {
- ThrowGib ("progs/gib2.mdl", self.health);
- }
- if (self.mdl_gib3 != "")
- {
- ThrowGib (self.mdl_gib3, self.health);
- }
- else
- {
- ThrowGib ("progs/gib3.mdl", self.health);
- }
- base_item::drop_stuff (self);
- return;
- }
- // insert death sounds here
- sound_death (self, CHAN_VOICE, "shalrath/death.wav", 1, ATTN_NORM);
- base_item::drop_stuff (self);
- shal_death1();
- self.solid = SOLID_NOT;
-};
-
-/*
-================
-ShalMissile
-================
-*/
-void() ShalMissileTouch;
-void() ShalMissile =
-{
- local entity missile;
- local vector dir;
- local float dist, flytime;
-
- dir = normalize((self.enemy.origin + '0 0 10') - self.origin);
- dist = vlen (self.enemy.origin - self.origin);
- flytime = dist * 0.002 * (1/self.proj_speed_mod);
- if (flytime < 0.1)
- flytime = 0.1;
-
- self.effects = self.effects | EF_MUZZLEFLASH;
- sound_misc (self, CHAN_WEAPON, "shalrath/attack2.wav", 1, ATTN_NORM);
-
- missile = spawn ();
- missile.owner = self;
-
- missile.solid = SOLID_BBOX;
- missile.movetype = MOVETYPE_FLYMISSILE;
-
- if (self.mdl_proj != "") // dumptruck_ds custom_mdls
- {
- setmodel (missile, self.mdl_proj);
- }
- else
- {
- setmodel (missile, "progs/v_spike.mdl");
- }
-
- if (!missile.skin_proj) // dumptruck_ds
- {
- missile.skin = self.skin_proj;
- }
- else
- {
- missile.skin = 0;
- }
-
- // setmodel (missile, "progs/v_spike.mdl");
-
- setsize (missile, '0 0 0', '0 0 0');
-
- missile.origin = self.origin + '0 0 10';
- SetSpeed(missile, dir, 400 * self.proj_speed_mod);
- missile.avelocity = self.avelocity; // custom spin on projectile --dumptruck_ds
- if !(missile.avelocity)
- missile.avelocity = '300 300 300';
- if (self.homing > 0) // If homing is off, don't bother doing any thinking
- {
- missile.homing = self.homing;
- missile.nextthink = flytime + time;
- missile.think = MissileHome;
- }
- if (skill == 3)
- missile.proj_basespeed = 350 * self.proj_speed_mod;
- else
- missile.proj_basespeed = 250 * self.proj_speed_mod;
- missile.enemy = self.enemy;
- missile.touch = ShalMissileTouch;
-};
-
-
-// void() ShalMissileTouch = --moved to misc.qc for voreball shooter --dumptruck_ds
-// {
-// if (other == self.owner)
-// return; // don't explode on owner
-//
-// if (other.classname == "monster_zombie")
-// T_Damage (other, self, self, 110);
-// T_RadiusDamage (self, self.owner, 40, world);
-// sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM);
-//
-// WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
-// WriteByte (MSG_BROADCAST, TE_EXPLOSION);
-// WriteCoord (MSG_BROADCAST, self.origin_x);
-// WriteCoord (MSG_BROADCAST, self.origin_y);
-// WriteCoord (MSG_BROADCAST, self.origin_z);
-//
-// self.velocity = '0 0 0';
-// self.touch = sub_null;
-// setmodel (self, "progs/s_explod.spr");
-// self.solid = SOLID_NOT;
-// s_explode1 ();
-// };
-
-//=================================================================
+$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 walk10
+$frame walk11 walk12
/*QUAKED monster_shalrath (1 0 0) (-32 -32 -24) (32 32 48) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
{
@@ -331,79 +82,402 @@ damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by
homing(float) : "Amount that the projectile should home in target. 1 is default, 0 is none."
*/
-void() monster_shalrath =
+class monster_shalrath: base_walkmonster
{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
+ //--------------------------------------------------------------
+ // ShalMissile
+ //--------------------------------------------------------------
+ nonvirtual void() attack_missile =
+ {
+ local entity missile;
+ local vector dir;
+ local float dist, flytime;
+
+ dir = normalize ((this.enemy.origin + '0 0 10') - this.origin);
+ dist = vlen (this.enemy.origin - this.origin);
+ flytime = dist * 0.002 * (1 / this.proj_speed_mod);
+ if (flytime < 0.1)
+ flytime = 0.1;
+
+ this.effects = this.effects | EF_MUZZLEFLASH;
+ sound_misc (this, CHAN_WEAPON, "shalrath/attack2.wav",
+ 1, ATTN_NORM);
+
+ missile = spawn ();
+ missile.owner = this;
+
+ missile.solid = SOLID_BBOX;
+ missile.movetype = MOVETYPE_FLYMISSILE;
+
+ // dumptruck_ds custom_mdls
+ if (this.mdl_proj != "")
+ setmodel (missile, this.mdl_proj);
+ else
+ setmodel (missile, "progs/v_spike.mdl");
+
+ // dumptruck_ds
+ if (!missile.skin_proj)
+ missile.skin = this.skin_proj;
+ else
+ missile.skin = 0;
+
+ // setmodel (missile, "progs/v_spike.mdl");
- if (deathmatch)
+ setsize (missile, '0 0 0', '0 0 0');
+
+ missile.origin = this.origin + '0 0 10';
+ SetSpeed (missile, dir, 400 * this.proj_speed_mod);
+ // custom spin on projectile -- dumptruck_ds
+ missile.avelocity = this.avelocity;
+ if !(missile.avelocity)
+ missile.avelocity = '300 300 300';
+ // If homing is off, don't bother doing any thinking
+ if (this.homing > 0)
+ {
+ missile.homing = this.homing;
+ missile.nextthink = flytime + time;
+ missile.think = MissileHome;
+ }
+ if (skill == 3)
+ missile.proj_basespeed = 350 * this.proj_speed_mod;
+ else
+ missile.proj_basespeed = 250 * this.proj_speed_mod;
+ missile.enemy = this.enemy;
+ missile.touch = ShalMissileTouch;
+ };
+
+ //--------------------------------------------------------------
+ virtual void() ai_sightsound =
{
- remove(self);
- return;
- }
- //dumptruck_ds custom_mdls
- precache_body_model2 ("progs/shalrath.mdl");
- precache_head_model2 ("progs/h_shal.mdl");
- precache_proj_model2 ("progs/v_spike.mdl");
-// dumptruck_ds
- precache_sound2_attack ("shalrath/attack.wav");
- precache_sound2_misc ("shalrath/attack2.wav");
- precache_sound2_death ("shalrath/death.wav");
- precache_sound2_idle ("shalrath/idle.wav");
- precache_sound2_pain ("shalrath/pain.wav");
- precache_sound2_sight ("shalrath/sight.wav");
-
- precache_gib1 ("progs/gib1.mdl");
- precache_gib2 ("progs/gib2.mdl");
- precache_gib3 ("progs/gib3.mdl");
-
- self.solid = SOLID_SLIDEBOX;
- self.movetype = MOVETYPE_STEP;
-
- body_model ("progs/shalrath.mdl");
- // setmodel (self, "progs/shalrath.mdl");
- setsize (self, VEC_HULL2_MIN, VEC_HULL2_MAX);
-
- if (!self.health) //thanks RennyC -- dumptruck_ds
- self.health = 400;
-
- if (!self.proj_speed_mod)
+ sound_sight (this, CHAN_VOICE, "shalrath/sight.wav",
+ 1, ATTN_NORM);
+ };
+
+ //--------------------------------------------------------------
+ // Shalrath Standing (only one frame)
+ //--------------------------------------------------------------
+ nonvirtual void() stand1 = [$walk1, stand1] { ai_stand (); };
+
+ //--------------------------------------------------------------
+ // Shalrath Walking functions
+ //--------------------------------------------------------------
+ nonvirtual void() walk1 = [$walk2, walk2]
{
- self.proj_speed_mod = 1;
- }
-
- if (!self.homing) // default to normal
+ if (random() < 0.2)
+ sound_idle (this, CHAN_VOICE, "shalrath/idle.wav",
+ 1, ATTN_IDLE);
+ ai_walk (6);
+ };
+ nonvirtual void() walk2 = [$walk3, walk3] { ai_walk (4); };
+ nonvirtual void() walk3 = [$walk4, walk4] { ai_walk (0); };
+ nonvirtual void() walk4 = [$walk5, walk5] { ai_walk (0); };
+ nonvirtual void() walk5 = [$walk6, walk6] { ai_walk (0); };
+ nonvirtual void() walk6 = [$walk7, walk7] { ai_walk (0); };
+ nonvirtual void() walk7 = [$walk8, walk8] { ai_walk (5); };
+ nonvirtual void() walk8 = [$walk9, walk9] { ai_walk (6); };
+ nonvirtual void() walk9 = [$walk10, walk10] { ai_walk (5); };
+ nonvirtual void() walk10 = [$walk11, walk11] { ai_walk (0); };
+ nonvirtual void() walk11 = [$walk12, walk12] { ai_walk (4); };
+ nonvirtual void() walk12 = [$walk1, walk1] { ai_walk (5); };
+
+ //--------------------------------------------------------------
+ // Shalrath Run functions
+ //--------------------------------------------------------------
+ nonvirtual void() run1 = [$walk2, run2]
{
- self.homing = 1;
- }
- else if (self.homing < 0) // disable with negative
+ if (random() < 0.2)
+ sound_idle (this, CHAN_VOICE, "shalrath/idle.wav",
+ 1, ATTN_IDLE);
+ ai_run (6);
+ };
+ nonvirtual void() run2 = [$walk3, run3] { ai_run (4); };
+ nonvirtual void() run3 = [$walk4, run4] { ai_run (0); };
+ nonvirtual void() run4 = [$walk5, run5] { ai_run (0); };
+ nonvirtual void() run5 = [$walk6, run6] { ai_run (0); };
+ nonvirtual void() run6 = [$walk7, run7] { ai_run (0); };
+ nonvirtual void() run7 = [$walk8, run8] { ai_run (5); };
+ nonvirtual void() run8 = [$walk9, run9] { ai_run (6); };
+ nonvirtual void() run9 = [$walk10, run10] { ai_run (5); };
+ nonvirtual void() run10 = [$walk11, run11] { ai_run (0); };
+ nonvirtual void() run11 = [$walk12, run12] { ai_run (4); };
+ nonvirtual void() run12 = [$walk1, run1] { ai_run (5); };
+
+ //--------------------------------------------------------------
+ // Shalrath Attack functions
+ //--------------------------------------------------------------
+ nonvirtual void() attack1 = [$attack1, attack2]
{
- self.homing = 0;
- }
+ sound_attack (this, CHAN_VOICE, "shalrath/attack.wav",
+ 1, ATTN_NORM);
+ ai_face ();
+ };
+ nonvirtual void() attack2 = [$attack2, attack3] { ai_face (); };
+ nonvirtual void() attack3 = [$attack3, attack4] { ai_face (); };
+ nonvirtual void() attack4 = [$attack4, attack5] { ai_face (); };
+ nonvirtual void() attack5 = [$attack5, attack6] { ai_face (); };
+ nonvirtual void() attack6 = [$attack6, attack7] { ai_face (); };
+ nonvirtual void() attack7 = [$attack7, attack8] { ai_face (); };
+ nonvirtual void() attack8 = [$attack8, attack9] { ai_face (); };
+ nonvirtual void() attack9 = [$attack9, attack10] { attack_missile (); };
+ nonvirtual void() attack10 = [$attack10, attack11] { ai_face (); };
+ nonvirtual void() attack11 = [$attack11, run1] { };
+
+ ////////////////////////////////////////
+ /// new frames for turret mode START ///
+ ////////////////////////////////////////
+
+ //--------------------------------------------------------------
+ // Shalrath Turret Attack
+ //--------------------------------------------------------------
+ nonvirtual void() turret_atk1 = [$attack1, turret_atk2]
+ {
+ sound_attack (this, CHAN_VOICE, "shalrath/attack.wav",
+ 1, ATTN_NORM);
+ ai_face ();
+ };
+ nonvirtual void() turret_atk2 = [$attack2, turret_atk3] { ai_face (); };
+ nonvirtual void() turret_atk3 = [$attack3, turret_atk4] { ai_face (); };
+ nonvirtual void() turret_atk4 = [$attack4, turret_atk5] { ai_face (); };
+ nonvirtual void() turret_atk5 = [$attack5, turret_atk6] { ai_face (); };
+ nonvirtual void() turret_atk6 = [$attack6, turret_atk7] { ai_face (); };
+ nonvirtual void() turret_atk7 = [$attack7, turret_atk8] { ai_face (); };
+ nonvirtual void() turret_atk8 = [$attack8, turret_atk9] { ai_face (); };
+ nonvirtual void() turret_atk9 = [$attack9, turret_atk10]
+ {
+ attack_missile ();
+ };
+ nonvirtual void() turret_atk10 = [$attack10, turret_atk11] {ai_face();};
+ nonvirtual void() turret_atk11 = [$attack11, turret_atk12] {ai_face();};
+ nonvirtual void() turret_atk12 = [$walk1, turret_atk13] { ai_face (); };
+ nonvirtual void() turret_atk13 = [$walk1, turret_atk14] { ai_face (); };
+ nonvirtual void() turret_atk14 = [$walk1, turret_atk15] { ai_face (); };
+ nonvirtual void() turret_atk15 = [$walk1, seek_stand1] { ai_run (0); };
+
+ //--------------------------------------------------------------
+ // Shalrath Turret Standing/Seeeking
+ //--------------------------------------------------------------
+ nonvirtual void() seek_stand1 = [$walk1, seek_stand2] { ai_run (0); };
+ nonvirtual void() seek_stand2 = [$walk1, seek_stand1] { ai_run (0); };
+
+ ////////////////////////////////////////
+ /// new frames for turret mode END ///
+ ////////////////////////////////////////
+
+ //--------------------------------------------------------------
+ // Shalrath Pain State
+ //--------------------------------------------------------------
+ nonvirtual void() pain1 = [$pain1, pain2] { };
+ nonvirtual void() pain2 = [$pain2, pain3] { };
+ nonvirtual void() pain3 = [$pain3, pain4] { };
+ nonvirtual void() pain4 = [$pain4, pain5] { };
+ nonvirtual void() pain5 = [$pain5, run1] { };
+
+ //--------------------------------------------------------------
+ // Shalrath Death State
+ //--------------------------------------------------------------
+ nonvirtual void() death1 = [$death1, death2] { };
+ nonvirtual void() death2 = [$death2, death3] { };
+ nonvirtual void() death3 = [$death3, death4] { };
+ nonvirtual void() death4 = [$death4, death5] { };
+ nonvirtual void() death5 = [$death5, death6] { };
+ nonvirtual void() death6 = [$death6, death7] { };
+ nonvirtual void() death7 = [$death7, death7] { };
+
+ //==============================================================
+ // Interaction
+ //==============================================================
+
+ //--------------------------------------------------------------
+ // shalrath_pain
+ //--------------------------------------------------------------
+ virtual void(entity attacker, float damage) do_damage =
+ {
+ if (this.pain_finished > time)
+ return;
+
+ // CHAN_AUTO was voice - dumptruck_ds
+ sound_pain (this, CHAN_AUTO, "shalrath/pain.wav",
+ 1, ATTN_NORM);
+ this.pain_finished = time + 3;
+
+ if (this.spawnflags & I_AM_TURRET)
+ return;
+ else
+ this.pain1 ();
+ };
- self.th_stand = shal_stand;
- self.th_walk = shal_walk1;
- if (self.spawnflags & I_AM_TURRET)
+ //--------------------------------------------------------------
+ // shalrath_die
+ //--------------------------------------------------------------
+ virtual void() do_destroy =
{
- self.th_run = shal_seek_stand1;
- }
- else
+ // check for gib
+ if (this.health < -90)
+ {
+ sound (this, CHAN_VOICE, "player/udeath.wav",
+ 1, ATTN_NORM);
+
+ // dumptruck_ds custom_mdls
+ if (this.mdl_head != "")
+ {
+ ThrowHead (this.mdl_head, this.health);
+ }
+ else
+ {
+ ThrowHead ("progs/h_shal.mdl", this.health);
+ }
+ // ThrowGib ("progs/gib1.mdl", this.health);
+ // ThrowGib ("progs/gib2.mdl", this.health);
+ // ThrowGib ("progs/gib3.mdl", this.health);
+ // custom models -- dumptruck_ds
+ if (this.mdl_gib1 != "")
+ {
+ ThrowGib (this.mdl_gib1, this.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib1.mdl", this.health);
+ }
+ if (this.mdl_gib2 != "")
+ {
+ ThrowGib (this.mdl_gib2, this.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib2.mdl", this.health);
+ }
+ if (this.mdl_gib3 != "")
+ {
+ ThrowGib (this.mdl_gib3, this.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib3.mdl", this.health);
+ }
+ base_item::drop_stuff (this);
+ return;
+ }
+ // insert death sounds here
+ sound_death (this, CHAN_VOICE, "shalrath/death.wav",
+ 1, ATTN_NORM);
+ base_item::drop_stuff (this);
+ this.death1 ();
+ this.solid = SOLID_NOT;
+ };
+
+ //==============================================================
+ // Initialization
+ //==============================================================
+
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
{
- self.th_run = shal_run1;
- }
+ if (deathmatch)
+ {
+ remove (this);
+ return;
+ }
- self.th_die = shalrath_die;
- if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
- self.th_pain = shalrath_pain;
- else
- self.th_pain = sub_nullpain;
- self.th_missile = shal_attack1;
- self.th_turret = shal_turret_attack1;
- self.think = walkmonster_start;
- self.nextthink = time + 0.1 + random ()*0.1;
+ // dumptruck_ds custom_mdls
+ precache_body_model2 ("progs/shalrath.mdl");
+ precache_head_model2 ("progs/h_shal.mdl");
+ precache_proj_model2 ("progs/v_spike.mdl");
+ // dumptruck_ds
+ precache_sound2_attack ("shalrath/attack.wav");
+ precache_sound2_misc ("shalrath/attack2.wav");
+ precache_sound2_death ("shalrath/death.wav");
+ precache_sound2_idle ("shalrath/idle.wav");
+ precache_sound2_pain ("shalrath/pain.wav");
+ precache_sound2_sight ("shalrath/sight.wav");
+
+ precache_gib1 ("progs/gib1.mdl");
+ precache_gib2 ("progs/gib2.mdl");
+ precache_gib3 ("progs/gib3.mdl");
+
+ this.solid = SOLID_SLIDEBOX;
+ this.movetype = MOVETYPE_STEP;
+
+ body_model ("progs/shalrath.mdl");
+ // setmodel (this, "progs/shalrath.mdl");
+ setsize (this, VEC_HULL2_MIN, VEC_HULL2_MAX);
+
+ if (!this.health)
+ // thanks RennyC -- dumptruck_ds
+ this.health = 400;
+
+ if (!this.proj_speed_mod)
+ this.proj_speed_mod = 1;
+
+ if (!this.homing)
+ // default to normal
+ this.homing = 1;
+ else if (this.homing < 0)
+ // disable with negative
+ this.homing = 0;
+
+ this.think_stand = this.stand1;
+ this.think_walk = this.walk1;
+ if (this.spawnflags & I_AM_TURRET)
+ this.think_run = this.seek_stand1;
+ else
+ this.think_run = this.run1;
+
+ this.th_die = this.do_destroy;
+
+ // Berserk test from
+ // http://celephais.net/board/view_thread.php?id=4&start=3465
+ // -- dumptruck_ds
+ if !(this.berserk)
+ this.th_pain = this.do_damage;
+ else
+ this.th_pain = sub_nullpain;
+ this.think_missile = this.attack1;
+ this.think_turret = this.turret_atk1;
+
+ /*
+ this.think = walkmonster_start;
+ this.nextthink = time + 0.1 + random ()*0.1;
+ */
+ // call walkmonster_start directly -- CEV
+ super::init_spawned ();
+ };
+
+ //--------------------------------------------------------------
+ void() monster_shalrath =
+ {
+ this.classtype = CT_MONSTER_VORE;
+ };
};
+// ShalMissileTouch --moved to misc.qc for voreball shooter -- dumptruck-ds
+/*
+void() ShalMissileTouch =
+{
+ if (other == self.owner)
+ return; // don't explode on owner
+
+ if (other.classname == "monster_zombie")
+ T_Damage (other, self, self, 110);
+ T_RadiusDamage (self, self.owner, 40, world);
+ sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM);
+
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_EXPLOSION);
+ WriteCoord (MSG_BROADCAST, self.origin_x);
+ WriteCoord (MSG_BROADCAST, self.origin_y);
+ WriteCoord (MSG_BROADCAST, self.origin_z);
+
+ self.velocity = '0 0 0';
+ self.touch = sub_null;
+ setmodel (self, "progs/s_explod.spr");
+ self.solid = SOLID_NOT;
+ s_explode1 ();
+};
+*/
+
+//==============================================================================
+
/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
/*QUAKED monster_dead_shalrath (0 0.5 0.8) (-32 -32 -24) (32 32 64) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
Return to the top of this page or return to the overview of this repo.
Diff qc/monsters/shambler.qc
diff --git a/qc/monsters/shambler.qc b/qc/monsters/shambler.qc
index 420319c..0a36b06 100644
--- a/qc/monsters/shambler.qc
+++ b/qc/monsters/shambler.qc
@@ -1,72 +1,10 @@
-/*
-==============================================================================
-
-SHAMBLER
-
-==============================================================================
-
-================
-ShamRocket
-================
-*/
-void() ShamRocket =
-{
- local entity missile;
- local float projspeed = 900 * self.proj_speed_mod;
-
- sound_attack (self, CHAN_AUTO, "boss1/throw.wav", 1, ATTN_NORM);
-
- missile = spawn ();
- missile.owner = self;
- missile.movetype = MOVETYPE_FLYMISSILE;
- missile.solid = SOLID_BBOX;
- missile.classname = "missile";
-
-// set missile speed -- dumptruck_ds below
-
- SetSpeed(missile, normalize(self.enemy.origin - self.origin), projspeed);
- missile.angles = vectoangles(missile.velocity);
- missile.avelocity = self.cust_avelocity; //custom spin of projectile
- if !(missile.avelocity)
- missile.avelocity = '200 100 300';
-
- missile.touch = T_MissileTouch;
-
-// set missile duration
- if (self.homing > 0)
- {
- SetupHoming(missile, projspeed);
- }
- else
- {
- missile.nextthink = time + 5;
- missile.think = sub_remove;
- }
- missile.skin = self.skin_proj; //dumptruck_ds
-
- if (self.mdl_proj != "") // dumptruck_ds
- {
- setmodel (missile, self.mdl_proj);
- }
- else
- {
- setmodel (missile, "progs/lavaball.mdl");
- }
-
- if (!missile.skin_proj) // dumptruck_ds
- {
- missile.skin = self.skin_proj;
- }
- else
- {
- missile.skin = 0;
- }
- setsize (missile, '0 0 0', '0 0 0');
- makevectors (self.angles); //thanks Voidforce -- dumptruck_ds
- setorigin (missile, self.origin + v_forward*8 + '0 0 24');
-};
-
+//==============================================================================
+// SHAMBLER
+//==============================================================================
+//======================================================================
+// frame macros
+//======================================================================
$cd id1/models/shams
$origin 0 0 24
$base base
@@ -97,609 +35,913 @@ $frame pain1 pain2 pain3 pain4 pain5 pain6
$frame death1 death2 death3 death4 death5 death6
$frame death7 death8 death9 death10 death11
-void() sham_stand1 =[ $stand1, sham_stand2 ] {ai_stand();};
-void() sham_stand2 =[ $stand2, sham_stand3 ] {ai_stand();};
-void() sham_stand3 =[ $stand3, sham_stand4 ] {ai_stand();};
-void() sham_stand4 =[ $stand4, sham_stand5 ] {ai_stand();};
-void() sham_stand5 =[ $stand5, sham_stand6 ] {ai_stand();};
-void() sham_stand6 =[ $stand6, sham_stand7 ] {ai_stand();};
-void() sham_stand7 =[ $stand7, sham_stand8 ] {ai_stand();};
-void() sham_stand8 =[ $stand8, sham_stand9 ] {ai_stand();};
-void() sham_stand9 =[ $stand9, sham_stand10] {ai_stand();};
-void() sham_stand10 =[ $stand10, sham_stand11] {ai_stand();};
-void() sham_stand11 =[ $stand11, sham_stand12] {ai_stand();};
-void() sham_stand12 =[ $stand12, sham_stand13] {ai_stand();};
-void() sham_stand13 =[ $stand13, sham_stand14] {ai_stand();};
-void() sham_stand14 =[ $stand14, sham_stand15] {ai_stand();};
-void() sham_stand15 =[ $stand15, sham_stand16] {ai_stand();};
-void() sham_stand16 =[ $stand16, sham_stand17] {ai_stand();};
-void() sham_stand17 =[ $stand17, sham_stand1 ] {ai_stand();};
-
-void() sham_walk1 =[ $walk1, sham_walk2 ] {ai_walk(10);};
-void() sham_walk2 =[ $walk2, sham_walk3 ] {ai_walk(9);};
-void() sham_walk3 =[ $walk3, sham_walk4 ] {ai_walk(9);};
-void() sham_walk4 =[ $walk4, sham_walk5 ] {ai_walk(5);};
-void() sham_walk5 =[ $walk5, sham_walk6 ] {ai_walk(6);};
-void() sham_walk6 =[ $walk6, sham_walk7 ] {ai_walk(12);};
-void() sham_walk7 =[ $walk7, sham_walk8 ] {ai_walk(8);};
-void() sham_walk8 =[ $walk8, sham_walk9 ] {ai_walk(3);};
-void() sham_walk9 =[ $walk9, sham_walk10] {ai_walk(13);};
-void() sham_walk10 =[ $walk10, sham_walk11] {ai_walk(9);};
-void() sham_walk11 =[ $walk11, sham_walk12] {ai_walk(7);};
-void() sham_walk12 =[ $walk12, sham_walk1 ] {ai_walk(7);
-if (random() > 0.8)
- sound_idle (self, CHAN_VOICE, "shambler/sidle.wav", 1, ATTN_IDLE);};
-
-void() sham_run1 =[ $run1, sham_run2 ] {ai_run(20);};
-void() sham_run2 =[ $run2, sham_run3 ] {ai_run(24);};
-void() sham_run3 =[ $run3, sham_run4 ] {ai_run(20);};
-void() sham_run4 =[ $run4, sham_run5 ] {ai_run(20);};
-void() sham_run5 =[ $run5, sham_run6 ] {ai_run(24);};
-void() sham_run6 =[ $run6, sham_run1 ] {ai_run(20);
-if (random() > 0.8)
- sound_idle (self, CHAN_VOICE, "shambler/sidle.wav", 1, ATTN_IDLE);
-};
-
-void() sham_smash1 =[ $smash1, sham_smash2 ] {
-sound_attack (self, CHAN_VOICE, "shambler/melee1.wav", 1, ATTN_NORM);
-ai_charge(2);};
-void() sham_smash2 =[ $smash2, sham_smash3 ] {ai_charge(6);};
-void() sham_smash3 =[ $smash3, sham_smash4 ] {ai_charge(6);};
-void() sham_smash4 =[ $smash4, sham_smash5 ] {ai_charge(5);};
-void() sham_smash5 =[ $smash5, sham_smash6 ] {ai_charge(4);};
-void() sham_smash6 =[ $smash6, sham_smash7 ] {ai_charge(1);};
-void() sham_smash7 =[ $smash7, sham_smash8 ] {ai_charge(0);};
-void() sham_smash8 =[ $smash8, sham_smash9 ] {ai_charge(0);};
-void() sham_smash9 =[ $smash9, sham_smash10 ] {ai_charge(0);};
-void() sham_smash10 =[ $smash10, sham_smash11 ] {
-local vector delta;
-local float ldmg;
-
- if (!self.enemy)
- return;
- ai_charge(0);
-
- delta = self.enemy.origin - self.origin;
-
- if (vlen(delta) > 100)
- return;
- if (!CanDamage (self.enemy, self))
- return;
-
- ldmg = (random() + random() + random()) * 40;
- T_Damage (self.enemy, self, self, ldmg);
- sound_hit (self, CHAN_VOICE, "shambler/smack.wav", 1, ATTN_NORM);
-
- SpawnMeatSpray (self.origin + v_forward*16, crandom() * 100 * v_right);
- SpawnMeatSpray (self.origin + v_forward*16, crandom() * 100 * v_right);
-};
-void() sham_smash11 =[ $smash11, sham_smash12 ] {ai_charge(5);};
-void() sham_smash12 =[ $smash12, sham_run1 ] {ai_charge(4);};
-/////////////////////////////////////
-// new frames for projectile style
-////////////////////////////////////
-void() sham_proj1 =[ $smash1, sham_proj2 ] {ai_face();};
-void() sham_proj2 =[ $smash2, sham_proj3 ] {ai_face();};
-void() sham_proj3 =[ $smash3, sham_proj4 ] {ai_face();};
-void() sham_proj4 =[ $smash4, sham_proj5 ] {ai_face();};
-void() sham_proj5 =[ $smash5, sham_proj6 ] {ai_face();};
-void() sham_proj6 =[ $smash6, sham_proj7 ] {ai_face();};
-void() sham_proj7 =[ $smash7, sham_proj8 ] {ai_face();};
-void() sham_proj8 =[ $smash8, sham_proj9 ] {ai_face();};
-void() sham_proj9 =[ $smash9, sham_proj10 ] {ai_face();};
-void() sham_proj10 =[ $smash10, sham_proj11 ]
-{
-ShamRocket();
-sound_attack (self, CHAN_VOICE, "shambler/melee1.wav", 1, ATTN_NORM); ai_face();
-};
-void() sham_proj11 =[ $smash11, sham_proj12 ] {ai_face();};
-void() sham_proj12 =[ $smash12, sham_run1 ] {ai_face();};
-/// projectile frames for turret mode
-void() sham_turret_proj1 =[ $smash1, sham_turret_proj2 ] {ai_face();};
-void() sham_turret_proj2 =[ $smash2, sham_turret_proj3 ] {ai_face();};
-void() sham_turret_proj3 =[ $smash3, sham_turret_proj4 ] {ai_face();};
-void() sham_turret_proj4 =[ $smash4, sham_turret_proj5 ] {ai_face();};
-void() sham_turret_proj5 =[ $smash5, sham_turret_proj6 ] {ai_face();};
-void() sham_turret_proj6 =[ $smash6, sham_turret_proj7 ] {ai_face();};
-void() sham_turret_proj7 =[ $smash7, sham_turret_proj8 ] {ai_face();};
-void() sham_turret_proj8 =[ $smash8, sham_turret_proj9 ] {ai_face();};
-void() sham_turret_proj9 =[ $smash9, sham_turret_proj10 ] {ai_face();};
-void() sham_turret_proj10 =[ $smash10, sham_turret_proj11 ]
+//----------------------------------------------------------------------
+// shambler trigger field think function
+//----------------------------------------------------------------------
+void() sham_arc_think =
{
-ShamRocket();
-sound_attack (self, CHAN_VOICE, "shambler/melee1.wav", 1, ATTN_NORM); ai_face();
+ if (self.owner != world && self.owner.trigger_field == self)
+ self.owner.trigger_field = world;
+ remove (self);
};
-void() sham_turret_proj11 =[ $smash11, sham_turret_proj12 ] {ai_face();};
-void() sham_turret_proj12 =[ $smash12, sham_seek_1 ] {ai_face();};
-
-void() sham_swingr1;
-void(float side) ShamClaw =
+/*QUAKED monster_shambler (1 0 0) (-32 -32 -24) (32 32 64) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
{
-local vector delta;
-local float ldmg;
+ model ("progs/shambler.mdl");
+}
+Shambler.
- if (!self.enemy)
- return;
- ai_charge(10);
+Default health = 600
- delta = self.enemy.origin - self.origin;
+snd_death(string) : "Path to custom death sound"
+snd_pain(string) : "Path to custom pain sound"
+snd_sight(string) : "Path to custom sight sound"
+snd_attack(string) : "Path to custom attack sound (GRUNT)"
+snd_hit(string) : "Path to custom hit sound (FLESH TEARING)"
+snd_idle(string) : "Path to custom idle sound"
+snd_misc(string) : "Path to custom sound (GRUNT 2)"
+snd_misc1(string) : "Path to custom sound (LIGHTNING ZAP)"
+snd_misc2(string) : "Path to custom sound (LIGHTNING BOOM)"
- if (vlen(delta) > 100)
- return;
+mdl_head(string) : "Path to custom head model"
+mdl_body(string) : "Path to custom body model"
+skin_head(float) : "Skin index of custom head model"
+mdl_gib1(string) : "Path to custom 1st gib model"
+mdl_gib2(string) : "Path to custom 2nd gib model"
+mdl_gib3(string) : "Path to custom 3rd gib model"
- ldmg = (random() + random() + random()) * 20;
- T_Damage (self.enemy, self, self, ldmg);
- sound_hit (self, CHAN_VOICE, "shambler/smack.wav", 1, ATTN_NORM);
+effects(choices) : "Add a visual effect to an entity"
+0 : "None (Default)"
+1 : "Brightfield (yellow particles)"
+4 : "Bright light"
+8 : "Dim light"
- if (side)
- {
- makevectors (self.angles);
- SpawnMeatSpray (self.origin + v_forward*16, side * v_right);
- }
-};
+berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
+0 : "Off (Default)"
+1 : "Berserk (skip pain animations)"
-void() sham_swingl1 =[ $swingl1, sham_swingl2 ] {
-sound_misc (self, CHAN_VOICE, "shambler/melee2.wav", 1, ATTN_NORM);
-ai_charge(5);};
-void() sham_swingl2 =[ $swingl2, sham_swingl3 ] {ai_charge(3);};
-void() sham_swingl3 =[ $swingl3, sham_swingl4 ] {ai_charge(7);};
-void() sham_swingl4 =[ $swingl4, sham_swingl5 ] {ai_charge(3);};
-void() sham_swingl5 =[ $swingl5, sham_swingl6 ] {ai_charge(7);};
-void() sham_swingl6 =[ $swingl6, sham_swingl7 ] {ai_charge(9);};
-void() sham_swingl7 =[ $swingl7, sham_swingl8 ] {ai_charge(5); ShamClaw(250);};
-void() sham_swingl8 =[ $swingl8, sham_swingl9 ] {ai_charge(4);};
-void() sham_swingl9 =[ $swingl9, sham_run1 ] {
-ai_charge(8);
-if (random()<0.5)
- self.think = sham_swingr1;
-};
+delay(float) : "Delay spawn in for this amount of time"
-void() sham_swingr1 =[ $swingr1, sham_swingr2 ] {
-sound_attack (self, CHAN_VOICE, "shambler/melee1.wav", 1, ATTN_NORM);
-ai_charge(1);};
-void() sham_swingr2 =[ $swingr2, sham_swingr3 ] {ai_charge(8);};
-void() sham_swingr3 =[ $swingr3, sham_swingr4 ] {ai_charge(14);};
-void() sham_swingr4 =[ $swingr4, sham_swingr5 ] {ai_charge(7);};
-void() sham_swingr5 =[ $swingr5, sham_swingr6 ] {ai_charge(3);};
-void() sham_swingr6 =[ $swingr6, sham_swingr7 ] {ai_charge(6);};
-void() sham_swingr7 =[ $swingr7, sham_swingr8 ] {ai_charge(6); ShamClaw(-250);};
-void() sham_swingr8 =[ $swingr8, sham_swingr9 ] {ai_charge(3);};
-void() sham_swingr9 =[ $swingr9, sham_run1 ] {ai_charge(1);
-ai_charge(10);
-if (random()<0.5)
- self.think = sham_swingl1;
-};
+wait(choices) : "Play an effect when trigger spawned?"
+0 : "Teleport Effects (Default)"
+1 : "Spawn Silently"
-void() sham_melee2 =
-{
- local float chance;
+spawn_angry(Choices)
+0 : "Only when trigger spawned, default behavior - not angry"
+1 : "Only when trigger spawned, set to 1 to spawn angry at player"
- chance = random();
+infight_mode(Choices)
+0 : "Default behavior, only with different classnames"
+1 : "Infight with monsters with the same classname but a different mdl_body"
+2 : "Infight with monsters with the same classname and model but a different skin"
+3 : "Infight no matter what"
- if (chance > 0.6)
- sham_swingr1 ();
- else
- sham_swingl1 ();
-};
+health(integer) : "Set this to a custom health amount"
+pain_target(string) : "Fire this target when pain_threshold is reached"
+pain_threshold(integer) : "Fire pain_target when health drops below this amount"
+sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
+skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
+obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
+obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
+damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
-void() sham_melee =
+*/
+class monster_shambler: base_walkmonster
{
- local float chance;
-
- chance = random();
+ //--------------------------------------------------------------
+ virtual void() ai_sightsound =
+ {
+ sound_sight (this, CHAN_VOICE, "shambler/ssight.wav",
+ 1, ATTN_NORM);
+ };
+
+ //--------------------------------------------------------------
+ // ShamCheckAttack
+ //
+ // The player is in view, so decide to move or launch an attack
+ // Returns FALSE if movement should continue
+ //--------------------------------------------------------------
+ virtual float() ai_checkattack =
+ {
+ local vector spot1, spot2;
+ local entity targ;
- if (chance > 0.6 || self.health == 600) // changed to >= as you can set custom health
- sham_smash1 ();
- else if (chance > 0.3)
- sham_swingr1 ();
- else
- sham_swingl1 ();
-};
+ if (enemy_range == RANGE_MELEE)
+ {
+ if (CanDamage(this.enemy, this))
+ {
+ this.attack_state = AS_MELEE;
+ return TRUE;
+ }
+ }
+ if (this.spawnflags & I_AM_TURRET)
+ {
+ this.attack_state = AS_MISSILE;
+ sub_attackfinished (2 + 2 * random());
+ return TRUE;
+ }
-//============================================================================
+ if (time < this.attack_finished)
+ return FALSE;
+ if (!enemy_vis)
+ return FALSE;
-void() sham_arc_think =
-{
- if (self.owner != world && self.owner.trigger_field == self)
- self.owner.trigger_field = world;
- remove (self);
-};
+ targ = this.enemy;
+ // see if any entities are in the way of the shot
+ spot1 = this.origin + this.view_ofs;
+ spot2 = targ.origin + targ.view_ofs;
-void() CastLightning =
-{
- local vector org, dir;
+ if (this.style == 0)
+ if (vlen(spot1 - spot2) > 600)
+ return FALSE;
- self.effects = self.effects | EF_MUZZLEFLASH;
+ if (this.spawnflags & I_AM_TURRET)
+ if (vlen(spot1 - spot2) > 900)
+ return FALSE;
- ai_face ();
+ // return FALSE;
- org = self.origin + '0 0 40';
+ traceline (spot1, spot2, FALSE, this);
- dir = self.enemy.origin + '0 0 16' - org;
- dir = normalize (dir);
+ if (trace_inopen && trace_inwater)
+ // sight line crossed contents
+ return FALSE;
- if (self.spawnflags & I_AM_TURRET)
+ if ((this.spawnflags & I_AM_TURRET) && (trace_ent != targ))
{
- traceline (org, self.origin + dir*900, TRUE, self);
- }
- else
- {
- traceline (org, self.origin + dir*600, TRUE, self);
+ // dprint("trace_ent...\n");
+ this.attack_state = AS_TURRET;
+ return FALSE;
}
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_LIGHTNING1);
- WriteEntity (MSG_BROADCAST, self);
- WriteCoord (MSG_BROADCAST, org_x);
- WriteCoord (MSG_BROADCAST, org_y);
- WriteCoord (MSG_BROADCAST, org_z);
- WriteCoord (MSG_BROADCAST, trace_endpos_x);
- WriteCoord (MSG_BROADCAST, trace_endpos_y);
- WriteCoord (MSG_BROADCAST, trace_endpos_z);
-
- LightningDamage (org, trace_endpos, self, 10);
-};
+ if (trace_ent != targ)
+ // don't have a clear shot
+ return FALSE;
-void() sham_magic1 =[ $magic1, sham_magic2 ] {ai_face();
- sound_misc1 (self, CHAN_WEAPON, "shambler/sattck1.wav", 1, ATTN_NORM);
-};
-void() sham_magic2 =[ $magic2, sham_magic3 ] {ai_face();};
-void() sham_magic3 =[ $magic3, sham_magic4 ] {ai_face();self.nextthink = time + 0.2;
-local entity o;
-
-self.effects = self.effects | EF_MUZZLEFLASH;
-ai_face();
-self.trigger_field = spawn();
-o = self.trigger_field;
-setmodel (o, "progs/s_light.mdl");
-setorigin (o, self.origin);
-o.owner = self;
-o.angles = self.angles;
-o.nextthink = time + 0.7;
-o.think = sham_arc_think;
-};
-void() sham_magic4 =[ $magic4, sham_magic5 ]
-{
-self.effects = self.effects | EF_MUZZLEFLASH;
-self.trigger_field.frame = 1;
-};
-void() sham_magic5 =[ $magic5, sham_magic6 ]
-{
-self.effects = self.effects | EF_MUZZLEFLASH;
-self.trigger_field.frame = 2;
-};
-void() sham_magic6 =[ $magic6, sham_magic9 ]
-{
-remove (self.trigger_field);
-self.trigger_field = world;
-CastLightning();
-sound_misc2 (self, CHAN_WEAPON, "shambler/sboom.wav", 1, ATTN_NORM);
-};
-void() sham_magic9 =[ $magic9, sham_magic10 ]
-{CastLightning();};
-void() sham_magic10 =[ $magic10, sham_magic11 ]
-{CastLightning();};
-void() sham_magic11 =[ $magic11, sham_magic12 ]
-{
-if (skill == 3)
- CastLightning();
-};
-void() sham_magic12 =[ $magic12, sham_run1 ] {};
-/////////////////////////
-//// turret start
-////////////////////////
-void() sham_turret_magic1 =[ $magic1, sham_turret_magic2 ] {ai_face();
- sound_misc1 (self, CHAN_WEAPON, "shambler/sattck1.wav", 1, ATTN_NORM);
-};
-void() sham_turret_magic2 =[ $magic2, sham_turret_magic3 ] {ai_face();};
-void() sham_turret_magic3 =[ $magic3, sham_turret_magic4 ] {ai_face();self.nextthink = time + 0.2;
-local entity o;
-
-self.effects = self.effects | EF_MUZZLEFLASH;
-ai_face();
-self.trigger_field = spawn();
-o = self.trigger_field;
-setmodel (o, "progs/s_light.mdl");
-setorigin (o, self.origin);
-o.owner = self;
-o.angles = self.angles;
-o.nextthink = time + 0.7;
-o.think = sham_arc_think;
-};
-void() sham_turret_magic4 =[ $magic4, sham_turret_magic5 ]
-{
-self.effects = self.effects | EF_MUZZLEFLASH;
-self.trigger_field.frame = 1;
-};
-void() sham_turret_magic5 =[ $magic5, sham_turret_magic6 ]
-{
-self.effects = self.effects | EF_MUZZLEFLASH;
-self.trigger_field.frame = 2;
-};
-void() sham_turret_magic6 =[ $magic6, sham_turret_magic9 ]
-{
-remove (self.trigger_field);
-self.trigger_field = world;
-CastLightning();
-sound_misc2 (self, CHAN_WEAPON, "shambler/sboom.wav", 1, ATTN_NORM);
-};
-void() sham_turret_magic9 =[ $magic9, sham_turret_magic10 ]
-{CastLightning();};
-void() sham_turret_magic10 =[ $magic10, sham_turret_magic11 ]
-{CastLightning();};
-void() sham_turret_magic11 =[ $magic11, sham_turret_magic12 ]
-{
-if (skill == 3)
- CastLightning();
-};
-void() sham_turret_magic12 =[ $magic12, sham_turret_magic13 ] {};
-void() sham_turret_magic13 =[ $stand14, sham_turret_magic14 ] {ai_face();};
-void() sham_turret_magic14 =[ $stand15, sham_turret_magic15 ] {ai_face();};
-void() sham_turret_magic15 =[ $stand16, sham_turret_magic16 ] {ai_face();};
-void() sham_turret_magic16 =[ $stand17, sham_seek_1 ] {};
-void() sham_seek_1 =[ $stand1, sham_seek_2 ] {ai_run(0);};
-void() sham_seek_2 =[ $stand2, sham_seek_3 ] {ai_run(0);};
-void() sham_seek_3 =[ $stand3, sham_seek_4 ] {ai_run(0);};
-void() sham_seek_4 =[ $stand4, sham_seek_5 ] {ai_run(0);};
-void() sham_seek_5 =[ $stand5, sham_seek_6 ] {ai_run(0);};
-void() sham_seek_6 =[ $stand6, sham_seek_7 ] {ai_run(0);};
-void() sham_seek_7 =[ $stand7, sham_seek_8 ] {ai_run(0);};
-void() sham_seek_8 =[ $stand8, sham_seek_9 ] {ai_run(0);};
-void() sham_seek_9 =[ $stand9, sham_seek_10] {ai_run(0);};
-void() sham_seek_10 =[ $stand10, sham_seek_11] {ai_run(0);};
-void() sham_seek_11 =[ $stand11, sham_seek_12] {ai_run(0);};
-void() sham_seek_12 =[ $stand12, sham_seek_13] {ai_run(0);};
-void() sham_seek_13 =[ $stand13, sham_seek_14] {ai_run(0);};
-void() sham_seek_14 =[ $stand14, sham_seek_15] {ai_run(0);};
-void() sham_seek_15 =[ $stand15, sham_seek_16] {ai_run(0);};
-void() sham_seek_16 =[ $stand16, sham_seek_17] {ai_run(0);};
-void() sham_seek_17 =[ $stand17, sham_seek_1 ] {ai_run(0);};
-/////////////////////////
-//// turret end
-////////////////////////
-
-void() sham_pain1 =[ $pain1, sham_pain2 ] {};
-void() sham_pain2 =[ $pain2, sham_pain3 ] {};
-void() sham_pain3 =[ $pain3, sham_pain4 ] {};
-void() sham_pain4 =[ $pain4, sham_pain5 ] {};
-void() sham_pain5 =[ $pain5, sham_pain6 ] {};
-void() sham_pain6 =[ $pain6, sham_run1 ] {};
-
-void(entity attacker, float damage) sham_pain =
-{
- sound_pain (self, CHAN_VOICE, "shambler/shurt2.wav", 1, ATTN_NORM);
+ // missile attack
+ if (this.style == 0 && enemy_range == RANGE_FAR)
+ return FALSE;
- if (self.spawnflags & I_AM_TURRET)
- return;
+ this.attack_state = AS_MISSILE;
+ sub_attackfinished (2 + 2 * random());
+ return TRUE;
+ };
- if (self.health <= 0)
- return; // allready dying, don't go into pain frame
+ //--------------------------------------------------------------
+ // ShamClaw
+ //--------------------------------------------------------------
+ nonvirtual void(float side) attack_claw =
+ {
+ local vector delta;
+ local float ldmg;
- if (random()*400 > damage)
- return; // didn't flinch
+ if (!this.enemy)
+ return;
- if (self.pain_finished > time)
- return;
- self.pain_finished = time + 2;
+ ai_charge (10);
- if (self.trigger_field != world && self.trigger_field.owner == self)
- self.trigger_field.frame = 2;
- self.trigger_field = world;
+ delta = this.enemy.origin - this.origin;
+ if (vlen(delta) > 100)
+ return;
- sham_pain1 ();
-};
+ ldmg = (random() + random() + random()) * 20;
+ T_Damage (this.enemy, this, this, ldmg);
+ sound_hit (this, CHAN_VOICE, "shambler/smack.wav",
+ 1, ATTN_NORM);
+ if (side)
+ {
+ makevectors (this.angles);
+ SpawnMeatSpray (this.origin + v_forward * 16,
+ side * v_right);
+ }
+ };
-//============================================================================
+ //--------------------------------------------------------------
+ // CastLightning
+ //--------------------------------------------------------------
+ nonvirtual void() attack_lightning =
+ {
+ local vector org, dir;
-void() sham_death1 =[ $death1, sham_death2 ] {};
-void() sham_death2 =[ $death2, sham_death3 ] {};
-void() sham_death3 =[ $death3, sham_death4 ] {self.solid = SOLID_NOT;};
-void() sham_death4 =[ $death4, sham_death5 ] {};
-void() sham_death5 =[ $death5, sham_death6 ] {};
-void() sham_death6 =[ $death6, sham_death7 ] {};
-void() sham_death7 =[ $death7, sham_death8 ] {};
-void() sham_death8 =[ $death8, sham_death9 ] {};
-void() sham_death9 =[ $death9, sham_death10 ] {};
-void() sham_death10 =[ $death10, sham_death11 ] {};
-void() sham_death11 =[ $death11, sham_death11 ] {};
+ this.effects = this.effects | EF_MUZZLEFLASH;
-void() sham_die =
-{
-// check for gib
- if (self.health < -60)
- {
- sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
- if (self.mdl_head != "") //dumptruck_ds custom_mdls
+ ai_face ();
+
+ org = this.origin + '0 0 40';
+
+ dir = this.enemy.origin + '0 0 16' - org;
+ dir = normalize (dir);
+
+ if (this.spawnflags & I_AM_TURRET)
{
- ThrowHead (self.mdl_head, self.health);
+ traceline (org, this.origin + dir * 900, TRUE, this);
}
else
{
- ThrowHead ("progs/h_shams.mdl", self.health);
+ traceline (org, this.origin + dir * 600, TRUE, this);
}
- // ThrowGib ("progs/gib1.mdl", self.health);
- // ThrowGib ("progs/gib2.mdl", self.health);
- // ThrowGib ("progs/gib3.mdl", self.health);
- if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
+
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_LIGHTNING1);
+ WriteEntity (MSG_BROADCAST, this);
+ WriteCoord (MSG_BROADCAST, org_x);
+ WriteCoord (MSG_BROADCAST, org_y);
+ WriteCoord (MSG_BROADCAST, org_z);
+ WriteCoord (MSG_BROADCAST, trace_endpos_x);
+ WriteCoord (MSG_BROADCAST, trace_endpos_y);
+ WriteCoord (MSG_BROADCAST, trace_endpos_z);
+
+ LightningDamage (org, trace_endpos, this, 10);
+ };
+
+ //--------------------------------------------------------------
+ // ShamRocket
+ //--------------------------------------------------------------
+ nonvirtual void() attack_rocket =
+ {
+ local entity missile;
+ local float projspeed = 900 * this.proj_speed_mod;
+
+ sound_attack (this, CHAN_AUTO, "boss1/throw.wav", 1, ATTN_NORM);
+
+ missile = spawn ();
+ missile.owner = this;
+ missile.movetype = MOVETYPE_FLYMISSILE;
+ missile.solid = SOLID_BBOX;
+ missile.classname = "missile";
+
+ // set missile speed -- dumptruck_ds below
+
+ SetSpeed (missile, normalize(this.enemy.origin - this.origin),
+ projspeed);
+ missile.angles = vectoangles (missile.velocity);
+ // custom spin of projectile
+ missile.avelocity = this.cust_avelocity;
+ if !(missile.avelocity)
+ missile.avelocity = '200 100 300';
+
+ missile.touch = T_MissileTouch;
+
+ // set missile duration
+ if (this.homing > 0)
{
- ThrowGib (self.mdl_gib1, self.health);
+ SetupHoming (missile, projspeed);
}
else
{
- ThrowGib ("progs/gib1.mdl", self.health);
+ missile.nextthink = time + 5;
+ missile.think = sub_remove;
}
- if (self.mdl_gib2 != "")
+ // dumptruck_ds
+ missile.skin = this.skin_proj;
+
+ // dumptruck_ds
+ if (this.mdl_proj != "")
{
- ThrowGib (self.mdl_gib2, self.health);
+ setmodel (missile, this.mdl_proj);
}
else
{
- ThrowGib ("progs/gib2.mdl", self.health);
+ setmodel (missile, "progs/lavaball.mdl");
}
- if (self.mdl_gib3 != "")
+
+ // dumptruck_ds
+ if (!missile.skin_proj)
{
- ThrowGib (self.mdl_gib3, self.health);
+ missile.skin = this.skin_proj;
}
else
{
- ThrowGib ("progs/gib3.mdl", self.health);
+ missile.skin = 0;
}
- base_item::drop_stuff (self);
- return;
- }
-
-// regular death
- sound_death (self, CHAN_VOICE, "shambler/sdeath.wav", 1, ATTN_NORM);
- base_item::drop_stuff (self);
- sham_death1 ();
-};
+ setsize (missile, '0 0 0', '0 0 0');
+ // thanks Voidforce -- dumptruck_ds
+ makevectors (this.angles);
+ setorigin (missile, this.origin + v_forward*8 + '0 0 24');
+ };
+
+ //--------------------------------------------------------------
+ nonvirtual void() attack_melee2 =
+ {
+ local float chance;
-//============================================================================
+ chance = random ();
+ if (chance > 0.6)
+ this.swingr1 ();
+ else
+ this.swingl1 ();
+ };
-/*QUAKED monster_shambler (1 0 0) (-32 -32 -24) (32 32 64) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ("progs/shambler.mdl");
-}
-Shambler.
+ //--------------------------------------------------------------
+ nonvirtual void() attack_melee =
+ {
+ local float chance;
-Default health = 600
+ chance = random ();
-snd_death(string) : "Path to custom death sound"
-snd_pain(string) : "Path to custom pain sound"
-snd_sight(string) : "Path to custom sight sound"
-snd_attack(string) : "Path to custom attack sound (GRUNT)"
-snd_hit(string) : "Path to custom hit sound (FLESH TEARING)"
-snd_idle(string) : "Path to custom idle sound"
-snd_misc(string) : "Path to custom sound (GRUNT 2)"
-snd_misc1(string) : "Path to custom sound (LIGHTNING ZAP)"
-snd_misc2(string) : "Path to custom sound (LIGHTNING BOOM)"
+ // changed to >= as you can set custom health
+ if (chance > 0.6 || this.health == 600)
+ this.smash1 ();
+ else if (chance > 0.3)
+ this.swingr1 ();
+ else
+ this.swingl1 ();
+ };
+
+ //--------------------------------------------------------------
+ // Shambler standing functions
+ //--------------------------------------------------------------
+ nonvirtual void() stand1 = [$stand1, stand2] { ai_stand (); };
+ nonvirtual void() stand2 = [$stand2, stand3] { ai_stand (); };
+ nonvirtual void() stand3 = [$stand3, stand4] { ai_stand (); };
+ nonvirtual void() stand4 = [$stand4, stand5] { ai_stand (); };
+ nonvirtual void() stand5 = [$stand5, stand6] { ai_stand (); };
+ nonvirtual void() stand6 = [$stand6, stand7] { ai_stand (); };
+ nonvirtual void() stand7 = [$stand7, stand8] { ai_stand (); };
+ nonvirtual void() stand8 = [$stand8, stand9] { ai_stand (); };
+ nonvirtual void() stand9 = [$stand9, stand10] { ai_stand (); };
+ nonvirtual void() stand10 = [$stand10, stand11] { ai_stand (); };
+ nonvirtual void() stand11 = [$stand11, stand12] { ai_stand (); };
+ nonvirtual void() stand12 = [$stand12, stand13] { ai_stand (); };
+ nonvirtual void() stand13 = [$stand13, stand14] { ai_stand (); };
+ nonvirtual void() stand14 = [$stand14, stand15] { ai_stand (); };
+ nonvirtual void() stand15 = [$stand15, stand16] { ai_stand (); };
+ nonvirtual void() stand16 = [$stand16, stand17] { ai_stand (); };
+ nonvirtual void() stand17 = [$stand17, stand1] { ai_stand (); };
+
+ //--------------------------------------------------------------
+ // Shambler walk functions
+ //--------------------------------------------------------------
+ nonvirtual void() walk1 = [$walk1, walk2] { ai_walk (10); };
+ nonvirtual void() walk2 = [$walk2, walk3] { ai_walk (9); };
+ nonvirtual void() walk3 = [$walk3, walk4] { ai_walk (9); };
+ nonvirtual void() walk4 = [$walk4, walk5] { ai_walk (5); };
+ nonvirtual void() walk5 = [$walk5, walk6] { ai_walk (6); };
+ nonvirtual void() walk6 = [$walk6, walk7] { ai_walk (12); };
+ nonvirtual void() walk7 = [$walk7, walk8] { ai_walk (8); };
+ nonvirtual void() walk8 = [$walk8, walk9] { ai_walk (3); };
+ nonvirtual void() walk9 = [$walk9, walk10] { ai_walk (13); };
+ nonvirtual void() walk10 = [$walk10, walk11] { ai_walk (9); };
+ nonvirtual void() walk11 = [$walk11, walk12] { ai_walk (7); };
+ nonvirtual void() walk12 = [$walk12, walk1]
+ {
+ ai_walk (7);
+ if (random() > 0.8)
+ sound_idle (this, CHAN_VOICE, "shambler/sidle.wav",
+ 1, ATTN_IDLE);
+ };
+
+ //--------------------------------------------------------------
+ // Shambler run functions
+ //--------------------------------------------------------------
+ nonvirtual void() run1 = [$run1, run2] { ai_run (20); };
+ nonvirtual void() run2 = [$run2, run3] { ai_run (24); };
+ nonvirtual void() run3 = [$run3, run4] { ai_run (20); };
+ nonvirtual void() run4 = [$run4, run5] { ai_run (20); };
+ nonvirtual void() run5 = [$run5, run6] { ai_run (24); };
+ nonvirtual void() run6 = [$run6, run1]
+ {
+ ai_run (20);
+ if (random() > 0.8)
+ sound_idle (this, CHAN_VOICE, "shambler/sidle.wav",
+ 1, ATTN_IDLE);
+ };
+
+ //--------------------------------------------------------------
+ // Shambler smash!
+ //--------------------------------------------------------------
+ nonvirtual void() smash1 = [$smash1, smash2]
+ {
+ sound_attack (this, CHAN_VOICE, "shambler/melee1.wav",
+ 1, ATTN_NORM);
+ ai_charge (2);
+ };
+ nonvirtual void() smash2 = [$smash2, smash3] { ai_charge (6); };
+ nonvirtual void() smash3 = [$smash3, smash4] { ai_charge (6); };
+ nonvirtual void() smash4 = [$smash4, smash5] { ai_charge (5); };
+ nonvirtual void() smash5 = [$smash5, smash6] { ai_charge (4); };
+ nonvirtual void() smash6 = [$smash6, smash7] { ai_charge (1); };
+ nonvirtual void() smash7 = [$smash7, smash8] { ai_charge (0); };
+ nonvirtual void() smash8 = [$smash8, smash9] { ai_charge (0); };
+ nonvirtual void() smash9 = [$smash9, smash10] { ai_charge (0); };
+ nonvirtual void() smash10 = [$smash10, smash11]
+ {
+ local vector delta;
+ local float ldmg;
+
+ if (!this.enemy)
+ return;
+ ai_charge (0);
+
+ delta = this.enemy.origin - this.origin;
+
+ if (vlen(delta) > 100)
+ return;
+ if (!CanDamage(this.enemy, this))
+ return;
+
+ ldmg = (random() + random() + random()) * 40;
+ T_Damage (this.enemy, this, this, ldmg);
+ sound_hit (this, CHAN_VOICE, "shambler/smack.wav",
+ 1, ATTN_NORM);
+
+ SpawnMeatSpray (this.origin + v_forward * 16,
+ crandom() * 100 * v_right);
+ SpawnMeatSpray (this.origin + v_forward * 16,
+ crandom() * 100 * v_right);
+ };
+ nonvirtual void() smash11 = [$smash11, smash12] { ai_charge (5); };
+ nonvirtual void() smash12 = [$smash12, run1] { ai_charge (4); };
+
+ /////////////////////////////////////
+ // new frames for projectile style //
+ /////////////////////////////////////
+
+ //--------------------------------------------------------------
+ // Shambler Projectile
+ //--------------------------------------------------------------
+ nonvirtual void() proj1 = [$smash1, proj2] { ai_face (); };
+ nonvirtual void() proj2 = [$smash2, proj3] { ai_face (); };
+ nonvirtual void() proj3 = [$smash3, proj4] { ai_face (); };
+ nonvirtual void() proj4 = [$smash4, proj5] { ai_face (); };
+ nonvirtual void() proj5 = [$smash5, proj6] { ai_face (); };
+ nonvirtual void() proj6 = [$smash6, proj7] { ai_face (); };
+ nonvirtual void() proj7 = [$smash7, proj8] { ai_face (); };
+ nonvirtual void() proj8 = [$smash8, proj9] { ai_face (); };
+ nonvirtual void() proj9 = [$smash9, proj10] { ai_face (); };
+ nonvirtual void() proj10 = [$smash10, proj11]
+ {
+ this.attack_rocket ();
+ sound_attack (this, CHAN_VOICE, "shambler/melee1.wav",
+ 1, ATTN_NORM);
+ ai_face ();
+ };
+ nonvirtual void() proj11 = [$smash11, proj12] { ai_face (); };
+ nonvirtual void() proj12 = [$smash12, run1] { ai_face (); };
+
+
+ //--------------------------------------------------------------
+ // Shambler Projectile (Turret Mode)
+ //--------------------------------------------------------------
+ nonvirtual void() turret_proj1 = [$smash1, turret_proj2] { ai_face (); };
+ nonvirtual void() turret_proj2 = [$smash2, turret_proj3] { ai_face (); };
+ nonvirtual void() turret_proj3 = [$smash3, turret_proj4] { ai_face (); };
+ nonvirtual void() turret_proj4 = [$smash4, turret_proj5] { ai_face (); };
+ nonvirtual void() turret_proj5 = [$smash5, turret_proj6] { ai_face (); };
+ nonvirtual void() turret_proj6 = [$smash6, turret_proj7] { ai_face (); };
+ nonvirtual void() turret_proj7 = [$smash7, turret_proj8] { ai_face (); };
+ nonvirtual void() turret_proj8 = [$smash8, turret_proj9] { ai_face (); };
+ nonvirtual void() turret_proj9 = [$smash9, turret_proj10] { ai_face (); };
+ nonvirtual void() turret_proj10 = [$smash10, turret_proj11]
+ {
+ this.attack_rocket ();
+ sound_attack (this, CHAN_VOICE, "shambler/melee1.wav",
+ 1, ATTN_NORM);
+ ai_face();
+ };
+ nonvirtual void() turret_proj11 = [$smash11, turret_proj12] { ai_face (); };
+ nonvirtual void() turret_proj12 = [$smash12, seek_1] { ai_face (); };
+
+ /////////////////////////////////////
+ // end projectile style frames //
+ /////////////////////////////////////
+
+ //--------------------------------------------------------------
+ // Shambler's left hook
+ //--------------------------------------------------------------
+ nonvirtual void() swingl1 = [$swingl1, swingl2]
+ {
+ sound_misc (this, CHAN_VOICE, "shambler/melee2.wav",
+ 1, ATTN_NORM);
+ ai_charge (5);
+ };
+ nonvirtual void() swingl2 = [$swingl2, swingl3] { ai_charge (3); };
+ nonvirtual void() swingl3 = [$swingl3, swingl4] { ai_charge (7); };
+ nonvirtual void() swingl4 = [$swingl4, swingl5] { ai_charge (3); };
+ nonvirtual void() swingl5 = [$swingl5, swingl6] { ai_charge (7); };
+ nonvirtual void() swingl6 = [$swingl6, swingl7] { ai_charge (9); };
+ nonvirtual void() swingl7 = [$swingl7, swingl8]
+ {
+ ai_charge (5);
+ this.attack_claw (250);
+ };
+ nonvirtual void() swingl8 = [$swingl8, swingl9] { ai_charge (4); };
+ nonvirtual void() swingl9 = [$swingl9, run1]
+ {
+ ai_charge (8);
+ if (random()<0.5)
+ this.think = this.swingr1;
+ };
+
+ //--------------------------------------------------------------
+ // Shambler's right hook
+ //--------------------------------------------------------------
+ nonvirtual void() swingr1 = [$swingr1, swingr2]
+ {
+ sound_attack (this, CHAN_VOICE, "shambler/melee1.wav",
+ 1, ATTN_NORM);
+ ai_charge (1);
+ };
+ nonvirtual void() swingr2 = [$swingr2, swingr3] { ai_charge (8); };
+ nonvirtual void() swingr3 = [$swingr3, swingr4] { ai_charge (14); };
+ nonvirtual void() swingr4 = [$swingr4, swingr5] { ai_charge (7); };
+ nonvirtual void() swingr5 = [$swingr5, swingr6] { ai_charge (3); };
+ nonvirtual void() swingr6 = [$swingr6, swingr7] { ai_charge (6); };
+ nonvirtual void() swingr7 = [$swingr7, swingr8]
+ {
+ ai_charge (6);
+ this.attack_claw (-250);
+ };
+ nonvirtual void() swingr8 = [$swingr8, swingr9] { ai_charge (3); };
+ nonvirtual void() swingr9 = [$swingr9, run1]
+ {
+ ai_charge (1);
+ ai_charge (10);
+ if (random()<0.5)
+ this.think = this.swingl1;
+ };
+
+ //--------------------------------------------------------------
+ // ~Shambler Magic~
+ //--------------------------------------------------------------
+ nonvirtual void() magic1 = [$magic1, magic2]
+ {
+ ai_face ();
+ sound_misc1 (this, CHAN_WEAPON, "shambler/sattck1.wav",
+ 1, ATTN_NORM);
+ };
+ nonvirtual void() magic2 = [$magic2, magic3] { ai_face (); };
+ nonvirtual void() magic3 = [$magic3, magic4]
+ {
+ ai_face ();
+ this.nextthink = time + 0.2;
+ local entity o;
+
+ this.effects = this.effects | EF_MUZZLEFLASH;
+ ai_face ();
+ this.trigger_field = spawn ();
+ o = this.trigger_field;
+ setmodel (o, "progs/s_light.mdl");
+ setorigin (o, this.origin);
+ o.owner = this;
+ o.angles = this.angles;
+ o.nextthink = time + 0.7;
+ o.think = sham_arc_think;
+ };
+ nonvirtual void() magic4 = [$magic4, magic5]
+ {
+ this.effects = this.effects | EF_MUZZLEFLASH;
+ this.trigger_field.frame = 1;
+ };
+ nonvirtual void() magic5 = [$magic5, magic6]
+ {
+ this.effects = this.effects | EF_MUZZLEFLASH;
+ this.trigger_field.frame = 2;
+ };
+ nonvirtual void() magic6 = [$magic6, magic9]
+ {
+ remove (this.trigger_field);
+ this.trigger_field = world;
+ this.attack_lightning ();
+ sound_misc2 (this, CHAN_WEAPON, "shambler/sboom.wav",
+ 1, ATTN_NORM);
+ };
+ nonvirtual void() magic9 = [$magic9, magic10]
+ {
+ this.attack_lightning ();
+ };
+ nonvirtual void() magic10 = [$magic10, magic11]
+ {
+ this.attack_lightning ();
+ };
+ nonvirtual void() magic11 = [$magic11, magic12]
+ {
+ if (skill == 3)
+ this.attack_lightning ();
+ };
+ nonvirtual void() magic12 = [$magic12, run1] { };
+
+ /////////////////////////
+ //// turret start ////
+ /////////////////////////
+
+ //--------------------------------------------------------------
+ // ~Shambler Turret Magic~
+ //--------------------------------------------------------------
+ nonvirtual void() turret_magic1 = [$magic1, turret_magic2]
+ {
+ ai_face ();
+ sound_misc1 (this, CHAN_WEAPON, "shambler/sattck1.wav",
+ 1, ATTN_NORM);
+ };
+ nonvirtual void() turret_magic2 = [$magic2, turret_magic3] {ai_face();};
+ nonvirtual void() turret_magic3 = [$magic3, turret_magic4]
+ {
+ ai_face ();
+ this.nextthink = time + 0.2;
+ local entity o;
+
+ this.effects = this.effects | EF_MUZZLEFLASH;
+ ai_face ();
+ this.trigger_field = spawn ();
+ o = this.trigger_field;
+ setmodel (o, "progs/s_light.mdl");
+ setorigin (o, this.origin);
+ o.owner = this;
+ o.angles = this.angles;
+ o.nextthink = time + 0.7;
+ o.think = sham_arc_think;
+ };
+ nonvirtual void() turret_magic4 = [$magic4, turret_magic5]
+ {
+ this.effects = this.effects | EF_MUZZLEFLASH;
+ this.trigger_field.frame = 1;
+ };
+ nonvirtual void() turret_magic5 = [$magic5, turret_magic6]
+ {
+ this.effects = this.effects | EF_MUZZLEFLASH;
+ this.trigger_field.frame = 2;
+ };
+ nonvirtual void() turret_magic6 = [$magic6, turret_magic9]
+ {
+ remove (this.trigger_field);
+ this.trigger_field = world;
+ this.attack_lightning ();
+ sound_misc2 (this, CHAN_WEAPON, "shambler/sboom.wav",
+ 1, ATTN_NORM);
+ };
+ nonvirtual void() turret_magic9 = [$magic9, turret_magic10]
+ {
+ this.attack_lightning ();
+ };
+ nonvirtual void() turret_magic10 = [$magic10, turret_magic11]
+ {
+ this.attack_lightning ();
+ };
+ nonvirtual void() turret_magic11 = [$magic11, turret_magic12]
+ {
+ if (skill == 3)
+ this.attack_lightning ();
+ };
+ nonvirtual void() turret_magic12 =[ $magic12, turret_magic13] { };
+ nonvirtual void() turret_magic13 =[ $stand14, turret_magic14]
+ {
+ ai_face ();
+ };
+ nonvirtual void() turret_magic14 =[ $stand15, turret_magic15]
+ {
+ ai_face ();
+ };
+ nonvirtual void() turret_magic15 =[ $stand16, turret_magic16]
+ {
+ ai_face ();
+ };
+ nonvirtual void() turret_magic16 =[ $stand17, seek_1] { };
+
+ //--------------------------------------------------------------
+ // Shambler Turret Seeking state (tracking target?)
+ //--------------------------------------------------------------
+ nonvirtual void() seek_1 = [$stand1, seek_2] { ai_run (0); };
+ nonvirtual void() seek_2 = [$stand2, seek_3] { ai_run (0); };
+ nonvirtual void() seek_3 = [$stand3, seek_4] { ai_run (0); };
+ nonvirtual void() seek_4 = [$stand4, seek_5] { ai_run (0); };
+ nonvirtual void() seek_5 = [$stand5, seek_6] { ai_run (0); };
+ nonvirtual void() seek_6 = [$stand6, seek_7] { ai_run (0); };
+ nonvirtual void() seek_7 = [$stand7, seek_8] { ai_run (0); };
+ nonvirtual void() seek_8 = [$stand8, seek_9] { ai_run (0); };
+ nonvirtual void() seek_9 = [$stand9, seek_10] { ai_run (0); };
+ nonvirtual void() seek_10 = [$stand10, seek_11] { ai_run (0); };
+ nonvirtual void() seek_11 = [$stand11, seek_12] { ai_run (0); };
+ nonvirtual void() seek_12 = [$stand12, seek_13] { ai_run (0); };
+ nonvirtual void() seek_13 = [$stand13, seek_14] { ai_run (0); };
+ nonvirtual void() seek_14 = [$stand14, seek_15] { ai_run (0); };
+ nonvirtual void() seek_15 = [$stand15, seek_16] { ai_run (0); };
+ nonvirtual void() seek_16 = [$stand16, seek_17] { ai_run (0); };
+ nonvirtual void() seek_17 = [$stand17, seek_1] { ai_run(0); };
+
+ /////////////////////////
+ //// turret end ////
+ /////////////////////////
+
+ //--------------------------------------------------------------
+ // Shambler Pain state
+ //--------------------------------------------------------------
+ nonvirtual void() pain1 = [$pain1, pain2] { };
+ nonvirtual void() pain2 = [$pain2, pain3] { };
+ nonvirtual void() pain3 = [$pain3, pain4] { };
+ nonvirtual void() pain4 = [$pain4, pain5] { };
+ nonvirtual void() pain5 = [$pain5, pain6] { };
+ nonvirtual void() pain6 = [$pain6, run1] { };
+
+ //--------------------------------------------------------------
+ // Shambler Death state
+ //--------------------------------------------------------------
+ nonvirtual void() death1 = [$death1, death2] { };
+ nonvirtual void() death2 = [$death2, death3] { };
+ nonvirtual void() death3 = [$death3, death4]
+ {
+ this.solid = SOLID_NOT;
+ };
+ nonvirtual void() death4 = [$death4, death5] { };
+ nonvirtual void() death5 = [$death5, death6] { };
+ nonvirtual void() death6 = [$death6, death7] { };
+ nonvirtual void() death7 = [$death7, death8] { };
+ nonvirtual void() death8 = [$death8, death9] { };
+ nonvirtual void() death9 = [$death9, death10] { };
+ nonvirtual void() death10 = [$death10, death11] { };
+ nonvirtual void() death11 = [$death11, death11] { };
+
+ //==============================================================
+ // Interaction
+ //==============================================================
+
+ //--------------------------------------------------------------
+ // sham_pain
+ //--------------------------------------------------------------
+ virtual void(entity attacker, float damage) do_damage =
+ {
+ sound_pain (this, CHAN_VOICE, "shambler/shurt2.wav",
+ 1, ATTN_NORM);
-mdl_head(string) : "Path to custom head model"
-mdl_body(string) : "Path to custom body model"
-skin_head(float) : "Skin index of custom head model"
-mdl_gib1(string) : "Path to custom 1st gib model"
-mdl_gib2(string) : "Path to custom 2nd gib model"
-mdl_gib3(string) : "Path to custom 3rd gib model"
+ if (this.spawnflags & I_AM_TURRET)
+ return;
-effects(choices) : "Add a visual effect to an entity"
-0 : "None (Default)"
-1 : "Brightfield (yellow particles)"
-4 : "Bright light"
-8 : "Dim light"
+ if (this.health <= 0)
+ // allready dying, don't go into pain frame
+ return;
-berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
-0 : "Off (Default)"
-1 : "Berserk (skip pain animations)"
+ if (random() * 400 > damage)
+ // didn't flinch
+ return;
-delay(float) : "Delay spawn in for this amount of time"
+ if (this.pain_finished > time)
+ return;
+ this.pain_finished = time + 2;
-wait(choices) : "Play an effect when trigger spawned?"
-0 : "Teleport Effects (Default)"
-1 : "Spawn Silently"
+ if (this.trigger_field != world &&
+ this.trigger_field.owner == this)
+ {
+ this.trigger_field.frame = 2;
+ }
+ this.trigger_field = world;
-spawn_angry(Choices)
-0 : "Only when trigger spawned, default behavior - not angry"
-1 : "Only when trigger spawned, set to 1 to spawn angry at player"
+ this.pain1 ();
+ };
-infight_mode(Choices)
-0 : "Default behavior, only with different classnames"
-1 : "Infight with monsters with the same classname but a different mdl_body"
-2 : "Infight with monsters with the same classname and model but a different skin"
-3 : "Infight no matter what"
+ //--------------------------------------------------------------
+ // sham_die
+ //--------------------------------------------------------------
+ virtual void() do_destroy =
+ {
+ // check for gib
+ if (this.health < -60)
+ {
+ sound (this, CHAN_VOICE, "player/udeath.wav",
+ 1, ATTN_NORM);
+ // dumptruck_ds custom_mdls
+ if (this.mdl_head != "")
+ {
+ ThrowHead (this.mdl_head, this.health);
+ }
+ else
+ {
+ ThrowHead ("progs/h_shams.mdl", this.health);
+ }
+ // ThrowGib ("progs/gib1.mdl", this.health);
+ // ThrowGib ("progs/gib2.mdl", this.health);
+ // ThrowGib ("progs/gib3.mdl", this.health);
+ // custom models -- dumptruck_ds
+ if (this.mdl_gib1 != "")
+ {
+ ThrowGib (this.mdl_gib1, this.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib1.mdl", this.health);
+ }
+ if (this.mdl_gib2 != "")
+ {
+ ThrowGib (this.mdl_gib2, this.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib2.mdl", this.health);
+ }
+ if (this.mdl_gib3 != "")
+ {
+ ThrowGib (this.mdl_gib3, this.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib3.mdl", this.health);
+ }
+ base_item::drop_stuff (this);
+ return;
+ }
-health(integer) : "Set this to a custom health amount"
-pain_target(string) : "Fire this target when pain_threshold is reached"
-pain_threshold(integer) : "Fire pain_target when health drops below this amount"
-sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
-skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
-obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
-obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
-damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
+ // regular death
+ sound_death (this, CHAN_VOICE, "shambler/sdeath.wav",
+ 1, ATTN_NORM);
+ base_item::drop_stuff (this);
+ this.death1 ();
+ };
-*/
-void() monster_shambler =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
+ //==============================================================
+ // Initialization
+ //==============================================================
- if (deathmatch)
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
{
- remove(self);
- return;
- }
- precache_body_model ("progs/shambler.mdl"); // custom_mdls dumptruck_ds
- precache_head_model ("progs/h_shams.mdl"); // custom_mdls dumptruck_ds
- // precache_model ("progs/shambler.mdl");
- precache_model ("progs/s_light.mdl");
- // precache_model ("progs/h_shams.mdl");
- precache_model ("progs/bolt.mdl");
- precache_proj_model ("progs/lavaball.mdl");
-
- precache_sound_misc1 ("shambler/sattck1.wav");
- precache_sound_misc2 ("shambler/sboom.wav");
- precache_sound_death ("shambler/sdeath.wav");
- precache_sound_pain ("shambler/shurt2.wav");
- precache_sound_idle ("shambler/sidle.wav");
- precache_sound_sight ("shambler/ssight.wav");
- precache_sound_attack ("shambler/melee1.wav");
- precache_sound_misc ("shambler/melee2.wav");
- precache_sound_hit ("shambler/smack.wav");
- precache_sound ("boss1/throw.wav"); // jaycie erysdren 2021-09-14
-
- precache_gib1 ("progs/gib1.mdl");
- precache_gib2 ("progs/gib2.mdl");
- precache_gib3 ("progs/gib3.mdl");
-
- self.solid = SOLID_SLIDEBOX;
- self.movetype = MOVETYPE_STEP;
- body_model ("progs/shambler.mdl");
- // setmodel (self, "progs/shambler.mdl");
-
- setsize (self, VEC_HULL2_MIN, VEC_HULL2_MAX);
-
- if (!self.health) //thanks RennyC -- dumptruck_ds
- self.health = 600;
- if (self.proj_speed_mod <= 0)
- {
- self.proj_speed_mod = 1;
- }
+ if (deathmatch)
+ {
+ remove (this);
+ return;
+ }
- self.th_stand = sham_stand1;
- self.th_walk = sham_walk1;
- if (self.spawnflags & I_AM_TURRET)
- {
- self.th_run = sham_seek_1;
- }
- else
- {
- self.th_run = sham_run1;
- }
- self.th_die = sham_die;
- if (self.style == 1)
- self.th_melee = sham_melee2;
- else
- self.th_melee = sham_melee;
- if (self.style == 1)
- self.th_missile = sham_proj1;
- else
- self.th_missile = sham_magic1;
- if (self.style == 1)
- self.th_turret = sham_turret_proj1;
- else
- self.th_turret = sham_turret_magic1;
- if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
- self.th_pain = sham_pain;
- else
- self.th_pain = sub_nullpain;
+ // custom_mdls dumptruck_ds
+ precache_body_model ("progs/shambler.mdl");
+ // custom_mdls dumptruck_ds
+ precache_head_model ("progs/h_shams.mdl");
+ // precache_model ("progs/shambler.mdl");
+ precache_model ("progs/s_light.mdl");
+ // precache_model ("progs/h_shams.mdl");
+ precache_model ("progs/bolt.mdl");
+ precache_proj_model ("progs/lavaball.mdl");
+
+ precache_sound_misc1 ("shambler/sattck1.wav");
+ precache_sound_misc2 ("shambler/sboom.wav");
+ precache_sound_death ("shambler/sdeath.wav");
+ precache_sound_pain ("shambler/shurt2.wav");
+ precache_sound_idle ("shambler/sidle.wav");
+ precache_sound_sight ("shambler/ssight.wav");
+ precache_sound_attack ("shambler/melee1.wav");
+ precache_sound_misc ("shambler/melee2.wav");
+ precache_sound_hit ("shambler/smack.wav");
+ // jaycie erysdren 2021-09-14
+ precache_sound ("boss1/throw.wav");
+
+ precache_gib1 ("progs/gib1.mdl");
+ precache_gib2 ("progs/gib2.mdl");
+ precache_gib3 ("progs/gib3.mdl");
+
+ this.solid = SOLID_SLIDEBOX;
+ this.movetype = MOVETYPE_STEP;
+ body_model ("progs/shambler.mdl");
+ // setmodel (this, "progs/shambler.mdl");
+
+ setsize (this, VEC_HULL2_MIN, VEC_HULL2_MAX);
+
+ if (!this.health)
+ // thanks RennyC -- dumptruck_ds
+ this.health = 600;
+
+ if (this.proj_speed_mod <= 0)
+ this.proj_speed_mod = 1;
+
+ this.think_stand = this.stand1;
+ this.think_walk = this.walk1;
+ if (this.spawnflags & I_AM_TURRET)
+ this.think_run = this.seek_1;
+ else
+ this.think_run = this.run1;
+ this.th_die = this.do_destroy;
+ if (this.style == 1)
+ this.think_melee = this.attack_melee2;
+ else
+ this.think_melee = this.attack_melee;
+ if (this.style == 1)
+ this.think_missile = this.proj1;
+ else
+ this.think_missile = this.magic1;
+ if (this.style == 1)
+ this.think_turret = this.turret_proj1;
+ else
+ this.think_turret = this.turret_magic1;
+ // Berserk test from
+ // http://celephais.net/board/view_thread.php?id=4&start=3465
+ // -- dumptruck_ds
+ if !(this.berserk)
+ this.th_pain = this.do_damage;
+ else
+ this.th_pain = sub_nullpain;
+
+ // walkmonster_start
+ super::init_spawned ();
+ };
- walkmonster_start();
+ //--------------------------------------------------------------
+ void() monster_shambler =
+ {
+ this.classtype = CT_MONSTER_SHAMBLER;
+ };
};
+
/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
/*QUAKED monster_dead_shambler (0 0.5 0.8) (-32 -32 -24) (32 32 64) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
Return to the top of this page or return to the overview of this repo.
Diff qc/monsters/soldier.qc
diff --git a/qc/monsters/soldier.qc b/qc/monsters/soldier.qc
index 4d17c84..7d6188a 100644
--- a/qc/monsters/soldier.qc
+++ b/qc/monsters/soldier.qc
@@ -1,11 +1,10 @@
-/*
-==============================================================================
-
-SOLDIER / PLAYER
-
-==============================================================================
-*/
+//==============================================================================
+// SOLDIER / PLAYER
+//==============================================================================
+//======================================================================
+// frame macros
+//======================================================================
$cd id1/models/soldier3
$origin 0 -6 24
$base base
@@ -37,639 +36,823 @@ $frame prowl_1 prowl_2 prowl_3 prowl_4 prowl_5 prowl_6 prowl_7 prowl_8
$frame prowl_9 prowl_10 prowl_11 prowl_12 prowl_13 prowl_14 prowl_15 prowl_16
$frame prowl_17 prowl_18 prowl_19 prowl_20 prowl_21 prowl_22 prowl_23 prowl_24
-/*
-==============================================================================
-SOLDIER CODE
-==============================================================================
-*/
-void() genforcer_fire =
-{
- local vector org;
-
- // self.effects = self.effects | EF_MUZZLEFLASH; //redundant -- dumptruck_ds
- makevectors (self.angles);
-
- org = self.origin + v_forward * 30 + v_right * 5 + '0 0 12';
-
- LaunchLaser(org, self.enemy.origin - self.origin);
-};
-/*
-================
-GruntFireGrenade
-================
-*/
-void() GruntFireGrenade =
+/*QUAKED monster_army (1 0 0) (-16 -16 -24) (16 16 40) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
{
- local entity missile;
+ model ("progs/soldier.mdl");
+}
+Grunt.
- // self.effects = self.effects | EF_MUZZLEFLASH; //redundant -- dumptruck_ds
+Default health = 30"
- sound_attack (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
+keep_ammo "1 = Don't drop backpack upon death"
+snd_death "Path to custom death sound"
+snd_pain "Path to custom pain sound"
+snd_sight "Path to custom sight sound"
+snd_attack "Path to custom attack sound (GUNSHOT)"
+snd_idle "Path to custom idle sound"
+snd_misc "Path to custom sound (PAIN 2)"
- missile = spawn ();
- missile.owner = self;
- missile.movetype = MOVETYPE_BOUNCE;
- missile.solid = SOLID_BBOX;
+mdl_head(string) : "Path to custom head model"
+mdl_body(string) : "Path to custom body model"
+skin_head(float) : "Skin index of custom head model"
+mdl_gib1(string) : "Path to custom 1st gib model"
+mdl_gib2(string) : "Path to custom 2nd gib model"
+mdl_gib3(string) : "Path to custom 3rd gib model"
-// set missile speed
+style "Attack type"
+0 "Default (shotgun)"
+1 "Rockets"
+2 "Grenades"
+3 "lasers"
+4 "Nails"
- makevectors (self.angles);
+effects(choices) : "Add a visual effect to an entity"
+0 : "None (Default)"
+1 : "Brightfield (yellow particles)"
+4 : "Bright light"
+8 : "Dim light"
- missile.velocity = normalize(self.enemy.origin - self.origin);
- missile.velocity = missile.velocity * 600;
- missile.velocity_z = 200;
+berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
+0 : "Off (Default)"
+1 : "Berserk (skip pain animations)"
- missile.avelocity = '300 300 300';
+delay(float) : "Delay spawn in for this amount of time"
- missile.angles = vectoangles(missile.velocity);
+wait(choices) : "Play an effect when trigger spawned?"
+0 : "Teleport Effects (Default)"
+1 : "Spawn Silently"
- missile.touch = OgreGrenadeTouch;
+spawn_angry(Choices)
+0 : "Only when trigger spawned, default behavior - not angry"
+1 : "Only when trigger spawned, set to 1 to spawn angry at player"
-// set missile duration
- missile.nextthink = time + 2.5;
- missile.think = OgreGrenadeExplode;
+infight_mode(Choices)
+0 : "Default behavior, only with different classnames"
+1 : "Infight with monsters with the same classname but a different mdl_body"
+2 : "Infight with monsters with the same classname and model but a different skin"
+3 : "Infight no matter what"
- // setmodel (missile, "progs/grenade.mdl");
- if (self.mdl_proj != "") // dumptruck_ds
+health(integer) : "Set this to a custom health amount"
+pain_target(string) : "Fire this target when pain_threshold is reached"
+pain_threshold(integer) : "Fire pain_target when health drops below this amount"
+sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
+skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
+obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
+obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
+damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
+*/
+class monster_army: base_walkmonster
+{
+ float attack_elevation;
+
+ //--------------------------------------------------------------
+ // SoldierCheckAttack
+ // The player is in view, so decide to move or launch an attack
+ // Returns FALSE if movement should continue
+ //--------------------------------------------------------------
+ virtual float() ai_checkattack =
{
- setmodel (missile, self.mdl_proj);
- }
- else
- {
- setmodel (missile, "progs/grenade.mdl");
- }
+ local vector spot1, spot2;
+ local entity targ;
+ local float chance;
- if (!missile.skin_proj) // dumptruck_ds
- {
- missile.skin = self.skin_proj;
- }
- else
+ // dprint ("SoldierAttack\n");
+ // dumptruck_ds
+ if (this.spawnflags & I_AM_TURRET)
{
- missile.skin = 0;
- }
+ // this.th_turret ();
+ this.attack_state = AS_MISSILE;
+ sub_attackfinished (1 + random());
+ if (random() < 0.3)
+ this.lefty = !this.lefty;
+ return TRUE;
+ }
- setsize (missile, '0 0 0', '0 0 0');
- setorigin (missile, self.origin + v_forward * 30 + v_right * 5 + '0 0 16'); //dumptruck_ds
-};
+ targ = this.enemy;
-/*
-================
-MonFireSpike // used for Grunts
-================
-*/
+ // see if any entities are in the way of the shot
+ spot1 = this.origin + this.view_ofs;
+ spot2 = targ.origin + targ.view_ofs;
-void() MonFireSpike =
-{
- local vector dir;
- // local entity old;
+ traceline (spot1, spot2, FALSE, this);
- sound_attack (self, CHAN_WEAPON, "weapons/rocket1i.wav", 1, ATTN_NORM);
- if (self.style == 5)
- self.attack_finished = time + 1.5;
- else
- self.attack_finished = time + 0.2;
+ if (trace_inopen && trace_inwater)
+ // sight line crossed contents
+ return FALSE;
- dir = normalize (self.enemy.origin - self.origin);
- makevectors (self.angles); //thanks Voidforce -- dumptruck_ds
-
- launch_spike (self.origin + v_forward * 30 + v_right * 5 + '0 0 12', dir); //dumptruck_ds
- // launch_spike (self.origin + '0 0 16', dir);
-
- //newmis.touch = superspike_touch;
- // setmodel (newmis, "progs/s_spike.mdl");
- if (self.mdl_proj != "") // dumptruck_ds
+ if ((this.spawnflags & I_AM_TURRET) && (trace_ent != targ))
{
- setmodel (newmis, self.mdl_proj);
- }
- else
- {
- setmodel (newmis, "progs/s_spike.mdl");
+ // dprint("trace_ent...\n");
+ this.attack_state = AS_TURRET;
+ return FALSE;
}
- if (!newmis.skin_proj) // dumptruck_ds
- {
- newmis.skin = self.skin_proj;
- }
- else
- {
- newmis.skin = 0;
- }
- // dumptruck_ds - end
+ if (trace_ent != targ)
+ // don't have a clear shot
+ return FALSE;
- setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
-};
+ // missile attack
+ if (time < this.attack_finished)
+ return FALSE;
-void() army_fire;
-
-void() army_stand1 =[ $stand1, army_stand2 ] {ai_stand();};
-void() army_stand2 =[ $stand2, army_stand3 ] {ai_stand();};
-void() army_stand3 =[ $stand3, army_stand4 ] {ai_stand();};
-void() army_stand4 =[ $stand4, army_stand5 ] {ai_stand();};
-void() army_stand5 =[ $stand5, army_stand6 ] {ai_stand();};
-void() army_stand6 =[ $stand6, army_stand7 ] {ai_stand();};
-void() army_stand7 =[ $stand7, army_stand8 ] {ai_stand();};
-void() army_stand8 =[ $stand8, army_stand1 ] {ai_stand();};
-
-void() army_walk1 =[ $prowl_1, army_walk2 ] {
-if (random() < 0.2)
- sound_idle (self, CHAN_VOICE, "soldier/idle.wav", 1, ATTN_IDLE);
-ai_walk(1);};
-void() army_walk2 =[ $prowl_2, army_walk3 ] {ai_walk(1);};
-void() army_walk3 =[ $prowl_3, army_walk4 ] {ai_walk(1);};
-void() army_walk4 =[ $prowl_4, army_walk5 ] {ai_walk(1);};
-void() army_walk5 =[ $prowl_5, army_walk6 ] {ai_walk(2);};
-void() army_walk6 =[ $prowl_6, army_walk7 ] {ai_walk(3);};
-void() army_walk7 =[ $prowl_7, army_walk8 ] {ai_walk(4);};
-void() army_walk8 =[ $prowl_8, army_walk9 ] {ai_walk(4);};
-void() army_walk9 =[ $prowl_9, army_walk10 ] {ai_walk(2);};
-void() army_walk10 =[ $prowl_10, army_walk11 ] {ai_walk(2);};
-void() army_walk11 =[ $prowl_11, army_walk12 ] {ai_walk(2);};
-void() army_walk12 =[ $prowl_12, army_walk13 ] {ai_walk(1);};
-void() army_walk13 =[ $prowl_13, army_walk14 ] {ai_walk(0);};
-void() army_walk14 =[ $prowl_14, army_walk15 ] {ai_walk(1);};
-void() army_walk15 =[ $prowl_15, army_walk16 ] {ai_walk(1);};
-void() army_walk16 =[ $prowl_16, army_walk17 ] {ai_walk(1);};
-void() army_walk17 =[ $prowl_17, army_walk18 ] {ai_walk(3);};
-void() army_walk18 =[ $prowl_18, army_walk19 ] {ai_walk(3);};
-void() army_walk19 =[ $prowl_19, army_walk20 ] {ai_walk(3);};
-void() army_walk20 =[ $prowl_20, army_walk21 ] {ai_walk(3);};
-void() army_walk21 =[ $prowl_21, army_walk22 ] {ai_walk(2);};
-void() army_walk22 =[ $prowl_22, army_walk23 ] {ai_walk(1);};
-void() army_walk23 =[ $prowl_23, army_walk24 ] {ai_walk(1);};
-void() army_walk24 =[ $prowl_24, army_walk1 ] {ai_walk(1);};
-
-void() army_run1 =[ $run1, army_run2 ] {
-if (random() < 0.2)
- sound_idle (self, CHAN_VOICE, "soldier/idle.wav", 1, ATTN_IDLE);
-ai_run(11);};
-void() army_run2 =[ $run2, army_run3 ] {ai_run(15);};
-void() army_run3 =[ $run3, army_run4 ] {ai_run(10);};
-void() army_run4 =[ $run4, army_run5 ] {ai_run(10);};
-void() army_run5 =[ $run5, army_run6 ] {ai_run(8);};
-void() army_run6 =[ $run6, army_run7 ] {ai_run(15);};
-void() army_run7 =[ $run7, army_run8 ] {ai_run(10);};
-void() army_run8 =[ $run8, army_run1 ] {ai_run(8);};
-
-
-void() army_atk6;
-void() army_atk1 =[ $shoot1, army_atk2 ] {ai_face();self.count = 0;self.t_length= 4 + floor(random()*4);};
-void() army_atk2 =[ $shoot2, army_atk3 ] {ai_face();};
-void() army_atk3 =[ $shoot3, army_atk4 ] {ai_face();};
-void() army_atk4 =[ $shoot4, army_atk5 ] {ai_face();};
-void() army_atk5 ={
-self.frame = $shoot5;
-self.nextthink = time + .1;
-if (self.style == 5 && self.count < self.t_length)
-{
- self.count +=1;
-}
-else
-{
- self.think = army_atk6;
-}
-ai_face();
-army_fire();
-self.effects = self.effects | EF_MUZZLEFLASH;};
-void() army_atk6 =[ $shoot6, army_atk7 ] {ai_face();};
-void() army_atk7 =[ $shoot7, army_atk8 ] {ai_face();SUB_CheckRefire (army_atk1);};
-void() army_atk8 =[ $shoot8, army_atk9 ] {ai_face();};
-void() army_atk9 =[ $shoot9, army_run1 ] {ai_face();};
-// new frames for turrets
-void() army_turret_atk6;
-void() army_turret_atk1 =[ $shoot1, army_turret_atk2 ] {ai_face();self.count = 0;self.t_length= 4 + floor(random()*4);};
-void() army_turret_atk2 =[ $shoot2, army_turret_atk3 ] {ai_face();self.attack_elevation = IterateElevation(OGRE_DEFAULT_ELEVATION, self.enemy.origin);};
-void() army_turret_atk3 =[ $shoot3, army_turret_atk4 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
-void() army_turret_atk4 =[ $shoot4, army_turret_atk5 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
-void() army_turret_atk5 ={
-self.frame = $shoot5;
-self.nextthink = time + .1;
-if (self.style == 5 && self.count < self.t_length)
-{
- self.count +=1;
-}
-else
-{
- self.think = army_turret_atk6;
-}
-ai_face();
-army_fire();
-self.effects = self.effects | EF_MUZZLEFLASH;};
-void() army_turret_atk6 =[ $shoot6, army_turret_atk7 ] {ai_face();};
-void() army_turret_atk7 =[ $shoot7, army_turret_atk8 ] {ai_face();SUB_CheckRefire (army_turret_atk1);};
-void() army_turret_atk8 =[ $shoot8, army_turret_atk9 ] {ai_face();};
-void() army_turret_atk9 =[ $stand4, army_turret_atk10 ] {ai_face();};
-void() army_turret_atk10 =[ $stand5, army_seeking_stand1 ] {ai_face();};
-void() army_seeking_stand1 =[ $stand1, army_seeking_stand2 ] {ai_run(0);};
-void() army_seeking_stand2 =[ $stand2, army_seeking_stand3 ] {ai_run(0);};
-void() army_seeking_stand3 =[ $stand3, army_seeking_stand4 ] {ai_run(0);};
-void() army_seeking_stand4 =[ $stand4, army_seeking_stand5 ] {ai_run(0);};
-void() army_seeking_stand5 =[ $stand5, army_seeking_stand6 ] {ai_run(0);};
-void() army_seeking_stand6 =[ $stand6, army_seeking_stand7 ] {ai_run(0);};
-void() army_seeking_stand7 =[ $stand7, army_seeking_stand8 ] {ai_run(0);};
-void() army_seeking_stand8 =[ $stand8, army_seeking_stand1 ] {ai_run(0);};
-// new frames for turrets end
-
-void() army_pain1 =[ $pain1, army_pain2 ] {};
-void() army_pain2 =[ $pain2, army_pain3 ] {};
-void() army_pain3 =[ $pain3, army_pain4 ] {};
-void() army_pain4 =[ $pain4, army_pain5 ] {};
-void() army_pain5 =[ $pain5, army_pain6 ] {};
-void() army_pain6 =[ $pain6, army_run1 ] {ai_pain(1);};
-
-void() army_painb1 =[ $painb1, army_painb2 ] {};
-void() army_painb2 =[ $painb2, army_painb3 ] {ai_painforward(13);};
-void() army_painb3 =[ $painb3, army_painb4 ] {ai_painforward(9);};
-void() army_painb4 =[ $painb4, army_painb5 ] {};
-void() army_painb5 =[ $painb5, army_painb6 ] {};
-void() army_painb6 =[ $painb6, army_painb7 ] {};
-void() army_painb7 =[ $painb7, army_painb8 ] {};
-void() army_painb8 =[ $painb8, army_painb9 ] {};
-void() army_painb9 =[ $painb9, army_painb10] {};
-void() army_painb10=[ $painb10, army_painb11] {};
-void() army_painb11=[ $painb11, army_painb12] {};
-void() army_painb12=[ $painb12, army_painb13] {ai_pain(2);};
-void() army_painb13=[ $painb13, army_painb14] {};
-void() army_painb14=[ $painb14, army_run1 ] {};
-
-void() army_painc1 =[ $painc1, army_painc2 ] {};
-void() army_painc2 =[ $painc2, army_painc3 ] {ai_pain(1);};
-void() army_painc3 =[ $painc3, army_painc4 ] {};
-void() army_painc4 =[ $painc4, army_painc5 ] {};
-void() army_painc5 =[ $painc5, army_painc6 ] {ai_painforward(1);};
-void() army_painc6 =[ $painc6, army_painc7 ] {ai_painforward(1);};
-void() army_painc7 =[ $painc7, army_painc8 ] {};
-void() army_painc8 =[ $painc8, army_painc9 ] {ai_pain(1);};
-void() army_painc9 =[ $painc9, army_painc10] {ai_painforward(4);};
-void() army_painc10=[ $painc10, army_painc11] {ai_painforward(3);};
-void() army_painc11=[ $painc11, army_painc12] {ai_painforward(6);};
-void() army_painc12=[ $painc12, army_painc13] {ai_painforward(8);};
-void() army_painc13=[ $painc13, army_run1] {};
-
-void(entity attacker, float damage) army_pain =
-{
- local float r;
+ if (enemy_range == RANGE_FAR)
+ return FALSE;
- if (self.pain_finished > time)
- return;
+ if (enemy_range == RANGE_MELEE)
+ chance = 0.9;
+ else if (enemy_range == RANGE_NEAR)
+ chance = 0.4;
+ else if (enemy_range == RANGE_MID)
+ chance = 0.05;
+ else
+ chance = 0;
- r = random();
+ if (random() < chance)
+ {
+ this.think_missile ();
+ sub_attackfinished (1 + random());
+ if (random() < 0.3)
+ this.lefty = !this.lefty;
- if (r < 0.2)
- { // turret checks moved here to play pain sounds correctly - dumptruck_ds
- self.pain_finished = time + 0.6;
- sound_pain (self, CHAN_VOICE, "soldier/pain1.wav", 1, ATTN_NORM);
- if (self.spawnflags & I_AM_TURRET)
- return;
- else
- army_pain1 ();
- }
- else if (r < 0.6)
+ return TRUE;
+ }
+
+ return FALSE;
+ };
+
+ //--------------------------------------------------------------
+ virtual void() ai_sightsound =
{
- self.pain_finished = time + 1.1;
- sound_misc (self, CHAN_VOICE, "soldier/pain2.wav", 1, ATTN_NORM);
- if (self.spawnflags & I_AM_TURRET)
- return;
- else
- army_painb1 ();
- }
- else
+ sound_sight (this, CHAN_VOICE, "soldier/sight1.wav",
+ 1, ATTN_NORM);
+ };
+
+ //--------------------------------------------------------------
+ nonvirtual void() army_fire =
{
- self.pain_finished = time + 1.1;
- sound_misc (self, CHAN_VOICE, "soldier/pain2.wav", 1, ATTN_NORM);
- if (self.spawnflags & I_AM_TURRET)
- return;
+ // TODO CEV this will need to be re-checked soon
+ /*
+ // dumptruck_ds start rocket grunt stuff
+ if (this.style == 1)
+ {
+ ai_face ();
+ W_GruntRocket ();
+ }
+ else if (this.style == 2)
+ {
+ ai_face ();
+ if (this.spawnflags & I_AM_TURRET)
+ PreachFireGrenade (this.attack_elevation);
+ else
+ GruntFireGrenade ();
+ }
+ else if (this.style == 3)
+ {
+ ai_face ();
+ genforcer_fire ();
+ }
+ else if (this.style == 4 || this.style == 5)
+ {
+ ai_face ();
+ MonFireSpike ();
+ }
else
- army_painc1 ();
- }
-};
-
-void() army_fire =
-{ //dumptruck_ds start rocket grunt stuff
-
-if (self.style == 1)
+ {
+ */
+ local vector dir;
+ local entity en;
+
+ ai_face ();
+
+ sound_attack (this, CHAN_WEAPON, "soldier/sattck1.wav",
+ 1, ATTN_NORM);
+
+ // fire somewhat behind the player, so a dodging player
+ // is harder to hit
+ en = this.enemy;
+ dir = en.origin - en.velocity * 0.2;
+ dir = normalize (dir - this.origin);
+ FireBullets (4, dir, '0.1 0.1 0');
+ /*
+ }
+ */
+ };
+ //--------------------------------------------------------------
+ virtual void(entity attacker, float damage) do_damage =
{
- ai_face();
+ if (this.pain_finished > time)
+ return;
- W_GruntRocket();
- }
+ local float r = random ();
-else if (self.style == 2)
+ if (r < 0.2)
+ {
+ // turret checks moved here to play pain sounds
+ // correctly -- dumptruck_ds
+ this.pain_finished = time + 0.6;
+ sound_pain (this, CHAN_VOICE, "soldier/pain1.wav",
+ 1, ATTN_NORM);
+ if (this.spawnflags & I_AM_TURRET)
+ return;
+ else
+ this.pain1 ();
+ }
+ else if (r < 0.6)
+ {
+ this.pain_finished = time + 1.1;
+ sound_misc (this, CHAN_VOICE, "soldier/pain2.wav",
+ 1, ATTN_NORM);
+ if (this.spawnflags & I_AM_TURRET)
+ return;
+ else
+ this.painb2 ();
+ }
+ else
+ {
+ this.pain_finished = time + 1.1;
+ sound_misc (this, CHAN_VOICE, "soldier/pain2.wav",
+ 1, ATTN_NORM);
+ if (this.spawnflags & I_AM_TURRET)
+ return;
+ else
+ this.painc1 ();
+ }
+ };
+ //--------------------------------------------------------------
+ nonvirtual void() do_destroy =
{
- ai_face();
- if (self.spawnflags & I_AM_TURRET)
+ // check for gib
+ if (this.health < -35)
+ {
+ sound (this, CHAN_VOICE, "player/udeath.wav",
+ 1, ATTN_NORM);
+ if (this.mdl_head != "")
{
- PreachFireGrenade(self.attack_elevation);
+ // dumptruck_ds custom_mdls
+ ThrowHead (this.mdl_head, this.health);
}
- else
- GruntFireGrenade();
- }
-
-else if (self.style == 3)
+ else
+ {
+ ThrowHead ("progs/h_guard.mdl", this.health);
+ }
+ // ThrowGib ("progs/gib1.mdl", this.health);
+ // ThrowGib ("progs/gib2.mdl", this.health);
+ // ThrowGib ("progs/gib3.mdl", this.health);
+ if (this.mdl_gib1 != "")
+ {
+ // custom models -- dumptruck_ds
+ ThrowGib (this.mdl_gib1, this.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib1.mdl", this.health);
+ }
+ if (this.mdl_gib2 != "")
+ {
+ ThrowGib (this.mdl_gib2, this.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib2.mdl", this.health);
+ }
+ if (this.mdl_gib3 != "")
+ {
+ ThrowGib (this.mdl_gib3, this.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib3.mdl", this.health);
+ }
+ base_item::drop_stuff (this);
+ return;
+ }
+ // regular death
+ sound_death (this, CHAN_VOICE, "soldier/death1.wav",
+ 1, ATTN_NORM);
+ base_item::drop_stuff (this);
+ if (random() < 0.5)
+ this.die1 ();
+ else
+ this.cdie1 ();
+ };
+
+ //--------------------------------------------------------------
+ // Grunt stand functions
+ //--------------------------------------------------------------
+ nonvirtual void() stand1 = [$stand1, stand2] { ai_stand (); };
+ nonvirtual void() stand2 = [$stand2, stand3] { ai_stand (); };
+ nonvirtual void() stand3 = [$stand3, stand4] { ai_stand (); };
+ nonvirtual void() stand4 = [$stand4, stand5] { ai_stand (); };
+ nonvirtual void() stand5 = [$stand5, stand6] { ai_stand (); };
+ nonvirtual void() stand6 = [$stand6, stand7] { ai_stand (); };
+ nonvirtual void() stand7 = [$stand7, stand8] { ai_stand (); };
+ nonvirtual void() stand8 = [$stand8, stand1] { ai_stand (); };
+
+ //--------------------------------------------------------------
+ // Grunt walk functions
+ //--------------------------------------------------------------
+ nonvirtual void() walk1 = [$prowl_1, walk2]
{
- ai_face();
- genforcer_fire();
- }
-
-else if (self.style == 4 || self.style == 5)
-
+ if (random() < 0.2)
+ sound_idle (this, CHAN_VOICE, "soldier/idle.wav",
+ 1, ATTN_IDLE);
+ ai_walk (1);
+ };
+ nonvirtual void() walk2 = [$prowl_2, walk3] { ai_walk (1); };
+ nonvirtual void() walk3 = [$prowl_3, walk4] { ai_walk (1); };
+ nonvirtual void() walk4 = [$prowl_4, walk5] { ai_walk (1); };
+ nonvirtual void() walk5 = [$prowl_5, walk6] { ai_walk (2); };
+ nonvirtual void() walk6 = [$prowl_6, walk7] { ai_walk (3); };
+ nonvirtual void() walk7 = [$prowl_7, walk8] { ai_walk (4); };
+ nonvirtual void() walk8 = [$prowl_8, walk9] { ai_walk (4); };
+ nonvirtual void() walk9 = [$prowl_9, walk10] { ai_walk (2); };
+ nonvirtual void() walk10 = [$prowl_10, walk11] { ai_walk (2); };
+ nonvirtual void() walk11 = [$prowl_11, walk12] { ai_walk (2); };
+ nonvirtual void() walk12 = [$prowl_12, walk13] { ai_walk (1); };
+ nonvirtual void() walk13 = [$prowl_13, walk14] { ai_walk (0); };
+ nonvirtual void() walk14 = [$prowl_14, walk15] { ai_walk (1); };
+ nonvirtual void() walk15 = [$prowl_15, walk16] { ai_walk (1); };
+ nonvirtual void() walk16 = [$prowl_16, walk17] { ai_walk (1); };
+ nonvirtual void() walk17 = [$prowl_17, walk18] { ai_walk (3); };
+ nonvirtual void() walk18 = [$prowl_18, walk19] { ai_walk (3); };
+ nonvirtual void() walk19 = [$prowl_19, walk20] { ai_walk (3); };
+ nonvirtual void() walk20 = [$prowl_20, walk21] { ai_walk (3); };
+ nonvirtual void() walk21 = [$prowl_21, walk22] { ai_walk (2); };
+ nonvirtual void() walk22 = [$prowl_22, walk23] { ai_walk (1); };
+ nonvirtual void() walk23 = [$prowl_23, walk24] { ai_walk (1); };
+ nonvirtual void() walk24 = [$prowl_24, walk1] { ai_walk (1); };
+
+ //--------------------------------------------------------------
+ // Grunt run functions
+ //--------------------------------------------------------------
+ nonvirtual void() run1 = [$run1, run2]
{
- ai_face();
- MonFireSpike();
- }
-
-else
-
+ if (random() < 0.2)
+ sound_idle (this, CHAN_VOICE, "soldier/idle.wav",
+ 1, ATTN_IDLE);
+ ai_run (11);
+ };
+ nonvirtual void() run2 = [$run2, run3] { ai_run (15); };
+ nonvirtual void() run3 = [$run3, run4] { ai_run (10); };
+ nonvirtual void() run4 = [$run4, run5] { ai_run (10); };
+ nonvirtual void() run5 = [$run5, run6] { ai_run (8); };
+ nonvirtual void() run6 = [$run6, run7] { ai_run (15); };
+ nonvirtual void() run7 = [$run7, run8] { ai_run (10); };
+ nonvirtual void() run8 = [$run8, run1] { ai_run (8); };
+
+ //--------------------------------------------------------------
+ // Grunt attack functions
+ //--------------------------------------------------------------
+ nonvirtual void() atk1 = [$shoot1, atk2]
{
- local vector dir;
- local entity en;
-
- ai_face();
-
- sound_attack (self, CHAN_WEAPON, "soldier/sattck1.wav", 1, ATTN_NORM);
-
- // fire somewhat behind the player, so a dodging player is harder to hit
- en = self.enemy;
-
- dir = en.origin - en.velocity*0.2;
- dir = normalize (dir - self.origin);
-
- FireBullets (4, dir, '0.1 0.1 0');
- }
-
-};
-
-void() army_die1 =[ $death1, army_die2 ] {};
-void() army_die2 =[ $death2, army_die3 ] {};
-void() army_die3 =[ $death3, army_die4 ]
-{self.solid = SOLID_NOT;
-// style ammotype check -- dumptruck_ds
- if (self.style == 1)
+ ai_face ();
+ this.count = 0;
+ this.t_length = 4 + floor (random() * 4);
+ };
+ nonvirtual void() atk2 = [$shoot2, atk3] { ai_face (); };
+ nonvirtual void() atk3 = [$shoot3, atk4] { ai_face (); };
+ nonvirtual void() atk4 = [$shoot4, atk5] { ai_face (); };
+ nonvirtual void() atk5 =
{
- self.ammo_rockets = 2;
- }
- if (self.style == 2)
+ this.frame = $shoot5;
+ this.nextthink = time + 0.1;
+ if (this.style == 5 && this.count < this.t_length)
+ {
+ this.count +=1;
+ }
+ else
+ {
+ this.think = this.atk6;
+ }
+ ai_face ();
+ army_fire ();
+ this.effects = this.effects | EF_MUZZLEFLASH;
+ };
+ nonvirtual void() atk6 = [$shoot6, atk7] { ai_face (); };
+ nonvirtual void() atk7 = [$shoot7, atk8]
{
- self.ammo_rockets = 2;
- }
- if (self.style == 3)
+ ai_face ();
+ sub_checkrefire (atk1);
+ };
+ nonvirtual void() atk8 = [$shoot8, atk9] { ai_face (); };
+ nonvirtual void() atk9 = [$shoot9, run1] { ai_face (); };
+
+ //--------------------------------------------------------------
+ // Grunt turrent attack functions
+ //--------------------------------------------------------------
+ nonvirtual void() turret_atk1 = [$shoot1, turret_atk2]
{
- self.ammo_cells = 5;
- }
- if (self.style == 4 || self.style == 5)
+ ai_face ();
+ this.count = 0;
+ this.t_length = 4 + floor (random() * 4);
+ };
+ nonvirtual void() turret_atk2 = [$shoot2, turret_atk3]
{
- self.ammo_nails = 5;
- }
- else if (self.style == 0)
+ ai_face ();
+ this.attack_elevation = IterateElevation (
+ OGRE_DEFAULT_ELEVATION, this.origin, this.enemy.origin);
+ };
+ nonvirtual void() turret_atk3 = [$shoot3, turret_atk4]
{
- self.ammo_shells = 5;
- }
-if(!self.keep_ammo)
- item_backpack::drop_backpack (self);
-};
-
-void() army_die4 =[ $death4, army_die5 ] {};
-void() army_die5 =[ $death5, army_die6 ] {};
-void() army_die6 =[ $death6, army_die7 ] {};
-void() army_die7 =[ $death7, army_die8 ] {};
-void() army_die8 =[ $death8, army_die9 ] {};
-void() army_die9 =[ $death9, army_die10 ] {};
-void() army_die10 =[ $death10, army_die10 ] {};
-
-void() army_cdie1 =[ $deathc1, army_cdie2 ] {};
-void() army_cdie2 =[ $deathc2, army_cdie3 ] {ai_back(5);};
-void() army_cdie3 =[ $deathc3, army_cdie4 ]
-{self.solid = SOLID_NOT;
-// style ammotype check -- dumptruck_ds
- if (self.style == 1)
- {
- self.ammo_rockets = 2;
- }
- if (self.style == 2)
+ ai_face ();
+ this.attack_elevation = IterateElevation (
+ this.attack_elevation, this.origin, this.enemy.origin);
+ };
+ nonvirtual void() turret_atk4 = [$shoot4, turret_atk5]
{
- self.ammo_rockets = 2;
- }
- if (self.style == 3)
+ ai_face ();
+ this.attack_elevation = IterateElevation (
+ this.attack_elevation, this.origin, this.enemy.origin);
+ };
+ nonvirtual void() turret_atk5 =
{
- self.ammo_cells = 5;
- }
- if (self.style == 4 || self.style == 5)
+ this.frame = $shoot5;
+ this.nextthink = time + .1;
+ if (this.style == 5 && this.count < this.t_length)
+ {
+ this.count +=1;
+ }
+ else
+ {
+ this.think = turret_atk6;
+ }
+ ai_face ();
+ army_fire ();
+ this.effects = this.effects | EF_MUZZLEFLASH;
+ };
+ nonvirtual void() turret_atk6 = [$shoot6, turret_atk7] { ai_face (); };
+ nonvirtual void() turret_atk7 = [$shoot7, turret_atk8]
{
- self.ammo_nails = 5;
- }
- else if (self.style == 0)
+ ai_face ();
+ sub_checkrefire (turret_atk1);
+ };
+ nonvirtual void() turret_atk8 = [$shoot8, turret_atk9] { ai_face (); };
+ nonvirtual void() turret_atk9 = [$stand4, turret_atk10]
{
- self.ammo_shells = 5;
- }
-if(!self.keep_ammo)
- item_backpack::drop_backpack (self);
- ai_back(4);
-}; //dumptruck_ds
-void() army_cdie4 =[ $deathc4, army_cdie5 ] {ai_back(13);};
-void() army_cdie5 =[ $deathc5, army_cdie6 ] {ai_back(3);};
-void() army_cdie6 =[ $deathc6, army_cdie7 ] {ai_back(4);};
-void() army_cdie7 =[ $deathc7, army_cdie8 ] {};
-void() army_cdie8 =[ $deathc8, army_cdie9 ] {};
-void() army_cdie9 =[ $deathc9, army_cdie10 ] {};
-void() army_cdie10 =[ $deathc10, army_cdie11 ] {};
-void() army_cdie11 =[ $deathc11, army_cdie11 ] {};
-
-
-void() army_die =
-{
-// check for gib
- if (self.health < -35)
+ ai_face ();
+ };
+ nonvirtual void() turret_atk10 = [$stand5, seek_stand1]
+ {
+ ai_face ();
+ };
+
+ //--------------------------------------------------------------
+ // Grunt turrent standing functions
+ //--------------------------------------------------------------
+ nonvirtual void() seek_stand1 = [$stand1, seek_stand2] { ai_run (0); };
+ nonvirtual void() seek_stand2 = [$stand2, seek_stand3] { ai_run (0); };
+ nonvirtual void() seek_stand3 = [$stand3, seek_stand4] { ai_run (0); };
+ nonvirtual void() seek_stand4 = [$stand4, seek_stand5] { ai_run (0); };
+ nonvirtual void() seek_stand5 = [$stand5, seek_stand6] { ai_run (0); };
+ nonvirtual void() seek_stand6 = [$stand6, seek_stand7] { ai_run (0); };
+ nonvirtual void() seek_stand7 = [$stand7, seek_stand8] { ai_run (0); };
+ nonvirtual void() seek_stand8 = [$stand8, seek_stand1] { ai_run (0); };
+
+ //--------------------------------------------------------------
+ // Grunt pain states
+ //--------------------------------------------------------------
+ nonvirtual void() pain1 = [$pain1, pain2] { };
+ nonvirtual void() pain2 = [$pain2, pain3] { };
+ nonvirtual void() pain3 = [$pain3, pain4] { };
+ nonvirtual void() pain4 = [$pain4, pain5] { };
+ nonvirtual void() pain5 = [$pain5, pain6] { };
+ nonvirtual void() pain6 = [$pain6, run1] { ai_pain (1); };
+
+ nonvirtual void() painb1 = [$painb1, painb2] { };
+ nonvirtual void() painb2 = [$painb2, painb3] { ai_painforward (13); };
+ nonvirtual void() painb3 = [$painb3, painb4] { ai_painforward (9); };
+ nonvirtual void() painb4 = [$painb4, painb5] { };
+ nonvirtual void() painb5 = [$painb5, painb6] { };
+ nonvirtual void() painb6 = [$painb6, painb7] { };
+ nonvirtual void() painb7 = [$painb7, painb8] { };
+ nonvirtual void() painb8 = [$painb8, painb9] { };
+ nonvirtual void() painb9 = [$painb9, painb10] { };
+ nonvirtual void() painb10 = [$painb10, painb11] { };
+ nonvirtual void() painb11 = [$painb11, painb12] { };
+ nonvirtual void() painb12 = [$painb12, painb13] { ai_pain(2); };
+ nonvirtual void() painb13 = [$painb13, painb14] { };
+ nonvirtual void() painb14 = [$painb14, run1] { };
+
+ nonvirtual void() painc1 = [$painc1, painc2] { };
+ nonvirtual void() painc2 = [$painc2, painc3] { ai_pain (1); };
+ nonvirtual void() painc3 = [$painc3, painc4] { };
+ nonvirtual void() painc4 = [$painc4, painc5] { };
+ nonvirtual void() painc5 = [$painc5, painc6] { ai_painforward (1); };
+ nonvirtual void() painc6 = [$painc6, painc7] { ai_painforward (1); };
+ nonvirtual void() painc7 = [$painc7, painc8] { };
+ nonvirtual void() painc8 = [$painc8, painc9] { ai_pain (1); };
+ nonvirtual void() painc9 = [$painc9, painc10] { ai_painforward (4); };
+ nonvirtual void() painc10 = [$painc10, painc11] { ai_painforward (3); };
+ nonvirtual void() painc11 = [$painc11, painc12] { ai_painforward (6); };
+ nonvirtual void() painc12 = [$painc12, painc13] { ai_painforward (8); };
+ nonvirtual void() painc13 = [$painc13, run1] { };
+
+ //--------------------------------------------------------------
+ // Grunt death states
+ //--------------------------------------------------------------
+ nonvirtual void() die1 = [$death1, die2] { };
+ nonvirtual void() die2 = [$death2, die3] { };
+ nonvirtual void() die3 = [$death3, die4]
{
- sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
- if (self.mdl_head != "") //dumptruck_ds custom_mdls
+ this.solid = SOLID_NOT;
+ // style ammotype check -- dumptruck_ds
+ if (this.style == 1)
{
- ThrowHead (self.mdl_head, self.health);
+ this.ammo_rockets = 2;
}
- else
+ if (this.style == 2)
{
- ThrowHead ("progs/h_guard.mdl", self.health);
+ this.ammo_rockets = 2;
}
- // ThrowGib ("progs/gib1.mdl", self.health);
- // ThrowGib ("progs/gib2.mdl", self.health);
- // ThrowGib ("progs/gib3.mdl", self.health);
- if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
+ if (this.style == 3)
{
- ThrowGib (self.mdl_gib1, self.health);
+ this.ammo_cells = 5;
}
- else
+ if (this.style == 4 || this.style == 5)
{
- ThrowGib ("progs/gib1.mdl", self.health);
+ this.ammo_nails = 5;
}
- if (self.mdl_gib2 != "")
+ else if (this.style == 0)
{
- ThrowGib (self.mdl_gib2, self.health);
+ this.ammo_shells = 5;
}
- else
+ if (!this.keep_ammo)
+ {
+ item_backpack::drop_backpack (this.origin,
+ this.weapon, ammo_shells, ammo_nails,
+ ammo_rockets, ammo_cells);
+ }
+ };
+ nonvirtual void() die4 = [$death4, die5] { };
+ nonvirtual void() die5 = [$death5, die6] { };
+ nonvirtual void() die6 = [$death6, die7] { };
+ nonvirtual void() die7 = [$death7, die8] { };
+ nonvirtual void() die8 = [$death8, die9] { };
+ nonvirtual void() die9 = [$death9, die10] { };
+ nonvirtual void() die10 = [$death10, die10] { };
+
+ nonvirtual void() cdie1 = [$deathc1, cdie2] { };
+ nonvirtual void() cdie2 = [$deathc2, cdie3] { ai_back (5); };
+ nonvirtual void() cdie3 = [$deathc3, cdie4]
+ {
+ this.solid = SOLID_NOT;
+ // style ammotype check -- dumptruck_ds
+ if (this.style == 1)
{
- ThrowGib ("progs/gib2.mdl", self.health);
+ this.ammo_rockets = 2;
}
- if (self.mdl_gib3 != "")
+ if (this.style == 2)
{
- ThrowGib (self.mdl_gib3, self.health);
+ this.ammo_rockets = 2;
}
- else
+ if (this.style == 3)
{
- ThrowGib ("progs/gib3.mdl", self.health);
+ this.ammo_cells = 5;
+ }
+ if (this.style == 4 || this.style == 5)
+ {
+ this.ammo_nails = 5;
+ }
+ else if (this.style == 0)
+ {
+ this.ammo_shells = 5;
+ }
+ if (!this.keep_ammo)
+ {
+ item_backpack::drop_backpack (this.origin,
+ this.weapon, ammo_shells, ammo_nails,
+ ammo_rockets, ammo_cells);
+ }
+ ai_back (4);
+ };
+ nonvirtual void() cdie4 = [$deathc4, cdie5] { ai_back (13); };
+ nonvirtual void() cdie5 = [$deathc5, cdie6] { ai_back (3); };
+ nonvirtual void() cdie6 = [$deathc6, cdie7] { ai_back (4); };
+ nonvirtual void() cdie7 = [$deathc7, cdie8] { };
+ nonvirtual void() cdie8 = [$deathc8, cdie9] { };
+ nonvirtual void() cdie9 = [$deathc9, cdie10] { };
+ nonvirtual void() cdie10 = [$deathc10, cdie11] { };
+ nonvirtual void() cdie11 = [$deathc11, cdie11] { };
+
+ //==============================================================
+ // Initialization
+ //==============================================================
+
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
+ {
+ if (deathmatch)
+ {
+ remove (this);
+ return;
}
- base_item::drop_stuff (self);
- return;
- }
-// regular death
- sound_death (self, CHAN_VOICE, "soldier/death1.wav", 1, ATTN_NORM);
- base_item::drop_stuff (self);
- if (random() < 0.5)
- army_die1 ();
- else
- army_cdie1 ();
-};
+ //dumptruck_ds custom_mdls
+ precache_body_model ("progs/soldier.mdl");
+ precache_head_model ("progs/h_guard.mdl");
+ // used if style == 1
+ precache_proj_model ("progs/missile.mdl");
+ // used if style == 2
+ precache_proj_model ("progs/grenade.mdl");
+ // used if style == 3
+ precache_model2 ("progs/laser.mdl");
+ //dumptruck_ds custom_mdls
+
+ precache_model ("progs/gib1.mdl");
+ precache_model ("progs/gib2.mdl");
+ precache_model ("progs/gib3.mdl");
+
+ precache_sound_death ("soldier/death1.wav");
+ precache_sound_idle ("soldier/idle.wav");
+ precache_sound_pain ("soldier/pain1.wav");
+ precache_sound_misc ("soldier/pain2.wav");
+ precache_sound_attack ("soldier/sattck1.wav");
+ precache_sound_sight ("soldier/sight1.wav");
+ // used if style == 3
+ precache_sound2 ("enforcer/enfire.wav");
+ // used if style == 3
+ precache_sound2 ("enforcer/enfstop.wav");
+
+ // gib death
+ precache_sound ("player/udeath.wav");
+
+ precache_gib1 ("progs/gib1.mdl");
+ precache_gib2 ("progs/gib2.mdl");
+ precache_gib3 ("progs/gib3.mdl");
+
+ this.solid = SOLID_SLIDEBOX;
+ this.movetype = MOVETYPE_STEP;
+
+ // dumptruck_ds custom_mdls
+ body_model ("progs/soldier.mdl");
+
+ setsize (this, '-16 -16 -24', '16 16 40');
+
+ if (!this.proj_speed_mod)
+ this.proj_speed_mod = 1;
+
+ if (!this.health)
+ // thanks RennyC -- dumptruck_ds
+ this.health = 30;
+
+ this.think_stand = this.stand1;
+ this.think_walk = this.walk1;
+ if (this.spawnflags & I_AM_TURRET)
+ this.think_run = this.seek_stand1;
+ else
+ this.think_run = this.run1;
+ this.think_missile = this.atk1;
+ this.think_turret = this.turret_atk1;
+
+ if !(this.berserk)
+ // Berserk test from
+ // celephais.net/board/view_thread.php?id=4&start=3465
+ // -- dumptruck_ds
+ this.th_pain = this.do_damage;
+ else
+ this.th_pain = sub_nullpain;
+ this.th_die = this.do_destroy;
-/*QUAKED monster_army (1 0 0) (-16 -16 -24) (16 16 40) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ("progs/soldier.mdl");
-}
-Grunt.
+ // walkmonster_start
+ super::init_spawned ();
+ };
-Default health = 30"
+ //--------------------------------------------------------------
+ void() monster_army =
+ {
+ this.classtype = CT_MONSTER_GRUNT;
+ };
+};
-keep_ammo "1 = Don't drop backpack upon death"
-snd_death "Path to custom death sound"
-snd_pain "Path to custom pain sound"
-snd_sight "Path to custom sight sound"
-snd_attack "Path to custom attack sound (GUNSHOT)"
-snd_idle "Path to custom idle sound"
-snd_misc "Path to custom sound (PAIN 2)"
+/*
+//----------------------------------------------------------------------
+// SOLDIER CODE
+//----------------------------------------------------------------------
+void() genforcer_fire =
+{
+ local vector org;
-mdl_head(string) : "Path to custom head model"
-mdl_body(string) : "Path to custom body model"
-skin_head(float) : "Skin index of custom head model"
-mdl_gib1(string) : "Path to custom 1st gib model"
-mdl_gib2(string) : "Path to custom 2nd gib model"
-mdl_gib3(string) : "Path to custom 3rd gib model"
+ // redundant -- dumptruck_ds
+ // self.effects = self.effects | EF_MUZZLEFLASH;
+ makevectors (self.angles);
-style "Attack type"
-0 "Default (shotgun)"
-1 "Rockets"
-2 "Grenades"
-3 "lasers"
-4 "Nails"
+ org = self.origin + v_forward * 30 + v_right * 5 + '0 0 12';
-effects(choices) : "Add a visual effect to an entity"
-0 : "None (Default)"
-1 : "Brightfield (yellow particles)"
-4 : "Bright light"
-8 : "Dim light"
+ LaunchLaser (org, self.enemy.origin - self.origin);
+};
-berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
-0 : "Off (Default)"
-1 : "Berserk (skip pain animations)"
+//----------------------------------------------------------------------
+// GruntFireGrenade
+//----------------------------------------------------------------------
+void() GruntFireGrenade =
+{
+ local entity missile;
-delay(float) : "Delay spawn in for this amount of time"
+ // redundant -- dumptruck_ds
+ // self.effects = self.effects | EF_MUZZLEFLASH;
-wait(choices) : "Play an effect when trigger spawned?"
-0 : "Teleport Effects (Default)"
-1 : "Spawn Silently"
+ sound_attack (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
-spawn_angry(Choices)
-0 : "Only when trigger spawned, default behavior - not angry"
-1 : "Only when trigger spawned, set to 1 to spawn angry at player"
+ missile = spawn ();
+ missile.owner = self;
+ missile.movetype = MOVETYPE_BOUNCE;
+ missile.solid = SOLID_BBOX;
-infight_mode(Choices)
-0 : "Default behavior, only with different classnames"
-1 : "Infight with monsters with the same classname but a different mdl_body"
-2 : "Infight with monsters with the same classname and model but a different skin"
-3 : "Infight no matter what"
+ // set missile speed
+ makevectors (self.angles);
-health(integer) : "Set this to a custom health amount"
-pain_target(string) : "Fire this target when pain_threshold is reached"
-pain_threshold(integer) : "Fire pain_target when health drops below this amount"
-sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
-skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
-obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
-obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
-damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
+ missile.velocity = normalize (self.enemy.origin - self.origin);
+ missile.velocity = missile.velocity * 600;
+ missile.velocity_z = 200;
+ missile.avelocity = '300 300 300';
+ missile.angles = vectoangles(missile.velocity);
+ missile.touch = OgreGrenadeTouch;
-*/
-void() monster_army =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
+ // set missile duration
+ missile.nextthink = time + 2.5;
+ missile.think = OgreGrenadeExplode;
+ // setmodel (missile, "progs/grenade.mdl");
- if (deathmatch)
+ // dumptruck_ds
+ if (self.mdl_proj != "")
{
- remove(self);
- return;
+ setmodel (missile, self.mdl_proj);
}
- //dumptruck_ds custom_mdls
- precache_body_model ("progs/soldier.mdl");
- precache_head_model ("progs/h_guard.mdl");
- precache_proj_model ("progs/missile.mdl"); // used if style == 1
- precache_proj_model ("progs/grenade.mdl"); // used if style == 2
- precache_model2 ("progs/laser.mdl"); // used if style == 3
- //dumptruck_ds custom_mdls
- precache_model ("progs/gib1.mdl");
- precache_model ("progs/gib2.mdl");
- precache_model ("progs/gib3.mdl");
-
- precache_sound_death ("soldier/death1.wav");
- precache_sound_idle ("soldier/idle.wav");
- precache_sound_pain ("soldier/pain1.wav");
- precache_sound_misc ("soldier/pain2.wav");
- precache_sound_attack ("soldier/sattck1.wav");
- precache_sound_sight ("soldier/sight1.wav");
- precache_sound2 ("enforcer/enfire.wav"); // used if style == 3
- precache_sound2 ("enforcer/enfstop.wav"); // used if style == 3
-
- precache_sound ("player/udeath.wav"); // gib death
-
- precache_gib1 ("progs/gib1.mdl");
- precache_gib2 ("progs/gib2.mdl");
- precache_gib3 ("progs/gib3.mdl");
-
- self.solid = SOLID_SLIDEBOX;
- self.movetype = MOVETYPE_STEP;
-
- //dumptruck_ds custom_mdls
- body_model ("progs/soldier.mdl");
-
- setsize (self, '-16 -16 -24', '16 16 40');
-
- if (!self.proj_speed_mod)
- {
- self.proj_speed_mod = 1;
+ else
+ {
+ setmodel (missile, "progs/grenade.mdl");
}
- if (!self.health) //thanks RennyC -- dumptruck_ds
- self.health = 30;
+ // dumptruck_ds
+ if (!missile.skin_proj)
+ {
+ missile.skin = self.skin_proj;
+ }
+ else
+ {
+ missile.skin = 0;
+ }
+
+ setsize (missile, '0 0 0', '0 0 0');
+ // dumptruck_ds
+ setorigin (missile, self.origin + v_forward * 30 +
+ v_right * 5 + '0 0 16');
+};
+
+//----------------------------------------------------------------------
+// MonFireSpike -- used for Grunts
+//----------------------------------------------------------------------
+void() MonFireSpike =
+{
+ local vector dir;
+ // local entity old;
+
+ sound_attack (self, CHAN_WEAPON, "weapons/rocket1i.wav", 1, ATTN_NORM);
+ if (self.style == 5)
+ self.attack_finished = time + 1.5;
+ else
+ self.attack_finished = time + 0.2;
- self.th_stand = army_stand1;
- self.th_walk = army_walk1;
- if (self.spawnflags & I_AM_TURRET)
+ dir = normalize (self.enemy.origin - self.origin);
+ // thanks Voidforce -- dumptruck_ds
+ makevectors (self.angles);
+
+ //dumptruck_ds
+ launch_spike (self.origin + v_forward * 30 +
+ v_right * 5 + '0 0 12', dir);
+ // launch_spike (self.origin + '0 0 16', dir);
+
+ // newmis.touch = superspike_touch;
+ // setmodel (newmis, "progs/s_spike.mdl");
+
+ // dumptruck_ds
+ if (self.mdl_proj != "")
{
- self.th_run = army_seeking_stand1;
+ setmodel (newmis, self.mdl_proj);
}
else
{
- self.th_run = army_run1;
+ setmodel (newmis, "progs/s_spike.mdl");
+ }
+
+ // dumptruck_ds
+ if (!newmis.skin_proj)
+ {
+ newmis.skin = self.skin_proj;
}
- self.th_missile = army_atk1;
- self.th_turret = army_turret_atk1;
- if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
- self.th_pain = army_pain;
else
- self.th_pain = sub_nullpain;
- self.th_die = army_die;
+ {
+ newmis.skin = 0;
+ }
+ // dumptruck_ds - end
- walkmonster_start ();
+ setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
};
+*/
/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
@@ -683,8 +866,8 @@ void() monster_dead_army =
if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
return;
- precache_model("progs/soldier.mdl");
- setmodel(self, "progs/soldier.mdl");
+ precache_model ("progs/soldier.mdl");
+ setmodel (self, "progs/soldier.mdl");
if (self.spawnflags & 2)
{
self.frame = $death10;
@@ -692,7 +875,7 @@ void() monster_dead_army =
if (self.spawnflags & 1)
{
self.solid = SOLID_BBOX;
- setsize(self,'-38.27 -30.47 -50.3','22.1 25.35 30');
+ setsize (self,'-38.27 -30.47 -50.3','22.1 25.35 30');
}
else
{
@@ -705,7 +888,7 @@ void() monster_dead_army =
if (self.spawnflags & 1)
{
self.solid = SOLID_BBOX;
- setsize(self,'-39.85 -29.35 -49.07','20.52 33.17 30');
+ setsize (self,'-39.85 -29.35 -49.07','20.52 33.17 30');
}
else
{
Return to the top of this page or return to the overview of this repo.
Diff qc/monsters/wizard.qc
diff --git a/qc/monsters/wizard.qc b/qc/monsters/wizard.qc
index 357b004..f5ab77e 100644
--- a/qc/monsters/wizard.qc
+++ b/qc/monsters/wizard.qc
@@ -1,11 +1,10 @@
-/*
-==============================================================================
-
-WIZARD
-
-==============================================================================
-*/
+//==============================================================================
+// WIZARD
+//==============================================================================
+//======================================================================
+// frame macros
+//======================================================================
$cd id1/models/a_wizard
$origin 0 0 24
$base wizbase
@@ -24,182 +23,28 @@ $frame pain1 pain2 pain3 pain4
$frame death1 death2 death3 death4 death5 death6 death7 death8
-/*
-==============================================================================
-
-WIZARD
-
-If the player moves behind cover before the missile is launched, launch it
-at the last visible spot with no velocity leading, in hopes that the player
-will duck back out and catch it.
-==============================================================================
-*/
-
-/*
-=============
-LaunchMissile
-
-Sets the given entities velocity and angles so that it will hit self.enemy
-if self.enemy maintains it's current velocity
-0.1 is moderately accurate, 0.0 is totally accurate
-=============
-*/
-void(entity missile, float mspeed, float accuracy) LaunchMissile =
-{
- local vector vec, move;
- local float fly;
-
- makevectors (self.angles);
-
-// set missile speed
- vec = self.enemy.origin + self.enemy.mins + self.enemy.size * 0.7 - missile.origin;
-
-// calc aproximate time for missile to reach vec
- fly = vlen (vec) / mspeed;
-
-// get the entities xy velocity
- move = self.enemy.velocity;
- move_z = 0;
-
-// project the target forward in time
- vec = vec + move * fly;
-
- vec = normalize(vec);
- vec = vec + accuracy*v_up*(random()- 0.5) + accuracy*v_right*(random()- 0.5);
-
- missile.velocity = vec * mspeed;
-
- missile.angles = '0 0 0';
- missile.angles_y = vectoyaw(missile.velocity);
-
- if (self.projexpl)
- {
- missile.touch = T_WizardMisTouch;
- }
-
-// set missile duration
- missile.nextthink = time + 5;
- missile.think = sub_remove;
-};
-
-
-void() wiz_run1;
-void() wiz_side1;
-
-/*
-=================
-WizardCheckAttack
-=================
-*/
-float() WizardCheckAttack =
-{
- local vector spot1, spot2;
- local entity targ;
- local float chance;
-
- if (time < self.attack_finished)
- return FALSE;
- if (!enemy_vis)
- return FALSE;
-
- if (enemy_range == RANGE_FAR)
- {
- if (self.attack_state != AS_STRAIGHT)
- {
- self.attack_state = AS_STRAIGHT;
- wiz_run1 ();
- }
- return FALSE;
- }
-
- targ = self.enemy;
-
-// see if any entities are in the way of the shot
- spot1 = self.origin + self.view_ofs;
- spot2 = targ.origin + targ.view_ofs;
-
- traceline (spot1, spot2, FALSE, self);
-
- if (trace_ent != targ)
- { // don't have a clear shot, so move to a side
- if (self.attack_state != AS_STRAIGHT)
- {
- self.attack_state = AS_STRAIGHT;
- wiz_run1 ();
- }
- return FALSE;
- }
-
- if (enemy_range == RANGE_MELEE)
- chance = 0.9;
- else if (enemy_range == RANGE_NEAR)
- chance = 0.6;
- else if (enemy_range == RANGE_MID)
- chance = 0.2;
- else
- chance = 0;
-
- if (random () < chance)
- {
- self.attack_state = AS_MISSILE;
- return TRUE;
- }
-
- if (enemy_range == RANGE_MID)
- {
- if (self.attack_state != AS_STRAIGHT)
- {
- self.attack_state = AS_STRAIGHT;
- wiz_run1 ();
- }
- }
- else
- {
- if (self.attack_state != AS_SLIDING)
- {
- self.attack_state = AS_SLIDING;
- wiz_side1 ();
- }
- }
-
- return FALSE;
-};
-
-/*
-=================
-WizardAttackFinished
-=================
-*/
-void() WizardAttackFinished =
-{
- if (enemy_range >= RANGE_MID || !enemy_vis)
- {
- self.attack_state = AS_STRAIGHT;
- self.think = wiz_run1;
- }
- else
- {
- self.attack_state = AS_SLIDING;
- self.think = wiz_side1;
- }
-};
+// Next two comments are strays preserved for reference purposes -- CEV
-/*
-==============================================================================
+//======================================================================
+// WIZARD
+//
+// If the player moves behind cover before the missile is launched,
+// launch it at the last visible spot with no velocity leading, in hopes
+// that the player will duck back out and catch it.
+//======================================================================
-FAST ATTACKS
-
-==============================================================================
-*/
-void() Wiz_AttackSound = // this is a hack to fix Wizard custom attack sounds
-{
- sound_attack (self, CHAN_AUTO, "wizard/wattack.wav", 1, ATTN_NORM);
-};
+//======================================================================
+// FAST ATTACKS
+//======================================================================
+//----------------------------------------------------------------------
+// Wizard missile think function
+// TODO CEV: rework into a proper projectile
+//----------------------------------------------------------------------
void() Wiz_FastFire =
{
- local vector vec;
- local vector dst;
+ local vector vec;
+ local vector dst;
local entity oldself;
local float projspeed = self.owner.proj_speed_mod * 600;
@@ -211,24 +56,29 @@ void() Wiz_FastFire =
dst = self.enemy.origin - 13*self.movedir;
vec = normalize(dst - self.origin);
- // sound_attack (self, CHAN_WEAPON, "wizard/wattack.wav", 1, ATTN_NORM);
+ // sound_attack (self, CHAN_WEAPON, "wizard/wattack.wav",
+ // 1, ATTN_NORM);
launch_spike (self.origin, vec);
- SetSpeed(newmis, vec, projspeed);
+ SetSpeed (newmis, vec, projspeed);
newmis.owner = self.owner;
newmis.classname = "wizspike";
+
if (self.owner.projexpl)
{
- // dprint("spawning exploding wizard proj from fastfire\n");
+ // dprint ("spawning exploding wizard proj "
+ // "from fastfire\n");
newmis.touch = T_WizardMisTouch;
}
+
if (self.owner.homing)
{
oldself = self;
self = self.owner;
- SetupHoming(newmis, projspeed);
+ SetupHoming (newmis, projspeed);
self = oldself;
}
- setmodel(newmis, self.owner.mdl_proj);
+
+ setmodel (newmis, self.owner.mdl_proj);
newmis.skin = self.owner.skin_proj;
setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
@@ -237,193 +87,6 @@ void() Wiz_FastFire =
remove (self);
};
-
-void() Wiz_StartFast =
-{
- local entity missile;
-
- // sound_attack (self, CHAN_WEAPON, "wizard/wattack.wav", 1, ATTN_NORM);
- self.v_angle = self.angles;
- makevectors (self.angles);
-
- missile = spawn ();
- missile.owner = self;
- missile.nextthink = time + 0.6;
- setsize (missile, '0 0 0', '0 0 0');
- setorigin (missile, self.origin + '0 0 30' + v_forward*14 + v_right*14);
- missile.enemy = self.enemy;
- missile.nextthink = time + 0.8;
- missile.think = Wiz_FastFire;
- missile.movedir = v_right;
-
- missile = spawn ();
- missile.owner = self;
- missile.nextthink = time + 1;
- setsize (missile, '0 0 0', '0 0 0');
- setorigin (missile, self.origin + '0 0 30' + v_forward*14 + v_right* -14);
- missile.enemy = self.enemy;
- missile.nextthink = time + 0.3;
- missile.think = Wiz_FastFire;
- missile.movedir = VEC_ORIGIN - v_right;
-};
-
-void() Wiz_idlesound =
-{
-local float wr;
- wr = random() * 5;
-
- if (self.fly_sound < time)
- {
- self.fly_sound = time + 2;
- if (wr > 4.5)
- sound_idle (self, CHAN_VOICE, "wizard/widle1.wav", 1, ATTN_IDLE);
- if (wr < 1.5)
- sound_misc (self, CHAN_VOICE, "wizard/widle2.wav", 1, ATTN_IDLE);
- }
- return;
-};
-
-void() wiz_stand1 =[ $hover1, wiz_stand2 ] {ai_stand();};
-void() wiz_stand2 =[ $hover2, wiz_stand3 ] {ai_stand();};
-void() wiz_stand3 =[ $hover3, wiz_stand4 ] {ai_stand();};
-void() wiz_stand4 =[ $hover4, wiz_stand5 ] {ai_stand();};
-void() wiz_stand5 =[ $hover5, wiz_stand6 ] {ai_stand();};
-void() wiz_stand6 =[ $hover6, wiz_stand7 ] {ai_stand();};
-void() wiz_stand7 =[ $hover7, wiz_stand8 ] {ai_stand();};
-void() wiz_stand8 =[ $hover8, wiz_stand1 ] {ai_stand();};
-
-void() wiz_walk1 =[ $hover1, wiz_walk2 ] {ai_walk(8);
-Wiz_idlesound();};
-void() wiz_walk2 =[ $hover2, wiz_walk3 ] {ai_walk(8);};
-void() wiz_walk3 =[ $hover3, wiz_walk4 ] {ai_walk(8);};
-void() wiz_walk4 =[ $hover4, wiz_walk5 ] {ai_walk(8);};
-void() wiz_walk5 =[ $hover5, wiz_walk6 ] {ai_walk(8);};
-void() wiz_walk6 =[ $hover6, wiz_walk7 ] {ai_walk(8);};
-void() wiz_walk7 =[ $hover7, wiz_walk8 ] {ai_walk(8);};
-void() wiz_walk8 =[ $hover8, wiz_walk1 ] {ai_walk(8);};
-
-void() wiz_side1 =[ $hover1, wiz_side2 ] {ai_run(8);
-Wiz_idlesound();};
-void() wiz_side2 =[ $hover2, wiz_side3 ] {ai_run(8);};
-void() wiz_side3 =[ $hover3, wiz_side4 ] {ai_run(8);};
-void() wiz_side4 =[ $hover4, wiz_side5 ] {ai_run(8);};
-void() wiz_side5 =[ $hover5, wiz_side6 ] {ai_run(8);};
-void() wiz_side6 =[ $hover6, wiz_side7 ] {ai_run(8);};
-void() wiz_side7 =[ $hover7, wiz_side8 ] {ai_run(8);};
-void() wiz_side8 =[ $hover8, wiz_side1 ] {ai_run(8);};
-
-void() wiz_run1 =[ $fly1, wiz_run2 ] {ai_run(16);
-Wiz_idlesound();
-};
-void() wiz_run2 =[ $fly2, wiz_run3 ] {ai_run(16);};
-void() wiz_run3 =[ $fly3, wiz_run4 ] {ai_run(16);};
-void() wiz_run4 =[ $fly4, wiz_run5 ] {ai_run(16);};
-void() wiz_run5 =[ $fly5, wiz_run6 ] {ai_run(16);};
-void() wiz_run6 =[ $fly6, wiz_run7 ] {ai_run(16);};
-void() wiz_run7 =[ $fly7, wiz_run8 ] {ai_run(16);};
-void() wiz_run8 =[ $fly8, wiz_run9 ] {ai_run(16);};
-void() wiz_run9 =[ $fly9, wiz_run10 ] {ai_run(16);};
-void() wiz_run10 =[ $fly10, wiz_run11 ] {ai_run(16);};
-void() wiz_run11 =[ $fly11, wiz_run12 ] {ai_run(16);};
-void() wiz_run12 =[ $fly12, wiz_run13 ] {ai_run(16);};
-void() wiz_run13 =[ $fly13, wiz_run14 ] {ai_run(16);};
-void() wiz_run14 =[ $fly14, wiz_run1 ] {ai_run(16);};
-
-void() wiz_fast1 =[ $magatt1, wiz_fast2 ] {ai_face();Wiz_StartFast();Wiz_AttackSound();};
-void() wiz_fast2 =[ $magatt2, wiz_fast3 ] {ai_face();};
-void() wiz_fast3 =[ $magatt3, wiz_fast4 ] {ai_face();};
-void() wiz_fast4 =[ $magatt4, wiz_fast5 ] {ai_face();};
-void() wiz_fast5 =[ $magatt5, wiz_fast6 ] {ai_face();};
-void() wiz_fast6 =[ $magatt6, wiz_fast7 ] {ai_face();};
-void() wiz_fast7 =[ $magatt5, wiz_fast8 ] {ai_face();Wiz_AttackSound();};
-void() wiz_fast8 =[ $magatt4, wiz_fast9 ] {ai_face();};
-void() wiz_fast9 =[ $magatt3, wiz_fast10 ] {ai_face();};
-void() wiz_fast10 =[ $magatt2, wiz_run1 ] {ai_face();SUB_AttackFinished(2);WizardAttackFinished ();};
-
-void() wiz_pain1 =[ $pain1, wiz_pain2 ] {};
-void() wiz_pain2 =[ $pain2, wiz_pain3 ] {};
-void() wiz_pain3 =[ $pain3, wiz_pain4 ] {};
-void() wiz_pain4 =[ $pain4, wiz_run1 ] {};
-
-void() wiz_death1 =[ $death1, wiz_death2 ] {
-
-self.velocity_x = -200 + 400*random();
-self.velocity_y = -200 + 400*random();
-self.velocity_z = 100 + 100*random();
-self.flags = self.flags - (self.flags & FL_ONGROUND);
-sound_death (self, CHAN_VOICE, "wizard/wdeath.wav", 1, ATTN_NORM);
-};
-void() wiz_death2 =[ $death2, wiz_death3 ] {};
-void() wiz_death3 =[ $death3, wiz_death4 ]{self.solid = SOLID_NOT;};
-void() wiz_death4 =[ $death4, wiz_death5 ] {};
-void() wiz_death5 =[ $death5, wiz_death6 ] {};
-void() wiz_death6 =[ $death6, wiz_death7 ] {};
-void() wiz_death7 =[ $death7, wiz_death8 ] {};
-void() wiz_death8 =[ $death8, wiz_death8 ] {};
-
-void() wiz_die =
-{
-// check for gib
- if (self.health < -40)
- {
- sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
- if (self.mdl_head != "") //dumptruck_ds custom_mdls
- {
- ThrowHead (self.mdl_head, self.health);
- }
- else
- {
- ThrowHead ("progs/h_wizard.mdl", self.health);
- }
- // ThrowGib ("progs/gib2.mdl", self.health);
- // ThrowGib ("progs/gib2.mdl", self.health);
- // ThrowGib ("progs/gib2.mdl", self.health);
- if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
- {
- ThrowGib (self.mdl_gib1, self.health);
- }
- else
- {
- ThrowGib ("progs/gib2.mdl", self.health);
- }
- if (self.mdl_gib2 != "")
- {
- ThrowGib (self.mdl_gib2, self.health);
- }
- else
- {
- ThrowGib ("progs/gib2.mdl", self.health);
- }
- if (self.mdl_gib3 != "")
- {
- ThrowGib (self.mdl_gib3, self.health);
- }
- else
- {
- ThrowGib ("progs/gib2.mdl", self.health);
- }
- base_item::drop_stuff (self);
- return;
- }
- base_item::drop_stuff (self);
- wiz_death1 ();
-};
-
-void(entity attacker, float damage) Wiz_Pain =
-{
- sound_pain (self, CHAN_VOICE, "wizard/wpain.wav", 1, ATTN_NORM);
- if (random()*70 > damage)
- return; // didn't flinch
-
- wiz_pain1 ();
-};
-
-
-void() Wiz_Missile =
-{
- wiz_fast1();
-};
-
/*QUAKED monster_wizard (1 0 0) (-16 -16 -24) (16 16 40) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
{
model ("progs/wizard.mdl");
@@ -486,69 +149,457 @@ obit_method(string) : "When used with obit_name, will set part of the text for a
damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
*/
-void() monster_wizard =
+class monster_wizard: base_flymonster
{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (self.spawnflags & I_AM_TURRET)
- objerror("Incompatible spawnflag: TURRET_MODE\n");
+ //--------------------------------------------------------------
+ // Wiz_StartFast -- TODO CEV rework into a new projectile class
+ //--------------------------------------------------------------
+ nonvirtual void() startfast =
+ {
+ local entity missile;
+
+ // sound_attack (this, CHAN_WEAPON, "wizard/wattack.wav",
+ // 1, ATTN_NORM);
+ this.v_angle = this.angles;
+ makevectors (this.angles);
+
+ missile = spawn ();
+ missile.owner = this;
+ missile.nextthink = time + 0.6;
+ setsize (missile, '0 0 0', '0 0 0');
+ setorigin (missile, this.origin + '0 0 30' +
+ v_forward * 14 + v_right * 14);
+ missile.enemy = this.enemy;
+ missile.nextthink = time + 0.8;
+ missile.think = Wiz_FastFire;
+ missile.movedir = v_right;
+
+ missile = spawn ();
+ missile.owner = this;
+ missile.nextthink = time + 1;
+ setsize (missile, '0 0 0', '0 0 0');
+ setorigin (missile, this.origin + '0 0 30' +
+ v_forward * 14 + v_right * -14);
+ missile.enemy = this.enemy;
+ missile.nextthink = time + 0.3;
+ missile.think = Wiz_FastFire;
+ missile.movedir = VEC_ORIGIN - v_right;
+ };
+
+ //--------------------------------------------------------------
+ // WizardAttackFinished
+ //--------------------------------------------------------------
+ nonvirtual void() attackfinished =
+ {
+ if (enemy_range >= RANGE_MID || !enemy_vis)
+ {
+ this.attack_state = AS_STRAIGHT;
+ this.think = this.run1;
+ }
+ else
+ {
+ this.attack_state = AS_SLIDING;
+ this.think = this.side1;
+ }
+ };
- if (deathmatch)
+ //--------------------------------------------------------------
+ virtual void() ai_sightsound =
+ {
+ sound_sight (this, CHAN_VOICE, "wizard/wsight.wav",
+ 1, ATTN_NORM);
+ };
+
+ //--------------------------------------------------------------
+ // Wiz_AttackSound
+ //--------------------------------------------------------------
+ nonvirtual void() attacksound =
+ {
+ // this is a hack to fix Wizard custom attack sounds
+ sound_attack (this, CHAN_AUTO, "wizard/wattack.wav",
+ 1, ATTN_NORM);
+ };
+
+ //--------------------------------------------------------------
+ // WizardIdleSound
+ //--------------------------------------------------------------
+ nonvirtual void() idlesound =
{
- remove(self);
+ local float wr = random() * 5;
+
+ if (this.fly_sound < time)
+ {
+ this.fly_sound = time + 2;
+ if (wr > 4.5)
+ sound_idle (this, CHAN_VOICE,
+ "wizard/widle1.wav", 1, ATTN_IDLE);
+ if (wr < 1.5)
+ sound_misc (this, CHAN_VOICE,
+ "wizard/widle2.wav", 1, ATTN_IDLE);
+ }
return;
- }
+ };
- if (!self.mdl_proj)
+ //--------------------------------------------------------------
+ nonvirtual void() wiz_missile =
{
- self.mdl_proj = "progs/w_spike.mdl";
- }
+ this.fast1();
+ };
- // dumptruck_ds custom_mdls
- precache_body_model ("progs/wizard.mdl");
- precache_head_model ("progs/h_wizard.mdl");
- precache_proj_model ("progs/w_spike.mdl");
- ////dumptruck_ds
- precache_sound_hit ("wizard/hit.wav"); // used by c code
- precache_sound_attack ("wizard/wattack.wav");
- precache_sound_death ("wizard/wdeath.wav");
- precache_sound_idle ("wizard/widle1.wav");
- precache_sound_misc ("wizard/widle2.wav");
- precache_sound_pain ("wizard/wpain.wav");
- precache_sound_sight ("wizard/wsight.wav");
+ //--------------------------------------------------------------
+ // WizardCheckAttack
+ //--------------------------------------------------------------
+ virtual float() ai_checkattack =
+ {
+ local vector spot1, spot2;
+ local entity targ;
+ local float chance;
+
+ if (time < this.attack_finished)
+ return FALSE;
+ if (!enemy_vis)
+ return FALSE;
+
+ if (enemy_range == RANGE_FAR)
+ {
+ if (this.attack_state != AS_STRAIGHT)
+ {
+ this.attack_state = AS_STRAIGHT;
+ this.run1 ();
+ }
+ return FALSE;
+ }
+
+ targ = this.enemy;
- precache_gib1 ("progs/gib1.mdl");
- precache_gib2 ("progs/gib2.mdl");
- precache_gib3 ("progs/gib3.mdl");
+ // see if any entities are in the way of the shot
+ spot1 = this.origin + this.view_ofs;
+ spot2 = targ.origin + targ.view_ofs;
- self.solid = SOLID_SLIDEBOX;
- self.movetype = MOVETYPE_STEP;
+ traceline (spot1, spot2, FALSE, this);
- body_model ("progs/wizard.mdl");
- // setmodel (self, "progs/wizard.mdl"); //dumptruck_ds
+ if (trace_ent != targ)
+ { // don't have a clear shot, so move to a side
+ if (this.attack_state != AS_STRAIGHT)
+ {
+ this.attack_state = AS_STRAIGHT;
+ this.run1 ();
+ }
+ return FALSE;
+ }
+
+ if (enemy_range == RANGE_MELEE)
+ chance = 0.9;
+ else if (enemy_range == RANGE_NEAR)
+ chance = 0.6;
+ else if (enemy_range == RANGE_MID)
+ chance = 0.2;
+ else
+ chance = 0;
- setsize (self, '-16 -16 -24', '16 16 40');
+ if (random () < chance)
+ {
+ this.attack_state = AS_MISSILE;
+ return TRUE;
+ }
- if (!self.proj_speed_mod)
+ if (enemy_range == RANGE_MID)
+ {
+ if (this.attack_state != AS_STRAIGHT)
+ {
+ this.attack_state = AS_STRAIGHT;
+ this.run1 ();
+ }
+ }
+ else
+ {
+ if (this.attack_state != AS_SLIDING)
+ {
+ this.attack_state = AS_SLIDING;
+ this.side1 ();
+ }
+ }
+
+ return FALSE;
+ };
+
+ //--------------------------------------------------------------
+ // Stationary wizard (?)
+ //--------------------------------------------------------------
+ nonvirtual void() stand1 = [$hover1, stand2] { ai_stand (); };
+ nonvirtual void() stand2 = [$hover2, stand3] { ai_stand (); };
+ nonvirtual void() stand3 = [$hover3, stand4] { ai_stand (); };
+ nonvirtual void() stand4 = [$hover4, stand5] { ai_stand (); };
+ nonvirtual void() stand5 = [$hover5, stand6] { ai_stand (); };
+ nonvirtual void() stand6 = [$hover6, stand7] { ai_stand (); };
+ nonvirtual void() stand7 = [$hover7, stand8] { ai_stand (); };
+ nonvirtual void() stand8 = [$hover8, stand1] { ai_stand (); };
+
+ //--------------------------------------------------------------
+ // Can a Wizard walk?
+ //--------------------------------------------------------------
+ nonvirtual void() walk1 = [$hover1, walk2]
{
- self.proj_speed_mod = 1;
- }
+ ai_walk (8);
+ this.idlesound ();
+ };
+ nonvirtual void() walk2 = [$hover2, walk3] { ai_walk (8); };
+ nonvirtual void() walk3 = [$hover3, walk4] { ai_walk (8); };
+ nonvirtual void() walk4 = [$hover4, walk5] { ai_walk (8); };
+ nonvirtual void() walk5 = [$hover5, walk6] { ai_walk (8); };
+ nonvirtual void() walk6 = [$hover6, walk7] { ai_walk (8); };
+ nonvirtual void() walk7 = [$hover7, walk8] { ai_walk (8); };
+ nonvirtual void() walk8 = [$hover8, walk1] { ai_walk (8); };
+
+ //--------------------------------------------------------------
+ // Wizards _can_ move side-to-side
+ //--------------------------------------------------------------
+ nonvirtual void() side1 = [$hover1, side2]
+ {
+ ai_run (8);
+ this.idlesound ();
+ };
+ nonvirtual void() side2 = [$hover2, side3] { ai_run (8); };
+ nonvirtual void() side3 = [$hover3, side4] { ai_run (8); };
+ nonvirtual void() side4 = [$hover4, side5] { ai_run (8); };
+ nonvirtual void() side5 = [$hover5, side6] { ai_run (8); };
+ nonvirtual void() side6 = [$hover6, side7] { ai_run (8); };
+ nonvirtual void() side7 = [$hover7, side8] { ai_run (8); };
+ nonvirtual void() side8 = [$hover8, side1] { ai_run (8); };
+
+ //--------------------------------------------------------------
+ // Wizard workout
+ //--------------------------------------------------------------
+ nonvirtual void() run1 = [$fly1, run2]
+ {
+ ai_run (16);
+ this.idlesound ();
+ };
+ nonvirtual void() run2 = [$fly2, run3] { ai_run (16); };
+ nonvirtual void() run3 = [$fly3, run4] { ai_run (16); };
+ nonvirtual void() run4 = [$fly4, run5] { ai_run (16); };
+ nonvirtual void() run5 = [$fly5, run6] { ai_run (16); };
+ nonvirtual void() run6 = [$fly6, run7] { ai_run (16); };
+ nonvirtual void() run7 = [$fly7, run8] { ai_run (16); };
+ nonvirtual void() run8 = [$fly8, run9] { ai_run (16); };
+ nonvirtual void() run9 = [$fly9, run10] { ai_run (16); };
+ nonvirtual void() run10 = [$fly10, run11] { ai_run (16); };
+ nonvirtual void() run11 = [$fly11, run12] { ai_run (16); };
+ nonvirtual void() run12 = [$fly12, run13] { ai_run (16); };
+ nonvirtual void() run13 = [$fly13, run14] { ai_run (16); };
+ nonvirtual void() run14 = [$fly14, run1] { ai_run (16); };
+
+ //--------------------------------------------------------------
+ // ~Fast~ Wizards
+ //--------------------------------------------------------------
+ nonvirtual void() fast1 = [$magatt1, fast2]
+ {
+ ai_face ();
+ this.startfast ();
+ this.attacksound ();
+ };
+ nonvirtual void() fast2 = [$magatt2, fast3] { ai_face (); };
+ nonvirtual void() fast3 = [$magatt3, fast4] { ai_face (); };
+ nonvirtual void() fast4 = [$magatt4, fast5] { ai_face (); };
+ nonvirtual void() fast5 = [$magatt5, fast6] { ai_face (); };
+ nonvirtual void() fast6 = [$magatt6, fast7] { ai_face (); };
+ nonvirtual void() fast7 = [$magatt5, fast8]
+ {
+ ai_face ();
+ this.attacksound ();
+ };
+ nonvirtual void() fast8 = [$magatt4, fast9] { ai_face (); };
+ nonvirtual void() fast9 = [$magatt3, fast10] { ai_face (); };
+ nonvirtual void() fast10 = [$magatt2, run1]
+ {
+ ai_face ();
+ sub_attackfinished (2);
+ this.attackfinished ();
+ };
+
+ //--------------------------------------------------------------
+ // Wizard Pain State
+ //--------------------------------------------------------------
+ nonvirtual void() pain1 = [$pain1, pain2] { };
+ nonvirtual void() pain2 = [$pain2, pain3] { };
+ nonvirtual void() pain3 = [$pain3, pain4] { };
+ nonvirtual void() pain4 = [$pain4, run1] { };
+
+ //--------------------------------------------------------------
+ // Wizard Death State
+ //--------------------------------------------------------------
+ nonvirtual void() death1 = [$death1, death2]
+ {
+ this.velocity_x = -200 + 400 * random ();
+ this.velocity_y = -200 + 400 * random ();
+ this.velocity_z = 100 + 100 * random ();
+ this.flags = this.flags - (this.flags & FL_ONGROUND);
+ sound_death (this, CHAN_VOICE, "wizard/wdeath.wav",
+ 1, ATTN_NORM);
+ };
+ nonvirtual void() death2 = [$death2, death3] { };
+ nonvirtual void() death3 = [$death3, death4]
+ {
+ this.solid = SOLID_NOT;
+ };
+ nonvirtual void() death4 = [$death4, death5] { };
+ nonvirtual void() death5 = [$death5, death6] { };
+ nonvirtual void() death6 = [$death6, death7] { };
+ nonvirtual void() death7 = [$death7, death8] { };
+ nonvirtual void() death8 = [$death8, death8] { };
+
+ //==============================================================
+ // Interaction
+ //==============================================================
+
+ //--------------------------------------------------------------
+ // Wiz_Pain
+ //--------------------------------------------------------------
+ virtual void(entity attacker, float damage) do_damage =
+ {
+ sound_pain (this, CHAN_VOICE, "wizard/wpain.wav",
+ 1, ATTN_NORM);
+ if (random() * 70 > damage)
+ // didn't flinch
+ return;
+
+ this.pain1 ();
+ };
+
+ //--------------------------------------------------------------
+ // wiz_die
+ //--------------------------------------------------------------
+ virtual void() do_destroy =
+ {
+ // check for gib
+ if (this.health < -40)
+ {
+ sound (this, CHAN_VOICE, "player/udeath.wav",
+ 1, ATTN_NORM);
+
+ // dumptruck_ds custom_mdls
+ if (this.mdl_head != "")
+ {
+ ThrowHead (this.mdl_head, this.health);
+ }
+ else
+ {
+ ThrowHead ("progs/h_wizard.mdl", this.health);
+ }
+ // ThrowGib ("progs/gib2.mdl", this.health);
+ // ThrowGib ("progs/gib2.mdl", this.health);
+ // ThrowGib ("progs/gib2.mdl", this.health);
+ // custom models -- dumptruck_ds
+ if (this.mdl_gib1 != "")
+ {
+ ThrowGib (this.mdl_gib1, this.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib2.mdl", this.health);
+ }
+ if (this.mdl_gib2 != "")
+ {
+ ThrowGib (this.mdl_gib2, this.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib2.mdl", this.health);
+ }
+ if (this.mdl_gib3 != "")
+ {
+ ThrowGib (this.mdl_gib3, this.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib2.mdl", this.health);
+ }
+ base_item::drop_stuff (this);
+ return;
+ }
- if (!self.health) //thanks RennyC -- dumptruck_ds
- self.health = 80;
+ base_item::drop_stuff (this);
+ this.death1 ();
+ };
- self.th_stand = wiz_stand1;
- self.th_walk = wiz_walk1;
- self.th_run = wiz_run1;
- self.th_missile = Wiz_Missile;
- if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
- self.th_pain = Wiz_Pain;
- else
- self.th_pain = sub_nullpain;
- self.th_die = wiz_die;
+ //==============================================================
+ // Initialization
+ //==============================================================
+
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
+ {
+ if (this.spawnflags & I_AM_TURRET)
+ objerror("Incompatible spawnflag: TURRET_MODE\n");
- flymonster_start ();
+ if (deathmatch)
+ {
+ remove (this);
+ return;
+ }
+
+ if (!this.mdl_proj)
+ {
+ this.mdl_proj = "progs/w_spike.mdl";
+ }
+
+ // dumptruck_ds custom_mdls
+ precache_body_model ("progs/wizard.mdl");
+ precache_head_model ("progs/h_wizard.mdl");
+ precache_proj_model ("progs/w_spike.mdl");
+ // dumptruck_ds
+ // wizard/hit used by c code
+ precache_sound_hit ("wizard/hit.wav");
+ precache_sound_attack ("wizard/wattack.wav");
+ precache_sound_death ("wizard/wdeath.wav");
+ precache_sound_idle ("wizard/widle1.wav");
+ precache_sound_misc ("wizard/widle2.wav");
+ precache_sound_pain ("wizard/wpain.wav");
+ precache_sound_sight ("wizard/wsight.wav");
+
+ precache_gib1 ("progs/gib1.mdl");
+ precache_gib2 ("progs/gib2.mdl");
+ precache_gib3 ("progs/gib3.mdl");
+
+ this.solid = SOLID_SLIDEBOX;
+ this.movetype = MOVETYPE_STEP;
+
+ body_model ("progs/wizard.mdl");
+ // setmodel (this, "progs/wizard.mdl"); //dumptruck_ds
+
+ setsize (this, '-16 -16 -24', '16 16 40');
+
+ if (!this.proj_speed_mod)
+ {
+ this.proj_speed_mod = 1;
+ }
+
+ if (!this.health)
+ // thanks RennyC -- dumptruck_ds
+ this.health = 80;
+
+ this.think_stand = this.stand1;
+ this.think_walk = this.walk1;
+ this.think_run = this.run1;
+ this.think_missile = this.wiz_missile;
+ // Berserk test from
+ // http://celephais.net/board/view_thread.php?id=4&start=3465
+ // -- dumptruck_ds
+ if !(this.berserk)
+ this.th_pain = do_damage;
+ else
+ this.th_pain = sub_nullpain;
+ this.th_die = do_destroy;
+
+ // flymonster_start
+ super::init_spawned ();
+ };
+
+ //--------------------------------------------------------------
+ void() monster_wizard =
+ {
+ this.classtype = CT_MONSTER_SCRAG;
+ };
};
/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
Return to the top of this page or return to the overview of this repo.
Diff qc/monsters/zombie.qc
diff --git a/qc/monsters/zombie.qc b/qc/monsters/zombie.qc
index 1efb2fe..51b4a75 100644
--- a/qc/monsters/zombie.qc
+++ b/qc/monsters/zombie.qc
@@ -1,17 +1,24 @@
-/*
-==============================================================================
-
-ZOMBIES!.qc - Version 1.1
-by Ace_Dave
-http://www.trenton.edu/~weiden/quake
-Weiden@Trenton.EDU
-
-==============================================================================
-*/
+//==============================================================================
+// ZOMBIES!.qc - Version 1.1
+// by Ace_Dave
+// http://www.trenton.edu/~weiden/quake
+// Weiden@Trenton.EDU
+//==============================================================================
+
+//======================================================================
+// Constants - spawnflags
+//======================================================================
+const float ZOMBIE_SPAWN_CRUCIFIED = 1;
+const float ZOMBIE_SPAWN_DEAD_CRUCIFIED = 4;
+// const float ZOMBIE_SPAWN_DEAD = 4; // from Zer src, saved for reference
+// const float ZOMBIE_SPAWN_DEAD_CRUCIFIED = 8; // from Zer src, for reference
+const float ZOMBIE_SPAWN_SLEEPING = 16; // changed from 2 which was Zer default
+
+//======================================================================
+// frame macros
+//======================================================================
$cd /raid/quake/id1/models/zombie
-
$origin 0 0 24
-
$base base
$skin skin
@@ -53,648 +60,6 @@ $frame paine29 paine30
$frame cruc_1 cruc_2 cruc_3 cruc_4 cruc_5 cruc_6
-float SPAWN_CRUCIFIED = 1;
-float SPAWN_DEAD_CRUCIFIED = 4;
-float SPAWN_SLEEPING = 16; //changed from 2 which was Zer default
-// float SPAWN_DEAD = 4; -- not used in progs_dump -- dumptruck_ds -- this is from Zer src for my reference
-// float SPAWN_DEAD_CRUCIFIED = 8; -- not used in progs_dump -- dumptruck_ds -- this is from Zer src for my reference
-
-//=============================================================================
-.float inpain;
-
-// motionless crucified zombie
-void() zombie_dead_cruc1 = [$cruc_1, zombie_dead_cruc1] {self.nextthink = time + 1;};
-
-// new "stand" - for sleeping zombies
-void() zombie_stand1 =[ $paine11, zombie_stand2 ]
-{
- self.solid = SOLID_NOT;
- if (self.count == 0) //dumptruck_ds -- count value > 0 to leave the zombie sleeping until triggered!
- ai_stand();
-};
-void() zombie_stand2 =[ $paine11, zombie_stand1 ]
-{
- if (self.count == 0)
- ai_stand();
-};
-
-// old "stand" - called when standing only
-void() alt_zombie_stand1 =[ $stand1, alt_zombie_stand2 ] {self.health = 60; ai_stand();};
-void() alt_zombie_stand2 =[ $stand2, zombie_stand3 ] {ai_stand();};
-void() zombie_stand3 =[ $stand3, zombie_stand4 ] {ai_stand();};
-void() zombie_stand4 =[ $stand4, zombie_stand5 ] {ai_stand();};
-void() zombie_stand5 =[ $stand5, zombie_stand6 ] {ai_stand();};
-void() zombie_stand6 =[ $stand6, zombie_stand7 ] {ai_stand();};
-void() zombie_stand7 =[ $stand7, zombie_stand8 ] {ai_stand();};
-void() zombie_stand8 =[ $stand8, zombie_stand9 ] {ai_stand();};
-void() zombie_stand9 =[ $stand9, zombie_stand10 ] {ai_stand();};
-void() zombie_stand10 =[ $stand10, zombie_stand11 ] {ai_stand();};
-void() zombie_stand11 =[ $stand11, zombie_stand12 ] {ai_stand();};
-void() zombie_stand12 =[ $stand12, zombie_stand13 ] {ai_stand();};
-void() zombie_stand13 =[ $stand13, zombie_stand14 ] {ai_stand();};
-void() zombie_stand14 =[ $stand14, zombie_stand15 ] {ai_stand();};
-void() zombie_stand15 =[ $stand15, alt_zombie_stand1 ] {ai_stand();};
-
-void() zombie_cruc1 = [ $cruc_1, zombie_cruc2 ] {
-if (random() < 0.1)
- sound_idle (self, CHAN_VOICE, "zombie/idle_w2.wav", 1, ATTN_STATIC);};
-void() zombie_cruc2 = [ $cruc_2, zombie_cruc3 ] {self.nextthink = time + 0.1 + random()*0.1;};
-void() zombie_cruc3 = [ $cruc_3, zombie_cruc4 ] {self.nextthink = time + 0.1 + random()*0.1;};
-void() zombie_cruc4 = [ $cruc_4, zombie_cruc5 ] {self.nextthink = time + 0.1 + random()*0.1;};
-void() zombie_cruc5 = [ $cruc_5, zombie_cruc6 ] {self.nextthink = time + 0.1 + random()*0.1;};
-void() zombie_cruc6 = [ $cruc_6, zombie_cruc1 ] {self.nextthink = time + 0.1 + random()*0.1;};
-
-void() zombie_walk1 =[ $walk1, zombie_walk2 ] {
- self.solid = SOLID_SLIDEBOX;
- self.health = 60; //so he doesn't fall
- ai_walk(0);};
-void() zombie_walk2 =[ $walk2, zombie_walk3 ] {ai_walk(2);};
-void() zombie_walk3 =[ $walk3, zombie_walk4 ] {ai_walk(3);};
-void() zombie_walk4 =[ $walk4, zombie_walk5 ] {ai_walk(2);};
-void() zombie_walk5 =[ $walk5, zombie_walk6 ] {ai_walk(1);};
-void() zombie_walk6 =[ $walk6, zombie_walk7 ] {ai_walk(0);};
-void() zombie_walk7 =[ $walk7, zombie_walk8 ] {ai_walk(0);};
-void() zombie_walk8 =[ $walk8, zombie_walk9 ] {ai_walk(0);};
-void() zombie_walk9 =[ $walk9, zombie_walk10 ] {ai_walk(0);};
-void() zombie_walk10 =[ $walk10, zombie_walk11 ] {ai_walk(0);};
-void() zombie_walk11 =[ $walk11, zombie_walk12 ] {ai_walk(2);};
-void() zombie_walk12 =[ $walk12, zombie_walk13 ] {ai_walk(2);};
-void() zombie_walk13 =[ $walk13, zombie_walk14 ] {ai_walk(1);};
-void() zombie_walk14 =[ $walk14, zombie_walk15 ] {ai_walk(0);};
-void() zombie_walk15 =[ $walk15, zombie_walk16 ] {ai_walk(0);};
-void() zombie_walk16 =[ $walk16, zombie_walk17 ] {ai_walk(0);};
-void() zombie_walk17 =[ $walk17, zombie_walk18 ] {ai_walk(0);};
-void() zombie_walk18 =[ $walk18, zombie_walk19 ] {ai_walk(0);};
-void() zombie_walk19 =[ $walk19, zombie_walk1 ] {
-ai_walk(0);
-if (random() < 0.2)
- sound_misc (self, CHAN_VOICE, "zombie/z_idle.wav", 1, ATTN_IDLE);};
-
-void() zombie_run1 =[ $run1, zombie_run2 ] {
- if (self.spawnflags & SPAWN_SLEEPING)
- { // sloppy hack, but it fixes the illusionary zombie bug
- body_model ("progs/zombie.mdl"); //custom_mdls dumptruck_ds
- // setmodel (self, "progs/zombie.mdl");
- setsize (self, '-16 -16 -24', '16 16 40');
- }
- ai_run(1);
- self.inpain = 0;};
-void() zombie_run2 =[ $run2, zombie_run3 ] {ai_run(1);};
-void() zombie_run3 =[ $run3, zombie_run4 ] {ai_run(0);};
-void() zombie_run4 =[ $run4, zombie_run5 ] {ai_run(1);};
-void() zombie_run5 =[ $run5, zombie_run6 ] {ai_run(2);};
-void() zombie_run6 =[ $run6, zombie_run7 ] {ai_run(3);};
-void() zombie_run7 =[ $run7, zombie_run8 ] {ai_run(4);};
-void() zombie_run8 =[ $run8, zombie_run9 ] {ai_run(4);};
-void() zombie_run9 =[ $run9, zombie_run10 ] {ai_run(2);};
-void() zombie_run10 =[ $run10, zombie_run11 ] {ai_run(0);};
-void() zombie_run11 =[ $run11, zombie_run12 ] {ai_run(0);};
-void() zombie_run12 =[ $run12, zombie_run13 ] {ai_run(0);};
-void() zombie_run13 =[ $run13, zombie_run14 ] {ai_run(2);};
-void() zombie_run14 =[ $run14, zombie_run15 ] {ai_run(4);};
-void() zombie_run15 =[ $run15, zombie_run16 ] {ai_run(6);};
-void() zombie_run16 =[ $run16, zombie_run17 ] {ai_run(7);};
-void() zombie_run17 =[ $run17, zombie_run18 ] {ai_run(3);};
-void() zombie_run18 =[ $run18, zombie_run1 ] {
-ai_run(8);
-if (random() < 0.2)
- sound_misc (self, CHAN_VOICE, "zombie/z_idle.wav", 1, ATTN_IDLE);
-if (random() > 0.8)
- sound_sight (self, CHAN_VOICE, "zombie/z_idle1.wav", 1, ATTN_IDLE);
-};
-
-/*
-=============================================================================
-
-ATTACKS
-
-=============================================================================
-*/
-// void() Z_hit =
-// {
-// sound_hit (self, CHAN_WEAPON, "zombie/z_hit.wav", 1, ATTN_NORM);
-// };
-//
-// void() Z_land =
-// {
-// sound_land (self, CHAN_WEAPON, "zombie/z_miss.wav", 1, ATTN_NORM); // bounce sound
-// };
-
-// void() ZombieGrenadeTouch2 =
-// {
-// if (other == self.owner)
-// return; // don't explode on owner
-// if (other.takedamage)
-// {
-// // Z_hit();
-// T_Damage (other, self, self.owner, 10 );
-// sound_hit (self, CHAN_WEAPON, "zombie/z_hit.wav", 1, ATTN_NORM);
-// remove (self);
-// return;
-// }
-// // Z_land();
-// sound_land (self, CHAN_WEAPON, "zombie/z_miss.wav", 1, ATTN_NORM); // bounce sound
-// self.velocity = '0 0 0';
-// self.avelocity = '0 0 0';
-// self.touch = sub_remove;
-// };
-
-/*
-================
-ZombieFireGrenade
-================
-*/
-void(vector st) ZombieFireGrenade =
-{
- local entity missile;
- local vector org;
-
- sound_attack (self, CHAN_WEAPON, "zombie/z_shot1.wav", 1, ATTN_NORM);
-
- missile = spawn ();
- missile.owner = self;
- missile.movetype = MOVETYPE_BOUNCE;
- missile.solid = SOLID_BBOX;
-
-// calc org
- org = self.origin + st_x * v_forward + st_y * v_right + (st_z - 24) * v_up;
-
-// set missile speed
-
- makevectors (self.angles);
-
- missile.velocity = normalize(self.enemy.origin - org);
- missile.velocity = missile.velocity * 600;
- missile.velocity_z = 200;
-
- missile.avelocity = '3000 1000 2000';
-
- missile.touch = ZombieGrenadeTouch;
-
-// set missile duration
- missile.nextthink = time + 2.5;
- missile.think = sub_remove;
- // setmodel (missile, "progs/zom_gib.mdl");
- if (self.mdl_proj != "") // dumptruck_ds custom_mdls
- {
- setmodel (missile, self.mdl_proj);
- }
- else
- {
- setmodel (missile, "progs/zom_gib.mdl");
- }
-
- if (!missile.skin_proj) // dumptruck_ds
- {
- missile.skin = self.skin_proj;
- }
- else
- {
- missile.skin = 0;
- }
-
- setsize (missile, '0 0 0', '0 0 0');
- setorigin (missile, org);
-};
-
-
-void() zombie_atta1 =[ $atta1, zombie_atta2 ] {ai_face();};
-void() zombie_atta2 =[ $atta2, zombie_atta3 ] {ai_face();};
-void() zombie_atta3 =[ $atta3, zombie_atta4 ] {ai_face();};
-void() zombie_atta4 =[ $atta4, zombie_atta5 ] {ai_face();};
-void() zombie_atta5 =[ $atta5, zombie_atta6 ] {ai_face();};
-void() zombie_atta6 =[ $atta6, zombie_atta7 ] {ai_face();};
-void() zombie_atta7 =[ $atta7, zombie_atta8 ] {ai_face();};
-void() zombie_atta8 =[ $atta8, zombie_atta9 ] {ai_face();};
-void() zombie_atta9 =[ $atta9, zombie_atta10 ] {ai_face();};
-void() zombie_atta10 =[ $atta10, zombie_atta11 ] {ai_face();};
-void() zombie_atta11 =[ $atta11, zombie_atta12 ] {ai_face();};
-void() zombie_atta12 =[ $atta12, zombie_atta13 ] {ai_face();};
-void() zombie_atta13 =[ $atta13, zombie_run1 ] {ai_face();ZombieFireGrenade('-10 -22 30');};
-
-void() zombie_attb1 =[ $attb1, zombie_attb2 ] {ai_face();};
-void() zombie_attb2 =[ $attb2, zombie_attb3 ] {ai_face();};
-void() zombie_attb3 =[ $attb3, zombie_attb4 ] {ai_face();};
-void() zombie_attb4 =[ $attb4, zombie_attb5 ] {ai_face();};
-void() zombie_attb5 =[ $attb5, zombie_attb6 ] {ai_face();};
-void() zombie_attb6 =[ $attb6, zombie_attb7 ] {ai_face();};
-void() zombie_attb7 =[ $attb7, zombie_attb8 ] {ai_face();};
-void() zombie_attb8 =[ $attb8, zombie_attb9 ] {ai_face();};
-void() zombie_attb9 =[ $attb9, zombie_attb10 ] {ai_face();};
-void() zombie_attb10 =[ $attb10, zombie_attb11 ] {ai_face();};
-void() zombie_attb11 =[ $attb11, zombie_attb12 ] {ai_face();};
-void() zombie_attb12 =[ $attb12, zombie_attb13 ] {ai_face();};
-void() zombie_attb13 =[ $attb13, zombie_attb14 ] {ai_face();};
-void() zombie_attb14 =[ $attb13, zombie_run1 ] {ai_face();ZombieFireGrenade('-10 -24 29');};
-
-void() zombie_attc1 =[ $attc1, zombie_attc2 ] {ai_face();};
-void() zombie_attc2 =[ $attc2, zombie_attc3 ] {ai_face();};
-void() zombie_attc3 =[ $attc3, zombie_attc4 ] {ai_face();};
-void() zombie_attc4 =[ $attc4, zombie_attc5 ] {ai_face();};
-void() zombie_attc5 =[ $attc5, zombie_attc6 ] {ai_face();};
-void() zombie_attc6 =[ $attc6, zombie_attc7 ] {ai_face();};
-void() zombie_attc7 =[ $attc7, zombie_attc8 ] {ai_face();};
-void() zombie_attc8 =[ $attc8, zombie_attc9 ] {ai_face();};
-void() zombie_attc9 =[ $attc9, zombie_attc10 ] {ai_face();};
-void() zombie_attc10 =[ $attc10, zombie_attc11 ] {ai_face();};
-void() zombie_attc11 =[ $attc11, zombie_attc12 ] {ai_face();};
-void() zombie_attc12 =[ $attc12, zombie_run1 ] {ai_face();ZombieFireGrenade('-12 -19 29');};
-
-void() zombie_missile =
-{
- local float r;
-
- r = random();
-
- if (r < 0.3)
- zombie_atta1 ();
- else if (r < 0.6)
- zombie_attb1 ();
- else
- zombie_attc1 ();
-};
-//////////////////////////
-/// turret frames START
-/////////////////////////
-void() zombie_turret_atta1 =[ $atta1, zombie_turret_atta2 ] {self.health = 60;ai_face();};
-void() zombie_turret_atta2 =[ $atta2, zombie_turret_atta3 ] {ai_face();};
-void() zombie_turret_atta3 =[ $atta3, zombie_turret_atta4 ] {ai_face();};
-void() zombie_turret_atta4 =[ $atta4, zombie_turret_atta5 ] {ai_face();};
-void() zombie_turret_atta5 =[ $atta5, zombie_turret_atta6 ] {ai_face();};
-void() zombie_turret_atta6 =[ $atta6, zombie_turret_atta7 ] {ai_face();};
-void() zombie_turret_atta7 =[ $atta7, zombie_turret_atta8 ] {ai_face();};
-void() zombie_turret_atta8 =[ $atta8, zombie_turret_atta9 ] {ai_face();};
-void() zombie_turret_atta9 =[ $atta9, zombie_turret_atta10 ] {ai_face();};
-void() zombie_turret_atta10 =[ $atta10, zombie_turret_atta11 ] {ai_face();self.attack_elevation = IterateElevation(OGRE_DEFAULT_ELEVATION, self.enemy.origin);};
-void() zombie_turret_atta11 =[ $atta11, zombie_turret_atta12 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
-void() zombie_turret_atta12 =[ $atta12, zombie_turret_atta13 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
-void() zombie_turret_atta13 =[ $atta13, alt_zombie_seek_stand1 ] {ai_run(0);PreachFireZombie(self.attack_elevation);};
-
-void() zombie_turret_attb1 =[ $attb1, zombie_turret_attb2 ] {self.health = 60;ai_face();};
-void() zombie_turret_attb2 =[ $attb2, zombie_turret_attb3 ] {ai_face();};
-void() zombie_turret_attb3 =[ $attb3, zombie_turret_attb4 ] {ai_face();};
-void() zombie_turret_attb4 =[ $attb4, zombie_turret_attb5 ] {ai_face();};
-void() zombie_turret_attb5 =[ $attb5, zombie_turret_attb6 ] {ai_face();};
-void() zombie_turret_attb6 =[ $attb6, zombie_turret_attb7 ] {ai_face();};
-void() zombie_turret_attb7 =[ $attb7, zombie_turret_attb8 ] {ai_face();};
-void() zombie_turret_attb8 =[ $attb8, zombie_turret_attb9 ] {ai_face();};
-void() zombie_turret_attb9 =[ $attb9, zombie_turret_attb10 ] {ai_face();};
-void() zombie_turret_attb10 =[ $attb10, zombie_turret_attb11 ] {ai_face();};
-void() zombie_turret_attb11 =[ $attb11, zombie_turret_attb12 ] {ai_face();self.attack_elevation = IterateElevation(OGRE_DEFAULT_ELEVATION, self.enemy.origin);};
-void() zombie_turret_attb12 =[ $attb12, zombie_turret_attb13 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
-void() zombie_turret_attb13 =[ $attb13, zombie_turret_attb14 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
-void() zombie_turret_attb14 =[ $attb13, alt_zombie_seek_stand1 ] {ai_run(0);PreachFireZombie(self.attack_elevation);};
-
-void() zombie_turret_attc1 =[ $attc1, zombie_turret_attc2 ] {self.health = 60;ai_face();};
-void() zombie_turret_attc2 =[ $attc2, zombie_turret_attc3 ] {ai_face();};
-void() zombie_turret_attc3 =[ $attc3, zombie_turret_attc4 ] {ai_face();};
-void() zombie_turret_attc4 =[ $attc4, zombie_turret_attc5 ] {ai_face();};
-void() zombie_turret_attc5 =[ $attc5, zombie_turret_attc6 ] {ai_face();};
-void() zombie_turret_attc6 =[ $attc6, zombie_turret_attc7 ] {ai_face();};
-void() zombie_turret_attc7 =[ $attc7, zombie_turret_attc8 ] {ai_face();};
-void() zombie_turret_attc8 =[ $attc8, zombie_turret_attc9 ] {ai_face();};
-void() zombie_turret_attc9 =[ $attc9, zombie_turret_attc10 ] {ai_face();self.attack_elevation = IterateElevation(OGRE_DEFAULT_ELEVATION, self.enemy.origin);};
-void() zombie_turret_attc10 =[ $attc10, zombie_turret_attc11 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
-void() zombie_turret_attc11 =[ $attc11, zombie_turret_attc12 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
-void() zombie_turret_attc12 =[ $attc12, alt_zombie_seek_stand1 ] {ai_run(0);PreachFireZombie(self.attack_elevation);};
-void() alt_zombie_seek_stand1 =[ $stand1, alt_zombie_seek_stand2 ] {self.health = 60; ai_run(0);};
-void() alt_zombie_seek_stand2 =[ $stand2, zombie_seek_stand3 ] {ai_run(0);};
-void() zombie_seek_stand3 =[ $stand3, zombie_seek_stand4 ] {ai_run(0);};
-void() zombie_seek_stand4 =[ $stand4, zombie_seek_stand5 ] {ai_run(0);};
-void() zombie_seek_stand5 =[ $stand5, zombie_seek_stand6 ] {ai_run(0);};
-void() zombie_seek_stand6 =[ $stand6, zombie_seek_stand7 ] {ai_run(0);};
-void() zombie_seek_stand7 =[ $stand7, zombie_seek_stand8 ] {ai_run(0);};
-void() zombie_seek_stand8 =[ $stand8, zombie_seek_stand9 ] {ai_run(0);};
-void() zombie_seek_stand9 =[ $stand9, zombie_seek_stand10 ] {ai_run(0);};
-void() zombie_seek_stand10 =[ $stand10, zombie_seek_stand11 ] {ai_run(0);};
-void() zombie_seek_stand11 =[ $stand11, zombie_seek_stand12 ] {ai_run(0);};
-void() zombie_seek_stand12 =[ $stand12, zombie_seek_stand13 ] {ai_run(0);};
-void() zombie_seek_stand13 =[ $stand13, zombie_seek_stand14 ] {ai_run(0);};
-void() zombie_seek_stand14 =[ $stand14, zombie_seek_stand15 ] {ai_run(0);};
-void() zombie_seek_stand15 =[ $stand15, alt_zombie_seek_stand1 ] {ai_run(0);};
-
-void() zombie_turret_missile =
-{
- local float r;
-
- r = random();
-
- if (r < 0.3)
- zombie_turret_attb1 ();
- else if (r < 0.6)
- zombie_turret_atta1 ();
- else
- zombie_turret_attc1 ();
-};
-//////////////////////////
-/// turret frames END
-/////////////////////////
-
-/*
-=============================================================================
-
-PAIN
-
-=============================================================================
-*/
-
-void() zombie_paina1 =[ $paina1, zombie_paina2 ] {sound_pain (self, CHAN_VOICE, "zombie/z_pain.wav", 1, ATTN_NORM);};
-void() zombie_paina2 =[ $paina2, zombie_paina3 ] {ai_painforward(3);};
-void() zombie_paina3 =[ $paina3, zombie_paina4 ] {ai_painforward(1);};
-void() zombie_paina4 =[ $paina4, zombie_paina5 ] {ai_pain(1);};
-void() zombie_paina5 =[ $paina5, zombie_paina6 ] {ai_pain(3);};
-void() zombie_paina6 =[ $paina6, zombie_paina7 ] {ai_pain(1);};
-void() zombie_paina7 =[ $paina7, zombie_paina8 ] {};
-void() zombie_paina8 =[ $paina8, zombie_paina9 ] {};
-void() zombie_paina9 =[ $paina9, zombie_paina10 ] {};
-void() zombie_paina10 =[ $paina10, zombie_paina11 ] {};
-void() zombie_paina11 =[ $paina11, zombie_paina12 ] {};
-void() zombie_paina12 =[ $paina12, zombie_run1 ] {};
-
-void() zombie_painb1 =[ $painb1, zombie_painb2 ] {sound_misc2 (self, CHAN_VOICE, "zombie/z_pain1.wav", 1, ATTN_NORM);};
-void() zombie_painb2 =[ $painb2, zombie_painb3 ] {ai_pain(2);};
-void() zombie_painb3 =[ $painb3, zombie_painb4 ] {ai_pain(8);};
-void() zombie_painb4 =[ $painb4, zombie_painb5 ] {ai_pain(6);};
-void() zombie_painb5 =[ $painb5, zombie_painb6 ] {ai_pain(2);};
-void() zombie_painb6 =[ $painb6, zombie_painb7 ] {};
-void() zombie_painb7 =[ $painb7, zombie_painb8 ] {};
-void() zombie_painb8 =[ $painb8, zombie_painb9 ] {};
-void() zombie_painb9 =[ $painb9, zombie_painb10 ] {sound_misc3 (self, CHAN_BODY, "zombie/z_fall.wav", 1, ATTN_NORM);};
-void() zombie_painb10 =[ $painb10, zombie_painb11 ] {};
-void() zombie_painb11 =[ $painb11, zombie_painb12 ] {};
-void() zombie_painb12 =[ $painb12, zombie_painb13 ] {};
-void() zombie_painb13 =[ $painb13, zombie_painb14 ] {};
-void() zombie_painb14 =[ $painb14, zombie_painb15 ] {};
-void() zombie_painb15 =[ $painb15, zombie_painb16 ] {};
-void() zombie_painb16 =[ $painb16, zombie_painb17 ] {};
-void() zombie_painb17 =[ $painb17, zombie_painb18 ] {};
-void() zombie_painb18 =[ $painb18, zombie_painb19 ] {};
-void() zombie_painb19 =[ $painb19, zombie_painb20 ] {};
-void() zombie_painb20 =[ $painb20, zombie_painb21 ] {};
-void() zombie_painb21 =[ $painb21, zombie_painb22 ] {};
-void() zombie_painb22 =[ $painb22, zombie_painb23 ] {};
-void() zombie_painb23 =[ $painb23, zombie_painb24 ] {};
-void() zombie_painb24 =[ $painb24, zombie_painb25 ] {};
-void() zombie_painb25 =[ $painb25, zombie_painb26 ] {ai_painforward(1);};
-void() zombie_painb26 =[ $painb26, zombie_painb27 ] {};
-void() zombie_painb27 =[ $painb27, zombie_painb28 ] {};
-void() zombie_painb28 =[ $painb28, zombie_run1 ] {};
-
-void() zombie_painc1 =[ $painc1, zombie_painc2 ] {sound_misc2 (self, CHAN_VOICE, "zombie/z_pain1.wav", 1, ATTN_NORM);};
-void() zombie_painc2 =[ $painc2, zombie_painc3 ] {};
-void() zombie_painc3 =[ $painc3, zombie_painc4 ] {ai_pain(3);};
-void() zombie_painc4 =[ $painc4, zombie_painc5 ] {ai_pain(1);};
-void() zombie_painc5 =[ $painc5, zombie_painc6 ] {};
-void() zombie_painc6 =[ $painc6, zombie_painc7 ] {};
-void() zombie_painc7 =[ $painc7, zombie_painc8 ] {};
-void() zombie_painc8 =[ $painc8, zombie_painc9 ] {};
-void() zombie_painc9 =[ $painc9, zombie_painc10 ] {};
-void() zombie_painc10 =[ $painc10, zombie_painc11 ] {};
-void() zombie_painc11 =[ $painc11, zombie_painc12 ] {ai_painforward(1);};
-void() zombie_painc12 =[ $painc12, zombie_painc13 ] {ai_painforward(1);};
-void() zombie_painc13 =[ $painc13, zombie_painc14 ] {};
-void() zombie_painc14 =[ $painc14, zombie_painc15 ] {};
-void() zombie_painc15 =[ $painc15, zombie_painc16 ] {};
-void() zombie_painc16 =[ $painc16, zombie_painc17 ] {};
-void() zombie_painc17 =[ $painc17, zombie_painc18 ] {};
-void() zombie_painc18 =[ $painc18, zombie_run1 ] {};
-
-void() zombie_paind1 =[ $paind1, zombie_paind2 ] {sound_pain (self, CHAN_VOICE, "zombie/z_pain.wav", 1, ATTN_NORM);};
-void() zombie_paind2 =[ $paind2, zombie_paind3 ] {};
-void() zombie_paind3 =[ $paind3, zombie_paind4 ] {};
-void() zombie_paind4 =[ $paind4, zombie_paind5 ] {};
-void() zombie_paind5 =[ $paind5, zombie_paind6 ] {};
-void() zombie_paind6 =[ $paind6, zombie_paind7 ] {};
-void() zombie_paind7 =[ $paind7, zombie_paind8 ] {};
-void() zombie_paind8 =[ $paind8, zombie_paind9 ] {};
-void() zombie_paind9 =[ $paind9, zombie_paind10 ] {ai_pain(1);};
-void() zombie_paind10 =[ $paind10, zombie_paind11 ] {};
-void() zombie_paind11 =[ $paind11, zombie_paind12 ] {};
-void() zombie_paind12 =[ $paind12, zombie_paind13 ] {};
-void() zombie_paind13 =[ $paind13, zombie_run1 ] {};
-
-void() zombie_paine1 =[ $paine1, zombie_paine2 ] {
-if (self.axhitme == 2) // Chainsaw will gib zombie
-{
- T_Damage(self, world, world, 80);
- return;
-}
-sound_pain (self, CHAN_VOICE, "zombie/z_pain.wav", 1, ATTN_NORM);
-self.health = 60;
-};
-void() zombie_paine2 =[ $paine2, zombie_paine3 ] {ai_pain(8);};
-void() zombie_paine3 =[ $paine3, zombie_paine4 ] {ai_pain(5);};
-void() zombie_paine4 =[ $paine4, zombie_paine5 ] {ai_pain(3);};
-void() zombie_paine5 =[ $paine5, zombie_paine6 ] {ai_pain(1);};
-void() zombie_paine6 =[ $paine6, zombie_paine7 ] {ai_pain(2);};
-void() zombie_paine7 =[ $paine7, zombie_paine8 ] {ai_pain(1);};
-void() zombie_paine8 =[ $paine8, zombie_paine9 ] {ai_pain(1);};
-void() zombie_paine9 =[ $paine9, zombie_paine10 ] {ai_pain(2);};
-void() zombie_paine10 =[ $paine10, zombie_paine11 ] {
-sound_misc3 (self, CHAN_BODY, "zombie/z_fall.wav", 1, ATTN_NORM);
-self.solid = SOLID_NOT;
-};
-void() zombie_paine11 =[ $paine11, zombie_paine12 ] {self.nextthink = self.nextthink + 5;self.health = 60;};
-void() zombie_paine12 =[ $paine12, zombie_paine13 ]{
-// see if ok to stand up
-self.health = 60;
-sound_misc (self, CHAN_VOICE, "zombie/z_idle.wav", 1, ATTN_IDLE);
-self.solid = SOLID_SLIDEBOX;
-if (!walkmove (0, 0))
-{
- self.think = zombie_paine11;
- self.solid = SOLID_NOT;
- return;
-}
-};
-void() zombie_paine13 =[ $paine13, zombie_paine14 ] {};
-void() zombie_paine14 =[ $paine14, zombie_paine15 ] {};
-void() zombie_paine15 =[ $paine15, zombie_paine16 ] {};
-void() zombie_paine16 =[ $paine16, zombie_paine17 ] {};
-void() zombie_paine17 =[ $paine17, zombie_paine18 ] {};
-void() zombie_paine18 =[ $paine18, zombie_paine19 ] {};
-void() zombie_paine19 =[ $paine19, zombie_paine20 ] {};
-void() zombie_paine20 =[ $paine20, zombie_paine21 ] {};
-void() zombie_paine21 =[ $paine21, zombie_paine22 ] {};
-void() zombie_paine22 =[ $paine22, zombie_paine23 ] {};
-void() zombie_paine23 =[ $paine23, zombie_paine24 ] {};
-void() zombie_paine24 =[ $paine24, zombie_paine25 ] {};
-void() zombie_paine25 =[ $paine25, zombie_paine26 ] {ai_painforward(5);};
-void() zombie_paine26 =[ $paine26, zombie_paine27 ] {ai_painforward(3);};
-void() zombie_paine27 =[ $paine27, zombie_paine28 ] {ai_painforward(1);};
-void() zombie_paine28 =[ $paine28, zombie_paine29 ] {ai_pain(1);};
-void() zombie_paine29 =[ $paine29, zombie_paine30 ] {};
-void() zombie_paine30 =[ $paine30, zombie_run1 ] {};
-
-void() zombie_die =
-{
- sound_death (self, CHAN_VOICE, "zombie/z_gib.wav", 1, ATTN_NORM);
- if (self.mdl_head != "") //dumptruck_ds custom_mdls
- {
- ThrowHead (self.mdl_head, self.health);
- }
- else
- {
- ThrowHead ("progs/h_zombie.mdl", self.health/*, self.dest*/); //commented out dest -- dumptruck_ds
- }
- // ThrowGib ("progs/gib1.mdl", self.health/*, self.dest*/);
- // ThrowGib ("progs/gib2.mdl", self.health/*, self.dest*/);
- // ThrowGib ("progs/gib3.mdl", self.health/*, self.dest*/);
- if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
- {
- ThrowGib (self.mdl_gib1, self.health);
- }
- else
- {
- ThrowGib ("progs/gib1.mdl", self.health);
- }
- if (self.mdl_gib2 != "")
- {
- ThrowGib (self.mdl_gib2, self.health);
- }
- else
- {
- ThrowGib ("progs/gib2.mdl", self.health);
- }
- if (self.mdl_gib3 != "")
- {
- ThrowGib (self.mdl_gib3, self.health);
- }
- else
- {
- ThrowGib ("progs/gib3.mdl", self.health);
- }
- base_item::drop_stuff (self);
-};
-
-/*
-=================
-zombie_pain
-
-Zombies can only be killed (gibbed) by doing 60 hit points of damage
-in a single frame (rockets, grenades, quad shotgun, quad nailgun).
-
-A hit of 25 points or more (super shotgun, quad nailgun) will always put it
-down to the ground.
-
-A hit of from 10 to 40 points in one frame will cause it to go down if it
-has been twice in two seconds, otherwise it goes into one of the four
-fast pain frames.
-
-A hit of less than 10 points of damage (winged by a shotgun) will be ignored.
-
-FIXME: don't use pain_finished because of nightmare hack
-=================
-*/
-void(entity attacker, float take) zombie_pain =
-{
- if (self.spawnflags & I_AM_TURRET)
- {
- self.health = 60; // always reset health
-
- if (take >= 60)
- {
- zombie_die();
- }
- else
- return;
- }
-
- local float r;
-
- self.health = 60; // always reset health
-
- if (take < 9)
- return; // totally ignore
-
- if (self.inpain == 2)
- return; // down on ground, so don't reset any counters
-
-// go down immediately if a big enough hit
- if ((take >= 25) || (self.axhitme == 2))
- {
- self.inpain = 2;
- zombie_paine1 ();
- return;
- }
-
- if (self.inpain)
- {
-// if hit again in next gre seconds while not in pain frames, definately drop
- self.pain_finished = time + 3;
- return; // currently going through an animation, don't change
- }
-
- if (self.pain_finished > time)
- {
-// hit again, so drop down
- self.inpain = 2;
- zombie_paine1 ();
- return;
- }
-
-// gp into one of the fast pain animations
- self.inpain = 1;
-
- r = random();
- if (r < 0.25)
- zombie_paina1 ();
- else if (r < 0.5)
- zombie_painb1 ();
- else if (r < 0.75)
- zombie_painc1 ();
- else
- zombie_paind1 ();
-};
-
-void() zombie_decide = // stand up if orig. lying down, else just start running
-{
- if (self.health==61)
- zombie_paine12();
- else
- zombie_run1();
-
- self.th_run = zombie_run1;
-};
-
-void() zombie_use = // wake up a sleeping zombie!
-
-{
- self.count = 0;
- //attacker = other;
- monster_use();
-};
-
-void() zombie_start = // determine if zombie is to be lying down, or standing
-{
- self.count = 1; //dumptruck_ds -- Don't start zombie_stand1 yet!
- self.use = zombie_use; //dumptruck_ds -- makes self.count = 0 so zombie_stand1 is called
-
- if (self.spawnflags & SPAWN_SLEEPING)
- {
- if (!SUB_IsTargeted ())
- {
- dprint ("WARNING: removed untargeted sleeping zombie at ");
- dprint (vtos (self.origin));
- dprint ("\n");
-
- monster_update_total (-1);
- remove (self);
- return;
- }
- self.inpain = 2;
- zombie_stand1 ();
- }
- else
- {
- alt_zombie_stand1 ();
- }
-
- self.th_stand = alt_zombie_stand1;
-};
-
-//============================================================================
-
/*QUAKED monster_zombie (1 0 0) (-16 -16 -24) (16 16 32) CRUCIFIED AMBUSH CRUCIFIED_MOTIONLESS TRIGGER_SPAWNED SPAWN_SLEEPING X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
{
model ( {{ spawnflags & 1 -> { "path" : "progs/zombie.mdl", "frame" : 192 }, "progs/zombie.mdl" }} );
@@ -764,74 +129,981 @@ spawnflags(Flags) =
4 : "Crucified motionless"
16 : "Spawn Sleeping"
*/
-void() monster_zombie =
+class monster_zombie: base_walkmonster
{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (deathmatch /*&& (!(self.spawnflags & SPAWN_DEAD_CRUCIFIED))*/)
- {
- remove(self);
- return;
- }
-
- precache_body_model ("progs/zombie.mdl"); //custom_mdls dumptruck_ds
- precache_head_model ("progs/h_zombie.mdl");
- precache_proj_model ("progs/zom_gib.mdl");
- // precache_model ("progs/zombie.mdl");
- // precache_model ("progs/h_zombie.mdl");
- // precache_model ("progs/zom_gib.mdl");
-
- precache_sound_misc ("zombie/z_idle.wav");
- precache_sound_sight ("zombie/z_idle1.wav");
- precache_sound_attack ("zombie/z_shot1.wav");
- precache_sound_death ("zombie/z_gib.wav");
- precache_sound_pain ("zombie/z_pain.wav");
- precache_sound_misc2 ("zombie/z_pain1.wav");
- precache_sound_misc3 ("zombie/z_fall.wav");
- precache_sound ("zombie/z_miss.wav");
- precache_sound ("zombie/z_hit.wav");
-
- precache_sound_idle ("zombie/idle_w2.wav");
-
- precache_gib1 ("progs/gib1.mdl");
- precache_gib2 ("progs/gib2.mdl");
- precache_gib3 ("progs/gib3.mdl");
-
- self.th_stand = zombie_start;
- self.th_walk = zombie_walk1;
- if (self.spawnflags & I_AM_TURRET)
- {
- self.th_run = alt_zombie_seek_stand1;
- }
- else
- {
- self.th_run = zombie_decide;
- }
-
- self.th_pain = zombie_pain;
- self.th_die = zombie_die;
- self.th_turret = zombie_turret_missile;
- self.th_missile = zombie_missile;
- self.solid = SOLID_SLIDEBOX;
- self.movetype = MOVETYPE_STEP;
-
- body_model ("progs/zombie.mdl"); //custom_mdls dumptruck_ds
- // setmodel (self, "progs/zombie.mdl");
-
- setsize (self, '-16 -16 -24', '16 16 40');
- self.health = 61;
-
- if (self.spawnflags & SPAWN_CRUCIFIED)
- {
- self.movetype = MOVETYPE_NONE;
- zombie_cruc1 ();
- }
- else if (self.spawnflags & SPAWN_DEAD_CRUCIFIED)
- {
- self.movetype = MOVETYPE_NONE;
- zombie_dead_cruc1 ();
- }
- else
- walkmonster_start();
+ float attack_elevation;
+ float inpain;
+
+ //--------------------------------------------------------------
+ virtual void() ai_sightsound =
+ {
+ sound_sight (this, CHAN_VOICE, "zombie/z_idle.wav",
+ 1, ATTN_NORM);
+ };
+
+ //--------------------------------------------------------------
+ // PreachFireZombie -- for Z-Aware Zombies in Turret Mode only
+ //--------------------------------------------------------------
+ nonvirtual void(float elevation) fire_preach =
+ {
+ local entity missile;
+ local vector ang;
+
+ // this.effects = this.effects | EF_MUZZLEFLASH;
+
+ sound_attack (this, CHAN_WEAPON, "zombie/z_shot1.wav",
+ 1, ATTN_NORM);
+
+ missile = spawn ();
+ missile.owner = this;
+ missile.movetype = MOVETYPE_BOUNCE;
+ missile.solid = SOLID_BBOX;
+
+ // set missile speed
+ ang = this.angles;
+ ang_x = -elevation;
+ makevectors (ang);
+
+ missile.velocity = v_forward * OGRE_G_VEL;
+ missile.avelocity = '3000 1000 2000';
+ missile.angles = vectoangles(missile.velocity);
+ missile.touch = ZombieGrenadeTouch;
+
+ // set missile duration
+ missile.nextthink = time + 2.5;
+ missile.think = sub_remove;
+ // setmodel (missile, "progs/grenade.mdl");
+ // dumptruck_ds
+ if (this.mdl_proj != "")
+ {
+ setmodel (missile, this.mdl_proj);
+ }
+ else
+ {
+ setmodel (missile, "progs/zom_gib.mdl");
+ }
+
+ // dumptruck_ds
+ if (!missile.skin_proj)
+ {
+ missile.skin = this.skin_proj;
+ }
+ else
+ {
+ missile.skin = 0;
+ }
+
+ setsize (missile, '0 0 0', '0 0 0');
+ setorigin (missile, this.origin);
+ };
+
+ //--------------------------------------------------------------
+ nonvirtual void() fire_missile =
+ {
+ local float r;
+
+ r = random ();
+
+ if (r < 0.3)
+ this.atta1 ();
+ else if (r < 0.6)
+ this.attb1 ();
+ else
+ this.attc1 ();
+ };
+
+ //--------------------------------------------------------------
+ nonvirtual void() fire_turret_missile =
+ {
+ local float r;
+
+ r = random ();
+
+ if (r < 0.3)
+ this.turret_attb1 ();
+ else if (r < 0.6)
+ this.turret_atta1 ();
+ else
+ this.turret_attc1 ();
+ };
+
+ //--------------------------------------------------------------
+ // ZombieFireGrenade
+ //--------------------------------------------------------------
+ nonvirtual void(vector st) fire_grenade =
+ {
+ local entity nade;
+ local vector org;
+
+ sound_attack (this, CHAN_WEAPON, "zombie/z_shot1.wav",
+ 1, ATTN_NORM);
+
+ nade = spawn ();
+ nade.owner = this;
+ nade.movetype = MOVETYPE_BOUNCE;
+ nade.solid = SOLID_BBOX;
+
+ // calc org
+ org = this.origin + st_x * v_forward +
+ st_y * v_right +
+ (st_z - 24) * v_up;
+
+ // set missile speed
+ makevectors (this.angles);
+ nade.velocity = normalize (this.enemy.origin - org);
+ nade.velocity = nade.velocity * 600;
+ nade.velocity_z = 200;
+ nade.avelocity = '3000 1000 2000';
+ nade.touch = ZombieGrenadeTouch;
+
+ // set missile duration
+ nade.nextthink = time + 2.5;
+ nade.think = sub_remove;
+
+ // setmodel (nade, "progs/zom_gib.mdl");
+ // dumptruck_ds custom_mdls
+ if (this.mdl_proj != "")
+ {
+ setmodel (nade, this.mdl_proj);
+ }
+ else
+ {
+ setmodel (nade, "progs/zom_gib.mdl");
+ }
+
+ // dumptruck_ds
+ if (!nade.skin_proj)
+ {
+ nade.skin = this.skin_proj;
+ }
+ else
+ {
+ nade.skin = 0;
+ }
+
+ setsize (nade, '0 0 0', '0 0 0');
+ setorigin (nade, org);
+ };
+
+ //--------------------------------------------------------------
+ // motionless crucified zombie
+ //--------------------------------------------------------------
+ nonvirtual void() dead_cruc1 = [$cruc_1, dead_cruc1]
+ {
+ this.nextthink = time + 1;
+ };
+
+ //--------------------------------------------------------------
+ // crucified zombie
+ //--------------------------------------------------------------
+ nonvirtual void() cruc1 = [$cruc_1, cruc2]
+ {
+ if (random() < 0.1)
+ sound_idle (this, CHAN_VOICE, "zombie/idle_w2.wav",
+ 1, ATTN_STATIC);
+ };
+ nonvirtual void() cruc2 = [$cruc_2, cruc3]
+ {
+ this.nextthink = time + 0.1 + random() * 0.1;
+ };
+ nonvirtual void() cruc3 = [$cruc_3, cruc4]
+ {
+ this.nextthink = time + 0.1 + random() * 0.1;
+ };
+ nonvirtual void() cruc4 = [$cruc_4, cruc5]
+ {
+ this.nextthink = time + 0.1 + random() * 0.1;
+ };
+ nonvirtual void() cruc5 = [$cruc_5, cruc6]
+ {
+ this.nextthink = time + 0.1 + random() * 0.1;
+ };
+ nonvirtual void() cruc6 = [$cruc_6, cruc1]
+ {
+ this.nextthink = time + 0.1 + random() * 0.1;
+ };
+
+ //--------------------------------------------------------------
+ // new "stand" - for sleeping zombies
+ //--------------------------------------------------------------
+ nonvirtual void() stand1 = [$paine11, stand2]
+ {
+ this.solid = SOLID_NOT;
+ // dumptruck_ds -- count value > 0 to leave the zombie
+ // sleeping until triggered!
+ if (this.count == 0)
+ ai_stand ();
+ };
+ nonvirtual void() stand2 = [$paine11, stand1]
+ {
+ if (this.count == 0)
+ ai_stand ();
+ };
+
+ //--------------------------------------------------------------
+ // old "stand" - called when standing only
+ //--------------------------------------------------------------
+ nonvirtual void() alt_stand1 = [$stand1, alt_stand2]
+ {
+ this.health = 60;
+ ai_stand ();
+ };
+ nonvirtual void() alt_stand2 = [$stand2, stand3] { ai_stand (); };
+ nonvirtual void() stand3 = [$stand3, stand4] { ai_stand (); };
+ nonvirtual void() stand4 = [$stand4, stand5] { ai_stand (); };
+ nonvirtual void() stand5 = [$stand5, stand6] { ai_stand (); };
+ nonvirtual void() stand6 = [$stand6, stand7] { ai_stand (); };
+ nonvirtual void() stand7 = [$stand7, stand8] { ai_stand (); };
+ nonvirtual void() stand8 = [$stand8, stand9] { ai_stand (); };
+ nonvirtual void() stand9 = [$stand9, stand10] { ai_stand (); };
+ nonvirtual void() stand10 = [$stand10, stand11] { ai_stand (); };
+ nonvirtual void() stand11 = [$stand11, stand12] { ai_stand (); };
+ nonvirtual void() stand12 = [$stand12, stand13] { ai_stand (); };
+ nonvirtual void() stand13 = [$stand13, stand14] { ai_stand (); };
+ nonvirtual void() stand14 = [$stand14, stand15] { ai_stand (); };
+ nonvirtual void() stand15 = [$stand15, alt_stand1] { ai_stand (); };
+
+ //--------------------------------------------------------------
+ // Zombie walk (shamble? shuffle?) functions
+ //--------------------------------------------------------------
+ nonvirtual void() walk1 = [$walk1, walk2]
+ {
+ this.solid = SOLID_SLIDEBOX;
+ // so he doesn't fall
+ this.health = 60;
+ ai_walk (0);
+ };
+ nonvirtual void() walk2 = [$walk2, walk3] { ai_walk (2); };
+ nonvirtual void() walk3 = [$walk3, walk4] { ai_walk (3); };
+ nonvirtual void() walk4 = [$walk4, walk5] { ai_walk (2); };
+ nonvirtual void() walk5 = [$walk5, walk6] { ai_walk (1); };
+ nonvirtual void() walk6 = [$walk6, walk7] { ai_walk (0); };
+ nonvirtual void() walk7 = [$walk7, walk8] { ai_walk (0); };
+ nonvirtual void() walk8 = [$walk8, walk9] { ai_walk (0); };
+ nonvirtual void() walk9 = [$walk9, walk10] { ai_walk (0); };
+ nonvirtual void() walk10 = [$walk10, walk11] { ai_walk (0); };
+ nonvirtual void() walk11 = [$walk11, walk12] { ai_walk (2); };
+ nonvirtual void() walk12 = [$walk12, walk13] { ai_walk (2); };
+ nonvirtual void() walk13 = [$walk13, walk14] { ai_walk (1); };
+ nonvirtual void() walk14 = [$walk14, walk15] { ai_walk (0); };
+ nonvirtual void() walk15 = [$walk15, walk16] { ai_walk (0); };
+ nonvirtual void() walk16 = [$walk16, walk17] { ai_walk (0); };
+ nonvirtual void() walk17 = [$walk17, walk18] { ai_walk (0); };
+ nonvirtual void() walk18 = [$walk18, walk19] { ai_walk (0); };
+ nonvirtual void() walk19 = [$walk19, walk1]
+ {
+ ai_walk (0);
+ if (random() < 0.2)
+ sound_misc (this, CHAN_VOICE, "zombie/z_idle.wav",
+ 1, ATTN_IDLE);
+ };
+
+ //--------------------------------------------------------------
+ // Zombie run functions
+ //--------------------------------------------------------------
+ nonvirtual void() run1 = [$run1, run2]
+ {
+ if (this.spawnflags & ZOMBIE_SPAWN_SLEEPING)
+ {
+ // sloppy hack, but it fixes the illusionary zombie bug
+ // custom_mdls dumptruck_ds
+ body_model ("progs/zombie.mdl");
+ // setmodel (this, "progs/zombie.mdl");
+ setsize (this, '-16 -16 -24', '16 16 40');
+ }
+ ai_run (1);
+ this.inpain = 0;
+ };
+ nonvirtual void() run2 = [$run2, run3] { ai_run (1); };
+ nonvirtual void() run3 = [$run3, run4] { ai_run (0); };
+ nonvirtual void() run4 = [$run4, run5] { ai_run (1); };
+ nonvirtual void() run5 = [$run5, run6] { ai_run (2); };
+ nonvirtual void() run6 = [$run6, run7] { ai_run (3); };
+ nonvirtual void() run7 = [$run7, run8] { ai_run (4); };
+ nonvirtual void() run8 = [$run8, run9] { ai_run (4); };
+ nonvirtual void() run9 = [$run9, run10] { ai_run (2); };
+ nonvirtual void() run10 = [$run10, run11] { ai_run (0); };
+ nonvirtual void() run11 = [$run11, run12] { ai_run (0); };
+ nonvirtual void() run12 = [$run12, run13] { ai_run (0); };
+ nonvirtual void() run13 = [$run13, run14] { ai_run (2); };
+ nonvirtual void() run14 = [$run14, run15] { ai_run (4); };
+ nonvirtual void() run15 = [$run15, run16] { ai_run (6); };
+ nonvirtual void() run16 = [$run16, run17] { ai_run (7); };
+ nonvirtual void() run17 = [$run17, run18] { ai_run (3); };
+ nonvirtual void() run18 = [$run18, run1]
+ {
+ ai_run (8);
+ if (random() < 0.2)
+ sound_misc (this, CHAN_VOICE, "zombie/z_idle.wav",
+ 1, ATTN_IDLE);
+ if (random() > 0.8)
+ sound_sight (this, CHAN_VOICE, "zombie/z_idle1.wav",
+ 1, ATTN_IDLE);
+ };
+
+ //--------------------------------------------------------------
+ // Zombie Attack A
+ //--------------------------------------------------------------
+ nonvirtual void() atta1 = [$atta1, atta2] { ai_face (); };
+ nonvirtual void() atta2 = [$atta2, atta3] { ai_face (); };
+ nonvirtual void() atta3 = [$atta3, atta4] { ai_face (); };
+ nonvirtual void() atta4 = [$atta4, atta5] { ai_face (); };
+ nonvirtual void() atta5 = [$atta5, atta6] { ai_face (); };
+ nonvirtual void() atta6 = [$atta6, atta7] { ai_face (); };
+ nonvirtual void() atta7 = [$atta7, atta8] { ai_face (); };
+ nonvirtual void() atta8 = [$atta8, atta9] { ai_face (); };
+ nonvirtual void() atta9 = [$atta9, atta10] { ai_face (); };
+ nonvirtual void() atta10 = [$atta10, atta11] { ai_face (); };
+ nonvirtual void() atta11 = [$atta11, atta12] { ai_face (); };
+ nonvirtual void() atta12 = [$atta12, atta13] { ai_face (); };
+ nonvirtual void() atta13 = [$atta13, run1]
+ {
+ ai_face ();
+ this.fire_grenade ('-10 -22 30');
+ };
+
+ //--------------------------------------------------------------
+ // Zombie Attack B
+ //--------------------------------------------------------------
+ nonvirtual void() attb1 = [$attb1, attb2] { ai_face (); };
+ nonvirtual void() attb2 = [$attb2, attb3] { ai_face (); };
+ nonvirtual void() attb3 = [$attb3, attb4] { ai_face (); };
+ nonvirtual void() attb4 = [$attb4, attb5] { ai_face (); };
+ nonvirtual void() attb5 = [$attb5, attb6] { ai_face (); };
+ nonvirtual void() attb6 = [$attb6, attb7] { ai_face (); };
+ nonvirtual void() attb7 = [$attb7, attb8] { ai_face (); };
+ nonvirtual void() attb8 = [$attb8, attb9] { ai_face (); };
+ nonvirtual void() attb9 = [$attb9, attb10] { ai_face (); };
+ nonvirtual void() attb10 = [$attb10, attb11] { ai_face (); };
+ nonvirtual void() attb11 = [$attb11, attb12] { ai_face (); };
+ nonvirtual void() attb12 = [$attb12, attb13] { ai_face (); };
+ nonvirtual void() attb13 = [$attb13, attb14] { ai_face (); };
+ nonvirtual void() attb14 = [$attb13, run1]
+ {
+ ai_face ();
+ this.fire_grenade ('-10 -24 29');
+ };
+
+ //--------------------------------------------------------------
+ // Zombie Attack C
+ //--------------------------------------------------------------
+ nonvirtual void() attc1 = [$attc1, attc2] { ai_face (); };
+ nonvirtual void() attc2 = [$attc2, attc3] { ai_face (); };
+ nonvirtual void() attc3 = [$attc3, attc4] { ai_face (); };
+ nonvirtual void() attc4 = [$attc4, attc5] { ai_face (); };
+ nonvirtual void() attc5 = [$attc5, attc6] { ai_face (); };
+ nonvirtual void() attc6 = [$attc6, attc7] { ai_face (); };
+ nonvirtual void() attc7 = [$attc7, attc8] { ai_face (); };
+ nonvirtual void() attc8 = [$attc8, attc9] { ai_face (); };
+ nonvirtual void() attc9 = [$attc9, attc10] { ai_face (); };
+ nonvirtual void() attc10 = [$attc10, attc11] { ai_face (); };
+ nonvirtual void() attc11 = [$attc11, attc12] { ai_face (); };
+ nonvirtual void() attc12 = [$attc12, run1]
+ {
+ ai_face ();
+ this.fire_grenade ('-12 -19 29');
+ };
+
+ ///////////////////////////
+ /// turret frames START ///
+ ///////////////////////////
+
+ //--------------------------------------------------------------
+ // Zombie Turret Attack A
+ //--------------------------------------------------------------
+ nonvirtual void() turret_atta1 = [$atta1, turret_atta2]
+ {
+ this.health = 60;
+ ai_face ();
+ };
+ nonvirtual void() turret_atta2 = [$atta2, turret_atta3] { ai_face (); };
+ nonvirtual void() turret_atta3 = [$atta3, turret_atta4] { ai_face (); };
+ nonvirtual void() turret_atta4 = [$atta4, turret_atta5] { ai_face (); };
+ nonvirtual void() turret_atta5 = [$atta5, turret_atta6] { ai_face (); };
+ nonvirtual void() turret_atta6 = [$atta6, turret_atta7] { ai_face (); };
+ nonvirtual void() turret_atta7 = [$atta7, turret_atta8] { ai_face (); };
+ nonvirtual void() turret_atta8 = [$atta8, turret_atta9] { ai_face (); };
+ nonvirtual void() turret_atta9 = [$atta9, turret_atta10] { ai_face ();};
+ nonvirtual void() turret_atta10 = [$atta10, turret_atta11]
+ {
+ ai_face ();
+ this.attack_elevation = IterateElevation (
+ OGRE_DEFAULT_ELEVATION, this.origin, this.enemy.origin);
+ };
+ nonvirtual void() turret_atta11 = [$atta11, turret_atta12]
+ {
+ ai_face ();
+ this.attack_elevation = IterateElevation (
+ this.attack_elevation, this.origin, this.enemy.origin);
+ };
+ nonvirtual void() turret_atta12 = [$atta12, turret_atta13]
+ {
+ ai_face ();
+ this.attack_elevation = IterateElevation (
+ this.attack_elevation, this.origin, this.enemy.origin);
+ };
+ nonvirtual void() turret_atta13 = [$atta13, alt_seek1]
+ {
+ ai_run (0);
+ fire_preach (this.attack_elevation);
+ };
+
+ //--------------------------------------------------------------
+ // Zombie Turret Attack B
+ //--------------------------------------------------------------
+ nonvirtual void() turret_attb1 = [$attb1, turret_attb2]
+ {
+ this.health = 60;
+ ai_face ();
+ };
+ nonvirtual void() turret_attb2 = [$attb2, turret_attb3] { ai_face (); };
+ nonvirtual void() turret_attb3 = [$attb3, turret_attb4] { ai_face (); };
+ nonvirtual void() turret_attb4 = [$attb4, turret_attb5] { ai_face (); };
+ nonvirtual void() turret_attb5 = [$attb5, turret_attb6] { ai_face (); };
+ nonvirtual void() turret_attb6 = [$attb6, turret_attb7] { ai_face (); };
+ nonvirtual void() turret_attb7 = [$attb7, turret_attb8] { ai_face (); };
+ nonvirtual void() turret_attb8 = [$attb8, turret_attb9] { ai_face (); };
+ nonvirtual void() turret_attb9 = [$attb9, turret_attb10] { ai_face ();};
+ nonvirtual void() turret_attb10 = [$attb10, turret_attb11] {ai_face();};
+ nonvirtual void() turret_attb11 = [$attb11, turret_attb12]
+ {
+ ai_face ();
+ this.attack_elevation = IterateElevation (
+ OGRE_DEFAULT_ELEVATION, this.origin, this.enemy.origin);
+ };
+ nonvirtual void() turret_attb12 = [$attb12, turret_attb13]
+ {
+ ai_face ();
+ this.attack_elevation = IterateElevation (
+ this.attack_elevation, this.origin, this.enemy.origin);
+ };
+ nonvirtual void() turret_attb13 = [$attb13, turret_attb14]
+ {
+ ai_face ();
+ this.attack_elevation = IterateElevation (
+ this.attack_elevation, this.origin, this.enemy.origin);
+ };
+ nonvirtual void() turret_attb14 = [$attb13, alt_seek1]
+ {
+ ai_run (0);
+ fire_preach (this.attack_elevation);
+ };
+
+ //--------------------------------------------------------------
+ // Zombie Turret Attack C
+ //--------------------------------------------------------------
+ nonvirtual void() turret_attc1 = [$attc1, turret_attc2]
+ {
+ this.health = 60;
+ ai_face ();
+ };
+ nonvirtual void() turret_attc2 = [$attc2, turret_attc3] { ai_face (); };
+ nonvirtual void() turret_attc3 = [$attc3, turret_attc4] { ai_face (); };
+ nonvirtual void() turret_attc4 = [$attc4, turret_attc5] { ai_face (); };
+ nonvirtual void() turret_attc5 = [$attc5, turret_attc6] { ai_face (); };
+ nonvirtual void() turret_attc6 = [$attc6, turret_attc7] { ai_face (); };
+ nonvirtual void() turret_attc7 = [$attc7, turret_attc8] { ai_face (); };
+ nonvirtual void() turret_attc8 = [$attc8, turret_attc9] { ai_face (); };
+ nonvirtual void() turret_attc9 = [$attc9, turret_attc10]
+ {
+ ai_face ();
+ this.attack_elevation = IterateElevation (
+ OGRE_DEFAULT_ELEVATION, this.origin, this.enemy.origin);
+ };
+ nonvirtual void() turret_attc10 = [$attc10, turret_attc11]
+ {
+ ai_face ();
+ this.attack_elevation = IterateElevation (
+ this.attack_elevation, this.origin, this.enemy.origin);
+ };
+ nonvirtual void() turret_attc11 = [$attc11, turret_attc12]
+ {
+ ai_face ();
+ this.attack_elevation = IterateElevation (
+ this.attack_elevation, this.origin, this.enemy.origin);
+ };
+ nonvirtual void() turret_attc12 = [$attc12, alt_seek1]
+ {
+ ai_run (0);
+ fire_preach (this.attack_elevation);
+ };
+
+ //--------------------------------------------------------------
+ // Zombie Turret Seek Stand
+ //--------------------------------------------------------------
+ nonvirtual void() alt_seek1 = [$stand1, alt_seek2]
+ {
+ this.health = 60;
+ ai_run(0);
+ };
+ nonvirtual void() alt_seek2 = [$stand2, seek3 ] { ai_run (0); };
+ nonvirtual void() seek3 = [$stand3, seek4] { ai_run (0); };
+ nonvirtual void() seek4 = [$stand4, seek5] { ai_run (0); };
+ nonvirtual void() seek5 = [$stand5, seek6] { ai_run (0); };
+ nonvirtual void() seek6 = [$stand6, seek7] { ai_run (0); };
+ nonvirtual void() seek7 = [$stand7, seek8] { ai_run (0); };
+ nonvirtual void() seek8 = [$stand8, seek9] { ai_run (0); };
+ nonvirtual void() seek9 = [$stand9, seek10] { ai_run (0); };
+ nonvirtual void() seek10 = [$stand10, seek11] { ai_run (0); };
+ nonvirtual void() seek11 = [$stand11, seek12] { ai_run (0); };
+ nonvirtual void() seek12 = [$stand12, seek13] { ai_run (0); };
+ nonvirtual void() seek13 = [$stand13, seek14] { ai_run (0); };
+ nonvirtual void() seek14 = [$stand14, seek15] { ai_run (0); };
+ nonvirtual void() seek15 = [$stand15, alt_seek1] { ai_run (0); };
+
+ ///////////////////////////
+ /// turret frames END ///
+ ///////////////////////////
+
+ //--------------------------------------------------------------
+ // Zombie Pain State A
+ //--------------------------------------------------------------
+ nonvirtual void() paina1 = [$paina1, paina2]
+ {
+ sound_pain (this, CHAN_VOICE, "zombie/z_pain.wav",
+ 1, ATTN_NORM);
+ };
+ nonvirtual void() paina2 = [$paina2, paina3] { ai_painforward (3); };
+ nonvirtual void() paina3 = [$paina3, paina4] { ai_painforward (1); };
+ nonvirtual void() paina4 = [$paina4, paina5] { ai_pain (1); };
+ nonvirtual void() paina5 = [$paina5, paina6] { ai_pain (3); };
+ nonvirtual void() paina6 = [$paina6, paina7] { ai_pain (1); };
+ nonvirtual void() paina7 = [$paina7, paina8] { };
+ nonvirtual void() paina8 = [$paina8, paina9] { };
+ nonvirtual void() paina9 = [$paina9, paina10] { };
+ nonvirtual void() paina10 = [$paina10, paina11] { };
+ nonvirtual void() paina11 = [$paina11, paina12] { };
+ nonvirtual void() paina12 = [$paina12, run1] { };
+
+ //--------------------------------------------------------------
+ // Zombie Pain State B
+ //--------------------------------------------------------------
+ nonvirtual void() painb1 = [$painb1, painb2]
+ {
+ sound_misc2 (this, CHAN_VOICE, "zombie/z_pain1.wav",
+ 1, ATTN_NORM);
+ };
+ nonvirtual void() painb2 = [$painb2, painb3] { ai_pain (2); };
+ nonvirtual void() painb3 = [$painb3, painb4] { ai_pain (8); };
+ nonvirtual void() painb4 = [$painb4, painb5] { ai_pain (6); };
+ nonvirtual void() painb5 = [$painb5, painb6] { ai_pain (2); };
+ nonvirtual void() painb6 = [$painb6, painb7] { };
+ nonvirtual void() painb7 = [$painb7, painb8] { };
+ nonvirtual void() painb8 = [$painb8, painb9] { };
+ nonvirtual void() painb9 = [$painb9, painb10]
+ {
+ sound_misc3 (this, CHAN_BODY, "zombie/z_fall.wav",
+ 1, ATTN_NORM);
+ };
+ nonvirtual void() painb10 = [$painb10, painb11] { };
+ nonvirtual void() painb11 = [$painb11, painb12] { };
+ nonvirtual void() painb12 = [$painb12, painb13] { };
+ nonvirtual void() painb13 = [$painb13, painb14] { };
+ nonvirtual void() painb14 = [$painb14, painb15] { };
+ nonvirtual void() painb15 = [$painb15, painb16] { };
+ nonvirtual void() painb16 = [$painb16, painb17] { };
+ nonvirtual void() painb17 = [$painb17, painb18] { };
+ nonvirtual void() painb18 = [$painb18, painb19] { };
+ nonvirtual void() painb19 = [$painb19, painb20] { };
+ nonvirtual void() painb20 = [$painb20, painb21] { };
+ nonvirtual void() painb21 = [$painb21, painb22] { };
+ nonvirtual void() painb22 = [$painb22, painb23] { };
+ nonvirtual void() painb23 = [$painb23, painb24] { };
+ nonvirtual void() painb24 = [$painb24, painb25] { };
+ nonvirtual void() painb25 = [$painb25, painb26] { ai_painforward (1); };
+ nonvirtual void() painb26 = [$painb26, painb27] { };
+ nonvirtual void() painb27 = [$painb27, painb28] { };
+ nonvirtual void() painb28 = [$painb28, run1] { };
+
+ //--------------------------------------------------------------
+ // Zombie Pain State C
+ //--------------------------------------------------------------
+ nonvirtual void() painc1 = [$painc1, painc2]
+ {
+ sound_misc2 (this, CHAN_VOICE, "zombie/z_pain1.wav",
+ 1, ATTN_NORM);
+ };
+ nonvirtual void() painc2 = [$painc2, painc3] { };
+ nonvirtual void() painc3 = [$painc3, painc4] { ai_pain (3); };
+ nonvirtual void() painc4 = [$painc4, painc5] { ai_pain (1); };
+ nonvirtual void() painc5 = [$painc5, painc6] { };
+ nonvirtual void() painc6 = [$painc6, painc7] { };
+ nonvirtual void() painc7 = [$painc7, painc8] { };
+ nonvirtual void() painc8 = [$painc8, painc9] { };
+ nonvirtual void() painc9 = [$painc9, painc10] { };
+ nonvirtual void() painc10 = [$painc10, painc11] { };
+ nonvirtual void() painc11 = [$painc11, painc12] { ai_painforward (1); };
+ nonvirtual void() painc12 = [$painc12, painc13] { ai_painforward (1); };
+ nonvirtual void() painc13 = [$painc13, painc14] { };
+ nonvirtual void() painc14 = [$painc14, painc15] { };
+ nonvirtual void() painc15 = [$painc15, painc16] { };
+ nonvirtual void() painc16 = [$painc16, painc17] { };
+ nonvirtual void() painc17 = [$painc17, painc18] { };
+ nonvirtual void() painc18 = [$painc18, run1] { };
+
+ //--------------------------------------------------------------
+ // Zombie Pain State D
+ //--------------------------------------------------------------
+ nonvirtual void() paind1 = [$paind1, paind2]
+ {
+ sound_pain (this, CHAN_VOICE, "zombie/z_pain.wav",
+ 1, ATTN_NORM);
+ };
+ nonvirtual void() paind2 = [$paind2, paind3] { };
+ nonvirtual void() paind3 = [$paind3, paind4] { };
+ nonvirtual void() paind4 = [$paind4, paind5] { };
+ nonvirtual void() paind5 = [$paind5, paind6] { };
+ nonvirtual void() paind6 = [$paind6, paind7] { };
+ nonvirtual void() paind7 = [$paind7, paind8] { };
+ nonvirtual void() paind8 = [$paind8, paind9] { };
+ nonvirtual void() paind9 = [$paind9, paind10] { ai_pain (1); };
+ nonvirtual void() paind10 = [$paind10, paind11] { };
+ nonvirtual void() paind11 = [$paind11, paind12] { };
+ nonvirtual void() paind12 = [$paind12, paind13] { };
+ nonvirtual void() paind13 = [$paind13, run1] { };
+
+ //--------------------------------------------------------------
+ // Zombie Pain State E
+ //--------------------------------------------------------------
+ nonvirtual void() paine1 = [$paine1, paine2]
+ {
+ // Chainsaw will gib zombie
+ if (this.axhitme == 2)
+ {
+ T_Damage (this, world, world, 80);
+ return;
+ }
+ sound_pain (this, CHAN_VOICE, "zombie/z_pain.wav",
+ 1, ATTN_NORM);
+ this.health = 60;
+ };
+ nonvirtual void() paine2 = [$paine2, paine3] { ai_pain (8); };
+ nonvirtual void() paine3 = [$paine3, paine4] { ai_pain (5); };
+ nonvirtual void() paine4 = [$paine4, paine5] { ai_pain (3); };
+ nonvirtual void() paine5 = [$paine5, paine6] { ai_pain (1); };
+ nonvirtual void() paine6 = [$paine6, paine7] { ai_pain (2); };
+ nonvirtual void() paine7 = [$paine7, paine8] { ai_pain (1); };
+ nonvirtual void() paine8 = [$paine8, paine9] { ai_pain (1); };
+ nonvirtual void() paine9 = [$paine9, paine10] { ai_pain (2); };
+ nonvirtual void() paine10 = [$paine10, paine11]
+ {
+ sound_misc3 (this, CHAN_BODY, "zombie/z_fall.wav",
+ 1, ATTN_NORM);
+ this.solid = SOLID_NOT;
+ };
+ nonvirtual void() paine11 = [$paine11, paine12]
+ {
+ this.nextthink = this.nextthink + 5;
+ this.health = 60;
+ };
+ nonvirtual void() paine12 = [$paine12, paine13]
+ {
+ // see if ok to stand up
+ this.health = 60;
+ sound_misc (this, CHAN_VOICE, "zombie/z_idle.wav",
+ 1, ATTN_IDLE);
+ this.solid = SOLID_SLIDEBOX;
+ if (!walkmove(0, 0))
+ {
+ this.think = paine11;
+ this.solid = SOLID_NOT;
+ return;
+ }
+ };
+ nonvirtual void() paine13 = [$paine13, paine14] { };
+ nonvirtual void() paine14 = [$paine14, paine15] { };
+ nonvirtual void() paine15 = [$paine15, paine16] { };
+ nonvirtual void() paine16 = [$paine16, paine17] { };
+ nonvirtual void() paine17 = [$paine17, paine18] { };
+ nonvirtual void() paine18 = [$paine18, paine19] { };
+ nonvirtual void() paine19 = [$paine19, paine20] { };
+ nonvirtual void() paine20 = [$paine20, paine21] { };
+ nonvirtual void() paine21 = [$paine21, paine22] { };
+ nonvirtual void() paine22 = [$paine22, paine23] { };
+ nonvirtual void() paine23 = [$paine23, paine24] { };
+ nonvirtual void() paine24 = [$paine24, paine25] { };
+ nonvirtual void() paine25 = [$paine25, paine26] { ai_painforward (5); };
+ nonvirtual void() paine26 = [$paine26, paine27] { ai_painforward (3); };
+ nonvirtual void() paine27 = [$paine27, paine28] { ai_painforward (1); };
+ nonvirtual void() paine28 = [$paine28, paine29] { ai_pain (1); };
+ nonvirtual void() paine29 = [$paine29, paine30] { };
+ nonvirtual void() paine30 = [$paine30, run1] { };
+
+ //==============================================================
+ // Interaction
+ //==============================================================
+
+ //--------------------------------------------------------------
+ // zombie_pain
+ //
+ // Zombies can only be killed (gibbed) by doing 60 hit points of
+ // damage in a single frame (rockets, grenades, quad shotgun,
+ // quad nailgun).
+ //
+ // A hit of 25 points or more (super shotgun, quad nailgun) will
+ // always put it down to the ground.
+ //
+ // A hit of from 10 to 40 points in one frame will cause it to
+ // go down if it has been twice in two seconds, otherwise it
+ // goes into one of the four fast pain frames.
+ //
+ // A hit of less than 10 points of damage (winged by a shotgun)
+ // will be ignored.
+ //
+ // FIXME: don't use pain_finished because of nightmare hack
+ //--------------------------------------------------------------
+ virtual void(entity attacker, float take) do_damage =
+ {
+ if (this.spawnflags & I_AM_TURRET)
+ {
+ // always reset health
+ this.health = 60;
+ if (take >= 60)
+ this.do_destroy ();
+ else
+ return;
+ }
+
+ local float r;
+
+ // always reset health
+ this.health = 60;
+
+ if (take < 9)
+ // totally ignore
+ return;
+
+ if (this.inpain == 2)
+ // down on ground, so don't reset any counters
+ return;
+
+ // go down immediately if a big enough hit
+ if ((take >= 25) || (this.axhitme == 2))
+ {
+ this.inpain = 2;
+ this.paine1 ();
+ return;
+ }
+
+ if (this.inpain)
+ {
+ // if hit again in next gre seconds while
+ // not in pain frames, definately drop
+ this.pain_finished = time + 3;
+ // currently going through an animation, don't change
+ return;
+ }
+
+ if (this.pain_finished > time)
+ {
+ // hit again, so drop down
+ this.inpain = 2;
+ this.paine1 ();
+ return;
+ }
+
+ // gp into one of the fast pain animations
+ this.inpain = 1;
+
+ r = random ();
+ if (r < 0.25)
+ this.paina1 ();
+ else if (r < 0.5)
+ this.painb1 ();
+ else if (r < 0.75)
+ this.painc1 ();
+ else
+ this.paind1 ();
+ };
+
+ //--------------------------------------------------------------
+ // zombie_die
+ //--------------------------------------------------------------
+ virtual void() do_destroy =
+ {
+ sound_death (this, CHAN_VOICE, "zombie/z_gib.wav",
+ 1, ATTN_NORM);
+
+ // dumptruck_ds custom_mdls
+ if (this.mdl_head != "")
+ {
+ ThrowHead (this.mdl_head, this.health);
+ }
+ else
+ {
+ // commented out dest -- dumptruck_ds
+ ThrowHead ("progs/h_zombie.mdl", this.health);
+ }
+ // ThrowGib ("progs/gib1.mdl", this.health/*, this.dest*/);
+ // ThrowGib ("progs/gib2.mdl", this.health/*, this.dest*/);
+ // ThrowGib ("progs/gib3.mdl", this.health/*, this.dest*/);
+ // custom models -- dumptruck_ds
+ if (this.mdl_gib1 != "")
+ {
+ ThrowGib (this.mdl_gib1, this.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib1.mdl", this.health);
+ }
+ if (this.mdl_gib2 != "")
+ {
+ ThrowGib (this.mdl_gib2, this.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib2.mdl", this.health);
+ }
+ if (this.mdl_gib3 != "")
+ {
+ ThrowGib (this.mdl_gib3, this.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib3.mdl", this.health);
+ }
+ base_item::drop_stuff (this);
+ };
+
+ //--------------------------------------------------------------
+ // dumptruck_ds -- makes self.count = 0 so zombie_stand1 is called
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_use =
+ {
+ // wake up a sleeping zombie!
+ this.count = 0;
+ // attacker = other;
+ // monster_use
+ super::do_use (caller);
+ };
+
+ //==============================================================
+ // Initialization
+ //==============================================================
+
+ //--------------------------------------------------------------
+ // stand up if orig. lying down, else just start running
+ //--------------------------------------------------------------
+ nonvirtual void() zombie_decide =
+ {
+ if (this.health == 61)
+ this.paine12 ();
+ else
+ this.run1 ();
+
+ this.think_run = this.run1;
+ };
+
+ //--------------------------------------------------------------
+ // determine if zombie is to be lying down, or standing
+ // shims think_stand -- CEV
+ //--------------------------------------------------------------
+ nonvirtual void() zombie_start =
+ {
+ // dumptruck_ds -- Don't start zombie_stand1 yet!
+ this.count = 1;
+
+ if (this.spawnflags & ZOMBIE_SPAWN_SLEEPING)
+ {
+ if (!sub_istargeted())
+ {
+ dprint (sprintf("monster_zombie::zombie_start: "
+ "WARNING removed untargeted sleeping "
+ "zombie at %v\n", this.origin));
+
+ monster_update_total (-1);
+ remove (this);
+ return;
+ }
+ this.inpain = 2;
+ this.stand1 ();
+ }
+ else
+ {
+ this.alt_stand1 ();
+ }
+
+ this.think_stand = this.alt_stand1;
+ };
+
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
+ {
+ if (deathmatch)
+ {
+ remove (this);
+ return;
+ }
+
+ // custom_mdls dumptruck_ds
+ precache_body_model ("progs/zombie.mdl");
+ precache_head_model ("progs/h_zombie.mdl");
+ precache_proj_model ("progs/zom_gib.mdl");
+ // precache_model ("progs/zombie.mdl");
+ // precache_model ("progs/h_zombie.mdl");
+ // precache_model ("progs/zom_gib.mdl");
+
+ precache_sound_misc ("zombie/z_idle.wav");
+ precache_sound_sight ("zombie/z_idle1.wav");
+ precache_sound_attack ("zombie/z_shot1.wav");
+ precache_sound_death ("zombie/z_gib.wav");
+ precache_sound_pain ("zombie/z_pain.wav");
+ precache_sound_misc2 ("zombie/z_pain1.wav");
+ precache_sound_misc3 ("zombie/z_fall.wav");
+ precache_sound ("zombie/z_miss.wav");
+ precache_sound ("zombie/z_hit.wav");
+
+ precache_sound_idle ("zombie/idle_w2.wav");
+
+ precache_gib1 ("progs/gib1.mdl");
+ precache_gib2 ("progs/gib2.mdl");
+ precache_gib3 ("progs/gib3.mdl");
+
+ this.think_stand = this.zombie_start;
+ this.think_walk = this.walk1;
+ if (this.spawnflags & I_AM_TURRET)
+ {
+ this.think_run = this.alt_seek1;
+ }
+ else
+ {
+ this.think_run = this.zombie_decide;
+ }
+
+ this.th_pain = this.do_damage;
+ this.th_die = this.do_destroy;
+ this.think_turret = fire_turret_missile;
+ this.think_missile = fire_missile;
+ this.solid = SOLID_SLIDEBOX;
+ this.movetype = MOVETYPE_STEP;
+
+ // custom_mdls dumptruck_ds
+ body_model ("progs/zombie.mdl");
+ // setmodel (this, "progs/zombie.mdl");
+
+ setsize (this, '-16 -16 -24', '16 16 40');
+ this.health = 61;
+
+ if (this.spawnflags & ZOMBIE_SPAWN_CRUCIFIED)
+ {
+ this.movetype = MOVETYPE_NONE;
+ this.cruc1 ();
+ }
+ else if (this.spawnflags & ZOMBIE_SPAWN_DEAD_CRUCIFIED)
+ {
+ this.movetype = MOVETYPE_NONE;
+ this.dead_cruc1 ();
+ }
+ else
+ {
+ // walkmonster_start
+ super::init_spawned ();
+ }
+ };
+
+ //--------------------------------------------------------------
+ void() monster_zombie =
+ {
+ this.classtype = CT_MONSTER_ZOMBIE;
+ };
};
Return to the top of this page or return to the overview of this repo.
Diff qc/newflags.qc
diff --git a/qc/newflags.qc b/qc/newflags.qc
index ef462ad..fa19279 100644
--- a/qc/newflags.qc
+++ b/qc/newflags.qc
@@ -70,7 +70,7 @@ float done_inhibition_summary;
//----------------------------------------------------------------------
// InitNewSpawnflags
-//
+//
// This function is intended to be called from the top of the worldspawn
// function (in world.qc). -- iw
//----------------------------------------------------------------------
@@ -146,7 +146,7 @@ float() SUB_Inhibit =
//----------------------------------------------------------------------
// PrintInhibitionTotal
-//
+//
// This just dprints the summary line about the total number of entities
// inhibited by one of the new spawnflags (see PrintInhibitionSummary
// below). -- iw
Return to the top of this page or return to the overview of this repo.
Diff qc/player/player.qc
diff --git a/qc/player/player.qc b/qc/player/player.qc
index 1724b94..22a3aa7 100644
--- a/qc/player/player.qc
+++ b/qc/player/player.qc
@@ -817,7 +817,7 @@ void() PlayerDie =
self.modelindex = modelindex_player;
if (deathmatch || coop)
- item_backpack::drop_backpack (self);
+ item_backpack::drop_backpack (self.origin, self.weapon, self.ammo_shells, self.ammo_nails, self.ammo_rockets, self.ammo_cells);
self.weaponmodel = "";
self.view_ofs = '0 0 -8';
@@ -1043,7 +1043,6 @@ void() info_player_deathmatch =
return;
self.alpha = 0.2;
- self.glowmod = [4.0, 4.0, 4.0];
self.model = "progs/player.mdl";
self.frame = $axstnd1;
setmodel (self, self.model);
Return to the top of this page or return to the overview of this repo.
Diff qc/player/playerthink.qc
diff --git a/qc/player/playerthink.qc b/qc/player/playerthink.qc
index 625f97a..260b292 100644
--- a/qc/player/playerthink.qc
+++ b/qc/player/playerthink.qc
@@ -592,7 +592,7 @@ void() PlayerPostThink =
self.jump_flag = self.velocity_z;
// dumptruck_ds -- this replaces item_megahealth_rot in items.qc
- if (self.health > self.max_health)
+ if (self.health > self.max_health)
{
if (self.megahealth_rottime < time)
{
Return to the top of this page or return to the overview of this repo.
Diff qc/player/pmove.qc
diff --git a/qc/player/pmove.qc b/qc/player/pmove.qc
index be4ca5d..ed699d7 100644
--- a/qc/player/pmove.qc
+++ b/qc/player/pmove.qc
@@ -32,10 +32,10 @@ const float PM_AIRACCELQ3 = 0.75f; // 1.0 in Q3 ?; now 0.75 or 0.8
const float PM_AIRACCELFWD = 0.75f; // 1 feels close to Q3 / CPM
const float PM_AIRACCELBACK = 5.0f; // Air stop speed in Q3?
const float PM_AIRACCELTURN = 100.0f; // affects +fwd style turning radius
-const float PM_BOOSTACCEL = 11.875f; // ground boost accel; 10 is enough; 11
+const float PM_BOOSTACCEL = 11.25f; // ground boost accel; 10; 10 + 1.25
const float PM_BOOSTFRICTION = 4.0f; // ground boost friction; 4 is Q1
-const float PM_GROUNDACCEL = 13.75f; // 10 is Q1, 15 is CPM; 12.5? 13.75?
-const float PM_GROUNDFRICTION = 8.0f; // 4 for Q1, 6 for Q3, 8 for CPM
+const float PM_GROUNDACCEL = 13.75f; // 10 is Q1, 15 is CPM; 15 - 1.25
+const float PM_GROUNDFRICTION = 8.0f; // 4 for Q1, 6 for Q3, 8 for (old?) CPM
const vector PM_GROUNDDIST_V = '0 0 1'; // distance for ground check
const float PM_WATERACCEL = 10.0f; // water acceleration
const float PM_WATERFRICTION = 4.0f; // friction in water
@@ -68,7 +68,7 @@ const float PM_DOUBLEJUMP_WINDOW = 0.4f;// 2 jumps in this time is a double
const float PM_GROUNDBOOST_WINDOW = 0.4f;// groundboost duration
const float PM_TELEJUMP_WINDOW = 0.4f; // duration to perform a telejump
const float PM_WALLJUMP_WINDOW = 0.2f; // duration between walljumps
-const float PM_WALLCLIP_WINDOW = 0.25f; //
+const float PM_WALLCLIP_WINDOW = 0.25f; //
// misc
const float PM_OVERCLIP = 1.0f; // Quake3's OVERCLIP is 1.001f
@@ -82,7 +82,7 @@ const int WATERLEVEL_FEET = 1;
const int WATERLEVEL_WAIST = 2;
const int WATERLEVEL_EYES = 3;
-//
+//
const vector CROUCHED_MINS = '-16 -16 -18';// VEC_HULL_MIN is '-16 -16 -24'
const vector CROUCHED_MAXS = '16 16 18';// VEC_HULL_MAX is '16 16 32'
@@ -146,7 +146,7 @@ static void(entity ent) PM_DoTouch =
if (ent && (ent.classgroup & CG_MAPENTITY))
{
other = self;
- ((base_mapentity)ent).handle_touch (self);
+ ((base_mapentity)ent).touch ();
return;
}
#endif
@@ -184,13 +184,13 @@ float() PM_Nudge =
test = org;
static float offsets[] = {0, -1./8, 1./8, -2./8, 2./8};
- for (float z = 0; z < offsets.length; z++)
+ for (float z = 0; z < offsets.length; z++)
{
test.z = org.z + offsets[z];
- for (float y = 0; y < offsets.length; y++)
+ for (float y = 0; y < offsets.length; y++)
{
test.y = org.y + offsets[y];
- for (float x = 0; x < offsets.length; x++)
+ for (float x = 0; x < offsets.length; x++)
{
test.x = org.x + offsets[x];
tracebox (test, self.mins, self.maxs, test,
@@ -257,7 +257,7 @@ void(float dogravity, float sticky, float dostep, float doskim) PM_DanceMove =
if (autocvar(pm_nostep, FALSE))
dostep = FALSE;
- // we need to bounce off surfaces (in order to slide along them),
+ // we need to bounce off surfaces (in order to slide along them),
// so we need at 2 attempts -- comment from the Nuclide SDK
// I've changed this to a larger number of attempts (from 3 to 5)
// to accommodate more complex plane interactions -- CEV
@@ -319,7 +319,7 @@ void(float dogravity, float sticky, float dostep, float doskim) PM_DanceMove =
// but this solves more interactions (ztndm3) -- CEV
local float roof_fraction = trace_fraction;
local vector roof_plane = trace_plane_normal;
-
+
// second: move forward
stepsize = trace_endpos_z - self.origin_z;
end = trace_endpos + (self.velocity * time_left);
@@ -531,7 +531,7 @@ void(float dogravity, float sticky, float dostep, float doskim) PM_DanceMove =
// an optimization from Quake 1; is this necessary? -- CEV
if ((self.velocity * start_v) <= 0)
{
- // we've turned against original velocity so
+ // we've turned against original velocity so
// clear vel and stop the loop
self.velocity = '0 0 0';
break;
@@ -690,7 +690,7 @@ void(float friction, float move_time) PM_Friction =
self.velocity = '0 0 0';
return;
}
-
+
// calculate what their new speed should be
control = speed < PM_STOPSPEED ? PM_STOPSPEED : speed;
newspeed = speed - control * friction * move_time;
@@ -777,7 +777,7 @@ void(vector wishdir, float wishspeed, float move_time) PM_AirControl =
//----------------------------------------------------------------------
// PM_Jump
//----------------------------------------------------------------------
-void() PM_Jump =
+void() PM_Jump =
{
// are we already waterjumping, or is jump being held?
if (self.pmove_flags & PMF_WATERJUMPED ||
Return to the top of this page or return to the overview of this repo.
Diff qc/progs.src
diff --git a/qc/progs.src b/qc/progs.src
index bcbb233..7fa428d 100644
--- a/qc/progs.src
+++ b/qc/progs.src
@@ -39,6 +39,7 @@ base_entities.qc // topmost entity classes
base_func.qc // base func_ classes
base_item.qc // ammo, armor, health, weapons, etc.
base_monster.qc // base monster classes
+base_projectile.qc // projectiles
base_trigger.qc // methods & fields for trigger entities
//----------------------------------------------------------------------
@@ -54,11 +55,33 @@ info/teleport_changedest.qc // Qmaster's info_teleport_changedest
info/teleport_destination.qc // teleporter endpoints
//----------------------------------------------------------------------
+// projectiles - these were all previously in weapons.qc
+//----------------------------------------------------------------------
+projectiles/bullet.qc // id1 shotguns
+projectiles/grenade.qc // id1 grenades
+projectiles/laser.qc // id1 lasers (enforcer, hazards)
+projectiles/rocket.qc // id1 rockets
+projectiles/spike.qc // id1 nails
+
+//----------------------------------------------------------------------
+// item entities & weapon firing code
+//----------------------------------------------------------------------
+items/ammo.qc // ammo; was in items.qc
+items/armor.qc // armor; was in items.qc
+items/keys.qc // key pickups; contains items.qc and keydata.qc
+items/health.qc // health; was in items.qc
+items/powerups.qc // envirosuit, pent, ring, quad; was in items.qc
+items/runes.qc // end-of-episode runes; was in items.qc
+items/weapons.qc // weapon pickups; was in items.qc
+items/backpacks.qc // backpack code; was in items.qc
+
+//----------------------------------------------------------------------
// combat & monster AI -- TODO CEV need to reformat
//----------------------------------------------------------------------
-fight.qc
-ai.qc
+// fight.qc
+// ai.qc
combat.qc
+weapons.qc // TODO CEV need to reformat
//----------------------------------------------------------------------
// client & player code
@@ -75,24 +98,10 @@ player/player.qc // player animation frames, pain & death, etc.
player/playerthink.qc // TODO CEV was in client.qc
player/pmove.qc // QC player movement code -- CEV
-weapons.qc // TODO CEV need to reformat
-
-//----------------------------------------------------------------------
-// item entities
-//----------------------------------------------------------------------
-items/ammo.qc // ammo; was in items.qc
-items/armor.qc // armor; was in items.qc
-items/keys.qc // key pickups; contains items.qc and keydata.qc
-items/health.qc // health; was in items.qc
-items/powerups.qc // envirosuit, pent, ring, quad; was in items.qc
-items/runes.qc // end-of-episode runes; was in items.qc
-items/weapons.qc // weapon pickups; was in items.qc
-items/backpacks.qc // backpack code; was in items.qc
-
//----------------------------------------------------------------------
// func entities
//----------------------------------------------------------------------
-func/shadow.qc //
+func/shadow.qc //
func/wall.qc // was misc.qc -- CEV
func/bob.qc // RennyC's stand alone version based on AD
func/bossgate.qc // was misc.qc -- CEV
@@ -123,7 +132,7 @@ func/train.qc // was plats.qc -- CEV
triggers/multiple.qc // need to add first, subclassed below -- CEV
triggers/camera.qc // was in cutscene.qc
triggers/changelevel.qc //
-triggers/changemusic.qc //
+triggers/changemusic.qc //
triggers/changetarget.qc
triggers/counter.qc //
triggers/cvarset.qc // was in cutscene.qc
@@ -140,7 +149,7 @@ triggers/onlyregistered.qc
triggers/push.qc // wind/push brushes, jumppads -- CEV
triggers/remove.qc // was in hip_trig.qc; currently commented out -- CEV
triggers/relay.qc //
-triggers/secret.qc //
+triggers/secret.qc //
triggers/setcount.qc // target_setcount
triggers/setgravity.qc // was in hip_trig.qc
triggers/setskill.qc //
@@ -172,7 +181,7 @@ monsters/oldone.qc // registered
monsters/oldone2.qc // killable Shub
monsters/shalrath.qc // registered
-monsters.qc // modified by dumptruck_ds from Preach's
+// monsters.qc // modified by dumptruck_ds from Preach's
// spawning tutorial | fish count fixed
//----------------------------------------------------------------------
Return to the top of this page or return to the overview of this repo.
Diff qc/projectiles/bullet.qc
diff --git a/qc/projectiles/bullet.qc b/qc/projectiles/bullet.qc
new file mode 100644
index 0000000..a41f7b0
--- /dev/null
+++ b/qc/projectiles/bullet.qc
@@ -0,0 +1,142 @@
+//======================================================================
+// Shotguns
+//======================================================================
+
+// globals
+entity multi_ent;
+float multi_damage;
+
+//----------------------------------------------------------------------
+// TraceAttack
+//----------------------------------------------------------------------
+void(float damage, vector dir) TraceAttack =
+{
+ local vector vel, org;
+
+ vel = normalize (dir + v_up * crandom() + v_right * crandom());
+ vel = vel + 2 * trace_plane_normal;
+ vel = vel * 200;
+
+ org = trace_endpos - dir * 4;
+
+ if (trace_ent.takedamage)
+ {
+ SpawnBlood (org, vel * 0.2, damage);
+ AddMultiDamage (trace_ent, damage);
+ }
+ else
+ {
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_GUNSHOT);
+ WriteCoord (MSG_BROADCAST, org_x);
+ WriteCoord (MSG_BROADCAST, org_y);
+ WriteCoord (MSG_BROADCAST, org_z);
+ }
+};
+
+/*======================================================================
+MULTI-DAMAGE
+Collects multiple small damages into a single damage
+======================================================================*/
+void() ClearMultiDamage =
+{
+ multi_ent = world;
+ multi_damage = 0;
+};
+
+void() ApplyMultiDamage =
+{
+ if (!multi_ent)
+ return;
+ T_Damage (multi_ent, self, self, multi_damage);
+};
+
+void(entity hit, float damage) AddMultiDamage =
+{
+ if (!hit)
+ return;
+
+ if (hit != multi_ent)
+ {
+ ApplyMultiDamage ();
+ multi_damage = damage;
+ multi_ent = hit;
+ }
+ else
+ {
+ multi_damage = multi_damage + damage;
+ }
+};
+
+
+//----------------------------------------------------------------------
+// FireBullets
+// Used by shotgun, super shotgun, and enemy soldier firing. Go to the
+// trouble of combining multiple pellets into a single damage call.
+//----------------------------------------------------------------------
+void(float shotcount, vector dir, vector spread) FireBullets =
+{
+ local vector direction;
+ local vector src;
+
+ makevectors (self.v_angle);
+
+ src = self.origin + v_forward * 10;
+ src_z = self.absmin_z + self.size_z * 0.7;
+
+ ClearMultiDamage ();
+ while (shotcount > 0)
+ {
+ direction = dir + crandom() * spread_x * v_right
+ + crandom() *spread_y * v_up;
+
+ traceline (src, src + direction * 2048, FALSE, self);
+ if (trace_fraction != 1.0)
+ TraceAttack (4, direction);
+
+ shotcount = shotcount - 1;
+ }
+
+ ApplyMultiDamage ();
+};
+
+//----------------------------------------------------------------------
+// W_FireShotgun
+//----------------------------------------------------------------------
+void() W_FireShotgun =
+{
+ local vector dir;
+
+ sound (self, CHAN_WEAPON, "weapons/guncock.wav", 1, ATTN_NORM);
+
+ self.punchangle_x = -2;
+
+ self.currentammo = self.ammo_shells = self.ammo_shells - 1;
+ dir = aim (self, 100000);
+ // TODO CEV
+ FireBullets (6, dir, '0.04 0.04 0');
+};
+
+//----------------------------------------------------------------------
+// W_FireSuperShotgun
+//----------------------------------------------------------------------
+void() W_FireSuperShotgun =
+{
+ local vector dir;
+
+ if (self.currentammo == 1)
+ {
+ W_FireShotgun ();
+ return;
+ }
+
+ sound (self, CHAN_WEAPON, "weapons/shotgn2.wav", 1, ATTN_NORM);
+
+ self.punchangle_x = -4;
+
+ self.currentammo = self.ammo_shells = self.ammo_shells - 2;
+ dir = aim (self, 100000);
+ FireBullets (14, dir, '0.14 0.08 0');
+};
+
+
Return to the top of this page or return to the overview of this repo.
Diff qc/projectiles/grenade.qc
diff --git a/qc/projectiles/grenade.qc b/qc/projectiles/grenade.qc
new file mode 100644
index 0000000..36ba547
--- /dev/null
+++ b/qc/projectiles/grenade.qc
@@ -0,0 +1,176 @@
+//==============================================================================
+// Grenades
+//==============================================================================
+
+//------------------------------------------------------------------------------
+class projectile_grenade: base_projectile
+{
+ float count;
+
+ //--------------------------------------------------------------
+ virtual void() do_think =
+ {
+ T_RadiusDamage (this, this.owner, 120, other);
+
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_EXPLOSION);
+ WriteCoord (MSG_BROADCAST, this.origin_x);
+ WriteCoord (MSG_BROADCAST, this.origin_y);
+ WriteCoord (MSG_BROADCAST, this.origin_z);
+
+ // BecomeExplosion
+ spawn (base_explosion, origin: this.origin);
+ remove (this);
+ };
+
+ //--------------------------------------------------------------
+ // GrenadeTouch
+ //
+ // This has been modified to fix a bug in the original code, which
+ // is that an entity with a very large bounding box (e.g. the size
+ // of monster_boss or monster_oldone) would receive little or no
+ // damage from a grenade impact. (In the original game, this bug
+ // didn't really matter because the largest DAMAGE_AIM entities
+ // were Shambler-sized.)
+ //
+ // In the original code, this function simply called GrenadeExplode,
+ // which called T_RadiusDamage, which deals an amount of damage
+ // based on the distance to the center of the victim's bounding box.
+ // Therefore, the larger the victim's bounding box, the lower the
+ // amount of damage that a grenade impact could deal.
+ //
+ // This modified version of GrenadeTouch adds a hack so that an
+ // entity which is larger than Shambler-size is treated differently:
+ // damage will be dealt to it using the same logic as a rocket
+ // impact, i.e. T_Damage will be called to deal damage to the
+ // impacted entity, and then radius damage will be dealt to any
+ // other entities in the vicinity. Grenades and rockets have
+ // always dealt the same amount of radius damage, so making the
+ // impact damage the same seemed a reasonable solution.
+ //
+ // The reason this logic is only used for very large entities is
+ // because I didn't want to affect the amount of damage that
+ // grenades deal to any of the original monsters under any
+ // circumstances. -- iw
+ //--------------------------------------------------------------
+ virtual void(entity toucher) do_touch =
+ {
+ local float damg;
+
+ if (other == this.owner)
+ // don't explode on owner
+ return;
+
+ if (other.takedamage == DAMAGE_AIM)
+ {
+ // see the explanation above -- iw
+ if (other.size_x > VEC_HULL2_SIZE_x ||
+ other.size_y > VEC_HULL2_SIZE_y ||
+ other.size_z > VEC_HULL2_SIZE_z)
+ {
+ // note that the logic for monster_shambler's
+ // partial immunity to explosions is not
+ // required because this is only for entities
+ // which are larger than monster_shambler -- iw
+ damg = 100 + random() * 20;
+ T_Damage (other, this, this.owner, damg);
+ this.do_think ();
+ return;
+ }
+ other = world;
+ this.do_think ();
+ return;
+ }
+ if (this.count < time)
+ {
+ // bounce sound
+ sound (this, CHAN_WEAPON, "weapons/bounce.wav",
+ 1, ATTN_NORM);
+ }
+ this.count = time + .02;
+ if (this.velocity == '0 0 0')
+ this.avelocity = '0 0 0';
+ };
+
+ //--------------------------------------------------------------
+ void() projectile_grenade =
+ {
+ this.classname = "grenade";
+ this.classtype = CT_TEMP_GRENADE;
+ this.movetype = MOVETYPE_BOUNCE;
+ this.solid = SOLID_BBOX;
+ this.avelocity = '300 300 300';
+ this.angles = vectoangles (this.velocity);
+
+ // set missile duration
+ this.nextthink = time + 2.5;
+ setmodel (this, "progs/grenade.mdl");
+ setsize (this, '0 0 0', '0 0 0');
+ setorigin (this, this.origin);
+ };
+};
+
+//----------------------------------------------------------------------
+// GrenadeExplode2
+//
+// This is the same as the original GrenadeExplode function except that
+// it will ignore the entity specified by the "ignore" parameter when
+// dealing damage. -- iw
+//----------------------------------------------------------------------
+void(entity ignore) GrenadeExplode2 =
+{
+ T_RadiusDamage (self, self.owner, 120, ignore);
+
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_EXPLOSION);
+ WriteCoord (MSG_BROADCAST, self.origin_x);
+ WriteCoord (MSG_BROADCAST, self.origin_y);
+ WriteCoord (MSG_BROADCAST, self.origin_z);
+
+ spawn (base_explosion, origin: self.origin);
+ remove (self);
+};
+
+//----------------------------------------------------------------------
+// GrenadeExplode -- Refactored. -- iw
+//----------------------------------------------------------------------
+void() GrenadeExplode =
+{
+ GrenadeExplode2 (world);
+};
+
+//----------------------------------------------------------------------
+// W_FireGrenade -- TODO CEV move into base_monster (when it's written)
+//----------------------------------------------------------------------
+void() W_FireGrenade =
+{
+ local entity missile;
+ local vector missile_velocity = '0 0 0';
+
+ self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
+
+ sound (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
+
+ self.punchangle_x = -2;
+
+ // set missile speed
+ makevectors (self.v_angle);
+
+ if (self.v_angle_x)
+ {
+ missile_velocity = v_forward * 600 +
+ v_up * 200 + crandom() * v_right * 10 +
+ crandom() * v_up * 10;
+ }
+ else
+ {
+ missile_velocity = aim (self, 10000);
+ missile_velocity = missile_velocity * 600;
+ missile_velocity_z = 200;
+ }
+
+ missile = spawn (projectile_grenade,
+ owner: self,
+ origin: self.origin,
+ velocity: missile_velocity);
+};
Return to the top of this page or return to the overview of this repo.
Diff qc/projectiles/laser.qc
diff --git a/qc/projectiles/laser.qc b/qc/projectiles/laser.qc
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/qc/projectiles/laser.qc
Return to the top of this page or return to the overview of this repo.
Diff qc/projectiles/rocket.qc
diff --git a/qc/projectiles/rocket.qc b/qc/projectiles/rocket.qc
new file mode 100644
index 0000000..e934fcd
--- /dev/null
+++ b/qc/projectiles/rocket.qc
@@ -0,0 +1,229 @@
+//======================================================================
+// Rockets
+//======================================================================
+
+void() T_MissileTouch =
+{
+ local float damg;
+
+ if (other == self.owner)
+ // don't explode on owner
+ return;
+
+ if (pointcontents(self.origin) == CONTENT_SKY)
+ {
+ remove (self);
+ return;
+ }
+
+ damg = 100 + random() * 20;
+
+ if (other.health)
+ {
+ if (other.classname == "monster_shambler")
+ // mostly immune
+ damg = damg * 0.5;
+ T_Damage (other, self, self.owner, damg);
+ }
+
+ // don't do radius damage to the other, because all the damage
+ // was done in the impact
+ T_RadiusDamage (self, self.owner, 120, other);
+
+ // sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM);
+ self.origin = self.origin - 8*normalize(self.velocity);
+
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_EXPLOSION);
+ WriteCoord (MSG_BROADCAST, self.origin_x);
+ WriteCoord (MSG_BROADCAST, self.origin_y);
+ WriteCoord (MSG_BROADCAST, self.origin_z);
+
+ // BecomeExplosion
+ spawn (base_explosion, origin: self.origin);
+ remove (self);
+};
+
+// dumptruck_ds start -- from inside qc tut http://www.insideqc.com/qctut/lesson-32.shtml
+
+void(float direct, float splash) T_MonsterMisTouch =
+{
+ local float damg;
+
+ if (other == self.owner)
+ // don't explode on owner
+ return;
+
+ if (pointcontents(self.origin) == CONTENT_SKY)
+ {
+ remove (self);
+ return;
+ }
+
+ // dumptruck_ds
+ damg = direct + random() * 2;
+
+ if (other.health)
+ {
+ if (other.classname == "monster_shambler")
+ // mostly immune
+ damg = damg * 0.5;
+ T_Damage (other, self, self.owner, damg);
+ }
+
+ // don't do radius damage to the other, because all the damage
+ // was done in the impact
+ T_RadiusDamage (self, self.owner, splash, other); // dumptruck_ds
+
+ // sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM);
+ self.origin = self.origin - 8 * normalize(self.velocity);
+
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_EXPLOSION);
+ WriteCoord (MSG_BROADCAST, self.origin_x);
+ WriteCoord (MSG_BROADCAST, self.origin_y);
+ WriteCoord (MSG_BROADCAST, self.origin_z);
+
+ // BecomeExplosion
+ spawn (base_explosion, origin: self.origin);
+ remove (self);
+};
+
+void() T_GruntMisTouch =
+{
+ T_MonsterMisTouch (30, 40);
+};
+
+ // less direct damage, more splash than grunt
+ // TODO: add damage modifier
+void() T_HellKnightMisTouch =
+{
+ T_MonsterMisTouch (20, 50);
+};
+
+// big damage. explody scrag should be beefy.
+// TODO: add damage modifier
+void() T_WizardMisTouch =
+{
+ T_MonsterMisTouch (50, 50);
+};
+// dumptruck_ds end
+
+//----------------------------------------------------------------------
+// W_FireRocket
+//----------------------------------------------------------------------
+void() W_FireRocket =
+{
+ local entity missile;
+
+ self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
+
+ sound (self, CHAN_WEAPON, "weapons/sgun1.wav", 1, ATTN_NORM);
+
+ self.punchangle_x = -2;
+
+ missile = spawn ();
+ missile.owner = self;
+ missile.movetype = MOVETYPE_FLYMISSILE;
+ missile.solid = SOLID_BBOX;
+ missile.classname = "missile";
+
+ // set missile speed
+ makevectors (self.v_angle);
+ missile.velocity = aim (self, 1000);
+ missile.velocity = missile.velocity * 1000;
+ missile.angles = vectoangles (missile.velocity);
+
+ missile.touch = T_MissileTouch;
+
+ // set missile duration
+ missile.nextthink = time + 5;
+ missile.think = sub_remove;
+
+ setmodel (missile, "progs/missile.mdl");
+ setsize (missile, '0 0 0', '0 0 0');
+ setorigin (missile, self.origin + v_forward * 8 + '0 0 16');
+};
+
+//----------------------------------------------------------------------
+// W_GruntRocket
+// dumptruck_ds start -- from inside qc tut
+// http://www.insideqc.com/qctut/lesson-32.shtml
+//----------------------------------------------------------------------
+void() W_GruntRocket =
+{
+ local entity missile;
+
+ /*
+ // dumptruck_ds
+ self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
+ */
+
+ sound_attack (self, CHAN_WEAPON, "weapons/sgun1.wav", 1, ATTN_NORM);
+
+ self.punchangle_x = -2;
+
+ missile = spawn ();
+ missile.owner = self;
+ missile.movetype = MOVETYPE_FLYMISSILE;
+ missile.solid = SOLID_BBOX;
+ missile.classname = "missile";
+
+ // set missile speed -- dumptruck_ds below
+
+ missile.velocity = normalize (self.enemy.origin - self.origin);
+ SetSpeed (missile, missile.velocity, 900 * self.proj_speed_mod);
+ missile.angles = vectoangles (missile.velocity);
+ missile.touch = T_GruntMisTouch;
+
+ // makevectors (self.v_angle);
+ // missile.velocity = aim(self, 1000);
+ // missile.velocity = missile.velocity * 1000;
+ // missile.angles = vectoangles(missile.velocity);
+
+ // missile.touch = T_MissileTouch;
+
+ // set missile duration
+ if (self.homing > 0)
+ {
+ SetupHoming (missile, 900 * self.proj_speed_mod);
+ }
+ else
+ {
+ missile.nextthink = time + 5;
+ missile.think = sub_remove;
+ }
+
+ if (self.mdl_proj != "")
+ {
+ // dumptruck_ds
+ setmodel (missile, self.mdl_proj);
+ }
+ else
+ {
+ setmodel (missile, "progs/missile.mdl");
+ }
+
+ if (!missile.skin_proj)
+ {
+ // dumptruck_ds
+ missile.skin = self.skin_proj;
+ }
+ else
+ {
+ missile.skin = 0;
+ }
+ // dumptruck_ds - end
+
+ // setmodel (missile, "progs/missile.mdl");
+ setsize (missile, '0 0 0', '0 0 0');
+ // thanks Voidforce -- dumptruck_ds
+ makevectors (self.angles);
+ setorigin (missile, self.origin + v_forward * 30 +
+ v_right * 5 + '0 0 12');
+ // setorigin (missile, self.origin + v_forward*8 + '0 0 16');
+};
+
+// end dumptruck_ds grunt missle end
+
+
Return to the top of this page or return to the overview of this repo.
Diff qc/projectiles/spike.qc
diff --git a/qc/projectiles/spike.qc b/qc/projectiles/spike.qc
new file mode 100644
index 0000000..ffd941f
--- /dev/null
+++ b/qc/projectiles/spike.qc
@@ -0,0 +1,223 @@
+//======================================================================
+// Nails
+//======================================================================
+
+void() spike_touch;
+void() superspike_touch;
+
+//----------------------------------------------------------------------
+// launch_spike -- Used for both the player and the ogre
+//----------------------------------------------------------------------
+void(vector org, vector dir, float speed) launch_spike2 =
+{
+ newmis = spawn ();
+ newmis.owner = self;
+ newmis.movetype = MOVETYPE_FLYMISSILE;
+ newmis.solid = SOLID_BBOX;
+
+ newmis.angles = vectoangles (dir);
+
+ newmis.touch = spike_touch;
+ newmis.classname = "spike";
+ if (self.homing > 0)
+ {
+ SetupHoming (newmis, speed);
+ }
+ else
+ {
+ newmis.think = sub_remove;
+ newmis.nextthink = time + 6;
+ }
+ setmodel (newmis, "progs/spike.mdl");
+ setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
+ setorigin (newmis, org);
+
+ SetSpeed (newmis, dir, speed *
+ (self.proj_speed_mod ? self.proj_speed_mod : 1));
+};
+
+void(vector org, vector dir) launch_spike =
+{
+ launch_spike2 (org,dir,1000);
+};
+
+void() W_FireSuperSpikes =
+{
+ local vector dir;
+
+ sound (self, CHAN_WEAPON, "weapons/spike2.wav", 1, ATTN_NORM);
+ self.attack_finished = time + 0.2;
+ self.currentammo = self.ammo_nails = self.ammo_nails - 2;
+ dir = aim (self, 1000);
+ launch_spike (self.origin + '0 0 16', dir);
+ newmis.touch = superspike_touch;
+ setmodel (newmis, "progs/s_spike.mdl");
+ setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
+ self.punchangle_x = -2;
+};
+
+void(float ox) W_FireSpikes =
+{
+ local vector dir;
+
+ makevectors (self.v_angle);
+
+ if (self.ammo_nails >= 2 && self.weapon == IT_SUPER_NAILGUN)
+ {
+ W_FireSuperSpikes ();
+ return;
+ }
+
+ if (self.ammo_nails < 1)
+ {
+ if (self.classname == "player")
+ {
+ self.weapon = PlayerBestWeapon ();
+ PlayerSetCurrentAmmo ();
+ }
+ return;
+ }
+
+ sound (self, CHAN_WEAPON, "weapons/rocket1i.wav", 1, ATTN_NORM);
+ self.attack_finished = time + 0.2;
+ self.currentammo = self.ammo_nails = self.ammo_nails - 1;
+ dir = aim (self, 1000);
+ // launch_spike (self.origin + '0 0 16' + v_right * ox, dir);
+ // seven Nailgun position fix - thanks to Greenwood -- dumptruck_ds
+ launch_spike (self.origin + self.view_ofs +
+ v_up * -8 +v_right * ox, dir);
+
+ self.punchangle_x = -2;
+};
+
+void() spike_touch =
+{
+ if (other == self.owner)
+ return;
+
+ if (other.solid == SOLID_TRIGGER)
+ // trigger field, do nothing
+ return;
+
+ if (pointcontents(self.origin) == CONTENT_SKY)
+ {
+ remove (self);
+ return;
+ }
+
+ // hit something that bleeds
+ if (other.takedamage)
+ {
+ spawn_touchblood (9);
+ T_Damage (other, self, self.owner, 9);
+ }
+ else
+ {
+
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ if (self.owner.snd_hit != __NULL__ && self.owner.snd_hit != "")
+ {
+ // dumptruck_ds
+ sound (self, CHAN_WEAPON, self.owner.snd_hit,
+ 1, ATTN_STATIC);
+ WriteByte(MSG_BROADCAST, TE_GUNSHOT);
+ }
+
+ else if (self.classname == "wizspike")
+ WriteByte (MSG_BROADCAST, TE_WIZSPIKE);
+ else if (self.classname == "knightspike")
+ WriteByte (MSG_BROADCAST, TE_KNIGHTSPIKE);
+ else
+ WriteByte (MSG_BROADCAST, TE_SPIKE);
+ WriteCoord (MSG_BROADCAST, self.origin_x);
+ WriteCoord (MSG_BROADCAST, self.origin_y);
+ WriteCoord (MSG_BROADCAST, self.origin_z);
+ }
+
+ remove (self);
+};
+
+void() superspike_touch =
+{
+ if (other == self.owner)
+ return;
+
+ if (other.solid == SOLID_TRIGGER)
+ // trigger field, do nothing
+ return;
+
+ if (pointcontents(self.origin) == CONTENT_SKY)
+ {
+ remove(self);
+ return;
+ }
+
+ // hit something that bleeds
+ if (other.takedamage)
+ {
+ spawn_touchblood (18);
+ T_Damage (other, self, self.owner, 18);
+ }
+ else
+ {
+ // TODO CEV radiusdamage from spikes (for climbing purposes)
+ T_RadiusDamage (self, self.owner, 40, world);
+ if (self.owner.snd_hit != __NULL__ && self.owner.snd_hit != "")
+ {
+ // dumptruck_ds
+ sound (self, CHAN_WEAPON, self.owner.snd_hit,
+ 1, ATTN_STATIC);
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte(MSG_BROADCAST, TE_GUNSHOT);
+ }
+ else
+ {
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_SUPERSPIKE);
+ }
+ WriteCoord (MSG_BROADCAST, self.origin_x);
+ WriteCoord (MSG_BROADCAST, self.origin_y);
+ WriteCoord (MSG_BROADCAST, self.origin_z);
+ }
+
+ remove (self);
+};
+
+//----------------------------------------------------------------------
+// dumptruck_ds for Style 2 Ogre see ogre.qc
+//----------------------------------------------------------------------
+void() superduperspike_touch =
+{
+ if (other == self.owner)
+ return;
+
+ if (other.solid == SOLID_TRIGGER)
+ // trigger field, do nothing
+ return;
+
+ if (pointcontents(self.origin) == CONTENT_SKY)
+ {
+ remove (self);
+ return;
+ }
+
+ // hit something that bleeds
+ if (other.takedamage)
+ {
+ spawn_touchblood (36);
+ T_Damage (other, self, self.owner, 36);
+ sound (self, CHAN_VOICE, "fish/bite.wav", 1, ATTN_NORM);
+ }
+ else
+ {
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_SUPERSPIKE);
+ WriteCoord (MSG_BROADCAST, self.origin_x);
+ WriteCoord (MSG_BROADCAST, self.origin_y);
+ WriteCoord (MSG_BROADCAST, self.origin_z);
+ }
+
+ remove (self);
+};
+
+
Return to the top of this page or return to the overview of this repo.
Diff qc/subs.qc
diff --git a/qc/subs.qc b/qc/subs.qc
index 420c3b8..b579de7 100644
--- a/qc/subs.qc
+++ b/qc/subs.qc
@@ -2,13 +2,6 @@
// subs.qc
//==============================================================================
-// Supa, Quoth respawning items support Respawn item like in DM if 'ritem' TRUE,
-// override respawn time with 'respawndelay' if set, inc 'cnt' with each respawn
-// and if 'respawncount' is set we'll remove the item if cnt > respawncount
-// remember that SUB_Regen is already set on every item that can respawn, all we
-// need to do is give a nextthink time in order to trigger it
-.float ritem, respawndelay, respawncount;
-
//----------------------------------------------------------------------
void() sub_null =
{
@@ -33,48 +26,6 @@ void() sub_remove =
//==============================================================================
//----------------------------------------------------------------------
-// CheckItemRespawn -- was in items.qc
-//----------------------------------------------------------------------
-void(entity whatitem, float defaultdelay) CheckItemRespawn =
-{
- // respawn item if true, otherwise abort
- if (!whatitem.ritem)
- return;
-
- // inc before check to account for zero indexing
- whatitem.cnt = whatitem.cnt + 1;
-
- // limited respawns
- if (whatitem.respawncount && whatitem.respawncount < whatitem.cnt)
- return;
-
- // okay, we're clear to set up a respawn
- if (whatitem.respawndelay)
- // custom respawn delay
- whatitem.nextthink = time + whatitem.respawndelay;
- else
- whatitem.nextthink = time + defaultdelay;
-};
-
-//----------------------------------------------------------------------
-// CheckValidTouch -- health and playerhood checks were duplicated everywhere
-// added noclip check because Quake's default still-touch-everything noclip
-// is awful -- from Copper -- dumptruck_ds (orginally found in triggers.qc)
-//----------------------------------------------------------------------
-float() CheckValidTouch =
-{
- if (other.classname != "player")
- return FALSE;
- if (other.health <= 0)
- return FALSE;
- if (other.movetype == MOVETYPE_NOCLIP)
- return FALSE;
- if (self.estate != STATE_ACTIVE)
- return FALSE;
- return TRUE;
-};
-
-//----------------------------------------------------------------------
void() DelayThink =
{
dprint (sprintf("DelayThink: self classname %s\n", self.classname));
@@ -355,7 +306,7 @@ void() SUB_UseAndForgetTargets =
//----------------------------------------------------------------------
// SUB_FieldIsTargeted
-//
+//
// Return TRUE if the "fld" field of this entity is non-empty and matches
// the target (or target2/3/4 or pain_target) field of any other entity,
// otherwise return FALSE. -- iw
@@ -388,7 +339,7 @@ float(.string fld) SUB_FieldIsTargeted =
//----------------------------------------------------------------------
// SUB_IsTargeted
-//
+//
// Return TRUE if the targetname (or targetname2/3/4) field of this entity
// is non-empty and matches the target (or target2/3/4 or pain_target)
// field of any other entity, otherwise return FALSE. -- iw
@@ -441,7 +392,9 @@ void(float normal) SUB_AttackFinished =
self.attack_finished = time + normal;
};
+// TODO CEV
//----------------------------------------------------------------------
+/*
void (void() thinkst) SUB_CheckRefire =
{
if (skill != 3)
@@ -454,6 +407,7 @@ void (void() thinkst) SUB_CheckRefire =
self.cnt = 1;
self.think = thinkst;
};
+*/
//--------------------------------------------------------------------//
// SUB_Think -- Drake -- This makes an entity do a think function right now.
@@ -467,29 +421,3 @@ void(entity ent, void() thinkst) SUB_Think =
thinkst ();
self = swap;
};
-
-//----------------------------------------------------------------------
-
-//----------------------------------------------------------------------
-// SUB_Regen -- was in items.qc
-//----------------------------------------------------------------------
-void() SUB_Regen =
-{
- // restore original model
- self.model = self.mdl;
-
- // allow it to be touched again
- self.solid = SOLID_TRIGGER;
-
- // TODO CEV
- // Respawn with DM effects
- // if (deathmatch || (self.spawnflags & ITEM_RESPAWNDM))
- // play respawn sound
- sound (self, CHAN_VOICE, "items/item_respawn_q3.wav",
- 1, ATTN_NORM);
- // else
- // play teleport sound and display particles
- // spawn_tfog (self.origin + self.particles_offset);
-
- setorigin (self, self.origin);
-};
Return to the top of this page or return to the overview of this repo.
Diff qc/triggers/changelevel.qc
diff --git a/qc/triggers/changelevel.qc b/qc/triggers/changelevel.qc
index b84919d..368d7bd 100644
--- a/qc/triggers/changelevel.qc
+++ b/qc/triggers/changelevel.qc
@@ -14,7 +14,7 @@ class trigger_changelevel: base_trigger
//--------------------------------------------------------------
// was changelevel_execute
//--------------------------------------------------------------
- virtual void(entity caller) do_think =
+ virtual void() do_think =
{
used_exit = this;
local entity pos;
Return to the top of this page or return to the overview of this repo.
Diff qc/triggers/changemusic.qc
diff --git a/qc/triggers/changemusic.qc b/qc/triggers/changemusic.qc
index 0d9531c..a146377 100644
--- a/qc/triggers/changemusic.qc
+++ b/qc/triggers/changemusic.qc
@@ -29,7 +29,7 @@ class base_changemusic: base_trigger
A trigger brush that changes the currently playing music track. The number of the track to play goes in the sounds key (just like worldspawn). */
class trigger_changemusic: base_changemusic
{
- virtual void(entity caller) do_think =
+ virtual void() do_think =
{
remove (this);
};
Return to the top of this page or return to the overview of this repo.
Diff qc/triggers/cvarset.qc
diff --git a/qc/triggers/cvarset.qc b/qc/triggers/cvarset.qc
index afb5e3c..30bddfe 100644
--- a/qc/triggers/cvarset.qc
+++ b/qc/triggers/cvarset.qc
@@ -12,7 +12,7 @@ class trigger_cvarset: base_trigger
//--------------------------------------------------------------
// was cvarset_delaythink
//--------------------------------------------------------------
- virtual void(entity caller) do_think =
+ virtual void() do_think =
{
sub_usetargets ();
};
Return to the top of this page or return to the overview of this repo.
Diff qc/triggers/fog.qc
diff --git a/qc/triggers/fog.qc b/qc/triggers/fog.qc
index 1ab18c8..a5e8f82 100644
--- a/qc/triggers/fog.qc
+++ b/qc/triggers/fog.qc
@@ -180,7 +180,7 @@ class base_fog_controller: base_mapentity
// fog controller think -- used by both trigger_fog and
// target_fogblend; was fog_blendTimeThink
//--------------------------------------------------------------
- virtual void(entity caller) do_think =
+ virtual void() do_think =
{
local float f;
local float dTo, sTo;
Return to the top of this page or return to the overview of this repo.
Diff qc/triggers/heal.qc
diff --git a/qc/triggers/heal.qc b/qc/triggers/heal.qc
index bef2258..4b539dc 100644
--- a/qc/triggers/heal.qc
+++ b/qc/triggers/heal.qc
@@ -53,7 +53,7 @@ class trigger_heal: base_trigger
};
//--------------------------------------------------------------
- virtual void(entity caller) do_think =
+ virtual void() do_think =
{
if (this.cnt == this.count)
{
@@ -115,7 +115,7 @@ class trigger_heal: base_trigger
}
if (this.count && this.cnt <= 0)
- {
+ {
if (this.message2 != __NULL__ && this.message2 != "")
centerprint (toucher, this.message2);
return;
@@ -137,7 +137,7 @@ class trigger_heal: base_trigger
else
calc_healing = heal_amount;
- if (this.count)
+ if (this.count)
{
if (calc_healing > this.cnt)
calc_healing = this.cnt;
@@ -148,7 +148,7 @@ class trigger_heal: base_trigger
{
interaction_flags &= ~DISABLE_THINK;
this.nextthink = time + this.delay;
- }
+ }
dprint (sprintf("trigger_heal::do_touch: "
"used [max: %f, current: %f, "
Return to the top of this page or return to the overview of this repo.
Diff qc/triggers/monsterface.qc
diff --git a/qc/triggers/monsterface.qc b/qc/triggers/monsterface.qc
index c0bab33..e7c3b7f 100644
--- a/qc/triggers/monsterface.qc
+++ b/qc/triggers/monsterface.qc
@@ -14,6 +14,29 @@ Keys:
class trigger_monsterface: base_trigger
{
//--------------------------------------------------------------
+ // visibleToOther - returns 1 if the entity is visible to other,
+ // even if not infront ()
+ //--------------------------------------------------------------
+ nonvirtual float(entity targ) newai_visible_to_other =
+ {
+ local vector spot1, spot2;
+
+ spot1 = other.origin + other.view_ofs;
+ spot2 = targ.origin + targ.view_ofs;
+ // see through other monsters
+ traceline (spot1, spot2, TRUE, other);
+
+ if (trace_inopen && trace_inwater)
+ // sight line crossed contents
+ return FALSE;
+
+ if (trace_fraction == 1)
+ return TRUE;
+
+ return FALSE;
+ };
+
+ //--------------------------------------------------------------
virtual void(entity toucher) do_touch =
{
// only affect ground monsters
@@ -21,7 +44,7 @@ class trigger_monsterface: base_trigger
(FL_MONSTER | FL_FLY | FL_SWIM) != FL_MONSTER)
return;
- if (!visibleToOther(toucher.enemy))
+ if (!newai_visible_to_other(toucher.enemy))
{
// enemy is hidden
// don't dodge around, just go straight
Return to the top of this page or return to the overview of this repo.
Diff qc/triggers/monsterjump.qc
diff --git a/qc/triggers/monsterjump.qc b/qc/triggers/monsterjump.qc
index 129e5d3..6e0a870 100644
--- a/qc/triggers/monsterjump.qc
+++ b/qc/triggers/monsterjump.qc
@@ -17,6 +17,22 @@ be targeted and toggled off and on.
*/
class trigger_monsterjump: base_trigger
{
+ // class fields
+ float height;
+
+ //--------------------------------------------------------------
+ virtual void(string fieldname, string fieldvalue) init_field =
+ {
+ switch (fieldname)
+ {
+ case "height":
+ height = stof (fieldvalue);
+ break;
+ default:
+ super::init_field (fieldname, fieldvalue);
+ }
+ };
+
//--------------------------------------------------------------
virtual void(entity toucher) do_touch =
{
Return to the top of this page or return to the overview of this repo.
Diff qc/triggers/multiple.qc
diff --git a/qc/triggers/multiple.qc b/qc/triggers/multiple.qc
index d7c8cbf..41d7083 100644
--- a/qc/triggers/multiple.qc
+++ b/qc/triggers/multiple.qc
@@ -108,7 +108,7 @@ class base_multiple: base_trigger
};
//--------------------------------------------------------------
- virtual void(entity caller) do_think =
+ virtual void() do_think =
{
if (this.is_removed == TRUE)
{
Return to the top of this page or return to the overview of this repo.
Diff qc/triggers/push.qc
diff --git a/qc/triggers/push.qc b/qc/triggers/push.qc
index 901df32..59cff6e 100644
--- a/qc/triggers/push.qc
+++ b/qc/triggers/push.qc
@@ -35,20 +35,20 @@ vector(float a, float b, float c) solve_quadratic =
}
else
{
- D = b*b - 4*a*c;
+ D = b * b - 4 * a * c;
if (D >= 0)
{
D = sqrt (D);
if (a > 0)
{
// put the smaller solution first
- v_x = ((-b)-D) / (2*a);
- v_y = ((-b)+D) / (2*a);
+ v_x = ((-b) - D) / (2 * a);
+ v_y = ((-b) + D) / (2 * a);
}
else
{
- v_x = (-b+D) / (2*a);
- v_y = (-b-D) / (2*a);
+ v_x = (-b + D) / (2 * a);
+ v_y = (-b - D) / (2 * a);
}
v_z = 1;
}
@@ -56,11 +56,11 @@ vector(float a, float b, float c) solve_quadratic =
{
// complex solutions!
D = sqrt (-D);
- v_x = -b / (2*a);
+ v_x = -b / (2 * a);
if (a > 0)
- v_y = D / (2*a);
+ v_y = D / (2 * a);
else
- v_y = -D / (2*a);
+ v_y = -D / (2 * a);
v_z = 0;
}
}
@@ -69,6 +69,22 @@ vector(float a, float b, float c) solve_quadratic =
class base_trigger_push: base_trigger
{
+ // class fields
+ float height;
+
+ //--------------------------------------------------------------
+ virtual void(string fieldname, string fieldvalue) init_field =
+ {
+ switch (fieldname)
+ {
+ case "height":
+ height = stof (fieldvalue);
+ break;
+ default:
+ super::init_field (fieldname, fieldvalue);
+ }
+ };
+
//--------------------------------------------------------------
// trigger_push_calculatevelocity
//
@@ -78,7 +94,7 @@ class base_trigger_push: base_trigger
// if it is the latter, its midpoint is used)
// ht - jump height, measured from the higher one of org and tgt's
// midpoint
- //
+ //
// Returns: velocity for the jump
// the global trigger_push_calculatevelocity_flighttime is set to the
// total jump time
@@ -239,7 +255,7 @@ class base_trigger_push: base_trigger
else
toucher.velocity = speed * movedir * 10;
- if (toucher.classtype == CT_PLAYER &&
+ if (toucher.classtype == CT_PLAYER &&
!(this.spawnflags & TRIGGER_PUSH_SILENT))
{
if (toucher.fly_sound < time)
@@ -266,7 +282,6 @@ class base_trigger_push: base_trigger
if (this.spawnflags & TRIGGER_PUSH_ONCE)
remove (this);
};
-
};
/*QUAKED trigger_push (.5 .5 .5) ? TRIGGER_PUSH_ONCE X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
Return to the top of this page or return to the overview of this repo.
Diff qc/triggers/shake.qc
diff --git a/qc/triggers/shake.qc b/qc/triggers/shake.qc
index dad5789..7ecf9b7 100644
--- a/qc/triggers/shake.qc
+++ b/qc/triggers/shake.qc
@@ -23,7 +23,7 @@ class trigger_shake: base_trigger
//--------------------------------------------------------------
// was shake_think
//--------------------------------------------------------------
- virtual void(entity caller) do_think =
+ virtual void() do_think =
{
if (this.attack_finished < time)
{
Return to the top of this page or return to the overview of this repo.
Diff qc/triggers/teleport.qc
diff --git a/qc/triggers/teleport.qc b/qc/triggers/teleport.qc
index 043c659..4687784 100644
--- a/qc/triggers/teleport.qc
+++ b/qc/triggers/teleport.qc
@@ -41,7 +41,7 @@ void() spawn_tfog_think =
void(vector org) spawn_tfog =
{
local entity s;
-
+
s = spawn ();
s.origin = org;
s.spawnflags = self.spawnflags; // dumptruck_ds
@@ -183,7 +183,7 @@ class trigger_teleport: base_trigger
{
local float rndm;
// local float rndm, num1;
- local entity spot,first;
+ local entity spot, first;
rndm = rint (random() * (this.count - 1));
spot = findfloat (world, ::classtype, CT_INFO_TELEPORT_RANDOM);
Return to the top of this page or return to the overview of this repo.
Diff qc/triggers/textstory.qc
diff --git a/qc/triggers/textstory.qc b/qc/triggers/textstory.qc
index 11dbd90..2cb7235 100644
--- a/qc/triggers/textstory.qc
+++ b/qc/triggers/textstory.qc
@@ -68,7 +68,7 @@ class base_textstory: base_trigger
csf_fade (this.enemy, 160, '0 0 0', 1);
else
csf_fade (this.enemy, this.fade_amt,
- '0 0 0', 1);
+ '0 0 0', 1);
}
}
@@ -104,7 +104,7 @@ class trigger_textstory: base_textstory
};
//--------------------------------------------------------------
- virtual void(entity caller) do_think =
+ virtual void() do_think =
{
if (this.think_state == TEXTSTORY_THINK_HIDE)
this.story_hide ();
@@ -212,7 +212,7 @@ class target_textstory_helper: base_textstory
};
//--------------------------------------------------------------
- virtual void(entity caller) do_think =
+ virtual void() do_think =
{
if (this.think_state == TEXTSTORY_THINK_HELPERHIDE)
this.helper_story_hide ();
Return to the top of this page or return to the overview of this repo.
Diff qc/triggers/usekey.qc
diff --git a/qc/triggers/usekey.qc b/qc/triggers/usekey.qc
index 510951c..6c9e995 100644
--- a/qc/triggers/usekey.qc
+++ b/qc/triggers/usekey.qc
@@ -37,10 +37,10 @@ class trigger_usekey: base_trigger
//--------------------------------------------------------------
// trigger_usekey_unlock
- //
+ //
// Perform the actions which should be performed when self is
// successfully unlocked with a key.
- //
+ //
// This function exists so that it can be passed as an argument
// to the new keylock_try_to_unlock function. This code was
// previously part of the trigger_usekey_use function. -- iw
@@ -61,7 +61,7 @@ class trigger_usekey: base_trigger
};
//--------------------------------------------------------------
- virtual void(entity caller) do_think =
+ virtual void() do_think =
{
if (this.is_removed == TRUE)
remove (this);
Return to the top of this page or return to the overview of this repo.
Diff qc/triggers/void.qc
diff --git a/qc/triggers/void.qc b/qc/triggers/void.qc
index 3a356eb..41df9b4 100644
--- a/qc/triggers/void.qc
+++ b/qc/triggers/void.qc
@@ -50,7 +50,7 @@ class trigger_void: base_trigger
// figure out!! -- dumptruck_ds
toucher.invincible_finished = 0;
T_Damage (toucher, this, this, toucher.health + 1000);
-
+
if (toucher.flags & FL_MONSTER)
remove (toucher);
}
Return to the top of this page or return to the overview of this repo.
Diff qc/utility.qc
diff --git a/qc/utility.qc b/qc/utility.qc
index 55fddea..e1e01a4 100644
--- a/qc/utility.qc
+++ b/qc/utility.qc
@@ -5,14 +5,14 @@
//----------------------------------------------------------------------
// dprint shims
//----------------------------------------------------------------------
-void(string s1, string s2) dprint2 =
+void(string s1, string s2) dprint2 =
{
dprint (s1);
dprint (s2);
};
//----------------------------------------------------------------------
-void(string s1, string s2, string s3) dprint3 =
+void(string s1, string s2, string s3) dprint3 =
{
dprint (s1);
dprint (s2);
@@ -20,7 +20,7 @@ void(string s1, string s2, string s3) dprint3 =
};
//----------------------------------------------------------------------
-void(string s1, string s2, string s3, string s4) dprint4 =
+void(string s1, string s2, string s3, string s4) dprint4 =
{
dprint (s1);
dprint (s2);
@@ -29,7 +29,7 @@ void(string s1, string s2, string s3, string s4) dprint4 =
};
//----------------------------------------------------------------------
-void(string s1, string s2, string s3, string s4, string s5) dprint5 =
+void(string s1, string s2, string s3, string s4, string s5) dprint5 =
{
dprint (s1);
dprint (s2);
@@ -78,7 +78,7 @@ void(string s1, string s2, string s3, string s4, string s5, string s6,
//----------------------------------------------------------------------
void(string s1, string s2, string s3, string s4, string s5, string s6,
- string s7, string s8, string s9) dprint9 =
+ string s7, string s8, string s9) dprint9 =
{
dprint (s1);
dprint (s2);
@@ -101,10 +101,10 @@ float(float in) bprint_int =
in = floor (in);
if (in <= 0)
return 0;
-
+
local float digit;
digit = in - bprint_int (in / 10);
-
+
switch (digit)
{
case 9: bprint("9"); break;
@@ -118,7 +118,7 @@ float(float in) bprint_int =
case 1: bprint("1"); break;
case 0: bprint("0"); break;
}
-
+
return in * 10;
};
@@ -132,7 +132,7 @@ float(float in, float def) defaultFl =
};
//----------------------------------------------------------------------
-// shorthand for turning -1 to 0 for keyvalues for which 0 is a
+// shorthand for turning -1 to 0 for keyvalues for which 0 is a
// valid non-default selection
//----------------------------------------------------------------------
float(float in) zeroconvert =
@@ -161,13 +161,13 @@ float(vector v, vector s) BoundsAngleSize =
v_x = fabs (v_x);
v_y = fabs (v_y);
v_z = fabs (v_z);
-
+
// size is always + + + but this is in case I switch the
// parameters somewhere
s_x = fabs (s_x);
s_y = fabs (s_y);
s_z = fabs (s_z);
-
+
return v * s;
};
@@ -220,7 +220,7 @@ void(entity client, float f) stuffcmd_digit =
void(entity client, float f, float numdigits) stuffcmd_int =
{
local float tmp;
-
+
if (f == 0)
{
stuffcmd (client, "0");
@@ -233,7 +233,7 @@ void(entity client, float f, float numdigits) stuffcmd_int =
stuffcmd (client, "-");
f = fabs (f);
}
-
+
if (numdigits <= 0)
{
tmp = f;
@@ -244,7 +244,7 @@ void(entity client, float f, float numdigits) stuffcmd_int =
numdigits = numdigits * 10;
}
}
-
+
// I don't know what I'm thinking here...
// I need to do this to get zero-padding to work.
@@ -260,31 +260,31 @@ void(entity client, float f, float numdigits) stuffcmd_int =
void(entity client, float f) stuffcmd_float =
{
local float intpart, decpart, isNegative;
-
+
isNegative = FALSE;
-
+
if (f == 0)
{
stuffcmd (client, "0");
return;
}
-
+
if (f < 0)
{
// easier this way
isNegative = TRUE;
f = fabs (f);
- }
-
+ }
+
// 1: stuff the integer part.
intpart = floor (f);
- if (isNegative)
+ if (isNegative)
stuffcmd (client, "-");
stuffcmd_int (client, intpart, 0);
-
+
// 2: stuff the decimal point.
stuffcmd (client, ".");
-
+
// 3: stuff the decimal part.
decpart = mod (f, 1);
decpart = decpart * 10000;
Return to the top of this page or return to the overview of this repo.
Diff qc/weapons.qc
diff --git a/qc/weapons.qc b/qc/weapons.qc
index eb0c8cd..e907511 100644
--- a/qc/weapons.qc
+++ b/qc/weapons.qc
@@ -14,25 +14,20 @@ void(entity mis, vector dir, float speed) SetSpeed =
}
};
-float() crandom =
-{
- return 2 * (random () - 0.5);
-};
-
//----------------------------------------------------------------------
vector() wall_velocity =
{
local vector vel;
vel = normalize (self.velocity);
- vel = normalize (vel + v_up*(random()- 0.5) + v_right*(random()- 0.5));
+ vel = normalize (vel + v_up*(random()- 0.5) +
+ v_right * (random() - 0.5));
vel = vel + 2 * trace_plane_normal;
vel = vel * 200;
return vel;
};
-
//----------------------------------------------------------------------
// SpawnMeatSpray
//----------------------------------------------------------------------
@@ -76,7 +71,7 @@ void(float damage) spawn_touchblood =
{
local vector vel;
- vel = wall_velocity () * 0.2;
+ vel = wall_velocity() * 0.2;
SpawnBlood (self.origin + vel* 0.01, vel, damage);
};
@@ -88,413 +83,36 @@ void(vector org, vector vel) SpawnChunk =
particle (org, vel * 0.02, 0, 10);
};
-/*======================================================================
-MULTI-DAMAGE
-Collects multiple small damages into a single damage
-======================================================================*/
-entity multi_ent;
-float multi_damage;
-
-void() ClearMultiDamage =
-{
- multi_ent = world;
- multi_damage = 0;
-};
-
-void() ApplyMultiDamage =
-{
- if (!multi_ent)
- return;
- T_Damage (multi_ent, self, self, multi_damage);
-};
-
-void(entity hit, float damage) AddMultiDamage =
-{
- if (!hit)
- return;
-
- if (hit != multi_ent)
- {
- ApplyMultiDamage ();
- multi_damage = damage;
- multi_ent = hit;
- }
- else
- {
- multi_damage = multi_damage + damage;
- }
-};
-
-// TODO CEV
-
//======================================================================
-// Shotguns
+// Lightning
//======================================================================
-/*
-================
-TraceAttack
-================
-*/
-void(float damage, vector dir) TraceAttack =
-{
- local vector vel, org;
-
- vel = normalize(dir + v_up*crandom() + v_right*crandom());
- vel = vel + 2*trace_plane_normal;
- vel = vel * 200;
-
- org = trace_endpos - dir*4;
-
- if (trace_ent.takedamage)
- {
- SpawnBlood (org, vel*0.2, damage);
- AddMultiDamage (trace_ent, damage);
- }
- else
- {
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_GUNSHOT);
- WriteCoord (MSG_BROADCAST, org_x);
- WriteCoord (MSG_BROADCAST, org_y);
- WriteCoord (MSG_BROADCAST, org_z);
- }
-};
-
-//----------------------------------------------------------------------
-// FireBullets
-// Used by shotgun, super shotgun, and enemy soldier firing. Go to the
-// trouble of combining multiple pellets into a single damage call.
-//----------------------------------------------------------------------
-void(float shotcount, vector dir, vector spread) FireBullets =
-{
- local vector direction;
- local vector src;
-
- makevectors (self.v_angle);
-
- src = self.origin + v_forward * 10;
- src_z = self.absmin_z + self.size_z * 0.7;
-
- ClearMultiDamage ();
- while (shotcount > 0)
- {
- direction = dir + crandom() * spread_x * v_right
- + crandom() *spread_y * v_up;
-
- traceline (src, src + direction * 2048, FALSE, self);
- if (trace_fraction != 1.0)
- TraceAttack (4, direction);
-
- shotcount = shotcount - 1;
- }
-
- ApplyMultiDamage ();
-};
-
//----------------------------------------------------------------------
-// W_FireShotgun
+// LightningDamage
//----------------------------------------------------------------------
-void() W_FireShotgun =
-{
- local vector dir;
-
- sound (self, CHAN_WEAPON, "weapons/guncock.wav", 1, ATTN_NORM);
-
- self.punchangle_x = -2;
-
- self.currentammo = self.ammo_shells = self.ammo_shells - 1;
- dir = aim (self, 100000);
- // TODO CEV
- FireBullets (6, dir, '0.04 0.04 0');
-};
-
-
-/*
-================
-W_FireSuperShotgun
-================
-*/
-void() W_FireSuperShotgun =
-{
- local vector dir;
-
- if (self.currentammo == 1)
- {
- W_FireShotgun ();
- return;
- }
-
- sound (self ,CHAN_WEAPON, "weapons/shotgn2.wav", 1, ATTN_NORM);
-
- self.punchangle_x = -4;
-
- self.currentammo = self.ammo_shells = self.ammo_shells - 2;
- dir = aim (self, 100000);
- FireBullets (14, dir, '0.14 0.08 0');
-};
-
-//======================================================================
-// Rockets
-//======================================================================
-
-void() s_explode1 = [0, s_explode2] { };
-void() s_explode2 = [1, s_explode3] { };
-void() s_explode3 = [2, s_explode4] { };
-void() s_explode4 = [3, s_explode5] { };
-void() s_explode5 = [4, s_explode6] { };
-void() s_explode6 = [5, sub_remove] { };
-
-void() BecomeExplosion =
-{
- self.movetype = MOVETYPE_NONE;
- self.velocity = '0 0 0';
- self.touch = sub_null;
- setmodel (self, "progs/s_explod.spr");
- self.solid = SOLID_NOT;
- s_explode1 ();
-};
-
-void() T_MissileTouch =
-{
- local float damg;
-
- if (other == self.owner)
- return; // don't explode on owner
-
- if (pointcontents(self.origin) == CONTENT_SKY)
- {
- remove(self);
- return;
- }
-
- damg = 100 + random()*20;
-
- if (other.health)
- {
- if (other.classname == "monster_shambler")
- damg = damg * 0.5; // mostly immune
- T_Damage (other, self, self.owner, damg );
- }
-
- // don't do radius damage to the other, because all the damage
- // was done in the impact
- T_RadiusDamage (self, self.owner, 120, other);
-
-// sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM);
- self.origin = self.origin - 8*normalize(self.velocity);
-
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_EXPLOSION);
- WriteCoord (MSG_BROADCAST, self.origin_x);
- WriteCoord (MSG_BROADCAST, self.origin_y);
- WriteCoord (MSG_BROADCAST, self.origin_z);
-
- BecomeExplosion ();
-
-};
-//dumptruck_ds start -- from inside qc tut http://www.insideqc.com/qctut/lesson-32.shtml
-
-void(float direct, float splash) T_MonsterMisTouch =
-{
- local float damg;
-
- if (other == self.owner)
- return; // don't explode on owner
-
- if (pointcontents(self.origin) == CONTENT_SKY)
- {
- remove(self);
- return;
- }
-
- damg = direct + random()*2; //dumptruck_ds
-
- if (other.health)
- {
- if (other.classname == "monster_shambler")
- damg = damg * 0.5; // mostly immune
- T_Damage (other, self, self.owner, damg );
- }
-
- // don't do radius damage to the other, because all the damage
- // was done in the impact
- T_RadiusDamage (self, self.owner, splash, other); //dumptruck_ds
-
-// sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM);
- self.origin = self.origin - 8*normalize(self.velocity);
-
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_EXPLOSION);
- WriteCoord (MSG_BROADCAST, self.origin_x);
- WriteCoord (MSG_BROADCAST, self.origin_y);
- WriteCoord (MSG_BROADCAST, self.origin_z);
-
- BecomeExplosion ();
-};
-
-void() T_GruntMisTouch =
-{
- T_MonsterMisTouch(30, 40);
-};
-
- // less direct damage, more splash than grunt
- // TODO: add damage modifier
-void() T_HellKnightMisTouch =
-{
- T_MonsterMisTouch(20, 50);
-};
-
-// big damage. explody scrag should be beefy.
-// TODO: add damage modifier
-void() T_WizardMisTouch =
-{
- T_MonsterMisTouch(50, 50);
-};
-//dumptruck_ds end
-
-/*
-================
-W_FireRocket
-================
-*/
-void() W_FireRocket =
-{
- local entity missile;
-
- self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
-
- sound (self, CHAN_WEAPON, "weapons/sgun1.wav", 1, ATTN_NORM);
-
- self.punchangle_x = -2;
-
- missile = spawn ();
- missile.owner = self;
- missile.movetype = MOVETYPE_FLYMISSILE;
- missile.solid = SOLID_BBOX;
- missile.classname = "missile";
-
-// set missile speed
-
- makevectors (self.v_angle);
- missile.velocity = aim(self, 1000);
- missile.velocity = missile.velocity * 1000;
- missile.angles = vectoangles(missile.velocity);
-
- missile.touch = T_MissileTouch;
-
-// set missile duration
- missile.nextthink = time + 5;
- missile.think = sub_remove;
-
- setmodel (missile, "progs/missile.mdl");
- setsize (missile, '0 0 0', '0 0 0');
- setorigin (missile, self.origin + v_forward*8 + '0 0 16');
-};
-/*
-================
-W_GruntRocket //dumptruck_ds start -- from inside qc tut http://www.insideqc.com/qctut/lesson-32.shtml
-================
-*/
-void() W_GruntRocket =
-{
- local entity missile;
-
- // self.currentammo = self.ammo_rockets = self.ammo_rockets - 1; dumptruck_ds
-
- sound_attack (self, CHAN_WEAPON, "weapons/sgun1.wav", 1, ATTN_NORM);
-
- self.punchangle_x = -2;
-
- missile = spawn ();
- missile.owner = self;
- missile.movetype = MOVETYPE_FLYMISSILE;
- missile.solid = SOLID_BBOX;
- missile.classname = "missile";
-
-// set missile speed -- dumptruck_ds below
-
- missile.velocity = normalize(self.enemy.origin - self.origin);
- SetSpeed(missile, missile.velocity, 900*self.proj_speed_mod);
- missile.angles = vectoangles(missile.velocity);
- missile.touch = T_GruntMisTouch;
-
- // makevectors (self.v_angle);
- // missile.velocity = aim(self, 1000);
- // missile.velocity = missile.velocity * 1000;
- // missile.angles = vectoangles(missile.velocity);
-
- // missile.touch = T_MissileTouch;
-
-// set missile duration
- if (self.homing > 0)
- {
- SetupHoming(missile, 900 * self.proj_speed_mod);
- }
- else {
- missile.nextthink = time + 5;
- missile.think = sub_remove;
- }
- if (self.mdl_proj != "") // dumptruck_ds
- {
- setmodel (missile, self.mdl_proj);
- }
- else
- {
- setmodel (missile, "progs/missile.mdl");
- }
-
- if (!missile.skin_proj) // dumptruck_ds
- {
- missile.skin = self.skin_proj;
- }
- else
- {
- missile.skin = 0;
- }
-// dumptruck_ds - end
-
- // setmodel (missile, "progs/missile.mdl");
- setsize (missile, '0 0 0', '0 0 0');
- makevectors (self.angles); //thanks Voidforce -- dumptruck_ds
- setorigin (missile, self.origin + v_forward * 30 + v_right * 5 + '0 0 12');
- // setorigin (missile, self.origin + v_forward*8 + '0 0 16');
-};
-
-//end dumptruck_ds grunt missle end
-
-//======================================================================
-// Lightning
-//======================================================================
-
-/*
-=================
-LightningDamage
-=================
-*/
void(vector p1, vector p2, entity from, float damage) LightningDamage =
{
- local entity e1, e2;
- local vector f;
+ local entity e1, e2;
+ local vector f;
f = p2 - p1;
normalize (f);
f_x = 0 - f_y;
f_y = f_x;
f_z = 0;
- f = f*16;
+ f = f * 16;
e1 = e2 = world;
traceline (p1, p2, FALSE, self);
if (trace_ent.takedamage)
{
- particle (trace_endpos, '0 0 100', 225, damage*4);
+ particle (trace_endpos, '0 0 100', 225, damage * 4);
T_Damage (trace_ent, from, from, damage);
if (self.classname == "player")
{
if (other.classname == "player")
- trace_ent.velocity_z = trace_ent.velocity_z + 400;
+ trace_ent.velocity_z += 400;
}
}
e1 = trace_ent;
@@ -502,7 +120,7 @@ void(vector p1, vector p2, entity from, float damage) LightningDamage =
traceline (p1 + f, p2 + f, FALSE, self);
if (trace_ent != e1 && trace_ent.takedamage)
{
- particle (trace_endpos, '0 0 100', 225, damage*4);
+ particle (trace_endpos, '0 0 100', 225, damage * 4);
T_Damage (trace_ent, from, from, damage);
}
e2 = trace_ent;
@@ -510,16 +128,15 @@ void(vector p1, vector p2, entity from, float damage) LightningDamage =
traceline (p1 - f, p2 - f, FALSE, self);
if (trace_ent != e1 && trace_ent != e2 && trace_ent.takedamage)
{
- particle (trace_endpos, '0 0 100', 225, damage*4);
+ particle (trace_endpos, '0 0 100', 225, damage * 4);
T_Damage (trace_ent, from, from, damage);
}
};
-
void() W_FireLightning =
{
- local vector org;
- local float cells;
+ local vector org;
+ local float cells;
if (self.ammo_cells < 1)
{
@@ -538,7 +155,7 @@ void() W_FireLightning =
self.ammo_cells = 0;
if (self.classname == "player")
PlayerSetCurrentAmmo ();
- T_RadiusDamage (self, self, 35*cells, world);
+ T_RadiusDamage (self, self, 35 * cells, world);
return;
}
@@ -555,7 +172,7 @@ void() W_FireLightning =
org = self.origin + '0 0 16';
// org = self.origin;
- traceline (org, org + v_forward*600, TRUE, self);
+ traceline (org, org + v_forward * 600, TRUE, self);
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_LIGHTNING2);
@@ -567,376 +184,7 @@ void() W_FireLightning =
WriteCoord (MSG_BROADCAST, trace_endpos_y);
WriteCoord (MSG_BROADCAST, trace_endpos_z);
- LightningDamage (self.origin, trace_endpos + v_forward*4, self, 30);
-};
-
-
-//=============================================================================
-
-//======================================================================
-// Grenades
-//======================================================================
-
-/*
-================
-GrenadeExplode2
-
-This is the same as the original GrenadeExplode function except that it
-will ignore the entity specified by the "ignore" parameter when dealing
-damage. -- iw
-================
-*/
-void(entity ignore) GrenadeExplode2 =
-{
- T_RadiusDamage (self, self.owner, 120, ignore);
-
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_EXPLOSION);
- WriteCoord (MSG_BROADCAST, self.origin_x);
- WriteCoord (MSG_BROADCAST, self.origin_y);
- WriteCoord (MSG_BROADCAST, self.origin_z);
-
- BecomeExplosion ();
-};
-
-
-/*
-================
-GrenadeExplode
-
-Refactored. -- iw
-================
-*/
-void() GrenadeExplode =
-{
- GrenadeExplode2 (world);
-};
-
-
-/*
-================
-GrenadeTouch
-
-This has been modified to fix a bug in the original code, which is that
-an entity with a very large bounding box (e.g. the size of monster_boss
-or monster_oldone) would receive little or no damage from a grenade
-impact. (In the original game, this bug didn't really matter because
-the largest DAMAGE_AIM entities were Shambler-sized.)
-
-In the original code, this function simply called GrenadeExplode, which
-called T_RadiusDamage, which deals an amount of damage based on the
-distance to the center of the victim's bounding box. Therefore, the
-larger the victim's bounding box, the lower the amount of damage that
-a grenade impact could deal.
-
-This modified version of GrenadeTouch adds a hack so that an entity
-which is larger than Shambler-size is treated differently: damage will
-be dealt to it using the same logic as a rocket impact, i.e. T_Damage
-will be called to deal damage to the impacted entity, and then radius
-damage will be dealt to any other entities in the vicinity. Grenades
-and rockets have always dealt the same amount of radius damage, so
-making the impact damage the same seemed a reasonable solution.
-
-The reason this logic is only used for very large entities is because
-I didn't want to affect the amount of damage that grenades deal to any
-of the original monsters under any circumstances. -- iw
-================
-*/
-void() GrenadeTouch =
-{
- local float damg;
-
- if (other == self.owner)
- return; // don't explode on owner
- if (other.takedamage == DAMAGE_AIM)
- {
- // see the explanation above -- iw
- if (other.size_x > VEC_HULL2_SIZE_x ||
- other.size_y > VEC_HULL2_SIZE_y ||
- other.size_z > VEC_HULL2_SIZE_z)
- {
- // note that the logic for monster_shambler's partial immunity
- // to explosions is not required because this is only for
- // entities which are larger than monster_shambler -- iw
- damg = 100 + random () * 20;
- T_Damage (other, self, self.owner, damg);
- GrenadeExplode2 (other);
- return;
- }
- GrenadeExplode ();
- return;
- }
- if (self.count < time) {
- sound (self, CHAN_WEAPON, "weapons/bounce.wav", 1, ATTN_NORM); // bounce sound
- }
- self.count = time + .02;
- if (self.velocity == '0 0 0')
- self.avelocity = '0 0 0';
-};
-
-
-/*
-================
-W_FireGrenade
-================
-*/
-void() W_FireGrenade =
-{
- local entity missile;
-
- self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
-
- sound (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
-
- self.punchangle_x = -2;
-
- missile = spawn ();
- missile.owner = self;
- missile.movetype = MOVETYPE_BOUNCE;
- missile.solid = SOLID_BBOX;
- missile.classname = "grenade";
-
-// set missile speed
-
- makevectors (self.v_angle);
-
- if (self.v_angle_x)
- missile.velocity = v_forward*600 + v_up * 200 + crandom()*v_right*10 + crandom()*v_up*10;
- else
- {
- missile.velocity = aim(self, 10000);
- missile.velocity = missile.velocity * 600;
- missile.velocity_z = 200;
- }
-
- missile.avelocity = '300 300 300';
-
- missile.angles = vectoangles(missile.velocity);
-
- missile.touch = GrenadeTouch;
-
-// set missile duration
- missile.nextthink = time + 2.5;
- missile.think = GrenadeExplode;
-
- setmodel (missile, "progs/grenade.mdl");
- setsize (missile, '0 0 0', '0 0 0');
- setorigin (missile, self.origin);
-};
-
-
-//=============================================================================
-
-//======================================================================
-// Nails
-//======================================================================
-
-void() spike_touch;
-void() superspike_touch;
-
-/*
-===============
-launch_spike
-
-Used for both the player and the ogre
-===============
-*/
-
-void(vector org, vector dir, float speed) launch_spike2 = {
- newmis = spawn ();
- newmis.owner = self;
- newmis.movetype = MOVETYPE_FLYMISSILE;
- newmis.solid = SOLID_BBOX;
-
- newmis.angles = vectoangles(dir);
-
- newmis.touch = spike_touch;
- newmis.classname = "spike";
- if (self.homing > 0)
- {
- SetupHoming(newmis, speed);
- }
- else
- {
- newmis.think = sub_remove;
- newmis.nextthink = time + 6;
- }
- setmodel (newmis, "progs/spike.mdl");
- setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
- setorigin (newmis, org);
-
- SetSpeed(newmis, dir, speed * (self.proj_speed_mod ? self.proj_speed_mod : 1));
-};
-void(vector org, vector dir) launch_spike = {
- launch_spike2(org,dir,1000);
-};
-
-void() W_FireSuperSpikes =
-{
- local vector dir;
-
- sound (self, CHAN_WEAPON, "weapons/spike2.wav", 1, ATTN_NORM);
- self.attack_finished = time + 0.2;
- self.currentammo = self.ammo_nails = self.ammo_nails - 2;
- dir = aim (self, 1000);
- launch_spike (self.origin + '0 0 16', dir);
- newmis.touch = superspike_touch;
- setmodel (newmis, "progs/s_spike.mdl");
- setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
- self.punchangle_x = -2;
-};
-
-void(float ox) W_FireSpikes =
-{
- local vector dir;
-
- makevectors (self.v_angle);
-
- if (self.ammo_nails >= 2 && self.weapon == IT_SUPER_NAILGUN)
- {
- W_FireSuperSpikes ();
- return;
- }
-
- if (self.ammo_nails < 1)
- {
- if (self.classname == "player")
- {
- self.weapon = PlayerBestWeapon ();
- PlayerSetCurrentAmmo ();
- }
- return;
- }
-
- sound (self, CHAN_WEAPON, "weapons/rocket1i.wav", 1, ATTN_NORM);
- self.attack_finished = time + 0.2;
- self.currentammo = self.ammo_nails = self.ammo_nails - 1;
- dir = aim (self, 1000);
- // launch_spike (self.origin + '0 0 16' + v_right*ox, dir);
- launch_spike (self.origin + self.view_ofs + v_up * -8 + v_right*ox, dir); //seven Nailgun position fix - thanks to Greenwood -- dumptruck_ds
-
- self.punchangle_x = -2;
-};
-
-void() spike_touch =
-{
- if (other == self.owner)
- return;
-
- if (other.solid == SOLID_TRIGGER)
- return; // trigger field, do nothing
-
- if (pointcontents(self.origin) == CONTENT_SKY)
- {
- remove(self);
- return;
- }
-
-// hit something that bleeds
- if (other.takedamage)
- {
- spawn_touchblood (9);
- T_Damage (other, self, self.owner, 9);
- }
- else
- {
-
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- if (self.owner.snd_hit != __NULL__ && self.owner.snd_hit != "")
- {
- sound (self, CHAN_WEAPON, self.owner.snd_hit, 1, ATTN_STATIC); //dumptruck_ds
- WriteByte(MSG_BROADCAST, TE_GUNSHOT);
- }
-
- else if (self.classname == "wizspike")
- WriteByte (MSG_BROADCAST, TE_WIZSPIKE);
- else if (self.classname == "knightspike")
- WriteByte (MSG_BROADCAST, TE_KNIGHTSPIKE);
- else
- WriteByte (MSG_BROADCAST, TE_SPIKE);
- WriteCoord (MSG_BROADCAST, self.origin_x);
- WriteCoord (MSG_BROADCAST, self.origin_y);
- WriteCoord (MSG_BROADCAST, self.origin_z);
- }
-
- remove(self);
-
-};
-
-void() superspike_touch =
-{
- if (other == self.owner)
- return;
-
- if (other.solid == SOLID_TRIGGER)
- return; // trigger field, do nothing
-
- if (pointcontents(self.origin) == CONTENT_SKY)
- {
- remove(self);
- return;
- }
-
-// hit something that bleeds
- if (other.takedamage)
- {
- spawn_touchblood (18);
- T_Damage (other, self, self.owner, 18);
- }
- else
- {
- // TODO CEV radiusdamage from spikes (for climbing purposes)
- T_RadiusDamage (self, self.owner, 40, world);
- if (self.owner.snd_hit != __NULL__ && self.owner.snd_hit != "")
- {
- sound (self, CHAN_WEAPON, self.owner.snd_hit, 1, ATTN_STATIC); //dumptruck_ds
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte(MSG_BROADCAST, TE_GUNSHOT);
- }
- else
- {
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_SUPERSPIKE);
- }
- WriteCoord (MSG_BROADCAST, self.origin_x);
- WriteCoord (MSG_BROADCAST, self.origin_y);
- WriteCoord (MSG_BROADCAST, self.origin_z);
- }
-
- remove(self);
-
-};
-void() superduperspike_touch = //dumptruck_ds for Style 2 Ogre see ogre.qc
-{
- if (other == self.owner)
- return;
-
- if (other.solid == SOLID_TRIGGER)
- return; // trigger field, do nothing
-
- if (pointcontents(self.origin) == CONTENT_SKY)
- {
- remove(self);
- return;
- }
-
-// hit something that bleeds
- if (other.takedamage)
- {
- spawn_touchblood (36);
- T_Damage (other, self, self.owner, 36);
- sound(self, CHAN_VOICE, "fish/bite.wav", 1, ATTN_NORM);
- }
- else
- {
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_SUPERSPIKE);
- WriteCoord (MSG_BROADCAST, self.origin_x);
- WriteCoord (MSG_BROADCAST, self.origin_y);
- WriteCoord (MSG_BROADCAST, self.origin_z);
- }
-
- remove(self);
+ LightningDamage (self.origin, trace_endpos + v_forward * 4, self, 30);
};
/*
@@ -947,13 +195,10 @@ PLAYER WEAPON USE
===============================================================================
*/
-/*
-========
-SuperDamageSound
-
-Plays sound if needed
-========
-*/
+//----------------------------------------------------------------------
+// SuperDamageSound
+// Plays sound if needed
+//----------------------------------------------------------------------
void() SuperDamageSound =
{
if (self.super_damage_finished > time)
@@ -961,62 +206,70 @@ void() SuperDamageSound =
if (self.super_sound < time)
{
self.super_sound = time + 1;
- sound (self, CHAN_BODY, "items/damage3.wav", 1, ATTN_NORM);
+ sound (self, CHAN_BODY, "items/damage3.wav",
+ 1, ATTN_NORM);
}
}
return;
};
+//----------------------------------------------------------------------
void() MissileHome =
{
- local vector dir, vtemp;
+ local vector dir, vtemp;
vtemp = self.enemy.origin + '0 0 10';
if (self.enemy.health < 1)
{
- remove(self);
+ remove (self);
return;
}
- dir = normalize(vtemp - self.origin);
- if (self.homing < 1 && self.homing > 0) // can't do better than 100% homing
- {
- /*
- This finds a vector somewhere between the vector the projectile is currently
- travelling on and the vector that it would normally snap to for homing
- homing = .25 means it will go 25% to the new direction, but keep 75% of the
- original vector, resulting in a wider turning range.
- */
- dir = normalize((dir * self.homing) + normalize(self.velocity * (1 - self.homing)));
+ dir = normalize (vtemp - self.origin);
+ // can't do better than 100% homing
+ if (self.homing < 1 && self.homing > 0)
+ {
+ // This finds a vector somewhere between the vector the
+ // projectile is currently travelling on and the vector
+ // that it would normally snap to for homing
+ // homing = .25 means it will go 25% to the new direction,
+ // but keep 75% of the original vector, resulting in a
+ // wider turning range.
+ dir = normalize ((dir * self.homing) +
+ normalize(self.velocity * (1 - self.homing)));
}
+
if (!self.avelocity)
- self.angles = vectoangles(dir);
- SetSpeed(self, dir, self.proj_basespeed);
+ self.angles = vectoangles (dir);
+ SetSpeed (self, dir, self.proj_basespeed);
if (self.homing > 0)
{
- if (self.homing < 1 && self.attack_finished && self.attack_finished < time )
+ if (self.homing < 1 && self.attack_finished &&
+ self.attack_finished < time)
{
- //dprint("incrementing homing | ");
- //dprint("old: ");
- //dprint(ftos(self.homing));
- //dprint(" | new: ");
+ // dprint("incrementing homing | ");
+ // dprint("old: ");
+ // dprint(ftos(self.homing));
+ // dprint(" | new: ");
self.homing = self.homing + 0.005;
- //dprint(ftos(self.homing));
- //dprint("\n");
+ // dprint(ftos(self.homing));
+ // dprint("\n");
}
+
self.nextthink = time + 0.2;
self.think = MissileHome;
}
};
+//----------------------------------------------------------------------
void(entity mis, float speed) SetupHoming =
{
- local vector dir;
- local float dist, flytime, speedmod;
+ local vector dir;
+ local float dist, flytime, speedmod;
if (self.proj_speed_mod > 1)
{
- speedmod = 1/self.proj_speed_mod;
+ speedmod = 1 / self.proj_speed_mod;
}
else if (speed > 250)
{
@@ -1026,7 +279,8 @@ void(entity mis, float speed) SetupHoming =
{
speedmod = 1;
}
- dir = normalize((self.enemy.origin + '0 0 10') - self.origin);
+
+ dir = normalize ((self.enemy.origin + '0 0 10') - self.origin);
dist = vlen (self.enemy.origin - self.origin);
flytime = dist * 0.002 * speedmod;
if (flytime < 0.1)
@@ -1039,6 +293,7 @@ void(entity mis, float speed) SetupHoming =
mis.think = MissileHome;
if (self.waitmin > 0)
{
- mis.attack_finished = time + self.waitmin; // store time to start increasing
+ // store time to start increasing
+ mis.attack_finished = time + self.waitmin;
}
};
Return to the top of this page or return to the overview of this repo.