Subversion Repositories Games.Carmageddon

Rev

Rev 20 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 pmbaty 1
#include "powerup.h"
20 pmbaty 2
#include "brender/brender.h"
1 pmbaty 3
#include "car.h"
4
#include "controls.h"
5
#include "crush.h"
6
#include "displays.h"
7
#include "errors.h"
8
#include "globvars.h"
9
#include "globvrpb.h"
10
#include "grafdata.h"
11
#include "graphics.h"
12
#include "harness/trace.h"
13
#include "input.h"
14
#include "loading.h"
15
#include "netgame.h"
16
#include "network.h"
17
#include "opponent.h"
18
#include "pedestrn.h"
19
#include "piping.h"
20
#include "pratcam.h"
21
#include "sound.h"
22
#include "utility.h"
23
#include <stdlib.h>
24
#include <string.h>
25
 
26
tGot_proc* gGot_procs[34] = {
27
    GotCredits,
28
    SetPedSpeed,
29
    SetPedSize,
30
    SetPedExplode,
31
    PickAtRandom,
32
    SetInvulnerability,
33
    SetFreeRepairs,
34
    DoInstantRepair,
35
    FreezeTimer,
36
    SetEngineFactor,
37
    SetUnderwater,
38
    GotTimeOrPower,
39
    TrashBodywork,
40
    TakeDrugs,
41
    SetOpponentsSpeed,
42
    SetCopsSpeed,
43
    SetGravity,
44
    SetPinball,
45
    SetWallclimb,
46
    SetBouncey,
47
    SetSuspension,
48
    SetTyreGrip,
49
    SetDamageMultiplier,
50
    SetHades,
51
    SetBlindPedestrians,
52
    PedestrianRespawn,
53
    GotVouchers,
54
    SetMassMultiplier,
55
    SetInstantHandbrake,
56
    ShowPedestrians,
57
    HitMine,
58
    SetProximity,
59
    SetPedHarvest,
60
    SetVesuvianCorpses,
61
};
62
tLose_proc* gLose_procs[34] = {
63
    NULL,
64
    ResetPedSpeed,
65
    ResetPedSize,
66
    ResetPedExplode,
67
    NULL,
68
    ResetInvulnerability,
69
    ResetFreeRepairs,
70
    NULL,
71
    UnfreezeTimer,
72
    ResetEngineFactor,
73
    ResetUnderwater,
74
    NULL,
75
    NULL,
76
    PukeDrugsBackUp,
77
    ResetOpponentsSpeed,
78
    ResetCopsSpeed,
79
    ResetGravity,
80
    ResetPinball,
81
    ResetWallclimb,
82
    ResetBouncey,
83
    ResetSuspension,
84
    ResetTyreGrip,
85
    ResetDamageMultiplier,
86
    ResetHades,
87
    ResetBlindPedestrians,
88
    NULL,
89
    NULL,
90
    ResetMassMultiplier,
91
    ResetInstantHandbrake,
92
    HidePedestrians,
93
    NULL,
94
    ResetProximity,
95
    ResetPedHarvest,
96
    ResetVesuvianCorpses,
97
};
98
tPeriodic_proc* gPeriodic_procs[34] = {
99
    NULL,
100
    NULL,
101
    NULL,
102
    NULL,
103
    NULL,
104
    NULL,
105
    NULL,
106
    NULL,
107
    NULL,
108
    NULL,
109
    NULL,
110
    NULL,
111
    NULL,
112
    TheEffectsOfDrugs,
113
    NULL,
114
    NULL,
115
    NULL,
116
    NULL,
117
    NULL,
118
    DoBouncey,
119
    NULL,
120
    NULL,
121
    NULL,
122
    NULL,
123
    NULL,
124
    NULL,
125
    MungeVouchers,
126
    NULL,
127
    NULL,
128
    NULL,
129
    NULL,
130
    NULL,
131
    NULL,
132
    NULL,
133
};
134
tU32* gReal_render_palette;
135
char* gFizzle_names[3] = { "CIRCLES.PIX", "SQUARES.PIX", "DIAMONDS.PIX" };
136
br_vector3 gZero_v__powerup; // suffix added to avoid duplicate symbol
137
int gPed_harvest_sounds[4] = { 4010, 4012, 4030, 4032 };
138
tHeadup_icon gIcon_list[20];
139
br_pixelmap* gFizzle_in[3];
140
int gNumber_of_powerups;
141
int gFizzle_height;
142
int gNumber_of_icons;
143
tPowerup* gPowerup_array;
144
 
20 pmbaty 145
#define GET_POWERUP_INDEX(POWERUP) (((POWERUP)-gPowerup_array) / sizeof(tPowerup))
1 pmbaty 146
 
147
// IDA: void __usercall LosePowerupX(tPowerup *pThe_powerup@<EAX>, int pTell_net_players@<EDX>)
148
void LosePowerupX(tPowerup* pThe_powerup, int pTell_net_players) {
149
    int i;
150
    tNet_message* the_message;
151
    LOG_TRACE("(%p, %d)", pThe_powerup, pTell_net_players);
152
 
153
    if (pThe_powerup->got_time != 0 && pThe_powerup->lose_proc != NULL) {
154
        pThe_powerup->lose_proc(pThe_powerup, pThe_powerup->car);
155
    }
156
    if (gNet_mode != eNet_mode_none) {
157
        the_message = NetBuildMessage(21, 0);
158
        the_message->contents.data.powerup.event = ePowerup_lost;
159
        the_message->contents.data.powerup.player = gLocal_net_ID;
160
        the_message->contents.data.powerup.event = GET_POWERUP_INDEX(pThe_powerup);
161
        NetGuaranteedSendMessageToAllPlayers(gCurrent_net_game, the_message, NULL);
162
    }
163
    for (i = 0; i < gNumber_of_icons; i++) {
164
        if (gIcon_list[i].powerup == pThe_powerup) {
165
            gIcon_list[i].fizzle_stage = 3;
166
            gIcon_list[i].fizzle_direction = -1;
167
            gIcon_list[i].fizzle_start = GetTotalTime();
168
            break;
169
        }
170
    }
171
    pThe_powerup->got_time = 0;
172
}
173
 
174
// IDA: void __usercall LosePowerup(tPowerup *pThe_powerup@<EAX>)
175
void LosePowerup(tPowerup* pThe_powerup) {
176
    LOG_TRACE("(%p)", pThe_powerup);
177
 
178
    LosePowerupX(pThe_powerup, 1);
179
}
180
 
181
// IDA: void __usercall LoseAllSimilarPowerups(tPowerup *pThe_powerup@<EAX>)
182
void LoseAllSimilarPowerups(tPowerup* pThe_powerup) {
183
    int i;
184
    tPowerup* the_powerup;
185
    LOG_TRACE("(%p)", pThe_powerup);
186
 
187
    for (i = 0, the_powerup = gPowerup_array; i < gNumber_of_powerups; i++, the_powerup++) {
188
        if (the_powerup != pThe_powerup && the_powerup->got_time != 0) {
189
            if ((pThe_powerup->group_inclusion & the_powerup->group_inclusion) != 0) {
190
                LosePowerup(the_powerup);
191
            }
192
        }
193
    }
194
}
195
 
