1 //-------------------------------------------------------------------------
2 /*
3 Copyright (C) 1997, 2005 - 3D Realms Entertainment
4
5 This file is part of Shadow Warrior version 1.2
6
7 Shadow Warrior is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; either version 2
10 of the License, or (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
16 See the GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
22 Original Source: 1997 - Frank Maddin and Jim Norwood
23 Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms
24 */
25 //-------------------------------------------------------------------------
26 #include "build.h"
27
28 #include "keys.h"
29 #include "names2.h"
30 #include "game.h"
31 #include "tags.h"
32 #include "ai.h"
33 #include "sprite.h"
34 #include "actor.h"
35 #include "weapon.h"
36 #include "track.h"
37
38 ANIMATOR DoCoolgCircle,InitCoolgCircle;
39
40 DECISION CoolgBattle[] =
41 {
42 {50, InitCoolgCircle },
43 {450, InitActorMoveCloser },
44 //{456, InitActorAmbientNoise },
45 //{760, InitActorRunAway },
46 {1024, InitActorAttack }
47 };
48
49 DECISION CoolgOffense[] =
50 {
51 {449, InitActorMoveCloser },
52 //{554, InitActorAmbientNoise },
53 {1024, InitActorAttack }
54 };
55
56 DECISION CoolgBroadcast[] =
57 {
58 //{1, InitActorAlertNoise },
59 {1, InitActorAmbientNoise },
60 {1024, InitActorDecide }
61 };
62
63 DECISION CoolgSurprised[] =
64 {
65 {100, InitCoolgCircle },
66 {701, InitActorMoveCloser },
67 {1024, InitActorDecide }
68 };
69
70 DECISION CoolgEvasive[] =
71 {
72 {20, InitCoolgCircle },
73 {1024, InitActorRunAway },
74 };
75
76 DECISION CoolgLostTarget[] =
77 {
78 {900, InitActorFindPlayer },
79 {1024, InitActorWanderAround }
80 };
81
82 DECISION CoolgCloseRange[] =
83 {
84 {800, InitActorAttack },
85 {1024, InitActorReposition }
86 };
87
88 DECISION CoolgTouchTarget[] =
89 {
90 //{50, InitCoolgCircle },
91 {1024, InitActorAttack },
92 };
93
94 PERSONALITY CoolgPersonality =
95 {
96 CoolgBattle,
97 CoolgOffense,
98 CoolgBroadcast,
99 CoolgSurprised,
100 CoolgEvasive,
101 CoolgLostTarget,
102 CoolgCloseRange,
103 CoolgTouchTarget
104 };
105
106 ATTRIBUTE CoolgAttrib =
107 {
108 {60, 80, 150, 190}, // Speeds
109 {3, 0, -2, -3}, // Tic Adjusts
110 3, // MaxWeapons;
111 {DIGI_CGAMBIENT, DIGI_CGALERT, 0,
112 DIGI_CGPAIN, DIGI_CGSCREAM, DIGI_CGMATERIALIZE,
113 DIGI_CGTHIGHBONE,DIGI_CGMAGIC,DIGI_CGMAGICHIT,0}
114 };
115
116 //////////////////////
117 //
118 // COOLG RUN
119 //////////////////////
120
121 #define COOLG_RUN_RATE 40
122
123 ANIMATOR DoCoolgMove,NullAnimator,DoStayOnFloor, DoActorDebris, NullCoolg, DoCoolgBirth;
124
125 STATE s_CoolgRun[5][4] =
126 {
127 {
128 {COOLG_RUN_R0 + 0, COOLG_RUN_RATE, DoCoolgMove, &s_CoolgRun[0][1]},
129 {COOLG_RUN_R0 + 1, COOLG_RUN_RATE, DoCoolgMove, &s_CoolgRun[0][2]},
130 {COOLG_RUN_R0 + 2, COOLG_RUN_RATE, DoCoolgMove, &s_CoolgRun[0][3]},
131 {COOLG_RUN_R0 + 3, COOLG_RUN_RATE, DoCoolgMove, &s_CoolgRun[0][0]},
132 },
133 {
134 {COOLG_RUN_R1 + 0, COOLG_RUN_RATE, DoCoolgMove, &s_CoolgRun[1][1]},
135 {COOLG_RUN_R1 + 1, COOLG_RUN_RATE, DoCoolgMove, &s_CoolgRun[1][2]},
136 {COOLG_RUN_R1 + 2, COOLG_RUN_RATE, DoCoolgMove, &s_CoolgRun[1][3]},
137 {COOLG_RUN_R1 + 3, COOLG_RUN_RATE, DoCoolgMove, &s_CoolgRun[1][0]},
138 },
139 {
140 {COOLG_RUN_R2 + 0, COOLG_RUN_RATE, DoCoolgMove, &s_CoolgRun[2][1]},
141 {COOLG_RUN_R2 + 1, COOLG_RUN_RATE, DoCoolgMove, &s_CoolgRun[2][2]},
142 {COOLG_RUN_R2 + 2, COOLG_RUN_RATE, DoCoolgMove, &s_CoolgRun[2][3]},
143 {COOLG_RUN_R2 + 3, COOLG_RUN_RATE, DoCoolgMove, &s_CoolgRun[2][0]},
144 },
145 {
146 {COOLG_RUN_R3 + 0, COOLG_RUN_RATE, DoCoolgMove, &s_CoolgRun[3][1]},
147 {COOLG_RUN_R3 + 1, COOLG_RUN_RATE, DoCoolgMove, &s_CoolgRun[3][2]},
148 {COOLG_RUN_R3 + 2, COOLG_RUN_RATE, DoCoolgMove, &s_CoolgRun[3][3]},
149 {COOLG_RUN_R3 + 3, COOLG_RUN_RATE, DoCoolgMove, &s_CoolgRun[3][0]},
150 },
151 {
152 {COOLG_RUN_R4 + 0, COOLG_RUN_RATE, DoCoolgMove, &s_CoolgRun[4][1]},
153 {COOLG_RUN_R4 + 1, COOLG_RUN_RATE, DoCoolgMove, &s_CoolgRun[4][2]},
154 {COOLG_RUN_R4 + 2, COOLG_RUN_RATE, DoCoolgMove, &s_CoolgRun[4][3]},
155 {COOLG_RUN_R4 + 3, COOLG_RUN_RATE, DoCoolgMove, &s_CoolgRun[4][0]},
156 }
157 };
158
159 STATEp sg_CoolgRun[] =
160 {
161 &s_CoolgRun[0][0],
162 &s_CoolgRun[1][0],
163 &s_CoolgRun[2][0],
164 &s_CoolgRun[3][0],
165 &s_CoolgRun[4][0]
166 };
167
168 //////////////////////
169 //
170 // COOLG STAND
171 //
172 //////////////////////
173
174
175 STATE s_CoolgStand[5][1] =
176 {
177 {
178 {COOLG_RUN_R0 + 0, COOLG_RUN_RATE, DoCoolgMove, &s_CoolgStand[0][0]},
179 },
180 {
181 {COOLG_RUN_R1 + 0, COOLG_RUN_RATE, DoCoolgMove, &s_CoolgStand[1][0]},
182 },
183 {
184 {COOLG_RUN_R2 + 0, COOLG_RUN_RATE, DoCoolgMove, &s_CoolgStand[2][0]},
185 },
186 {
187 {COOLG_RUN_R3 + 0, COOLG_RUN_RATE, DoCoolgMove, &s_CoolgStand[3][0]},
188 },
189 {
190 {COOLG_RUN_R4 + 0, COOLG_RUN_RATE, DoCoolgMove, &s_CoolgStand[4][0]},
191 }
192 };
193
194 STATEp sg_CoolgStand[] =
195 {
196 &s_CoolgStand[0][0],
197 &s_CoolgStand[1][0],
198 &s_CoolgStand[2][0],
199 &s_CoolgStand[3][0],
200 &s_CoolgStand[4][0]
201 };
202
203 //////////////////////
204 //
205 // COOLG CLUB
206 //
207 //////////////////////
208
209 #define COOLG_RATE 16
210 ANIMATOR InitCoolgBash;
211
212 STATE s_CoolgClub[5][6] =
213 {
214 {
215 {COOLG_CLUB_R0 + 0, COOLG_RATE, NullCoolg, &s_CoolgClub[0][1]},
216 {COOLG_RUN_R0 + 0, COOLG_RATE, NullCoolg, &s_CoolgClub[0][2]},
217 {COOLG_CLUB_R0 + 1, 0|SF_QUICK_CALL, InitCoolgBash, &s_CoolgClub[0][3]},
218 {COOLG_CLUB_R0 + 1, COOLG_RATE, NullCoolg, &s_CoolgClub[0][4]},
219 {COOLG_CLUB_R0 + 1, 0|SF_QUICK_CALL, InitActorDecide, &s_CoolgClub[0][5]},
220 {COOLG_CLUB_R0 + 1, COOLG_RATE, DoCoolgMove, &s_CoolgClub[0][5]}
221 },
222 {
223 {COOLG_CLUB_R1 + 0, COOLG_RATE, NullCoolg, &s_CoolgClub[1][1]},
224 {COOLG_RUN_R1 + 0, COOLG_RATE, NullCoolg, &s_CoolgClub[1][2]},
225 {COOLG_CLUB_R1 + 1, 0|SF_QUICK_CALL, InitCoolgBash, &s_CoolgClub[1][3]},
226 {COOLG_CLUB_R1 + 1, COOLG_RATE, NullCoolg, &s_CoolgClub[1][4]},
227 {COOLG_CLUB_R1 + 1, 0|SF_QUICK_CALL, InitActorDecide, &s_CoolgClub[1][5]},
228 {COOLG_CLUB_R1 + 1, COOLG_RATE, DoCoolgMove, &s_CoolgClub[1][5]}
229 },
230 {
231 {COOLG_CLUB_R2 + 0, COOLG_RATE, NullCoolg, &s_CoolgClub[2][1]},
232 {COOLG_RUN_R2 + 0, COOLG_RATE, NullCoolg, &s_CoolgClub[2][2]},
233 {COOLG_CLUB_R2 + 1, 0|SF_QUICK_CALL, InitCoolgBash, &s_CoolgClub[2][3]},
234 {COOLG_CLUB_R2 + 1, COOLG_RATE, NullCoolg, &s_CoolgClub[2][4]},
235 {COOLG_CLUB_R2 + 1, 0|SF_QUICK_CALL, InitActorDecide, &s_CoolgClub[2][5]},
236 {COOLG_CLUB_R2 + 1, COOLG_RATE, DoCoolgMove, &s_CoolgClub[2][5]}
237 },
238 {
239 {COOLG_CLUB_R3 + 0, COOLG_RATE, NullCoolg, &s_CoolgClub[3][1]},
240 {COOLG_RUN_R3 + 0, COOLG_RATE, NullCoolg, &s_CoolgClub[3][2]},
241 {COOLG_CLUB_R3 + 1, 0|SF_QUICK_CALL, InitCoolgBash, &s_CoolgClub[3][3]},
242 {COOLG_CLUB_R3 + 1, COOLG_RATE, NullCoolg, &s_CoolgClub[3][4]},
243 {COOLG_CLUB_R3 + 1, 0|SF_QUICK_CALL, InitActorDecide, &s_CoolgClub[3][5]},
244 {COOLG_CLUB_R3 + 1, COOLG_RATE, DoCoolgMove, &s_CoolgClub[3][5]}
245 },
246 {
247 {COOLG_CLUB_R4 + 0, COOLG_RATE, NullCoolg, &s_CoolgClub[4][1]},
248 {COOLG_RUN_R4 + 0, COOLG_RATE, NullCoolg, &s_CoolgClub[4][2]},
249 {COOLG_CLUB_R4 + 1, 0|SF_QUICK_CALL, InitCoolgBash, &s_CoolgClub[4][3]},
250 {COOLG_CLUB_R4 + 1, COOLG_RATE, NullCoolg, &s_CoolgClub[4][4]},
251 {COOLG_CLUB_R4 + 1, 0|SF_QUICK_CALL, InitActorDecide, &s_CoolgClub[4][5]},
252 {COOLG_CLUB_R4 + 1, COOLG_RATE, DoCoolgMove, &s_CoolgClub[4][5]}
253 }
254 };
255
256 STATEp sg_CoolgClub[] =
257 {
258 &s_CoolgClub[0][0],
259 &s_CoolgClub[1][0],
260 &s_CoolgClub[2][0],
261 &s_CoolgClub[3][0],
262 &s_CoolgClub[4][0]
263 };
264
265 //////////////////////
266 //
267 // COOLG FIRE
268 //
269 //////////////////////
270
271 ANIMATOR InitCoolgFire;
272 #define COOLG_FIRE_RATE 12
273
274 STATE s_CoolgAttack[5][7] =
275 {
276 {
277 {COOLG_FIRE_R0 + 0, COOLG_FIRE_RATE*2, NullCoolg, &s_CoolgAttack[0][1]},
278 {COOLG_FIRE_R0 + 1, COOLG_FIRE_RATE*2, NullCoolg, &s_CoolgAttack[0][2]},
279 {COOLG_FIRE_R0 + 2, COOLG_FIRE_RATE*2, NullCoolg, &s_CoolgAttack[0][3]},
280 {COOLG_FIRE_R0 + 2, 0|SF_QUICK_CALL, InitCoolgFire, &s_CoolgAttack[0][4]},
281 {COOLG_FIRE_R0 + 2, COOLG_FIRE_RATE, NullCoolg, &s_CoolgAttack[0][5]},
282 {COOLG_FIRE_R0 + 2, 0|SF_QUICK_CALL, InitActorDecide, &s_CoolgAttack[0][6]},
283 {COOLG_RUN_R0 + 2, COOLG_FIRE_RATE, DoCoolgMove, &s_CoolgAttack[0][6]}
284 },
285 {
286 {COOLG_FIRE_R1 + 0, COOLG_FIRE_RATE*2, NullCoolg, &s_CoolgAttack[1][1]},
287 {COOLG_FIRE_R1 + 1, COOLG_FIRE_RATE*2, NullCoolg, &s_CoolgAttack[1][2]},
288 {COOLG_FIRE_R1 + 2, COOLG_FIRE_RATE*2, NullCoolg, &s_CoolgAttack[1][3]},
289 {COOLG_FIRE_R1 + 2, 0|SF_QUICK_CALL, InitCoolgFire, &s_CoolgAttack[1][4]},
290 {COOLG_FIRE_R1 + 2, COOLG_FIRE_RATE, NullCoolg, &s_CoolgAttack[1][5]},
291 {COOLG_FIRE_R1 + 2, 0|SF_QUICK_CALL, InitActorDecide, &s_CoolgAttack[1][6]},
292 {COOLG_RUN_R0 + 2, COOLG_FIRE_RATE, DoCoolgMove, &s_CoolgAttack[1][6]}
293 },
294 {
295 {COOLG_FIRE_R2 + 0, COOLG_FIRE_RATE*2, NullCoolg, &s_CoolgAttack[2][1]},
296 {COOLG_FIRE_R2 + 1, COOLG_FIRE_RATE*2, NullCoolg, &s_CoolgAttack[2][2]},
297 {COOLG_FIRE_R2 + 2, COOLG_FIRE_RATE*2, NullCoolg, &s_CoolgAttack[2][3]},
298 {COOLG_FIRE_R2 + 2, 0|SF_QUICK_CALL, InitCoolgFire, &s_CoolgAttack[2][4]},
299 {COOLG_FIRE_R2 + 2, COOLG_FIRE_RATE, NullCoolg, &s_CoolgAttack[2][5]},
300 {COOLG_FIRE_R2 + 2, 0|SF_QUICK_CALL, InitActorDecide, &s_CoolgAttack[2][6]},
301 {COOLG_RUN_R0 + 2, COOLG_FIRE_RATE, DoCoolgMove, &s_CoolgAttack[2][6]}
302 },
303 {
304 {COOLG_RUN_R3 + 0, COOLG_FIRE_RATE*2, NullCoolg, &s_CoolgAttack[3][1]},
305 {COOLG_RUN_R3 + 1, COOLG_FIRE_RATE*2, NullCoolg, &s_CoolgAttack[3][2]},
306 {COOLG_RUN_R3 + 2, COOLG_FIRE_RATE*2, NullCoolg, &s_CoolgAttack[3][3]},
307 {COOLG_RUN_R3 + 2, 0|SF_QUICK_CALL, InitCoolgFire, &s_CoolgAttack[3][4]},
308 {COOLG_RUN_R3 + 2, COOLG_FIRE_RATE, NullCoolg, &s_CoolgAttack[3][5]},
309 {COOLG_RUN_R3 + 2, 0|SF_QUICK_CALL, InitActorDecide, &s_CoolgAttack[3][6]},
310 {COOLG_RUN_R0 + 2, COOLG_FIRE_RATE, DoCoolgMove, &s_CoolgAttack[3][6]}
311 },
312 {
313 {COOLG_RUN_R4 + 0, COOLG_FIRE_RATE*2, NullCoolg, &s_CoolgAttack[4][1]},
314 {COOLG_RUN_R4 + 1, COOLG_FIRE_RATE*2, NullCoolg, &s_CoolgAttack[4][2]},
315 {COOLG_RUN_R4 + 2, COOLG_FIRE_RATE*2, NullCoolg, &s_CoolgAttack[4][3]},
316 {COOLG_RUN_R4 + 2, 0|SF_QUICK_CALL, InitCoolgFire, &s_CoolgAttack[4][4]},
317 {COOLG_RUN_R4 + 2, COOLG_FIRE_RATE, NullCoolg, &s_CoolgAttack[4][5]},
318 {COOLG_RUN_R4 + 2, 0|SF_QUICK_CALL, InitActorDecide, &s_CoolgAttack[4][6]},
319 {COOLG_RUN_R0 + 2, COOLG_FIRE_RATE, DoCoolgMove, &s_CoolgAttack[4][6]}
320 }
321 };
322
323 STATEp sg_CoolgAttack[] =
324 {
325 &s_CoolgAttack[0][0],
326 &s_CoolgAttack[1][0],
327 &s_CoolgAttack[2][0],
328 &s_CoolgAttack[3][0],
329 &s_CoolgAttack[4][0]
330 };
331
332 //////////////////////
333 //
334 // COOLG PAIN
335 //
336 //////////////////////
337
338 #define COOLG_PAIN_RATE 15
339 ANIMATOR DoCoolgPain;
340
341 STATE s_CoolgPain[5][2] =
342 {
343 {
344 {COOLG_PAIN_R0 + 0, COOLG_PAIN_RATE, DoCoolgPain, &s_CoolgPain[0][1]},
345 {COOLG_PAIN_R0 + 0, COOLG_PAIN_RATE, DoCoolgPain, &s_CoolgPain[0][1]},
346 },
347 {
348 {COOLG_RUN_R1 + 0, COOLG_PAIN_RATE, DoCoolgPain, &s_CoolgPain[1][1]},
349 {COOLG_RUN_R1 + 0, COOLG_PAIN_RATE, DoCoolgPain, &s_CoolgPain[1][1]},
350 },
351 {
352 {COOLG_RUN_R2 + 0, COOLG_PAIN_RATE, DoCoolgPain, &s_CoolgPain[2][1]},
353 {COOLG_RUN_R2 + 0, COOLG_PAIN_RATE, DoCoolgPain, &s_CoolgPain[2][1]},
354 },
355 {
356 {COOLG_RUN_R3 + 0, COOLG_PAIN_RATE, DoCoolgPain, &s_CoolgPain[3][1]},
357 {COOLG_RUN_R3 + 0, COOLG_PAIN_RATE, DoCoolgPain, &s_CoolgPain[3][1]},
358 },
359 {
360 {COOLG_RUN_R4 + 0, COOLG_PAIN_RATE, DoCoolgPain, &s_CoolgPain[4][1]},
361 {COOLG_RUN_R4 + 0, COOLG_PAIN_RATE, DoCoolgPain, &s_CoolgPain[4][1]},
362 },
363 };
364
365 STATEp sg_CoolgPain[] =
366 {
367 s_CoolgPain[0],
368 s_CoolgPain[1],
369 s_CoolgPain[2],
370 s_CoolgPain[3],
371 s_CoolgPain[4]
372 };
373
374
375 //////////////////////
376 //
377 // COOLG DIE
378 //
379 //////////////////////
380
381 #define COOLG_DIE_RATE 20
382
383 #define COOLG_DIE 4307
384 #define COOLG_DEAD 4307+5
385 ANIMATOR DoCoolgDeath;
386 STATE s_CoolgDie[] =
387 {
388 {COOLG_DIE + 0, COOLG_DIE_RATE, DoCoolgDeath, &s_CoolgDie[1]},
389 {COOLG_DIE + 1, COOLG_DIE_RATE, DoCoolgDeath, &s_CoolgDie[2]},
390 {COOLG_DIE + 2, COOLG_DIE_RATE, DoCoolgDeath, &s_CoolgDie[3]},
391 {COOLG_DIE + 3, COOLG_DIE_RATE, DoCoolgDeath, &s_CoolgDie[4]},
392 {COOLG_DIE + 4, COOLG_DIE_RATE, DoCoolgDeath, &s_CoolgDie[5]},
393 {COOLG_DIE + 5, COOLG_DIE_RATE, DoCoolgDeath, &s_CoolgDie[5]},
394 };
395
396 STATEp sg_CoolgDie[] =
397 {
398 s_CoolgDie
399 };
400
401 STATE s_CoolgDead[] =
402 {
403 {COOLG_DEAD, SF_QUICK_CALL , QueueFloorBlood, &s_CoolgDead[1]},
404 {COOLG_DEAD, COOLG_DIE_RATE, DoActorDebris, &s_CoolgDead[1]},
405 };
406
407 STATEp sg_CoolgDead[] =
408 {
409 s_CoolgDead
410 };
411
412 //////////////////////
413 //
414 // COOLG BIRTH
415 //
416 //////////////////////
417
418 #define COOLG_BIRTH_RATE 20
419 #define COOLG_BIRTH 4268
420
421 STATE s_CoolgBirth[] =
422 {
423 {COOLG_BIRTH + 0, COOLG_BIRTH_RATE, NullAnimator, &s_CoolgBirth[1]},
424 {COOLG_BIRTH + 1, COOLG_BIRTH_RATE, NullAnimator, &s_CoolgBirth[2]},
425 {COOLG_BIRTH + 2, COOLG_BIRTH_RATE, NullAnimator, &s_CoolgBirth[3]},
426 {COOLG_BIRTH + 3, COOLG_BIRTH_RATE, NullAnimator, &s_CoolgBirth[4]},
427 {COOLG_BIRTH + 4, COOLG_BIRTH_RATE, NullAnimator, &s_CoolgBirth[5]},
428 {COOLG_BIRTH + 5, COOLG_BIRTH_RATE, NullAnimator, &s_CoolgBirth[6]},
429 {COOLG_BIRTH + 6, COOLG_BIRTH_RATE, NullAnimator, &s_CoolgBirth[7]},
430 {COOLG_BIRTH + 7, COOLG_BIRTH_RATE, NullAnimator, &s_CoolgBirth[8]},
431 {COOLG_BIRTH + 8, COOLG_BIRTH_RATE, NullAnimator, &s_CoolgBirth[9]},
432 {COOLG_BIRTH + 8, COOLG_BIRTH_RATE, NullAnimator, &s_CoolgBirth[10]},
433 {COOLG_BIRTH + 8, 0|SF_QUICK_CALL, DoCoolgBirth, &s_CoolgBirth[10]}
434 };
435
436 STATEp sg_CoolgBirth[] =
437 {
438 s_CoolgBirth
439 };
440
441 /*
442 STATEp *Stand[MAX_WEAPONS];
443 STATEp *Run;
444 STATEp *Jump;
445 STATEp *Fall;
446 STATEp *Crawl;
447 STATEp *Swim;
448 STATEp *Fly;
449 STATEp *Rise;
450 STATEp *Sit;
451 STATEp *Look;
452 STATEp *Climb;
453 STATEp *Pain;
454 STATEp *Death1;
455 STATEp *Death2;
456 STATEp *Dead;
457 STATEp *DeathJump;
458 STATEp *DeathFall;
459 STATEp *CloseAttack[2];
460 STATEp *Attack[6];
461 STATEp *Special[2];
462 */
463
464
465 ACTOR_ACTION_SET CoolgActionSet =
466 {
467 sg_CoolgStand,
468 sg_CoolgRun,
469 NULL,
470 NULL,
471 NULL,
472 NULL,
473 NULL,
474 NULL,
475 NULL,
476 NULL,
477 NULL,//climb
478 sg_CoolgPain,//pain
479 sg_CoolgDie,
480 NULL,
481 sg_CoolgDead,
482 NULL,
483 NULL,
484 // {sg_CoolgClub},
485 {sg_CoolgAttack},
486 {1024},
487 {sg_CoolgAttack},
488 {1024},
489 {NULL,NULL},
490 NULL,
491 NULL
492 };
493
494 int DoCoolgMatchPlayerZ(short SpriteNum);
495
496 void
CoolgCommon(short SpriteNum)497 CoolgCommon(short SpriteNum)
498 {
499 SPRITEp sp = &sprite[SpriteNum];
500 USERp u = User[SpriteNum];
501
502 sp->clipdist = (200) >> 2;
503 //u->floor_dist = Z(5);
504 u->floor_dist = Z(16);
505 u->ceiling_dist = Z(20);
506
507 u->sz = sp->z;
508
509 sp->xrepeat = 42;
510 sp->yrepeat = 42;
511 SET(sp->extra, SPRX_PLAYER_OR_ENEMY);
512 }
513
514 int
SetupCoolg(short SpriteNum)515 SetupCoolg(short SpriteNum)
516 {
517 SPRITEp sp = &sprite[SpriteNum];
518 USERp u;
519 ANIMATOR DoActorDecide;
520
521 if (TEST(sp->cstat, CSTAT_SPRITE_RESTORE))
522 {
523 u = User[SpriteNum];
524 ASSERT(u);
525 }
526 else
527 {
528 User[SpriteNum] = u = SpawnUser(SpriteNum,COOLG_RUN_R0,s_CoolgRun[0]);
529 u->Health = HEALTH_COOLIE_GHOST;
530 }
531
532 ChangeState(SpriteNum, s_CoolgRun[0]);
533 u->Attrib = &CoolgAttrib;
534 DoActorSetSpeed(SpriteNum, NORM_SPEED);
535 u->StateEnd = s_CoolgDie;
536 u->Rot = sg_CoolgRun;
537
538 EnemyDefaults(SpriteNum, &CoolgActionSet, &CoolgPersonality);
539
540 SET(u->Flags, SPR_NO_SCAREDZ|SPR_XFLIP_TOGGLE);
541
542 CoolgCommon(SpriteNum);
543
544 return(0);
545 }
546
547 extern short TotalKillable;
548
549 int
NewCoolg(short SpriteNum)550 NewCoolg(short SpriteNum)
551 {
552 USERp u = User[SpriteNum];
553 SPRITEp sp = User[SpriteNum]->SpriteP;
554 USERp nu;
555 SPRITEp np;
556 ANIMATOR DoActorDecide;
557 short new;
558
559 new = SpawnSprite(STAT_ENEMY, COOLG_RUN_R0, &s_CoolgBirth[0], sp->sectnum, sp->x, sp->y, sp->z, sp->ang, 50);
560
561 nu = User[new];
562 np = &sprite[new];
563
564 ChangeState(new, &s_CoolgBirth[0]);
565 nu->StateEnd = s_CoolgDie;
566 nu->Rot = sg_CoolgRun;
567 np->pal = nu->spal = u->spal;
568
569 nu->ActorActionSet = &CoolgActionSet;
570
571 np->shade = sp->shade;
572 nu->Personality = &CoolgPersonality;
573 nu->Attrib = &CoolgAttrib;
574
575 // special case
576 TotalKillable++;
577 CoolgCommon(new);
578
579 return(0);
580 }
581
582
583 int
DoCoolgBirth(short new)584 DoCoolgBirth(short new)
585 {
586 SPRITEp sp;
587 USERp u;
588 ANIMATOR DoActorDecide;
589
590 u = User[new];
591 sp = &sprite[new];
592
593 u->Health = HEALTH_COOLIE_GHOST;
594 u->Attrib = &CoolgAttrib;
595 DoActorSetSpeed(new, NORM_SPEED);
596
597 ChangeState(new, s_CoolgRun[0]);
598 u->StateEnd = s_CoolgDie;
599 u->Rot = sg_CoolgRun;
600
601 EnemyDefaults(new, &CoolgActionSet, &CoolgPersonality);
602 // special case
603 TotalKillable--;
604
605 SET(u->Flags, SPR_NO_SCAREDZ|SPR_XFLIP_TOGGLE);
606 CoolgCommon(new);
607
608 return(0);
609 }
610
NullCoolg(short SpriteNum)611 int NullCoolg(short SpriteNum)
612 {
613 USERp u = User[SpriteNum];
614 SPRITEp sp = User[SpriteNum]->SpriteP;
615
616 u->ShellNum -= ACTORMOVETICS;
617
618 if (TEST(u->Flags,SPR_SLIDING))
619 DoActorSlide(SpriteNum);
620
621 DoCoolgMatchPlayerZ(SpriteNum);
622
623 DoActorSectorDamage(SpriteNum);
624
625 return(0);
626 }
627
628
DoCoolgMatchPlayerZ(short SpriteNum)629 int DoCoolgMatchPlayerZ(short SpriteNum)
630 {
631 SPRITEp sp = &sprite[SpriteNum];
632 USERp u = User[SpriteNum];
633 SPRITEp tsp = User[SpriteNum]->tgt_sp;
634 int zdiff,zdist;
635 int loz,hiz;
636
637 int bound;
638
639 // If blocking bits get unset, just die
640 if (!TEST(sp->cstat,CSTAT_SPRITE_BLOCK) || !TEST(sp->cstat,CSTAT_SPRITE_BLOCK_HITSCAN))
641 {
642 InitBloodSpray(SpriteNum, TRUE, 105);
643 InitBloodSpray(SpriteNum, TRUE, 105);
644 UpdateSinglePlayKills(SpriteNum);
645 SetSuicide(SpriteNum);
646 }
647
648 // actor does a sine wave about u->sz - this is the z mid point
649
650 zdiff = (SPRITEp_MID(tsp)) - u->sz;
651
652 // check z diff of the player and the sprite
653 zdist = Z(20 + RANDOM_RANGE(100)); // put a random amount
654 //zdist = Z(20);
655 if (labs(zdiff) > zdist)
656 {
657 if (zdiff > 0)
658 u->sz += 170 * ACTORMOVETICS;
659 else
660 u->sz -= 170 * ACTORMOVETICS;
661 }
662
663 #define COOLG_BOB_AMT (Z(8))
664
665 // save off lo and hi z
666 loz = u->loz;
667 hiz = u->hiz;
668
669 // adjust loz/hiz for water depth
670 if (u->lo_sectp && SectUser[u->lo_sectp - sector] && SectUser[u->lo_sectp - sector]->depth)
671 loz -= Z(SectUser[u->lo_sectp - sector]->depth) - Z(8);
672
673 // lower bound
674 if (u->lo_sp)
675 bound = loz - u->floor_dist;
676 else
677 bound = loz - u->floor_dist - COOLG_BOB_AMT;
678
679 if (u->sz > bound)
680 {
681 u->sz = bound;
682 }
683
684 // upper bound
685 if (u->hi_sp)
686 bound = hiz + u->ceiling_dist;
687 else
688 bound = hiz + u->ceiling_dist + COOLG_BOB_AMT;
689
690 if (u->sz < bound)
691 {
692 u->sz = bound;
693 }
694
695 u->sz = min(u->sz, loz - u->floor_dist);
696 u->sz = max(u->sz, hiz + u->ceiling_dist);
697
698 u->Counter = (u->Counter + (ACTORMOVETICS<<3)) & 2047;
699 sp->z = u->sz + ((COOLG_BOB_AMT * (int)sintable[u->Counter]) >> 14);
700
701 bound = u->hiz + u->ceiling_dist + COOLG_BOB_AMT;
702 if (sp->z < bound)
703 {
704 // bumped something
705 sp->z = u->sz = bound + COOLG_BOB_AMT;
706 }
707
708 return(0);
709 }
710
InitCoolgCircle(short SpriteNum)711 int InitCoolgCircle(short SpriteNum)
712 {
713 SPRITEp sp = &sprite[SpriteNum];
714 USERp u = User[SpriteNum];
715
716
717 u->ActorActionFunc = DoCoolgCircle;
718
719 NewStateGroup(SpriteNum, u->ActorActionSet->Run);
720
721 // set it close
722 DoActorSetSpeed(SpriteNum, FAST_SPEED);
723
724 // set to really fast
725 sp->xvel = 400;
726 // angle adjuster
727 u->Counter2 = sp->xvel/3;
728 // random angle direction
729 if (RANDOM_P2(1024) < 512)
730 u->Counter2 = -u->Counter2;
731
732 // z velocity
733 u->jump_speed = 400 + RANDOM_P2(256);
734 if (labs(u->sz - u->hiz) < labs(u->sz - u->loz))
735 u->jump_speed = -u->jump_speed;
736
737 u->WaitTics = (RANDOM_RANGE(3)+1) * 120;
738
739 (*u->ActorActionFunc) (SpriteNum);
740
741 return(0);
742 }
743
DoCoolgCircle(short SpriteNum)744 int DoCoolgCircle(short SpriteNum)
745 {
746 SPRITEp sp = &sprite[SpriteNum];
747 USERp u = User[SpriteNum];
748 SPRITEp tsp = User[SpriteNum]->tgt_sp;
749 int nx,ny,bound;
750
751
752 sp->ang = NORM_ANGLE(sp->ang + u->Counter2);
753
754 nx = sp->xvel * (int) sintable[NORM_ANGLE(sp->ang + 512)] >> 14;
755 ny = sp->xvel * (int) sintable[sp->ang] >> 14;
756
757 if (!move_actor(SpriteNum, nx, ny, 0L))
758 {
759 InitActorReposition(SpriteNum);
760 return (0);
761 }
762
763 // move in the z direction
764 u->sz -= u->jump_speed * ACTORMOVETICS;
765
766 bound = u->hiz + u->ceiling_dist + COOLG_BOB_AMT;
767 if (u->sz < bound)
768 {
769 // bumped something
770 u->sz = bound;
771 InitActorReposition(SpriteNum);
772 return (0);
773 }
774
775 // time out
776 if ((u->WaitTics -= ACTORMOVETICS) < 0)
777 {
778 InitActorReposition(SpriteNum);
779 u->WaitTics = 0;
780 return (0);
781 }
782
783 return(0);
784 }
785
786
787 int
DoCoolgDeath(short SpriteNum)788 DoCoolgDeath(short SpriteNum)
789 {
790 SPRITEp sp = &sprite[SpriteNum];
791 USERp u = User[SpriteNum];
792 int nx, ny;
793
794
795 RESET(sp->cstat, CSTAT_SPRITE_TRANSLUCENT);
796 RESET(sp->cstat, CSTAT_SPRITE_INVISIBLE);
797 sp->xrepeat = 42;
798 sp->shade = -10;
799
800 if (TEST(u->Flags, SPR_FALLING))
801 {
802 DoFall(SpriteNum);
803 }
804 else
805 {
806 DoFindGroundPoint(SpriteNum);
807 u->floor_dist = 0;
808 DoBeginFall(SpriteNum);
809 }
810
811 if (TEST(u->Flags, SPR_SLIDING))
812 DoActorSlide(SpriteNum);
813
814 // slide while falling
815 nx = sp->xvel * (int) sintable[NORM_ANGLE(sp->ang + 512)] >> 14;
816 ny = sp->xvel * (int) sintable[sp->ang] >> 14;
817
818 u->ret = move_sprite(SpriteNum, nx, ny, 0L, u->ceiling_dist, u->floor_dist, CLIPMASK_MISSILE, ACTORMOVETICS);
819 DoFindGroundPoint(SpriteNum);
820
821 // on the ground
822 if (sp->z >= u->loz)
823 {
824 RESET(u->Flags, SPR_FALLING|SPR_SLIDING);
825 RESET(sp->cstat, CSTAT_SPRITE_YFLIP); // If upside down, reset it
826 NewStateGroup(SpriteNum, u->ActorActionSet->Dead);
827 return(0);
828 }
829
830 return(0);
831 }
832
DoCoolgMove(short SpriteNum)833 int DoCoolgMove(short SpriteNum)
834 {
835 SPRITEp sp = &sprite[SpriteNum];
836 USERp u = User[SpriteNum];
837
838 if ((u->ShellNum -= ACTORMOVETICS) <= 0)
839 {
840 switch (u->FlagOwner)
841 {
842 case 0:
843 SET(sp->cstat, CSTAT_SPRITE_TRANSLUCENT);
844 u->ShellNum = SEC(2);
845 break;
846 case 1:
847 PlaySound(DIGI_VOID3, &sp->x, &sp->y, &sp->z, v3df_follow);
848 RESET(sp->cstat, CSTAT_SPRITE_TRANSLUCENT);
849 SET(sp->cstat, CSTAT_SPRITE_INVISIBLE);
850 u->ShellNum = SEC(1) + SEC(RANDOM_RANGE(2));
851 break;
852 case 2:
853 SET(sp->cstat, CSTAT_SPRITE_TRANSLUCENT);
854 RESET(sp->cstat, CSTAT_SPRITE_INVISIBLE);
855 u->ShellNum = SEC(2);
856 break;
857 case 3:
858 PlaySound(DIGI_VOID3, &sp->x, &sp->y, &sp->z, v3df_follow);
859 RESET(sp->cstat, CSTAT_SPRITE_TRANSLUCENT);
860 RESET(sp->cstat, CSTAT_SPRITE_INVISIBLE);
861 u->ShellNum = SEC(2) + SEC(RANDOM_RANGE(3));
862 break;
863 default:
864 u->FlagOwner = 0;
865 break;
866 }
867 u->FlagOwner++;
868 if (u->FlagOwner > 3) u->FlagOwner = 0;
869 }
870
871 if (u->FlagOwner-1 == 0)
872 {
873 sp->xrepeat--;
874 sp->shade++;
875 if (sp->xrepeat < 4) sp->xrepeat = 4;
876 if (sp->shade > 126)
877 {
878 sp->shade = 127;
879 sp->hitag = 9998;
880 }
881 } else
882 if (u->FlagOwner-1 == 2)
883 {
884 sp->hitag = 0;
885 sp->xrepeat++;
886 sp->shade--;
887 if (sp->xrepeat > 42) sp->xrepeat = 42;
888 if (sp->shade < -10) sp->shade = -10;
889 } else
890 if (u->FlagOwner == 0)
891 {
892 sp->xrepeat = 42;
893 sp->shade = -10;
894 sp->hitag = 0;
895 }
896
897 if (TEST(u->Flags,SPR_SLIDING))
898 DoActorSlide(SpriteNum);
899
900 if (u->track >= 0)
901 ActorFollowTrack(SpriteNum, ACTORMOVETICS);
902 else
903 {
904 (*u->ActorActionFunc)(SpriteNum);
905 }
906
907 if (RANDOM_P2(1024) < 32 && !TEST(sp->cstat, CSTAT_SPRITE_INVISIBLE))
908 InitCoolgDrip(SpriteNum);
909
910 DoCoolgMatchPlayerZ(SpriteNum);
911
912 DoActorSectorDamage(SpriteNum);
913
914
915 return(0);
916
917 }
918
DoCoolgPain(short SpriteNum)919 int DoCoolgPain(short SpriteNum)
920 {
921 SPRITEp sp = &sprite[SpriteNum];
922 USERp u = User[SpriteNum];
923
924 NullCoolg(SpriteNum);
925
926 if ((u->WaitTics -= ACTORMOVETICS) <= 0)
927 InitActorDecide(SpriteNum);
928
929 return(0);
930 }
931
932
933 #include "saveable.h"
934
935 static saveable_code saveable_coolg_code[] = {
936 SAVE_CODE(CoolgCommon),
937 SAVE_CODE(SetupCoolg),
938 SAVE_CODE(NewCoolg),
939 SAVE_CODE(DoCoolgBirth),
940 SAVE_CODE(NullCoolg),
941 SAVE_CODE(DoCoolgMatchPlayerZ),
942 SAVE_CODE(InitCoolgCircle),
943 SAVE_CODE(DoCoolgCircle),
944 SAVE_CODE(DoCoolgDeath),
945 SAVE_CODE(DoCoolgMove),
946 SAVE_CODE(DoCoolgPain),
947 };
948
949 static saveable_data saveable_coolg_data[] = {
950 SAVE_DATA(CoolgBattle),
951 SAVE_DATA(CoolgOffense),
952 SAVE_DATA(CoolgBroadcast),
953 SAVE_DATA(CoolgSurprised),
954 SAVE_DATA(CoolgEvasive),
955 SAVE_DATA(CoolgLostTarget),
956 SAVE_DATA(CoolgCloseRange),
957 SAVE_DATA(CoolgTouchTarget),
958
959 SAVE_DATA(CoolgPersonality),
960
961 SAVE_DATA(CoolgAttrib),
962
963 SAVE_DATA(s_CoolgRun),
964 SAVE_DATA(sg_CoolgRun),
965 SAVE_DATA(s_CoolgStand),
966 SAVE_DATA(sg_CoolgStand),
967 SAVE_DATA(s_CoolgClub),
968 SAVE_DATA(sg_CoolgClub),
969 SAVE_DATA(s_CoolgAttack),
970 SAVE_DATA(sg_CoolgAttack),
971 SAVE_DATA(s_CoolgPain),
972 SAVE_DATA(sg_CoolgPain),
973 SAVE_DATA(s_CoolgDie),
974 SAVE_DATA(sg_CoolgDie),
975 SAVE_DATA(s_CoolgDead),
976 SAVE_DATA(sg_CoolgDead),
977 SAVE_DATA(s_CoolgBirth),
978 SAVE_DATA(sg_CoolgBirth),
979
980 SAVE_DATA(CoolgActionSet),
981 };
982
983 saveable_module saveable_coolg = {
984 // code
985 saveable_coolg_code,
986 SIZ(saveable_coolg_code),
987
988 // data
989 saveable_coolg_data,
990 SIZ(saveable_coolg_data)
991 };
992