## Engine
Class PlayerController

source: C:\XIII\Engine\Classes\PlayerController.uc

    Core.Object
       |
       +--Engine.Actor
          |
          +--Engine.Controller
             |
             +--Engine.PlayerController

Direct Known Subclasses:Admin, Camera, MessagingSpectator, XIIIPlayerController

class PlayerController
extends Engine.Controller

    //=============================================================================
    // PlayerController
    //
    // PlayerControllers are used by human players to control pawns.
    //
    // This is a built-in Unreal class and it shouldn't be modified.
    // CHANGENOTE: All Changes since v739 in this class are related to the Weapon code update, except
    // for the change in Possess().
    //=============================================================================

Variables
`vector` | `AdjustedAimForFiring` Aim to use when firing Projectiles (because display don't show anticipation
`int` | `AnnouncerVolume` heads up display info
`LandBob,` | `AppliedBob` Used to store everything that should be usefull for on-line ladder/rankings
`Actor` | `BestTarget` to memorize the best target and use it in interaction
`float` | `Bob` Used to store everything that should be usefull for on-line ladder/rankings
`float` | `CameraDist` multiplier for behindview camera dist
`class` | `CheatClass` class of my CheatManager
`CheatManager` | `CheatManager` Object within playercontroller that manages "cheat" commands
`CurrentTimeStamp,LastUpdateTime,ServerTimeStamp,TimeMargin,` | `ClientUpdateTime` freed moves, available for buffering
`eConfigType` | `ConfigType` auto center view afer walking a while
`float` | `DefaultFOV` multiplier for behindview camera dist
`float` | `DeltaT` to enable using it anywhere (needed for death camera sfxs at least)
`int` | `DemoViewPitch` class of my PlayerInput
`int` | `DemoViewYaw` class of my PlayerInput
`float` | `DesiredFOV` multiplier for behindview camera dist
`EDoubleClickDir` | `DoubleClickDir` direction of movement key double click (for special moves)
`int` | `EnemyTurnSpeed` how long to roll. if value is < 1.0, then MaxShakeOffset gets damped by this, else if > 1 then its the number of times to repeat undamped
`color` | `FilterColor` multiplier for behindview camera dist
`float` | `FilterColorSpeed` multiplier for behindview camera dist
`color` | `FilterColorWanted` multiplier for behindview camera dist
`int` | `FilterInternalInc` multiplier for behindview camera dist
`FlashScale,` | `FlashFog` multiplier for behindview camera dist
`SavedMove` | `FreeMoves` freed moves, available for buffering
`GameReplicationInfo` | `GameReplicationInfo` freed moves, available for buffering
`int` | `GroundPitch` how long to roll. if value is < 1.0, then MaxShakeOffset gets damped by this, else if > 1 then its the number of times to repeat undamped
`class` | `InputClass` class of my PlayerInput
`ConstantGlowScale,` | `InstantFlash` multiplier for behindview camera dist
`ConstantGlowFog,` | `InstantFog` multiplier for behindview camera dist
`float` | `LastPlaySound` heads up display info
`class` | `LocalMessageClass` Used to store everything that should be usefull for on-line ladder/rankings
`vector` | `MaxShakeOffset` max magnitude to offset camera position
`float` | `MaxShakeRoll` max magnitude to roll camera
`float` | `MaxTimeMargin` freed moves, available for buffering
`vector` | `MemAim` memorize aim when switching bLocked
`int` | `Misc1,Misc2` direction of movement key double click (for special moves)
`string` | `NoPauseMessage` freed moves, available for buffering
`vector` | `OldAdjustAim` Used to smooth autoaim, Aim to use when firing non-projectiles
`Actor` | `OldBestTarget` to memorize the best target and use it in interaction
`Weapon` | `OldClientWeapon` freed moves, available for buffering
`vector` | `OldFloor` used by PlayerSpider mode - floor for which old rotation was based;
`float` | `OrthoZoom` Orthogonal/map view zoom factor.
`string` | `OwnCamera` freed moves, available for buffering
`SavedMove` | `PendingMove` freed moves, available for buffering
`Player` | `Player`
`PlayerInput` | `PlayerInput` Object within playercontroller that manages player input.
`PlayerStats` | `PlayerStat` Used to store everything that should be usefull for on-line ladder/rankings
`color` | `ProgressColor[4]` freed moves, available for buffering
`string` | `ProgressMessage[4]` freed moves, available for buffering
`float` | `ProgressTimeOut` freed moves, available for buffering
`string` | `QuickSaveString` freed moves, available for buffering
`bool` | `ReceivedSecretChecksum` freed moves, available for buffering
`int` | `RendMap` direction of movement key double click (for special moves)
`SavedMove` | `SavedMoves` buffered moves pending position updates
`ShakeFrame,` | `ShakeFrameRate` how long to roll. if value is < 1.0, then MaxShakeOffset gets damped by this, else if > 1 then its the number of times to repeat undamped
`float` | `ShakeFrameTime` how long to roll. if value is < 1.0, then MaxShakeOffset gets damped by this, else if > 1 then its the number of times to repeat undamped
`vector` | `ShakeOffset` current magnitude to offset camera from shake
`vector` | `ShakeOffsetRate` rate to change roll
`vector` | `ShakeOffsetTime` how long to roll. if value is < 1.0, then MaxShakeOffset gets damped by this, else if > 1 then its the number of times to repeat undamped
`float` | `ShakeRollRate` rate to change roll
`float` | `ShakeRollTime` how long to roll. if value is < 1.0, then MaxShakeOffset gets damped by this, else if > 1 then its the number of times to repeat undamped
`int` | `ShowFlags` direction of movement key double click (for special moves)
`float` | `TargetEyeHeight` multiplier for behindview camera dist
`rotator` | `TargetViewRotation` multiplier for behindview camera dist
`vector` | `TargetWeaponViewOffset` multiplier for behindview camera dist
`rotator` | `TurnRot180` how long to roll. if value is < 1.0, then MaxShakeOffset gets damped by this, else if > 1 then its the number of times to repeat undamped
`Pawn` | `TurnTarget` how long to roll. if value is < 1.0, then MaxShakeOffset gets damped by this, else if > 1 then its the number of times to repeat undamped
`byte` | `UseVignetteFilter` class of my PlayerInput
`byte` | `UseVignetteFilter` class of my PlayerInput
`byte` | `UseVignetteHighlight` class of my PlayerInput
`byte` | `UseVignetteHighlight` class of my PlayerInput
`int` | `UserPadConfig` auto center view afer walking a while
`vector` | `ViewAdjustAim` Used to smooth Weapon rot on screen
`Actor` | `ViewTarget` Orthogonal/map view zoom factor.
`string` | `ViewingFrom` freed moves, available for buffering
`color` | `VignetteColor` class of my PlayerInput
`color` | `VignetteColor` class of my PlayerInput
`float` | `VignetteHighLight` class of my PlayerInput
`float` | `VignetteHighLight` class of my PlayerInput
`Material` | `VignetteMaterial` class of my PlayerInput
`Material` | `VignetteMaterial` class of my PlayerInput
`float` | `WaitDelay` Delay time until can restart
`vector` | `WalkBob` Used to store everything that should be usefull for on-line ladder/rankings
`int` | `WeaponUpdate` freed moves, available for buffering
`float` | `ZoomLevel` multiplier for behindview camera dist
`b90Right,` | `b180Turn` To make us turn fast to left or right.
`byte` | `bAltDuck` To enable the AltDuck Mode
`byte` | `bAltJump` To be used for Hook Mode using Duck/Jump
`byte` | `bAltRun`
`bool` | `bAlwaysLevel` This controller is not allowed to possess pawns
`bool` | `bAlwaysMouseLook` Snap to level eyeheight when not mouselooking
`bool` | `bAutoPickup` AutoPickup objects.
`bool` | `bBehindView` Outside-the-player view.
`bool` | `bCenterView` no snapping when true
`bool` | `bCheatFlying` instantly stop in flying mode
`bool` | `bDontUseVolumeFog` adjustaim locked someone (to handle transitions between crosshair pos
`bool` | `bFixedCamera` used to fix camera in position (to view animations)
`bool` | `bFreeCamera` free camera when in behindview mode (for checking out player models and animations)
`bool` | `bFrozen` set when game ends or player dies to temporarily prevent player from restarting (until cleared by timer)
`bool` | `bInverseLook` Inverse FlightSim/Std Pad look axis
`bool` | `bIsInMenu` adjustaim locked someone (to handle transitions between crosshair pos
`bool` | `bIsTyping` set when game ends or player dies to temporarily prevent player from restarting (until cleared by timer)
`bool` | `bJumpStatus` used in net games
`bool` | `bKeyboardLook` no snapping when true
`bool` | `bLocked` adjustaim locked someone (to handle transitions between crosshair pos
`bool` | `bLookUpStairs` look up/down stairs (player)
`bool` | `bNeverSwitchOnPickup` if true, don't automatically switch to picked up weapon
`bool` | `bOnlySpectator` This controller is not allowed to possess pawns
`bool` | `bPressedJump` set when game ends or player dies to temporarily prevent player from restarting (until cleared by timer)
`bLeft,` | `bRight` check if KEYs are pressed and not pad.
`bool` | `bSetTurnRot` This controller is not allowed to possess pawns
`bool` | `bSnapToLevel` Snap to level eyeheight when not mouselooking
`bool` | `bUpdatePosition` set when game ends or player dies to temporarily prevent player from restarting (until cleared by timer)
`bool` | `bUpdating` used in net games
`bool` | `bUseRumble` auto center view afer walking a while
`bool` | `bWalkCenterView` auto center view afer walking a while
`bool` | `bZeroRoll` free camera when in behindview mode (for checking out player models and animations)
`bool` | `bZooming` if true, don't automatically switch to picked up weapon
`float` | `bobtime` Used to store everything that should be usefull for on-line ladder/rankings
`input` | `byte` Delay time until can restart
`float` | `fAdjustAimTrans` to handle crosshair/Adjust aim transition
`float` | `fLookSpeed` auto center view afer walking a while
`input` | `float` Delay time until can restart
`int` | `iAutoAimMode` 0 = off, 1 = on.
`HUD` | `myHUD` heads up display info
`bool` | `ngSecretSet` freed moves, available for buffering
`string` | `ngWorldSecret` freed moves, available for buffering

States
Dead, GameEnded, WaitingForPawn, Player, Player, PlayerWaiting, PlayerWaiting, Spectating, BaseSpectating, PlayerHelicoptering, PlayerFlying, PlayerSwimming, PlayerSpidering, PlayerClimbing, PlayerWalking

Function Summary
`void` | `ActivateInventoryItem(class InvItem)`
    // Activate specific inventory item
`void` | `ActivateItem()`
    // The player wants to active selected item
`rotator` | `AdjustAim(Ammunition FiredAmmunition, vector projStart, int aimerror)`
    /* AdjustAim()
    Calls this version for player aiming help.
    Aimerror not used in this version.
    Only adjusts aiming at pawns
    */
`rotator` | `AdjustAimForDisplay(Ammunition FiredAmmunition, vector projStart)`
    // if not leading, add slight random error ( significant at long distances )
    		if ( !bNoZAdjust )
    		{
    			AimRot = rotator(AimSpot - projStart);
    			if ( FOVAngle < DefaultFOV - 8 )
    				AimRot.Yaw = AimRot.Yaw + 200 - Rand(400);
    			else
    				AimRot.Yaw = AimRot.Yaw + 375 - Rand(750);
    			return AimRot;
    		}
    	}
    	else if ( !FastTrace(projStart + 0.9 * bestDist * Normal(FireDir), projStart) )
    	{
    		FireDir = BestTarget.Location - projStart;
    		AimSpot = projStart + bestDist * Normal(FireDir);
    	}

    	return rotator(AimSpot - projStart);
    }
    */
`void` | `AdjustRadius(float MaxMove)`
`void` | `AdjustView(float DeltaTime)`
    // Player view.
    // Compute the rendering viewpoint for the player.
    //
`void` | `AltFire(optional float)`
    // The player wants to alternate-fire.
`void` | `AskForPawn()`
`eAttitude` | `AttitudeTo(Pawn Other)`
`void` | `AttribPadToViewport()`
`void` | `BehindView(Bool B)`
`void` | `CalcBehindView(out vector, out rotator, float Dist)`
`void` | `CalcFirstPersonView(out vector, out rotator)`
    // First-person view.
    	CameraRotation = Rotation;
    	CameraLocation = CameraLocation + Pawn.EyePosition() + WalkBob + ShakeOffset;
    }*/
`void` | `CalcFirstPersonView(out vector, out rotator)`
    // First-person view.
    	CameraRotation = Rotation;
    	CameraLocation = CameraLocation + Pawn.EyePosition() + WalkBob + ShakeOffset;
    }*/
`void` | `ChangeName(string S)`
`void` | `ChangeSetHand(string S)`
`void` | `ChangeTeam(int N)`
`void` | `ChangedWeapon()`
    // Just changed to pendingWeapon
`void` | `CheckBob(float DeltaTime, float Speed2D, vector Y)`
    {
    	if ( Speed2D < 10 )
    		BobTime += 0.2 * DeltaTime;
    	else
    		BobTime += DeltaTime * (0.3 + 0.7 * Speed2D/Pawn.GroundSpeed);
    	WalkBob = Y * 0.4 * Bob * Speed2D * sin(8 * BobTime);
    	AppliedBob = AppliedBob * (1 - FMin(1, 16 * deltatime));
    	if ( Speed2D < 10 )
    		WalkBob.Z = AppliedBob;
    	else
    		WalkBob.Z = AppliedBob + 0.3 * Bob * Speed2D * sin(16 * BobTime);
    	if ( LandBob > 0.01 )
    	{
    		AppliedBob += FMin(1, 16 * deltatime) * LandBob;
    		LandBob *= (1 - 8*Deltatime);
    	}
    }*/
`void` | `CheckBob(float DeltaTime, float Speed2D, vector Y)`
    {
    	if ( Speed2D < 10 )
    		BobTime += 0.2 * DeltaTime;
    	else
    		BobTime += DeltaTime * (0.3 + 0.7 * Speed2D/Pawn.GroundSpeed);
    	WalkBob = Y * 0.4 * Bob * Speed2D * sin(8 * BobTime);
    	AppliedBob = AppliedBob * (1 - FMin(1, 16 * deltatime));
    	if ( Speed2D < 10 )
    		WalkBob.Z = AppliedBob;
    	else
    		WalkBob.Z = AppliedBob + 0.3 * Bob * Speed2D * sin(16 * BobTime);
    	if ( LandBob > 0.01 )
    	{
    		AppliedBob += FMin(1, 16 * deltatime) * LandBob;
    		LandBob *= (1 - 8*Deltatime);
    	}
    }*/
`void` | `CheckShake(out float, out float, out float, out float)`
    /*
`void` | `ClearProgressMessages()`
`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` | `ClientFilter(Color FC, color FCW, float FCS)`
`void` | `ClientFlash(float scale, vector fog)`
`void` | `ClientGotoState(name NewState, name NewLabel)`
    /* ClientGotoState()
    server uses this to force client into NewState
    */
`void` | `ClientHighLight(color TargetColor, float TargetHighLight, optional Material)`
`void` | `ClientInstantFlash(float scale, vector fog)`
`simulated` | `ClientPlaySound(sound ASound, optional bool)`
    //Play a sound client side (so only client will hear it
`simulated` | `ClientReliablePlaySound(sound ASound, optional bool)`
`void` | `ClientReplicateSkins(Material Skin1, optional Material, optional Material, optional Material)`
`void` | `ClientRestart()`
`void` | `ClientSetBehindView(bool B)`
`void` | `ClientSetFixedCamera(bool B)`
`void` | `ClientShake(vector ShakeRoll, vector OffsetMag, vector ShakeRate, float OffsetTime)`
    /* ClientShake()
    Function called on client to shake view.
    Only ShakeView() should call ClientShake()
    */
`event` | `ClientTravel(string URL, ETravelType TravelType, bool bItems)`
`void` | `ClientUpdatePosition()`
`void` | `ClientVoiceMessage(PlayerReplicationInfo Sender, PlayerReplicationInfo Recipient, name messagetype, byte messageID)`
    {
    	Local Vector WBob;

    	WBob = BobDamping * WalkBob;
    	WBob.Z = (0.45 + 0.55 * BobDamping) * WalkBob.Z;

    	return (WBob + 0.9 * ShakeOffset);
    }*/
`int` | `CompressAccel(int C)`
`string` | `ConsoleCommand(string Command)`
`void` | `CopyToClipboard(string Text)`
    // Execute a console command in the context of this player, then forward to Actor.ConsoleCommand.
`void` | `EndZoom()`
`void` | `EnterStartState()`
`void` | `FOV(float F)`
`int` | `FindStairRotation(float DeltaTime)`
    /* FindStairRotation()
    returns an integer to use as a pitch to orient player view along current ground (flat, up, or down)
    */
`void` | `Fire(optional float)`
    // The player wants to fire.
`void` | `FixFOV()`
`void` | `ForceDeathUpdate()`
    /* ForceDeathUpdate()
    Make sure ClientAdjustPosition immediately informs client of pawn's death
    */
`void` | `ForceReload()`
`string` | `GetDefaultURL(string Option)`
`LevelInfo` | `GetEntryLevel()`
`int` | `GetFacingDirection()`
    /* GetFacingDirection()
    returns direction faced relative to movement dir
    0 = forward
    16384 = right
    32768 = back
    49152 = left
    */
`SavedMove` | `GetFreeMove()`
`int` | `GetPadNumber()`
    // Pad management
`string` | `GetPlayerNetworkAddress()`
`void` | `GivePawn(Pawn NewPawn)`
`void` | `HandlePickup(Pickup pick)`
`void` | `HandleWalking()`
    {
    	if ( Pawn != None )
    		Pawn.SetWalking(((bRun != 0) || (bDuck != 0)) && !Region.Zone.IsA('WarpZoneInfo'));
    }*/
`void` | `HandleWalking()`
    {
    	if ( Pawn != None )
    		Pawn.SetWalking(((bRun != 0) || (bDuck != 0)) && !Region.Zone.IsA('WarpZoneInfo'));
    }*/
`void` | `Jump(optional float)`
    //*************************************************************************************
    // Normal gameplay execs
    // Type the name of the exec function at the console to execute it
`void` | `LocalTravel(string URL)`
`void` | `LongClientAdjustPosition(float TimeStamp, name newState, EPhysics newPhysics, float NewLocX, float NewLocY, float NewLocZ, float NewVelX, float NewVelY, float NewVelZ, Actor NewBase, float NewFloorX, float NewFloorY, float NewFloorZ)`
    /* LongClientAdjustPosition
    long version, when care about pawn's floor normal
    */
`void` | `MoveAutonomous(float DeltaTime, bool NewbRun, bool NewbDuck, bool NewbPressedJump, eDoubleClickDir DoubleClickMove, vector newAccel, rotator DeltaRot)`
`void` | `Name(string S)`
`void` | `NextWeapon()`
    /* NextWeapon()
    - switch to next inventory group weapon
    */
`bool` | `NotifyLanded(vector HitNormal)`
`void` | `OptimizeInputBindings()`
    // "Compile" the commands associated with each input key
`string` | `PasteFromClipboard()`
`void` | `Pause()`
    /* Pause()
    Command to try to pause the game.
    */
`void` | `PawnDied()`
    // unpossessed a pawn (because pawn was killed)
`simulated` | `PlayBeepSound()`
`void` | `PlayerMove(float DeltaTime)`
`void` | `Possess(Pawn aPawn)`
    // Possess a pawn
`void` | `PrevItem()`
    // The player wants to select previous item
`void` | `PrevWeapon()`
    /* PrevWeapon()
    - switch to previous inventory group weapon
    */
`void` | `ProcessMove(float DeltaTime, vector newAccel, eDoubleClickDir DoubleClickMove, rotator DeltaRot)`
`void` | `QuickLoad()`
    /* QuickLoad()
    Load game from slot 9
    */
`void` | `QuickSave()`
    /* QuickSave()
    Save game to slot 9
    */
`void` | `ReplicateMove(float DeltaTime, vector NewAccel, eDoubleClickDir DoubleClickMove, rotator DeltaRot)`
    //
    // Replicate this client's desired movement to the server.
    //
`void` | `Reset()`
    /* Reset()
    reset actor to initial state - used when restarting level without reloading.
    */
`void` | `ResetFOV()`
`void` | `ResetKeyboard()`
`void` | `Restart()`
`void` | `RestartLevel()`
`void` | `Say(string Msg)`
    // Send a message to all players.
`void` | `ServerMove()`
    /*
    ========================================================================
    Here's how player movement prediction, replication and correction works in network games:

    Every tick, the PlayerTick() function is called.  It calls the PlayerMove() function (which is implemented
    in various states).  PlayerMove() figures out the acceleration and rotation, and then calls ProcessMove()
    (for single player or listen servers), or ReplicateMove() (if its a network client).

    ReplicateMove() saves the move (in the PendingMove list), calls ProcessMove(), and then replicates the move
    to the server by calling the replicated
`void` | `ServerMove()`
    /*
    ========================================================================
    Here's how player movement prediction, replication and correction works in network games:

    Every tick, the PlayerTick() function is called.  It calls the PlayerMove() function (which is implemented
    in various states).  PlayerMove() figures out the acceleration and rotation, and then calls ProcessMove()
    (for single player or listen servers), or ReplicateMove() (if its a network client).

    ReplicateMove() saves the move (in the PendingMove list), calls ProcessMove(), and then replicates the move
    to the server by calling the replicated
`void` | `ServerRestartGame()`
`void` | `ServerSetHandedness(float hand)`
    // ------------------------------------------------------------------------
`void` | `SetFOV(float NewFOV)`
`void` | `SetFOVAngle(float newFOV)`
`void` | `SetHand()`
`bool` | `SetPause(BOOL bPause)`
    /* SetPause()
     Try to pause game; returns success indicator.
     Replicated to server in network games.
     */
