4b825dc642cb6eb9a060e54bf8d69288fbee490494a6641b73026d662261604d7d192beae70b11dc
 
 
1
#include "system.h"
 
 
2
#include "prototyp.h"
 
 
3
#include "stratdef.h"
 
 
4
#include "bh_types.h"
 
 
5
#include "dynamics.h"
 
 
6
#include "weapons.h"
 
 
7
#include "pheromon.h"
 
 
8
#include "scream.h"
 
 
9
#include "savegame.h"
 
 
10
#include "pfarlocs.h"
 
 
11
#include "bh_ais.h"
 
 
12
#include "game_statistics.h"
 
 
13
#include "psndplat.h"
 
 
14
#include "pldghost.h"
 
 
15
#include "frustum.h"
 
 
16
#include <assert.h>
 
 
17
#include <stdlib.h>
 
 
18
#include <stdio.h>
 
 
19
#include "usr_io.h"
 
 
20
#include "userprofile.h"
 
 
21
#include "corpse.h"
 
 
22
#include "sequnces.h"
 
 
23
#include "extents.h"
 
 
24
#include "hud.h"
 
 
25
 
 
 
26
PLAYER_INPUT_CONFIGURATION *primaryInput;
 
 
27
PLAYER_INPUT_CONFIGURATION *secondaryInput;
 
 
28
 
 
 
29
extern void InitialiseGrapplingHook();
 
 
30
 
 
 
31
extern int Keyboard_input_operate();
 
 
32
extern void handle_user_input();
 
 
33
extern unsigned int mission_messages_timer;
 
 
34
extern char * mission_messages;
 
 
35
extern HMODELCONTROLLER PlayersWeaponHModelController;
 
 
36
extern int predHUDSoundHandle;
 
 
37
extern int predOVision_SoundHandle;
 
 
38
extern int weaponHandle;
 
 
39
extern int AVPDPNetID;
 
 
40
extern int myNetworkKillerId;
 
 
41
extern int MyHitBodyPartId;
 
 
42
extern int MultiplayerObservedPlayer;
 
 
43
extern int PlayersMaxHeightWhilstNotInContactWithGround;
 
 
44
 
 
 
45
const SECTION * GetNamedHierarchyFromLibrary(const char * rif_name, const char *);
 
 
46
extern int SlotForThisWeapon(enum WEAPON_ID weaponID);
 
 
47
extern void LoadAllWeapons();
 
 
48
extern void DisengageGrapplingHook();
 
 
49
extern int LightIntensityAtPoint(VECTORCH *pointPtr);
 
 
50
extern void PointAlert(int level, VECTORCH *point);
 
 
51
extern void InitMarineHUD();
 
 
52
 
 
 
53
PLAYER_STATUS PlayerStatus;
 
 
54
int AlienTeethOffset = 0;
 
 
55
int AlienTongueOffset = 0;
 
 
56
int deathFadeLevel;
 
 
57
int CloakingPhase;
 
 
58
EULER HeadOrientation = {0,0,0};
 
 
59
 
 
 
60
extern int TURNSCALE;
 
 
61
int ALIEN_STRAFESCALE;
 
 
62
int PREDATOR_STRAFESCALE;
 
 
63
int MARINE_STRAFESCALE;
 
 
64
 
 
 
65
static void InitialisePlayersInventory()
 
 
66
{
 
 
67
    int a;
 
 
68
 
 
 
69
    switch(AvP.PlayerType)
 
 
70
    {
 
 
71
        case I_Marine:
 
 
72
        {
 
 
73
            GrenadeLauncherData.StandardRoundsRemaining = 0;    
 
 
74
            GrenadeLauncherData.StandardMagazinesRemaining = 0;
 
 
75
            GrenadeLauncherData.ProximityRoundsRemaining = 0;
 
 
76
            GrenadeLauncherData.ProximityMagazinesRemaining = 0;
 
 
77
            GrenadeLauncherData.FragmentationRoundsRemaining = 0;
 
 
78
            GrenadeLauncherData.FragmentationMagazinesRemaining = 0;
 
 
79
            GrenadeLauncherData.SelectedAmmo = AMMO_GRENADE;
 
 
80
 
 
 
81
            PlayerStatus.JetpackEnabled = PlayerStatus.StartingEquipment.marine_jetpack;
 
 
82
 
 
 
83
            a = SlotForThisWeapon(WEAPON_CUDGEL);
 
 
84
 
 
 
85
            if (a != -1)
 
 
86
                PlayerStatus.WeaponSlot[a].Possessed = 1;
 
 
87
 
 
 
88
            /*if in a multiplayer game , check to see if player is a specialist marine*/
 
 
89
            if(SinglePlayer != AvP.PlayMode)
 
 
90
            {
 
 
91
                if (netGameData.specialistPistols)
 
 
92
                {
 
 
93
                    /* Conditional pistol! */
 
 
94
                    a = SlotForThisWeapon(WEAPON_MARINE_PISTOL);
 
 
95
 
 
 
96
                    if (a != -1)
 
 
97
                    {
 
 
98
                        PlayerStatus.WeaponSlot[a].Possessed = 1;
 
 
99
                        PlayerStatus.WeaponSlot[a].MagazinesRemaining = 6;
 
 
100
                    }
 
 
101
                }
 
 
102
 
 
 
103
                switch(netGameData.myCharacterSubType)
 
 
104
                {
 
 
105
                    case NGSCT_Smartgun:
 
 
106
                        a = SlotForThisWeapon(WEAPON_SMARTGUN);
 
 
107
                        PlayerStatus.WeaponSlot[a].Possessed = 1;
 
 
108
 
 
 
109
                        PlayerStatus.WeaponSlot[a].MagazinesRemaining = 6;
 
 
110
                    break;
 
 
111
                    case NGSCT_Flamer:
 
 
112
                        a = SlotForThisWeapon(WEAPON_FLAMETHROWER);
 
 
113
                        PlayerStatus.WeaponSlot[a].Possessed = 1;
 
 
114
 
 
 
115
                        PlayerStatus.WeaponSlot[a].MagazinesRemaining = 8;
 
 
116
                    break;
 
 
117
                    case NGSCT_Sadar:
 
 
118
                        a = SlotForThisWeapon(WEAPON_SADAR);
 
 
119
                        PlayerStatus.WeaponSlot[a].Possessed = 1;
 
 
120
 
 
 
121
                        PlayerStatus.WeaponSlot[a].PrimaryRoundsRemaining = 10;
 
 
122
                    break;
 
 
123
                    case NGSCT_GrenadeLauncher:
 
 
124
                        a = SlotForThisWeapon(WEAPON_GRENADELAUNCHER);
 
 
125
                        PlayerStatus.WeaponSlot[a].Possessed = 1;
 
 
126
 
 
 
127
                        PlayerStatus.WeaponSlot[a].MagazinesRemaining = 4;
 
 
128
                        GrenadeLauncherData.StandardMagazinesRemaining = 4;
 
 
129
                        GrenadeLauncherData.ProximityMagazinesRemaining = 4;
 
 
130
                        GrenadeLauncherData.FragmentationMagazinesRemaining = 4;
 
 
131
                    break;
 
 
132
                    case NGSCT_Minigun:
 
 
133
                        a = SlotForThisWeapon(WEAPON_MINIGUN);
 
 
134
                        PlayerStatus.WeaponSlot[a].Possessed = 1;
 
 
135
 
 
 
136
                        PlayerStatus.WeaponSlot[a].MagazinesRemaining = 4;
 
 
137
                    break;
 
 
138
                    case NGSCT_PulseRifle:
 
 
139
                        a = SlotForThisWeapon(WEAPON_PULSERIFLE);
 
 
140
                        PlayerStatus.WeaponSlot[a].Possessed = 1;
 
 
141
 
 
 
142
                        PlayerStatus.WeaponSlot[a].MagazinesRemaining = 10;
 
 
143
                        PlayerStatus.WeaponSlot[a].SecondaryRoundsRemaining = 15;
 
 
144
                    break;
 
 
145
                    case NGSCT_Frisbee:
 
 
146
                        a = SlotForThisWeapon(WEAPON_FRISBEE_LAUNCHER);
 
 
147
                        PlayerStatus.WeaponSlot[a].Possessed = 1;
 
 
148
 
 
 
149
                        PlayerStatus.WeaponSlot[a].MagazinesRemaining = 5;
 
 
150
                    break;
 
 
151
                    case NGSCT_Pistols:
 
 
152
                        a = SlotForThisWeapon(WEAPON_MARINE_PISTOL);
 
 
153
 
 
 
154
                        if (a != -1)
 
 
155
                        {
 
 
156
                            PlayerStatus.WeaponSlot[a].Possessed = 1;
 
 
157
                            PlayerStatus.WeaponSlot[a].MagazinesRemaining = 30;
 
 
158
                        }
 
 
159
 
 
 
160
                        a = SlotForThisWeapon(WEAPON_TWO_PISTOLS);
 
 
161
 
 
 
162
                        if (a != -1)
 
 
163
                        {
 
 
164
                            PlayerStatus.WeaponSlot[a].Possessed = 1;
 
 
165
                            PlayerStatus.WeaponSlot[a].MagazinesRemaining = 30;
 
 
166
                        }
 
 
167
                    break;
 
 
168
                    case NGSCT_General:
 
 
169
                    default:
 
 
170
 
 
 
171
                        a = SlotForThisWeapon(WEAPON_PULSERIFLE);
 
 
172
                        PlayerStatus.WeaponSlot[a].Possessed = 1;
 
 
173
                        PlayerStatus.WeaponSlot[a].MagazinesRemaining = 6;
 
 
174
                        PlayerStatus.WeaponSlot[a].SecondaryRoundsRemaining = 5;
 
 
175
                }
 
 
176
            }
 
 
177
            else
 
 
178
            {
 
 
179
                a = SlotForThisWeapon(WEAPON_PULSERIFLE);
 
 
180
                PlayerStatus.WeaponSlot[a].Possessed = 1;
 
 
181
 
 
 
182
                if (CHEATMODE_GRENADE == UserProfile.active_bonus)
 
 
183
                {
 
 
184
                    PlayerStatus.WeaponSlot[a].MagazinesRemaining = 0;
 
 
185
                    PlayerStatus.WeaponSlot[a].SecondaryRoundsRemaining = 99;
 
 
186
                }
 
 
187
                else
 
 
188
                {
 
 
189
                    PlayerStatus.WeaponSlot[a].MagazinesRemaining = 4;
 
 
190
                    PlayerStatus.WeaponSlot[a].SecondaryRoundsRemaining = 4;
 
 
191
                }
 
 
192
            }
 
 
193
        }
 
 
194
            break;    
 
 
195
        case I_Predator:
 
 
196
        {
 
 
197
            PlayerStatus.GrapplingHookEnabled = PlayerStatus.StartingEquipment.predator_grappling_hook;    
 
 
198
 
 
 
199
            if(PlayerStatus.StartingEquipment.predator_pistol)
 
 
200
            {
 
 
201
                a = SlotForThisWeapon(WEAPON_PRED_PISTOL);
 
 
202
                PlayerStatus.WeaponSlot[a].Possessed = 1;
 
 
203
            }
 
 
204
 
 
 
205
            if(PlayerStatus.StartingEquipment.predator_num_spears)
 
 
206
            {
 
 
207
                a = SlotForThisWeapon(WEAPON_PRED_RIFLE);
 
 
208
                PlayerStatus.WeaponSlot[a].Possessed = 1;
 
 
209
                PlayerStatus.WeaponSlot[a].PrimaryRoundsRemaining = PlayerStatus.StartingEquipment.predator_num_spears;
 
 
210
            }
 
 
211
 
 
 
212
            if(PlayerStatus.StartingEquipment.predator_plasmacaster)
 
 
213
            {
 
 
214
                a = SlotForThisWeapon(WEAPON_PRED_SHOULDERCANNON);
 
 
215
                PlayerStatus.WeaponSlot[a].Possessed = 1;
 
 
216
            }
 
 
217
 
 
 
218
            if(PlayerStatus.StartingEquipment.predator_disc)
 
 
219
            {
 
 
220
                a = SlotForThisWeapon(WEAPON_PRED_DISC);
 
 
221
                PlayerStatus.WeaponSlot[a].Possessed = 1;
 
 
222
                PlayerStatus.WeaponSlot[a].PrimaryRoundsRemaining = 1;
 
 
223
            }
 
 
224
 
 
 
225
            if(PlayerStatus.StartingEquipment.predator_medicomp)
 
 
226
            {
 
 
227
                a = SlotForThisWeapon(WEAPON_PRED_MEDICOMP);
 
 
228
                PlayerStatus.WeaponSlot[a].Possessed = 1;
 
 
229
            }
 
 
230
 
 
 
231
            a = SlotForThisWeapon(WEAPON_PRED_WRISTBLADE);
 
 
232
            PlayerStatus.WeaponSlot[a].Possessed = 1;
 
 
233
        }
 
 
234
        break;
 
 
235
        case I_Alien:
 
 
236
        {
 
 
237
            a = SlotForThisWeapon(WEAPON_ALIEN_CLAW);
 
 
238
            PlayerStatus.WeaponSlot[a].Possessed = 1;
 
 
239
            PlayerStatus.SelectedWeapon = &PlayerStatus.WeaponSlot[a];
 
 
240
        return;
 
 
241
        }
 
 
242
    }
 
 
243
 
 
 
244
    PlayerStatus.PreviouslySelectedWeaponSlot = a;
 
 
245
        PlayerStatus.SwapToWeaponSlot = a;
 
 
246
    PlayerStatus.SelectedWeapon = &PlayerStatus.WeaponSlot[a];
 
 
247
    LoadAllWeapons();
 
 
248
}
 
 
249
 
 
 