196
// IDA: int __usercall GotPowerupX@<EAX>(tCar_spec *pCar@<EAX>, int pIndex@<EDX>, int pTell_net_players@<EBX>, int pDisplay_headup@<ECX>, tU32 pTime_left)
197
int GotPowerupX(tCar_spec* pCar, int pIndex, int pTell_net_players, int pDisplay_headup, tU32 pTime_left) {
198
    tPowerup* the_powerup;
199
    int i;
200
    int original_index;
201
    //int icon_index; // Pierre-Marie Baty -- unused variable
202
    int ps_power;
203
    char s[256];
204
    char* s2;
205
    tNet_message* the_message;
206
    LOG_TRACE("(%p, %d, %d, %d, %d)", pCar, pIndex, pTell_net_players, pDisplay_headup, pTime_left);
207
 
208
    if (pIndex < 0 || pIndex >= gNumber_of_powerups) {
209
        return -1;
210
    }
211
    the_powerup = &gPowerup_array[pIndex];
212
    if (the_powerup->type == ePowerup_dummy) {
213
        return -1;
214
    }
215
    if (the_powerup->got_proc == NULL) {
21 pmbaty 216
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 3000, -4, GetMiscString(kMiscString_UNAVAILABLE_IN_DEMO));
1 pmbaty 217
        return -1;
218
    }
219
    original_index = pIndex;
220
    if (((gProgram_state.sausage_eater_mode || gTotal_peds < 2)
221
            && (strstr(the_powerup->message, "Ped") != NULL
222
                || strstr(the_powerup->message, "ped") != NULL
223
                || strstr(the_powerup->message, "corpses") != NULL))
224
        || (gNet_mode != eNet_mode_none && the_powerup->net_type == eNet_powerup_inappropriate)) {
225
        pIndex = 0;
226
        the_powerup = &gPowerup_array[pIndex];
227
    }
228
    the_powerup->current_value = -1;
229
    LoseAllSimilarPowerups(the_powerup);
230
    ps_power = gNet_mode != eNet_mode_none && the_powerup->got_proc == GotTimeOrPower;
231
    if (the_powerup->message[0] != '\0' && pDisplay_headup && !ps_power) {
232
        strcpy(s, the_powerup->message);
233
        s2 = s;
234
        if (the_powerup->got_proc == FreezeTimer) {
235
            s2 = strtok(s, "/");
236
            if (gFreeze_timer) {
237
                s2 = strtok(NULL, "/");
238
            }
239
        }
21 pmbaty 240
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 3000, -4, s2);
1 pmbaty 241
    }
242
    the_powerup->car = pCar;
243
    if (the_powerup->got_proc != NULL) {
244
        pIndex = the_powerup->got_proc(the_powerup, pCar);
245
    }
246
    if (pCar->driver == eDriver_non_car_unused_slot || pCar->driver == eDriver_non_car) {
247
        return pIndex;
248
    }
249
    if (the_powerup->type == ePowerup_timed) {
250
        the_powerup->got_time = GetTotalTime();
251
        if (pTell_net_players) {
252
            the_powerup->lose_time = the_powerup->got_time + the_powerup->duration;
253
        } else {
254
            the_powerup->lose_time = the_powerup->got_time + pTime_left;
255
        }
256
        gProgram_state.current_car.powerups[pIndex] = the_powerup->lose_time;
257
    } else if (the_powerup->type == ePowerup_whole_race) {
258
        the_powerup->got_time = GetTotalTime();
259
        gProgram_state.current_car.powerups[pIndex] = -1;
260
    }
261
    if (the_powerup->prat_cam_event >= 0) {
262
        PratcamEvent(the_powerup->prat_cam_event);
263
    }
264
    if (gNet_mode != eNet_mode_none && pTell_net_players && pIndex == original_index && !ps_power) {
265
        the_message = NetBuildMessage(21, 0);
266
        the_message->contents.data.powerup.event = ePowerup_gained;
267
        the_message->contents.data.powerup.player = gLocal_net_ID;
268
        the_message->contents.data.powerup.powerup_index = pIndex;
269
        if (the_powerup->type == ePowerup_timed) {
270
            the_message->contents.data.powerup.time_left = the_powerup->duration;
271
        } else {
272
            the_message->contents.data.powerup.time_left = 0;
273
        }
274
        NetGuaranteedSendMessageToAllPlayers(gCurrent_net_game, the_message, NULL);
275
    }
276
    if (the_powerup->type != ePowerup_instantaneous && the_powerup->icon != NULL) {
277
        for (i = 0; i < gNumber_of_icons; i++) {
278
            if (gIcon_list[i].powerup == the_powerup) {
279
                gIcon_list[i].fizzle_stage = 4;
280
                return pIndex;
281
            }
282
        }
283
        if (gNumber_of_icons != COUNT_OF(gIcon_list)) {
284
            gIcon_list[gNumber_of_icons].powerup = the_powerup;
285
            gIcon_list[gNumber_of_icons].fizzle_stage = 0;
286
            gIcon_list[gNumber_of_icons].fizzle_direction = 1;
287
            gIcon_list[gNumber_of_icons].fizzle_start = GetTotalTime();
288
            gNumber_of_icons++;
289
        }
290
    }
291
    return pIndex;
292
}
293
 
294
// IDA: int __usercall GotPowerup@<EAX>(tCar_spec *pCar@<EAX>, int pIndex@<EDX>)
295
int GotPowerup(tCar_spec* pCar, int pIndex) {
296
    LOG_TRACE("(%p, %d)", pCar, pIndex);
297
 
298
    return GotPowerupX(pCar, pIndex, 1, 1, 0);
299
}
300
 
301
// IDA: void __cdecl LoadPowerups()
302
void LoadPowerups(void) {
303
    FILE* f;
304
    tPath_name the_path;
305
    char s[256];
306
    int i;
307
    int j;
308
    int time;
309
    int action_index;
310
    tPowerup* the_powerup;
311
    LOG_TRACE("()");
312
 
313
    for (i = 0; i < COUNT_OF(gFizzle_in); i++) {
314
        gFizzle_in[i] = LoadPixelmap(gFizzle_names[i]);
315
    }
316
 
317
    gFizzle_height = gFizzle_in[0]->height / 4;
318
    PathCat(the_path, gApplication_path, "POWERUP.TXT");
319
    f = DRfopen(the_path, "rt");
320
    if (f == NULL) {
321
        FatalError(kFatalError_LoadResolutionIndependentFile);
322
    }
323
    gNumber_of_powerups = GetAnInt(f);
324
    gPowerup_array = BrMemAllocate(sizeof(tPowerup) * gNumber_of_powerups, kMem_powerup_array);
325
    for (i = 0; i < gNumber_of_powerups; i++) {
326
        the_powerup = &gPowerup_array[i];
327
 
328
        GetALineAndDontArgue(f, the_powerup->message);
329
        if (strcmp(the_powerup->message, "dummy") == 0) {
330
            the_powerup->type = 0;
331
        } else {
332
            if (strcmp(the_powerup->message, "n/a") == 0) {
333
                the_powerup->message[0] = 0;
334
            }
335
            GetAString(f, s);
336
            the_powerup->icon = LoadPixelmap(s);
337
            the_powerup->fizzle_type = GetAnInt(f);
338
            time = 1000 * GetAnInt(f);
339
            the_powerup->duration = time;
340
            if (time > 0) {
341
                the_powerup->type = ePowerup_timed;
342
            } else if (time == 0) {
343
                the_powerup->type = ePowerup_whole_race;
344
            } else {
345
                the_powerup->type = ePowerup_instantaneous;
346
            }
347
        }
348
        action_index = GetAnInt(f);
349
        if (action_index >= 0) {
350
            the_powerup->got_proc = gGot_procs[action_index];
351
            the_powerup->lose_proc = gLose_procs[action_index];
352
            the_powerup->periodic_proc = gPeriodic_procs[action_index];
353
        } else {
354
            the_powerup->lose_proc = NULL;
355
            the_powerup->periodic_proc = NULL;
356
            the_powerup->got_proc = NULL;
357
        }
358
        the_powerup->number_of_float_params = GetAnInt(f);
359
        the_powerup->float_params = BrMemAllocate(sizeof(float) * the_powerup->number_of_float_params, kMem_powerup_float_parms);
360
        for (j = 0; j < the_powerup->number_of_float_params; j++) {
361
            the_powerup->float_params[j] = GetAFloat(f);
362
        }
363
        the_powerup->number_of_integer_params = GetAnInt(f);
364
        the_powerup->integer_params = BrMemAllocate(sizeof(int) * the_powerup->number_of_integer_params, kMem_powerup_int_parms);
365
        for (j = 0; j < the_powerup->number_of_integer_params; j++) {
366
            the_powerup->integer_params[j] = GetAnInt(f);
367
        }
368
        the_powerup->group_inclusion = GetAnInt(f);
369
        the_powerup->prat_cam_event = GetAnInt(f);
370
        the_powerup->net_type = GetAnInt(f);
371
    }
372
    fclose(f);
373
}
374
 
