4b825dc642cb6eb9a060e54bf8d69288fbee4904ebd360ec63ec976c05699f3180e866b3f69e5472
 
 
1
#include "species_sound.h"
 
 
2
#include "system.h"
 
 
3
#include "stratdef.h"
 
 
4
#include "pheromon.h"
 
 
5
#include "bh_types.h"
 
 
6
#include "usr_io.h"
 
 
7
#include "paintball.h"
 
 
8
#include "net.h"
 
 
9
#include "lighting.h"
 
 
10
#include "hud.h"
 
 
11
#include "kshape.h"
 
 
12
#include "los.h"
 
 
13
#include "weapons.h"
 
 
14
 
 
 
15
extern int move_player();
 
 
16
extern int LightIntensityAtPoint(VECTORCH *pointPtr);
 
 
17
extern void ActivateGrapplingHook();
 
 
18
extern void HandleGrapplingHookForces();
 
 
19
extern void RenderGrapplingHook();
 
 
20
extern void RequestChangeOfWeapon(int);
 
 
21
extern void mission_messages_show_history();
 
 
22
extern void StartPlayerTaunt();
 
 
23
extern void Recall_Disc();
 
 
24
extern void ThrowAFlare();
 
 
25
extern void toggle_cloak();
 
 
26
 
 
 
27
#define MARINE_JUMPVELOCITY    10000
 
 
28
#define ALIEN_JUMPVELOCITY    13000
 
 
29
#define PREDATOR_JUMPVELOCITY    12000
 
 
30
 
 
 
31
#define FASTMOVESCALE        12000
 
 
32
#define FASTSTRAFESCALE        10000
 
 
33
#define PANRATESHIFT        6
 
 
34
#define JETPACK_MAX_SPEED    10000
 
 
35
#define JETPACK_THRUST        40000
 
 
36
#define TIMEBEFOREAUTOCENTREVIEW 16384
 
 
37
 
 
 
38
#define ALIEN_MAXMOVESCALE    16000 // crouch on flat
 
 
39
#define ALIEN_STANDINGRUNNINGMOVESCALE    14000
 
 
40
#define ALIEN_CLIMBINGMOVESCALE    13000
 
 
41
 
 
 
42
#define PREDATOR_MOVESCALE    12000
 
 
43
#define MARINE_MOVESCALE    10000
 
 
44
 
 
 
45
extern int ALIEN_STRAFESCALE;
 
 
46
extern int PREDATOR_STRAFESCALE;
 
 
47
extern int MARINE_STRAFESCALE;
 
 
48
extern int cloakDebounce;
 
 
49
extern int CameraZoomLevel;
 
 
50
extern int predOVision_SoundHandle;
 
 
51
extern int CrouchIsToggleKey;
 
 
52
extern int FlareDebounced;
 
 
53
extern uint8_t * Keyboard;
 
 
54
extern PLAYER_INPUT_CONFIGURATION *primaryInput;
 
 
55
extern PLAYER_INPUT_CONFIGURATION *secondaryInput;
 
 
56
 
 
 
57
static int visionModeDebounced = 0;
 
 
58
static int ViewModeDebounced = 0;
 
 
59
 
 
 
60
static const int PredatorVisionThreshold = (3 * ONE_FIXED);
 
 
61
 
 
 
62
int PlayersMaxHeightWhilstNotInContactWithGround;
 
 
63
int FlyModeOn = 0;
 
 
64
int TURNSCALE = 2000;
 
 
65
int AllowedLookUpAngle;
 
 
66
int AllowedLookDownAngle;
 
 
67
 
 
 
68
PLAYER_INPUT_CONFIGURATION DefaultAlienInputPrimaryConfig =
 
 
69
{
 
 
70
    SDLK_d,            // Forward
 
 
71
    SDLK_x,            // Backward
 
 
72
    SDLK_CLEAR,         // Left
 
 
73
    SDLK_CLEAR,         // Right
 
 
74
    SDLK_CLEAR,        // Strafe
 
 
75
    SDLK_a,             // StrafeLeft
 
 
76
    SDLK_f,             // StrafeRight
 
 
77
    SDLK_CLEAR,        // LookUp
 
 
78
    SDLK_CLEAR,        // LookDown
 
 
79
    SDLK_CLEAR,        // CentreView
 
 
80
    SDLK_CLEAR,        // Walk
 
 
81
    SDL_BUTTON_MIDDLE,    // Jump
 
 
82
    SDLK_SPACE,        // Operate
 
 
83
    SDLK_t,            // Taunt
 
 
84
    SDLK_y,            // ViewMode
 
 
85
    SDLK_F1,        // MessageHistory
 
 
86
    SDLK_s,             // Crouch / Climb
 
 
87
    SDL_BUTTON_LEFT,    // Claw Attack
 
 
88
    SDL_BUTTON_RIGHT,    // Tail Attack
 
 
89
    {SDL_BUTTON_WHEELUP},    // AlternateVision
 
 
90
    SDLK_CLEAR,        // Empty
 
 
91
    SDLK_CLEAR,        // Empty
 
 
92
    SDLK_CLEAR,        // Empty
 
 
93
    {SDLK_CLEAR},        // Empty
 
 
94
    {SDLK_CLEAR},        // Empty
 
 
95
    SDLK_CLEAR,        // Empty
 
 
96
    SDLK_CLEAR,        // Empty
 
 
97
    SDLK_CLEAR        // Empty
 
 
98
};
 
 
99
 
 
 
100
 
 
 
101
PLAYER_INPUT_CONFIGURATION DefaultAlienInputSecondaryConfig =
 
 
102
{
 
 
103
    SDLK_CLEAR,        // Forward
 
 
104
    SDLK_CLEAR,        // Backward
 
 
105
    SDLK_j,         // Left
 
 
106
    SDLK_k,         // Right
 
 
107
    SDLK_CLEAR,        // Strafe
 
 
108
    SDLK_CLEAR,         // StrafeLeft
 
 
109
    SDLK_CLEAR,         // StrafeRight
 
 
110
    SDLK_CLEAR,        // LookUp
 
 
111
    SDLK_CLEAR,        // LookDown
 
 
112
    SDLK_CLEAR,        // CentreView
 
 
113
    SDLK_CLEAR,        // Walk
 
 
114
    SDLK_CLEAR,        // Jump
 
 
115
    SDLK_CLEAR,        // Operate
 
 
116
    SDLK_CLEAR,         // Taunt
 
 
117
    SDLK_CLEAR,        // ViewMode
 
 
118
    SDLK_CLEAR,        // MessageHistory
 
 
119
    SDLK_RSHIFT,        // Crouch
 
 
120
    SDLK_CLEAR,         // FirePrimaryWeapon
 
 
121
    SDLK_CLEAR,         // FireSecondaryWeapon
 
 
122
    {SDLK_CLEAR},        // AlternateVision
 
 
123
    SDLK_CLEAR,        // Empty
 
 
124
    SDLK_CLEAR,        // Empty
 
 
125
    SDLK_CLEAR,        // Empty
 
 
126
    {SDLK_CLEAR},        // Empty
 
 
127
    {SDLK_CLEAR},        // Empty
 
 
128
    SDLK_CLEAR,        // Empty
 
 
129
    SDLK_CLEAR,        // Empty
 
 
130
    SDLK_CLEAR        // Empty
 
 
131
};
 
 
132
 
 
 
133
PLAYER_INPUT_CONFIGURATION DefaultMarineInputPrimaryConfig =
 
 
134
{
 
 
135
    SDLK_d,            // Forward
 
 
136
    SDLK_x,            // Backward
 
 
137
    SDLK_CLEAR,         // Left
 
 
138
    SDLK_CLEAR,         // Right
 
 
139
    SDLK_CLEAR,        // Strafe
 
 
140
    SDLK_a,         // StrafeLeft
 
 
141
    SDLK_f,         // StrafeRight
 
 
142
    SDLK_CLEAR,        // LookUp
 
 
143
    SDLK_CLEAR,        // LookDown
 
 
144
    SDLK_CLEAR,        // CentreView
 
 
145
    SDLK_CLEAR,        // Walk
 
 
146
    SDL_BUTTON_MIDDLE,    // Jump
 
 
147
    SDLK_SPACE,        // Operate
 
 
148
    SDLK_t,            // Taunt
 
 
149
    SDLK_y,            // ViewMode
 
 
150
    SDLK_F1,        // MessageHistory
 
 
151
    SDLK_s,             // Crouch
 
 
152
    SDL_BUTTON_LEFT,    // FirePrimaryWeapon
 
 
153
    SDL_BUTTON_RIGHT,    // FireSecondaryWeapon
 
 
154
    {SDLK_w},        // ImageIntensifier
 
 
155
    SDL_BUTTON_WHEELUP,      // NextWeapon
 
 
156
    SDL_BUTTON_WHEELDOWN,    // PreviousWeapon
 
 
157
    SDLK_TAB,        // FlashbackWeapon
 
 
158
    {SDLK_g},        // ThrowFlare
 
 
159
    {SDLK_r},        // Reload
 
 
160
    SDLK_CLEAR,        // Empty
 
 
161
    SDLK_CLEAR,        // Empty
 
 
162
    SDLK_CLEAR        // Empty
 
 
163
};
 
 
164
 
 
 