250
void create_player_hmodel()
 
 
251
{
 
 
252
    const SECTION *root_section;
 
 
253
 
 
 
254
    switch(AvP.PlayerType)
 
 
255
    {
 
 
256
        case I_Alien:
 
 
257
            root_section = GetNamedHierarchyFromLibrary("hnpcalien", "alien");
 
 
258
            //root_section = GetNamedHierarchyFromLibrary("hnpcpred_alien", "TEMPLATE");
 
 
259
            //root_section = GetNamedHierarchyFromLibrary("hnpcpretorian","Template");
 
 
260
        break;
 
 
261
        case I_Marine:
 
 
262
            switch (PlayerStatus.SelectedWeapon->WeaponIDNumber)
 
 
263
            {
 
 
264
                default:
 
 
265
                case WEAPON_PULSERIFLE:
 
 
266
                    root_section = GetNamedHierarchyFromLibrary("hnpcmarine", "marine with pulse rifle");
 
 
267
                break;
 
 
268
                case WEAPON_TWO_PISTOLS:
 
 
269
                    root_section = GetNamedHierarchyFromLibrary("hnpcmarine", "Two Pistol");
 
 
270
                break;
 
 
271
                case WEAPON_MARINE_PISTOL:
 
 
272
                    root_section = GetNamedHierarchyFromLibrary("hnpcmarine", "PISTOL");
 
 
273
                break;
 
 
274
                case WEAPON_FLAMETHROWER:
 
 
275
                    root_section = GetNamedHierarchyFromLibrary("hnpcmarine", "marine with flame thrower");
 
 
276
                break;
 
 
277
                case WEAPON_SMARTGUN:
 
 
278
                    root_section = GetNamedHierarchyFromLibrary("hnpcmarine", "marine with smart gun");
 
 
279
                break;
 
 
280
                case WEAPON_MINIGUN:
 
 
281
                    root_section = GetNamedHierarchyFromLibrary("hnpcmarine", "Marine with Mini Gun");
 
 
282
                break;
 
 
283
                case WEAPON_SADAR:
 
 
284
                    root_section = GetNamedHierarchyFromLibrary("hnpcmarine", "marine with SADAR");
 
 
285
                break;
 
 
286
                case WEAPON_GRENADELAUNCHER:
 
 
287
                    root_section = GetNamedHierarchyFromLibrary("hnpcmarine", "marine + grenade launcher");
 
 
288
                break;
 
 
289
                case WEAPON_CUDGEL:
 
 
290
                    root_section = GetNamedHierarchyFromLibrary("hnpcmarine", "Cudgel");
 
 
291
                break;
 
 
292
                case WEAPON_FRISBEE_LAUNCHER:
 
 
293
                    root_section = GetNamedHierarchyFromLibrary("hnpcmarine", "skeeter");
 
 
294
            }
 
 
295
        break;
 
 
296
        case I_Predator:
 
 
297
        switch (PlayerStatus.SelectedWeapon->WeaponIDNumber)
 
 
298
        {
 
 
299
            default:
 
 
300
            case WEAPON_PRED_WRISTBLADE:
 
 
301
                root_section = GetNamedHierarchyFromLibrary("hnpcpredator", "pred with wristblade");
 
 
302
            break;
 
 
303
            case WEAPON_PRED_RIFLE:
 
 
304
                root_section = GetNamedHierarchyFromLibrary("hnpcpredator", "Speargun");
 
 
305
            break;
 
 
306
            case WEAPON_PRED_MEDICOMP:
 
 
307
                root_section = GetNamedHierarchyFromLibrary("hnpcpredator", "medicomp");
 
 
308
            break;
 
 
309
            case WEAPON_PRED_SHOULDERCANNON:
 
 
310
                root_section = GetNamedHierarchyFromLibrary("hnpcpredator", "pred with Plasma Caster");
 
 
311
            break;
 
 
312
            case WEAPON_PRED_PISTOL:
 
 
313
                root_section = GetNamedHierarchyFromLibrary("hnpcpredator", "pred + pistol");
 
 
314
            break;
 
 
315
            case WEAPON_PRED_DISC:
 
 
316
                root_section = GetNamedHierarchyFromLibrary("hnpcpredator", "pred with disk");
 
 
317
                //root_section = GetNamedHierarchyFromLibrary("hnpcpredator", "pred with staff");
 
 
318
        }
 
 
319
    }
 
 
320
 
 
 
321
    Dispel_HModel(&PlayerStatus.HModelController);
 
 
322
    Create_HModel(&PlayerStatus.HModelController, root_section);
 
 
323
    InitHModelSequence(&PlayerStatus.HModelController, 0, 0, ONE_FIXED);
 
 
324
    //PlayerStatus.HModelController.Playing = 0;
 
 
325
    PlayerStatus.HModelController.Looped = 0;
 
 
326
    ProveHModel_Far(&PlayerStatus.HModelController, PlayerStatus.sbptr);
 
 
327
}
 
 
328
 
 
 
329
static void ConfigurePlayer() 
 
 
330
{
 
 
331
    mission_messages = NULL;
 
 
332
    mission_messages_timer = 0;
 
 
333
    mission_messages_clear();
 
 
334
 
 
 
335
    PlayerStatus.LeanScale = ONE_FIXED;
 
 
336
 
 
 
337
    if (CHEATMODE_MIRROR == UserProfile.active_bonus)
 
 
338
    {
 
 
339
        TURNSCALE = -2000;
 
 
340
        ALIEN_STRAFESCALE = -12000;  
 
 
341
        PREDATOR_STRAFESCALE = -8000;  
 
 
342
        MARINE_STRAFESCALE = -7000;
 
 
343
    }
 
 
344
    else
 
 
345
    {
 
 
346
        TURNSCALE = 2000;
 
 
347
        ALIEN_STRAFESCALE = 12000;  
 
 
348
        PREDATOR_STRAFESCALE = 8000;  
 
 
349
        MARINE_STRAFESCALE = 7000;
 
 
350
    }
 
 
351
 
 
 
352
    {
 
 
353
        extern int AllowedLookUpAngle;
 
 
354
        extern int AllowedLookDownAngle;
 
 
355
        extern float CameraZoomScale;
 
 
356
        extern int CameraZoomLevel;
 
 
357
        extern SCREENDESCRIPTORBLOCK ScreenDescriptorBlock;
 
 
358
 
 
 
359
        Global_VDB.VDB_ProjX = ScreenDescriptorBlock.SDB_CentreX;
 
 
360
        Global_VDB.VDB_ProjY = ScreenDescriptorBlock.SDB_CentreY;
 
 
361
 
 
 
362
        const NPC_DATA *NpcData;
 
 
363
        AllowedLookUpAngle = 328;
 
 
364
        AllowedLookDownAngle = 1700;
 
 
365
        HeadOrientation.EulerX = HeadOrientation.EulerY = HeadOrientation.EulerZ = 0;
 
 
366
        PlayerStatus.VisionMode = VISION_MODE_NORMAL;
 
 
367
        CameraZoomScale = 1.0f;
 
 
368
        CameraZoomLevel = 0;
 
 
369
        PredatorVisionChangeCounter = 0;
 
 
370
        enum WEAPON_ID *PlayerWeaponKey;
 
 
371
 
 
 
372
        PlayerStatus.imageintensifier_battery = 0;
 
 
373
        PlayerStatus.FlaresLeft = 20;
 
 
374
        PlayerStatus.sbptr->DamageBlock.Health = 0;
 
 
375
        PlayerStatus.sbptr->DamageBlock.Armour = 0;
 
 
376
        PlayerStatus.sbptr->DamageBlock.AcidResistant = 0;
 
 
377
        PlayerStatus.sbptr->DamageBlock.FireResistant = 0;
 
 
378
        PlayerStatus.sbptr->DamageBlock.ElectricResistant = 0;
 
 
379
        PlayerStatus.sbptr->DamageBlock.PerfectArmour = 0;
 
 
380
        PlayerStatus.sbptr->DamageBlock.ElectricSensitive = 0;
 
 
381
        PlayerStatus.sbptr->DamageBlock.IsOnFire = 0;
 
 
382
        PlayerStatus.sbptr->DamageBlock.Indestructable = 0;
 
 
383
        PlayerStatus.sbptr->DamageBlock.Combustability =  1;
 
 
384
 
 
 
385
        if(!UserProfile.GameOptions.BloodParticles)
 
 
386
            AvP.Difficulty = I_Easy;
 
 
387
 
 
 
388
        switch(AvP.PlayerType)
 
 
389
        {
 
 
390
            case I_Marine:
 
 
391
                switch (AvP.Difficulty) 
 
 
392
                {
 
 
393
                    default:
 
 
394
                    case I_Easy:
 
 
395
                        PlayerStatus.sbptr->DamageBlock.AcidResistant = 1;
 
 
396
                    case I_Medium:
 
 
397
                        PlayerStatus.imageintensifier_battery = FIXED_MINUTE * 3;
 
 
398
                    case I_Hard:
 
 
399
                        NpcData = &NpcDataList[I_NPC_Marine];
 
 
400
                }
 
 
401
                PlayerStatus.sbptr->DynPtr->ToppleForce = TOPPLE_FORCE_NONE;
 
 
402
                PlayerStatus.sbptr->DynPtr->Mass = 80;
 
 
403
                PlayerWeaponKey = MarineWeaponKey;
 
 
404
                PlayerStatus.bhvr_type = I_BehaviourMarinePlayer;
 
 
405
                PlayerStatus.sbptr->type = I_BehaviourMarinePlayer;
 
 
406
                SetFrustrumType(FRUSTRUM_TYPE_NORMAL);
 
 
407
                InitMarineHUD();
 
 
408
                primaryInput = &UserProfile.MarineInputPrimaryConfig;
 
 
409
                secondaryInput = &UserProfile.MarineInputSecondaryConfig;
 
 
410
                PlayerStatus.Hud = marine_hud;
 
 
411
                PlayerStatus.weapon_func = maintain_marine_weapons;
 
 
412
            break;
 
 
413
            case I_Predator:
 
 
414
                switch (AvP.Difficulty)
 
 
415
                 {
 
 
416
                    default:
 
 
417
                    case I_Easy:
 
 
418
                        PlayerStatus.sbptr->DamageBlock.AcidResistant = 1;
 
 
419
                    case I_Medium:
 
 
420
                    case I_Hard:
 
 
421
                        NpcData = &NpcDataList[I_NPC_PredatorAlien];
 
 
422
                }
 
 
423
                PlayerStatus.sbptr->DynPtr->ToppleForce = TOPPLE_FORCE_NONE;
 
 
424
                PlayerStatus.sbptr->DynPtr->Mass = 180;
 
 
425
                PlayerWeaponKey = PredatorWeaponKey;
 
 
426
                PlayerStatus.bhvr_type = I_BehaviourPredatorPlayer;
 
 
427
                PlayerStatus.sbptr->type = I_BehaviourPredatorPlayer;
 
 
428
                SetFrustrumType(FRUSTRUM_TYPE_NORMAL);
 
 
429
                InitialiseGrapplingHook();
 
 
430
                primaryInput = &UserProfile.PredatorInputPrimaryConfig;
 
 
431
                secondaryInput = &UserProfile.PredatorInputSecondaryConfig;
 
 
432
                predOVision_SoundHandle = SOUND_NOACTIVEINDEX;
 
 
433
                PlayerStatus.Hud = predator_hud;
 
 
434
                PlayerStatus.weapon_func = maintain_predator_weapons;
 
 
435
            break;
 
 
436
            case I_Alien:
 
 
437
                NpcData = &NpcDataList[I_NPC_Alien];
 
 
438
                PlayerStatus.sbptr->DamageBlock.AcidResistant = 1;
 
 
439
                PlayerStatus.sbptr->DamageBlock.ElectricSensitive = 1;
 
 
440
                PlayerStatus.sbptr->DamageBlock.PerfectArmour = 1;
 
 
441
                PlayerStatus.sbptr->DamageBlock.Combustability =  0;
 
 
442
                PlayerStatus.sbptr->DynPtr->Mass = 160;
 
 
443
                PlayerWeaponKey = AlienWeaponKey;
 
 
444
                PlayerStatus.sbptr->DynPtr->ToppleForce = TOPPLE_FORCE_ALIEN;
 
 
445
                PlayerStatus.bhvr_type = I_BehaviourAlienPlayer;
 
 
446
                PlayerStatus.sbptr->type = I_BehaviourAlienPlayer;
 
 
447
                AlienTeethOffset = 0;
 
 
448
                AlienTongueOffset = 0;
 
 
449
                /* setup wide-angle lens */
 
 
450
                Global_VDB.VDB_ProjX /= 2;
 
 
451
                Global_VDB.VDB_ProjY /= 2;
 
 
452
                SetFrustrumType(FRUSTRUM_TYPE_WIDE);
 
 
453
                PlayerStatus.LeanScale *= 3;
 
 
454
                primaryInput = &UserProfile.AlienInputPrimaryConfig;
 
 
455
                 secondaryInput = &UserProfile.AlienInputSecondaryConfig;
 
 
456
                AllowedLookUpAngle = 0;
 
 
457
                PlayerStatus.Hud = alien_hud;
 
 
458
                PlayerStatus.weapon_func = maintain_alien_weapons;
 
 
459
        }
 
 
460
 
 
 
461
        PlayerStatus.StartingHealth = NpcData->StartingStats.Health;
 
 
462
        PlayerStatus.StartingArmour = NpcData->StartingStats.Armour;
 
 
463
 
 
 
464
        PlayerStatus.sbptr->DamageBlock = NpcData->StartingStats;
 
 
465
        PlayerStatus.sbptr->DamageBlock.Health = PlayerStatus.StartingHealth << ONE_FIXED_SHIFT;
 
 
466
        PlayerStatus.sbptr->DamageBlock.Armour = PlayerStatus.StartingArmour << ONE_FIXED_SHIFT;
 
 
467
 
 
 
468
        PlayerStatus.sbptr->DynPtr->UseStandardGravity = 1;
 
 
469
 
 
 
470
        {
 
 
471
            int slot = MAX_NO_OF_WEAPON_SLOTS;
 
 
472
 
 
 
473
            do
 
 
474
            {
 
 
475
                struct PLAYER_WEAPON_DATA *wdPtr = &PlayerStatus.WeaponSlot[--slot];
 
 
476
 
 
 
477
                wdPtr->WeaponIDNumber = PlayerWeaponKey[slot];
 
 
478
                wdPtr->PrimaryRoundsRemaining = 0;
 
 
479
                wdPtr->SecondaryRoundsRemaining = 0;
 
 
480
                wdPtr->MagazinesRemaining = 0;
 
 
481
                wdPtr->LeftOverBullets = 0;
 
 
482
                wdPtr->Possessed = 0;
 
 
483
 
 
 
484
            } while(slot);
 
 
485
        }
 
 
486
    }
 
 
487
 
 
 
488
    PlayerStatus.incidentFlag = 0;
 
 
489
    PlayerStatus.incidentTimer = 0;
 
 
490
 
 
 
491
    PlayerStatus.cloakOn = 0;
 
 
492
    PlayerStatus.muzzle_flash = 0;
 
 
493
    PlayerStatus.Noise = 0;
 
 
494
    PlayerStatus.FirstPersonView = 1;
 
 
495
    PlayerStatus.CloakingEffectiveness = 0;
 
 
496
    PlayerStatus.FieldCharge = PLAYERCLOAK_MAXENERGY;
 
 
497
    PlayerStatus.PlasmaCasterCharge = 0;
 
 
498
 
 
 
499
    /* CDF 16/9/97 Now, those health and armour stats are those of the last cycle. */
 
 
500
 
 
 
501
    PlayerStatus.Health = PlayerStatus.sbptr->DamageBlock.Health;
 
 
502
    PlayerStatus.Armour = PlayerStatus.sbptr->DamageBlock.Armour;
 
 
503
 
 
 
504
    PlayerStatus.InputRequests.Rqst_FirePrimaryWeapon = 0;
 
 
505
    PlayerStatus.InputRequests.Rqst_FireSecondaryWeapon = 0;
 
 
506
    PlayerStatus.InputRequests.Rqst_Forward = 0;
 
 
507
    PlayerStatus.InputRequests.Rqst_Backward = 0;
 
 
508
    PlayerStatus.InputRequests.Rqst_SideStepLeft = 0;
 
 
509
    PlayerStatus.InputRequests.Rqst_SideStepRight = 0;
 
 
510
    PlayerStatus.InputRequests.Rqst_Strafe = 0;
 
 
511
    PlayerStatus.InputRequests.Rqst_Jump = 0;
 
 
512
    PlayerStatus.InputRequests.Rqst_Walk = 0;
 
 
513
 
 
 
514
    PlayerStatus.Alive = 1;
 
 
515
    PlayerStatus.RequestsToStandUp = 0;
 
 
516
    PlayerStatus.IHaveAPlacedAutogun = 0;
 
 
517
    PlayerStatus.tauntTimer = 0;
 
 
518
    PlayerStatus.invulnerabilityTimer = 0;
 
 
519
    PlayerStatus.ForwardInertia = 0;
 
 
520
    PlayerStatus.StrafeInertia = 0; 
 
 
521
    PlayerStatus.TurnInertia = 0;     
 
 
522
    PlayerStatus.Crouching = 0;
 
 
523
        PlayerStatus.ViewPanX = 0;
 
 
524
    PlayerStatus.securityClearances = 0;
 
 
525
    PlayerStatus.DamagedOverlayIntensity = 0;
 
 
526
    PlayerStatus.CurrentLightAtPlayer = 0;
 
 
527
 
 
 
528
    /* Better safe than sorry. */
 
 
529
    PlayerStatus.sound_mouth = SOUND_NOACTIVEINDEX;
 
 
530
    PlayerStatus.soundCracklingFire = SOUND_NOACTIVEINDEX;
 
 
531
    PlayerStatus.sound_watersplash = SOUND_NOACTIVEINDEX;
 
 
532
    PlayerStatus.sound_jetpack = SOUND_NOACTIVEINDEX;
 
 
533
 
 
 
534
    PlayerStatus.WeaponStateTimeOutCounter = 0;
 
 
535
    PlayerStatus.WeaponState = WEAPONSTATE_SWAPPING_IN;
 
 
536
    PlayerStatus.WeaponPositionOffset.vx = 0;
 
 
537
    PlayerStatus.WeaponPositionOffset.vy = 0;
 
 
538
    PlayerStatus.WeaponPositionOffset.vz = 0;
 
 
539
 
 
 
540
    switch(AvP.Difficulty)
 
 
541
    {
 
 
542
        case I_Easy:
 
 
543
            PlayerStatus.saves_left = 4;
 
 
544
        break;
 
 
545
        case I_Medium: 
 
 
546
            PlayerStatus.saves_left = 2;
 
 
547
        break;
 
 
548
        case I_Hard:
 
 
549
        default:
 
 
550
            PlayerStatus.saves_left = 1;
 
 
551
    }
 
 
552
 
 
 
553
    InitialisePlayersInventory();
 
 
554
    GrabWeaponShape();
 
 
555
 
 
 
556
    if(SinglePlayer == AvP.PlayMode)
 
 
557
        SoundSys_FadeIn();
 
 
558
    else
 
 
559
        SoundSys_ResetFadeLevel();
 
 
560
}
 
 
561
 
 
 
