1/* 2============================================================================== 3 4SHAL-RATH 5 6============================================================================== 7*/ 8$cd /raid/quake/id1/models/shalrath 9$origin 0 0 24 10$base base 11$skin skin 12$scale 0.7 13 14$frame attack1 attack2 attack3 attack4 attack5 attack6 attack7 attack8 15$frame attack9 attack10 attack11 16 17$frame pain1 pain2 pain3 pain4 pain5 18 19$frame death1 death2 death3 death4 death5 death6 death7 20 21$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 walk10 22$frame walk11 walk12 23 24void() shalrath_pain; 25void() ShalMissile; 26void() shal_stand =[ $walk1, shal_stand ] {ai_stand();}; 27 28void() shal_walk1 =[ $walk2, shal_walk2 ] { 29if (random() < 0.2) 30 sound (self, CHAN_VOICE, "shalrath/idle.wav", 1, ATTN_IDLE); 31ai_walk(6);}; 32void() shal_walk2 =[ $walk3, shal_walk3 ] {ai_walk(4);}; 33void() shal_walk3 =[ $walk4, shal_walk4 ] {ai_walk(0);}; 34void() shal_walk4 =[ $walk5, shal_walk5 ] {ai_walk(0);}; 35void() shal_walk5 =[ $walk6, shal_walk6 ] {ai_walk(0);}; 36void() shal_walk6 =[ $walk7, shal_walk7 ] {ai_walk(0);}; 37void() shal_walk7 =[ $walk8, shal_walk8 ] {ai_walk(5);}; 38void() shal_walk8 =[ $walk9, shal_walk9 ] {ai_walk(6);}; 39void() shal_walk9 =[ $walk10, shal_walk10 ] {ai_walk(5);}; 40void() shal_walk10 =[ $walk11, shal_walk11 ] {ai_walk(0);}; 41void() shal_walk11 =[ $walk12, shal_walk12 ] {ai_walk(4);}; 42void() shal_walk12 =[ $walk1, shal_walk1 ] {ai_walk(5);}; 43 44void() shal_run1 =[ $walk2, shal_run2 ] { 45if (random() < 0.2) 46 sound (self, CHAN_VOICE, "shalrath/idle.wav", 1, ATTN_IDLE); 47ai_run(6);}; 48void() shal_run2 =[ $walk3, shal_run3 ] {ai_run(4);}; 49void() shal_run3 =[ $walk4, shal_run4 ] {ai_run(0);}; 50void() shal_run4 =[ $walk5, shal_run5 ] {ai_run(0);}; 51void() shal_run5 =[ $walk6, shal_run6 ] {ai_run(0);}; 52void() shal_run6 =[ $walk7, shal_run7 ] {ai_run(0);}; 53void() shal_run7 =[ $walk8, shal_run8 ] {ai_run(5);}; 54void() shal_run8 =[ $walk9, shal_run9 ] {ai_run(6);}; 55void() shal_run9 =[ $walk10, shal_run10 ] {ai_run(5);}; 56void() shal_run10 =[ $walk11, shal_run11 ] {ai_run(0);}; 57void() shal_run11 =[ $walk12, shal_run12 ] {ai_run(4);}; 58void() shal_run12 =[ $walk1, shal_run1 ] {ai_run(5);}; 59 60void() shal_attack1 =[ $attack1, shal_attack2 ] { 61sound (self, CHAN_VOICE, "shalrath/attack.wav", 1, ATTN_NORM); 62ai_face(); 63}; 64void() shal_attack2 =[ $attack2, shal_attack3 ] {ai_face();}; 65void() shal_attack3 =[ $attack3, shal_attack4 ] {ai_face();}; 66void() shal_attack4 =[ $attack4, shal_attack5 ] {ai_face();}; 67void() shal_attack5 =[ $attack5, shal_attack6 ] {ai_face();}; 68void() shal_attack6 =[ $attack6, shal_attack7 ] {ai_face();}; 69void() shal_attack7 =[ $attack7, shal_attack8 ] {ai_face();}; 70void() shal_attack8 =[ $attack8, shal_attack9 ] {ai_face();}; 71void() shal_attack9 =[ $attack9, shal_attack10 ] {ShalMissile();}; 72void() shal_attack10 =[ $attack10, shal_attack11 ] {ai_face();}; 73void() shal_attack11 =[ $attack11, shal_run1 ] {}; 74 75void() shal_pain1 =[ $pain1, shal_pain2 ] {}; 76void() shal_pain2 =[ $pain2, shal_pain3 ] {}; 77void() shal_pain3 =[ $pain3, shal_pain4 ] {}; 78void() shal_pain4 =[ $pain4, shal_pain5 ] {}; 79void() shal_pain5 =[ $pain5, shal_run1 ] {}; 80 81void() shal_death1 =[ $death1, shal_death2 ] {}; 82void() shal_death2 =[ $death2, shal_death3 ] {}; 83void() shal_death3 =[ $death3, shal_death4 ] {}; 84void() shal_death4 =[ $death4, shal_death5 ] {}; 85void() shal_death5 =[ $death5, shal_death6 ] {}; 86void() shal_death6 =[ $death6, shal_death7 ] {}; 87void() shal_death7 =[ $death7, shal_death7 ] {}; 88 89 90void() shalrath_pain = 91{ 92 if (self.pain_finished > time) 93 return; 94 95 sound (self, CHAN_VOICE, "shalrath/pain.wav", 1, ATTN_NORM); 96 shal_pain1(); 97 self.pain_finished = time + 3; 98}; 99 100void() shalrath_die = 101{ 102// check for gib 103 if (self.health < -90) 104 { 105 sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM); 106 ThrowHead ("progs/h_shal.mdl", self.health); 107 ThrowGib ("progs/gib1.mdl", self.health); 108 ThrowGib ("progs/gib2.mdl", self.health); 109 ThrowGib ("progs/gib3.mdl", self.health); 110 return; 111 } 112 113 sound (self, CHAN_VOICE, "shalrath/death.wav", 1, ATTN_NORM); 114 shal_death1(); 115 self.solid = SOLID_NOT; 116 // insert death sounds here 117}; 118 119/* 120================ 121ShalMissile 122================ 123*/ 124void() ShalMissileTouch; 125void() ShalHome; 126void() ShalMissile = 127{ 128 local entity missile; 129 local vector dir; 130 local float dist, flytime; 131 132 dir = normalize((self.enemy.origin + '0 0 10') - self.origin); 133 dist = vlen (self.enemy.origin - self.origin); 134 flytime = dist * 0.002; 135 if (flytime < 0.1) 136 flytime = 0.1; 137 138 self.effects = self.effects | EF_MUZZLEFLASH; 139 sound (self, CHAN_WEAPON, "shalrath/attack2.wav", 1, ATTN_NORM); 140 141 missile = spawn (); 142 missile.owner = self; 143 144 missile.solid = SOLID_BBOX; 145 missile.movetype = MOVETYPE_FLYMISSILE; 146 setmodel (missile, "progs/v_spike.mdl"); 147 148 setsize (missile, '0 0 0', '0 0 0'); 149 150 missile.origin = self.origin + '0 0 10'; 151 missile.velocity = dir * 400; 152 missile.avelocity = '300 300 300'; 153 missile.nextthink = flytime + time; 154 missile.think = ShalHome; 155 missile.enemy = self.enemy; 156 missile.touch = ShalMissileTouch; 157}; 158 159void() ShalHome = 160{ 161 local vector dir, vtemp; 162 vtemp = self.enemy.origin + '0 0 10'; 163 if (self.enemy.health < 1) 164 { 165 remove(self); 166 return; 167 } 168 dir = normalize(vtemp - self.origin); 169 if (skill == 3) 170 self.velocity = dir * 350; 171 else 172 self.velocity = dir * 250; 173 self.nextthink = time + 0.2; 174 self.think = ShalHome; 175}; 176 177void() ShalMissileTouch = 178{ 179 if (other == self.owner) 180 return; // don't explode on owner 181 182 if (other.classname == "monster_zombie") 183 T_Damage (other, self, self, 110); 184 T_RadiusDamage (self, self.owner, 40, world); 185 sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM); 186 187 WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); 188 WriteByte (MSG_BROADCAST, TE_EXPLOSION); 189 WriteCoord (MSG_BROADCAST, self.origin_x); 190 WriteCoord (MSG_BROADCAST, self.origin_y); 191 WriteCoord (MSG_BROADCAST, self.origin_z); 192 193 self.velocity = '0 0 0'; 194 self.touch = SUB_Null; 195 setmodel (self, "progs/s_explod.spr"); 196 self.solid = SOLID_NOT; 197 s_explode1 (); 198}; 199 200//================================================================= 201 202/*QUAKED monster_shalrath (1 0 0) (-32 -32 -24) (32 32 48) Ambush 203*/ 204void() monster_shalrath = 205{ 206 if (deathmatch) 207 { 208 remove(self); 209 return; 210 } 211 precache_model2 ("progs/shalrath.mdl"); 212 precache_model2 ("progs/h_shal.mdl"); 213 precache_model2 ("progs/v_spike.mdl"); 214 215 precache_sound2 ("shalrath/attack.wav"); 216 precache_sound2 ("shalrath/attack2.wav"); 217 precache_sound2 ("shalrath/death.wav"); 218 precache_sound2 ("shalrath/idle.wav"); 219 precache_sound2 ("shalrath/pain.wav"); 220 precache_sound2 ("shalrath/sight.wav"); 221 222 self.solid = SOLID_SLIDEBOX; 223 self.movetype = MOVETYPE_STEP; 224 225 setmodel (self, "progs/shalrath.mdl"); 226 setsize (self, VEC_HULL2_MIN, VEC_HULL2_MAX); 227 self.health = 400; 228 229 self.th_stand = shal_stand; 230 self.th_walk = shal_walk1; 231 self.th_run = shal_run1; 232 self.th_die = shalrath_die; 233 self.th_pain = shalrath_pain; 234 self.th_missile = shal_attack1; 235 236 self.think = walkmonster_start; 237 self.nextthink = time + 0.1 + random ()*0.1; 238 239}; 240