165
PLAYER_INPUT_CONFIGURATION DefaultMarineInputSecondaryConfig =
 
 
166
{
 
 
167
    SDLK_CLEAR,        // Forward
 
 
168
    SDLK_CLEAR,        // Backward
 
 
169
    SDLK_j,         // Left
 
 
170
    SDLK_k,         // Right
 
 
171
    SDLK_CLEAR,        // Strafe
 
 
172
    SDLK_CLEAR,         // StrafeLeft
 
 
173
    SDLK_CLEAR,         // StrafeRight
 
 
174
    SDLK_CLEAR,        // LookUp
 
 
175
    SDLK_CLEAR,        // LookDown
 
 
176
    SDLK_CLEAR,        // CentreView
 
 
177
    SDLK_CLEAR,        // Walk
 
 
178
    SDLK_CLEAR,        // Jump
 
 
179
    SDLK_CLEAR,        // Operate
 
 
180
    SDLK_CLEAR,        // Taunt
 
 
181
    SDLK_CLEAR,        // ViewMode
 
 
182
    SDLK_CLEAR,        // MessageHistory
 
 
183
    SDLK_CLEAR,         // Crouch
 
 
184
    SDLK_CLEAR,         // FirePrimaryWeapon
 
 
185
    SDLK_CLEAR,         // FireSecondaryWeapon
 
 
186
    {SDLK_CLEAR},        // ImageIntensifier
 
 
187
    SDLK_CLEAR,        // NextWeapon
 
 
188
    SDLK_CLEAR,         // PreviousWeapon
 
 
189
    SDLK_CLEAR,        // FlashbackWeapon
 
 
190
    {SDLK_CLEAR},         // ThrowFlare
 
 
191
    {SDLK_CLEAR},        // Empty
 
 
192
    SDLK_CLEAR,        // Empty
 
 
193
    SDLK_CLEAR,        // Empty
 
 
194
    SDLK_CLEAR        // Empty
 
 
195
};
 
 
196
 
 
 
197
PLAYER_INPUT_CONFIGURATION DefaultPredatorInputPrimaryConfig =
 
 
198
{
 
 
199
    SDLK_d,            // Forward
 
 
200
    SDLK_x,            // Backward
 
 
201
    SDLK_CLEAR,         // Left
 
 
202
    SDLK_CLEAR,         // Right
 
 
203
    SDLK_CLEAR,        // Strafe
 
 
204
    SDLK_a,         // StrafeLeft
 
 
205
    SDLK_f,         // StrafeRight
 
 
206
    SDLK_CLEAR,        // LookUp
 
 
207
    SDLK_CLEAR,        // LookDown
 
 
208
    SDLK_CLEAR,        // CentreView
 
 
209
    SDLK_CLEAR,        // Walk
 
 
210
    SDL_BUTTON_MIDDLE,    // Jump
 
 
211
    SDLK_SPACE,        // Operate
 
 
212
    SDLK_t,            // Taunt
 
 
213
    SDLK_y,            // ViewMode
 
 
214
    SDLK_F1,        // MessageHistory
 
 
215
    SDLK_s,             // Crouch
 
 
216
    SDL_BUTTON_LEFT,    // FirePrimaryWeapon
 
 
217
    SDL_BUTTON_RIGHT,    // FireSecondaryWeapon
 
 
218
    {SDLK_w},        // CycleVisionMode
 
 
219
    SDLK_RIGHTBRACKET,    // NextWeapon
 
 
220
    SDLK_LEFTBRACKET,     // PreviousWeapon
 
 
221
    SDLK_TAB,        // FlashbackWeapon
 
 
222
    {SDLK_r},        // RecallDisk
 
 
223
    {SDLK_g},        // GrapplingHook
 
 
224
    SDLK_v,            // Cloak
 
 
225
    SDL_BUTTON_WHEELUP,    // ZoomIn
 
 
226
    SDL_BUTTON_WHEELDOWN    // ZoomOut
 
 
227
};
 
 
228
 
 
 
229
PLAYER_INPUT_CONFIGURATION DefaultPredatorInputSecondaryConfig =
 
 
230
{
 
 
231
    SDLK_CLEAR,        // Forward
 
 
232
    SDLK_CLEAR,        // Backward
 
 
233
    SDLK_j,         // Left
 
 
234
    SDLK_k,         // Right
 
 
235
    SDLK_CLEAR,        // Strafe
 
 
236
    SDLK_CLEAR,         // StrafeLeft
 
 
237
    SDLK_CLEAR,         // StrafeRight
 
 
238
    SDLK_CLEAR,        // LookUp
 
 
239
    SDLK_CLEAR,        // LookDown
 
 
240
    SDLK_CLEAR,        // CentreView
 
 
241
    SDLK_CLEAR,        // Walk
 
 
242
    SDLK_CLEAR,        // Jump
 
 
243
    SDLK_CLEAR,        // Operate
 
 
244
    SDLK_CLEAR,        // Taunt
 
 
245
    SDLK_CLEAR,        // ViewMode
 
 
246
    SDLK_CLEAR,        // MessageHistory
 
 
247
    SDLK_CLEAR,         // Crouch
 
 
248
    SDLK_CLEAR,         // FirePrimaryWeapon
 
 
249
    SDLK_CLEAR,         // FireSecondaryWeapon
 
 
250
    {SDLK_CLEAR},         // CycleVisionMode
 
 
251
    SDLK_CLEAR,        // NextWeapon
 
 
252
    SDLK_CLEAR,         // PreviousWeapon
 
 
253
    SDLK_CLEAR,        // FlashbackWeapon
 
 
254
    {SDLK_CLEAR},        // RecallDisk
 
 
255
    {SDLK_CLEAR},         // GrapplingHook
 
 
256
    SDLK_CLEAR,         // Cloak
 
 
257
    SDLK_CLEAR,        // ZoomIn
 
 
258
    SDLK_CLEAR        // ZoomOut
 
 
259
};
 
 
260
 
 
 
261
CONTROL_METHODS ControlMethods =
 
 
262
{
 
 
263
    // analogue stuff 
 
 
264
    DEFAULT_MOUSEX_SENSITIVITY,
 
 
265
    DEFAULT_MOUSEY_SENSITIVITY,
 
 
266
 
 
 
267
    0,//unsigned int VAxisIsMovement :1; // else it's looking
 
 
268
    1,//unsigned int HAxisIsTurning :1; // else it's sidestepping
 
 
269
    0,//unsigned int FlipVerticalAxis :1;
 
 
270
    // general stuff 
 
 
271
    0,//unsigned int AutoCentreOnMovement :1;
 
 
272
};
 
 
273
 
 
 
274
/* in mm */
 
 
275
#define ACTIVATION_Z_RANGE 3000
 
 
276
#define ACTIVATION_X_RANGE 1000
 
 
277
#define ACTIVATION_Y_RANGE 1000
 
 
278
 
 
 
279
static void OperateObjectInLineOfSight()
 
 
280
{
 
 
281
    extern struct KObject VisibleObjects[maxobjects];
 
 
282
    extern int numVisObjs;
 
 
283
    int numberOfObjects = numVisObjs;
 
 
284
 
 
 
285
    DISPLAYBLOCK *nearestObjectPtr = NULL;
 
 
286
    int nearestMagnitude = ACTIVATION_X_RANGE * ACTIVATION_X_RANGE + ACTIVATION_Y_RANGE * ACTIVATION_Y_RANGE;
 
 
287
 
 
 
288
    while (numberOfObjects)
 
 
289
    {
 
 
290
        DISPLAYBLOCK* objectPtr = VisibleObjects[--numberOfObjects].DispPtr;
 
 
291
 
 
 
292
        if (objectPtr->ObStrategyBlock)
 
 
293
        {        
 
 
294
            /* is it operable? */
 
 
295
            switch(objectPtr->ObStrategyBlock->type)
 
 
296
            {
 
 
297
                case I_BehaviourBinarySwitch:
 
 
298
                case I_BehaviourLinkSwitch:
 
 
299
                case I_BehaviourAutoGun:
 
 
300
                {
 
 
301
                    /* is it in range? */
 
 
302
                    if (objectPtr->ObView.vz > 0 && objectPtr->ObView.vz < ACTIVATION_Z_RANGE)
 
 
303
                    {
 
 
304
                        int absX = abs(objectPtr->ObView.vx);
 
 
305
                        int absY = abs(objectPtr->ObView.vy);
 
 
306
 
 
 
307
                        if (absX < ACTIVATION_X_RANGE && absY < ACTIVATION_Y_RANGE)
 
 
308
                        {
 
 
309
                            int magnitude = (absX*absX + absY*absY);
 
 
310
 
 
 
311
                            if (nearestMagnitude > magnitude)
 
 
312
                            {
 
 
313
                                nearestMagnitude = magnitude;
 
 
314
                                nearestObjectPtr = objectPtr;
 
 
315
                            }
 
 
316
                        }
 
 
317
                    }
 
 
318
                }
 
 
319
                default:
 
 
320
                break;
 
 
321
            }
 
 
322
        }
 
 
323
    }
 
 
324
 
 
 
325
    /* if we found a suitable object, operate it */
 
 
326
    if (nearestObjectPtr)
 
 
327
    {
 
 
328
        //only allow activation if you have a line of sight to the switch
 
 
329
        //allow the switch to be activated anyway for the moment
 
 
330
        if(IsThisObjectVisibleFromThisPosition_WithIgnore(PlayerStatus.DisplayBlock, nearestObjectPtr, &nearestObjectPtr->ObWorld))
 
 
331
        {
 
 
332
            switch(nearestObjectPtr->ObStrategyBlock->type)
 
 
333
            {
 
 
334
                case I_BehaviourBinarySwitch:
 
 
335
                {
 
 
336
                    if(SinglePlayer != AvP.PlayMode)
 
 
337
                        AddNetMsg_LOSRequestBinarySwitch(nearestObjectPtr->ObStrategyBlock);
 
 
338
 
 
 
339
                    RequestState(nearestObjectPtr->ObStrategyBlock, 1, 0);
 
 
340
                }
 
 
341
                break;
 
 
342
                case I_BehaviourLinkSwitch:
 
 
343
                {
 
 
344
                    if(SinglePlayer != AvP.PlayMode)
 
 
345
                        AddNetMsg_LOSRequestBinarySwitch(nearestObjectPtr->ObStrategyBlock);
 
 
346
 
 
 
347
                    RequestState(nearestObjectPtr->ObStrategyBlock, 1, 0);
 
 
348
                }
 
 
349
                break;
 
 
350
                case I_BehaviourAutoGun:
 
 
351
                    RequestState(nearestObjectPtr->ObStrategyBlock, 1, 0);
 
 
352
                default:
 
 
353
                break;
 
 
354
            }
 
 
355
        }
 
 
356
    }
 
 
357
}
 
 
358
 
 
 
