Engine
Class PlayerPawn

source: e:\games\UnrealTournament\Engine\Classes\PlayerPawn.uc
Core.Object
   |
   +--Engine.Actor
      |
      +--Engine.Pawn
         |
         +--Engine.PlayerPawn
Direct Known Subclasses:TournamentPlayer, Camera, Spectator, MoviePlayer, UnrealIPlayer

class PlayerPawn
extends Engine.Pawn

//============================================================================= // PlayerPawn. // player controlled pawns // Note that Pawns which implement functions for the PlayerTick messages // must handle player control in these functions //=============================================================================
Variables
 BorrowedMouseX, BorrowedMouseY
           weapon class priorities (9 is highest)
 byte CdTrack
 CurrentTimeStamp,LastUpdateTime,ServerTimeStamp,TimeMargin, ClientUpdateTime
           weapon class priorities (9 is highest)
 float DefaultFOV
 string DelayedCommand
           used in net games
 int DemoViewPitch
           weapon class priorities (9 is highest)
 int DemoViewYaw
           weapon class priorities (9 is highest)
 float DesiredFOV
 string FailedView
           weapon class priorities (9 is highest)
 FlashScale, FlashFog
 SavedMove FreeMoves
           weapon class priorities (9 is highest)
 GameReplicationInfo GameReplicationInfo
           weapon class priorities (9 is highest)
 class HUDType
 float Handedness
           max vertical shake magnitude
 ConstantGlowScale, InstantFlash
 ConstantGlowFog, InstantFog
 float LastMessageWindow
           weapon class priorities (9 is highest)
 float LastPlaySound
           weapon class priorities (9 is highest)
 float MaxTimeMargin
           weapon class priorities (9 is highest)
 int Misc1
 int Misc2
 float MouseSensitivity
           used in net games
 float MouseSmoothThreshold
           weapon class priorities (9 is highest)
 float MouseZeroTime
           weapon class priorities (9 is highest)
 float MyAutoAim
           max vertical shake magnitude
 string NoPauseMessage
           weapon class priorities (9 is highest)
 string OwnCamera
           weapon class priorities (9 is highest)
 SavedMove PendingMove
           weapon class priorities (9 is highest)
 Player Player
 color ProgressColor[8]
           weapon class priorities (9 is highest)
 string ProgressMessage[8]
           weapon class priorities (9 is highest)
 float ProgressTimeOut
           weapon class priorities (9 is highest)
 string QuickSaveString
           weapon class priorities (9 is highest)
 bool ReceivedSecretChecksum
           weapon class priorities (9 is highest)
 int RendMap
 SavedMove SavedMoves
           weapon class priorities (9 is highest)
 ScoreBoard Scoring
 class ScoringType
 int ShowFlags
 music Song
 byte SongSection
 class SpecialMenu
           used in net games
 float TargetEyeHeight
           weapon class priorities (9 is highest)
 rotator TargetViewRotation
           weapon class priorities (9 is highest)
 vector TargetWeaponViewOffset
           weapon class priorities (9 is highest)
 EMusicTransition Transition
 Actor ViewTarget
 string ViewingFrom
           weapon class priorities (9 is highest)
 name WeaponPriority[50]
           weapon class priorities (9 is highest)
 float ZoomLevel
           used in net games
 bool bAdmin
           max vertical shake magnitude
 bool bAlwaysMouseLook
           Snap to level eyeheight when not mouselooking
 bool bAnimTransition
           used for dodge move
 bool bBadConnectionAlert
           used for dodge move
 bool bCenterView
           used for dodge move
 bool bCheatsEnabled
           used in net games
 bool bDelayedCommand
           used for dodge move
 bool bEdgeBack
           used for dodge move
 bool bEdgeForward
           used for dodge move
 bool bEdgeLeft
           used for dodge move
 bool bEdgeRight
           used for dodge move
 bool bFixedCamera
           this class allowed in single player
 bool bFrozen
           used for dodge move
 bool bInvertMouse
           used for dodge move
 bool bIsCrouching
           used for dodge move
 bool bIsTurning
           used for dodge move
 bool bIsTyping
           this class allowed in single player
 bool bJumpStatus
           used in net games
 bool bJustAltFired
           this class allowed in single player
 bool bJustFired
           this class allowed in single player
 bool bKeyboardLook
           no snapping when true
 bool bLookUpStairs
           look up/down stairs (player)
 bool bMaxMouseSmoothing
           used for dodge move
 bool bMessageBeep
           used for dodge move
 bool bMouseZeroed
           used for dodge move
 bool bNeverAutoSwitch
           if true, don't automatically switch to picked up weapon
 bool bNoFlash
           used for dodge move
 bool bNoVoices
           used for dodge move
 bool bPressedJump
           used for dodge move
 bool bReadyToPlay
           used for dodge move
 bool bReducedVis
           used for dodge move
 bool bRising
           used for dodge move
 bool bShowMenu
           used for dodge move
 bool bShowScores
           used for dodge move
 bool bSinglePlayer
           this class allowed in single player
 bool bSnapToLevel
           Snap to level eyeheight when not mouselooking
 bool bSpecialMenu
           used for dodge move
 bool bUpdatePosition
           used for dodge move
 bool bWasBack
           used for dodge move
 bool bWasForward
           used for dodge move
 bool bWasLeft
           used for dodge move
 bool bWasRight
           used for dodge move
 bool bWokeUp
           used for dodge move
 bool bZooming
           used for dodge move
 float bobtime
 input float
           weapon class priorities (9 is highest)
 float maxshake
           max vertical shake magnitude
 HUD myHUD
 bool ngSecretSet
           weapon class priorities (9 is highest)
 string ngWorldSecret
           weapon class priorities (9 is highest)
 int shakemag
           max magnitude in degrees of shaking
 float shaketimer
           player uses this for shaking view
 float shakevert
           max vertical shake magnitude
 float verttimer
           max vertical shake magnitude

States
GameEnded, Dying, PlayerWaking, PlayerSpectating, PlayerWaiting, CheatFlying, PlayerFlying, PlayerSwimming, FeigningDeath, PlayerWalking, InvalidState

Function Summary
 void ActivateHint()
     
// Translator Hotkey
 void ActivateInventoryItem(class InvItem)
     
// Activate specific inventory item
 void ActivateItem()
     
// The player wants to active selected item
 void ActivateTranslator()
     
// Translator Hotkey
 void AddBots(int N)
 rotator AdjustAim(float projSpeed, vector projStart, int aimerror, bool bLeadTarget, bool bWarnTarget)
     
/* AdjustAim()
Calls this version for player aiming help.
Aimerror not used in this version.
Only adjusts aiming at pawns
*/
 bool AdjustHitLocation(out vector, vector TraceDir)
     
/* Adjust hit location - adjusts the hit location in for pawns, and returns
true if it was really a hit, and false if not (for ducking, etc.)
*/
 void Admin(string CommandLine)
     
// Execute an administrative console command on the server.
 void AdminLogin(string Password)
     
// Login as the administrator.
 void AdminLogout()
     
// Logout as the administrator.
 void AllAmmo()
 void AltFire(optional float)
     
// The player wants to alternate-fire.
 void AlwaysMouseLook(Bool B)
 void Amphibious()
 eAttitude AttitudeTo(Pawn Other)
 void BehindView(Bool B)
 void CalcBehindView(out vector, out rotator, float Dist)
     
// Player view.
// Compute the rendering viewpoint for the player.
//
 void CallForHelp()
 void CauseEvent(name N)
 void ChangeAlwaysMouseLook(Bool B)
 void ChangeAutoAim(float F)
 void ChangeCrosshair()
     
// Crosshair
 void ChangeDodgeClickTime(float F)
 void ChangeHud()
     
// HUD
 void ChangeName(string S)
 void ChangeSetHand(string S)
 void ChangeSnapView(bool B)
 void ChangeStairLook(bool B)
 void ChangeTeam(int N)
 void ChangedWeapon()
     
// Just changed to pendingWeapon
 void CheckBob(float DeltaTime, float Speed2D, vector Y)
 void ClearProgressMessages()
     
//*************************************************************************************
// Special purpose/cheat execs
 void ClientAdjustGlow(float scale, vector fog)
 void ClientAdjustPosition(float TimeStamp, name newState, EPhysics newPhysics, float NewLocX, float NewLocY, float NewLocZ, float NewVelX, float NewVelY, float NewVelZ, Actor NewBase)
     
// ClientAdjustPosition - pass newloc and newvel in components so they don't get rounded
 void ClientChangeTeam(int N)
 void ClientFlash(float scale, vector fog)
 void ClientInstantFlash(float scale, vector fog)
 
simulated
ClientPlaySound(sound ASound, optional bool, optional bool)
     
//Play a sound client side (so only client will hear it
 
simulated
ClientReliablePlaySound(sound ASound, optional bool, optional bool)
 void ClientReplicateSkins(Texture Skin1, optional texture, optional texture, optional texture)
 void ClientSetMusic(music NewSong, byte NewSection, byte NewCdTrack, EMusicTransition NewTransition)
 void ClientShake(vector shake)
 void ClientUpdatePosition()
 void ClientVoiceMessage(PlayerReplicationInfo Sender, PlayerReplicationInfo Recipient, name messagetype, byte messageID)
 void ClientWeaponEvent(name EventType)
 int CompressAccel(int C)
 string ConsoleCommand(string Command)
     
// Execute a console command in the context of this player, then forward to Actor.ConsoleCommand.
 void CopyToClipboard(string Text)
 void Died(Pawn Killer, name damageType, vector HitLocation)
 void DoJump(optional float)
     
//Player Jumped
 void EndZoom()
 void FOV(float F)
 void Falling()
 void FeignDeath()
 void Fire(optional float)
     
// The player wants to fire.
 void Fly()
 void FunctionKey(byte Num)
     
// Handle function keypress for F1-F10.
 string GetDefaultURL(string Option)
 LevelInfo GetEntryLevel()
 SavedMove GetFreeMove()
 string GetPlayerNetworkAddress()
 void Ghost()
 bool Gibbed(name damageType)
 void God()
 void Grab()
 void HandleWalking()
 void InitPlayerReplicationInfo()
 void InvertMouse(bool B)
 void Invisible(bool B)
 void Jump(optional float)
 void JumpOffPawn()
 void Kick(string S)
 void KickBan(string S)
 string KillMessage(name damageType, Pawn Other)
 void KillPawns()
 void KilledBy(Pawn EventInstigator)
     
//=============================================================================
// Player Control
 void Landed(vector HitNormal)
 void LocalTravel(string URL)
 void MoveAutonomous(float DeltaTime, bool NewbRun, bool NewbDuck, bool NewbPressedJump, eDodgeDir DodgeMove, vector newAccel, rotator DeltaRot)
 void Mutate(string MutateString)
 void Name(string S)
 void NeverSwitchOnPickup(bool B)
 void NextWeapon()
     
/* NextWeapon()
- switch to next inventory group weapon
*/
 string PasteFromClipboard()
 void Pause()
     
// Try to pause the game.
 void Ping()
 
simulated
PlayBeepSound()
 void PlayChatting()
 void PlayDodge(eDodgeDir DodgeMove)
     
//=============================================================================
// Animation playing - should be implemented in subclass, 
//
 void PlayFeignDeath()
 void PlayHit(float Damage, vector HitLocation, name damageType, vector Momentum)
 void PlayRising()
 void PlaySwimming()
 void PlayTurning()
 void PlayerList()
 void PlayersOnly()
 void PrevItem()
     
// The player wants to select previous item
 void PrevWeapon()
     
/* PrevWeapon()
- switch to previous inventory group weapon
*/
 void ProcessMove(float DeltaTime, vector newAccel, eDodgeDir DodgeMove, rotator DeltaRot)
 void Profile()
 void QuickLoad()
 void QuickSave()
 void RememberSpot()
 void ReplaceText(out string, string Replace, string With)
 void ReplicateMove(float DeltaTime, vector NewAccel, eDodgeDir DodgeMove, rotator DeltaRot)
     
//
// Replicate this client's desired movement to the server.
//
 void ResetKeyboard()
     
//
// native client-side functions.
//
 void RestartLevel()
 void SShot()
 void Say(string Msg)
     
// Send a message to all players.
 void ServerAddBots(int N)
 void ServerChangeSkin(string SkinName, string FaceName, byte TeamNum)
 void ServerFeignDeath()
 void ServerMove(float TimeStamp, vector InAccel, vector ClientLoc, bool NewbRun, bool NewbDuck, bool NewbJumpStatus, bool bFired, bool bAltFired, bool bForceFire, bool bForceAltFire, eDodgeDir DodgeMove, byte ClientRoll, int View, optional byte, optional int)
     
//
// Send movement to the server.
// Passes acceleration in components so it doesn't get rounded.
//
 void ServerNeverSwitchOnPickup(bool B)
 void ServerReStartGame()
 void ServerReStartPlayer()
 void ServerSetHandedness(float hand)
 void ServerSetSloMo(float T)
 void ServerSetWeaponPriority(byte i, name WeaponName)
 void ServerTaunt(name Sequence)
 void ServerUpdateWeapons()
 void SetAutoAim(float F)
 void SetBob(float F)
 void SetDesiredFOV(float F)
 void SetDodgeClickTime(float F)
 void SetFOVAngle(float newFOV)
 void SetFriction(float F)
 void SetHand(string S)
 void SetJumpZ(float F)
 void SetMaxMouseSmoothing(bool B)
 void SetMouseSmoothThreshold(float F)
 void SetName(string S)
 bool SetPause(BOOL bPause)
     
// Try to set the pause state; returns success indicator.
 void SetProgressColor(color C, int Index)
 void SetProgressMessage(string S, int Index)
 void SetProgressTime(float T)
 void SetSensitivity(float F)
 void SetSpeed(float F)
 void SetViewFlash(bool B)
 void SetWeaponStay(bool B)
 void ShakeView(float shaketime, float RollMag, float vertmag)
 void ShowInventory()
 void ShowLoadMenu()
 void ShowMenu()
 void ShowPath()
     
//==============
// Navigation Aids
 void ShowScores()
 void ShowSpecialMenu(string ClassName)
     
//*************************************************************************************
// Normal gameplay execs
// Type the name of the exec function at the console to execute it
 void SloMo(float T)
 void SnapView(bool B)
 Carcass SpawnCarcass()
 void SpawnGibbedCarcass()
 void Speech(int Type, int Index, int Callsign)
     
// Send a voice message of a certain type to a certain player.
 void StairLook(bool B)
 void StartWalk()
 void StartZoom()
 void StopZoom()
 void Suicide()
 void Summon(string ClassName)
 void SwimAnimUpdate(bool bNotForward)
 void SwitchCoopLevel(string URL)
 void SwitchLevel(string URL)
 void SwitchWeapon(byte F)
     
// The player wants to switch to weapon group numer I.
 void Taunt(name Sequence)
 void TeamSay(string Msg)
 void ThrowWeapon()
 void ToggleZoom()
 void Typing(bool bTyping)
 void UpdateBob(float F)
 void UpdateRotation(float DeltaTime, float maxPitch)
 void UpdateSensitivity(float F)
 void UpdateURL(string NewOption, string NewValue, bool bSaveDefault)
 void UpdateWeaponPriorities()
 void ViewFlash(float DeltaTime)
 void ViewPlayer(string S)
 void ViewPlayerNum(optional int)
 void ViewSelf()
 void ViewShake(float DeltaTime)
 void Walk()
 void damageAttitudeTo(Pawn Other)


State GameEnded Function Summary
 void SetNGSecret(string newSecret)
 string GetNGSecret()
     
// ngStats Accessors
 void BeginState()
 void Timer()
 void FindGoodView()
 void ServerMove(float TimeStamp, vector InAccel, vector ClientLoc, bool NewbRun, bool NewbDuck, bool NewbJumpStatus, bool bFired, bool bAltFired, bool bForceFire, bool bForceAltFire, eDodgeDir DodgeMove, byte ClientRoll, int View, optional byte, optional int)
 void PlayerMove(float DeltaTime)
 void AltFire(optional float)
 void Fire(optional float)
 void ServerReStartGame()
 void ViewPlayer(string S)
 void Taunt(Name Sequence)
 void ThrowWeapon()


State Dying Function Summary
 void EndState()
 void BeginState()
 void Timer()
 void TakeDamage(int Damage, Pawn instigatedBy, Vector hitlocation, Vector momentum, Name damageType)
 void FindGoodView()
 void PlayerMove(float DeltaTime)
 void PlayerCalcView(out actor, out vector, out rotator)
 void ServerMove(float TimeStamp, vector Accel, vector ClientLoc, bool NewbRun, bool NewbDuck, bool NewbJumpStatus, bool bFired, bool bAltFired, bool bForceFire, bool bForceAltFire, eDodgeDir DodgeMove, byte ClientRoll, int View, optional byte, optional int)
 void Taunt(Name Sequence)
 void PlayChatting()
 void AltFire(optional float)
 void Fire(optional float)
 void ServerReStartPlayer()
 void Suicide()


State PlayerWaking Function Summary
 void BeginState()
 void PlayerMove(Float DeltaTime)
 void Timer()


State PlayerSpectating Function Summary
 void BeginState()
 void EndState()
 void PlayerMove(float DeltaTime)
 void ProcessMove(float DeltaTime, vector NewAccel, eDodgeDir DodgeMove, rotator DeltaRot)
 void Fire(optional float)
 void ChangeTeam(int N)
 void AltFire(optional float)
 void SendVoiceMessage(PlayerReplicationInfo Sender, PlayerReplicationInfo Recipient, Name messagetype, byte messageID, Name broadcasttype)
 void Suicide()


State PlayerWaiting Function Summary
 void BeginState()
 void EndState()
 void PlayerMove(float DeltaTime)
 void PlayWaiting()
 void ProcessMove(float DeltaTime, vector NewAccel, eDodgeDir DodgeMove, rotator DeltaRot)
 void AltFire(optional float)
 void Fire(optional float)
 void ChangeTeam(int N)
 void Suicide()
 void Jump(optional float)


State CheatFlying Function Summary
 void BeginState()
 void PlayerMove(float DeltaTime)
 void ProcessMove(float DeltaTime, vector NewAccel, eDodgeDir DodgeMove, rotator DeltaRot)
 void AnimEnd()


State PlayerFlying Function Summary
 void BeginState()
 void PlayerMove(float DeltaTime)
 void AnimEnd()


State PlayerSwimming Function Summary
 void BeginState()
 void Timer()
 void PlayerMove(float DeltaTime)
 void ProcessMove(float DeltaTime, vector NewAccel, eDodgeDir DodgeMove, rotator DeltaRot)
 void ZoneChange(ZoneInfo NewZone)
 void AnimEnd()
 void Landed(vector HitNormal)


State FeigningDeath Function Summary
 void BeginState()
 void EndState()
 void ChangedWeapon()
 void PlayDying(Name DamageType, vector HitLocation)
 void PlayTakeHit(float tweentime, vector HitLoc, int Damage)
 void PlayerMove(float DeltaTime)
 void ServerMove(float TimeStamp, vector Accel, vector ClientLoc, bool NewbRun, bool NewbDuck, bool NewbJumpStatus, bool bFired, bool bAltFired, bool bForceFire, bool bForceAltFire, eDodgeDir DodgeMove, byte ClientRoll, int View, optional byte, optional int)
 void ProcessMove(float DeltaTime, vector NewAccel, eDodgeDir DodgeMove, rotator DeltaRot)
 void Rise()
 void Landed(vector HitNormal)
 void AnimEnd()
 void Taunt(Name Sequence)
 void PlayChatting()
 void AltFire(optional float)
 void Fire(optional float)
 void ZoneChange(ZoneInfo NewZone)


State PlayerWalking Function Summary
 void EndState()
 void BeginState()
 void PlayerMove(float DeltaTime)
 void ProcessMove(float DeltaTime, vector NewAccel, eDodgeDir DodgeMove, rotator DeltaRot)
 void Dodge(eDodgeDir DodgeMove)
 void Landed(vector HitNormal)
 void AnimEnd()
 void ZoneChange(ZoneInfo NewZone)
 void ServerFeignDeath()
 void FeignDeath()


State InvalidState Function Summary
 void PlayerMove(float DeltaTime)



Source Code