562
int InitPlayer() 
 
 
563
{
 
 
564
    PlayerStatus.DisplayBlock = CreateActiveObject();
 
 
565
    PlayerStatus.sbptr = CreateActiveStrategyBlock(I_BehaviourMarinePlayer);
 
 
566
    PlayerStatus.HModelController.Deltas = NULL;
 
 
567
    PlayerStatus.HModelController.Root_Section = NULL;
 
 
568
    PlayerStatus.HModelController.section_data= NULL;
 
 
569
 
 
 
570
    if((NULL != PlayerStatus.sbptr) && (NULL != PlayerStatus.DisplayBlock))
 
 
571
    {
 
 
572
        PlayerStatus.DisplayBlock->ObStrategyBlock = PlayerStatus.sbptr;
 
 
573
        PlayerStatus.sbptr->DisplayBlock = PlayerStatus.DisplayBlock;
 
 
574
        PlayerStatus.DisplayBlock->HModelControlBlock = &PlayerStatus.HModelController;
 
 
575
        PlayerStatus.DisplayBlock->ObFlags |= ObFlag_NotVis;
 
 
576
        PlayerStatus.sbptr->maintainVisibility = 0; // player is always near; skip DoObjectVisibility.
 
 
577
 
 
 
578
        PlayerStatus.sbptr->dataptr = (void*)&PlayerStatus;
 
 
579
        AssignNewSBName(PlayerStatus.sbptr);
 
 
580
        PlayerStatus.sbptr->DynPtr = AllocateDynamicsBlock(DYNAMICS_TEMPLATE_DEFAULT);
 
 
581
 
 
 
582
        if(NULL != PlayerStatus.sbptr->DynPtr)
 
 
583
        {
 
 
584
            extern const DISPLAYBLOCK Zero_Displayblock;
 
 
585
            DYNAMICSBLOCK *dynPtr = PlayerStatus.sbptr->DynPtr;
 
 
586
 
 
 
587
            dynPtr->PrevPosition = dynPtr->Position = PlayerStatus.DisplayBlock->ObWorld = PlayerStatus.StartLocation;
 
 
588
            dynPtr->PrevOrientMat = dynPtr->OrientMat = PlayerStatus.StartMat;
 
 
589
            MatrixToEuler(&dynPtr->OrientMat, &dynPtr->OrientEuler);
 
 
590
 
 
 
591
            dynPtr->PrevOrientEuler = dynPtr->OrientEuler;
 
 
592
 
 
 
593
            PlayersMaxHeightWhilstNotInContactWithGround = dynPtr->Position.vy;
 
 
594
 
 
 
595
            PlayerStatus.weapon = Zero_Displayblock;
 
 
596
            PlayerStatus.weapon.HModelControlBlock = &PlayersWeaponHModelController;
 
 
597
 
 
 
598
            ConfigurePlayer();
 
 
599
            return 1;
 
 
600
        }
 
 
601
    }
 
 
602
 
 
 
603
 
 
 
604
return 0;
 
 
605
}
 
 
606
 
 
 
607
static void MakePlayersWeaponPickupVisible()
 
 
608
{
 
 
609
    int i = NumActiveStBlocks - 1;
 
 
610
 
 
 
611
    /*
 
 
612
    Search through the strategy block list for weapons.
 
 
613
    Any weapons that have a lifespan timer should be made visible.
 
 
614
    There should only be one such object , so we can stop looking once we find it
 
 
615
    */
 
 
616
 
 
 
617
    for(; i >= 0; i--)
 
 
618
    {
 
 
619
        STRATEGYBLOCK* sbPtr = ActiveStBlockList[i];
 
 
620
 
 
 
621
        if(sbPtr->type == I_BehaviourInanimateObject && !sbPtr->maintainVisibility)
 
 
622
        {
 
 
623
            INANIMATEOBJECT_STATUSBLOCK* objectstatusptr = (INANIMATEOBJECT_STATUSBLOCK*)sbPtr->dataptr;
 
 
624
 
 
 
625
            if(objectstatusptr->typeId == IOT_Weapon)
 
 
626
            {
 
 
627
                if(objectstatusptr->lifespanTimer > 0)
 
 
628
                {
 
 
629
                    //okay we've found the object , so allow it to be visible
 
 
630
                    sbPtr->DynPtr->IsPickupObject = 1;
 
 
631
                    sbPtr->maintainVisibility = 1;
 
 
632
                    return;
 
 
633
                }    
 
 
634
            }
 
 
635
        }
 
 
636
    }
 
 
637
}
 
 
638
 
 
 
639
static int ObjectIsPlayersDisc(STRATEGYBLOCK *sbPtr)
 
 
640
{
 
 
641
    switch(sbPtr->type)
 
 
642
    {
 
 
643
        case I_BehaviourInanimateObject:
 
 
644
        {
 
 
645
            INANIMATEOBJECT_STATUSBLOCK* objStatPtr = sbPtr->dataptr;
 
 
646
 
 
 
647
            /* Make sure the object hasn't already been picked up this frame */
 
 
648
            if(!sbPtr->please_destroy_me && !objStatPtr->respawnTimer)
 
 
649
            {
 
 
650
                if (objStatPtr->typeId == IOT_Ammo)
 
 
651
                {
 
 
652
                    if (objStatPtr->subType == AMMO_PRED_DISC)
 
 
653
                        return 1;
 
 
654
                }            
 
 
655
            }
 
 
656
        }
 
 
657
        break;
 
 
658
        case I_BehaviourPredatorDisc_SeekTrack:
 
 
659
        {
 
 
660
            /* Erm... just return? */
 
 
661
            return 1;
 
 
662
        }
 
 
663
        default:
 
 
664
        return 0;
 
 
665
    }
 
 
666
 
 
 
667
return 0;
 
 
668
}
 
 
669
 
 
 
670
static void RemoveAllThisPlayersDiscs()
 
 
671
{
 
 
672
    int a;
 
 
673
 
 
 
674
    /* All discs that are NOT ghosted must 'belong' to this player. */
 
 
675
 
 
 
676
    for (a=0; a < NumActiveStBlocks; a++) 
 
 
677
    {
 
 
678
        STRATEGYBLOCK *candidate = ActiveStBlockList[a];
 
 
679
 
 
 
680
        if (candidate->DynPtr && ObjectIsPlayersDisc(candidate)) 
 
 
681
        {
 
 
682
            /* Are we the right type? */
 
 
683
            AddNetMsg_LocalObjectDestroyed(candidate);
 
 
684
            candidate->please_destroy_me = 1;
 
 
685
        }
 
 
686
    }
 
 
687
}
 
 
688
 
 
 
689
static void NetPlayerRespawn()
 
 
690
{
 
 
691
    /* When you're going to respawn... you might change */
 
 
692
    /* character class, after all. */
 
 
693
 
 
 
694
    if (PlayerStatus.sound_mouth != SOUND_NOACTIVEINDEX)
 
 
695
         Sound_Stop(PlayerStatus.sound_mouth);
 
 
696
 
 
 
697
    if (PlayerStatus.soundCracklingFire != SOUND_NOACTIVEINDEX)
 
 
698
         Sound_Stop(PlayerStatus.soundCracklingFire);
 
 
699
 
 
 
700
    if (weaponHandle != SOUND_NOACTIVEINDEX)
 
 
701
         Sound_Stop(weaponHandle);
 
 
702
 
 
 
703
    if (predHUDSoundHandle != SOUND_NOACTIVEINDEX)
 
 
704
        Sound_Stop(predHUDSoundHandle);
 
 
705
 
 
 
706
    if (predOVision_SoundHandle != SOUND_NOACTIVEINDEX)
 
 
707
        Sound_Stop(predOVision_SoundHandle);
 
 
708
 
 
 
709
    ConfigurePlayer();
 
 
710
    //reset the player's elasticity (which gets altered upon death)
 
 
711
    PlayerStatus.sbptr->DynPtr->Elasticity = 0;
 
 
712
 
 
 
713
    TurnOffMultiplayerObserveMode();
 
 
714
 
 
 
715
    //The player's dropped weapon (if there was one) can now be drawn
 
 
716
    MakePlayersWeaponPickupVisible();
 
 
717
    RemoveAllThisPlayersDiscs();
 
 
718
    ChooseLightingModel();
 
 
719
}
 
 
720
 
 
 
