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