375
// IDA: void __cdecl InitPowerups()
376
void InitPowerups(void) {
377
    int i;
378
    tPowerup* the_powerup;
379
    LOG_TRACE("()");
380
 
381
    for (i = 0, the_powerup = gPowerup_array; i < gNumber_of_powerups; i++, the_powerup++) {
382
        the_powerup->got_time = 0;
383
        the_powerup->current_value = -1;
384
    }
385
}
386
 
387
// IDA: void __cdecl CloseDownPowerUps()
388
void CloseDownPowerUps(void) {
389
    int i;
390
    tPowerup* the_powerup;
391
    LOG_TRACE("()");
392
 
393
    for (i = 0, the_powerup = gPowerup_array; i < gNumber_of_powerups; i++, the_powerup++) {
394
        if (the_powerup->got_time != 0) {
395
            LosePowerup(the_powerup);
396
        }
397
    }
398
}
399
 
400
// IDA: void __usercall DrawPowerups(tU32 pTime@<EAX>)
401
void DrawPowerups(tU32 pTime) {
402
    int i;
403
    int y;
404
    int timer;
405
    tPowerup* the_powerup;
406
    char s[8];
407
    tHeadup_icon* the_icon;
408
    br_pixelmap* fizzle_pix;
409
    LOG_TRACE("(%d)", pTime);
410
 
411
    y = gCurrent_graf_data->power_up_icon_y;
412
    for (i = 0; i < gNumber_of_icons && i < 5; i++) {
413
        the_icon = &gIcon_list[i];
414
        the_powerup = the_icon->powerup;
415
        if (the_powerup->icon == NULL) {
416
            continue;
417
        }
418
        y += gCurrent_graf_data->power_up_icon_y_pitch;
419
        if (the_icon->fizzle_stage < 4) {
420
            if (the_icon->fizzle_direction >= 0) {
421
                the_icon->fizzle_stage = (pTime - the_icon->fizzle_start) / 100;
422
            } else {
423
                the_icon->fizzle_stage = 3 - (pTime - the_icon->fizzle_start) / 100;
424
            }
425
            if (the_icon->fizzle_stage >= 5) {
426
                the_icon->fizzle_stage = 4;
427
            } else if (the_icon->fizzle_stage < 0) {
428
                memmove(the_icon, the_icon + 1, sizeof(tHeadup_icon) * (gNumber_of_icons - i - 1));
429
                gNumber_of_icons--;
430
                continue;
431
            }
432
        }
433
        if (the_icon->fizzle_stage >= 4) {
434
            DRPixelmapRectangleMaskedCopy(gBack_screen,
435
                gCurrent_graf_data->power_up_icon_x, y,
436
                the_powerup->icon, 0, 0, the_powerup->icon->width, the_powerup->icon->height);
437
            if (the_powerup->type == ePowerup_timed) {
438
                timer = the_powerup->lose_time - pTime;
439
                if (timer <= 0) {
440
                    timer = 0;
441
                }
442
                TimerString(timer, s, 0, 0);
443
                TransDRPixelmapText(gBack_screen,
444
                    gCurrent_graf_data->power_up_icon_countdown_x,
445
                    y + gCurrent_graf_data->power_up_icon_countdown_y_offset,
11 pmbaty 446
                    &gFonts[kFont_ORANGHED], s, gCurrent_graf_data->power_up_icon_countdown_x + 30);
1 pmbaty 447
            } else if (the_powerup->current_value > 0) {
448
                sprintf(s, "%d", the_powerup->current_value);
449
                TransDRPixelmapText(gBack_screen,
450
                    gCurrent_graf_data->power_up_icon_countdown_x,
451
                    y + gCurrent_graf_data->power_up_icon_countdown_y_offset,
11 pmbaty 452
                    &gFonts[kFont_BLUEHEAD], s, gCurrent_graf_data->power_up_icon_countdown_x + 30);
1 pmbaty 453
            }
454
        } else {
455
            fizzle_pix = gFizzle_in[the_powerup->fizzle_type];
456
            DRPixelmapRectangleMaskedCopy(gBack_screen,
457
                gCurrent_graf_data->power_up_icon_x, y, fizzle_pix, 0,
458
                the_icon->fizzle_stage * gFizzle_height, fizzle_pix->width, gFizzle_height);
459
        }
460
    }
461
}
462
 
463
// IDA: void __usercall DoPowerupPeriodics(tU32 pFrame_period@<EAX>)
464
void DoPowerupPeriodics(tU32 pFrame_period) {
465
    int i;
466
    tPowerup* the_powerup;
467
    tU32 the_time;
468
    LOG_TRACE("(%d)", pFrame_period);
469
 
470
    the_time = GetTotalTime();
471
    for (i = 0, the_powerup = gPowerup_array; i < gNumber_of_powerups; i++, the_powerup++) {
472
        if (the_powerup->got_time != 0) {
473
            if (the_powerup->type == ePowerup_timed && the_powerup->lose_time <= the_time) {
474
                LosePowerup(the_powerup);
475
            } else if (the_powerup->current_value == 0) {
476
                LosePowerup(the_powerup);
477
            } else if (the_powerup->periodic_proc != NULL) {
478
                the_powerup->periodic_proc(the_powerup, pFrame_period);
479
            }
480
        }
481
    }
482
}
483
 
