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 "panel.h"
31 #include "game.h"
32 #include "tags.h"
33 #include "ai.h"
34 #include "pal.h"
35 #include "actor.h"
36 #include "sprite.h"
37 #include "track.h"
38 #include "fx_man.h"
39 
40 ANIMATOR InitRipper2Hang;
41 ANIMATOR DoActorMoveJump;
42 ANIMATOR DoRipper2MoveJump;
43 ANIMATOR DoRipper2HangJF;
44 ANIMATOR DoRipper2QuickJump;
45 ANIMATOR InitRipper2Charge;
46 
47 DECISION Ripper2Battle[] =
48 {
49     {879, InitRipper2Charge},
50     {883, InitActorAttackNoise},
51     {900, InitRipper2Hang},
52     {1024, InitActorAttack}
53 };
54 
55 DECISION Ripper2Offense[] =
56 {
57     {789, InitActorMoveCloser},
58     {790, InitActorAttackNoise},
59     {800, InitRipper2Hang},
60     {1024, InitActorAttack}
61 };
62 
63 DECISION Ripper2Broadcast[] =
64 {
65     {3, InitActorAmbientNoise},
66     {1024, InitActorDecide}
67 };
68 
69 DECISION Ripper2Surprised[] =
70 {
71     {40, InitRipper2Hang},
72     {701, InitActorMoveCloser},
73     {1024, InitActorDecide}
74 };
75 
76 DECISION Ripper2Evasive[] =
77 {
78     {10, InitActorMoveCloser},
79     {1024, InitRipper2Charge}
80 };
81 
82 DECISION Ripper2LostTarget[] =
83 {
84     {900, InitActorFindPlayer},
85     {1024, InitActorWanderAround}
86 };
87 
88 DECISION Ripper2CloseRange[] =
89 {
90     {1024,  InitActorAttack         }
91 };
92 
93 PERSONALITY Ripper2Personality =
94 {
95     Ripper2Battle,
96     Ripper2Offense,
97     Ripper2Broadcast,
98     Ripper2Surprised,
99     Ripper2Evasive,
100     Ripper2LostTarget,
101     Ripper2CloseRange,
102     Ripper2CloseRange
103 };
104 
105 ATTRIBUTE Ripper2Attrib =
106 {
107     {100, 120, 300, 380},               // Speeds
108     {5, 0, -2, -4},                     // Tic Adjusts
109     3,                                  // MaxWeapons;
110     {
111         DIGI_RIPPER2AMBIENT, DIGI_RIPPER2ALERT, DIGI_RIPPER2ATTACK,
112         DIGI_RIPPER2PAIN, DIGI_RIPPER2SCREAM, DIGI_RIPPER2HEARTOUT,
113         0,0,0,0
114     }
115 };
116 
117 //////////////////////
118 //
119 // RIPPER2 RUN
120 //
121 //////////////////////
122 
123 #define RIPPER2_RUN_RATE 16
124 
125 ANIMATOR DoRipper2Move, NullRipper2, DoActorDebris;
126 
127 STATE s_Ripper2Run[5][4] =
128 {
129     {
130         {RIPPER2_RUN_R0 + 0, RIPPER2_RUN_RATE | SF_TIC_ADJUST, DoRipper2Move, &s_Ripper2Run[0][1]},
131         {RIPPER2_RUN_R0 + 1, RIPPER2_RUN_RATE | SF_TIC_ADJUST, DoRipper2Move, &s_Ripper2Run[0][2]},
132         {RIPPER2_RUN_R0 + 2, RIPPER2_RUN_RATE | SF_TIC_ADJUST, DoRipper2Move, &s_Ripper2Run[0][3]},
133         {RIPPER2_RUN_R0 + 3, RIPPER2_RUN_RATE | SF_TIC_ADJUST, DoRipper2Move, &s_Ripper2Run[0][0]},
134     },
135     {
136         {RIPPER2_RUN_R1 + 0, RIPPER2_RUN_RATE | SF_TIC_ADJUST, DoRipper2Move, &s_Ripper2Run[1][1]},
137         {RIPPER2_RUN_R1 + 1, RIPPER2_RUN_RATE | SF_TIC_ADJUST, DoRipper2Move, &s_Ripper2Run[1][2]},
138         {RIPPER2_RUN_R1 + 2, RIPPER2_RUN_RATE | SF_TIC_ADJUST, DoRipper2Move, &s_Ripper2Run[1][3]},
139         {RIPPER2_RUN_R1 + 3, RIPPER2_RUN_RATE | SF_TIC_ADJUST, DoRipper2Move, &s_Ripper2Run[1][0]},
140     },
141     {
142         {RIPPER2_RUN_R2 + 0, RIPPER2_RUN_RATE | SF_TIC_ADJUST, DoRipper2Move, &s_Ripper2Run[2][1]},
143         {RIPPER2_RUN_R2 + 1, RIPPER2_RUN_RATE | SF_TIC_ADJUST, DoRipper2Move, &s_Ripper2Run[2][2]},
144         {RIPPER2_RUN_R2 + 2, RIPPER2_RUN_RATE | SF_TIC_ADJUST, DoRipper2Move, &s_Ripper2Run[2][3]},
145         {RIPPER2_RUN_R2 + 3, RIPPER2_RUN_RATE | SF_TIC_ADJUST, DoRipper2Move, &s_Ripper2Run[2][0]},
146     },
147     {
148         {RIPPER2_RUN_R3 + 0, RIPPER2_RUN_RATE | SF_TIC_ADJUST, DoRipper2Move, &s_Ripper2Run[3][1]},
149         {RIPPER2_RUN_R3 + 1, RIPPER2_RUN_RATE | SF_TIC_ADJUST, DoRipper2Move, &s_Ripper2Run[3][2]},
150         {RIPPER2_RUN_R3 + 2, RIPPER2_RUN_RATE | SF_TIC_ADJUST, DoRipper2Move, &s_Ripper2Run[3][3]},
151         {RIPPER2_RUN_R3 + 3, RIPPER2_RUN_RATE | SF_TIC_ADJUST, DoRipper2Move, &s_Ripper2Run[3][0]},
152     },
153     {
154         {RIPPER2_RUN_R4 + 0, RIPPER2_RUN_RATE | SF_TIC_ADJUST, DoRipper2Move, &s_Ripper2Run[4][1]},
155         {RIPPER2_RUN_R4 + 1, RIPPER2_RUN_RATE | SF_TIC_ADJUST, DoRipper2Move, &s_Ripper2Run[4][2]},
156         {RIPPER2_RUN_R4 + 2, RIPPER2_RUN_RATE | SF_TIC_ADJUST, DoRipper2Move, &s_Ripper2Run[4][3]},
157         {RIPPER2_RUN_R4 + 3, RIPPER2_RUN_RATE | SF_TIC_ADJUST, DoRipper2Move, &s_Ripper2Run[4][0]},
158     }
159 };
160 
161 
162 STATEp sg_Ripper2Run[] =
163 {
164     &s_Ripper2Run[0][0],
165     &s_Ripper2Run[1][0],
166     &s_Ripper2Run[2][0],
167     &s_Ripper2Run[3][0],
168     &s_Ripper2Run[4][0]
169 };
170 
171 //////////////////////
172 //
173 // RIPPER2 RUNFAST
174 //
175 //////////////////////
176 
177 #define RIPPER2_RUNFAST_RATE 14
178 
179 ANIMATOR NullRipper2, DoActorDebris;
180 
181 STATE s_Ripper2RunFast[5][4] =
182 {
183     {
184         {RIPPER2_RUNFAST_R0 + 0, RIPPER2_RUNFAST_RATE | SF_TIC_ADJUST, DoRipper2Move, &s_Ripper2RunFast[0][1]},
185         {RIPPER2_RUNFAST_R0 + 1, RIPPER2_RUNFAST_RATE | SF_TIC_ADJUST, DoRipper2Move, &s_Ripper2RunFast[0][2]},
186         {RIPPER2_RUNFAST_R0 + 2, RIPPER2_RUNFAST_RATE | SF_TIC_ADJUST, DoRipper2Move, &s_Ripper2RunFast[0][3]},
187         {RIPPER2_RUNFAST_R0 + 3, RIPPER2_RUNFAST_RATE | SF_TIC_ADJUST, DoRipper2Move, &s_Ripper2RunFast[0][0]},
188     },
189     {
190         {RIPPER2_RUNFAST_R1 + 0, RIPPER2_RUNFAST_RATE | SF_TIC_ADJUST, DoRipper2Move, &s_Ripper2RunFast[1][1]},
191         {RIPPER2_RUNFAST_R1 + 1, RIPPER2_RUNFAST_RATE | SF_TIC_ADJUST, DoRipper2Move, &s_Ripper2RunFast[1][2]},
192         {RIPPER2_RUNFAST_R1 + 2, RIPPER2_RUNFAST_RATE | SF_TIC_ADJUST, DoRipper2Move, &s_Ripper2RunFast[1][3]},
193         {RIPPER2_RUNFAST_R1 + 3, RIPPER2_RUNFAST_RATE | SF_TIC_ADJUST, DoRipper2Move, &s_Ripper2RunFast[1][0]},
194     },
195     {
196         {RIPPER2_RUNFAST_R2 + 0, RIPPER2_RUNFAST_RATE | SF_TIC_ADJUST, DoRipper2Move, &s_Ripper2RunFast[2][1]},
197         {RIPPER2_RUNFAST_R2 + 1, RIPPER2_RUNFAST_RATE | SF_TIC_ADJUST, DoRipper2Move, &s_Ripper2RunFast[2][2]},
198         {RIPPER2_RUNFAST_R2 + 2, RIPPER2_RUNFAST_RATE | SF_TIC_ADJUST, DoRipper2Move, &s_Ripper2RunFast[2][3]},
199         {RIPPER2_RUNFAST_R2 + 3, RIPPER2_RUNFAST_RATE | SF_TIC_ADJUST, DoRipper2Move, &s_Ripper2RunFast[2][0]},
200     },
201     {
202         {RIPPER2_RUNFAST_R3 + 0, RIPPER2_RUNFAST_RATE | SF_TIC_ADJUST, DoRipper2Move, &s_Ripper2RunFast[3][1]},
203         {RIPPER2_RUNFAST_R3 + 1, RIPPER2_RUNFAST_RATE | SF_TIC_ADJUST, DoRipper2Move, &s_Ripper2RunFast[3][2]},
204         {RIPPER2_RUNFAST_R3 + 2, RIPPER2_RUNFAST_RATE | SF_TIC_ADJUST, DoRipper2Move, &s_Ripper2RunFast[3][3]},
205         {RIPPER2_RUNFAST_R3 + 3, RIPPER2_RUNFAST_RATE | SF_TIC_ADJUST, DoRipper2Move, &s_Ripper2RunFast[3][0]},
206     },
207     {
208         {RIPPER2_RUNFAST_R4 + 0, RIPPER2_RUNFAST_RATE | SF_TIC_ADJUST, DoRipper2Move, &s_Ripper2RunFast[4][1]},
209         {RIPPER2_RUNFAST_R4 + 1, RIPPER2_RUNFAST_RATE | SF_TIC_ADJUST, DoRipper2Move, &s_Ripper2RunFast[4][2]},
210         {RIPPER2_RUNFAST_R4 + 2, RIPPER2_RUNFAST_RATE | SF_TIC_ADJUST, DoRipper2Move, &s_Ripper2RunFast[4][3]},
211         {RIPPER2_RUNFAST_R4 + 3, RIPPER2_RUNFAST_RATE | SF_TIC_ADJUST, DoRipper2Move, &s_Ripper2RunFast[4][0]},
212     }
213 };
214 
215 
216 STATEp sg_Ripper2RunFast[] =
217 {
218     &s_Ripper2RunFast[0][0],
219     &s_Ripper2RunFast[1][0],
220     &s_Ripper2RunFast[2][0],
221     &s_Ripper2RunFast[3][0],
222     &s_Ripper2RunFast[4][0]
223 };
224 
225 //////////////////////
226 //
227 // RIPPER2 STAND
228 //
229 //////////////////////
230 
231 #define RIPPER2_STAND_RATE 12
232 
233 STATE s_Ripper2Stand[5][1] =
234 {
235     {
236         {RIPPER2_STAND_R0 + 0, RIPPER2_STAND_RATE, DoRipper2Move, &s_Ripper2Stand[0][0]},
237     },
238     {
239         {RIPPER2_STAND_R1 + 0, RIPPER2_STAND_RATE, DoRipper2Move, &s_Ripper2Stand[1][0]},
240     },
241     {
242         {RIPPER2_STAND_R2 + 0, RIPPER2_STAND_RATE, DoRipper2Move, &s_Ripper2Stand[2][0]},
243     },
244     {
245         {RIPPER2_STAND_R3 + 0, RIPPER2_STAND_RATE, DoRipper2Move, &s_Ripper2Stand[3][0]},
246     },
247     {
248         {RIPPER2_STAND_R4 + 0, RIPPER2_STAND_RATE, DoRipper2Move, &s_Ripper2Stand[4][0]},
249     },
250 };
251 
252 STATEp sg_Ripper2Stand[] =
253 {
254     s_Ripper2Stand[0],
255     s_Ripper2Stand[1],
256     s_Ripper2Stand[2],
257     s_Ripper2Stand[3],
258     s_Ripper2Stand[4]
259 };
260 
261 //////////////////////
262 //
263 // RIPPER2 SWIPE
264 //
265 //////////////////////
266 
267 #define RIPPER2_SWIPE_RATE 14
268 ANIMATOR InitActorDecide;
269 ANIMATOR InitRipperSlash;
270 
271 STATE s_Ripper2Swipe[5][8] =
272 {
273     {
274         {RIPPER2_SWIPE_R0 + 0, RIPPER2_SWIPE_RATE, NullRipper2, &s_Ripper2Swipe[0][1]},
275         {RIPPER2_SWIPE_R0 + 1, RIPPER2_SWIPE_RATE, NullRipper2, &s_Ripper2Swipe[0][2]},
276         {RIPPER2_SWIPE_R0 + 1, 0 | SF_QUICK_CALL, InitRipperSlash, &s_Ripper2Swipe[0][3]},
277         {RIPPER2_SWIPE_R0 + 2, RIPPER2_SWIPE_RATE, NullRipper2, &s_Ripper2Swipe[0][4]},
278         {RIPPER2_SWIPE_R0 + 3, RIPPER2_SWIPE_RATE, NullRipper2, &s_Ripper2Swipe[0][5]},
279         {RIPPER2_SWIPE_R0 + 3, 0 | SF_QUICK_CALL, InitRipperSlash, &s_Ripper2Swipe[0][6]},
280         {RIPPER2_SWIPE_R0 + 3, 0 | SF_QUICK_CALL, InitActorDecide, &s_Ripper2Swipe[0][7]},
281         {RIPPER2_SWIPE_R0 + 3, RIPPER2_SWIPE_RATE, DoRipper2Move, &s_Ripper2Swipe[0][7]},
282     },
283     {
284         {RIPPER2_SWIPE_R1 + 0, RIPPER2_SWIPE_RATE, NullRipper2, &s_Ripper2Swipe[1][1]},
285         {RIPPER2_SWIPE_R1 + 1, RIPPER2_SWIPE_RATE, NullRipper2, &s_Ripper2Swipe[1][2]},
286         {RIPPER2_SWIPE_R1 + 1, 0 | SF_QUICK_CALL, InitRipperSlash, &s_Ripper2Swipe[1][3]},
287         {RIPPER2_SWIPE_R1 + 2, RIPPER2_SWIPE_RATE, NullRipper2, &s_Ripper2Swipe[1][4]},
288         {RIPPER2_SWIPE_R1 + 3, RIPPER2_SWIPE_RATE, NullRipper2, &s_Ripper2Swipe[1][5]},
289         {RIPPER2_SWIPE_R1 + 3, 0 | SF_QUICK_CALL, InitRipperSlash, &s_Ripper2Swipe[1][6]},
290         {RIPPER2_SWIPE_R1 + 3, 0 | SF_QUICK_CALL, InitActorDecide, &s_Ripper2Swipe[1][7]},
291         {RIPPER2_SWIPE_R1 + 3, RIPPER2_SWIPE_RATE, DoRipper2Move, &s_Ripper2Swipe[1][7]},
292     },
293     {
294         {RIPPER2_SWIPE_R2 + 0, RIPPER2_SWIPE_RATE, NullRipper2, &s_Ripper2Swipe[2][1]},
295         {RIPPER2_SWIPE_R2 + 1, RIPPER2_SWIPE_RATE, NullRipper2, &s_Ripper2Swipe[2][2]},
296         {RIPPER2_SWIPE_R2 + 1, 0 | SF_QUICK_CALL, InitRipperSlash, &s_Ripper2Swipe[2][3]},
297         {RIPPER2_SWIPE_R2 + 2, RIPPER2_SWIPE_RATE, NullRipper2, &s_Ripper2Swipe[2][4]},
298         {RIPPER2_SWIPE_R2 + 3, RIPPER2_SWIPE_RATE, NullRipper2, &s_Ripper2Swipe[2][5]},
299         {RIPPER2_SWIPE_R2 + 3, 0 | SF_QUICK_CALL, InitRipperSlash, &s_Ripper2Swipe[2][6]},
300         {RIPPER2_SWIPE_R2 + 3, 0 | SF_QUICK_CALL, InitActorDecide, &s_Ripper2Swipe[2][7]},
301         {RIPPER2_SWIPE_R2 + 3, RIPPER2_SWIPE_RATE, DoRipper2Move, &s_Ripper2Swipe[2][7]},
302     },
303     {
304         {RIPPER2_SWIPE_R3 + 0, RIPPER2_SWIPE_RATE, NullRipper2, &s_Ripper2Swipe[3][1]},
305         {RIPPER2_SWIPE_R3 + 1, RIPPER2_SWIPE_RATE, NullRipper2, &s_Ripper2Swipe[3][2]},
306         {RIPPER2_SWIPE_R3 + 1, 0 | SF_QUICK_CALL, InitRipperSlash, &s_Ripper2Swipe[3][3]},
307         {RIPPER2_SWIPE_R3 + 2, RIPPER2_SWIPE_RATE, NullRipper2, &s_Ripper2Swipe[3][4]},
308         {RIPPER2_SWIPE_R3 + 3, RIPPER2_SWIPE_RATE, NullRipper2, &s_Ripper2Swipe[3][5]},
309         {RIPPER2_SWIPE_R3 + 3, 0 | SF_QUICK_CALL, InitRipperSlash, &s_Ripper2Swipe[3][6]},
310         {RIPPER2_SWIPE_R3 + 3, 0 | SF_QUICK_CALL, InitActorDecide, &s_Ripper2Swipe[3][7]},
311         {RIPPER2_SWIPE_R3 + 3, RIPPER2_SWIPE_RATE, DoRipper2Move, &s_Ripper2Swipe[3][7]},
312     },
313     {
314         {RIPPER2_SWIPE_R4 + 0, RIPPER2_SWIPE_RATE, NullRipper2, &s_Ripper2Swipe[4][1]},
315         {RIPPER2_SWIPE_R4 + 1, RIPPER2_SWIPE_RATE, NullRipper2, &s_Ripper2Swipe[4][2]},
316         {RIPPER2_SWIPE_R4 + 1, 0 | SF_QUICK_CALL, InitRipperSlash, &s_Ripper2Swipe[4][3]},
317         {RIPPER2_SWIPE_R4 + 2, RIPPER2_SWIPE_RATE, NullRipper2, &s_Ripper2Swipe[4][4]},
318         {RIPPER2_SWIPE_R4 + 3, RIPPER2_SWIPE_RATE, NullRipper2, &s_Ripper2Swipe[4][5]},
319         {RIPPER2_SWIPE_R4 + 3, 0 | SF_QUICK_CALL, InitRipperSlash, &s_Ripper2Swipe[4][6]},
320         {RIPPER2_SWIPE_R4 + 3, 0 | SF_QUICK_CALL, InitActorDecide, &s_Ripper2Swipe[4][7]},
321         {RIPPER2_SWIPE_R4 + 3, RIPPER2_SWIPE_RATE, DoRipper2Move, &s_Ripper2Swipe[4][7]},
322     }
323 };
324 
325 
326 STATEp sg_Ripper2Swipe[] =
327 {
328     &s_Ripper2Swipe[0][0],
329     &s_Ripper2Swipe[1][0],
330     &s_Ripper2Swipe[2][0],
331     &s_Ripper2Swipe[3][0],
332     &s_Ripper2Swipe[4][0]
333 };
334 
335 //////////////////////
336 //
337 // RIPPER2 KONG
338 //
339 //////////////////////
340 
341 #define RIPPER2_MEKONG_RATE 18
342 ANIMATOR InitActorDecide, ChestRipper2;
343 
344 STATE s_Ripper2Kong[5][7] =
345 {
346     {
347         {RIPPER2_MEKONG_R0 + 0, RIPPER2_MEKONG_RATE, NullRipper2, &s_Ripper2Kong[0][1]},
348         {RIPPER2_MEKONG_R0 + 0, SF_QUICK_CALL,       ChestRipper2, &s_Ripper2Kong[0][2]},
349         {RIPPER2_MEKONG_R0 + 1, RIPPER2_MEKONG_RATE, NullRipper2, &s_Ripper2Kong[0][3]},
350         {RIPPER2_MEKONG_R0 + 2, RIPPER2_MEKONG_RATE, NullRipper2, &s_Ripper2Kong[0][4]},
351         {RIPPER2_MEKONG_R0 + 3, RIPPER2_MEKONG_RATE, NullRipper2, &s_Ripper2Kong[0][5]},
352         {RIPPER2_MEKONG_R0 + 3, 0 | SF_QUICK_CALL, InitActorDecide, &s_Ripper2Kong[0][6]},
353         {RIPPER2_MEKONG_R0 + 0, RIPPER2_MEKONG_RATE, DoRipper2Move, &s_Ripper2Kong[0][6]},
354     },
355     {
356         {RIPPER2_MEKONG_R1 + 0, RIPPER2_MEKONG_RATE, NullRipper2, &s_Ripper2Kong[1][1]},
357         {RIPPER2_MEKONG_R0 + 0, SF_QUICK_CALL,       ChestRipper2, &s_Ripper2Kong[1][2]},
358         {RIPPER2_MEKONG_R1 + 1, RIPPER2_MEKONG_RATE, NullRipper2, &s_Ripper2Kong[1][3]},
359         {RIPPER2_MEKONG_R1 + 2, RIPPER2_MEKONG_RATE, NullRipper2, &s_Ripper2Kong[1][4]},
360         {RIPPER2_MEKONG_R1 + 3, RIPPER2_MEKONG_RATE, NullRipper2, &s_Ripper2Kong[1][5]},
361         {RIPPER2_MEKONG_R1 + 3, 0 | SF_QUICK_CALL, InitActorDecide, &s_Ripper2Kong[1][6]},
362         {RIPPER2_MEKONG_R1 + 0, RIPPER2_MEKONG_RATE, DoRipper2Move, &s_Ripper2Kong[1][6]},
363     },
364     {
365         {RIPPER2_MEKONG_R2 + 0, RIPPER2_MEKONG_RATE, NullRipper2, &s_Ripper2Kong[2][1]},
366         {RIPPER2_MEKONG_R0 + 0, SF_QUICK_CALL,       ChestRipper2, &s_Ripper2Kong[2][2]},
367         {RIPPER2_MEKONG_R2 + 1, RIPPER2_MEKONG_RATE, NullRipper2, &s_Ripper2Kong[2][3]},
368         {RIPPER2_MEKONG_R2 + 2, RIPPER2_MEKONG_RATE, NullRipper2, &s_Ripper2Kong[2][4]},
369         {RIPPER2_MEKONG_R2 + 3, RIPPER2_MEKONG_RATE, NullRipper2, &s_Ripper2Kong[2][5]},
370         {RIPPER2_MEKONG_R2 + 3, 0 | SF_QUICK_CALL, InitActorDecide, &s_Ripper2Kong[2][6]},
371         {RIPPER2_MEKONG_R2 + 0, RIPPER2_MEKONG_RATE, DoRipper2Move, &s_Ripper2Kong[2][6]},
372     },
373     {
374         {RIPPER2_MEKONG_R3 + 0, RIPPER2_MEKONG_RATE, NullRipper2, &s_Ripper2Kong[3][1]},
375         {RIPPER2_MEKONG_R0 + 0, SF_QUICK_CALL,       ChestRipper2, &s_Ripper2Kong[3][2]},
376         {RIPPER2_MEKONG_R3 + 1, RIPPER2_MEKONG_RATE, NullRipper2, &s_Ripper2Kong[3][3]},
377         {RIPPER2_MEKONG_R3 + 2, RIPPER2_MEKONG_RATE, NullRipper2, &s_Ripper2Kong[3][4]},
378         {RIPPER2_MEKONG_R3 + 3, RIPPER2_MEKONG_RATE, NullRipper2, &s_Ripper2Kong[3][5]},
379         {RIPPER2_MEKONG_R3 + 3, 0 | SF_QUICK_CALL, InitActorDecide, &s_Ripper2Kong[3][6]},
380         {RIPPER2_MEKONG_R3 + 0, RIPPER2_MEKONG_RATE, DoRipper2Move, &s_Ripper2Kong[3][6]},
381     },
382     {
383         {RIPPER2_MEKONG_R4 + 0, RIPPER2_MEKONG_RATE, NullRipper2, &s_Ripper2Kong[4][1]},
384         {RIPPER2_MEKONG_R0 + 0, SF_QUICK_CALL,       ChestRipper2, &s_Ripper2Kong[4][2]},
385         {RIPPER2_MEKONG_R4 + 1, RIPPER2_MEKONG_RATE, NullRipper2, &s_Ripper2Kong[4][3]},
386         {RIPPER2_MEKONG_R4 + 2, RIPPER2_MEKONG_RATE, NullRipper2, &s_Ripper2Kong[4][4]},
387         {RIPPER2_MEKONG_R4 + 3, RIPPER2_MEKONG_RATE, NullRipper2, &s_Ripper2Kong[4][5]},
388         {RIPPER2_MEKONG_R4 + 3, 0 | SF_QUICK_CALL, InitActorDecide, &s_Ripper2Kong[4][6]},
389         {RIPPER2_MEKONG_R4 + 0, RIPPER2_MEKONG_RATE, DoRipper2Move, &s_Ripper2Kong[4][6]},
390     }
391 };
392 
393 
394 STATEp sg_Ripper2Kong[] =
395 {
396     &s_Ripper2Kong[0][0],
397     &s_Ripper2Kong[1][0],
398     &s_Ripper2Kong[2][0],
399     &s_Ripper2Kong[3][0],
400     &s_Ripper2Kong[4][0]
401 };
402 
403 
404 //////////////////////
405 //
406 // RIPPER2 HEART - show players heart
407 //
408 //////////////////////
409 
410 #define RIPPER2_HEART_RATE 20
411 ANIMATOR DoRipper2StandHeart;
412 
413 STATE s_Ripper2Heart[5][4] =
414 {
415     {
416         {RIPPER2_HEART_R0 + 0, RIPPER2_HEART_RATE, DoRipper2StandHeart, &s_Ripper2Heart[0][1]},
417         {RIPPER2_HEART_R0 + 1, RIPPER2_HEART_RATE, DoRipper2StandHeart, &s_Ripper2Heart[0][0]},
418     },
419     {
420         {RIPPER2_HEART_R1 + 0, RIPPER2_HEART_RATE, DoRipper2StandHeart, &s_Ripper2Heart[1][1]},
421         {RIPPER2_HEART_R1 + 1, RIPPER2_HEART_RATE, DoRipper2StandHeart, &s_Ripper2Heart[1][0]},
422     },
423     {
424         {RIPPER2_HEART_R2 + 0, RIPPER2_HEART_RATE, DoRipper2StandHeart, &s_Ripper2Heart[2][1]},
425         {RIPPER2_HEART_R2 + 1, RIPPER2_HEART_RATE, DoRipper2StandHeart, &s_Ripper2Heart[2][0]},
426     },
427     {
428         {RIPPER2_HEART_R3 + 0, RIPPER2_HEART_RATE, DoRipper2StandHeart, &s_Ripper2Heart[3][1]},
429         {RIPPER2_HEART_R3 + 1, RIPPER2_HEART_RATE, DoRipper2StandHeart, &s_Ripper2Heart[3][0]},
430     },
431     {
432         {RIPPER2_HEART_R4 + 0, RIPPER2_HEART_RATE, DoRipper2StandHeart, &s_Ripper2Heart[4][1]},
433         {RIPPER2_HEART_R4 + 1, RIPPER2_HEART_RATE, DoRipper2StandHeart, &s_Ripper2Heart[4][0]},
434     }
435 };
436 
437 
438 STATEp sg_Ripper2Heart[] =
439 {
440     &s_Ripper2Heart[0][0],
441     &s_Ripper2Heart[1][0],
442     &s_Ripper2Heart[2][0],
443     &s_Ripper2Heart[3][0],
444     &s_Ripper2Heart[4][0]
445 };
446 
447 //////////////////////
448 //
449 // RIPPER2 HANG
450 //
451 //////////////////////
452 
453 #define RIPPER2_HANG_RATE 14
454 ANIMATOR DoRipper2Hang;
455 
456 STATE s_Ripper2Hang[5][4] =
457 {
458     {
459         {RIPPER2_HANG_R0, RIPPER2_HANG_RATE, DoRipper2Hang, &s_Ripper2Hang[0][0]},
460     },
461     {
462         {RIPPER2_HANG_R1, RIPPER2_HANG_RATE, DoRipper2Hang, &s_Ripper2Hang[1][0]},
463     },
464     {
465         {RIPPER2_HANG_R2, RIPPER2_HANG_RATE, DoRipper2Hang, &s_Ripper2Hang[2][0]},
466     },
467     {
468         {RIPPER2_HANG_R3, RIPPER2_HANG_RATE, DoRipper2Hang, &s_Ripper2Hang[3][0]},
469     },
470     {
471         {RIPPER2_HANG_R4, RIPPER2_HANG_RATE, DoRipper2Hang, &s_Ripper2Hang[4][0]},
472     }
473 };
474 
475 
476 STATEp sg_Ripper2Hang[] =
477 {
478     &s_Ripper2Hang[0][0],
479     &s_Ripper2Hang[1][0],
480     &s_Ripper2Hang[2][0],
481     &s_Ripper2Hang[3][0],
482     &s_Ripper2Hang[4][0]
483 };
484 
485 
486 //////////////////////
487 //
488 // RIPPER2 PAIN
489 //
490 //////////////////////
491 
492 #define RIPPER2_PAIN_RATE 38
493 ANIMATOR DoRipper2Pain;
494 
495 STATE s_Ripper2Pain[5][1] =
496 {
497     {
498         {4414 + 0, RIPPER2_PAIN_RATE, DoRipper2Pain, &s_Ripper2Pain[0][0]},
499     },
500     {
501         {4414 + 0, RIPPER2_PAIN_RATE, DoRipper2Pain, &s_Ripper2Pain[1][0]},
502     },
503     {
504         {4414 + 0, RIPPER2_PAIN_RATE, DoRipper2Pain, &s_Ripper2Pain[2][0]},
505     },
506     {
507         {4414 + 0, RIPPER2_PAIN_RATE, DoRipper2Pain, &s_Ripper2Pain[3][0]},
508     },
509     {
510         {4414 + 0, RIPPER2_PAIN_RATE, DoRipper2Pain, &s_Ripper2Pain[4][0]},
511     }
512 };
513 
514 STATEp sg_Ripper2Pain[] =
515 {
516     &s_Ripper2Pain[0][0],
517     &s_Ripper2Pain[1][0],
518     &s_Ripper2Pain[2][0],
519     &s_Ripper2Pain[3][0],
520     &s_Ripper2Pain[4][0]
521 };
522 
523 //////////////////////
524 //
525 // RIPPER2 JUMP
526 //
527 //////////////////////
528 
529 #define RIPPER2_JUMP_RATE 25
530 
531 STATE s_Ripper2Jump[5][6] =
532 {
533     {
534         {RIPPER2_JUMP_R0 + 0, RIPPER2_JUMP_RATE, NullRipper2, &s_Ripper2Jump[0][1]},
535         {RIPPER2_JUMP_R0 + 1, RIPPER2_JUMP_RATE, DoRipper2MoveJump, &s_Ripper2Jump[0][1]},
536     },
537     {
538         {RIPPER2_JUMP_R1 + 0, RIPPER2_JUMP_RATE, NullRipper2, &s_Ripper2Jump[1][1]},
539         {RIPPER2_JUMP_R1 + 1, RIPPER2_JUMP_RATE, DoRipper2MoveJump, &s_Ripper2Jump[1][1]},
540     },
541     {
542         {RIPPER2_JUMP_R2 + 0, RIPPER2_JUMP_RATE, NullRipper2, &s_Ripper2Jump[2][1]},
543         {RIPPER2_JUMP_R2 + 1, RIPPER2_JUMP_RATE, DoRipper2MoveJump, &s_Ripper2Jump[2][1]},
544     },
545     {
546         {RIPPER2_JUMP_R3 + 0, RIPPER2_JUMP_RATE, NullRipper2, &s_Ripper2Jump[3][1]},
547         {RIPPER2_JUMP_R3 + 1, RIPPER2_JUMP_RATE, DoRipper2MoveJump, &s_Ripper2Jump[3][1]},
548     },
549     {
550         {RIPPER2_JUMP_R4 + 0, RIPPER2_JUMP_RATE, NullRipper2, &s_Ripper2Jump[4][1]},
551         {RIPPER2_JUMP_R4 + 1, RIPPER2_JUMP_RATE, DoRipper2MoveJump, &s_Ripper2Jump[4][1]},
552     }
553 };
554 
555 
556 STATEp sg_Ripper2Jump[] =
557 {
558     &s_Ripper2Jump[0][0],
559     &s_Ripper2Jump[1][0],
560     &s_Ripper2Jump[2][0],
561     &s_Ripper2Jump[3][0],
562     &s_Ripper2Jump[4][0]
563 };
564 
565 
566 //////////////////////
567 //
568 // RIPPER2 FALL
569 //
570 //////////////////////
571 
572 #define RIPPER2_FALL_RATE 25
573 
574 STATE s_Ripper2Fall[5][6] =
575 {
576     {
577         {RIPPER2_FALL_R0 + 0, RIPPER2_FALL_RATE, DoRipper2MoveJump, &s_Ripper2Fall[0][0]},
578     },
579     {
580         {RIPPER2_FALL_R1 + 0, RIPPER2_FALL_RATE, DoRipper2MoveJump, &s_Ripper2Fall[1][0]},
581     },
582     {
583         {RIPPER2_FALL_R2 + 0, RIPPER2_FALL_RATE, DoRipper2MoveJump, &s_Ripper2Fall[2][0]},
584     },
585     {
586         {RIPPER2_FALL_R3 + 0, RIPPER2_FALL_RATE, DoRipper2MoveJump, &s_Ripper2Fall[3][0]},
587     },
588     {
589         {RIPPER2_FALL_R4 + 0, RIPPER2_FALL_RATE, DoRipper2MoveJump, &s_Ripper2Fall[4][0]},
590     }
591 };
592 
593 
594 STATEp sg_Ripper2Fall[] =
595 {
596     &s_Ripper2Fall[0][0],
597     &s_Ripper2Fall[1][0],
598     &s_Ripper2Fall[2][0],
599     &s_Ripper2Fall[3][0],
600     &s_Ripper2Fall[4][0]
601 };
602 
603 
604 //////////////////////
605 //
606 // RIPPER2 JUMP ATTACK
607 //
608 //////////////////////
609 
610 #define RIPPER2_JUMP_ATTACK_RATE 35
611 int DoRipper2BeginJumpAttack(short SpriteNum);
612 
613 STATE s_Ripper2JumpAttack[5][6] =
614 {
615     {
616         {RIPPER2_JUMP_R0 + 0, RIPPER2_JUMP_ATTACK_RATE, NullRipper2, &s_Ripper2JumpAttack[0][1]},
617         {RIPPER2_JUMP_R0 + 0, 0 | SF_QUICK_CALL, DoRipper2BeginJumpAttack, &s_Ripper2JumpAttack[0][2]},
618         {RIPPER2_JUMP_R0 + 2, RIPPER2_JUMP_ATTACK_RATE, DoRipper2MoveJump, &s_Ripper2JumpAttack[0][3]},
619         {RIPPER2_JUMP_R0 + 1, RIPPER2_JUMP_ATTACK_RATE, DoRipper2MoveJump, &s_Ripper2JumpAttack[0][3]},
620     },
621     {
622         {RIPPER2_JUMP_R1 + 0, RIPPER2_JUMP_ATTACK_RATE, NullRipper2, &s_Ripper2JumpAttack[1][1]},
623         {RIPPER2_JUMP_R1 + 0, 0 | SF_QUICK_CALL, DoRipper2BeginJumpAttack, &s_Ripper2JumpAttack[1][2]},
624         {RIPPER2_JUMP_R1 + 2, RIPPER2_JUMP_ATTACK_RATE, DoRipper2MoveJump, &s_Ripper2JumpAttack[1][3]},
625         {RIPPER2_JUMP_R1 + 1, RIPPER2_JUMP_ATTACK_RATE, DoRipper2MoveJump, &s_Ripper2JumpAttack[1][3]},
626     },
627     {
628         {RIPPER2_JUMP_R2 + 0, RIPPER2_JUMP_ATTACK_RATE, NullRipper2, &s_Ripper2JumpAttack[2][1]},
629         {RIPPER2_JUMP_R2 + 0, 0 | SF_QUICK_CALL, DoRipper2BeginJumpAttack, &s_Ripper2JumpAttack[2][2]},
630         {RIPPER2_JUMP_R2 + 2, RIPPER2_JUMP_ATTACK_RATE, DoRipper2MoveJump, &s_Ripper2JumpAttack[2][3]},
631         {RIPPER2_JUMP_R1 + 1, RIPPER2_JUMP_ATTACK_RATE, DoRipper2MoveJump, &s_Ripper2JumpAttack[2][3]},
632     },
633     {
634         {RIPPER2_JUMP_R3 + 0, RIPPER2_JUMP_ATTACK_RATE, NullRipper2, &s_Ripper2JumpAttack[3][1]},
635         {RIPPER2_JUMP_R3 + 0, 0 | SF_QUICK_CALL, DoRipper2BeginJumpAttack, &s_Ripper2JumpAttack[3][2]},
636         {RIPPER2_JUMP_R3 + 2, RIPPER2_JUMP_ATTACK_RATE, DoRipper2MoveJump, &s_Ripper2JumpAttack[3][3]},
637         {RIPPER2_JUMP_R1 + 1, RIPPER2_JUMP_ATTACK_RATE, DoRipper2MoveJump, &s_Ripper2JumpAttack[3][3]},
638     },
639     {
640         {RIPPER2_JUMP_R4 + 0, RIPPER2_JUMP_ATTACK_RATE, NullRipper2, &s_Ripper2JumpAttack[4][1]},
641         {RIPPER2_JUMP_R4 + 0, 0 | SF_QUICK_CALL, DoRipper2BeginJumpAttack, &s_Ripper2JumpAttack[4][2]},
642         {RIPPER2_JUMP_R4 + 2, RIPPER2_JUMP_ATTACK_RATE, DoRipper2MoveJump, &s_Ripper2JumpAttack[4][3]},
643         {RIPPER2_JUMP_R1 + 1, RIPPER2_JUMP_ATTACK_RATE, DoRipper2MoveJump, &s_Ripper2JumpAttack[4][3]},
644     }
645 };
646 
647 
648 STATEp sg_Ripper2JumpAttack[] =
649 {
650     &s_Ripper2JumpAttack[0][0],
651     &s_Ripper2JumpAttack[1][0],
652     &s_Ripper2JumpAttack[2][0],
653     &s_Ripper2JumpAttack[3][0],
654     &s_Ripper2JumpAttack[4][0]
655 };
656 
657 
658 //////////////////////
659 //
660 // RIPPER2 HANG_JUMP
661 //
662 //////////////////////
663 
664 #define RIPPER2_HANG_JUMP_RATE 20
665 
666 STATE s_Ripper2HangJump[5][6] =
667 {
668     {
669         {RIPPER2_JUMP_R0 + 0, RIPPER2_HANG_JUMP_RATE, NullRipper2, &s_Ripper2HangJump[0][1]},
670         {RIPPER2_JUMP_R0 + 1, RIPPER2_HANG_JUMP_RATE, DoRipper2HangJF, &s_Ripper2HangJump[0][1]},
671     },
672     {
673         {RIPPER2_JUMP_R1 + 0, RIPPER2_HANG_JUMP_RATE, NullRipper2, &s_Ripper2HangJump[1][1]},
674         {RIPPER2_JUMP_R1 + 1, RIPPER2_HANG_JUMP_RATE, DoRipper2HangJF, &s_Ripper2HangJump[1][1]},
675     },
676     {
677         {RIPPER2_JUMP_R2 + 0, RIPPER2_HANG_JUMP_RATE, NullRipper2, &s_Ripper2HangJump[2][1]},
678         {RIPPER2_JUMP_R2 + 1, RIPPER2_HANG_JUMP_RATE, DoRipper2HangJF, &s_Ripper2HangJump[2][1]},
679     },
680     {
681         {RIPPER2_JUMP_R3 + 0, RIPPER2_HANG_JUMP_RATE, NullRipper2, &s_Ripper2HangJump[3][1]},
682         {RIPPER2_JUMP_R3 + 1, RIPPER2_HANG_JUMP_RATE, DoRipper2HangJF, &s_Ripper2HangJump[3][1]},
683     },
684     {
685         {RIPPER2_JUMP_R4 + 0, RIPPER2_HANG_JUMP_RATE, NullRipper2, &s_Ripper2HangJump[4][1]},
686         {RIPPER2_JUMP_R4 + 1, RIPPER2_HANG_JUMP_RATE, DoRipper2HangJF, &s_Ripper2HangJump[4][1]},
687     }
688 };
689 
690 
691 STATEp sg_Ripper2HangJump[] =
692 {
693     &s_Ripper2HangJump[0][0],
694     &s_Ripper2HangJump[1][0],
695     &s_Ripper2HangJump[2][0],
696     &s_Ripper2HangJump[3][0],
697     &s_Ripper2HangJump[4][0]
698 };
699 
700 //////////////////////
701 //
702 // RIPPER2 HANG_FALL
703 //
704 //////////////////////
705 
706 #define RIPPER2_FALL_RATE 25
707 
708 STATE s_Ripper2HangFall[5][6] =
709 {
710     {
711         {RIPPER2_FALL_R0 + 0, RIPPER2_FALL_RATE, DoRipper2HangJF, &s_Ripper2HangFall[0][0]},
712     },
713     {
714         {RIPPER2_FALL_R1 + 0, RIPPER2_FALL_RATE, DoRipper2HangJF, &s_Ripper2HangFall[1][0]},
715     },
716     {
717         {RIPPER2_FALL_R2 + 0, RIPPER2_FALL_RATE, DoRipper2HangJF, &s_Ripper2HangFall[2][0]},
718     },
719     {
720         {RIPPER2_FALL_R3 + 0, RIPPER2_FALL_RATE, DoRipper2HangJF, &s_Ripper2HangFall[3][0]},
721     },
722     {
723         {RIPPER2_FALL_R4 + 0, RIPPER2_FALL_RATE, DoRipper2HangJF, &s_Ripper2HangFall[4][0]},
724     }
725 };
726 
727 
728 STATEp sg_Ripper2HangFall[] =
729 {
730     &s_Ripper2HangFall[0][0],
731     &s_Ripper2HangFall[1][0],
732     &s_Ripper2HangFall[2][0],
733     &s_Ripper2HangFall[3][0],
734     &s_Ripper2HangFall[4][0]
735 };
736 
737 
738 
739 //////////////////////
740 //
741 // RIPPER2 DIE
742 //
743 //////////////////////
744 
745 #define RIPPER2_DIE_RATE 18
746 
747 STATE s_Ripper2Die[] =
748 {
749     {RIPPER2_DIE + 0, RIPPER2_DIE_RATE, NullRipper2, &s_Ripper2Die[1]},
750     {RIPPER2_DIE + 1, RIPPER2_DIE_RATE, NullRipper2, &s_Ripper2Die[2]},
751     {RIPPER2_DIE + 2, RIPPER2_DIE_RATE, NullRipper2, &s_Ripper2Die[3]},
752     {RIPPER2_DIE + 3, RIPPER2_DIE_RATE, NullRipper2, &s_Ripper2Die[4]},
753     {RIPPER2_DIE + 4, RIPPER2_DIE_RATE, NullRipper2, &s_Ripper2Die[5]},
754     {RIPPER2_DIE + 5, RIPPER2_DIE_RATE, NullRipper2, &s_Ripper2Die[6]},
755     {RIPPER2_DIE + 6, RIPPER2_DIE_RATE, NullRipper2, &s_Ripper2Die[7]},
756     {RIPPER2_DEAD, RIPPER2_DIE_RATE, DoActorDebris, &s_Ripper2Die[7]},
757 };
758 
759 #define RIPPER2_DEAD_RATE 8
760 
761 STATE s_Ripper2Dead[] =
762 {
763     {RIPPER2_DIE + 0, RIPPER2_DIE_RATE, NullRipper2, &s_Ripper2Dead[1]},
764     {RIPPER2_DIE + 1, RIPPER2_DIE_RATE, NullRipper2, &s_Ripper2Dead[2]},
765     {RIPPER2_DIE + 2, RIPPER2_DIE_RATE, NullRipper2, &s_Ripper2Dead[3]},
766     {RIPPER2_DIE + 3, RIPPER2_DIE_RATE, NullRipper2, &s_Ripper2Dead[4]},
767     {RIPPER2_DIE + 4, RIPPER2_DIE_RATE, NullRipper2, &s_Ripper2Dead[5]},
768     {RIPPER2_DIE + 5, RIPPER2_DIE_RATE, NullRipper2, &s_Ripper2Dead[6]},
769     {RIPPER2_DIE + 6, RIPPER2_DIE_RATE, NullRipper2, &s_Ripper2Dead[7]},
770     {RIPPER2_DEAD, SF_QUICK_CALL, QueueFloorBlood, &s_Ripper2Dead[8]},
771     {RIPPER2_DEAD, RIPPER2_DEAD_RATE, DoActorDebris, &s_Ripper2Dead[8]},
772 };
773 
774 STATEp sg_Ripper2Die[] =
775 {
776     s_Ripper2Die
777 };
778 
779 STATEp sg_Ripper2Dead[] =
780 {
781     s_Ripper2Dead
782 };
783 
784 STATE s_Ripper2DeathJump[] =
785 {
786     {RIPPER2_DIE + 0, RIPPER2_DIE_RATE, DoActorDeathMove, &s_Ripper2DeathJump[0]}
787 };
788 
789 STATE s_Ripper2DeathFall[] =
790 {
791     {RIPPER2_DIE + 1, RIPPER2_DIE_RATE, DoActorDeathMove, &s_Ripper2DeathFall[0]}
792 };
793 
794 
795 STATEp sg_Ripper2DeathJump[] =
796 {
797     s_Ripper2DeathJump
798 };
799 
800 STATEp sg_Ripper2DeathFall[] =
801 {
802     s_Ripper2DeathFall
803 };
804 
805 
806 /*
807 STATEp *Stand[MAX_WEAPONS];
808 STATEp *Run;
809 STATEp *Jump;
810 STATEp *Fall;
811 STATEp *Crawl;
812 STATEp *Swim;
813 STATEp *Fly;
814 STATEp *Rise;
815 STATEp *Sit;
816 STATEp *Look;
817 STATEp *Climb;
818 STATEp *Pain;
819 STATEp *Death1;
820 STATEp *Death2;
821 STATEp *Dead;
822 STATEp *DeathJump;
823 STATEp *DeathFall;
824 STATEp *CloseAttack[2];
825 STATEp *Attack[6];
826 STATEp *Special[2];
827 */
828 
829 
830 ACTOR_ACTION_SET Ripper2ActionSet =
831 {
832     sg_Ripper2Stand,
833     sg_Ripper2Run,
834     sg_Ripper2Jump,
835     sg_Ripper2Fall,
836     NULL,                               // sg_Ripper2Crawl,
837     NULL,                               // sg_Ripper2Swim,
838     NULL,                               // sg_Ripper2Fly,
839     NULL,                               // sg_Ripper2Rise,
840     NULL,                               // sg_Ripper2Sit,
841     NULL,                               // sg_Ripper2Look,
842     NULL,                               // climb
843     sg_Ripper2Pain,
844     sg_Ripper2Die,
845     NULL,                               // sg_Ripper2HariKari,
846     sg_Ripper2Dead,
847     sg_Ripper2DeathJump,
848     sg_Ripper2DeathFall,
849     {sg_Ripper2Swipe},
850     {1024},
851     {sg_Ripper2JumpAttack, sg_Ripper2Kong},
852     {500, 1024},
853     {sg_Ripper2Heart, sg_Ripper2Hang},
854     NULL,
855     NULL
856 };
857 
858 ACTOR_ACTION_SET Ripper2BrownActionSet =
859 {
860     sg_Ripper2Stand,
861     sg_Ripper2Run,
862     sg_Ripper2Jump,
863     sg_Ripper2Fall,
864     NULL,                               // sg_Ripper2Crawl,
865     NULL,                               // sg_Ripper2Swim,
866     NULL,                               // sg_Ripper2Fly,
867     NULL,                               // sg_Ripper2Rise,
868     NULL,                               // sg_Ripper2Sit,
869     NULL,                               // sg_Ripper2Look,
870     NULL,                               // climb
871     sg_Ripper2Pain,                      // pain
872     sg_Ripper2Die,
873     NULL,                               // sg_Ripper2HariKari,
874     sg_Ripper2Dead,
875     sg_Ripper2DeathJump,
876     sg_Ripper2DeathFall,
877     {sg_Ripper2Swipe},
878     {1024},
879     {sg_Ripper2JumpAttack, sg_Ripper2Kong},
880     {400, 1024},
881     {sg_Ripper2Heart, sg_Ripper2Hang},
882     NULL,
883     NULL
884 };
885 
886 int
SetupRipper2(short SpriteNum)887 SetupRipper2(short SpriteNum)
888 {
889     SPRITEp sp = &sprite[SpriteNum];
890     USERp u;
891     ANIMATOR DoActorDecide;
892 
893     if (TEST(sp->cstat, CSTAT_SPRITE_RESTORE))
894     {
895         u = User[SpriteNum];
896         ASSERT(u);
897     }
898     else
899     {
900         User[SpriteNum] = u = SpawnUser(SpriteNum, RIPPER2_RUN_R0, s_Ripper2Run[0]);
901         u->Health = HEALTH_RIPPER2;
902     }
903 
904     ChangeState(SpriteNum, s_Ripper2Run[0]);
905     u->Attrib = &Ripper2Attrib;
906     DoActorSetSpeed(SpriteNum, NORM_SPEED);
907     u->StateEnd = s_Ripper2Die;
908     u->Rot = sg_Ripper2Run;
909     sp->clipdist = 512 >> 2;  // This actor is bigger, needs bigger box.
910     sp->xrepeat = sp->yrepeat = 55;
911 
912     if (sp->pal == PALETTE_BROWN_RIPPER)
913     {
914         EnemyDefaults(SpriteNum, &Ripper2BrownActionSet, &Ripper2Personality);
915         sp->xrepeat += 40;
916         sp->yrepeat += 40;
917 
918         if (!TEST(sp->cstat, CSTAT_SPRITE_RESTORE))
919             u->Health = HEALTH_MOMMA_RIPPER;
920 
921         sp->clipdist += 128 >> 2;
922     }
923     else
924     {
925         EnemyDefaults(SpriteNum, &Ripper2ActionSet, &Ripper2Personality);
926     }
927 
928     SET(u->Flags, SPR_XFLIP_TOGGLE);
929 
930     return 0;
931 }
932 
933 //
934 // HANGING - Jumping/Falling/Stationary
935 //
936 
937 int
InitRipper2Hang(short SpriteNum)938 InitRipper2Hang(short SpriteNum)
939 {
940     SPRITEp sp = &sprite[SpriteNum];
941     USERp u = User[SpriteNum];
942     int dist;
943 
944     hitdata_t hitinfo = { { 0, 0, 0 }, -2, 0, -2 };
945 
946     SWBOOL Found = FALSE;
947     short dang, tang;
948 
949     for (dang = 0; dang < 2048; dang += 128)
950     {
951         tang = NORM_ANGLE(sp->ang + dang);
952 
953         FAFhitscan(sp->x, sp->y, sp->z - SPRITEp_SIZE_Z(sp), sp->sectnum,  // Start position
954                    sintable[NORM_ANGLE(tang + 512)],   // X vector of 3D ang
955                    sintable[tang],             // Y vector of 3D ang
956                    0,                          // Z vector of 3D ang
957                    &hitinfo, CLIPMASK_MISSILE);
958 
959         if (hitinfo.sect < 0)
960             continue;
961 
962         dist = Distance(sp->x, sp->y, hitinfo.pos.x, hitinfo.pos.y);
963 
964         if (hitinfo.wall < 0 || dist < 2000 || dist > 7000)
965         {
966             continue;
967         }
968 
969         Found = TRUE;
970         sp->ang = tang;
971         break;
972     }
973 
974     if (!Found)
975     {
976         InitActorDecide(SpriteNum);
977         return 0;
978     }
979 
980     NewStateGroup(SpriteNum, sg_Ripper2HangJump);
981     u->StateFallOverride = sg_Ripper2HangFall;
982     DoActorSetSpeed(SpriteNum, FAST_SPEED);
983 
984     //u->jump_speed = -800;
985     PickJumpMaxSpeed(SpriteNum, -(RANDOM_RANGE(400)+100));
986 
987     SET(u->Flags, SPR_JUMPING);
988     RESET(u->Flags, SPR_FALLING);
989 
990     // set up individual actor jump gravity
991     u->jump_grav = 8;
992 
993     DoJump(SpriteNum);
994 
995     return 0;
996 }
997 
998 int
DoRipper2Hang(short SpriteNum)999 DoRipper2Hang(short SpriteNum)
1000 {
1001     USERp u = User[SpriteNum];
1002 
1003     if ((u->WaitTics -= ACTORMOVETICS) > 0)
1004         return 0;
1005 
1006     NewStateGroup(SpriteNum, sg_Ripper2JumpAttack);
1007     // move to the 2nd frame - past the pause frame
1008     u->Tics += u->State->Tics;
1009 
1010     return 0;
1011 }
1012 
1013 int
DoRipper2MoveHang(short SpriteNum)1014 DoRipper2MoveHang(short SpriteNum)
1015 {
1016     SPRITEp sp = &sprite[SpriteNum];
1017     USERp u = User[SpriteNum];
1018     int nx, ny;
1019 
1020     // Move while jumping
1021     nx = sp->xvel * (int) sintable[NORM_ANGLE(sp->ang + 512)] >> 14;
1022     ny = sp->xvel * (int) sintable[sp->ang] >> 14;
1023 
1024     // if cannot move the sprite
1025     if (!move_actor(SpriteNum, nx, ny, 0L))
1026     {
1027         switch (TEST(u->ret, HIT_MASK))
1028         {
1029         case HIT_WALL:
1030         {
1031             short hit_wall;
1032             short w, nw;
1033 
1034             // Don't keep clinging and going ever higher!
1035             if (abs(sp->z - u->tgt_sp->z) > (4000<<4))
1036                 break;
1037 
1038             hit_wall = NORM_WALL(u->ret);
1039 
1040             NewStateGroup(SpriteNum, u->ActorActionSet->Special[1]);
1041             if (RANDOM_P2(1024<<8)>>8 > 500)
1042                 u->WaitTics = ((RANDOM_P2(2 << 8) >> 8) * 120);
1043             else
1044                 u->WaitTics = 0; // Double jump
1045 
1046             // hang flush with the wall
1047             w = hit_wall;
1048             nw = wall[w].point2;
1049             sp->ang = NORM_ANGLE(getangle(wall[nw].x - wall[w].x, wall[nw].y - wall[w].y) - 512);
1050 
1051             return 0;
1052         }
1053         }
1054     }
1055 
1056     return 0;
1057 }
1058 
1059 
1060 int
DoRipper2HangJF(short SpriteNum)1061 DoRipper2HangJF(short SpriteNum)
1062 {
1063     USERp u = User[SpriteNum];
1064 
1065     if (TEST(u->Flags, SPR_JUMPING | SPR_FALLING))
1066     {
1067         if (TEST(u->Flags, SPR_JUMPING))
1068             DoJump(SpriteNum);
1069         else
1070             DoFall(SpriteNum);
1071     }
1072 
1073     if (!TEST(u->Flags, SPR_JUMPING | SPR_FALLING))
1074     {
1075         if (DoRipper2QuickJump(SpriteNum))
1076             return 0;
1077 
1078         InitActorDecide(SpriteNum);
1079     }
1080 
1081     DoRipper2MoveHang(SpriteNum);
1082 
1083     return 0;
1084 
1085 }
1086 
1087 //
1088 // JUMP ATTACK
1089 //
1090 
1091 int
DoRipper2BeginJumpAttack(short SpriteNum)1092 DoRipper2BeginJumpAttack(short SpriteNum)
1093 {
1094     SPRITEp sp = &sprite[SpriteNum];
1095     USERp u = User[SpriteNum];
1096     SPRITEp psp = User[SpriteNum]->tgt_sp;
1097     int CanSeePlayer(short SpriteNum);
1098     short tang;
1099 
1100     tang = getangle(psp->x - sp->x, psp->y - sp->y);
1101 
1102     // Always jump at player if mad.
1103     //if(u->speed < FAST_SPEED)
1104     //{
1105     if (move_sprite(SpriteNum, sintable[NORM_ANGLE(tang+512)] >> 7, sintable[tang] >> 7,
1106                     0L, u->ceiling_dist, u->floor_dist, CLIPMASK_ACTOR, ACTORMOVETICS))
1107         sp->ang = NORM_ANGLE((sp->ang + 1024) + (RANDOM_NEG(256, 6) >> 6));
1108     else
1109         sp->ang = NORM_ANGLE(tang);
1110     //    sp->ang = NORM_ANGLE(tang + (RANDOM_NEG(256, 6) >> 6));
1111     //} else
1112     //    sp->ang = NORM_ANGLE(tang);
1113 
1114 
1115     DoActorSetSpeed(SpriteNum, FAST_SPEED);
1116 
1117     //u->jump_speed = -800;
1118     PickJumpMaxSpeed(SpriteNum, -(RANDOM_RANGE(400)+100));
1119 
1120     SET(u->Flags, SPR_JUMPING);
1121     RESET(u->Flags, SPR_FALLING);
1122 
1123     // set up individual actor jump gravity
1124     u->jump_grav = 8;
1125 
1126     // if I didn't do this here they get stuck in the air sometimes
1127     DoActorZrange(SpriteNum);
1128 
1129     DoJump(SpriteNum);
1130 
1131     return 0;
1132 }
1133 
1134 int
DoRipper2MoveJump(short SpriteNum)1135 DoRipper2MoveJump(short SpriteNum)
1136 {
1137     USERp u = User[SpriteNum];
1138 
1139     if (TEST(u->Flags, SPR_JUMPING | SPR_FALLING))
1140     {
1141         if (TEST(u->Flags, SPR_JUMPING))
1142             DoJump(SpriteNum);
1143         else
1144             DoFall(SpriteNum);
1145     }
1146 
1147     if (!TEST(u->Flags, SPR_JUMPING | SPR_FALLING))
1148     {
1149         if (DoRipper2QuickJump(SpriteNum))
1150             return 0;
1151 
1152         InitActorDecide(SpriteNum);
1153     }
1154 
1155     DoRipper2MoveHang(SpriteNum);
1156     return 0;
1157 }
1158 
1159 //
1160 // STD MOVEMENT
1161 //
1162 
1163 int
DoRipper2QuickJump(short SpriteNum)1164 DoRipper2QuickJump(short SpriteNum)
1165 {
1166     USERp u = User[SpriteNum];
1167 
1168     // Tests to see if ripper2 is on top of a player/enemy and then immediatly
1169     // does another jump
1170 
1171     if (u->lo_sp)
1172     {
1173         SPRITEp tsp = u->lo_sp;
1174 
1175         if (TEST(tsp->extra, SPRX_PLAYER_OR_ENEMY))
1176         {
1177             NewStateGroup(SpriteNum, sg_Ripper2JumpAttack);
1178             // move past the first state
1179             u->Tics = 30;
1180             return TRUE;
1181         }
1182     }
1183 
1184     return FALSE;
1185 }
1186 
1187 
1188 int
NullRipper2(short SpriteNum)1189 NullRipper2(short SpriteNum)
1190 {
1191     USERp u = User[SpriteNum];
1192 
1193     if (TEST(u->Flags,SPR_SLIDING))
1194         DoActorSlide(SpriteNum);
1195 
1196     DoActorSectorDamage(SpriteNum);
1197 
1198     return 0;
1199 }
1200 
1201 
DoRipper2Pain(short SpriteNum)1202 int DoRipper2Pain(short SpriteNum)
1203 {
1204     USERp u = User[SpriteNum];
1205 
1206     NullRipper2(SpriteNum);
1207 
1208     if ((u->WaitTics -= ACTORMOVETICS) <= 0)
1209         InitActorDecide(SpriteNum);
1210     return 0;
1211 }
1212 
1213 
DoRipper2RipHeart(short SpriteNum)1214 int DoRipper2RipHeart(short SpriteNum)
1215 {
1216     SPRITEp sp = &sprite[SpriteNum];
1217     USERp u = User[SpriteNum];
1218 
1219     SPRITEp tsp = u->tgt_sp;
1220 
1221     NewStateGroup(SpriteNum, sg_Ripper2Heart);
1222     u->WaitTics = 6 * 120;
1223 
1224     // player face ripper2
1225     tsp->ang = getangle(sp->x - tsp->x, sp->y - tsp->y);
1226     return 0;
1227 }
1228 
DoRipper2StandHeart(short SpriteNum)1229 int DoRipper2StandHeart(short SpriteNum)
1230 {
1231     SPRITEp sp = &sprite[SpriteNum];
1232     USERp u = User[SpriteNum];
1233     static int riphearthandle;
1234 
1235     NullRipper2(SpriteNum);
1236 
1237     if (!FX_SoundValidAndActive(riphearthandle))
1238         riphearthandle = PlaySound(DIGI_RIPPER2HEARTOUT,&sp->x,&sp->y,&sp->z,v3df_none);
1239 
1240     if ((u->WaitTics -= ACTORMOVETICS) <= 0)
1241         NewStateGroup(SpriteNum, sg_Ripper2Run);
1242     return 0;
1243 }
1244 
Ripper2Hatch(short Weapon)1245 void Ripper2Hatch(short Weapon)
1246 {
1247     SPRITEp wp = &sprite[Weapon];
1248 
1249     short New,i;
1250     SPRITEp np;
1251     USERp nu;
1252 #define MAX_RIPPER2S 1
1253     short rip_ang[MAX_RIPPER2S];
1254 
1255     rip_ang[0] = RANDOM_P2(2048);
1256 #if MAX_RIPPER2S > 1
1257     rip_ang[1] = NORM_ANGLE(rip_ang[0] + 1024 + (RANDOM_P2(512) - 256));
1258 #endif
1259 
1260     for (i = 0; i < MAX_RIPPER2S; i++)
1261     {
1262         New = COVERinsertsprite(wp->sectnum, STAT_DEFAULT);
1263         np = &sprite[New];
1264         memset(np,0,sizeof(SPRITE));
1265         np->sectnum = wp->sectnum;
1266         np->statnum = STAT_DEFAULT;
1267         np->x = wp->x;
1268         np->y = wp->y;
1269         np->z = wp->z;
1270         np->owner = -1;
1271         //np->xrepeat = np->yrepeat = 36;
1272         np->xrepeat = np->yrepeat = 64;
1273         np->ang = rip_ang[i];
1274         np->pal = 0;
1275         np->shade = -10;
1276         SetupRipper2(New);
1277         nu = User[New];
1278 
1279         // make immediately active
1280         SET(nu->Flags, SPR_ACTIVE);
1281 
1282         NewStateGroup(New, nu->ActorActionSet->Jump);
1283         nu->ActorActionFunc = DoActorMoveJump;
1284         DoActorSetSpeed(New, FAST_SPEED);
1285         PickJumpMaxSpeed(New, -600);
1286 
1287         SET(nu->Flags, SPR_JUMPING);
1288         RESET(nu->Flags, SPR_FALLING);
1289 
1290         nu->jump_grav = 8;
1291 
1292         // if I didn't do this here they get stuck in the air sometimes
1293         DoActorZrange(New);
1294 
1295         DoJump(New);
1296     }
1297 }
1298 
1299 int
DoRipper2Move(short SpriteNum)1300 DoRipper2Move(short SpriteNum)
1301 {
1302     SPRITEp sp = &sprite[SpriteNum];
1303     USERp u = User[SpriteNum];
1304     int DoCheckSwarm(short SpriteNum);
1305 
1306     if (sp->hitag == TAG_SWARMSPOT && sp->lotag == 1)
1307         DoCheckSwarm(SpriteNum);
1308 
1309     if (u->scale_speed)
1310     {
1311         DoScaleSprite(SpriteNum);
1312     }
1313 
1314     if (TEST(u->Flags, SPR_JUMPING | SPR_FALLING))
1315     {
1316         if (TEST(u->Flags, SPR_JUMPING))
1317             DoJump(SpriteNum);
1318         else
1319             DoFall(SpriteNum);
1320     }
1321 
1322     // if on a player/enemy sprite jump quickly
1323     if (!TEST(u->Flags, SPR_JUMPING | SPR_FALLING))
1324     {
1325         if (DoRipper2QuickJump(SpriteNum))
1326             return 0;
1327 
1328         KeepActorOnFloor(SpriteNum);
1329     }
1330 
1331     if (TEST(u->Flags, SPR_SLIDING))
1332         DoActorSlide(SpriteNum);
1333 
1334     if (u->track >= 0)
1335         ActorFollowTrack(SpriteNum, ACTORMOVETICS);
1336     else
1337         (*u->ActorActionFunc)(SpriteNum);
1338 
1339     DoActorSectorDamage(SpriteNum);
1340 
1341     return 0;
1342 }
1343 
1344 
InitRipper2Charge(short SpriteNum)1345 int InitRipper2Charge(short SpriteNum)
1346 {
1347     DoActorSetSpeed(SpriteNum, FAST_SPEED);
1348 
1349     InitActorMoveCloser(SpriteNum);
1350 
1351     NewStateGroup(SpriteNum, sg_Ripper2RunFast);
1352 
1353     return 0;
1354 }
1355 
ChestRipper2(short SpriteNum)1356 int ChestRipper2(short SpriteNum)
1357 {
1358     SPRITEp sp = &sprite[SpriteNum];
1359 
1360     PlaySound(DIGI_RIPPER2CHEST,&sp->x,&sp->y,&sp->z,v3df_follow);
1361 
1362     return 0;
1363 }
1364 
1365 
1366 #include "saveable.h"
1367 
1368 static saveable_code saveable_ripper2_code[] =
1369 {
1370     SAVE_CODE(SetupRipper2),
1371 
1372     SAVE_CODE(InitRipper2Hang),
1373     SAVE_CODE(DoRipper2Hang),
1374     SAVE_CODE(DoRipper2MoveHang),
1375     SAVE_CODE(DoRipper2HangJF),
1376 
1377     SAVE_CODE(DoRipper2BeginJumpAttack),
1378     SAVE_CODE(DoRipper2MoveJump),
1379     SAVE_CODE(DoRipper2QuickJump),
1380     SAVE_CODE(NullRipper2),
1381     SAVE_CODE(DoRipper2Pain),
1382     SAVE_CODE(DoRipper2RipHeart),
1383     SAVE_CODE(DoRipper2StandHeart),
1384     SAVE_CODE(Ripper2Hatch),
1385     SAVE_CODE(DoRipper2Move),
1386     SAVE_CODE(InitRipper2Charge),
1387     SAVE_CODE(ChestRipper2),
1388 };
1389 
1390 static saveable_data saveable_ripper2_data[] =
1391 {
1392     SAVE_DATA(Ripper2Battle),
1393     SAVE_DATA(Ripper2Offense),
1394     SAVE_DATA(Ripper2Broadcast),
1395     SAVE_DATA(Ripper2Surprised),
1396     SAVE_DATA(Ripper2Evasive),
1397     SAVE_DATA(Ripper2LostTarget),
1398     SAVE_DATA(Ripper2CloseRange),
1399 
1400     SAVE_DATA(Ripper2Personality),
1401 
1402     SAVE_DATA(Ripper2Attrib),
1403 
1404     SAVE_DATA(s_Ripper2Run),
1405     SAVE_DATA(sg_Ripper2Run),
1406     SAVE_DATA(s_Ripper2RunFast),
1407     SAVE_DATA(sg_Ripper2RunFast),
1408     SAVE_DATA(s_Ripper2Stand),
1409     SAVE_DATA(sg_Ripper2Stand),
1410     SAVE_DATA(s_Ripper2Swipe),
1411     SAVE_DATA(sg_Ripper2Swipe),
1412     SAVE_DATA(s_Ripper2Kong),
1413     SAVE_DATA(sg_Ripper2Kong),
1414     SAVE_DATA(s_Ripper2Heart),
1415     SAVE_DATA(sg_Ripper2Heart),
1416     SAVE_DATA(s_Ripper2Hang),
1417     SAVE_DATA(sg_Ripper2Hang),
1418     SAVE_DATA(s_Ripper2Pain),
1419     SAVE_DATA(sg_Ripper2Pain),
1420     SAVE_DATA(s_Ripper2Jump),
1421     SAVE_DATA(sg_Ripper2Jump),
1422     SAVE_DATA(s_Ripper2Fall),
1423     SAVE_DATA(sg_Ripper2Fall),
1424     SAVE_DATA(s_Ripper2JumpAttack),
1425     SAVE_DATA(sg_Ripper2JumpAttack),
1426     SAVE_DATA(s_Ripper2HangJump),
1427     SAVE_DATA(sg_Ripper2HangJump),
1428     SAVE_DATA(s_Ripper2HangFall),
1429     SAVE_DATA(sg_Ripper2HangFall),
1430     SAVE_DATA(s_Ripper2Die),
1431     SAVE_DATA(s_Ripper2Dead),
1432     SAVE_DATA(sg_Ripper2Die),
1433     SAVE_DATA(sg_Ripper2Dead),
1434     SAVE_DATA(s_Ripper2DeathJump),
1435     SAVE_DATA(s_Ripper2DeathFall),
1436     SAVE_DATA(sg_Ripper2DeathJump),
1437     SAVE_DATA(sg_Ripper2DeathFall),
1438 
1439     SAVE_DATA(Ripper2ActionSet),
1440     SAVE_DATA(Ripper2BrownActionSet),
1441 };
1442 
1443 saveable_module saveable_ripper2 =
1444 {
1445     // code
1446     saveable_ripper2_code,
1447     SIZ(saveable_ripper2_code),
1448 
1449     // data
1450     saveable_ripper2_data,
1451     SIZ(saveable_ripper2_data)
1452 };
1453