359
static void ChangePredVision()
 
 
360
{
 
 
361
    if ((PlayerStatus.FieldCharge > PredatorVisionThreshold) && visionModeDebounced)
 
 
362
    {
 
 
363
        visionModeDebounced = 0;
 
 
364
 
 
 
365
        switch (PlayerStatus.VisionMode)
 
 
366
        {
 
 
367
            case VISION_MODE_NORMAL:
 
 
368
                PlayerStatus.VisionMode = VISION_MODE_PRED_THERMAL;
 
 
369
            break;
 
 
370
            case VISION_MODE_PRED_THERMAL:
 
 
371
                PlayerStatus.VisionMode = VISION_MODE_PRED_SEEALIENS;
 
 
372
            break;
 
 
373
            case VISION_MODE_PRED_SEEALIENS:
 
 
374
                PlayerStatus.VisionMode = VISION_MODE_PRED_SEEPREDTECH;
 
 
375
            break;
 
 
376
            case VISION_MODE_PRED_SEEPREDTECH:
 
 
377
                PlayerStatus.VisionMode = VISION_MODE_NORMAL;
 
 
378
                Sound_Stop(predOVision_SoundHandle);
 
 
379
            default:
 
 
380
            break;
 
 
381
        }
 
 
382
 
 
 
383
        Sound_Play(SID_PRED_VISION_ON, "h");
 
 
384
        PredatorVisionChangeCounter = ONE_FIXED / 2;
 
 
385
        ChooseLightingModel();
 
 
386
    }
 
 
387
}
 
 
388
 
 
 
389
static void ChangeMarineVision()
 
 
390
{
 
 
391
    if (visionModeDebounced)
 
 
392
    {
 
 
393
        visionModeDebounced = 0;
 
 
394
 
 
 
395
        if (PlayerStatus.VisionMode == VISION_MODE_IMAGEINTENSIFIER)
 
 
396
        {
 
 
397
            PlayerStatus.VisionMode = VISION_MODE_NORMAL;
 
 
398
            Sound_Play(SID_IMAGE_OFF, "h");
 
 
399
        }
 
 
400
        else
 
 
401
        {
 
 
402
            PlayerStatus.VisionMode = VISION_MODE_IMAGEINTENSIFIER;
 
 
403
            Sound_Play(SID_IMAGE, "h");
 
 
404
        }
 
 
405
        ChooseLightingModel();
 
 
406
    }
 
 
407
}
 
 
408
 
 
 
409
static void ChangeAlienVision()
 
 
410
{
 
 
411
    if (visionModeDebounced)
 
 
412
    {
 
 
413
        visionModeDebounced = 0;
 
 
414
        PlayerStatus.VisionMode = (VISION_MODE_ALIEN_SENSE == PlayerStatus.VisionMode) ? VISION_MODE_NORMAL : VISION_MODE_ALIEN_SENSE;
 
 
415
        ChooseLightingModel();
 
 
416
    }
 
 
417
}
 
 
418
 
 
 
419
static void look_up(signed int pitch_increment)
 
 
420
{
 
 
421
    PlayerStatus.ViewPanX += 1024;
 
 
422
    PlayerStatus.ViewPanX &= wrap360;
 
 
423
 
 
 
424
    PlayerStatus.ViewPanX += MUL_FIXED(pitch_increment, NormalFrameTime >> PANRATESHIFT);
 
 
425
 
 
 
426
    if (PlayerStatus.ViewPanX < AllowedLookUpAngle)
 
 
427
        PlayerStatus.ViewPanX = AllowedLookUpAngle; 
 
 
428
 
 
 
429
    PlayerStatus.ViewPanX -= 1024;
 
 
430
    PlayerStatus.ViewPanX &= wrap360;
 
 
431
}
 
 
432
 
 
 
433
static void look_down(signed int pitch_increment)
 
 
434
{
 
 
435
    PlayerStatus.ViewPanX += 1024;
 
 
436
    PlayerStatus.ViewPanX &= wrap360;
 
 
437
 
 
 
438
    PlayerStatus.ViewPanX += MUL_FIXED(pitch_increment, NormalFrameTime >> PANRATESHIFT);
 
 
439
 
 
 
440
    if (PlayerStatus.ViewPanX > AllowedLookDownAngle)
 
 
441
        PlayerStatus.ViewPanX = AllowedLookDownAngle;
 
 
442
 
 
 
443
    PlayerStatus.ViewPanX -= 1024;
 
 
444
    PlayerStatus.ViewPanX &= wrap360;
 
 
445
}
 
 
446
 
 
 
447
static void centre_view()
 
 
448
{
 
 
449
    PlayerStatus.ViewPanX += 1024;
 
 
450
    PlayerStatus.ViewPanX &= wrap360;
 
 
451
 
 
 
452
    if (PlayerStatus.ViewPanX > 1024)
 
 
453
    {                  
 
 
454
        PlayerStatus.ViewPanX -= (NormalFrameTime >> PANRATESHIFT) * 2;
 
 
455
 
 
 
456
        if (PlayerStatus.ViewPanX < 1024) 
 
 
457
            PlayerStatus.ViewPanX = 1024; 
 
 
458
    }
 
 
459
    else if (PlayerStatus.ViewPanX < 1024)
 
 
460
    {                  
 
 
461
        PlayerStatus.ViewPanX += (NormalFrameTime >> PANRATESHIFT) * 2;
 
 
462
 
 
 
463
        if (PlayerStatus.ViewPanX > 1024) 
 
 
464
            PlayerStatus.ViewPanX = 1024; 
 
 
465
    }
 
 
466
 
 
 
467
    PlayerStatus.ViewPanX -= 1024;
 
 
468
    PlayerStatus.ViewPanX &= wrap360;
 
 
469
}
 
 
470
 
 
 
