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.3;
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)
68 void ShalMissile_Spawn ()
70 local vector dir = '0 0 0';
73 self.realowner.effects |= EF_MUZZLEFLASH;
75 dir = normalize((self.owner.enemy.origin + '0 0 10') - self.owner.origin);
76 dist = vlen (self.owner.enemy.origin - self.owner.origin);
78 self.solid = SOLID_BBOX;
79 self.movetype = MOVETYPE_FLYMISSILE;
80 CSQCProjectile(self, TRUE, PROJECTILE_CRYLINK, TRUE);
82 self.realowner.v_angle = self.realowner.angles;
83 makevectors (self.realowner.angles);
85 setsize (self, '0 0 0', '0 0 0');
87 setorigin (self, self.realowner.origin + v_forward * 14 + '0 0 30' + v_right * -14);
88 self.velocity = dir * 400;
89 self.avelocity = '300 300 300';
90 self.enemy = self.realowner.enemy;
91 self.touch = W_Plasma_TouchExplode;
97 local entity missile = world;
99 sound (self, CHAN_WEAPON, "weapons/spike.wav", 1, ATTN_NORM);
102 missile.owner = missile.realowner = self;
104 missile.think = ShalMissile_Spawn;
105 missile.nextthink = time;
111 local vector dir = '0 0 0', vtemp = self.enemy.origin + '0 0 10';
113 self.shal_cycles += 1;
114 if (self.enemy.health <= 0 || self.owner.health <= 0 || self.shal_cycles >= 20)
119 dir = normalize(vtemp - self.origin);
120 UpdateCSQCProjectile(self);
121 if (autocvar_skill == 3)
122 self.velocity = dir * 350;
124 self.velocity = dir * 250;
125 self.nextthink = time + 0.2;
126 self.think = ShalHome;
129 float ShalrathCheckAttack ()
131 local vector spot1 = '0 0 0', spot2 = '0 0 0';
132 local entity targ = self.enemy;
134 if (self.health <= 0 || targ == world || targ.health < 1)
137 if(self.monster_delayedattack && self.delay != -1)
139 if(time < self.delay)
142 self.monster_delayedattack();
144 self.monster_delayedattack = func_null;
147 if(time < self.attack_finished_single)
150 if (vlen(self.enemy.origin - self.origin) <= 120)
152 if (self.attack_melee)
159 if (vlen(targ.origin - self.origin) >= 2000) // long traces are slow
162 // see if any entities are in the way of the shot
163 spot1 = self.origin + '0 0 10';
164 spot2 = targ.origin + '0 0 10';
166 traceline (spot1, spot2, FALSE, self);
168 if (trace_ent != targ && trace_fraction < 1)
169 return FALSE; // don't have a clear shot
171 //if (trace_inopen && trace_inwater)
172 // return FALSE; // sight line crossed contents
175 if (self.attack_ranged())
183 Monster_CheckDropCvars ("shalrath");
185 self.think = Monster_Fade;
186 self.frame = shalrath_anim_death;
187 self.solid = SOLID_NOT;
188 self.takedamage = DAMAGE_NO;
189 self.event_damage = func_null;
191 self.nextthink = time + 2.1;
192 self.pain_finished = self.nextthink;
193 self.movetype = MOVETYPE_TOSS;
195 monster_hook_death(); // for post-death mods
198 void shalrath_spawn ()
201 self.health = autocvar_g_monster_shalrath_health * self.scale;
203 self.damageforcescale = 0.003;
204 self.classname = "monster_shalrath";
205 self.checkattack = ShalrathCheckAttack;
206 self.attack_ranged = shal_missile;
207 self.attack_melee = shalrath_attack_melee;
208 self.nextthink = time + random() * 0.5 + 0.1;
209 self.think = shalrath_think;
210 self.frame = shalrath_anim_walk;
211 self.sprite_height = 40 * self.scale;
213 monster_hook_spawn(); // for post-spawn mods
216 void spawnfunc_monster_shalrath ()
218 if not(autocvar_g_monster_shalrath)
224 self.monster_spawnfunc = spawnfunc_monster_shalrath;
226 if(self.spawnflags & MONSTERFLAG_APPEAR)
228 self.think = func_null;
230 self.use = Monster_Appear;
237 if not (monster_initialize(
239 "models/monsters/shalrath.mdl",
240 SHALRATH_MIN, SHALRATH_MAX,
242 shalrath_die, shalrath_spawn))
249 // compatibility with old spawns
250 void spawnfunc_monster_vore () { spawnfunc_monster_shalrath(); }