484
// IDA: void __usercall GotPowerupN(int pN@<EAX>)
485
void GotPowerupN(int pN) {
486
    int modifiers;
487
    LOG_TRACE("(%d)", pN);
488
 
489
    modifiers = 0;
490
    if (PDKeyDown(KEY_SHIFT_ANY) != 0) {
491
        modifiers += 10;
492
    }
493
    if (PDKeyDown(KEY_ALT_ANY) != 0) {
494
        modifiers += 20;
495
    }
496
    if (PDKeyDown(KEY_CTRL_ANY) != 0) {
497
        modifiers += 40;
498
    }
499
    GotPowerup(&gProgram_state.current_car, modifiers + pN);
500
}
501
 
502
// IDA: void __cdecl GotPowerup0()
503
void GotPowerup0(void) {
504
    LOG_TRACE("()");
505
 
506
    GotPowerupN(0);
507
}
508
 
509
// IDA: void __cdecl GotPowerup1()
510
void GotPowerup1(void) {
511
    LOG_TRACE("()");
512
 
513
    GotPowerupN(1);
514
}
515
 
516
// IDA: void __cdecl GotPowerup2()
517
void GotPowerup2(void) {
518
    LOG_TRACE("()");
519
 
520
    GotPowerupN(2);
521
}
522
 
523
// IDA: void __cdecl GotPowerup3()
524
void GotPowerup3(void) {
525
    LOG_TRACE("()");
526
 
527
    GotPowerupN(3);
528
}
529
 
530
// IDA: void __cdecl GotPowerup4()
531
void GotPowerup4(void) {
532
    LOG_TRACE("()");
533
 
534
    GotPowerupN(4);
535
}
536
 
537
// IDA: void __cdecl GotPowerup5()
538
void GotPowerup5(void) {
539
    LOG_TRACE("()");
540
 
541
    GotPowerupN(5);
542
}
543
 
544
// IDA: void __cdecl GotPowerup6()
545
void GotPowerup6(void) {
546
    LOG_TRACE("()");
547
 
548
    GotPowerupN(6);
549
}
550
 
551
// IDA: void __cdecl GotPowerup7()
552
void GotPowerup7(void) {
553
    LOG_TRACE("()");
554
 
555
    GotPowerupN(7);
556
}
557
 
558
// IDA: void __cdecl GotPowerup8()
559
void GotPowerup8(void) {
560
    LOG_TRACE("()");
561
 
562
    GotPowerupN(8);
563
}
564
 
565
// IDA: void __cdecl GotPowerup9()
566
void GotPowerup9(void) {
567
    LOG_TRACE("()");
568
 
569
    GotPowerupN(9);
570
}
571
 
572
// IDA: int __usercall GotCredits@<EAX>(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
573
int GotCredits(tPowerup* pPowerup, tCar_spec* pCar) {
574
    //int credits; // Pierre-Marie Baty -- unused variable
575
    char s[256];
576
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
577
 
578
    if (pCar->driver == eDriver_local_human) {
579
        strcpy(s, pPowerup->message);
580
        strcat(s, " ");
581
        EarnCredits2((IRandomBetween(pPowerup->integer_params[0], pPowerup->integer_params[1]) / 100) * 100, s);
582
    }
583
    return GET_POWERUP_INDEX(pPowerup);
584
}
585
 
586
// IDA: void __usercall ImprovePSPowerup(tCar_spec *pCar@<EAX>, int pIndex@<EDX>)
587
void ImprovePSPowerup(tCar_spec* pCar, int pIndex) {
588
    //tNet_message* the_message; // Pierre-Marie Baty -- unused variable
589
    LOG_TRACE("(%p, %d)", pCar, pIndex);
590
 
591
    pCar->power_up_levels[pIndex]++;
21 pmbaty 592
    NewTextHeadupSlot(eHeadupSlot_misc, 0, 3000, -4, GetMiscString(kMiscString_APOGained_START + pIndex));
1 pmbaty 593
}
594
 
595
// IDA: int __usercall GotTimeOrPower@<EAX>(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
596
int GotTimeOrPower(tPowerup* pPowerup, tCar_spec* pCar) {
597
    int time;
598
    int index;
599
    int i;
600
    int not_allowed_power;
601
    //char s[256]; // Pierre-Marie Baty -- unused variable
602
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
603
 
604
    if (gNet_mode == eNet_mode_none) {
605
        if (pCar->driver == eDriver_local_human) {
606
            time = IRandomBetween(pPowerup->integer_params[0], pPowerup->integer_params[1]);
607
            AwardTime(time);
608
        }
609
    } else {
610
        not_allowed_power = (gCurrent_net_game->type == eNet_game_type_foxy && gThis_net_player_index == gIt_or_fox)
611
            || (gCurrent_net_game->type == eNet_game_type_tag && gThis_net_player_index != gIt_or_fox);
612
        if (pCar->power_up_levels[0] < 4 || (pCar->power_up_levels[1] < 4 && !not_allowed_power) || pCar->power_up_levels[2] < 4) {
613
            for (i = 0; i < 50; i++) {
614
                if (not_allowed_power) {
615
                    index = PercentageChance(50) ? 0 : 2;
616
                } else {
617
                    index = IRandomBetween(0, 2);
618
                }
619
                if (pCar->power_up_levels[index] < 4) {
620
                    ImprovePSPowerup(pCar, index);
621
                    break;
622
                }
623
            }
624
        } else {
21 pmbaty 625
            NewTextHeadupSlot(eHeadupSlot_misc, 0, 3000, -4, GetMiscString(kMiscString_YOU_ARE_ALREADY_AT_MAX));
1 pmbaty 626
        }
627
    }
628
    return GET_POWERUP_INDEX(pPowerup);
629
}
630
 
631
// IDA: int __usercall SetPedSpeed@<EAX>(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
632
int SetPedSpeed(tPowerup* pPowerup, tCar_spec* pCar) {
633
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
634
 
635
    gPedestrian_speed_factor = pPowerup->float_params[0];
636
    return GET_POWERUP_INDEX(pPowerup);
637
}
638
 
639
// IDA: int __usercall SetHades@<EAX>(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
640
int SetHades(tPowerup* pPowerup, tCar_spec* pCar) {
641
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
642
 
643
    PedMaterialFromHell();
644
    return GET_POWERUP_INDEX(pPowerup);
645
}
646
 
647
// IDA: void __usercall ResetHades(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
648
void ResetHades(tPowerup* pPowerup, tCar_spec* pCar) {
649
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
650
 
651
    ResetPedMaterial();
652
}
653
 
654
// IDA: int __usercall SetPedSize@<EAX>(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
655
int SetPedSize(tPowerup* pPowerup, tCar_spec* pCar) {
656
    br_scalar old_scale;
657
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
658
 
659
    old_scale = gPed_scale_factor;
660
    if (old_scale != pPowerup->float_params[0]) {
661
        if (gPed_scale_factor > 1.f) {
662
            gPed_scale_factor = pPowerup->float_params[0];
663
            PipeSingleSpecial(ePipe_special_giant_ped_off);
664
        } else {
665
            gPed_scale_factor = pPowerup->float_params[0];
666
            if (old_scale < 1.f) {
667
                PipeSingleSpecial(ePipe_special_min_ped_off);
668
            }
669
        }
670
        if (gPed_scale_factor > 1.f) {
671
            PipeSingleSpecial(ePipe_special_giant_ped_on);
672
            old_scale = gPed_scale_factor;
673
        } else {
674
            old_scale = gPed_scale_factor;
675
            if (gPed_scale_factor < 1.f) {
676
                PipeSingleSpecial(ePipe_special_min_ped_on);
677
                old_scale = gPed_scale_factor;
678
            }
679
        }
680
    }
681
    gPed_scale_factor = old_scale;
682
    return GET_POWERUP_INDEX(pPowerup);
683
}
684
 