721
void ChangeToMarine()
 
 
722
{
 
 
723
    if (I_Marine != AvP.PlayerType)
 
 
724
    {
 
 
725
        AvP.PlayerType = I_Marine;
 
 
726
        NetPlayerRespawn();
 
 
727
        netGameData.myCharacterType = netGameData.myNextCharacterType = NGCT_Marine;
 
 
728
 
 
 
729
        //reorient the player
 
 
730
        {
 
 
731
            EULER e;
 
 
732
            MatrixToEuler(&PlayerStatus.sbptr->DynPtr->OrientMat, &e);
 
 
733
            e.EulerX = e.EulerZ = 0;
 
 
734
 
 
 
735
            CreateEulerMatrix(&e, &PlayerStatus.sbptr->DynPtr->OrientMat);
 
 
736
            TransposeMatrixCH(&PlayerStatus.sbptr->DynPtr->OrientMat);
 
 
737
        }
 
 
738
    }
 
 
739
}
 
 
740
 
 
 
741
void ChangeToAlien()
 
 
742
{
 
 
743
    if (I_Alien != AvP.PlayerType)
 
 
744
    {
 
 
745
        AvP.PlayerType = I_Alien;
 
 
746
        NetPlayerRespawn();
 
 
747
        netGameData.myCharacterType = netGameData.myNextCharacterType = NGCT_Alien;
 
 
748
    }
 
 
749
}
 
 
750
 
 
 
751
void ChangeToPredator()
 
 
752
{
 
 
753
    if (I_Predator != AvP.PlayerType)
 
 
754
    {
 
 
755
        AvP.PlayerType = I_Predator;
 
 
756
        NetPlayerRespawn();
 
 
757
        netGameData.myCharacterType = netGameData.myNextCharacterType = NGCT_Predator;
 
 
758
 
 
 
759
        {
 
 
760
            EULER e;
 
 
761
            MatrixToEuler(&PlayerStatus.sbptr->DynPtr->OrientMat,&e);
 
 
762
            e.EulerX = e.EulerZ = 0;
 
 
763
 
 
 
764
            CreateEulerMatrix(&e, &PlayerStatus.sbptr->DynPtr->OrientMat);
 
 
765
            TransposeMatrixCH(&PlayerStatus.sbptr->DynPtr->OrientMat);
 
 
766
        }
 
 
767
    }
 
 
768
}
 
 
769
 
 
 
770
void ShowAdjacencies() 
 
 
771
{
 
 
772
    /* Utility function... */
 
 
773
    printf("Adjacencies FROM Player's Module (%s):\n", (*(PlayerStatus.sbptr->containingModule->m_aimodule->m_module_ptrs))->name);
 
 
774
 
 
 
775
    AIMODULE *thisModule = PlayerStatus.sbptr->containingModule->m_aimodule;
 
 
776
    AIMODULE **AdjModuleRefPtr = thisModule->m_link_ptrs;
 
 
777
 
 
 
778
    if(AdjModuleRefPtr)     /* check that there is a list of adjacent modules */
 
 
779
    {
 
 
780
        while(*AdjModuleRefPtr != 0)
 
 
781
        {
 
 
782
            /* Probably want some validity test for the link. */
 
 
783
            if (AIModuleIsPhysical(*AdjModuleRefPtr))
 
 
784
            {
 
 
785
                /* Probably a valid link... */
 
 
786
                if (CheckAdjacencyValidity((*AdjModuleRefPtr),thisModule,0))
 
 
787
                {
 
 
788
                    printf("--AI Module of %s, general.\n",(*((*AdjModuleRefPtr)->m_module_ptrs))->name);
 
 
789
                }
 
 
790
                else if (CheckAdjacencyValidity((*AdjModuleRefPtr),thisModule,1))
 
 
791
                {
 
 
792
                    printf("--AI Module of %s, alien only.\n",(*((*AdjModuleRefPtr)->m_module_ptrs))->name);
 
 
793
                }
 
 
794
                else
 
 
795
                {
 
 
796
                    printf("--AI Module of %s, fails validity test!\n",(*((*AdjModuleRefPtr)->m_module_ptrs))->name);
 
 
797
                }
 
 
798
            }
 
 
799
 
 
 
800
            /* next adjacent module reference pointer */
 
 
801
            AdjModuleRefPtr++;
 
 
802
        }
 
 
803
    }
 
 
804
 
 
 
805
    printf("Adjacencies TO Player's Module:\n");
 
 
806
 
 
 
807
    AIMODULE *ModuleListPointer = AIModuleArray;
 
 
808
 
 
 
809
    /* go through each aimodule in the environment  */    
 
 
810
    int moduleCounter = 0;
 
 
811
    for(; moduleCounter < AIModuleArraySize; moduleCounter++)
 
 
812
    {
 
 
813
        /* get a pointer to the next current module */
 
 
814
        thisModule = &(ModuleListPointer[moduleCounter]); 
 
 
815
        assert(thisModule);
 
 
816
 
 
 
817
        AdjModuleRefPtr = thisModule->m_link_ptrs;
 
 
818
 
 
 
819
        if(AdjModuleRefPtr)     /* check that there is a list of adjacent modules */
 
 
820
        {
 
 
821
            while(*AdjModuleRefPtr != 0)
 
 
822
            {
 
 
823
                /* Probably want some validity test for the link. */
 
 
824
                if (AIModuleIsPhysical(*AdjModuleRefPtr))
 
 
825
                {
 
 
826
                    /* Is this the target? */
 
 
827
                    if ((*AdjModuleRefPtr) == (PlayerStatus.sbptr->containingModule->m_aimodule))
 
 
828
                    {
 
 
829
                        /* Probably a valid link... */
 
 
830
                        if (CheckAdjacencyValidity((*AdjModuleRefPtr),thisModule,0))
 
 
831
                        {
 
 
832
                            printf("--AI Module of %s, general.\n",(*(thisModule->m_module_ptrs))->name);
 
 
833
                        }
 
 
834
                        else if (CheckAdjacencyValidity((*AdjModuleRefPtr),thisModule,1))
 
 
835
                        {
 
 
836
                            printf("--AI Module of %s, alien only.\n",(*(thisModule->m_module_ptrs))->name);
 
 
837
                        }
 
 
838
                        else
 
 
839
                        {
 
 
840
                            printf("--AI Module of %s, fails validity test!\n",(*(thisModule->m_module_ptrs))->name);
 
 
841
                        }
 
 
842
 
 
 
843
                    }
 
 
844
                }
 
 
845
 
 
 
846
                /* next adjacent module reference pointer */
 
 
847
                AdjModuleRefPtr++;
 
 
848
            }
 
 
849
        }
 
 
850
    }
 
 
851
}
 
 
852
 
 
 
853
void StartPlayerTaunt()
 
 
854
{
 
 
855
        if (PlayerStatus.tauntTimer)
 
 
856
                return;
 
 
857
 
 
 
858
        PlayerStatus.tauntTimer = -1; /* Cue to start. */
 
 
859
 
 
 
860
    if(SinglePlayer == AvP.PlayMode)
 
 
861
         PlayerStatus.tauntTimer = TAUNT_LENGTH;
 
 
862
 
 
 
863
    PlayerStatus.Noise = 1;
 
 
864
    /* An actual noise, too, would probably be good. */
 
 
865
 
 
 
866
    /* That should make sure we don't get more than one. */
 
 
867
    if (PlayerStatus.sound_mouth == SOUND_NOACTIVEINDEX) 
 
 
868
    {
 
 
869
        switch(AvP.PlayerType)
 
 
870
        {
 
 
871
            case I_Alien:
 
 
872
            {
 
 
873
                PlayAlienSound(0, ASC_Taunt, 0, &PlayerStatus.sound_mouth, &PlayerStatus.sbptr->DynPtr->Position);
 
 
874
 
 
 
875
                if(SinglePlayer != AvP.PlayMode)
 
 
876
                    netGameData.myLastScream = ASC_Taunt;
 
 
877
            }
 
 
878
            break;
 
 
879
            case I_Marine:
 
 
880
            {
 
 
881
                PlayMarineScream(0, MSC_Taunt, 0, &PlayerStatus.sound_mouth, NULL);
 
 
882
 
 
 
883
                if(SinglePlayer != AvP.PlayMode)
 
 
884
                    netGameData.myLastScream = MSC_Taunt;
 
 
885
            }
 
 
886
            break;
 
 
887
            case I_Predator:
 
 
888
            {
 
 
889
                PlayPredatorSound(0, PSC_Taunt, 0, &PlayerStatus.sound_mouth, NULL);
 
 
890
 
 
 
891
                if(SinglePlayer != AvP.PlayMode)
 
 
892
                    netGameData.myLastScream = PSC_Taunt;
 
 
893
            }
 
 
894
        }
 
 
895
    }
 
 
896
}
 
 
897
 
 
 
898
static STRATEGYBLOCK *MakePlayerCorpse()
 
 
899
{
 
 
900
    STRATEGYBLOCK *sbPtr = CreateActiveStrategyBlock(I_BehaviourCorpse);
 
 
901
 
 
 
902
    if(NULL != sbPtr) 
 
 
903
    {
 
 
904
        AssignNewSBName(sbPtr);
 
 
905
 
 
 
906
        DYNAMICSBLOCK *dynPtr = sbPtr->DynPtr = AllocateDynamicsBlock(DYNAMICS_TEMPLATE_DEFAULT);
 
 
907
        CORPSEDATABLOCK *corpseData = sbPtr->dataptr = make_new_corpse(I_BehaviourCorpse);
 
 
908
 
 
 
909
        if(!dynPtr || !corpseData)
 
 
910
        {
 
 
911
            RemoveBehaviourStrategy(sbPtr);
 
 
912
            return NULL;
 
 
913
        }
 
 
914
 
 
 
915
        dynPtr->CanClimbStairs = 0;
 
 
916
        dynPtr->IgnoreThePlayer = 1;
 
 
917
 
 
 
918
        dynPtr->Position = dynPtr->PrevPosition = PlayerStatus.sbptr->DynPtr->Position;
 
 
919
        dynPtr->OrientEuler = PlayerStatus.sbptr->DynPtr->OrientEuler;
 
 
920
        CreateEulerMatrix(&dynPtr->OrientEuler, &dynPtr->OrientMat);
 
 
921
        TransposeMatrixCH(&dynPtr->OrientMat);
 
 
922
 
 
 
923
        sbPtr->maintainVisibility = 1;
 
 
924
        sbPtr->containingModule = ModuleFromPosition(&sbPtr->DynPtr->Position, NULL);
 
 
925
        Splice_HModels(&corpseData->HModelController, PlayerStatus.HModelController.section_data);
 
 
926
 
 
 
927
        switch(AvP.PlayerType)
 
 
928
        {
 
 
929
            case I_Marine:
 
 
930
            {
 
 
931
                corpseData->Type = I_BehaviourMarinePlayer;
 
 
932
                corpseData->hltable = GetThisHitLocationTable("marine with pulse rifle");
 
 
933
                /* Select hierarchy from character's selected weapon. */
 
 
934
                //while we're at it , also deal with creating the pickupable weapon
 
 
935
                {
 
 
936
                    STRATEGYBLOCK* weaponSbPtr = CreateMultiplayerWeaponPickup(&PlayerStatus.sbptr->DynPtr->Position,
PlayerStatus.SelectedWeapon->WeaponIDNumber, 0);
 
 
937
 
 
 
938
                    //hide the newly created weapon from this player , until the player respawns
 
 
939
 
 
 
940
                    if(weaponSbPtr)
 
 
941
                    {
 
 
942
                        weaponSbPtr->maintainVisibility = 0;
 
 
943
                        weaponSbPtr->DynPtr->IsPickupObject = 0;
 
 
944
                    }
 
 
945
                }
 
 
946
            }
 
 
947
            break;
 
 
948
            case I_Alien:
 
 
949
            {
 
 
950
                corpseData->Type = I_BehaviourAlienPlayer;
 
 
951
                corpseData->hltable = GetThisHitLocationTable("alien");
 
 
952
            }
 
 
953
            break;
 
 
954
            case I_Predator:
 
 
955
            {
 
 
956
                corpseData->Type = I_BehaviourPredatorPlayer;
 
 
957
                corpseData->hltable = GetThisHitLocationTable("predator");
 
 
958
            }
 
 
959
        }
 
 
960
 
 
 
961
        /* Now fix timer. */
 
 
962
        corpseData->timer = CORPSE_EXPIRY_TIME; /* Arbitrarily */
 
 
963
        corpseData->validityTimer = CORPSE_VALIDITY_TIME;
 
 
964
        corpseData->HModelController.Looped = 0;
 
 
965
        //ProveHModel_Far(&corpseData->HModelController, sbPtr);
 
 
966
        MakeCorpseNear(sbPtr);
 
 
967
        //sbPtr->DisplayBlock->ObFlags |= ObFlag_NotVis;
 
 
968
 
 
 
969
        if (PlayerStatus.sbptr->DamageBlock.IsOnFire)
 
 
970
        {
 
 
971
            sbPtr->DamageBlock.IsOnFire = 1;
 
 
972
            corpseData->SoundHandle3 = PlayerStatus.soundCracklingFire;
 
 
973
            PlayerStatus.soundCracklingFire = SOUND_NOACTIVEINDEX;
 
 
974
        }
 
 
975
    }
 
 
976
 
 
 
977
return sbPtr;
 
 
978
}
 
 
979
 
 
 