471
void handle_user_input()
 
 
472
{
 
 
473
    int auto_centre = 0;
 
 
474
    int forwardSpeed;
 
 
475
    int strafeSpeed;
 
 
476
    int acceleration;
 
 
477
 
 
 
478
    DYNAMICSBLOCK *dynPtr = PlayerStatus.sbptr->DynPtr;
 
 
479
 
 
 
480
    signed int Mvt_MotionIncrement = 0;    /* 65536 (Forward) to -65536 (Backward) */
 
 
481
    signed int Mvt_TurnIncrement = 0;    /* 65536 (Right) to -65536 (Left)*/
 
 
482
    signed int Mvt_SideStepIncrement = 0;    /* 65536 to -65536 */
 
 
483
    PlayerStatus.TurnInertia = TURNSCALE;
 
 
484
 
 
 
485
    switch (AvP.PlayerType)
 
 
486
    {
 
 
487
        case I_Marine:
 
 
488
        {
 
 
489
            forwardSpeed = MARINE_MOVESCALE;
 
 
490
            strafeSpeed = MARINE_STRAFESCALE;
 
 
491
            acceleration = 2;
 
 
492
 
 
 
493
            switch(PlayerStatus.SelectedWeapon->WeaponIDNumber)
 
 
494
            {
 
 
495
                case WEAPON_SMARTGUN:
 
 
496
                case WEAPON_SADAR:
 
 
497
                case WEAPON_MINIGUN:
 
 
498
                case WEAPON_FRISBEE_LAUNCHER:
 
 
499
                forwardSpeed /= 2;
 
 
500
                strafeSpeed /= 2;
 
 
501
                default:
 
 
502
                break;
 
 
503
            }
 
 
504
 
 
 
505
            if(PlayerStatus.imageintensifier_battery)
 
 
506
            {
 
 
507
                if(Keyboard[primaryInput->visions.ImageIntensifier] || Keyboard[secondaryInput->visions.ImageIntensifier])
 
 
508
                    ChangeMarineVision();
 
 
509
                else
 
 
510
                    visionModeDebounced = 1;
 
 
511
             }
 
 
512
 
 
 
513
            if(PlayerStatus.FlaresLeft)
 
 
514
            {
 
 
515
                if(Keyboard[primaryInput->misc.ThrowFlare] || Keyboard[secondaryInput->misc.ThrowFlare])
 
 
516
                    ThrowAFlare();
 
 
517
                else
 
 
518
                    FlareDebounced = 1;
 
 
519
            }
 
 
520
 
 
 
521
            if(Keyboard[primaryInput->extra.Reload] || Keyboard[secondaryInput->extra.Reload])
 
 
522
            {
 
 
523
                if((WEAPONSTATE_IDLE == PlayerStatus.WeaponState) && PlayerStatus.SelectedWeapon->MagazinesRemaining)
 
 
524
                {
 
 
525
                    const TEMPLATE_AMMO_DATA *templateAmmoPtr = &TemplateAmmo[PlayerStatus.twPtr->PrimaryAmmoID];
 
 
526
 
 
 
527
                    if (PlayerStatus.SelectedWeapon->PrimaryRoundsRemaining != templateAmmoPtr->AmmoPerMagazine)
 
 
528
                    {
 
 
529
                        PlayerStatus.SelectedWeapon->LeftOverBullets += PlayerStatus.SelectedWeapon->PrimaryRoundsRemaining;
 
 
530
 
 
 
531
                        if(PlayerStatus.SelectedWeapon->LeftOverBullets >= templateAmmoPtr->AmmoPerMagazine)
 
 
532
                        {
 
 
533
                            PlayerStatus.SelectedWeapon->LeftOverBullets -= templateAmmoPtr->AmmoPerMagazine;
 
 
534
                            PlayerStatus.SelectedWeapon->MagazinesRemaining++;
 
 
535
                        }
 
 
536
 
 
 
537
                        PlayerStatus.SelectedWeapon->PrimaryRoundsRemaining = 0;
 
 
538
                    }
 
 
539
                }
 
 
540
            }
 
 
541
 
 
 
542
            AddPheromones(PlayerStatus.sbptr->containingModule->m_aimodule);
 
 
543
        }
 
 
544
        break;
 
 
545
        case I_Predator:
 
 
546
        {
 
 
547
            forwardSpeed = PREDATOR_MOVESCALE;
 
 
548
            strafeSpeed = PREDATOR_STRAFESCALE;
 
 
549
            acceleration = 3;
 
 
550
 
 
 
551
            if(Keyboard[primaryInput->Cloak] || Keyboard[secondaryInput->Cloak])
 
 
552
                toggle_cloak();
 
 
553
            else
 
 
554
                cloakDebounce = 1;
 
 
555
 
 
 
556
            if(Keyboard[primaryInput->visions.CycleVisionMode] || Keyboard[secondaryInput->visions.CycleVisionMode])
 
 
557
                ChangePredVision();
 
 
558
            else
 
 
559
                visionModeDebounced = 1;
 
 
560
 
 
 
561
            if (PlayerStatus.GrapplingHookEnabled)
 
 
562
            {
 
 
563
                static int GrapplinghookDebounced = 1;
 
 
564
 
 
 
565
                if(Keyboard[primaryInput->extra.GrapplingHook] || Keyboard[secondaryInput->extra.GrapplingHook])
 
 
566
                {
 
 
567
                    if (GrapplinghookDebounced)
 
 
568
                    {
 
 
569
                        GrapplinghookDebounced = 0;
 
 
570
                        ActivateGrapplingHook();
 
 
571
                    }
 
 
572
                }
 
 
573
                else
 
 
574
                {
 
 
575
                    GrapplinghookDebounced = 1;
 
 
576
                }
 
 
577
 
 
 
578
                RenderGrapplingHook();
 
 
579
                HandleGrapplingHookForces();
 
 
580
            }    
 
 
581
 
 
 
582
            if(Keyboard[primaryInput->ZoomIn] || Keyboard[secondaryInput->ZoomIn])
 
 
583
            {
 
 
584
                if (CameraZoomLevel < 3)
 
 
585
                    CameraZoomLevel++;
 
 
586
            }
 
 
587
 
 
 
588
            if(Keyboard[primaryInput->ZoomOut] || Keyboard[secondaryInput->ZoomOut])
 
 
589
            {
 
 
590
                if (CameraZoomLevel > 0)
 
 
591
                    CameraZoomLevel--;
 
 
592
            }
 
 
593
 
 
 
594
            if(CameraZoomLevel)
 
 
595
                PlayerStatus.TurnInertia >>= CameraZoomLevel;
 
 
596
 
 
 
597
            if(Keyboard[primaryInput->misc.RecallDisc] || Keyboard[secondaryInput->misc.RecallDisc])
 
 
598
                Recall_Disc();
 
 
599
 
 
 
600
            PlayerStatus.CurrentLightAtPlayer = LightIntensityAtPoint(&PlayerStatus.sbptr->DynPtr->Position);
 
 
601
            AddPheromones(PlayerStatus.sbptr->containingModule->m_aimodule);
 
 
602
        }
 
 
603
        break;
 
 
604
        case I_Alien:
 
 
605
        {
 
 
606
            forwardSpeed = (dynPtr->OrientMat.mat22 < 63000) ? ALIEN_CLIMBINGMOVESCALE : PlayerStatus.Crouching ? ALIEN_MAXMOVESCALE :
ALIEN_STANDINGRUNNINGMOVESCALE;
 
 
607
            strafeSpeed = ALIEN_STRAFESCALE;
 
 
608
            acceleration = 3;
 
 
609
 
 
 
610
            if(Keyboard[primaryInput->visions.AlternateVision] || Keyboard[secondaryInput->visions.AlternateVision])
 
 
611
                ChangeAlienVision();
 
 
612
            else
 
 
613
                visionModeDebounced = 1;
 
 
614
 
 
 
615
            if (PlayerStatus.RequestsToStandUp) // FIX ME
 
 
616
                dynPtr->UseStandardGravity = 1;
 
 
617
 
 
 
618
            /* Decay alien superhealth. */
 
 
619
            if (PlayerStatus.sbptr->DamageBlock.Health > (PlayerStatus.StartingHealth << ONE_FIXED_SHIFT)) 
 
 
620
            {
 
 
621
                /* Decay health a bit. */
 
 
622
                PlayerStatus.sbptr->DamageBlock.Health -= NormalFrameTime;
 
 
623
 
 
 
624
                if (PlayerStatus.sbptr->DamageBlock.Health < (PlayerStatus.StartingHealth << ONE_FIXED_SHIFT)) 
 
 
625
                    PlayerStatus.sbptr->DamageBlock.Health = PlayerStatus.StartingHealth << ONE_FIXED_SHIFT;
 
 
626
 
 
 
627
                PlayerStatus.Health = PlayerStatus.sbptr->DamageBlock.Health;
 
 
628
            }
 
 
629
 
 
 
630
            PlayerStatus.CurrentLightAtPlayer = LightIntensityAtPoint(&PlayerStatus.sbptr->DynPtr->Position);
 
 
631
            HModel_Regen(PlayerStatus.DisplayBlock->HModelControlBlock, 4 * ONE_FIXED );
 
 
632
        }
 
 
633
    }
 
 
634
 
 
 
635
    PlayerStatus.InputRequests.Rqst_SideStepLeft = 0;
 
 
636
    PlayerStatus.InputRequests.Rqst_SideStepRight = 0;
 
 
637
    PlayerStatus.InputRequests.Rqst_Strafe = 0;
 
 
638
 
 
 
639
    PlayerStatus.InputRequests.Rqst_Jump = (Keyboard[primaryInput->Jump] || Keyboard[secondaryInput->Jump]);
 
 
640
    PlayerStatus.InputRequests.Rqst_Walk = (Keyboard[primaryInput->Walk] || Keyboard[secondaryInput->Walk]);
 
 
641
    PlayerStatus.InputRequests.Rqst_FirePrimaryWeapon = (Keyboard[primaryInput->FirePrimaryWeapon] || Keyboard[secondaryInput->FirePrimaryWeapon]);
 
 
642
    PlayerStatus.InputRequests.Rqst_FireSecondaryWeapon = (Keyboard[primaryInput->FireSecondaryWeapon] || Keyboard[secondaryInput->FireSecondaryWeapon]);
 
 
643
    PlayerStatus.InputRequests.Rqst_Forward = (Keyboard[primaryInput->Forward] || Keyboard[secondaryInput->Forward]);
 
 
644
    PlayerStatus.InputRequests.Rqst_Backward = (Keyboard[primaryInput->Backward] || Keyboard[secondaryInput->Backward]);
 
 
645
 
 
 
646
    if(PlayerStatus.InputRequests.Rqst_Forward)
 
 
647
        Mvt_MotionIncrement = ONE_FIXED;
 
 
648
 
 
 
649
    if(PlayerStatus.InputRequests.Rqst_Backward)
 
 
650
        Mvt_MotionIncrement = -ONE_FIXED;
 
 
651
 
 
 
652
    if(!PaintBallMode.IsOn)
 
 
653
    {
 
 
654
        if(Keyboard[primaryInput->LookUp] || Keyboard[secondaryInput->LookUp])
 
 
655
        {
 
 
656
            auto_centre = 1;
 
 
657
            look_up(-ONE_FIXED >> CameraZoomLevel);
 
 
658
        }
 
 
659
 
 
 
660
        if(Keyboard[primaryInput->LookDown] || Keyboard[secondaryInput->LookDown])
 
 
661
        {
 
 
662
            auto_centre = 1;
 
 
663
            look_down(ONE_FIXED >> CameraZoomLevel);
 
 
664
        }
 
 
665
 
 
 
666
        if(Keyboard[primaryInput->CentreView] || Keyboard[secondaryInput->CentreView])
 
 
667
            centre_view();
 
 
668
 
 
 
669
        if(Keyboard[primaryInput->NextWeapon] || Keyboard[secondaryInput->NextWeapon])
 
 
670
            RequestChangeOfWeapon(1);
 
 
671
 
 
 
672
        if(Keyboard[primaryInput->PreviousWeapon] || Keyboard[secondaryInput->PreviousWeapon])
 
 
673
            RequestChangeOfWeapon(0);
 
 
674
 
 
 
675
        if(Keyboard[primaryInput->FlashbackWeapon] || Keyboard[secondaryInput->FlashbackWeapon])
 
 
676
        {
 
 
677
            if (PlayerStatus.PreviouslySelectedWeaponSlot != PlayerStatus.SelectedWeaponSlot)
 
 
678
                RequestChangeOfWeaponNo(PlayerStatus.PreviouslySelectedWeaponSlot);
 
 
679
        }
 
 
680
    }
 
 
681
    else // Cool - paintball mode
 
 
682
    {
 
 
683
        PaintBallMode.TargetDispPtr = LOS_ObjectHitPtr;
 
 
684
        PaintBallMode.TargetPosition = LOS_Point;
 
 
685
        PaintBallMode.TargetNormal = LOS_ObjectNormal;
 
 
686
 
 
 
687
        if(PlayerStatus.InputRequests.Rqst_FirePrimaryWeapon)
 
 
688
            //PaintBallMode_AddDecal();
 
 
689
            PaintBallMode_DrawCurrentDecalAtTarget();
 
 
690
 
 
 
691
        if(PlayerStatus.InputRequests.Rqst_FireSecondaryWeapon)
 
 
692
            PaintBallMode_RemoveDecal();
 
 
693
 
 
 
694
        if(Keyboard[primaryInput->NextWeapon] || Keyboard[secondaryInput->NextWeapon])
 
 
695
            PaintBallMode_ChangeSelectedDecalID(+1);
 
 
696
 
 
 
697
        if(Keyboard[primaryInput->PreviousWeapon] || Keyboard[secondaryInput->PreviousWeapon])
 
 
698
            PaintBallMode_ChangeSelectedDecalID(-1);
 
 
699
 
 
 
700
        if(Keyboard[primaryInput->LookUp] || Keyboard[secondaryInput->LookUp])
 
 
701
            PaintBallMode_ChangeSize(+1);
 
 
702
 
 
 
703
        if(Keyboard[primaryInput->LookDown] || Keyboard[secondaryInput->LookDown])
 
 
704
            PaintBallMode_ChangeSize(-1);
 
 
705
 
 
 
706
        if(Keyboard[primaryInput->CentreView] || Keyboard[secondaryInput->CentreView])
 
 
707
            PaintBallMode_Rotate();                
 
 
708
    }
 
 
709
 
 
 
710
    if(!PlayerStatus.FirstPersonView)
 
 
711
    {
 
 
712
        // strafe disable for third person view no animation sequense for it, looks weird
 
 
713
        if(!move_player())
 
 
714
        PlayerStatus.InputRequests.Rqst_Backward = PlayerStatus.InputRequests.Rqst_Forward = Mvt_MotionIncrement = 0;
 
 
715
    }
 
 
716
    else
 
 
717
    {
 
 
718
        move_player(); // needed for foot step sounds
 
 
719
 
 
 
720
        if(Keyboard[primaryInput->StrafeLeft] || Keyboard[secondaryInput->StrafeLeft])
 
 
721
        {
 
 
722
            PlayerStatus.InputRequests.Rqst_SideStepLeft = 1;
 
 
723
            strafeSpeed = MUL_FIXED(strafeSpeed, -ONE_FIXED);
 
 
724
        Mvt_SideStepIncrement = -ONE_FIXED;
 
 
725
        }
 
 
726
 
 
 
727
        if(Keyboard[primaryInput->StrafeRight] || Keyboard[secondaryInput->StrafeRight])
 
 
728
        {
 
 
729
            PlayerStatus.InputRequests.Rqst_SideStepRight = 1;
 
 
730
            strafeSpeed = MUL_FIXED(strafeSpeed, ONE_FIXED);
 
 
731
        Mvt_SideStepIncrement = ONE_FIXED;
 
 
732
        }
 
 
733
    }
 
 
734
 
 
 
735
    int x,y;
 
 
736
    SDL_GetRelativeMouseState(&x, &y);
 
 
737
 
 
 
738
    int MouseVelX = DIV_FIXED(x, NormalFrameTime);
 
 
739
    int MouseVelY = DIV_FIXED(y, NormalFrameTime);
 
 
740
 
 
 
741
    if(!ControlMethods.VAxisIsMovement)
 
 
742
    {
 
 
743
        int newMouseVelY = MouseVelY;
 
 
744
 
 
 
745
        if (ControlMethods.FlipVerticalAxis)
 
 
746
            newMouseVelY = -MouseVelY;
 
 
747
 
 
 
748
        if(newMouseVelY < 0)
 
 
749
        {
 
 
750
            auto_centre = 1;
 
 
751
            look_up((newMouseVelY * ControlMethods.MouseYSensitivity) >> CameraZoomLevel);
 
 
752
        }
 
 
753
        else if(newMouseVelY > 0)
 
 
754
        {
 
 
755
            auto_centre = 1;
 
 
756
            look_down((newMouseVelY * ControlMethods.MouseYSensitivity) >> CameraZoomLevel);
 
 
757
        }
 
 
758
    }
 
 
759
    else
 
 
760
    {
 
 
761
        if(MouseVelY < 0)
 
 
762
        {
 
 
763
            PlayerStatus.InputRequests.Rqst_Forward = 1;
 
 
764
            Mvt_MotionIncrement = -MouseVelY * ControlMethods.MouseYSensitivity;
 
 
765
        }
 
 
766
        else if(MouseVelY > 0)
 
 
767
        {
 
 
768
            PlayerStatus.InputRequests.Rqst_Backward = 1;
 
 
769
            Mvt_MotionIncrement = -MouseVelY * ControlMethods.MouseYSensitivity;
 
 
770
        }
 
 
771
 
 
 
772
        if(Mvt_MotionIncrement < -ONE_FIXED)
 
 
773
            Mvt_MotionIncrement = -ONE_FIXED;
 
 
774
        else if(Mvt_MotionIncrement > ONE_FIXED)
 
 
775
            Mvt_MotionIncrement = ONE_FIXED;
 
 
776
    }
 
 
777
 
 
 
778
    static int CrouchKeyDebounced = 0;
 
 
779
 
 
 
780
    if(Keyboard[primaryInput->Crouch] || Keyboard[secondaryInput->Crouch])
 
 
781
    {
 
 
782
        if (PlayerStatus.Crouching)
 
 
783
        {
 
 
784
            if (CrouchIsToggleKey && CrouchKeyDebounced)
 
 
785
            {
 
 
786
                CrouchKeyDebounced = 0;
 
 
787
                PlayerStatus.RequestsToStandUp = 1;
 
 
788
            }
 
 
789
 
 
 
790
            // let alien player move half speed if walking
 
 
791
            if((I_Alien != AvP.PlayerType) || PlayerStatus.InputRequests.Rqst_Walk)
 
 
792
            {
 
 
793
                forwardSpeed /= 2;
 
 
794
                strafeSpeed /= 2; 
 
 
795
                PlayerStatus.TurnInertia /= 2;
 
 
796
            }
 
 
797
        }
 
 
798
        else if (CrouchKeyDebounced)
 
 
799
        {
 
 
800
            CrouchKeyDebounced = 0;
 
 
801
            PlayerStatus.Crouching = 1;
 
 
802
 
 
 
803
            if (I_Alien == AvP.PlayerType)
 
 
804
                dynPtr->UseStandardGravity = 0;
 
 
805
            else
 
 
806
                forwardSpeed /= 2;
 
 
807
        }
 
 
808
    }
 
 
809
    else
 
 
810
    {
 
 
811
        CrouchKeyDebounced = 1;
 
 
812
 
 
 
813
        if(PlayerStatus.InputRequests.Rqst_Walk || PlayerStatus.InputRequests.Rqst_Backward)
 
 
814
        {
 
 
815
            forwardSpeed /= 2;
 
 
816
            strafeSpeed /= 2; 
 
 
817
            PlayerStatus.TurnInertia /= 2;
 
 
818
        }
 
 
819
 
 
 
820
        if (PlayerStatus.Crouching && !CrouchIsToggleKey)
 
 
821
            PlayerStatus.RequestsToStandUp = 1;
 
 
822
    }
 
 
823
 
 
 
824
    if(ControlMethods.HAxisIsTurning)
 
 
825
    {
 
 
826
        Mvt_TurnIncrement = MouseVelX * ControlMethods.MouseXSensitivity;
 
 
827
    }
 
 
828
    else // it's sidestep
 
 
829
    {
 
 
830
        if(MouseVelX < 0)
 
 
831
        {
 
 
832
            PlayerStatus.InputRequests.Rqst_SideStepLeft = 1;
 
 
833
            Mvt_SideStepIncrement = MouseVelX * ControlMethods.MouseXSensitivity;
 
 
834
 
 
 
835
            if(Mvt_SideStepIncrement < -ONE_FIXED)
 
 
836
                Mvt_SideStepIncrement = -ONE_FIXED;
 
 
837
 
 
 
838
            strafeSpeed = MUL_FIXED(strafeSpeed, Mvt_SideStepIncrement);
 
 
839
        }
 
 
840
        else if(MouseVelX > 0)
 
 
841
        {
 
 
842
            PlayerStatus.InputRequests.Rqst_SideStepRight = 1;
 
 
843
            Mvt_SideStepIncrement = MouseVelX * ControlMethods.MouseXSensitivity;
 
 
844
 
 
 
845
            if(Mvt_SideStepIncrement > ONE_FIXED)
 
 
846
                Mvt_SideStepIncrement = ONE_FIXED;
 
 
847
 
 
 
848
            strafeSpeed = MUL_FIXED(strafeSpeed, Mvt_SideStepIncrement);
 
 
849
        }
 
 
850
    }
 
 
851
 
 
 
852
    if(!Mvt_TurnIncrement)
 
 
853
    {
 
 
854
        if(Keyboard[primaryInput->Left] || Keyboard[secondaryInput->Left])
 
 
855
            Mvt_TurnIncrement = -ONE_FIXED;
 
 
856
 
 
 
857
        if(Keyboard[primaryInput->Right] || Keyboard[secondaryInput->Right])
 
 
858
            Mvt_TurnIncrement = ONE_FIXED;
 
 
859
    }
 
 
860
 
 
 
861
    /* KJL 17:45:03 9/9/97 - inertia means it's difficult to stop */
 
 
862
    if (Mvt_MotionIncrement * PlayerStatus.ForwardInertia < 0)
 
 
863
        PlayerStatus.ForwardInertia = 0;
 
 
864
 
 
 
865
    switch(Mvt_MotionIncrement)
 
 
866
    {
 
 
867
        case ONE_FIXED:
 
 
868
        {
 
 
869
            forwardSpeed = MUL_FIXED(forwardSpeed, Mvt_MotionIncrement);
 
 
870
            int deltaForward = MUL_FIXED(forwardSpeed * acceleration, NormalFrameTime);
 
 
871
            int a = PlayerStatus.ForwardInertia + deltaForward;
 
 
872
 
 
 
873
            if (a < forwardSpeed)
 
 
874
                forwardSpeed = a;
 
 
875
        }
 
 
876
        break;
 
 
877
        case -ONE_FIXED:
 
 
878
        {
 
 
879
            forwardSpeed = MUL_FIXED(forwardSpeed, Mvt_MotionIncrement) / 2;
 
 
880
            int deltaForward = MUL_FIXED(forwardSpeed * acceleration, NormalFrameTime);
 
 
881
            int a = PlayerStatus.ForwardInertia + deltaForward;
 
 
882
 
 
 
883
                if (a > forwardSpeed)
 
 
884
                    forwardSpeed = a;
 
 
885
        }
 
 
886
        break;
 
 
887
        default:
 
 
888
        {
 
 
889
            int deltaForward = (FASTMOVESCALE * NormalFrameTime) >> 14;
 
 
890
            forwardSpeed = 0;
 
 
891
 
 
 
892
            if (PlayerStatus.ForwardInertia > 0)
 
 
893
            {
 
 
894
                forwardSpeed = PlayerStatus.ForwardInertia - deltaForward;
 
 
895
 
 
 
896
                if (forwardSpeed < 0)
 
 
897
                    forwardSpeed = 0;
 
 
898
            }
 
 
899
            else if (PlayerStatus.ForwardInertia < 0)
 
 
900
            {
 
 
901
                forwardSpeed = PlayerStatus.ForwardInertia + deltaForward;
 
 
902
 
 
 
903
                if (forwardSpeed > 0)
 
 
904
                    forwardSpeed = 0;
 
 
905
            }
 
 
906
        }
 
 
907
    }
 
 
908
 
 
 
909
    PlayerStatus.ForwardInertia = forwardSpeed;
 
 
910
    dynPtr->AngVelocity.EulerX = dynPtr->AngVelocity.EulerZ = dynPtr->AngVelocity.EulerY = 0;
 
 
911
 
 
 
912
    if(Keyboard[primaryInput->Strafe] || Keyboard[secondaryInput->Strafe])
 
 
913
    {
 
 
914
        if(Mvt_TurnIncrement)
 
 
915
        {
 
 
916
            PlayerStatus.InputRequests.Rqst_Strafe = 1;
 
 
917
 
 
 
918
            if(Mvt_TurnIncrement < -ONE_FIXED && ControlMethods.HAxisIsTurning)
 
 
919
                Mvt_TurnIncrement = -ONE_FIXED;
 
 
920
            else if(Mvt_TurnIncrement > ONE_FIXED && ControlMethods.HAxisIsTurning)
 
 
921
                Mvt_TurnIncrement = ONE_FIXED;
 
 
922
 
 
 
923
            if(!Mvt_SideStepIncrement)
 
 
924
                strafeSpeed = MUL_FIXED(strafeSpeed, Mvt_TurnIncrement);
 
 
925
        }
 
 
926
    }
 
 
927
    else
 
 
928
    {
 
 
929
        MATRIXCH mat;
 
 
930
        mat.mat12 = mat.mat21 = mat.mat23 = mat.mat32 = 0;
 
 
931
        PlayerStatus.TurnInertia = MUL_FIXED(PlayerStatus.TurnInertia, Mvt_TurnIncrement);
 
 
932
        dynPtr->AngVelocity.EulerY = PlayerStatus.TurnInertia;
 
 
933
 
 
 
934
        int angle = MUL_FIXED(NormalFrameTime, PlayerStatus.TurnInertia) & 4095;
 
 
935
        int cos = GetCos(angle);
 
 
936
        int sin = GetSin(angle);
 
 
937
        mat.mat11 = cos;
 
 
938
        mat.mat13 = -sin;
 
 
939
        mat.mat22 = 65536;
 
 
940
        mat.mat31 = sin;
 
 
941
        mat.mat33 = cos;
 
 
942
 
 
 
943
        MatrixMultiply(&dynPtr->OrientMat, &mat, &dynPtr->OrientMat);
 
 
944
        MatrixToEuler(&dynPtr->OrientMat, &dynPtr->OrientEuler);
 
 
945
    }
 
 
946
 
 
 
947
    if (strafeSpeed * PlayerStatus.StrafeInertia < 0)
 
 
948
        PlayerStatus.StrafeInertia = 0;
 
 
949
 
 
 
950
    if (!strafeSpeed)
 
 
951
    {
 
 
952
        int deltaStrafe = (FASTSTRAFESCALE * NormalFrameTime) >> 14;
 
 
953
 
 
 
954
        if (PlayerStatus.StrafeInertia > 0)
 
 
955
        {
 
 
956
            strafeSpeed = PlayerStatus.StrafeInertia - deltaStrafe;
 
 
957
 
 
 
958
            if (strafeSpeed < 0)
 
 
959
                strafeSpeed = 0;
 
 
960
        }
 
 
961
        else if (PlayerStatus.StrafeInertia < 0)
 
 
962
        {
 
 
963
            strafeSpeed = PlayerStatus.StrafeInertia + deltaStrafe;
 
 
964
 
 
 
965
            if (strafeSpeed > 0)
 
 
966
                strafeSpeed = 0;
 
 
967
        }
 
 
968
    }
 
 
969
    else
 
 
970
    {
 
 
971
        int deltaForward = MUL_FIXED(strafeSpeed*4, NormalFrameTime);
 
 
972
        int a = PlayerStatus.StrafeInertia + deltaForward;
 
 
973
 
 
 
974
        if (strafeSpeed > 0)
 
 
975
        {
 
 
976
            if (a < strafeSpeed)
 
 
977
                strafeSpeed = a;
 
 
978
        }
 
 
979
        else
 
 
980
        {
 
 
981
            if (a > strafeSpeed)
 
 
982
                strafeSpeed = a;
 
 
983
        }
 
 
984
    }
 
 
985
 
 
 
986
    PlayerStatus.StrafeInertia = strafeSpeed;
 
 
987
 
 
 
988
    dynPtr->GravityOn = 1;
 
 
989
 
 
 
990
#ifdef AFRAID_OF_GROUND
 
 
991
    if(!FlyModeOn)
 
 
992
#endif
 
 
993
    {
 
 
994
        static int PlayersFallingSpeed = 0;
 
 
995
 
 
 
996
        if(dynPtr->IsInContactWithFloor)
 
 
997
        {
 
 
998
            dynPtr->LinVelocity.vx = dynPtr->LinVelocity.vy = 0;
 
 
999
            dynPtr->LinVelocity.vz = forwardSpeed;
 
 
1000
 
 
 
1001
            if(PlayerStatus.InputRequests.Rqst_Strafe || PlayerStatus.InputRequests.Rqst_SideStepLeft || PlayerStatus.InputRequests.Rqst_SideStepRight)
 
 
1002
                dynPtr->LinVelocity.vx = strafeSpeed;
 
 
1003
 
 
 
1004
            /* rotate LinVelocity into world space */
 
 
1005
            RotateVector(&dynPtr->LinVelocity, &dynPtr->OrientMat);
 
 
1006
 
 
 
1007
            if (PlayerStatus.InputRequests.Rqst_Jump)// && (PlayerStatus.InputRequests.Rqst_Forward || (PlayerStatus.Crouching &&
!PlayerStatus.InputRequests.Rqst_Backward)))
 
 
1008
            {
 
 
1009
                COLLISIONREPORT *reportPtr = dynPtr->CollisionReportPtr;
 
 
1010
 
 
 
1011
                while (reportPtr) /* while there is a valid report */
 
 
1012
                {
 
 
1013
                    if (DotProduct(&reportPtr->ObstacleNormal, &dynPtr->GravityDirection) < -60000) // notTooSteep;
 
 
1014
                    {
 
 
1015
 
 
 
1016
                        // alien can jump in the direction it's looking
 
 
1017
                        switch(AvP.PlayerType)
 
 
1018
                        {
 
 
1019
                            case I_Alien:
 
 
1020
                            {
 
 
1021
                                VECTORCH viewDir;
 
 
1022
                                int jumpSpeed = MUL_FIXED(ALIEN_JUMPVELOCITY, ONE_FIXED);
 
 
1023
 
 
 
1024
                                viewDir.vx = Global_VDB.VDB_Mat.mat13;
 
 
1025
                                viewDir.vy = Global_VDB.VDB_Mat.mat23;
 
 
1026
                                viewDir.vz = Global_VDB.VDB_Mat.mat33;
 
 
1027
 
 
 
1028
                                if (PlayerStatus.Crouching && !DynamicObjectIsMoving(dynPtr) && DotProduct(&viewDir,
&dynPtr->GravityDirection) < -32768)
 
 
1029
                                {
 
 
1030
                                    dynPtr->LinImpulse.vx += MUL_FIXED(viewDir.vx, jumpSpeed * 2);
 
 
1031
                                    dynPtr->LinImpulse.vy += MUL_FIXED(viewDir.vy, jumpSpeed * 2);
 
 
1032
                                    dynPtr->LinImpulse.vz += MUL_FIXED(viewDir.vz, jumpSpeed * 2);
 
 
1033
                                }
 
 
1034
                                else
 
 
1035
                                {
 
 
1036
                                    dynPtr->LinImpulse.vx -= MUL_FIXED(dynPtr->GravityDirection.vx, jumpSpeed);
 
 
1037
                                    dynPtr->LinImpulse.vy -= MUL_FIXED(dynPtr->GravityDirection.vy, jumpSpeed);
 
 
1038
                                    dynPtr->LinImpulse.vz -= MUL_FIXED(dynPtr->GravityDirection.vz, jumpSpeed);
 
 
1039
                                    //dynPtr->LinVelocity.vz += jumpSpeed;    
 
 
1040
                                }
 
 
1041
 
 
 
1042
                                dynPtr->TimeNotInContactWithFloor = -1;
 
 
1043
                            }
 
 
1044
                            break;
 
 
1045
                            case I_Marine:
 
 
1046
                            {
 
 
1047
                                int jumpSpeed = MUL_FIXED(MARINE_JUMPVELOCITY, ONE_FIXED);
 
 
1048
                                dynPtr->LinImpulse.vx -= MUL_FIXED(dynPtr->GravityDirection.vx, jumpSpeed);
 
 
1049
                                dynPtr->LinImpulse.vy -= MUL_FIXED(dynPtr->GravityDirection.vy, jumpSpeed);
 
 
1050
                                dynPtr->LinImpulse.vz -= MUL_FIXED(dynPtr->GravityDirection.vz, jumpSpeed);
 
 
1051
                                dynPtr->TimeNotInContactWithFloor = 0;
 
 
1052
 
 
 
1053
                                if (PlayerStatus.sound_mouth == SOUND_NOACTIVEINDEX) 
 
 
1054
                                {
 
 
1055
                                    SpeciesSound(0, MSC_Jump, 0, &PlayerStatus.sound_mouth, NULL, HUMAN_SOUND);
 
 
1056
 
 
 
1057
                                    if(SinglePlayer != AvP.PlayMode)
 
 
1058
                                        netGameData.myLastScream = MSC_Jump;
 
 
1059
                                }
 
 
1060
                            }
 
 
1061
                            break;
 
 
1062
                            case I_Predator:
 
 
1063
                            {
 
 
1064
                                int jumpSpeed = MUL_FIXED(PREDATOR_JUMPVELOCITY, ONE_FIXED);
 
 
1065
                                dynPtr->LinImpulse.vx -= MUL_FIXED(dynPtr->GravityDirection.vx, jumpSpeed);
 
 
1066
                                dynPtr->LinImpulse.vy -= MUL_FIXED(dynPtr->GravityDirection.vy, jumpSpeed);
 
 
1067
                                dynPtr->LinImpulse.vz -= MUL_FIXED(dynPtr->GravityDirection.vz, jumpSpeed);
 
 
1068
                                dynPtr->TimeNotInContactWithFloor = 0;
 
 
1069
 
 
 
1070
                                if (PlayerStatus.sound_mouth == SOUND_NOACTIVEINDEX) 
 
 
1071
                                {
 
 
1072
                                    SpeciesSound(0, PSC_Jump, 0, &PlayerStatus.sound_mouth, NULL, PREDATOR_SOUND);
 
 
1073
 
 
 
1074
                                    if(SinglePlayer != AvP.PlayMode)
 
 
1075
                                        netGameData.myLastScream = PSC_Jump;
 
 
1076
                                }
 
 
1077
                            }
 
 
1078
                        }
 
 
1079
                    break;
 
 
1080
                    }
 
 
1081
 
 
 
1082
                    reportPtr = reportPtr->NextCollisionReportPtr;
 
 
1083
                }
 
 
1084
            }
 
 
