2 const vector SHALRATH_MIN = '-32 -32 -24';
3 const vector SHALRATH_MAX = '32 32 32';
6 float autocvar_g_monster_shalrath;
7 float autocvar_g_monster_shalrath_health;
8 float autocvar_g_monster_shalrath_damage;
9 float autocvar_g_monster_shalrath_speed;
12 #define shalrath_anim_attack 0
13 #define shalrath_anim_pain 1
14 #define shalrath_anim_death 2
15 #define shalrath_anim_walk 3
19 void shalrath_think ()
21 self.think = shalrath_think;
22 self.nextthink = time + 0.1;
25 self.nextthink = self.delay;
27 monster_move(autocvar_g_monster_shalrath_speed, autocvar_g_monster_shalrath_speed, 50, shalrath_anim_walk, shalrath_anim_walk, shalrath_anim_walk);
30 void shalrath_attack ()
32 self.frame = shalrath_anim_attack;
33 self.delay = time + 0.1;
34 self.attack_finished_single = time + 0.7;
35 self.monster_delayedattack = ShalMissile;
38 void shalrathattack_melee ()
40 float bigdmg = 0, rdmg = autocvar_g_monster_shalrath_damage * random();
42 bigdmg = rdmg * self.scale;
44 monster_melee(self.enemy, bigdmg * monster_skill, 120, DEATH_MONSTER_SHALRATH_MELEE);
47 void shalrath_attack_melee ()
49 self.monster_delayedattack = shalrathattack_melee;
50 self.delay = time + 0.2;
51 self.frame = shalrath_anim_attack;
52 self.attack_finished_single = time + 0.7;
57 // don't throw if it is blocked
58 traceline(self.origin + '0 0 10', self.enemy.origin + '0 0 10', FALSE, self);
59 if (enemy_range() > 1000)
61 if (trace_ent != self.enemy)
70 local vector dir = '0 0 0', vtemp = self.enemy.origin + '0 0 10';
72 self.shal_cycles += 1;
73 if (self.enemy.health <= 0 || self.owner.health <= 0 || self.shal_cycles >= 20)
78 dir = normalize(vtemp - self.origin);
79 UpdateCSQCProjectile(self);
80 if (monster_skill == 3)
81 self.velocity = dir * 350;
83 self.velocity = dir * 250;
84 self.nextthink = time + 0.2;
85 self.think = ShalHome;
90 local entity missile = world;
91 local vector dir = '0 0 0';
94 self.effects |= EF_MUZZLEFLASH;
96 sound (self, CHAN_WEAPON, "weapons/spike.wav", 1, ATTN_NORM);
99 missile.owner = missile.realowner = self;
101 self.v_angle = self.angles;
102 makevectors (self.angles);
104 dir = normalize((self.enemy.origin + '0 0 10') - self.origin);
105 dist = vlen (self.enemy.origin - self.origin);
107 missile.think = ShalHome;
108 missile.nextthink = time;
109 missile.solid = SOLID_BBOX;
110 missile.movetype = MOVETYPE_FLYMISSILE;
111 missile.flags = FL_PROJECTILE;
112 setorigin (missile, self.origin + v_forward * 14 + '0 0 30' + v_right * -14);
113 setsize (missile, '0 0 0', '0 0 0');
114 missile.velocity = dir * 400;
115 missile.avelocity = '300 300 300';
116 missile.enemy = self.enemy;
117 missile.touch = W_Plasma_TouchExplode;
119 CSQCProjectile(missile, TRUE, PROJECTILE_CRYLINK, TRUE);
122 float ShalrathCheckAttack ()
124 local vector spot1 = '0 0 0', spot2 = '0 0 0';
125 local entity targ = self.enemy;
127 if (self.health <= 0 || targ == world || targ.health < 1)
130 if(self.monster_delayedattack && self.delay != -1)
132 if(time < self.delay)
135 self.monster_delayedattack();
137 self.monster_delayedattack = func_null;
140 if(time < self.attack_finished_single)
143 if (vlen(self.enemy.origin - self.origin) <= 120)
145 if (self.attack_melee)
152 if (vlen(targ.origin - self.origin) >= 2000) // long traces are slow
155 // see if any entities are in the way of the shot
156 spot1 = self.origin + '0 0 10';
157 spot2 = targ.origin + '0 0 10';
159 traceline (spot1, spot2, FALSE, self);
161 if (trace_ent != targ && trace_fraction < 1)
162 return FALSE; // don't have a clear shot
164 //if (trace_inopen && trace_inwater)
165 // return FALSE; // sight line crossed contents
168 if (self.attack_ranged())
176 Monster_CheckDropCvars ("shalrath");
178 self.think = Monster_Fade;
179 self.frame = shalrath_anim_death;
180 self.solid = SOLID_NOT;
181 self.takedamage = DAMAGE_NO;
182 self.event_damage = func_null;
184 self.nextthink = time + 2.1;
185 self.pain_finished = self.nextthink;
186 self.movetype = MOVETYPE_TOSS;
188 monster_hook_death(); // for post-death mods
191 void shalrath_spawn ()
194 self.health = autocvar_g_monster_shalrath_health * self.scale;
196 self.damageforcescale = 0.003;
197 self.classname = "monster_shalrath";
198 self.checkattack = ShalrathCheckAttack;
199 self.attack_ranged = shal_missile;
200 self.attack_melee = shalrath_attack_melee;
201 self.nextthink = time + random() * 0.5 + 0.1;
202 self.think = shalrath_think;
203 self.frame = shalrath_anim_walk;
204 self.sprite_height = 40 * self.scale;
206 monster_hook_spawn(); // for post-spawn mods
209 void spawnfunc_monster_shalrath ()
211 if not(autocvar_g_monster_shalrath)
217 self.monster_spawnfunc = spawnfunc_monster_shalrath;
219 if(self.spawnflags & MONSTERFLAG_APPEAR)
221 self.think = func_null;
223 self.use = Monster_Appear;
230 if not (monster_initialize(
232 "models/monsters/shalrath.mdl",
233 SHALRATH_MIN, SHALRATH_MAX,
235 shalrath_die, shalrath_spawn))
242 // compatibility with old spawns
243 void spawnfunc_monster_vore () { spawnfunc_monster_shalrath(); }