980
static void PlayerIsDead(const DAMAGE_PROFILE* damage, int multiplier, VECTORCH* incoming)
 
 
981
{
 
 
982
    if(predHUDSoundHandle != SOUND_NOACTIVEINDEX)
 
 
983
        Sound_Stop(predHUDSoundHandle);
 
 
984
 
 
 
985
    if(predOVision_SoundHandle != SOUND_NOACTIVEINDEX)
 
 
986
        Sound_Stop(predOVision_SoundHandle);
 
 
987
 
 
 
988
    if(weaponHandle != SOUND_NOACTIVEINDEX)
 
 
989
        Sound_Stop(weaponHandle);
 
 
990
 
 
 
991
    if (PlayerStatus.sound_mouth != SOUND_NOACTIVEINDEX) 
 
 
992
         Sound_Stop(PlayerStatus.sound_mouth);
 
 
993
 
 
 
994
    switch (AvP.PlayerType)
 
 
995
    {
 
 
996
        case I_Alien:
 
 
997
            PlayAlienSound(0, ASC_Scream_Dying, 0, NULL, NULL);
 
 
998
        break;
 
 
999
        case I_Marine:
 
 
1000
        {
 
 
1001
            if (damage->Id == AMMO_FACEHUGGER)
 
 
1002
                PlayMarineScream(0, MSC_Facehugged, 0, NULL, NULL);
 
 
1003
            else
 
 
1004
                PlayMarineScream(0, MSC_Death, 0, NULL, NULL);
 
 
1005
        }  
 
 
1006
        break;
 
 
1007
        case I_Predator:
 
 
1008
        {
 
 
1009
            if (damage->Id == AMMO_FACEHUGGER)
 
 
1010
                PlayPredatorSound(0, PSC_Facehugged, 0, NULL, NULL);
 
 
1011
            else
 
 
1012
                PlayPredatorSound(0, PSC_Scream_Dying, 0, NULL, NULL);
 
 
1013
        }
 
 
1014
    }
 
 
1015
 
 
 
1016
    PlayerStatus.Alive = 0;
 
 
1017
    mission_messages = NULL;
 
 
1018
    mission_messages_timer = 0;
 
 
1019
 
 
 
1020
    /* give player a little bounce */
 
 
1021
    PlayerStatus.sbptr->DynPtr->Elasticity = 16384;
 
 
1022
    /* but a lot of friction */
 
 
1023
//    PlayerStatus.sbptr->DynPtr->Friction = 1 << 20;
 
 
1024
//    PlayerStatus.sbptr->DynPtr->Mass = 1 << 20;
 
 
1025
 
 
 
1026
    /* cancel any velocity */
 
 
1027
    PlayerStatus.sbptr->DynPtr->LinVelocity.vx = PlayerStatus.sbptr->DynPtr->LinVelocity.vy = PlayerStatus.sbptr->DynPtr->LinVelocity.vz = 0;
 
 
1028
 
 
 
1029
    deathFadeLevel = ONE_FIXED;
 
 
1030
 
 
 
1031
    PlayerStatus.sbptr->DynPtr->UseStandardGravity = 1;
 
 
1032
 
 
 
1033
    if(SinglePlayer != AvP.PlayMode)
 
 
1034
    {
 
 
1035
        STRATEGYBLOCK *MyCorpse = MakePlayerCorpse();
 
 
1036
        AddNetMsg_PlayerKilled((*((int *)(&(MyCorpse->SBname[4])))), damage);
 
 
1037
 
 
 
1038
        if(damage)
 
 
1039
        {
 
 
1040
            if (damage->Id == AMMO_ALIEN_BITE_KILLSECTION)
 
 
1041
                Sound_Play(SID_ALIEN_JAW_ATTACK,"d", &PlayerStatus.sbptr->DynPtr->Position);
 
 
1042
        }
 
 
1043
        /*---------------------------------**
 
 
1044
        **         Choose death anim sequence **
 
 
1045
        **---------------------------------*/
 
 
1046
        {
 
 
1047
            int deathId;
 
 
1048
            switch(AvP.PlayerType)
 
 
1049
            {
 
 
1050
                case I_Marine:
 
 
1051
                    deathId = Deduce_PlayerMarineDeathSequence(&PlayerStatus.HModelController, damage, multiplier, incoming);
 
 
1052
                break;
 
 
1053
                case I_Alien:
 
 
1054
                    deathId = Deduce_PlayerAlienDeathSequence(&PlayerStatus.HModelController, damage, multiplier, incoming);
 
 
1055
                break;
 
 
1056
                case I_Predator:
 
 
1057
                    deathId = Deduce_PlayerPredatorDeathSequence(&PlayerStatus.HModelController, damage, multiplier ,incoming);
 
 
1058
            }
 
 
1059
            //apply the animation
 
 
1060
            ApplyCorpseDeathAnim(MyCorpse, deathId);
 
 
1061
            //tell everyone else about the chosen death
 
 
1062
            AddNetMsg_PlayerDeathAnim(deathId, *(int*)&MyCorpse->SBname[4]);
 
 
1063
        }
 
 
1064
 
 
 
1065
        //does this death require a change in character type?
 
 
1066
        if(netGameData.gameType == NGT_LastManStanding)
 
 
1067
        {
 
 
1068
            //Am I a marine or predator?
 
 
1069
            if(AvP.PlayerType != I_Alien)
 
 
1070
            {
 
 
1071
                //was I killed by an alien?
 
 
1072
                if(myNetworkKillerId && myNetworkKillerId != AVPDPNetID)
 
 
1073
                {
 
 
1074
                    int killer_index = PlayerIdInPlayerList(myNetworkKillerId);
 
 
1075
 
 
 
1076
                    assert(killer_index != NET_IDNOTINPLAYERLIST);
 
 
1077
 
 
 
1078
                    if(netGameData.playerData[killer_index].characterType == NGCT_Alien)
 
 
1079
                    {
 
 
1080
                        //set  the next character to be an alien then
 
 
1081
                        netGameData.myNextCharacterType = NGCT_Alien;
 
 
1082
                    }
 
 
1083
                }
 
 
1084
                else
 
 
1085
                {
 
 
1086
                    //suicide , so become an alien anyway
 
 
1087
                        netGameData.myNextCharacterType = NGCT_Alien;
 
 
1088
                }
 
 
1089
            }
 
 
1090
        }
 
 
1091
        else if(netGameData.gameType == NGT_PredatorTag || netGameData.gameType == NGT_AlienTag)
 
 
1092
        {
 
 
1093
            //we may need to change character
 
 
1094
            extern void SpeciesTag_DetermineMyNextCharacterType();
 
 
1095
            SpeciesTag_DetermineMyNextCharacterType();
 
 
1096
        }
 
 
1097
    }
 
 
1098
    else
 
 
1099
    {
 
 
1100
        SoundSys_FadeOut();
 
 
1101
    }
 
 
1102
 
 
 
1103
    if (PlayerStatus.soundCracklingFire != SOUND_NOACTIVEINDEX) 
 
 
1104
         Sound_Stop(PlayerStatus.soundCracklingFire);
 
 
1105
 
 
 
1106
    DisengageGrapplingHook();
 
 
1107
}
 
 
1108
 
 
 
1109
static void ModifyHeadOrientation()
 
 
1110
{
 
 
1111
    #define TILT_THRESHOLD 128
 
 
1112
 
 
 
1113
    if (!PlayerStatus.Alive && !MultiplayerObservedPlayer)
 
 
1114
    {
 
 
1115
        int decay = NormalFrameTime >> 6;
 
 
1116
 
 
 
1117
        HeadOrientation.EulerX &= 4095;
 
 
1118
           HeadOrientation.EulerX -= decay;
 
 
1119
 
 
 
1120
        if(HeadOrientation.EulerX < 3072)
 
 
1121
            HeadOrientation.EulerX = 3072;
 
 
1122
    }
 
 
1123
    else
 
 
1124
    {
 
 
1125
        int decay = NormalFrameTime >> 8;
 
 
1126
 
 
 
1127
        if(HeadOrientation.EulerX > 2048)
 
 
1128
        {
 
 
1129
            if (HeadOrientation.EulerX < 4096 - TILT_THRESHOLD)
 
 
1130
                HeadOrientation.EulerX = 4096 - TILT_THRESHOLD;
 
 
1131
 
 
 
1132
               HeadOrientation.EulerX += decay;
 
 
1133
 
 
 
1134
            if(HeadOrientation.EulerX > 4095)
 
 
1135
                HeadOrientation.EulerX = 0;
 
 
1136
        }
 
 
1137
        else
 
 
1138
        {
 
 
1139
            if (HeadOrientation.EulerX > TILT_THRESHOLD)
 
 
1140
                HeadOrientation.EulerX = TILT_THRESHOLD;
 
 
1141
 
 
 
1142
               HeadOrientation.EulerX -= decay;
 
 
1143
 
 
 
1144
            if(HeadOrientation.EulerX < 0)
 
 
1145
                HeadOrientation.EulerX = 0;
 
 
1146
        }
 
 
1147
 
 
 
1148
        if(HeadOrientation.EulerY > 2048)
 
 
1149
        {
 
 
1150
            if (HeadOrientation.EulerY < 4096 - TILT_THRESHOLD)
 
 
1151
                HeadOrientation.EulerY = 4096 - TILT_THRESHOLD;
 
 
1152
 
 
 
1153
               HeadOrientation.EulerY += decay;
 
 
1154
 
 
 
1155
            if(HeadOrientation.EulerY > 4095)
 
 
1156
                HeadOrientation.EulerY = 0;
 
 
1157
        }
 
 
1158
        else
 
 
1159
        {
 
 
1160
            if (HeadOrientation.EulerY > TILT_THRESHOLD)
 
 
1161
                HeadOrientation.EulerY = TILT_THRESHOLD;
 
 
1162
 
 
 
1163
               HeadOrientation.EulerY -= decay;
 
 
1164
 
 
 
1165
            if(HeadOrientation.EulerY < 0)
 
 
1166
                HeadOrientation.EulerY = 0;
 
 
1167
        }
 
 
1168
 
 
 
1169
        if(HeadOrientation.EulerZ > 2048)
 
 
1170
        {
 
 
1171
            if (HeadOrientation.EulerZ < 4096 - TILT_THRESHOLD)
 
 
1172
                HeadOrientation.EulerZ = 4096 - TILT_THRESHOLD;
 
 
1173
 
 
 
1174
               HeadOrientation.EulerZ += decay;
 
 
1175
 
 
 
1176
            if(HeadOrientation.EulerZ > 4095)
 
 
1177
                HeadOrientation.EulerZ = 0;
 
 
1178
        }
 
 
1179
        else
 
 
1180
        {
 
 
1181
            if (HeadOrientation.EulerZ > TILT_THRESHOLD)
 
 
1182
                HeadOrientation.EulerZ = TILT_THRESHOLD;
 
 
1183
 
 
 
1184
               HeadOrientation.EulerZ -= decay;
 
 
1185
 
 
 
1186
            if(HeadOrientation.EulerZ < 0)
 
 
1187
                HeadOrientation.EulerZ = 0;
 
 
1188
        }
 
 
1189
    }
 
 
1190
}
 
 
1191
 
 
 
