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