home *** CD-ROM | disk | FTP | other *** search
/ Game Level Design / GLDesign.bin / Software / UnrealEngine2Runtime / UE2Runtime-22262001_Demo.exe / Engine / Classes / PlayerController.uc < prev    next >
Text File  |  2004-03-31  |  110KB  |  4,351 lines

  1. //=============================================================================
  2. // PlayerController
  3. //
  4. // PlayerControllers are used by human players to control pawns.
  5. //
  6. // This is a built-in Unreal class and it shouldn't be modified.
  7. // for the change in Possess().
  8. //=============================================================================
  9. class PlayerController extends Controller
  10.     config(user)
  11.     native
  12.     nativereplication;
  13.  
  14. // Player info.
  15. var const player Player;
  16.  
  17. // player input control
  18. var globalconfig    bool     bLookUpStairs;    // look up/down stairs (player)
  19. var globalconfig    bool    bSnapToLevel;    // Snap to level eyeheight when not mouselooking
  20. var globalconfig    bool    bAlwaysMouseLook;
  21. var globalconfig    bool    bKeyboardLook;    // no snapping when true
  22. var bool                    bCenterView;
  23.  
  24. // Player control flags
  25. var bool        bBehindView;    // Outside-the-player view.
  26. var bool        bFrozen;        // set when game ends or player dies to temporarily prevent player from restarting (until cleared by timer)
  27. var bool        bPressedJump;
  28. var    bool        bDoubleJump;
  29. var bool        bUpdatePosition;
  30. var bool        bIsTyping;
  31. var bool        bFixedCamera;    // used to fix camera in position (to view animations)
  32. var bool        bJumpStatus;    // used in net games
  33. var    bool        bUpdating;
  34. var globalconfig bool    bNeverSwitchOnPickup;    // if true, don't automatically switch to picked up weapon
  35.  
  36. var bool        bZooming;
  37.  
  38. var globalconfig bool bAlwaysLevel;
  39. var bool        bSetTurnRot;
  40. var bool        bCheatFlying;    // instantly stop in flying mode
  41. var bool        bFreeCamera;    // free camera when in behindview mode (for checking out player models and animations)
  42. var    bool        bZeroRoll;
  43. var    bool        bCameraPositionLocked;
  44. var    bool        bViewBot;
  45. var bool        UseFixedVisibility;
  46. var bool    bBlockCloseCamera;
  47. var bool    bValidBehindCamera;
  48. var bool    bForcePrecache;
  49. var bool    bClientDemo;
  50. var const bool bAllActorsRelevant;    // used by UTTV.  DO NOT SET THIS TRUE - it has a huge impact on network performance
  51. var bool    bShortConnectTimeOut;    // when true, reduces connect timeout to 15 seconds
  52. var bool    bPendingDestroy;        // when true, playercontroller is being destroyed
  53.  
  54. var globalconfig bool bNoVoiceMessages;
  55. var globalconfig bool bNoVoiceTaunts;
  56. var globalconfig bool bNoAutoTaunts;
  57. var globalconfig bool bAutoTaunt;
  58. var globalconfig bool bNoMatureLanguage;
  59. var globalconfig bool bDynamicNetSpeed;
  60.  
  61. var globalconfig byte AnnouncerLevel;  // 0=none, 1=no possession announcements, 2=all
  62. var globalconfig byte AnnouncerVolume; // 1 to 4
  63. var globalconfig float AimingHelp;
  64. var globalconfig float MaxResponseTime;        // how long server will wait for client move update before setting position
  65. var float WaitDelay;            // Delay time until can restart
  66.  
  67. var input float
  68.     aBaseX, aBaseY, aBaseZ,    aMouseX, aMouseY,
  69.     aForward, aTurn, aStrafe, aUp, aLookUp;
  70.  
  71. var input byte
  72.     bStrafe, bSnapLevel, bLook, bFreeLook, bTurn180, bTurnToNearest, bXAxis, bYAxis;
  73.  
  74. var EDoubleClickDir DoubleClickDir;        // direction of movement key double click (for special moves)
  75.  
  76. // Camera info.
  77. var int ShowFlags;
  78. var int Misc1,Misc2;
  79. var int RendMap;
  80. var float        OrthoZoom;     // Orthogonal/map view zoom factor.
  81. var const actor ViewTarget;
  82. var const Controller RealViewTarget;
  83. var PlayerController DemoViewer;
  84. var float CameraDist;        // multiplier for behindview camera dist
  85. var vector OldCameraLoc;        // used in behindview calculations
  86. var rotator OldCameraRot;
  87. var transient array<CameraEffect> CameraEffects;    // A stack of camera effects.
  88.  
  89. var globalconfig float DesiredFOV;
  90. var globalconfig float DefaultFOV;
  91. var float        ZoomLevel;
  92.  
  93. // Fixed visibility.
  94. var vector    FixedLocation;
  95. var rotator    FixedRotation;
  96. var matrix    RenderWorldToCamera;
  97.  
  98. // Screen flashes
  99. var vector FlashScale, FlashFog;
  100. var float ConstantGlowScale;
  101. var vector ConstantGlowFog;
  102.  
  103. // Distance fog fading.
  104. var color    LastDistanceFogColor;
  105. var float    LastDistanceFogStart;
  106. var float    LastDistanceFogEnd;
  107. var float    CurrentDistanceFogEnd;
  108. var float    TimeSinceLastFogChange;
  109. var int        LastZone;
  110.  
  111. // Remote Pawn ViewTargets
  112. var rotator        TargetViewRotation; 
  113. var rotator     BlendedTargetViewRotation;
  114. var float        TargetEyeHeight;
  115. var vector        TargetWeaponViewOffset;
  116.  
  117. var HUD    myHUD;    // heads up display info
  118.  
  119. var float LastPlaySound;
  120. var float LastPlaySpeech;
  121.  
  122. // Music info.
  123. var string                Song;
  124. var EMusicTransition    Transition;
  125.  
  126. // Move buffering for network games.  Clients save their un-acknowledged moves in order to replay them
  127. // when they get position updates from the server.
  128. var SavedMove SavedMoves;    // buffered moves pending position updates
  129. var SavedMove FreeMoves;    // freed moves, available for buffering
  130. var SavedMove PendingMove;    
  131. var float CurrentTimeStamp,LastUpdateTime,ServerTimeStamp,TimeMargin, ClientUpdateTime;
  132. var globalconfig float MaxTimeMargin;
  133. var Weapon OldClientWeapon;
  134. var int WeaponUpdate;
  135.  
  136. // Progess Indicator - used by the engine to provide status messages (HUD is responsible for displaying these).
  137. var string    ProgressMessage[4];
  138. var color    ProgressColor[4];
  139. var float    ProgressTimeOut;
  140.  
  141. // Localized strings
  142. var localized string QuickSaveString;
  143. var localized string NoPauseMessage;
  144. var localized string ViewingFrom;
  145. var localized string OwnCamera;
  146.  
  147. // ReplicationInfo
  148. var GameReplicationInfo GameReplicationInfo;
  149.  
  150. // Stats Logging
  151. var globalconfig string StatsUsername;
  152. var globalconfig string StatsPassword;
  153.  
  154. var class<LocalMessage> LocalMessageClass;
  155.  
  156. // view shaking (affects roll, and offsets camera position)
  157. var float    MaxShakeRoll; // max magnitude to roll camera
  158. var vector    MaxShakeOffset; // max magnitude to offset camera position
  159. var float    ShakeRollRate;    // rate to change roll
  160. var vector    ShakeOffsetRate;
  161. var vector    ShakeOffset; //current magnitude to offset camera from shake
  162. var float    ShakeRollTime; // how long to roll.  if value is < 1.0, then MaxShakeOffset gets damped by this, else if > 1 then its the number of times to repeat undamped
  163. var vector    ShakeOffsetTime;
  164.  
  165. var Pawn        TurnTarget;
  166. var config int    EnemyTurnSpeed;
  167. var int            GroundPitch;
  168. var rotator        TurnRot180;
  169.  
  170. var vector OldFloor;        // used by PlayerSpider mode - floor for which old rotation was based;
  171.  
  172. // Components ( inner classes )
  173. var private transient CheatManager    CheatManager;   // Object within playercontroller that manages "cheat" commands
  174. var class<CheatManager>        CheatClass;        // class of my CheatManager
  175. var private transient PlayerInput    PlayerInput;    // Object within playercontroller that manages player input.
  176. var config class<PlayerInput>       InputClass;     // class of my PlayerInput
  177. var const vector FailedPathStart;
  178.  
  179. // Demo recording view rotation
  180. var int DemoViewPitch;
  181. var int DemoViewYaw;
  182.  
  183. var Security PlayerSecurity;    // Used for Cheat Protection
  184. var float ForcePrecacheTime;
  185.  
  186. var float LastPingUpdate;
  187. var float ExactPing;
  188. var float OldPing;
  189. var float SpectateSpeed;
  190. var globalconfig float DynamicPingThreshold;
  191. var float NextSpeedChange;
  192. var int ClientCap;
  193.  
  194. var(ForceFeedback) globalconfig bool bEnablePickupForceFeedback;
  195. var(ForceFeedback) globalconfig bool bEnableWeaponForceFeedback;
  196. var(ForceFeedback) globalconfig bool bEnableDamageForceFeedback;
  197. var(ForceFeedback) globalconfig bool bEnableGUIForceFeedback;
  198. var(ForceFeedback) bool bForceFeedbackSupported;  // true if a device is detected
  199.  
  200. var(Menu) config string MidGameMenuClass; // Menu that is shown when Escape is pressed (Runtime)
  201.  
  202. replication
  203. {
  204.     // Things the server should send to the client.
  205.     reliable if( bNetDirty && bNetOwner && Role==ROLE_Authority )
  206.         GameReplicationInfo;
  207.     unreliable if ( bNetOwner && Role==ROLE_Authority && (ViewTarget != Pawn) && (Pawn(ViewTarget) != None) )
  208.         TargetViewRotation, TargetEyeHeight, TargetWeaponViewOffset;
  209.     reliable if( bDemoRecording && Role==ROLE_Authority )
  210.         DemoViewPitch, DemoViewYaw;
  211.  
  212.     // Functions server can call.
  213.     reliable if( Role==ROLE_Authority )
  214.         ClientSetHUD,ClientReliablePlaySound, FOV, StartZoom, 
  215.         ToggleZoom, StopZoom, EndZoom, ClientSetMusic, ClientRestart,
  216.         ClientAdjustGlow, 
  217.         ClientSetBehindView, ClientSetFixedCamera, ClearProgressMessages, 
  218.         SetProgressMessage, SetProgressTime,
  219.         GivePawn, ClientGotoState,
  220.         ClientChangeVoiceChatter,
  221.         ClientLeaveVoiceChat,
  222.         ClientValidate,
  223.         ClientSetViewTarget, ClientCapBandwidth,
  224.         ClientOpenMenu, ClientCloseMenu;
  225.  
  226.     reliable if ( (Role == ROLE_Authority) && (!bDemoRecording || (bClientDemoRecording && bClientDemoNetFunc)) )
  227.         ClientMessage, TeamMessage, ReceiveLocalizedMessage;
  228.     unreliable if( Role==ROLE_Authority && !bDemoRecording )
  229.         ClientPlaySound,PlayAnnouncement;
  230.     reliable if( Role==ROLE_Authority && !bDemoRecording )
  231.         ClientStopForceFeedback, ClientTravel;
  232.     unreliable if( Role==ROLE_Authority )
  233.         SetFOVAngle, ClientShake, ClientFlash,  
  234.         ClientAdjustPosition, ShortClientAdjustPosition, VeryShortClientAdjustPosition, LongClientAdjustPosition;
  235.     unreliable if( (!bDemoRecording || bClientDemoRecording && bClientDemoNetFunc) && Role==ROLE_Authority )
  236.         ClientHearSound;
  237.     reliable if( bClientDemoRecording && ROLE==ROLE_Authority )
  238.         DemoClientSetHUD;
  239.  
  240.     // Functions client can call.
  241.     unreliable if( Role<ROLE_Authority )
  242.         ServerUpdatePing, ShortServerMove, ServerMove, 
  243.         RocketServerMove, Say, TeamSay, ServerSetHandedness, 
  244.         ServerViewNextPlayer, ServerViewSelf,ServerUse, ServerDrive, ServerToggleBehindView;
  245.     reliable if( Role<ROLE_Authority )
  246.         Speech, Pause, SetPause,Mutate,
  247.         PrevItem, ActivateItem, ServerReStartGame, AskForPawn,
  248.         ChangeName, ChangeTeam, Suicide,
  249.         ServerThrowWeapon, BehindView, Typing,
  250.         ServerChangeVoiceChatter,
  251.         ServerGetVoiceChatters,
  252.         ServerValidationResponse, ServerVerifyViewTarget, ServerSpectateSpeed, ServerSetClientDemo;
  253. }
  254.  
  255. native final function SetNetSpeed(int NewSpeed);
  256. native final function string GetPlayerNetworkAddress();
  257. native final function string GetServerNetworkAddress();
  258. native function string ConsoleCommand( string Command );
  259. native final function LevelInfo GetEntryLevel();
  260. native(544) final function ResetKeyboard();
  261. native final function SetViewTarget(Actor NewViewTarget);
  262. native event ClientTravel( string URL, ETravelType TravelType, bool bItems );
  263. native(546) final function UpdateURL(string NewOption, string NewValue, bool bSaveDefault);
  264. native final function string GetDefaultURL(string Option);
  265. // Execute a console command in the context of this player, then forward to Actor.ConsoleCommand.
  266. native function CopyToClipboard( string Text );
  267. native function string PasteFromClipboard();
  268.  
  269. // Validation.
  270. private native event ClientValidate(string C);
  271. private native event ServerValidationResponse(string R);
  272.  
  273. /* FindStairRotation()
  274. returns an integer to use as a pitch to orient player view along current ground (flat, up, or down)
  275. */
  276. native(524) final function int FindStairRotation(float DeltaTime);
  277.  
  278. native event ClientHearSound ( 
  279.     actor Actor, 
  280.     int Id, 
  281.     sound S, 
  282.     vector SoundLocation, 
  283.     vector Parameters,
  284.     bool Attenuate
  285. );
  286.  
  287. event PostBeginPlay()
  288. {
  289.     Super.PostBeginPlay();
  290.     SpawnDefaultHUD();
  291.     if (Level.LevelEnterText != "" )
  292.         ClientMessage(Level.LevelEnterText);
  293.  
  294.     DesiredFOV = DefaultFOV;
  295.     SetViewTarget(self);  // MUST have a view target!
  296.     if ( Level.NetMode == NM_Standalone )
  297.         AddCheats();
  298.     
  299.     bForcePrecache = (Role < ROLE_Authority);
  300.     ForcePrecacheTime = Level.TimeSeconds + 2;
  301. }
  302.  
  303. exec function SetSpectateSpeed(Float F)
  304. {
  305.     SpectateSpeed = F;
  306.     ServerSpectateSpeed(F);
  307. }
  308.  
  309. function ServerSpectateSpeed(Float F)
  310. {
  311.     SpectateSpeed = F;
  312. }
  313.  
  314. function ServerGivePawn()
  315. {
  316.     GivePawn(Pawn);
  317. }
  318.  
  319. function ClientCapBandwidth(int Cap)
  320. {
  321.     ClientCap = Cap;
  322.     if ( (Player != None) && (Player.CurrentNetSpeed > Cap) )
  323.         SetNetSpeed(Cap);
  324. }
  325.         
  326. function PendingStasis()
  327. {
  328.     bStasis = true;
  329.     Pawn = None;
  330.     GotoState('Scripting');
  331. }
  332.  
  333. function AddCheats()
  334. {
  335.     // Assuming that this never gets called for NM_Client
  336.     if ( CheatManager == None && (Level.NetMode == NM_Standalone) )
  337.         CheatManager = new(Self) CheatClass;
  338. }
  339.  
  340. function HandlePickup(Pickup pick)
  341. {
  342.     ReceiveLocalizedMessage(pick.MessageClass,,,,pick.class);
  343. }
  344.  
  345. event ClientSetViewTarget( Actor a )
  346. {
  347.     if ( A == None )
  348.         ServerVerifyViewTarget();
  349.     SetViewTarget( a );
  350. }
  351.  
  352. function ServerVerifyViewTarget()
  353. {
  354.     if ( ViewTarget == self )
  355.         return;
  356.  
  357.     ClientSetViewTarget(ViewTarget);
  358. }
  359.  
  360. /* SpawnDefaultHUD()
  361. Spawn a HUD (make sure that PlayerController always has valid HUD, even if \
  362. ClientSetHUD() hasn't been called\
  363. */
  364. function SpawnDefaultHUD()
  365. {
  366.     myHUD = spawn(class'HUD',self);
  367. }
  368.     
  369. /* Reset() 
  370. reset actor to initial state - used when restarting level without reloading.
  371. */
  372. function Reset()
  373. {
  374.     PawnDied(Pawn);
  375.     Super.Reset();
  376.     SetViewTarget(self);
  377.     bBehindView = false;
  378.     WaitDelay = Level.TimeSeconds + 2;
  379.     FixFOV();
  380.     if ( !PlayerReplicationInfo.bOnlySpectator )
  381.         GotoState('PlayerWaiting');
  382. }
  383.  
  384. function CleanOutSavedMoves()
  385. {
  386.     local SavedMove Next;
  387.     
  388.     // clean out saved moves
  389.     while ( SavedMoves != None )
  390.     {
  391.         Next = SavedMoves.NextMove;
  392.         SavedMoves.Destroy();
  393.         SavedMoves = Next;
  394.     }
  395.     if ( PendingMove != None )
  396.     {
  397.         PendingMove.Destroy();
  398.         PendingMove = None;
  399.     }
  400. }
  401.  
  402. /* InitInputSystem()
  403. Spawn the appropriate class of PlayerInput
  404. Only called for playercontrollers that belong to local players
  405. */
  406. event InitInputSystem()
  407. {
  408.     PlayerInput = new(Self) InputClass;
  409. }
  410.  
  411. /* ClientGotoState()
  412. server uses this to force client into NewState
  413. */
  414. function ClientGotoState(name NewState, name NewLabel)
  415. {
  416.     GotoState(NewState,NewLabel);
  417. }
  418.  
  419. function AskForPawn()
  420. {
  421.     if ( IsInState('GameEnded') )
  422.         ClientGotoState('GameEnded', 'Begin');
  423.     else if ( Pawn != None )
  424.         GivePawn(Pawn);
  425.     else
  426.     {
  427.         bFrozen = false;
  428.         ServerRestartPlayer();
  429.     }        
  430. }    
  431.  
  432. function GivePawn(Pawn NewPawn)
  433. {
  434.     if ( NewPawn == None )
  435.         return;
  436.     Pawn = NewPawn;
  437.     NewPawn.Controller = self;
  438.     ClientRestart();
  439. }    
  440.  
  441. /* GetFacingDirection()
  442. returns direction faced relative to movement dir
  443. 0 = forward
  444. 16384 = right
  445. 32768 = back
  446. 49152 = left
  447. */
  448. function int GetFacingDirection()
  449. {
  450.     local vector X,Y,Z, Dir;
  451.  
  452.     GetAxes(Pawn.Rotation, X,Y,Z);
  453.     Dir = Normal(Pawn.Acceleration);
  454.     if ( Y Dot Dir > 0 )
  455.         return ( 49152 + 16384 * (X Dot Dir) );
  456.     else
  457.         return ( 16384 - 16384 * (X Dot Dir) );
  458. }
  459.  
  460. // Possess a pawn
  461. function Possess(Pawn aPawn)
  462. {
  463.     if ( PlayerReplicationInfo.bOnlySpectator )
  464.         return;
  465.  
  466.     SetRotation(aPawn.Rotation);
  467.     aPawn.PossessedBy(self);
  468.     Pawn = aPawn;
  469.     Pawn.bStasis = false;
  470.     CleanOutSavedMoves();  // don't replay moves previous to possession
  471.     PlayerReplicationInfo.bIsFemale = Pawn.bIsFemale;
  472.     ServerSetHandedness(Handedness);
  473.     Restart();
  474. }
  475.  
  476. // unpossessed a pawn (not because pawn was killed)
  477. function UnPossess()
  478. {
  479.     if ( Pawn != None )
  480.     {
  481.         SetLocation(Pawn.Location);
  482.         Pawn.RemoteRole = ROLE_SimulatedProxy;
  483.         Pawn.UnPossessed();
  484.         CleanOutSavedMoves();  // don't replay moves previous to unpossession
  485.         if ( Viewtarget == Pawn )
  486.             SetViewTarget(self);
  487.     }
  488.     Pawn = None;
  489.     GotoState('Spectating');
  490. }
  491.  
  492. function ViewNextBot()
  493. {
  494.     if ( CheatManager != None )
  495.         CheatManager.ViewBot();
  496. }
  497.  
  498. // unpossessed a pawn (because pawn was killed)
  499. function PawnDied(Pawn P)
  500. {
  501.     if ( P != Pawn )
  502.         return;
  503.     EndZoom();
  504.     if ( Pawn != None )
  505.         Pawn.RemoteRole = ROLE_SimulatedProxy;
  506.     if ( ViewTarget == Pawn )
  507.         bBehindView = true;
  508.  
  509.     Super.PawnDied(P);
  510. }
  511.  
  512. function ClientSetHUD(class<HUD> newHUDType, class<Scoreboard> newScoringType)
  513. {
  514.     local HUD NewHUD;
  515.  
  516.     if ( (myHUD == None) || ((newHUDType != None) && (newHUDType != myHUD.Class)) )
  517.     {
  518.         NewHUD = spawn(newHUDType, self); 
  519.         if ( NewHUD != None )
  520.         {
  521.             if ( myHUD != None )
  522.                 myHUD.Destroy();
  523.             myHUD = NewHUD;
  524.         }
  525.     }
  526.     if ( (myHUD != None) && (newScoringType != None) )
  527.         MyHUD.SpawnScoreBoard(newScoringType);
  528. }
  529.  
  530. // jdf ---
  531. // Server ignores this call, client plays effect
  532. simulated function ClientPlayForceFeedback( String EffectName )
  533. {
  534.     if (bForceFeedbackSupported && Viewport(Player) != None)
  535.         PlayFeedbackEffect( EffectName );
  536. }
  537.  
  538. simulated function StopForceFeedback( optional String EffectName )
  539. {
  540.     if (bForceFeedbackSupported && Viewport(Player) != None)
  541.     {
  542.         if (EffectName != "")
  543.             StopFeedbackEffect( EffectName );
  544.         else
  545.             StopFeedbackEffect();
  546.     }
  547. }
  548.  
  549. function ClientStopForceFeedback( optional String EffectName )
  550. {
  551.     if (bForceFeedbackSupported && Viewport(Player) != None)
  552.     {
  553.         if (EffectName != "")
  554.             StopFeedbackEffect( EffectName );
  555.         else
  556.             StopFeedbackEffect();
  557.     }
  558. }
  559. // --- jdf
  560.  
  561. final function float UpdateFlashComponent(float current, float Step, float goal)
  562. {
  563.     if ( goal > current )
  564.         return FMin(current + Step, goal);
  565.     else
  566.         return FMax(current - Step, goal);
  567. }
  568.  
  569. function ViewFlash(float DeltaTime)
  570. {
  571.     local vector goalFog;
  572.     local float goalscale, delta, Step;
  573.  
  574.     delta = FMin(0.1, DeltaTime);
  575.     goalScale = 1; // + ConstantGlowScale;
  576.     goalFog = vect(0,0,0); // ConstantGlowFog;
  577.  
  578.     if ( Pawn != None )
  579.     {
  580.         goalScale += Pawn.HeadVolume.ViewFlash.X; 
  581.         goalFog += Pawn.HeadVolume.ViewFog;
  582.     }
  583.     Step = 0.6 * delta;
  584.     FlashScale.X = UpdateFlashComponent(FlashScale.X,step,goalScale);
  585.     FlashScale = FlashScale.X * vect(1,1,1);
  586.  
  587.     FlashFog.X = UpdateFlashComponent(FlashFog.X,step,goalFog.X);
  588.     FlashFog.Y = UpdateFlashComponent(FlashFog.Y,step,goalFog.Y);
  589.     FlashFog.Z = UpdateFlashComponent(FlashFog.Z,step,goalFog.Z);
  590. }
  591.  
  592. simulated event ReceiveLocalizedMessage( class<LocalMessage> Message, optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2, optional Object OptionalObject )
  593. {
  594.     Message.Static.ClientReceive( Self, Switch, RelatedPRI_1, RelatedPRI_2, OptionalObject );
  595.     if ( Message.default.bIsConsoleMessage && (Player != None) && (Player.Console != None) )
  596.         Player.Console.Message(Message.Static.GetString(Switch, RelatedPRI_1, RelatedPRI_2, OptionalObject),0 );
  597. }
  598.  
  599. event ClientMessage( coerce string S, optional Name Type )
  600. {
  601.     if (Type == '')
  602.         Type = 'Event';
  603.  
  604.     TeamMessage(PlayerReplicationInfo, S, Type);
  605. }
  606.  
  607. event TeamMessage( PlayerReplicationInfo PRI, coerce string S, name Type  )
  608. {
  609.     if ( myHUD != None )
  610.     myHUD.Message( PRI, S, Type );
  611.  
  612.     if ( ((Type == 'Say') || (Type == 'TeamSay')) && (PRI != None) )
  613.         S = PRI.PlayerName$": "$S;
  614.  
  615.     if(Player != None)
  616.         Player.Console.Message( S, 6.0 );
  617. }
  618.  
  619. simulated function PlayBeepSound();
  620.  
  621. simulated function PlayAnnouncement(sound ASound, byte AnnouncementLevel, optional bool bForce)
  622. {    
  623.     local float Atten;
  624.     
  625.     if ( AnnouncementLevel > AnnouncerLevel )
  626.         return;
  627.     if ( !bForce && (Level.TimeSeconds - LastPlaySound < 1) )
  628.         return;
  629.     LastPlaySound = Level.TimeSeconds;    // so voice messages won't overlap
  630.     LastPlaySpeech = Level.TimeSeconds;    // don't want chatter to overlap announcements
  631.     
  632.     Atten = FClamp(0.1 + float(AnnouncerVolume)*0.225,0.2,1.0);
  633.     ClientPlaySound(ASound,true,Atten,SLOT_Talk);
  634. }
  635.  
  636. function bool AllowVoiceMessage(name MessageType)
  637. {
  638.     if ( Level.NetMode == NM_Standalone )
  639.         return true;
  640.         
  641.     if ( Level.TimeSeconds - OldMessageTime < 3 )
  642.     {
  643.         if ( (MessageType == 'TAUNT') || (MessageType == 'AUTOTAUNT') )
  644.             return false;
  645.         if ( Level.TimeSeconds - OldMessageTime < 1 )
  646.             return false;
  647.     }
  648.     if ( Level.TimeSeconds - OldMessageTime < 6 )
  649.         OldMessageTime = Level.TimeSeconds + 3;
  650.     else
  651.         OldMessageTime = Level.TimeSeconds;
  652.     return true;
  653. }
  654.     
  655. //Play a sound client side (so only client will hear it
  656. simulated function ClientPlaySound(sound ASound, optional bool bVolumeControl, optional float inAtten, optional ESoundSlot slot )
  657. {
  658.     local float atten;
  659.  
  660.     atten = 0.9;
  661.     if( bVolumeControl )
  662.         atten = FClamp(inAtten,0,1);
  663.  
  664.     if ( ViewTarget != None )
  665.         ViewTarget.PlaySound(ASound, slot, atten,,,,false);
  666. }
  667.  
  668. simulated function ClientReliablePlaySound(sound ASound, optional bool bVolumeControl )
  669. {
  670.     ClientPlaySound(ASound, bVolumeControl);
  671. }
  672.  
  673. simulated event Destroyed()
  674. {
  675.     local SavedMove Next;
  676.     local KVehicle DrivenVehicle;
  677.     local SVehicle DrivenSVehicle;
  678.     local Pawn Driver;
  679.  
  680.     // cheatmanager, adminmanager, and playerinput cleaned up in C++ PostScriptDestroyed()
  681.  
  682.     StopFeedbackEffect();
  683.  
  684.     if ( Pawn != None )
  685.     {
  686.         // If its a vehicle, just destroy the driver, otherwise do the normal.
  687.         DrivenVehicle = KVehicle(Pawn);
  688.         if(DrivenVehicle != None)
  689.         {    
  690.             Driver = DrivenVehicle.Driver;
  691.             DrivenVehicle.KDriverLeave(true); // Force the driver out of the car
  692.             Driver.Destroy();
  693.         }
  694.         else
  695.         {
  696.             DrivenSVehicle = SVehicle(Pawn);
  697.             if(DrivenSVehicle != None)
  698.             {    
  699.                 Driver = DrivenSVehicle.Driver;
  700.                 DrivenSVehicle.KDriverLeave(true); // Force the driver out of the car
  701.                 Driver.Destroy();
  702.             }
  703.             else
  704.             {
  705.  
  706.         Pawn.Health = 0;
  707.         Pawn.Unpossessed();
  708.         Pawn.Died( self, class'Suicided', Pawn.Location );
  709.         }
  710.         }
  711.     }
  712.     myHud.Destroy();
  713.  
  714.     while ( FreeMoves != None )
  715.     {
  716.         Next = FreeMoves.NextMove;
  717.         FreeMoves.Destroy();
  718.         FreeMoves = Next;
  719.     }
  720.     while ( SavedMoves != None )
  721.     {
  722.         Next = SavedMoves.NextMove;
  723.         SavedMoves.Destroy();
  724.         SavedMoves = Next;
  725.     }
  726.     
  727.     if( PlayerSecurity != None )
  728.     {
  729.         PlayerSecurity.Destroy();
  730.         PlayerSecurity = None;
  731.     }
  732.  
  733.     Super.Destroyed();
  734. }
  735.  
  736. function ClientSetMusic( string NewSong, EMusicTransition NewTransition )
  737. {
  738.     StopAllMusic( 0.0 );
  739.     PlayMusic( NewSong, 3.0 );
  740.     Song        = NewSong;
  741.     Transition  = NewTransition;
  742. }
  743.     
  744. // ------------------------------------------------------------------------
  745. // Zooming/FOV change functions
  746.  
  747. function ToggleZoom()
  748. {
  749.     if ( DefaultFOV != DesiredFOV )
  750.         EndZoom();
  751.     else
  752.         StartZoom();
  753. }
  754.     
  755. function StartZoom()
  756. {
  757.     ZoomLevel = 0.0;
  758.     bZooming = true;
  759. }
  760.  
  761. function StopZoom()
  762. {
  763.     bZooming = false;
  764. }
  765.  
  766. function EndZoom()
  767. {
  768.     bZooming = false;
  769.     DesiredFOV = DefaultFOV;
  770. }
  771.  
  772. function FixFOV()
  773. {
  774.     FOVAngle = Default.DefaultFOV;
  775.     DesiredFOV = Default.DefaultFOV;
  776.     DefaultFOV = Default.DefaultFOV;
  777. }
  778.  
  779. function SetFOV(float NewFOV)
  780. {
  781.     DesiredFOV = NewFOV;
  782.     FOVAngle = NewFOV;
  783. }
  784.  
  785. function ResetFOV()
  786. {
  787.     DesiredFOV = DefaultFOV;
  788.     FOVAngle = DefaultFOV;
  789. }
  790.  
  791. exec function FOV(float F)
  792. {
  793.     if( (F >= 80.0) || (Level.Netmode==NM_Standalone) )
  794.     {
  795.         DefaultFOV = FClamp(F, 1, 170);
  796.         DesiredFOV = DefaultFOV;
  797.         SaveConfig();
  798.     }
  799. }
  800.  
  801. exec function Mutate(string MutateString)
  802. {
  803.     if( Level.NetMode == NM_Client )
  804.         return;
  805.     Level.Game.BaseMutator.Mutate(MutateString, Self);
  806. }
  807.  
  808. exec function SetSensitivity(float F)
  809. {
  810.     PlayerInput.UpdateSensitivity(F);
  811. }
  812.  
  813. exec function SetMouseSmoothing( int Mode )
  814. {
  815.     PlayerInput.UpdateSmoothing( Mode );
  816. }
  817.  
  818. exec function SetMouseAccel(float F)
  819. {
  820.     PlayerInput.UpdateAccel(F);
  821. }
  822.  
  823. exec function ForceReload()
  824. {
  825.     if ( (Pawn != None) && (Pawn.Weapon != None) )
  826.     {
  827.         Pawn.Weapon.ForceReload();
  828.     }
  829. }
  830.  
  831. // ------------------------------------------------------------------------
  832. // Messaging functions
  833.  
  834. // Send a message to all players.
  835. exec function Say( string Msg )
  836. {
  837.     if (PlayerReplicationInfo.bAdmin && left(Msg,1) == "#" )
  838.     {
  839.         Level.Game.AdminSay(right(Msg,len(Msg)-1));
  840.         return;
  841.     }
  842.     Level.Game.Broadcast(self, Msg, 'Say');
  843. }
  844.  
  845. exec function TeamSay( string Msg )
  846. {
  847.     if( !GameReplicationInfo.bTeamGame )
  848.     {
  849.         Say( Msg );
  850.         return;
  851.     }
  852.  
  853.     Level.Game.BroadcastTeam( self, Level.Game.ParseMessageString( Level.Game.BaseMutator , self, Msg ) , 'TeamSay');
  854. }
  855.  
  856. // ------------------------------------------------------------------------
  857.  
  858. function ServerSetHandedness( float hand)
  859. {
  860.     Handedness = hand;
  861.     if ( (Pawn != None) && (Pawn.Weapon != None) )
  862.         Pawn.Weapon.SetHand(Handedness);
  863. }
  864.  
  865. function SetHand(int IntValue)
  866. {
  867.     class'PlayerController'.default.Handedness = IntValue;
  868.     class'PlayerController'.static.StaticSaveConfig();
  869.     Handedness = IntValue;
  870.     if( (Pawn != None) && (Pawn.Weapon != None) )
  871.     Pawn.Weapon.SetHand(Handedness);
  872.      
  873.     ServerSetHandedness(Handedness);
  874. }
  875.  
  876. exec function SetWeaponHand ( string S )
  877. {
  878.     if ( S ~= "Left" )
  879.         Handedness = -1;
  880.     else if ( S~= "Right" )
  881.         Handedness = 1;
  882.     else if ( S ~= "Center" )
  883.         Handedness = 0;
  884.     else if ( S ~= "Hidden" )
  885.         Handedness = 2;
  886.     SetHand(Handedness);
  887. }
  888.  
  889. function bool IsDead()
  890. {
  891.     return false;
  892. }
  893.  
  894. exec function ShowGun ()
  895. {
  896.     if( Handedness == 2 )
  897.         Handedness = 1;
  898.     else
  899.         Handedness = 2;
  900.  
  901.     SetHand(Handedness);
  902. }
  903.  
  904. event PreClientTravel()
  905. {
  906.     log("PreClientTravel");
  907.     ClientStopForceFeedback();  // jdf
  908. }
  909.  
  910. function ClientSetFixedCamera(bool B)
  911. {
  912.     bFixedCamera = B;
  913. }
  914.  
  915. function ClientSetBehindView(bool B)
  916. {
  917.     bBehindView = B;
  918. }
  919.  
  920. function ClientVoiceMessage(PlayerReplicationInfo Sender, PlayerReplicationInfo Recipient, name messagetype, byte messageID)
  921. {
  922.     local VoicePack V;
  923.  
  924.     if ( (Sender == None) || (Sender.voicetype == None) || (Player.Console == None) )
  925.         return;
  926.         
  927.     V = Spawn(Sender.voicetype, self);
  928.     if ( V != None )
  929.         V.ClientInitialize(Sender, Recipient, messagetype, messageID);
  930. }
  931.  
  932. /* ForceDeathUpdate()
  933. Make sure ClientAdjustPosition immediately informs client of pawn's death
  934. */
  935. function ForceDeathUpdate()
  936. {
  937.     LastUpdateTime = Level.TimeSeconds - 10;
  938. }
  939.  
  940. /* RocketServerMove()
  941. compressed version of server move for PlayerRocketing state
  942. */
  943. function RocketServerMove
  944. (
  945.     float TimeStamp, 
  946.     vector InAccel, 
  947.     vector ClientLoc,
  948.     byte ClientRoll, 
  949.     int View
  950. )
  951. {
  952.     ServerMove(TimeStamp,InAccel,ClientLoc,false,false,false,false, DCLICK_NONE,ClientRoll,View);
  953. }    
  954.  
  955. /* ShortServerMove()
  956. compressed version of server move for bandwidth saving
  957. */
  958. function ShortServerMove
  959. (
  960.     float TimeStamp, 
  961.     vector ClientLoc,
  962.     bool NewbRun,
  963.     bool NewbDuck,
  964.     bool NewbJumpStatus, 
  965.     byte ClientRoll, 
  966.     int View
  967. )
  968. {
  969.     ServerMove(TimeStamp,vect(0,0,0),ClientLoc,NewbRun,NewbDuck,NewbJumpStatus,false,DCLICK_None,ClientRoll,View);
  970. }
  971.  
  972. /* ServerMove() 
  973. - replicated function sent by client to server - contains client movement and firing info
  974. Passes acceleration in components so it doesn't get rounded.
  975. */
  976. function ServerMove
  977. (
  978.     float TimeStamp, 
  979.     vector InAccel, 
  980.     vector ClientLoc,
  981.     bool NewbRun,
  982.     bool NewbDuck,
  983.     bool NewbJumpStatus, 
  984.     bool NewbDoubleJump,
  985.     eDoubleClickDir DoubleClickMove, 
  986.     byte ClientRoll, 
  987.     int View,
  988.     optional byte OldTimeDelta,
  989.     optional int OldAccel
  990. )
  991. {
  992.     local float DeltaTime, clientErr, OldTimeStamp;
  993.     local rotator DeltaRot, Rot, ViewRot;
  994.     local vector Accel, LocDiff, ClientVel, ClientFloor;
  995.     local int maxPitch, ViewPitch, ViewYaw;
  996.     local bool NewbPressedJump, OldbRun, OldbDoubleJump;
  997.     local eDoubleClickDir OldDoubleClickMove;
  998.     local actor ClientBase;
  999.     local ePhysics ClientPhysics;
  1000.  
  1001.  
  1002.     // If this move is outdated, discard it.
  1003.     if ( CurrentTimeStamp >= TimeStamp )
  1004.         return;
  1005.  
  1006.     bShortConnectTimeOut = true;
  1007.  
  1008.     // if OldTimeDelta corresponds to a lost packet, process it first
  1009.     if (  OldTimeDelta != 0 )
  1010.     {
  1011.         OldTimeStamp = TimeStamp - float(OldTimeDelta)/500 - 0.001;
  1012.         if ( CurrentTimeStamp < OldTimeStamp - 0.001 )
  1013.         {
  1014.             // split out components of lost move (approx)
  1015.             Accel.X = OldAccel >>> 23;
  1016.             if ( Accel.X > 127 )
  1017.                 Accel.X = -1 * (Accel.X - 128);
  1018.             Accel.Y = (OldAccel >>> 15) & 255;
  1019.             if ( Accel.Y > 127 )
  1020.                 Accel.Y = -1 * (Accel.Y - 128);
  1021.             Accel.Z = (OldAccel >>> 7) & 255;
  1022.             if ( Accel.Z > 127 )
  1023.                 Accel.Z = -1 * (Accel.Z - 128);
  1024.             Accel *= 20;
  1025.             
  1026.             OldbRun = ( (OldAccel & 64) != 0 );
  1027.             OldbDoubleJump = ( (OldAccel & 32) != 0 );
  1028.             NewbPressedJump = ( (OldAccel & 16) != 0 );
  1029.             if ( NewbPressedJump )
  1030.                 bJumpStatus = NewbJumpStatus;
  1031.             switch (OldAccel & 7)
  1032.             {
  1033.                 case 0:
  1034.                     OldDoubleClickMove = DCLICK_None;
  1035.                     break;
  1036.                 case 1:
  1037.                     OldDoubleClickMove = DCLICK_Left;
  1038.                     break;
  1039.                 case 2:
  1040.                     OldDoubleClickMove = DCLICK_Right;
  1041.                     break;
  1042.                 case 3:
  1043.                     OldDoubleClickMove = DCLICK_Forward;
  1044.                     break;
  1045.                 case 4:
  1046.                     OldDoubleClickMove = DCLICK_Back;
  1047.                     break;
  1048.             }
  1049.             //log("Recovered move from "$OldTimeStamp$" acceleration "$Accel$" from "$OldAccel);
  1050.             OldTimeStamp = FMin(OldTimeStamp, CurrentTimeStamp + MaxResponseTime);
  1051.             MoveAutonomous(OldTimeStamp - CurrentTimeStamp, OldbRun, (bDuck == 1), NewbPressedJump, OldbDoubleJump, OldDoubleClickMove, Accel, rot(0,0,0));
  1052.             CurrentTimeStamp = OldTimeStamp;
  1053.         }
  1054.     }        
  1055.  
  1056.     // View components
  1057.     ViewPitch = View/32768;
  1058.     ViewYaw = 2 * (View - 32768 * ViewPitch);
  1059.     ViewPitch *= 2;
  1060.     // Make acceleration.
  1061.     Accel = InAccel/10;
  1062.  
  1063.     NewbPressedJump = (bJumpStatus != NewbJumpStatus);
  1064.     bJumpStatus = NewbJumpStatus;
  1065.  
  1066.     // Save move parameters.
  1067.     DeltaTime = FMin(MaxResponseTime,TimeStamp - CurrentTimeStamp);
  1068.  
  1069.     if ( ServerTimeStamp > 0 )
  1070.     {
  1071.         // allow 1% error
  1072.         TimeMargin = FMax(0,TimeMargin + DeltaTime - 1.01 * (Level.TimeSeconds - ServerTimeStamp));
  1073.         if ( TimeMargin > MaxTimeMargin )
  1074.         {
  1075.             // player is too far ahead
  1076.             TimeMargin -= DeltaTime;
  1077.             if ( TimeMargin < 0.5 )
  1078.                 MaxTimeMargin = Default.MaxTimeMargin;
  1079.             else
  1080.                 MaxTimeMargin = 0.5;
  1081.             DeltaTime = 0;
  1082.         }
  1083.     }
  1084.  
  1085.     CurrentTimeStamp = TimeStamp;
  1086.     ServerTimeStamp = Level.TimeSeconds;
  1087.     ViewRot.Pitch = ViewPitch;
  1088.     ViewRot.Yaw = ViewYaw;
  1089.     ViewRot.Roll = 0;
  1090.     SetRotation(ViewRot);
  1091.  
  1092.     if ( Pawn != None )
  1093.     {
  1094.         Rot.Roll = 256 * ClientRoll;
  1095.         Rot.Yaw = ViewYaw;
  1096.         if ( (Pawn.Physics == PHYS_Swimming) || (Pawn.Physics == PHYS_Flying) )
  1097.             maxPitch = 2;
  1098.         else
  1099.             maxPitch = 0;
  1100.         If ( (ViewPitch > maxPitch * RotationRate.Pitch) && (ViewPitch < 65536 - maxPitch * RotationRate.Pitch) )
  1101.         {
  1102.             If (ViewPitch < 32768) 
  1103.                 Rot.Pitch = maxPitch * RotationRate.Pitch;
  1104.             else
  1105.                 Rot.Pitch = 65536 - maxPitch * RotationRate.Pitch;
  1106.         }
  1107.         else
  1108.             Rot.Pitch = ViewPitch;
  1109.         DeltaRot = (Rotation - Rot);
  1110.         Pawn.SetRotation(Rot);
  1111.     }
  1112.  
  1113.     // Perform actual movement
  1114.     if ( (Level.Pauser == None) && (DeltaTime > 0) )
  1115.         MoveAutonomous(DeltaTime, NewbRun, NewbDuck, NewbPressedJump, NewbDoubleJump, DoubleClickMove, Accel, DeltaRot);
  1116.  
  1117.     // Accumulate movement error.
  1118.     if ( Level.TimeSeconds - LastUpdateTime > 0.3 )
  1119.         ClientErr = 10000;
  1120.     else if ( Level.TimeSeconds - LastUpdateTime > 180.0/Player.CurrentNetSpeed )
  1121.     {
  1122.         if ( Pawn == None )
  1123.             LocDiff = Location - ClientLoc;
  1124.         else
  1125.             LocDiff = Pawn.Location - ClientLoc;
  1126.         ClientErr = LocDiff Dot LocDiff;
  1127.     }
  1128.  
  1129.     // If client has accumulated a noticeable positional error, correct him.
  1130.     if ( ClientErr > 3 )
  1131.     {
  1132.         if ( Pawn == None )
  1133.         {
  1134.             ClientPhysics = Physics;
  1135.             ClientLoc = Location;
  1136.             ClientVel = Velocity;
  1137.         }
  1138.         else
  1139.         {
  1140.             ClientPhysics = Pawn.Physics;
  1141.             ClientVel = Pawn.Velocity;
  1142.             ClientBase = Pawn.Base;
  1143.             if ( Mover(Pawn.Base) != None )
  1144.                 ClientLoc = Pawn.Location - Pawn.Base.Location;
  1145.             else
  1146.                 ClientLoc = Pawn.Location;
  1147.             ClientFloor = Pawn.Floor;
  1148.         }
  1149.         //    log(Level.TimeSeconds$" Client Error at "$TimeStamp$" is "$ClientErr$" with acceleration "$Accel$" LocDiff "$LocDiff$" Physics "$Pawn.Physics);
  1150.         LastUpdateTime = Level.TimeSeconds;
  1151.  
  1152.         if ( (Pawn == None) || (Pawn.Physics != PHYS_Spider) )
  1153.         {
  1154.             if ( ClientVel == vect(0,0,0) )
  1155.             {
  1156.                     ShortClientAdjustPosition
  1157.                     (
  1158.                         TimeStamp, 
  1159.                         GetStateName(), 
  1160.                         ClientPhysics, 
  1161.                         ClientLoc.X, 
  1162.                         ClientLoc.Y, 
  1163.                         ClientLoc.Z, 
  1164.                         ClientBase
  1165.                     );
  1166.             }
  1167.             else
  1168.                 ClientAdjustPosition
  1169.                 (
  1170.                     TimeStamp, 
  1171.                     GetStateName(), 
  1172.                     ClientPhysics, 
  1173.                     ClientLoc.X, 
  1174.                     ClientLoc.Y, 
  1175.                     ClientLoc.Z, 
  1176.                     ClientVel.X, 
  1177.                     ClientVel.Y, 
  1178.                     ClientVel.Z,
  1179.                     ClientBase
  1180.                 );
  1181.         }
  1182.         else
  1183.             LongClientAdjustPosition
  1184.             (
  1185.                 TimeStamp, 
  1186.                 GetStateName(), 
  1187.                 ClientPhysics, 
  1188.                 ClientLoc.X, 
  1189.                 ClientLoc.Y, 
  1190.                 ClientLoc.Z, 
  1191.                 ClientVel.X, 
  1192.                 ClientVel.Y, 
  1193.                 ClientVel.Z,
  1194.                 ClientBase,
  1195.                 ClientFloor.X,
  1196.                 ClientFloor.Y,
  1197.                 ClientFloor.Z
  1198.             );
  1199.     }
  1200.     //log("Server moved stamp "$TimeStamp$" location "$Pawn.Location$" Acceleration "$Pawn.Acceleration$" Velocity "$Pawn.Velocity);
  1201. }    
  1202.  
  1203. // Only executed on server
  1204. function ServerDrive(float InForward, float InStrafe, float InUp, bool InJump)
  1205. {
  1206.     ProcessDrive(InForward, InStrafe, InUp, InJump);
  1207. }
  1208.  
  1209. function ProcessDrive(float InForward, float InStrafe, float InUp, bool InJump)
  1210. {
  1211.     Log("ProcessDrive Not Valid Outside State PlayerDriving");
  1212. }
  1213.  
  1214. function ProcessMove ( float DeltaTime, vector newAccel, eDoubleClickDir DoubleClickMove, rotator DeltaRot)
  1215. {
  1216.     if ( Pawn != None )
  1217.         Pawn.Acceleration = newAccel;
  1218. }
  1219.  
  1220. final function MoveAutonomous
  1221. (    
  1222.     float DeltaTime,     
  1223.     bool NewbRun,
  1224.     bool NewbDuck,
  1225.     bool NewbPressedJump, 
  1226.     bool NewbDoubleJump,
  1227.     eDoubleClickDir DoubleClickMove, 
  1228.     vector newAccel, 
  1229.     rotator DeltaRot
  1230. )
  1231. {
  1232.     if ( NewbRun )
  1233.         bRun = 1;
  1234.     else
  1235.         bRun = 0;
  1236.  
  1237.     if ( NewbDuck )
  1238.         bDuck = 1;
  1239.     else
  1240.         bDuck = 0;
  1241.     bPressedJump = NewbPressedJump;
  1242.     bDoubleJump = NewbDoubleJump;
  1243.     HandleWalking();
  1244.     ProcessMove(DeltaTime, newAccel, DoubleClickMove, DeltaRot);
  1245.     if ( Pawn != None )    
  1246.         Pawn.AutonomousPhysics(DeltaTime);
  1247.     else
  1248.         AutonomousPhysics(DeltaTime);
  1249.     bDoubleJump = false;
  1250.     //log("Role "$Role$" moveauto time "$100 * DeltaTime$" ("$Level.TimeDilation$")");
  1251. }
  1252.  
  1253. /* VeryShortClientAdjustPosition
  1254. bandwidth saving version, when velocity is zeroed, and pawn is walking
  1255. */
  1256. function VeryShortClientAdjustPosition
  1257. (
  1258.     float TimeStamp, 
  1259.     float NewLocX, 
  1260.     float NewLocY, 
  1261.     float NewLocZ, 
  1262.     Actor NewBase
  1263. )
  1264. {
  1265.     local vector Floor;
  1266.  
  1267.     if ( Pawn != None )
  1268.         Floor = Pawn.Floor;
  1269.     LongClientAdjustPosition(TimeStamp,'PlayerWalking',PHYS_Walking,NewLocX,NewLocY,NewLocZ,0,0,0,NewBase,Floor.X,Floor.Y,Floor.Z);
  1270. }
  1271.  
  1272. /* ShortClientAdjustPosition
  1273. bandwidth saving version, when velocity is zeroed
  1274. */
  1275. function ShortClientAdjustPosition
  1276. (
  1277.     float TimeStamp, 
  1278.     name newState, 
  1279.     EPhysics newPhysics,
  1280.     float NewLocX, 
  1281.     float NewLocY, 
  1282.     float NewLocZ, 
  1283.     Actor NewBase
  1284. )
  1285. {
  1286.     local vector Floor;
  1287.  
  1288.     if ( Pawn != None )
  1289.         Floor = Pawn.Floor;
  1290.     LongClientAdjustPosition(TimeStamp,newState,newPhysics,NewLocX,NewLocY,NewLocZ,0,0,0,NewBase,Floor.X,Floor.Y,Floor.Z);
  1291. }
  1292.  
  1293. /* ClientAdjustPosition
  1294. - pass newloc and newvel in components so they don't get rounded
  1295. */
  1296. function ClientAdjustPosition
  1297. (
  1298.     float TimeStamp, 
  1299.     name newState, 
  1300.     EPhysics newPhysics,
  1301.     float NewLocX, 
  1302.     float NewLocY, 
  1303.     float NewLocZ, 
  1304.     float NewVelX, 
  1305.     float NewVelY, 
  1306.     float NewVelZ,
  1307.     Actor NewBase
  1308. )
  1309. {
  1310.     local vector Floor;
  1311.  
  1312.     if ( Pawn != None )
  1313.         Floor = Pawn.Floor;
  1314.     LongClientAdjustPosition(TimeStamp,newState,newPhysics,NewLocX,NewLocY,NewLocZ,NewVelX,NewVelY,NewVelZ,NewBase,Floor.X,Floor.Y,Floor.Z);
  1315. }
  1316.  
  1317. /* LongClientAdjustPosition 
  1318. long version, when care about pawn's floor normal
  1319. */
  1320. function LongClientAdjustPosition
  1321. (
  1322.     float TimeStamp, 
  1323.     name newState, 
  1324.     EPhysics newPhysics,
  1325.     float NewLocX, 
  1326.     float NewLocY, 
  1327.     float NewLocZ, 
  1328.     float NewVelX, 
  1329.     float NewVelY, 
  1330.     float NewVelZ,
  1331.     Actor NewBase,
  1332.     float NewFloorX,
  1333.     float NewFloorY,
  1334.     float NewFloorZ
  1335. )
  1336. {
  1337.     local vector NewLocation, NewVelocity, NewFloor;
  1338.     local Actor MoveActor;
  1339.     local SavedMove CurrentMove;
  1340.  
  1341.     // update ping
  1342.     if ( (PlayerReplicationInfo != None) && !bDemoOwner )
  1343.     {
  1344.         if ( ExactPing < 0.006 )
  1345.             ExactPing = Level.TimeSeconds - TimeStamp;
  1346.         else
  1347.             ExactPing = 0.99 * ExactPing + 0.008 * (Level.TimeSeconds - TimeStamp); // placebo effect
  1348.         PlayerReplicationInfo.Ping = 1000 * ExactPing;
  1349.  
  1350.         if ( Level.TimeSeconds - LastPingUpdate > 4 )
  1351.         {
  1352.             if ( bDynamicNetSpeed && (OldPing > DynamicPingThreshold * 0.001) && (ExactPing > DynamicPingThreshold * 0.001) )
  1353.             {
  1354.                 if ( Player.CurrentNetSpeed > 5000 )
  1355.                     SetNetSpeed(5000);
  1356.                 else if ( Level.MoveRepSize < 80 )
  1357.                     Level.MoveRepSize += 8;
  1358.                 else if ( Player.CurrentNetSpeed > 4000 )
  1359.                     SetNetSpeed(4000);
  1360.                 OldPing = 0;
  1361.             }
  1362.             else
  1363.                 OldPing = ExactPing;
  1364.             LastPingUpdate = Level.TimeSeconds;
  1365.             ServerUpdatePing(1000 * ExactPing);
  1366.         }
  1367.     }
  1368.     if ( Pawn != None )
  1369.     {
  1370.         if ( Pawn.bTearOff )
  1371.         {
  1372.             Pawn = None;
  1373.             if ( !IsInState('GameEnded') && !IsInState('Dead') )
  1374.             {
  1375.             GotoState('Dead');
  1376.             }
  1377.             return;
  1378.         }
  1379.         MoveActor = Pawn;
  1380.         if ( (ViewTarget != Pawn)
  1381.             && ((ViewTarget == self) || ((Pawn(ViewTarget) != None) && (Pawn(ViewTarget).Health <= 0))) )
  1382.         {
  1383.             bBehindView = false;
  1384.             SetViewTarget(Pawn);
  1385.         }
  1386.     }
  1387.     else 
  1388.     {
  1389.         MoveActor = self;
  1390.             if( GetStateName() != newstate )
  1391.         {
  1392.             if ( NewState == 'GameEnded' )
  1393.                 GotoState(NewState);
  1394.             else if ( IsInState('Dead') )
  1395.             {
  1396.                 if ( (NewState != 'PlayerWalking') && (NewState != 'PlayerSwimming') )
  1397.                 {
  1398.                     GotoState(NewState);
  1399.                 }
  1400.                 return;
  1401.             }
  1402.             else if ( NewState == 'Dead' )
  1403.                 GotoState(NewState);
  1404.         }
  1405.     }
  1406.     if ( CurrentTimeStamp >= TimeStamp )
  1407.         return;
  1408.     CurrentTimeStamp = TimeStamp;
  1409.  
  1410.     NewLocation.X = NewLocX;
  1411.     NewLocation.Y = NewLocY;
  1412.     NewLocation.Z = NewLocZ;
  1413.     NewVelocity.X = NewVelX;
  1414.     NewVelocity.Y = NewVelY;
  1415.     NewVelocity.Z = NewVelZ;
  1416.  
  1417.     // skip update if no error
  1418.     CurrentMove = SavedMoves;
  1419.     while ( CurrentMove != None )
  1420.     {
  1421.         if ( CurrentMove.TimeStamp <= CurrentTimeStamp )
  1422.         {
  1423.             SavedMoves = CurrentMove.NextMove;
  1424.             CurrentMove.NextMove = FreeMoves;
  1425.             FreeMoves = CurrentMove;
  1426.             if ( CurrentMove.TimeStamp == CurrentTimeStamp )
  1427.             { 
  1428.                 FreeMoves.Clear();
  1429.                 if ( (VSize(CurrentMove.SavedLocation - NewLocation) < 3)
  1430.                     && (VSize(CurrentMove.SavedVelocity - NewVelocity) < 3)
  1431.                     && (GetStateName() == NewState)
  1432.                     && ((MoveActor.Physics != PHYS_Flying) || !IsInState('PlayerWalking')) )
  1433.                 {
  1434.                     return;
  1435.                 }
  1436.                 CurrentMove = None;
  1437.             }
  1438.             else
  1439.             {
  1440.                 FreeMoves.Clear();
  1441.                 CurrentMove = SavedMoves;
  1442.             }
  1443.         }
  1444.         else
  1445.             CurrentMove = None;
  1446.     }
  1447.  
  1448.     NewFloor.X = NewFloorX;
  1449.     NewFloor.Y = NewFloorY;
  1450.     NewFloor.Z = NewFloorZ;
  1451.     MoveActor.SetBase(NewBase, NewFloor);
  1452.     if ( Mover(NewBase) != None )
  1453.         NewLocation += NewBase.Location;
  1454.  
  1455.     if ( !bDemoOwner )
  1456.     {
  1457.     //log("Client "$Role$" adjust "$self$" stamp "$TimeStamp$" location "$MoveActor.Location);
  1458.     MoveActor.bCanTeleport = false;
  1459.     if ( !MoveActor.SetLocation(NewLocation) && (Pawn(MoveActor) != None)
  1460.         && (MoveActor.CollisionHeight > Pawn(MoveActor).CrouchHeight)
  1461.         && !Pawn(MoveActor).bIsCrouched
  1462.         && (newPhysics == PHYS_Walking)
  1463.         && (MoveActor.Physics != PHYS_Karma) && (MoveActor.Physics != PHYS_KarmaRagDoll) )
  1464.     {
  1465.         MoveActor.SetPhysics(newPhysics);
  1466.         Pawn(MoveActor).ForceCrouch();
  1467.     MoveActor.SetLocation(NewLocation);
  1468.     }
  1469.     MoveActor.bCanTeleport = true;
  1470.     }
  1471.     // Hack. Don't let network change physics mode of karma stuff on the client.
  1472.     if( MoveActor.Physics != PHYS_Karma && MoveActor.Physics != PHYS_KarmaRagDoll &&
  1473.         newPhysics != PHYS_Karma && newPhysics != PHYS_KarmaRagDoll )
  1474.     {
  1475.         MoveActor.SetPhysics(newPhysics);
  1476.     }
  1477.  
  1478.     MoveActor.Velocity = NewVelocity;
  1479.  
  1480.     if( GetStateName() != newstate )
  1481.         GotoState(newstate);
  1482.  
  1483.     bUpdatePosition = true;
  1484. }
  1485.  
  1486. function ServerUpdatePing(int NewPing)
  1487. {
  1488.     PlayerReplicationInfo.Ping = NewPing;
  1489.     PlayerReplicationInfo.bReceivedPing = true;
  1490. }
  1491.  
  1492. function ClientUpdatePosition()
  1493. {
  1494.     local SavedMove CurrentMove;
  1495.     local int realbRun, realbDuck;
  1496.     local bool bRealJump;
  1497.  
  1498.     // Dont do any network position updates on things running PHYS_Karma
  1499.     if( Pawn != None && (Pawn.Physics == PHYS_Karma || Pawn.Physics == PHYS_KarmaRagDoll) )
  1500.         return;
  1501.  
  1502.     bUpdatePosition = false;
  1503.     realbRun= bRun;
  1504.     realbDuck = bDuck;
  1505.     bRealJump = bPressedJump;
  1506.     CurrentMove = SavedMoves;
  1507.     bUpdating = true;
  1508.     while ( CurrentMove != None )
  1509.     {
  1510.         if ( CurrentMove.TimeStamp <= CurrentTimeStamp )
  1511.         {
  1512.             SavedMoves = CurrentMove.NextMove;
  1513.             CurrentMove.NextMove = FreeMoves;
  1514.             FreeMoves = CurrentMove;
  1515.             FreeMoves.Clear();
  1516.             CurrentMove = SavedMoves;
  1517.         }
  1518.         else
  1519.         {
  1520.             MoveAutonomous(CurrentMove.Delta, CurrentMove.bRun, CurrentMove.bDuck, CurrentMove.bPressedJump, CurrentMove.bDoubleJump, CurrentMove.DoubleClickMove, CurrentMove.Acceleration, rot(0,0,0));
  1521.             CurrentMove = CurrentMove.NextMove;
  1522.         }
  1523.     }
  1524.     if ( PendingMove != None )
  1525.         MoveAutonomous(PendingMove.Delta, PendingMove.bRun, PendingMove.bDuck, PendingMove.bPressedJump, PendingMove.bDoubleJump, PendingMove.DoubleClickMove, PendingMove.Acceleration, rot(0,0,0));
  1526.     
  1527.     //log("Client updated position to "$Pawn.Location);
  1528.     bUpdating = false;
  1529.     bDuck = realbDuck;
  1530.     bRun = realbRun;
  1531.     bPressedJump = bRealJump;
  1532. }
  1533.  
  1534. final function SavedMove GetFreeMove()
  1535. {
  1536.     local SavedMove s, first;
  1537.     local int i;
  1538.  
  1539.     if ( FreeMoves == None )
  1540.     {
  1541.         // don't allow more than 100 saved moves
  1542.         For ( s=SavedMoves; s!=None; s=s.NextMove )
  1543.         {
  1544.             i++;
  1545.             if ( i > 100 )
  1546.             {
  1547.                 first = SavedMoves;
  1548.                 SavedMoves = SavedMoves.NextMove;
  1549.                 first.Clear();
  1550.                 first.NextMove = None;
  1551.                 // clear out all the moves
  1552.                 While ( SavedMoves != None )
  1553.                 {
  1554.                     s = SavedMoves;
  1555.                     SavedMoves = SavedMoves.NextMove;
  1556.                     s.Clear();
  1557.                     s.NextMove = FreeMoves;
  1558.                     FreeMoves = s;
  1559.                 }
  1560.                 return first;
  1561.             }
  1562.         }
  1563.         return Spawn(class'SavedMove');
  1564.     }
  1565.     else
  1566.     {
  1567.         s = FreeMoves;
  1568.         FreeMoves = FreeMoves.NextMove;
  1569.         s.NextMove = None;
  1570.         return s;
  1571.     }    
  1572. }
  1573.  
  1574. function int CompressAccel(int C)
  1575. {
  1576.     if ( C >= 0 )
  1577.         C = Min(C, 127);
  1578.     else
  1579.         C = Min(abs(C), 127) + 128;
  1580.     return C;
  1581. }
  1582.  
  1583. /* 
  1584. ========================================================================
  1585. Here's how player movement prediction, replication and correction works in network games:
  1586.  
  1587. Every tick, the PlayerTick() function is called.  It calls the PlayerMove() function (which is implemented 
  1588. in various states).  PlayerMove() figures out the acceleration and rotation, and then calls ProcessMove() 
  1589. (for single player or listen servers), or ReplicateMove() (if its a network client).
  1590.  
  1591. ReplicateMove() saves the move (in the PendingMove list), calls ProcessMove(), and then replicates the move 
  1592. to the server by calling the replicated function ServerMove() - passing the movement parameters, the client's 
  1593. resultant position, and a timestamp.
  1594.  
  1595. ServerMove() is executed on the server.  It decodes the movement parameters and causes the appropriate movement 
  1596. to occur.  It then looks at the resulting position and if enough time has passed since the last response, or the 
  1597. position error is significant enough, the server calls ClientAdjustPosition(), a replicated function.
  1598.  
  1599. ClientAdjustPosition() is executed on the client.  The client sets its position to the servers version of position, 
  1600. and sets the bUpdatePosition flag to true.  
  1601.  
  1602. When PlayerTick() is called on the client again, if bUpdatePosition is true, the client will call 
  1603. ClientUpdatePosition() before calling PlayerMove().  ClientUpdatePosition() replays all the moves in the pending 
  1604. move list which occured after the timestamp of the move the server was adjusting.
  1605. */
  1606.  
  1607. //
  1608. // Replicate this client's desired movement to the server.
  1609. //
  1610. function ReplicateMove
  1611. (
  1612.     float DeltaTime, 
  1613.     vector NewAccel, 
  1614.     eDoubleClickDir DoubleClickMove, 
  1615.     rotator DeltaRot
  1616. )
  1617. {
  1618.     local SavedMove NewMove, OldMove, LastMove;
  1619.     local byte ClientRoll;
  1620.     local float OldTimeDelta, NetMoveDelta;
  1621.     local int OldAccel;
  1622.     local vector BuildAccel, AccelNorm, MoveLoc;
  1623.  
  1624.     // find the most recent move, and the most recent interesting move
  1625.     if ( SavedMoves != None )
  1626.     {
  1627.         LastMove = SavedMoves;
  1628.         AccelNorm = Normal(NewAccel);
  1629.         while ( LastMove.NextMove != None )
  1630.         {
  1631.             // find most recent interesting move to send redundantly
  1632.             if ( LastMove.bPressedJump || LastMove.bDoubleJump || ((LastMove.DoubleClickMove != DCLICK_NONE) && (LastMove.DoubleClickMove < 5))
  1633.                 || ((LastMove.Acceleration != NewAccel) && ((normal(LastMove.Acceleration) Dot AccelNorm) < 0.95)) )
  1634.                 OldMove = LastMove;
  1635.             LastMove = LastMove.NextMove;
  1636.         }
  1637.         if ( LastMove.bPressedJump || LastMove.bDoubleJump || ((LastMove.DoubleClickMove != DCLICK_NONE) && (LastMove.DoubleClickMove < 5))
  1638.             || ((LastMove.Acceleration != NewAccel) && ((normal(LastMove.Acceleration) Dot AccelNorm) < 0.95)) )
  1639.             OldMove = LastMove;
  1640.     }
  1641.     // Get a SavedMove actor to store the movement in.
  1642.     if ( PendingMove != None )
  1643.         PendingMove.SetMoveFor(self, DeltaTime, NewAccel, DoubleClickMove);
  1644.  
  1645.     NewMove = GetFreeMove();
  1646.     if ( NewMove == None )
  1647.         return;
  1648.     NewMove.SetMoveFor(self, DeltaTime, NewAccel, DoubleClickMove);
  1649.     
  1650.     // Simulate the movement locally.
  1651.     bDoubleJump = false;
  1652.     ProcessMove(NewMove.Delta, NewMove.Acceleration, NewMove.DoubleClickMove, DeltaRot);
  1653.     
  1654.     if ( Pawn != None )
  1655.         Pawn.AutonomousPhysics(NewMove.Delta);
  1656.     else
  1657.         AutonomousPhysics(DeltaTime);
  1658.  
  1659.     if ( PendingMove == None )
  1660.         PendingMove = NewMove;
  1661.     else
  1662.     {
  1663.         NewMove.NextMove = FreeMoves;
  1664.         FreeMoves = NewMove;
  1665.         FreeMoves.Clear();
  1666.         NewMove = PendingMove;
  1667.     }
  1668.     NewMove.PostUpdate(self);
  1669.     NetMoveDelta = FMax(80.0/Player.CurrentNetSpeed, 0.015);
  1670.     
  1671.     // Decide whether to hold off on move
  1672.     // send if double click move, jump, or fire unless really too soon, or if newmove.delta big enough
  1673.     if ( !Level.bCapFramerate && !PendingMove.bPressedJump && !PendingMove.bDoubleJump 
  1674.         && ((PendingMove.DoubleClickMove == DCLICK_None) || (PendingMove.DoubleClickMove == DCLICK_Active))
  1675.         && ((PendingMove.Acceleration == NewAccel) || ((Normal(NewAccel) Dot Normal(PendingMove.Acceleration)) > 0.95)) 
  1676.         && (PendingMove.Delta < NetMoveDelta - ClientUpdateTime) )
  1677.     {
  1678.         return;
  1679.     }
  1680.     else
  1681.     {
  1682.         ClientUpdateTime = PendingMove.Delta - NetMoveDelta;
  1683.         if ( SavedMoves == None )
  1684.             SavedMoves = PendingMove;
  1685.         else
  1686.             LastMove.NextMove = PendingMove;
  1687.         PendingMove = None;
  1688.     }
  1689.  
  1690.     // check if need to redundantly send previous move
  1691.     if ( OldMove != None )
  1692.     {
  1693.         // old move important to replicate redundantly
  1694.         OldTimeDelta = FMin(255, (Level.TimeSeconds - OldMove.TimeStamp) * 500);
  1695.         BuildAccel = 0.05 * OldMove.Acceleration + vect(0.5, 0.5, 0.5);
  1696.         OldAccel = (CompressAccel(BuildAccel.X) << 23) 
  1697.                     + (CompressAccel(BuildAccel.Y) << 15) 
  1698.                     + (CompressAccel(BuildAccel.Z) << 7);
  1699.         if ( OldMove.bRun )
  1700.             OldAccel += 64;
  1701.         if ( OldMove.bDoubleJump )
  1702.             OldAccel += 32;
  1703.         if ( OldMove.bPressedJump )
  1704.             OldAccel += 16;
  1705.         OldAccel += OldMove.DoubleClickMove;
  1706.     }
  1707.  
  1708.     // Send to the server
  1709.     ClientRoll = (Rotation.Roll >> 8) & 255;
  1710.     if ( NewMove.bPressedJump )
  1711.         bJumpStatus = !bJumpStatus;
  1712.  
  1713.     if ( Pawn == None )
  1714.         MoveLoc = Location;
  1715.     else
  1716.         MoveLoc = Pawn.Location;
  1717.  
  1718.     if ( IsInState('PlayerRocketing') )
  1719.         RocketServerMove
  1720.         (
  1721.             NewMove.TimeStamp, 
  1722.             NewMove.Acceleration * 10,
  1723.             MoveLoc,
  1724.             ClientRoll, 
  1725.             (32767 & (Rotation.Pitch/2)) * 32768 + (32767 & (Rotation.Yaw/2))
  1726.         );
  1727.     else if ( (NewMove.Acceleration == vect(0,0,0)) && (NewMove.DoubleClickMove == DCLICK_None) && !NewMove.bDoubleJump )
  1728.         ShortServerMove
  1729.         (
  1730.             NewMove.TimeStamp, 
  1731.             MoveLoc, 
  1732.             NewMove.bRun,
  1733.             NewMove.bDuck,
  1734.             bJumpStatus, 
  1735.             ClientRoll,
  1736.             (32767 & (Rotation.Pitch/2)) * 32768 + (32767 & (Rotation.Yaw/2))
  1737.         );
  1738.     else
  1739.         ServerMove
  1740.         (
  1741.             NewMove.TimeStamp, 
  1742.             NewMove.Acceleration * 10, 
  1743.             MoveLoc, 
  1744.             NewMove.bRun,
  1745.             NewMove.bDuck,
  1746.             bJumpStatus, 
  1747.             NewMove.bDoubleJump,
  1748.             NewMove.DoubleClickMove, 
  1749.             ClientRoll,
  1750.             (32767 & (Rotation.Pitch/2)) * 32768 + (32767 & (Rotation.Yaw/2)),
  1751.             OldTimeDelta,
  1752.             OldAccel 
  1753.         );
  1754. }
  1755.  
  1756. function HandleWalking()
  1757. {
  1758.     if ( Pawn != None )
  1759.         Pawn.SetWalking( (bRun != 0) && !Region.Zone.IsA('WarpZoneInfo') ); 
  1760. }
  1761.  
  1762. function ServerRestartGame()
  1763. {
  1764. }
  1765.  
  1766. function SetFOVAngle(float newFOV)
  1767. {
  1768.     FOVAngle = newFOV;
  1769. }
  1770.      
  1771. function ClientFlash( float scale, vector fog )
  1772. {
  1773.     FlashScale = scale * vect(1,1,1);
  1774.     flashfog = 0.001 * fog;
  1775. }
  1776.    
  1777. function ClientAdjustGlow( float scale, vector fog )
  1778. {
  1779.     ConstantGlowScale += scale;
  1780.     ConstantGlowFog += 0.001 * fog;
  1781. }
  1782.  
  1783. /* ClientShake()
  1784. Function called on client to shake view.
  1785. Only ShakeView() should call ClientShake()
  1786. */
  1787. private function ClientShake(vector ShakeRoll, vector OffsetMag, vector ShakeRate, float OffsetTime)
  1788. {
  1789.     if ( (MaxShakeRoll < ShakeRoll.X) || (ShakeRollTime < 0.01 * ShakeRoll.Y) )
  1790. {
  1791.         MaxShakeRoll = ShakeRoll.X;
  1792.         ShakeRollTime = 0.01 * ShakeRoll.Y;    
  1793.         ShakeRollRate = 0.01 * ShakeRoll.Z;
  1794. }
  1795.     if ( VSize(OffsetMag) > VSize(MaxShakeOffset) )
  1796.     {
  1797.         ShakeOffsetTime = OffsetTime * vect(1,1,1);
  1798.         MaxShakeOffset = OffsetMag;
  1799.         ShakeOffsetRate = ShakeRate;
  1800.     }
  1801.     }
  1802.  
  1803. /* ShakeView()
  1804. Call this function to shake the player's view
  1805. shaketime = how long to roll view
  1806. RollMag = how far to roll view as it shakes
  1807. OffsetMag = max view offset
  1808. RollRate = how fast to roll view
  1809. OffsetRate = how fast to offset view
  1810. OffsetTime = how long to offset view (number of shakes)
  1811. */
  1812. function ShakeView( float shaketime, float RollMag, vector OffsetMag, float RollRate, vector OffsetRate, float OffsetTime)
  1813. {
  1814.     local vector ShakeRoll;
  1815.  
  1816.     ShakeRoll.X = RollMag;
  1817.     ShakeRoll.Y = 100 * shaketime;
  1818.     ShakeRoll.Z = 100 * rollrate;
  1819.     ClientShake(ShakeRoll, OffsetMag, OffsetRate, OffsetTime);
  1820. }
  1821.  
  1822. function damageAttitudeTo(pawn Other, float Damage)
  1823. {
  1824.     if ( (Other != None) && (Other != Pawn) && (Damage > 0) )
  1825.         Enemy = Other;
  1826. }
  1827.  
  1828. function Typing( bool bTyping )
  1829. {
  1830.     bIsTyping = bTyping;
  1831.      Pawn.bIsTyping = bIsTyping;
  1832.     if ( bTyping && (Pawn != None) && !Pawn.bTearOff )
  1833.         Pawn.ChangeAnimation();
  1834.  
  1835. }
  1836.  
  1837. //*************************************************************************************
  1838. // Normal gameplay execs
  1839. // Type the name of the exec function at the console to execute it
  1840.  
  1841. exec function Jump( optional float F )
  1842. {
  1843.     if ( Level.Pauser == PlayerReplicationInfo )
  1844.         SetPause(False);
  1845.     else
  1846.         bPressedJump = true;
  1847. }
  1848.  
  1849. // Send a voice message of a certain type to a certain player.
  1850. exec function Speech( name Type, int Index, string Callsign )
  1851. {
  1852.     if(PlayerReplicationInfo.VoiceType != None)
  1853.         PlayerReplicationInfo.VoiceType.static.PlayerSpeech( Type, Index, Callsign, Self );
  1854. }
  1855.  
  1856. exec function RestartLevel()
  1857. {
  1858.     if( Level.Netmode==NM_Standalone )
  1859.         ClientTravel( "?restart", TRAVEL_Relative, false );
  1860. }
  1861.  
  1862. exec function LocalTravel( string URL )
  1863. {
  1864.     if( Level.Netmode==NM_Standalone )
  1865.         ClientTravel( URL, TRAVEL_Relative, true );
  1866. }
  1867.  
  1868. // ------------------------------------------------------------------------
  1869. // Loading and saving
  1870.  
  1871. /* QuickSave()
  1872. Save game to slot 9
  1873. */
  1874. exec function QuickSave()
  1875. {
  1876.     if ( (Pawn.Health > 0) 
  1877.         && (Level.NetMode == NM_Standalone) )
  1878.     {
  1879.         ClientMessage(QuickSaveString);
  1880.         ConsoleCommand("SaveGame 9");
  1881.     }
  1882. }
  1883.  
  1884. /* QuickLoad()
  1885. Load game from slot 9
  1886. */
  1887. exec function QuickLoad()
  1888. {
  1889.     if ( Level.NetMode == NM_Standalone )
  1890.         ClientTravel( "?load=9", TRAVEL_Absolute, false);
  1891. }
  1892.  
  1893. /* SetPause()
  1894.  Try to pause game; returns success indicator.
  1895.  Replicated to server in network games.
  1896.  */
  1897. function bool SetPause( BOOL bPause )
  1898. {
  1899.     bFire = 0;
  1900.     bAltFire = 0;
  1901.     return Level.Game.SetPause(bPause, self);
  1902. }
  1903.  
  1904. /* Pause()
  1905. Command to try to pause the game.
  1906. */
  1907. exec function Pause()
  1908. {
  1909.     // Pause if not already
  1910.     if(Level.Pauser == None)
  1911.         SetPause(true);
  1912.     else
  1913.         SetPause(false);
  1914. }
  1915.  
  1916. exec function ShowMenu()
  1917. {
  1918.     // Pause if not already
  1919.     if(Level.Pauser == None && Level.NetMode == NM_StandAlone)
  1920.         SetPause(true);
  1921.  
  1922.     StopForceFeedback();  // jdf - no way to pause feedback
  1923.  
  1924.     // Open menu
  1925.     ClientOpenMenu(MidGameMenuClass); //Added by Demiurge (Runtime) (make menus work)
  1926. }
  1927.  
  1928. // Activate specific inventory item
  1929. exec function ActivateInventoryItem( class InvItem )
  1930. {
  1931.     local Powerups Inv;
  1932.  
  1933.     Inv = Powerups(Pawn.FindInventoryType(InvItem));
  1934.     if ( Inv != None )
  1935.         Inv.Activate();
  1936. }
  1937.  
  1938. // ------------------------------------------------------------------------
  1939. // Weapon changing functions
  1940.  
  1941. /* ThrowWeapon()
  1942. Throw out current weapon, and switch to a new weapon
  1943. */
  1944. exec function ThrowWeapon()
  1945. {
  1946.     if ( (Pawn == None) || (Pawn.Weapon == None) )
  1947.         return;
  1948.  
  1949.     ServerThrowWeapon();
  1950. }
  1951.  
  1952. function ServerThrowWeapon()
  1953. {
  1954.     local Vector TossVel;
  1955.  
  1956.     if (Pawn.CanThrowWeapon())
  1957.     {
  1958.         TossVel = Vector(GetViewRotation());
  1959.         TossVel = TossVel * ((Pawn.Velocity Dot TossVel) + 500) + Vect(0,0,200);
  1960.         Pawn.TossWeapon(TossVel);
  1961.         ClientSwitchToBestWeapon();
  1962.     }
  1963. }
  1964.  
  1965. /* PrevWeapon()
  1966. - switch to previous inventory group weapon
  1967. */
  1968. exec function PrevWeapon()
  1969. {
  1970.     if( Level.Pauser!=None )
  1971.         return;
  1972.     if ( Pawn.Weapon == None )
  1973.     {
  1974.         SwitchToBestWeapon();
  1975.         return;
  1976.     }
  1977.     if ( Pawn.PendingWeapon != None )
  1978.         Pawn.PendingWeapon = Pawn.Inventory.PrevWeapon(None, Pawn.PendingWeapon);
  1979.     else
  1980.         Pawn.PendingWeapon = Pawn.Inventory.PrevWeapon(None, Pawn.Weapon);
  1981.  
  1982.     if ( Pawn.PendingWeapon != None )
  1983.         Pawn.Weapon.PutDown();
  1984. }
  1985.  
  1986. /* NextWeapon()
  1987. - switch to next inventory group weapon
  1988. */
  1989. exec function NextWeapon()
  1990. {
  1991.     if( Level.Pauser!=None )
  1992.         return;
  1993.     if ( Pawn.Weapon == None )
  1994.     {
  1995.         SwitchToBestWeapon();
  1996.         return;
  1997.     }
  1998.     if ( Pawn.PendingWeapon != None )
  1999.         Pawn.PendingWeapon = Pawn.Inventory.NextWeapon(None, Pawn.PendingWeapon);
  2000.     else
  2001.         Pawn.PendingWeapon = Pawn.Inventory.NextWeapon(None, Pawn.Weapon);
  2002.  
  2003.     if ( Pawn.PendingWeapon != None )
  2004.         Pawn.Weapon.PutDown();
  2005. }
  2006.  
  2007. exec function PipedSwitchWeapon(byte F)
  2008. {
  2009.     if ( (Pawn == None) || (Pawn.PendingWeapon != None) )
  2010.         return;
  2011.  
  2012.     SwitchWeapon(F);
  2013. }
  2014.  
  2015. // The player wants to switch to weapon group number F.
  2016. exec function SwitchWeapon (byte F )
  2017. {
  2018.     local weapon newWeapon;
  2019.  
  2020.     if ( (Level.Pauser!=None) || (Pawn == None) || (Pawn.Inventory == None) )
  2021.         return;
  2022.     if ( (Pawn.Weapon != None) && (Pawn.Weapon.Inventory != None) )
  2023.         newWeapon = Pawn.Weapon.Inventory.WeaponChange(F, false);
  2024.     else
  2025.         newWeapon = None;    
  2026.     if ( newWeapon == None )
  2027.         newWeapon = Pawn.Inventory.WeaponChange(F, true);
  2028.  
  2029.     if ( newWeapon == None )
  2030.         return;
  2031.  
  2032.     if ( Pawn.Weapon == None )
  2033.     {
  2034.         Pawn.PendingWeapon = newWeapon;
  2035.         Pawn.ChangedWeapon();
  2036.     }
  2037.     else if ( Pawn.Weapon != newWeapon || Pawn.PendingWeapon != None )
  2038.     {
  2039.         Pawn.PendingWeapon = newWeapon;
  2040.         if ( !Pawn.Weapon.PutDown() )
  2041.             Pawn.PendingWeapon = None;
  2042.     }
  2043. }
  2044.  
  2045. exec function GetWeapon(class<Weapon> NewWeaponClass )
  2046. {
  2047.     local Inventory Inv;
  2048.     local int Count;
  2049.  
  2050.     if ( (Pawn.Inventory == None) || (NewWeaponClass == None)
  2051.         || ((Pawn.Weapon != None) && (Pawn.Weapon.Class == NewWeaponClass)) )
  2052.         return;
  2053.  
  2054.     for ( Inv=Pawn.Inventory; Inv!=None; Inv=Inv.Inventory )
  2055.     {
  2056.         if ( Inv.Class == NewWeaponClass )
  2057.         {
  2058.             Pawn.PendingWeapon = Weapon(Inv);
  2059.             if ( !Pawn.PendingWeapon.HasAmmo() )
  2060.             {
  2061.                 ClientMessage( Pawn.PendingWeapon.ItemName$Pawn.PendingWeapon.MessageNoAmmo );
  2062.                 Pawn.PendingWeapon = None;
  2063.                 return;
  2064.             }
  2065.             Pawn.Weapon.PutDown();
  2066.             return;
  2067.         }
  2068.         Count++;
  2069.         if ( Count > 1000 )
  2070.             return;
  2071.     }
  2072. }
  2073.     
  2074. // The player wants to select previous item
  2075. exec function PrevItem()
  2076. {
  2077.     local Inventory Inv;
  2078.     local Powerups LastItem;
  2079.  
  2080.     if ( (Level.Pauser!=None) || (Pawn == None) )
  2081.         return;
  2082.     if (Pawn.SelectedItem==None) 
  2083.     {
  2084.         Pawn.SelectedItem = Pawn.Inventory.SelectNext();
  2085.         Return;
  2086.     }
  2087.     if (Pawn.SelectedItem.Inventory!=None) 
  2088.         for( Inv=Pawn.SelectedItem.Inventory; Inv!=None; Inv=Inv.Inventory ) 
  2089.         {
  2090.             if (Inv==None) Break;
  2091.             if ( Inv.IsA('Powerups') && Powerups(Inv).bActivatable) LastItem=Powerups(Inv);
  2092.         }
  2093.     for( Inv=Pawn.Inventory; Inv!=Pawn.SelectedItem; Inv=Inv.Inventory ) 
  2094.     {
  2095.         if (Inv==None) Break;
  2096.         if ( Inv.IsA('Powerups') && Powerups(Inv).bActivatable) LastItem=Powerups(Inv);
  2097.     }
  2098.     if (LastItem!=None) 
  2099.         Pawn.SelectedItem = LastItem;
  2100. }
  2101.  
  2102. // The player wants to active selected item
  2103. exec function ActivateItem()
  2104. {
  2105.     if( Level.Pauser!=None )
  2106.         return;
  2107.     if ( (Pawn != None) && (Pawn.SelectedItem!=None) ) 
  2108.         Pawn.SelectedItem.Activate();
  2109. }
  2110.  
  2111. // The player wants to fire.
  2112. exec function Fire( optional float F )
  2113. {
  2114.     if ( Level.Pauser == PlayerReplicationInfo )
  2115.     {
  2116.         SetPause(false);
  2117.         return;
  2118.     }
  2119.     if( bDemoOwner || (Pawn == None) )
  2120.         return;
  2121.     Pawn.Fire(F);
  2122. }
  2123.  
  2124. // The player wants to alternate-fire.
  2125. exec function AltFire( optional float F )
  2126. {
  2127.     if ( Level.Pauser == PlayerReplicationInfo )
  2128.     {
  2129.         SetPause(false);
  2130.         return;
  2131.     }
  2132.     if( bDemoOwner || (Pawn == None) )
  2133.         return;
  2134.     if( Pawn.Weapon!=None )
  2135.         Pawn.Weapon.AltFire(F);
  2136. }
  2137.  
  2138. // The player wants to use something in the level.
  2139. exec function Use()
  2140. {
  2141.     ServerUse();
  2142. }
  2143.  
  2144. function ServerUse()
  2145. {
  2146.     local Actor A;
  2147.  
  2148.     if ( Level.Pauser == PlayerReplicationInfo )
  2149.     {
  2150.         SetPause(false);
  2151.         return;
  2152.     }
  2153.  
  2154.     if (Pawn==None)
  2155.         return;
  2156.     
  2157.     // Send the 'DoUse' event to each actor player is touching.
  2158.     ForEach Pawn.TouchingActors(class'Actor', A)
  2159.     {
  2160.         A.UsedBy(Pawn);
  2161.     }
  2162. }
  2163.  
  2164. exec function Suicide()
  2165. {
  2166.     if ( (Pawn != None) && (Level.TimeSeconds - Pawn.LastStartTime > 1) )
  2167.     Pawn.KilledBy( Pawn );
  2168. }
  2169.  
  2170. exec function Name( coerce string S )
  2171. {
  2172.     SetName(S);
  2173. }
  2174.  
  2175. exec function SetName( coerce string S)
  2176. {
  2177.     ChangeName(S);
  2178.     UpdateURL("Name", S, true);
  2179.     SaveConfig();
  2180. }
  2181.  
  2182. function ChangeName( coerce string S )
  2183. {
  2184.     if ( Len(S) > 20 )
  2185.         S = left(S,20);
  2186.     ReplaceText(S, " ", "_");
  2187.     Level.Game.ChangeName( self, S, true );
  2188. }
  2189.  
  2190. exec function SwitchTeam()
  2191. {
  2192.     if ( (PlayerReplicationInfo.Team == None) || (PlayerReplicationInfo.Team.TeamIndex == 1) )
  2193.         ChangeTeam(0);
  2194.     else
  2195.         ChangeTeam(1);
  2196. }
  2197.  
  2198. exec function ChangeTeam( int N )
  2199. {
  2200.     local TeamInfo OldTeam;
  2201.  
  2202.     OldTeam = PlayerReplicationInfo.Team;
  2203.     Level.Game.ChangeTeam(self, N, true);
  2204.     if ( Level.Game.bTeamGame && (PlayerReplicationInfo.Team != OldTeam) )
  2205.     {
  2206.         if ( Pawn != None )
  2207.         Pawn.Died( None, class'DamageType', Pawn.Location );
  2208. }
  2209. }
  2210.  
  2211.  
  2212. exec function SwitchLevel( string URL )
  2213. {
  2214.     if( Level.NetMode==NM_Standalone || Level.netMode==NM_ListenServer )
  2215.         Level.ServerTravel( URL, false );
  2216. }
  2217.  
  2218. exec function ClearProgressMessages()
  2219. {
  2220.     local int i;
  2221.  
  2222.     for (i=0; i<ArrayCount(ProgressMessage); i++)
  2223.     {
  2224.         ProgressMessage[i] = "";
  2225.         ProgressColor[i] = class'Canvas'.Static.MakeColor(255,255,255);
  2226.     }
  2227. }
  2228.  
  2229. exec event SetProgressMessage( int Index, string S, color C )
  2230. {
  2231.     if ( Index < ArrayCount(ProgressMessage) )
  2232.     {
  2233.         ProgressMessage[Index] = S;
  2234.         ProgressColor[Index] = C;
  2235.     }
  2236. }
  2237.  
  2238. exec event SetProgressTime( float T )
  2239. {
  2240.     ProgressTimeOut = T + Level.TimeSeconds;
  2241. }
  2242.  
  2243. function Restart()
  2244. {
  2245.     Super.Restart();
  2246.     ServerTimeStamp = 0;
  2247.     TimeMargin = 0;
  2248.     EnterStartState();
  2249.     SetViewTarget(Pawn);
  2250.     bBehindView = Pawn.PointOfView();
  2251.     ClientRestart();
  2252. }
  2253.  
  2254. function EnterStartState()
  2255. {
  2256.     local name NewState;
  2257.  
  2258.     if ( Pawn.PhysicsVolume.bWaterVolume )
  2259.     {
  2260.         if ( Pawn.HeadVolume.bWaterVolume )
  2261.             Pawn.BreathTime = Pawn.UnderWaterTime;
  2262.         NewState = Pawn.WaterMovementState;
  2263.     }
  2264.     else  
  2265.         NewState = Pawn.LandMovementState;
  2266.  
  2267.     if ( IsInState(NewState) )
  2268.         BeginState();
  2269.     else
  2270.         GotoState(NewState);
  2271. }
  2272.  
  2273. function ClientRestart()
  2274. {
  2275.     if ( (Pawn != None) && Pawn.bTearOff )
  2276.     {
  2277.         Pawn.Controller = None;
  2278.         Pawn = None;
  2279.     }
  2280.     if ( Pawn == None )
  2281.     {
  2282.         GotoState('WaitingForPawn');
  2283.         return;
  2284.     }
  2285.     Pawn.ClientRestart();
  2286.     SetViewTarget(Pawn);
  2287.     bBehindView = Pawn.PointOfView();
  2288.     CleanOutSavedMoves();
  2289.     EnterStartState();    
  2290. }
  2291.  
  2292. exec function BehindView( Bool B )
  2293. {
  2294.     if ( (Level.NetMode == NM_Standalone) || Level.Game.bAllowBehindView || PlayerReplicationInfo.bOnlySpectator || PlayerReplicationInfo.bAdmin || IsA('Admin') )
  2295.     {
  2296.         bBehindView = B;
  2297.         ClientSetBehindView(bBehindView);
  2298.     }
  2299. }
  2300.     
  2301. exec function ToggleBehindView()
  2302. {
  2303.     ServerToggleBehindview();
  2304. }
  2305.  
  2306. function ServerToggleBehindView()
  2307. {
  2308.     bBehindView = !bBehindView;
  2309.     ClientSetBehindView(bBehindView);
  2310. }
  2311.  
  2312. //=============================================================================
  2313. // functions.
  2314.  
  2315. // Just changed to pendingWeapon
  2316. function ChangedWeapon()
  2317. {
  2318.     if ( Pawn.Weapon != None )
  2319.     {
  2320.         Pawn.Weapon.SetHand(Handedness);
  2321.         LastPawnWeapon = Pawn.Weapon.Class;
  2322.     }
  2323. }
  2324.  
  2325. event TravelPostAccept()
  2326. {
  2327.     if ( Pawn.Health <= 0 )
  2328.         Pawn.Health = Pawn.Default.Health;
  2329. }
  2330.  
  2331. event PlayerTick( float DeltaTime )
  2332. {
  2333.     if ( bForcePrecache && (Level.TimeSeconds > ForcePrecacheTime) )
  2334.     {
  2335.         bForcePrecache = false;
  2336.         Level.FillPrecacheMaterialsArray();
  2337.         Level.FillPrecacheStaticMeshesArray();
  2338.     }        
  2339.     PlayerInput.PlayerInput(DeltaTime);
  2340.     if ( bUpdatePosition )
  2341.         ClientUpdatePosition();
  2342.     PlayerMove(DeltaTime);
  2343. }
  2344.  
  2345. function PlayerMove(float DeltaTime);
  2346.  
  2347. //
  2348. /* AdjustAim()
  2349. Calls this version for player aiming help.
  2350. Aimerror not used in this version.
  2351. Only adjusts aiming at pawns
  2352. */
  2353. function rotator AdjustAim(Ammunition FiredAmmunition, vector projStart, int aimerror)
  2354. {
  2355.     local vector FireDir, AimSpot, HitNormal, HitLocation, OldAim, AimOffset;
  2356.     local actor BestTarget;
  2357.     local float bestAim, bestDist, projspeed;
  2358.     local actor HitActor;
  2359.     local bool bNoZAdjust, bLeading;
  2360.     local rotator AimRot;
  2361.  
  2362.     FireDir = vector(Rotation);
  2363.     if ( FiredAmmunition.bInstantHit )
  2364.         HitActor = Trace(HitLocation, HitNormal, projStart + 10000 * FireDir, projStart, true);
  2365.     else 
  2366.         HitActor = Trace(HitLocation, HitNormal, projStart + 4000 * FireDir, projStart, true);
  2367.     if ( (HitActor != None) && HitActor.bProjTarget )
  2368.     {
  2369.         FiredAmmunition.WarnTarget(Target,Pawn,FireDir);
  2370.         BestTarget = HitActor;
  2371.         bNoZAdjust = true;
  2372.         OldAim = HitLocation;
  2373.         BestDist = VSize(BestTarget.Location - Pawn.Location);
  2374.     }
  2375.     else
  2376.     {
  2377.         // adjust aim based on FOV
  2378.         bestAim = 0.95;
  2379.         if ( AimingHelp == 1 )
  2380.         {
  2381.             bestAim = 0.93;
  2382.             if ( FiredAmmunition.bInstantHit )
  2383.                 bestAim = 0.97; 
  2384.             if ( FOVAngle < DefaultFOV - 8 )
  2385.                 bestAim = 0.99;
  2386.         }
  2387.         else
  2388.         {
  2389.             if ( FiredAmmunition.bInstantHit )
  2390.                 bestAim = 0.98; 
  2391.             if ( FOVAngle != DefaultFOV )
  2392.                 bestAim = 0.995;
  2393.         }
  2394.         BestTarget = PickTarget(bestAim, bestDist, FireDir, projStart,FiredAmmunition.MaxAutoAimRange);
  2395.         if ( BestTarget == None )
  2396.         {
  2397.             if (bBehindView)
  2398.                 return Pawn.Rotation;
  2399.             else
  2400.                 return Rotation;
  2401.         }
  2402.         FiredAmmunition.WarnTarget(Target,Pawn,FireDir);
  2403.         OldAim = projStart + FireDir * bestDist;
  2404.     }
  2405.     if ( (AimingHelp == 0) || (Level.NetMode != NM_Standalone) )
  2406.     {
  2407.         if (bBehindView)
  2408.             return Pawn.Rotation;
  2409.         else
  2410.             return Rotation;
  2411.     }
  2412.  
  2413.     // aim at target - help with leading also
  2414.     if ( !FiredAmmunition.bInstantHit )
  2415.     {
  2416.         projspeed = FiredAmmunition.ProjectileClass.default.speed;
  2417.         BestDist = vsize(BestTarget.Location + BestTarget.Velocity * FMin(2, 0.02 + BestDist/projSpeed) - projStart); 
  2418.         bLeading = true;
  2419.         FireDir = BestTarget.Location + BestTarget.Velocity * FMin(2, 0.02 + BestDist/projSpeed) - projStart;
  2420.         AimSpot = projStart + bestDist * Normal(FireDir);
  2421.         // if splash damage weapon, try aiming at feet - trace down to find floor
  2422.         if ( FiredAmmunition.bTrySplash 
  2423.             && ((BestTarget.Velocity != vect(0,0,0)) || (BestDist > 1500)) )
  2424.         {
  2425.             HitActor = Trace(HitLocation, HitNormal, AimSpot - BestTarget.CollisionHeight * vect(0,0,2), AimSpot, false);
  2426.             if ( (HitActor != None)
  2427.                 && FastTrace(HitLocation + vect(0,0,4),projstart) )
  2428.                 return rotator(HitLocation + vect(0,0,6) - projStart);
  2429.         }
  2430.     }
  2431.     else
  2432.     {
  2433.         FireDir = BestTarget.Location - projStart;
  2434.         AimSpot = projStart + bestDist * Normal(FireDir);
  2435.     }
  2436.     AimOffset = AimSpot - OldAim;
  2437.  
  2438.     // adjust Z of shooter if necessary
  2439.     if ( bNoZAdjust || (bLeading && (Abs(AimOffset.Z) < BestTarget.CollisionHeight)) )
  2440.         AimSpot.Z = OldAim.Z;
  2441.     else if ( AimOffset.Z < 0 )
  2442.         AimSpot.Z = BestTarget.Location.Z + 0.4 * BestTarget.CollisionHeight;
  2443.     else
  2444.         AimSpot.Z = BestTarget.Location.Z - 0.7 * BestTarget.CollisionHeight;
  2445.  
  2446.     if ( !bLeading )
  2447.     {
  2448.         // if not leading, add slight random error ( significant at long distances )
  2449.         if ( !bNoZAdjust )
  2450.         {
  2451.             AimRot = rotator(AimSpot - projStart);
  2452.             if ( FOVAngle < DefaultFOV - 8 )
  2453.                 AimRot.Yaw = AimRot.Yaw + 200 - Rand(400);
  2454.             else
  2455.                 AimRot.Yaw = AimRot.Yaw + 375 - Rand(750);
  2456.             return AimRot;
  2457.         }    
  2458.     }
  2459.     else if ( !FastTrace(projStart + 0.9 * bestDist * Normal(FireDir), projStart) )
  2460.     {
  2461.         FireDir = BestTarget.Location - projStart;
  2462.         AimSpot = projStart + bestDist * Normal(FireDir);
  2463.     }
  2464.         
  2465.     return rotator(AimSpot - projStart);
  2466. }
  2467.  
  2468. function bool NotifyLanded(vector HitNormal)
  2469. {
  2470.     return bUpdating;
  2471. }
  2472.  
  2473. //=============================================================================
  2474. // Player Control
  2475.  
  2476. // Player view.
  2477. // Compute the rendering viewpoint for the player.
  2478. //
  2479.  
  2480. function AdjustView(float DeltaTime )
  2481. {
  2482.     // teleporters affect your FOV, so adjust it back down
  2483.     if ( FOVAngle != DesiredFOV )
  2484.     {
  2485.         if ( FOVAngle > DesiredFOV )
  2486.             FOVAngle = FOVAngle - FMax(7, 0.9 * DeltaTime * (FOVAngle - DesiredFOV)); 
  2487.         else 
  2488.             FOVAngle = FOVAngle - FMin(-7, 0.9 * DeltaTime * (FOVAngle - DesiredFOV)); 
  2489.         if ( Abs(FOVAngle - DesiredFOV) <= 10 )
  2490.             FOVAngle = DesiredFOV;
  2491.     }
  2492.  
  2493.     // adjust FOV for weapon zooming
  2494.     if ( bZooming )
  2495.     {    
  2496.         ZoomLevel += DeltaTime * 1.0;
  2497.         if (ZoomLevel > 0.9)
  2498.             ZoomLevel = 0.9;
  2499.         DesiredFOV = FClamp(90.0 - (ZoomLevel * 88.0), 1, 170);
  2500.     } 
  2501. }
  2502.  
  2503. function CalcBehindView(out vector CameraLocation, out rotator CameraRotation, float Dist)
  2504. {
  2505.     local vector View,HitLocation,HitNormal;
  2506.     local float ViewDist,RealDist;
  2507.  
  2508.     CameraRotation = Rotation;
  2509.     if ( bBlockCloseCamera )
  2510.         CameraLocation.Z += 12;
  2511.  
  2512.     View = vect(1,0,0) >> CameraRotation;
  2513.  
  2514.     // add view radius offset to camera location and move viewpoint up from origin (amb)
  2515.     RealDist = Dist;
  2516.  
  2517.     if( Trace( HitLocation, HitNormal, CameraLocation - Dist * vector(CameraRotation), CameraLocation,false,vect(10,10,10) ) != None )
  2518.         ViewDist = FMin( (CameraLocation - HitLocation) Dot View, Dist );
  2519.     else
  2520.         ViewDist = Dist;
  2521.     
  2522.     if ( !bBlockCloseCamera || !bValidBehindCamera || (ViewDist > 10 + FMax(ViewTarget.CollisionRadius, ViewTarget.CollisionHeight)) )
  2523.     {
  2524.         //Log("Update Cam ");
  2525.         bValidBehindCamera = true;
  2526.         OldCameraLoc = CameraLocation - ViewDist * View;
  2527.         OldCameraRot = CameraRotation;
  2528.     }
  2529.     else
  2530.     {
  2531.         //Log("Dont Update Cam "$bBlockCloseCamera@bValidBehindCamera@ViewDist);
  2532.         SetRotation(OldCameraRot);
  2533.     }
  2534.  
  2535.     CameraLocation = OldCameraLoc; 
  2536.     CameraRotation = OldCameraRot;
  2537. }
  2538.  
  2539. function CalcFirstPersonView( out vector CameraLocation, out rotator CameraRotation )
  2540. {
  2541.     // First-person view.
  2542.     CameraRotation = Rotation;
  2543.     CameraLocation = CameraLocation + Pawn.EyePosition() + ShakeOffset;
  2544. }
  2545.  
  2546. event AddCameraEffect(CameraEffect NewEffect,optional bool RemoveExisting)
  2547. {
  2548.     if(RemoveExisting)
  2549.         RemoveCameraEffect(NewEffect);
  2550.  
  2551.     CameraEffects.Length = CameraEffects.Length + 1;
  2552.     CameraEffects[CameraEffects.Length - 1] = NewEffect;
  2553. }
  2554.  
  2555. event RemoveCameraEffect(CameraEffect ExEffect)
  2556. {
  2557.     local int    EffectIndex;
  2558.  
  2559.     for(EffectIndex = 0;EffectIndex < CameraEffects.Length;EffectIndex++)
  2560.         if(CameraEffects[EffectIndex] == ExEffect)
  2561.         {
  2562.             CameraEffects.Remove(EffectIndex,1);
  2563.             return;
  2564.         }
  2565. }
  2566.  
  2567. exec function CreateCameraEffect(class<CameraEffect> EffectClass)
  2568. {
  2569.     AddCameraEffect(new EffectClass);
  2570. }
  2571.  
  2572. function rotator GetViewRotation()
  2573. {
  2574.     if ( bBehindView && (Pawn != None) )
  2575.         return Pawn.Rotation;
  2576.     return Rotation;
  2577. }
  2578.  
  2579. event PlayerCalcView(out actor ViewActor, out vector CameraLocation, out rotator CameraRotation )
  2580. {
  2581.     local Pawn PTarget;
  2582.  
  2583.     // If desired, call the pawn's own special callview
  2584.     if( Pawn != None && Pawn.bSpecialCalcView )
  2585.     {
  2586.         // try the 'special' calcview. This may return false if its not applicable, and we do the usual.
  2587.         if( Pawn.SpecialCalcView(ViewActor, CameraLocation, CameraRotation) )
  2588.             return;
  2589.     }
  2590.  
  2591.     if ( (ViewTarget == None) || ViewTarget.bDeleteMe )
  2592.     {
  2593.         if ( bViewBot && (CheatManager != None) )
  2594.             CheatManager.ViewBot();
  2595.         else if ( (Pawn != None) && !Pawn.bDeleteMe )
  2596.             SetViewTarget(Pawn);
  2597.         else if ( RealViewTarget != None )
  2598.             SetViewTarget(RealViewTarget);
  2599.         else
  2600.             SetViewTarget(self);
  2601.     }
  2602.  
  2603.     ViewActor = ViewTarget;
  2604.     CameraLocation = ViewTarget.Location;
  2605.  
  2606.     if ( ViewTarget == Pawn )
  2607.     {
  2608.         if( bBehindView ) //up and behind
  2609.             CalcBehindView(CameraLocation, CameraRotation, CameraDist * Pawn.Default.CollisionRadius);
  2610.         else
  2611.             CalcFirstPersonView( CameraLocation, CameraRotation );
  2612.         return;
  2613.     }
  2614.     if ( ViewTarget == self )
  2615.     {
  2616.         if ( bCameraPositionLocked )
  2617.             CameraRotation = CheatManager.LockedRotation;
  2618.         else
  2619.             CameraRotation = Rotation;
  2620.         return;
  2621.     }
  2622.  
  2623.     if ( ViewTarget.IsA('Projectile') && !bBehindView ) 
  2624.     {
  2625.         CameraLocation += (ViewTarget.CollisionHeight) * vect(0,0,1);
  2626.         CameraRotation = Rotation;
  2627.         return;
  2628.     }
  2629.  
  2630.     CameraRotation = ViewTarget.Rotation;
  2631.     PTarget = Pawn(ViewTarget);
  2632.     if ( PTarget != None )
  2633.     {
  2634.         if ( Level.NetMode == NM_Client )
  2635.         {
  2636.             PTarget.SetViewRotation(TargetViewRotation);
  2637.             CameraRotation = BlendedTargetViewRotation;
  2638.  
  2639.             PTarget.EyeHeight = TargetEyeHeight;
  2640.             if ( PTarget.Weapon != None )
  2641.                 PTarget.Weapon.PlayerViewOffset = TargetWeaponViewOffset;
  2642.         }
  2643.         else if ( PTarget.IsPlayerPawn() )
  2644.             CameraRotation = PTarget.GetViewRotation();
  2645.         if ( !bBehindView )
  2646.             CameraLocation += PTarget.EyePosition();
  2647.     }
  2648.     if ( bBehindView )
  2649.     {
  2650.         CameraLocation = CameraLocation + (ViewTarget.Default.CollisionHeight - ViewTarget.CollisionHeight) * vect(0,0,1);
  2651.         CalcBehindView(CameraLocation, CameraRotation, CameraDist * ViewTarget.Default.CollisionRadius);
  2652.     }
  2653. }
  2654.  
  2655. function int BlendRot(float DeltaTime, int BlendC, int NewC)
  2656. {
  2657.     if ( Abs(BlendC - NewC) > 32767 )
  2658.     {
  2659.         if ( BlendC > NewC )
  2660.             NewC += 65536;
  2661.         else
  2662.             BlendC += 65536;
  2663.     }
  2664.     if ( Abs(BlendC - NewC) > 4096 )
  2665.         BlendC = NewC;
  2666.     else
  2667.         BlendC = BlendC + (NewC - BlendC) * FMin(1,24 * DeltaTime);
  2668.  
  2669.     return (BlendC & 65535);
  2670. }
  2671.  
  2672. function CheckShake(out float MaxOffset, out float Offset, out float Rate, out float Time)
  2673. {
  2674.     if ( abs(Offset) < abs(MaxOffset) )
  2675.         return;
  2676.  
  2677.     Offset = MaxOffset;
  2678.     if ( Time > 1 )
  2679.     {
  2680.         if ( Time * abs(MaxOffset/Rate) <= 1 )
  2681.             MaxOffset = MaxOffset * (1/Time - 1);
  2682.         else
  2683.             MaxOffset *= -1;
  2684.         Time -= 1;
  2685.         Rate *= -1;
  2686.     }
  2687.     else
  2688.     {
  2689.         MaxOffset = 0;
  2690.         Offset = 0;
  2691.         Rate = 0;
  2692.     }
  2693. }
  2694.  
  2695. function ViewShake(float DeltaTime)
  2696. {
  2697.     local Rotator ViewRotation;
  2698.     local float FRoll;
  2699.  
  2700.     if ( ShakeOffsetRate != vect(0,0,0) )
  2701.     {
  2702.         // modify shake offset
  2703.         ShakeOffset.X += DeltaTime * ShakeOffsetRate.X;
  2704.         CheckShake(MaxShakeOffset.X, ShakeOffset.X, ShakeOffsetRate.X, ShakeOffsetTime.X);
  2705.         
  2706.         ShakeOffset.Y += DeltaTime * ShakeOffsetRate.Y;
  2707.         CheckShake(MaxShakeOffset.Y, ShakeOffset.Y, ShakeOffsetRate.Y, ShakeOffsetTime.Y);
  2708.         
  2709.         ShakeOffset.Z += DeltaTime * ShakeOffsetRate.Z;
  2710.         CheckShake(MaxShakeOffset.Z, ShakeOffset.Z, ShakeOffsetRate.Z, ShakeOffsetTime.Z);
  2711.     }                
  2712.  
  2713.     ViewRotation = Rotation;
  2714.  
  2715.     if ( ShakeRollRate != 0 )
  2716.     {
  2717.         ViewRotation.Roll = ((ViewRotation.Roll & 65535) + ShakeRollRate * DeltaTime) & 65535;
  2718.         if ( ViewRotation.Roll > 32768 )
  2719.             ViewRotation.Roll -= 65536;
  2720.         FRoll = ViewRotation.Roll;
  2721.         CheckShake(MaxShakeRoll, FRoll, ShakeRollRate, ShakeRollTime);
  2722.         ViewRotation.Roll = FRoll;
  2723.     }
  2724.     else if ( bZeroRoll )
  2725.         ViewRotation.Roll = 0;
  2726.     SetRotation(ViewRotation);
  2727. }
  2728.  
  2729. function bool TurnTowardNearestEnemy();
  2730.  
  2731. function TurnAround()
  2732. {
  2733.     if ( !bSetTurnRot )
  2734.     {
  2735.         TurnRot180 = Rotation;
  2736.         TurnRot180.Yaw += 32768;
  2737.         bSetTurnRot = true;
  2738.     }
  2739.     
  2740.     DesiredRotation = TurnRot180;
  2741.     bRotateToDesired = ( DesiredRotation.Yaw != Rotation.Yaw );
  2742. }
  2743.                     
  2744. function UpdateRotation(float DeltaTime, float maxPitch)
  2745. {
  2746.     local rotator newRotation, ViewRotation;
  2747.  
  2748.     if ( bInterpolating || ((Pawn != None) && Pawn.bInterpolating) )
  2749.     {
  2750.         ViewShake(deltaTime);
  2751.         return;
  2752.     }
  2753.     ViewRotation = Rotation;
  2754.     DesiredRotation = ViewRotation; //save old rotation
  2755.     if ( bTurnToNearest != 0 )
  2756.         TurnTowardNearestEnemy();
  2757.     else if ( bTurn180 != 0 )
  2758.         TurnAround();
  2759.     else
  2760.     {
  2761.         TurnTarget = None;
  2762.         bRotateToDesired = false;
  2763.         bSetTurnRot = false;
  2764.         ViewRotation.Yaw += 32.0 * DeltaTime * aTurn;
  2765.         ViewRotation.Pitch += 32.0 * DeltaTime * aLookUp;
  2766.     }
  2767.     ViewRotation.Pitch = ViewRotation.Pitch & 65535;
  2768.     If ((ViewRotation.Pitch > 18000) && (ViewRotation.Pitch < 49152))
  2769.     {
  2770.         If (aLookUp > 0) 
  2771.             ViewRotation.Pitch = 18000;
  2772.         else
  2773.             ViewRotation.Pitch = 49152;
  2774.     }
  2775.  
  2776.     SetRotation(ViewRotation);
  2777.  
  2778.     ViewShake(deltaTime);
  2779.     ViewFlash(deltaTime);
  2780.         
  2781.     NewRotation = ViewRotation;
  2782.     NewRotation.Roll = Rotation.Roll;
  2783.  
  2784.     if ( !bRotateToDesired && (Pawn != None) && (!bFreeCamera || !bBehindView) )
  2785.         Pawn.FaceRotation(NewRotation, deltatime);
  2786. }
  2787.  
  2788. function ClearDoubleClick()
  2789. {
  2790.     if (PlayerInput != None)
  2791.         PlayerInput.DoubleClickTimer = 0.0;
  2792. }
  2793.  
  2794. // Player movement.
  2795. // Player Standing, walking, running, falling.
  2796. state PlayerWalking
  2797. {
  2798. ignores SeePlayer, HearNoise, Bump;
  2799.  
  2800.     function bool NotifyPhysicsVolumeChange( PhysicsVolume NewVolume )
  2801.     {
  2802.         if ( NewVolume.bWaterVolume )
  2803.             GotoState(Pawn.WaterMovementState);
  2804.         return false;
  2805.     }
  2806.  
  2807.     function ProcessMove(float DeltaTime, vector NewAccel, eDoubleClickDir DoubleClickMove, rotator DeltaRot)    
  2808.     {
  2809.         local vector OldAccel;
  2810.         local bool OldCrouch;
  2811.  
  2812.         if ( Pawn == None )
  2813.             return;
  2814.         OldAccel = Pawn.Acceleration;
  2815.         Pawn.Acceleration = NewAccel;
  2816.         if ( bDoubleJump && (bUpdating || Pawn.CanDoubleJump()) )
  2817.             Pawn.DoDoubleJump(bUpdating);
  2818.         else if ( bPressedJump )
  2819.             Pawn.DoJump(bUpdating);
  2820.         if ( Pawn.Physics != PHYS_Falling )
  2821.         {
  2822.             OldCrouch = Pawn.bWantsToCrouch;
  2823.             if (bDuck == 0)
  2824.                 Pawn.ShouldCrouch(false);
  2825.             else if ( Pawn.bCanCrouch )
  2826.                 Pawn.ShouldCrouch(true);
  2827.         }
  2828.     }
  2829.  
  2830.     function PlayerMove( float DeltaTime )
  2831.     {
  2832.         local vector X,Y,Z, NewAccel;
  2833.         local eDoubleClickDir DoubleClickMove;
  2834.         local rotator OldRotation, ViewRotation;
  2835.         local bool    bSaveJump;
  2836.  
  2837.         GetAxes(Pawn.Rotation,X,Y,Z);
  2838.  
  2839.         // Update acceleration.
  2840.         NewAccel = aForward*X + aStrafe*Y; 
  2841.         NewAccel.Z = 0;
  2842.         if ( VSize(NewAccel) < 1.0 )
  2843.             NewAccel = vect(0,0,0);
  2844.         DoubleClickMove = PlayerInput.CheckForDoubleClickMove(DeltaTime);
  2845.         
  2846.         GroundPitch = 0;    
  2847.         ViewRotation = Rotation;
  2848.         if ( Pawn.Physics == PHYS_Walking )
  2849.         {
  2850.             // tell pawn about any direction changes to give it a chance to play appropriate animation
  2851.             //if walking, look up/down stairs - unless player is rotating view
  2852.             if ( (bLook == 0) 
  2853.                 && (((Pawn.Acceleration != Vect(0,0,0)) && bSnapToLevel) || !bKeyboardLook) )
  2854.             {
  2855.                 if ( bLookUpStairs || bSnapToLevel )
  2856.                 {
  2857.                     GroundPitch = FindStairRotation(deltaTime);
  2858.                     ViewRotation.Pitch = GroundPitch;
  2859.                 }
  2860.                 else if ( bCenterView )
  2861.                 {
  2862.                     ViewRotation.Pitch = ViewRotation.Pitch & 65535;
  2863.                     if (ViewRotation.Pitch > 32768)
  2864.                         ViewRotation.Pitch -= 65536;
  2865.                     ViewRotation.Pitch = ViewRotation.Pitch * (1 - 12 * FMin(0.0833, deltaTime));
  2866.                     if ( Abs(ViewRotation.Pitch) < 200 )
  2867.                         ViewRotation.Pitch = 0;    
  2868.                 }
  2869.             }
  2870.         }    
  2871.         else
  2872.         {
  2873.             if ( !bKeyboardLook && (bLook == 0) && bCenterView )
  2874.             {
  2875.                 ViewRotation.Pitch = ViewRotation.Pitch & 65535;
  2876.                 if (ViewRotation.Pitch > 32768)
  2877.                     ViewRotation.Pitch -= 65536;
  2878.                 ViewRotation.Pitch = ViewRotation.Pitch * (1 - 12 * FMin(0.0833, deltaTime));
  2879.                 if ( Abs(ViewRotation.Pitch) < 200 )
  2880.                     ViewRotation.Pitch = 0;    
  2881.             }
  2882.         }
  2883.         Pawn.CheckBob(DeltaTime, Y);
  2884.  
  2885.         // Update rotation.
  2886.         SetRotation(ViewRotation);
  2887.         OldRotation = Rotation;
  2888.         UpdateRotation(DeltaTime, 1);
  2889.         bDoubleJump = false;
  2890.  
  2891.         if ( bPressedJump && Pawn.CannotJumpNow() )
  2892.         {
  2893.             bSaveJump = true;
  2894.             bPressedJump = false;
  2895.         }
  2896.         else
  2897.             bSaveJump = false;
  2898.  
  2899.         if ( Role < ROLE_Authority ) // then save this move and replicate it
  2900.             ReplicateMove(DeltaTime, NewAccel, DoubleClickMove, OldRotation - Rotation);
  2901.         else
  2902.             ProcessMove(DeltaTime, NewAccel, DoubleClickMove, OldRotation - Rotation);
  2903.         bPressedJump = bSaveJump;
  2904.     }
  2905.  
  2906.     function BeginState()
  2907.     {
  2908.            DoubleClickDir = DCLICK_None;
  2909.            bPressedJump = false;
  2910.            GroundPitch = 0;
  2911.         if ( Pawn != None )
  2912.         {
  2913.         if ( Pawn.Mesh == None )
  2914.             Pawn.SetMesh();
  2915.         Pawn.ShouldCrouch(false);
  2916.         if (Pawn.Physics != PHYS_Falling && Pawn.Physics != PHYS_Karma) // FIXME HACK!!!
  2917.             Pawn.SetPhysics(PHYS_Walking);
  2918.         }
  2919.     }
  2920.     
  2921.     function EndState()
  2922.     {
  2923.  
  2924.         GroundPitch = 0;
  2925.         if ( Pawn != None && bDuck==0 )
  2926.         {
  2927.             Pawn.ShouldCrouch(false);
  2928.         }
  2929.     }
  2930. }
  2931.  
  2932. // player is climbing ladder
  2933. state PlayerClimbing
  2934. {
  2935. ignores SeePlayer, HearNoise, Bump;
  2936.  
  2937.     function bool NotifyPhysicsVolumeChange( PhysicsVolume NewVolume )
  2938.     {
  2939.         if ( NewVolume.bWaterVolume )
  2940.             GotoState(Pawn.WaterMovementState);
  2941.         else
  2942.             GotoState(Pawn.LandMovementState);
  2943.         return false;
  2944.     }
  2945.  
  2946.     function ProcessMove(float DeltaTime, vector NewAccel, eDoubleClickDir DoubleClickMove, rotator DeltaRot)    
  2947.     {
  2948.         local vector OldAccel;
  2949.  
  2950.         OldAccel = Pawn.Acceleration;
  2951.         Pawn.Acceleration = NewAccel;
  2952.  
  2953.         if ( bPressedJump )
  2954.         {
  2955.             Pawn.DoJump(bUpdating);
  2956.             if ( Pawn.Physics == PHYS_Falling )
  2957.                 GotoState('PlayerWalking');
  2958.         }
  2959.     }
  2960.  
  2961.     function PlayerMove( float DeltaTime )
  2962.     {
  2963.         local vector X,Y,Z, NewAccel;
  2964.         local eDoubleClickDir DoubleClickMove;
  2965.         local rotator OldRotation, ViewRotation;
  2966.         local bool    bSaveJump;
  2967.  
  2968.         GetAxes(Rotation,X,Y,Z);
  2969.  
  2970.         // Update acceleration.
  2971.         if ( Pawn.OnLadder != None )
  2972.             NewAccel = aForward*Pawn.OnLadder.ClimbDir; 
  2973.         else
  2974.             NewAccel = aForward*X + aStrafe*Y;
  2975.         if ( VSize(NewAccel) < 1.0 )
  2976.             NewAccel = vect(0,0,0);
  2977.         
  2978.         ViewRotation = Rotation;
  2979.  
  2980.         // Update rotation.
  2981.         SetRotation(ViewRotation);
  2982.         OldRotation = Rotation;
  2983.         UpdateRotation(DeltaTime, 1);
  2984.  
  2985.         if ( Role < ROLE_Authority ) // then save this move and replicate it
  2986.             ReplicateMove(DeltaTime, NewAccel, DoubleClickMove, OldRotation - Rotation);
  2987.         else
  2988.             ProcessMove(DeltaTime, NewAccel, DoubleClickMove, OldRotation - Rotation);
  2989.         bPressedJump = bSaveJump;
  2990.     }
  2991.  
  2992.     function BeginState()
  2993.     {
  2994.         Pawn.ShouldCrouch(false);
  2995.         bPressedJump = false;
  2996.     }
  2997.     
  2998.     function EndState()
  2999.     {
  3000.         if ( Pawn != None )
  3001.             Pawn.ShouldCrouch(false);
  3002.     }
  3003. }
  3004.  
  3005. // Player movement.
  3006. // Player Driving a Karma vehicle.
  3007. state PlayerDriving
  3008. {
  3009. ignores SeePlayer, HearNoise, Bump;
  3010.  
  3011.     function ProcessMove(float DeltaTime, vector NewAccel, eDoubleClickDir DoubleClickMove, rotator DeltaRot)    
  3012.     {
  3013.  
  3014.     }
  3015.  
  3016.     exec function Fire(optional float F)
  3017.     {
  3018.         local KVehicle DrivenVehicle;
  3019.  
  3020.         DrivenVehicle = KVehicle(Pawn);
  3021.         if(DrivenVehicle != None)
  3022.         {
  3023.             DrivenVehicle.VehicleFire(false);
  3024.             DrivenVehicle.bVehicleIsFiring = true;
  3025.         }
  3026.     }
  3027.  
  3028.     exec function AltFire(optional float F)
  3029.     {
  3030.         local KVehicle DrivenVehicle;
  3031.  
  3032.         DrivenVehicle = KVehicle(Pawn);
  3033.         if(DrivenVehicle != None)
  3034.         {
  3035.             DrivenVehicle.VehicleFire(true);
  3036.             DrivenVehicle.bVehicleIsAltFiring = true;
  3037.         }
  3038.     }
  3039.  
  3040.     // When you hit use inside the SVehicle, you get out.
  3041.     function ServerUse()
  3042.     {
  3043.         local SVehicle DrivenSVehicle;
  3044.  
  3045.         if(Role != ROLE_Authority)
  3046.             return;
  3047.  
  3048.         DrivenSVehicle = SVehicle(Pawn);
  3049.         if(DrivenSVehicle != None)
  3050.         {
  3051.             DrivenSVehicle.bGetOut = true;
  3052.         }
  3053.     }
  3054.  
  3055.     // Set the throttle, steering etc. for the vehicle based on the input provided
  3056.     function ProcessDrive(float InForward, float InStrafe, float InUp, bool InJump)
  3057.     {
  3058.         local KVehicle DrivenVehicle;
  3059.         local SVehicle DrivenSVehicle;
  3060.  
  3061.         DrivenVehicle = KVehicle(Pawn);
  3062.         
  3063.         if(DrivenVehicle == None)
  3064.         {
  3065.             // URGH! Need to make superclass of KVehicle and SVehicle
  3066.             DrivenSVehicle = SVehicle(Pawn);
  3067.  
  3068.             if(DrivenSVehicle == None)
  3069.             {
  3070.             log("PlayerDriving.PlayerMove: No Vehicle");
  3071.             return;
  3072.         }
  3073.  
  3074.             //log("Drive:"$InForward$" Steer:"$InStrafe);
  3075.  
  3076.             if(InForward > 1)
  3077.                 DrivenSVehicle.Throttle = 1;
  3078.             else if(InForward < -1)
  3079.                 DrivenSVehicle.Throttle = -1;
  3080.             else
  3081.                 DrivenSVehicle.Throttle = 0;
  3082.  
  3083.             if(InStrafe < -1)
  3084.                 DrivenSVehicle.Steering = 1;
  3085.             else if(InStrafe > 1)
  3086.                 DrivenSVehicle.Steering = -1;
  3087.             else
  3088.                 DrivenSVehicle.Steering = 0;
  3089.  
  3090.             if(InUp < -1)
  3091.                 DrivenSVehicle.Rise = -1;
  3092.             else if(InUp > 1)
  3093.                 DrivenSVehicle.Rise = 1;
  3094.             else
  3095.                 DrivenSVehicle.Rise = 0;
  3096.  
  3097.             return;
  3098.         }
  3099.  
  3100.         // // // //
  3101.  
  3102.         // check for 'jump' to throw the driver out.
  3103.         if(InJump && Role == ROLE_Authority)
  3104.         {
  3105.             DrivenVehicle.bGetOut = true;
  3106.             return;
  3107.         }
  3108.  
  3109.         //log("Drive:"$InForward$" Steer:"$InStrafe);
  3110.  
  3111.         if(InForward > 1)
  3112.             DrivenVehicle.Throttle = 1;
  3113.         else if(InForward < -1)
  3114.             DrivenVehicle.Throttle = -1;
  3115.         else
  3116.             DrivenVehicle.Throttle = 0;
  3117.  
  3118.         if(InStrafe < -1)
  3119.             DrivenVehicle.Steering = 1;
  3120.         else if(InStrafe > 1)
  3121.             DrivenVehicle.Steering = -1;
  3122.         else
  3123.             DrivenVehicle.Steering = 0;
  3124.         }
  3125.  
  3126.     function PlayerMove( float DeltaTime )
  3127.         {
  3128.         local KVehicle DrivenVehicle;
  3129.  
  3130.         // Only servers can actually do the driving logic.
  3131.         if(Role < ROLE_Authority)
  3132.             ServerDrive(aForward, aStrafe, aUp, bPressedJump);
  3133.         else
  3134.             ProcessDrive(aForward, aStrafe, aUp, bPressedJump);
  3135.  
  3136.         // If the vehicle is being controlled here - set replicated variables.
  3137.         DrivenVehicle = KVehicle(Pawn);
  3138.         if(DrivenVehicle != None)
  3139.             {
  3140.             if(bFire == 0 && DrivenVehicle.bVehicleIsFiring)
  3141.             {
  3142.                 DrivenVehicle.VehicleCeaseFire(false);
  3143.                 DrivenVehicle.bVehicleIsFiring = false;
  3144.             }
  3145.             
  3146.             if(bAltFire == 0 && DrivenVehicle.bVehicleIsAltFiring)
  3147.         {
  3148.                 DrivenVehicle.VehicleCeaseFire(true);
  3149.                 DrivenVehicle.bVehicleIsAltFiring = false;
  3150.             }
  3151.         }
  3152.  
  3153.         // update 'looking' rotation - no affect on driving
  3154.         UpdateRotation(DeltaTime, 2);
  3155.     }
  3156.  
  3157.     function BeginState()
  3158.     {
  3159.         CleanOutSavedMoves();
  3160.     }
  3161.     
  3162.     function EndState()
  3163.     {
  3164.         CleanOutSavedMoves();
  3165.     }
  3166. }
  3167.  
  3168. // Player movement.
  3169. // Player walking on walls
  3170. state PlayerSpidering
  3171. {
  3172. ignores SeePlayer, HearNoise, Bump;
  3173.  
  3174.     event bool NotifyHitWall(vector HitNormal, actor HitActor)
  3175.     {
  3176.         Pawn.SetPhysics(PHYS_Spider);
  3177.         Pawn.SetBase(HitActor, HitNormal);    
  3178.         return true;
  3179.     }
  3180.  
  3181.     // if spider mode, update rotation based on floor                    
  3182.     function UpdateRotation(float DeltaTime, float maxPitch)
  3183.     {
  3184.         local rotator ViewRotation;
  3185.         local vector MyFloor, CrossDir, FwdDir, OldFwdDir, OldX, RealFloor;
  3186.  
  3187.         if ( bInterpolating || Pawn.bInterpolating )
  3188.         {
  3189.             ViewShake(deltaTime);
  3190.             return;
  3191.         }
  3192.  
  3193.         TurnTarget = None;
  3194.         bRotateToDesired = false;
  3195.         bSetTurnRot = false;
  3196.  
  3197.         if ( (Pawn.Base == None) || (Pawn.Floor == vect(0,0,0)) )
  3198.             MyFloor = vect(0,0,1);
  3199.         else
  3200.             MyFloor = Pawn.Floor;
  3201.  
  3202.         if ( MyFloor != OldFloor )
  3203.         {
  3204.             // smoothly change floor
  3205.             RealFloor = MyFloor;
  3206.             MyFloor = Normal(6*DeltaTime * MyFloor + (1 - 6*DeltaTime) * OldFloor);
  3207.             if ( (RealFloor Dot MyFloor) > 0.999 )
  3208.                 MyFloor = RealFloor;
  3209.  
  3210.             // translate view direction
  3211.             CrossDir = Normal(RealFloor Cross OldFloor);
  3212.             FwdDir = CrossDir Cross MyFloor;
  3213.             OldFwdDir = CrossDir Cross OldFloor;
  3214.             ViewX = MyFloor * (OldFloor Dot ViewX) 
  3215.                         + CrossDir * (CrossDir Dot ViewX) 
  3216.                         + FwdDir * (OldFwdDir Dot ViewX);
  3217.             ViewX = Normal(ViewX);
  3218.             
  3219.             ViewZ = MyFloor * (OldFloor Dot ViewZ) 
  3220.                         + CrossDir * (CrossDir Dot ViewZ) 
  3221.                         + FwdDir * (OldFwdDir Dot ViewZ);
  3222.             ViewZ = Normal(ViewZ);
  3223.             OldFloor = MyFloor;  
  3224.             ViewY = Normal(MyFloor Cross ViewX); 
  3225.         }
  3226.  
  3227.         if ( (aTurn != 0) || (aLookUp != 0) )
  3228.         {
  3229.             // adjust Yaw based on aTurn
  3230.             if ( aTurn != 0 )
  3231.                 ViewX = Normal(ViewX + 2 * ViewY * Sin(0.0005*DeltaTime*aTurn));
  3232.  
  3233.             // adjust Pitch based on aLookUp
  3234.             if ( aLookUp != 0 )
  3235.             {
  3236.                 OldX = ViewX;
  3237.                 ViewX = Normal(ViewX + 2 * ViewZ * Sin(0.0005*DeltaTime*aLookUp));
  3238.                 ViewZ = Normal(ViewX Cross ViewY);
  3239.  
  3240.                 // bound max pitch
  3241.                 if ( (ViewZ Dot MyFloor) < 0.707   )
  3242.                 {
  3243.                     OldX = Normal(OldX - MyFloor * (MyFloor Dot OldX));
  3244.                     if ( (ViewX Dot MyFloor) > 0)
  3245.                         ViewX = Normal(OldX + MyFloor);
  3246.                     else
  3247.                         ViewX = Normal(OldX - MyFloor);
  3248.  
  3249.                     ViewZ = Normal(ViewX Cross ViewY);
  3250.                 }
  3251.             }
  3252.             
  3253.             // calculate new Y axis
  3254.             ViewY = Normal(MyFloor Cross ViewX);
  3255.         }
  3256.         ViewRotation =  OrthoRotation(ViewX,ViewY,ViewZ);
  3257.         SetRotation(ViewRotation);
  3258.         ViewShake(deltaTime);
  3259.         ViewFlash(deltaTime);
  3260.         Pawn.FaceRotation(ViewRotation, deltaTime );
  3261.     }
  3262.  
  3263.     function bool NotifyLanded(vector HitNormal)
  3264.     {
  3265.         Pawn.SetPhysics(PHYS_Spider);
  3266.         return bUpdating;
  3267.     }
  3268.  
  3269.     function bool NotifyPhysicsVolumeChange( PhysicsVolume NewVolume )
  3270.     {
  3271.         if ( NewVolume.bWaterVolume )
  3272.             GotoState(Pawn.WaterMovementState);
  3273.         return false;
  3274.     }
  3275.     
  3276.     function ProcessMove(float DeltaTime, vector NewAccel, eDoubleClickDir DoubleClickMove, rotator DeltaRot)    
  3277.     {
  3278.         local vector OldAccel;
  3279.  
  3280.         OldAccel = Pawn.Acceleration;
  3281.         Pawn.Acceleration = NewAccel;
  3282.  
  3283.         if ( bPressedJump )
  3284.             Pawn.DoJump(bUpdating);
  3285.     }
  3286.  
  3287.     function PlayerMove( float DeltaTime )
  3288.     {
  3289.         local vector NewAccel;
  3290.         local eDoubleClickDir DoubleClickMove;
  3291.         local rotator OldRotation, ViewRotation;
  3292.         local bool    bSaveJump;
  3293.  
  3294.         GroundPitch = 0;    
  3295.         ViewRotation = Rotation;
  3296.  
  3297.         if ( !bKeyboardLook && (bLook == 0) && bCenterView )
  3298.         {
  3299.             // FIXME - center view rotation based on current floor
  3300.         }
  3301.         Pawn.CheckBob(DeltaTime,vect(0,0,0));
  3302.  
  3303.         // Update rotation.
  3304.         SetRotation(ViewRotation);
  3305.         OldRotation = Rotation;
  3306.         UpdateRotation(DeltaTime, 1);
  3307.  
  3308.         // Update acceleration.
  3309.         NewAccel = aForward*Normal(ViewX - OldFloor * (OldFloor Dot ViewX)) + aStrafe*ViewY; 
  3310.         if ( VSize(NewAccel) < 1.0 )
  3311.             NewAccel = vect(0,0,0);
  3312.  
  3313.         if ( bPressedJump && Pawn.CannotJumpNow() )
  3314.         {
  3315.             bSaveJump = true;
  3316.             bPressedJump = false;
  3317.         }
  3318.         else
  3319.             bSaveJump = false;
  3320.  
  3321.         if ( Role < ROLE_Authority ) // then save this move and replicate it
  3322.             ReplicateMove(DeltaTime, NewAccel, DoubleClickMove, OldRotation - Rotation);
  3323.         else
  3324.             ProcessMove(DeltaTime, NewAccel, DoubleClickMove, OldRotation - Rotation);
  3325.         bPressedJump = bSaveJump;
  3326.     }
  3327.  
  3328.     function BeginState()
  3329.     {
  3330.         if ( Pawn.Mesh == None )
  3331.             Pawn.SetMesh();
  3332.         OldFloor = vect(0,0,1);
  3333.         GetAxes(Rotation,ViewX,ViewY,ViewZ);
  3334.         DoubleClickDir = DCLICK_None;
  3335.         Pawn.ShouldCrouch(false);
  3336.         bPressedJump = false;
  3337.         if (Pawn.Physics != PHYS_Falling) 
  3338.             Pawn.SetPhysics(PHYS_Spider);
  3339.         GroundPitch = 0;
  3340.         Pawn.bCrawler = true;
  3341.         Pawn.SetCollisionSize(Pawn.Default.CollisionHeight,Pawn.Default.CollisionHeight);
  3342.     }
  3343.     
  3344.     function EndState()
  3345.     {
  3346.         GroundPitch = 0;
  3347.         if ( Pawn != None )
  3348.         {
  3349.             Pawn.SetCollisionSize(Pawn.Default.CollisionRadius,Pawn.Default.CollisionHeight);
  3350.             Pawn.ShouldCrouch(false);
  3351.             Pawn.bCrawler = Pawn.Default.bCrawler;
  3352.         }
  3353.     }
  3354. }
  3355.     
  3356. // Player movement.
  3357. // Player Swimming
  3358. state PlayerSwimming
  3359. {
  3360. ignores SeePlayer, HearNoise, Bump;
  3361.  
  3362.     function bool WantsSmoothedView()
  3363.     {
  3364.         return ( !Pawn.bJustLanded );
  3365.     }
  3366.  
  3367.     function bool NotifyLanded(vector HitNormal)
  3368.     {
  3369.         if ( Pawn.PhysicsVolume.bWaterVolume )
  3370.             Pawn.SetPhysics(PHYS_Swimming);
  3371.         else
  3372.             GotoState(Pawn.LandMovementState);
  3373.         return bUpdating;
  3374.     }
  3375.     
  3376.     function bool NotifyPhysicsVolumeChange( PhysicsVolume NewVolume )
  3377.     {
  3378.         local actor HitActor;
  3379.         local vector HitLocation, HitNormal, checkpoint;
  3380.  
  3381.         if ( !NewVolume.bWaterVolume )
  3382.         {
  3383.             Pawn.SetPhysics(PHYS_Falling);
  3384.             if ( Pawn.Velocity.Z > 0 )
  3385.             {
  3386.                 if (Pawn.bUpAndOut && Pawn.CheckWaterJump(HitNormal)) //check for waterjump
  3387.                 {
  3388.                     Pawn.velocity.Z = FMax(Pawn.JumpZ,420) + 2 * Pawn.CollisionRadius; //set here so physics uses this for remainder of tick
  3389.                     GotoState(Pawn.LandMovementState);
  3390.                 }                
  3391.                 else if ( (Pawn.Velocity.Z > 160) || !Pawn.TouchingWaterVolume() )
  3392.                     GotoState(Pawn.LandMovementState);
  3393.                 else //check if in deep water
  3394.                 {
  3395.                     checkpoint = Pawn.Location;
  3396.                     checkpoint.Z -= (Pawn.CollisionHeight + 6.0);
  3397.                     HitActor = Trace(HitLocation, HitNormal, checkpoint, Pawn.Location, false);
  3398.                     if (HitActor != None)
  3399.                         GotoState(Pawn.LandMovementState);
  3400.                     else
  3401.                     {
  3402.                         Enable('Timer');
  3403.                         SetTimer(0.7,false);
  3404.                     }
  3405.                 }
  3406.             }
  3407.         }
  3408.         else
  3409.         {
  3410.             Disable('Timer');
  3411.             Pawn.SetPhysics(PHYS_Swimming);
  3412.         }
  3413.         return false;
  3414.     }
  3415.  
  3416.     function ProcessMove(float DeltaTime, vector NewAccel, eDoubleClickDir DoubleClickMove, rotator DeltaRot)    
  3417.     {
  3418.         local vector X,Y,Z, OldAccel;
  3419.     
  3420.         GetAxes(Rotation,X,Y,Z);
  3421.         OldAccel = Pawn.Acceleration;
  3422.         Pawn.Acceleration = NewAccel;
  3423.         Pawn.bUpAndOut = ((X Dot Pawn.Acceleration) > 0) && ((Pawn.Acceleration.Z > 0) || (Rotation.Pitch > 2048));
  3424.         if ( !Pawn.PhysicsVolume.bWaterVolume ) //check for waterjump
  3425.             NotifyPhysicsVolumeChange(Pawn.PhysicsVolume);
  3426.     }
  3427.  
  3428.     function PlayerMove(float DeltaTime)
  3429.     {
  3430.         local rotator oldRotation;
  3431.         local vector X,Y,Z, NewAccel;
  3432.     
  3433.         GetAxes(Rotation,X,Y,Z);
  3434.  
  3435.         NewAccel = aForward*X + aStrafe*Y + aUp*vect(0,0,1); 
  3436.         if ( VSize(NewAccel) < 1.0 )
  3437.             NewAccel = vect(0,0,0);
  3438.     
  3439.         //add bobbing when swimming
  3440.         Pawn.CheckBob(DeltaTime, Y);
  3441.  
  3442.         // Update rotation.
  3443.         oldRotation = Rotation;
  3444.         UpdateRotation(DeltaTime, 2);
  3445.  
  3446.         if ( Role < ROLE_Authority ) // then save this move and replicate it
  3447.             ReplicateMove(DeltaTime, NewAccel, DCLICK_None, OldRotation - Rotation);
  3448.         else
  3449.             ProcessMove(DeltaTime, NewAccel, DCLICK_None, OldRotation - Rotation);
  3450.         bPressedJump = false;
  3451.     }
  3452.  
  3453.     function Timer()
  3454.     {
  3455.         if ( !Pawn.PhysicsVolume.bWaterVolume && (Role == ROLE_Authority) )
  3456.             GotoState(Pawn.LandMovementState);
  3457.     
  3458.         Disable('Timer');
  3459.     }
  3460.     
  3461.     function BeginState()
  3462.     {
  3463.         Disable('Timer');
  3464.         Pawn.SetPhysics(PHYS_Swimming);
  3465.     }
  3466. }
  3467.  
  3468. state PlayerFlying
  3469. {
  3470. ignores SeePlayer, HearNoise, Bump;
  3471.  
  3472.     function PlayerMove(float DeltaTime)
  3473.     {
  3474.         local vector X,Y,Z;
  3475.  
  3476.         GetAxes(Rotation,X,Y,Z);
  3477.  
  3478.         Pawn.Acceleration = aForward*X + aStrafe*Y; 
  3479.         if ( VSize(Pawn.Acceleration) < 1.0 )
  3480.             Pawn.Acceleration = vect(0,0,0);
  3481.         if ( bCheatFlying && (Pawn.Acceleration == vect(0,0,0)) )
  3482.             Pawn.Velocity = vect(0,0,0);
  3483.         // Update rotation.
  3484.         UpdateRotation(DeltaTime, 2);
  3485.         
  3486.         if ( Role < ROLE_Authority ) // then save this move and replicate it
  3487.             ReplicateMove(DeltaTime, Pawn.Acceleration, DCLICK_None, rot(0,0,0));
  3488.         else
  3489.             ProcessMove(DeltaTime, Pawn.Acceleration, DCLICK_None, rot(0,0,0));
  3490.     }
  3491.     
  3492.     function BeginState()
  3493.     {
  3494.         Pawn.SetPhysics(PHYS_Flying);
  3495.     }
  3496. }
  3497.  
  3498. state PlayerRocketing
  3499. {
  3500. ignores SeePlayer, HearNoise, Bump;
  3501.  
  3502.     /* ServerMove() 
  3503.     - replicated function sent by client to server - contains client movement and firing info
  3504.     Passes acceleration in components so it doesn't get rounded.
  3505.     IGNORE VANILLA SERVER MOVES
  3506.     */
  3507.     function ServerMove
  3508.     (
  3509.         float TimeStamp, 
  3510.         vector InAccel, 
  3511.         vector ClientLoc,
  3512.         bool NewbRun,
  3513.         bool NewbDuck,
  3514.         bool NewbJumpStatus, 
  3515.         bool NewbDoubleJump,
  3516.         eDoubleClickDir DoubleClickMove, 
  3517.         byte ClientRoll, 
  3518.         int View,
  3519.         optional byte OldTimeDelta,
  3520.         optional int OldAccel
  3521.     )
  3522.     {
  3523.         if ( CurrentTimeStamp < TimeStamp )
  3524.            Pawn.AutonomousPhysics(TimeStamp - CurrentTimeStamp);
  3525.         CurrentTimeStamp = TimeStamp;
  3526.         ServerTimeStamp = Level.TimeSeconds;
  3527.     }    
  3528.  
  3529.     function RocketServerMove
  3530.     (
  3531.         float TimeStamp, 
  3532.         vector InAccel, 
  3533.         vector ClientLoc,
  3534.         byte ClientRoll, 
  3535.         int View
  3536.     )
  3537.     {
  3538.         //if ( InAccel Dot Pawn.Velocity < 0 )
  3539.         //    InAccel = 0.1 * Pawn.AccelRate * Normal(Pawn.Velocity);
  3540.         Global.ServerMove(TimeStamp,InAccel,ClientLoc,false,false,false,false, DCLICK_NONE,ClientRoll,View);
  3541.     }    
  3542.         
  3543.     function PlayerMove(float DeltaTime)
  3544.     {
  3545.         Pawn.UpdateRocketAcceleration(DeltaTime,aTurn,aLookUp);
  3546.         SetRotation(Pawn.Rotation);        
  3547.         if ( Role < ROLE_Authority ) // then save this move and replicate it
  3548.             ReplicateMove(DeltaTime, Pawn.Acceleration, DCLICK_None, rot(0,0,0));
  3549.         else
  3550.             ProcessMove(DeltaTime, Pawn.Acceleration, DCLICK_None, rot(0,0,0));
  3551.     }
  3552.     
  3553.     function BeginState()
  3554.     {
  3555.         Pawn.SetPhysics(PHYS_Flying);
  3556.     }
  3557. }
  3558.  
  3559. function bool IsSpectating()
  3560. {
  3561.     return false;
  3562. }
  3563.  
  3564. state BaseSpectating
  3565. {
  3566.     function bool IsSpectating()
  3567.     {
  3568.         return true;
  3569.     }
  3570.  
  3571.     function ProcessMove(float DeltaTime, vector NewAccel, eDoubleClickDir DoubleClickMove, rotator DeltaRot)    
  3572.     {
  3573.         Acceleration = NewAccel;
  3574.         MoveSmooth(SpectateSpeed * Normal(Acceleration) * DeltaTime);
  3575.     }
  3576.  
  3577.     function PlayerMove(float DeltaTime)
  3578.     {
  3579.         local vector X,Y,Z;
  3580.  
  3581.         if ( (Pawn(ViewTarget) != None) && (Level.NetMode == NM_Client) )
  3582.         {
  3583.             if ( Pawn(ViewTarget).bSimulateGravity )
  3584.                 TargetViewRotation.Roll = 0;
  3585.             BlendedTargetViewRotation.Pitch = BlendRot(DeltaTime, BlendedTargetViewRotation.Pitch, TargetViewRotation.Pitch & 65535);
  3586.             BlendedTargetViewRotation.Yaw = BlendRot(DeltaTime, BlendedTargetViewRotation.Yaw, TargetViewRotation.Yaw & 65535);
  3587.             BlendedTargetViewRotation.Roll = BlendRot(DeltaTime, BlendedTargetViewRotation.Roll, TargetViewRotation.Roll & 65535);
  3588.         }
  3589.         GetAxes(Rotation,X,Y,Z);
  3590.     
  3591.         Acceleration = 0.02 * (aForward*X + aStrafe*Y + aUp*vect(0,0,1));  
  3592.  
  3593.         UpdateRotation(DeltaTime, 1);
  3594.  
  3595.         if ( Role < ROLE_Authority ) // then save this move and replicate it
  3596.             ReplicateMove(DeltaTime, Acceleration, DCLICK_None, rot(0,0,0));
  3597.         else
  3598.             ProcessMove(DeltaTime, Acceleration, DCLICK_None, rot(0,0,0));
  3599.     }
  3600. }
  3601.  
  3602. state Scripting
  3603. {
  3604.     // FIXME - IF HIT FIRE, AND NOT bInterpolating, Leave script
  3605.     exec function Fire( optional float F )
  3606.     {
  3607.     }
  3608.  
  3609.     exec function AltFire( optional float F )
  3610.     {
  3611.         Fire(F);
  3612.     }
  3613. }
  3614.  
  3615. function ServerViewNextPlayer()
  3616. {
  3617.     local Controller C, Pick;
  3618.     local bool bFound, bRealSpec, bWasSpec;
  3619.     local TeamInfo RealTeam;
  3620.  
  3621.     bRealSpec = PlayerReplicationInfo.bOnlySpectator;
  3622.     bWasSpec = !bBehindView && (ViewTarget != Pawn) && (ViewTarget != self);
  3623.     PlayerReplicationInfo.bOnlySpectator = true;
  3624.     RealTeam = PlayerReplicationInfo.Team;
  3625.     
  3626.     // view next player
  3627.     for ( C=Level.ControllerList; C!=None; C=C.NextController )
  3628.     {
  3629.         if ( Level.Game.CanSpectate(self,true,C) )
  3630.         {
  3631.             if ( Pick == None )
  3632.                 Pick = C;
  3633.             if ( bFound )
  3634.             {
  3635.                 Pick = C;
  3636.                 break;
  3637.             }    
  3638.             else
  3639.                 bFound = ( (RealViewTarget == C) || (ViewTarget == C) );
  3640.         }
  3641.     }
  3642.     PlayerReplicationInfo.Team = RealTeam;
  3643.     SetViewTarget(Pick);
  3644.     ClientSetViewTarget(Pick);
  3645.     if ( (ViewTarget == self) || bWasSpec )
  3646.         bBehindView = false;
  3647.     else
  3648.         bBehindView = true; //bChaseCam;
  3649.     ClientSetBehindView(bBehindView);
  3650.     PlayerReplicationInfo.bOnlySpectator = bRealSpec;
  3651. }
  3652.  
  3653. function ServerViewSelf()
  3654. {
  3655.     bBehindView = false;
  3656.     SetViewTarget(self);
  3657.     ClientSetViewTarget(self);
  3658.     ClientMessage(OwnCamera, 'Event');
  3659. }
  3660.  
  3661. function LoadPlayers()
  3662. {
  3663.     local int i;
  3664.     
  3665.     if ( GameReplicationInfo == None )
  3666.         return;
  3667.         
  3668.     for ( i=0; i<GameReplicationInfo.PRIArray.Length; i++ )
  3669.         GameReplicationInfo.PRIArray[i].UpdatePrecacheMaterials();
  3670. }
  3671.  
  3672. state Spectating extends BaseSpectating
  3673. {
  3674.     ignores SwitchWeapon, RestartLevel, ClientRestart, Suicide,
  3675.      ThrowWeapon, NotifyPhysicsVolumeChange, NotifyHeadVolumeChange;
  3676.  
  3677.     exec function Fire( optional float F )
  3678.     {
  3679.         ServerViewNextPlayer();
  3680.     }
  3681.  
  3682.     // Return to spectator's own camera.
  3683.     exec function AltFire( optional float F )
  3684.     {
  3685.         bBehindView = false;
  3686.         ServerViewSelf();
  3687.     }
  3688.  
  3689.     function BeginState()
  3690.     {
  3691.         if ( Pawn != None )
  3692.         {
  3693.             SetLocation(Pawn.Location);
  3694.             UnPossess();
  3695.         }
  3696.         bCollideWorld = true;
  3697.     }
  3698.  
  3699.     function EndState()
  3700.     {
  3701.         PlayerReplicationInfo.bIsSpectator = false;        
  3702.         bCollideWorld = false;
  3703.     }
  3704. }
  3705.  
  3706. auto state PlayerWaiting extends BaseSpectating
  3707. {
  3708. ignores SeePlayer, HearNoise, NotifyBump, TakeDamage, PhysicsVolumeChange, NextWeapon, PrevWeapon, SwitchToBestWeapon;
  3709.  
  3710.     exec function Jump( optional float F )
  3711.     {
  3712.     }
  3713.  
  3714.     exec function Suicide()
  3715.     {
  3716.     }
  3717.  
  3718.     function ChangeTeam( int N )
  3719.     {
  3720.         Level.Game.ChangeTeam(self, N, true);
  3721.     }
  3722.  
  3723.     function ServerRestartPlayer()
  3724.     {
  3725.         if ( Level.TimeSeconds < WaitDelay )
  3726.             return;
  3727.         if ( Level.NetMode == NM_Client )
  3728.             return;
  3729.         if ( Level.Game.bWaitingToStartMatch )
  3730.             PlayerReplicationInfo.bReadyToPlay = true;
  3731.         else
  3732.             Level.Game.RestartPlayer(self);
  3733.     }
  3734.  
  3735.     exec function Fire(optional float F)
  3736.     {
  3737.         LoadPlayers();
  3738.         ServerReStartPlayer();
  3739.     }
  3740.     
  3741.     exec function AltFire(optional float F)
  3742.     {
  3743.         Fire(F);
  3744.     }
  3745.  
  3746.     function EndState()
  3747.     {
  3748.         if ( Pawn != None )
  3749.             Pawn.SetMesh();
  3750.         if ( PlayerReplicationInfo != None )
  3751.         PlayerReplicationInfo.SetWaitingPlayer(false);
  3752.         bCollideWorld = false;
  3753.     }
  3754.  
  3755.     function BeginState()
  3756.     {
  3757.         if ( PlayerReplicationInfo != None )
  3758.             PlayerReplicationInfo.SetWaitingPlayer(true);
  3759.         bCollideWorld = true;
  3760.     }
  3761. }
  3762.  
  3763. state WaitingForPawn extends BaseSpectating
  3764. {
  3765. ignores SeePlayer, HearNoise, KilledBy, SwitchWeapon;
  3766.  
  3767.     exec function Fire( optional float F )
  3768.     {
  3769.         AskForPawn();
  3770.     }
  3771.  
  3772.     exec function AltFire( optional float F )
  3773.     {
  3774.     }
  3775.  
  3776.     function LongClientAdjustPosition
  3777.     (
  3778.         float TimeStamp, 
  3779.         name newState, 
  3780.         EPhysics newPhysics,
  3781.         float NewLocX, 
  3782.         float NewLocY, 
  3783.         float NewLocZ, 
  3784.         float NewVelX, 
  3785.         float NewVelY, 
  3786.         float NewVelZ,
  3787.         Actor NewBase,
  3788.         float NewFloorX,
  3789.         float NewFloorY,
  3790.         float NewFloorZ
  3791.     )
  3792.     {
  3793.         if ( newState == 'GameEnded' )
  3794.             GotoState(newState);
  3795.     }
  3796.  
  3797.     function PlayerTick(float DeltaTime)
  3798.     {
  3799.         Global.PlayerTick(DeltaTime);
  3800.  
  3801.         if ( Pawn != None )
  3802.         {
  3803.             Pawn.Controller = self;
  3804.             Pawn.bUpdateEyeHeight = true;
  3805.             ClientRestart();
  3806.         }
  3807.         else if ( (TimerRate <= 0.0) || (TimerRate > 1.0) )
  3808.         {
  3809.             SetTimer(0.2,true);
  3810.             AskForPawn();
  3811.         }
  3812.     }
  3813.  
  3814.     function Timer()
  3815.     {
  3816.         AskForPawn();
  3817.     }
  3818.  
  3819.     function BeginState()
  3820.     {
  3821.         SetTimer(0.2, true);
  3822.         AskForPawn();
  3823.     }
  3824.  
  3825.     function EndState()
  3826.     {
  3827.         bBehindView = false;
  3828.         SetTimer(0.0, false);
  3829.     }
  3830. }
  3831.  
  3832. state GameEnded
  3833. {
  3834. ignores SeePlayer, HearNoise, KilledBy, NotifyBump, HitWall, NotifyHeadVolumeChange, NotifyPhysicsVolumeChange, Falling, TakeDamage, Suicide;
  3835.  
  3836.     function ServerReStartPlayer()
  3837.     {
  3838.     }
  3839.     
  3840.     function bool IsSpectating()
  3841.     {
  3842.         return true;
  3843.     }
  3844.     
  3845.     exec function ThrowWeapon()
  3846.     {
  3847.     }
  3848.  
  3849.     function ServerReStartGame()
  3850.     {
  3851.         Level.Game.RestartGame();
  3852.     }
  3853.  
  3854.     exec function Fire( optional float F )
  3855.     {
  3856.         if ( Role < ROLE_Authority)
  3857.             return;
  3858.         if ( !bFrozen )
  3859.             ServerReStartGame();
  3860.         else if ( TimerRate <= 0 )
  3861.             SetTimer(1.5, false);
  3862.     }
  3863.     
  3864.     exec function AltFire( optional float F )
  3865.     {
  3866.         Fire(F);
  3867.     }
  3868.  
  3869.     function PlayerMove(float DeltaTime)
  3870.     {
  3871.         local vector X,Y,Z;
  3872.         local Rotator ViewRotation;
  3873.  
  3874.         GetAxes(Rotation,X,Y,Z);
  3875.         // Update view rotation.
  3876.  
  3877.         if ( !bFixedCamera )
  3878.         {
  3879.             ViewRotation = Rotation;
  3880.             ViewRotation.Yaw += 32.0 * DeltaTime * aTurn;
  3881.             ViewRotation.Pitch += 32.0 * DeltaTime * aLookUp;
  3882.             ViewRotation.Pitch = ViewRotation.Pitch & 65535;
  3883.             If ((ViewRotation.Pitch > 18000) && (ViewRotation.Pitch < 49152))
  3884.             {
  3885.                 If (aLookUp > 0) 
  3886.                     ViewRotation.Pitch = 18000;
  3887.                 else
  3888.                     ViewRotation.Pitch = 49152;
  3889.             }
  3890.             SetRotation(ViewRotation);
  3891.         }
  3892.         else if ( ViewTarget != None )
  3893.             SetRotation(ViewTarget.Rotation);
  3894.  
  3895.         ViewShake(DeltaTime);
  3896.         ViewFlash(DeltaTime);
  3897.  
  3898.         if ( Role < ROLE_Authority ) // then save this move and replicate it
  3899.             ReplicateMove(DeltaTime, vect(0,0,0), DCLICK_None, rot(0,0,0));
  3900.         else
  3901.             ProcessMove(DeltaTime, vect(0,0,0), DCLICK_None, rot(0,0,0));
  3902.         bPressedJump = false;
  3903.     }
  3904.  
  3905.     function ServerMove
  3906.     (
  3907.         float TimeStamp, 
  3908.         vector InAccel, 
  3909.         vector ClientLoc,
  3910.         bool NewbRun,
  3911.         bool NewbDuck,
  3912.         bool NewbJumpStatus, 
  3913.         bool NewbDoubleJump, 
  3914.         eDoubleClickDir DoubleClickMove, 
  3915.         byte ClientRoll, 
  3916.         int View,
  3917.         optional byte OldTimeDelta,
  3918.         optional int OldAccel
  3919.     )
  3920.     {
  3921.         Global.ServerMove(TimeStamp, InAccel, ClientLoc, NewbRun, NewbDuck, NewbJumpStatus,NewbDoubleJump,
  3922.                             DoubleClickMove, ClientRoll, (32767 & (Rotation.Pitch/2)) * 32768 + (32767 & (Rotation.Yaw/2)) );
  3923.  
  3924.     }
  3925.  
  3926.     function FindGoodView()
  3927.     {
  3928.         local vector cameraLoc;
  3929.         local rotator cameraRot, ViewRotation;
  3930.         local int tries, besttry;
  3931.         local float bestdist, newdist;
  3932.         local int startYaw;
  3933.         local actor ViewActor;
  3934.         
  3935.         ViewRotation = Rotation;
  3936.         ViewRotation.Pitch = 56000;
  3937.         tries = 0;
  3938.         besttry = 0;
  3939.         bestdist = 0.0;
  3940.         startYaw = ViewRotation.Yaw;
  3941.         
  3942.         for (tries=0; tries<16; tries++)
  3943.         {
  3944.             cameraLoc = ViewTarget.Location;
  3945.             SetRotation(ViewRotation);
  3946.             PlayerCalcView(ViewActor, cameraLoc, cameraRot);
  3947.             newdist = VSize(cameraLoc - ViewTarget.Location);
  3948.             if (newdist > bestdist)
  3949.             {
  3950.                 bestdist = newdist;    
  3951.                 besttry = tries;
  3952.             }
  3953.             ViewRotation.Yaw += 4096;
  3954.         }
  3955.             
  3956.         ViewRotation.Yaw = startYaw + besttry * 4096;
  3957.         SetRotation(ViewRotation);
  3958.     }
  3959.     
  3960.     function Timer()
  3961.     {
  3962.         bFrozen = false;
  3963.     }
  3964.     
  3965.     function LongClientAdjustPosition
  3966.     (
  3967.         float TimeStamp, 
  3968.         name newState, 
  3969.         EPhysics newPhysics,
  3970.         float NewLocX, 
  3971.         float NewLocY, 
  3972.         float NewLocZ, 
  3973.         float NewVelX, 
  3974.         float NewVelY, 
  3975.         float NewVelZ,
  3976.         Actor NewBase,
  3977.         float NewFloorX,
  3978.         float NewFloorY,
  3979.         float NewFloorZ
  3980.     )
  3981.     {   
  3982.     }
  3983.          
  3984.     function BeginState()
  3985.     {
  3986.         local Pawn P;
  3987.  
  3988.         EndZoom();
  3989.         FOVAngle = DesiredFOV;
  3990.         bFire = 0;
  3991.         bAltFire = 0;
  3992.         if ( Pawn != None )
  3993.         {
  3994.             Pawn.Velocity = vect(0,0,0);
  3995.             Pawn.SetPhysics(PHYS_None);
  3996.             Pawn.AmbientSound = None;
  3997.             Pawn.bSpecialHUD = false;
  3998.              Pawn.bNoWeaponFiring = true;
  3999.             Pawn.SimAnim.AnimRate = 0;
  4000.             Pawn.bPhysicsAnimUpdate = false;
  4001.             Pawn.StopAnimating();
  4002.             Pawn.SetCollision(true,false,false);
  4003.             StopFiring();
  4004.              Pawn.bIgnoreForces = true;
  4005.         }
  4006.         myHUD.bShowScores = true;
  4007.         bFrozen = true;
  4008.         if ( !bFixedCamera )
  4009.         {
  4010.             FindGoodView();
  4011.             bBehindView = true;
  4012.         }
  4013.         SetTimer(5, false);
  4014.         ForEach DynamicActors(class'Pawn', P)
  4015.         {
  4016.             if ( P.Role == ROLE_Authority )
  4017.                 P.RemoteRole = ROLE_DumbProxy;
  4018.             P.SetCollision(true,false,false);
  4019.             P.AmbientSound = None;
  4020.              P.bNoWeaponFiring = true;
  4021.             P.Velocity = vect(0,0,0);
  4022.             P.SetPhysics(PHYS_None);
  4023.             P.bPhysicsAnimUpdate = false;
  4024.             P.StopAnimating();
  4025.             P.bIgnoreForces = true;
  4026.         }
  4027.     }
  4028.  
  4029. Begin:
  4030. }
  4031.  
  4032. state Dead
  4033. {
  4034. ignores SeePlayer, HearNoise, KilledBy, SwitchWeapon, NextWeapon, PrevWeapon;
  4035.  
  4036.     function bool IsDead()
  4037.     {
  4038.         return true;
  4039.     }
  4040.  
  4041.     function ServerReStartPlayer()
  4042.     {
  4043.         Super.ServerRestartPlayer();
  4044.     }
  4045.  
  4046.     exec function Fire( optional float F )
  4047.     {
  4048.         if ( bFrozen )
  4049.         {
  4050.             if ( (TimerRate <= 0.0) || (TimerRate > 1.0) )
  4051.                 bFrozen = false;
  4052.             return;
  4053.         }
  4054.         LoadPlayers();
  4055.         ServerReStartPlayer();
  4056.     }
  4057.     
  4058.     exec function AltFire( optional float F )
  4059.     {
  4060.             Fire(F);
  4061.     }
  4062.  
  4063.     function ServerMove
  4064.     (
  4065.         float TimeStamp, 
  4066.         vector Accel, 
  4067.         vector ClientLoc,
  4068.         bool NewbRun,
  4069.         bool NewbDuck,
  4070.         bool NewbJumpStatus,
  4071.         bool NewbDoubleJump,
  4072.         eDoubleClickDir DoubleClickMove, 
  4073.         byte ClientRoll, 
  4074.         int View,
  4075.         optional byte OldTimeDelta,
  4076.         optional int OldAccel
  4077.     )
  4078.     {
  4079.         Global.ServerMove(
  4080.                     TimeStamp,
  4081.                     Accel, 
  4082.                     ClientLoc,
  4083.                     false,
  4084.                     false,
  4085.                     false,
  4086.                     false,
  4087.                     DoubleClickMove, 
  4088.                     ClientRoll, 
  4089.                     View);
  4090.     }
  4091.  
  4092.     function PlayerMove(float DeltaTime)
  4093.     {
  4094.         local vector X,Y,Z;
  4095.         local rotator ViewRotation;
  4096.  
  4097.         if ( !bFrozen )
  4098.         {
  4099.             if ( bPressedJump )
  4100.             {
  4101.                 Fire(0);
  4102.                 bPressedJump = false;
  4103.             }
  4104.             GetAxes(Rotation,X,Y,Z);
  4105.             // Update view rotation.
  4106.             ViewRotation = Rotation;
  4107.             ViewRotation.Yaw += 32.0 * DeltaTime * aTurn;
  4108.             ViewRotation.Pitch += 32.0 * DeltaTime * aLookUp;
  4109.             ViewRotation.Pitch = ViewRotation.Pitch & 65535;
  4110.             If ((ViewRotation.Pitch > 18000) && (ViewRotation.Pitch < 49152))
  4111.             {
  4112.                 If (aLookUp > 0) 
  4113.                     ViewRotation.Pitch = 18000;
  4114.                 else
  4115.                     ViewRotation.Pitch = 49152;
  4116.             }
  4117.             SetRotation(ViewRotation);
  4118.             if ( Role < ROLE_Authority ) // then save this move and replicate it
  4119.                 ReplicateMove(DeltaTime, vect(0,0,0), DCLICK_None, rot(0,0,0));
  4120.         }
  4121.         else if ( (TimerRate <= 0.0) || (TimerRate > 1.0) )
  4122.             bFrozen = false;
  4123.  
  4124.         ViewShake(DeltaTime);
  4125.         ViewFlash(DeltaTime);
  4126.     }
  4127.  
  4128.     function FindGoodView()
  4129.     {
  4130.         local vector cameraLoc;
  4131.         local rotator cameraRot, ViewRotation;
  4132.         local int tries, besttry;
  4133.         local float bestdist, newdist;
  4134.         local int startYaw;
  4135.         local actor ViewActor;
  4136.         
  4137.         ////log("Find good death scene view");
  4138.         ViewRotation = Rotation;
  4139.         ViewRotation.Pitch = 56000;
  4140.         tries = 0;
  4141.         besttry = 0;
  4142.         bestdist = 0.0;
  4143.         startYaw = ViewRotation.Yaw;
  4144.         
  4145.         for (tries=0; tries<16; tries++)
  4146.         {
  4147.             cameraLoc = ViewTarget.Location;
  4148.             SetRotation(ViewRotation);
  4149.             PlayerCalcView(ViewActor, cameraLoc, cameraRot);
  4150.             newdist = VSize(cameraLoc - ViewTarget.Location);
  4151.             if (newdist > bestdist)
  4152.             {
  4153.                 bestdist = newdist;    
  4154.                 besttry = tries;
  4155.             }
  4156.             ViewRotation.Yaw += 4096;
  4157.         }
  4158.             
  4159.         ViewRotation.Yaw = startYaw + besttry * 4096;
  4160.         SetRotation(ViewRotation);
  4161.     }
  4162.     
  4163.     function Timer()
  4164.     {
  4165.         if (!bFrozen)
  4166.             return;
  4167.             
  4168.         bFrozen = false;
  4169.         bPressedJump = false;
  4170.     }
  4171.     
  4172.     function BeginState()
  4173.     {
  4174.         if ( (Pawn != None) && (Pawn.Controller == self) )
  4175.             Pawn.Controller = None;
  4176.         EndZoom();
  4177.         FOVAngle = DesiredFOV;
  4178.         Pawn = None;
  4179.         Enemy = None;
  4180.         bBehindView = true;
  4181.         bFrozen = true;
  4182.         bJumpStatus = false;
  4183.         bPressedJump = false;
  4184.         bBlockCloseCamera = true;
  4185.         bValidBehindCamera = false;
  4186.         FindGoodView();
  4187.         SetTimer(1.0, false); 
  4188.         StopForceFeedback();
  4189.         ClientPlayForceFeedback("Damage");  // jdf
  4190.         CleanOutSavedMoves();
  4191.     }
  4192.     
  4193.     function EndState()
  4194.     {
  4195.         bBlockCloseCamera = false;
  4196.         CleanOutSavedMoves();
  4197.         Velocity = vect(0,0,0);
  4198.         Acceleration = vect(0,0,0);
  4199.         if ( !PlayerReplicationInfo.bOutOfLives )
  4200.         bBehindView = false;
  4201.         bPressedJump = false;
  4202.         myHUD.bShowScores = false;
  4203. }
  4204. Begin:
  4205.     Sleep(3.0);
  4206.     myHUD.bShowScores = true;
  4207. }
  4208.  
  4209. //------------------------------------------------------------------------------
  4210. // Control options    
  4211. function ChangeStairLook( bool B )
  4212. {
  4213.     bLookUpStairs = B;
  4214.     if ( bLookUpStairs )
  4215.         bAlwaysMouseLook = false;
  4216. }
  4217.  
  4218. function ChangeAlwaysMouseLook(Bool B)
  4219. {
  4220.     bAlwaysMouseLook = B;
  4221.     if ( bAlwaysMouseLook )
  4222.         bLookUpStairs = false;
  4223. }
  4224.  
  4225. // Replace with good code
  4226.  
  4227. event ClientOpenMenu (string Menu, optional bool bDisconnect,optional string Msg1, optional string Msg2)
  4228. {
  4229.     Player.GUIController.OpenMenu(Menu, Msg1, Msg2);
  4230.     if (bDisconnect)
  4231.         ConsoleCommand("Disconnect");
  4232. }
  4233.  
  4234. event ClientCloseMenu(optional bool bCloseAll, optional bool bCancel)
  4235. {
  4236.     if (bCloseAll)
  4237.         Player.GUIController.CloseAll(bCancel);
  4238.     else
  4239.         Player.GUIController.CloseMenu(bCancel);
  4240. }
  4241.  
  4242. function bool CanRestartPlayer()
  4243. {
  4244.     return !PlayerReplicationInfo.bOnlySpectator;
  4245. }
  4246.  
  4247. event ServerChangeVoiceChatter( PlayerController Player, int IpAddr, int Handle, bool Add )
  4248. {
  4249.     if( (Level.NetMode == NM_DedicatedServer) || (Level.NetMode == NM_ListenServer) )
  4250.     {
  4251.         Level.Game.ChangeVoiceChatter( Player, IpAddr, Handle, Add );
  4252.     }
  4253. }
  4254.  
  4255. event ServerGetVoiceChatters( PlayerController Player )
  4256. {
  4257.     local int i;
  4258.     
  4259.     if( (Level.NetMode == NM_DedicatedServer) || (Level.NetMode == NM_ListenServer) )
  4260.     {
  4261.         for( i=0; i<Level.Game.VoiceChatters.Length; i++ )
  4262.         {
  4263.             if( Player != Level.Game.VoiceChatters[i].Controller )
  4264.             {
  4265.                 Player.ClientChangeVoiceChatter( Level.Game.VoiceChatters[i].IpAddr, Level.Game.VoiceChatters[i].Handle, true );
  4266.             }
  4267.         }
  4268.     }
  4269. }
  4270.  
  4271. simulated function ClientChangeVoiceChatter( int IpAddr, int Handle, bool Add )
  4272. {
  4273.     ChangeVoiceChatter( IpAddr, Handle, Add );
  4274. }
  4275.     
  4276. simulated function ClientLeaveVoiceChat()
  4277. {
  4278.     LeaveVoiceChat();
  4279. }
  4280.     
  4281. native final function LeaveVoiceChat();
  4282. native final function ChangeVoiceChatter( int IpAddr, int Handle, bool Add );
  4283.     
  4284. //--------------------- Demo recording stuff
  4285.  
  4286. // Called on the client during client-side demo recording
  4287. simulated event StartClientDemoRec()
  4288. {
  4289.     // Here we replicate functions which the demo never saw.
  4290.     DemoClientSetHUD( MyHud.Class, MyHud.ScoreBoard.Class );
  4291.     
  4292.     // tell server to replicate more stuff to me
  4293.     bClientDemo = true;
  4294.     ServerSetClientDemo();
  4295. }
  4296.  
  4297. function ServerSetClientDemo()
  4298. {
  4299.     bClientDemo = true;
  4300. }
  4301.  
  4302. // Called on the playback client during client-side demo playback
  4303. simulated function DemoClientSetHUD(class<HUD> newHUDClass, class<Scoreboard> newScoringClass )
  4304. {
  4305.     if( MyHUD == None )
  4306.         ClientSetHUD( newHUDClass, newScoringClass );
  4307. }
  4308.  
  4309. defaultproperties
  4310. {
  4311.      AimingHelp=0.0
  4312.      OrthoZoom=+40000.000000
  4313.      FlashScale=(X=1.000000,Y=1.000000,Z=1.000000)
  4314.      AnnouncerVolume=4
  4315.      FOVAngle=85.000
  4316.      DesiredFOV=85.000000
  4317.      DefaultFOV=85.000000
  4318.      Handedness=1.000000
  4319.      bAlwaysMouseLook=True
  4320.      ViewingFrom="Now viewing from"
  4321.      OwnCamera="Now viewing from own camera"
  4322.      QuickSaveString="Quick Saving"
  4323.      NoPauseMessage="Game is not pauseable"
  4324.      bTravel=True
  4325.      bStasis=False
  4326.      NetPriority=3
  4327.     MaxTimeMargin=+0.35
  4328.      LocalMessageClass=class'LocalMessage'
  4329.      bIsPlayer=true
  4330.      bCanOpenDoors=true
  4331.      bCanDoSpecial=true
  4332.      Physics=PHYS_None
  4333.      EnemyTurnSpeed=45000
  4334.      CheatClass=class'Engine.CheatManager'
  4335.      InputClass=class'Engine.PlayerInput'
  4336.      CameraDist=+9.0
  4337.      bZeroRoll=true
  4338.     bDynamicNetSpeed=true
  4339.     // jdf ---
  4340.     bEnableWeaponForceFeedback=True
  4341.     bEnablePickupForceFeedback=True
  4342.     bEnableDamageForceFeedback=True
  4343.     bEnableGUIForceFeedback=True
  4344.     bForceFeedbackSupported=True
  4345.     // --- jdf
  4346.     ProgressTimeOut=8.0
  4347.     MaxResponseTime=0.7
  4348.     SpectateSpeed=+600.0
  4349.     DynamicPingThreshold=+400.0
  4350.     ClientCap=0
  4351. }