1192
static void InteriorType_Body()
 
 
1193
{
 
 
1194
    static int verticalSpeed = 0;
 
 
1195
    static int zAxisTilt = 0;
 
 
1196
 
 
 
1197
    {
 
 
1198
        VECTORCH offset = { 0, 0, 0 };
 
 
1199
 
 
 
1200
        switch(AvP.PlayerType)
 
 
1201
        {
 
 
1202
            case I_Alien:
 
 
1203
                //offset.vy = CollisionExtents[(PlayerStatus.Crouching ? CE_ALIEN_CROUCH : CE_ALIEN)].StandingTop;
 
 
1204
                offset.vy = CollisionExtents[CE_ALIEN].StandingTop;
 
 
1205
            break;
 
 
1206
            case I_Marine:
 
 
1207
                offset.vy = (PlayerStatus.Crouching ? CollisionExtents[CE_MARINE].CrouchingTop : CollisionExtents[CE_MARINE].StandingTop);
 
 
1208
            break;
 
 
1209
            case I_Predator:
 
 
1210
                offset.vy = (PlayerStatus.Crouching ? CollisionExtents[CE_PREDATOR].CrouchingTop : CollisionExtents[CE_PREDATOR].StandingTop);
 
 
1211
        }
 
 
1212
 
 
 
1213
        if(PlayerStatus.FirstPersonView)
 
 
1214
        {
 
 
1215
            ModifyHeadOrientation();
 
 
1216
            //if (CHEATMODE_LANDOFTHEGIANTS == UserProfile.active_bonus) offset.vy /= 4;
 
 
1217
        }
 
 
1218
        else
 
 
1219
        {
 
 
1220
            if(1)
 
 
1221
            {
 
 
1222
                offset.vz = -CollisionExtents[AvP.PlayerType].CollisionRadius * 3;
 
 
1223
                offset.vy = PlayerStatus.Crouching ? CollisionExtents[AvP.PlayerType].CrouchingTop : CollisionExtents[AvP.PlayerType].StandingTop;
 
 
1224
                offset.vy -= 1500;
 
 
1225
            }
 
 
1226
            else if(1)
 
 
1227
            {
 
 
1228
                offset.vz = -CollisionExtents[AvP.PlayerType].CollisionRadius;
 
 
1229
                offset.vy = PlayerStatus.Crouching ? CollisionExtents[AvP.PlayerType].CrouchingTop : CollisionExtents[AvP.PlayerType].StandingTop;
 
 
1230
                offset.vy -= 50;
 
 
1231
            }
 
 
1232
            else // first person view with model
 
 
1233
            {
 
 
1234
                offset.vz = CollisionExtents[AvP.PlayerType].CollisionRadius;
 
 
1235
                offset.vy = PlayerStatus.Crouching ? CollisionExtents[AvP.PlayerType].CrouchingTop : CollisionExtents[AvP.PlayerType].StandingTop;
 
 
1236
                offset.vy += 100;
 
 
1237
            }
 
 
1238
        }
 
 
1239
 
 
 
1240
        if (!PlayerStatus.Alive && !MultiplayerObservedPlayer)
 
 
1241
        {
 
 
1242
            offset.vy = MUL_FIXED(deathFadeLevel * 4 - 3 * ONE_FIXED, offset.vy);
 
 
1243
 
 
 
1244
            if (offset.vy > -100)
 
 
1245
                offset.vy = -100;
 
 
1246
        }
 
 
1247
 
 
 
1248
        //offset.vy += verticalSpeed / 16+200;
 
 
1249
 
 
 
1250
        RotateVector(&offset, &PlayerStatus.DisplayBlock->ObMat);
 
 
1251
        Global_VDB.VDB_World.vx += offset.vx;
 
 
1252
        Global_VDB.VDB_World.vy += offset.vy;
 
 
1253
        Global_VDB.VDB_World.vz += offset.vz;
 
 
1254
    }
 
 
1255
 
 
 
1256
    {
 
 
1257
        EULER orientation = HeadOrientation;
 
 
1258
 
 
 
1259
        orientation.EulerZ += zAxisTilt >> 8;
 
 
1260
        orientation.EulerZ &= 4095;
 
 
1261
 
 
 
1262
        if (CHEATMODE_NAUSEA == UserProfile.active_bonus)
 
 
1263
        {
 
 
1264
            orientation.EulerZ = (orientation.EulerZ + GetSin((CloakingPhase/2) & 4095) / 256) & 4095;
 
 
1265
            orientation.EulerX = (orientation.EulerX + GetSin((CloakingPhase/2+500) & 4095) / 512) & 4095;
 
 
1266
            orientation.EulerY = (orientation.EulerY + GetSin((CloakingPhase/3+800) & 4095) / 512) & 4095;
 
 
1267
        }
 
 
1268
        // The next test drops the matrix multiply if the orientation is close to zero
 
 
1269
        // There is an inaccuracy problem with the Z angle at this point
 
 
1270
 
 
 
1271
        if (orientation.EulerX || orientation.EulerY || (orientation.EulerZ > 1 && orientation.EulerZ <    4095))
 
 
1272
        {
 
 
1273
            MATRIXCH matrix;
 
 
1274
            CreateEulerMatrix(&orientation, &matrix);
 
 
1275
            MatrixMultiply(&Global_VDB.VDB_Mat, &matrix, &Global_VDB.VDB_Mat);
 
 
1276
         }
 
 
1277
    }
 
 
1278
 
 
 
1279
    {
 
 
1280
        VECTORCH relativeVelocity;
 
 
1281
 
 
 
1282
        /* get subject's total velocity */
 
 
1283
        {
 
 
1284
            DYNAMICSBLOCK *dynPtr = PlayerStatus.sbptr->DynPtr;    
 
 
1285
            /* make world to local matrix */
 
 
1286
            MATRIXCH worldToLocalMatrix = PlayerStatus.DisplayBlock->ObMat;
 
 
1287
 
 
 
1288
            TransposeMatrixCH(&worldToLocalMatrix);                                                       
 
 
1289
 
 
 
1290
            relativeVelocity.vx = dynPtr->Position.vx - dynPtr->PrevPosition.vx;        
 
 
1291
            relativeVelocity.vy = dynPtr->Position.vy - dynPtr->PrevPosition.vy;
 
 
1292
            relativeVelocity.vz = dynPtr->Position.vz - dynPtr->PrevPosition.vz;
 
 
1293
            /* rotate into object space */
 
 
1294
 
 
 
1295
            RotateVector(&relativeVelocity, &worldToLocalMatrix);
 
 
1296
        }
 
 
1297
 
 
 
1298
        {
 
 
1299
            int targetingSpeed = 10 * NormalFrameTime;
 
 
1300
 
 
 
1301
            /* KJL 14:08:50 09/20/96 - the targeting is FRI, but care has to be taken
 
 
1302
               at very low frame rates to ensure that you can't overshoot */
 
 
1303
            if (targetingSpeed > 65536)
 
 
1304
                targetingSpeed = 65536;
 
 
1305
 
 
 
1306
            zAxisTilt += MUL_FIXED ( DIV_FIXED ( MUL_FIXED(relativeVelocity.vx, PlayerStatus.LeanScale), NormalFrameTime )-zAxisTilt, targetingSpeed );
 
 
1307
 
 
 
1308
            {
 
 
1309
                static int previousVerticalSpeed = 0;
 
 
1310
                int difference = 0;
 
 
1311
 
 
 
1312
                if (relativeVelocity.vy >= 0)
 
 
1313
                    difference = DIV_FIXED ( previousVerticalSpeed - relativeVelocity.vy, NormalFrameTime );
 
 
1314
 
 
 
1315
                if (verticalSpeed < difference)
 
 
1316
                    verticalSpeed = difference;
 
 
1317
 
 
 
1318
                 if(verticalSpeed > 150*16)
 
 
1319
                    verticalSpeed = 150*16;
 
 
1320
 
 
 
1321
                verticalSpeed -= NormalFrameTime>>2;
 
 
1322
 
 
 
1323
                if (verticalSpeed < 0)
 
 
1324
                    verticalSpeed = 0;                
 
 
1325
 
 
 
1326
                previousVerticalSpeed = relativeVelocity.vy;
 
 
1327
            }
 
 
1328
         }
 
 
1329
    }
 
 
1330
}
 
 
1331
 
 
 
1332
void PlayerIsDamaged(const DAMAGE_PROFILE *damage, int multiplier, VECTORCH* incoming)
 
 
1333
{
 
 
1334
     int deltaHealth = PlayerStatus.Health - PlayerStatus.sbptr->DamageBlock.Health;
 
 
1335
     int deltaArmour = PlayerStatus.Armour - PlayerStatus.sbptr->DamageBlock.Armour;
 
 
1336
 
 
 
1337
    if (PlayerStatus.Alive)
 
 
1338
    {
 
 
1339
        CurrentGameStats_DamageTaken(deltaHealth, deltaArmour);
 
 
1340
 
 
 
1341
        {
 
 
1342
            int maxTilt = deltaHealth >> 12; 
 
 
1343
            int halfTilt = maxTilt / 2;
 
 
1344
 
 
 
1345
            if (maxTilt)
 
 
1346
            {
 
 
1347
                HeadOrientation.EulerX = (FastRandom()%maxTilt)-halfTilt;
 
 
1348
                HeadOrientation.EulerY = (FastRandom()%maxTilt)-halfTilt;
 
 
1349
                HeadOrientation.EulerZ = (FastRandom()%maxTilt)-halfTilt;
 
 
1350
 
 
 
1351
                if (HeadOrientation.EulerX < 0) HeadOrientation.EulerX += 4096;
 
 
1352
                if (HeadOrientation.EulerY < 0) HeadOrientation.EulerY += 4096;
 
 
1353
                if (HeadOrientation.EulerZ < 0) HeadOrientation.EulerZ += 4096;
 
 
1354
            }
 
 
1355
        }    
 
 
1356
 
 
 
1357
        if ((PlayerStatus.sound_mouth == SOUND_NOACTIVEINDEX) && (deltaHealth || deltaArmour))
 
 
1358
        {
 
 
1359
            int pitch = (FastRandom() & 255) - 128;
 
 
1360
 
 
 
1361
             switch (AvP.PlayerType)
 
 
1362
             {
 
 
1363
                case I_Alien:
 
 
1364
                {
 
 
1365
                    if (!damage->Impact && !damage->Cutting && !damage->Penetrative && damage->Fire &&
!damage->Electrical && !damage->Acid)
 
 
1366
                    {
 
 
1367
                        PlayAlienSound(0, ASC_PC_OnFire, pitch, &PlayerStatus.sound_mouth, NULL);
 
 
1368
 
 
 
1369
                        if(SinglePlayer != AvP.PlayMode)
 
 
1370
                            netGameData.myLastScream = ASC_PC_OnFire;
 
 
1371
                    }
 
 
1372
                    else
 
 
1373
                    {
 
 
1374
                        PlayAlienSound(0, ASC_Scream_Hurt, pitch, &PlayerStatus.sound_mouth, NULL);
 
 
1375
 
 
 
1376
                        if(SinglePlayer != AvP.PlayMode)
 
 
1377
                            netGameData.myLastScream = ASC_Scream_Hurt;
 
 
1378
                    }
 
 
1379
                }
 
 
1380
                break;
 
 
1381
                case I_Marine:
 
 
1382
                {
 
 
1383
                    /* Alert marines, pretty much whoever you are. */
 
 
1384
                    PointAlert(3, &PlayerStatus.sbptr->DynPtr->Position);
 
 
1385
 
 
 
1386
                    switch(damage->Id)
 
 
1387
                    {
 
 
1388
                        case AMMO_FACEHUGGER:
 
 
1389
                            PlayMarineScream(0, MSC_Facehugged, pitch, &PlayerStatus.sound_mouth, NULL);
 
 
1390
                        break;
 
 
1391
                        case AMMO_FALLINGDAMAGE:
 
 
1392
                            PlayMarineScream(0, MSC_Falling, pitch, &PlayerStatus.sound_mouth, NULL);
 
 
1393
                        break;
 
 
1394
                        default:
 
 
1395
                        {
 
 
1396
                            if( !damage->Impact && !damage->Cutting && !damage->Penetrative && !damage->Electrical)
 
 
1397
                            {
 
 
1398
                                if (damage->Acid)
 
 
1399
                                {
 
 
1400
                                    if (!damage->Fire)
 
 
1401
                                    {
 
 
1402
                                        PlayMarineScream(0, MSC_Acid, pitch, &PlayerStatus.sound_mouth, NULL);
 
 
1403
 
 
 
1404
                                        if(SinglePlayer != AvP.PlayMode)
 
 
1405
                                            netGameData.myLastScream = MSC_Acid;
 
 
1406
                                    break;
 
 
1407
                                    }
 
 
1408
                                }
 
 
1409
                                else if (damage->Fire)
 
 
1410
                                {
 
 
1411
                                    PlayMarineScream(0, MSC_PC_OnFire, pitch, &PlayerStatus.sound_mouth, NULL);
 
 
1412
 
 
 
1413
                                    if(SinglePlayer != AvP.PlayMode)
 
 
1414
                                        netGameData.myLastScream = MSC_PC_OnFire;
 
 
1415
                                break;
 
 
1416
                                }
 
 
1417
 
 
 
1418
                            }
 
 
1419
 
 
 
1420
                            PlayMarineScream(0, MSC_Pain, pitch, &PlayerStatus.sound_mouth, NULL);
 
 
1421
 
 
 
1422
                            if(SinglePlayer != AvP.PlayMode)
 
 
1423
                                netGameData.myLastScream = MSC_Pain;
 
 
1424
                        }
 
 
1425
                    }
 
 
1426
                }
 
 
1427
                break;
 
 
1428
                case I_Predator:
 
 
1429
                {
 
 
1430
                    if (damage->Id == AMMO_FACEHUGGER)
 
 
1431
                    {
 
 
1432
                        PlayPredatorSound(0, PSC_Facehugged, pitch, &PlayerStatus.sound_mouth, NULL);
 
 
1433
                    }
 
 
1434
                    else
 
 
1435
                    {
 
 
1436
                        if (!damage->Impact && !damage->Cutting && !damage->Penetrative && !damage->Electrical)
 
 
1437
                        {
 
 
1438
                            if (!damage->Fire)
 
 
1439
                            {
 
 
1440
                                if (damage->Acid)
 
 
1441
                                {
 
 
1442
                                    PlayPredatorSound(0, PSC_Acid, pitch, &PlayerStatus.sound_mouth, NULL);
 
 
1443
 
 
 
1444
                                    if(SinglePlayer != AvP.PlayMode)
 
 
1445
                                        netGameData.myLastScream = PSC_Acid;
 
 
1446
                                break;
 
 
1447
                                }
 
 
1448
                            }
 
 
1449
                            else if (!damage->Acid)
 
 
1450
                            {
 
 
1451
                                PlayPredatorSound(0, PSC_PC_OnFire, pitch, &PlayerStatus.sound_mouth, NULL);
 
 
1452
 
 
 
1453
                                if(SinglePlayer != AvP.PlayMode)
 
 
1454
                                    netGameData.myLastScream = PSC_PC_OnFire;
 
 
1455
                            break;
 
 
1456
                            } 
 
 
1457
                        }
 
 
1458
 
 
 
1459
                        PlayPredatorSound(0, PSC_Scream_Hurt, pitch, &PlayerStatus.sound_mouth, NULL);
 
 
1460
 
 
 
1461
                        if(SinglePlayer != AvP.PlayMode)
 
 
1462
                            netGameData.myLastScream = PSC_Scream_Hurt;
 
 
1463
                    }
 
 
1464
                }
 
 
1465
                default:
 
 
1466
                    break;
 
 
1467
            }
 
 
1468
 
 
 
1469
            PlayerStatus.Noise = 1;
 
 
1470
        }
 
 
1471
 
 
 
1472
        {
 
 
1473
            /* Compute scaled deltaHealth... */
 
 
1474
            int scaled_DeltaHealth = MUL_FIXED(deltaHealth, 100);
 
 
1475
            scaled_DeltaHealth = DIV_FIXED(scaled_DeltaHealth, PlayerStatus.StartingHealth);
 
 
1476
 
 
 
1477
            if (scaled_DeltaHealth > PlayerStatus.DamagedOverlayIntensity)
 
 
1478
                PlayerStatus.DamagedOverlayIntensity = scaled_DeltaHealth;
 
 
1479
        }
 
 
1480
 
 
 
1481
/*
 
 
1482
        if (deltaHealth > ONE_FIXED)
 
 
1483
        {
 
 
1484
            VECTORCH abovePosition = Global_VDB.VDB_World;
 
 
1485
            abovePosition.vy -= 1000;
 
 
1486
 
 
 
1487
             switch (AvP.PlayerType)
 
 
1488
             {
 
 
1489
                case I_Alien:
 
 
1490
                    MakeBloodExplosion(&Global_VDB.VDB_World, 127, &abovePosition, deltaHealth/ONE_FIXED, PARTICLE_ALIEN_BLOOD);
 
 
1491
                break;
 
 
1492
                case I_Marine:
 
 
1493
                    MakeBloodExplosion(&Global_VDB.VDB_World, 127, &abovePosition, deltaHealth/ONE_FIXED, PARTICLE_HUMAN_BLOOD);
 
 
1494
                break;
 
 
1495
                case I_Predator:
 
 
1496
                    MakeBloodExplosion(&Global_VDB.VDB_World, 127, &abovePosition, deltaHealth/ONE_FIXED, PARTICLE_PREDATOR_BLOOD);
 
 
1497
            }
 
 
1498
        }
 
 
1499
*/
 
 
1500
 
 
 
1501
        if (PlayerStatus.sbptr->DamageBlock.Health <= 0)
 
 
1502
            PlayerIsDead(damage, multiplier, incoming);
 
 
1503
 
 
 
1504
        PlayerStatus.Health = PlayerStatus.sbptr->DamageBlock.Health;
 
 
1505
        PlayerStatus.Armour = PlayerStatus.sbptr->DamageBlock.Armour;
 
 
1506
    }
 
 
1507
}
 
 
1508
 
 
 