`void` | `SetViewTarget(Actor NewViewTarget)`
`void` | `ShakeView(float shaketime, float RollMag, vector OffsetMag, float RollRate, vector OffsetRate, float OffsetTime)`
    /* ShakeView()
    Call this function to shake the player's view
    shaketime = how long to roll view
    RollMag = how far to roll view as it shakes
    OffsetMag = max view offset
    RollRate = how fast to roll view
    OffsetRate = how fast to offset view
    OffsetTime = how long to offset view (number of shakes)
    */
`void` | `ShortClientAdjustPosition(float TimeStamp, name newState, EPhysics newPhysics, float NewLocX, float NewLocY, float NewLocZ, Actor NewBase)`
    /* ShortClientAdjustPosition
    bandwidth saving version, when velocity is zeroed
    */
`void` | `ShortServerMove(float TimeStamp, vector ClientLoc, bool NewbRun, bool NewbDuck, bool NewbJumpStatus, byte ClientRoll, int View)`
    /* ShortServerMove()
    compressed version of server move for bandwidth saving
    */
`void` | `SpawnDefaultHUD()`
    /* SpawnDefaultHUD()
    Spawn a HUD (make sure that PlayerController always has valid HUD, even if \
    ClientSetHUD() hasn't been called\
    */
`void` | `Speech(int Type, int Index, int Callsign)`
    // Send a voice message of a certain type to a certain player.
`void` | `StartZoom()`
`void` | `StopZoom()`
`void` | `Suicide()`
`void` | `SwitchLevel(string URL)`
`void` | `SwitchTeam()`
`void` | `SwitchWeapon(byte F)`
    // The player wants to switch to weapon group number F.
`void` | `TeamSay(string Msg)`
`void` | `ThrowWeapon()`
    /* ThrowWeapon()
    Throw out current weapon, and switch to a new weapon
    */
`void` | `ToggleZoom()`
    // ------------------------------------------------------------------------
    // Zooming/FOV change functions
`void` | `TurnAround()`
`bool` | `TurnTowardNearestEnemy()`
`void` | `Typing(bool bTyping)`
`void` | `UnPossess()`
    // unpossessed a pawn (not because pawn was killed)
`void` | `UpdateBob(float F)`
`void` | `UpdateRotation(float DeltaTime, float maxPitch)`
`void` | `UpdateURL(string NewOption, string NewValue, bool bSaveDefault)`
`void` | `Use()`
    // The player wants to use something in the level.
`void` | `VeryShortClientAdjustPosition(float TimeStamp, float NewLocX, float NewLocY, float NewLocZ, Actor NewBase)`
    /* VeryShortClientAdjustPosition
    bandwidth saving version, when velocity is zeroed, and pawn is walking
    */
`void` | `ViewFlash(float DeltaTime)`
    {
    	local vector goalFog;
    	local float goalscale, delta;

    	delta = FMin(0.1, DeltaTime);
    	goalScale = 1 + DesiredFlashScale + ConstantGlowScale;
    	goalFog = DesiredFlashFog + ConstantGlowFog;

    	if ( Pawn != None )
    	{
    		goalScale += Pawn.HeadVolume.ViewFlash.X;
    		goalFog += Pawn.HeadVolume.ViewFog;
    	}

    	DesiredFlashScale -= DesiredFlashScale * 2 * delta;
    	DesiredFlashFog -= DesiredFlashFog * 2 * delta;
    	FlashScale.X += (goalScale - FlashScale.X + InstantFlash) * 10 * delta;
    	FlashFog += (goalFog - FlashFog + InstantFog) * 10 * delta;
    	InstantFlash = 0;
    	InstantFog = vect(0,0,0);

    	if ( FlashScale.X > 0.981 )
    		FlashScale.X = 1;
    	FlashScale = FlashScale.X * vect(1,1,1);

    	if ( FlashFog.X < 0.019 )
    		FlashFog.X = 0;
    	if ( FlashFog.Y < 0.019 )
    		FlashFog.Y = 0;
    	if ( FlashFog.Z < 0.019 )
    		FlashFog.Z = 0;
    }*/
`void` | `ViewFlash(float DeltaTime)`
    {
    	local vector goalFog;
    	local float goalscale, delta;

    	delta = FMin(0.1, DeltaTime);
    	goalScale = 1 + DesiredFlashScale + ConstantGlowScale;
    	goalFog = DesiredFlashFog + ConstantGlowFog;

    	if ( Pawn != None )
    	{
    		goalScale += Pawn.HeadVolume.ViewFlash.X;
    		goalFog += Pawn.HeadVolume.ViewFog;
    	}

    	DesiredFlashScale -= DesiredFlashScale * 2 * delta;
    	DesiredFlashFog -= DesiredFlashFog * 2 * delta;
    	FlashScale.X += (goalScale - FlashScale.X + InstantFlash) * 10 * delta;
    	FlashFog += (goalFog - FlashFog + InstantFog) * 10 * delta;
    	InstantFlash = 0;
    	InstantFog = vect(0,0,0);

    	if ( FlashScale.X > 0.981 )
    		FlashScale.X = 1;
    	FlashScale = FlashScale.X * vect(1,1,1);

    	if ( FlashFog.X < 0.019 )
    		FlashFog.X = 0;
    	if ( FlashFog.Y < 0.019 )
    		FlashFog.Y = 0;
    	if ( FlashFog.Z < 0.019 )
    		FlashFog.Z = 0;
    }*/
`void` | `ViewShake(float DeltaTime)`
    // modify shake offset
    		ShakeOffset.X += DeltaTime * ShakeOffsetRate.X;
    		CheckShake(MaxShakeOffset.X, ShakeOffset.X, ShakeOffsetRate.X, ShakeOffsetTime.X);

    		ShakeOffset.Y += DeltaTime * ShakeOffsetRate.Y;
    		CheckShake(MaxShakeOffset.Y, ShakeOffset.Y, ShakeOffsetRate.Y, ShakeOffsetTime.Y);

    		ShakeOffset.Z += DeltaTime * ShakeOffsetRate.Z;
    		CheckShake(MaxShakeOffset.Z, ShakeOffset.Z, ShakeOffsetRate.Z, ShakeOffsetTime.Z);
    	}

    	ViewRotation = Rotation;

    	if ( ShakeRollRate != 0 )
    	{
    		ViewRotation.Roll = ((ViewRotation.Roll & 65535) + ShakeRollRate * DeltaTime) & 65535;
    		if ( ViewRotation.Roll > 32768 )
    			ViewRotation.Roll -= 65536;
    		FRoll = ViewRotation.Roll;
    		CheckShake(MaxShakeRoll, FRoll, ShakeRollRate, ShakeRollTime);
    		ViewRotation.Roll = FRoll;
    	}
    	else if ( bZeroRoll )
    		ViewRotation.Roll = 0;
    	SetRotation(ViewRotation);
    }*/
`void` | `ViewShake(float DeltaTime)`
    // modify shake offset
    		ShakeOffset.X += DeltaTime * ShakeOffsetRate.X;
    		CheckShake(MaxShakeOffset.X, ShakeOffset.X, ShakeOffsetRate.X, ShakeOffsetTime.X);

    		ShakeOffset.Y += DeltaTime * ShakeOffsetRate.Y;
    		CheckShake(MaxShakeOffset.Y, ShakeOffset.Y, ShakeOffsetRate.Y, ShakeOffsetTime.Y);

    		ShakeOffset.Z += DeltaTime * ShakeOffsetRate.Z;
    		CheckShake(MaxShakeOffset.Z, ShakeOffset.Z, ShakeOffsetRate.Z, ShakeOffsetTime.Z);
    	}

    	ViewRotation = Rotation;

    	if ( ShakeRollRate != 0 )
    	{
    		ViewRotation.Roll = ((ViewRotation.Roll & 65535) + ShakeRollRate * DeltaTime) & 65535;
    		if ( ViewRotation.Roll > 32768 )
    			ViewRotation.Roll -= 65536;
    		FRoll = ViewRotation.Roll;
    		CheckShake(MaxShakeRoll, FRoll, ShakeRollRate, ShakeRollTime);
    		ViewRotation.Roll = FRoll;
    	}
    	else if ( bZeroRoll )
    		ViewRotation.Roll = 0;
    	SetRotation(ViewRotation);
    }*/
