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