1509
static void NetPlayerDeadProcessing()
 
 
1510
{
 
 
1511
    /* call the read input function so that we can still respawn/quit, etc */
 
 
1512
 
 
 
1513
    /* check for re-spawn */
 
 
1514
    if(Keyboard_input_operate())
 
 
1515
    {
 
 
1516
        if(AreThereAnyLivesLeft())
 
 
1517
        {
 
 
1518
            //check for change of character
 
 
1519
            if(netGameData.myCharacterType != netGameData.myNextCharacterType)
 
 
1520
            {
 
 
1521
                switch(netGameData.myNextCharacterType)
 
 
1522
                {
 
 
1523
                    case NGCT_Marine:
 
 
1524
                        ChangeToMarine();
 
 
1525
                    break;
 
 
1526
                    case NGCT_Alien:
 
 
1527
                        ChangeToAlien();
 
 
1528
                    break;
 
 
1529
                    case NGCT_Predator:
 
 
1530
                        ChangeToPredator();
 
 
1531
                    break;
 
 
1532
                    default:
 
 
1533
                        assert("dodgy character type"==0);
 
 
1534
                        break;
 
 
1535
                }
 
 
1536
 
 
 
1537
                netGameData.myCharacterType = netGameData.myNextCharacterType;
 
 
1538
            }
 
 
1539
            else
 
 
1540
            {
 
 
1541
                NetPlayerRespawn();
 
 
1542
            }
 
 
1543
 
 
 
1544
            /* dynamics block stuff... */
 
 
1545
            {
 
 
1546
                EULER zeroEuler = {0,0,0};
 
 
1547
                VECTORCH zeroVec = {0,0,0};
 
 
1548
                DYNAMICSBLOCK *dynPtr = PlayerStatus.sbptr->DynPtr;
 
 
1549
 
 
 
1550
                dynPtr->Position = zeroVec;
 
 
1551
                dynPtr->OrientEuler = zeroEuler;
 
 
1552
                dynPtr->LinVelocity = zeroVec;
 
 
1553
                dynPtr->LinImpulse = zeroVec;
 
 
1554
 
 
 
1555
                CreateEulerMatrix(&dynPtr->OrientEuler, &dynPtr->OrientMat);
 
 
1556
                TransposeMatrixCH(&dynPtr->OrientMat);
 
 
1557
 
 
 
1558
                //Need to get rid of collisions for this frame , so player doesn't pick up
 
 
1559
                //his dropped weapon when he respawns.
 
 
1560
                dynPtr->CollisionReportPtr = 0;
 
 
1561
            }
 
 
1562
 
 
 
1563
            TeleportNetPlayerToAStartingPosition(0);
 
 
1564
        }
 
 
1565
        else
 
 
1566
        {
 
 
1567
            //no lives left , so have to act as an observer
 
 
1568
            GetNextMultiplayerObservedPlayer();
 
 
1569
 
 
 
1570
            //The player's dropped weapon (if there was one) can now be drawn
 
 
1571
            MakePlayersWeaponPickupVisible();
 
 
1572
        }
 
 
1573
    }
 
 
1574
}
 
 
1575
 
 
 
1576
void PlayerBehaviour()
 
 
1577
{
 
 
1578
    PlayerStatus.Noise = 0;
 
 
1579
    PlayerStatus.sbptr->containingModule = ModuleFromPosition(&PlayerStatus.DisplayBlock->ObWorld, PlayerStatus.sbptr->containingModule);
 
 
1580
 
 
 
1581
{
 
 
1582
    int cos = GetCos(PlayerStatus.ViewPanX);
 
 
1583
    int sin = GetSin(PlayerStatus.ViewPanX);
 
 
1584
    MATRIXCH mat = { 0 };
 
 
1585
 
 
 
1586
    Global_VDB.VDB_World = PlayerStatus.DisplayBlock->ObWorld;
 
 
1587
 
 
 
1588
    mat.mat11 = ONE_FIXED;
 
 
1589
    mat.mat22 = cos;
 
 
1590
    mat.mat23 = -sin;
 
 
1591
    mat.mat32 = sin;
 
 
1592
    mat.mat33 = cos;
 
 
1593
 
 
 
1594
     MatrixMultiply(&PlayerStatus.DisplayBlock->ObMat, &mat, &Global_VDB.VDB_Mat);
 
 
1595
    TransposeMatrixCH(&Global_VDB.VDB_Mat);
 
 
1596
}
 
 
1597
 
 
 
1598
    InteriorType_Body();
 
 
1599
    MNormalise(&PlayerStatus.sbptr->DynPtr->OrientMat);
 
 
1600
 
 
 
1601
/*
 
 
1602
    {
 
 
1603
        extern int GlobalFrameCounter;
 
 
1604
        DYNAMICSBLOCK *dynPtr = PlayerStatus.sbptr->DynPtr;
 
 
1605
        printf("player Impulse at %d,%d,%d\n", dynPtr->LinImpulse.vx, dynPtr->LinImpulse.vy, dynPtr->LinImpulse.vz);
 
 
1606
 
 
 
1607
        printf (
 
 
1608
            "Dynamics Logging: frame %d\nDL: player's Position %d,%d,%d\nDL: player's Displacement %d,%d,%d\nDL: NormalFrameTime %d\n",
 
 
1609
            GlobalFrameCounter,
 
 
1610
            dynPtr->Position.vx, dynPtr->Position.vy, dynPtr->Position.vz,
 
 
1611
            dynPtr->Displacement.vx, dynPtr->Displacement.vy, dynPtr->Displacement.vz,
 
 
1612
            NormalFrameTime);
 
 
1613
 
 
 
1614
    }
 
 
1615
*/    
 
 
1616
    if (PlayerStatus.Alive)
 
 
1617
    {
 
 
1618
        if (PlayerStatus.tauntTimer) 
 
 
1619
        {
 
 
1620
            PlayerStatus.tauntTimer -= NormalFrameTime;
 
 
1621
 
 
 
1622
            if (PlayerStatus.tauntTimer < 0) 
 
 
1623
                PlayerStatus.tauntTimer = 0;
 
 
1624
 
 
 
1625
            switch(AvP.PlayerType)
 
 
1626
            {
 
 
1627
                case I_Alien:
 
 
1628
                {
 
 
1629
                    extern EULER HeadOrientation;
 
 
1630
                    int ex = MUL_FIXED( 64, GetSin(((PlayerStatus.tauntTimer >> 6) & wrap360)));
 
 
1631
                    int ey = MUL_FIXED(128, GetSin(((PlayerStatus.tauntTimer >> 5) & wrap360)));
 
 
1632
                    int ez = MUL_FIXED(-64, GetSin(((PlayerStatus.tauntTimer >> 5) & wrap360)));
 
 
1633
 
 
 
1634
                    ex &= wrap360;
 
 
1635
                    ey &= wrap360;
 
 
1636
                    ez &= wrap360;
 
 
1637
 
 
 
1638
                    HeadOrientation.EulerX = ex;
 
 
1639
                    HeadOrientation.EulerY = ey;
 
 
1640
                    HeadOrientation.EulerZ = ez;
 
 
1641
                }
 
 
1642
                default:
 
 
1643
                break;
 
 
1644
            }
 
 
1645
        }
 
 
1646
 
 
 
1647
        handle_user_input();
 
 
1648
        PlayerStatus.weapon_func();
 
 
1649
 
 
 
1650
        if(SinglePlayer != AvP.PlayMode)
 
 
1651
        {
 
 
1652
            if(PlayerStatus.invulnerabilityTimer)
 
 
1653
            {
 
 
1654
                PlayerStatus.sbptr->DamageBlock.IsOnFire = 0;
 
 
1655
                PlayerStatus.invulnerabilityTimer -= NormalFrameTime;
 
 
1656
 
 
 
1657
                if(PlayerStatus.invulnerabilityTimer < 0)
 
 
1658
                    PlayerStatus.invulnerabilityTimer = 0;
 
 
1659
 
 
 
1660
                //lose invulnerability if player is firing
 
 
1661
 
 
 
1662
                if(PlayerStatus.InputRequests.Rqst_FirePrimaryWeapon)
 
 
1663
                {
 
 
1664
                    if(WEAPON_PRED_MEDICOMP != PlayerStatus.SelectedWeapon->WeaponIDNumber)
 
 
1665
                        PlayerStatus.invulnerabilityTimer = 0;
 
 
1666
                }
 
 
1667
 
 
 
1668
                if(PlayerStatus.InputRequests.Rqst_FireSecondaryWeapon)
 
 
1669
                {
 
 
1670
                    //not many weapons have an offensive secondary fire
 
 
1671
 
 
 
1672
                    switch(PlayerStatus.SelectedWeapon->WeaponIDNumber)
 
 
1673
                    {
 
 
1674
                        case WEAPON_PULSERIFLE:
 
 
1675
                        case WEAPON_CUDGEL:
 
 
1676
                        case WEAPON_MARINE_PISTOL:
 
 
1677
                        case WEAPON_TWO_PISTOLS:
 
 
1678
                        case WEAPON_PRED_WRISTBLADE:
 
 
1679
                        case WEAPON_ALIEN_CLAW:
 
 
1680
                            PlayerStatus.invulnerabilityTimer = 0;
 
 
1681
                        default:
 
 
1682
                        break;
 
 
1683
                    }
 
 
1684
                }
 
 
1685
 
 
 
1686
                PlayerStatus.sbptr->DamageBlock.Indestructable = PlayerStatus.invulnerabilityTimer;
 
 
1687
            }
 
 
1688
        }
 
 
1689
        else
 
 
1690
        {
 
 
1691
            CurrentGameStats_VisionMode(PlayerStatus.VisionMode);
 
 
1692
            CurrentGameStats_UsingWeapon(PlayerStatus.SelectedWeaponSlot);
 
 
1693
            CurrentGameStats_SpeedSample(Approximate3dMagnitude(&PlayerStatus.sbptr->DynPtr->LinVelocity), NormalFrameTime);
 
 
1694
        }
 
 
1695
 
 
 
1696
        //printf("PlayerLight %d\n", PlayerStatus.CurrentLightAtPlayer);
 
 
1697
    }
 
 
1698
    else
 
 
1699
    {
 
 
1700
        extern int RealFrameTime;
 
 
1701
 
 
 
1702
        if(SinglePlayer == AvP.PlayMode)
 
 
1703
        {
 
 
1704
            if(deathFadeLevel > ONE_FIXED/2)
 
 
1705
            {
 
 
1706
                deathFadeLevel -= RealFrameTime / 4;
 
 
1707
                //FadeDownScreen(deathFadeLevel, 0);
 
 
1708
            }
 
 
1709
            else
 
 
1710
            {
 
 
1711
                extern SCREENDESCRIPTORBLOCK ScreenDescriptorBlock;
 
 
1712
                //deathFadeLevel = 0;
 
 
1713
                RenderStringCentred("Press operate to restart game", ScreenDescriptorBlock.SDB_CentreX, ScreenDescriptorBlock.SDB_Height-20,
0xffffffff);
 
 
1714
                AvP.MainLoopRunning = !(AvP.RestartLevel = Keyboard_input_operate());
 
 
1715
            }
 
 
1716
        }
 
 
1717
        else
 
 
1718
        {
 
 
1719
            if(deathFadeLevel > 0)
 
 
1720
            {
 
 
1721
                deathFadeLevel -= RealFrameTime / 2;    
 
 
1722
            }
 
 
1723
            else
 
 
1724
            {
 
 
1725
                deathFadeLevel = 0;
 
 
1726
                NetPlayerDeadProcessing();
 
 
1727
            }
 
 
1728
        }
 
 
1729
    }
 
 
1730
}
 
 
1731
 
 
 
1732
/*---------------------------**
 
 
1733
** Loading and saving player **
 
 
1734
**---------------------------*/
 
 
1735
 
 
 