`vector` | `WeaponBob(float BobDamping)`
    /* --> Become a 100% C++ virtual function
`void` | `damageAttitudeTo(Pawn Other, float Damage)`

State Dead Function Summary
`void` | `ChangeAlwaysMouseLook(Bool B)`
`void` | `ChangeStairLook(bool B)`
    //------------------------------------------------------------------------------
    // Control options
`void` | `SetNGSecret(string newSecret)`
`string` | `GetNGSecret()`
    //------------------------------------------------------------------------------
    // ngStats Accessors
`void` | `EndState()`
`void` | `BeginState()`
`void` | `Timer2()`
`void` | `Timer()`
`void` | `FindGoodView()`
`void` | `PlayerMove(float DeltaTime)`
`void` | `ServerMove(float TimeStamp, vector Accel, vector ClientLoc, bool NewbRun, bool NewbDuck, bool NewbJumpStatus, eDoubleClickDir DoubleClickMove, byte ClientRoll, int View, optional byte, optional int)`
`void` | `AltFire(optional float)`
`void` | `Fire(optional float)`
`void` | `ServerRestartPlayer()`

State GameEnded Function Summary
`void` | `BeginState()`
`void` | `Timer()`
`void` | `FindGoodView()`
`void` | `ServerMove(float TimeStamp, vector InAccel, vector ClientLoc, bool NewbRun, bool NewbDuck, bool NewbJumpStatus, eDoubleClickDir DoubleClickMove, byte ClientRoll, int View, optional byte, optional int)`
`void` | `PlayerMove(float DeltaTime)`
`void` | `AltFire(optional float)`
`void` | `Fire(optional float)`
`void` | `ServerReStartGame()`
`void` | `ThrowWeapon()`

State WaitingForPawn Function Summary
`void` | `EndState()`
`void` | `BeginState()`
`void` | `Timer()`
`void` | `PlayerTick(float DeltaTime)`
`void` | `LongClientAdjustPosition(float TimeStamp, Name newState, EPhysics newPhysics, float NewLocX, float NewLocY, float NewLocZ, float NewVelX, float NewVelY, float NewVelZ, Actor NewBase, float NewFloorX, float NewFloorY, float NewFloorZ)`
`void` | `AltFire(optional float)`
`void` | `Fire(optional float)`

State Player Function Summary
`void` | `UnFire(optional float)`
        {
          if (!Player.LocalInteractions[0].IsInState('UWindows'))
            ServerReStartPlayer();
        }
        exec
`void` | `Fire(optional float)`
    ="$player);
        }
        exec

State Player Function Summary
`void` | `BeginState()`
    ="$player);
        }

State PlayerWaiting Function Summary
`void` | `EndState()`
    {

State PlayerWaiting Function Summary
`void` | `BeginState()`
`void` | `EndState()`
`void` | `AltFire(optional float)`
`void` | `Fire(optional float)`
`void` | `ServerReStartPlayer()`
`void` | `ChangeTeam(int N)`
`void` | `Suicide()`
`void` | `Jump(optional float)`
`void` | `PlayerMove(float DeltaTime)`
`void` | `ProcessMove(float DeltaTime, vector NewAccel, eDoubleClickDir DoubleClickMove, rotator DeltaRot)`

State Spectating Function Summary
`void` | `EndState()`
`void` | `BeginState()`
`void` | `AltFire(optional float)`
    // Return to spectator's own camera.
`void` | `Fire(optional float)`
`void` | `PrevWeapon()`
`void` | `NextWeapon()`

State BaseSpectating Function Summary
`void` | `PlayerMove(float DeltaTime)`
`void` | `ProcessMove(float DeltaTime, vector NewAccel, eDoubleClickDir DoubleClickMove, rotator DeltaRot)`

State PlayerHelicoptering Function Summary
`void` | `PlayerMove(float DeltaTime)`

State PlayerFlying Function Summary
`void` | `BeginState()`
`void` | `PlayerMove(float DeltaTime)`

State PlayerSwimming Function Summary
`void` | `BeginState()`
`void` | `Timer()`
`void` | `PlayerMove(float DeltaTime)`
`void` | `ProcessMove(float DeltaTime, vector NewAccel, eDoubleClickDir DoubleClickMove, rotator DeltaRot)`
`bool` | `NotifyPhysicsVolumeChange(PhysicsVolume NewVolume)`
`bool` | `NotifyLanded(vector HitNormal)`
`bool` | `WantsSmoothedView()`

State PlayerSpidering Function Summary
`void` | `EndState()`
`void` | `BeginState()`
`void` | `PlayerMove(float DeltaTime)`
`void` | `ProcessMove(float DeltaTime, vector NewAccel, eDoubleClickDir DoubleClickMove, rotator DeltaRot)`
`bool` | `NotifyPhysicsVolumeChange(PhysicsVolume NewVolume)`
`bool` | `NotifyLanded(vector HitNormal)`
`void` | `UpdateRotation(float DeltaTime, float maxPitch)`
    // if spider mode, update rotation based on floor

State PlayerClimbing Function Summary
`void` | `EndState()`
`void` | `BeginState()`
`void` | `PlayerMove(float DeltaTime)`
`void` | `ProcessMove(float DeltaTime, vector NewAccel, eDoubleClickDir DoubleClickMove, rotator DeltaRot)`
`bool` | `NotifyPhysicsVolumeChange(PhysicsVolume NewVolume)`

State PlayerWalking Function Summary
`void` | `EndState()`
`void` | `BeginState()`
`void` | `PlayerMove(float DeltaTime)`
`void` | `ProcessMove(float DeltaTime, vector NewAccel, eDoubleClickDir DoubleClickMove, rotator DeltaRot)`
`bool` | `NotifyPhysicsVolumeChange(PhysicsVolume NewVolume)`

Source Code

    00001	//=============================================================================
    00002	// PlayerController
    00003	//
    00004	// PlayerControllers are used by human players to control pawns.
    00005	//
    00006	// This is a built-in Unreal class and it shouldn't be modified.
    00007	// CHANGENOTE: All Changes since v739 in this class are related to the Weapon code update, except
    00008	// for the change in Possess().
    00009	//=============================================================================
    00010	class PlayerController extends Controller
    00011	  config(user)
    00012	  native
    00013	  nativereplication;
    00014
    00015	// Player info.
    00016	var const player Player;
    00017
    00018	// player input control
    00019	var globalconfig bool bLookUpStairs;  // look up/down stairs (player)
    00020	var globalconfig bool bSnapToLevel;   // Snap to level eyeheight when not mouselooking
    00021	var globalconfig bool bAlwaysMouseLook;
    00022	var globalconfig bool bKeyboardLook;  // no snapping when true
    00023	var bool bCenterView;
    00024
    00025	// Player control flags
    00026	var bool bBehindView;                 // Outside-the-player view.
    00027	var bool bFrozen;                     // set when game ends or player dies to temporarily prevent player from restarting (until cleared by timer)
    00028	var bool bPressedJump;
    00029	var bool bUpdatePosition;
    00030	var bool bIsTyping;
    00031	var bool bFixedCamera;                // used to fix camera in position (to view animations)
    00032	var bool bJumpStatus;                 // used in net games
    00033	var bool bUpdating;
    00034	var globalconfig bool bNeverSwitchOnPickup;  // if true, don't automatically switch to picked up weapon
    00035
    00036	var bool bZooming;
    00037	var bool bOnlySpectator;              // This controller is not allowed to possess pawns
    00038
    00039	var globalconfig bool bAlwaysLevel;
    00040	var bool bSetTurnRot;
    00041	var bool bCheatFlying;                // instantly stop in flying mode
    00042	var bool bFreeCamera;                 // free camera when in behindview mode (for checking out player models and animations)
    00043	var bool bZeroRoll;
    00044
    00045	// XIII Added
    00046	//var config bool bAltDuckMode;         // True = Crouch toggle, False = Crouch on/off
    00047	var bool bLocked;                     // adjustaim locked someone (to handle transitions between crosshair pos
    00048
    00049	var bool bDontUseVolumeFog;
    00050	var bool bIsInMenu;
    00051
    00052	var globalconfig bool bAutoPickup;    // AutoPickup objects.
    00053	var globalconfig int iAutoAimMode;    // 0 = off, 1 = on.
    00054
    00055	// XIIIUNUSED var float AimingHelp;
    00056	var float WaitDelay;                  // Delay time until can restart
    00057
    00058	var input float
    00059	  aBaseX, aBaseY, aBaseZ,  aMouseX, aMouseY,
    00060	  aForward, aTurn, aStrafe, aUp, aLookUp;
    00061
    00062	var input byte
    00063	  bStrafe, bSnapLevel, bLook, bFreeLook, bTurn180, bTurnToNearest;
    00064
    00065	// XIII Additional inputs
    00066	var input byte bUp, bDown, bLeft, bRight;   // check if KEYs are pressed and not pad.
    00067	var input byte b90Left, b90Right, b180Turn; // To make us turn fast to left or right.
    00068	var input byte bAltDuck;                    // To enable the AltDuck Mode
    00069	var input byte bAltJump;                    // To be used for Hook Mode using Duck/Jump
    00070	var input byte bAltRun;                     //
    00071	var globalconfig bool bInverseLook;   // Inverse FlightSim/Std Pad look axis
    00072	var globalconfig bool bWalkCenterView;// auto center view afer walking a while
    00073	//var float Ym,Lm,Sm,Tm;  // DBUG used to check max value of inputs
    00074	enum eConfigType
    00075	{
    00076	  CT_StrafeLookSameAxis,
    00077	  CT_StrafeLookNotSameAxis,
    00078	};
    00079	var config eConfigType ConfigType;
    00080	var config float fLookSpeed;
    00081	var config bool bUseRumble;
    00082	var config int UserPadConfig;
    00083	//
    00084	var EDoubleClickDir DoubleClickDir;   // direction of movement key double click (for special moves)
    00085
    00086	// Camera info.
    00087	var int ShowFlags;
    00088	var int Misc1,Misc2;
    00089	var int RendMap;
    00090	var float OrthoZoom;                  // Orthogonal/map view zoom factor.
    00091	var const actor ViewTarget;
    00092	var float CameraDist;                 // multiplier for behindview camera dist
    00093
    00094	var float DesiredFOV;
    00095	var globalconfig float DefaultFOV;
    00096	var float ZoomLevel;
    00097
    00098	// Screen flashes
    00099	var vector FlashScale, FlashFog;
    00100	var float DesiredFlashScale, ConstantGlowScale, InstantFlash;
    00101	var vector DesiredFlashFog, ConstantGlowFog, InstantFog;
    00102
    00103	// Filter.
    00104	var color FilterColor;
    00105	var color FilterColorWanted;
    00106	var float FilterColorSpeed;
    00107	var int FilterInternalInc;
    00108
    00109	// Remote Pawn ViewTargets
    00110	var rotator TargetViewRotation;
    00111	var float TargetEyeHeight;
    00112	var vector TargetWeaponViewOffset;
    00113
    00114	var HUD myHUD;  // heads up display info
    00115
    00116	var float LastPlaySound;
    00117	var globalconfig int AnnouncerVolume;
    00118
    00119	// Move buffering for network games.  Clients save their un-acknowledged moves in order to replay them
    00120	// when they get position updates from the server.
    00121	var SavedMove SavedMoves;  // buffered moves pending position updates
    00122	var SavedMove FreeMoves;  // freed moves, available for buffering
    00123	var SavedMove PendingMove;
    00124	var float CurrentTimeStamp,LastUpdateTime,ServerTimeStamp,TimeMargin, ClientUpdateTime;
    00125	var globalconfig float MaxTimeMargin;
    00126	var Weapon OldClientWeapon;
    00127	var int WeaponUpdate;
    00128
    00129	// Progess Indicator - used by the engine to provide status messages (HUD is responsible for displaying these).
    00130	var string ProgressMessage[4];
    00131	var color ProgressColor[4];
    00132	var float ProgressTimeOut;
    00133
    00134	// Localized strings
    00135	var localized string QuickSaveString;
    00136	var localized string NoPauseMessage;
    00137	var localized string ViewingFrom;
    00138	var localized string OwnCamera;
    00139
    00140	// ReplicationInfo
    00141	var GameReplicationInfo GameReplicationInfo;
    00142
    00143	// ngWorldStats Logging
    00144	var globalconfig private string ngWorldSecret;
    00145	var globalconfig bool ngSecretSet;
    00146	var bool ReceivedSecretChecksum;
    00147	var PlayerStats PlayerStat;   // Used to store everything that should be usefull for on-line ladder/rankings
    00148	                              // Server side only (no replication).
    00149
    00150	var class<LocalMessage> LocalMessageClass;
    00151
    00152	var globalconfig float Bob;
    00153	var float LandBob, AppliedBob;
    00154	var float bobtime;
    00155	var vector WalkBob;
    00156
    00157	// view shaking (affects roll, and offsets camera position)
    00158	var float MaxShakeRoll; // max magnitude to roll camera
    00159	var vector MaxShakeOffset; // max magnitude to offset camera position
    00160	var float ShakeRollRate;  // rate to change roll
    00161	var vector ShakeOffsetRate;
    00162	var vector ShakeOffset; //current magnitude to offset camera from shake
    00163	var float ShakeRollTime; // how long to roll.  if value is < 1.0, then MaxShakeOffset gets damped by this, else if > 1 then its the number of times to repeat undamped
    00164	var vector ShakeOffsetTime;
    00165	/* iKi=> */
    00166	var vector MaxShakeFrame, ShakeFrame, ShakeFrameRate;
    00167	var float ShakeFrameTime;
    00168	/* <=iKi */
    00169
    00170	var Pawn TurnTarget;
    00171	var config int EnemyTurnSpeed;
    00172	var int GroundPitch;
    00173	var rotator TurnRot180;
    00174
    00175	var vector OldFloor;    // used by PlayerSpider mode - floor for which old rotation was based;
    00176
    00177	// Components ( inner classes )
    00178	var CheatManager  CheatManager;  // Object within playercontroller that manages "cheat" commands
    00179	var class<CheatManager> CheatClass;    // class of my CheatManager
    00180	var transient PlayerInput PlayerInput;  // Object within playercontroller that manages player input.
    00181	var class<PlayerInput> InputClass;    // class of my PlayerInput
    00182
    00183	// Demo recording view rotation
    00184	var int DemoViewPitch;
    00185	var int DemoViewYaw;
    00186
    00187	// Use alpha filter.
    00188	var byte UseVignetteFilter;
    00189	// Use highlight filter.
    00190	var byte UseVignetteHighlight;
    00191	// Alpha filter color.
    00192	var color VignetteColor;
    00193	// Highlight intensity.
    00194	var float VignetteHighLight;
    00195	// Alpha filter texture.
    00196	var material VignetteMaterial;
    00197
    00198	var vector OldAdjustAim;          // Used to smooth autoaim, Aim to use when firing non-projectiles
    00199	var vector ViewAdjustAim;         // Used to smooth Weapon rot on screen
    00200	//var float LastOldAdjustAimUpdate; // to update it only once per frame (if called by interaction and weapon at the same frame don't update twice)
    00201	var float fAdjustAimTrans;        // to handle crosshair/Adjust aim transition
    00202	var vector MemAim;                // memorize aim when switching bLocked
    00203	var vector AdjustedAimForFiring;  // Aim to use when firing Projectiles (because display don't show anticipation
    00204	var actor BestTarget;             // to memorize the best target and use it in interaction
    00205	var actor OldBestTarget;          // to memorize the best target and use it in interaction
    00206
    00207	var float DeltaT;                 // to enable using it anywhere (needed for death camera sfxs  at least)
    00208
    00209	replication
    00210	{
    00211		// Things the server should send to the client.
    00212		reliable if( bNetDirty && bNetOwner && Role==ROLE_Authority )
    00213
ViewTarget, GameReplicationInfo; 00214 unreliable if ( bNetOwner && Role==ROLE_Authority && (ViewTarget != Pawn) && (Pawn(ViewTarget) != None) ) 00215 TargetViewRotation, TargetEyeHeight, TargetWeaponViewOffset; 00216 reliable if( bDemoRecording && Role==ROLE_Authority ) 00217 DemoViewPitch, DemoViewYaw; 00218 00219 // Functions server can call. 00220 reliable if( Role==ROLE_Authority ) 00221 ClientSetHUD,ClientReliablePlaySound, FOV, StartZoom, 00222 ToggleZoom, StopZoom, EndZoom, ClientRestart, 00223 ClientReplicateSkins, ClientAdjustGlow, 00224 ClientSetBehindView, ClientSetFixedCamera, ClearProgressMessages, 00225 SetProgressMessage, SetProgressTime, 00226 GivePawn, ClientGotoState; 00227 reliable if ( (Role == ROLE_Authority) && (!bDemoRecording || (bClientDemoRecording && bClientDemoNetFunc)) ) 00228 ClientMessage, TeamMessage, ReceiveLocalizedMessage; 00229 unreliable if( Role==ROLE_Authority && !bDemoRecording ) 00230 ClientPlaySound; 00231 reliable if( Role==ROLE_Authority && !bDemoRecording ) 00232 ClientTravel; 00233 unreliable if( Role==ROLE_Authority ) 00234 SetFOVAngle, ClientShake, ClientFlash, ClientInstantFlash, ClientFilter, ClientHighLight, 00235 ClientAdjustPosition, ShortClientAdjustPosition, VeryShortClientAdjustPosition, LongClientAdjustPosition; 00236 00237 // Functions client can call. 00238 unreliable if( Role<ROLE_Authority ) 00239 ShortServerMove, ServerMove, Say, TeamSay, ServerSetHandedness; 00240 reliable if( Role<ROLE_Authority ) 00241 Speech, Pause, SetPause, 00242 PrevItem, ActivateItem, ServerReStartGame, AskForPawn, 00243 ChangeName, ChangeTeam, Suicide, 00244 ThrowWeapon, BehindView, Typing; 00245 } 00246 00247 // Pad management 00248 native(538) static final function int GetPadNumber(); 00249 native(537) static final function AttribPadToViewport(); 00250 00251 // "Compile" the commands associated with each input key 00252 native(535) static final function OptimizeInputBindings(); 00253 00254 native(519) static final function string GetPlayerNetworkAddress(); 00255 native static function string ConsoleCommand( string Command ); 00256 native(515) static final function LevelInfo GetEntryLevel(); 00257 native(544) static final function ResetKeyboard(); 00258 native(513) static final function SetViewTarget(Actor NewViewTarget); 00259 native static function event ClientTravel( string URL, ETravelType TravelType, bool bItems ); 00260 native(546) static final function UpdateURL(string NewOption, string NewValue, bool bSaveDefault); 00261 native(510) static final function string GetDefaultURL(string Option); 00262 // Execute a console command in the context of this player, then forward to Actor.ConsoleCommand. 00263 native(507) static final function CopyToClipboard( string Text ); 00264 native(506) static final function string PasteFromClipboard(); 00265 00266 /* FindStairRotation() 00267 returns an integer to use as a pitch to orient player view along current ground (flat, up, or down) 00268 */ 00269 native(524) static final function int FindStairRotation(float DeltaTime); 00270 00271 event PostBeginPlay() 00272 { 00273 Super.PostBeginPlay(); 00274 SpawnDefaultHUD(); 00275 if (Level.LevelEnterText != "" ) 00276 ClientMessage(Level.LevelEnterText); 00277 00278 DesiredFOV = DefaultFOV; 00279 SetViewTarget(self); // MUST have a view target! 00280 if ( Level.NetMode == NM_Standalone ) 00281 CheatManager = new CheatClass; 00282 } 00283 00284 /* SpawnDefaultHUD() 00285 Spawn a HUD (make sure that PlayerController always has valid HUD, even if \ 00286 ClientSetHUD() hasn't been called\ 00287 */ 00288 function SpawnDefaultHUD() 00289 { 00290 myHUD = spawn(class'HUD',self); 00291 } 00292 00293 /* Reset() 00294 reset actor to initial state - used when restarting level without reloading. 00295 */ 00296 function Reset() 00297 { 00298 PawnDied(); 00299 Super.Reset(); 00300 SetViewTarget(self); 00301 bBehindView = false; 00302 WaitDelay = Level.TimeSeconds + 2; 00303 GotoState('PlayerWaiting'); 00304 } 00305 00306 /* InitInputSystem() 00307 Spawn the appropriate class of PlayerInput 00308 Only called for playercontrollers that belong to local players 00309 */ 00310 event InitInputSystem() 00311 { 00312 PlayerInput = new InputClass; 00313 } 00314 00315 /* ClientGotoState() 00316 server uses this to force client into NewState 00317 */ 00318 function ClientGotoState(name NewState, name NewLabel) 00319 { 00320 GotoState(NewState,NewLabel); 00321 } 00322 00323 function AskForPawn() 00324 { 00325 Log(self@"AskForPawn"@Pawn@"InState"@GetStateName()); 00326 if ( Pawn != None ) 00327 GivePawn(Pawn); 00328 else if ( IsInState('GameEnded') ) 00329 ClientGotoState('GameEnded', 'Begin'); 00330 else if ( IsInState('Dead') ) 00331 { 00332 bFrozen = false; 00333 ServerRestartPlayer(); 00334 } 00335 } 00336 00337 function GivePawn(Pawn NewPawn) 00338 { 00339 if ( NewPawn == None ) 00340 return; 00341 Pawn = NewPawn; 00342 NewPawn.Controller = self; 00343 ClientRestart(); 00344 } 00345 00346 /* GetFacingDirection() 00347 returns direction faced relative to movement dir 00348 0 = forward 00349 16384 = right 00350 32768 = back 00351 49152 = left 00352 */ 00353 function int GetFacingDirection() 00354 { 00355 local vector X,Y,Z, Dir; 00356 00357 GetAxes(Pawn.Rotation, X,Y,Z); 00358 Dir = Normal(Pawn.Acceleration); 00359 if ( Y Dot Dir > 0 ) 00360 return ( 49152 + 16384 * (X Dot Dir) ); 00361 else 00362 return ( 16384 - 16384 * (X Dot Dir) ); 00363 } 00364 00365 // Possess a pawn 00366 function Possess(Pawn aPawn) 00367 { 00368 if ( bOnlySpectator ) 00369 return; 00370 00371 SetRotation(aPawn.Rotation); 00372 aPawn.PossessedBy(self); 00373 Pawn = aPawn; 00374 Pawn.bStasis = false; 00375 PlayerReplicationInfo.bIsFemale = Pawn.bIsFemale; 00376 ServerSetHandedness(Handedness); 00377 Restart(); 00378 } 00379 00380 // unpossessed a pawn (not because pawn was killed) 00381 function UnPossess() 00382 { 00383 if ( Pawn != None ) 00384 { 00385 SetLocation(Pawn.Location); 00386 Pawn.RemoteRole = ROLE_SimulatedProxy; 00387 Pawn.UnPossessed(); 00388 if ( Viewtarget == Pawn ) 00389 SetViewTarget(self); 00390 } 00391 Pawn = None; 00392 GotoState('Spectating'); 00393 } 00394 00395 // unpossessed a pawn (because pawn was killed) 00396 function PawnDied() 00397 { 00398 StopZoom(); 00399 if ( Pawn != None ) 00400 Pawn.RemoteRole = ROLE_SimulatedProxy; 00401 if ( ViewTarget == Pawn ) 00402 bBehindView = true; 00403 00404 Super.PawnDied(); 00405 } 00406 00407 // called when kicked 00408 simulated event IAmKicked(); 00409 00410 00411 function ClientSetHUD(class<HUD> newHUDType, class<Scoreboard> newScoringType) 00412 { 00413 local HUD NewHUD; 00414 00415 if ( (myHUD == None) || ((newHUDType != None) && (newHUDType != myHUD.Class)) ) 00416 { 00417 NewHUD = spawn(newHUDType, self); 00418 if ( NewHUD != None ) 00419 { 00420 if ( myHUD != None ) 00421 myHUD.Destroy(); 00422 myHUD = NewHUD; 00423 } 00424 } 00425 if ( (myHUD != None) && (newScoringType != None) ) 00426 MyHUD.SpawnScoreBoard(newScoringType); 00427 } 00428 00429 function HandlePickup(Pickup pick) 00430 { 00431 ReceiveLocalizedMessage( pick.MessageClass, 0, None, None, pick.Class ); 00432 } 00433 00434 /*function ViewFlash(float DeltaTime) 00435 { 00436 local vector goalFog; 00437 local float goalscale, delta; 00438 00439 delta = FMin(0.1, DeltaTime); 00440 goalScale = 1 + DesiredFlashScale + ConstantGlowScale; 00441 goalFog = DesiredFlashFog + ConstantGlowFog; 00442 00443 if ( Pawn != None ) 00444 { 00445 goalScale += Pawn.HeadVolume.ViewFlash.X; 00446 goalFog += Pawn.HeadVolume.ViewFog; 00447 } 00448 00449 DesiredFlashScale -= DesiredFlashScale * 2 * delta; 00450 DesiredFlashFog -= DesiredFlashFog * 2 * delta; 00451 FlashScale.X += (goalScale - FlashScale.X + InstantFlash) * 10 * delta; 00452 FlashFog += (goalFog - FlashFog + InstantFog) * 10 * delta; 00453 InstantFlash = 0; 00454 InstantFog = vect(0,0,0); 00455 00456 if ( FlashScale.X > 0.981 ) 00457 FlashScale.X = 1; 00458 FlashScale = FlashScale.X * vect(1,1,1); 00459 00460 if ( FlashFog.X < 0.019 ) 00461 FlashFog.X = 0; 00462 if ( FlashFog.Y < 0.019 ) 00463 FlashFog.Y = 0; 00464 if ( FlashFog.Z < 0.019 ) 00465 FlashFog.Z = 0; 00466 }*/ 00467 native(505) static final function ViewFlash(float DeltaTime); 00468 00469 event ReceiveLocalizedMessage( class<LocalMessage> Message, optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2, optional Object OptionalObject ) 00470 { 00471 Message.Static.ClientReceive( Self, Switch, RelatedPRI_1, RelatedPRI_2, OptionalObject ); 00472 } 00473 00474 event ClientMessage( coerce string S, optional Name Type ) 00475 { 00476 if (Type == '') 00477 Type = 'Event'; 00478 TeamMessage(PlayerReplicationInfo, S, Type); 00479 } 00480 00481 event TeamMessage( PlayerReplicationInfo PRI, coerce string S, name Type ) 00482 { 00483 local string ConsoleString; 00484 00485 //log("Teammessage with PRI "$PRI$" hud "$myHud$" Player "$Player$" console "$Player.console$" string "$S); 00486 ConsoleString = S; 00487 if ( (Type == 'Say') || (Type == 'TeamSay') ) 00488 ConsoleString = PRI.PlayerName$": "$ConsoleString; 00489 00490 Player.Console.Message( ConsoleString, 6.0 ); 00491 myHUD.Message( PRI, S, Type ); 00492 } 00493 00494 simulated function PlayBeepSound(); 00495 00496 //Play a sound client side (so only client will hear it 00497 simulated function ClientPlaySound(sound ASound, optional bool bVolumeControl ) 00498 { 00499 local int i; 00500 00501 if ( !bVolumeControl ) 00502 ViewTarget.PlaySound(ASound); 00503 else 00504 for ( i=0; i<AnnouncerVolume; i++ ) 00505 ViewTarget.PlaySound(ASound); 00506 } 00507 00508 simulated function ClientReliablePlaySound(sound ASound, optional bool bVolumeControl ) 00509 { 00510 ClientPlaySound(ASound, bVolumeControl); 00511 } 00512 00513 simulated event Destroyed() 00514 { 00515 local SavedMove Next; 00516 00517 if ( Pawn != None ) 00518 { 00519 Pawn.Health = 0; 00520 Pawn.Died( self, class'Suicided', Pawn.Location ); 00521 } 00522 Super.Destroyed(); 00523 myHud.Destroy(); 00524 00525 while ( FreeMoves != None ) 00526 { 00527 Next = FreeMoves.NextMove; 00528 FreeMoves.Destroy(); 00529 FreeMoves = Next; 00530 } 00531 while ( SavedMoves != None ) 00532 { 00533 Next = SavedMoves.NextMove; 00534 SavedMoves.Destroy(); 00535 SavedMoves = Next; 00536 } 00537 } 00538 00539 // ------------------------------------------------------------------------ 00540 // Zooming/FOV change functions 00541 00542 function ToggleZoom() 00543 { 00544 if ( DefaultFOV != DesiredFOV ) 00545 EndZoom(); 00546 else 00547 StartZoom(); 00548 } 00549 00550 function StartZoom() 00551 { 00552 ZoomLevel = 0.0; 00553 bZooming = true; 00554 } 00555 00556 function StopZoom() 00557 { 00558 bZooming = false; 00559 } 00560 00561 function EndZoom() 00562 { 00563 bZooming = false; 00564 DesiredFOV = DefaultFOV; 00565 } 00566 00567 function FixFOV() 00568 { 00569 FOVAngle = Default.DefaultFOV; 00570 DesiredFOV = Default.DefaultFOV; 00571 DefaultFOV = Default.DefaultFOV; 00572 } 00573 00574 function SetFOV(float NewFOV) 00575 { 00576 DesiredFOV = NewFOV; 00577 FOVAngle = NewFOV; 00578 } 00579 00580 function ResetFOV() 00581 { 00582 DesiredFOV = DefaultFOV; 00583 FOVAngle = DefaultFOV; 00584 } 00585 00586 exec function FOV(float F) 00587 { 00588 if( (F >= 80.0) || (Level.Netmode==NM_Standalone) ) 00589 { 00590 DefaultFOV = FClamp(F, 1, 170); 00591 DesiredFOV = DefaultFOV; 00592 SaveConfig(); 00593 } 00594 } 00595 00596 exec function ForceReload() 00597 { 00598 if ( (Pawn != None) && (Pawn.Weapon != None) ) 00599 Pawn.Weapon.ForceReload(); 00600 } 00601 00602 // ------------------------------------------------------------------------ 00603 // Messaging functions 00604 00605 // Send a message to all players. 00606 exec function Say( string Msg ) 00607 { 00608 Level.Game.Broadcast(self, Msg, 'Say'); 00609 } 00610 00611 exec function TeamSay( string Msg ) 00612 { 00613 Level.Game.BroadcastTeam(self, Msg, 'Say'); 00614 } 00615 // ------------------------------------------------------------------------ 00616 00617 function ServerSetHandedness( float hand) 00618 { 00619 Handedness = hand; 00620 if ( Pawn.Weapon != None ) 00621 Pawn.Weapon.SetHand(Handedness); 00622 } 00623 00624 function SetHand() 00625 { 00626 Pawn.Weapon.SetHand(Handedness); 00627 ServerSetHandedness(Handedness); 00628 } 00629 00630 function ChangeSetHand( string S ) 00631 { 00632 if ( S ~= "Left" ) 00633 Handedness = -1; 00634 else if ( S~= "Right" ) 00635 Handedness = 1; 00636 else if ( S ~= "Center" ) 00637 Handedness = 0; 00638 else if ( S ~= "Hidden" ) 00639 Handedness = 2; 00640 SetHand(); 00641 } 00642 00643 event PreClientTravel() 00644 { 00645 } 00646 00647 function ClientSetFixedCamera(bool B) 00648 { 00649 bFixedCamera = B; 00650 } 00651 00652 function ClientSetBehindView(bool B) 00653 { 00654 bBehindView = B; 00655 } 00656 00657 function ClientReplicateSkins(Material Skin1, optional Material Skin2, optional Material Skin3, optional Material Skin4) 00658 { 00659 // do nothing (just loading other player skins onto client) 00660 log("Getting "$Skin1$", "$Skin2$", "$Skin3$", "$Skin4); 00661 return; 00662 } 00663 00664 /*function CheckBob(float DeltaTime, float Speed2D, vector Y) 00665 { 00666 if ( Speed2D < 10 ) 00667 BobTime += 0.2 * DeltaTime; 00668 else 00669 BobTime += DeltaTime * (0.3 + 0.7 * Speed2D/Pawn.GroundSpeed); 00670 WalkBob = Y * 0.4 * Bob * Speed2D * sin(8 * BobTime); 00671 AppliedBob = AppliedBob * (1 - FMin(1, 16 * deltatime)); 00672 if ( Speed2D < 10 ) 00673 WalkBob.Z = AppliedBob; 00674 else 00675 WalkBob.Z = AppliedBob + 0.3 * Bob * Speed2D * sin(16 * BobTime); 00676 if ( LandBob > 0.01 ) 00677 { 00678 AppliedBob += FMin(1, 16 * deltatime) * LandBob; 00679 LandBob *= (1 - 8*Deltatime); 00680 } 00681 }*/ 00682 native(504) static final function CheckBob(float DeltaTime, float Speed2D, vector Y); 00683 00684 00685 /* --> Become a 100% C++ virtual function 00686 function vector WeaponBob(float BobDamping) 00687 { 00688 Local Vector WBob; 00689 00690 WBob = BobDamping * WalkBob; 00691 WBob.Z = (0.45 + 0.55 * BobDamping) * WalkBob.Z; 00692 00693 return (WBob + 0.9 * ShakeOffset); 00694 }*/ 00695 00696 00697 function ClientVoiceMessage(PlayerReplicationInfo Sender, PlayerReplicationInfo Recipient, name messagetype, byte messageID) 00698 { 00699 local VoicePack V; 00700 00701 if ( (Sender == None) || (Sender.voicetype == None) || (Player.Console == None) ) 00702 return; 00703 00704 V = Spawn(Sender.voicetype, self); 00705 if ( V != None ) 00706 V.ClientInitialize(Sender, Recipient, messagetype, messageID); 00707 } 00708 00709 /* ForceDeathUpdate() 00710 Make sure ClientAdjustPosition immediately informs client of pawn's death 00711 */ 00712 function ForceDeathUpdate() 00713 { 00714 LastUpdateTime = Level.TimeSeconds - 10; 00715 } 00716 00717 /* ShortServerMove() 00718 compressed version of server move for bandwidth saving 00719 */ 00720 function ShortServerMove 00721 ( 00722 float TimeStamp, 00723 vector ClientLoc, 00724 bool NewbRun, 00725 bool NewbDuck, 00726 bool NewbJumpStatus, 00727 byte ClientRoll, 00728 int View 00729 ) 00730 { 00731 ServerMove(TimeStamp,vect(0,0,0),ClientLoc,NewbRun,NewbDuck,NewbJumpStatus,DCLICK_None,ClientRoll,View); 00732 } 00733 00734 /* ServerMove() 00735 - replicated function sent by client to server - contains client movement and firing info 00736 Passes acceleration in components so it doesn't get rounded. 00737 */ 00738 function ServerMove 00739 ( 00740 float TimeStamp, 00741 vector InAccel, 00742 vector ClientLoc, 00743 bool NewbRun, 00744 bool NewbDuck, 00745 bool NewbJumpStatus, 00746 eDoubleClickDir DoubleClickMove, 00747 byte ClientRoll, 00748 int View, 00749 optional byte OldTimeDelta, 00750 optional int OldAccel 00751 ) 00752 { 00753 local float DeltaTime, clientErr, OldTimeStamp; 00754 local rotator DeltaRot, Rot, ViewRot; 00755 local vector Accel, LocDiff, ClientVel, ClientFloor; 00756 local int maxPitch, ViewPitch, ViewYaw; 00757 local bool NewbPressedJump, OldbRun, OldbDuck; 00758 local eDoubleClickDir OldDoubleClickMove; 00759 local actor ClientBase; 00760 local ePhysics ClientPhysics; 00761 00762 // If this move is outdated, discard it. 00763 if ( CurrentTimeStamp >= TimeStamp ) 00764 return; 00765 00766 // if OldTimeDelta corresponds to a lost packet, process it first 00767 if ( OldTimeDelta != 0 ) 00768 { 00769 OldTimeStamp = TimeStamp - float(OldTimeDelta)/500 - 0.001; 00770 if ( CurrentTimeStamp < OldTimeStamp - 0.001 ) 00771 { 00772 // split out components of lost move (approx) 00773 Accel.X = OldAccel >>> 23; 00774 if ( Accel.X > 127 ) 00775 Accel.X = -1 * (Accel.X - 128); 00776 Accel.Y = (OldAccel >>> 15) & 255; 00777 if ( Accel.Y > 127 ) 00778 Accel.Y = -1 * (Accel.Y - 128); 00779 Accel.Z = (OldAccel >>> 7) & 255; 00780 if ( Accel.Z > 127 ) 00781 Accel.Z = -1 * (Accel.Z - 128); 00782 Accel *= 20; 00783 00784 OldbRun = ( (OldAccel & 64) != 0 ); 00785 OldbDuck = ( (OldAccel & 32) != 0 ); 00786 NewbPressedJump = ( (OldAccel & 16) != 0 ); 00787 if ( NewbPressedJump ) 00788 bJumpStatus = NewbJumpStatus; 00789 00790 switch (OldAccel & 7) 00791 { 00792 case 0: 00793 OldDoubleClickMove = DCLICK_None; 00794 break; 00795 case 1: 00796 OldDoubleClickMove = DCLICK_Left; 00797 break; 00798 case 2: 00799 OldDoubleClickMove = DCLICK_Right; 00800 break; 00801 case 3: 00802 OldDoubleClickMove = DCLICK_Forward; 00803 break; 00804 case 4: 00805 OldDoubleClickMove = DCLICK_Back; 00806 break; 00807 } 00808 //log("Recovered move from "$OldTimeStamp$" acceleration "$Accel$" from "$OldAccel); 00809 MoveAutonomous(OldTimeStamp - CurrentTimeStamp, OldbRun, OldbDuck, NewbPressedJump, OldDoubleClickMove, Accel, rot(0,0,0)); 00810 CurrentTimeStamp = OldTimeStamp; 00811 } 00812 } 00813 00814 // View components 00815 ViewPitch = View/32768; 00816 ViewYaw = 2 * (View - 32768 * ViewPitch); 00817 ViewPitch *= 2; 00818 // Make acceleration. 00819 Accel = InAccel/10; 00820 00821 NewbPressedJump = (bJumpStatus != NewbJumpStatus); 00822 bJumpStatus = NewbJumpStatus; 00823 00824 // Save move parameters. 00825 DeltaTime = TimeStamp - CurrentTimeStamp; 00826 if ( ServerTimeStamp > 0 ) 00827 { 00828 // allow 1% error 00829 TimeMargin += DeltaTime - 1.01 * (Level.TimeSeconds - ServerTimeStamp); 00830 if ( TimeMargin > MaxTimeMargin ) 00831 { 00832 // player is too far ahead 00833 TimeMargin -= DeltaTime; 00834 if ( TimeMargin < 0.5 ) 00835 MaxTimeMargin = Default.MaxTimeMargin; 00836 else 00837 MaxTimeMargin = 0.5; 00838 DeltaTime = 0; 00839 } 00840 } 00841 00842 CurrentTimeStamp = TimeStamp; 00843 ServerTimeStamp = Level.TimeSeconds; 00844 ViewRot.Pitch = ViewPitch; 00845 ViewRot.Yaw = ViewYaw; 00846 ViewRot.Roll = 0; 00847 SetRotation(ViewRot); 00848 00849 if ( Pawn != None ) 00850 { 00851 Rot.Roll = 256 * ClientRoll; 00852 Rot.Yaw = ViewYaw; 00853 if ( (Pawn.Physics == PHYS_Swimming) || (Pawn.Physics == PHYS_Flying) ) 00854 maxPitch = 2; 00855 else 00856 maxPitch = 1; 00857 If ( (ViewPitch > maxPitch * RotationRate.Pitch) && (ViewPitch < 65536 - maxPitch * RotationRate.Pitch) ) 00858 { 00859 If (ViewPitch < 32768) 00860 Rot.Pitch = maxPitch * RotationRate.Pitch; 00861 else 00862 Rot.Pitch = 65536 - maxPitch * RotationRate.Pitch; 00863 } 00864 else 00865 Rot.Pitch = ViewPitch; 00866 DeltaRot = (Rotation - Rot); 00867 Pawn.SetRotation(Rot); 00868 if ( Pawn.ControllerPitch != Rotation.Pitch / 256 ) // test to avoid bNetDirtied by useless change 00869 Pawn.ControllerPitch = ViewPitch / 256; 00870 // Log("Setting Pawn.controllerPitch="$Pawn.ControllerPitch); 00871 } 00872 00873 // Perform actual movement. 00874 if ( (Level.Pauser == None) && (DeltaTime > 0) ) 00875 MoveAutonomous(DeltaTime, NewbRun, NewbDuck, NewbPressedJump, DoubleClickMove, Accel, DeltaRot); 00876 00877 // Accumulate movement error. 00878 if ( Level.TimeSeconds - LastUpdateTime > 0.3 ) 00879 ClientErr = 10000; 00880 else if ( Level.TimeSeconds - LastUpdateTime > 180.0/Player.CurrentNetSpeed ) 00881 { 00882 if ( Pawn == None ) 00883 LocDiff = Location - ClientLoc; 00884 else 00885 LocDiff = Pawn.Location - ClientLoc; 00886 ClientErr = LocDiff Dot LocDiff; 00887 } 00888 00889 // If client has accumulated a noticeable positional error, correct him. 00890 if ( ClientErr > 3 ) 00891 { 00892 if ( Pawn == None ) 00893 { 00894 ClientPhysics = Physics; 00895 ClientLoc = Location; 00896 ClientVel = Velocity; 00897 } 00898 else 00899 { 00900 ClientPhysics = Pawn.Physics; 00901 ClientVel = Pawn.Velocity; 00902 ClientBase = Pawn.Base; 00903 if ( Mover(Pawn.Base) != None ) 00904 ClientLoc = Pawn.Location - Pawn.Base.Location; 00905 else 00906 ClientLoc = Pawn.Location; 00907 ClientFloor = Pawn.Floor; 00908 } 00909 //log("Client Error at "$TimeStamp$" is "$ClientErr$" with acceleration "$Accel$" LocDiff "$LocDiff$" Physics "$Pawn.Physics); 00910 LastUpdateTime = Level.TimeSeconds; 00911 00912 if ( (Pawn == None) || (Pawn.Physics != PHYS_Spider) ) 00913 { 00914 if ( ClientVel == vect(0,0,0) ) 00915 { 00916 if ( IsInState('PlayerWalking') && (Pawn != None) && (Pawn.Physics == PHYS_Walking) ) 00917 { 00918 VeryShortClientAdjustPosition 00919 ( 00920 TimeStamp, 00921 ClientLoc.X, 00922 ClientLoc.Y, 00923 ClientLoc.Z, 00924 ClientBase 00925 ); 00926 } 00927 else 00928 ShortClientAdjustPosition 00929 ( 00930 TimeStamp, 00931 GetStateName(), 00932 ClientPhysics, 00933 ClientLoc.X, 00934 ClientLoc.Y, 00935 ClientLoc.Z, 00936 ClientBase 00937 ); 00938 } 00939 else 00940 ClientAdjustPosition 00941 ( 00942 TimeStamp, 00943 GetStateName(), 00944 ClientPhysics, 00945 ClientLoc.X, 00946 ClientLoc.Y, 00947 ClientLoc.Z, 00948 ClientVel.X, 00949 ClientVel.Y, 00950 ClientVel.Z, 00951 ClientBase 00952 ); 00953 } 00954 else 00955 LongClientAdjustPosition 00956 ( 00957 TimeStamp, 00958 GetStateName(), 00959 ClientPhysics, 00960 ClientLoc.X, 00961 ClientLoc.Y, 00962 ClientLoc.Z, 00963 ClientVel.X, 00964 ClientVel.Y, 00965 ClientVel.Z, 00966 ClientBase, 00967 ClientFloor.X, 00968 ClientFloor.Y, 00969 ClientFloor.Z 00970 ); 00971 } 00972 //log("Server moved stamp "$TimeStamp$" location "$Pawn.Location$" Acceleration "$Pawn.Acceleration$" Velocity "$Pawn.Velocity); 00973 00974 /* To track down some multiplayer problems... 00975 //debuglog("In ServerMove()"); 00976 //DumpContent(TimeStamp, 2); 00977 DumpChosenContent(TimeStamp); 00978 */ 00979 } 00980 00981 function ProcessMove ( float DeltaTime, vector newAccel, eDoubleClickDir DoubleClickMove, rotator DeltaRot) 00982 { 00983 if ( Pawn != None ) 00984 Pawn.Acceleration = newAccel; 00985 } 00986 00987 final function MoveAutonomous 00988 ( 00989 float DeltaTime, 00990 bool NewbRun, 00991 bool NewbDuck, 00992 bool NewbPressedJump, 00993 eDoubleClickDir DoubleClickMove, 00994 vector newAccel, 00995 rotator DeltaRot 00996 ) 00997 { 00998 if ( NewbRun ) 00999 bRun = 1; 01000 else 01001 bRun = 0; 01002 01003 if ( NewbDuck ) 01004 bDuck = 1; 01005 else 01006 bDuck = 0; 01007 bPressedJump = NewbPressedJump; 01008 01009 HandleWalking(); 01010 ProcessMove(DeltaTime, newAccel, DoubleClickMove, DeltaRot); 01011 if ( Pawn != None ) 01012 Pawn.AutonomousPhysics(DeltaTime); 01013 else 01014 AutonomousPhysics(DeltaTime); 01015 //log("Role "$Role$" moveauto time "$100 * DeltaTime$" ("$Level.TimeDilation$")"); 01016 } 01017 01018 /* VeryShortClientAdjustPosition 01019 bandwidth saving version, when velocity is zeroed, and pawn is walking 01020 */ 01021 function VeryShortClientAdjustPosition 01022 ( 01023 float TimeStamp, 01024 float NewLocX, 01025 float NewLocY, 01026 float NewLocZ, 01027 Actor NewBase 01028 ) 01029 { 01030 local vector Floor; 01031 01032 if ( Pawn != None ) 01033 Floor = Pawn.Floor; 01034 LongClientAdjustPosition(TimeStamp,'PlayerWalking',PHYS_Walking,NewLocX,NewLocY,NewLocZ,0,0,0,NewBase,Floor.X,Floor.Y,Floor.Z); 01035 } 01036 01037 /* ShortClientAdjustPosition 01038 bandwidth saving version, when velocity is zeroed 01039 */ 01040 function ShortClientAdjustPosition 01041 ( 01042 float TimeStamp, 01043 name newState, 01044 EPhysics newPhysics, 01045 float NewLocX, 01046 float NewLocY, 01047 float NewLocZ, 01048 Actor NewBase 01049 ) 01050 { 01051 local vector Floor; 01052 01053 if ( Pawn != None ) 01054 Floor = Pawn.Floor; 01055 LongClientAdjustPosition(TimeStamp,newState,newPhysics,NewLocX,NewLocY,NewLocZ,0,0,0,NewBase,Floor.X,Floor.Y,Floor.Z); 01056 } 01057 01058 /* ClientAdjustPosition 01059 - pass newloc and newvel in components so they don't get rounded 01060 */ 01061 function ClientAdjustPosition 01062 ( 01063 float TimeStamp, 01064 name newState, 01065 EPhysics newPhysics, 01066 float NewLocX, 01067 float NewLocY, 01068 float NewLocZ, 01069 float NewVelX, 01070 float NewVelY, 01071 float NewVelZ, 01072 Actor NewBase 01073 ) 01074 { 01075 local vector Floor; 01076 01077 if ( Pawn != None ) 01078 Floor = Pawn.Floor; 01079 LongClientAdjustPosition(TimeStamp,newState,newPhysics,NewLocX,NewLocY,NewLocZ,NewVelX,NewVelY,NewVelZ,NewBase,Floor.X,Floor.Y,Floor.Z); 01080 } 01081 01082 /* LongClientAdjustPosition 01083 long version, when care about pawn's floor normal 01084 */ 01085 function LongClientAdjustPosition 01086 ( 01087 float TimeStamp, 01088 name newState, 01089 EPhysics newPhysics, 01090 float NewLocX, 01091 float NewLocY, 01092 float NewLocZ, 01093 float NewVelX, 01094 float NewVelY, 01095 float NewVelZ, 01096 Actor NewBase, 01097 float NewFloorX, 01098 float NewFloorY, 01099 float NewFloorZ 01100 ) 01101 { 01102 local vector NewLocation, NewFloor; 01103 local Actor MoveActor; 01104 01105 if ( Pawn != None ) 01106 { 01107 if ( Pawn.bTearOff ) 01108 { 01109 Pawn = None; 01110 GotoState('Dead'); 01111 return; 01112 } 01113 MoveActor = Pawn; 01114 } 01115 else 01116 MoveActor = self; 01117 01118 if ( CurrentTimeStamp > TimeStamp ) 01119 return; 01120 CurrentTimeStamp = TimeStamp; 01121 01122 NewLocation.X = NewLocX; 01123 NewLocation.Y = NewLocY; 01124 NewLocation.Z = NewLocZ; 01125 MoveActor.Velocity.X = NewVelX; 01126 MoveActor.Velocity.Y = NewVelY; 01127 MoveActor.Velocity.Z = NewVelZ; 01128 01129 NewFloor.X = NewFloorX; 01130 NewFloor.Y = NewFloorY; 01131 NewFloor.Z = NewFloorZ; 01132 MoveActor.SetBase(NewBase, NewFloor); 01133 if ( Mover(NewBase) != None ) 01134 NewLocation += NewBase.Location; 01135 01136 //log("Client "$Role$" adjust "$self$" stamp "$TimeStamp$" location "$MoveActor.Location); 01137 MoveActor.bCanTeleport = false; 01138 MoveActor.SetLocation(NewLocation); 01139 MoveActor.bCanTeleport = true; 01140 MoveActor.SetPhysics(newPhysics); 01141 01142 if( GetStateName() != newstate ) 01143 GotoState(newstate); 01144 01145 bUpdatePosition = true; 01146 01147 /* To track down some multiplayer problems... 01148 //debuglog("In LongClientAdjustPosition():"); 01149 //DumpContent(TimeStamp, 2); 01150 DumpChosenContent(TimeStamp); 01151 */ 01152 } 01153 01154 function ClientUpdatePosition() 01155 { 01156 local SavedMove CurrentMove; 01157 local int realbRun, realbDuck; 01158 local bool bRealJump; 01159 local float TotalTime; 01160 01161 bUpdatePosition = false; 01162 realbRun= bRun; 01163 realbDuck = bDuck; 01164 bRealJump = bPressedJump; 01165 CurrentMove = SavedMoves; 01166 bUpdating = true; 01167 while ( CurrentMove != None ) 01168 { 01169 if ( CurrentMove.TimeStamp <= CurrentTimeStamp ) 01170 { 01171 SavedMoves = CurrentMove.NextMove; 01172 CurrentMove.NextMove = FreeMoves; 01173 FreeMoves = CurrentMove; 01174 FreeMoves.Clear(); 01175 CurrentMove = SavedMoves; 01176 } 01177 else 01178 { 01179 if ( (TotalTime > 0) && (Pawn != None) ) 01180 AdjustRadius(CurrentMove.Delta * Pawn.GroundSpeed); 01181 TotalTime += CurrentMove.Delta; 01182 MoveAutonomous(CurrentMove.Delta, CurrentMove.bRun, CurrentMove.bDuck, CurrentMove.bPressedJump, CurrentMove.DoubleClickMove, CurrentMove.Acceleration, rot(0,0,0)); 01183 CurrentMove = CurrentMove.NextMove; 01184 } 01185 } 01186 //log("Client updated position to "$Pawn.Location); 01187 bUpdating = false; 01188 bDuck = realbDuck; 01189 bRun = realbRun; 01190 bPressedJump = bRealJump; 01191 } 01192 01193 function AdjustRadius(float MaxMove) 01194 { 01195 local Pawn P; 01196 local vector Dir; 01197 01198 // if other pawn moving away from player, push it away if its close 01199 // since the client-side position is behind the server side position 01200 ForEach DynamicActors(class'Pawn', P) 01201 if ( (P != Pawn) && (P.Velocity != vect(0,0,0)) && P.bBlockPlayers ) 01202 { 01203 Dir = Normal(P.Location - Pawn.Location); 01204 if ( (Pawn.Velocity Dot Dir > 0) && (P.Velocity Dot Dir > 0) ) 01205 { 01206 if ( VSize(P.Location - Pawn.Location) < P.CollisionRadius + Pawn.CollisionRadius + MaxMove ) 01207 P.MoveSmooth(P.Velocity * 0.5 * PlayerReplicationInfo.Ping); 01208 } 01209 } 01210 } 01211 01212 final function SavedMove GetFreeMove() 01213 { 01214 local SavedMove s, first; 01215 local int i; 01216 01217 if ( FreeMoves == None ) 01218 { 01219 // don't allow more than 30 saved moves 01220 For ( s=SavedMoves; s!=None; s=s.NextMove ) 01221 { 01222 i++; 01223 if ( i > 30 ) 01224 { 01225 first = SavedMoves; 01226 SavedMoves = SavedMoves.NextMove; 01227 first.Clear(); 01228 first.NextMove = None; 01229 // clear out all the moves 01230 While ( SavedMoves != None ) 01231 { 01232 s = SavedMoves; 01233 SavedMoves = SavedMoves.NextMove; 01234 s.Clear(); 01235 s.NextMove = FreeMoves; 01236 FreeMoves = s; 01237 } 01238 return first; 01239 } 01240 } 01241 return Spawn(class'SavedMove'); 01242 } 01243 else 01244 { 01245 s = FreeMoves; 01246 FreeMoves = FreeMoves.NextMove; 01247 s.NextMove = None; 01248 return s; 01249 } 01250 } 01251 01252 function int CompressAccel(int C) 01253 { 01254 if ( C >= 0 ) 01255 C = Min(C, 127); 01256 else 01257 C = Min(abs(C), 127) + 128; 01258 return C; 01259 } 01260 01261 /* 01262 ======================================================================== 01263 Here's how player movement prediction, replication and correction works in network games: 01264 01265 Every tick, the PlayerTick() function is called. It calls the PlayerMove() function (which is implemented 01266 in various states). PlayerMove() figures out the acceleration and rotation, and then calls ProcessMove() 01267 (for single player or listen servers), or ReplicateMove() (if its a network client). 01268 01269 ReplicateMove() saves the move (in the PendingMove list), calls ProcessMove(), and then replicates the move 01270 to the server by calling the replicated function ServerMove() - passing the movement parameters, the client's 01271 resultant position, and a timestamp. 01272 01273 ServerMove() is executed on the server. It decodes the movement parameters and causes the appropriate movement 01274 to occur. It then looks at the resulting position and if enough time has passed since the last response, or the 01275 position error is significant enough, the server calls ClientAdjustPosition(), a replicated function. 01276 01277 ClientAdjustPosition() is executed on the client. The client sets its position to the servers version of position, 01278 and sets the bUpdatePosition flag to true. 01279 01280 When PlayerTick() is called on the client again, if bUpdatePosition is true, the client will call 01281 ClientUpdatePosition() before calling PlayerMove(). ClientUpdatePosition() replays all the moves in the pending 01282 move list which occured after the timestamp of the move the server was adjusting. 01283 */ 01284 01285 // 01286 // Replicate this client's desired movement to the server. 01287 // 01288 function ReplicateMove 01289 ( 01290 float DeltaTime, 01291 vector NewAccel, 01292 eDoubleClickDir DoubleClickMove, 01293 rotator DeltaRot 01294 ) 01295 { 01296 local SavedMove NewMove, OldMove, LastMove; 01297 local byte ClientRoll; 01298 local float OldTimeDelta, NetMoveDelta; 01299 local int i, OldAccel; 01300 local vector BuildAccel, AccelNorm, MoveLoc; 01301 01302 // Get a SavedMove actor to store the movement in. 01303 if ( PendingMove != None ) 01304 PendingMove.SetMoveFor(self, DeltaTime, NewAccel, DoubleClickMove); 01305 01306 if ( SavedMoves != None ) 01307 { 01308 NewMove = SavedMoves; 01309 AccelNorm = Normal(NewAccel); 01310 while ( NewMove.NextMove != None ) 01311 { 01312 // find most recent interesting move to send redundantly 01313 if ( NewMove.bPressedJump || ((NewMove.DoubleClickMove != DCLICK_NONE) && (NewMove.DoubleClickMove < 5)) 01314 || ((NewMove.Acceleration != NewAccel) && ((normal(NewMove.Acceleration) Dot AccelNorm) < 0.95)) ) 01315 OldMove = NewMove; 01316 NewMove = NewMove.NextMove; 01317 } 01318 if ( NewMove.bPressedJump || ((NewMove.DoubleClickMove != DCLICK_NONE) && (NewMove.DoubleClickMove < 5)) 01319 || ((NewMove.Acceleration != NewAccel) && ((normal(NewMove.Acceleration) Dot AccelNorm) < 0.95)) ) 01320 OldMove = NewMove; 01321 } 01322 01323 LastMove = NewMove; 01324 NewMove = GetFreeMove(); 01325 if ( NewMove == None ) 01326 return; 01327 NewMove.SetMoveFor(self, DeltaTime, NewAccel, DoubleClickMove); 01328 01329 // adjust radius of nearby players with uncertain location 01330 if ( Pawn != None ) 01331 AdjustRadius(NewMove.Delta * Pawn.GroundSpeed); 01332 01333 // Simulate the movement locally. 01334 ProcessMove(NewMove.Delta, NewMove.Acceleration, NewMove.DoubleClickMove, DeltaRot); 01335 if ( Pawn != None ) 01336 Pawn.AutonomousPhysics(NewMove.Delta); 01337 else 01338 AutonomousPhysics(DeltaTime); 01339 01340 //log("Role "$Role$" repmove at "$Level.TimeSeconds$" Move time "$100 * DeltaTime$" ("$Level.TimeDilation$")"); 01341 01342 // Decide whether to hold off on move 01343 // send if double click move, jump, or fire unless really too soon, or if newmove.delta big enough 01344 // on client side, save extra buffered time in LastUpdateTime 01345 if ( PendingMove == None ) 01346 PendingMove = NewMove; 01347 else 01348 { 01349 NewMove.NextMove = FreeMoves; 01350 FreeMoves = NewMove; 01351 FreeMoves.Clear(); 01352 NewMove = PendingMove; 01353 } 01354 NetMoveDelta = FMax(64.0/Player.CurrentNetSpeed, 0.011); 01355 01356 if ( !PendingMove.bPressedJump && (PendingMove.Delta < NetMoveDelta - ClientUpdateTime) ) 01357 { 01358 // save as pending move 01359 return; 01360 } 01361 else if ( (ClientUpdateTime < 0) && (PendingMove.Delta < NetMoveDelta - ClientUpdateTime) ) 01362 return; 01363 else 01364 { 01365 ClientUpdateTime = PendingMove.Delta - NetMoveDelta; 01366 if ( SavedMoves == None ) 01367 SavedMoves = PendingMove; 01368 else 01369 LastMove.NextMove = PendingMove; 01370 PendingMove = None; 01371 } 01372 01373 // check if need to redundantly send previous move 01374 if ( OldMove != None ) 01375 { 01376 // log("Redundant send timestamp "$OldMove.TimeStamp$" accel "$OldMove.Acceleration$" at "$Level.Timeseconds$" New accel "$NewAccel); 01377 // old move important to replicate redundantly 01378 OldTimeDelta = FMin(255, (Level.TimeSeconds - OldMove.TimeStamp) * 500); 01379 BuildAccel = 0.05 * OldMove.Acceleration + vect(0.5, 0.5, 0.5); 01380 OldAccel = (CompressAccel(BuildAccel.X) << 23) 01381 + (CompressAccel(BuildAccel.Y) << 15) 01382 + (CompressAccel(BuildAccel.Z) << 7); 01383 if ( OldMove.bRun ) 01384 OldAccel += 64; 01385 if ( OldMove.bDuck ) 01386 OldAccel += 32; 01387 if ( OldMove.bPressedJump ) 01388 OldAccel += 16; 01389 OldAccel += OldMove.DoubleClickMove; 01390 } 01391 //else 01392 // log("No redundant timestamp at "$Level.TimeSeconds$" with accel "$NewAccel); 01393 //log("Replicate move at "$NewMove.TimeStamp$" location "$Pawn.Location); 01394 // Send to the server 01395 ClientRoll = (Rotation.Roll >> 8) & 255; 01396 if ( NewMove.bPressedJump ) 01397 bJumpStatus = !bJumpStatus; 01398 01399 if ( Pawn == None ) 01400 MoveLoc = Location; 01401 else 01402 MoveLoc = Pawn.Location; 01403 01404 if ( (NewMove.Acceleration == vect(0,0,0)) && (NewMove.DoubleClickMove == DCLICK_None) ) 01405 ShortServerMove 01406 ( 01407 NewMove.TimeStamp, 01408 MoveLoc, 01409 NewMove.bRun, 01410 NewMove.bDuck, 01411 bJumpStatus, 01412 ClientRoll, 01413 (32767 & (Rotation.Pitch/2)) * 32768 + (32767 & (Rotation.Yaw/2)) 01414 ); 01415 else 01416 ServerMove 01417 ( 01418 NewMove.TimeStamp, 01419 NewMove.Acceleration * 10, 01420 MoveLoc, 01421 NewMove.bRun, 01422 NewMove.bDuck, 01423 bJumpStatus, 01424 NewMove.DoubleClickMove, 01425 ClientRoll, 01426 (32767 & (Rotation.Pitch/2)) * 32768 + (32767 & (Rotation.Yaw/2)), 01427 OldTimeDelta, 01428 OldAccel 01429 ); 01430 } 01431 01432 /*function HandleWalking() 01433 { 01434 if ( Pawn != None ) 01435 Pawn.SetWalking(((bRun != 0) || (bDuck != 0)) && !Region.Zone.IsA('WarpZoneInfo')); 01436 }*/ 01437 native(499) static final function HandleWalking(); 01438 01439 function ServerRestartGame() 01440 { 01441 } 01442 01443 function SetFOVAngle(float newFOV) 01444 { 01445 FOVAngle = newFOV; 01446 } 01447 01448 function ClientFlash( float scale, vector fog ) 01449 { 01450 DesiredFlashScale = scale; 01451 DesiredFlashFog = 0.001 * fog; 01452 } 01453 01454 function ClientInstantFlash( float scale, vector fog ) 01455 { 01456 InstantFlash = scale; 01457 InstantFog = 0.001 * fog; 01458 } 01459 01460 function ClientAdjustGlow( float scale, vector fog ) 01461 { 01462 ConstantGlowScale = scale; 01463 ConstantGlowFog = 0.001 * fog; 01464 } 01465 01466 function ClientFilter( Color FC, color FCW, float FCS ) 01467 { 01468 FilterColor = FC; 01469 FilterColorWanted = FCW; 01470 FilterColorSpeed = FCS; 01471 } 01472 01473 function ClientHighLight( color TargetColor, float TargetHighLight, optional Material Mat ) 01474 { 01475 /* 01476 var byte UseVignetteFilter; 01477 var byte UseVignetteHighlight; 01478 var color VignetteColor; 01479 var float VignetteHighLight; 01480 var material VignetteMaterial; 01481 */ 01482 if (TargetHighLight != 0) 01483 { 01484 UseVignetteFilter = 1; 01485 UseVignetteHighlight = 1; 01486 VignetteColor = TargetColor; 01487 VignetteHighLight = TargetHighLight; 01488 VignetteMaterial = Mat; 01489 } 01490 else 01491 { 01492 UseVignetteFilter = 0; 01493 UseVignetteHighlight = 0; 01494 } 01495 } 01496 01497 /* ClientShake() 01498 Function called on client to shake view. 01499 Only ShakeView() should call ClientShake() 01500 */ 01501 private function ClientShake(vector ShakeRoll, vector OffsetMag, vector ShakeRate, float OffsetTime) 01502 { 01503 if ( (MaxShakeRoll < ShakeRoll.X) || (ShakeRollTime < 0.01 * ShakeRoll.Y) ) 01504 { 01505 MaxShakeRoll = ShakeRoll.X; 01506 ShakeRollTime = 0.01 * ShakeRoll.Y; 01507 ShakeRollRate = 0.01 * ShakeRoll.Z; 01508 } 01509 if ( VSize(OffsetMag) > VSize(MaxShakeOffset) ) 01510 { 01511 ShakeOffsetTime = OffsetTime * vect(1,1,1); 01512 MaxShakeOffset = OffsetMag; 01513 ShakeOffsetRate = ShakeRate; 01514 } 01515 // if (MaxShakeFrame < ShakeFrameMag) 01516 // { 01517 /* MaxShakeFrame.X = 0.08; 01518 MaxShakeFrame.Y = 0.06; 01519 ShakeFrameTime = 10; 01520 ShakeFrameRate.X = 0.4; 01521 ShakeFrameRate.Y = 0.25;*/ 01522 // } 01523 01524 } 01525 01526 01527 /* ShakeView() 01528 Call this function to shake the player's view 01529 shaketime = how long to roll view 01530 RollMag = how far to roll view as it shakes 01531 OffsetMag = max view offset 01532 RollRate = how fast to roll view 01533 OffsetRate = how fast to offset view 01534 OffsetTime = how long to offset view (number of shakes) 01535 */ 01536 function ShakeView( float shaketime, float RollMag, vector OffsetMag, float RollRate, vector OffsetRate, float OffsetTime) 01537 { 01538 local vector ShakeRoll; 01539 01540 ShakeRoll.X = RollMag; 01541 ShakeRoll.Y = 100 * shaketime; 01542 ShakeRoll.Z = 100 * rollrate; 01543 ClientShake(ShakeRoll, OffsetMag, OffsetRate, OffsetTime); 01544 } 01545 01546 function damageAttitudeTo(pawn Other, float Damage) 01547 { 01548 if ( (Other != None) && (Other != Pawn) && (Damage > 0) ) 01549 Enemy = Other; 01550 } 01551 01552 function Typing( bool bTyping ) 01553 { 01554 bIsTyping = bTyping; 01555 if ( bTyping && (Pawn != None) && !Pawn.bTearOff ) 01556 Pawn.ChangeAnimation(); 01557 01558 if (Level.Game.StatLog != None) 01559 Level.Game.StatLog.LogTypingEvent(bTyping, Self); 01560 } 01561 01562 //************************************************************************************* 01563 // Normal gameplay execs 01564 // Type the name of the exec function at the console to execute it 01565 01566 exec function Jump( optional float F ) 01567 { 01568 if ( Level.Pauser == PlayerReplicationInfo ) 01569 SetPause(False); 01570 else 01571 bPressedJump = true; 01572 } 01573 01574 // Send a voice message of a certain type to a certain player. 01575 exec function Speech( int Type, int Index, int Callsign ) 01576 { 01577 local VoicePack V; 01578 01579 V = Spawn( PlayerReplicationInfo.VoiceType, Self ); 01580 if (V != None) 01581 V.PlayerSpeech( Type, Index, Callsign ); 01582 } 01583 01584 exec function RestartLevel() 01585 { 01586 if( Level.Netmode==NM_Standalone ) 01587 ClientTravel( "?restart", TRAVEL_Relative, false ); 01588 } 01589 01590 exec function LocalTravel( string URL ) 01591 { 01592 if( Level.Netmode==NM_Standalone ) 01593 ClientTravel( URL, TRAVEL_Relative, true ); 01594 } 01595 01596 // ------------------------------------------------------------------------ 01597 // Loading and saving 01598 01599 /* QuickSave() 01600 Save game to slot 9 01601 */ 01602 exec function QuickSave() 01603 { 01604 if ( (Pawn.Health > 0) 01605 && (Level.NetMode == NM_Standalone) ) 01606 { 01607 ClientMessage(QuickSaveString); 01608 ConsoleCommand("SaveGame 9"); 01609 } 01610 } 01611 01612 /* QuickLoad() 01613 Load game from slot 9 01614 */ 01615 exec function QuickLoad() 01616 { 01617 if ( Level.NetMode == NM_Standalone ) 01618 ClientTravel( "?load=9", TRAVEL_Absolute, false); 01619 } 01620 01621 /* SetPause() 01622 Try to pause game; returns success indicator. 01623 Replicated to server in network games. 01624 */ 01625 function bool SetPause( BOOL bPause ) 01626 { 01627 local bool ret; 01628 01629 if( bPause ) 01630 ret = Level.Game.SetPause(True, self); 01631 else 01632 ret = Level.Game.SetPause(False, self); 01633 return ret; 01634 } 01635 01636 /* Pause() 01637 Command to try to pause the game. 01638 */ 01639 exec function Pause() 01640 { 01641 if( !SetPause(Level.Pauser==None) ) 01642 ClientMessage(NoPauseMessage); 01643 } 01644 01645 // Activate specific inventory item 01646 exec function ActivateInventoryItem( class InvItem ) 01647 { 01648 local Powerups Inv; 01649 01650 Inv = Powerups(Pawn.FindInventoryType(InvItem)); 01651 if ( Inv != None ) 01652 Inv.Activate(); 01653 } 01654 01655 // ------------------------------------------------------------------------ 01656 // Weapon changing functions 01657 01658 /* ThrowWeapon() 01659 Throw out current weapon, and switch to a new weapon 01660 */ 01661 exec function ThrowWeapon() 01662 { 01663 if( Level.NetMode == NM_Client ) 01664 return; 01665 if( Pawn.Weapon==None || !Pawn.Weapon.bCanThrow ) 01666 return; 01667 Pawn.Weapon.bTossedOut = true; 01668 Pawn.TossWeapon(Vector(Rotation) * 500 + vect(0,0,220)); 01669 if ( Pawn.Weapon == None ) 01670 SwitchToBestWeapon(); 01671 } 01672 01673 /* PrevWeapon() 01674 - switch to previous inventory group weapon 01675 */ 01676 exec function PrevWeapon() 01677 { 01678 if( Level.Pauser!=None ) 01679 return; 01680 if ( Pawn.Weapon == None ) 01681 { 01682 SwitchToBestWeapon(); 01683 return; 01684 } 01685 if ( Pawn.PendingWeapon != None ) 01686 Pawn.PendingWeapon = Pawn.Inventory.PrevWeapon(None, Pawn.PendingWeapon); 01687 else 01688 Pawn.PendingWeapon = Pawn.Inventory.PrevWeapon(None, Pawn.Weapon); 01689 01690 if ( Pawn.PendingWeapon != None ) 01691 Pawn.Weapon.PutDown(); 01692 } 01693 01694 /* NextWeapon() 01695 - switch to next inventory group weapon 01696 */ 01697 exec function NextWeapon() 01698 { 01699 if( Level.Pauser!=None ) 01700 return; 01701 if ( Pawn.Weapon == None ) 01702 { 01703 SwitchToBestWeapon(); 01704 return; 01705 } 01706 if ( Pawn.PendingWeapon != None ) 01707 Pawn.PendingWeapon = Pawn.Inventory.NextWeapon(None, Pawn.PendingWeapon); 01708 else 01709 Pawn.PendingWeapon = Pawn.Inventory.NextWeapon(None, Pawn.Weapon); 01710 01711 if ( Pawn.PendingWeapon != None ) 01712 Pawn.Weapon.PutDown(); 01713 } 01714 01715 // The player wants to switch to weapon group number F. 01716 exec function SwitchWeapon (byte F ) 01717 { 01718 local weapon newWeapon; 01719 01720 if ( (Level.Pauser!=None) || (Pawn == None) || (Pawn.Inventory == None) ) 01721 return; 01722 if ( (Pawn.Weapon != None) && (Pawn.Weapon.Inventory != None) ) 01723 newWeapon = Pawn.Weapon.Inventory.WeaponChange(F); 01724 else 01725 newWeapon = None; 01726 if ( newWeapon == None ) 01727 newWeapon = Pawn.Inventory.WeaponChange(F); 01728 01729 if ( newWeapon == None ) 01730 return; 01731 01732 if ( Pawn.Weapon == None ) 01733 { 01734 Pawn.PendingWeapon = newWeapon; 01735 Pawn.ChangedWeapon(); 01736 } 01737 else if ( Pawn.Weapon != newWeapon ) 01738 { 01739 Pawn.PendingWeapon = newWeapon; 01740 if ( !Pawn.Weapon.PutDown() ) 01741 Pawn.PendingWeapon = None; 01742 } 01743 } 01744 01745 exec function GetWeapon(class<Weapon> NewWeaponClass ) 01746 { 01747 local Inventory Inv; 01748 01749 if ( (Pawn.Inventory == None) || (NewWeaponClass == None) 01750 || ((Pawn.Weapon != None) && (Pawn.Weapon.Class == NewWeaponClass)) ) 01751 return; 01752 01753 for ( Inv=Pawn.Inventory; Inv!=None; Inv=Inv.Inventory ) 01754 if ( Inv.Class == NewWeaponClass ) 01755 { 01756 Pawn.PendingWeapon = Weapon(Inv); 01757 if ( !Pawn.PendingWeapon.HasAmmo() ) 01758 { 01759 ClientMessage( Pawn.PendingWeapon.ItemName$Pawn.PendingWeapon.MessageNoAmmo ); 01760 Pawn.PendingWeapon = None; 01761 return; 01762 } 01763 Pawn.Weapon.PutDown(); 01764 return; 01765 } 01766 } 01767 01768 // The player wants to select previous item 01769 exec function PrevItem() 01770 { 01771 local Inventory Inv; 01772 local Powerups LastItem; 01773 01774 if ( Level.Pauser!=None ) 01775 return; 01776 if (Pawn.SelectedItem==None) 01777 { 01778 Pawn.SelectedItem = Inventory.SelectNext(); 01779 Return; 01780 } 01781 if (Pawn.SelectedItem.Inventory!=None) 01782 for( Inv=Pawn.SelectedItem.Inventory; Inv!=None; Inv=Inv.Inventory ) 01783 { 01784 if (Inv==None) Break; 01785 if ( Inv.IsA('Powerups') && Powerups(Inv).bActivatable) LastItem=Powerups(Inv); 01786 } 01787 for( Inv=Pawn.Inventory; Inv!=Pawn.SelectedItem; Inv=Inv.Inventory ) 01788 { 01789 if (Inv==None) Break; 01790 if ( Inv.IsA('Powerups') && Powerups(Inv).bActivatable) LastItem=Powerups(Inv); 01791 } 01792 if (LastItem!=None) 01793 Pawn.SelectedItem = LastItem; 01794 } 01795 01796 // The player wants to active selected item 01797 exec function ActivateItem() 01798 { 01799 if( Level.Pauser!=None ) 01800 return; 01801 if ( (Pawn != None) && (Pawn.SelectedItem!=None) ) 01802 Pawn.SelectedItem.Activate(); 01803 } 01804 01805 // The player wants to fire. 01806 exec function Fire( optional float F ) 01807 { 01808 if ( Level.Pauser == PlayerReplicationInfo ) 01809 { 01810 SetPause(false); 01811 return; 01812 } 01813 if( Pawn.Weapon!=None ) 01814 Pawn.Weapon.Fire(F); 01815 } 01816 01817 // The player wants to alternate-fire. 01818 exec function AltFire( optional float F ) 01819 { 01820 if ( Level.Pauser == PlayerReplicationInfo ) 01821 { 01822 SetPause(false); 01823 return; 01824 } 01825 if( Pawn.Weapon!=None ) 01826 Pawn.Weapon.AltFire(F); 01827 } 01828 01829 // The player wants to use something in the level. 01830 exec function Use() 01831 { 01832 local Actor A; 01833 01834 if ( Level.Pauser == PlayerReplicationInfo ) 01835 { 01836 SetPause(false); 01837 return; 01838 } 01839 01840 // Send the 'DoUse' event to each actor player is touching. 01841 ForEach Pawn.TouchingActors(class'Actor', A) 01842 { 01843 A.UsedBy(Pawn); 01844 } 01845 } 01846 01847 exec function Suicide() 01848 { 01849 Pawn.KilledBy( Pawn ); 01850 } 01851 01852 function Name( coerce string S ) 01853 { 01854 S = Left(S,15); 01855 01856 ChangeName(S); 01857 UpdateURL("Name", S, true); 01858 SaveConfig(); 01859 } 01860 01861 function ChangeName( coerce string S ) 01862 { 01863 if ( Len(S) > 28 ) 01864 S = left(S,28); 01865 ReplaceText(S, " ", "_"); 01866 Level.Game.ChangeName( self, S, false ); 01867 } 01868 01869 exec function SwitchTeam() 01870 { 01871 if ( (PlayerReplicationInfo.Team == None) || (PlayerReplicationInfo.Team.TeamIndex == 1) ) 01872 ChangeTeam(0); 01873 else 01874 ChangeTeam(1); 01875 } 01876 01877 function ChangeTeam( int N ) 01878 { 01879 local TeamInfo OldTeam; 01880 01881 OldTeam = PlayerReplicationInfo.Team; 01882 Level.Game.ChangeTeam(self, N); 01883 if ( Level.Game.bTeamGame && (PlayerReplicationInfo.Team != OldTeam) ) 01884 Pawn.Died( self, class'DamageType', Pawn.Location ); 01885 } 01886 01887 01888 exec function SwitchLevel( string URL ) 01889 { 01890 if( Level.NetMode==NM_Standalone || Level.netMode==NM_ListenServer ) 01891 Level.ServerTravel( URL, false ); 01892 } 01893 01894 exec function ClearProgressMessages() 01895 { 01896 local int i; 01897 01898 for (i=0; i<ArrayCount(ProgressMessage); i++) 01899 { 01900 ProgressMessage[i] = ""; 01901 ProgressColor[i] = class'Canvas'.Static.MakeColor(255,255,255); 01902 } 01903 } 01904 01905 exec event SetProgressMessage( int Index, string S, color C ) 01906 { 01907 if ( Index < ArrayCount(ProgressMessage) ) 01908 { 01909 ProgressMessage[Index] = S; 01910 ProgressColor[Index] = C; 01911 } 01912 } 01913 01914 exec event SetProgressTime( float T ) 01915 { 01916 ProgressTimeOut = T + Level.TimeSeconds; 01917 } 01918 01919 function Restart() 01920 { 01921 ServerTimeStamp = 0; 01922 TimeMargin = 0; 01923 Enemy = None; 01924 EnterStartState(); 01925 SetViewTarget(Pawn); 01926 bBehindView = Pawn.PointOfView(); 01927 ClientRestart(); 01928 } 01929 01930 function EnterStartState() 01931 { 01932 local name NewState; 01933 01934 if ( Pawn.PhysicsVolume.bWaterVolume ) 01935 { 01936 if ( Pawn.HeadVolume.bWaterVolume ) 01937 Pawn.BreathTime = Pawn.UnderWaterTime; 01938 NewState = Pawn.WaterMovementState; 01939 } 01940 else 01941 NewState = Pawn.LandMovementState; 01942 01943 if ( IsInState(NewState) ) 01944 BeginState(); 01945 else 01946 GotoState(NewState); 01947 } 01948 01949 function ClientRestart() 01950 { 01951 /* 01952 if ( Pawn == None ) 01953 { 01954 GotoState('WaitingForPawn'); 01955 return; 01956 } 01957 Pawn.ClientRestart(); 01958 SetViewTarget(Pawn); 01959 bBehindView = Pawn.PointOfView(); 01960 EnterStartState(); 01961 */ 01962 } 01963 01964 exec function BehindView( Bool B ) 01965 { 01966 bBehindView = B; 01967 ClientSetBehindView(bBehindView); 01968 } 01969 01970 function UpdateBob(float F) 01971 { 01972 Bob = FClamp(F,0,0.032); 01973 } 01974 01975 01976 //============================================================================= 01977 // functions. 01978 01979 // Just changed to pendingWeapon 01980 function ChangedWeapon() 01981 { 01982 if ( Pawn.PendingWeapon != None ) 01983 Pawn.PendingWeapon.SetHand(Handedness); 01984 } 01985 01986 event TravelPostAccept() 01987 { 01988 if ( Pawn.Health <= 0 ) 01989 Pawn.Health = Pawn.Default.Health; 01990 } 01991 01992 event PlayerTick( float DeltaTime ) 01993 { 01994 if ( bUpdatePosition ) 01995 ClientUpdatePosition(); 01996 01997 PlayerMove(DeltaTime); 01998 } 01999 02000 function PlayerMove(float DeltaTime); 02001 02002 02003 // 02004 /* AdjustAim() 02005 Calls this version for player aiming help. 02006 Aimerror not used in this version. 02007 Only adjusts aiming at pawns 02008 */ 02009 function rotator AdjustAim(Ammunition FiredAmmunition, vector projStart, int aimerror); 02010 /* 02011 { 02012 local vector FireDir, AimSpot, HitNormal, HitLocation, OldAim, AimOffset; 02013 local actor BestTarget; 02014 local float bestAim, bestDist, projspeed; 02015 local actor HitActor; 02016 local bool bNoZAdjust, bLeading; 02017 local rotator AimRot; 02018 02019 FireDir = vector(Rotation); 02020 if ( FiredAmmunition.bInstantHit ) 02021 HitActor = Trace(HitLocation, HitNormal, projStart + 10000 * FireDir, projStart, true); 02022 else 02023 HitActor = Trace(HitLocation, HitNormal, projStart + 4000 * FireDir, projStart, true); 02024 if ( (HitActor != None) && HitActor.bProjTarget ) 02025 { 02026 FiredAmmunition.WarnTarget(Target,Pawn,FireDir); 02027 BestTarget = HitActor; 02028 bNoZAdjust = true; 02029 OldAim = HitLocation; 02030 BestDist = VSize(BestTarget.Location - Pawn.Location); 02031 } 02032 else 02033 { 02034 // adjust aim based on FOV 02035 bestAim = 0.95; 02036 if ( AimingHelp == 1 ) 02037 { 02038 bestAim = 0.93; 02039 if ( FiredAmmunition.bInstantHit ) 02040 bestAim = 0.97; 02041 if ( FOVAngle < DefaultFOV - 8 ) 02042 bestAim = 0.99; 02043 } 02044 else 02045 { 02046 if ( FiredAmmunition.bInstantHit ) 02047 bestAim = 0.98; 02048 if ( FOVAngle != DefaultFOV ) 02049 bestAim = 0.995; 02050 } 02051 BestTarget = PickTarget(bestAim, bestDist, FireDir, projStart); 02052 if ( BestTarget == None ) 02053 return Rotation; 02054 FiredAmmunition.WarnTarget(Target,Pawn,FireDir); 02055 OldAim = projStart + FireDir * bestDist; 02056 } 02057 if ( AimingHelp == 0 ) 02058 return Rotation; 02059 02060 // aim at target - help with leading also 02061 if ( !FiredAmmunition.bInstantHit ) 02062 { 02063 projspeed = FiredAmmunition.ProjectileClass.default.speed; 02064 BestDist = vsize(BestTarget.Location + BestTarget.Velocity * FMin(2, 0.02 + BestDist/projSpeed) - projStart); 02065 bLeading = true; 02066 FireDir = BestTarget.Location + BestTarget.Velocity * FMin(2, 0.02 + BestDist/projSpeed) - projStart; 02067 AimSpot = projStart + bestDist * Normal(FireDir); 02068 // if splash damage weapon, try aiming at feet - trace down to find floor 02069 } 02070 else 02071 { 02072 FireDir = BestTarget.Location - projStart; 02073 AimSpot = projStart + bestDist * Normal(FireDir); 02074 } 02075 AimOffset = AimSpot - OldAim; 02076 02077 // adjust Z of shooter if necessary 02078 if ( bNoZAdjust || (bLeading && (Abs(AimOffset.Z) < BestTarget.CollisionHeight)) ) 02079 AimSpot.Z = OldAim.Z; 02080 else if ( AimOffset.Z < 0 ) 02081 AimSpot.Z = BestTarget.Location.Z + 0.4 * BestTarget.CollisionHeight; 02082 else 02083 AimSpot.Z = BestTarget.Location.Z - 0.7 * BestTarget.CollisionHeight; 02084 02085 if ( !bLeading ) 02086 { 02087 // if not leading, add slight random error ( significant at long distances ) 02088 if ( !bNoZAdjust ) 02089 { 02090 AimRot = rotator(AimSpot - projStart); 02091 if ( FOVAngle < DefaultFOV - 8 ) 02092 AimRot.Yaw = AimRot.Yaw + 200 - Rand(400); 02093 else 02094 AimRot.Yaw = AimRot.Yaw + 375 - Rand(750); 02095 return AimRot; 02096 } 02097 } 02098 else if ( !FastTrace(projStart + 0.9 * bestDist * Normal(FireDir), projStart) ) 02099 { 02100 FireDir = BestTarget.Location - projStart; 02101 AimSpot = projStart + bestDist * Normal(FireDir); 02102 } 02103 02104 return rotator(AimSpot - projStart); 02105 } 02106 */ 02107 02108 native(498) static final function rotator AdjustAimForDisplay(Ammunition FiredAmmunition, vector projStart); 02109 02110 function bool NotifyLanded(vector HitNormal) 02111 { 02112 if ( bUpdating ) 02113 return true; 02114 LandBob = FMin(50, 0.055 * Pawn.Velocity.Z); 02115 return false; 02116 } 02117 02118 function eAttitude AttitudeTo(Pawn Other) 02119 { 02120 if ( Other.Controller == None ) 02121 return ATTITUDE_Ignore; 02122 if ( Other.IsPlayerPawn() ) 02123 return AttitudeToPlayer; 02124 return Other.Controller.AttitudeToPlayer; 02125 } 02126 02127 //============================================================================= 02128 // Player Control 02129 02130 // Player view. 02131 // Compute the rendering viewpoint for the player. 02132 // 02133 02134 function AdjustView(float DeltaTime ) 02135 { 02136 // teleporters affect your FOV, so adjust it back down 02137 if ( FOVAngle != DesiredFOV ) 02138 { 02139 if ( FOVAngle > DesiredFOV ) 02140 FOVAngle = FOVAngle - FMax(7, 0.9 * DeltaTime * (FOVAngle - DesiredFOV)); 02141 else 02142 FOVAngle = FOVAngle - FMin(-7, 0.9 * DeltaTime * (FOVAngle - DesiredFOV)); 02143 if ( Abs(FOVAngle - DesiredFOV) <= 10 ) 02144 FOVAngle = DesiredFOV; 02145 } 02146 02147 // adjust FOV for weapon zooming 02148 if ( bZooming ) 02149 { 02150 ZoomLevel += DeltaTime * 1.0; 02151 if (ZoomLevel > 0.9) 02152 ZoomLevel = 0.9; 02153 DesiredFOV = FClamp(90.0 - (ZoomLevel * 88.0), 1, 170); 02154 } 02155 } 02156 02157 function CalcBehindView(out vector CameraLocation, out rotator CameraRotation, float Dist) 02158 { 02159 local vector View,HitLocation,HitNormal; 02160 local float ViewDist; 02161 02162 CameraRotation = Rotation; 02163 View = vect(1,0,0) >> CameraRotation; 02164 if( Trace( HitLocation, HitNormal, CameraLocation - (Dist + 30) * vector(CameraRotation), CameraLocation ) != None ) 02165 ViewDist = FMin( (CameraLocation - HitLocation) Dot View, Dist ); 02166 else 02167 ViewDist = Dist; 02168 CameraLocation -= (ViewDist - 30) * View; 02169 } 02170 02171 /*function CalcFirstPersonView( out vector CameraLocation, out rotator CameraRotation ) 02172 { 02173 // First-person view. 02174 CameraRotation = Rotation; 02175 CameraLocation = CameraLocation + Pawn.EyePosition() + WalkBob + ShakeOffset; 02176 }*/ 02177 native(497) static final function CalcFirstPersonView( out vector CameraLocation, out rotator CameraRotation ); 02178 02179 event PlayerCalcView(out actor ViewActor, out vector CameraLocation, out rotator CameraRotation ) 02180 { 02181 local Pawn PTarget; 02182 02183 if ( (ViewTarget == None) || ViewTarget.bDeleteMe ) 02184 { 02185 if ( (Pawn != None) && !Pawn.bDeleteMe ) 02186 SetViewTarget(Pawn); 02187 else 02188 SetViewTarget(self); 02189 } 02190 02191 ViewActor = ViewTarget; 02192 CameraLocation = ViewTarget.Location; 02193 02194 if ( ViewTarget == Pawn ) 02195 { 02196 if( bBehindView ) //up and behind 02197 CalcBehindView(CameraLocation, CameraRotation, CameraDist * Pawn.Default.CollisionRadius); 02198 else 02199 CalcFirstPersonView( CameraLocation, CameraRotation ); 02200 return; 02201 } 02202 if ( ViewTarget == self ) 02203 { 02204 CameraRotation = Rotation; 02205 return; 02206 } 02207 CameraRotation = ViewTarget.Rotation; 02208 PTarget = Pawn(ViewTarget); 02209 if ( PTarget != None ) 02210 { 02211 if ( Level.NetMode == NM_Client ) 02212 { 02213 if ( PTarget.IsPlayerPawn() ) 02214 { 02215 PTarget.SetViewRotation(TargetViewRotation); 02216 CameraRotation = TargetViewRotation; 02217 } 02218 PTarget.EyeHeight = TargetEyeHeight; 02219 if ( PTarget.Weapon != None ) 02220 PTarget.Weapon.PlayerViewOffset = TargetWeaponViewOffset; 02221 } 02222 else if ( PTarget.IsPlayerPawn() ) 02223 CameraRotation = PTarget.GetViewRotation(); 02224 if ( !bBehindView ) 02225 CameraLocation += PTarget.EyePosition(); 02226 } 02227 if ( bBehindView ) 02228 { 02229 CameraLocation = CameraLocation + (ViewTarget.Default.CollisionHeight - ViewTarget.CollisionHeight) * vect(0,0,1); 02230 CalcBehindView(CameraLocation, CameraRotation, CameraDist * ViewTarget.Default.CollisionRadius); 02231 } 02232 } 02233 02234 /*function CheckShake(out float MaxOffset, out float Offset, out float Rate, out float Time) 02235 { 02236 if ( abs(Offset) < abs(MaxOffset) ) 02237 return; 02238 02239 Offset = MaxOffset; 02240 if ( Time > 1 ) 02241 { 02242 if ( Time * abs(MaxOffset/Rate) <= 1 ) 02243 MaxOffset = MaxOffset * (1/Time - 1); 02244 else 02245 MaxOffset *= -1; 02246 Time -= 1; 02247 Rate *= -1; 02248 } 02249 else 02250 { 02251 MaxOffset = 0; 02252 Offset = 0; 02253 Rate = 0; 02254 } 02255 } 02256 02257 function ViewShake(float DeltaTime) 02258 { 02259 local Rotator ViewRotation; 02260 local float FRoll; 02261 02262 if ( ShakeOffsetRate != vect(0,0,0) ) 02263 { 02264 // modify shake offset 02265 ShakeOffset.X += DeltaTime * ShakeOffsetRate.X; 02266 CheckShake(MaxShakeOffset.X, ShakeOffset.X, ShakeOffsetRate.X, ShakeOffsetTime.X); 02267 02268 ShakeOffset.Y += DeltaTime * ShakeOffsetRate.Y; 02269 CheckShake(MaxShakeOffset.Y, ShakeOffset.Y, ShakeOffsetRate.Y, ShakeOffsetTime.Y); 02270 02271 ShakeOffset.Z += DeltaTime * ShakeOffsetRate.Z; 02272 CheckShake(MaxShakeOffset.Z, ShakeOffset.Z, ShakeOffsetRate.Z, ShakeOffsetTime.Z); 02273 } 02274 02275 ViewRotation = Rotation; 02276 02277 if ( ShakeRollRate != 0 ) 02278 { 02279 ViewRotation.Roll = ((ViewRotation.Roll & 65535) + ShakeRollRate * DeltaTime) & 65535; 02280 if ( ViewRotation.Roll > 32768 ) 02281 ViewRotation.Roll -= 65536; 02282 FRoll = ViewRotation.Roll; 02283 CheckShake(MaxShakeRoll, FRoll, ShakeRollRate, ShakeRollTime); 02284 ViewRotation.Roll = FRoll; 02285 } 02286 else if ( bZeroRoll ) 02287 ViewRotation.Roll = 0; 02288 SetRotation(ViewRotation); 02289 }*/ 02290 native(496) static final function ViewShake(float DeltaTime); 02291 02292 function bool TurnTowardNearestEnemy(); 02293 02294 function TurnAround() 02295 { 02296 if ( !bSetTurnRot ) 02297 { 02298 TurnRot180 = Rotation; 02299 TurnRot180.Yaw += 32768; 02300 bSetTurnRot = true; 02301 } 02302 02303 DesiredRotation = TurnRot180; 02304 bRotateToDesired = ( DesiredRotation.Yaw != Rotation.Yaw ); 02305 } 02306 02307 function UpdateRotation(float DeltaTime, float maxPitch) 02308 { 02309 local rotator newRotation, ViewRotation; 02310 02311 if ( bInterpolating || ((Pawn != None) && Pawn.bInterpolating) ) 02312 { 02313 ViewShake(deltaTime); 02314 return; 02315 } 02316 ViewRotation = Rotation; 02317 DesiredRotation = ViewRotation; //save old rotation 02318 if ( bTurnToNearest != 0 ) 02319 TurnTowardNearestEnemy(); 02320 else if ( bTurn180 != 0 ) 02321 TurnAround(); 02322 else 02323 { 02324 TurnTarget = None; 02325 bRotateToDesired = false; 02326 bSetTurnRot = false; 02327 ViewRotation.Yaw += 32.0 * DeltaTime * aTurn; 02328 ViewRotation.Pitch += 32.0 * DeltaTime * aLookUp; 02329 } 02330 ViewRotation.Pitch = ViewRotation.Pitch & 65535; 02331 If ((ViewRotation.Pitch > 18000) && (ViewRotation.Pitch < 49152)) 02332 { 02333 If (aLookUp > 0) 02334 ViewRotation.Pitch = 18000; 02335 else 02336 ViewRotation.Pitch = 49152; 02337 } 02338 02339 SetRotation(ViewRotation); 02340 ViewShake(deltaTime); 02341 ViewFlash(deltaTime); 02342 02343 NewRotation = ViewRotation; 02344 NewRotation.Roll = Rotation.Roll; 02345 02346 if ( !bRotateToDesired && (Pawn != None) && (!bFreeCamera || !bBehindView) ) 02347 Pawn.FaceRotation(NewRotation, deltatime); 02348 } 02349 02350 // Player movement. 02351 // Player Standing, walking, running, falling. 02352 state PlayerWalking 02353 { 02354 ignores SeePlayer, Bump; 02355 02356 function bool NotifyPhysicsVolumeChange( PhysicsVolume NewVolume ) 02357 { 02358 if ( NewVolume.bWaterVolume ) 02359 GotoState(Pawn.WaterMovementState); 02360 return false; 02361 } 02362 02363 function ProcessMove(float DeltaTime, vector NewAccel, eDoubleClickDir DoubleClickMove, rotator DeltaRot) 02364 { 02365 local vector OldAccel; 02366 local bool OldCrouch; 02367 02368 OldAccel = Pawn.Acceleration; 02369 Pawn.Acceleration = NewAccel; 02370 if ( bPressedJump ) 02371 Pawn.DoJump(bUpdating); 02372 if ( Pawn.Physics != PHYS_Falling ) 02373 { 02374 OldCrouch = Pawn.bWantsToCrouch; 02375 if (bDuck == 0) 02376 Pawn.ShouldCrouch(false); 02377 else if ( Pawn.bCanCrouch ) 02378 Pawn.ShouldCrouch(true); 02379 } 02380 } 02381 02382 function PlayerMove( float DeltaTime ) 02383 { 02384 local vector X,Y,Z, NewAccel; 02385 local eDoubleClickDir DoubleClickMove; 02386 local rotator OldRotation, ViewRotation; 02387 local float Speed2D; 02388 local bool bSaveJump; 02389 02390 GetAxes(Pawn.Rotation,X,Y,Z); 02391 02392 // Update acceleration. 02393 NewAccel = aForward*X + aStrafe*Y; 02394 NewAccel.Z = 0; 02395 if ( VSize(NewAccel) < 1.0 ) 02396 NewAccel = vect(0,0,0); 02397 DoubleClickMove = PlayerInput.CheckForDoubleClickMove(DeltaTime); 02398 02399 GroundPitch = 0; 02400 ViewRotation = Rotation; 02401 if ( Pawn.Physics == PHYS_Walking ) 02402 { 02403 // tell pawn about any direction changes to give it a chance to play appropriate animation 02404 //if walking, look up/down stairs - unless player is rotating view 02405 GroundPitch = FindStairRotation(deltaTime); 02406 if ( (bLook == 0) 02407 && (((Pawn.Acceleration != Vect(0,0,0)) && bAlwaysLevel && bSnapToLevel) || !bKeyboardLook) ) 02408 { 02409 if ( bLookUpStairs || bSnapToLevel ) 02410 { 02411 ViewRotation.Pitch = GroundPitch; 02412 } 02413 else if ( bCenterView ) 02414 { 02415 ViewRotation.Pitch = ViewRotation.Pitch & 65535; 02416 if (ViewRotation.Pitch > 32768) 02417 ViewRotation.Pitch -= 65536; 02418 ViewRotation.Pitch = ViewRotation.Pitch * (1 - 12 * FMin(0.0833, deltaTime)); 02419 if ( Abs(ViewRotation.Pitch) < 1000 ) 02420 ViewRotation.Pitch = 0; 02421 } 02422 } 02423 02424 Speed2D = Sqrt(Pawn.Velocity.X * Pawn.Velocity.X + Pawn.Velocity.Y * Pawn.Velocity.Y); 02425 //add bobbing when walking 02426 CheckBob(DeltaTime, Speed2D, Y); 02427 } 02428 else 02429 { 02430 if ( !bKeyboardLook && (bLook == 0) && bCenterView ) 02431 { 02432 ViewRotation.Pitch = ViewRotation.Pitch & 65535; 02433 if (ViewRotation.Pitch > 32768) 02434 ViewRotation.Pitch -= 65536; 02435 ViewRotation.Pitch = ViewRotation.Pitch * (1 - 12 * FMin(0.0833, deltaTime)); 02436 if ( Abs(ViewRotation.Pitch) < 1000 ) 02437 ViewRotation.Pitch = 0; 02438 } 02439 BobTime = 0; 02440 WalkBob = WalkBob * (1 - FMin(1, 8 * deltatime)); 02441 } 02442 02443 // Update rotation. 02444 SetRotation(ViewRotation); 02445 OldRotation = Rotation; 02446 UpdateRotation(DeltaTime, 1); 02447 02448 if ( bPressedJump && Pawn.CannotJumpNow() ) 02449 { 02450 bSaveJump = true; 02451 bPressedJump = false; 02452 } 02453 else 02454 bSaveJump = false; 02455 02456 if ( Role < ROLE_Authority ) // then save this move and replicate it 02457 ReplicateMove(DeltaTime, NewAccel, DoubleClickMove, OldRotation - Rotation); 02458 else 02459 ProcessMove(DeltaTime, NewAccel, DoubleClickMove, OldRotation - Rotation); 02460 bPressedJump = bSaveJump; 02461 } 02462 02463 function BeginState() 02464 { 02465 if ( Pawn.Mesh == None ) 02466 Pawn.SetMesh(); 02467 WalkBob = vect(0,0,0); 02468 DoubleClickDir = DCLICK_None; 02469 Pawn.ShouldCrouch(false); 02470 bPressedJump = false; 02471 if (Pawn.Physics != PHYS_Falling) 02472 Pawn.SetPhysics(PHYS_Walking); 02473 GroundPitch = 0; 02474 } 02475 02476 function EndState() 02477 { 02478 GroundPitch = 0; 02479 WalkBob = vect(0,0,0); 02480 if ( Pawn != None ) 02481 Pawn.ShouldCrouch(false); 02482 } 02483 } 02484 02485 // player is climbing ladder 02486 state PlayerClimbing 02487 { 02488 ignores SeePlayer, Bump; 02489 02490 function bool NotifyPhysicsVolumeChange( PhysicsVolume NewVolume ) 02491 { 02492 if ( NewVolume.bWaterVolume ) 02493 GotoState(Pawn.WaterMovementState); 02494 else 02495 GotoState(Pawn.LandMovementState); 02496 return false; 02497 } 02498 02499 function ProcessMove(float DeltaTime, vector NewAccel, eDoubleClickDir DoubleClickMove, rotator DeltaRot) 02500 { 02501 local vector OldAccel; 02502 02503 OldAccel = Pawn.Acceleration; 02504 Pawn.Acceleration = NewAccel; 02505 02506 if ( bPressedJump ) 02507 { 02508 Pawn.DoJump(bUpdating); 02509 if ( Pawn.Physics == PHYS_Falling ) 02510 GotoState('PlayerWalking'); 02511 } 02512 } 02513 02514 function PlayerMove( float DeltaTime ) 02515 { 02516 local vector X,Y,Z, NewAccel; 02517 local eDoubleClickDir DoubleClickMove; 02518 local rotator OldRotation, ViewRotation; 02519 local float Speed2D; 02520 local bool bSaveJump; 02521 02522 GetAxes(Rotation,X,Y,Z); 02523 02524 // Update acceleration. 02525 //if ( Pawn.OnLadder != None ) 02526 // NewAccel = aForward*Pawn.OnLadder.ClimbDir; 02527 //else 02528 NewAccel = aForward*X + aStrafe*Y; 02529 if ( VSize(NewAccel) < 1.0 ) 02530 NewAccel = vect(0,0,0); 02531 02532 ViewRotation = Rotation; 02533 02534 // Update rotation. 02535 SetRotation(ViewRotation); 02536 OldRotation = Rotation; 02537 UpdateRotation(DeltaTime, 1); 02538 02539 if ( Role < ROLE_Authority ) // then save this move and replicate it 02540 ReplicateMove(DeltaTime, NewAccel, DoubleClickMove, OldRotation - Rotation); 02541 else 02542 ProcessMove(DeltaTime, NewAccel, DoubleClickMove, OldRotation - Rotation); 02543 bPressedJump = bSaveJump; 02544 } 02545 02546 function BeginState() 02547 { 02548 Pawn.ShouldCrouch(false); 02549 bPressedJump = false; 02550 } 02551 02552 function EndState() 02553 { 02554 if ( Pawn != None ) 02555 Pawn.ShouldCrouch(false); 02556 } 02557 } 02558 02559 02560 // Player movement. 02561 // Player walking on walls 02562 state PlayerSpidering 02563 { 02564 ignores SeePlayer, Bump; 02565 02566 event bool NotifyHitWall(vector HitNormal, actor HitActor) 02567 { 02568 // FIXME - pawn should have bool identifying if this was a voluntary jump 02569 Pawn.SetPhysics(PHYS_Spider); 02570 Pawn.SetBase(HitActor, HitNormal); 02571 return true; 02572 } 02573 02574 // if spider mode, update rotation based on floor 02575 function UpdateRotation(float DeltaTime, float maxPitch) 02576 { 02577 local rotator TempRot, ViewRotation; 02578 local vector MyFloor, CrossDir, FwdDir, OldFwdDir, OldX, RealFloor; 02579 02580 if ( bInterpolating || Pawn.bInterpolating ) 02581 { 02582 ViewShake(deltaTime); 02583 return; 02584 } 02585 02586 TurnTarget = None; 02587 bRotateToDesired = false; 02588 bSetTurnRot = false; 02589 02590 if ( (Pawn.Base == None) || (Pawn.Floor == vect(0,0,0)) ) 02591 MyFloor = vect(0,0,1); 02592 else 02593 MyFloor = Pawn.Floor; 02594 02595 if ( MyFloor != OldFloor ) 02596 { 02597 // smoothly change floor 02598 RealFloor = MyFloor; 02599 MyFloor = Normal(6*DeltaTime * MyFloor + (1 - 6*DeltaTime) * OldFloor); 02600 if ( (RealFloor Dot MyFloor) > 0.999 ) 02601 MyFloor = RealFloor; 02602 02603 // translate view direction 02604 CrossDir = Normal(RealFloor Cross OldFloor); 02605 FwdDir = CrossDir Cross MyFloor; 02606 OldFwdDir = CrossDir Cross OldFloor; 02607 ViewX = MyFloor * (OldFloor Dot ViewX) 02608 + CrossDir * (CrossDir Dot ViewX) 02609 + FwdDir * (OldFwdDir Dot ViewX); 02610 ViewX = Normal(ViewX); 02611 02612 ViewZ = MyFloor * (OldFloor Dot ViewZ) 02613 + CrossDir * (CrossDir Dot ViewZ) 02614 + FwdDir * (OldFwdDir Dot ViewZ); 02615 ViewZ = Normal(ViewZ); 02616 OldFloor = MyFloor; 02617 ViewY = Normal(MyFloor Cross ViewX); 02618 } 02619 02620 if ( (aTurn != 0) || (aLookUp != 0) ) 02621 { 02622 // adjust Yaw based on aTurn 02623 if ( aTurn != 0 ) 02624 ViewX = Normal(ViewX + 2 * ViewY * Sin(0.0005*DeltaTime*aTurn)); 02625 02626 // adjust Pitch based on aLookUp 02627 if ( aLookUp != 0 ) 02628 { 02629 OldX = ViewX; 02630 ViewX = Normal(ViewX + 2 * ViewZ * Sin(0.0005*DeltaTime*aLookUp)); 02631 ViewZ = Normal(ViewX Cross ViewY); 02632 02633 // bound max pitch 02634 if ( (ViewZ Dot MyFloor) < 0.707 ) 02635 { 02636 OldX = Normal(OldX - MyFloor * (MyFloor Dot OldX)); 02637 if ( (ViewX Dot MyFloor) > 0) 02638 ViewX = Normal(OldX + MyFloor); 02639 else 02640 ViewX = Normal(OldX - MyFloor); 02641 02642 ViewZ = Normal(ViewX Cross ViewY); 02643 } 02644 } 02645 02646 // calculate new Y axis 02647 ViewY = Normal(MyFloor Cross ViewX); 02648 } 02649 ViewRotation = OrthoRotation(ViewX,ViewY,ViewZ); 02650 SetRotation(ViewRotation); 02651 ViewShake(deltaTime); 02652 ViewFlash(deltaTime); 02653 Pawn.FaceRotation(ViewRotation, deltaTime ); 02654 } 02655 02656 function bool NotifyLanded(vector HitNormal) 02657 { 02658 Pawn.SetPhysics(PHYS_Spider); 02659 if ( bUpdating ) 02660 return true; 02661 LandBob = FMin(50, 0.055 * Pawn.Velocity.Z); 02662 return false; 02663 } 02664 02665 function bool NotifyPhysicsVolumeChange( PhysicsVolume NewVolume ) 02666 { 02667 if ( NewVolume.bWaterVolume ) 02668 GotoState(Pawn.WaterMovementState); 02669 return false; 02670 } 02671 02672 function ProcessMove(float DeltaTime, vector NewAccel, eDoubleClickDir DoubleClickMove, rotator DeltaRot) 02673 { 02674 local vector OldAccel; 02675 02676 OldAccel = Pawn.Acceleration; 02677 Pawn.Acceleration = NewAccel; 02678 02679 if ( bPressedJump ) 02680 Pawn.DoJump(bUpdating); 02681 } 02682 02683 function PlayerMove( float DeltaTime ) 02684 { 02685 local vector NewAccel; 02686 local eDoubleClickDir OldDoubleClick; 02687 local eDoubleClickDir DoubleClickMove; 02688 local rotator OldRotation, ViewRotation; 02689 local float Speed2D; 02690 local bool bSaveJump; 02691 02692 GroundPitch = 0; 02693 ViewRotation = Rotation; 02694 02695 if ( !bKeyboardLook && (bLook == 0) && bCenterView ) 02696 { 02697 // FIXME - center view rotation based on current floor 02698 } 02699 BobTime = 0; 02700 WalkBob = WalkBob * (1 - FMin(1, 8 * deltatime)); 02701 02702 // Update rotation. 02703 SetRotation(ViewRotation); 02704 OldRotation = Rotation; 02705 UpdateRotation(DeltaTime, 1); 02706 02707 // Update acceleration. 02708 NewAccel = aForward*Normal(ViewX - OldFloor * (OldFloor Dot ViewX)) + aStrafe*ViewY; 02709 if ( VSize(NewAccel) < 1.0 ) 02710 NewAccel = vect(0,0,0); 02711 02712 if ( bPressedJump && Pawn.CannotJumpNow() ) 02713 { 02714 bSaveJump = true; 02715 bPressedJump = false; 02716 } 02717 else 02718 bSaveJump = false; 02719 02720 if ( Role < ROLE_Authority ) // then save this move and replicate it 02721 ReplicateMove(DeltaTime, NewAccel, DoubleClickMove, OldRotation - Rotation); 02722 else 02723 ProcessMove(DeltaTime, NewAccel, DoubleClickMove, OldRotation - Rotation); 02724 bPressedJump = bSaveJump; 02725 } 02726 02727 function BeginState() 02728 { 02729 local Rotator NewRot; 02730 02731 if ( Pawn.Mesh == None ) 02732 Pawn.SetMesh(); 02733 OldFloor = vect(0,0,1); 02734 GetAxes(Rotation,ViewX,ViewY,ViewZ); 02735 WalkBob = vect(0,0,0); 02736 DoubleClickDir = DCLICK_None; 02737 Pawn.ShouldCrouch(false); 02738 bPressedJump = false; 02739 if (Pawn.Physics != PHYS_Falling) 02740 Pawn.SetPhysics(PHYS_Spider); 02741 GroundPitch = 0; 02742 Pawn.bCrawler = true; 02743 Pawn.SetCollisionSize(Pawn.Default.CollisionHeight,Pawn.Default.CollisionHeight); 02744 } 02745 02746 function EndState() 02747 { 02748 GroundPitch = 0; 02749 WalkBob = vect(0,0,0); 02750 if ( Pawn != None ) 02751 { 02752 Pawn.SetCollisionSize(Pawn.Default.CollisionRadius,Pawn.Default.CollisionHeight); 02753 Pawn.ShouldCrouch(false); 02754 Pawn.bCrawler = Pawn.Default.bCrawler; 02755 } 02756 } 02757 } 02758 02759 // Player movement. 02760 // Player Swimming 02761 state PlayerSwimming 02762 { 02763 ignores SeePlayer, Bump; 02764 02765 function bool WantsSmoothedView() 02766 { 02767 return ( !Pawn.bJustLanded ); 02768 } 02769 02770 function bool NotifyLanded(vector HitNormal) 02771 { 02772 if ( Pawn.PhysicsVolume.bWaterVolume ) 02773 Pawn.SetPhysics(PHYS_Swimming); 02774 else 02775 GotoState(Pawn.LandMovementState); 02776 return bUpdating; 02777 } 02778 02779 function bool NotifyPhysicsVolumeChange( PhysicsVolume NewVolume ) 02780 { 02781 local actor HitActor; 02782 local vector HitLocation, HitNormal, checkpoint; 02783 02784 if ( !NewVolume.bWaterVolume ) 02785 { 02786 Pawn.SetPhysics(PHYS_Falling); 02787 if (Pawn.bUpAndOut && Pawn.CheckWaterJump(HitNormal)) //check for waterjump 02788 { 02789 Pawn.velocity.Z = 330 + 2 * Pawn.CollisionRadius; //set here so physics uses this for remainder of tick 02790 GotoState(Pawn.LandMovementState); 02791 } 02792 else if ( (Pawn.Velocity.Z > 160) || !Pawn.TouchingWaterVolume() ) 02793 GotoState(Pawn.LandMovementState); 02794 else //check if in deep water 02795 { 02796 checkpoint = Pawn.Location; 02797 checkpoint.Z -= (Pawn.CollisionHeight + 6.0); 02798 HitActor = Trace(HitLocation, HitNormal, checkpoint, Pawn.Location, false); 02799 if (HitActor != None) 02800 GotoState(Pawn.LandMovementState); 02801 else 02802 { 02803 Enable('Timer'); 02804 SetTimer(0.7,false); 02805 } 02806 } 02807 } 02808 else 02809 { 02810 Disable('Timer'); 02811 Pawn.SetPhysics(PHYS_Swimming); 02812 } 02813 return false; 02814 } 02815 02816 function ProcessMove(float DeltaTime, vector NewAccel, eDoubleClickDir DoubleClickMove, rotator DeltaRot) 02817 { 02818 local vector X,Y,Z, OldAccel; 02819 02820 GetAxes(Rotation,X,Y,Z); 02821 OldAccel = Pawn.Acceleration; 02822 Pawn.Acceleration = NewAccel; 02823 Pawn.bUpAndOut = ((X Dot Pawn.Acceleration) > 0) && ((Pawn.Acceleration.Z > 0) || (Rotation.Pitch > 2048)); 02824 if ( !Pawn.PhysicsVolume.bWaterVolume ) //check for waterjump 02825 NotifyPhysicsVolumeChange(Pawn.PhysicsVolume); 02826 } 02827 02828 function PlayerMove(float DeltaTime) 02829 { 02830 local rotator oldRotation; 02831 local vector X,Y,Z, NewAccel; 02832 local float Speed2D; 02833 02834 GetAxes(Rotation,X,Y,Z); 02835 02836 NewAccel = aForward*X + aStrafe*Y + aUp*vect(0,0,1); 02837 if ( VSize(NewAccel) < 1.0 ) 02838 NewAccel = vect(0,0,0); 02839 02840 //add bobbing when swimming 02841 Speed2D = Sqrt(Pawn.Velocity.X * Pawn.Velocity.X + Pawn.Velocity.Y * Pawn.Velocity.Y); 02842 WalkBob = Y * Bob * 0.5 * Speed2D * sin(4.0 * Level.TimeSeconds); 02843 WalkBob.Z = Bob * 1.5 * Speed2D * sin(8.0 * Level.TimeSeconds); 02844 02845 // Update rotation. 02846 oldRotation = Rotation; 02847 UpdateRotation(DeltaTime, 2); 02848 02849 if ( Role < ROLE_Authority ) // then save this move and replicate it 02850 ReplicateMove(DeltaTime, NewAccel, DCLICK_None, OldRotation - Rotation); 02851 else 02852 ProcessMove(DeltaTime, NewAccel, DCLICK_None, OldRotation - Rotation); 02853 bPressedJump = false; 02854 } 02855 02856 function Timer() 02857 { 02858 if ( !Pawn.PhysicsVolume.bWaterVolume && (Role == ROLE_Authority) ) 02859 GotoState(Pawn.LandMovementState); 02860 02861 Disable('Timer'); 02862 } 02863 02864 function BeginState() 02865 { 02866 Disable('Timer'); 02867 Pawn.SetPhysics(PHYS_Swimming); 02868 } 02869 } 02870 02871 state PlayerFlying 02872 { 02873 ignores SeePlayer, Bump; 02874 02875 function PlayerMove(float DeltaTime) 02876 { 02877 local rotator newRotation; 02878 local vector X,Y,Z; 02879 02880 GetAxes(Rotation,X,Y,Z); 02881 02882 Pawn.Acceleration = aForward*X + aStrafe*Y; 02883 if ( VSize(Pawn.Acceleration) < 1.0 ) 02884 Pawn.Acceleration = vect(0,0,0); 02885 if ( bCheatFlying && (Pawn.Acceleration == vect(0,0,0)) ) 02886 Pawn.Velocity = vect(0,0,0); 02887 // Update rotation. 02888 UpdateRotation(DeltaTime, 2); 02889 02890 if ( Role < ROLE_Authority ) // then save this move and replicate it 02891 ReplicateMove(DeltaTime, Pawn.Acceleration, DCLICK_None, rot(0,0,0)); 02892 else 02893 ProcessMove(DeltaTime, Pawn.Acceleration, DCLICK_None, rot(0,0,0)); 02894 } 02895 02896 function BeginState() 02897 { 02898 Pawn.SetPhysics(PHYS_Flying); 02899 } 02900 } 02901 02902 state PlayerHelicoptering extends PlayerFlying 02903 { 02904 function PlayerMove(float DeltaTime) 02905 { 02906 local rotator newRotation; 02907 local vector X,Y,Z; 02908 02909 GetAxes(Rotation,X,Y,Z); 02910 02911 Pawn.Acceleration = aForward*X + aStrafe*Y + aUp*vect(0,0,1); 02912 if ( VSize(Pawn.Acceleration) < 1.0 ) 02913 Pawn.Acceleration = vect(0,0,0); 02914 if ( bCheatFlying && (Pawn.Acceleration == vect(0,0,0)) ) 02915 Pawn.Velocity = vect(0,0,0); 02916 // Update rotation. 02917 UpdateRotation(DeltaTime, 2); 02918 02919 if ( Role < ROLE_Authority ) // then save this move and replicate it 02920 ReplicateMove(DeltaTime, Pawn.Acceleration, DCLICK_None, rot(0,0,0)); 02921 else 02922 ProcessMove(DeltaTime, Pawn.Acceleration, DCLICK_None, rot(0,0,0)); 02923 } 02924 } 02925 02926 state BaseSpectating 02927 { 02928 function ProcessMove(float DeltaTime, vector NewAccel, eDoubleClickDir DoubleClickMove, rotator DeltaRot) 02929 { 02930 Acceleration = NewAccel; 02931 MoveSmooth(Acceleration * DeltaTime); 02932 } 02933 02934 function PlayerMove(float DeltaTime) 02935 { 02936 local rotator newRotation; 02937 local vector X,Y,Z; 02938 02939 GetAxes(Rotation,X,Y,Z); 02940 02941 Acceleration = 0.02 * (aForward*X + aStrafe*Y + aUp*vect(0,0,1)); 02942 02943 UpdateRotation(DeltaTime, 1); 02944 02945 if ( Role < ROLE_Authority ) // then save this move and replicate it 02946 ReplicateMove(DeltaTime, Acceleration, DCLICK_None, rot(0,0,0)); 02947 else 02948 ProcessMove(DeltaTime, Acceleration, DCLICK_None, rot(0,0,0)); 02949 } 02950 } 02951 02952 state Spectating extends BaseSpectating 02953 { 02954 ignores SwitchWeapon, RestartLevel, ClientRestart, Suicide, 02955 ThrowWeapon, NotifyPhysicsVolumeChange, NotifyHeadVolumeChange; 02956 02957 exec function NextWeapon() 02958 { 02959 Fire(); 02960 } 02961 02962 exec function PrevWeapon() 02963 { 02964 if ( ViewTarget == self ) 02965 bBehindView = false; 02966 else 02967 bBehindView = true; //bChaseCam; 02968 } 02969 02970 exec function Fire( optional float F ) 02971 { 02972 local Controller C, Pick; 02973 local bool bFound; 02974 02975 if ( Role == ROLE_Authority ) 02976 { 02977 // view next player 02978 for ( C=Level.ControllerList; C!=None; C=C.NextController ) 02979 if ( (C.Pawn != None) && Level.Game.CanSpectate(self,C.Pawn) ) 02980 { 02981 if ( Pick == None ) 02982 Pick = C; 02983 if ( bFound ) 02984 { 02985 Pick = C; 02986 break; 02987 } 02988 else 02989 bFound = ( ViewTarget == C.Pawn ); 02990 } 02991 SetViewTarget(Pick.Pawn); 02992 if ( ViewTarget == self ) 02993 bBehindView = false; 02994 else 02995 bBehindView = true; //bChaseCam; 02996 } 02997 } 02998 02999 // Return to spectator's own camera. 03000 exec function AltFire( optional float F ) 03001 { 03002 bBehindView = false; 03003 SetViewtarget(self); 03004 ClientMessage(OwnCamera, 'Event'); 03005 } 03006 03007 function BeginState() 03008 { 03009 if ( Pawn != None ) 03010 { 03011 SetLocation(Pawn.Location); 03012 UnPossess(); 03013 } 03014 bCollideWorld = true; 03015 } 03016 03017 function EndState() 03018 { 03019 PlayerReplicationInfo.bIsSpectator = false; 03020 bCollideWorld = false; 03021 } 03022 } 03023 03024 //_____________________________________________________________________________ 03025 auto state PlayerWaiting extends BaseSpectating 03026 { 03027 ignores SeePlayer, NotifyBump, TakeDamage, PhysicsVolumeChange; 03028 function ProcessMove(float DeltaTime, vector NewAccel, eDoubleClickDir DoubleClickMove, rotator DeltaRot); 03029 function PlayerMove(float DeltaTime); 03030 exec function Jump( optional float F ); 03031 exec function Suicide(); 03032 03033 function ChangeTeam( int N ) 03034 { 03035 Level.Game.ChangeTeam(self, N); 03036 } 03037 03038 function ServerReStartPlayer() 03039 { 03040 Log("PlayerWaiting ServerReStartPlayer"@self); 03041 if ( Level.TimeSeconds < WaitDelay ) 03042 { 03043 Log(" Cancel ServerReStartPlayer because WaitDelay"@WaitDelay@">Level.TimeSeconds"@Level.TimeSeconds); 03044 return; 03045 } 03046 if ( Level.NetMode == NM_Client ) 03047 { 03048 Log(" Cancel ServerReStartPlayer because Client"); 03049 return; 03050 } 03051 if ( Level.Game.bWaitingToStartMatch ) 03052 { 03053 Log(" Set PRI"@PlayerReplicationInfo@"ReadyToPlay"); 03054 PlayerReplicationInfo.bReadyToPlay = true; 03055 } 03056 else 03057 { 03058 Log(" Restart Player"@self); 03059 Level.Game.RestartPlayer(self); 03060 } 03061 } 03062 03063 exec function Fire(optional float F) 03064 { 03065 Log("PlayerWaiting Fire"@self); 03066 ServerReStartPlayer(); 03067 } 03068 03069 exec function AltFire(optional float F); 03070 03071 function EndState() 03072 { 03073 if ( Pawn != None ) 03074 Pawn.SetMesh(); 03075 PlayerReplicationInfo.SetWaitingPlayer(false); 03076 bCollideWorld = false; 03077 Log("PlayerWaiting EndState"@self); 03078 } 03079 03080 function BeginState() 03081 { 03082 if ( PlayerReplicationInfo != None ) 03083 PlayerReplicationInfo.SetWaitingPlayer(true); 03084 bCollideWorld = true; 03085 myHUD.bShowScores = false; 03086 Log("PlayerWaiting BeginState"@self); 03087 } 03088 } 03089 /* 03090 auto state PlayerWaiting 03091 { 03092 function EndState() 03093 { 03094 if ( Pawn != None ) 03095 Pawn.SetMesh(); 03096 PlayerReplicationInfo.SetWaitingPlayer(false); 03097 bCollideWorld = false; 03098 Log("PlayerWaiting EndState Player="$player); 03099 } 03100 03101 function BeginState() 03102 { 03103 Super.BeginState(); 03104 Log("PlayerWaiting BeginState Player="$player); 03105 } 03106 exec function Fire(optional float F) 03107 { 03108 if (!Player.LocalInteractions[0].IsInState('UWindows')) 03109 ServerReStartPlayer(); 03110 } 03111 exec function UnFire(optional float F); 03112 }*/ 03113 03114 state WaitingForPawn extends BaseSpectating 03115 { 03116 ignores SeePlayer, HearNoise, KilledBy, SwitchWeapon; 03117 03118 exec function Fire( optional float F ) 03119 { 03120 } 03121 03122 exec function AltFire( optional float F ) 03123 { 03124 } 03125 03126 function LongClientAdjustPosition 03127 ( 03128 float TimeStamp, 03129 name newState, 03130 EPhysics newPhysics, 03131 float NewLocX, 03132 float NewLocY, 03133 float NewLocZ, 03134 float NewVelX, 03135 float NewVelY, 03136 float NewVelZ, 03137 Actor NewBase, 03138 float NewFloorX, 03139 float NewFloorY, 03140 float NewFloorZ 03141 ) 03142 { 03143 } 03144 03145 function PlayerTick(float DeltaTime) 03146 { 03147 // Log(self@"WaitingForPawn PlayerTick"); 03148 Global.PlayerTick(DeltaTime); 03149 03150 if ( !bTimerLoop ) 03151 { 03152 Log(" WaitingForPawn PlayerTick, Timer not activated ?"); 03153 SetTimer(0.2, true); 03154 } 03155 03156 if ( Pawn != None ) 03157 { 03158 Log(" WaitingForPawn PlayerTick, Found Pawn"); 03159 Pawn.Controller = self; 03160 ClientRestart(); 03161 } 03162 } 03163 03164 function Timer() 03165 { 03166 Log(self@"WaitingForPawn Timer"); 03167 AskForPawn(); 03168 MyHud.bShowScores = true; 03169 } 03170 03171 function BeginState() 03172 { 03173 Log(self@"WaitingForPawn BeginState"); 03174 SetTimer(0.2, true); 03175 MyHud.bShowScores = true; 03176 } 03177 03178 function EndState() 03179 { 03180 Log(self@"WaitingForPawn EndState"); 03181 SetTimer(0.0, false); 03182 MyHud.bShowScores = false; 03183 } 03184 } 03185 03186 state GameEnded 03187 { 03188 ignores SeePlayer, HearNoise, KilledBy, NotifyBump, HitWall, NotifyHeadVolumeChange, NotifyPhysicsVolumeChange, Falling, TakeDamage, Suicide; 03189 03190 exec function ThrowWeapon() 03191 { 03192 } 03193 03194 function ServerReStartGame() 03195 { 03196 Level.Game.RestartGame(); 03197 } 03198 03199 exec function Fire( optional float F ) 03200 { 03201 if ( Role < ROLE_Authority) 03202 return; 03203 if ( !bFrozen ) 03204 ServerReStartGame(); 03205 else if ( TimerRate <= 0 ) 03206 SetTimer(1.5, false); 03207 } 03208 03209 exec function AltFire( optional float F ) 03210 { 03211 Fire(F); 03212 } 03213 03214 function PlayerMove(float DeltaTime) 03215 { 03216 local vector X,Y,Z; 03217 local Rotator ViewRotation; 03218 03219 GetAxes(Rotation,X,Y,Z); 03220 // Update view rotation. 03221 03222 if ( !bFixedCamera ) 03223 { 03224 ViewRotation = Rotation; 03225 ViewRotation.Yaw += 32.0 * DeltaTime * aTurn; 03226 ViewRotation.Pitch += 32.0 * DeltaTime * aLookUp; 03227 ViewRotation.Pitch = ViewRotation.Pitch & 65535; 03228 If ((ViewRotation.Pitch > 18000) && (ViewRotation.Pitch < 49152)) 03229 { 03230 If (aLookUp > 0) 03231 ViewRotation.Pitch = 18000; 03232 else 03233 ViewRotation.Pitch = 49152; 03234 } 03235 SetRotation(ViewRotation); 03236 } 03237 else if ( ViewTarget != None ) 03238 SetRotation(ViewTarget.Rotation); 03239 03240 ViewShake(DeltaTime); 03241 ViewFlash(DeltaTime); 03242 03243 if ( Role < ROLE_Authority ) // then save this move and replicate it 03244 ReplicateMove(DeltaTime, vect(0,0,0), DCLICK_None, rot(0,0,0)); 03245 else 03246 ProcessMove(DeltaTime, vect(0,0,0), DCLICK_None, rot(0,0,0)); 03247 bPressedJump = false; 03248 } 03249 03250 function ServerMove 03251 ( 03252 float TimeStamp, 03253 vector InAccel, 03254 vector ClientLoc, 03255 bool NewbRun, 03256 bool NewbDuck, 03257 bool NewbJumpStatus, 03258 eDoubleClickDir DoubleClickMove, 03259 byte ClientRoll, 03260 int View, 03261 optional byte OldTimeDelta, 03262 optional int OldAccel 03263 ) 03264 { 03265 Global.ServerMove(TimeStamp, InAccel, ClientLoc, NewbRun, NewbDuck, NewbJumpStatus, 03266 DoubleClickMove, ClientRoll, (32767 & (Rotation.Pitch/2)) * 32768 + (32767 & (Rotation.Yaw/2)) ); 03267 03268 } 03269 03270 function FindGoodView() 03271 { 03272 local vector cameraLoc; 03273 local rotator cameraRot, ViewRotation; 03274 local int tries, besttry; 03275 local float bestdist, newdist; 03276 local int startYaw; 03277 local actor ViewActor; 03278 03279 ViewRotation = Rotation; 03280 ViewRotation.Pitch = 56000; 03281 tries = 0; 03282 besttry = 0; 03283 bestdist = 0.0; 03284 startYaw = ViewRotation.Yaw; 03285 03286 for (tries=0; tries<16; tries++) 03287 { 03288 cameraLoc = ViewTarget.Location; 03289 PlayerCalcView(ViewActor, cameraLoc, cameraRot); 03290 newdist = VSize(cameraLoc - ViewTarget.Location); 03291 if (newdist > bestdist) 03292 { 03293 bestdist = newdist; 03294 besttry = tries; 03295 } 03296 ViewRotation.Yaw += 4096; 03297 } 03298 03299 ViewRotation.Yaw = startYaw + besttry * 4096; 03300 SetRotation(ViewRotation); 03301 } 03302 03303 function Timer() 03304 { 03305 bFrozen = false; 03306 } 03307 03308 function BeginState() 03309 { 03310 local Pawn P; 03311 03312 EndZoom(); 03313 bFire = 0; 03314 bAltFire = 0; 03315 if ( Pawn != None ) 03316 { 03317 Pawn.SimAnim.AnimRate = 0; 03318 Pawn.bPhysicsAnimUpdate = false; 03319 Pawn.StopAnimating(); 03320 Pawn.SetCollision(false,false,false); 03321 } 03322 myHUD.bShowScores = true; 03323 bFrozen = true; 03324 if ( !bFixedCamera ) 03325 { 03326 FindGoodView(); 03327 bBehindView = true; 03328 } 03329 SetTimer(1.5, false); 03330 SetPhysics(PHYS_None); 03331 ForEach DynamicActors(class'Pawn', P) 03332 { 03333 P.Velocity = vect(0,0,0); 03334 P.SetPhysics(PHYS_None); 03335 } 03336 } 03337 } 03338 03339 state Dead 03340 { 03341 ignores SeePlayer, HearNoise, KilledBy, SwitchWeapon; 03342 03343 function ServerRestartPlayer() 03344 { 03345 if ( bFrozen ) 03346 return; 03347 Super.ServerRestartPlayer(); 03348 } 03349 03350 exec function Fire( optional float F ) 03351 { 03352 if ( !bFrozen ) 03353 ServerReStartPlayer(); 03354 } 03355 03356 exec function AltFire( optional float F ) 03357 { 03358 Fire(F); 03359 } 03360 03361 function ServerMove 03362 ( 03363 float TimeStamp, 03364 vector Accel, 03365 vector ClientLoc, 03366 bool NewbRun, 03367 bool NewbDuck, 03368 bool NewbJumpStatus, 03369 eDoubleClickDir DoubleClickMove, 03370 byte ClientRoll, 03371 int View, 03372 optional byte OldTimeDelta, 03373 optional int OldAccel 03374 ) 03375 { 03376 Global.ServerMove( 03377 TimeStamp, 03378 Accel, 03379 ClientLoc, 03380 false, 03381 false, 03382 false, 03383 DoubleClickMove, 03384 ClientRoll, 03385 View); 03386 } 03387 03388 function PlayerMove(float DeltaTime) 03389 { 03390 local vector X,Y,Z; 03391 local rotator ViewRotation; 03392 03393 if ( !bFrozen ) 03394 { 03395 if ( bPressedJump ) 03396 { 03397 Fire(0); 03398 bPressedJump = false; 03399 } 03400 GetAxes(Rotation,X,Y,Z); 03401 // Update view rotation. 03402 ViewRotation = Rotation; 03403 ViewRotation.Yaw += 32.0 * DeltaTime * aTurn; 03404 ViewRotation.Pitch += 32.0 * DeltaTime * aLookUp; 03405 ViewRotation.Pitch = ViewRotation.Pitch & 65535; 03406 If ((ViewRotation.Pitch > 18000) && (ViewRotation.Pitch < 49152)) 03407 { 03408 If (aLookUp > 0) 03409 ViewRotation.Pitch = 18000; 03410 else 03411 ViewRotation.Pitch = 49152; 03412 } 03413 SetRotation(ViewRotation); 03414 if ( Role < ROLE_Authority ) // then save this move and replicate it 03415 ReplicateMove(DeltaTime, vect(0,0,0), DCLICK_None, rot(0,0,0)); 03416 } 03417 ViewShake(DeltaTime); 03418 ViewFlash(DeltaTime); 03419 } 03420 03421 function FindGoodView() 03422 { 03423 local vector cameraLoc; 03424 local rotator cameraRot, ViewRotation; 03425 local int tries, besttry; 03426 local float bestdist, newdist; 03427 local int startYaw; 03428 local actor ViewActor; 03429 03430 ////log("Find good death scene view"); 03431 ViewRotation = Rotation; 03432 ViewRotation.Pitch = 56000; 03433 tries = 0; 03434 besttry = 0; 03435 bestdist = 0.0; 03436 startYaw = ViewRotation.Yaw; 03437 03438 for (tries=0; tries<16; tries++) 03439 { 03440 cameraLoc = ViewTarget.Location; 03441 PlayerCalcView(ViewActor, cameraLoc, cameraRot); 03442 newdist = VSize(cameraLoc - ViewTarget.Location); 03443 if (newdist > bestdist) 03444 { 03445 bestdist = newdist; 03446 besttry = tries; 03447 } 03448 ViewRotation.Yaw += 4096; 03449 } 03450 03451 ViewRotation.Yaw = startYaw + besttry * 4096; 03452 SetRotation(ViewRotation); 03453 } 03454 03455 function Timer() 03456 { 03457 myHUD.bShowScores = true; 03458 bPressedJump = false; 03459 // SetTimer2(5.0,false); 03460 bFrozen = false; 03461 } 03462 03463 function Timer2() 03464 { 03465 bFrozen = false; 03466 } 03467 03468 function BeginState() 03469 { 03470 local SavedMove Next; 03471 03472 Enemy = None; 03473 bBehindView = true; 03474 bFrozen = true; 03475 bPressedJump = false; 03476 FindGoodView(); 03477 SetTimer(1.0, false); 03478 03479 // clean out saved moves 03480 while ( SavedMoves != None ) 03481 { 03482 Next = SavedMoves.NextMove; 03483 SavedMoves.Destroy(); 03484 SavedMoves = Next; 03485 } 03486 if ( PendingMove != None ) 03487 { 03488 PendingMove.Destroy(); 03489 PendingMove = None; 03490 } 03491 } 03492 03493 function EndState() 03494 { 03495 local SavedMove Next; 03496 03497 // clean out saved moves 03498 while ( SavedMoves != None ) 03499 { 03500 Next = SavedMoves.NextMove; 03501 SavedMoves.Destroy(); 03502 SavedMoves = Next; 03503 } 03504 if ( PendingMove != None ) 03505 { 03506 PendingMove.Destroy(); 03507 PendingMove = None; 03508 } 03509 Velocity = vect(0,0,0); 03510 Acceleration = vect(0,0,0); 03511 bBehindView = false; 03512 myHUD.bShowScores = false; 03513 bPressedJump = false; 03514 //Log(self$" exiting dying with remote role "$RemoteRole$" and role "$Role); 03515 } 03516 } 03517 03518 //------------------------------------------------------------------------------ 03519 // ngStats Accessors 03520 function string GetNGSecret() 03521 { 03522 return ngWorldSecret; 03523 } 03524 03525 function SetNGSecret(string newSecret) 03526 { 03527 ngWorldSecret = newSecret; 03528 } 03529 03530 //------------------------------------------------------------------------------ 03531 // Control options 03532 function ChangeStairLook( bool B ) 03533 { 03534 bLookUpStairs = B; 03535 if ( bLookUpStairs ) 03536 bAlwaysMouseLook = false; 03537 } 03538 03539 function ChangeAlwaysMouseLook(Bool B) 03540 { 03541 bAlwaysMouseLook = B; 03542 if ( bAlwaysMouseLook ) 03543 bLookUpStairs = false; 03544 } 03545 03546 debugonly simulated function DumpContent(float TimeStamp, int tabulation) 03547 { 03548 local int j; 03549 local string Tab; 03550 03551 for (j=0; j<tabulation; j++) Tab = Tab$" "; 03552 03553 log(Tab$"PlayerController's dump at "$TimeStamp$":"); 03554 //log(Tab$" bLookUpStairs:"$bLookUpStairs$" bSnapToLevel:"$bSnapToLevel$" bAlwaysMouseLook:"$bAlwaysMouseLook$" bKeyboardLook:"$bKeyboardLook$" bCenterView:"$bCenterView); 03555 //log(Tab$" bBehindView:"$bBehindView$" bFrozen:"$bFrozen$" bPressedJump:"$bPressedJump$" bUpdatePosition:"$bUpdatePosition$" bIsTyping:"$bIsTyping); 03556 //log(Tab$" bFixedCamera:"$bFixedCamera$" bJumpStatus:"$bJumpStatus$" bUpdating:"$bUpdating$" bNeverSwitchOnPickup:"$bNeverSwitchOnPickup); 03557 //log(Tab$" bZooming:"$bZooming$" bOnlySpectator:"$bOnlySpectator$" bAlwaysLevel:"$bAlwaysLevel$" bSetTurnRot:"$bSetTurnRot); 03558 //log(Tab$" bCheatFlying:"$bCheatFlying$" bFreeCamera:"$bFreeCamera$" bZeroRoll:"$bZeroRoll); 03559 //log(Tab$" AimingHelp:"$AimingHelp$" WaitDelay:"$WaitDelay); 03560 //log(Tab$" aBaseX:"$aBaseX$" aBaseY:"$aBaseY$" aBaseZ:"$aBaseZ$" aMouseX:"$aMouseX$" aMouseY:"$aMouseY$" aForward:"$aForward$" aTurn:"$aTurn$" aStrafe:"$aStrafe$" aUp:"$aUp$" aLookUp:"$aLookUp); 03561 //log(Tab$" bStrafe:"$bStrafe$" bSnapLevel:"$bSnapLevel$" bLook:"$bLook$" bFreeLook:"$bFreeLook$" bTurn180:"$bTurn180$" bTurnToNearest:"$bTurnToNearest); 03562 //log(Tab$" DoubleClickDir:"$DoubleClickDir); 03563 //log(Tab$" ShowFlags:"$ShowFlags$" Misc1:"$Misc1$" Misc2:"$Misc2$" RendMap:"$RendMap$" OrthoZoom:"$OrthoZoom$" ViewTarget:"$ViewTarget$" CameraDist:"$CameraDist); 03564 //log(Tab$" DesiredFOV:"$DesiredFOV$" DefaultFOV:"$DefaultFOV$" ZoomLevel:"$ZoomLevel); 03565 //log(Tab$" FlashScale:"$FlashScale$" FlashFog:"$FlashFog); 03566 //log(Tab$" DesiredFlashScale:"$DesiredFlashScale$" ConstantGlowScale:"$ConstantGlowScale); 03567 //log(Tab$" InstantFlash:"$InstantFlash$" DesiredFlashFog:"$DesiredFlashFog$" ConstantGlowFog:"$ConstantGlowFog$" InstantFog:"$InstantFog); 03568 //log(Tab$" FilterColor:"$FilterColor.B$","$FilterColor.G$","$FilterColor.R$","$FilterColor.A$" FilterColorWanted:"$FilterColorWanted.B$","$FilterColorWanted.G$","$FilterColorWanted.R$","$FilterColorWanted.A$" FilterColorSpeed:"$FilterColorSpeed$" FilterInternalInc:"$FilterInternalInc); 03569 //log(Tab$" TargetViewRotation:"$TargetViewRotation$" TargetEyeHeight:"$TargetEyeHeight$" TargetWeaponViewOffset:"$TargetWeaponViewOffset); 03570 //log(Tab$" myHUD:"$myHUD$" LastPlaySound:"$LastPlaySound$" AnnouncerVolume:"$AnnouncerVolume); 03571 //log(Tab$" SavedMoves:"$SavedMoves$" FreeMoves:"$FreeMoves$" PendingMove:"$PendingMove); 03572 //log(Tab$" CurrentTimeStamp:"$CurrentTimeStamp$" LastUpdateTime:"$LastUpdateTime$" ServerTimeStamp:"$ServerTimeStamp$" TimeMargin:"$TimeMargin$" ClientUpdateTime:"$ClientUpdateTime$" MaxTimeMargin:"$MaxTimeMargin); 03573 log(Tab$" LastUpdateTime:"$LastUpdateTime$" ServerTimeStamp:"$ServerTimeStamp$" TimeMargin:"$TimeMargin$" ClientUpdateTime:"$ClientUpdateTime); 03574 //log(Tab$" OldClientWeapon:"$OldClientWeapon$" WeaponUpdate:"$WeaponUpdate); 03575 //log(Tab$" ProgressMessage[0]:"$ProgressMessage[0]$" ProgressMessage[1]:"$ProgressMessage[1]$" ProgressMessage[2]:"$ProgressMessage[2]$" ProgressMessage[3]:"$ProgressMessage[3]); 03576 // discarded log(Tab$" ProgressColor[0]:"$ProgressColor[0]$" ProgressColor[1]:"$ProgressColor[1]$" ProgressColor[2]:"$ProgressColor[2]$" ProgressColor[3]:"$ProgressColor[3]); 03577 //log(Tab$" ProgressTimeOut:"$ProgressTimeOut$" QuickSaveString:"$QuickSaveString$" NoPauseMessage:"$NoPauseMessage$" ViewingFrom:"$ViewingFrom$" OwnCamera:"$OwnCamera); 03578 //log(Tab$" QuickSaveString:"$QuickSaveString$" NoPauseMessage:"$NoPauseMessage$" ViewingFrom:"$ViewingFrom$" OwnCamera:"$OwnCamera); 03579 //log(Tab$" ngWorldSecret:"$ngWorldSecret$" ngSecretSet:"$ngSecretSet$" ReceivedSecretChecksum:"$ReceivedSecretChecksum$" LocalMessageClass:"$LocalMessageClass); 03580 log(Tab$" Bob:"$Bob$" LandBob:"$LandBob$" AppliedBob:"$AppliedBob$" bobtime:"$bobtime$" WalkBob:"$WalkBob); 03581 //log(Tab$" MaxShakeRoll:"$MaxShakeRoll$" MaxShakeOffset:"$MaxShakeOffset$" ShakeRollRate:"$ShakeRollRate$" ShakeOffsetRate:"$ShakeOffsetRate); 03582 //log(Tab$" ShakeOffset:"$ShakeOffset$" ShakeRollTime:"$ShakeRollTime$" ShakeOffsetTime:"$ShakeOffsetTime); 03583 //log(Tab$" TurnTarget:"$TurnTarget$" EnemyTurnSpeed:"$EnemyTurnSpeed$" GroundPitch:"$GroundPitch$" TurnRot180:"$TurnRot180); 03584 //log(Tab$" OldFloor:"$OldFloor); 03585 //log(Tab$" CheatManager:"$CheatManager$" CheatClass:"$CheatClass$" PlayerInput:"$PlayerInput$" InputClass:"$InputClass); 03586 //log(Tab$" DemoViewPitch:"$DemoViewPitch$" DemoViewYaw:"$DemoViewYaw); 03587 //log(Tab$" GameReplicationInfo:"$GameReplicationInfo); 03588 //log(Tab$" GameReplicationInfo:"); 03589 //GameReplicationInfo.DumpContent(TimeStamp, tabulation) 03590 03591 Super.DumpContent(TimeStamp, tabulation); 03592 } 03593 03594 03595 debugonly simulated function DumpChosenContent(float TimeStamp) 03596 { 03597 log("At "$TimeStamp$":"); 03598 if (pawn!=none) 03599 { 03600 if (pawn.velocity.z>0.0) 03601 { 03602 log("GroundSpeed:"$pawn.GroundSpeed$" jumping:"$pawn.velocity.z); 03603 } 03604 else 03605 { 03606 log("GroundSpeed:"$pawn.GroundSpeed); 03607 } 03608 } 03609 } 03610 03611 // AimingHelp=0.0 03612 03613 defaultproperties 03614 { 03615 bAlwaysMouseLook=True 03616 bKeyboardLook=True 03617 bZeroRoll=True 03618 bAutoPickup=True 03619 ConfigType=CT_StrafeLookNotSameAxis 03620 OrthoZoom=40000.000000 03621 CameraDist=9.000000 03622 DesiredFOV=85.000000 03623 DefaultFOV=85.000000 03624 FlashScale=(X=1.000000,Y=1.000000,Z=1.000000) 03625 FilterColor=(B=128,G=128,R=128) 03626 FilterColorWanted=(B=128,G=128,R=128) 03627 FilterColorSpeed=1.000000 03628 AnnouncerVolume=4 03629 MaxTimeMargin=1.000000 03630 QuickSaveString="Quick Saving" 03631 NoPauseMessage="Game is not pauseable" 03632 ViewingFrom="Now viewing from" 03633 OwnCamera="Now viewing from own camera" 03634 LocalMessageClass=Class'Engine.LocalMessage' 03635 Bob=0.016000 03636 EnemyTurnSpeed=45000 03637 CheatClass=Class'Engine.CheatManager' 03638 InputClass=Class'Engine.PlayerInput' 03639 FovAngle=85.000000 03640 Handedness=1.000000 03641 bIsPlayer=True 03642 bCanOpenDoors=True 03643 bCanDoSpecial=True 03644 bTravel=True 03645 NetPriority=3.000000 03646 }

End Source Code