685
// IDA: int __usercall SetPedExplode@<EAX>(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
686
int SetPedExplode(tPowerup* pPowerup, tCar_spec* pCar) {
687
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
688
 
689
    gExploding_pedestrians = 1;
690
    return GET_POWERUP_INDEX(pPowerup);
691
}
692
 
693
// IDA: int __usercall SetInvulnerability@<EAX>(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
694
int SetInvulnerability(tPowerup* pPowerup, tCar_spec* pCar) {
695
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
696
 
697
    pCar->invulnerable = 1;
698
    return GET_POWERUP_INDEX(pPowerup);
699
}
700
 
701
// IDA: void __usercall ResetInvulnerability(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
702
void ResetInvulnerability(tPowerup* pPowerup, tCar_spec* pCar) {
703
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
704
 
705
    pCar->invulnerable = 0;
706
}
707
 
708
// IDA: int __usercall SetFreeRepairs@<EAX>(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
709
int SetFreeRepairs(tPowerup* pPowerup, tCar_spec* pCar) {
710
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
711
 
712
    if (pCar->driver == eDriver_local_human) {
713
        gFree_repairs = 1;
714
    }
715
    return GET_POWERUP_INDEX(pPowerup);
716
}
717
 
718
// IDA: void __usercall ResetFreeRepairs(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
719
void ResetFreeRepairs(tPowerup* pPowerup, tCar_spec* pCar) {
720
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
721
 
722
    if (pCar->driver == eDriver_local_human) {
723
        gFree_repairs = 0;
724
    }
725
}
726
 
727
// IDA: int __usercall SetBlindPedestrians@<EAX>(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
728
int SetBlindPedestrians(tPowerup* pPowerup, tCar_spec* pCar) {
729
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
730
 
731
    gBlind_pedestrians = 1;
732
    return GET_POWERUP_INDEX(pPowerup);
733
}
734
 
735
// IDA: void __usercall ResetBlindPedestrians(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
736
void ResetBlindPedestrians(tPowerup* pPowerup, tCar_spec* pCar) {
737
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
738
 
739
    gBlind_pedestrians = 0;
740
}
741
 
742
// IDA: int __usercall FreezeTimer@<EAX>(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
743
int FreezeTimer(tPowerup* pPowerup, tCar_spec* pCar) {
744
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
745
 
746
    if (pCar->driver == eDriver_local_human) {
747
        gFreeze_timer = !gFreeze_timer;
748
    }
749
    return GET_POWERUP_INDEX(pPowerup);
750
}
751
 
752
// IDA: void __usercall UnfreezeTimer(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
753
void UnfreezeTimer(tPowerup* pPowerup, tCar_spec* pCar) {
754
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
755
 
756
    if (pCar->driver == eDriver_local_human) {
757
        gFreeze_timer = 0;
758
    }
759
}
760
 
761
// IDA: int __usercall DoInstantRepair@<EAX>(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
762
int DoInstantRepair(tPowerup* pPowerup, tCar_spec* pCar) {
763
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
764
 
765
    if (pCar->driver == eDriver_local_human) {
766
        TotallyRepairCar();
767
    }
768
    return GET_POWERUP_INDEX(gPowerup_array);
769
}
770
 
771
// IDA: void __usercall ResetPedSpeed(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
772
void ResetPedSpeed(tPowerup* pPowerup, tCar_spec* pCar) {
773
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
774
 
775
    gPedestrian_speed_factor = 1.f;
776
}
777
 
778
// IDA: void __usercall ResetPedSize(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
779
void ResetPedSize(tPowerup* pPowerup, tCar_spec* pCar) {
780
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
781
 
782
    gPed_scale_factor = 1.f;
783
    PipeSingleSpecial(ePipe_special_giant_ped_off);
784
}
785
 
786
// IDA: void __usercall ResetPedExplode(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
787
void ResetPedExplode(tPowerup* pPowerup, tCar_spec* pCar) {
788
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
789
 
790
    gExploding_pedestrians = 0;
791
}
792
 
793
// IDA: int __usercall SetEngineFactor@<EAX>(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
794
int SetEngineFactor(tPowerup* pPowerup, tCar_spec* pCar) {
795
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
796
 
797
    pCar->engine_power_multiplier = pPowerup->float_params[0];
798
    pCar->grip_multiplier = pPowerup->float_params[1];
799
    SetCarSuspGiveAndHeight(pCar, pPowerup->float_params[2], pPowerup->float_params[3],
800
        pPowerup->float_params[6], pPowerup->float_params[4], pPowerup->float_params[5]);
801
    return GET_POWERUP_INDEX(pPowerup);
802
}
803
 
804
// IDA: int __usercall SetUnderwater@<EAX>(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
805
int SetUnderwater(tPowerup* pPowerup, tCar_spec* pCar) {
806
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
807
 
808
    pCar->underwater_ability = 1;
809
    return GET_POWERUP_INDEX(pPowerup);
810
}
811
 
812
// IDA: int __usercall TrashBodywork@<EAX>(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
813
int TrashBodywork(tPowerup* pPowerup, tCar_spec* pCar) {
814
    int i;
815
    //tCar_spec* c; // Pierre-Marie Baty -- unused variable
816
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
817
 
818
    for (i = 0; i < pCar->car_actor_count; i++) {
819
        TotallySpamTheModel(pCar, i, pCar->car_model_actors[i].actor, &pCar->car_model_actors[i].crush_data, 0.5f);
820
    }
821
    if (pCar->driver == eDriver_local_human) {
822
        DRS3StartSound2(gCar_outlet, 5000, 1, 255, 255, -1, -1);
823
        DRS3StartSound2(gCar_outlet, 5001, 1, 255, 255, -1, -1);
824
        DRS3StartSound2(gCar_outlet, 5002, 1, 255, 255, -1, -1);
825
    }
826
    return GET_POWERUP_INDEX(pPowerup);
827
}
828
 
829
// IDA: int __usercall TakeDrugs@<EAX>(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
830
int TakeDrugs(tPowerup* pPowerup, tCar_spec* pCar) {
831
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
832
 
833
    if (pCar->driver == eDriver_local_human) {
834
        if (gReal_render_palette == NULL) {
835
            gReal_render_palette = BrMemAllocate(sizeof(tU32) * 256, kMem_drugs_palette);
836
            memcpy(gReal_render_palette, gRender_palette->pixels, sizeof(tU32) * 256);
837
        }
838
        gOn_drugs = 1;
839
    }
840
    return GET_POWERUP_INDEX(pPowerup);
841
}
842
 
843
// IDA: void __usercall PaletteFuckedUpByDrugs(br_pixelmap *pPixelmap@<EAX>, int pOffset@<EDX>)
844
void PaletteFuckedUpByDrugs(br_pixelmap* pPixelmap, int pOffset) {
845
    int i;
846
    LOG_TRACE("(%p, %d)", pPixelmap, pOffset);
847
 
848
    ((tU32*)gRender_palette->pixels)[0] = gReal_render_palette[0];
849
    for (i = 1; i < 224; i++) {
850
        ((tU32*)gRender_palette->pixels)[i] = gReal_render_palette[(i + pOffset) & 0xff];
851
    }
852
    for (i = 224; i < 256; i++) {
853
        ((tU32*)gRender_palette->pixels)[i] = gReal_render_palette[i];
854
    }
855
}
856
 