1085
 
 
 
1086
            if (PlayersFallingSpeed)
 
 
1087
            {
 
 
1088
                int distanceFallen = (dynPtr->Position.vy - PlayersMaxHeightWhilstNotInContactWithGround);
 
 
1089
 
 
 
1090
                switch(AvP.PlayerType)
 
 
1091
                {
 
 
1092
                    case I_Alien:
 
 
1093
                    {
 
 
1094
                        if (distanceFallen > 2500)
 
 
1095
                        {
 
 
1096
                            Sound_Play(SID_MARINE_SMALLLANDING, "hd", dynPtr);
 
 
1097
 
 
 
1098
                            if(distanceFallen > 30000)
 
 
1099
                            {
 
 
1100
                                if((SinglePlayer == AvP.PlayMode) || netGameData.fallingDamage)
 
 
1101
                                {
 
 
1102
                                    int damage = (PlayersFallingSpeed - 15000) * 256;
 
 
1103
 
 
 
1104
                                    if (damage > ONE_FIXED)
 
 
1105
                                        CauseDamageToObject(PlayerStatus.sbptr, &damage_profiles[FALLINGDAMAGE], damage, NULL);
 
 
1106
                                }
 
 
1107
 
 
 
1108
                                if(SinglePlayer != AvP.PlayMode)
 
 
1109
                                    netGameData.landingNoise = 1;
 
 
1110
 
 
 
1111
                                PlayerStatus.Crouching = 1;
 
 
1112
                            }
 
 
1113
                        }
 
 
1114
                    }
 
 
1115
                    break;
 
 
1116
                    case I_Marine:
 
 
1117
                    {
 
 
1118
                        if (distanceFallen > 1500)
 
 
1119
                        {
 
 
1120
                            Sound_Play(SID_MARINE_SMALLLANDING, "hd", dynPtr);
 
 
1121
 
 
 
1122
                            if(distanceFallen > 5000)
 
 
1123
                            {
 
 
1124
                                if((SinglePlayer == AvP.PlayMode) || netGameData.fallingDamage)
 
 
1125
                                {
 
 
1126
                                    int damage = (PlayersFallingSpeed - 15000) * 256;
 
 
1127
 
 
 
1128
                                    if (damage > ONE_FIXED)
 
 
1129
                                        CauseDamageToObject(PlayerStatus.sbptr, &damage_profiles[FALLINGDAMAGE], damage, NULL);
 
 
1130
                                }
 
 
1131
 
 
 
1132
                                if(SinglePlayer != AvP.PlayMode)
 
 
1133
                                    netGameData.landingNoise = 1;
 
 
1134
 
 
 
1135
                                PlayerStatus.Crouching = 1;
 
 
1136
                            }
 
 
1137
                        }
 
 
1138
                    }
 
 
1139
                    break;
 
 
1140
                    case I_Predator:
 
 
1141
                    {
 
 
1142
                        if (distanceFallen > 1500)
 
 
1143
                        {
 
 
1144
                            Sound_Play(SID_PRED_SMALLLANDING, "hd", dynPtr);
 
 
1145
 
 
 
1146
                            if(distanceFallen > 12000)
 
 
1147
                            {
 
 
1148
                                if((SinglePlayer == AvP.PlayMode) || netGameData.fallingDamage)
 
 
1149
                                {
 
 
1150
                                    int damage = (PlayersFallingSpeed - 15000) * 256;
 
 
1151
 
 
 
1152
                                    if (damage > ONE_FIXED)
 
 
1153
                                        CauseDamageToObject(PlayerStatus.sbptr, &damage_profiles[FALLINGDAMAGE], damage, NULL);
 
 
1154
                                }
 
 
1155
 
 
 
1156
                                if(SinglePlayer != AvP.PlayMode)
 
 
1157
                                    netGameData.landingNoise = 1;
 
 
1158
 
 
 
1159
                                PlayerStatus.Crouching = 1;
 
 
1160
                            }
 
 
1161
                        }
 
 
1162
                    }
 
 
1163
                }
 
 
1164
 
 
 
1165
                PlayersMaxHeightWhilstNotInContactWithGround = dynPtr->Position.vy;
 
 
1166
                PlayersFallingSpeed = 0;
 
 
1167
            }
 
 
