Subversion Repositories eduke32

Rev

Rev 8685 | 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
    USERp u = User[SpriteNum];
884
 
885
    //ASSERT(pix_height < 128);
886
 
887
    u->jump_speed = -600;
888
    u->jump_grav = 8;
889
 
890
    while (TRUE)
891
    {
892
        if (GetJumpHeight(u->jump_speed, u->jump_grav) > pix_height + 20)
893
            break;
894
 
895
        u->jump_speed -= 100;
896
 
897
        ASSERT(u->jump_speed > -3000);
898
    }
899
 
900
    return u->jump_speed;
901
}
902
 
903
 
904
int
905
PickJumpMaxSpeed(short SpriteNum, short max_speed)
906
{
907
    SPRITEp sp = &sprite[SpriteNum];
908
    USERp u = User[SpriteNum];
909
    int zh;
910
 
911
    ASSERT(max_speed < 0);
912
 
913
    u->jump_speed = max_speed;
914
    u->jump_grav = 8;
915
 
916
    zh = SPRITEp_TOS(sp);
917
 
918
    while (TRUE)
919
    {
920
        if (zh - Z(GetJumpHeight(u->jump_speed, u->jump_grav)) - Z(16) > u->hiz)
921
            break;
922
 
923
        u->jump_speed += 100;
924
 
925
        if (u->jump_speed > -200)
926
            break;
927
    }
928
 
929
    return u->jump_speed;
930
}
931
 
932
 
933
//
934
// HANGING - Jumping/Falling/Stationary
935
//
936
 