857
// IDA: void __usercall TheEffectsOfDrugs(tPowerup *pPowerup@<EAX>, tU32 pPeriod@<EDX>)
858
void TheEffectsOfDrugs(tPowerup* pPowerup, tU32 pPeriod) {
859
    LOG_TRACE("(%p, %d)", pPowerup, pPeriod);
860
 
861
    PaletteFuckedUpByDrugs(gRender_palette, GetTotalTime() / 100);
862
    ResetPalette();
863
}
864
 
865
// IDA: int __usercall SetOpponentsSpeed@<EAX>(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
866
int SetOpponentsSpeed(tPowerup* pPowerup, tCar_spec* pCar) {
867
    int i;
868
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
869
 
870
    for (i = 0; i < gCurrent_race.number_of_racers && gCurrent_race.opponent_list[i].index != 29; i++) {
871
    }
872
    if (i < gCurrent_race.number_of_racers) {
873
        SetEngineFactor(gPowerup_array + 5, gCurrent_race.opponent_list[i].car_spec);
874
    }
875
    gOpponent_speed_factor = pPowerup->float_params[0];
876
    return GET_POWERUP_INDEX(pPowerup);
877
}
878
 
879
// IDA: int __usercall SetCopsSpeed@<EAX>(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
880
int SetCopsSpeed(tPowerup* pPowerup, tCar_spec* pCar) {
881
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
882
 
883
    gCop_speed_factor = pPowerup->float_params[0];
884
    return GET_POWERUP_INDEX(pPowerup);
885
}
886
 
887
// IDA: int __usercall SetGravity@<EAX>(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
888
int SetGravity(tPowerup* pPowerup, tCar_spec* pCar) {
889
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
890
 
891
    gGravity_multiplier = pPowerup->float_params[0];
892
    return GET_POWERUP_INDEX(pPowerup);
893
}
894
 
895
// IDA: int __usercall SetPinball@<EAX>(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
896
int SetPinball(tPowerup* pPowerup, tCar_spec* pCar) {
897
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
898
 
899
    gPinball_factor = pPowerup->float_params[0];
900
    return GET_POWERUP_INDEX(pPowerup);
901
}
902
 
903
// IDA: int __usercall SetWallclimb@<EAX>(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
904
int SetWallclimb(tPowerup* pPowerup, tCar_spec* pCar) {
905
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
906
 
907
    pCar->wall_climber_mode = 1;
908
    return GET_POWERUP_INDEX(pPowerup);
909
}
910
 
911
// IDA: int __usercall SetBouncey@<EAX>(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
912
int SetBouncey(tPowerup* pPowerup, tCar_spec* pCar) {
913
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
914
 
915
    pCar->bounce_rate = 1000.f / pPowerup->float_params[0];
916
    pCar->bounce_amount = pPowerup->float_params[1];
917
    pCar->last_bounce = 0;
918
    return GET_POWERUP_INDEX(pPowerup);
919
}
920
 
921
// IDA: int __usercall SetSuspension@<EAX>(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
922
int SetSuspension(tPowerup* pPowerup, tCar_spec* pCar) {
923
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
924
 
925
    SetCarSuspGiveAndHeight(pCar,
926
        pPowerup->float_params[0], pPowerup->float_params[1], pPowerup->float_params[4],
927
        pPowerup->float_params[2], pPowerup->float_params[3]);
928
    return GET_POWERUP_INDEX(pPowerup);
929
}
930
 
931
// IDA: int __usercall SetTyreGrip@<EAX>(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
932
int SetTyreGrip(tPowerup* pPowerup, tCar_spec* pCar) {
933
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
934
 
935
    pCar->grip_multiplier = pPowerup->float_params[0];
936
    return GET_POWERUP_INDEX(pPowerup);
937
}
938
 
939
// IDA: int __usercall SetDamageMultiplier@<EAX>(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
940
int SetDamageMultiplier(tPowerup* pPowerup, tCar_spec* pCar) {
941
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
942
 
943
    pCar->damage_multiplier = pPowerup->float_params[0];
944
    return GET_POWERUP_INDEX(pPowerup);
945
}
946
 
947
// IDA: void __usercall ResetEngineFactor(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
948
void ResetEngineFactor(tPowerup* pPowerup, tCar_spec* pCar) {
949
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
950
 
951
    pCar->engine_power_multiplier = 1.f;
952
    pCar->grip_multiplier = 1.f;
953
    SetCarSuspGiveAndHeight(pCar, 1.f, 1.f, 1.f, 0.f, 0.f);
954
}
955
 
956
// IDA: void __usercall ResetUnderwater(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
957
void ResetUnderwater(tPowerup* pPowerup, tCar_spec* pCar) {
958
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
959
 
960
    pCar->underwater_ability = 0;
961
}
962
 
963
// IDA: void __usercall PukeDrugsBackUp(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
964
void PukeDrugsBackUp(tPowerup* pPowerup, tCar_spec* pCar) {
965
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
966
 
967
    if (pCar->driver == eDriver_local_human) {
968
        gOn_drugs = 0;
969
        PaletteFuckedUpByDrugs(gRender_palette, 0);
970
        ResetPalette();
971
    }
972
}
973
 
974
// IDA: void __usercall ResetOpponentsSpeed(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
975
void ResetOpponentsSpeed(tPowerup* pPowerup, tCar_spec* pCar) {
976
    int i;
977
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
978
 
979
    for (i = 0; i < gCurrent_race.number_of_racers && gCurrent_race.opponent_list[i].index != 29; i++) {
980
    }
981
    if (i < gCurrent_race.number_of_racers) {
982
        ResetEngineFactor(&gPowerup_array[5], gCurrent_race.opponent_list[i].car_spec);
983
    }
984
    gOpponent_speed_factor = 1.f;
985
}
986
 
987
// IDA: void __usercall ResetCopsSpeed(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
988
void ResetCopsSpeed(tPowerup* pPowerup, tCar_spec* pCar) {
989
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
990
 
991
    gCop_speed_factor = 1.f;
992
}
993
 
994
// IDA: void __usercall ResetGravity(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
995
void ResetGravity(tPowerup* pPowerup, tCar_spec* pCar) {
996
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
997
 
998
    gGravity_multiplier = gDefault_gravity;
999
}
1000
 
1001
// IDA: void __usercall ResetPinball(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
1002
void ResetPinball(tPowerup* pPowerup, tCar_spec* pCar) {
1003
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
1004
 
1005
    gPinball_factor = 0.f;
1006
}
1007
 
1008
// IDA: void __usercall ResetWallclimb(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
1009
void ResetWallclimb(tPowerup* pPowerup, tCar_spec* pCar) {
1010
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
1011
 
1012
    pCar->wall_climber_mode = 0;
1013
}
1014
 
1015
// IDA: void __usercall ResetBouncey(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
1016
void ResetBouncey(tPowerup* pPowerup, tCar_spec* pCar) {
1017
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
1018
 
1019
    pCar->bounce_rate = 0.f;
1020
    pCar->bounce_amount = 0.f;
1021
}
1022
 