1168
        }
 
 
1169
        else
 
 
1170
        {
 
 
1171
            switch(AvP.PlayerType)
 
 
1172
            {
 
 
1173
                case I_Marine:
 
 
1174
                {
 
 
1175
                    if (PlayerStatus.JetpackEnabled)
 
 
1176
                    {
 
 
1177
                        if(PlayerStatus.InputRequests.Rqst_Jump)
 
 
1178
                        {
 
 
1179
                            if (dynPtr->LinImpulse.vy > -JETPACK_MAX_SPEED)
 
 
1180
                                dynPtr->LinImpulse.vy -= MUL_FIXED(JETPACK_THRUST, NormalFrameTime);
 
 
1181
 
 
 
1182
                            //if(!dynPtr->IsInContactWithFloor)
 
 
1183
                            {
 
 
1184
                                dynPtr->LinVelocity.vx = 0;
 
 
1185
                                dynPtr->LinVelocity.vy = 0;
 
 
1186
                                dynPtr->LinVelocity.vz = forwardSpeed / 2;
 
 
1187
 
 
 
1188
                                if (forwardSpeed < 0)
 
 
1189
                                    dynPtr->LinVelocity.vz /= 2;
 
 
1190
 
 
 
1191
                                if(PlayerStatus.InputRequests.Rqst_Strafe ||
 
 
1192
                                PlayerStatus.InputRequests.Rqst_SideStepLeft ||
 
 
1193
                                PlayerStatus.InputRequests.Rqst_SideStepRight)
 
 
1194
                                {
 
 
1195
                                    dynPtr->LinVelocity.vx = strafeSpeed / 4;
 
 
1196
                                }
 
 
1197
                                // rotate LinVelocity into world space
 
 
1198
                                RotateVector(&dynPtr->LinVelocity, &dynPtr->OrientMat);
 
 
1199
                            }
 
 
1200
 
 
 
1201
                            AddLightingEffectToObject(PlayerStatus.DisplayBlock, LFX_OBJECTONFIRE);
 
 
1202
 
 
 
1203
                            if (PlayerStatus.sound_jetpack == SOUND_NOACTIVEINDEX) 
 
 
1204
                            {
 
 
1205
                                Sound_Play(SID_JETPACK_START, "h");
 
 
1206
                                Sound_Play(SID_JETPACK_MID, "el", &PlayerStatus.sound_jetpack);
 
 
1207
                            }
 
 
1208
                        }
 
 
1209
                        else if (PlayerStatus.sound_jetpack != SOUND_NOACTIVEINDEX)
 
 
1210
                        {
 
 
1211
                            Sound_Play(SID_JETPACK_END, "h");
 
 
1212
                            Sound_Stop(PlayerStatus.sound_jetpack);
 
 
1213
                        }
 
 
1214
                    }
 
 
1215
                } // no break
 
 
1216
                default:
 
 
1217
                case I_Predator:
 
 
1218
                {
 
 
1219
                    if(dynPtr->LinImpulse.vy < 0)
 
 
1220
                    {
 
 
1221
                        PlayersMaxHeightWhilstNotInContactWithGround = 1000000;
 
 
1222
                    }
 
 
1223
                    else if(PlayersMaxHeightWhilstNotInContactWithGround > dynPtr->Position.vy)
 
 
1224
                    {
 
 
1225
                        PlayersMaxHeightWhilstNotInContactWithGround = dynPtr->Position.vy;
 
 
1226
                    }
 
 
1227
                }
 
 
1228
            }
 
 
1229
 
 
 
1230
            if (dynPtr->CollisionReportPtr && !PlayerStatus.JetpackEnabled)
 
 
1231
            {
 
 
1232
                /* KJL 12:28:48 14/04/98 - if we're not in contact with the floor, but we've hit something,
 
 
1233
                set our velocity to zero (otherwise leave it alone) */
 
 
1234
 
 
 
1235
                //dynPtr->LinVelocity.vz /= 8;
 
 
1236
                dynPtr->LinVelocity.vz = 0;
 
 
1237
                dynPtr->LinVelocity.vx = 0;
 
 
1238
                dynPtr->LinVelocity.vy = 0;
 
 
1239
                // rotate LinVelocity into world space
 
 
1240
                RotateVector(&dynPtr->LinVelocity, &dynPtr->OrientMat);
 
 
1241
            }
 
 
1242
 
 
 
1243
            PlayersFallingSpeed = dynPtr->LinVelocity.vy + dynPtr->LinImpulse.vy;
 
 
1244
        }
 
 