1736
typedef struct player_save_block
 
 
1737
{
 
 
1738
    SAVE_BLOCK_STRATEGY_HEADER header;
 
 
1739
 
 
 
1740
//behaviour block things
 
 
1741
    struct PLAYER_WEAPON_DATA    WeaponSlot[MAX_NO_OF_WEAPON_SLOTS];
 
 
1742
    struct PLAYER_WEAPON_DATA    *SelectedWeapon;
 
 
1743
 
 
 
1744
    enum WEAPON_SLOT    SelectedWeaponSlot;
 
 
1745
    enum WEAPON_SLOT    SwapToWeaponSlot;
 
 
1746
    enum WEAPON_SLOT    PreviouslySelectedWeaponSlot;
 
 
1747
    enum WEAPON_STATE    WeaponState;
 
 
1748
    enum VISION_MODE_ID    VisionMode;
 
 
1749
 
 
 
1750
    VECTORCH    WeaponPositionOffset;
 
 
1751
    int        WeaponStateTimeOutCounter;
 
 
1752
 
 
 
1753
    int    Health;     /* in 16.16 */
 
 
1754
    int    Armour;     /* in 16.16 */
 
 
1755
 
 
 
1756
    unsigned int Crouching;
 
 
1757
 
 
 
1758
    signed int ForwardInertia;
 
 
1759
    signed int StrafeInertia; 
 
 
1760
    signed int TurnInertia;     
 
 
1761
 
 
 
1762
    int ViewPanX; /* the looking up/down value that used to be in displayblock */
 
 
1763
 
 
 
1764
    unsigned int securityClearances;
 
 
1765
    unsigned int IHaveAPlacedAutogun :1;
 
 
1766
    unsigned int JetpackEnabled :1;
 
 
1767
    unsigned int GrapplingHookEnabled :1;
 
 
1768
    unsigned int cloakOn :1;
 
 
1769
    unsigned int muzzle_flash:1;
 
 
1770
    unsigned int FirstPersonView:1;
 
 
1771
 
 
 
1772
    int FieldCharge;
 
 
1773
    int PlasmaCasterCharge;
 
 
1774
    int imageintensifier_battery;
 
 
1775
    int FlaresLeft;
 
 
1776
    int CloakingEffectiveness; 
 
 
1777
    int SmartGunMode;
 
 
1778
    int tauntTimer;
 
 
1779
    int incidentFlag;
 
 
1780
    int incidentTimer;
 
 
1781
 
 
 
1782
//some stuff for the weapon displayblock
 
 
1783
    VECTORCH Weapon_World;
 
 
1784
    EULER Weapon_Euler;
 
 
1785
    MATRIXCH Weapon_Matrix;
 
 
1786
 
 
 
1787
//and  globals
 
 
1788
    GRENADE_LAUNCHER_DATA GrenadeLauncherData;
 
 
1789
 
 
 
1790
//strategy block stuff
 
 
1791
    DYNAMICSBLOCK dynamics;
 
 
1792
    DAMAGEBLOCK DamageBlock;
 
 
1793
 
 
 
1794
} PLAYER_SAVE_BLOCK;
 
 
1795
 
 
 
1796
//defines for load/save macros
 
 
1797
#define SAVELOAD_BLOCK block
 
 
1798
#define SAVELOAD_BEHAV playerStatusPtr
 
 
1799
 
 
 
1800
void SaveStrategy_Player(STRATEGYBLOCK* sbPtr)
 
 
1801
{
 
 
1802
    PLAYER_SAVE_BLOCK* block;
 
 
1803
    int i;
 
 
1804
    PLAYER_STATUS *playerStatusPtr = &PlayerStatus;
 
 
1805
 
 
 
1806
    GET_STRATEGY_SAVE_BLOCK(block, sbPtr);
 
 
1807
 
 
 
1808
    COPYELEMENT_SAVE(SelectedWeaponSlot)
 
 
1809
    COPYELEMENT_SAVE(SwapToWeaponSlot)
 
 
1810
    COPYELEMENT_SAVE(PreviouslySelectedWeaponSlot)
 
 
1811
    COPYELEMENT_SAVE(WeaponState)
 
 
1812
    COPYELEMENT_SAVE(VisionMode)
 
 
1813
    COPYELEMENT_SAVE(WeaponPositionOffset)
 
 
1814
    COPYELEMENT_SAVE(WeaponStateTimeOutCounter)
 
 
1815
    COPYELEMENT_SAVE(Health)     /* in 16.16 */
 
 
1816
    COPYELEMENT_SAVE(Armour)     /* in 16.16 */
 
 
1817
    COPYELEMENT_SAVE(Crouching)
 
 
1818
    COPYELEMENT_SAVE(ForwardInertia)
 
 
1819
    COPYELEMENT_SAVE(StrafeInertia) 
 
 
1820
    COPYELEMENT_SAVE(TurnInertia)     
 
 
1821
    COPYELEMENT_SAVE(ViewPanX) /* the looking up/down value that used to be in displayblock */
 
 
1822
    COPYELEMENT_SAVE(securityClearances)
 
 
1823
    COPYELEMENT_SAVE(IHaveAPlacedAutogun)
 
 
1824
    COPYELEMENT_SAVE(JetpackEnabled)
 
 
1825
    COPYELEMENT_SAVE(GrapplingHookEnabled )
 
 
1826
    COPYELEMENT_SAVE(cloakOn)
 
 
1827
    COPYELEMENT_SAVE(muzzle_flash)
 
 
1828
    COPYELEMENT_SAVE(FirstPersonView)
 
 
1829
    COPYELEMENT_SAVE(FieldCharge)
 
 
1830
    COPYELEMENT_SAVE(PlasmaCasterCharge)
 
 
1831
    COPYELEMENT_SAVE(imageintensifier_battery)
 
 
1832
    COPYELEMENT_SAVE(FlaresLeft)
 
 
1833
    COPYELEMENT_SAVE(CloakingEffectiveness) 
 
 
1834
    COPYELEMENT_SAVE(SmartGunMode) 
 
 
1835
    COPYELEMENT_SAVE(tauntTimer)
 
 
1836
    COPYELEMENT_SAVE(incidentFlag)
 
 
1837
    COPYELEMENT_SAVE(incidentTimer)
 
 
1838
 
 
 
1839
    for(i=0; i < MAX_NO_OF_WEAPON_SLOTS; i++)
 
 
1840
    {
 
 
1841
        block->WeaponSlot[i].WeaponIDNumber = PlayerStatus.WeaponSlot[i].WeaponIDNumber;         
 
 
1842
        block->WeaponSlot[i].PrimaryRoundsRemaining = PlayerStatus.WeaponSlot[i].PrimaryRoundsRemaining;         
 
 
1843
        block->WeaponSlot[i].SecondaryRoundsRemaining = PlayerStatus.WeaponSlot[i].SecondaryRoundsRemaining;         
 
 
1844
        block->WeaponSlot[i].MagazinesRemaining = PlayerStatus.WeaponSlot[i].MagazinesRemaining;    
 
 
1845
        block->WeaponSlot[i].Possessed = PlayerStatus.WeaponSlot[i].Possessed;         
 
 
1846
    }
 
 
1847
 
 
 
1848
    //some stuff for the weapon displayblock
 
 
1849
    block->Weapon_World = PlayerStatus.weapon.ObWorld;
 
 
1850
    block->Weapon_Euler = PlayerStatus.weapon.ObEuler;
 
 
1851
    block->Weapon_Matrix = PlayerStatus.weapon.ObMat;
 
 
1852
 
 
 
1853
    //global
 
 
1854
    block->GrenadeLauncherData = GrenadeLauncherData;
 
 
1855
 
 
 
1856
    //strategy block stuff
 
 
1857
    block->DamageBlock = sbPtr->DamageBlock;
 
 
1858
    block->dynamics = *sbPtr->DynPtr;
 
 
1859
    block->dynamics.CollisionReportPtr = NULL;
 
 
1860
 
 
 
1861
    //save the weapon hierarchy
 
 
1862
    SaveHierarchy(&PlayersWeaponHModelController);
 
 
1863
 
 
 
1864
    Save_SoundState(&PlayerStatus.sound_mouth);
 
 
1865
    Save_SoundState(&PlayerStatus.soundCracklingFire);
 
 
1866
    Save_SoundState(&PlayerStatus.sound_jetpack);
 
 
1867
}
 
 
1868
 
 
 
1869
void LoadStrategy_Player(SAVE_BLOCK_STRATEGY_HEADER* header)
 
 
1870
{
 
 
1871
    PLAYER_SAVE_BLOCK* block = (PLAYER_SAVE_BLOCK*) header;
 
 
1872
    STRATEGYBLOCK* sbPtr = PlayerStatus.sbptr;
 
 
1873
    int i;
 
 
1874
 
 
 
1875
    if(block->header.size != sizeof(*block))
 
 
1876
        return;
 
 
1877
 
 
 
1878
    COPY_NAME(sbPtr->SBname, header->SBname);
 
 
1879
 
 
 
1880
    PlayerStatus.SelectedWeaponSlot = block->SelectedWeaponSlot;
 
 
1881
    PlayerStatus.SwapToWeaponSlot = block->SwapToWeaponSlot;
 
 
1882
    PlayerStatus.PreviouslySelectedWeaponSlot = block->PreviouslySelectedWeaponSlot;
 
 
1883
    PlayerStatus.WeaponState = block->WeaponState;
 
 
1884
    PlayerStatus.VisionMode = block->VisionMode;
 
 
1885
    PlayerStatus.WeaponPositionOffset = block->WeaponPositionOffset;
 
 
1886
    PlayerStatus.WeaponStateTimeOutCounter = block->WeaponStateTimeOutCounter;
 
 
1887
    PlayerStatus.Health = block->Health;
 
 
1888
    PlayerStatus.Armour = block->Armour;
 
 
1889
    PlayerStatus.Crouching = block->Crouching;
 
 
1890
    PlayerStatus.ForwardInertia = block->ForwardInertia;
 
 
1891
    PlayerStatus.StrafeInertia = block->StrafeInertia;
 
 
1892
    PlayerStatus.TurnInertia = block->TurnInertia;    
 
 
1893
    PlayerStatus.ViewPanX = block->ViewPanX;
 
 
1894
    PlayerStatus.securityClearances = block->securityClearances;
 
 
1895
    PlayerStatus.IHaveAPlacedAutogun = block->IHaveAPlacedAutogun;
 
 
1896
    PlayerStatus.JetpackEnabled = block->JetpackEnabled;
 
 
1897
    PlayerStatus.GrapplingHookEnabled = block->GrapplingHookEnabled;
 
 
1898
    PlayerStatus.cloakOn = block->cloakOn;
 
 
1899
    PlayerStatus.muzzle_flash = block->muzzle_flash;
 
 
1900
    PlayerStatus.FirstPersonView = block->FirstPersonView;
 
 
1901
    PlayerStatus.FieldCharge = block->FieldCharge;
 
 
1902
    PlayerStatus.PlasmaCasterCharge = block->PlasmaCasterCharge;
 
 
1903
    PlayerStatus.imageintensifier_battery = block->imageintensifier_battery;
 
 
1904
    PlayerStatus.FlaresLeft = block->FlaresLeft;
 
 
1905
    PlayerStatus.CloakingEffectiveness = block->CloakingEffectiveness;
 
 
1906
    PlayerStatus.SmartGunMode = block->SmartGunMode;
 
 
1907
    PlayerStatus.tauntTimer = block->tauntTimer;
 
 
1908
    PlayerStatus.incidentFlag = block->incidentFlag;
 
 
1909
    PlayerStatus.incidentTimer = block->incidentTimer;
 
 
1910
 
 
 
1911
    for(i=0; i < MAX_NO_OF_WEAPON_SLOTS; i++)
 
 
1912
    {
 
 
1913
        PlayerStatus.WeaponSlot[i].WeaponIDNumber = block->WeaponSlot[i].WeaponIDNumber;         
 
 
1914
        PlayerStatus.WeaponSlot[i].PrimaryRoundsRemaining = block->WeaponSlot[i].PrimaryRoundsRemaining;         
 
 
1915
        PlayerStatus.WeaponSlot[i].SecondaryRoundsRemaining = block->WeaponSlot[i].SecondaryRoundsRemaining;         
 
 
1916
        PlayerStatus.WeaponSlot[i].MagazinesRemaining = block->WeaponSlot[i].MagazinesRemaining;    
 
 
1917
        PlayerStatus.WeaponSlot[i].Possessed = block->WeaponSlot[i].Possessed;         
 
 
1918
    }
 
 
1919
 
 
 
1920
    PlayerStatus.SelectedWeapon = &PlayerStatus.WeaponSlot[PlayerStatus.SelectedWeaponSlot];
 
 
1921
 
 
 
1922
    //some stuff for the weapon displayblock
 
 
1923
    PlayerStatus.weapon.ObWorld = block->Weapon_World;
 
 
1924
    PlayerStatus.weapon.ObEuler = block->Weapon_Euler;
 
 
1925
    PlayerStatus.weapon.ObMat = block->Weapon_Matrix;
 
 
1926
 
 
 
1927
    //global
 
 
1928
    GrenadeLauncherData = block->GrenadeLauncherData;
 
 
1929
 
 
 
1930
    //strategy block stuff
 
 
1931
    *sbPtr->DynPtr = block->dynamics;
 
 
1932
    sbPtr->DamageBlock = block->DamageBlock;
 
 
1933
       sbPtr->containingModule = ModuleFromPosition(&sbPtr->DynPtr->Position, NULL);
 
 
1934
    Global_VDB.VDB_World = sbPtr->DynPtr->Position;
 
 
1935
 
 
 
1936
    //load the weapon hierarchy
 
 
1937
    {
 
 
1938
        SAVE_BLOCK_HEADER* hier_header = GetNextBlockIfOfType(SaveBlock_Hierarchy);
 
 
1939
 
 
 
1940
        if(hier_header)
 
 
1941
            LoadHierarchy(hier_header, &PlayersWeaponHModelController);
 
 
1942
        else
 
 
1943
            Dispel_HModel(&PlayersWeaponHModelController);
 
 
1944
    }
 
 
1945
 
 
 
1946
    GrabWeaponShape(); // alien needs this
 
 
1947
 
 
 
1948
    Load_SoundState(&PlayerStatus.sound_mouth);
 
 
1949
    Load_SoundState(&PlayerStatus.soundCracklingFire);
 
 
1950
    Load_SoundState(&PlayerStatus.sound_jetpack);
 
 
1951
}