Subversion Repositories eduke32

Rev

Rev 5198 | Rev 5228 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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