1023
// IDA: void __usercall ResetSuspension(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
1024
void ResetSuspension(tPowerup* pPowerup, tCar_spec* pCar) {
1025
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
1026
 
1027
    SetCarSuspGiveAndHeight(pCar, 1.f, 1.f, 1.f, 0.f, 0.f);
1028
}
1029
 
1030
// IDA: void __usercall ResetDamageMultiplier(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
1031
void ResetDamageMultiplier(tPowerup* pPowerup, tCar_spec* pCar) {
1032
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
1033
 
1034
    pCar->damage_multiplier = 1.f;
1035
}
1036
 
1037
// IDA: void __usercall ResetTyreGrip(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
1038
void ResetTyreGrip(tPowerup* pPowerup, tCar_spec* pCar) {
1039
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
1040
 
1041
    pCar->grip_multiplier = 1.f;
1042
    ;
1043
}
1044
 
1045
// IDA: int __usercall PickAtRandom@<EAX>(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
1046
int PickAtRandom(tPowerup* pPowerup, tCar_spec* pCar) {
1047
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
1048
 
1049
    return GotPowerup(pCar, pPowerup->integer_params[IRandomBetween(0, pPowerup->number_of_integer_params - 1)]);
1050
}
1051
 
1052
// IDA: int __usercall PedestrianRespawn@<EAX>(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
1053
int PedestrianRespawn(tPowerup* pPowerup, tCar_spec* pCar) {
1054
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
1055
 
1056
    RespawnPedestrians();
1057
    return GET_POWERUP_INDEX(pPowerup);
1058
}
1059
 
1060
// IDA: int __usercall GotVouchers@<EAX>(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
1061
int GotVouchers(tPowerup* pPowerup, tCar_spec* pCar) {
1062
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
1063
 
1064
    if (pCar->driver == eDriver_local_human) {
1065
        AddVouchers(pPowerup->integer_params[0]);
1066
    }
1067
    return GET_POWERUP_INDEX(pPowerup);
1068
}
1069
 
1070
// IDA: void __usercall MungeVouchers(tPowerup *pPowerup@<EAX>, tU32 pPeriod@<EDX>)
1071
void MungeVouchers(tPowerup* pPowerup, tU32 pPeriod) {
1072
    LOG_TRACE("(%p, %d)", pPowerup, pPeriod);
1073
 
1074
    pPowerup->current_value = GetRecoverVoucherCount();
1075
}
1076
 
1077
// IDA: int __usercall SetInstantHandbrake@<EAX>(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
1078
int SetInstantHandbrake(tPowerup* pPowerup, tCar_spec* pCar) {
1079
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
1080
 
1081
    if (pCar->driver == eDriver_local_human) {
1082
        gInstant_handbrake = 1;
1083
    }
1084
    return GET_POWERUP_INDEX(pPowerup);
1085
}
1086
 
1087
// IDA: void __usercall ResetInstantHandbrake(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
1088
void ResetInstantHandbrake(tPowerup* pPowerup, tCar_spec* pCar) {
1089
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
1090
 
1091
    if (pCar->driver == eDriver_local_human) {
1092
        gInstant_handbrake = 0;
1093
    }
1094
}
1095
 
1096
// IDA: void __usercall DoBouncey(tPowerup *pPowerup@<EAX>, tU32 pPeriod@<EDX>)
1097
void DoBouncey(tPowerup* pPowerup, tU32 pPeriod) {
1098
    LOG_TRACE("(%p, %d)", pPowerup, pPeriod);
1099
 
1100
    if (gProgram_state.current_car.bounce_rate <= GetTotalTime() - gProgram_state.current_car.last_bounce && gProgram_state.current_car.number_of_wheels_on_ground > 2) {
1101
        PratcamEvent(42);
1102
        gProgram_state.current_car.last_bounce = GetTotalTime();
1103
        gProgram_state.current_car.v.v[1] += gProgram_state.current_car.bounce_amount;
1104
        DRS3StartSound(gCar_outlet, 9010);
1105
    }
1106
}
1107
 
1108
// IDA: int __usercall HitMine@<EAX>(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
1109
int HitMine(tPowerup* pPowerup, tCar_spec* pCar) {
1110
    int i;
1111
    float fudge_multiplier;
1112
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
1113
 
1114
    pCar->v.v[1] = FRandomBetween(pPowerup->float_params[0], pPowerup->float_params[1]) / pCar->M + pCar->v.v[1];
1115
    pCar->omega.v[2] = FRandomPosNeg(pPowerup->float_params[2]) * TAU / pCar->M + pCar->omega.v[2];
1116
    pCar->omega.v[0] = FRandomPosNeg(pPowerup->float_params[3]) * TAU / pCar->M + pCar->omega.v[0];
1117
    if (pCar->driver != eDriver_non_car_unused_slot && !pCar->invulnerable) {
1118
        fudge_multiplier = pCar->car_model_actors[pCar->principal_car_actor].crush_data.softness_factor / .7f;
1119
        for (i = 0; i < pCar->car_actor_count; i++) {
1120
            TotallySpamTheModel(pCar, i, pCar->car_model_actors[i].actor,
1121
                &pCar->car_model_actors[i].crush_data, fudge_multiplier * .1f);
1122
        }
1123
        for (i = 0; i < 12; i++) {
1124
            DamageUnit(pCar, i, IRandomBetween(0, fudge_multiplier * 15.f));
1125
        }
1126
    }
1127
    return GET_POWERUP_INDEX(pPowerup);
1128
}
1129
 
1130
// IDA: int __usercall SetMassMultiplier@<EAX>(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
1131
int SetMassMultiplier(tPowerup* pPowerup, tCar_spec* pCar) {
1132
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
1133
 
1134
    pCar->collision_mass_multiplier = pPowerup->float_params[0];
1135
    return GET_POWERUP_INDEX(pPowerup);
1136
}
1137
 
1138
// IDA: void __usercall ResetMassMultiplier(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
1139
void ResetMassMultiplier(tPowerup* pPowerup, tCar_spec* pCar) {
1140
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
1141
 
1142
    pCar->collision_mass_multiplier = 1.f;
1143
}
1144
 
1145
// IDA: int __usercall ShowPedestrians@<EAX>(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
1146
int ShowPedestrians(tPowerup* pPowerup, tCar_spec* pCar) {
1147
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
1148
 
1149
    if (pCar->driver == eDriver_local_human) {
1150
        gShow_peds_on_map = 1;
1151
    }
1152
    return GET_POWERUP_INDEX(pPowerup);
1153
}
1154
 
1155
// IDA: void __usercall HidePedestrians(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
1156
void HidePedestrians(tPowerup* pPowerup, tCar_spec* pCar) {
1157
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
1158
 
1159
    if (pCar->driver == eDriver_local_human) {
1160
        gShow_peds_on_map = 0;
1161
    }
1162
}
1163
 
1164
// IDA: int __usercall SetProximity@<EAX>(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
1165
int SetProximity(tPowerup* pPowerup, tCar_spec* pCar) {
1166
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
1167
 
1168
    pCar->proxy_ray_distance = pPowerup->float_params[0] * pPowerup->float_params[0];
1169
    return GET_POWERUP_INDEX(pPowerup);
1170
}
1171
 