00001	//=============================================================================
00002	// PlayerPawn.
00003	// player controlled pawns
00004	// Note that Pawns which implement functions for the PlayerTick messages
00005	// must handle player control in these functions
00006	//=============================================================================
00007	class PlayerPawn expands Pawn
00008		config(user)
00009		native
00010		nativereplication;
00011	
00012	// Player info.
00013	var const player Player;
00014	var	globalconfig string Password;	// for restarting coop savegames
00015	
00016	var	travel	  float DodgeClickTimer; // max double click interval for dodge move
00017	var(Movement) globalconfig float	DodgeClickTime;
00018	var(Movement) globalconfig float Bob;
00019	var			  float				LandBob, AppliedBob;
00020	var float bobtime;
00021	
00022	// Camera info.
00023	var int ShowFlags;
00024	var int RendMap;
00025	var int Misc1;
00026	var int Misc2;
00027	
00028	var actor ViewTarget;
00029	var vector FlashScale, FlashFog;
00030	var HUD	myHUD;
00031	var ScoreBoard Scoring;
00032	var class<hud> HUDType;
00033	var class<scoreboard> ScoringType;
00034	
00035	var float DesiredFlashScale, ConstantGlowScale, InstantFlash;
00036	var vector DesiredFlashFog, ConstantGlowFog, InstantFog;
00037	var globalconfig float DesiredFOV;
00038	var globalconfig float DefaultFOV;
00039	
00040	// Music info.
00041	var music Song;
00042	var byte  SongSection;
00043	var byte  CdTrack;
00044	var EMusicTransition Transition;
00045	
00046	var float shaketimer; // player uses this for shaking view
00047	var int shakemag;	// max magnitude in degrees of shaking
00048	var float shakevert; // max vertical shake magnitude
00049	var float maxshake;
00050	var float verttimer;
00051	var(Pawn) class<carcass> CarcassType;
00052	var travel globalconfig float MyAutoAim;
00053	var travel globalconfig float Handedness;
00054	var(Sounds) sound JumpSound;
00055	
00056	// Player control flags
00057	var bool		bAdmin;
00058	var() globalconfig bool 		bLookUpStairs;	// look up/down stairs (player)
00059	var() globalconfig bool		bSnapToLevel;	// Snap to level eyeheight when not mouselooking
00060	var() globalconfig bool		bAlwaysMouseLook;
00061	var globalconfig bool 		bKeyboardLook;	// no snapping when true
00062	var bool		bWasForward;	// used for dodge move 
00063	var bool		bWasBack;
00064	var bool		bWasLeft;
00065	var bool		bWasRight;
00066	var bool		bEdgeForward;
00067	var bool		bEdgeBack;
00068	var bool		bEdgeLeft;
00069	var bool 		bEdgeRight;
00070	var bool		bIsCrouching;
00071	var	bool		bShakeDir;			
00072	var bool		bAnimTransition;
00073	var bool		bIsTurning;
00074	var bool		bFrozen;
00075	var bool        bBadConnectionAlert;
00076	var globalconfig bool	bInvertMouse;
00077	var bool		bShowScores;
00078	var bool		bShowMenu;
00079	var bool		bSpecialMenu;
00080	var bool		bWokeUp;
00081	var bool		bPressedJump;
00082	var bool		bUpdatePosition;
00083	var bool		bDelayedCommand;
00084	var bool		bRising;
00085	var bool		bReducedVis;
00086	var bool		bCenterView;
00087	var() globalconfig bool bMaxMouseSmoothing;
00088	var bool		bMouseZeroed;
00089	var bool		bReadyToPlay;
00090	var globalconfig bool bNoFlash;
00091	var globalconfig bool bNoVoices;
00092	var globalconfig bool bMessageBeep;
00093	var bool		bZooming;
00094	var() bool		bSinglePlayer;		// this class allowed in single player
00095	var bool		bJustFired;
00096	var bool		bJustAltFired;
00097	var bool		bIsTyping;
00098	var bool		bFixedCamera;
00099	var globalconfig bool	bNeverAutoSwitch;	// if true, don't automatically switch to picked up weapon
00100	var bool		bJumpStatus;	// used in net games
00101	var	bool		bUpdating;
00102	var bool		bCheatsEnabled;
00103	
00104	var float		ZoomLevel;
00105	
00106	var class<menu> SpecialMenu;
00107	var string DelayedCommand;
00108	var globalconfig float	MouseSensitivity;
00109	
00110	var globalconfig name	WeaponPriority[50]; //weapon class priorities (9 is highest)
00111	
00112	var float SmoothMouseX, SmoothMouseY, BorrowedMouseX, BorrowedMouseY;
00113	var() globalconfig float MouseSmoothThreshold;
00114	var float MouseZeroTime;
00115	
00116	// Input axes.
00117	var input float 
00118		aBaseX, aBaseY, aBaseZ,
00119		aMouseX, aMouseY,
00120		aForward, aTurn, aStrafe, aUp, 
00121		aLookUp, aExtra4, aExtra3, aExtra2,
00122		aExtra1, aExtra0;
00123	
00124	// Move Buffering.
00125	var SavedMove SavedMoves;
00126	var SavedMove FreeMoves;
00127	var SavedMove PendingMove;
00128	var float CurrentTimeStamp,LastUpdateTime,ServerTimeStamp,TimeMargin, ClientUpdateTime;
00129	var globalconfig float MaxTimeMargin;
00130	
00131	// Progess Indicator.
00132	var string ProgressMessage[8];
00133	var color ProgressColor[8];
00134	var float ProgressTimeOut;
00135	
00136	// Localized strings
00137	var localized string QuickSaveString;
00138	var localized string NoPauseMessage;
00139	var localized string ViewingFrom;
00140	var localized string OwnCamera;
00141	var localized string FailedView;
00142	
00143	// ReplicationInfo
00144	var GameReplicationInfo GameReplicationInfo;
00145	
00146	// ngWorldStats Logging
00147	var() globalconfig private string ngWorldSecret;
00148	var() globalconfig bool ngSecretSet;
00149	var bool ReceivedSecretChecksum;
00150	
00151	// Remote Pawn ViewTargets
00152	var rotator TargetViewRotation; 
00153	var float TargetEyeHeight;
00154	var vector TargetWeaponViewOffset;
00155	
00156	// Demo recording view rotation
00157	var int DemoViewPitch;
00158	var int DemoViewYaw;
00159	
00160	var float LastPlaySound;
00161	
00162	// text message sending
00163	var float LastMessageWindow;
00164	
00165	replication
00166	{
00167		// Things the server should send to the client.
00168		reliable if( bNetOwner && Role==ROLE_Authority )
00169			ViewTarget, ScoringType, HUDType, GameReplicationInfo, bFixedCamera, bCheatsEnabled;
00170		unreliable if ( bNetOwner && Role==ROLE_Authority )
00171			TargetViewRotation, TargetEyeHeight, TargetWeaponViewOffset;
00172		reliable if( bDemoRecording && Role==ROLE_Authority )
00173			DemoViewPitch, DemoViewYaw;
00174	
00175		// Things the client should send to the server
00176		reliable if ( Role<ROLE_Authority )
00177			Password, bReadyToPlay;
00178	
00179		// Functions client can call.
00180		unreliable if( Role<ROLE_Authority )
00181			CallForHelp;
00182		reliable if( Role<ROLE_Authority )
00183			ShowPath, RememberSpot, Speech, Say, TeamSay, RestartLevel, SwitchWeapon, Pause, SetPause, ServerSetHandedness,
00184			PrevItem, ActivateItem, ShowInventory, Grab, ServerFeignDeath, ServerSetWeaponPriority,
00185			ChangeName, ChangeTeam, God, Suicide, ViewClass, ViewPlayerNum, ViewSelf, ViewPlayer, ServerSetSloMo, ServerAddBots,
00186			PlayersOnly, ThrowWeapon, ServerRestartPlayer, NeverSwitchOnPickup, BehindView, ServerNeverSwitchOnPickup, 
00187			PrevWeapon, NextWeapon, GetWeapon, ServerReStartGame, ServerUpdateWeapons, ServerTaunt, ServerChangeSkin,
00188			SwitchLevel, SwitchCoopLevel, Kick, KickBan, KillAll, Summon, ActivateTranslator, Admin, AdminLogin, AdminLogout, Typing, Mutate;
00189		unreliable if( Role<ROLE_Authority )
00190			ServerMove, Fly, Walk, Ghost;
00191	
00192		// Functions server can call.
00193		reliable if( Role==ROLE_Authority && !bDemoRecording )
00194			ClientTravel;
00195		reliable if( Role==ROLE_Authority )
00196			ClientReliablePlaySound, ClientReplicateSkins, ClientAdjustGlow, ClientChangeTeam, ClientSetMusic, StartZoom, ToggleZoom, StopZoom, EndZoom, SetDesiredFOV, ClearProgressMessages, SetProgressColor, SetProgressMessage, SetProgressTime, ClientWeaponEvent;
00197		unreliable if( Role==ROLE_Authority )
00198			SetFOVAngle, ClientShake, ClientFlash, ClientInstantFlash;
00199		unreliable if( Role==ROLE_Authority && !bDemoRecording )
00200			ClientPlaySound;
00201		unreliable if( RemoteRole==ROLE_AutonomousProxy )//***
00202			ClientAdjustPosition;
00203	}
00204	
00205	//
00206	// native client-side functions.
00207	//
00208	native event ClientTravel( string URL, ETravelType TravelType, bool bItems );
00209	native(544) final function ResetKeyboard();
00210	native(546) final function UpdateURL(string NewOption, string NewValue, bool bSaveDefault);
00211	native final function string GetDefaultURL(string Option);
00212	native final function LevelInfo GetEntryLevel();
00213	native final function string GetPlayerNetworkAddress();
00214	// Execute a console command in the context of this player, then forward to Actor.ConsoleCommand.
00215	native function string ConsoleCommand( string Command );
00216	native function CopyToClipboard( string Text );
00217	native function string PasteFromClipboard();
00218	
00219	function InitPlayerReplicationInfo()
00220	{
00221		Super.InitPlayerReplicationInfo();
00222	
00223		PlayerReplicationInfo.bAdmin = bAdmin;
00224	}
00225	
00226	event PreClientTravel()
00227	{
00228	}
00229	
00230	exec function Ping()
00231	{
00232		ClientMessage("Current ping is"@PlayerReplicationInfo.Ping);
00233	}
00234	
00235	function ClientWeaponEvent(name EventType)
00236	{
00237		if ( Weapon != None )
00238			Weapon.ClientWeaponEvent(EventType);
00239	}
00240	
00241	simulated event RenderOverlays( canvas Canvas )
00242	{
00243		if ( Weapon != None )
00244			Weapon.RenderOverlays(Canvas);
00245	
00246		if ( myHUD != None )
00247			myHUD.RenderOverlays(Canvas);
00248	}
00249	
00250	function ClientReplicateSkins(texture Skin1, optional texture Skin2, optional texture Skin3, optional texture Skin4)
00251	{
00252		// do nothing (just loading other player skins onto client)
00253		log("Getting "$Skin1$", "$Skin2$", "$Skin3$", "$Skin4);
00254		return;
00255	}
00256	
00257	function CheckBob(float DeltaTime, float Speed2D, vector Y)
00258	{
00259		local float OldBobTime;
00260	
00261		OldBobTime = BobTime;
00262		if ( Speed2D < 10 )
00263			BobTime += 0.2 * DeltaTime;
00264		else
00265			BobTime += DeltaTime * (0.3 + 0.7 * Speed2D/GroundSpeed);
00266		WalkBob = Y * 0.65 * Bob * Speed2D * sin(6 * BobTime);
00267		AppliedBob = AppliedBob * (1 - FMin(1, 16 * deltatime));
00268		if ( LandBob > 0.01 )
00269		{
00270			AppliedBob += FMin(1, 16 * deltatime) * LandBob;
00271			LandBob *= (1 - 8*Deltatime);
00272		}
00273		if ( Speed2D < 10 )
00274			WalkBob.Z = AppliedBob + Bob * 30 * sin(12 * BobTime);
00275		else
00276			WalkBob.Z = AppliedBob + Bob * Speed2D * sin(12 * BobTime);
00277	}
00278	
00279	exec function ViewPlayerNum(optional int num)
00280	{
00281		local Pawn P;
00282	
00283		if ( !PlayerReplicationInfo.bIsSpectator && !Level.Game.bTeamGame )
00284			return;
00285		if ( num >= 0 )
00286		{
00287			P = Pawn(ViewTarget);
00288			if ( (P != None) && P.bIsPlayer && (P.PlayerReplicationInfo.TeamID == num) )
00289			{
00290				ViewTarget = None;
00291				bBehindView = false;
00292				return;
00293			}
00294			for ( P=Level.PawnList; P!=None; P=P.NextPawn )
00295				if ( (P.PlayerReplicationInfo != None) && (P.PlayerReplicationInfo.Team == PlayerReplicationInfo.Team)
00296					&& !P.PlayerReplicationInfo.bIsSpectator
00297					&& (P.PlayerReplicationInfo.TeamID == num) )
00298				{
00299					if ( P != self )
00300					{
00301						ViewTarget = P;
00302						bBehindView = true;
00303					}
00304					return;
00305				}
00306			return;
00307		}
00308		if ( Role == ROLE_Authority )
00309		{
00310			ViewClass(class'Pawn', true);
00311			While ( (ViewTarget != None) 
00312					&& (!Pawn(ViewTarget).bIsPlayer || Pawn(ViewTarget).PlayerReplicationInfo.bIsSpectator) )
00313				ViewClass(class'Pawn', true);
00314	
00315			if ( ViewTarget != None )
00316				ClientMessage(ViewingFrom@Pawn(ViewTarget).PlayerReplicationInfo.PlayerName, 'Event', true);
00317			else
00318				ClientMessage(ViewingFrom@OwnCamera, 'Event', true);
00319		}
00320	}
00321	
00322	exec function Profile()
00323	{
00324		//TEMP for performance measurement
00325	
00326		log("Average AI Time"@Level.AvgAITime);
00327		log(" < 5% "$Level.AIProfile[0]);
00328		log(" < 10% "$Level.AIProfile[1]);
00329		log(" < 15% "$Level.AIProfile[2]);
00330		log(" < 20% "$Level.AIProfile[3]);
00331		log(" < 25% "$Level.AIProfile[4]);
00332		log(" < 30% "$Level.AIProfile[5]);
00333		log(" < 35% "$Level.AIProfile[6]);
00334		log(" > 35% "$Level.AIProfile[7]);
00335	}
00336	
00337	// Execute an administrative console command on the server.
00338	exec function Admin( string CommandLine )
00339	{
00340		local string Result;
00341		if( bAdmin )
00342			Result = ConsoleCommand( CommandLine );
00343		if( Result!="" )
00344			ClientMessage( Result );
00345	}
00346	
00347	// Login as the administrator.
00348	exec function AdminLogin( string Password )
00349	{
00350		Level.Game.AdminLogin( Self, Password );
00351	}
00352	
00353	// Logout as the administrator.
00354	exec function AdminLogout()
00355	{
00356		Level.Game.AdminLogout( Self );
00357	}
00358	
00359	exec function SShot()
00360	{
00361		local float b;
00362		b = float(ConsoleCommand("get ini:Engine.Engine.ViewportManager Brightness"));
00363		ConsoleCommand("set ini:Engine.Engine.ViewportManager Brightness 1");
00364		ConsoleCommand("flush");
00365		ConsoleCommand("shot");
00366		ConsoleCommand("set ini:Engine.Engine.ViewportManager Brightness "$string(B));
00367		ConsoleCommand("flush");
00368	}
00369	
00370	exec function PlayerList()
00371	{
00372		local PlayerReplicationInfo PRI;
00373	
00374		log("Player List:");
00375		ForEach AllActors(class'PlayerReplicationInfo', PRI)
00376			log(PRI.PlayerName@"( ping"@PRI.Ping$")");
00377	}
00378	
00379	//
00380	// Native ClientSide Functions
00381	//
00382	
00383	event ReceiveLocalizedMessage( class<LocalMessage> Message, optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2, optional Object OptionalObject )
00384	{
00385		Message.Static.ClientReceive( Self, Switch, RelatedPRI_1, RelatedPRI_2, OptionalObject );
00386	}
00387	
00388	event ClientMessage( coerce string S, optional Name Type, optional bool bBeep )
00389	{
00390		if (Player == None)
00391			return;
00392	
00393		if (Type == '')
00394			Type = 'Event';
00395	
00396		if (Player.Console != None)
00397			Player.Console.Message( PlayerReplicationInfo, S, Type );
00398		if (bBeep && bMessageBeep)
00399			PlayBeepSound();
00400		if ( myHUD != None )
00401			myHUD.Message( PlayerReplicationInfo, S, Type );
00402	}
00403	
00404	event TeamMessage( PlayerReplicationInfo PRI, coerce string S, name Type, optional bool bBeep  )
00405	{
00406		if (Player.Console != None)
00407			Player.Console.Message ( PRI, S, Type );
00408		if (bBeep && bMessageBeep)
00409			PlayBeepSound();
00410		if ( myHUD != None )
00411			myHUD.Message( PRI, S, Type );
00412	}
00413	
00414	function ClientVoiceMessage(PlayerReplicationInfo Sender, PlayerReplicationInfo Recipient, name messagetype, byte messageID)
00415	{
00416		local VoicePack V;
00417	
00418		if ( (Sender == None) || (Sender.voicetype == None) || (Player.Console == None) )
00419			return;
00420			
00421		V = Spawn(Sender.voicetype, self);
00422		if ( V != None )
00423			V.ClientInitialize(Sender, Recipient, messagetype, messageID);
00424	}
00425	
00426	simulated function PlayBeepSound();
00427	
00428	//
00429	// Send movement to the server.
00430	// Passes acceleration in components so it doesn't get rounded.
00431	//
00432	function ServerMove
00433	(
00434		float TimeStamp, 
00435		vector InAccel, 
00436		vector ClientLoc,
00437		bool NewbRun,
00438		bool NewbDuck,
00439		bool NewbJumpStatus, 
00440		bool bFired,
00441		bool bAltFired,
00442		bool bForceFire,
00443		bool bForceAltFire,
00444		eDodgeDir DodgeMove, 
00445		byte ClientRoll, 
00446		int View,
00447		optional byte OldTimeDelta,
00448		optional int OldAccel
00449	)
00450	{
00451		local float DeltaTime, clientErr, OldTimeStamp;
00452		local rotator DeltaRot, Rot;
00453		local vector Accel, LocDiff;
00454		local int maxPitch, ViewPitch, ViewYaw;
00455		local actor OldBase;
00456		local bool NewbPressedJump, OldbRun, OldbDuck;
00457		local eDodgeDir OldDodgeMove;
00458	
00459		// If this move is outdated, discard it.
00460		if ( CurrentTimeStamp >= TimeStamp )
00461			return;
00462	
00463		// if OldTimeDelta corresponds to a lost packet, process it first
00464		if (  OldTimeDelta != 0 )
00465		{
00466			OldTimeStamp = TimeStamp - float(OldTimeDelta)/500 - 0.001;
00467			if ( CurrentTimeStamp < OldTimeStamp - 0.001 )
00468			{
00469				// split out components of lost move (approx)
00470				Accel.X = OldAccel >>> 23;
00471				if ( Accel.X > 127 )
00472					Accel.X = -1 * (Accel.X - 128);
00473				Accel.Y = (OldAccel >>> 15) & 255;
00474				if ( Accel.Y > 127 )
00475					Accel.Y = -1 * (Accel.Y - 128);
00476				Accel.Z = (OldAccel >>> 7) & 255;
00477				if ( Accel.Z > 127 )
00478					Accel.Z = -1 * (Accel.Z - 128);
00479				Accel *= 20;
00480				
00481				OldbRun = ( (OldAccel & 64) != 0 );
00482				OldbDuck = ( (OldAccel & 32) != 0 );
00483				NewbPressedJump = ( (OldAccel & 16) != 0 );
00484				if ( NewbPressedJump )
00485					bJumpStatus = NewbJumpStatus;
00486	
00487				switch (OldAccel & 7)
00488				{
00489					case 0:
00490						OldDodgeMove = DODGE_None;
00491						break;
00492					case 1:
00493						OldDodgeMove = DODGE_Left;
00494						break;
00495					case 2:
00496						OldDodgeMove = DODGE_Right;
00497						break;
00498					case 3:
00499						OldDodgeMove = DODGE_Forward;
00500						break;
00501					case 4:
00502						OldDodgeMove = DODGE_Back;
00503						break;
00504				}
00505				//log("Recovered move from "$OldTimeStamp$" acceleration "$Accel$" from "$OldAccel);
00506				MoveAutonomous(OldTimeStamp - CurrentTimeStamp, OldbRun, OldbDuck, NewbPressedJump, OldDodgeMove, Accel, rot(0,0,0));
00507				CurrentTimeStamp = OldTimeStamp;
00508			}
00509		}		
00510	
00511		// View components
00512		ViewPitch = View/32768;
00513		ViewYaw = 2 * (View - 32768 * ViewPitch);
00514		ViewPitch *= 2;
00515		// Make acceleration.
00516		Accel = InAccel/10;
00517	
00518		NewbPressedJump = (bJumpStatus != NewbJumpStatus);
00519		bJumpStatus = NewbJumpStatus;
00520	
00521		// handle firing and alt-firing
00522		if ( bFired )
00523		{
00524			if ( bForceFire && (Weapon != None) )
00525				Weapon.ForceFire();
00526			else if ( bFire == 0 )
00527				Fire(0);
00528			bFire = 1;
00529		}
00530		else
00531			bFire = 0;
00532	
00533	
00534		if ( bAltFired )
00535		{
00536			if ( bForceAltFire && (Weapon != None) )
00537				Weapon.ForceAltFire();
00538			else if ( bAltFire == 0 )
00539				AltFire(0);
00540			bAltFire = 1;
00541		}
00542		else
00543			bAltFire = 0;
00544	
00545		// Save move parameters.
00546		DeltaTime = TimeStamp - CurrentTimeStamp;
00547		if ( ServerTimeStamp > 0 )
00548		{
00549			// allow 1% error
00550			TimeMargin += DeltaTime - 1.01 * (Level.TimeSeconds - ServerTimeStamp);
00551			if ( TimeMargin > MaxTimeMargin )
00552			{
00553				// player is too far ahead
00554				TimeMargin -= DeltaTime;
00555				if ( TimeMargin < 0.5 )
00556					MaxTimeMargin = Default.MaxTimeMargin;
00557				else
00558					MaxTimeMargin = 0.5;
00559				DeltaTime = 0;
00560			}
00561		}
00562	
00563		CurrentTimeStamp = TimeStamp;
00564		ServerTimeStamp = Level.TimeSeconds;
00565		Rot.Roll = 256 * ClientRoll;
00566		Rot.Yaw = ViewYaw;
00567		if ( (Physics == PHYS_Swimming) || (Physics == PHYS_Flying) )
00568			maxPitch = 2;
00569		else
00570			maxPitch = 1;
00571		If ( (ViewPitch > maxPitch * RotationRate.Pitch) && (ViewPitch < 65536 - maxPitch * RotationRate.Pitch) )
00572		{
00573			If (ViewPitch < 32768) 
00574				Rot.Pitch = maxPitch * RotationRate.Pitch;
00575			else
00576				Rot.Pitch = 65536 - maxPitch * RotationRate.Pitch;
00577		}
00578		else
00579			Rot.Pitch = ViewPitch;
00580		DeltaRot = (Rotation - Rot);
00581		ViewRotation.Pitch = ViewPitch;
00582		ViewRotation.Yaw = ViewYaw;
00583		ViewRotation.Roll = 0;
00584		SetRotation(Rot);
00585	
00586		OldBase = Base;
00587	
00588		// Perform actual movement.
00589		if ( (Level.Pauser == "") && (DeltaTime > 0) )
00590			MoveAutonomous(DeltaTime, NewbRun, NewbDuck, NewbPressedJump, DodgeMove, Accel, DeltaRot);
00591	
00592		// Accumulate movement error.
00593		if ( Level.TimeSeconds - LastUpdateTime > 500.0/Player.CurrentNetSpeed )
00594			ClientErr = 10000;
00595		else if ( Level.TimeSeconds - LastUpdateTime > 180.0/Player.CurrentNetSpeed )
00596		{
00597			LocDiff = Location - ClientLoc;
00598			ClientErr = LocDiff Dot LocDiff;
00599		}
00600	
00601		// If client has accumulated a noticeable positional error, correct him.
00602		if ( ClientErr > 3 )
00603		{
00604			if ( Mover(Base) != None )
00605				ClientLoc = Location - Base.Location;
00606			else
00607				ClientLoc = Location;
00608			//log("Client Error at "$TimeStamp$" is "$ClientErr$" with acceleration "$Accel$" LocDiff "$LocDiff$" Physics "$Physics);
00609			LastUpdateTime = Level.TimeSeconds;
00610			ClientAdjustPosition
00611			(
00612				TimeStamp, 
00613				GetStateName(), 
00614				Physics, 
00615				ClientLoc.X, 
00616				ClientLoc.Y, 
00617				ClientLoc.Z, 
00618				Velocity.X, 
00619				Velocity.Y, 
00620				Velocity.Z,
00621				Base
00622			);
00623		}
00624		//log("Server "$Role$" moved "$self$" stamp "$TimeStamp$" location "$Location$" Acceleration "$Acceleration$" Velocity "$Velocity);
00625	}	
00626	
00627	function ProcessMove ( float DeltaTime, vector newAccel, eDodgeDir DodgeMove, rotator DeltaRot)
00628	{
00629		Acceleration = newAccel;
00630	}
00631	
00632	final function MoveAutonomous
00633	(	
00634		float DeltaTime, 	
00635		bool NewbRun,
00636		bool NewbDuck,
00637		bool NewbPressedJump, 
00638		eDodgeDir DodgeMove, 
00639		vector newAccel, 
00640		rotator DeltaRot
00641	)
00642	{
00643		if ( NewbRun )
00644			bRun = 1;
00645		else
00646			bRun = 0;
00647	
00648		if ( NewbDuck )
00649			bDuck = 1;
00650		else
00651			bDuck = 0;
00652		bPressedJump = NewbPressedJump;
00653	
00654		HandleWalking();
00655		ProcessMove(DeltaTime, newAccel, DodgeMove, DeltaRot);	
00656		AutonomousPhysics(DeltaTime);
00657		//log("Role "$Role$" moveauto time "$100 * DeltaTime$" ("$Level.TimeDilation$")");
00658	}
00659	
00660	// ClientAdjustPosition - pass newloc and newvel in components so they don't get rounded
00661	
00662	function ClientAdjustPosition
00663	(
00664		float TimeStamp, 
00665		name newState, 
00666		EPhysics newPhysics,
00667		float NewLocX, 
00668		float NewLocY, 
00669		float NewLocZ, 
00670		float NewVelX, 
00671		float NewVelY, 
00672		float NewVelZ,
00673		Actor NewBase
00674	)
00675	{
00676		local Decoration Carried;
00677		local vector OldLoc, NewLocation;
00678	
00679		if ( CurrentTimeStamp > TimeStamp )
00680			return;
00681		CurrentTimeStamp = TimeStamp;
00682	
00683		NewLocation.X = NewLocX;
00684		NewLocation.Y = NewLocY;
00685		NewLocation.Z = NewLocZ;
00686		Velocity.X = NewVelX;
00687		Velocity.Y = NewVelY;
00688		Velocity.Z = NewVelZ;
00689	
00690		SetBase(NewBase);
00691		if ( Mover(NewBase) != None )
00692			NewLocation += NewBase.Location;
00693	
00694		//log("Client "$Role$" adjust "$self$" stamp "$TimeStamp$" location "$Location);
00695		Carried = CarriedDecoration;
00696		OldLoc = Location;
00697		bCanTeleport = false;
00698		SetLocation(NewLocation);
00699		bCanTeleport = true;
00700		if ( Carried != None )
00701		{
00702			CarriedDecoration = Carried;
00703			CarriedDecoration.SetLocation(NewLocation + CarriedDecoration.Location - OldLoc);
00704			CarriedDecoration.SetPhysics(PHYS_None);
00705			CarriedDecoration.SetBase(self);
00706		}
00707		SetPhysics(newPhysics);
00708	
00709		if ( !IsInState(newState) )
00710			GotoState(newState);
00711	
00712		bUpdatePosition = true;
00713	}
00714	
00715	function ClientUpdatePosition()
00716	{
00717		local SavedMove CurrentMove;
00718		local int realbRun, realbDuck;
00719		local bool bRealJump;
00720	
00721		local float TotalTime, AdjPCol;
00722		local pawn P;
00723		local vector Dir;
00724	
00725		bUpdatePosition = false;
00726		realbRun= bRun;
00727		realbDuck = bDuck;
00728		bRealJump = bPressedJump;
00729		CurrentMove = SavedMoves;
00730		bUpdating = true;
00731		while ( CurrentMove != None )
00732		{
00733			if ( CurrentMove.TimeStamp <= CurrentTimeStamp )
00734			{
00735				SavedMoves = CurrentMove.NextMove;
00736				CurrentMove.NextMove = FreeMoves;
00737				FreeMoves = CurrentMove;
00738				FreeMoves.Clear();
00739				CurrentMove = SavedMoves;
00740			}
00741			else
00742			{
00743				// adjust radius of nearby players with uncertain location
00744				if ( TotalTime > 0 )
00745					ForEach AllActors(class'Pawn', P)
00746						if ( (P != self) && (P.Velocity != vect(0,0,0)) && P.bBlockPlayers )
00747						{
00748							Dir = Normal(P.Location - Location);
00749							if ( (Velocity Dot Dir > 0) && (P.Velocity Dot Dir > 0) )
00750							{
00751								// if other pawn moving away from player, push it away if its close
00752								// since the client-side position is behind the server side position
00753								if ( VSize(P.Location - Location) < P.CollisionRadius + CollisionRadius + CurrentMove.Delta * GroundSpeed )
00754									P.MoveSmooth(P.Velocity * 0.5 * PlayerReplicationInfo.Ping);
00755							}
00756						} 
00757				TotalTime += CurrentMove.Delta;
00758				MoveAutonomous(CurrentMove.Delta, CurrentMove.bRun, CurrentMove.bDuck, CurrentMove.bPressedJump, CurrentMove.DodgeMove, CurrentMove.Acceleration, rot(0,0,0));
00759				CurrentMove = CurrentMove.NextMove;
00760			}
00761		}
00762		bUpdating = false;
00763		bDuck = realbDuck;
00764		bRun = realbRun;
00765		bPressedJump = bRealJump;
00766		//log("Client adjusted "$self$" stamp "$CurrentTimeStamp$" location "$Location$" dodge "$DodgeDir);
00767	}
00768	
00769	final function SavedMove GetFreeMove()
00770	{
00771		local SavedMove s;
00772	
00773		if ( FreeMoves == None )
00774			return Spawn(class'SavedMove');
00775		else
00776		{
00777			s = FreeMoves;
00778			FreeMoves = FreeMoves.NextMove;
00779			s.NextMove = None;
00780			return s;
00781		}	
00782	}
00783	
00784	function int CompressAccel(int C)
00785	{
00786		if ( C >= 0 )
00787			C = Min(C, 127);
00788		else
00789			C = Min(abs(C), 127) + 128;
00790		return C;
00791	}
00792	
00793	//
00794	// Replicate this client's desired movement to the server.
00795	//
00796	function ReplicateMove
00797	(
00798		float DeltaTime, 
00799		vector NewAccel, 
00800		eDodgeDir DodgeMove, 
00801		rotator DeltaRot
00802	)
00803	{
00804		local SavedMove NewMove, OldMove, LastMove;
00805		local byte ClientRoll;
00806		local int i;
00807		local float OldTimeDelta, TotalTime, NetMoveDelta;
00808		local int OldAccel;
00809		local vector BuildAccel, AccelNorm;
00810	
00811		local float AdjPCol;
00812		local pawn P;
00813		local vector Dir;
00814	
00815		// Get a SavedMove actor to store the movement in.
00816		if ( PendingMove != None )
00817		{
00818			//add this move to the pending move
00819			PendingMove.TimeStamp = Level.TimeSeconds; 
00820			if ( VSize(NewAccel) > 3072 )
00821				NewAccel = 3072 * Normal(NewAccel);
00822			TotalTime = PendingMove.Delta + DeltaTime;
00823			PendingMove.Acceleration = (DeltaTime * NewAccel + PendingMove.Delta * PendingMove.Acceleration)/TotalTime;
00824	
00825			// Set this move's data.
00826			if ( PendingMove.DodgeMove == DODGE_None )
00827				PendingMove.DodgeMove = DodgeMove;
00828			PendingMove.bRun = (bRun > 0);
00829			PendingMove.bDuck = (bDuck > 0);
00830			PendingMove.bPressedJump = bPressedJump || PendingMove.bPressedJump;
00831			PendingMove.bFire = PendingMove.bFire || bJustFired || (bFire != 0);
00832			PendingMove.bForceFire = PendingMove.bForceFire || bJustFired;
00833			PendingMove.bAltFire = PendingMove.bAltFire || bJustAltFired || (bAltFire != 0);
00834			PendingMove.bForceAltFire = PendingMove.bForceAltFire || bJustFired;
00835			PendingMove.Delta = TotalTime;
00836		}
00837		if ( SavedMoves != None )
00838		{
00839			NewMove = SavedMoves;
00840			AccelNorm = Normal(NewAccel);
00841			while ( NewMove.NextMove != None )
00842			{
00843				// find most recent interesting move to send redundantly
00844				if ( NewMove.bPressedJump || ((NewMove.DodgeMove != Dodge_NONE) && (NewMove.DodgeMove < 5))
00845					|| ((NewMove.Acceleration != NewAccel) && ((normal(NewMove.Acceleration) Dot AccelNorm) < 0.95)) )
00846					OldMove = NewMove;
00847				NewMove = NewMove.NextMove;
00848			}
00849			if ( NewMove.bPressedJump || ((NewMove.DodgeMove != Dodge_NONE) && (NewMove.DodgeMove < 5))
00850				|| ((NewMove.Acceleration != NewAccel) && ((normal(NewMove.Acceleration) Dot AccelNorm) < 0.95)) )
00851				OldMove = NewMove;
00852		}
00853	
00854		LastMove = NewMove;
00855		NewMove = GetFreeMove();
00856		NewMove.Delta = DeltaTime;
00857		if ( VSize(NewAccel) > 3072 )
00858			NewAccel = 3072 * Normal(NewAccel);
00859		NewMove.Acceleration = NewAccel;
00860	
00861		// Set this move's data.
00862		NewMove.DodgeMove = DodgeMove;
00863		NewMove.TimeStamp = Level.TimeSeconds;
00864		NewMove.bRun = (bRun > 0);
00865		NewMove.bDuck = (bDuck > 0);
00866		NewMove.bPressedJump = bPressedJump;
00867		NewMove.bFire = (bJustFired || (bFire != 0));
00868		NewMove.bForceFire = bJustFired;
00869		NewMove.bAltFire = (bJustAltFired || (bAltFire != 0));
00870		NewMove.bForceAltFire = bJustAltFired;
00871		if ( Weapon != None ) // approximate pointing so don't have to replicate
00872			Weapon.bPointing = ((bFire != 0) || (bAltFire != 0));
00873		bJustFired = false;
00874		bJustAltFired = false;
00875		
00876		// adjust radius of nearby players with uncertain location
00877		ForEach AllActors(class'Pawn', P)
00878			if ( (P != self) && (P.Velocity != vect(0,0,0)) && P.bBlockPlayers )
00879			{
00880				Dir = Normal(P.Location - Location);
00881				if ( (Velocity Dot Dir > 0) && (P.Velocity Dot Dir > 0) )
00882				{
00883					// if other pawn moving away from player, push it away if its close
00884					// since the client-side position is behind the server side position
00885					if ( VSize(P.Location - Location) < P.CollisionRadius + CollisionRadius + NewMove.Delta * GroundSpeed )
00886						P.MoveSmooth(P.Velocity * 0.5 * PlayerReplicationInfo.Ping);
00887				}
00888			} 
00889	
00890		// Simulate the movement locally.
00891		ProcessMove(NewMove.Delta, NewMove.Acceleration, NewMove.DodgeMove, DeltaRot);
00892		AutonomousPhysics(NewMove.Delta);
00893	
00894		//log("Role "$Role$" repmove at "$Level.TimeSeconds$" Move time "$100 * DeltaTime$" ("$Level.TimeDilation$")");
00895	
00896		// Decide whether to hold off on move
00897		// send if dodge, jump, or fire unless really too soon, or if newmove.delta big enough
00898		// on client side, save extra buffered time in LastUpdateTime
00899		if ( PendingMove == None )
00900			PendingMove = NewMove;
00901		else
00902		{
00903			NewMove.NextMove = FreeMoves;
00904			FreeMoves = NewMove;
00905			FreeMoves.Clear();
00906			NewMove = PendingMove;
00907		}
00908		NetMoveDelta = FMax(64.0/Player.CurrentNetSpeed, 0.011);
00909		
00910		if ( !PendingMove.bForceFire && !PendingMove.bForceAltFire && !PendingMove.bPressedJump
00911			&& (PendingMove.Delta < NetMoveDelta - ClientUpdateTime) )
00912		{
00913			// save as pending move
00914			return;
00915		}
00916		else if ( (ClientUpdateTime < 0) && (PendingMove.Delta < NetMoveDelta - ClientUpdateTime) )
00917			return;
00918		else
00919		{
00920			ClientUpdateTime = PendingMove.Delta - NetMoveDelta;
00921			if ( SavedMoves == None )
00922				SavedMoves = PendingMove;
00923			else
00924				LastMove.NextMove = PendingMove;
00925			PendingMove = None;
00926		}
00927	
00928		// check if need to redundantly send previous move
00929		if ( OldMove != None )
00930		{
00931			// log("Redundant send timestamp "$OldMove.TimeStamp$" accel "$OldMove.Acceleration$" at "$Level.Timeseconds$" New accel "$NewAccel);
00932			// old move important to replicate redundantly
00933			OldTimeDelta = FMin(255, (Level.TimeSeconds - OldMove.TimeStamp) * 500);
00934			BuildAccel = 0.05 * OldMove.Acceleration + vect(0.5, 0.5, 0.5);
00935			OldAccel = (CompressAccel(BuildAccel.X) << 23) 
00936						+ (CompressAccel(BuildAccel.Y) << 15) 
00937						+ (CompressAccel(BuildAccel.Z) << 7);
00938			if ( OldMove.bRun )
00939				OldAccel += 64;
00940			if ( OldMove.bDuck )
00941				OldAccel += 32;
00942			if ( OldMove.bPressedJump )
00943				OldAccel += 16;
00944			OldAccel += OldMove.DodgeMove;
00945		}
00946		//else
00947		//	log("No redundant timestamp at "$Level.TimeSeconds$" with accel "$NewAccel);
00948	
00949		// Send to the server
00950		ClientRoll = (Rotation.Roll >> 8) & 255;
00951		if ( NewMove.bPressedJump )
00952			bJumpStatus = !bJumpStatus;
00953		ServerMove
00954		(
00955			NewMove.TimeStamp, 
00956			NewMove.Acceleration * 10, 
00957			Location, 
00958			NewMove.bRun,
00959			NewMove.bDuck,
00960			bJumpStatus, 
00961			NewMove.bFire,
00962			NewMove.bAltFire,
00963			NewMove.bForceFire,
00964			NewMove.bForceAltFire,
00965			NewMove.DodgeMove, 
00966			ClientRoll,
00967			(32767 & (ViewRotation.Pitch/2)) * 32768 + (32767 & (ViewRotation.Yaw/2)),
00968			OldTimeDelta,
00969			OldAccel 
00970		);
00971		//log("Replicated "$self$" stamp "$NewMove.TimeStamp$" location "$Location$" dodge "$NewMove.DodgeMove$" to "$DodgeDir);
00972	}
00973	
00974	function HandleWalking()
00975	{
00976		local rotator carried;
00977	
00978		bIsWalking = ((bRun != 0) || (bDuck != 0)) && !Region.Zone.IsA('WarpZoneInfo'); 
00979		if ( CarriedDecoration != None )
00980		{
00981			if ( (Role == ROLE_Authority) && (standingcount == 0) ) 
00982				CarriedDecoration = None;
00983			if ( CarriedDecoration != None ) //verify its still in front
00984			{
00985				bIsWalking = true;
00986				if ( Role == ROLE_Authority )
00987				{
00988					carried = Rotator(CarriedDecoration.Location - Location);
00989					carried.Yaw = ((carried.Yaw & 65535) - (Rotation.Yaw & 65535)) & 65535;
00990					if ( (carried.Yaw > 3072) && (carried.Yaw < 62463) )
00991						DropDecoration();
00992				}
00993			}
00994		}
00995	}
00996	
00997	//----------------------------------------------
00998	
00999	simulated event Destroyed()
01000	{
01001		Super.Destroyed();
01002		if ( myHud != None )
01003			myHud.Destroy();
01004		if ( Scoring != None )
01005			Scoring.Destroy();
01006	
01007		While ( FreeMoves != None )
01008		{
01009			FreeMoves.Destroy();
01010			FreeMoves = FreeMoves.NextMove;
01011		}
01012	
01013		While ( SavedMoves != None )
01014		{
01015			SavedMoves.Destroy();
01016			SavedMoves = SavedMoves.NextMove;
01017		}
01018	}
01019	
01020	function ServerReStartGame()
01021	{
01022	}
01023	
01024	function PlayHit(float Damage, vector HitLocation, name damageType, vector Momentum)
01025	{
01026		Level.Game.SpecialDamageString = "";
01027	}
01028	
01029	function SetFOVAngle(float newFOV)
01030	{
01031		FOVAngle = newFOV;
01032	}
01033		 
01034	function ClientFlash( float scale, vector fog )
01035	{
01036		DesiredFlashScale = scale;
01037		DesiredFlashFog = 0.001 * fog;
01038	}
01039	
01040	function ClientInstantFlash( float scale, vector fog )
01041	{
01042		InstantFlash = scale;
01043		InstantFog = 0.001 * fog;
01044	}
01045	
01046	//Play a sound client side (so only client will hear it
01047	simulated function ClientPlaySound(sound ASound, optional bool bInterrupt, optional bool bVolumeControl )
01048	{	
01049		local actor SoundPlayer;
01050	
01051		LastPlaySound = Level.TimeSeconds;	// so voice messages won't overlap
01052		if ( ViewTarget != None )
01053			SoundPlayer = ViewTarget;
01054		else
01055			SoundPlayer = self;
01056	
01057		SoundPlayer.PlaySound(ASound, SLOT_None, 16.0, bInterrupt);
01058		SoundPlayer.PlaySound(ASound, SLOT_Interface, 16.0, bInterrupt);
01059		SoundPlayer.PlaySound(ASound, SLOT_Misc, 16.0, bInterrupt);
01060		SoundPlayer.PlaySound(ASound, SLOT_Talk, 16.0, bInterrupt);
01061	}
01062	
01063	simulated function ClientReliablePlaySound(sound ASound, optional bool bInterrupt, optional bool bVolumeControl )
01064	{
01065		ClientPlaySound(ASound, bInterrupt, bVolumeControl);
01066	}
01067	   
01068	function ClientAdjustGlow( float scale, vector fog )
01069	{
01070		ConstantGlowScale += scale;
01071		ConstantGlowFog += 0.001 * fog;
01072	}
01073	
01074	function ClientShake(vector shake)
01075	{
01076		if ( (shakemag < shake.X) || (shaketimer <= 0.01 * shake.Y) )
01077		{
01078			shakemag = shake.X;
01079			shaketimer = 0.01 * shake.Y;	
01080			maxshake = 0.01 * shake.Z;
01081			verttimer = 0;
01082			ShakeVert = -1.1 * maxshake;
01083		}
01084	}
01085	
01086	function ShakeView( float shaketime, float RollMag, float vertmag)
01087	{
01088		local vector shake;
01089	
01090		shake.X = RollMag;
01091		shake.Y = 100 * shaketime;
01092		shake.Z = 100 * vertmag;
01093		ClientShake(shake);
01094	}
01095	
01096	function ClientSetMusic( music NewSong, byte NewSection, byte NewCdTrack, EMusicTransition NewTransition )
01097	{
01098		Song        = NewSong;
01099		SongSection = NewSection;
01100		CdTrack     = NewCdTrack;
01101		Transition  = NewTransition;
01102	}
01103	
01104	function ServerFeignDeath()
01105	{
01106	}
01107	
01108	function ServerSetHandedness( float hand)
01109	{
01110		Handedness = hand;
01111		if ( Weapon != None )
01112			Weapon.SetHand(Handedness);
01113	}
01114	
01115	function ServerReStartPlayer()
01116	{
01117	}
01118	
01119	function ServerChangeSkin( coerce string SkinName, coerce string FaceName, byte TeamNum )
01120	{
01121		local string MeshName;
01122	
01123		MeshName = GetItemName(string(Mesh));
01124		if ( Level.Game.bCanChangeSkin )
01125		{
01126			Self.static.SetMultiSkin(Self, SkinName, FaceName, TeamNum );
01127		}
01128	}
01129	
01130	//*************************************************************************************
01131	// Normal gameplay execs
01132	// Type the name of the exec function at the console to execute it
01133	
01134	exec function ShowSpecialMenu( string ClassName )
01135	{
01136		local class<menu> aMenuClass;
01137	
01138		aMenuClass = class<menu>( DynamicLoadObject( ClassName, class'Class' ) );
01139		if( aMenuClass!=None )
01140		{
01141			bSpecialMenu = true;
01142			SpecialMenu = aMenuClass;
01143			ShowMenu();
01144		}
01145	}
01146		
01147	exec function Jump( optional float F )
01148	{
01149		if ( !bShowMenu && (Level.Pauser == PlayerReplicationInfo.PlayerName) )
01150			SetPause(False);
01151		else
01152			bPressedJump = true;
01153	}
01154	
01155	exec function CauseEvent( name N )
01156	{
01157		local actor A;
01158		if( !bCheatsEnabled )
01159			return;
01160		if( (bAdmin || (Level.Netmode == NM_Standalone)) && (N != '') )
01161			foreach AllActors( class 'Actor', A, N )
01162				A.Trigger( Self, Self );
01163	}
01164	
01165	exec function Taunt( name Sequence )
01166	{
01167		if ( GetAnimGroup(Sequence) == 'Gesture' ) 
01168		{
01169			ServerTaunt(Sequence);
01170			PlayAnim(Sequence, 0.7, 0.2);
01171		}
01172	}
01173	
01174	function ServerTaunt(name Sequence )
01175	{
01176		PlayAnim(Sequence, 0.7, 0.2);
01177	}
01178	
01179	exec function FeignDeath()
01180	{
01181	}
01182	
01183	exec function CallForHelp()
01184	{
01185		local Pawn P;
01186	
01187		if ( !Level.Game.bTeamGame || (Enemy == None) || (Enemy.Health <= 0) )
01188			return;
01189	
01190		for ( P=Level.PawnList; P!=None; P=P.NextPawn )
01191			if ( P.bIsPlayer && (P.PlayerReplicationInfo.Team == PlayerReplicationInfo.Team) )
01192				P.HandleHelpMessageFrom(self);
01193	}
01194	
01195	function damageAttitudeTo(pawn Other)
01196	{
01197		if ( Other != Self )
01198			Enemy = Other;
01199	}
01200	
01201	exec function Grab()
01202	{
01203		if (CarriedDecoration == None)
01204			GrabDecoration();
01205		else
01206			DropDecoration();
01207	}
01208	
01209	// Send a voice message of a certain type to a certain player.
01210	exec function Speech( int Type, int Index, int Callsign )
01211	{
01212		local VoicePack V;
01213	
01214		V = Spawn( PlayerReplicationInfo.VoiceType, Self );
01215		if (V != None)
01216			V.PlayerSpeech( Type, Index, Callsign );
01217	}
01218	
01219	function PlayChatting();
01220	
01221	function Typing( bool bTyping )
01222	{
01223		bIsTyping = bTyping;
01224		if (bTyping)
01225		{
01226			if (Level.Game.WorldLog != None)
01227				Level.Game.WorldLog.LogTypingEvent(True, Self);
01228			if (Level.Game.LocalLog != None)
01229				Level.Game.LocalLog.LogTypingEvent(True, Self);
01230			PlayChatting();
01231		} 
01232		else 
01233		{
01234			if (Level.Game.WorldLog != None)
01235				Level.Game.WorldLog.LogTypingEvent(False, Self);
01236			if (Level.Game.LocalLog != None)
01237				Level.Game.LocalLog.LogTypingEvent(False, Self);
01238		}
01239	}
01240	
01241	
01242	// Send a message to all players.
01243	exec function Say( string Msg )
01244	{
01245		local Pawn P;
01246	
01247		if ( bAdmin && (left(Msg,1) == "#") )
01248		{
01249			Msg = right(Msg,len(Msg)-1);
01250			for( P=Level.PawnList; P!=None; P=P.nextPawn )
01251				if( P.IsA('PlayerPawn') )
01252				{
01253					PlayerPawn(P).SetProgressTime(6);
01254					PlayerPawn(P).SetProgressMessage(Msg,0);
01255				}
01256			return;
01257		}
01258		if ( Level.Game.AllowsBroadcast(self, Len(Msg)) )
01259			for( P=Level.PawnList; P!=None; P=P.nextPawn )
01260				if( P.bIsPlayer || P.IsA('MessagingSpectator') )
01261				{
01262					if ( (Level.Game != None) && (Level.Game.MessageMutator != None) )
01263					{
01264						if ( Level.Game.MessageMutator.MutatorTeamMessage(Self, P, PlayerReplicationInfo, Msg, 'Say', true) )
01265							P.TeamMessage( PlayerReplicationInfo, Msg, 'Say', true );
01266					} else
01267						P.TeamMessage( PlayerReplicationInfo, Msg, 'Say', true );
01268				}
01269		return;
01270	}
01271	
01272	exec function TeamSay( string Msg )
01273	{
01274		local Pawn P;
01275	
01276		if ( !Level.Game.bTeamGame )
01277		{
01278			Say(Msg);
01279			return;
01280		}
01281	
01282		if ( Msg ~= "Help" )
01283		{
01284			CallForHelp();
01285			return;
01286		}
01287				
01288		if ( Level.Game.AllowsBroadcast(self, Len(Msg)) )
01289			for( P=Level.PawnList; P!=None; P=P.nextPawn )
01290				if( P.bIsPlayer && (P.PlayerReplicationInfo.Team == PlayerReplicationInfo.Team) )
01291				{
01292					if ( P.IsA('PlayerPawn') )
01293					{
01294						if ( (Level.Game != None) && (Level.Game.MessageMutator != None) )
01295						{
01296							if ( Level.Game.MessageMutator.MutatorTeamMessage(Self, P, PlayerReplicationInfo, Msg, 'TeamSay', true) )
01297								P.TeamMessage( PlayerReplicationInfo, Msg, 'TeamSay', true );
01298						} else
01299							P.TeamMessage( PlayerReplicationInfo, Msg, 'TeamSay', true );
01300					}
01301				}
01302	}
01303	
01304	exec function RestartLevel()
01305	{
01306		if( bAdmin || Level.Netmode==NM_Standalone )
01307			ClientTravel( "?restart", TRAVEL_Relative, false );
01308	}
01309	
01310	exec function LocalTravel( string URL )
01311	{
01312		if( bAdmin || Level.Netmode==NM_Standalone )
01313			ClientTravel( URL, TRAVEL_Relative, true );
01314	}
01315	
01316	exec function ThrowWeapon()
01317	{
01318		if( Level.NetMode == NM_Client )
01319			return;
01320		if( Weapon==None || (Weapon.Class==Level.Game.BaseMutator.MutatedDefaultWeapon())
01321			|| !Weapon.bCanThrow )
01322			return;
01323		Weapon.Velocity = Vector(ViewRotation) * 500 + vect(0,0,220);
01324		Weapon.bTossedOut = true;
01325		TossWeapon();
01326		if ( Weapon == None )
01327			SwitchToBestWeapon();
01328	}
01329	
01330	function ToggleZoom()
01331	{
01332		if ( DefaultFOV != DesiredFOV )
01333			EndZoom();
01334		else
01335			StartZoom();
01336	}
01337		
01338	function StartZoom()
01339	{
01340		ZoomLevel = 0.0;
01341		bZooming = true;
01342	}
01343	
01344	function StopZoom()
01345	{
01346		bZooming = false;
01347	}
01348	
01349	function EndZoom()
01350	{
01351		bZooming = false;
01352		DesiredFOV = DefaultFOV;
01353	}
01354	
01355	exec function FOV(float F)
01356	{
01357		SetDesiredFOV(F);
01358	}
01359		
01360	exec function SetDesiredFOV(float F)
01361	{
01362		if( (F >= 80.0) || Level.bAllowFOV || bAdmin || (Level.Netmode==NM_Standalone) )
01363		{
01364			DefaultFOV = FClamp(F, 1, 170);
01365			DesiredFOV = DefaultFOV;
01366			SaveConfig();
01367		}
01368	}
01369	
01370	/* PrevWeapon()
01371	- switch to previous inventory group weapon
01372	*/
01373	exec function PrevWeapon()
01374	{
01375		local int prevGroup;
01376		local Inventory inv;
01377		local Weapon realWeapon, w, Prev;
01378		local bool bFoundWeapon;
01379	
01380		if( bShowMenu || Level.Pauser!="" )
01381			return;
01382		if ( Weapon == None )
01383		{
01384			SwitchToBestWeapon();
01385			return;
01386		}
01387		prevGroup = 0;
01388		realWeapon = Weapon;
01389		if ( PendingWeapon != None )
01390			Weapon = PendingWeapon;
01391		PendingWeapon = None;
01392		
01393		for (inv=Inventory; inv!=None; inv=inv.Inventory)
01394		{
01395			w = Weapon(inv);
01396			if ( w != None )
01397			{
01398				if ( w.InventoryGroup == Weapon.InventoryGroup )
01399				{
01400					if ( w == Weapon )
01401					{
01402						bFoundWeapon = true;
01403						if ( Prev != None )
01404						{
01405							PendingWeapon = Prev;
01406							break;
01407						}
01408					}
01409					else if ( !bFoundWeapon && ((w.AmmoType == None) || (w.AmmoType.AmmoAmount>0)) )
01410						Prev = W;
01411				}
01412				else if ( (w.InventoryGroup < Weapon.InventoryGroup) 
01413						&& ((w.AmmoType == None) || (w.AmmoType.AmmoAmount>0)) 
01414						&& (w.InventoryGroup >= prevGroup) )
01415				{
01416					prevGroup = w.InventoryGroup;
01417					PendingWeapon = w;
01418				}
01419			}
01420		}
01421		bFoundWeapon = false;
01422		prevGroup = Weapon.InventoryGroup;
01423		if ( PendingWeapon == None )
01424			for (inv=Inventory; inv!=None; inv=inv.Inventory)
01425			{
01426				w = Weapon(inv);
01427				if ( w != None )
01428				{
01429					if ( w.InventoryGroup == Weapon.InventoryGroup )
01430					{
01431						if ( w == Weapon )
01432							bFoundWeapon = true;
01433						else if ( bFoundWeapon && (PendingWeapon == None) && ((w.AmmoType == None) || (w.AmmoType.AmmoAmount>0)) )
01434							PendingWeapon = W;
01435					}
01436					else if ( (w.InventoryGroup > PrevGroup) 
01437							&& ((w.AmmoType == None) || (w.AmmoType.AmmoAmount>0)) ) 
01438					{
01439						prevGroup = w.InventoryGroup;
01440						PendingWeapon = w;
01441					}
01442				}
01443			}
01444	
01445		Weapon = realWeapon;
01446		if ( PendingWeapon == None )
01447			return;
01448	
01449		Weapon.PutDown();
01450	}
01451	
01452	/* NextWeapon()
01453	- switch to next inventory group weapon
01454	*/
01455	exec function NextWeapon()
01456	{
01457		local int nextGroup;
01458		local Inventory inv;
01459		local Weapon realWeapon, w, Prev;
01460		local bool bFoundWeapon;
01461	
01462		if( bShowMenu || Level.Pauser!="" )
01463			return;
01464		if ( Weapon == None )
01465		{
01466			SwitchToBestWeapon();
01467			return;
01468		}
01469		nextGroup = 100;
01470		realWeapon = Weapon;
01471		if ( PendingWeapon != None )
01472			Weapon = PendingWeapon;
01473		PendingWeapon = None;
01474	
01475		for (inv=Inventory; inv!=None; inv=inv.Inventory)
01476		{
01477			w = Weapon(inv);
01478			if ( w != None )
01479			{
01480				if ( w.InventoryGroup == Weapon.InventoryGroup )
01481				{
01482					if ( w == Weapon )
01483						bFoundWeapon = true;
01484					else if ( bFoundWeapon && ((w.AmmoType == None) || (w.AmmoType.AmmoAmount>0)) )
01485					{
01486						PendingWeapon = W;
01487						break;
01488					}
01489				}
01490				else if ( (w.InventoryGroup > Weapon.InventoryGroup) 
01491						&& ((w.AmmoType == None) || (w.AmmoType.AmmoAmount>0)) 
01492						&& (w.InventoryGroup < nextGroup) )
01493				{
01494					nextGroup = w.InventoryGroup;
01495					PendingWeapon = w;
01496				}
01497			}
01498		}
01499	
01500		bFoundWeapon = false;
01501		nextGroup = Weapon.InventoryGroup;
01502		if ( PendingWeapon == None )
01503			for (inv=Inventory; inv!=None; inv=inv.Inventory)
01504			{
01505				w = Weapon(Inv);
01506				if ( w != None )
01507				{
01508					if ( w.InventoryGroup == Weapon.InventoryGroup )
01509					{
01510						if ( w == Weapon )
01511						{
01512							bFoundWeapon = true;
01513							if ( Prev != None )
01514								PendingWeapon = Prev;
01515						}
01516						else if ( !bFoundWeapon && (PendingWeapon == None) && ((w.AmmoType == None) || (w.AmmoType.AmmoAmount>0)) )
01517							Prev = W;
01518					}
01519					else if ( (w.InventoryGroup < nextGroup) 
01520						&& ((w.AmmoType == None) || (w.AmmoType.AmmoAmount>0)) ) 
01521					{
01522						nextGroup = w.InventoryGroup;
01523						PendingWeapon = w;
01524					}
01525				}
01526			}
01527	
01528		Weapon = realWeapon;
01529		if ( PendingWeapon == None )
01530			return;
01531	
01532		Weapon.PutDown();
01533	}
01534	
01535	exec function Mutate(string MutateString)
01536	{
01537		if( Level.NetMode == NM_Client )
01538			return;
01539		Level.Game.BaseMutator.Mutate(MutateString, Self);
01540	}
01541	
01542	exec function QuickSave()
01543	{
01544		if ( (Health > 0) 
01545			&& (Level.NetMode == NM_Standalone)
01546			&& !Level.Game.bDeathMatch )
01547		{
01548			ClientMessage(QuickSaveString);
01549			ConsoleCommand("SaveGame 9");
01550		}
01551	}
01552	
01553	exec function QuickLoad()
01554	{
01555		if ( (Level.NetMode == NM_Standalone)
01556			&& !Level.Game.bDeathMatch )
01557			ClientTravel( "?load=9", TRAVEL_Absolute, false);
01558	}
01559	
01560	exec function Kick( string S ) 
01561	{
01562		local Pawn aPawn;
01563		if( !bAdmin )
01564			return;
01565		for( aPawn=Level.PawnList; aPawn!=None; aPawn=aPawn.NextPawn )
01566			if
01567			(	aPawn.bIsPlayer
01568				&&	aPawn.PlayerReplicationInfo.PlayerName~=S 
01569				&&	(PlayerPawn(aPawn)==None || NetConnection(PlayerPawn(aPawn).Player)!=None ) )
01570			{
01571				aPawn.Destroy();
01572				return;
01573			}
01574	}
01575	
01576	exec function KickBan( string S ) 
01577	{
01578		local Pawn aPawn;
01579		local string IP;
01580		local int j;
01581		if( !bAdmin )
01582			return;
01583		for( aPawn=Level.PawnList; aPawn!=None; aPawn=aPawn.NextPawn )
01584			if
01585			(	aPawn.bIsPlayer
01586				&&	aPawn.PlayerReplicationInfo.PlayerName~=S 
01587				&&	(PlayerPawn(aPawn)==None || NetConnection(PlayerPawn(aPawn).Player)!=None ) )
01588			{
01589				IP = PlayerPawn(aPawn).GetPlayerNetworkAddress();
01590				if(Level.Game.CheckIPPolicy(IP))
01591				{
01592					IP = Left(IP, InStr(IP, ":"));
01593					Log("Adding IP Ban for: "$IP);
01594					for(j=0;j<50;j++)
01595						if(Level.Game.IPPolicies[j] == "")
01596							break;
01597					if(j < 50)
01598						Level.Game.IPPolicies[j] = "DENY,"$IP;
01599					Level.Game.SaveConfig();
01600				}
01601				aPawn.Destroy();
01602				return;
01603			}
01604	}
01605	
01606	// Try to set the pause state; returns success indicator.
01607	function bool SetPause( BOOL bPause )
01608	{
01609		return Level.Game.SetPause(bPause, self);
01610	}
01611	
01612	exec function SetMouseSmoothThreshold( float F )
01613	{
01614		MouseSmoothThreshold = FClamp(F, 0, 0.1);
01615		SaveConfig();
01616	}
01617	
01618	exec function SetMaxMouseSmoothing( bool B )
01619	{
01620		bMaxMouseSmoothing = B;
01621		SaveConfig();
01622	}
01623	
01624	// Try to pause the game.
01625	exec function Pause()
01626	{
01627		if ( bShowMenu )
01628			return;
01629		if( !SetPause(Level.Pauser=="") )
01630			ClientMessage(NoPauseMessage);
01631	}
01632	
01633	// Activate specific inventory item
01634	exec function ActivateInventoryItem( class InvItem )
01635	{
01636		local Inventory Inv;
01637	
01638		Inv = FindInventoryType(InvItem);
01639		if ( Inv != None )
01640			Inv.Activate();
01641	}
01642	
01643	// Translator Hotkey
01644	exec function ActivateTranslator()
01645	{
01646		if ( bShowMenu || Level.Pauser!="" )
01647			return;
01648		If (Inventory!=None) Inventory.ActivateTranslator(False);
01649	}
01650	
01651	// Translator Hotkey
01652	exec function ActivateHint()
01653	{
01654		if ( bShowMenu || Level.Pauser!="" )
01655			return;
01656		If (Inventory!=None) Inventory.ActivateTranslator(True);
01657	}
01658	
01659	// HUD
01660	exec function ChangeHud()
01661	{
01662		if ( myHud != None )
01663			myHUD.ChangeHud(1);
01664		myHUD.SaveConfig();
01665	}
01666	
01667	// Crosshair
01668	exec function ChangeCrosshair()
01669	{
01670		if ( myHud != None ) 
01671			myHUD.ChangeCrosshair(1);
01672		myHUD.SaveConfig();
01673	}
01674	
01675	
01676	event PreRender( canvas Canvas )
01677	{
01678		if ( myHud != None )	
01679			myHUD.PreRender(Canvas);
01680		else if ( (Viewport(Player) != None) && (HUDType != None) )
01681			myHUD = spawn(HUDType, self);
01682	}
01683	
01684	event PostRender( canvas Canvas )
01685	{
01686		if ( myHud != None )	
01687			myHUD.PostRender(Canvas);
01688		else if ( (Viewport(Player) != None) && (HUDType != None) )
01689			myHUD = spawn(HUDType, self);
01690	}
01691	
01692	//=============================================================================
01693	// Inventory-related input notifications.
01694	
01695	// Handle function keypress for F1-F10.
01696	exec function FunctionKey( byte Num )
01697	{
01698	}
01699	
01700	// The player wants to switch to weapon group numer I.
01701	exec function SwitchWeapon (byte F )
01702	{
01703		local weapon newWeapon;
01704	
01705		if ( bShowMenu || Level.Pauser!="" )
01706		{
01707			if ( myHud != None )
01708				myHud.InputNumber(F);
01709			return;
01710		}
01711		if ( Inventory == None )
01712			return;
01713		if ( (Weapon != None) && (Weapon.Inventory != None) )
01714			newWeapon = Weapon.Inventory.WeaponChange(F);
01715		else
01716			newWeapon = None;	
01717		if ( newWeapon == None )
01718			newWeapon = Inventory.WeaponChange(F);
01719		if ( newWeapon == None )
01720			return;
01721	
01722		if ( Weapon == None )
01723		{
01724			PendingWeapon = newWeapon;
01725			ChangedWeapon();
01726		}
01727		else if ( Weapon != newWeapon )
01728		{
01729			PendingWeapon = newWeapon;
01730			if ( !Weapon.PutDown() )
01731				PendingWeapon = None;
01732		}
01733	}
01734	
01735	exec function GetWeapon(class<Weapon> NewWeaponClass )
01736	{
01737		local Inventory Inv;
01738	
01739		if ( (Inventory == None) || (NewWeaponClass == None)
01740			|| ((Weapon != None) && (Weapon.Class == NewWeaponClass)) )
01741			return;
01742	
01743		for ( Inv=Inventory; Inv!=None; Inv=Inv.Inventory )
01744			if ( Inv.Class == NewWeaponClass )
01745			{
01746				PendingWeapon = Weapon(Inv);
01747				if ( (PendingWeapon.AmmoType != None) && (PendingWeapon.AmmoType.AmmoAmount <= 0) )
01748				{
01749					Pawn(Owner).ClientMessage( PendingWeapon.ItemName$PendingWeapon.MessageNoAmmo );
01750					PendingWeapon = None;
01751					return;
01752				}
01753				Weapon.PutDown();
01754				return;
01755			}
01756	}
01757		
01758	// The player wants to select previous item
01759	exec function PrevItem()
01760	{
01761		local Inventory Inv, LastItem;
01762	
01763		if ( bShowMenu || Level.Pauser!="" )
01764			return;
01765		if (SelectedItem==None) {
01766			SelectedItem = Inventory.SelectNext();
01767			Return;
01768		}
01769		if (SelectedItem.Inventory!=None) 
01770			for( Inv=SelectedItem.Inventory; Inv!=None; Inv=Inv.Inventory ) {
01771				if (Inv==None) Break;
01772				if (Inv.bActivatable) LastItem=Inv;
01773			}
01774		for( Inv=Inventory; Inv!=SelectedItem; Inv=Inv.Inventory ) {
01775			if (Inv==None) Break;
01776			if (Inv.bActivatable) LastItem=Inv;
01777		}
01778		if (LastItem!=None) {
01779			SelectedItem = LastItem;
01780			ClientMessage(SelectedItem.ItemName$SelectedItem.M_Selected);
01781		}
01782	}
01783	
01784	// The player wants to active selected item
01785	exec function ActivateItem()
01786	{
01787		if( bShowMenu || Level.Pauser!="" )
01788			return;
01789		if (SelectedItem!=None) 
01790			SelectedItem.Activate();
01791	}
01792	
01793	// The player wants to fire.
01794	exec function Fire( optional float F )
01795	{
01796		bJustFired = true;
01797		if( bShowMenu || (Level.Pauser!="") || (Role < ROLE_Authority) )
01798		{
01799			if( (Role < ROLE_Authority) && (Weapon!=None) )
01800				bJustFired = Weapon.ClientFire(F);
01801			if ( !bShowMenu && (Level.Pauser == PlayerReplicationInfo.PlayerName)  )
01802				SetPause(False);
01803			return;
01804		}
01805		if( Weapon!=None )
01806		{
01807			Weapon.bPointing = true;
01808			PlayFiring();
01809			Weapon.Fire(F);
01810		}
01811	}
01812	
01813	// The player wants to alternate-fire.
01814	exec function AltFire( optional float F )
01815	{
01816		bJustAltFired = true;
01817		if( bShowMenu || (Level.Pauser!="") || (Role < ROLE_Authority) )
01818		{
01819			if( (Role < ROLE_Authority) && (Weapon!=None) )
01820				bJustAltFired = Weapon.ClientAltFire(F);
01821			if ( !bShowMenu && (Level.Pauser == PlayerReplicationInfo.PlayerName) )
01822				SetPause(False);
01823			return;
01824		}
01825		if( Weapon!=None )
01826		{
01827			Weapon.bPointing = true;
01828			PlayFiring();
01829			Weapon.AltFire(F);
01830		}
01831	}
01832	
01833	//Player Jumped
01834	function DoJump( optional float F )
01835	{
01836		if ( CarriedDecoration != None )
01837			return;
01838		if ( !bIsCrouching && (Physics == PHYS_Walking) )
01839		{
01840			if ( !bUpdating )
01841				PlayOwnedSound(JumpSound, SLOT_Talk, 1.5, true, 1200, 1.0 );
01842			if ( (Level.Game != None) && (Level.Game.Difficulty > 0) )
01843				MakeNoise(0.1 * Level.Game.Difficulty);
01844			PlayInAir();
01845			if ( bCountJumps && (Role == ROLE_Authority) && (Inventory != None) )
01846				Inventory.OwnerJumped();
01847			Velocity.Z = JumpZ;
01848			if ( (Base != Level) && (Base != None) )
01849				Velocity.Z += Base.Velocity.Z; 
01850			SetPhysics(PHYS_Falling);
01851		}
01852	}
01853	
01854	exec function Suicide()
01855	{
01856		KilledBy( None );
01857	}
01858	
01859	exec function AlwaysMouseLook( Bool B )
01860	{
01861		ChangeAlwaysMouseLook(B);
01862		SaveConfig();
01863	}
01864	
01865	function ChangeAlwaysMouseLook(Bool B)
01866	{
01867		bAlwaysMouseLook = B;
01868		if ( bAlwaysMouseLook )
01869			bLookUpStairs = false;
01870	}
01871		
01872	exec function SnapView( bool B )
01873	{
01874		ChangeSnapView(B);
01875		SaveConfig();
01876	}
01877	
01878	function ChangeSnapView( bool B )
01879	{
01880		bSnapToLevel = B;
01881	}
01882		
01883	exec function StairLook( bool B )
01884	{
01885		ChangeStairLook(B);
01886		SaveConfig();
01887	}
01888	
01889	function ChangeStairLook( bool B )
01890	{
01891		bLookUpStairs = B;
01892		if ( bLookUpStairs )
01893			bAlwaysMouseLook = false;
01894	}
01895	
01896	exec function SetDodgeClickTime( float F )
01897	{
01898		ChangeDodgeClickTime(F);
01899		SaveConfig();
01900	}
01901	
01902	function ChangeDodgeClickTime( float F )
01903	{
01904		DodgeClickTime = FMin(0.3, F);
01905	}
01906	
01907	final function ReplaceText(out string Text, string Replace, string With)
01908	{
01909		local int i;
01910		local string Input;
01911			
01912		Input = Text;
01913		Text = "";
01914		i = InStr(Input, Replace);
01915		while(i != -1)
01916		{	
01917			Text = Text $ Left(Input, i) $ With;
01918			Input = Mid(Input, i + Len(Replace));	
01919			i = InStr(Input, Replace);
01920		}
01921		Text = Text $ Input;
01922	}
01923	
01924	exec function SetName( coerce string S )
01925	{
01926		if ( Len(S) > 28 )
01927			S = left(S,28);
01928		ReplaceText(S, " ", "_");
01929		ChangeName(S);
01930		UpdateURL("Name", S, true);
01931		SaveConfig();
01932	}
01933	
01934	exec function Name( coerce string S )
01935	{
01936		SetName(S);
01937	}
01938	
01939	function ChangeName( coerce string S )
01940	{
01941		Level.Game.ChangeName( self, S, false );
01942	}
01943	
01944	function ChangeTeam( int N )
01945	{
01946		local int OldTeam;
01947	
01948		OldTeam = PlayerReplicationInfo.Team;
01949		Level.Game.ChangeTeam(self, N);
01950		if ( Level.Game.bTeamGame && (PlayerReplicationInfo.Team != OldTeam) )
01951			Died( None, '', Location );
01952	}
01953	
01954	function ClientChangeTeam( int N )
01955	{
01956		local Pawn P;
01957			
01958		if ( PlayerReplicationInfo != None )
01959			PlayerReplicationInfo.Team = N;
01960	
01961		// if listen server, this may be called for non-local players that are logging in
01962		// if so, don't update URL
01963		if ( (Level.NetMode == NM_ListenServer) && (Player == None) )
01964		{
01965			// check if any other players exist
01966			for ( P=Level.PawnList; P!=None; P=P.NextPawn )
01967				if ( P.IsA('PlayerPawn') && (ViewPort(PlayerPawn(P).Player) != None) )
01968					return;
01969		}
01970			
01971		UpdateURL("Team",string(N), true);	
01972	}
01973	
01974	exec function SetAutoAim( float F )
01975	{
01976		ChangeAutoAim(F);
01977		SaveConfig();
01978	}
01979	
01980	function ChangeAutoAim( float F )
01981	{
01982		MyAutoAim = FMax(Level.Game.AutoAim, F);
01983	}
01984	
01985	exec function PlayersOnly()
01986	{
01987		if ( Level.Netmode != NM_Standalone )
01988			return;
01989	
01990		Level.bPlayersOnly = !Level.bPlayersOnly;
01991	}
01992	
01993	exec function SetHand( string S )
01994	{
01995		ChangeSetHand(S);
01996		SaveConfig();
01997	}
01998	
01999	function ChangeSetHand( string S )
02000	{
02001		if ( S ~= "Left" )
02002			Handedness = 1;
02003		else if ( S~= "Right" )
02004			Handedness = -1;
02005		else if ( S ~= "Center" )
02006			Handedness = 0;
02007		else if ( S ~= "Hidden" )
02008			Handedness = 2;
02009		ServerSetHandedness(Handedness);
02010	}
02011	
02012	exec function ViewPlayer( string S )
02013	{
02014		local pawn P;
02015	
02016		for ( P=Level.pawnList; P!=None; P= P.NextPawn )
02017			if ( P.bIsPlayer && (P.PlayerReplicationInfo.PlayerName ~= S) )
02018				break;
02019	
02020		if ( (P != None) && Level.Game.CanSpectate(self, P) )
02021		{
02022			ClientMessage(ViewingFrom@P.PlayerReplicationInfo.PlayerName, 'Event', true);
02023			if ( P == self)
02024				ViewTarget = None;
02025			else
02026				ViewTarget = P;
02027		}
02028		else
02029			ClientMessage(FailedView);
02030	
02031		bBehindView = ( ViewTarget != None );
02032		if ( bBehindView )
02033			ViewTarget.BecomeViewTarget();
02034	}
02035	
02036	exec function CheatView( class<actor> aClass )
02037	{
02038		local actor other, first;
02039		local bool bFound;
02040	
02041		if( !bCheatsEnabled )
02042			return;
02043	
02044		if( !bAdmin && Level.NetMode!=NM_Standalone )
02045			return;
02046	
02047		first = None;
02048		ForEach AllActors( aClass, other )
02049		{
02050			if ( (first == None) && (other != self) )
02051			{
02052				first = other;
02053				bFound = true;
02054			}
02055			if ( other == ViewTarget ) 
02056				first = None;
02057		}  
02058	
02059		if ( first != None )
02060		{
02061			if ( first.IsA('Pawn') && Pawn(first).bIsPlayer && (Pawn(first).PlayerReplicationInfo.PlayerName != "") )
02062				ClientMessage(ViewingFrom@Pawn(first).PlayerReplicationInfo.PlayerName, 'Event', true);
02063			else
02064				ClientMessage(ViewingFrom@first, 'Event', true);
02065			ViewTarget = first;
02066		}
02067		else
02068		{
02069			if ( bFound )
02070				ClientMessage(ViewingFrom@OwnCamera, 'Event', true);
02071			else
02072				ClientMessage(FailedView, 'Event', true);
02073			ViewTarget = None;
02074		}
02075	
02076		bBehindView = ( ViewTarget != None );
02077		if ( bBehindView )
02078			ViewTarget.BecomeViewTarget();
02079	}
02080	
02081	exec function ViewSelf()
02082	{
02083		bBehindView = false;
02084		Viewtarget = None;
02085		ClientMessage(ViewingFrom@OwnCamera, 'Event', true);
02086	}
02087	
02088	exec function ViewClass( class<actor> aClass, optional bool bQuiet )
02089	{
02090		local actor other, first;
02091		local bool bFound;
02092	
02093		if ( (Level.Game != None) && !Level.Game.bCanViewOthers )
02094			return;
02095	
02096		first = None;
02097		ForEach AllActors( aClass, other )
02098		{
02099			if ( (first == None) && (other != self)
02100				 && ( (bAdmin && Level.Game==None) || Level.Game.CanSpectate(self, other) ) )
02101			{
02102				first = other;
02103				bFound = true;
02104			}
02105			if ( other == ViewTarget ) 
02106				first = None;
02107		}  
02108	
02109		if ( first != None )
02110		{
02111			if ( !bQuiet )
02112			{
02113				if ( first.IsA('Pawn') && Pawn(first).bIsPlayer && (Pawn(first).PlayerReplicationInfo.PlayerName != "") )
02114					ClientMessage(ViewingFrom@Pawn(first).PlayerReplicationInfo.PlayerName, 'Event', true);
02115				else
02116					ClientMessage(ViewingFrom@first, 'Event', true);
02117			}
02118			ViewTarget = first;
02119		}
02120		else
02121		{
02122			if ( !bQuiet )
02123			{
02124				if ( bFound )
02125					ClientMessage(ViewingFrom@OwnCamera, 'Event', true);
02126				else
02127					ClientMessage(FailedView, 'Event', true);
02128			}
02129			ViewTarget = None;
02130		}
02131	
02132		bBehindView = ( ViewTarget != None );
02133		if ( bBehindView )
02134			ViewTarget.BecomeViewTarget();
02135	}
02136	
02137	exec function NeverSwitchOnPickup( bool B )
02138	{
02139		bNeverAutoSwitch = B;
02140		bNeverSwitchOnPickup = B;
02141		ServerNeverSwitchOnPickup(B);
02142		SaveConfig();
02143	}
02144		
02145	function ServerNeverSwitchOnPickup(bool B)
02146	{
02147		bNeverSwitchOnPickup = B;
02148	}
02149	
02150	exec function InvertMouse( bool B )
02151	{
02152		bInvertMouse = B;
02153		SaveConfig();
02154	}
02155	
02156	exec function SwitchLevel( string URL )
02157	{
02158		if( bAdmin || Player.IsA('ViewPort') )
02159			Level.ServerTravel( URL, false );
02160	}
02161	
02162	exec function SwitchCoopLevel( string URL )
02163	{
02164		if( bAdmin || Player.IsA('ViewPort') )
02165			Level.ServerTravel( URL, true );
02166	}
02167	
02168	exec function ShowScores()
02169	{
02170		bShowScores = !bShowScores;
02171	}
02172	 
02173	exec function ShowMenu()
02174	{
02175		WalkBob = vect(0,0,0);
02176		bShowMenu = true; // menu is responsible for turning this off
02177		Player.Console.GotoState('Menuing');
02178			
02179		if( Level.Netmode == NM_Standalone )
02180			SetPause(true);
02181	}
02182	
02183	exec function ShowLoadMenu()
02184	{
02185		ShowMenu();
02186	}
02187	
02188	exec function AddBots(int N)
02189	{
02190		ServerAddBots(N);
02191	}
02192	
02193	function ServerAddBots(int N)
02194	{
02195		local int i;
02196	
02197		if ( !bAdmin && (Level.Netmode != NM_Standalone) )
02198			return;
02199	
02200		if ( !Level.Game.bDeathMatch )
02201			return;
02202	
02203		for ( i=0; i<N; i++ )
02204			Level.Game.ForceAddBot();
02205	}
02206	
02207		
02208	//*************************************************************************************
02209	// Special purpose/cheat execs
02210	
02211	exec function ClearProgressMessages()
02212	{
02213		local int i;
02214	
02215		for (i=0; i<8; i++)
02216		{
02217			ProgressMessage[i] = "";
02218			ProgressColor[i].R = 255;
02219			ProgressColor[i].G = 255;
02220			ProgressColor[i].B = 255;
02221		}
02222	}
02223	
02224	exec function SetProgressMessage( string S, int Index )
02225	{
02226		if (Index < 8)
02227			ProgressMessage[Index] = S;
02228	}
02229	
02230	exec function SetProgressColor( color C, int Index )
02231	{
02232		if (Index < 8)
02233			ProgressColor[Index] = C;
02234	}
02235	
02236	exec function SetProgressTime( float T )
02237	{
02238		ProgressTimeOut = T + Level.TimeSeconds;
02239	}
02240	
02241	exec event ShowUpgradeMenu();
02242	
02243	exec function Amphibious()
02244	{
02245		if( !bCheatsEnabled )
02246			return;
02247	
02248		if ( !bAdmin && (Level.Netmode != NM_Standalone) )
02249			return;
02250		UnderwaterTime = +999999.0;
02251	}
02252		
02253	exec function Fly()
02254	{
02255		if( !bCheatsEnabled )
02256			return;
02257	
02258		if ( !bAdmin && (Level.Netmode != NM_Standalone) )
02259			return;
02260			
02261		UnderWaterTime = Default.UnderWaterTime;	
02262		ClientMessage("You feel much lighter");
02263		SetCollision(true, true , true);
02264		bCollideWorld = true;
02265		GotoState('CheatFlying');
02266	}
02267	
02268	exec function SetWeaponStay( bool B)
02269	{
02270		local Weapon W;
02271	
02272		if ( !bAdmin && (Level.Netmode != NM_Standalone) )
02273			return;
02274	
02275		Level.Game.bCoopWeaponMode = B;
02276		ForEach AllActors(class'Weapon', W)
02277		{
02278			W.bWeaponStay = false;
02279			W.SetWeaponStay();
02280		}
02281	}
02282	
02283	exec function Walk()
02284	{	
02285		if ( !bAdmin && (Level.Netmode != NM_Standalone) )
02286			return;
02287	
02288		StartWalk();
02289	}
02290	
02291	function StartWalk()
02292	{
02293		UnderWaterTime = Default.UnderWaterTime;	
02294		SetCollision(true, true , true);
02295		SetPhysics(PHYS_Walking);
02296		bCollideWorld = true;
02297		ClientReStart();	
02298	}
02299	
02300	exec function Ghost()
02301	{
02302		if( !bCheatsEnabled )
02303			return;
02304	
02305		if ( !bAdmin && (Level.Netmode != NM_Standalone) )
02306			return;
02307		
02308		UnderWaterTime = -1.0;	
02309		ClientMessage("You feel ethereal");
02310		SetCollision(false, false, false);
02311		bCollideWorld = false;
02312		GotoState('CheatFlying');
02313	}
02314	
02315	exec function ShowInventory()
02316	{
02317		local Inventory Inv;
02318		
02319		if( Weapon!=None )
02320			log( "   Weapon: " $ Weapon.Class );
02321		for( Inv=Inventory; Inv!=None; Inv=Inv.Inventory ) 
02322			log( "Inv: "$Inv $ " state "$Inv.GetStateName());
02323		if ( SelectedItem != None )
02324			log( "Selected Item"@SelectedItem@"Charge"@SelectedItem.Charge );
02325	}
02326	
02327	exec function AllAmmo()
02328	{
02329		local Inventory Inv;
02330	
02331		if( !bCheatsEnabled )
02332			return;
02333	
02334		if ( !bAdmin && (Level.Netmode != NM_Standalone) )
02335			return;
02336	
02337		for( Inv=Inventory; Inv!=None; Inv=Inv.Inventory ) 
02338			if (Ammo(Inv)!=None) 
02339			{
02340				Ammo(Inv).AmmoAmount  = 999;
02341				Ammo(Inv).MaxAmmo  = 999;				
02342			}
02343	}	
02344	
02345	exec function Invisible(bool B)
02346	{
02347		if( !bCheatsEnabled )
02348			return;
02349	
02350		if ( !bAdmin && (Level.Netmode != NM_Standalone) )
02351			return;
02352	
02353		if (B)
02354		{
02355			bHidden = true;
02356			Visibility = 0;
02357		}
02358		else
02359		{
02360			bHidden = false;
02361			Visibility = Default.Visibility;
02362		}	
02363	}
02364		
02365	exec function God()
02366	{
02367		if( !bCheatsEnabled )
02368			return;
02369	
02370		if ( !bAdmin && (Level.Netmode != NM_Standalone) )
02371			return;
02372	
02373		if ( ReducedDamageType == 'All' )
02374		{
02375			ReducedDamageType = '';
02376			ClientMessage("God mode off");
02377			return;
02378		}
02379	
02380		ReducedDamageType = 'All'; 
02381		ClientMessage("God Mode on");
02382	}
02383	
02384	exec function BehindView( Bool B )
02385	{
02386		bBehindView = B;
02387	}
02388	
02389	exec function SetBob(float F)
02390	{
02391		UpdateBob(F);
02392		SaveConfig();
02393	}
02394	
02395	function UpdateBob(float F)
02396	{
02397		Bob = FClamp(F,0,0.032);
02398	}
02399	
02400	exec function SetSensitivity(float F)
02401	{
02402		UpdateSensitivity(F);
02403		SaveConfig();
02404	}
02405	
02406	function UpdateSensitivity(float F)
02407	{
02408		MouseSensitivity = FMax(0,F);
02409	}
02410	
02411	exec function SloMo( float T )
02412	{
02413			ServerSetSloMo(T);
02414	}
02415	
02416	function ServerSetSloMo(float T)
02417	{
02418		if ( bAdmin || (Level.Netmode == NM_Standalone) )
02419		{
02420			Level.Game.SetGameSpeed(T);
02421			Level.Game.SaveConfig(); 
02422			Level.Game.GameReplicationInfo.SaveConfig();
02423		}
02424	}
02425	
02426	exec function SetJumpZ( float F )
02427	{
02428		if( !bCheatsEnabled )
02429			return;
02430		if ( !bAdmin && (Level.Netmode != NM_Standalone) )
02431			return;
02432		JumpZ = F;
02433	}
02434	
02435	exec function SetFriction( float F )
02436	{
02437		local ZoneInfo Z;
02438		if ( !bAdmin && (Level.Netmode != NM_Standalone) )
02439			return;
02440		ForEach AllActors(class'ZoneInfo', Z)
02441			Z.ZoneGroundFriction = F;
02442	}
02443	
02444	exec function SetSpeed( float F )
02445	{
02446		if( !bCheatsEnabled )
02447			return;
02448		if ( !bAdmin && (Level.Netmode != NM_Standalone) )
02449			return;
02450		GroundSpeed = Default.GroundSpeed * f;
02451		WaterSpeed = Default.WaterSpeed * f;
02452	}
02453	
02454	exec function KillAll(class<actor> aClass)
02455	{
02456		local Actor A;
02457	
02458		if( !bAdmin && (Level.Netmode != NM_Standalone) )
02459			return;
02460		ForEach AllActors(class 'Actor', A)
02461			if ( ClassIsChildOf(A.class, aClass) )
02462				A.Destroy();
02463	}
02464	
02465	exec function KillPawns()
02466	{
02467		local Pawn P;
02468		
02469		if( !bCheatsEnabled || (Level.Netmode != NM_Standalone) )
02470			return;
02471		ForEach AllActors(class 'Pawn', P)
02472			if (PlayerPawn(P) == None)
02473				P.Destroy();
02474	}
02475	
02476	exec function Summon( string ClassName )
02477	{
02478		local class<actor> NewClass;
02479		if( !bCheatsEnabled )
02480			return;
02481		if( !bAdmin && (Level.Netmode != NM_Standalone) )
02482			return;
02483		log( "Fabricate " $ ClassName );
02484		NewClass = class<actor>( DynamicLoadObject( ClassName, class'Class' ) );
02485		if( NewClass!=None )
02486			Spawn( NewClass,,,Location + 72 * Vector(Rotation) + vect(0,0,1) * 15 );
02487	}
02488	
02489	
02490	//==============
02491	// Navigation Aids
02492	exec function ShowPath()
02493	{
02494		//find next path to remembered spot
02495		local Actor node;
02496		node = FindPathTo(Destination);
02497		if (node != None)
02498		{
02499			log("found path");
02500			Spawn(class 'WayBeacon', self, '', node.location);
02501		}
02502		else
02503			log("didn't find path");
02504	}
02505	
02506	exec function RememberSpot()
02507	{
02508		//remember spot
02509		Destination = Location;
02510	}
02511		
02512	//=============================================================================
02513	// Input related functions.
02514	
02515	// Postprocess the player's input.
02516	
02517	event PlayerInput( float DeltaTime )
02518	{
02519		local float SmoothTime, FOVScale, MouseScale, AbsSmoothX, AbsSmoothY, MouseTime;
02520	
02521		if ( bShowMenu && (myHud != None) ) 
02522		{
02523			if ( myHud.MainMenu != None )
02524				myHud.MainMenu.MenuTick( DeltaTime );
02525			// clear inputs
02526			bEdgeForward = false;
02527			bEdgeBack = false;
02528			bEdgeLeft = false;
02529			bEdgeRight = false;
02530			bWasForward = false;
02531			bWasBack = false;
02532			bWasLeft = false;
02533			bWasRight = false;
02534			aStrafe = 0;
02535			aTurn = 0;
02536			aForward = 0;
02537			aLookUp = 0;
02538			return;
02539		}
02540		else if ( bDelayedCommand )
02541		{
02542			bDelayedCommand = false;
02543			ConsoleCommand(DelayedCommand);
02544		}
02545					
02546		// Check for Dodge move
02547		// flag transitions
02548		bEdgeForward = (bWasForward ^^ (aBaseY > 0));
02549		bEdgeBack = (bWasBack ^^ (aBaseY < 0));
02550		bEdgeLeft = (bWasLeft ^^ (aStrafe > 0));
02551		bEdgeRight = (bWasRight ^^ (aStrafe < 0));
02552		bWasForward = (aBaseY > 0);
02553		bWasBack = (aBaseY < 0);
02554		bWasLeft = (aStrafe > 0);
02555		bWasRight = (aStrafe < 0);
02556		
02557		// Smooth and amplify mouse movement
02558		SmoothTime = FMin(0.2, 3 * DeltaTime * Level.TimeDilation);
02559		FOVScale = DesiredFOV * 0.01111; 
02560		MouseScale = MouseSensitivity * FOVScale;
02561	
02562		aMouseX *= MouseScale;
02563		aMouseY *= MouseScale;
02564	
02565	//************************************************************************
02566	
02567		//log("X "$aMouseX$" Smooth "$SmoothMouseX$" Borrowed "$BorrowedMouseX$" zero time "$(Level.TimeSeconds - MouseZeroTime)$" vs "$MouseSmoothThreshold);
02568		AbsSmoothX = SmoothMouseX;
02569		AbsSmoothY = SmoothMouseY;
02570		MouseTime = (Level.TimeSeconds - MouseZeroTime)/Level.TimeDilation;
02571		if ( bMaxMouseSmoothing && (aMouseX == 0) && (MouseTime < MouseSmoothThreshold) )
02572		{
02573			SmoothMouseX = 0.5 * (MouseSmoothThreshold - MouseTime) * AbsSmoothX/MouseSmoothThreshold;
02574			BorrowedMouseX += SmoothMouseX;
02575		}
02576		else
02577		{
02578			if ( (SmoothMouseX == 0) || (aMouseX == 0) 
02579					|| ((SmoothMouseX > 0) != (aMouseX > 0)) )
02580			{
02581				SmoothMouseX = aMouseX;
02582				BorrowedMouseX = 0;
02583			}
02584			else
02585			{
02586				SmoothMouseX = 0.5 * (SmoothMouseX + aMouseX - BorrowedMouseX);
02587				if ( (SmoothMouseX > 0) != (aMouseX > 0) )
02588				{
02589					if ( AMouseX > 0 )
02590						SmoothMouseX = 1;
02591					else
02592						SmoothMouseX = -1;
02593				} 
02594				BorrowedMouseX = SmoothMouseX - aMouseX;
02595			}
02596			AbsSmoothX = SmoothMouseX;
02597		}
02598		if ( bMaxMouseSmoothing && (aMouseY == 0) && (MouseTime < MouseSmoothThreshold) )
02599		{
02600			SmoothMouseY = 0.5 * (MouseSmoothThreshold - MouseTime) * AbsSmoothY/MouseSmoothThreshold;
02601			BorrowedMouseY += SmoothMouseY;
02602		}
02603		else
02604		{
02605			if ( (SmoothMouseY == 0) || (aMouseY == 0) 
02606					|| ((SmoothMouseY > 0) != (aMouseY > 0)) )
02607			{
02608				SmoothMouseY = aMouseY;
02609				BorrowedMouseY = 0;
02610			}
02611			else
02612			{
02613				SmoothMouseY = 0.5 * (SmoothMouseY + aMouseY - BorrowedMouseY);
02614				if ( (SmoothMouseY > 0) != (aMouseY > 0) )
02615				{
02616					if ( AMouseY > 0 )
02617						SmoothMouseY = 1;
02618					else
02619						SmoothMouseY = -1;
02620				} 
02621				BorrowedMouseY = SmoothMouseY - aMouseY;
02622			}
02623			AbsSmoothY = SmoothMouseY;
02624		}
02625		if ( (aMouseX != 0) || (aMouseY != 0) )
02626			MouseZeroTime = Level.TimeSeconds;
02627	
02628		// adjust keyboard and joystick movements
02629		aLookUp *= FOVScale;
02630		aTurn   *= FOVScale;
02631	
02632		// Remap raw x-axis movement.
02633		if( bStrafe!=0 )
02634		{
02635			// Strafe.
02636			aStrafe += aBaseX + SmoothMouseX;
02637			aBaseX   = 0;
02638		}
02639		else
02640		{
02641			// Forward.
02642			aTurn  += aBaseX * FOVScale + SmoothMouseX;
02643			aBaseX  = 0;
02644		}
02645	
02646		// Remap mouse y-axis movement.
02647		if( (bStrafe == 0) && (bAlwaysMouseLook || (bLook!=0)) )
02648		{
02649			// Look up/down.
02650			if ( bInvertMouse )
02651				aLookUp -= SmoothMouseY;
02652			else
02653				aLookUp += SmoothMouseY;
02654		}
02655		else
02656		{
02657			// Move forward/backward.
02658			aForward += SmoothMouseY;
02659		}
02660		SmoothMouseX = AbsSmoothX;
02661		SmoothMouseY = AbsSmoothY;
02662	
02663		if ( bSnapLevel != 0 )
02664		{
02665			bCenterView = true;
02666			bKeyboardLook = false;
02667		}
02668		else if (aLookUp != 0)
02669		{
02670			bCenterView = false;
02671			bKeyboardLook = true;
02672		}
02673		else if ( bSnapToLevel && !bAlwaysMouseLook )
02674		{
02675			bCenterView = true;
02676			bKeyboardLook = false;
02677		}
02678	
02679		// Remap other y-axis movement.
02680		if ( bFreeLook != 0 )
02681		{
02682			bKeyboardLook = true;
02683			aLookUp += 0.5 * aBaseY * FOVScale;
02684		}
02685		else
02686			aForward += aBaseY;
02687	
02688		aBaseY = 0;
02689	
02690		// Handle walking.
02691		HandleWalking();
02692	}
02693	
02694	//=============================================================================
02695	// functions.
02696	
02697	event UpdateEyeHeight(float DeltaTime)
02698	{
02699		local float smooth, bound;
02700		
02701		// smooth up/down stairs
02702		If( (Physics==PHYS_Walking) && !bJustLanded )
02703		{
02704			smooth = FMin(1.0, 10.0 * DeltaTime/Level.TimeDilation);
02705			EyeHeight = (EyeHeight - Location.Z + OldLocation.Z) * (1 - smooth) + ( ShakeVert + BaseEyeHeight) * smooth;
02706			bound = -0.5 * CollisionHeight;
02707			if (EyeHeight < bound)
02708				EyeHeight = bound;
02709			else
02710			{
02711				bound = CollisionHeight + FClamp((OldLocation.Z - Location.Z), 0.0, MaxStepHeight); 
02712				if ( EyeHeight > bound )
02713					EyeHeight = bound;
02714			}
02715		}
02716		else
02717		{
02718			smooth = FClamp(10.0 * DeltaTime/Level.TimeDilation, 0.35,1.0);
02719			bJustLanded = false;
02720			EyeHeight = EyeHeight * ( 1 - smooth) + (BaseEyeHeight + ShakeVert) * smooth;
02721		}
02722	
02723		// teleporters affect your FOV, so adjust it back down
02724		if ( FOVAngle != DesiredFOV )
02725		{
02726			if ( FOVAngle > DesiredFOV )
02727				FOVAngle = FOVAngle - FMax(7, 0.9 * DeltaTime * (FOVAngle - DesiredFOV)); 
02728			else 
02729				FOVAngle = FOVAngle - FMin(-7, 0.9 * DeltaTime * (FOVAngle - DesiredFOV)); 
02730			if ( Abs(FOVAngle - DesiredFOV) <= 10 )
02731				FOVAngle = DesiredFOV;
02732		}
02733	
02734		// adjust FOV for weapon zooming
02735		if ( bZooming )
02736		{	
02737			ZoomLevel += DeltaTime * 1.0;
02738			if (ZoomLevel > 0.9)
02739				ZoomLevel = 0.9;
02740			DesiredFOV = FClamp(90.0 - (ZoomLevel * 88.0), 1, 170);
02741		} 
02742	}
02743	
02744	event PlayerTimeOut()
02745	{
02746		if (Health > 0)
02747			Died(None, 'Suicided', Location);
02748	}
02749	
02750	// Just changed to pendingWeapon
02751	function ChangedWeapon()
02752	{
02753		Super.ChangedWeapon();
02754		if ( PendingWeapon != None )
02755			PendingWeapon.SetHand(Handedness);
02756	}
02757	
02758	function JumpOffPawn()
02759	{
02760		Velocity += 60 * VRand();
02761		Velocity.Z = 120;
02762		SetPhysics(PHYS_Falling);
02763	}
02764	
02765	event TravelPostAccept()
02766	{
02767		if ( Health <= 0 )
02768			Health = Default.Health;
02769	}
02770	
02771	// This pawn was possessed by a player.
02772	event Possess()
02773	{
02774		if ( Level.Netmode == NM_Client )
02775		{
02776			// replicate client weapon preferences to server
02777			ServerNeverSwitchOnPickup(bNeverAutoSwitch);
02778			ServerSetHandedness(Handedness);
02779			UpdateWeaponPriorities();
02780		}
02781		ServerUpdateWeapons();
02782		bIsPlayer = true;
02783		DodgeClickTime = FMin(0.3, DodgeClickTime);
02784		EyeHeight = BaseEyeHeight;
02785		NetPriority = 3;
02786		StartWalk();
02787	}
02788	
02789	function UpdateWeaponPriorities()
02790	{
02791		local byte i;
02792	
02793		// send new priorities to server
02794		if ( Level.Netmode == NM_Client )
02795			for ( i=0; i<ArrayCount(WeaponPriority); i++ )
02796				ServerSetWeaponPriority(i, WeaponPriority[i]);
02797	}
02798	
02799	function ServerSetWeaponPriority(byte i, name WeaponName )
02800	{
02801		local inventory inv;
02802	
02803		WeaponPriority[i] = WeaponName;
02804	
02805		for ( inv=Inventory; inv!=None; inv=inv.inventory )
02806			if ( inv.class.name == WeaponName )
02807				Weapon(inv).SetSwitchPriority(self);
02808	}
02809	
02810	// This pawn was unpossessed by a player.
02811	event UnPossess()
02812	{
02813		log(Self$" being unpossessed");
02814		if ( myHUD != None )
02815			myHUD.Destroy();
02816		bIsPlayer = false;
02817		EyeHeight = 0.8 * CollisionHeight;
02818	}
02819	
02820	function Carcass SpawnCarcass()
02821	{
02822		local carcass carc;
02823	
02824		carc = Spawn(CarcassType);
02825		if ( carc == None )
02826			return None;
02827		carc.Initfor(self);
02828		if (Player != None)
02829			carc.bPlayerCarcass = true;
02830		if ( !Level.Game.bGameEnded && (Carcass(ViewTarget) == None) )
02831			ViewTarget = carc; //for Player 3rd person views
02832		return carc;
02833	}
02834	
02835	function bool Gibbed(name damageType)
02836	{
02837		if ( (damageType == 'decapitated') || (damageType == 'shot') )
02838			return false; 	
02839		if ( (Health < -80) || ((Health < -40) && (FRand() < 0.6)) )
02840			return true;
02841		return false;
02842	}
02843	
02844	function SpawnGibbedCarcass()
02845	{
02846		local carcass carc;
02847	
02848		carc = Spawn(CarcassType);
02849		if ( carc != None )
02850		{
02851			carc.Initfor(self);
02852			carc.ChunkUp(-1 * Health);
02853		}
02854	}
02855	
02856	event PlayerTick( float Time );
02857	
02858	//
02859	// Called immediately before gameplay begins.
02860	//
02861	event PreBeginPlay()
02862	{
02863		bIsPlayer = true;
02864		Super.PreBeginPlay();
02865	}
02866	
02867	event PostBeginPlay()
02868	{
02869		Super.PostBeginPlay();
02870		if (Level.LevelEnterText != "" )
02871			ClientMessage(Level.LevelEnterText);
02872		if ( Level.NetMode != NM_Client )
02873		{
02874			HUDType = Level.Game.HUDType;
02875			ScoringType = Level.Game.ScoreboardType;
02876			MyAutoAim = FMax(MyAutoAim, Level.Game.AutoAim);
02877		}
02878		bIsPlayer = true;
02879		DodgeClickTime = FMin(0.3, DodgeClickTime);
02880		DesiredFOV = DefaultFOV;
02881		EyeHeight = BaseEyeHeight;
02882		if ( Level.Game.IsA('SinglePlayer') && (Level.NetMode == NM_Standalone) )
02883			FlashScale = vect(0,0,0);
02884	}
02885	
02886	function ServerUpdateWeapons()
02887	{
02888		local inventory Inv;
02889	
02890		For ( Inv=Inventory; Inv!=None; Inv=Inv.Inventory )
02891			if ( Inv.IsA('Weapon') )
02892				Weapon(Inv).SetSwitchPriority(self); 
02893	}
02894	
02895	//=============================================================================
02896	// Animation playing - should be implemented in subclass, 
02897	//
02898	
02899	function PlayDodge(eDodgeDir DodgeMove)
02900	{
02901		PlayDuck();
02902	}
02903	
02904	function PlayTurning();
02905	
02906	function PlaySwimming()
02907	{
02908		PlayRunning();
02909	}
02910	
02911	function PlayFeignDeath();
02912	function PlayRising();
02913	
02914	/* Adjust hit location - adjusts the hit location in for pawns, and returns
02915	true if it was really a hit, and false if not (for ducking, etc.)
02916	*/
02917	simulated function bool AdjustHitLocation(out vector HitLocation, vector TraceDir)
02918	{
02919		local float adjZ, maxZ;
02920	
02921		TraceDir = Normal(TraceDir);
02922		HitLocation = HitLocation + 0.5 * CollisionRadius * TraceDir;
02923		if ( BaseEyeHeight == Default.BaseEyeHeight )
02924			return true;
02925	
02926		maxZ = Location.Z + EyeHeight + 0.25 * CollisionHeight;
02927		if ( HitLocation.Z > maxZ )
02928		{
02929			if ( TraceDir.Z >= 0 )
02930				return false;
02931			adjZ = (maxZ - HitLocation.Z)/TraceDir.Z;
02932			HitLocation.Z = maxZ;
02933			HitLocation.X = HitLocation.X + TraceDir.X * adjZ;
02934			HitLocation.Y = HitLocation.Y + TraceDir.Y * adjZ;
02935			if ( VSize(HitLocation - Location) > CollisionRadius )	
02936				return false;
02937		}
02938		return true;
02939	}
02940	
02941	/* AdjustAim()
02942	Calls this version for player aiming help.
02943	Aimerror not used in this version.
02944	Only adjusts aiming at pawns
02945	*/
02946	
02947	function rotator AdjustAim(float projSpeed, vector projStart, int aimerror, bool bLeadTarget, bool bWarnTarget)
02948	{
02949		local vector FireDir, AimSpot, HitNormal, HitLocation;
02950		local actor BestTarget;
02951		local float bestAim, bestDist;
02952		local actor HitActor;
02953		
02954		FireDir = vector(ViewRotation);
02955		HitActor = Trace(HitLocation, HitNormal, projStart + 4000 * FireDir, projStart, true);
02956		if ( (HitActor != None) && HitActor.bProjTarget )
02957		{
02958			if ( bWarnTarget && HitActor.IsA('Pawn') )
02959				Pawn(HitActor).WarnTarget(self, projSpeed, FireDir);
02960			return ViewRotation;
02961		}
02962	
02963		bestAim = FMin(0.93, MyAutoAim);
02964		BestTarget = PickTarget(bestAim, bestDist, FireDir, projStart);
02965	
02966		if ( bWarnTarget && (Pawn(BestTarget) != None) )
02967			Pawn(BestTarget).WarnTarget(self, projSpeed, FireDir);	
02968	
02969		if ( (Level.NetMode != NM_Standalone) || (Level.Game.Difficulty > 2) 
02970			|| bAlwaysMouseLook || ((BestTarget != None) && (bestAim < MyAutoAim)) || (MyAutoAim >= 1) )
02971			return ViewRotation;
02972		
02973		if ( BestTarget == None )
02974		{
02975			bestAim = MyAutoAim;
02976			BestTarget = PickAnyTarget(bestAim, bestDist, FireDir, projStart);
02977			if ( BestTarget == None )
02978				return ViewRotation;
02979		}
02980	
02981		AimSpot = projStart + FireDir * bestDist;
02982		AimSpot.Z = BestTarget.Location.Z + 0.3 * BestTarget.CollisionHeight;
02983	
02984		return rotator(AimSpot - projStart);
02985	}
02986	
02987	function Falling()
02988		{
02989			//SetPhysics(PHYS_Falling); //Note - physics changes type to PHYS_Falling by default
02990			//log(class$" Falling");
02991			PlayInAir();
02992		}
02993	
02994	function Landed(vector HitNormal)
02995	{
02996		//Note - physics changes type to PHYS_Walking by default for landed pawns
02997		if ( bUpdating )
02998			return;
02999		PlayLanded(Velocity.Z);
03000		LandBob = FMin(50, 0.055 * Velocity.Z); 
03001		TakeFallingDamage();
03002		bJustLanded = true;
03003	}
03004	
03005	function Died(pawn Killer, name damageType, vector HitLocation)
03006	{
03007		StopZoom();
03008	
03009		Super.Died(Killer, damageType, HitLocation);	
03010	}
03011	
03012	function eAttitude AttitudeTo(Pawn Other)
03013	{
03014		if (Other.bIsPlayer)
03015			return AttitudeToPlayer;
03016		else 
03017			return Other.AttitudeToPlayer;
03018	}
03019	
03020	
03021	function string KillMessage( name damageType, pawn Other )
03022	{
03023		return ( Level.Game.PlayerKillMessage(damageType, Other.PlayerReplicationInfo)$PlayerReplicationInfo.PlayerName );
03024	}
03025		
03026	//=============================================================================
03027	// Player Control
03028	
03029	function KilledBy( pawn EventInstigator )
03030	{
03031		Health = 0;
03032		Died( EventInstigator, 'Suicided', Location );
03033	}
03034	
03035	// Player view.
03036	// Compute the rendering viewpoint for the player.
03037	//
03038	
03039	function CalcBehindView(out vector CameraLocation, out rotator CameraRotation, float Dist)
03040	{
03041		local vector View,HitLocation,HitNormal;
03042		local float ViewDist;
03043	
03044		CameraRotation = ViewRotation;
03045		View = vect(1,0,0) >> CameraRotation;
03046		if( Trace( HitLocation, HitNormal, CameraLocation - (Dist + 30) * vector(CameraRotation), CameraLocation ) != None )
03047			ViewDist = FMin( (CameraLocation - HitLocation) Dot View, Dist );
03048		else
03049			ViewDist = Dist;
03050		CameraLocation -= (ViewDist - 30) * View; 
03051	}
03052	
03053	event PlayerCalcView(out actor ViewActor, out vector CameraLocation, out rotator CameraRotation )
03054	{
03055		local Pawn PTarget;
03056	
03057		if ( ViewTarget != None )
03058		{
03059			ViewActor = ViewTarget;
03060			CameraLocation = ViewTarget.Location;
03061			CameraRotation = ViewTarget.Rotation;
03062			PTarget = Pawn(ViewTarget);
03063			if ( PTarget != None )
03064			{
03065				if ( Level.NetMode == NM_Client )
03066				{
03067					if ( PTarget.bIsPlayer )
03068						PTarget.ViewRotation = TargetViewRotation;
03069					PTarget.EyeHeight = TargetEyeHeight;
03070					if ( PTarget.Weapon != None )
03071						PTarget.Weapon.PlayerViewOffset = TargetWeaponViewOffset;
03072				}
03073				if ( PTarget.bIsPlayer )
03074					CameraRotation = PTarget.ViewRotation;
03075				if ( !bBehindView )
03076					CameraLocation.Z += PTarget.EyeHeight;
03077			}
03078			if ( bBehindView )
03079				CalcBehindView(CameraLocation, CameraRotation, 180);
03080			return;
03081		}
03082	
03083		ViewActor = Self;
03084		CameraLocation = Location;
03085	
03086		if( bBehindView ) //up and behind
03087			CalcBehindView(CameraLocation, CameraRotation, 150);
03088		else
03089		{
03090			// First-person view.
03091			CameraRotation = ViewRotation;
03092			CameraLocation.Z += EyeHeight;
03093			CameraLocation += WalkBob;
03094		}
03095	}
03096	
03097	exec function SetViewFlash(bool B)
03098	{
03099		bNoFlash = !B;
03100	}
03101	
03102	function ViewFlash(float DeltaTime)
03103	{
03104		local vector goalFog;
03105		local float goalscale, delta;
03106	
03107		if ( bNoFlash )
03108		{
03109			InstantFlash = 0;
03110			InstantFog = vect(0,0,0);
03111		}
03112	
03113		delta = FMin(0.1, DeltaTime);
03114		goalScale = 1 + DesiredFlashScale + ConstantGlowScale + HeadRegion.Zone.ViewFlash.X; 
03115		goalFog = DesiredFlashFog + ConstantGlowFog + HeadRegion.Zone.ViewFog;
03116		DesiredFlashScale -= DesiredFlashScale * 2 * delta;  
03117		DesiredFlashFog -= DesiredFlashFog * 2 * delta;
03118		FlashScale.X += (goalScale - FlashScale.X + InstantFlash) * 10 * delta;
03119		FlashFog += (goalFog - FlashFog + InstantFog) * 10 * delta;
03120		InstantFlash = 0;
03121		InstantFog = vect(0,0,0);
03122	
03123		if ( FlashScale.X > 0.981 )
03124			FlashScale.X = 1;
03125		FlashScale = FlashScale.X * vect(1,1,1);
03126	
03127		if ( FlashFog.X < 0.019 )
03128			FlashFog.X = 0;
03129		if ( FlashFog.Y < 0.019 )
03130			FlashFog.Y = 0;
03131		if ( FlashFog.Z < 0.019 )
03132			FlashFog.Z = 0;
03133	}
03134	
03135	function ViewShake(float DeltaTime)
03136	{
03137		if (shaketimer > 0.0) //shake view
03138		{
03139			shaketimer -= DeltaTime;
03140			if ( verttimer == 0 )
03141			{
03142				verttimer = 0.1;
03143				ShakeVert = -1.1 * maxshake;
03144			}
03145			else
03146			{
03147				verttimer -= DeltaTime;
03148				if ( verttimer < 0 )
03149				{
03150					verttimer = 0.2 * FRand();
03151					shakeVert = (2 * FRand() - 1) * maxshake;  
03152				}
03153			}
03154			ViewRotation.Roll = ViewRotation.Roll & 65535;
03155			if (bShakeDir)
03156			{
03157				ViewRotation.Roll += Int( 10 * shakemag * FMin(0.1, DeltaTime));
03158				bShakeDir = (ViewRotation.Roll > 32768) || (ViewRotation.Roll < (0.5 + FRand()) * shakemag);
03159				if ( (ViewRotation.Roll < 32768) && (ViewRotation.Roll > 1.3 * shakemag) )
03160				{
03161					ViewRotation.Roll = 1.3 * shakemag;
03162					bShakeDir = false;
03163				}
03164				else if (FRand() < 3 * DeltaTime)
03165					bShakeDir = !bShakeDir;
03166			}
03167			else
03168			{
03169				ViewRotation.Roll -= Int( 10 * shakemag * FMin(0.1, DeltaTime));
03170				bShakeDir = (ViewRotation.Roll > 32768) && (ViewRotation.Roll < 65535 - (0.5 + FRand()) * shakemag);
03171				if ( (ViewRotation.Roll > 32768) && (ViewRotation.Roll < 65535 - 1.3 * shakemag) )
03172				{
03173					ViewRotation.Roll = 65535 - 1.3 * shakemag;
03174					bShakeDir = true;
03175				}
03176				else if (FRand() < 3 * DeltaTime)
03177					bShakeDir = !bShakeDir;
03178			}
03179		}
03180		else
03181		{
03182			ShakeVert = 0;
03183			ViewRotation.Roll = ViewRotation.Roll & 65535;
03184			if (ViewRotation.Roll < 32768)
03185			{
03186				if ( ViewRotation.Roll > 0 )
03187					ViewRotation.Roll = Max(0, ViewRotation.Roll - (Max(ViewRotation.Roll,500) * 10 * FMin(0.1,DeltaTime)));
03188			}
03189			else
03190			{
03191				ViewRotation.Roll += ((65536 - Max(500,ViewRotation.Roll)) * 10 * FMin(0.1,DeltaTime));
03192				if ( ViewRotation.Roll > 65534 )
03193					ViewRotation.Roll = 0;
03194			}
03195		} 
03196	}
03197	
03198	function UpdateRotation(float DeltaTime, float maxPitch)
03199	{
03200		local rotator newRotation;
03201		
03202		DesiredRotation = ViewRotation; //save old rotation
03203		ViewRotation.Pitch += 32.0 * DeltaTime * aLookUp;
03204		ViewRotation.Pitch = ViewRotation.Pitch & 65535;
03205		If ((ViewRotation.Pitch > 18000) && (ViewRotation.Pitch < 49152))
03206		{
03207			If (aLookUp > 0) 
03208				ViewRotation.Pitch = 18000;
03209			else
03210				ViewRotation.Pitch = 49152;
03211		}
03212		ViewRotation.Yaw += 32.0 * DeltaTime * aTurn;
03213		ViewShake(deltaTime);
03214		ViewFlash(deltaTime);
03215			
03216		newRotation = Rotation;
03217		newRotation.Yaw = ViewRotation.Yaw;
03218		newRotation.Pitch = ViewRotation.Pitch;
03219		If ( (newRotation.Pitch > maxPitch * RotationRate.Pitch) && (newRotation.Pitch < 65536 - maxPitch * RotationRate.Pitch) )
03220		{
03221			If (ViewRotation.Pitch < 32768) 
03222				newRotation.Pitch = maxPitch * RotationRate.Pitch;
03223			else
03224				newRotation.Pitch = 65536 - maxPitch * RotationRate.Pitch;
03225		}
03226		setRotation(newRotation);
03227	}
03228	
03229	function SwimAnimUpdate(bool bNotForward)
03230	{
03231		if ( !bAnimTransition && (GetAnimGroup(AnimSequence) != 'Gesture') )
03232		{
03233			if ( bNotForward )
03234		 	{
03235			 	 if ( GetAnimGroup(AnimSequence) != 'Waiting' )
03236					TweenToWaiting(0.1);
03237			}
03238			else if ( GetAnimGroup(AnimSequence) == 'Waiting' )
03239				TweenToSwimming(0.1);
03240		}
03241	}
03242	
03243	auto state InvalidState
03244	{
03245		event PlayerTick( float DeltaTime )
03246		{
03247			log(self$" invalid state");
03248			if ( bUpdatePosition )
03249				ClientUpdatePosition();
03250	
03251			PlayerMove(DeltaTime);
03252		}
03253	
03254		function PlayerMove( float DeltaTime )
03255		{
03256			if ( Role < ROLE_Authority ) // then save this move and replicate it
03257				ReplicateMove(DeltaTime, vect(0,0,0), Dodge_None, rot(0,0,0));
03258		}
03259	}
03260	
03261	// Player movement.
03262	// Player Standing, walking, running, falling.
03263	state PlayerWalking
03264	{
03265	ignores SeePlayer, HearNoise, Bump;
03266	
03267		exec function FeignDeath()
03268		{
03269			if ( Physics == PHYS_Walking )
03270			{
03271				ServerFeignDeath();
03272				Acceleration = vect(0,0,0);
03273				GotoState('FeigningDeath');
03274			}
03275		}
03276	
03277		function ServerFeignDeath()
03278		{
03279			local Weapon W;
03280	
03281			W = Weapon;
03282			PendingWeapon = None;
03283			if ( Weapon != None )
03284				Weapon.PutDown();
03285			PendingWeapon = W;
03286			GotoState('FeigningDeath');
03287		}
03288	
03289		function ZoneChange( ZoneInfo NewZone )
03290		{
03291			if (NewZone.bWaterZone)
03292			{
03293				setPhysics(PHYS_Swimming);
03294				GotoState('PlayerSwimming');
03295			}
03296		}
03297	
03298		function AnimEnd()
03299		{
03300			local name MyAnimGroup;
03301	
03302			bAnimTransition = false;
03303			if (Physics == PHYS_Walking)
03304			{
03305				if (bIsCrouching)
03306				{
03307					if ( !bIsTurning && ((Velocity.X * Velocity.X + Velocity.Y * Velocity.Y) < 1000) )
03308						PlayDuck();	
03309					else
03310						PlayCrawling();
03311				}
03312				else
03313				{
03314					MyAnimGroup = GetAnimGroup(AnimSequence);
03315					if ((Velocity.X * Velocity.X + Velocity.Y * Velocity.Y) < 1000)
03316					{
03317						if ( MyAnimGroup == 'Waiting' )
03318							PlayWaiting();
03319						else
03320						{
03321							bAnimTransition = true;
03322							TweenToWaiting(0.2);
03323						}
03324					}	
03325					else if (bIsWalking)
03326					{
03327						if ( (MyAnimGroup == 'Waiting') || (MyAnimGroup == 'Landing') || (MyAnimGroup == 'Gesture') || (MyAnimGroup == 'TakeHit')  )
03328						{
03329							TweenToWalking(0.1);
03330							bAnimTransition = true;
03331						}
03332						else 
03333							PlayWalking();
03334					}
03335					else
03336					{
03337						if ( (MyAnimGroup == 'Waiting') || (MyAnimGroup == 'Landing') || (MyAnimGroup == 'Gesture') || (MyAnimGroup == 'TakeHit')  )
03338						{
03339							bAnimTransition = true;
03340							TweenToRunning(0.1);
03341						}
03342						else
03343							PlayRunning();
03344					}
03345				}
03346			}
03347			else
03348				PlayInAir();
03349		}
03350	
03351		function Landed(vector HitNormal)
03352		{
03353			Global.Landed(HitNormal);
03354			if (DodgeDir == DODGE_Active)
03355			{
03356				DodgeDir = DODGE_Done;
03357				DodgeClickTimer = 0.0;
03358				Velocity *= 0.1;
03359			}
03360			else
03361				DodgeDir = DODGE_None;
03362		}
03363	
03364		function Dodge(eDodgeDir DodgeMove)
03365		{
03366			local vector X,Y,Z;
03367	
03368			if ( bIsCrouching || (Physics != PHYS_Walking) )
03369				return;
03370	
03371			GetAxes(Rotation,X,Y,Z);
03372			if (DodgeMove == DODGE_Forward)
03373				Velocity = 1.5*GroundSpeed*X + (Velocity Dot Y)*Y;
03374			else if (DodgeMove == DODGE_Back)
03375				Velocity = -1.5*GroundSpeed*X + (Velocity Dot Y)*Y; 
03376			else if (DodgeMove == DODGE_Left)
03377				Velocity = 1.5*GroundSpeed*Y + (Velocity Dot X)*X; 
03378			else if (DodgeMove == DODGE_Right)
03379				Velocity = -1.5*GroundSpeed*Y + (Velocity Dot X)*X; 
03380	
03381			Velocity.Z = 160;
03382			PlayOwnedSound(JumpSound, SLOT_Talk, 1.0, true, 800, 1.0 );
03383			PlayDodge(DodgeMove);
03384			DodgeDir = DODGE_Active;
03385			SetPhysics(PHYS_Falling);
03386		}
03387		
03388		function ProcessMove(float DeltaTime, vector NewAccel, eDodgeDir DodgeMove, rotator DeltaRot)	
03389		{
03390			local vector OldAccel;
03391			
03392			OldAccel = Acceleration;
03393			Acceleration = NewAccel;
03394			bIsTurning = ( Abs(DeltaRot.Yaw/DeltaTime) > 5000 );
03395			if ( (DodgeMove == DODGE_Active) && (Physics == PHYS_Falling) )
03396				DodgeDir = DODGE_Active;	
03397			else if ( (DodgeMove != DODGE_None) && (DodgeMove < DODGE_Active) )
03398				Dodge(DodgeMove);
03399	
03400			if ( bPressedJump )
03401				DoJump();
03402			if ( (Physics == PHYS_Walking) && (GetAnimGroup(AnimSequence) != 'Dodge') )
03403			{
03404				if (!bIsCrouching)
03405				{
03406					if (bDuck != 0)
03407					{
03408						bIsCrouching = true;
03409						PlayDuck();
03410					}
03411				}
03412				else if (bDuck == 0)
03413				{
03414					OldAccel = vect(0,0,0);
03415					bIsCrouching = false;
03416					TweenToRunning(0.1);
03417				}
03418	
03419				if ( !bIsCrouching )
03420				{
03421					if ( (!bAnimTransition || (AnimFrame > 0)) && (GetAnimGroup(AnimSequence) != 'Landing') )
03422					{
03423						if ( Acceleration != vect(0,0,0) )
03424						{
03425							if ( (GetAnimGroup(AnimSequence) == 'Waiting') || (GetAnimGroup(AnimSequence) == 'Gesture') || (GetAnimGroup(AnimSequence) == 'TakeHit') )
03426							{
03427								bAnimTransition = true;
03428								TweenToRunning(0.1);
03429							}
03430						}
03431				 		else if ( (Velocity.X * Velocity.X + Velocity.Y * Velocity.Y < 1000) 
03432							&& (GetAnimGroup(AnimSequence) != 'Gesture') ) 
03433				 		{
03434				 			if ( GetAnimGroup(AnimSequence) == 'Waiting' )
03435				 			{
03436								if ( bIsTurning && (AnimFrame >= 0) ) 
03437								{
03438									bAnimTransition = true;
03439									PlayTurning();
03440								}
03441							}
03442				 			else if ( !bIsTurning ) 
03443							{
03444								bAnimTransition = true;
03445								TweenToWaiting(0.2);
03446							}
03447						}
03448					}
03449				}
03450				else
03451				{
03452					if ( (OldAccel == vect(0,0,0)) && (Acceleration != vect(0,0,0)) )
03453						PlayCrawling();
03454				 	else if ( !bIsTurning && (Acceleration == vect(0,0,0)) && (AnimFrame > 0.1) )
03455						PlayDuck();
03456				}
03457			}
03458		}
03459				
03460		event PlayerTick( float DeltaTime )
03461		{
03462			if ( bUpdatePosition )
03463				ClientUpdatePosition();
03464	
03465			PlayerMove(DeltaTime);
03466		}
03467	
03468		function PlayerMove( float DeltaTime )
03469		{
03470			local vector X,Y,Z, NewAccel;
03471			local EDodgeDir OldDodge;
03472			local eDodgeDir DodgeMove;
03473			local rotator OldRotation;
03474			local float Speed2D;
03475			local bool	bSaveJump;
03476			local name AnimGroupName;
03477	
03478			GetAxes(Rotation,X,Y,Z);
03479	
03480			aForward *= 0.4;
03481			aStrafe  *= 0.4;
03482			aLookup  *= 0.24;
03483			aTurn    *= 0.24;
03484	
03485			// Update acceleration.
03486			NewAccel = aForward*X + aStrafe*Y; 
03487			NewAccel.Z = 0;
03488			// Check for Dodge move
03489			if ( DodgeDir == DODGE_Active )
03490				DodgeMove = DODGE_Active;
03491			else
03492				DodgeMove = DODGE_None;
03493			if (DodgeClickTime > 0.0)
03494			{
03495				if ( DodgeDir < DODGE_Active )
03496				{
03497					OldDodge = DodgeDir;
03498					DodgeDir = DODGE_None;
03499					if (bEdgeForward && bWasForward)
03500						DodgeDir = DODGE_Forward;
03501					if (bEdgeBack && bWasBack)
03502						DodgeDir = DODGE_Back;
03503					if (bEdgeLeft && bWasLeft)
03504						DodgeDir = DODGE_Left;
03505					if (bEdgeRight && bWasRight)
03506						DodgeDir = DODGE_Right;
03507					if ( DodgeDir == DODGE_None)
03508						DodgeDir = OldDodge;
03509					else if ( DodgeDir != OldDodge )
03510						DodgeClickTimer = DodgeClickTime + 0.5 * DeltaTime;
03511					else 
03512						DodgeMove = DodgeDir;
03513				}
03514		
03515				if (DodgeDir == DODGE_Done)
03516				{
03517					DodgeClickTimer -= DeltaTime;
03518					if (DodgeClickTimer < -0.35) 
03519					{
03520						DodgeDir = DODGE_None;
03521						DodgeClickTimer = DodgeClickTime;
03522					}
03523				}		
03524				else if ((DodgeDir != DODGE_None) && (DodgeDir != DODGE_Active))
03525				{
03526					DodgeClickTimer -= DeltaTime;			
03527					if (DodgeClickTimer < 0)
03528					{
03529						DodgeDir = DODGE_None;
03530						DodgeClickTimer = DodgeClickTime;
03531					}
03532				}
03533			}
03534			
03535			AnimGroupName = GetAnimGroup(AnimSequence);		
03536			if ( (Physics == PHYS_Walking) && (AnimGroupName != 'Dodge') )
03537			{
03538				//if walking, look up/down stairs - unless player is rotating view
03539				if ( !bKeyboardLook && (bLook == 0) )
03540				{
03541					if ( bLookUpStairs )
03542						ViewRotation.Pitch = FindStairRotation(deltaTime);
03543					else if ( bCenterView )
03544					{
03545						ViewRotation.Pitch = ViewRotation.Pitch & 65535;
03546						if (ViewRotation.Pitch > 32768)
03547							ViewRotation.Pitch -= 65536;
03548						ViewRotation.Pitch = ViewRotation.Pitch * (1 - 12 * FMin(0.0833, deltaTime));
03549						if ( Abs(ViewRotation.Pitch) < 1000 )
03550							ViewRotation.Pitch = 0;	
03551					}
03552				}
03553	
03554				Speed2D = Sqrt(Velocity.X * Velocity.X + Velocity.Y * Velocity.Y);
03555				//add bobbing when walking
03556				if ( !bShowMenu )
03557					CheckBob(DeltaTime, Speed2D, Y);
03558			}	
03559			else if ( !bShowMenu )
03560			{ 
03561				BobTime = 0;
03562				WalkBob = WalkBob * (1 - FMin(1, 8 * deltatime));
03563			}
03564	
03565			// Update rotation.
03566			OldRotation = Rotation;
03567			UpdateRotation(DeltaTime, 1);
03568	
03569			if ( bPressedJump && (AnimGroupName == 'Dodge') )
03570			{
03571				bSaveJump = true;
03572				bPressedJump = false;
03573			}
03574			else
03575				bSaveJump = false;
03576	
03577			if ( Role < ROLE_Authority ) // then save this move and replicate it
03578				ReplicateMove(DeltaTime, NewAccel, DodgeMove, OldRotation - Rotation);
03579			else
03580				ProcessMove(DeltaTime, NewAccel, DodgeMove, OldRotation - Rotation);
03581			bPressedJump = bSaveJump;
03582		}
03583	
03584		function BeginState()
03585		{
03586			if ( Mesh == None )
03587				SetMesh();
03588			WalkBob = vect(0,0,0);
03589			DodgeDir = DODGE_None;
03590			bIsCrouching = false;
03591			bIsTurning = false;
03592			bPressedJump = false;
03593			if (Physics != PHYS_Falling) SetPhysics(PHYS_Walking);
03594			if ( !IsAnimating() )
03595				PlayWaiting();
03596		}
03597		
03598		function EndState()
03599		{
03600			WalkBob = vect(0,0,0);
03601			bIsCrouching = false;
03602		}
03603	}
03604	
03605	state FeigningDeath
03606	{
03607	ignores SeePlayer, HearNoise, Bump;
03608	
03609		function ZoneChange( ZoneInfo NewZone )
03610		{
03611			if (NewZone.bWaterZone)
03612			{
03613				setPhysics(PHYS_Swimming);
03614				GotoState('PlayerSwimming');
03615			}
03616		}
03617	
03618		exec function Fire( optional float F )
03619		{
03620			bJustFired = true;
03621		}
03622	
03623		exec function AltFire( optional float F )
03624		{
03625			bJustFired = true;
03626		}
03627	
03628		function PlayChatting()
03629		{
03630		}
03631	
03632		exec function Taunt( name Sequence )
03633		{
03634		}
03635	
03636		function AnimEnd()
03637		{
03638			if ( Role < ROLE_Authority )
03639				return;
03640			if ( Health <= 0 )
03641			{
03642				GotoState('Dying');
03643				return;
03644			}
03645			GotoState('PlayerWalking');
03646			PendingWeapon.SetDefaultDisplayProperties();
03647			ChangedWeapon();
03648		}
03649		
03650		function Landed(vector HitNormal)
03651		{
03652			if ( Role == ROLE_Authority )
03653				PlaySound(Land, SLOT_Interact, 0.3, false, 800, 1.0);
03654			if ( bUpdating )
03655				return;
03656			TakeFallingDamage();
03657			bJustLanded = true;				
03658		}
03659	
03660		function Rise()
03661		{
03662			if ( (Role == ROLE_Authority) && (Health <= 0) )
03663			{
03664				GotoState('Dying');
03665				return;
03666			}
03667			if ( !bRising )
03668			{
03669				Enable('AnimEnd');
03670				BaseEyeHeight = Default.BaseEyeHeight;
03671				bRising = true;
03672				PlayRising();
03673			}
03674		}
03675	
03676		function ProcessMove(float DeltaTime, vector NewAccel, eDodgeDir DodgeMove, rotator DeltaRot)	
03677		{
03678			if ( bJustFired || bPressedJump || (NewAccel.Z > 0) )
03679				Rise();
03680			Acceleration = vect(0,0,0);
03681		}
03682	
03683		event PlayerTick( float DeltaTime )
03684		{
03685			Weapon = None; // in case client confused because of weapon switch just before feign death
03686			if ( bUpdatePosition )
03687				ClientUpdatePosition();
03688			
03689			PlayerMove(DeltaTime);
03690		}
03691	
03692		function ServerMove
03693		(
03694			float TimeStamp, 
03695			vector Accel, 
03696			vector ClientLoc,
03697			bool NewbRun,
03698			bool NewbDuck,
03699			bool NewbJumpStatus, 
03700			bool bFired,
03701			bool bAltFired,
03702			bool bForceFire,
03703			bool bForceAltFire,
03704			eDodgeDir DodgeMove, 
03705			byte ClientRoll, 
03706			int View,
03707			optional byte OldTimeDelta,
03708			optional int OldAccel
03709		)
03710		{
03711			Global.ServerMove(TimeStamp, Accel, ClientLoc, NewbRun, NewbDuck, NewbJumpStatus,
03712								bFired, bAltFired, bForceFire, bForceAltFire, DodgeMove, ClientRoll, (32767 & (Rotation.Pitch/2)) * 32768 + (32767 & (Rotation.Yaw/2)));
03713		}
03714	
03715		function PlayerMove( float DeltaTime)
03716		{
03717			local rotator currentRot;
03718			local vector NewAccel;
03719	
03720			aLookup  *= 0.24;
03721			aTurn    *= 0.24;
03722	
03723			// Update acceleration.
03724			if ( !IsAnimating() && (aForward != 0) || (aStrafe != 0) )
03725				NewAccel = vect(0,0,1);
03726			else
03727				NewAccel = vect(0,0,0);
03728	
03729			// Update view rotation.
03730			currentRot = Rotation;
03731			UpdateRotation(DeltaTime, 1);
03732			SetRotation(currentRot);
03733	
03734			if ( Role < ROLE_Authority ) // then save this move and replicate it
03735				ReplicateMove(DeltaTime, NewAccel, DODGE_None, Rot(0,0,0));
03736			else
03737				ProcessMove(DeltaTime, NewAccel, DODGE_None, Rot(0,0,0));
03738			bPressedJump = false;
03739		}
03740	
03741		function PlayTakeHit(float tweentime, vector HitLoc, int Damage)
03742		{
03743			if ( IsAnimating() )
03744			{
03745				Enable('AnimEnd');
03746				Global.PlayTakeHit(tweentime, HitLoc, Damage);
03747			}
03748		}
03749		
03750		function PlayDying(name DamageType, vector HitLocation)
03751		{
03752			BaseEyeHeight = Default.BaseEyeHeight;
03753			if ( bRising || IsAnimating() )
03754				Global.PlayDying(DamageType, HitLocation);
03755		}
03756		
03757		function ChangedWeapon()
03758		{
03759			Weapon = None;
03760			Inventory.ChangedWeapon();
03761		}
03762	
03763		function EndState()
03764		{
03765			bJustFired = false;
03766			PlayerReplicationInfo.bFeigningDeath = false;
03767		}
03768	
03769		function BeginState()
03770		{
03771			local rotator NewRot;
03772			if ( carriedDecoration != None )
03773				DropDecoration();
03774			NewRot = Rotation;
03775			NewRot.Pitch = 0;
03776			SetRotation(NewRot);
03777			BaseEyeHeight = -0.5 * CollisionHeight;
03778			bIsCrouching = false;
03779			bPressedJump = false;
03780			bJustFired = false;
03781			bRising = false;
03782			Disable('AnimEnd');
03783			PlayFeignDeath();
03784			PlayerReplicationInfo.bFeigningDeath = true;
03785		}
03786	}
03787	
03788	// Player movement.
03789	// Player Swimming
03790	state PlayerSwimming
03791	{
03792	ignores SeePlayer, HearNoise, Bump;
03793	
03794		event UpdateEyeHeight(float DeltaTime)
03795		{
03796			local float smooth, bound;
03797			
03798			// smooth up/down stairs
03799			if( !bJustLanded )
03800			{
03801				smooth = FMin(1.0, 10.0 * DeltaTime/Level.TimeDilation);
03802				EyeHeight = (EyeHeight - Location.Z + OldLocation.Z) * (1 - smooth) + ( ShakeVert + BaseEyeHeight) * smooth;
03803				bound = -0.5 * CollisionHeight;
03804				if (EyeHeight < bound)
03805					EyeHeight = bound;
03806				else
03807				{
03808					bound = CollisionHeight + FClamp((OldLocation.Z - Location.Z), 0.0, MaxStepHeight); 
03809					 if ( EyeHeight > bound )
03810						EyeHeight = bound;
03811				}
03812			}
03813			else
03814			{
03815				smooth = FClamp(10.0 * DeltaTime/Level.TimeDilation, 0.35, 1.0);
03816				bJustLanded = false;
03817				EyeHeight = EyeHeight * ( 1 - smooth) + (BaseEyeHeight + ShakeVert) * smooth;
03818			}
03819	
03820			// teleporters affect your FOV, so adjust it back down
03821			if ( FOVAngle != DesiredFOV )
03822			{
03823				if ( FOVAngle > DesiredFOV )
03824					FOVAngle = FOVAngle - FMax(7, 0.9 * DeltaTime * (FOVAngle - DesiredFOV)); 
03825				else 
03826					FOVAngle = FOVAngle - FMin(-7, 0.9 * DeltaTime * (FOVAngle - DesiredFOV)); 
03827				if ( Abs(FOVAngle - DesiredFOV) <= 10 )
03828					FOVAngle = DesiredFOV;
03829			}
03830	
03831			// adjust FOV for weapon zooming
03832			if ( bZooming )
03833			{	
03834				ZoomLevel += DeltaTime * 1.0;
03835				if (ZoomLevel > 0.9)
03836					ZoomLevel = 0.9;
03837				DesiredFOV = FClamp(90.0 - (ZoomLevel * 88.0), 1, 170);
03838			} 
03839		}
03840	
03841		function Landed(vector HitNormal)
03842		{
03843			if ( !bUpdating )
03844			{
03845				//log(class$" Landed while swimming");
03846				PlayLanded(Velocity.Z);
03847				TakeFallingDamage();
03848				bJustLanded = true;
03849			}
03850			if ( Region.Zone.bWaterZone )
03851				SetPhysics(PHYS_Swimming);
03852			else
03853			{
03854				GotoState('PlayerWalking');
03855				AnimEnd();
03856			}
03857		}
03858	
03859		function AnimEnd()
03860		{
03861			local vector X,Y,Z;
03862			GetAxes(Rotation, X,Y,Z);
03863			if ( (Acceleration Dot X) <= 0 )
03864			{
03865				if ( GetAnimGroup(AnimSequence) == 'TakeHit' )
03866				{
03867					bAnimTransition = true;
03868					TweenToWaiting(0.2);
03869				} 
03870				else
03871					PlayWaiting();
03872			}	
03873			else
03874			{
03875				if ( GetAnimGroup(AnimSequence) == 'TakeHit' )
03876				{
03877					bAnimTransition = true;
03878					TweenToSwimming(0.2);
03879				} 
03880				else
03881					PlaySwimming();
03882			}
03883		}
03884		
03885		function ZoneChange( ZoneInfo NewZone )
03886		{
03887			local actor HitActor;
03888			local vector HitLocation, HitNormal, checkpoint;
03889	
03890			if (!NewZone.bWaterZone)
03891			{
03892				SetPhysics(PHYS_Falling);
03893				if (bUpAndOut && CheckWaterJump(HitNormal)) //check for waterjump
03894				{
03895					velocity.Z = 330 + 2 * CollisionRadius; //set here so physics uses this for remainder of tick
03896					PlayDuck();
03897					GotoState('PlayerWalking');
03898				}				
03899				else if (!FootRegion.Zone.bWaterZone || (Velocity.Z > 160) )
03900				{
03901					GotoState('PlayerWalking');
03902					AnimEnd();
03903				}
03904				else //check if in deep water
03905				{
03906					checkpoint = Location;
03907					checkpoint.Z -= (CollisionHeight + 6.0);
03908					HitActor = Trace(HitLocation, HitNormal, checkpoint, Location, false);
03909					if (HitActor != None)
03910					{
03911						GotoState('PlayerWalking');
03912						AnimEnd();
03913					}
03914					else
03915					{
03916						Enable('Timer');
03917						SetTimer(0.7,false);
03918					}
03919				}
03920				//log("Out of water");
03921			}
03922			else
03923			{
03924				Disable('Timer');
03925				SetPhysics(PHYS_Swimming);
03926			}
03927		}
03928	
03929		function ProcessMove(float DeltaTime, vector NewAccel, eDodgeDir DodgeMove, rotator DeltaRot)	
03930		{
03931			local vector X,Y,Z, Temp;
03932		
03933			GetAxes(ViewRotation,X,Y,Z);
03934			Acceleration = NewAccel;
03935	
03936			SwimAnimUpdate( (X Dot Acceleration) <= 0 );
03937	
03938			bUpAndOut = ((X Dot Acceleration) > 0) && ((Acceleration.Z > 0) || (ViewRotation.Pitch > 2048));
03939			if ( bUpAndOut && !Region.Zone.bWaterZone && CheckWaterJump(Temp) ) //check for waterjump
03940			{
03941				velocity.Z = 330 + 2 * CollisionRadius; //set here so physics uses this for remainder of tick
03942				PlayDuck();
03943				GotoState('PlayerWalking');
03944			}				
03945		}
03946	
03947		event PlayerTick( float DeltaTime )
03948		{
03949			if ( bUpdatePosition )
03950				ClientUpdatePosition();
03951			
03952			PlayerMove(DeltaTime);
03953		}
03954	
03955		function PlayerMove(float DeltaTime)
03956		{
03957			local rotator oldRotation;
03958			local vector X,Y,Z, NewAccel;
03959			local float Speed2D;
03960		
03961			GetAxes(ViewRotation,X,Y,Z);
03962	
03963			aForward *= 0.2;
03964			aStrafe  *= 0.1;
03965			aLookup  *= 0.24;
03966			aTurn    *= 0.24;
03967			aUp		 *= 0.1;  
03968			
03969			NewAccel = aForward*X + aStrafe*Y + aUp*vect(0,0,1); 
03970		
03971			//add bobbing when swimming
03972			if ( !bShowMenu )
03973			{
03974				Speed2D = Sqrt(Velocity.X * Velocity.X + Velocity.Y * Velocity.Y);
03975				WalkBob = Y * Bob *  0.5 * Speed2D * sin(4.0 * Level.TimeSeconds);
03976				WalkBob.Z = Bob * 1.5 * Speed2D * sin(8.0 * Level.TimeSeconds);
03977			}
03978	
03979			// Update rotation.
03980			oldRotation = Rotation;
03981			UpdateRotation(DeltaTime, 2);
03982	
03983			if ( Role < ROLE_Authority ) // then save this move and replicate it
03984				ReplicateMove(DeltaTime, NewAccel, DODGE_None, OldRotation - Rotation);
03985			else
03986				ProcessMove(DeltaTime, NewAccel, DODGE_None, OldRotation - Rotation);
03987			bPressedJump = false;
03988		}
03989	
03990		function Timer()
03991		{
03992			if ( !Region.Zone.bWaterZone && (Role == ROLE_Authority) )
03993			{
03994				//log("timer out of water");
03995				GotoState('PlayerWalking');
03996				AnimEnd();
03997			}
03998		
03999			Disable('Timer');
04000		}
04001		
04002		function BeginState()
04003		{
04004			Disable('Timer');
04005			if ( !IsAnimating() )
04006				TweenToWaiting(0.3);
04007			//log("player swimming");
04008		}
04009	}
04010	
04011	state PlayerFlying
04012	{
04013	ignores SeePlayer, HearNoise, Bump;
04014			
04015		function AnimEnd()
04016		{
04017			PlaySwimming();
04018		}
04019		
04020		event PlayerTick( float DeltaTime )
04021		{
04022			if ( bUpdatePosition )
04023				ClientUpdatePosition();
04024		
04025			PlayerMove(DeltaTime);
04026		}
04027	
04028		function PlayerMove(float DeltaTime)
04029		{
04030			local rotator newRotation;
04031			local vector X,Y,Z;
04032	
04033			GetAxes(Rotation,X,Y,Z);
04034	
04035			aForward *= 0.2;
04036			aStrafe  *= 0.2;
04037			aLookup  *= 0.24;
04038			aTurn    *= 0.24;
04039	
04040			Acceleration = aForward*X + aStrafe*Y;  
04041			// Update rotation.
04042			UpdateRotation(DeltaTime, 2);
04043	
04044			if ( Role < ROLE_Authority ) // then save this move and replicate it
04045				ReplicateMove(DeltaTime, Acceleration, DODGE_None, rot(0,0,0));
04046			else
04047				ProcessMove(DeltaTime, Acceleration, DODGE_None, rot(0,0,0));
04048		}
04049		
04050		function BeginState()
04051		{
04052			SetPhysics(PHYS_Flying);
04053			if  ( !IsAnimating() ) PlayWalking();
04054			//log("player flying");
04055		}
04056	}
04057	
04058	state CheatFlying
04059	{
04060	ignores SeePlayer, HearNoise, Bump, TakeDamage;
04061			
04062		function AnimEnd()
04063		{
04064			PlaySwimming();
04065		}
04066		
04067		function ProcessMove(float DeltaTime, vector NewAccel, eDodgeDir DodgeMove, rotator DeltaRot)	
04068		{
04069			Acceleration = Normal(NewAccel);
04070			Velocity = Normal(NewAccel) * 300;
04071			AutonomousPhysics(DeltaTime);
04072		}
04073	
04074		event PlayerTick( float DeltaTime )
04075		{
04076			if ( bUpdatePosition )
04077				ClientUpdatePosition();
04078	
04079			PlayerMove(DeltaTime);
04080		}
04081	
04082		function PlayerMove(float DeltaTime)
04083		{
04084			local rotator newRotation;
04085			local vector X,Y,Z;
04086	
04087			GetAxes(ViewRotation,X,Y,Z);
04088	
04089			aForward *= 0.1;
04090			aStrafe  *= 0.1;
04091			aLookup  *= 0.24;
04092			aTurn    *= 0.24;
04093			aUp		 *= 0.1;
04094		
04095			Acceleration = aForward*X + aStrafe*Y + aUp*vect(0,0,1);  
04096	
04097			UpdateRotation(DeltaTime, 1);
04098	
04099			if ( Role < ROLE_Authority ) // then save this move and replicate it
04100				ReplicateMove(DeltaTime, Acceleration, DODGE_None, rot(0,0,0));
04101			else
04102				ProcessMove(DeltaTime, Acceleration, DODGE_None, rot(0,0,0));
04103		}
04104	
04105		function BeginState()
04106		{
04107			EyeHeight = BaseEyeHeight;
04108			SetPhysics(PHYS_Flying);
04109			if  ( !IsAnimating() ) PlaySwimming();
04110			// log("cheat flying");
04111		}
04112	}
04113	
04114	state PlayerWaiting
04115	{
04116	ignores SeePlayer, HearNoise, Bump, TakeDamage, Died, ZoneChange, FootZoneChange;
04117	
04118		exec function Jump( optional float F )
04119		{
04120		}
04121	
04122		exec function Suicide()
04123		{
04124		}
04125	
04126		function ChangeTeam( int N )
04127		{
04128			Level.Game.ChangeTeam(self, N);
04129		}
04130	
04131		exec function Fire(optional float F)
04132		{
04133			bReadyToPlay = true;
04134		}
04135		
04136		exec function AltFire(optional float F)
04137		{
04138			bReadyToPlay = true;
04139		}
04140			
04141		function ProcessMove(float DeltaTime, vector NewAccel, eDodgeDir DodgeMove, rotator DeltaRot)	
04142		{
04143			Acceleration = NewAccel;
04144			MoveSmooth(Acceleration * DeltaTime);
04145		}
04146	
04147		function PlayWaiting() {}
04148	
04149		event PlayerTick( float DeltaTime )
04150		{
04151			if ( bUpdatePosition )
04152				ClientUpdatePosition();
04153	
04154			PlayerMove(DeltaTime);
04155		}
04156	
04157		function PlayerMove(float DeltaTime)
04158		{
04159			local rotator newRotation;
04160			local vector X,Y,Z;
04161	
04162			GetAxes(ViewRotation,X,Y,Z);
04163	
04164			aForward *= 0.1;
04165			aStrafe  *= 0.1;
04166			aLookup  *= 0.24;
04167			aTurn    *= 0.24;
04168			aUp		 *= 0.1;
04169		
04170			Acceleration = aForward*X + aStrafe*Y + aUp*vect(0,0,1);  
04171	
04172			UpdateRotation(DeltaTime, 1);
04173	
04174			if ( Role < ROLE_Authority ) // then save this move and replicate it
04175				ReplicateMove(DeltaTime, Acceleration, DODGE_None, rot(0,0,0));
04176			else
04177				ProcessMove(DeltaTime, Acceleration, DODGE_None, rot(0,0,0));
04178		}
04179	
04180		function EndState()
04181		{
04182			SetMesh();
04183			PlayerReplicationInfo.bIsSpectator = false;
04184			PlayerReplicationInfo.bWaitingPlayer = false;
04185			SetCollision(true,true,true);
04186		}
04187	
04188		function BeginState()
04189		{
04190			Mesh = None;
04191			if ( PlayerReplicationInfo != None )
04192			{
04193				PlayerReplicationInfo.bIsSpectator = true;
04194				PlayerReplicationInfo.bWaitingPlayer = true;
04195			}
04196			SetCollision(false,false,false);
04197			EyeHeight = BaseEyeHeight;
04198			SetPhysics(PHYS_None);
04199		}
04200	}
04201	
04202	state PlayerSpectating
04203	{
04204	ignores SeePlayer, HearNoise, Bump, TakeDamage, Died, ZoneChange, FootZoneChange;
04205	
04206		exec function Suicide()
04207		{
04208		}
04209	
04210		function SendVoiceMessage(PlayerReplicationInfo Sender, PlayerReplicationInfo Recipient, name messagetype, byte messageID, name broadcasttype)
04211		{
04212		}
04213	
04214		exec function AltFire( optional float F )
04215		{
04216			bBehindView = false;
04217			Viewtarget = None;
04218			ClientMessage(ViewingFrom@OwnCamera, 'Event', true);
04219		}
04220	
04221		function ChangeTeam( int N )
04222		{
04223			Level.Game.ChangeTeam(self, N);
04224		}
04225	
04226		exec function Fire( optional float F )
04227		{
04228			if ( Role == ROLE_Authority )
04229			{
04230				ViewPlayerNum(-1);
04231				bBehindView = true;
04232			}
04233		} 
04234	
04235		function ProcessMove(float DeltaTime, vector NewAccel, eDodgeDir DodgeMove, rotator DeltaRot)	
04236		{
04237			Acceleration = NewAccel;
04238			MoveSmooth(Acceleration * DeltaTime);
04239		}
04240	
04241		event PlayerTick( float DeltaTime )
04242		{
04243			if ( bUpdatePosition )
04244				ClientUpdatePosition();
04245	
04246			PlayerMove(DeltaTime);
04247		}
04248	
04249		function PlayerMove(float DeltaTime)
04250		{
04251			local rotator newRotation;
04252			local vector X,Y,Z;
04253	
04254			GetAxes(ViewRotation,X,Y,Z);
04255	
04256			aForward *= 0.1;
04257			aStrafe  *= 0.1;
04258			aLookup  *= 0.24;
04259			aTurn    *= 0.24;
04260			aUp		 *= 0.1;
04261		
04262			Acceleration = aForward*X + aStrafe*Y + aUp*vect(0,0,1);  
04263	
04264			UpdateRotation(DeltaTime, 1);
04265	
04266			if ( Role < ROLE_Authority ) // then save this move and replicate it
04267				ReplicateMove(DeltaTime, Acceleration, DODGE_None, rot(0,0,0));
04268			else
04269				ProcessMove(DeltaTime, Acceleration, DODGE_None, rot(0,0,0));
04270		}
04271	
04272		function EndState()
04273		{
04274			PlayerReplicationInfo.bIsSpectator = false;
04275			PlayerReplicationInfo.bWaitingPlayer = false;
04276			SetMesh();
04277			SetCollision(true,true,true);
04278		}
04279	
04280		function BeginState()
04281		{
04282			PlayerReplicationInfo.bIsSpectator = true;
04283			PlayerReplicationInfo.bWaitingPlayer = true;
04284			bShowScores = true;
04285			Mesh = None;
04286			SetCollision(false,false,false);
04287			EyeHeight = Default.BaseEyeHeight;
04288			SetPhysics(PHYS_None);
04289		}
04290	}
04291	//===============================================================================
04292	state PlayerWaking
04293	{
04294	ignores SeePlayer, HearNoise, KilledBy, Bump, HitWall, HeadZoneChange, FootZoneChange, ZoneChange, SwitchWeapon, Falling;
04295	
04296		function Timer()
04297		{
04298			BaseEyeHeight = Default.BaseEyeHeight;
04299		}
04300	
04301		event PlayerTick( float DeltaTime )
04302		{
04303			if ( bUpdatePosition )
04304				ClientUpdatePosition();
04305	
04306			PlayerMove(DeltaTime);
04307		}
04308	
04309		function PlayerMove(Float DeltaTime)
04310		{
04311			ViewFlash(deltaTime * 0.5);
04312			if ( TimerRate == 0 )
04313			{
04314				ViewRotation.Pitch -= DeltaTime * 12000;
04315				if ( ViewRotation.Pitch < 0 )
04316				{
04317					ViewRotation.Pitch = 0;
04318					GotoState('PlayerWalking');
04319				}
04320			}
04321	
04322			if ( Role < ROLE_Authority ) // then save this move and replicate it
04323				ReplicateMove(DeltaTime, vect(0,0,0), DODGE_None, rot(0,0,0));
04324			else
04325				ProcessMove(DeltaTime, vect(0,0,0), DODGE_None, rot(0,0,0));
04326		}
04327	
04328		function BeginState()
04329		{
04330			if ( bWokeUp )
04331			{
04332				ViewRotation.Pitch = 0;
04333				SetTimer(0, false);
04334				return;
04335			}
04336			BaseEyeHeight = 0;
04337			EyeHeight = 0;
04338			SetTimer(3.0, false);
04339			bWokeUp = true;
04340		}
04341	}
04342	
04343	state Dying
04344	{
04345	ignores SeePlayer, HearNoise, KilledBy, Bump, HitWall, HeadZoneChange, FootZoneChange, ZoneChange, SwitchWeapon, Falling, PainTimer;
04346	
04347		exec function Suicide()
04348		{
04349		}
04350	
04351		function ServerReStartPlayer()
04352		{
04353			//log("calling restartplayer in dying with netmode "$Level.NetMode);
04354			if ( (bFrozen && (TimerRate>0.0)) || (Level.NetMode == NM_Client) )
04355				return;
04356			if( Level.Game.RestartPlayer(self) )
04357			{
04358				ServerTimeStamp = 0;
04359				TimeMargin = 0;
04360				Enemy = None;
04361				Level.Game.StartPlayer(self);
04362				if ( Mesh != None )
04363					PlayWaiting();
04364				ClientReStart();
04365			}
04366			else
04367				log("Restartplayer failed");
04368		}
04369	
04370		exec function Fire( optional float F )
04371		{
04372			if ( (Level.NetMode == NM_Standalone) && !Level.Game.bDeathMatch )
04373			{
04374				if ( bFrozen )
04375					return;
04376				ShowLoadMenu();
04377			}
04378			else if ( !bFrozen || (TimerRate <= 0.0) )
04379				ServerReStartPlayer();
04380		}
04381		
04382		exec function AltFire( optional float F )
04383		{
04384			Fire(F);
04385		}
04386	
04387		function PlayChatting()
04388		{
04389		}
04390	
04391		exec function Taunt( name Sequence )
04392		{
04393		}
04394	
04395		function ServerMove
04396		(
04397			float TimeStamp, 
04398			vector Accel, 
04399			vector ClientLoc,
04400			bool NewbRun,
04401			bool NewbDuck,
04402			bool NewbJumpStatus,
04403			bool bFired,
04404			bool bAltFired,
04405			bool bForceFire,
04406			bool bForceAltFire,
04407			eDodgeDir DodgeMove, 
04408			byte ClientRoll, 
04409			int View,
04410			optional byte OldTimeDelta,
04411			optional int OldAccel
04412		)
04413		{
04414			Global.ServerMove(
04415						TimeStamp,
04416						Accel, 
04417						ClientLoc,
04418						false,
04419						false,
04420						false, 
04421						false,
04422						false,
04423						false,
04424						false,
04425						DodgeMove, 
04426						ClientRoll, 
04427						View);
04428		}
04429	
04430		function PlayerCalcView(out actor ViewActor, out vector CameraLocation, out rotator CameraRotation )
04431		{
04432			local vector View,HitLocation,HitNormal, FirstHit, spot;
04433			local float DesiredDist, ViewDist, WallOutDist;
04434			local actor HitActor;
04435			local Pawn PTarget;
04436	
04437			if ( ViewTarget != None )
04438			{
04439				ViewActor = ViewTarget;
04440				CameraLocation = ViewTarget.Location;
04441				CameraRotation = ViewTarget.Rotation;
04442				PTarget = Pawn(ViewTarget);
04443				if ( PTarget != None )
04444				{
04445					if ( Level.NetMode == NM_Client )
04446					{
04447						if ( PTarget.bIsPlayer )
04448							PTarget.ViewRotation = TargetViewRotation;
04449						PTarget.EyeHeight = TargetEyeHeight;
04450						if ( PTarget.Weapon != None )
04451							PTarget.Weapon.PlayerViewOffset = TargetWeaponViewOffset;
04452					}
04453					if ( PTarget.bIsPlayer )
04454						CameraRotation = PTarget.ViewRotation;
04455					CameraLocation.Z += PTarget.EyeHeight;
04456				}
04457	
04458				if ( Carcass(ViewTarget) != None )
04459				{
04460					if ( bBehindView || (ViewTarget.Physics == PHYS_None) )
04461						CameraRotation = ViewRotation;
04462					else 
04463						ViewRotation = CameraRotation;
04464					if ( bBehindView )
04465						CalcBehindView(CameraLocation, CameraRotation, 190);
04466				}
04467				else if ( bBehindView )
04468					CalcBehindView(CameraLocation, CameraRotation, 180);
04469	
04470				return;
04471			}
04472	
04473			// View rotation.
04474			CameraRotation = ViewRotation;
04475			DesiredFOV = DefaultFOV;		
04476			ViewActor = self;
04477			if( bBehindView ) //up and behind (for death scene)
04478				CalcBehindView(CameraLocation, CameraRotation, 180);
04479			else
04480			{
04481				// First-person view.
04482				CameraLocation = Location;
04483				CameraLocation.Z += Default.BaseEyeHeight;
04484			}
04485		}
04486	
04487		event PlayerTick( float DeltaTime )
04488		{
04489			if ( bUpdatePosition )
04490				ClientUpdatePosition();
04491			
04492			PlayerMove(DeltaTime);
04493		}
04494	
04495		function PlayerMove(float DeltaTime)
04496		{
04497			local vector X,Y,Z;
04498	
04499			if ( !bFrozen )
04500			{
04501				if ( bPressedJump )
04502				{
04503					Fire(0);
04504					bPressedJump = false;
04505				}
04506				GetAxes(ViewRotation,X,Y,Z);
04507				// Update view rotation.
04508				aLookup  *= 0.24;
04509				aTurn    *= 0.24;
04510				ViewRotation.Yaw += 32.0 * DeltaTime * aTurn;
04511				ViewRotation.Pitch += 32.0 * DeltaTime * aLookUp;
04512				ViewRotation.Pitch = ViewRotation.Pitch & 65535;
04513				If ((ViewRotation.Pitch > 18000) && (ViewRotation.Pitch < 49152))
04514				{
04515					If (aLookUp > 0) 
04516						ViewRotation.Pitch = 18000;
04517					else
04518						ViewRotation.Pitch = 49152;
04519				}
04520				if ( Role < ROLE_Authority ) // then save this move and replicate it
04521					ReplicateMove(DeltaTime, vect(0,0,0), DODGE_None, rot(0,0,0));
04522			}
04523			ViewShake(DeltaTime);
04524			ViewFlash(DeltaTime);
04525		}
04526	
04527		function FindGoodView()
04528		{
04529			local vector cameraLoc;
04530			local rotator cameraRot;
04531			local int tries, besttry;
04532			local float bestdist, newdist;
04533			local int startYaw;
04534			local actor ViewActor;
04535			
04536			//fixme - try to pick view with killer visible
04537			//fixme - also try varying starting pitch
04538			////log("Find good death scene view");
04539			ViewRotation.Pitch = 56000;
04540			tries = 0;
04541			besttry = 0;
04542			bestdist = 0.0;
04543			startYaw = ViewRotation.Yaw;
04544			
04545			for (tries=0; tries<16; tries++)
04546			{
04547				cameraLoc = Location;
04548				PlayerCalcView(ViewActor, cameraLoc, cameraRot);
04549				newdist = VSize(cameraLoc - Location);
04550				if (newdist > bestdist)
04551				{
04552					bestdist = newdist;	
04553					besttry = tries;
04554				}
04555				ViewRotation.Yaw += 4096;
04556			}
04557				
04558			ViewRotation.Yaw = startYaw + besttry * 4096;
04559		}
04560		
04561		function TakeDamage( int Damage, Pawn instigatedBy, Vector hitlocation, 
04562								Vector momentum, name damageType)
04563		{
04564			if ( !bHidden )
04565				Super.TakeDamage(Damage, instigatedBy, hitlocation, momentum, damageType);
04566		}
04567		
04568		function Timer()
04569		{
04570			bFrozen = false;
04571			bShowScores = true;
04572			bPressedJump = false;
04573		}
04574		
04575		function BeginState()
04576		{
04577			BaseEyeheight = Default.BaseEyeHeight;
04578			EyeHeight = BaseEyeHeight;
04579			if ( Carcass(ViewTarget) == None )
04580				bBehindView = true;
04581			bFrozen = true;
04582			bPressedJump = false;
04583			bJustFired = false;
04584			bJustAltFired = false;
04585			FindGoodView();
04586			if ( (Role == ROLE_Authority) && !bHidden )
04587				Super.Timer(); 
04588			SetTimer(1.0, false);
04589	
04590			// clean out saved moves
04591			while ( SavedMoves != None )
04592			{
04593				SavedMoves.Destroy();
04594				SavedMoves = SavedMoves.NextMove;
04595			}
04596			if ( PendingMove != None )
04597			{
04598				PendingMove.Destroy();
04599				PendingMove = None;
04600			}
04601		}
04602		
04603		function EndState()
04604		{
04605			// clean out saved moves
04606			while ( SavedMoves != None )
04607			{
04608				SavedMoves.Destroy();
04609				SavedMoves = SavedMoves.NextMove;
04610			}
04611			if ( PendingMove != None )
04612			{
04613				PendingMove.Destroy();
04614				PendingMove = None;
04615			}
04616			Velocity = vect(0,0,0);
04617			Acceleration = vect(0,0,0);
04618			bBehindView = false;
04619			bShowScores = false;
04620			bJustFired = false;
04621			bJustAltFired = false;
04622			bPressedJump = false;
04623			if ( Carcass(ViewTarget) != None )
04624				ViewTarget = None;
04625			//Log(self$" exiting dying with remote role "$RemoteRole$" and role "$Role);
04626		}
04627	}
04628	
04629	state GameEnded
04630	{
04631	ignores SeePlayer, HearNoise, KilledBy, Bump, HitWall, HeadZoneChange, FootZoneChange, ZoneChange, Falling, TakeDamage, PainTimer, Died, Suicide;
04632	
04633		exec function ThrowWeapon()
04634		{
04635		}
04636	
04637		exec function Taunt( name Sequence )
04638		{
04639			if ( Health > 0 )
04640				Global.Taunt(Sequence);
04641		}
04642	
04643		exec function ViewClass( class<actor> aClass, optional bool bQuiet )
04644		{
04645		}
04646		exec function ViewPlayer( string S )
04647		{
04648		}
04649	
04650	
04651		function ServerReStartGame()
04652		{
04653			Level.Game.RestartGame();
04654		}
04655	
04656		exec function Fire( optional float F )
04657		{
04658			if ( Role < ROLE_Authority)
04659				return;
04660			if ( !bFrozen )
04661				ServerReStartGame();
04662			else if ( TimerRate <= 0 )
04663				SetTimer(1.5, false);
04664		}
04665		
04666		exec function AltFire( optional float F )
04667		{
04668			Fire(F);
04669		}
04670	
04671		event PlayerTick( float DeltaTime )
04672		{
04673			if ( bUpdatePosition )
04674				ClientUpdatePosition();
04675	
04676			PlayerMove(DeltaTime);
04677		}
04678	
04679		function PlayerMove(float DeltaTime)
04680		{
04681			local vector X,Y,Z;
04682			
04683			GetAxes(ViewRotation,X,Y,Z);
04684			// Update view rotation.
04685	
04686			if ( !bFixedCamera )
04687			{
04688				aLookup  *= 0.24;
04689				aTurn    *= 0.24;
04690				ViewRotation.Yaw += 32.0 * DeltaTime * aTurn;
04691				ViewRotation.Pitch += 32.0 * DeltaTime * aLookUp;
04692				ViewRotation.Pitch = ViewRotation.Pitch & 65535;
04693				If ((ViewRotation.Pitch > 18000) && (ViewRotation.Pitch < 49152))
04694				{
04695					If (aLookUp > 0) 
04696						ViewRotation.Pitch = 18000;
04697					else
04698						ViewRotation.Pitch = 49152;
04699				}
04700			}
04701			else if ( ViewTarget != None )
04702				ViewRotation = ViewTarget.Rotation;
04703	
04704			ViewShake(DeltaTime);
04705			ViewFlash(DeltaTime);
04706	
04707			if ( Role < ROLE_Authority ) // then save this move and replicate it
04708				ReplicateMove(DeltaTime, vect(0,0,0), DODGE_None, rot(0,0,0));
04709			else
04710				ProcessMove(DeltaTime, vect(0,0,0), DODGE_None, rot(0,0,0));
04711			bPressedJump = false;
04712		}
04713	
04714		function ServerMove
04715		(
04716			float TimeStamp, 
04717			vector InAccel, 
04718			vector ClientLoc,
04719			bool NewbRun,
04720			bool NewbDuck,
04721			bool NewbJumpStatus, 
04722			bool bFired,
04723			bool bAltFired,
04724			bool bForceFire,
04725			bool bForceAltFire,
04726			eDodgeDir DodgeMove, 
04727			byte ClientRoll, 
04728			int View,
04729			optional byte OldTimeDelta,
04730			optional int OldAccel
04731		)
04732		{
04733			Global.ServerMove(TimeStamp, InAccel, ClientLoc, NewbRun, NewbDuck, NewbJumpStatus,
04734								bFired, bAltFired, bForceFire, bForceAltFire, DodgeMove, ClientRoll, (32767 & (ViewRotation.Pitch/2)) * 32768 + (32767 & (ViewRotation.Yaw/2)) );
04735	
04736		}
04737	
04738		function FindGoodView()
04739		{
04740			local vector cameraLoc;
04741			local rotator cameraRot;
04742			local int tries, besttry;
04743			local float bestdist, newdist;
04744			local int startYaw;
04745			local actor ViewActor;
04746			
04747			ViewRotation.Pitch = 56000;
04748			tries = 0;
04749			besttry = 0;
04750			bestdist = 0.0;
04751			startYaw = ViewRotation.Yaw;
04752			
04753			for (tries=0; tries<16; tries++)
04754			{
04755				if ( ViewTarget != None )
04756					cameraLoc = ViewTarget.Location;
04757				else
04758					cameraLoc = Location;
04759				PlayerCalcView(ViewActor, cameraLoc, cameraRot);
04760				newdist = VSize(cameraLoc - Location);
04761				if (newdist > bestdist)
04762				{
04763					bestdist = newdist;	
04764					besttry = tries;
04765				}
04766				ViewRotation.Yaw += 4096;
04767			}
04768				
04769			ViewRotation.Yaw = startYaw + besttry * 4096;
04770		}
04771		
04772		function Timer()
04773		{
04774			bFrozen = false;
04775		}
04776		
04777		function BeginState()
04778		{
04779			local Pawn P;
04780	
04781			EndZoom();
04782			AnimRate = 0.0;
04783			SimAnim.Y = 0;
04784			bFire = 0;
04785			bAltFire = 0;
04786			SetCollision(false,false,false);
04787			bShowScores = true;
04788			bFrozen = true;
04789			if ( !bFixedCamera )
04790			{
04791				FindGoodView();
04792				bBehindView = true;
04793			}
04794			SetTimer(1.5, false);
04795			SetPhysics(PHYS_None);
04796			ForEach AllActors(class'Pawn', P)
04797			{
04798				P.Velocity = vect(0,0,0);
04799				P.SetPhysics(PHYS_None);
04800			}
04801		}
04802	}
04803	
04804	// ngStats Accessors
04805	function string GetNGSecret()
04806	{
04807		return ngWorldSecret;
04808	}
04809	
04810	function SetNGSecret(string newSecret)
04811	{
04812		ngWorldSecret = newSecret;
04813	}
04814	
04815	defaultproperties
04816	{
04817	     DodgeClickTime=0.250000
04818	     Bob=0.016000
04819	     FlashScale=(X=1.000000,Y=1.000000,Z=1.000000)
04820	     DesiredFOV=52.900002
04821	     DefaultFOV=90.000000
04822	     CdTrack=255
04823	     MyAutoAim=0.930000
04824	     Handedness=-1.000000
04825	     bAlwaysMouseLook=True
04826	     bKeyboardLook=True
04827	     bMaxMouseSmoothing=True
04828	     bNoFlash=True
04829	     bMessageBeep=True
04830	     MouseSensitivity=3.000000
04831	     WeaponPriority(0)=Translocator
04832	     WeaponPriority(1)=ChainSaw
04833	     WeaponPriority(2)=ImpactHammer
04834	     WeaponPriority(3)=enforcer
04835	     WeaponPriority(4)=doubleenforcer
04836	     WeaponPriority(5)=ShockRifle
04837	     WeaponPriority(6)=ut_biorifle
04838	     WeaponPriority(7)=PulseGun
04839	     WeaponPriority(8)=SniperRifle
04840	     WeaponPriority(9)=ripper
04841	     WeaponPriority(10)=minigun2
04842	     WeaponPriority(11)=UT_FlakCannon
04843	     WeaponPriority(12)=UT_Eightball
04844	     WeaponPriority(13)=WarheadLauncher
04845	     MouseSmoothThreshold=0.070000
04846	     MaxTimeMargin=3.000000
04847	     QuickSaveString="Quick Saving"
04848	     NoPauseMessage="Game is not pauseable"
04849	     ViewingFrom="Now viewing from"
04850	     OwnCamera="own camera"
04851	     FailedView="Failed to change view."
04852	     ngSecretSet=True
04853	     bIsPlayer=True
04854	     bCanJump=True
04855	     bViewTarget=True
04856	     DesiredSpeed=0.300000
04857	     SightRadius=4100.000000
04858	     bStasis=False
04859	     bTravel=True
04860	     NetPriority=3.000000
04861	}

End Source Code