1245
    }
 
 
1246
#ifdef AFRAID_OF_GROUND
 
 
1247
    else
 
 
1248
    {
 
 
1249
        dynPtr->LinVelocity.vx = dynPtr->LinVelocity.vy = 0;
 
 
1250
        dynPtr->LinVelocity.vz = forwardSpeed;
 
 
1251
 
 
 
1252
        if(PlayerStatus.InputRequests.Rqst_Strafe || PlayerStatus.InputRequests.Rqst_SideStepLeft || PlayerStatus.InputRequests.Rqst_SideStepRight)
 
 
1253
            dynPtr->LinVelocity.vx = strafeSpeed;
 
 
1254
 
 
 
1255
        /* rotate LinVelocity along camera view */
 
 
1256
        {
 
 
1257
            MATRIXCH mat = Global_VDB.VDB_Mat;
 
 
1258
            TransposeMatrixCH(&mat);
 
 
1259
            RotateVector(&dynPtr->LinVelocity,&mat);
 
 
1260
        }
 
 
1261
 
 
 
1262
        dynPtr->GravityOn = 0;
 
 
1263
        dynPtr->LinImpulse.vx = dynPtr->LinImpulse.vy = dynPtr->LinImpulse.vz = 0;
 
 
1264
    }
 
 
1265
#endif
 
 
1266
 
 
 
