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 "sprite.h"
36 #include "actor.h"
37 #include "weapon.h"
38 #include "track.h"
39
40 short Bunny_Count = 0;
41 ANIMATOR DoActorMoveJump;
42 ANIMATOR DoBunnyMoveJump;
43 ANIMATOR DoBunnyQuickJump;
44
45 DECISION BunnyBattle[] =
46 {
47 {748, InitActorMoveCloser},
48 {750, InitActorAlertNoise},
49 {760, InitActorAttackNoise},
50 {1024, InitActorMoveCloser}
51 };
52
53 DECISION BunnyOffense[] =
54 {
55 {600, InitActorMoveCloser},
56 {700, InitActorAlertNoise},
57 {1024, InitActorMoveCloser}
58 };
59
60 DECISION BunnyBroadcast[] =
61 {
62 {21, InitActorAlertNoise},
63 {51, InitActorAmbientNoise},
64 {1024, InitActorDecide}
65 };
66
67 DECISION BunnySurprised[] =
68 {
69 {500, InitActorRunAway},
70 {701, InitActorMoveCloser},
71 {1024, InitActorDecide}
72 };
73
74 DECISION BunnyEvasive[] =
75 {
76 {500, InitActorWanderAround},
77 {1020, InitActorRunAway},
78 {1024, InitActorAmbientNoise}
79 };
80
81 DECISION BunnyLostTarget[] =
82 {
83 {900, InitActorFindPlayer},
84 {1024, InitActorWanderAround}
85 };
86
87 DECISION BunnyCloseRange[] =
88 {
89 {1024, InitActorAttack },
90 // {1024, InitActorReposition }
91 };
92
93 DECISION BunnyWander[] =
94 {
95 {1024, InitActorReposition}
96 };
97
98 PERSONALITY WhiteBunnyPersonality =
99 {
100 BunnyBattle,
101 BunnyOffense,
102 BunnyBroadcast,
103 BunnySurprised,
104 BunnyEvasive,
105 BunnyLostTarget,
106 BunnyCloseRange,
107 BunnyCloseRange
108 };
109
110 PERSONALITY BunnyPersonality =
111 {
112 BunnyEvasive,
113 BunnyEvasive,
114 BunnyEvasive,
115 BunnyWander,
116 BunnyWander,
117 BunnyWander,
118 BunnyEvasive,
119 BunnyEvasive
120 };
121
122 ATTRIBUTE BunnyAttrib =
123 {
124 {100, 120, 140, 180}, // Speeds
125 {5, 0, -2, -4}, // Tic Adjusts
126 3, // MaxWeapons;
127 {
128 DIGI_BUNNYAMBIENT, 0, DIGI_BUNNYATTACK,
129 DIGI_BUNNYATTACK, DIGI_BUNNYDIE2, 0,
130 0,0,0,0
131 }
132 };
133
134 ATTRIBUTE WhiteBunnyAttrib =
135 {
136 {200, 220, 340, 380}, // Speeds
137 {5, 0, -2, -4}, // Tic Adjusts
138 3, // MaxWeapons;
139 {
140 DIGI_BUNNYAMBIENT, 0, DIGI_BUNNYATTACK,
141 DIGI_BUNNYATTACK, DIGI_BUNNYDIE2, 0,
142 0,0,0,0
143 }
144 };
145
146 //////////////////////
147 //
148 // BUNNY RUN
149 //
150 //////////////////////
151
152 #define BUNNY_RUN_RATE 10
153
154 ANIMATOR DoBunnyMove, NullBunny, DoActorDebris, DoBunnyGrowUp;
155
156 STATE s_BunnyRun[5][6] =
157 {
158 {
159 {BUNNY_RUN_R0 + 0, BUNNY_RUN_RATE | SF_TIC_ADJUST, DoBunnyMove, &s_BunnyRun[0][1]},
160 {BUNNY_RUN_R0 + 1, BUNNY_RUN_RATE | SF_TIC_ADJUST, DoBunnyMove, &s_BunnyRun[0][2]},
161 {BUNNY_RUN_R0 + 2, BUNNY_RUN_RATE | SF_TIC_ADJUST, DoBunnyMove, &s_BunnyRun[0][3]},
162 {BUNNY_RUN_R0 + 3, BUNNY_RUN_RATE | SF_TIC_ADJUST, DoBunnyMove, &s_BunnyRun[0][4]},
163 {BUNNY_RUN_R0 + 4, SF_QUICK_CALL, DoBunnyGrowUp, &s_BunnyRun[0][5]},
164 {BUNNY_RUN_R0 + 4, BUNNY_RUN_RATE | SF_TIC_ADJUST, DoBunnyMove, &s_BunnyRun[0][0]},
165 },
166 {
167 {BUNNY_RUN_R1 + 0, BUNNY_RUN_RATE | SF_TIC_ADJUST, DoBunnyMove, &s_BunnyRun[1][1]},
168 {BUNNY_RUN_R1 + 1, BUNNY_RUN_RATE | SF_TIC_ADJUST, DoBunnyMove, &s_BunnyRun[1][2]},
169 {BUNNY_RUN_R1 + 2, BUNNY_RUN_RATE | SF_TIC_ADJUST, DoBunnyMove, &s_BunnyRun[1][3]},
170 {BUNNY_RUN_R1 + 3, BUNNY_RUN_RATE | SF_TIC_ADJUST, DoBunnyMove, &s_BunnyRun[1][4]},
171 {BUNNY_RUN_R1 + 4, SF_QUICK_CALL, DoBunnyGrowUp, &s_BunnyRun[1][5]},
172 {BUNNY_RUN_R1 + 4, BUNNY_RUN_RATE | SF_TIC_ADJUST, DoBunnyMove, &s_BunnyRun[1][0]},
173 },
174 {
175 {BUNNY_RUN_R2 + 0, BUNNY_RUN_RATE | SF_TIC_ADJUST, DoBunnyMove, &s_BunnyRun[2][1]},
176 {BUNNY_RUN_R2 + 1, BUNNY_RUN_RATE | SF_TIC_ADJUST, DoBunnyMove, &s_BunnyRun[2][2]},
177 {BUNNY_RUN_R2 + 2, BUNNY_RUN_RATE | SF_TIC_ADJUST, DoBunnyMove, &s_BunnyRun[2][3]},
178 {BUNNY_RUN_R2 + 3, BUNNY_RUN_RATE | SF_TIC_ADJUST, DoBunnyMove, &s_BunnyRun[2][4]},
179 {BUNNY_RUN_R2 + 4, SF_QUICK_CALL, DoBunnyGrowUp, &s_BunnyRun[2][5]},
180 {BUNNY_RUN_R2 + 4, BUNNY_RUN_RATE | SF_TIC_ADJUST, DoBunnyMove, &s_BunnyRun[2][0]},
181 },
182 {
183 {BUNNY_RUN_R3 + 0, BUNNY_RUN_RATE | SF_TIC_ADJUST, DoBunnyMove, &s_BunnyRun[3][1]},
184 {BUNNY_RUN_R3 + 1, BUNNY_RUN_RATE | SF_TIC_ADJUST, DoBunnyMove, &s_BunnyRun[3][2]},
185 {BUNNY_RUN_R3 + 2, BUNNY_RUN_RATE | SF_TIC_ADJUST, DoBunnyMove, &s_BunnyRun[3][3]},
186 {BUNNY_RUN_R3 + 3, BUNNY_RUN_RATE | SF_TIC_ADJUST, DoBunnyMove, &s_BunnyRun[3][4]},
187 {BUNNY_RUN_R3 + 4, SF_QUICK_CALL, DoBunnyGrowUp, &s_BunnyRun[3][5]},
188 {BUNNY_RUN_R3 + 4, BUNNY_RUN_RATE | SF_TIC_ADJUST, DoBunnyMove, &s_BunnyRun[3][0]},
189 },
190 {
191 {BUNNY_RUN_R4 + 0, BUNNY_RUN_RATE | SF_TIC_ADJUST, DoBunnyMove, &s_BunnyRun[4][1]},
192 {BUNNY_RUN_R4 + 1, BUNNY_RUN_RATE | SF_TIC_ADJUST, DoBunnyMove, &s_BunnyRun[4][2]},
193 {BUNNY_RUN_R4 + 2, BUNNY_RUN_RATE | SF_TIC_ADJUST, DoBunnyMove, &s_BunnyRun[4][3]},
194 {BUNNY_RUN_R4 + 3, BUNNY_RUN_RATE | SF_TIC_ADJUST, DoBunnyMove, &s_BunnyRun[4][4]},
195 {BUNNY_RUN_R4 + 4, SF_QUICK_CALL, DoBunnyGrowUp, &s_BunnyRun[4][5]},
196 {BUNNY_RUN_R4 + 4, BUNNY_RUN_RATE | SF_TIC_ADJUST, DoBunnyMove, &s_BunnyRun[4][0]},
197 }
198 };
199
200
201 STATEp sg_BunnyRun[] =
202 {
203 &s_BunnyRun[0][0],
204 &s_BunnyRun[1][0],
205 &s_BunnyRun[2][0],
206 &s_BunnyRun[3][0],
207 &s_BunnyRun[4][0]
208 };
209
210 //////////////////////
211 //
212 // BUNNY STAND
213 //
214 //////////////////////
215
216 #define BUNNY_STAND_RATE 12
217 ANIMATOR DoBunnyEat;
218
219 STATE s_BunnyStand[5][3] =
220 {
221 {
222 {BUNNY_STAND_R0 + 0, BUNNY_STAND_RATE, DoBunnyEat, &s_BunnyStand[0][1]},
223 {BUNNY_STAND_R0 + 4, SF_QUICK_CALL, DoBunnyGrowUp, &s_BunnyStand[0][2]},
224 {BUNNY_STAND_R0 + 4, BUNNY_STAND_RATE, DoBunnyEat, &s_BunnyStand[0][0]},
225 },
226 {
227 {BUNNY_STAND_R1 + 0, BUNNY_STAND_RATE, DoBunnyEat, &s_BunnyStand[1][1]},
228 {BUNNY_STAND_R1 + 4, SF_QUICK_CALL, DoBunnyGrowUp, &s_BunnyStand[1][2]},
229 {BUNNY_STAND_R1 + 4, BUNNY_STAND_RATE, DoBunnyEat, &s_BunnyStand[1][0]},
230 },
231 {
232 {BUNNY_STAND_R2 + 0, BUNNY_STAND_RATE, DoBunnyEat, &s_BunnyStand[2][1]},
233 {BUNNY_STAND_R2 + 4, SF_QUICK_CALL, DoBunnyGrowUp, &s_BunnyStand[2][2]},
234 {BUNNY_STAND_R2 + 4, BUNNY_STAND_RATE, DoBunnyEat, &s_BunnyStand[2][0]},
235 },
236 {
237 {BUNNY_STAND_R3 + 0, BUNNY_STAND_RATE, DoBunnyEat, &s_BunnyStand[3][1]},
238 {BUNNY_STAND_R3 + 4, SF_QUICK_CALL, DoBunnyGrowUp, &s_BunnyStand[3][2]},
239 {BUNNY_STAND_R3 + 4, BUNNY_STAND_RATE, DoBunnyEat, &s_BunnyStand[3][0]},
240 },
241 {
242 {BUNNY_STAND_R4 + 0, BUNNY_STAND_RATE, DoBunnyEat, &s_BunnyStand[4][1]},
243 {BUNNY_STAND_R4 + 4, SF_QUICK_CALL, DoBunnyGrowUp, &s_BunnyStand[4][2]},
244 {BUNNY_STAND_R4 + 4, BUNNY_STAND_RATE, DoBunnyEat, &s_BunnyStand[4][0]},
245 },
246 };
247
248
249 STATEp sg_BunnyStand[] =
250 {
251 s_BunnyStand[0],
252 s_BunnyStand[1],
253 s_BunnyStand[2],
254 s_BunnyStand[3],
255 s_BunnyStand[4]
256 };
257
258 //////////////////////
259 //
260 // BUNNY GET LAYED
261 //
262 //////////////////////
263
264 #define BUNNY_SCREW_RATE 16
265 ANIMATOR DoBunnyScrew;
266
267 STATE s_BunnyScrew[5][2] =
268 {
269 {
270 {BUNNY_STAND_R0 + 0, BUNNY_SCREW_RATE, DoBunnyScrew, &s_BunnyScrew[0][1]},
271 {BUNNY_STAND_R0 + 2, BUNNY_SCREW_RATE, DoBunnyScrew, &s_BunnyScrew[0][0]},
272 },
273 {
274 {BUNNY_STAND_R1 + 0, BUNNY_SCREW_RATE, DoBunnyScrew, &s_BunnyScrew[1][1]},
275 {BUNNY_STAND_R1 + 2, BUNNY_SCREW_RATE, DoBunnyScrew, &s_BunnyScrew[1][0]},
276 },
277 {
278 {BUNNY_STAND_R2 + 0, BUNNY_SCREW_RATE, DoBunnyScrew, &s_BunnyScrew[2][1]},
279 {BUNNY_STAND_R2 + 2, BUNNY_SCREW_RATE, DoBunnyScrew, &s_BunnyScrew[2][0]},
280 },
281 {
282 {BUNNY_STAND_R3 + 0, BUNNY_SCREW_RATE, DoBunnyScrew, &s_BunnyScrew[3][1]},
283 {BUNNY_STAND_R3 + 2, BUNNY_SCREW_RATE, DoBunnyScrew, &s_BunnyScrew[3][0]},
284 },
285 {
286 {BUNNY_STAND_R4 + 0, BUNNY_SCREW_RATE, DoBunnyScrew, &s_BunnyScrew[4][1]},
287 {BUNNY_STAND_R4 + 2, BUNNY_SCREW_RATE, DoBunnyScrew, &s_BunnyScrew[4][0]},
288 },
289 };
290
291
292 STATEp sg_BunnyScrew[] =
293 {
294 s_BunnyScrew[0],
295 s_BunnyScrew[1],
296 s_BunnyScrew[2],
297 s_BunnyScrew[3],
298 s_BunnyScrew[4]
299 };
300
301 //////////////////////
302 //
303 // BUNNY SWIPE
304 //
305 //////////////////////
306
307 #define BUNNY_SWIPE_RATE 8
308 ANIMATOR InitActorDecide;
309 ANIMATOR InitBunnySlash;
310
311 STATE s_BunnySwipe[5][8] =
312 {
313 {
314 {BUNNY_SWIPE_R0 + 0, BUNNY_SWIPE_RATE, NullBunny, &s_BunnySwipe[0][1]},
315 {BUNNY_SWIPE_R0 + 1, BUNNY_SWIPE_RATE, NullBunny, &s_BunnySwipe[0][2]},
316 {BUNNY_SWIPE_R0 + 1, 0 | SF_QUICK_CALL, InitBunnySlash, &s_BunnySwipe[0][3]},
317 {BUNNY_SWIPE_R0 + 2, BUNNY_SWIPE_RATE, NullBunny, &s_BunnySwipe[0][4]},
318 {BUNNY_SWIPE_R0 + 3, BUNNY_SWIPE_RATE, NullBunny, &s_BunnySwipe[0][5]},
319 {BUNNY_SWIPE_R0 + 3, 0 | SF_QUICK_CALL, InitBunnySlash, &s_BunnySwipe[0][6]},
320 {BUNNY_SWIPE_R0 + 3, 0 | SF_QUICK_CALL, InitActorDecide, &s_BunnySwipe[0][7]},
321 {BUNNY_SWIPE_R0 + 3, BUNNY_SWIPE_RATE, DoBunnyMove, &s_BunnySwipe[0][7]},
322 },
323 {
324 {BUNNY_SWIPE_R1 + 0, BUNNY_SWIPE_RATE, NullBunny, &s_BunnySwipe[1][1]},
325 {BUNNY_SWIPE_R1 + 1, BUNNY_SWIPE_RATE, NullBunny, &s_BunnySwipe[1][2]},
326 {BUNNY_SWIPE_R1 + 1, 0 | SF_QUICK_CALL, InitBunnySlash, &s_BunnySwipe[1][3]},
327 {BUNNY_SWIPE_R1 + 2, BUNNY_SWIPE_RATE, NullBunny, &s_BunnySwipe[1][4]},
328 {BUNNY_SWIPE_R1 + 3, BUNNY_SWIPE_RATE, NullBunny, &s_BunnySwipe[1][5]},
329 {BUNNY_SWIPE_R1 + 3, 0 | SF_QUICK_CALL, InitBunnySlash, &s_BunnySwipe[1][6]},
330 {BUNNY_SWIPE_R1 + 3, 0 | SF_QUICK_CALL, InitActorDecide, &s_BunnySwipe[1][7]},
331 {BUNNY_SWIPE_R1 + 3, BUNNY_SWIPE_RATE, DoBunnyMove, &s_BunnySwipe[1][7]},
332 },
333 {
334 {BUNNY_SWIPE_R2 + 0, BUNNY_SWIPE_RATE, NullBunny, &s_BunnySwipe[2][1]},
335 {BUNNY_SWIPE_R2 + 1, BUNNY_SWIPE_RATE, NullBunny, &s_BunnySwipe[2][2]},
336 {BUNNY_SWIPE_R2 + 1, 0 | SF_QUICK_CALL, InitBunnySlash, &s_BunnySwipe[2][3]},
337 {BUNNY_SWIPE_R2 + 2, BUNNY_SWIPE_RATE, NullBunny, &s_BunnySwipe[2][4]},
338 {BUNNY_SWIPE_R2 + 3, BUNNY_SWIPE_RATE, NullBunny, &s_BunnySwipe[2][5]},
339 {BUNNY_SWIPE_R2 + 3, 0 | SF_QUICK_CALL, InitBunnySlash, &s_BunnySwipe[2][6]},
340 {BUNNY_SWIPE_R2 + 3, 0 | SF_QUICK_CALL, InitActorDecide, &s_BunnySwipe[2][7]},
341 {BUNNY_SWIPE_R2 + 3, BUNNY_SWIPE_RATE, DoBunnyMove, &s_BunnySwipe[2][7]},
342 },
343 {
344 {BUNNY_SWIPE_R3 + 0, BUNNY_SWIPE_RATE, NullBunny, &s_BunnySwipe[3][1]},
345 {BUNNY_SWIPE_R3 + 1, BUNNY_SWIPE_RATE, NullBunny, &s_BunnySwipe[3][2]},
346 {BUNNY_SWIPE_R3 + 1, 0 | SF_QUICK_CALL, InitBunnySlash, &s_BunnySwipe[3][3]},
347 {BUNNY_SWIPE_R3 + 2, BUNNY_SWIPE_RATE, NullBunny, &s_BunnySwipe[3][4]},
348 {BUNNY_SWIPE_R3 + 3, BUNNY_SWIPE_RATE, NullBunny, &s_BunnySwipe[3][5]},
349 {BUNNY_SWIPE_R3 + 3, 0 | SF_QUICK_CALL, InitBunnySlash, &s_BunnySwipe[3][6]},
350 {BUNNY_SWIPE_R3 + 3, 0 | SF_QUICK_CALL, InitActorDecide, &s_BunnySwipe[3][7]},
351 {BUNNY_SWIPE_R3 + 3, BUNNY_SWIPE_RATE, DoBunnyMove, &s_BunnySwipe[3][7]},
352 },
353 {
354 {BUNNY_SWIPE_R4 + 0, BUNNY_SWIPE_RATE, NullBunny, &s_BunnySwipe[4][1]},
355 {BUNNY_SWIPE_R4 + 1, BUNNY_SWIPE_RATE, NullBunny, &s_BunnySwipe[4][2]},
356 {BUNNY_SWIPE_R4 + 1, 0 | SF_QUICK_CALL, InitBunnySlash, &s_BunnySwipe[4][3]},
357 {BUNNY_SWIPE_R4 + 2, BUNNY_SWIPE_RATE, NullBunny, &s_BunnySwipe[4][4]},
358 {BUNNY_SWIPE_R4 + 3, BUNNY_SWIPE_RATE, NullBunny, &s_BunnySwipe[4][5]},
359 {BUNNY_SWIPE_R4 + 3, 0 | SF_QUICK_CALL, InitBunnySlash, &s_BunnySwipe[4][6]},
360 {BUNNY_SWIPE_R4 + 3, 0 | SF_QUICK_CALL, InitActorDecide, &s_BunnySwipe[4][7]},
361 {BUNNY_SWIPE_R4 + 3, BUNNY_SWIPE_RATE, DoBunnyMove, &s_BunnySwipe[4][7]},
362 }
363 };
364
365
366 STATEp sg_BunnySwipe[] =
367 {
368 &s_BunnySwipe[0][0],
369 &s_BunnySwipe[1][0],
370 &s_BunnySwipe[2][0],
371 &s_BunnySwipe[3][0],
372 &s_BunnySwipe[4][0]
373 };
374
375
376 //////////////////////
377 //
378 // BUNNY HEART - show players heart
379 //
380 //////////////////////
381
382 #define BUNNY_HEART_RATE 14
383 ANIMATOR DoBunnyStandKill;
384
385 STATE s_BunnyHeart[5][4] =
386 {
387 {
388 {BUNNY_SWIPE_R0 + 0, BUNNY_HEART_RATE, DoBunnyStandKill, &s_BunnyHeart[0][0]},
389 },
390 {
391 {BUNNY_SWIPE_R1 + 0, BUNNY_HEART_RATE, DoBunnyStandKill, &s_BunnyHeart[1][0]},
392 },
393 {
394 {BUNNY_SWIPE_R2 + 0, BUNNY_HEART_RATE, DoBunnyStandKill, &s_BunnyHeart[2][0]},
395 },
396 {
397 {BUNNY_SWIPE_R3 + 0, BUNNY_HEART_RATE, DoBunnyStandKill, &s_BunnyHeart[3][0]},
398 },
399 {
400 {BUNNY_SWIPE_R4 + 0, BUNNY_HEART_RATE, DoBunnyStandKill, &s_BunnyHeart[4][0]},
401 }
402 };
403
404
405 STATEp sg_BunnyHeart[] =
406 {
407 &s_BunnyHeart[0][0],
408 &s_BunnyHeart[1][0],
409 &s_BunnyHeart[2][0],
410 &s_BunnyHeart[3][0],
411 &s_BunnyHeart[4][0]
412 };
413
414 //////////////////////
415 //
416 // BUNNY PAIN
417 //
418 //////////////////////
419
420 #define BUNNY_PAIN_RATE 38
421 ANIMATOR DoBunnyPain;
422
423 STATE s_BunnyPain[5][1] =
424 {
425 {
426 {BUNNY_SWIPE_R0 + 0, BUNNY_PAIN_RATE, DoBunnyPain, &s_BunnyPain[0][0]},
427 },
428 {
429 {BUNNY_SWIPE_R0 + 0, BUNNY_PAIN_RATE, DoBunnyPain, &s_BunnyPain[1][0]},
430 },
431 {
432 {BUNNY_SWIPE_R0 + 0, BUNNY_PAIN_RATE, DoBunnyPain, &s_BunnyPain[2][0]},
433 },
434 {
435 {BUNNY_SWIPE_R0 + 0, BUNNY_PAIN_RATE, DoBunnyPain, &s_BunnyPain[3][0]},
436 },
437 {
438 {BUNNY_SWIPE_R0 + 0, BUNNY_PAIN_RATE, DoBunnyPain, &s_BunnyPain[4][0]},
439 }
440 };
441
442 STATEp sg_BunnyPain[] =
443 {
444 &s_BunnyPain[0][0],
445 &s_BunnyPain[1][0],
446 &s_BunnyPain[2][0],
447 &s_BunnyPain[3][0],
448 &s_BunnyPain[4][0]
449 };
450
451 //////////////////////
452 //
453 // BUNNY JUMP
454 //
455 //////////////////////
456
457 #define BUNNY_JUMP_RATE 25
458
459 STATE s_BunnyJump[5][6] =
460 {
461 {
462 {BUNNY_RUN_R0 + 1, BUNNY_JUMP_RATE, DoBunnyMoveJump, &s_BunnyJump[0][1]},
463 {BUNNY_RUN_R0 + 2, BUNNY_JUMP_RATE, DoBunnyMoveJump, &s_BunnyJump[0][1]},
464 },
465 {
466 {BUNNY_RUN_R1 + 1, BUNNY_JUMP_RATE, DoBunnyMoveJump, &s_BunnyJump[1][1]},
467 {BUNNY_RUN_R1 + 2, BUNNY_JUMP_RATE, DoBunnyMoveJump, &s_BunnyJump[1][1]},
468 },
469 {
470 {BUNNY_RUN_R2 + 1, BUNNY_JUMP_RATE, DoBunnyMoveJump, &s_BunnyJump[2][1]},
471 {BUNNY_RUN_R2 + 2, BUNNY_JUMP_RATE, DoBunnyMoveJump, &s_BunnyJump[2][1]},
472 },
473 {
474 {BUNNY_RUN_R3 + 1, BUNNY_JUMP_RATE, DoBunnyMoveJump, &s_BunnyJump[3][1]},
475 {BUNNY_RUN_R3 + 2, BUNNY_JUMP_RATE, DoBunnyMoveJump, &s_BunnyJump[3][1]},
476 },
477 {
478 {BUNNY_RUN_R4 + 1, BUNNY_JUMP_RATE, DoBunnyMoveJump, &s_BunnyJump[4][1]},
479 {BUNNY_RUN_R4 + 2, BUNNY_JUMP_RATE, DoBunnyMoveJump, &s_BunnyJump[4][1]},
480 }
481 };
482
483
484 STATEp sg_BunnyJump[] =
485 {
486 &s_BunnyJump[0][0],
487 &s_BunnyJump[1][0],
488 &s_BunnyJump[2][0],
489 &s_BunnyJump[3][0],
490 &s_BunnyJump[4][0]
491 };
492
493
494 //////////////////////
495 //
496 // BUNNY FALL
497 //
498 //////////////////////
499
500 #define BUNNY_FALL_RATE 25
501
502 STATE s_BunnyFall[5][6] =
503 {
504 {
505 {BUNNY_RUN_R0 + 3, BUNNY_FALL_RATE, DoBunnyMoveJump, &s_BunnyFall[0][0]},
506 },
507 {
508 {BUNNY_RUN_R1 + 3, BUNNY_FALL_RATE, DoBunnyMoveJump, &s_BunnyFall[1][0]},
509 },
510 {
511 {BUNNY_RUN_R2 + 3, BUNNY_FALL_RATE, DoBunnyMoveJump, &s_BunnyFall[2][0]},
512 },
513 {
514 {BUNNY_RUN_R3 + 3, BUNNY_FALL_RATE, DoBunnyMoveJump, &s_BunnyFall[3][0]},
515 },
516 {
517 {BUNNY_RUN_R4 + 3, BUNNY_FALL_RATE, DoBunnyMoveJump, &s_BunnyFall[4][0]},
518 }
519 };
520
521
522 STATEp sg_BunnyFall[] =
523 {
524 &s_BunnyFall[0][0],
525 &s_BunnyFall[1][0],
526 &s_BunnyFall[2][0],
527 &s_BunnyFall[3][0],
528 &s_BunnyFall[4][0]
529 };
530
531
532 //////////////////////
533 //
534 // BUNNY JUMP ATTACK
535 //
536 //////////////////////
537
538 #define BUNNY_JUMP_ATTACK_RATE 35
539 int DoBunnyBeginJumpAttack(short SpriteNum);
540
541 STATE s_BunnyJumpAttack[5][6] =
542 {
543 {
544 {BUNNY_RUN_R0 + 1, BUNNY_JUMP_ATTACK_RATE, NullBunny, &s_BunnyJumpAttack[0][1]},
545 {BUNNY_RUN_R0 + 1, 0 | SF_QUICK_CALL, DoBunnyBeginJumpAttack, &s_BunnyJumpAttack[0][2]},
546 {BUNNY_RUN_R0 + 2, BUNNY_JUMP_ATTACK_RATE, DoBunnyMoveJump, &s_BunnyJumpAttack[0][2]},
547 },
548 {
549 {BUNNY_RUN_R1 + 1, BUNNY_JUMP_ATTACK_RATE, NullBunny, &s_BunnyJumpAttack[1][1]},
550 {BUNNY_RUN_R1 + 1, 0 | SF_QUICK_CALL, DoBunnyBeginJumpAttack, &s_BunnyJumpAttack[1][2]},
551 {BUNNY_RUN_R1 + 2, BUNNY_JUMP_ATTACK_RATE, DoBunnyMoveJump, &s_BunnyJumpAttack[1][2]},
552 },
553 {
554 {BUNNY_RUN_R2 + 1, BUNNY_JUMP_ATTACK_RATE, NullBunny, &s_BunnyJumpAttack[2][1]},
555 {BUNNY_RUN_R2 + 1, 0 | SF_QUICK_CALL, DoBunnyBeginJumpAttack, &s_BunnyJumpAttack[2][2]},
556 {BUNNY_RUN_R2 + 2, BUNNY_JUMP_ATTACK_RATE, DoBunnyMoveJump, &s_BunnyJumpAttack[2][2]},
557 },
558 {
559 {BUNNY_RUN_R3 + 1, BUNNY_JUMP_ATTACK_RATE, NullBunny, &s_BunnyJumpAttack[3][1]},
560 {BUNNY_RUN_R3 + 1, 0 | SF_QUICK_CALL, DoBunnyBeginJumpAttack, &s_BunnyJumpAttack[3][2]},
561 {BUNNY_RUN_R3 + 2, BUNNY_JUMP_ATTACK_RATE, DoBunnyMoveJump, &s_BunnyJumpAttack[3][2]},
562 },
563 {
564 {BUNNY_RUN_R4 + 1, BUNNY_JUMP_ATTACK_RATE, NullBunny, &s_BunnyJumpAttack[4][1]},
565 {BUNNY_RUN_R4 + 1, 0 | SF_QUICK_CALL, DoBunnyBeginJumpAttack, &s_BunnyJumpAttack[4][2]},
566 {BUNNY_RUN_R4 + 2, BUNNY_JUMP_ATTACK_RATE, DoBunnyMoveJump, &s_BunnyJumpAttack[4][2]},
567 }
568 };
569
570
571 STATEp sg_BunnyJumpAttack[] =
572 {
573 &s_BunnyJumpAttack[0][0],
574 &s_BunnyJumpAttack[1][0],
575 &s_BunnyJumpAttack[2][0],
576 &s_BunnyJumpAttack[3][0],
577 &s_BunnyJumpAttack[4][0]
578 };
579
580
581 //////////////////////
582 //
583 // BUNNY DIE
584 //
585 //////////////////////
586
587 #define BUNNY_DIE_RATE 16
588 ANIMATOR BunnySpew;
589
590 STATE s_BunnyDie[] =
591 {
592 {BUNNY_DIE + 0, BUNNY_DIE_RATE, NullBunny, &s_BunnyDie[1]},
593 {BUNNY_DIE + 0, SF_QUICK_CALL, BunnySpew, &s_BunnyDie[2]},
594 {BUNNY_DIE + 1, BUNNY_DIE_RATE, NullBunny, &s_BunnyDie[3]},
595 {BUNNY_DIE + 2, BUNNY_DIE_RATE, NullBunny, &s_BunnyDie[4]},
596 {BUNNY_DIE + 2, BUNNY_DIE_RATE, NullBunny, &s_BunnyDie[5]},
597 {BUNNY_DEAD, BUNNY_DIE_RATE, DoActorDebris, &s_BunnyDie[5]},
598 };
599
600 #define BUNNY_DEAD_RATE 8
601
602 STATE s_BunnyDead[] =
603 {
604 {BUNNY_DIE + 0, BUNNY_DEAD_RATE, NullAnimator, &s_BunnyDie[1]},
605 {BUNNY_DIE + 0, SF_QUICK_CALL, BunnySpew, &s_BunnyDie[2]},
606 {BUNNY_DIE + 1, BUNNY_DEAD_RATE, NullAnimator, &s_BunnyDead[3]},
607 {BUNNY_DIE + 2, BUNNY_DEAD_RATE, NullAnimator, &s_BunnyDead[4]},
608 {BUNNY_DEAD, SF_QUICK_CALL, QueueFloorBlood, &s_BunnyDead[5]},
609 {BUNNY_DEAD, BUNNY_DEAD_RATE, DoActorDebris, &s_BunnyDead[5]},
610 };
611
612 STATEp sg_BunnyDie[] =
613 {
614 s_BunnyDie
615 };
616
617 STATEp sg_BunnyDead[] =
618 {
619 s_BunnyDead
620 };
621
622 STATE s_BunnyDeathJump[] =
623 {
624 {BUNNY_DIE + 0, BUNNY_DIE_RATE, DoActorDeathMove, &s_BunnyDeathJump[0]}
625 };
626
627 STATE s_BunnyDeathFall[] =
628 {
629 {BUNNY_DIE + 1, BUNNY_DIE_RATE, DoActorDeathMove, &s_BunnyDeathFall[0]}
630 };
631
632 STATEp sg_BunnyDeathJump[] =
633 {
634 s_BunnyDeathJump
635 };
636
637 STATEp sg_BunnyDeathFall[] =
638 {
639 s_BunnyDeathFall
640 };
641
642
643 /*
644 STATEp *Stand[MAX_WEAPONS];
645 STATEp *Run;
646 STATEp *Jump;
647 STATEp *Fall;
648 STATEp *Crawl;
649 STATEp *Swim;
650 STATEp *Fly;
651 STATEp *Rise;
652 STATEp *Sit;
653 STATEp *Look;
654 STATEp *Climb;
655 STATEp *Pain;
656 STATEp *Death1;
657 STATEp *Death2;
658 STATEp *Dead;
659 STATEp *DeathJump;
660 STATEp *DeathFall;
661 STATEp *CloseAttack[2];
662 STATEp *Attack[6];
663 STATEp *Special[2];
664 */
665
666 ACTOR_ACTION_SET BunnyActionSet =
667 {
668 sg_BunnyStand,
669 sg_BunnyRun,
670 sg_BunnyJump,
671 sg_BunnyFall,
672 NULL, // sg_BunnyCrawl,
673 NULL, // sg_BunnySwim,
674 NULL, // sg_BunnyFly,
675 NULL, // sg_BunnyRise,
676 NULL, // sg_BunnySit,
677 NULL, // sg_BunnyLook,
678 NULL, // climb
679 sg_BunnyPain,
680 sg_BunnyDie,
681 NULL,
682 sg_BunnyDead,
683 sg_BunnyDeathJump,
684 sg_BunnyDeathFall,
685 {NULL},
686 {1024},
687 {NULL},
688 {1024},
689 {sg_BunnyHeart, sg_BunnyRun},
690 NULL,
691 NULL
692 };
693
694 ACTOR_ACTION_SET BunnyWhiteActionSet =
695 {
696 sg_BunnyStand,
697 sg_BunnyRun,
698 sg_BunnyJump,
699 sg_BunnyFall,
700 NULL, // sg_BunnyCrawl,
701 NULL, // sg_BunnySwim,
702 NULL, // sg_BunnyFly,
703 NULL, // sg_BunnyRise,
704 NULL, // sg_BunnySit,
705 NULL, // sg_BunnyLook,
706 NULL, // climb
707 sg_BunnyPain, // pain
708 sg_BunnyDie,
709 NULL,
710 sg_BunnyDead,
711 sg_BunnyDeathJump,
712 sg_BunnyDeathFall,
713 {sg_BunnySwipe},
714 {1024},
715 // {sg_BunnyJumpAttack, sg_BunnySwipe},
716 // {800, 1024},
717 {sg_BunnySwipe},
718 {1024},
719 {sg_BunnyHeart, sg_BunnySwipe},
720 NULL,
721 NULL
722 };
723
724 int
SetupBunny(short SpriteNum)725 SetupBunny(short SpriteNum)
726 {
727 SPRITEp sp = &sprite[SpriteNum];
728 USERp u;
729 ANIMATOR DoActorDecide;
730
731 if (TEST(sp->cstat, CSTAT_SPRITE_RESTORE))
732 {
733 u = User[SpriteNum];
734 ASSERT(u);
735 }
736 else
737 {
738 User[SpriteNum] = u = SpawnUser(SpriteNum, BUNNY_RUN_R0, s_BunnyRun[0]);
739 u->Health = 10;
740 }
741
742 Bunny_Count++;
743 //if(Bunny_Count > 20)
744 // {
745 // KillSprite(SpriteNum);
746 // Bunny_Count--;
747 // return(0);
748 // }
749
750 ChangeState(SpriteNum, s_BunnyRun[0]);
751 u->StateEnd = s_BunnyDie;
752 u->Rot = sg_BunnyRun;
753 //sp->xrepeat = 64;
754 //sp->yrepeat = 64;
755 u->ShellNum = 0; // Not Pregnant right now
756 u->FlagOwner = 0;
757
758 sp->clipdist = (150) >> 2;
759
760 if (sp->pal == PALETTE_PLAYER1)
761 {
762 EnemyDefaults(SpriteNum, &BunnyWhiteActionSet, &WhiteBunnyPersonality);
763 u->Attrib = &WhiteBunnyAttrib;
764 sp->xrepeat = 96;
765 sp->yrepeat = 90;
766
767 sp->clipdist = 200>>2;
768
769 if (!TEST(sp->cstat, CSTAT_SPRITE_RESTORE))
770 u->Health = 60;
771 }
772 else if (sp->pal == PALETTE_PLAYER8) // Male Rabbit
773 {
774 EnemyDefaults(SpriteNum, &BunnyActionSet, &BunnyPersonality);
775 u->Attrib = &BunnyAttrib;
776 //sp->xrepeat = 76;
777 //sp->yrepeat = 70;
778
779 //sp->shade = 0; // darker
780 if (!TEST(sp->cstat, CSTAT_SPRITE_RESTORE))
781 u->Health = 20;
782 u->Flag1 = 0;
783 }
784 else
785 {
786 // Female Rabbit
787 EnemyDefaults(SpriteNum, &BunnyActionSet, &BunnyPersonality);
788 u->Attrib = &BunnyAttrib;
789 u->spal = sp->pal = PALETTE_PLAYER0;
790 u->Flag1 = SEC(5);
791 //sp->shade = 0; // darker
792 }
793
794 DoActorSetSpeed(SpriteNum, FAST_SPEED);
795
796 SET(u->Flags, SPR_XFLIP_TOGGLE);
797
798
799 u->zclip = Z(16);
800 u->floor_dist = Z(8);
801 u->ceiling_dist = Z(8);
802 u->lo_step = Z(16);
803
804 return 0;
805 }
806
807 int
GetBunnyJumpHeight(short jump_speed,short jump_grav)808 GetBunnyJumpHeight(short jump_speed, short jump_grav)
809 {
810 int jump_iterations;
811 int height;
812
813 jump_speed = labs(jump_speed);
814
815 jump_iterations = jump_speed / (jump_grav * ACTORMOVETICS);
816
817 height = jump_speed * jump_iterations * ACTORMOVETICS;
818
819 height = DIV256(height);
820
821 return DIV2(height);
822 }
823
824 int
PickBunnyJumpSpeed(short SpriteNum,int pix_height)825 PickBunnyJumpSpeed(short SpriteNum, int pix_height)
826 {
827 USERp u = User[SpriteNum];
828
829 ASSERT(pix_height < 128);
830
831 u->jump_speed = -600;
832 u->jump_grav = 8;
833
834 while (TRUE)
835 {
836 if (GetBunnyJumpHeight(u->jump_speed, u->jump_grav) > pix_height + 20)
837 break;
838
839 u->jump_speed -= 100;
840
841 ASSERT(u->jump_speed > -3000);
842 }
843
844 return u->jump_speed;
845 }
846
847 //
848 // JUMP ATTACK
849 //
850
851 int
DoBunnyBeginJumpAttack(short SpriteNum)852 DoBunnyBeginJumpAttack(short SpriteNum)
853 {
854 SPRITEp sp = &sprite[SpriteNum];
855 USERp u = User[SpriteNum];
856 SPRITEp psp = User[SpriteNum]->tgt_sp;
857 int CanSeePlayer(short SpriteNum);
858 short tang;
859
860 tang = getangle(psp->x - sp->x, psp->y - sp->y);
861
862 if (move_sprite(SpriteNum, sintable[NORM_ANGLE(tang+512)] >> 7, sintable[tang] >> 7,
863 0L, u->ceiling_dist, u->floor_dist, CLIPMASK_ACTOR, ACTORMOVETICS))
864 sp->ang = NORM_ANGLE(sp->ang + 1024) + (RANDOM_NEG(256, 6) >> 6);
865 else
866 sp->ang = NORM_ANGLE(tang + (RANDOM_NEG(256, 6) >> 6));
867
868 DoActorSetSpeed(SpriteNum, FAST_SPEED);
869
870 //u->jump_speed = -800;
871 PickJumpMaxSpeed(SpriteNum, -400); // was -800
872
873 SET(u->Flags, SPR_JUMPING);
874 RESET(u->Flags, SPR_FALLING);
875
876 // set up individual actor jump gravity
877 u->jump_grav = 17; // was 8
878
879 // if I didn't do this here they get stuck in the air sometimes
880 DoActorZrange(SpriteNum);
881
882 DoJump(SpriteNum);
883
884 return 0;
885 }
886
887 int
DoBunnyMoveJump(short SpriteNum)888 DoBunnyMoveJump(short SpriteNum)
889 {
890 SPRITEp sp = &sprite[SpriteNum];
891 USERp u = User[SpriteNum];
892
893 if (TEST(u->Flags, SPR_JUMPING | SPR_FALLING))
894 {
895 int nx, ny;
896
897 // Move while jumping
898 nx = sp->xvel * (int) sintable[NORM_ANGLE(sp->ang + 512)] >> 14;
899 ny = sp->xvel * (int) sintable[sp->ang] >> 14;
900
901 move_actor(SpriteNum, nx, ny, 0L);
902
903 if (TEST(u->Flags, SPR_JUMPING))
904 DoActorJump(SpriteNum);
905 else
906 DoActorFall(SpriteNum);
907 }
908
909 DoActorZrange(SpriteNum);
910
911 if (!TEST(u->Flags, SPR_JUMPING | SPR_FALLING))
912 {
913 // if (DoBunnyQuickJump(SpriteNum))
914 // return (0);
915
916 InitActorDecide(SpriteNum);
917 }
918
919 return 0;
920 }
921
922 int
DoPickCloseBunny(short SpriteNum)923 DoPickCloseBunny(short SpriteNum)
924 {
925 USERp u = User[SpriteNum],tu;
926 SPRITEp sp = &sprite[SpriteNum],tsp;
927 int dist, near_dist = 1000, a,b,c;
928 short i, nexti;
929 //short BunnyCount=0, Bunny_Result = -1;
930
931 // if actor can still see the player
932 int look_height = SPRITEp_TOS(sp);
933 SWBOOL ICanSee = FALSE;
934
935 TRAVERSE_SPRITE_STAT(headspritestat[STAT_ENEMY], i, nexti)
936 {
937 tsp = &sprite[i];
938 tu = User[i];
939
940 if (sp == tsp) continue;
941
942 if (tu->ID != BUNNY_RUN_R0) continue;
943
944 DISTANCE(tsp->x, tsp->y, sp->x, sp->y, dist, a, b, c);
945
946 if (dist > near_dist) continue;
947
948 ICanSee = FAFcansee(sp->x, sp->y, look_height, sp->sectnum, tsp->x, tsp->y, SPRITEp_UPPER(tsp), tsp->sectnum);
949
950 if (ICanSee && dist < near_dist && tu->ID == BUNNY_RUN_R0)
951 {
952 near_dist = dist;
953 u->tgt_sp = u->lo_sp = tsp;
954 //Bunny_Result = i;
955 return i;
956 }
957 }
958 return -1;
959 }
960
961 int
DoBunnyQuickJump(short SpriteNum)962 DoBunnyQuickJump(short SpriteNum)
963 {
964 SPRITEp sp = &sprite[SpriteNum];
965 USERp u = User[SpriteNum];
966
967 if (u->spal != PALETTE_PLAYER8) return FALSE;
968
969 if (!u->lo_sp && u->spal == PALETTE_PLAYER8 && MoveSkip4)
970 DoPickCloseBunny(SpriteNum);
971
972 // Random Chance of like sexes fighting
973 if (u->lo_sp)
974 {
975 short hit_sprite = u->lo_sp - sprite;
976 SPRITEp tsp = u->lo_sp;
977 USERp tu = User[hit_sprite];
978
979 if (!tu || tu->ID != BUNNY_RUN_R0) return FALSE;
980
981
982 // Not mature enough yet
983 if (sp->xrepeat != 64 || sp->yrepeat != 64) return FALSE;
984 if (tsp->xrepeat != 64 || tsp->yrepeat != 64) return FALSE;
985
986 // Kill a rival
987 // Only males fight
988 if (tu->spal == sp->pal && RANDOM_RANGE(1000) > 995)
989 {
990 if (u->spal == PALETTE_PLAYER8 && tu->spal == PALETTE_PLAYER8)
991 {
992 PlaySound(DIGI_BUNNYATTACK, &sp->x, &sp->y, &sp->z, v3df_follow);
993 PlaySound(DIGI_BUNNYDIE2, &tsp->x, &tsp->y, &tsp->z, v3df_follow);
994 tu->Health = 0;
995
996 // Blood fountains
997 InitBloodSpray(hit_sprite,TRUE,-1);
998
999 if (SpawnShrap(hit_sprite, SpriteNum))
1000 {
1001 SetSuicide(hit_sprite);
1002 }
1003 else
1004 DoActorDie(hit_sprite, SpriteNum);
1005
1006 Bunny_Count--; // Bunny died
1007
1008 u->lo_sp = NULL;
1009 return TRUE;
1010 }
1011 }
1012 }
1013
1014 // Get layed!
1015 if (u->lo_sp && u->spal == PALETTE_PLAYER8) // Only males check this
1016 {
1017 short hit_sprite = u->lo_sp - sprite;
1018 SPRITEp tsp = u->lo_sp;
1019 USERp tu = User[hit_sprite];
1020
1021
1022 if (!tu || tu->ID != BUNNY_RUN_R0) return FALSE;
1023
1024 // Not mature enough to mate yet
1025 if (sp->xrepeat != 64 || sp->yrepeat != 64) return FALSE;
1026 if (tsp->xrepeat != 64 || tsp->yrepeat != 64) return FALSE;
1027
1028 if (tu->ShellNum <= 0 && tu->WaitTics <= 0 && u->WaitTics <= 0)
1029 {
1030 if (TEST(tsp->extra, SPRX_PLAYER_OR_ENEMY))
1031 {
1032 PLAYERp pp = NULL;
1033
1034 if (RANDOM_RANGE(1000) < 995 && tu->spal != PALETTE_PLAYER0) return FALSE;
1035
1036 DoActorPickClosePlayer(SpriteNum);
1037
1038 if (User[u->tgt_sp-sprite]->PlayerP)
1039 pp = User[u->tgt_sp-sprite]->PlayerP;
1040
1041 if (tu->spal != PALETTE_PLAYER0)
1042 {
1043 if (tu->Flag1 > 0) return FALSE;
1044 tu->FlagOwner = 1; // FAG!
1045 tu->Flag1 = SEC(10);
1046 if (pp)
1047 {
1048 short choose_snd;
1049 int fagsnds[] = {DIGI_FAGRABBIT1,DIGI_FAGRABBIT2,DIGI_FAGRABBIT3};
1050
1051 if (pp == Player+myconnectindex)
1052 {
1053 choose_snd = STD_RANDOM_RANGE(2<<8)>>8;
1054 if (FAFcansee(sp->x,sp->y,SPRITEp_TOS(sp),sp->sectnum,pp->posx, pp->posy, pp->posz, pp->cursectnum) && FACING(sp, u->tgt_sp))
1055 PlayerSound(fagsnds[choose_snd],&pp->posx,&pp->posy,&pp->posz,v3df_doppler|v3df_follow|v3df_dontpan,pp);
1056 }
1057 }
1058 }
1059 else
1060 {
1061 if (pp && RANDOM_RANGE(1000) > 200)
1062 {
1063 short choose_snd;
1064 int straightsnds[] = {DIGI_RABBITHUMP1,DIGI_RABBITHUMP2,
1065 DIGI_RABBITHUMP3,DIGI_RABBITHUMP4};
1066
1067 if (pp == Player+myconnectindex)
1068 {
1069 choose_snd = STD_RANDOM_RANGE(3<<8)>>8;
1070 if (FAFcansee(sp->x,sp->y,SPRITEp_TOS(sp),sp->sectnum,pp->posx, pp->posy, pp->posz, pp->cursectnum) && FACING(sp, u->tgt_sp))
1071 PlayerSound(straightsnds[choose_snd],&pp->posx,&pp->posy,&pp->posz,v3df_doppler|v3df_follow|v3df_dontpan,pp);
1072 }
1073 }
1074 }
1075
1076 sp->x = tsp->x; // Mount up little bunny
1077 sp->y = tsp->y;
1078 sp->ang = tsp->ang;
1079 sp->ang = NORM_ANGLE(sp->ang + 1024);
1080 HelpMissileLateral(SpriteNum, 2000L);
1081 sp->ang = tsp->ang;
1082 u->Vis = sp->ang; // Remember angles for later
1083 tu->Vis = tsp->ang;
1084
1085 NewStateGroup(SpriteNum, sg_BunnyScrew);
1086 NewStateGroup(hit_sprite, sg_BunnyScrew);
1087 if (gs.ParentalLock || Global_PLock)
1088 {
1089 SET(sp->cstat, CSTAT_SPRITE_INVISIBLE); // Turn em' invisible
1090 SET(tsp->cstat, CSTAT_SPRITE_INVISIBLE); // Turn em' invisible
1091 }
1092 u->WaitTics = tu->WaitTics = SEC(10); // Mate for this long
1093 return TRUE;
1094 }
1095 }
1096 }
1097
1098 return FALSE;
1099 }
1100
1101
1102 int
NullBunny(short SpriteNum)1103 NullBunny(short SpriteNum)
1104 {
1105 USERp u = User[SpriteNum];
1106
1107
1108 if (TEST(u->Flags, SPR_JUMPING | SPR_FALLING))
1109 {
1110 if (TEST(u->Flags, SPR_JUMPING))
1111 DoActorJump(SpriteNum);
1112 else
1113 DoActorFall(SpriteNum);
1114 }
1115
1116 // stay on floor unless doing certain things
1117 if (!TEST(u->Flags, SPR_JUMPING | SPR_FALLING))
1118 KeepActorOnFloor(SpriteNum);
1119
1120 if (TEST(u->Flags,SPR_SLIDING))
1121 DoActorSlide(SpriteNum);
1122
1123 DoActorSectorDamage(SpriteNum);
1124
1125 return 0;
1126 }
1127
1128
DoBunnyPain(short SpriteNum)1129 int DoBunnyPain(short SpriteNum)
1130 {
1131 USERp u = User[SpriteNum];
1132
1133 NullBunny(SpriteNum);
1134
1135 if ((u->WaitTics -= ACTORMOVETICS) <= 0)
1136 InitActorDecide(SpriteNum);
1137 return 0;
1138 }
1139
DoBunnyRipHeart(short SpriteNum)1140 int DoBunnyRipHeart(short SpriteNum)
1141 {
1142 SPRITEp sp = &sprite[SpriteNum];
1143 USERp u = User[SpriteNum];
1144
1145 SPRITEp tsp = u->tgt_sp;
1146
1147 NewStateGroup(SpriteNum, sg_BunnyHeart);
1148 u->WaitTics = 6 * 120;
1149
1150 // player face bunny
1151 tsp->ang = getangle(sp->x - tsp->x, sp->y - tsp->y);
1152 return 0;
1153 }
1154
DoBunnyStandKill(short SpriteNum)1155 int DoBunnyStandKill(short SpriteNum)
1156 {
1157 SPRITEp sp = &sprite[SpriteNum];
1158 USERp u = User[SpriteNum];
1159
1160 NullBunny(SpriteNum);
1161
1162 // Growl like the bad ass bunny you are!
1163 if (RANDOM_RANGE(1000) > 800)
1164 PlaySound(DIGI_BUNNYATTACK,&sp->x,&sp->y,&sp->z,v3df_none);
1165
1166 if ((u->WaitTics -= ACTORMOVETICS) <= 0)
1167 NewStateGroup(SpriteNum, sg_BunnyRun);
1168 return 0;
1169 }
1170
BunnyHatch(short Weapon)1171 void BunnyHatch(short Weapon)
1172 {
1173 SPRITEp wp = &sprite[Weapon];
1174 USERp wu = User[Weapon];
1175
1176 short New,i;
1177 SPRITEp np;
1178 USERp nu;
1179 #define MAX_BUNNYS 1
1180 short rip_ang[MAX_BUNNYS];
1181
1182 rip_ang[0] = RANDOM_P2(2048);
1183
1184 for (i = 0; i < MAX_BUNNYS; i++)
1185 {
1186 New = COVERinsertsprite(wp->sectnum, STAT_DEFAULT);
1187 np = &sprite[New];
1188 memset(np,0,sizeof(SPRITE));
1189 np->sectnum = wp->sectnum;
1190 np->statnum = STAT_DEFAULT;
1191 np->x = wp->x;
1192 np->y = wp->y;
1193 np->z = wp->z;
1194 np->owner = -1;
1195 np->xrepeat = 30; // Baby size
1196 np->yrepeat = 24;
1197 np->ang = rip_ang[i];
1198 np->pal = 0;
1199 SetupBunny(New);
1200 nu = User[New];
1201 np->shade = wp->shade;
1202
1203 // make immediately active
1204 SET(nu->Flags, SPR_ACTIVE);
1205 if (RANDOM_RANGE(1000) > 500) // Boy or Girl?
1206 nu->spal = np->pal = PALETTE_PLAYER0; // Girl
1207 else
1208 {
1209 nu->spal = np->pal = PALETTE_PLAYER8; // Boy
1210 // Oops, mommy died giving birth to a boy
1211 if (RANDOM_RANGE(1000) > 500)
1212 {
1213 wu->Health = 0;
1214 Bunny_Count--; // Bunny died
1215
1216 // Blood fountains
1217 InitBloodSpray(Weapon,TRUE,-1);
1218
1219 if (SpawnShrap(Weapon, New))
1220 {
1221 SetSuicide(Weapon);
1222 }
1223 else
1224 DoActorDie(Weapon, New);
1225 }
1226 }
1227
1228 nu->ShellNum = 0; // Not Pregnant right now
1229
1230 NewStateGroup(New, nu->ActorActionSet->Jump);
1231 nu->ActorActionFunc = DoActorMoveJump;
1232 DoActorSetSpeed(New, FAST_SPEED);
1233 PickJumpMaxSpeed(New, -600);
1234
1235 SET(nu->Flags, SPR_JUMPING);
1236 RESET(nu->Flags, SPR_FALLING);
1237
1238 nu->jump_grav = 8;
1239
1240 // if I didn't do this here they get stuck in the air sometimes
1241 DoActorZrange(New);
1242
1243 DoActorJump(New);
1244 }
1245 }
1246
BunnyHatch2(short Weapon)1247 int BunnyHatch2(short Weapon)
1248 {
1249 SPRITEp wp = &sprite[Weapon];
1250
1251 short New;
1252 SPRITEp np;
1253 USERp nu;
1254
1255 New = COVERinsertsprite(wp->sectnum, STAT_DEFAULT);
1256 np = &sprite[New];
1257 memset(np,0,sizeof(SPRITE));
1258 np->sectnum = wp->sectnum;
1259 np->statnum = STAT_DEFAULT;
1260 np->x = wp->x;
1261 np->y = wp->y;
1262 np->z = wp->z;
1263 np->owner = -1;
1264 np->xrepeat = 30; // Baby size
1265 np->yrepeat = 24;
1266 np->ang = RANDOM_P2(2048);
1267 np->pal = 0;
1268 SetupBunny(New);
1269 nu = User[New];
1270 np->shade = wp->shade;
1271
1272 // make immediately active
1273 SET(nu->Flags, SPR_ACTIVE);
1274 if (RANDOM_RANGE(1000) > 500) // Boy or Girl?
1275 {
1276 nu->spal = np->pal = PALETTE_PLAYER0; // Girl
1277 nu->Flag1 = SEC(5);
1278 }
1279 else
1280 {
1281 nu->spal = np->pal = PALETTE_PLAYER8; // Boy
1282 nu->Flag1 = 0;
1283 }
1284
1285 nu->ShellNum = 0; // Not Pregnant right now
1286
1287 NewStateGroup(New, nu->ActorActionSet->Jump);
1288 nu->ActorActionFunc = DoActorMoveJump;
1289 DoActorSetSpeed(New, FAST_SPEED);
1290 if (TEST_BOOL3(wp))
1291 {
1292 PickJumpMaxSpeed(New, -600-RANDOM_RANGE(600));
1293 np->xrepeat = np->yrepeat = 64;
1294 np->xvel = 150 + RANDOM_RANGE(1000);
1295 nu->Health = 1; // Easy to pop. Like shootn' skeet.
1296 np->ang -= RANDOM_RANGE(128);
1297 np->ang += RANDOM_RANGE(128);
1298 }
1299 else
1300 PickJumpMaxSpeed(New, -600);
1301
1302 SET(nu->Flags, SPR_JUMPING);
1303 RESET(nu->Flags, SPR_FALLING);
1304
1305 nu->jump_grav = 8;
1306 nu->FlagOwner = 0;
1307
1308 nu->active_range = 75000; // Set it far
1309
1310 // if I didn't do this here they get stuck in the air sometimes
1311 DoActorZrange(New);
1312
1313 DoActorJump(New);
1314
1315 return New;
1316 }
1317
1318 int
DoBunnyMove(short SpriteNum)1319 DoBunnyMove(short SpriteNum)
1320 {
1321 SPRITEp sp = &sprite[SpriteNum];
1322 USERp u = User[SpriteNum];
1323
1324 // Parental lock crap
1325 if (TEST(sp->cstat, CSTAT_SPRITE_INVISIBLE))
1326 RESET(sp->cstat, CSTAT_SPRITE_INVISIBLE); // Turn em' back on
1327
1328 // Sometimes they just won't die!
1329 if (u->Health <= 0)
1330 SetSuicide(SpriteNum);
1331
1332 if (u->scale_speed)
1333 {
1334 DoScaleSprite(SpriteNum);
1335 }
1336
1337 if (TEST(u->Flags, SPR_JUMPING | SPR_FALLING))
1338 {
1339 if (TEST(u->Flags, SPR_JUMPING))
1340 DoActorJump(SpriteNum);
1341 else
1342 DoActorFall(SpriteNum);
1343 }
1344
1345 // if on a player/enemy sprite jump quickly
1346 if (!TEST(u->Flags, SPR_JUMPING | SPR_FALLING))
1347 {
1348 DoBunnyQuickJump(SpriteNum);
1349 }
1350
1351 if (TEST(u->Flags, SPR_SLIDING))
1352 DoActorSlide(SpriteNum);
1353
1354 if (u->track >= 0)
1355 ActorFollowTrack(SpriteNum, ACTORMOVETICS);
1356 else
1357 (*u->ActorActionFunc)(SpriteNum);
1358
1359 // stay on floor unless doing certain things
1360 if (!TEST(u->Flags, SPR_JUMPING | SPR_FALLING))
1361 KeepActorOnFloor(SpriteNum);
1362
1363 DoActorSectorDamage(SpriteNum);
1364
1365 if (RANDOM_RANGE(1000) > 985 && sp->pal != PALETTE_PLAYER1 && u->track < 0)
1366 {
1367 switch (sector[sp->sectnum].floorpicnum)
1368 {
1369 case 153:
1370 case 154:
1371 case 193:
1372 case 219:
1373 case 2636:
1374 case 2689:
1375 case 3561:
1376 case 3562:
1377 case 3563:
1378 case 3564:
1379 NewStateGroup(SpriteNum,sg_BunnyStand);
1380 break;
1381 default:
1382 sp->ang = NORM_ANGLE(RANDOM_RANGE(2048 << 6) >> 6);
1383 u->jump_speed = -350;
1384 DoActorBeginJump(SpriteNum);
1385 u->ActorActionFunc = DoActorMoveJump;
1386 break;
1387 }
1388 }
1389
1390 return 0;
1391 }
1392
1393 int
BunnySpew(short SpriteNum)1394 BunnySpew(short SpriteNum)
1395 {
1396 //InitBloodSpray(SpriteNum,TRUE,-1);
1397 InitBloodSpray(SpriteNum,TRUE,-1);
1398 return 0;
1399 }
1400
1401 int
DoBunnyEat(short SpriteNum)1402 DoBunnyEat(short SpriteNum)
1403 {
1404 SPRITEp sp = &sprite[SpriteNum];
1405 USERp u = User[SpriteNum];
1406
1407
1408 if (TEST(u->Flags, SPR_JUMPING | SPR_FALLING))
1409 {
1410 if (TEST(u->Flags, SPR_JUMPING))
1411 DoActorJump(SpriteNum);
1412 else
1413 DoActorFall(SpriteNum);
1414 }
1415
1416 // if on a player/enemy sprite jump quickly
1417 if (!TEST(u->Flags, SPR_JUMPING | SPR_FALLING))
1418 {
1419 DoBunnyQuickJump(SpriteNum);
1420 }
1421
1422 if (TEST(u->Flags, SPR_SLIDING))
1423 DoActorSlide(SpriteNum);
1424
1425 // stay on floor unless doing certain things
1426 if (!TEST(u->Flags, SPR_JUMPING | SPR_FALLING))
1427 KeepActorOnFloor(SpriteNum);
1428
1429 DoActorSectorDamage(SpriteNum);
1430
1431 switch (sector[sp->sectnum].floorpicnum)
1432 {
1433 case 153:
1434 case 154:
1435 case 193:
1436 case 219:
1437 case 2636:
1438 case 2689:
1439 case 3561:
1440 case 3562:
1441 case 3563:
1442 case 3564:
1443 if (RANDOM_RANGE(1000) > 970)
1444 NewStateGroup(SpriteNum,sg_BunnyRun);
1445 break;
1446 default:
1447 NewStateGroup(SpriteNum,sg_BunnyRun);
1448 break;
1449 }
1450 return 0;
1451 }
1452
1453 int
DoBunnyScrew(short SpriteNum)1454 DoBunnyScrew(short SpriteNum)
1455 {
1456 SPRITEp sp = &sprite[SpriteNum];
1457 USERp u = User[SpriteNum];
1458
1459 if (TEST(u->Flags, SPR_JUMPING | SPR_FALLING))
1460 {
1461 if (TEST(u->Flags, SPR_JUMPING))
1462 DoActorJump(SpriteNum);
1463 else
1464 DoActorFall(SpriteNum);
1465 }
1466
1467 if (TEST(u->Flags, SPR_SLIDING))
1468 DoActorSlide(SpriteNum);
1469
1470 // stay on floor unless doing certain things
1471 if (!TEST(u->Flags, SPR_JUMPING | SPR_FALLING))
1472 KeepActorOnFloor(SpriteNum);
1473
1474 DoActorSectorDamage(SpriteNum);
1475
1476 if (RANDOM_RANGE(1000) > 990) // Bunny sex sounds
1477 {
1478 if (!gs.ParentalLock && !Global_PLock)
1479 PlaySound(DIGI_BUNNYATTACK, &sp->x, &sp->y, &sp->z, v3df_follow);
1480 }
1481
1482 u->WaitTics -= ACTORMOVETICS;
1483
1484 if ((u->FlagOwner || u->spal == PALETTE_PLAYER0) && u->WaitTics > 0) // Keep Girl still
1485 NewStateGroup(SpriteNum,sg_BunnyScrew);
1486
1487 if (u->spal == PALETTE_PLAYER0 && u->WaitTics <= 0) // Female has baby
1488 {
1489 u->Flag1 = SEC(5); // Count down to babies
1490 u->ShellNum = 1; // She's pregnant now
1491 }
1492
1493 if (u->WaitTics <= 0)
1494 {
1495 RESET(sp->cstat, CSTAT_SPRITE_INVISIBLE); // Turn em' back on
1496 u->FlagOwner = 0;
1497 NewStateGroup(SpriteNum,sg_BunnyRun);
1498 }
1499
1500 return 0;
1501 }
1502
1503 int
DoBunnyGrowUp(short SpriteNum)1504 DoBunnyGrowUp(short SpriteNum)
1505 {
1506 SPRITEp sp = &sprite[SpriteNum];
1507 USERp u = User[SpriteNum];
1508
1509 if (sp->pal == PALETTE_PLAYER1) return 0; // Don't bother white bunnies
1510
1511 if ((u->Counter -= ACTORMOVETICS) <= 0)
1512 {
1513 if ((++sp->xrepeat) > 64) sp->xrepeat = 64;
1514 if ((++sp->yrepeat) > 64) sp->yrepeat = 64;
1515 u->Counter = 60;
1516 }
1517
1518 // Don't go homo too much!
1519 if (sp->pal != PALETTE_PLAYER0 && u->Flag1 > 0)
1520 u->Flag1 -= ACTORMOVETICS;
1521
1522 // Gestation period for female rabbits
1523 if (sp->pal == PALETTE_PLAYER0 && u->ShellNum > 0)
1524 {
1525 if ((u->Flag1 -= ACTORMOVETICS) <= 0)
1526 {
1527 if (Bunny_Count < 20)
1528 {
1529 PlaySound(DIGI_BUNNYDIE2, &sp->x, &sp->y, &sp->z, v3df_follow);
1530 BunnyHatch(SpriteNum); // Baby time
1531 }
1532 u->ShellNum = 0; // Not pregnent anymore
1533 }
1534 }
1535
1536 return 0;
1537 }
1538
1539
1540 #include "saveable.h"
1541
1542 static saveable_code saveable_bunny_code[] =
1543 {
1544 SAVE_CODE(SetupBunny),
1545 SAVE_CODE(GetBunnyJumpHeight),
1546 SAVE_CODE(PickBunnyJumpSpeed),
1547 SAVE_CODE(DoBunnyBeginJumpAttack),
1548 SAVE_CODE(DoBunnyMoveJump),
1549 SAVE_CODE(DoPickCloseBunny),
1550 SAVE_CODE(DoBunnyQuickJump),
1551 SAVE_CODE(NullBunny),
1552 SAVE_CODE(DoBunnyPain),
1553 SAVE_CODE(DoBunnyRipHeart),
1554 SAVE_CODE(DoBunnyStandKill),
1555 SAVE_CODE(BunnyHatch),
1556 SAVE_CODE(BunnyHatch2),
1557 SAVE_CODE(DoBunnyMove),
1558 SAVE_CODE(BunnySpew),
1559 SAVE_CODE(DoBunnyEat),
1560 SAVE_CODE(DoBunnyScrew),
1561 SAVE_CODE(DoBunnyGrowUp),
1562 };
1563
1564 static saveable_data saveable_bunny_data[] =
1565 {
1566 SAVE_DATA(BunnyBattle),
1567 SAVE_DATA(BunnyOffense),
1568 SAVE_DATA(BunnyBroadcast),
1569 SAVE_DATA(BunnySurprised),
1570 SAVE_DATA(BunnyEvasive),
1571 SAVE_DATA(BunnyLostTarget),
1572 SAVE_DATA(BunnyCloseRange),
1573 SAVE_DATA(BunnyWander),
1574
1575 SAVE_DATA(WhiteBunnyPersonality),
1576 SAVE_DATA(BunnyPersonality),
1577
1578 SAVE_DATA(WhiteBunnyAttrib),
1579 SAVE_DATA(BunnyAttrib),
1580
1581 SAVE_DATA(s_BunnyRun),
1582 SAVE_DATA(sg_BunnyRun),
1583 SAVE_DATA(s_BunnyStand),
1584 SAVE_DATA(sg_BunnyStand),
1585 SAVE_DATA(s_BunnyScrew),
1586 SAVE_DATA(sg_BunnyScrew),
1587 SAVE_DATA(s_BunnySwipe),
1588 SAVE_DATA(sg_BunnySwipe),
1589 SAVE_DATA(s_BunnyHeart),
1590 SAVE_DATA(sg_BunnyHeart),
1591 SAVE_DATA(s_BunnyPain),
1592 SAVE_DATA(sg_BunnyPain),
1593 SAVE_DATA(s_BunnyJump),
1594 SAVE_DATA(sg_BunnyJump),
1595 SAVE_DATA(s_BunnyFall),
1596 SAVE_DATA(sg_BunnyFall),
1597 SAVE_DATA(s_BunnyJumpAttack),
1598 SAVE_DATA(sg_BunnyJumpAttack),
1599 SAVE_DATA(s_BunnyDie),
1600 SAVE_DATA(sg_BunnyDie),
1601 SAVE_DATA(s_BunnyDead),
1602 SAVE_DATA(sg_BunnyDead),
1603 SAVE_DATA(s_BunnyDeathJump),
1604 SAVE_DATA(sg_BunnyDeathJump),
1605 SAVE_DATA(s_BunnyDeathFall),
1606 SAVE_DATA(sg_BunnyDeathFall),
1607
1608 SAVE_DATA(BunnyActionSet),
1609 SAVE_DATA(BunnyWhiteActionSet),
1610 };
1611
1612 saveable_module saveable_bunny =
1613 {
1614 // code
1615 saveable_bunny_code,
1616 SIZ(saveable_bunny_code),
1617
1618 // data
1619 saveable_bunny_data,
1620 SIZ(saveable_bunny_data)
1621 };
1622