1172
// IDA: void __usercall ResetProximity(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
1173
void ResetProximity(tPowerup* pPowerup, tCar_spec* pCar) {
1174
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
1175
 
1176
    pCar->proxy_ray_distance = 0.f;
1177
}
1178
 
1179
// IDA: int __usercall SetPedHarvest@<EAX>(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
1180
int SetPedHarvest(tPowerup* pPowerup, tCar_spec* pCar) {
1181
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
1182
 
1183
    gPedestrian_harvest = 1;
1184
    return GET_POWERUP_INDEX(pPowerup);
1185
}
1186
 
1187
// IDA: void __usercall ResetPedHarvest(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
1188
void ResetPedHarvest(tPowerup* pPowerup, tCar_spec* pCar) {
1189
    int i;
1190
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
1191
 
1192
    gPedestrian_harvest = 0;
1193
    for (i = 0; i < COUNT_OF(gPed_harvest_sounds); i++) {
1194
        DRS3StartSound3D(gPedestrians_outlet, gPed_harvest_sounds[i], &pCar->pos,
1195
            &gZero_v__powerup, 1, 255, -1, -1);
1196
    }
1197
}
1198
 
1199
// IDA: int __usercall SetVesuvianCorpses@<EAX>(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
1200
int SetVesuvianCorpses(tPowerup* pPowerup, tCar_spec* pCar) {
1201
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
1202
 
1203
    gVesuvian_corpses = 1;
1204
    return GET_POWERUP_INDEX(pPowerup);
1205
}
1206
 
1207
// IDA: void __usercall ResetVesuvianCorpses(tPowerup *pPowerup@<EAX>, tCar_spec *pCar@<EDX>)
1208
void ResetVesuvianCorpses(tPowerup* pPowerup, tCar_spec* pCar) {
1209
    LOG_TRACE("(%p, %p)", pPowerup, pCar);
1210
 
1211
    gVesuvian_corpses = 0;
1212
}
1213
 
1214
// IDA: void __usercall ReceivedPowerup(tNet_contents *pContents@<EAX>)
1215
void ReceivedPowerup(tNet_contents* pContents) {
1216
    tPowerup* powerup;
1217
    tCar_spec* car;
1218
    LOG_TRACE("(%p)", pContents);
1219
 
1220
    if (gProgram_state.racing && pContents->data.powerup.powerup_index >= 0 && pContents->data.powerup.powerup_index < gNumber_of_powerups) {
1221
        powerup = &gPowerup_array[pContents->data.powerup.powerup_index];
1222
        if (pContents->data.powerup.event == ePowerup_gained || pContents->data.powerup.event == ePowerup_ongoing) {
1223
            if (powerup->net_type == eNet_powerup_global) {
1224
                GotPowerupX(&gProgram_state.current_car, pContents->data.powerup.powerup_index, 0,
1225
                    pContents->data.powerup.event == ePowerup_gained, pContents->data.powerup.time_left);
1226
            } else if (powerup->net_type == eNet_powerup_local && pContents->data.powerup.player != gLocal_net_ID && powerup->got_proc != NULL) {
1227
                car = NetCarFromPlayerID(pContents->data.powerup.player);
1228
                if (car != NULL) {
1229
                    powerup->got_proc(powerup, car);
1230
                    switch (powerup->type) {
1231
                    case ePowerup_timed:
1232
                        car->powerups[pContents->data.powerup.powerup_index] = GetTotalTime() + pContents->data.powerup.time_left;
1233
                        break;
1234
                    case ePowerup_whole_race:
1235
                        car->powerups[pContents->data.powerup.powerup_index] = -1;
1236
                        break;
1237
                    default:
1238
                        break;
1239
                    }
1240
                }
1241
            }
1242
        } else if (powerup->net_type == eNet_powerup_local && powerup->lose_proc != NULL) {
1243
            car = NetCarFromPlayerID(pContents->data.powerup.player);
1244
            if (car != NULL) {
1245
                powerup->lose_proc(powerup, car);
1246
                car->powerups[pContents->data.powerup.powerup_index] = 0;
1247
            }
1248
        }
1249
    }
1250
}
1251
 
1252
// IDA: void __cdecl SendCurrentPowerups()
1253
void SendCurrentPowerups(void) {
1254
    int i;
1255
    int cat;
1256
    int j;
1257
    int car_count;
1258
    tCar_spec* car;
1259
    tNet_contents* the_contents;
1260
    tPlayer_ID ID;
1261
    LOG_TRACE("()");
1262
 
1263
    for (cat = eVehicle_self; cat < eVehicle_net_player; cat++) {
1264
        if (cat == eVehicle_self) {
1265
            car_count = 1;
1266
        } else {
1267
            car_count = GetCarCount(cat);
1268
        }
1269
        for (i = 0; i < car_count; i++) {
1270
            if (cat == eVehicle_self) {
1271
                car = &gProgram_state.current_car;
1272
            } else {
1273
                car = GetCarSpec(cat, i);
1274
            }
1275
#if defined(DETHRACE_FIX_BUGS)
1276
            ID = gNet_players[0].ID;
1277
#endif
1278
            for (j = 0; j < gNumber_of_net_players; j++) {
1279
                if (gNet_players[j].car == car) {
1280
                    ID = gNet_players[j].ID;
1281
                    break;
1282
                }
1283
            }
1284
            for (j = 0; j < gNumber_of_powerups; j++) {
1285
                if (car->powerups[j] != 0) {
1286
                    the_contents = NetGetBroadcastContents(21, 0);
1287
                    the_contents->data.powerup.event = ePowerup_ongoing;
1288
                    the_contents->data.powerup.player = ID;
1289
                    the_contents->data.powerup.powerup_index = j;
1290
                    the_contents->data.powerup.time_left = car->powerups[i] - GetTotalTime();
1291
                }
1292
            }
1293
        }
1294
    }
1295
}
1296
 
1297
// IDA: void __usercall LoseAllLocalPowerups(tCar_spec *pCar@<EAX>)
1298
void LoseAllLocalPowerups(tCar_spec* pCar) {
1299
    int i;
1300
    LOG_TRACE("(%p)", pCar);
1301
 
1302
    if (pCar->driver == eDriver_local_human) {
1303
        for (i = 0; i < gNumber_of_powerups; i++) {
1304
            if (pCar->powerups[i] != 0 && gPowerup_array[i].net_type == eNet_powerup_local) {
1305
                LosePowerup(&gPowerup_array[i]);
1306
            }
1307
        }
1308
    }
1309
}
1310
 
1311
// Added by dethrace
1312
void GetPowerupMessage(int pN, char* pMessage) {
1313
    switch (pN) {
1314
    case 0:
1315
        strcpy(pMessage, "Bonus");
1316
        break;
1317
    case 1:
1318
        strcpy(pMessage, "Mega Bonus");
1319
        break;
1320
    case 14:
1321
    case 46:
1322
        strcpy(pMessage, "Mine");
1323
        break;
1324
    case 28:
1325
    case 29:
1326
    case 30:
1327
    case 31:
1328
        strcpy(pMessage, "Random");
1329
        break;
1330
    default:
1331
        strcpy(pMessage, gPowerup_array[pN].message);
1332
        break;
1333
    }
1334
}