1/*
2==============================================================================
3
4SOLDIER / PLAYER
5
6==============================================================================
7*/
8
9$cd /raid/quake/id1/models/enforcer
10$origin 0 -6 24
11$base base
12$skin skin
13
14$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7
15
16$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 walk10
17$frame walk11 walk12 walk13 walk14 walk15 walk16
18
19$frame run1 run2 run3 run4 run5 run6 run7 run8
20
21$frame attack1 attack2 attack3 attack4 attack5 attack6
22$frame attack7 attack8 attack9 attack10
23
24$frame death1 death2 death3 death4 death5 death6 death7 death8
25$frame death9 death10 death11 death12 death13 death14
26
27$frame fdeath1 fdeath2 fdeath3 fdeath4 fdeath5 fdeath6 fdeath7 fdeath8
28$frame fdeath9 fdeath10 fdeath11
29
30$frame paina1 paina2 paina3 paina4
31
32$frame painb1 painb2 painb3 painb4 painb5
33
34$frame painc1 painc2 painc3 painc4 painc5 painc6 painc7 painc8
35
36$frame paind1 paind2 paind3 paind4 paind5 paind6 paind7 paind8
37$frame paind9 paind10 paind11 paind12 paind13 paind14 paind15 paind16
38$frame paind17 paind18 paind19
39
40
41void() Laser_Touch =
42{
43	local vector org;
44
45	if (other == self.owner)
46		return;		// don't explode on owner
47
48	if (pointcontents(self.origin) == CONTENT_SKY)
49	{
50		remove(self);
51		return;
52	}
53
54	sound (self, CHAN_WEAPON, "enforcer/enfstop.wav", 1, ATTN_STATIC);
55	org = self.origin - 8*normalize(self.velocity);
56
57	if (other.health)
58	{
59		SpawnBlood (org, self.velocity*0.2, 15);
60		T_Damage (other, self, self.owner, 15);
61	}
62	else
63	{
64		WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
65		WriteByte (MSG_BROADCAST, TE_GUNSHOT);
66		WriteCoord (MSG_BROADCAST, org_x);
67		WriteCoord (MSG_BROADCAST, org_y);
68		WriteCoord (MSG_BROADCAST, org_z);
69	}
70
71	remove(self);
72};
73
74void(vector org, vector vec) LaunchLaser =
75{
76	local	vector	vec;
77
78	if (self.classname == "monster_enforcer")
79		sound (self, CHAN_WEAPON, "enforcer/enfire.wav", 1, ATTN_NORM);
80
81	vec = normalize(vec);
82
83	newmis = spawn();
84	newmis.owner = self;
85	newmis.movetype = MOVETYPE_FLY;
86	newmis.solid = SOLID_BBOX;
87	newmis.effects = EF_DIMLIGHT;
88
89	setmodel (newmis, "progs/laser.mdl");
90	setsize (newmis, '0 0 0', '0 0 0');
91
92	setorigin (newmis, org);
93
94	newmis.velocity = vec * 600;
95	newmis.angles = vectoangles(newmis.velocity);
96
97	newmis.nextthink = time + 5;
98	newmis.think = SUB_Remove;
99	newmis.touch = Laser_Touch;
100};
101
102
103
104void() enforcer_fire =
105{
106	local vector org;
107
108	self.effects = self.effects | EF_MUZZLEFLASH;
109	makevectors (self.angles);
110
111	org = self.origin + v_forward * 30 + v_right * 8.5 + '0 0 16';
112
113	LaunchLaser(org, self.enemy.origin - self.origin);
114};
115
116//============================================================================
117
118void()	enf_stand1	=[	$stand1,	enf_stand2	] {ai_stand();};
119void()	enf_stand2	=[	$stand2,	enf_stand3	] {ai_stand();};
120void()	enf_stand3	=[	$stand3,	enf_stand4	] {ai_stand();};
121void()	enf_stand4	=[	$stand4,	enf_stand5	] {ai_stand();};
122void()	enf_stand5	=[	$stand5,	enf_stand6	] {ai_stand();};
123void()	enf_stand6	=[	$stand6,	enf_stand7	] {ai_stand();};
124void()	enf_stand7	=[	$stand7,	enf_stand1	] {ai_stand();};
125
126void()	enf_walk1	=[	$walk1 ,	enf_walk2	] {
127if (random() < 0.2)
128	sound (self, CHAN_VOICE, "enforcer/idle1.wav", 1, ATTN_IDLE);
129ai_walk(2);};
130void()	enf_walk2	=[	$walk2 ,	enf_walk3	] {ai_walk(4);};
131void()	enf_walk3	=[	$walk3 ,	enf_walk4	] {ai_walk(4);};
132void()	enf_walk4	=[	$walk4 ,	enf_walk5	] {ai_walk(3);};
133void()	enf_walk5	=[	$walk5 ,	enf_walk6	] {ai_walk(1);};
134void()	enf_walk6	=[	$walk6 ,	enf_walk7	] {ai_walk(2);};
135void()	enf_walk7	=[	$walk7 ,	enf_walk8	] {ai_walk(2);};
136void()	enf_walk8	=[	$walk8 ,	enf_walk9	] {ai_walk(1);};
137void()	enf_walk9	=[	$walk9 ,	enf_walk10	] {ai_walk(2);};
138void()	enf_walk10	=[	$walk10,	enf_walk11	] {ai_walk(4);};
139void()	enf_walk11	=[	$walk11,	enf_walk12	] {ai_walk(4);};
140void()	enf_walk12	=[	$walk12,	enf_walk13	] {ai_walk(1);};
141void()	enf_walk13	=[	$walk13,	enf_walk14	] {ai_walk(2);};
142void()	enf_walk14	=[	$walk14,	enf_walk15	] {ai_walk(3);};
143void()	enf_walk15	=[	$walk15,	enf_walk16	] {ai_walk(4);};
144void()	enf_walk16	=[	$walk16,	enf_walk1	] {ai_walk(2);};
145
146void()	enf_run1	=[	$run1  ,	enf_run2	] {
147if (random() < 0.2)
148	sound (self, CHAN_VOICE, "enforcer/idle1.wav", 1, ATTN_IDLE);
149ai_run(18);};
150void()	enf_run2	=[	$run2  ,	enf_run3	] {ai_run(14);};
151void()	enf_run3	=[	$run3  ,	enf_run4	] {ai_run(7);};
152void()	enf_run4	=[	$run4  ,	enf_run5	] {ai_run(12);};
153void()	enf_run5	=[	$run5  ,	enf_run6	] {ai_run(14);};
154void()	enf_run6	=[	$run6  ,	enf_run7	] {ai_run(14);};
155void()	enf_run7	=[	$run7  ,	enf_run8	] {ai_run(7);};
156void()	enf_run8	=[	$run8  ,	enf_run1	] {ai_run(11);};
157
158void()	enf_atk1	=[	$attack1,	enf_atk2	] {ai_face();};
159void()	enf_atk2	=[	$attack2,	enf_atk3	] {ai_face();};
160void()	enf_atk3	=[	$attack3,	enf_atk4	] {ai_face();};
161void()	enf_atk4	=[	$attack4,	enf_atk5	] {ai_face();};
162void()	enf_atk5	=[	$attack5,	enf_atk6	] {ai_face();};
163void()	enf_atk6	=[	$attack6,	enf_atk7	] {enforcer_fire();};
164void()	enf_atk7	=[	$attack7,	enf_atk8	] {ai_face();};
165void()	enf_atk8	=[	$attack8,	enf_atk9	] {ai_face();};
166void()	enf_atk9	=[	$attack5,	enf_atk10	] {ai_face();};
167void()	enf_atk10	=[	$attack6,	enf_atk11	] {enforcer_fire();};
168void()	enf_atk11	=[	$attack7,	enf_atk12	] {ai_face();};
169void()	enf_atk12	=[	$attack8,	enf_atk13	] {ai_face();};
170void()	enf_atk13	=[	$attack9,	enf_atk14	] {ai_face();};
171void()	enf_atk14	=[	$attack10,	enf_run1	] {ai_face();
172SUB_CheckRefire (enf_atk1);
173};
174
175void()	enf_paina1	=[	$paina1,	enf_paina2	] {};
176void()	enf_paina2	=[	$paina2,	enf_paina3	] {};
177void()	enf_paina3	=[	$paina3,	enf_paina4	] {};
178void()	enf_paina4	=[	$paina4,	enf_run1	] {};
179
180void()	enf_painb1	=[	$painb1,	enf_painb2	] {};
181void()	enf_painb2	=[	$painb2,	enf_painb3	] {};
182void()	enf_painb3	=[	$painb3,	enf_painb4	] {};
183void()	enf_painb4	=[	$painb4,	enf_painb5	] {};
184void()	enf_painb5	=[	$painb5,	enf_run1	] {};
185
186void()	enf_painc1	=[	$painc1,	enf_painc2	] {};
187void()	enf_painc2	=[	$painc2,	enf_painc3	] {};
188void()	enf_painc3	=[	$painc3,	enf_painc4	] {};
189void()	enf_painc4	=[	$painc4,	enf_painc5	] {};
190void()	enf_painc5	=[	$painc5,	enf_painc6	] {};
191void()	enf_painc6	=[	$painc6,	enf_painc7	] {};
192void()	enf_painc7	=[	$painc7,	enf_painc8	] {};
193void()	enf_painc8	=[	$painc8,	enf_run1	] {};
194
195void()	enf_paind1	=[	$paind1,	enf_paind2	] {};
196void()	enf_paind2	=[	$paind2,	enf_paind3	] {};
197void()	enf_paind3	=[	$paind3,	enf_paind4	] {};
198void()	enf_paind4	=[	$paind4,	enf_paind5	] {ai_painforward(2);};
199void()	enf_paind5	=[	$paind5,	enf_paind6	] {ai_painforward(1);};
200void()	enf_paind6	=[	$paind6,	enf_paind7	] {};
201void()	enf_paind7	=[	$paind7,	enf_paind8	] {};
202void()	enf_paind8	=[	$paind8,	enf_paind9	] {};
203void()	enf_paind9	=[	$paind9,	enf_paind10	] {};
204void()	enf_paind10	=[	$paind10,	enf_paind11	] {};
205void()	enf_paind11	=[	$paind11,	enf_paind12	] {ai_painforward(1);};
206void()	enf_paind12	=[	$paind12,	enf_paind13	] {ai_painforward(1);};
207void()	enf_paind13	=[	$paind13,	enf_paind14	] {ai_painforward(1);};
208void()	enf_paind14	=[	$paind14,	enf_paind15	] {};
209void()	enf_paind15	=[	$paind15,	enf_paind16	] {};
210void()	enf_paind16	=[	$paind16,	enf_paind17	] {ai_pain(1);};
211void()	enf_paind17	=[	$paind17,	enf_paind18	] {ai_pain(1);};
212void()	enf_paind18	=[	$paind18,	enf_paind19	] {};
213void()	enf_paind19	=[	$paind19,	enf_run1	] {};
214
215void(entity attacker, float damage)	enf_pain =
216{
217	local float r;
218
219	r = random ();
220	if (self.pain_finished > time)
221		return;
222
223
224	if (r < 0.5)
225		sound (self, CHAN_VOICE, "enforcer/pain1.wav", 1, ATTN_NORM);
226	else
227		sound (self, CHAN_VOICE, "enforcer/pain2.wav", 1, ATTN_NORM);
228
229	if (r < 0.2)
230	{
231		self.pain_finished = time + 1;
232		enf_paina1 ();
233	}
234	else if (r < 0.4)
235	{
236		self.pain_finished = time + 1;
237		enf_painb1 ();
238	}
239	else if (r < 0.7)
240	{
241		self.pain_finished = time + 1;
242		enf_painc1 ();
243	}
244	else
245	{
246		self.pain_finished = time + 2;
247		enf_paind1 ();
248	}
249};
250
251//============================================================================
252
253
254
255
256void()	enf_die1	=[	$death1,	enf_die2	] {};
257void()	enf_die2	=[	$death2,	enf_die3	] {};
258void()	enf_die3	=[	$death3,	enf_die4	]
259{self.solid = SOLID_NOT;self.ammo_cells = 5;DropBackpack();};
260void()	enf_die4	=[	$death4,	enf_die5	] {ai_forward(14);};
261void()	enf_die5	=[	$death5,	enf_die6	] {ai_forward(2);};
262void()	enf_die6	=[	$death6,	enf_die7	] {};
263void()	enf_die7	=[	$death7,	enf_die8	] {};
264void()	enf_die8	=[	$death8,	enf_die9	] {};
265void()	enf_die9	=[	$death9,	enf_die10	] {ai_forward(3);};
266void()	enf_die10	=[	$death10,	enf_die11	] {ai_forward(5);};
267void()	enf_die11	=[	$death11,	enf_die12	] {ai_forward(5);};
268void()	enf_die12	=[	$death12,	enf_die13	] {ai_forward(5);};
269void()	enf_die13	=[	$death13,	enf_die14	] {};
270void()	enf_die14	=[	$death14,	enf_die14	] {};
271
272void()	enf_fdie1	=[	$fdeath1,	enf_fdie2	] {
273
274};
275void()	enf_fdie2	=[	$fdeath2,	enf_fdie3	] {};
276void()	enf_fdie3	=[	$fdeath3,	enf_fdie4	]
277{self.solid = SOLID_NOT;self.ammo_cells = 5;DropBackpack();};
278void()	enf_fdie4	=[	$fdeath4,	enf_fdie5	] {};
279void()	enf_fdie5	=[	$fdeath5,	enf_fdie6	] {};
280void()	enf_fdie6	=[	$fdeath6,	enf_fdie7	] {};
281void()	enf_fdie7	=[	$fdeath7,	enf_fdie8	] {};
282void()	enf_fdie8	=[	$fdeath8,	enf_fdie9	] {};
283void()	enf_fdie9	=[	$fdeath9,	enf_fdie10	] {};
284void()	enf_fdie10	=[	$fdeath10,	enf_fdie11	] {};
285void()	enf_fdie11	=[	$fdeath11,	enf_fdie11	] {};
286
287
288void() enf_die =
289{
290// check for gib
291	if (self.health < -35)
292	{
293		sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
294		ThrowHead ("progs/h_mega.mdl", self.health);
295		ThrowGib ("progs/gib1.mdl", self.health);
296		ThrowGib ("progs/gib2.mdl", self.health);
297		ThrowGib ("progs/gib3.mdl", self.health);
298		return;
299	}
300
301// regular death
302	sound (self, CHAN_VOICE, "enforcer/death1.wav", 1, ATTN_NORM);
303	if (random() > 0.5)
304		enf_die1 ();
305	else
306		enf_fdie1 ();
307};
308
309
310/*QUAKED monster_enforcer (1 0 0) (-16 -16 -24) (16 16 40) Ambush
311
312*/
313void() monster_enforcer =
314{
315	if (deathmatch)
316	{
317		remove(self);
318		return;
319	}
320	precache_model2 ("progs/enforcer.mdl");
321	precache_model2 ("progs/h_mega.mdl");
322	precache_model2 ("progs/laser.mdl");
323
324	precache_sound2 ("enforcer/death1.wav");
325	precache_sound2 ("enforcer/enfire.wav");
326	precache_sound2 ("enforcer/enfstop.wav");
327	precache_sound2 ("enforcer/idle1.wav");
328	precache_sound2 ("enforcer/pain1.wav");
329	precache_sound2 ("enforcer/pain2.wav");
330	precache_sound2 ("enforcer/sight1.wav");
331	precache_sound2 ("enforcer/sight2.wav");
332	precache_sound2 ("enforcer/sight3.wav");
333	precache_sound2 ("enforcer/sight4.wav");
334
335	self.solid = SOLID_SLIDEBOX;
336	self.movetype = MOVETYPE_STEP;
337
338	setmodel (self, "progs/enforcer.mdl");
339
340	setsize (self, '-16 -16 -24', '16 16 40');
341	self.health = 80;
342
343	self.th_stand = enf_stand1;
344	self.th_walk = enf_walk1;
345	self.th_run = enf_run1;
346	self.th_pain = enf_pain;
347	self.th_die = enf_die;
348	self.th_missile = enf_atk1;
349
350	walkmonster_start();
351};
352