937
int
938
InitRipperHang(short SpriteNum)
939
{
940
    SPRITEp sp = &sprite[SpriteNum];
941
    USERp u = User[SpriteNum];
942
    int dist;
943
 
5202 hendricks2 944
    hitdata_t hitinfo = { { 0, 0, 0 }, -2, 0, -2 };
5196 hendricks2 945
 
5198 hendricks2 946
    SWBOOL Found = FALSE;
5196 hendricks2 947
    short dang, tang;
948
 
949
    for (dang = 0; dang < 2048; dang += 128)
950
    {
951
        tang = NORM_ANGLE(sp->ang + dang);
952
 
953
        FAFhitscan(sp->x, sp->y, sp->z - SPRITEp_SIZE_Z(sp), sp->sectnum,  // Start position
954
                   sintable[NORM_ANGLE(tang + 512)],   // X vector of 3D ang
955
                   sintable[tang],             // Y vector of 3D ang
956
                   0,                          // Z vector of 3D ang
5202 hendricks2 957
                   &hitinfo, CLIPMASK_MISSILE);
5196 hendricks2 958
 
5202 hendricks2 959
        //ASSERT(hitinfo.sect >= 0);
960
        if (hitinfo.sect < 0)
5196 hendricks2 961
            continue;
962
 
5202 hendricks2 963
        dist = Distance(sp->x, sp->y, hitinfo.pos.x, hitinfo.pos.y);
5196 hendricks2 964
 
5202 hendricks2 965
        if (hitinfo.wall < 0 || dist < 2000 || dist > 7000)
5196 hendricks2 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_RipperHangJump);
982
    u->StateFallOverride = sg_RipperHangFall;
983
    DoActorSetSpeed(SpriteNum, FAST_SPEED);
984
 
985
    //u->jump_speed = -800;
986
    PickJumpMaxSpeed(SpriteNum, -800);
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
1000
DoRipperHang(short SpriteNum)
1001
{
1002
    USERp u = User[SpriteNum];
1003
 
1004
    if ((u->WaitTics -= ACTORMOVETICS) > 0)
1005
        return 0;
1006
 
1007
    NewStateGroup(SpriteNum, sg_RipperJumpAttack);
1008
    // move to the 2nd frame - past the pause frame
1009
    u->Tics += u->State->Tics;
1010
    return 0;
1011
}
1012
 
1013
int
1014
DoRipperMoveHang(short SpriteNum)
1015
{
1016
    SPRITEp sp = &sprite[SpriteNum];
1017
    USERp u = User[SpriteNum];
1018
    int nx, ny;
1019
 
1020
    // Move while jumping
1021
    nx = sp->xvel * (int) sintable[NORM_ANGLE(sp->ang + 512)] >> 14;
1022
    ny = sp->xvel * (int) sintable[sp->ang] >> 14;
1023
 
1024
    // if cannot move the sprite
1025
    if (!move_actor(SpriteNum, nx, ny, 0L))
1026
    {
1027
        switch (TEST(u->ret, HIT_MASK))
1028
        {
1029
        case HIT_WALL:
1030
        {
5202 hendricks2 1031
            short hit_wall;
5196 hendricks2 1032
            short w, nw;
1033
 
5202 hendricks2 1034
            hit_wall = NORM_WALL(u->ret);
5196 hendricks2 1035
 
1036
            NewStateGroup(SpriteNum, u->ActorActionSet->Special[1]);
1037
            u->WaitTics = 2 + ((RANDOM_P2(4 << 8) >> 8) * 120);
1038
 
1039
            // hang flush with the wall
5202 hendricks2 1040
            w = hit_wall;
5196 hendricks2 1041
            nw = wall[w].point2;
1042
            sp->ang = NORM_ANGLE(getangle(wall[nw].x - wall[w].x, wall[nw].y - wall[w].y) - 512);
1043
 
1044
            return 0;
1045
        }
1046
        }
1047
    }
1048
 
1049
    return 0;
1050
}
1051
 
1052
 
1053
int
1054
DoRipperHangJF(short SpriteNum)
1055
{
1056
    USERp u = User[SpriteNum];
1057
 
1058
    if (TEST(u->Flags, SPR_JUMPING | SPR_FALLING))
1059
    {
1060
        if (TEST(u->Flags, SPR_JUMPING))
1061
            DoJump(SpriteNum);
1062
        else
1063
            DoFall(SpriteNum);
1064
    }
1065
 
1066
    if (!TEST(u->Flags, SPR_JUMPING | SPR_FALLING))
1067
    {
1068
        if (DoRipperQuickJump(SpriteNum))
1069
            return 0;
1070
 
1071
        InitActorDecide(SpriteNum);
1072
    }
1073
 
1074
    DoRipperMoveHang(SpriteNum);
1075
 
1076
    return 0;
1077
 
1078
}
1079
 
1080
//
1081
// JUMP ATTACK
1082
//
1083
 
1084
int
1085
DoRipperBeginJumpAttack(short SpriteNum)
1086
{
1087
    SPRITEp sp = &sprite[SpriteNum];
1088
    USERp u = User[SpriteNum];
1089
    SPRITEp psp = User[SpriteNum]->tgt_sp;
1090
    int CanSeePlayer(short SpriteNum);
1091
    short tang;
1092
 
1093
    tang = getangle(psp->x - sp->x, psp->y - sp->y);
1094
 
1095
    if (move_sprite(SpriteNum, sintable[NORM_ANGLE(tang+512)] >> 7, sintable[tang] >> 7,
1096
                    0L, u->ceiling_dist, u->floor_dist, CLIPMASK_ACTOR, ACTORMOVETICS))
8798 ny00123 1097
        sp->ang = NORM_ANGLE((sp->ang + 1024) + (RANDOM_NEG(256, 6) >> 6));
5196 hendricks2 1098
    else
8798 ny00123 1099
        sp->ang = NORM_ANGLE(tang + (RANDOM_NEG(256, 6) >> 6));
5196 hendricks2 1100
 
1101
    DoActorSetSpeed(SpriteNum, FAST_SPEED);
1102
 
1103
    //u->jump_speed = -800;
1104
    PickJumpMaxSpeed(SpriteNum, -400); // was -800
1105
 
1106
    SET(u->Flags, SPR_JUMPING);
1107
    RESET(u->Flags, SPR_FALLING);
1108
 
1109
    // set up individual actor jump gravity
1110
    u->jump_grav = 17; // was 8
1111
 
1112
    // if I didn't do this here they get stuck in the air sometimes
1113
    DoActorZrange(SpriteNum);
1114
 
1115
    DoJump(SpriteNum);
1116
 
1117
    return 0;
1118
}
1119
 
1120
int
1121
DoRipperMoveJump(short SpriteNum)
1122
{
1123
    USERp u = User[SpriteNum];
1124
 
1125
    if (TEST(u->Flags, SPR_JUMPING | SPR_FALLING))
1126
    {
1127
        if (TEST(u->Flags, SPR_JUMPING))
1128
            DoJump(SpriteNum);
1129
        else
1130
            DoFall(SpriteNum);
1131
    }
1132
 
1133
    if (!TEST(u->Flags, SPR_JUMPING | SPR_FALLING))
1134
    {
1135
        if (DoRipperQuickJump(SpriteNum))
1136
            return 0;
1137
 
1138
        InitActorDecide(SpriteNum);
1139
    }
1140
 
1141
    DoRipperMoveHang(SpriteNum);
1142
    return 0;
1143
}
1144
 
1145
//
1146
// STD MOVEMENT
1147
//
1148
 
1149
int
1150
DoRipperQuickJump(short SpriteNum)
1151
{
1152
    USERp u = User[SpriteNum];
1153
 
1154
    // Tests to see if ripper is on top of a player/enemy and then immediatly
1155
    // does another jump
1156
 
1157
    if (u->lo_sp)
1158
    {
1159
        SPRITEp tsp = u->lo_sp;
1160
 
1161
        if (TEST(tsp->extra, SPRX_PLAYER_OR_ENEMY))
1162
        {
1163
            NewStateGroup(SpriteNum, sg_RipperJumpAttack);
1164
            // move past the first state
1165
            u->Tics = 30;
1166
            return TRUE;
1167
        }
1168
    }
1169
 
1170
    return FALSE;
1171
}
1172
 
1173
 
1174
int
1175
NullRipper(short SpriteNum)
1176
{
1177
    USERp u = User[SpriteNum];
1178
 
1179
    if (TEST(u->Flags,SPR_SLIDING))
1180
        DoActorSlide(SpriteNum);
1181
 
1182
    DoActorSectorDamage(SpriteNum);
1183
 
1184
    return 0;
1185
}
1186
 
1187
 
1188
int DoRipperPain(short SpriteNum)
1189
{
1190
    USERp u = User[SpriteNum];
1191
 
1192
    NullRipper(SpriteNum);
1193
 
1194
    if ((u->WaitTics -= ACTORMOVETICS) <= 0)
1195
        InitActorDecide(SpriteNum);
1196
    return 0;
1197
}
1198
 
1199
 
1200
// CTW MODIFICATION
1201
//int DoRipperRipHeart(SpriteNum)
1202
int DoRipperRipHeart(short SpriteNum)
1203
// CTW MODIFICATION END
1204
{
1205
    SPRITEp sp = &sprite[SpriteNum];
1206
    USERp u = User[SpriteNum];
1207
 
1208
    SPRITEp tsp = u->tgt_sp;
1209
 
1210
    NewStateGroup(SpriteNum, sg_RipperHeart);
1211
    u->WaitTics = 6 * 120;
1212
 
1213
    // player face ripper
1214
    tsp->ang = getangle(sp->x - tsp->x, sp->y - tsp->y);
1215
    return 0;
1216
}
1217
 
1218
// CTW MODIFICATION
1219
//int DoRipperStandHeart(SpriteNum)
1220
int DoRipperStandHeart(short SpriteNum)
1221
// CTW MODIFICATION END
1222
{
1223
    USERp u = User[SpriteNum];
1224
 
1225
    NullRipper(SpriteNum);
1226
 
1227
    if ((u->WaitTics -= ACTORMOVETICS) <= 0)
1228
        NewStateGroup(SpriteNum, sg_RipperRun);
1229
    return 0;
1230
}
1231
 
1232
void RipperHatch(short Weapon)
1233
{
1234
    SPRITEp wp = &sprite[Weapon];
1235
 
6048 hendricks2 1236
    short New,i;
5196 hendricks2 1237
    SPRITEp np;
1238
    USERp nu;
1239
#define MAX_RIPPERS 1
1240
    short rip_ang[MAX_RIPPERS];
1241
 
1242
    rip_ang[0] = RANDOM_P2(2048);
5228 hendricks2 1243
    // rip_ang[1] = NORM_ANGLE(rip_ang[0] + 1024 + (RANDOM_P2(512) - 256));
5196 hendricks2 1244
 
1245
    for (i = 0; i < MAX_RIPPERS; i++)
1246
    {
6048 hendricks2 1247
        New = COVERinsertsprite(wp->sectnum, STAT_DEFAULT);
1248
        np = &sprite[New];
5196 hendricks2 1249
        memset(np,0,sizeof(SPRITE));
1250
        np->sectnum = wp->sectnum;
1251
        np->statnum = STAT_DEFAULT;
1252
        np->x = wp->x;
1253
        np->y = wp->y;
1254
        np->z = wp->z;
1255
        np->owner = -1;
1256
        //np->xrepeat = np->yrepeat = 36;
1257
        np->xrepeat = np->yrepeat = 64;
1258
        np->ang = rip_ang[i];
1259
        np->pal = 0;
6048 hendricks2 1260
        SetupRipper(New);
1261
        nu = User[New];
5196 hendricks2 1262
 
1263
        // make immediately active
1264
        SET(nu->Flags, SPR_ACTIVE);
1265
 
6048 hendricks2 1266
        NewStateGroup(New, nu->ActorActionSet->Jump);
5196 hendricks2 1267
        nu->ActorActionFunc = DoActorMoveJump;
6048 hendricks2 1268
        DoActorSetSpeed(New, FAST_SPEED);
1269
        PickJumpMaxSpeed(New, -600);
5196 hendricks2 1270
 
1271
        SET(nu->Flags, SPR_JUMPING);
1272
        RESET(nu->Flags, SPR_FALLING);
1273
 
1274
        nu->jump_grav = 8;
1275
 
1276
        // if I didn't do this here they get stuck in the air sometimes
6048 hendricks2 1277
        DoActorZrange(New);
5196 hendricks2 1278
 
6048 hendricks2 1279
        DoJump(New);
5196 hendricks2 1280
    }
1281
}
1282
 
1283
int
1284
DoRipperMove(short SpriteNum)
1285
{
1286
    USERp u = User[SpriteNum];
1287
 
1288
    if (u->scale_speed)
1289
    {
1290
        DoScaleSprite(SpriteNum);
1291
    }
1292
 
1293
    if (TEST(u->Flags, SPR_JUMPING | SPR_FALLING))
1294
    {
1295
        if (TEST(u->Flags, SPR_JUMPING))
1296
            DoJump(SpriteNum);
1297
        else
1298
            DoFall(SpriteNum);
1299
    }
1300
 
1301
    // if on a player/enemy sprite jump quickly
1302
    if (!TEST(u->Flags, SPR_JUMPING | SPR_FALLING))
1303
    {
1304
        if (DoRipperQuickJump(SpriteNum))
1305
            return 0;
1306
 
1307
        KeepActorOnFloor(SpriteNum);
1308
    }
1309
 
1310
    if (TEST(u->Flags, SPR_SLIDING))
1311
        DoActorSlide(SpriteNum);
1312
 
1313
    if (u->track >= 0)
1314
        ActorFollowTrack(SpriteNum, ACTORMOVETICS);
1315
    else
1316
        (*u->ActorActionFunc)(SpriteNum);
1317
 
1318
    DoActorSectorDamage(SpriteNum);
1319
    return 0;
1320
}
1321
 
1322
 
1323
#include "saveable.h"
1324
 
1325
static saveable_code saveable_ripper_code[] =
1326
{
1327
    SAVE_CODE(SetupRipper),
1328
    SAVE_CODE(GetJumpHeight),
1329
    SAVE_CODE(PickJumpSpeed),
1330
    SAVE_CODE(PickJumpMaxSpeed),
1331
 
1332
    SAVE_CODE(InitRipperHang),
1333
    SAVE_CODE(DoRipperHang),
1334
    SAVE_CODE(DoRipperMoveHang),
1335
    SAVE_CODE(DoRipperHangJF),
1336
 
1337
    SAVE_CODE(DoRipperBeginJumpAttack),
1338
    SAVE_CODE(DoRipperMoveJump),
1339
 
1340
    SAVE_CODE(DoRipperQuickJump),
1341
    SAVE_CODE(NullRipper),
1342
    SAVE_CODE(DoRipperPain),
1343
    SAVE_CODE(DoRipperRipHeart),
1344
    SAVE_CODE(DoRipperStandHeart),
1345
    SAVE_CODE(RipperHatch),
1346
    SAVE_CODE(DoRipperMove),
1347
};
1348
 
1349
static saveable_data saveable_ripper_data[] =
1350
{
1351
    SAVE_DATA(RipperBattle),
1352
    SAVE_DATA(RipperOffense),
1353
    SAVE_DATA(RipperBroadcast),
1354
    SAVE_DATA(RipperSurprised),
1355
    SAVE_DATA(RipperEvasive),
1356
    SAVE_DATA(RipperLostTarget),
1357
    SAVE_DATA(RipperCloseRange),
1358
 
1359
    SAVE_DATA(RipperPersonality),
1360
 
1361
    SAVE_DATA(RipperAttrib),
1362
 
1363
    SAVE_DATA(s_RipperRun),
1364
    SAVE_DATA(sg_RipperRun),
1365
    SAVE_DATA(s_RipperStand),
1366
    SAVE_DATA(sg_RipperStand),
1367
    SAVE_DATA(s_RipperSwipe),
1368
    SAVE_DATA(sg_RipperSwipe),
1369
    SAVE_DATA(s_RipperSpew),
1370
    SAVE_DATA(sg_RipperSpew),
1371
    SAVE_DATA(s_RipperHeart),
1372
    SAVE_DATA(sg_RipperHeart),
1373
    SAVE_DATA(s_RipperHang),
1374
    SAVE_DATA(sg_RipperHang),
1375
    SAVE_DATA(s_RipperPain),
1376
    SAVE_DATA(sg_RipperPain),
1377
    SAVE_DATA(s_RipperJump),
1378
    SAVE_DATA(sg_RipperJump),
1379
    SAVE_DATA(s_RipperFall),
1380
    SAVE_DATA(sg_RipperFall),
1381
    SAVE_DATA(s_RipperJumpAttack),
1382
    SAVE_DATA(sg_RipperJumpAttack),
1383
    SAVE_DATA(s_RipperHangJump),
1384
    SAVE_DATA(sg_RipperHangJump),
1385
    SAVE_DATA(s_RipperHangFall),
1386
    SAVE_DATA(sg_RipperHangFall),
1387
    SAVE_DATA(s_RipperDie),
1388
    SAVE_DATA(s_RipperDead),
1389
    SAVE_DATA(sg_RipperDie),
1390
    SAVE_DATA(sg_RipperDead),
1391
    SAVE_DATA(s_RipperDeathJump),
1392
    SAVE_DATA(s_RipperDeathFall),
1393
    SAVE_DATA(sg_RipperDeathJump),
1394
    SAVE_DATA(sg_RipperDeathFall),
1395
 
1396
    SAVE_DATA(RipperActionSet),
1397
    SAVE_DATA(RipperBrownActionSet),
1398
};
1399
 
1400
saveable_module saveable_ripper =
1401
{
1402
    // code
1403
    saveable_ripper_code,
1404
    SIZ(saveable_ripper_code),
1405
 
1406
    // data
1407
    saveable_ripper_data,
1408
    SIZ(saveable_ripper_data)
1409
};