1267
    if(Keyboard[primaryInput->Operate] || Keyboard[secondaryInput->Operate])
 
 
1268
        OperateObjectInLineOfSight();
 
 
1269
 
 
 
1270
    if(Keyboard[primaryInput->ViewMode] || Keyboard[secondaryInput->ViewMode])
 
 
1271
    {
 
 
1272
        if(ViewModeDebounced)
 
 
1273
        {
 
 
1274
            if(PlayerStatus.FirstPersonView)
 
 
1275
                PlayerStatus.DisplayBlock->ObFlags &= ~ObFlag_NotVis;
 
 
1276
            else
 
 
1277
                PlayerStatus.DisplayBlock->ObFlags |= ObFlag_NotVis;
 
 
1278
 
 
 
1279
            PlayerStatus.FirstPersonView ^= 1;
 
 
1280
            ViewModeDebounced = 0;
 
 
1281
        }
 
 
1282
    }
 
 
1283
    else
 
 
1284
    {
 
 
1285
        ViewModeDebounced = 1;
 
 
1286
    }
 
 
1287
 
 
 
1288
    if(Keyboard[primaryInput->Taunt] || Keyboard[secondaryInput->Taunt])
 
 
1289
            StartPlayerTaunt();
 
 
1290
 
 
 
1291
    if(Keyboard[primaryInput->MessageHistory] || Keyboard[secondaryInput->MessageHistory])
 
 
1292
            mission_messages_show_history();
 
 
1293
 
 
 
1294
    if (ControlMethods.AutoCentreOnMovement)
 
 
1295
    {
 
 
1296
        static int timeBeenContinuouslyMoving = 0;
 
 
1297
 
 
 
1298
        if (Mvt_MotionIncrement)
 
 
1299
        {
 
 
1300
            if (timeBeenContinuouslyMoving > TIMEBEFOREAUTOCENTREVIEW && !auto_centre )
 
 
1301
                centre_view();
 
 
1302
            else
 
 
1303
                timeBeenContinuouslyMoving += NormalFrameTime;    
 
 
1304
        }
 
 
1305
        else
 
 
1306
            timeBeenContinuouslyMoving = 0;
 
 
1307
    }
 
 
1308
}
 
 
1309
 
 
 
1310
int Keyboard_input_operate()
 
 
1311
{
 
 
1312
    return (Keyboard[primaryInput->Operate] || Keyboard[secondaryInput->Operate]);
 
 
1313
}