RuneI
Class RunePlayer

source: c:\runehov\RuneI\Classes\RunePlayer.uc
Core.Object
   |
   +--Engine.Actor
      |
      +--Engine.Pawn
         |
         +--Engine.PlayerPawn
            |
            +--RuneI.RunePlayer
Direct Known Subclasses:PlayerAlric, PlayerBerserker, PlayerConrack, PlayerDarkViking, PlayerDarkWarrior, PlayerElder, PlayerKarl, PlayerLokiGuard, PlayerSarkAxe, PlayerSarkConrack, PlayerSarkHammer, PlayerSarkRagnar, PlayerSarkSpawn, PlayerSarkSword, PlayerSigurd, PlayerSven, PlayerUlf, PlayerValkyrie, PlayerWolfgar, PlayerZombie, PlayerZombie2, Ragnar, RagnarFlight, RagnarSnow, SarkRagnar, ShipWreckRagnar, TownRagnar, TrialPitRagnar

class RunePlayer
extends Engine.PlayerPawn

//============================================================================= // RunePlayer. //=============================================================================
Variables
 int BerserkLoopId
           RUNE: Necessary to stop the berserk looping sound
 Actor BloodLustEyes
           RUNE: The eye gear that toggles when the player bloodlusts
 float CombatSpeed
           RUNE: Crouching
 float CrouchHeight
           RUNE: Crouching
 float CurrentDist
           RUNE: Crouching
 rotator CurrentRotation
           RUNE: Crouching
 float CurrentTime
           RUNE: Crouching
 int DispatchAction
           Index of current action of ScriptDispatcher
 vector DropZFloor
           Go to first person
 vector DropZRag
           Go to first person
 vector DropZResult
           Go to first person
 vector DropZRoll
           Go to first person
 float ExploreSpeed
           RUNE: Crouching
 float GrabLocationDist
           RUNE: Used in edge grab code
 Weapon LastHeldWeapon
           RUNE: Necessary to stop the berserk looping sound
 float LastTime
           RUNE: Crouching
 Actor NextPoint
           For queueing OrderObject (NextState, NextLabel)
 string NoRunePowerMsg
           RUNE: Used in edge grab code
 vector OldCameraStart
           RUNE: Crouching
 Actor OrderObject
           Object containing current script orders
 float RopeDist
           Call PlayMoving() to update move anim
 vector SavedCameraLoc
           RUNE: Crouching
 rotator SavedCameraRot
           RUNE: Crouching
 rotator ShakeDelta
           RUNE: Necessary to stop the berserk looping sound
 int SpeechPos
           Position within controls for speech
 name StatueAnim
           Call PlayMoving() to update move anim
 Pawn StatueInstigator
           Call PlayMoving() to update move anim
 string TestString
           Go to first person
 Rope TheRope
           Call PlayMoving() to update move anim
 Pawn ZTarget
           Go to first person
 ZTargetDecal ZTargetDecal
           Go to first person
 bool bCameraLock
           Go to first person
 bool bCameraOverhead
           Go to first person
 bool bCanRestart
           RUNE: Used to allow/disallow player-restarting after death
 bool bGotoFP
           Go to first person
 bool bPlayedFallingSound
           Go to first person
 bool bScriptMoving
           Call PlayMoving() to update move anim
 bool bSurfaceSwimming
           RUNE: The eye gear that toggles when the player bloodlusts
 rotator baseRot
           Go to first person
 int i
           Go to first person
 rotator pelvisRot
           Go to first person
 rotator ragnarRot
           Go to first person
 rotator velRot
           Go to first person

States
Unresponsive, Pain, Scripting, Dying, PlayerSwimming, PlayerRopeClimbing, EdgeHanging, PlayerWalking

Function Summary
 void AcquireInventory(Inventory item)
     
//=============================================================================
//
// AcquireInventory
//
//=============================================================================
 void ApplyGoreCap(int BodyPart)
     
//============================================================
//
// ApplyGoreCap
//
//============================================================
 void BehindView(Bool B)
 bool BodyPartCritical(int BodyPart)
     
//============================================================
//
// BodyPartCritical
//
//============================================================
 int BodyPartForJoint(int joint)
     
//============================================================
//
// BodyPartForJoint
//
// Returns the body part a joint is associated with
//============================================================
 int BodyPartForPolyGroup(int polygroup)
     
//============================================================
//
// BodyPartForPolyGroup
//
//============================================================
 bool BodyPartSeverable(int BodyPart)
     
//============================================================
//
// BodyPartSeverable
//
//============================================================
 void BoostStrength(int amount)
     
//------------------------------------------------------------
//
// BoostStrength
//
//------------------------------------------------------------
 void CameraIn()
 void CameraOut()
 bool CanPickup(Inventory item)
     
//=============================================================================
//
// CamPickUp
//
//=============================================================================
 bool CanStandUp()
 void CheckMatter()
 void ClientReStart()
 
simulated
ClientTryPlayTorsoAnim(name TorsoAnim)
 void Damage(string parms)
     
//-----------------------------------------------------------------------------
// Exec functions
 bool DamageBodyPart(int Damage, Pawn EventInstigator, vector HitLocation, vector Momentum, name DamageType, int bodypart)
     
//=============================================================================
//
// DamageBodyPart
//
//=============================================================================
 
simulated
DetermineLookFocus()
     
//=============================================================================
//
// DetermineLookFocus
//
// Checks for the ideal actor for the player's focus
// TODO:
//	- Object priorities
//	- Proper distance usage
//  - Angle from RunePlayer(Owner) to object
//	- Special "chasing actor" mode that allows the player to look backwards
//=============================================================================
 void DoJump(optional float)
     
//=============================================================================
//
// DoJump
//
//=============================================================================
 
simulated
DoTryPlayTorsoAnim(name TorsoAnim, float speed, float tween)
 void DropShield()
     
//=============================================================================
//
// DropShield
//
//=============================================================================
 void DropZ()
     
//=============================================================================
//
// DropZ
//
// TEST FUNCTION
//=============================================================================
 void DumpWeaponInfo()
 bool FindInventoryItem(Inventory testItem)
 bool FollowOrders(name order, name tag)
     
//=============================================================================
//
// FollowOrders
//
//=============================================================================
 void Gasp()
 Name GetGroup(Name AnimSequence)
     
//=============================================================================
//
// GetGroup
//
//=============================================================================
 Weapon GetNextWeapon(Weapon current)
     
//=============================================================================
//
// GetNextWeapon
//
// Returns the next sequential weapon of a certain type in the inventory.
// This function is circular, so it will wrap around to the first weapon in the
// inventory
//=============================================================================
 Weapon GetStowedWeapon(int stowindex)
     
//=============================================================================
//
// GetStowedWeapon
//
//=============================================================================
 void HitWall(vector HitNormal, Actor HitWall)
     
//=============================================================================
//
// HitWall
//
//=============================================================================
 void InstantStow()
     
//=============================================================================
//
// InstantStow
//
// Instantly stows the current weapon, and properly updates LastHeldWeapon
// for later retrieval
//=============================================================================
 bool JointDamaged(int Damage, Pawn EventInstigator, vector HitLoc, vector Momentum, name DamageType, int joint)
     
//=============================================================================
//
// JointDamaged
//
// Only overridden for the VikingAxe Empathy powerup in multiplayer
//=============================================================================
 void LimbSevered(int BodyPart, vector Momentum)
     
//============================================================
//
// LimbSevered
//
//============================================================
 float PawnDamageModifier(Weapon w)
     
//------------------------------------------------------------
//
// PawnDamageModifier
//
// Returns the modification of the damage amount 
// Used to increase damage for special attacks, or reduce damage
// for simple attack types
//------------------------------------------------------------
 void PlayAltFiring()
     
//=============================================================================
//
// PlayAltFiring 
//
//=============================================================================
 void PlayBackDeath(name DamageType)
 void PlayBackHit(float tweentime)
     
//=============================================================================
//
// PlayBackHit
//
// NOTE:  Hit functions force the torso to play the hit animation
//=============================================================================
 
simulated
PlayBeepSound()
     
//-----------------------------------------------------------------------------
// Sound functions
 void PlayCrawling(optional float)
     
//=============================================================================
//
// PlayCrawling
//
//=============================================================================
 void PlayDeath(name DamageType)
 void PlayDrownDeath(name DamageType)
 void PlayDrowning(float tweentime)
     
//=============================================================================
//
// PlayDrowning
//
// NOTE:  Hit functions force the torso to play the hit animation
//=============================================================================
 void PlayDuck(optional float)
     
//=============================================================================
//
// PlayDuck
//
//=============================================================================
 void PlayDyingSound(name DamageType)
 void PlayFeignDeath()
     
//=============================================================================
//
// PlayFeignDeath
//
// Obsolete Unreal Code
//=============================================================================
 void PlayFiring()
     
//=============================================================================
//
// PlayFiring
//
//=============================================================================
 void PlayFrontHit(float tweentime)
     
//=============================================================================
//
// PlayFrontHit
//
// NOTE:  Hit functions force the torso to play the hit animation
//=============================================================================
 void PlayGibDeath(name DamageType)
 void PlayGutHit(float tweentime)
     
//=============================================================================
//
// PlayGutHit
//
// NOTE:  Hit functions force the torso to play the hit animation
//=============================================================================
 void PlayHeadDeath(name DamageType)
 void PlayHeadHit(float tweentime)
     
//=============================================================================
//
// PlayHeadHit
//
// NOTE:  Hit functions force the torso to play the hit animation
//=============================================================================
 void PlayInAir(optional float)
     
//=============================================================================
//
// PlayInAir
//
//=============================================================================
 void PlayJump()
     
//=============================================================================
//
// PlayJump
//
//=============================================================================
 void PlayLanded(float impactVel)
     
//=============================================================================
//
// PlayLanded
//
//=============================================================================
 void PlayLeftDeath(name DamageType)
 void PlayLeftHit(float tweentime)
     
//=============================================================================
//
// PlayLeftHit
//
// NOTE:  Hit functions force the torso to play the hit animation
//=============================================================================
 void PlayMoving(optional float)
     
//=============================================================================
//
// PlayMoving
//
//=============================================================================
 void PlayPullUp(optional float)
     
//=============================================================================
//
// PlayPullUp
//
//=============================================================================
 void PlayRightDeath(name DamageType)
 void PlayRightHit(float tweentime)
     
//=============================================================================
//
// PlayRightHit
//
// NOTE:  Hit functions force the torso to play the hit animation
//=============================================================================
 void PlayRising()
     
//=============================================================================
//
// PlayRising
//
// Obsolete Unreal Code
//=============================================================================
 void PlayRopeIdle()
     
//=============================================================================
//
// PlayRopeIdle
//
//=============================================================================
 void PlayRopeLeapOff()
     
//=============================================================================
//
// PlayRopeLeapOff
//
//=============================================================================
 void PlaySkewerDeath(name DamageType)
 void PlayStepUp(optional float)
     
//=============================================================================
//
// PlayStepUp
//
//=============================================================================
 void PlaySwimming()
     
//=============================================================================
//
// PlaySwimming
//
//=============================================================================
 void PlayTakeHit(float tweentime, int damage, vector HitLoc, name damageType, vector Momentum, int BodyPart)
     
//=============================================================================
//
// PlayTakeHit
//
//=============================================================================
 void PlayTakeHitSound(int damage, name damageType, int Mult)
 void PlayTurning(optional float)
     
//=============================================================================
//
// PlayTurning
//
//=============================================================================
 void PlayWaiting(optional float)
     
//=============================================================================
//
// PlayWaiting
//
//=============================================================================
 void PlayWeaponSwitch(Weapon NewWeapon)
     
//=============================================================================
//
// PlayWeaponSwitch
//
// Obsolete Unreal Code
//=============================================================================
 void PlayerRestart()
 void Powerup()
     
//=============================================================================
//
// Powerup
//
//=============================================================================
 void PowerupBlaze(Pawn EventInstigator)
 void PowerupElectricity(Pawn EventInstigator)
 void PowerupFire(Pawn EventInstigator)
     
//-----------------------------------------------------------------------------
//	Powerup functions
 void PowerupFriend(Pawn EventInstigator)
 void PowerupIce(Pawn EventInstigator)
 void PowerupStone(Pawn EventInstigator)
 void PreBeginPlay()
     
//=============================================================================
//
// PreBeginPlay
//
//=============================================================================
 void RetrieveWeapon(int stowIndex)
     
//=============================================================================
//
// RetrieveWeapon
//
//=============================================================================
 float ScoreLookActor(Actor A)
     
// ----- LOOK Code -----
 void SelectWeapon(Weapon newWeapon)
     
//=============================================================================
//
// SelectWeapon
//
//=============================================================================
 void SetCrouch(bool crouch)
     
//=============================================================================
//
// SetCrouch
//
//=============================================================================
 void SetCrouchHeight()
 void SetMovementMode()
     
//=============================================================================
//
// SetMovementMode
//
//=============================================================================
 void SetNormalHeight()
 void SetOnFire(Pawn EventInstigator, int joint)
 void SetStowedWeapon(int stowindex, Weapon w)
     
//=============================================================================
//
// SetStowedWeapon
//
//=============================================================================
 void StowWeapon(Weapon oldWeapon)
     
//=============================================================================
//
// StowWeapon
//
//=============================================================================
 void StrengthDecay(float Time)
     
//------------------------------------------------------------
//
// StrengthDecay
//
//------------------------------------------------------------
 void Summon(string ClassName)
 void SwapStowToNext(int stowIndex)
     
//=============================================================================
//
// SwapStowToNext
//
// Swaps a weapon in a given stow stop with the next available weapon in the inventory
//=============================================================================
 void SwitchWeapon(byte F)
     
//=============================================================================
//
// SwitchWeapon
//
//=============================================================================
 void Taunt()
     
//------------------------------------------------------------
//
// Taunt
//
//------------------------------------------------------------
 void Throw()
     
//=============================================================================
//
// Throw
//
//=============================================================================
 void ThrowGhost()
     
//=============================================================================
//
// ThrowGhost
//
// Notify for Throw powerup
//=============================================================================
 void ThrowWeapon()
     
//=============================================================================
//
// ThrowWeapon
//
// RUNE:  Throw the current weapon
//=============================================================================
 void Touch(Actor Other)
     
//=============================================================================
//
// Touch
//
//=============================================================================
 void TraceTex()
     
//=============================================================================
//
// TraceTex
//
//=============================================================================
 void TravelPostAccept()
     
//=============================================================================
//
// TravelPostAccept
//
// Called after the player has entered a new level, and after the player's
// inventory has been accepted.  This simply sets the correct movement mode
// for the player.
//=============================================================================
 void TryPlayTorsoAnim(name TorsoAnim, float speed, float tween)
     
//=============================================================================
//
// TryPlayTorsoAnim
//
// Attempts to play the torso anim on the legs.
//=============================================================================
 void TweenToMoving(float tweentime)
     
//=============================================================================
//
// TweenToMoving
//
//=============================================================================
 void TweenToSwimming(float tweentime)
     
//=============================================================================
//
// TweenToSwimming
//
//=============================================================================
 void TweenToWaiting(float tweentime)
     
//=============================================================================
//
// TweenToWaiting
//
//=============================================================================
 void UnPowerupFriend()
 void Use()
     
//=============================================================================
//
// Use
//
//=============================================================================
 void ViewShake(float DeltaTime)
     
//------------------------------------------------------------
//
// ViewShake
//
//------------------------------------------------------------
 bool WantsToPickUp(Inventory item)
     
//------------------------------------------------------------
//
// WantsToPickup
//
// Returns whether the item is desired
//------------------------------------------------------------
 void ZTargetToggle()


State Unresponsive Function Summary
 bool TraceIt()
 void AnimEnd()
 void BeginState()
 void EndState()
 void PlayTakeHit(float tweentime, int damage, vector HitLoc, name damageType, vector Momentum, int BodyPart)
 void PlayerMove(float DeltaTime)
 void ProcessMove(float DeltaTime, vector NewAccel, eDodgeDir DodgeMove, rotator DeltaRot)
 bool JointDamaged(int Damage, Pawn EventInstigator, vector HitLoc, vector Momentum, name DamageType, int joint)
 bool CanGotoPainState()
 bool CanBeStatued()
 void Suicide()
 void Ghost()
 void Walk()
 void Fly()
 void SwitchWeapon(byte F)
 void Use()
 void AltFire(optional float)
 void Fire(optional float)
 void Throw()
 void Powerup()
 void Taunt()


State Pain Function Summary
 void SlowAnimation()
 void Landed(vector HitNormal, Actor HitActor)
 void EndState()
 void BeginState()
 void Timer()
 void InventoryNormal()
 void InventoryStatue()
 void CreatureNormal()
 void CreatureStatue()
 bool JointDamaged(int Damage, Pawn EventInstigator, vector HitLoc, vector Momentum, name DamageType, int joint)
 void PlayDyingSound(name damageType)
 void SpawnDebris(vector Momentum)
 EMatterType MatterForJoint(int joint)
 void PlayerMove(float DeltaTime)
 bool CanGotoPainState()
 bool CanBeStatued()
 void SwitchWeapon(byte F)
 void Taunt()
 void Powerup()
 void Throw()
 void Use()
 void AltFire(optional float)
 void Fire(optional float)
     
//================================================
//
// IceStatue
//
// Used only for Ice Powerup
//================================================
 void Landed(vector HitNormal, Actor HitActor)
 void EndState()
 void BeginState()
 void Timer()
 void InventoryNormal()
 void InventoryStatue()
 void CreatureNormal()
 void DebrisCloud()
 void CreatureStatue()
 bool JointDamaged(int Damage, Pawn EventInstigator, vector HitLoc, vector Momentum, name DamageType, int joint)
 void PlayDyingSound(name damageType)
 void SpawnDebris(vector Momentum)
 EMatterType MatterForJoint(int joint)
 void PlayerMove(float DeltaTime)
 void ZoneChange(ZoneInfo newZone)
 bool CanGotoPainState()
 bool CanBeStatued()
 void SwitchWeapon(byte F)
 void Taunt()
 void Powerup()
 void Throw()
 void Use()
 void AltFire(optional float)
 void Fire(optional float)
     
//================================================
//
// Statue
//
//================================================
 bool CanGotoPainState()


State Scripting Function Summary
 void ExecuteScriptDispatcherAction(int i)
 void FinishScriptDispatcher()
 void Timer()
 void SpeechTimer()
 void ExecuteScriptAction()
     
//============================================
 void ExecuteScriptPoint()
     
//============================================
 void Use()
     
// Use, Fire, AltFire allow skipping cinematics
 void ReleaseFromCinematic()
 void BeginState()
 void EndState()
 void PlayDying(name DamageType, vector HitLocation)
 void PlayTakeHit(float tweentime, int damage, vector HitLoc, name damageType, vector Momentum, int BodyPart)
 void PlayerMove(float DeltaTime)
 void ProcessMove(float DeltaTime, vector NewAccel, eDodgeDir DodgeMove, rotator DeltaRot)
 bool JointDamaged(int Damage, Pawn EventInstigator, vector HitLoc, vector Momentum, name DamageType, int joint)
 bool CanGotoPainState()
 bool CanBeStatued()
 void Throw()
 void Powerup()
 void Ghost()
 void Walk()
 void Fly()
 void Taunt()
 void Landed(vector HitNormal, Actor HitActor)


State Dying Function Summary
 void ReleaseFromCinematic()
     
//-----------------------------------------------------------------------------
//
// STATE Scripting
//
// This state disallows any player input until the cinema ends
//-----------------------------------------------------------------------------
 void AnimEnd()
 void Landed(vector HitNormal, Actor HitActor)
     
// Not run on clients
		SetPhysics(PHYS_None);
		SetCollision(false, false, false);
		bCollideWorld = false;
		ReplaceWithCarcass();
	}*/
 void Done()
     
/*	
 void EndState()
 void BeginState()
 void ServerReStartPlayer()


State PlayerSwimming Function Summary
 bool GrabEdge(float grabDistance, vector grabNormal)
 void UpdateRotation(float DeltaTime, float maxPitch)
 void ProcessMove(float DeltaTime, vector NewAccel, eDodgeDir DodgeMove, rotator DeltaRot)
 void CheckForSubmerge()
 bool CheckWaterJump(out vector)
 void PlayerMove(float DeltaTime)
 void HeadZoneChange(ZoneInfo NewZone)
 void EndState()
 void BeginState()
 void AnimEnd()
 bool CanGotoPainState()
 void StopUnderwaterSound()
 void SetSurfaceSwim(bool surface)
 void PlayUnderwaterSound()
 void PlayMoving(optional float)


State PlayerRopeClimbing Function Summary
 void ChangedWeapon()
 void PlayDying(name DamageType, vector HitLocation)
 void PlayTakeHit(float tweentime, int damage, vector HitLoc, name damageType, vector Momentum, int BodyPart)
 void PlayerMove(float DeltaTime)
 void ServerMove(float TimeStamp, vector Accel, vector ClientLoc, bool NewbRun, bool NewbDuck, bool NewbJumpStatus, bool bFired, bool bAltFired, bool bForceFire, bool bForceAltFire, eDodgeDir DodgeMove, byte ClientRoll, int View, optional byte, optional int)
 void ProcessMove(float DeltaTime, vector NewAccel, eDodgeDir DodgeMove, rotator DeltaRot)
 void Landed(vector HitNormal, Actor HitActor)
 void Taunt()
 void PlayChatting()
 void LeapOff()
 void FallOff()
 void Use()
 void ZoneChange(ZoneInfo NewZone)
 void EndState()
 void BeginState()
 void AnimEnd()
 void PlayRopeClimb()


State EdgeHanging Function Summary
 void StopAttack()
     
//=============================================================================
//
// StopAttack
//
//=============================================================================
 void BeginState()
 void AnimEnd()
 void EndState()
 void Throw()
 void Powerup()
 void Ghost()
 void Walk()
 void Fly()
 void Taunt()


State PlayerWalking Function Summary
 void EndState()
 void BeginState()
 void ZoneChange(ZoneInfo NewZone)
 void UpdateRotation(float DeltaTime, float maxPitch)
 void ProcessMove(float DeltaTime, vector NewAccel, eDodgeDir DodgeMove, rotator DeltaRot)
 void Dodge(eDodgeDir DodgeMove)
 bool GrabEdge(float grabDistance, vector grabNormal)
 void Landed(vector HitNormal, Actor HitActor)
 void AnimEnd()



Source Code


00001	//=============================================================================
00002	// RunePlayer.
00003	//=============================================================================
00004	class RunePlayer extends PlayerPawn
00005		config(user)
00006		abstract;
00007	
00008	#exec AUDIO IMPORT FILE="Sounds\message.wav" NAME=MessageBeep
00009	
00010	const ZTARGET_DIST = 600;
00011	
00012	var() float CrouchHeight; // RUNE:  Crouching
00013	
00014	// Combat versus Exploration Mode vars
00015	var() float ExploreSpeed;
00016	var() float CombatSpeed;
00017	
00018	var(Advanced) bool        bBurnable;			// RUNE: Can be set on fire
00019	
00020	// Client-side Camera Vars
00021	var vector OldCameraStart;
00022	var(Camera) float CameraDist;
00023	var(Camera) float CameraAccel;
00024	var(Camera) float CameraHeight;
00025	var(Camera) float CameraPitch;
00026	var(Camera) rotator CameraRotSpeed;
00027	var(Camera) float TranslucentDist;
00028	var rotator CurrentRotation;
00029	var float LastTime;
00030	var float CurrentTime;
00031	var float CurrentDist;
00032	
00033	var rotator	SavedCameraRot;
00034	var vector	SavedCameraLoc;
00035	
00036	var bool bGotoFP; // Go to first person
00037	var bool bCameraLock;
00038	var bool bCameraOverhead;
00039	var bool bPlayedFallingSound;
00040	var pawn ZTarget;
00041	var ZTargetDecal ZTargetDecal;
00042	
00043	var int i;
00044	var string TestString;
00045	
00046	// Debug!
00047	var vector DropZFloor;
00048	var vector DropZRag;
00049	var vector DropZResult;
00050	var vector DropZRoll;
00051	
00052	var rotator velRot;
00053	var rotator ragnarRot;
00054	var rotator pelvisRot;
00055	var rotator baseRot;
00056	
00057	// Scripting support
00058	var actor				NextPoint;			// For queueing OrderObject (NextState, NextLabel)
00059	var int					SpeechPos;			// Position within controls for speech
00060	var int					DispatchAction;		// Index of current action of ScriptDispatcher
00061	var actor				OrderObject;		// Object containing current script orders
00062	var bool				bScriptMoving;		// Call PlayMoving() to update move anim
00063	
00064	// Rope variables
00065	var Rope TheRope;
00066	var float RopeDist;
00067	const HandOffset = 10;
00068	
00069	// Statue variables
00070	var Pawn StatueInstigator;
00071	var name StatueAnim;
00072	
00073	enum MovementDir_e
00074	{
00075		MD_FORWARD,
00076		MD_BACKWARD,
00077		MD_LEFT,
00078		MD_RIGHT,
00079		MD_FORWARDLEFT,
00080		MD_FORWARDRIGHT,
00081		MD_BACKWARDLEFT,
00082		MD_BACKWARDRIGHT
00083	};
00084	
00085	var(Sounds) sound breathagain;
00086	var(Sounds) sound Die4;
00087	var(Sounds) sound GaspSound;
00088	var(Sounds) sound UnderWaterHitSound[3];
00089	var(Sounds) sound PowerupFail;
00090	
00091	var(Sounds) sound WeaponPickupSound;
00092	var(Sounds) sound WeaponThrowSound;
00093	var(Sounds) sound WeaponDropSound;
00094	var(Sounds) sound JumpGruntSound[3];
00095	var(Sounds) sound FallingDeathSound;
00096	var(Sounds) sound FallingScreamSound;
00097	var(Sounds) sound UnderWaterDeathSound;
00098	var(Sounds) sound EdgeGrabSound;
00099	var(Sounds) sound StepupSound;
00100	var(Sounds) sound KickSound;
00101	var(Sounds) sound HitSoundLow[3]; // Low damage
00102	var(Sounds) sound HitSoundMed[3]; // Med damage
00103	var(Sounds) sound HitSoundHigh[3]; // High damage
00104	var(Sounds) sound UnderwaterAmbient[6];
00105	var(Sounds) sound BerserkSoundStart;
00106	var(Sounds) sound BerserkSoundEnd;
00107	var(Sounds) sound BerserkSoundLoop;
00108	var(Sounds) sound BerserkYellSound[6];
00109	var(Sounds)	sound CrouchSound;
00110	var(Sounds) sound RopeClimbSound[3];
00111	
00112	var int BerserkLoopId; // RUNE:  Necessary to stop the berserk looping sound
00113	
00114	var Weapon LastHeldWeapon;
00115	
00116	var rotator ShakeDelta;
00117	var actor BloodLustEyes; // RUNE:  The eye gear that toggles when the player bloodlusts
00118	
00119	var bool bSurfaceSwimming;
00120	var float GrabLocationDist; // RUNE:  Used in edge grab code 
00121	
00122	var localized string NoRunePowerMsg;
00123	var bool bCanRestart;	// RUNE: Used to allow/disallow player-restarting after death
00124	
00125	
00126	replication
00127	{
00128		// Things the server should send to the client.
00129		unreliable if(bNetOwner && Role == ROLE_Authority)
00130			CameraAccel, CameraDist, CameraPitch, CameraHeight, CameraRotSpeed,
00131			ZTarget, CrouchHeight, bGotoFP, TheRope;
00132	
00133		// Things the client should send to the server
00134	//	unreliable if(Role < ROLE_Authority)
00135	//		;
00136	
00137		// Functions client can call.
00138		reliable if(Role < ROLE_Authority)
00139			CameraIn, CameraOut, ZTargetToggle;
00140	
00141		// Functions server can call.
00142		unreliable if(Role==ROLE_Authority && RemoteRole==ROLE_AutonomousProxy)
00143			ClientTryPlayTorsoAnim;
00144	}
00145	
00146	//=============================================================================
00147	//
00148	// PreBeginPlay
00149	//
00150	//=============================================================================
00151	
00152	function PreBeginPlay()
00153	{
00154		Enable('Tick');
00155	
00156		Super.PreBeginPlay();
00157	
00158		// Spawn Torso Animation proxy
00159		AnimProxy = spawn(class'RunePlayerProxy', self);
00160	
00161		OldCameraStart = Location;
00162		OldCameraStart.Z += CameraHeight;
00163	
00164		CurrentDist = CameraDist;
00165		LastTime = 0;
00166		CurrentTime = 0;
00167		CurrentRotation = Rotation;
00168	
00169		// Adjust CrouchHeight to new DrawScale
00170		CrouchHeight = CrouchHeight * DrawScale;		
00171	}
00172	
00173	//=============================================================================
00174	//
00175	// PostBeginPlay
00176	//
00177	//=============================================================================
00178	
00179	event PostBeginPlay()
00180	{	
00181		Super(PlayerPawn).PostBeginPlay();
00182	
00183		Weapon = None;
00184	
00185		SetMovementMode();
00186	
00187		BloodLustEyes = Spawn(Class'SarkEyeRagnarRed');
00188		if(BloodLustEyes != None)
00189		{
00190			AttachActorToJoint(BloodLustEyes, JointNamed('head'));
00191			BloodLustEyes.bHidden = true;
00192		}
00193	}
00194	
00195	function PlayerRestart()
00196	{
00197		// Add back on default attachments (eyes)
00198		BloodLustEyes = Spawn(Class'SarkEyeRagnarRed');
00199		if(BloodLustEyes != None)
00200		{
00201			AttachActorToJoint(BloodLustEyes, JointNamed('head'));
00202			BloodLustEyes.bHidden = true;
00203		}
00204	}
00205	
00206	function ClientReStart()
00207	{
00208		local int i;
00209	
00210		// Reset client-side camera
00211		OldCameraStart = Location;
00212		OldCameraStart.Z += CameraHeight;
00213		CurrentDist = CameraDist;
00214		LastTime = 0;
00215		CurrentTime = 0;
00216		CurrentRotation = Rotation;
00217	
00218		Super.ClientRestart();
00219		SetMovementMode();
00220	
00221		// If the player was touching a rope when the level was saved, make certain the player
00222		// goes back into rope-grabbing state
00223		for(i = 0; i < ARRAYCOUNT(Touching); i++)
00224		{
00225			if(Touching[i] != None && Touching[i].IsA('Rope'))
00226			{
00227				SetPhysics(PHYS_Falling); // Can only grab ropes when in the air
00228				Touch(Touching[i]);
00229			}
00230		}
00231	}
00232	
00233	//=============================================================================
00234	//
00235	// TravelPostAccept
00236	//
00237	// Called after the player has entered a new level, and after the player's
00238	// inventory has been accepted.  This simply sets the correct movement mode
00239	// for the player.
00240	//=============================================================================
00241	
00242	function TravelPostAccept()
00243	{
00244		SetMovementMode();
00245	
00246		Super.TravelPostAccept();
00247	}
00248	
00249	
00250	//=============================================================================
00251	//
00252	// PostRender
00253	//
00254	//=============================================================================
00255	event PostRender( canvas Canvas )
00256	{
00257		local Texture Tex;
00258	
00259		// Handle level fade in
00260		if (Level.bFadeIn)
00261		{
00262			LevelFadeAlpha = 1.0;
00263			Level.FadeRate = FClamp(Level.FadeRate, 0.5, 10.0);
00264			Level.bFadeIn = false;
00265		}
00266		if (LevelFadeAlpha > 0)
00267		{	// Draw black with fadealpha
00268			Tex = Texture'RuneFX.Letterbox';
00269			if (LevelFadeAlpha < 1.0)
00270				Canvas.Style = ERenderStyle.STY_AlphaBlend;
00271			Canvas.SetPos(0, 0);
00272			Canvas.AlphaScale = LevelFadeAlpha;
00273			Canvas.DrawTile(Tex, Canvas.ClipX, Canvas.ClipY, 0, 0, Tex.USize, Tex.VSize);
00274			Canvas.Style = ERenderStyle.STY_Normal;
00275		}
00276	
00277		Super.PostRender(Canvas);
00278	}
00279	
00280	//=============================================================================
00281	//
00282	// FollowOrders
00283	//
00284	//=============================================================================
00285	function bool FollowOrders(name order, name tag)
00286	{
00287		if (Order != '')
00288		{
00289	//		bTaskLocked = true;
00290			OrderObject = ActorTagged(Tag);
00291			GotoState(Order);
00292			return true;
00293		}
00294	
00295		return false;
00296	}
00297	
00298	//============================================================
00299	//
00300	// BodyPartForJoint
00301	//
00302	// Returns the body part a joint is associated with
00303	//============================================================
00304	function int BodyPartForJoint(int joint)
00305	{
00306		switch(joint)
00307		{
00308			case 24:					return BODYPART_LARM1;
00309			case 31:					return BODYPART_RARM1;
00310			case 6:  case 7:			return BODYPART_RLEG1;
00311			case 2:  case 3:			return BODYPART_LLEG1;
00312			case 17:					return BODYPART_HEAD;
00313			case 11:					return BODYPART_TORSO;
00314			default:					return BODYPART_BODY;
00315		}
00316	}
00317	
00318	//============================================================
00319	//
00320	// BodyPartForPolyGroup
00321	//
00322	//============================================================
00323	function int BodyPartForPolyGroup(int polygroup)
00324	{
00325		return BODYPART_BODY;
00326	}
00327	
00328	//============================================================
00329	//
00330	// BodyPartSeverable
00331	//
00332	//============================================================
00333	function bool BodyPartSeverable(int BodyPart)
00334	{
00335		switch(BodyPart)
00336		{
00337			case BODYPART_HEAD:
00338				return true;
00339			case BODYPART_LARM1:
00340			case BODYPART_RARM1:
00341				if(Level.Game != None)
00342					return (Level.NetMode != NM_StandAlone && Level.Game.bAllowLimbSever);
00343				else
00344					return (Level.NetMode != NM_StandAlone);
00345		}
00346		return false;
00347	}
00348	
00349	//============================================================
00350	//
00351	// BodyPartCritical
00352	//
00353	//============================================================
00354	function bool BodyPartCritical(int BodyPart)
00355	{
00356		return (BodyPart == BODYPART_HEAD);
00357	}
00358	
00359	//============================================================
00360	//
00361	// ApplyGoreCap
00362	//
00363	//============================================================
00364	function ApplyGoreCap(int BodyPart)
00365	{
00366	}
00367	
00368	//================================================
00369	//
00370	// SeveredLimbClass
00371	//
00372	// Override in subclasses
00373	//================================================
00374	function class<Actor> SeveredLimbClass(int BodyPart)
00375	{
00376		return None;
00377	}
00378	
00379	//============================================================
00380	//
00381	// LimbSevered
00382	//
00383	//============================================================
00384	function LimbSevered(int BodyPart, vector Momentum)
00385	{
00386		local int joint;
00387		local actor part;
00388		local vector X,Y,Z,pos;
00389		local class<actor> partclass;
00390	
00391		ApplyGoreCap(BodyPart);
00392		partclass = SeveredLimbClass(BodyPart);
00393	
00394		switch(BodyPart)
00395		{
00396			case BODYPART_LARM1:
00397				DropShield();
00398				joint = JointNamed('lshouldb');
00399				pos = GetJointPos(joint);
00400				GetAxes(Rotation, X, Y, Z);
00401				part = Spawn(partclass,,, pos, Rotation);
00402				if(part != None)
00403				{
00404					part.DrawScale = 1.0; // Necessary to scale down SarkArms
00405					part.Velocity = -Y * 100 + vect(0, 0, 175);
00406					part.GotoState('Drop');
00407				}
00408				part = Spawn(class'BloodSpurt', self,, pos, Rotation);
00409				if(part != None)
00410				{
00411					AttachActorToJoint(part, joint);
00412				}
00413				break;
00414		
00415			case BODYPART_RARM1:
00416				LastHeldWeapon = None; // No retrieving
00417				DropWeapon();
00418				joint = JointNamed('rshouldb');
00419				pos = GetJointPos(joint);
00420				GetAxes(Rotation, X, Y, Z);
00421				part = Spawn(partclass,,, pos, Rotation);
00422				if(part != None)
00423				{
00424					part.DrawScale = 1.0; // Necessary to scale down SarkArms
00425					part.Velocity = Y * 100 + vect(0, 0, 175);
00426					part.GotoState('Drop');
00427				}
00428				part = Spawn(class'BloodSpurt', self,, pos, Rotation);
00429				if(part != None)
00430				{
00431					AttachActorToJoint(part, joint);
00432				}
00433				break;
00434			case BODYPART_HEAD:
00435				joint = JointNamed('head');
00436				pos = GetJointPos(joint);
00437				part = Spawn(partclass,,, pos, Rotation);
00438				if(part != None)
00439				{
00440					part.Velocity = 0.75 * (momentum / Mass) + vect(0, 0, 300);
00441					part.GotoState('Drop');
00442				}
00443				part = Spawn(class'BloodSpurt', self,, pos, Rotation);
00444				if(part != None)
00445				{
00446					AttachActorToJoint(part, joint);
00447				}
00448				break;
00449		}
00450	
00451		SetMovementMode(); // Set combat or exploration mode (player could lose an arm)
00452	}
00453	
00454	
00455	//=============================================================================
00456	//
00457	// DamageBodyPart
00458	//
00459	//=============================================================================
00460	
00461	function bool DamageBodyPart(int Damage, Pawn EventInstigator, vector HitLocation, vector Momentum, name DamageType, int bodypart)
00462	{
00463		if(bBloodLust)
00464		{
00465			Damage /= 2;
00466			Strength -= Damage;
00467			if(Strength > 0)
00468				return(true);  // Damage to Ragnar takes away his bloodlust (but doesn't damage him)
00469			else
00470				Damage = -Strength * 2;
00471			
00472			// Force the strength to atrophy by removing the last strength point
00473			Strength = 1;
00474			StrengthDecay(999.0); // force the strength to atrophy
00475	
00476			// Then, this passes through and the remainder damage is applied to Ragnar
00477		}
00478	
00479		return(Super.DamageBodyPart(Damage, EventInstigator, HitLocation, Momentum, DamageType, bodyPart));
00480	}
00481	
00482	function SetOnFire(Pawn EventInstigator, int joint)
00483	{
00484		local PawnFire F;
00485	
00486		if (bBurnable)
00487		{
00488			if (ActorAttachedTo(joint) == None)
00489			{
00490				F = Spawn(class'PawnFire',EventInstigator);
00491				if (F != None)
00492				{
00493					AttachActorToJoint(F, joint);
00494				}
00495			}
00496		}
00497	}
00498	
00499	//=============================================================================
00500	//
00501	// JointDamaged
00502	//
00503	// Only overridden for the VikingAxe Empathy powerup in multiplayer
00504	//=============================================================================
00505	
00506	function bool JointDamaged(int Damage, Pawn EventInstigator, vector HitLoc, vector Momentum, name DamageType, int joint)
00507	{
00508		local int halfDamage;
00509	
00510		if(Weapon != None && Weapon.IsA('VikingAxe') && Weapon.bPoweredup && Level.Netmode != NM_StandAlone)
00511		{ // Multiplayer only Empathy weapon on the VikingAxe.  If a player with empathy enabled is hit
00512			// by an opponent, then the opponent will receive 1/2 of the damage
00513			halfDamage = Damage / 2;
00514			Damage -= halfDamage; // Adjust the amount of damage taken by this player
00515	
00516			if(!EventInstigator.IsA('PlayerPawn') || PlayerPawn(EventInstigator).Weapon == None
00517				|| !PlayerPawn(EventInstigator).Weapon.IsA('VikingAxe') || !PlayerPawn(EventInstigator).Weapon.bPoweredUp)
00518			{ // Guard against infinite loops if more than one person has empathy enabled
00519				EventInstigator.JointDamaged(halfDamage, EventInstigator, HitLoc, Momentum, DamageType, 0);
00520				Spawn(class'EmpathyFlash',,,HitLoc,);
00521			}
00522		}
00523	
00524		// Damage the originally struck player
00525		Super.JointDamaged(Damage, EventInstigator, HitLoc, Momentum, DamageType, joint);
00526	}
00527	
00528	// Animation Functions
00529	
00530	//=============================================================================
00531	//
00532	// GetGroup
00533	//
00534	//=============================================================================
00535	
00536	function Name GetGroup(Name AnimSequence)
00537	{
00538		//TODO: Order these by how often they are playing for speed (waiting/running first)
00539		if(AnimSequence == 'MOV_ALL_jump1_AA0S')			return('Moving');
00540		else if(AnimSequence == 'MOV_ALL_run1_AA0N')		return('Moving');
00541		else if(AnimSequence == 'MOV_ALL_run1_AA0S')		return('Moving');
00542		else if(AnimSequence == 'MOV_ALL_run1_AN0N')		return('Moving');
00543		else if(AnimSequence == 'MOV_ALL_run1_AN0S')		return('Moving');
00544		else if(AnimSequence == 'MOV_ALL_lstrafe1_AA0S')	return('Moving');
00545		else if(AnimSequence == 'MOV_ALL_lstrafe1_AN0N')	return('Moving');
00546		else if(AnimSequence == 'MOV_ALL_rstrafe1_AA0S')	return('Moving');
00547		else if(AnimSequence == 'MOV_ALL_rstrafe1_AN0N')	return('Moving');
00548		else if(AnimSequence == 'MOV_ALL_runback1_AA0S')	return('Moving');
00549		else if(AnimSequence == 'MOV_ALL_pullup1_AA0N')		return('Moving');
00550		else if(AnimSequence == 'pullup')					return('Moving');
00551		else if(AnimSequence == 'ropetest')					return('Moving');
00552	
00553		// Waiting
00554		else if(AnimSequence == 'neutral_defend')			return('Waiting');
00555		else if(AnimSequence == 'neutral_idle')				return('Waiting');
00556		else if(AnimSequence == 'Neutral_kick')				return('Waiting');
00557		else if(AnimSequence == 's1_defendPose')			return('Waiting');
00558		else if(AnimSequence == 'IDL_ALL_crbreathe1_AN0N')	return('Waiting');
00559		else if(AnimSequence == 'IDL_ALL_crbreathe1_AA0N')	return('Waiting');
00560		else if(AnimSequence == 'IDL_ALL_crbreathe1_AN0S')	return('Waiting');
00561		else if(AnimSequence == 'IDL_ALL_crbreathe1_AA0S')	return('Waiting');
00562	
00563		else if(AnimSequence == 'S1_Throw')		return('Throwing');
00564		else if(AnimSequence == 'S2_Throw')		return('Throwing');
00565		else if(AnimSequence == 'S3_Throw')		return('Throwing');
00566		else if(AnimSequence == 'S4_Throw')		return('Throwing');
00567		else if(AnimSequence == 'S5_Throw')		return('Throwing');
00568	
00569		else if(AnimSequence == 'H1_Throw')		return('Throwing');
00570		else if(AnimSequence == 'H2_Throw')		return('Throwing');
00571		else if(AnimSequence == 'H3_Throw')		return('Throwing');
00572		else if(AnimSequence == 'H4_Throw')		return('Throwing');
00573		else if(AnimSequence == 'H5_Throw')		return('Throwing');
00574	
00575		else if(AnimSequence == 'X1_Throw')		return('Throwing');
00576		else if(AnimSequence == 'X2_Throw')		return('Throwing');
00577		else if(AnimSequence == 'X3_Throw')		return('Throwing');
00578		else if(AnimSequence == 'X4_Throw')		return('Throwing');
00579		else if(AnimSequence == 'X5_Throw')		return('Throwing');
00580	
00581		if(Weapon != None)
00582		{ // TODO!  Check weapon anims versus AnimSequence to see if Ragnar is moving
00583			if(AnimSequence == Weapon.A_Forward
00584				|| AnimSequence == Weapon.A_Backward
00585				|| AnimSequence == Weapon.A_StrafeLeft
00586				|| AnimSequence == Weapon.A_StrafeRight
00587				|| AnimSequence == Weapon.A_Forward45Left
00588				|| AnimSequence == Weapon.A_Forward45Right
00589				|| AnimSequence == Weapon.A_Backward45Left
00590				|| AnimSequence == Weapon.A_Backward45Right
00591				|| AnimSequence == Weapon.A_Jump)
00592			{ // Playing a movement attack animation
00593				return('Moving');		
00594			}
00595			else if(AnimSequence == Weapon.A_AttackA
00596				|| AnimSequence == Weapon.A_AttackAReturn
00597				|| AnimSequence == Weapon.A_AttackB
00598				|| AnimSequence == Weapon.A_AttackBReturn
00599				|| AnimSequence == Weapon.A_AttackC
00600				|| AnimSequence == Weapon.A_AttackCReturn
00601				|| AnimSequence == Weapon.A_AttackD
00602				|| AnimSequence == Weapon.A_AttackDReturn
00603				|| AnimSequence == Weapon.A_AttackBackupA
00604				|| AnimSequence == Weapon.A_AttackBackupAReturn
00605				|| AnimSequence == Weapon.A_AttackBackupB
00606				|| AnimSequence == Weapon.A_AttackBackupAReturn)
00607			{ // Playing a movement attack animation
00608				return('AttackMoving');		
00609			}
00610			else if(AnimSequence == Weapon.A_AttackStandA
00611				|| AnimSequence == Weapon.A_AttackStandAReturn
00612				|| AnimSequence == Weapon.A_AttackStandB
00613				|| AnimSequence == Weapon.A_AttackStandBReturn)
00614			{ // Playing a standing attack animation
00615				return('AttackStanding');		
00616			}
00617			else if(AnimSequence == Weapon.A_Throw)		return('Throwing');
00618			else if(AnimSequence == Weapon.A_Idle)		return('Waiting');
00619			else if(AnimSequence == Weapon.A_Powerup)	return('Powerup');
00620			else if(AnimSequence == Weapon.A_JumpAttack) return('JumpAttack');
00621		}
00622	
00623		return('None');	
00624	}
00625	
00626	//=============================================================================
00627	//
00628	// PlayJump
00629	//
00630	//=============================================================================
00631	
00632	function PlayJump()
00633	{
00634		local name anim;
00635	
00636		if(Weapon != None && Weapon.A_Jump != '')
00637			anim = Weapon.A_Jump;
00638		else
00639			anim = 'MOV_ALL_jump1_AA0S';
00640		
00641		PlayAnim(anim, 1.0, 0.1);
00642	
00643		if(AnimProxy != None)
00644			AnimProxy.TryPlayAnim(anim, 1.0, 0.1);
00645	
00646		// Play Jump Grunt Sound
00647		PlaySound(JumpGruntSound[Rand(3)], SLOT_Talk, 1.0, false, 1200, FRand() * 0.08 + 0.96);
00648	}
00649	
00650	//=============================================================================
00651	//
00652	// PlayRopeLeapOff
00653	//
00654	//=============================================================================
00655	
00656	function PlayRopeLeapOff()
00657	{
00658		PlayAnim('MOV_ALL_jump1_AA0S', 1.0, 0.1);
00659	
00660		if(AnimProxy != None)
00661			AnimProxy.PlayAnim('MOV_ALL_jump1_AA0S', 1.0, 0.1);
00662	
00663		// Play Jump Grunt Sound
00664		PlaySound(JumpGruntSound[Rand(3)], SLOT_Talk, 1.0, false, 1200, FRand() * 0.08 + 0.96);
00665	}
00666	
00667	//=============================================================================
00668	//
00669	// PlayTakeHit
00670	//
00671	//=============================================================================
00672	
00673	function PlayTakeHit(float tweentime, int damage, vector HitLoc, name damageType, vector Momentum, int BodyPart)
00674	{
00675		local float rnd;
00676		local float time;
00677	
00678		rnd = FClamp(Damage, 10, 40);
00679		if ( damageType == 'burned' )
00680			ClientFlash( -0.009375 * rnd, rnd * vect(16.41, 11.719, 4.6875));
00681		else if ( damageType == 'corroded' )
00682			ClientFlash( -0.01171875 * rnd, rnd * vect(9.375, 14.0625, 4.6875));
00683		else if ( damageType == 'drowned' )
00684			ClientFlash(-0.390, vect(312.5,468.75,468.75));
00685		else 
00686			ClientFlash( -0.017 * rnd, rnd * vect(24, 4, 4));
00687	
00688		time = 0.15 + 0.005 * Damage;
00689		ShakeView(time, Damage * 10, time * 0.5);
00690	
00691		Super.PlayTakeHit(tweentime, damage, HitLoc, damageType, Momentum, BodyPart);
00692	}
00693	
00694	//=============================================================================
00695	//
00696	// PlayTurning
00697	//
00698	//=============================================================================
00699	
00700	function PlayTurning(optional float tween)
00701	{
00702	}
00703	
00704	//=============================================================================
00705	//
00706	// PlayRising
00707	//
00708	// Obsolete Unreal Code
00709	//=============================================================================
00710	
00711	function PlayRising()
00712	{
00713	}
00714	
00715	//=============================================================================
00716	//
00717	// PlayFeignDeath
00718	//
00719	// Obsolete Unreal Code
00720	//=============================================================================
00721	
00722	function PlayFeignDeath()
00723	{
00724	}
00725	
00726	//=============================================================================
00727	//
00728	// PlayWeaponSwitch
00729	//
00730	// Obsolete Unreal Code
00731	//=============================================================================
00732			
00733	function PlayWeaponSwitch(Weapon NewWeapon)
00734	{
00735	}
00736	
00737	//=============================================================================
00738	//
00739	// PlayFrontHit
00740	//
00741	// NOTE:  Hit functions force the torso to play the hit animation
00742	//=============================================================================
00743	
00744	function PlayFrontHit(float tweentime)
00745	{
00746		if(Weapon == None)
00747		{ // Neutral anims
00748			TryPlayTorsoAnim('n_painFront', 1.0, 0.1);
00749	
00750			if(AnimProxy != None)
00751				AnimProxy.PlayAnim('n_painFront', 1.0, 0.1);
00752		}
00753		else
00754		{ // Weapon-specific
00755			TryPlayTorsoAnim(Weapon.A_PainFront, 1.0, 0.1);
00756	
00757			if(AnimProxy != None)
00758				AnimProxy.PlayAnim(Weapon.A_PainFront, 1.0, 0.1);
00759		}
00760	}
00761	
00762	//=============================================================================
00763	//
00764	// PlayBackHit
00765	//
00766	// NOTE:  Hit functions force the torso to play the hit animation
00767	//=============================================================================
00768	
00769	function PlayBackHit(float tweentime)
00770	{
00771		if(Weapon == None)
00772		{ // Neutral anims
00773			TryPlayTorsoAnim('n_painBack', 1.0, 0.1);
00774	
00775			if(AnimProxy != None)
00776				AnimProxy.PlayAnim('n_painBack', 1.0, 0.1);
00777		}
00778		else
00779		{ // Weapon-specific
00780			TryPlayTorsoAnim(Weapon.A_PainBack, 1.0, 0.1);
00781	
00782			if(AnimProxy != None)
00783				AnimProxy.PlayAnim(Weapon.A_PainBack, 1.0, 0.1);
00784		}
00785	}
00786	
00787	//=============================================================================
00788	//
00789	// PlayGutHit
00790	//
00791	// NOTE:  Hit functions force the torso to play the hit animation
00792	//=============================================================================
00793	
00794	function PlayGutHit(float tweentime)
00795	{
00796		PlayBackHit(tweentime);
00797	}
00798	
00799	//=============================================================================
00800	//
00801	// PlayHeadHit
00802	//
00803	// NOTE:  Hit functions force the torso to play the hit animation
00804	//=============================================================================
00805	
00806	function PlayHeadHit(float tweentime)
00807	{
00808		PlayFrontHit(tweentime);
00809	}
00810	
00811	//=============================================================================
00812	//
00813	// PlayLeftHit
00814	//
00815	// NOTE:  Hit functions force the torso to play the hit animation
00816	//=============================================================================
00817	
00818	function PlayLeftHit(float tweentime)
00819	{
00820		if(Weapon == None)
00821		{ // Neutral anims
00822			TryPlayTorsoAnim('s1_painLeft', 1.0, 0.08);
00823	
00824			if(AnimProxy != None)
00825				AnimProxy.PlayAnim('s1_painLeft', 1.0, 0.08);
00826		}
00827		else
00828		{ // Weapon-specific
00829			TryPlayTorsoAnim(Weapon.A_PainLeft, 1.0, 0.1);
00830	
00831			if(AnimProxy != None)
00832				AnimProxy.PlayAnim(Weapon.A_PainLeft, 1.0, 0.1);
00833		}
00834	}
00835	
00836	//=============================================================================
00837	//
00838	// PlayRightHit
00839	//
00840	// NOTE:  Hit functions force the torso to play the hit animation
00841	//=============================================================================
00842	
00843	function PlayRightHit(float tweentime)
00844	{
00845		if(Weapon == None)
00846		{ // Neutral anims
00847			TryPlayTorsoAnim('s1_painRight', 1.0, 0.08);
00848	
00849			if(AnimProxy != None)
00850				AnimProxy.PlayAnim('s1_painRight', 1.0, 0.08);
00851		}
00852		else
00853		{ // Weapon-specific
00854			TryPlayTorsoAnim(Weapon.A_PainRight, 1.0, 0.1);
00855	
00856			if(AnimProxy != None)
00857				AnimProxy.PlayAnim(Weapon.A_PainRight, 1.0, 0.1);
00858		}
00859	}
00860	
00861	//=============================================================================
00862	//
00863	// PlayDrowning
00864	//
00865	// NOTE:  Hit functions force the torso to play the hit animation
00866	//=============================================================================
00867	
00868	function PlayDrowning(float tweentime)
00869	{
00870		local int joint;
00871		local vector l;
00872		local name anim;
00873	
00874		if(HeadRegion.Zone.bWaterZone)
00875		{
00876			// Spawn Bubbles
00877			joint = JointNamed('jaw');
00878			l = GetJointPos(joint);
00879			if(FRand() < 0.75)
00880			{
00881				Spawn(class'BubbleSystemOneShot',,, l,);
00882			}
00883		}
00884	
00885		if(AnimSequence == 'SwimUnderWaterDown')
00886		{ // This anim sequence doesn't have a pain animation
00887			return;
00888		}
00889	
00890		if(AnimSequence == 'Treadwateridle' || AnimSequence == 'Swimbackwards' || AnimSequence == 'Swimbackwards45Left'
00891			|| AnimSequence == 'Swimbackwards45Right' || AnimSequence == 'SwimUnderWaterUp')
00892		{
00893			anim = 'treadpain'; // Treading in water pain
00894		}
00895		else
00896			anim = 'swimpain'; // normal swimming pain
00897			
00898		TryPlayTorsoAnim(anim, 1.0, 0.1);	
00899		if(AnimProxy != None)
00900			AnimProxy.PlayAnim(anim, 1.0, 0.1);
00901	}
00902	
00903	function PlayDeath(name DamageType)
00904	{
00905		local name anim;
00906		local float tween;
00907	
00908		tween = 0.1;
00909	
00910		if(DamageType == 'fire')
00911			anim = 'DeathF';
00912		else if(DamageType == 'fell')
00913		{
00914			anim = 'DeathImpact';
00915		}
00916		else
00917		{ // Normal death, randomly choose one
00918			anim = 'DTH_ALL_death1_AN0N';
00919	
00920			switch(RandRange(0, 5))
00921			{
00922			case 0:
00923				anim = 'DTH_ALL_death1_AN0N';
00924				break;
00925			case 1:
00926				anim = 'DeathH';
00927				break;
00928			case 2:
00929				anim = 'DeathL';
00930				break;
00931			case 3:
00932				anim = 'DeathB';
00933				break;
00934			case 4:
00935				anim = 'DeathKnockback';
00936				break;
00937			default:
00938				anim = 'DTH_ALL_death1_AN0N';
00939				break;
00940			}
00941		}
00942	
00943		PlayAnim(anim, 1.0, tween);
00944		if(AnimProxy != None)
00945			AnimProxy.PlayAnim(anim, 1.0, tween);
00946	}
00947	
00948	function PlayBackDeath(name DamageType)		
00949	{
00950		local name anim;
00951	
00952		if(FRand() < 0.25)
00953			anim = 'DeathH';
00954		else
00955			anim  = 'DeathFront';
00956	
00957		PlayAnim(anim, 1.0, 0.1);
00958		if(AnimProxy != None)
00959			AnimProxy.PlayAnim(anim, 1.0, 0.1);	
00960	}
00961	
00962	function PlayLeftDeath(name DamageType)		{ PlayDeath(DamageType);			}
00963	function PlayRightDeath(name DamageType)	{ PlayDeath(DamageType);			}
00964	function PlayHeadDeath(name DamageType)		
00965	{
00966		PlayAnim('DeathH', 1.0, 0.1);
00967		if(AnimProxy != None)
00968			AnimProxy.PlayAnim('DeathH', 1.0, 0.1);	
00969	}
00970	
00971	function PlayDrownDeath(name DamageType)	
00972	{
00973		PlayAnim('Drown', 1.0, 0.1);
00974		if(AnimProxy != None)
00975			AnimProxy.PlayAnim('Drown', 1.0, 0.1);	
00976	}
00977	
00978	function PlayGibDeath(name DamageType)		{ Super.PlayGibDeath(DamageType);	}
00979	
00980	function PlaySkewerDeath(name DamageType)	  
00981	{
00982		PlayAnim('deathb', 1.0, 0.1);	
00983		if(AnimProxy != None)
00984			AnimProxy.PlayAnim('deathb', 1.0, 0.1);	
00985	}
00986	
00987	//=============================================================================
00988	//
00989	// PlayFiring
00990	//
00991	//=============================================================================
00992	
00993	function PlayFiring()
00994	{
00995		if(GetStateName() == 'PlayerSwimming')
00996			return;
00997	
00998		if(AnimProxy != None)
00999			AnimProxy.Attack();
01000	
01001		if(Velocity.X * Velocity.X + Velocity.Y * Velocity.Y >= 1000)
01002			PlayMoving();
01003	}
01004	
01005	//=============================================================================
01006	//
01007	// PlayAltFiring 
01008	//
01009	//=============================================================================
01010	
01011	function PlayAltFiring()
01012	{
01013		if(GetStateName() == 'PlayerSwimming')
01014			return;
01015	
01016		if(AnimProxy != None)
01017			AnimProxy.Defend();
01018	/*
01019		if(AnimProxy.Defend() && GetGroup(AnimSequence) == 'Waiting')
01020		{
01021			PlayAnim(RunePlayerProxy(AnimProxy).TorsoAnim, 1.0, 0.1);
01022		}
01023	*/
01024	}
01025	
01026	//=============================================================================
01027	//
01028	// PlayMoving
01029	//
01030	//=============================================================================
01031	
01032	function PlayMoving(optional float tween)
01033	{
01034		local name LowerName, UpperName;
01035		local bool bDefending;
01036		local float dp;
01037		local vector X, Y, Z;
01038		local bool bRight;
01039		local MovementDir_e dir;
01040	
01041		if (health <= 0)
01042			return;
01043		
01044		if(AnimProxy != None)
01045			bDefending = (AnimProxy.GetStateName() == 'Defending');
01046		else
01047			bDefending = false;
01048	
01049		// Determine the direction the player is attempting to move
01050		GetAxes(Rotation, X, Y, Z);
01051		dp = vector(Rotation) dot Normal(Acceleration);
01052	
01053		if(Normal(Acceleration) dot Y >= 0)
01054		{
01055			bRight = true;
01056		}
01057	
01058		if(dp > 0.9)
01059		{ // Distinctly forward
01060			dir = MD_FORWARD;
01061		}
01062		else if(dp > 0.5)
01063		{ // forward left/right
01064			if(bRight)
01065			{
01066				if (!bMirrored)
01067					dir = MD_FORWARDRIGHT;
01068				else
01069					dir = MD_FORWARDLEFT;
01070			}
01071			else
01072			{
01073				if (!bMirrored)
01074					dir = MD_FORWARDLEFT;
01075				else
01076					dir = MD_FORWARDRIGHT;
01077			}
01078		}
01079		else if(dp < -0.9)
01080		{ // Distinctly backward
01081			dir = MD_BACKWARD;		
01082		}
01083		else if(dp < -0.5)
01084		{ // backward left/right
01085			if(bRight)
01086			{
01087				if (!bMirrored)
01088					dir = MD_BACKWARDRIGHT;
01089				else
01090					dir = MD_BACKWARDLEFT;
01091			}
01092			else
01093			{
01094				if (!bMirrored)
01095					dir = MD_BACKWARDLEFT;
01096				else
01097					dir = MD_BACKWARDRIGHT;
01098			}
01099		}
01100		else if(bRight)
01101		{ // Strafe right
01102			if (!bMirrored)
01103				dir = MD_RIGHT;
01104			else
01105				dir = MD_LEFT;
01106		}
01107		else
01108		{ // Strafe left
01109			if (!bMirrored)
01110				dir = MD_LEFT;
01111			else
01112				dir = MD_RIGHT;
01113		}
01114	
01115		// If Attacking and running foward or backward, then let the upper body handle the leg motion
01116		if(AnimProxy != None && AnimProxy.GetStateName() == 'Attacking')
01117		{
01118			if(GetGroup(AnimSequence) == 'JumpAttack')
01119				return;
01120			if((dir == MD_FORWARD || dir == MD_BACKWARD) && (GetGroup(AnimSequence) == 'AttackMoving'
01121				&& AnimSequence != 'ghostthrow'))
01122				return;
01123		}
01124	
01125		// Set the proper animation based upon the motion
01126		LowerName = 'MOV_ALL_run1_AA0N';
01127	
01128		if(Weapon == None)
01129		{ // Explore mode
01130			if(!bIsCrouching)
01131			{
01132				switch(dir)
01133				{
01134				case MD_FORWARD:
01135					LowerName = 'MOV_ALL_run1_AA0N';
01136					break;
01137				case MD_FORWARDRIGHT:
01138					LowerName = 'MOV_ALL_rstrafe1_AA0S';
01139					break;
01140				case MD_FORWARDLEFT:
01141					LowerName = 'MOV_ALL_lstrafe1_AA0S';
01142					break;
01143				case MD_BACKWARD:
01144					LowerName = 'MOV_ALL_runback1_AA0S';
01145					break;
01146				case MD_BACKWARDRIGHT:
01147					LowerName = 'MOV_ALL_lstrafe1_AA0S';
01148					break;
01149				case MD_BACKWARDLEFT:
01150					LowerName = 'MOV_ALL_rstrafe1_AA0S';
01151					break;
01152				case MD_RIGHT:
01153					LowerName = 'MOV_ALL_rstrafe1_AN0N';
01154					break;
01155				case MD_LEFT:
01156					LowerName = 'MOV_ALL_lstrafe1_AN0N';
01157					break;
01158				default:
01159					break;
01160				}
01161	
01162				if(LowerName == 'MOV_ALL_run1_AA0N')
01163				{
01164					// Upper-body animation
01165					if(Shield == None)
01166					{
01167						UpperName = 'MOV_ALL_run1_AN0N'; 
01168					}
01169					else
01170					{
01171						UpperName = 'MOV_ALL_run1_AN0S';
01172					}
01173				}
01174				else
01175				{ // Strafing, so match the upper-body with the lower-body
01176					UpperName = LowerName;
01177				}
01178			}
01179			else
01180			{ // Crouching
01181				switch(dir)
01182				{
01183				case MD_FORWARD:
01184					LowerName = 'crouch_walkforward';
01185					break;
01186				case MD_FORWARDRIGHT:
01187					LowerName = 'crouch_walkforward45Right';
01188					break;
01189				case MD_FORWARDLEFT:
01190					LowerName = 'crouch_walkforward45Left';
01191					break;
01192				case MD_BACKWARD:
01193					LowerName = 'crouch_walkbackward';
01194					break;
01195				case MD_BACKWARDRIGHT:
01196					LowerName = 'crouch_walkbackward45Right';
01197					break;
01198				case MD_BACKWARDLEFT:
01199					LowerName = 'crouch_walkbackward45Left';
01200					break;
01201				case MD_RIGHT:
01202					LowerName = 'crouch_straferight';
01203					break;
01204				case MD_LEFT:
01205					LowerName = 'crouch_strafeleft';
01206					break;
01207				default:
01208					break;
01209				}
01210	
01211				UpperName = LowerName;
01212			}
01213		}
01214		else
01215		{ // Combat Mode
01216			if(!bIsCrouching)
01217			{
01218				switch(dir)
01219				{
01220				case MD_FORWARD:
01221					if(!bDefending)
01222					{
01223						if(AnimProxy.GetStateName() == 'Attacking')
01224						{
01225							LowerName = Weapon.A_ForwardAttack;
01226						}
01227						else
01228						{
01229							LowerName = Weapon.A_Forward;
01230						}
01231					}
01232					else
01233						LowerName = 'weapon_DefendWalk'; //Weapon.ForwardAnim;
01234					break;
01235				case MD_FORWARDRIGHT:
01236					if(!bDefending)
01237						LowerName = Weapon.A_Forward45Right;
01238					else
01239						LowerName = 'weapon_DefendWalk45Right';
01240					break;
01241				case MD_FORWARDLEFT:
01242					if(!bDefending)
01243						LowerName = Weapon.A_Forward45Left;
01244					else
01245						LowerName = 'weapon_DefendWalk45Left';
01246					break;
01247				case MD_BACKWARD:
01248					if(!bDefending)
01249						LowerName = Weapon.A_Backward;
01250					else
01251						LowerName = 'weapon_DefendBackup';
01252					break;
01253				case MD_BACKWARDRIGHT:
01254					if(!bDefending)
01255						LowerName = Weapon.A_Backward45Right;
01256					else
01257						LowerName = 'weapon_DefendBackup45Right';
01258					break;
01259				case MD_BACKWARDLEFT:
01260					if(!bDefending)
01261						LowerName = Weapon.A_Backward45Left;
01262					else
01263						LowerName = 'weapon_DefendBackup45Left';
01264					break;
01265				case MD_RIGHT:
01266					if(!bDefending)
01267						LowerName = Weapon.A_StrafeRight;
01268					else
01269						LowerName = Weapon.A_StrafeRight;
01270					break;
01271				case MD_LEFT:
01272					if(!bDefending)
01273						LowerName = Weapon.A_StrafeLeft;
01274					else
01275						LowerName = Weapon.A_StrafeLeft;
01276					break;
01277				default:
01278					break;
01279				}
01280			}
01281			else
01282			{ // Crouch
01283				switch(dir)
01284				{
01285				case MD_FORWARD:
01286					if(Weapon.bCrouchTwoHands)
01287						LowerName = 'crouch_walkforward2hands';
01288					else
01289						LowerName = 'crouch_walkforward';
01290					break;
01291				case MD_FORWARDRIGHT:
01292					if(Weapon.bCrouchTwoHands)
01293						LowerName = 'crouch_walkforward45Right2hands';
01294					else
01295						LowerName = 'crouch_walkforward45Right';
01296					break;
01297				case MD_FORWARDLEFT:
01298					if(Weapon.bCrouchTwoHands)
01299						LowerName = 'crouch_walkforward45Left2hands';
01300					else
01301						LowerName = 'crouch_walkforward45Left';
01302					break;
01303				case MD_BACKWARD:
01304					if(Weapon.bCrouchTwoHands)
01305						LowerName = 'crouch_walkbackward2hands';
01306					else
01307						LowerName = 'crouch_walkbackward';
01308					break;
01309				case MD_BACKWARDRIGHT:
01310					if(Weapon.bCrouchTwoHands)
01311						LowerName = 'crouch_walkbackward45Right2hands';
01312					else
01313						LowerName = 'crouch_walkbackward45Right';
01314					break;
01315				case MD_BACKWARDLEFT:
01316					if(Weapon.bCrouchTwoHands)
01317						LowerName = 'crouch_walkbackward45Left2hands';
01318					else
01319						LowerName = 'crouch_walkbackward45Left';
01320					break;
01321				case MD_RIGHT:
01322					if(Weapon.bCrouchTwoHands)
01323						LowerName = 'crouch_straferight2hands';
01324					else
01325						LowerName = 'crouch_straferight';
01326					break;
01327				case MD_LEFT:
01328					if(Weapon.bCrouchTwoHands)
01329						LowerName = 'crouch_strafeleft2hands';
01330					else
01331						LowerName = 'crouch_strafeleft';
01332					break;
01333				default:
01334					break;
01335				}
01336			}
01337	
01338			UpperName = LowerName;
01339		}
01340	
01341		LoopAnim(LowerName, 1.0, 0.1);
01342	
01343		if(AnimProxy != None)
01344			AnimProxy.TryLoopAnim(UpperName, 1.0, 0.1);
01345	}
01346	
01347	//=============================================================================
01348	//
01349	// PlayInAir
01350	//
01351	//=============================================================================
01352	
01353	function PlayInAir(optional float tween)
01354	{
01355		local name anim;
01356	
01357		if(Weapon != None && Weapon.A_Jump != '')
01358			anim = Weapon.A_Jump;
01359		else
01360			anim = 'MOV_ALL_jump1_AA0S';
01361		
01362		PlayAnim(anim, 1.0, 0.1);
01363	
01364		if(AnimProxy != None)
01365			AnimProxy.TryPlayAnim(anim, 1.0, 0.1);
01366	/*
01367		PlayAnim('MOV_ALL_run1_AA0N', 0.1, tween);
01368	
01369		if(AnimProxy != None)
01370			AnimProxy.TryPlayAnim('MOV_ALL_run1_AA0N', 0.1, tween);
01371	*/
01372	}
01373	
01374	//=============================================================================
01375	//
01376	// PlayPullUp
01377	//
01378	//=============================================================================
01379	
01380	function PlayPullUp(optional float tween)
01381	{
01382		PlaySound(EdgeGrabSound, SLOT_Talk, 1.0, false, 1200, FRand() * 0.4 + 0.8);
01383	
01384		PlayAnim('intropullupA', 1.0, tween); // No tween
01385	
01386		if(AnimProxy != None)
01387			AnimProxy.TryPlayAnim('intropullupA', 1.0, tween);
01388	}
01389	
01390	//=============================================================================
01391	//
01392	// PlayStepUp
01393	//
01394	//=============================================================================
01395	
01396	function PlayStepUp(optional float tween)
01397	{
01398		PlaySound(StepupSound, SLOT_Talk, 1.0, false, 1200, FRand() * 0.4 + 0.8);
01399	
01400		PlayAnim('pullupTest', 1.0, tween);
01401	
01402		if(AnimProxy != None)
01403			AnimProxy.TryPlayAnim('pullupTest', 1.0, tween);
01404	}
01405	
01406	//=============================================================================
01407	//
01408	// PlayDuck
01409	//
01410	//=============================================================================
01411	
01412	function PlayDuck(optional float tween)
01413	{
01414		local name n;
01415	
01416		if(Weapon == None || !Weapon.bCrouchTwoHands)
01417			n = 'crouch_idle';
01418		else
01419			n = 'crouch_idle2hands';
01420	
01421		LoopAnim(n, 1.0, 0.1);
01422		if(AnimProxy != None)
01423			AnimProxy.TryPlayAnim(n, 1.0, 0.1);
01424	}
01425	
01426	//=============================================================================
01427	//
01428	// PlayCrawling
01429	//
01430	//=============================================================================
01431	
01432	function PlayCrawling(optional float tween)
01433	{
01434		PlayMoving(tween);
01435	}
01436	
01437	
01438	//=============================================================================
01439	//
01440	// PlayWaiting
01441	//
01442	//=============================================================================
01443	
01444	function PlayWaiting(optional float tween)
01445	{
01446		local Name n;
01447		local name group;
01448	
01449		if(Health <= 0)
01450			return;
01451	
01452		group = GetGroup(AnimSequence);
01453		if(group == 'Powerup')
01454		{ // Don't play wait anim if playing powerup animation
01455			return;
01456		}
01457	
01458		// Don't play anim if the legs are in a standing throw animation
01459		if(AnimProxy != None && AnimProxy.GetStateName() == 'Throwing' && group == 'Throwing')
01460			return;
01461	
01462		if(!bIsCrouching)
01463		{	
01464			if(Weapon==None)
01465			{ // Exploration mode
01466				if(AnimProxy != None && AnimProxy.GetStateName() == 'Defending')
01467				{
01468					n = 'neutral_defend';
01469				}	
01470				else
01471				{
01472					n = 'neutral_idle';
01473				}
01474			}
01475			else
01476			{ // Combat Mode
01477				if(AnimProxy != None && AnimProxy.GetStateName() == 'Defending' )
01478				{
01479					tween = 0.01; // Near instant bringing up of shields
01480					if(AnimProxy.AnimSequence != Weapon.A_Defend)
01481						n = AnimProxy.AnimSequence;
01482					else
01483						return;
01484				}
01485				else if(GetGroup(AnimSequence) == 'AttackStanding')
01486				{ // Don't play the animation if standing and attacking
01487					return;
01488				}
01489				else
01490				{
01491					n = Weapon.A_Idle;
01492				}
01493			}
01494		}
01495		else
01496		{ // Crouching
01497			tween = 0.1;
01498			if(Weapon == None || !Weapon.bCrouchTwoHands)
01499				n = 'crouch_idle';
01500			else
01501				n = 'crouch_idle2hands';
01502		}
01503	
01504		LoopAnim(n, 1.0, tween);
01505		if(AnimProxy != None)
01506			AnimProxy.TryLoopAnim(n, 1.0, tween);
01507	}
01508	
01509	//=============================================================================
01510	//
01511	// TweenToWaiting
01512	//
01513	//=============================================================================
01514	
01515	function TweenToWaiting(float tweentime)
01516	{	
01517		PlayWaiting(0.1);
01518	}
01519	
01520	//=============================================================================
01521	//
01522	// TweenToMoving
01523	//
01524	//=============================================================================
01525	
01526	function TweenToMoving(float tweentime)
01527	{
01528		PlayMoving();
01529	}
01530	
01531	//=============================================================================
01532	//
01533	// PlayLanded
01534	//
01535	//=============================================================================
01536	
01537	function PlayLanded(float impactVel)
01538	{		
01539		local EMatterType matter;
01540		local vector end;
01541		local sound snd;
01542	
01543		impactVel = impactVel/JumpZ;
01544		impactVel = 0.1 * impactVel * impactVel;
01545		BaseEyeHeight = Default.BaseEyeHeight;
01546	
01547		if (!FootRegion.Zone.bWaterZone)
01548		{
01549			FootstepLeft();
01550			FootstepRight();
01551		}
01552	
01553		if ( Role == ROLE_Authority )
01554		{
01555			if(impactVel > 0.15)
01556				PlaySound(LandGrunt, SLOT_Talk, FMin(5, 5 * impactVel),false,1200,FRand() * 0.08 + 0.96);
01557	
01558			if(impactVel > 0.01)
01559			{ // Play Land Sound			
01560				if(FootRegion.Zone.bPainZone)
01561					matter = MATTER_LAVA;
01562				else if(FootRegion.Zone.bWaterZone)
01563					matter = MATTER_WATER;
01564				else
01565				{
01566					end = Location;
01567					end.Z -= CollisionHeight;
01568					matter = MatterTrace(end, Location, 10);
01569				}
01570	
01571				PlayLandSound(matter, impactVel);
01572			}
01573		}
01574		
01575		if(Velocity.X * Velocity.X + Velocity.Y * Velocity.Y < 1000)
01576		{
01577			PlayWaiting(0.2);
01578		}
01579		else
01580		{
01581			PlayMoving();
01582		}
01583	}
01584	
01585	//=============================================================================
01586	//
01587	// PlaySwimming
01588	//
01589	//=============================================================================
01590	
01591	function PlaySwimming()
01592	{
01593		local name Anim;
01594		local float dp;
01595		local vector dir,X,Y,Z;
01596	
01597		// Recalculate these since they aren't known on clients
01598		GetAxes(Rotation,X,Y,Z);
01599		dir = Normal(Acceleration);
01600		dp = dir dot X;
01601		bWasForward	= dp >  0.5;
01602		bWasBack	= dp < -0.5;
01603		dp = dir dot Y;
01604		bWasLeft	= dp >  0.3 ;
01605		bWasRight	= dp < -0.3;
01606	
01607		if(bSurfaceSwimming)
01608			Anim = 'TreadOnWaterIdle';
01609		else
01610			Anim = 'Treadwateridle';
01611		
01612		if(bWasForward)
01613		{
01614			if(!bWasLeft && !bWasRight)
01615			{ // Normal running forwards
01616				if(bSurfaceSwimming)
01617					Anim = 'SwimOnWater';
01618				else
01619					Anim = 'SwimUnderWater';
01620			}
01621			else if(bWasLeft)
01622			{ // Strafe right 45
01623				if(bSurfaceSwimming)
01624				{
01625					if (!bMirrored)
01626						Anim = 'Swim45RightOnWater';
01627					else
01628						Anim = 'Swim45LeftOnWater';
01629				}
01630				else
01631				{
01632					if (!bMirrored)
01633						Anim = 'SwimUnderWater45Right';
01634					else
01635						Anim = 'SwimUnderWater45Left';
01636				}
01637			}
01638			else if(bWasRight)
01639			{ // Strafe left 45
01640				if(bSurfaceSwimming)
01641				{
01642					if (!bMirrored)
01643						Anim = 'Swim45LeftOnWater';
01644					else
01645						Anim = 'Swim45RightOnWater';
01646				}
01647				else
01648				{
01649					if (!bMirrored)
01650						Anim = 'SwimUnderWater45Left';
01651					else
01652						Anim = 'SwimUnderWater45Right';
01653				}
01654			}
01655		}
01656		else if(bWasBack)
01657		{
01658			if(!bWasLeft && !bWasRight)
01659			{ // Normal running backwards
01660				if(bSurfaceSwimming)
01661					Anim = 'SwimbackwardsOnWater';
01662				else
01663					Anim = 'Swimbackwards';
01664			}
01665			else if(bWasRight)
01666			{ // Strafe Left 45
01667				if(bSurfaceSwimming)
01668				{
01669					if (!bMirrored)
01670						Anim = 'TreadOnWaterIdle'; // BROKEN: 'SwimbackwardsLeftOnWater';
01671					else
01672						Anim = 'SwimbackwardsRightOnWater';
01673				}
01674				else
01675				{
01676					if (!bMirrored)
01677						Anim = 'Swimbackwards45Left';
01678					else
01679						Anim = 'Swimbackwards45Right';
01680				}
01681			}
01682			else if(bWasLeft)
01683			{ // Strafe right 45
01684				if(bSurfaceSwimming)
01685				{
01686					if (!bMirrored)
01687						Anim = 'SwimbackwardsRightOnWater';
01688					else
01689						Anim = 'TreadOnWaterIdle';	// BROKEN: 'SwimbackwardsLeftOnWater';
01690				}
01691				else
01692				{
01693					if (!bMirrored)
01694						Anim = 'Swimbackwards45Right';
01695					else
01696						Anim = 'Swimbackwards45Left';
01697				}
01698			}
01699		}
01700		else if(bWasLeft)
01701		{ // Strafe right
01702			if(bSurfaceSwimming)
01703			{
01704				if (!bMirrored)
01705					Anim = 'SwimRightOnWater';
01706				else
01707					Anim = 'SwimLeftOnWater';
01708			}
01709			else
01710			{
01711				if (!bMirrored)
01712					Anim = 'SwimRight';
01713				else
01714					Anim = 'SwimLeft';
01715			}
01716		}
01717		else if(bWasRight)
01718		{ // Strafe left
01719			if(bSurfaceSwimming)
01720			{
01721				if (!bMirrored)
01722					Anim = 'SwimLeftOnWater';
01723				else
01724					Anim = 'SwimRightOnWater';
01725			}
01726			else
01727			{
01728				if (!bMirrored)
01729					Anim = 'SwimLeft';
01730				else
01731					Anim = 'SwimRight';
01732			}
01733		}
01734		else if(Acceleration.Z > 50 && !bSurfaceSwimming)
01735		{
01736			Anim = 'SwimUnderWaterUp';
01737		}
01738		else if(Acceleration.Z < -50 && !bSurfaceSwimming)
01739		{
01740			Anim = 'SwimUnderWaterDown';
01741		}
01742	
01743		LoopAnim(Anim, 1.0, 0.3);	
01744	
01745		if(AnimProxy != None)
01746			AnimProxy.TryLoopAnim(Anim, 1.0, 0.3);
01747	}
01748	
01749	//=============================================================================
01750	//
01751	// TweenToSwimming
01752	//
01753	//=============================================================================
01754	
01755	function TweenToSwimming(float tweentime)
01756	{
01757		PlaySwimming();
01758	}
01759	
01760	//=============================================================================
01761	//
01762	// PlayRopeIdle
01763	//
01764	//=============================================================================
01765	
01766	function PlayRopeIdle()
01767	{
01768		LoopAnim('ropetest');	
01769		if(AnimProxy != None)
01770			AnimProxy.LoopAnim('ropetest');	
01771	}
01772	
01773	//=============================================================================
01774	//
01775	// TryPlayTorsoAnim
01776	//
01777	// Attempts to play the torso anim on the legs.
01778	//=============================================================================
01779	
01780	function TryPlayTorsoAnim(name TorsoAnim, float speed, float tween)
01781	{
01782		DoTryPlayTorsoAnim(TorsoAnim, speed, tween);
01783		ClientTryPlayTorsoAnim(TorsoAnim);
01784	}
01785	
01786	simulated function ClientTryPlayTorsoAnim(name TorsoAnim)
01787	{
01788		DoTryPlayTorsoAnim(TorsoAnim, 1.0, 0.01);
01789	}
01790	
01791	simulated function DoTryPlayTorsoAnim(name TorsoAnim, float speed, float tween)
01792	{
01793		local vector X, Y, Z;
01794		local float dp;
01795	
01796		if(AnimProxy != None && AnimProxy.GetStateName() == 'Attacking' && Weapon != None)
01797		{
01798			// Determine the direction the player is attempting to move
01799			GetAxes(Rotation, X, Y, Z);
01800			dp = vector(Rotation) dot Normal(Acceleration);
01801	
01802			if(dp > 0.9 || dp < -0.9)
01803			{ // Distinctly forward or backward
01804				if(TorsoAnim == Weapon.A_AttackA || TorsoAnim == Weapon.A_AttackAReturn
01805					|| TorsoAnim == Weapon.A_AttackB // Note that AttackBReturn is NOT played on the legs to avoid sliding
01806					|| TorsoAnim == Weapon.A_AttackC || TorsoAnim == Weapon.A_AttackCReturn
01807					|| TorsoAnim == Weapon.A_AttackBackupA || TorsoAnim == Weapon.A_AttackBackupAReturn
01808					|| TorsoAnim == Weapon.A_AttackBackupB || TorsoAnim == Weapon.A_AttackBackupBReturn
01809					|| TorsoAnim == Weapon.A_JumpAttack)
01810				{
01811					PlayAnim(TorsoAnim, speed, tween);	
01812					return;
01813				}
01814			}
01815		}
01816	/*
01817		if(GetGroup(AnimSequence) == 'Moving')
01818		{
01819			return;
01820		}
01821	*/
01822		// Check Ragnar's movement with the movement on the weapon
01823		if(Weapon != None)
01824		{
01825			if(AnimSequence == Weapon.A_Forward
01826				|| AnimSequence == Weapon.A_Backward
01827				|| AnimSequence == Weapon.A_StrafeLeft
01828				|| AnimSequence == Weapon.A_StrafeRight
01829				|| AnimSequence == Weapon.A_Forward45Left
01830				|| AnimSequence == Weapon.A_Forward45Right
01831				|| AnimSequence == Weapon.A_Backward45Left
01832				|| AnimSequence == Weapon.A_Backward45Right
01833				|| AnimSequence == Weapon.A_Jump
01834				|| AnimSequence == Weapon.A_ForwardAttack)
01835			{ // Playing a movement animation
01836				return;
01837			}
01838		}
01839		
01840		PlayAnim(TorsoAnim, speed, tween);
01841	}
01842	
01843	// ----- LOOK Code -----
01844	
01845	simulated function float ScoreLookActor(Actor A)
01846	{
01847		local float score;
01848		local rotator r;
01849		local vector vectA, vectR;
01850		local float angle;
01851		
01852		vectA = A.Location - Location;
01853		r.Pitch = 0;
01854		r.Yaw = Rotation.Yaw;
01855		r.Roll = 0;
01856		vectR = vector(r);	
01857		
01858		angle = (Normal(vectA) dot vectR);
01859		
01860		if(angle < PeripheralVision)
01861		{
01862			return(9999999.0);
01863		}
01864		
01865		score = VSize(vectA) * (2.0 - angle);
01866	
01867		if(A.IsA('Pawn'))
01868		{
01869			score *= 0.5;
01870		}
01871		else if(A.IsA('LookTarget'))
01872		{
01873			score *= 0.25;
01874		}
01875				
01876		return(score);
01877	}
01878	
01879	//=============================================================================
01880	//
01881	// DetermineLookFocus
01882	//
01883	// Checks for the ideal actor for the player's focus
01884	// TODO:
01885	//	- Object priorities
01886	//	- Proper distance usage
01887	//  - Angle from RunePlayer(Owner) to object
01888	//	- Special "chasing actor" mode that allows the player to look backwards
01889	//=============================================================================
01890	simulated function DetermineLookFocus()
01891	{
01892		local Actor A;
01893		local float bestScore;
01894		local Actor bestActor;
01895		local float score;
01896		local vector delta;
01897	
01898		bestScore = 9999999.0;	
01899		bestActor = None;
01900	
01901		if (Health < 0)
01902			return;
01903	
01904		foreach VisibleActors(class'actor', A, 1000, Location)
01905		{
01906			if(A == self || A.Owner == self)
01907				continue;
01908			
01909			if(A.bLookFocusPlayer)
01910			{
01911				score = ScoreLookActor(A);
01912				if(score < bestScore)
01913				{
01914					bestScore = score;
01915					bestActor = A;
01916				}
01917			}
01918		}	
01919		LookTarget = bestActor;
01920		LookSpot = vect(0,0,0);
01921	
01922	/*
01923		if(bestActor == None && Weapon==None)
01924		{
01925			LookSpot = Location + 100 * vector(DesiredRotation);
01926		}
01927	*/
01928	/* Uncomment this to make player look at the dropped camera spot -- a little weird right now
01929		if(bestActor == None && bCameraLock)
01930		{
01931			LookSpot = SavedCameraLoc;
01932		}
01933	*/
01934	}
01935	
01936	
01937	
01938	function bool FindInventoryItem(Inventory testItem)
01939	{
01940		local inventory Inv;
01941	
01942		if(testItem == None)
01943			return(true);
01944	
01945		for( Inv=Inventory; Inv!=None; Inv=Inv.Inventory )
01946			if( Inv == testItem)
01947				return(true);
01948	
01949		return(false);
01950	}
01951	
01952	//=============================================================================
01953	//
01954	// Tick
01955	//
01956	//=============================================================================
01957	
01958	simulated event Tick(float DeltaTime)
01959	{
01960		local int i;
01961		local texture tex;
01962	
01963		// Update look target
01964		DetermineLookFocus();
01965	
01966		// Update Camera Timer
01967		CurrentTime += DeltaTime / Level.TimeDilation;
01968	
01969		// Atrophy Strength
01970		StrengthDecay(DeltaTime);
01971	
01972		// Handle level fade in
01973		if (LevelFadeAlpha > 0)
01974		{
01975			LevelFadeAlpha -= DeltaTime * Level.FadeRate;
01976			if (LevelFadeAlpha < 0)
01977				LevelFadeAlpha = 0;
01978		}
01979	
01980	/*
01981		// DEBUG! DEBUG! DEBUG! DEBUG!
01982		// DEBUG! DEBUG! DEBUG! DEBUG!
01983		// DEBUG! DEBUG! DEBUG! DEBUG!
01984		// Iterate through the players inventory and if it mismatches with the what the 
01985		// player has in his hands/stowed, then print a warning message!
01986	
01987		if(Level.NetMode != NM_Client)
01988		{	// Client's may not receive the property for a few ticks
01989	
01990			if(!FindInventoryItem(Weapon) || !FindInventoryItem(Shield)
01991				|| !FindInventoryItem(StowSpot[0]) || !FindInventoryItem(StowSpot[1])
01992				|| !FindInventoryItem(StowSpot[2]))
01993			{
01994				Slog("WARNING!!  Inventory mismatch.  Pause the game and find a programmer IMMEDIATELY!");
01995			}
01996		}
01997	
01998		// DEBUG! DEBUG! DEBUG! DEBUG!
01999		// DEBUG! DEBUG! DEBUG! DEBUG!
02000		// DEBUG! DEBUG! DEBUG! DEBUG!
02001	*/
02002	
02003		Super.Tick(DeltaTime);
02004	}
02005	
02006	
02007	//-----------------------------------------------------------------------------
02008	// Utility functions
02009	
02010	//=============================================================================
02011	//
02012	// SetMovementMode
02013	//
02014	//=============================================================================
02015	
02016	function SetMovementMode()
02017	{
02018		if(Weapon != None)
02019		{ // Combat Mode
02020	//		GroundSpeed = CombatSpeed;
02021			bRotateTorso = False;
02022	
02023			if(Level.NetMode != NM_Standalone)
02024				SpeedScale = SS_Circular; // No elliptical movement in netplay
02025			else
02026				SpeedScale = SS_Elliptical;
02027		}
02028		else
02029		{ // Exploration Mode
02030	//		GroundSpeed = ExploreSpeed;
02031			bRotateTorso = True;
02032			SpeedScale = SS_Circular;
02033		}
02034	}
02035	
02036	function SetCrouchHeight()
02037	{
02038		local vector newloc;
02039		local float offset;
02040	
02041		SetCollisionSize(CollisionRadius, CrouchHeight);
02042	
02043		// Adjust so player is standing on ground
02044		offset = default.CollisionHeight - CrouchHeight;
02045		newloc = Location;
02046		newloc.Z -= offset;
02047		SetLocation(newloc);
02048		PrePivot.Z += offset;
02049		BaseEyeHeight = (CrouchHeight/Default.CollisionHeight) * Default.BaseEyeHeight;
02050	}
02051	
02052	function SetNormalHeight()
02053	{
02054		local vector newloc;
02055		local float offset;
02056	
02057		SetCollisionSize(CollisionRadius, default.CollisionHeight);
02058	
02059		// Adjust so player is standing on ground
02060		offset = default.CollisionHeight - CrouchHeight;
02061		newloc = Location;
02062		newloc.Z += offset;
02063		SetLocation(newloc);
02064		PrePivot.Z += offset;
02065		BaseEyeHeight = Default.BaseEyeHeight;
02066	}
02067	
02068	function bool CanStandUp()
02069	{
02070		local vector end, extent;
02071		local vector HitLocation, HitNormal;
02072	
02073		end = Location;
02074		end.Z += CollisionHeight + CrouchHeight; // Generous fudge factor
02075	
02076		extent.X = CollisionRadius;
02077		extent.Y = CollisionRadius;
02078		extent.Z = 8;
02079	
02080		if(Trace(HitLocation, HitNormal, end, Location, true, extent) == None)
02081		{
02082			return(true);
02083		}
02084		
02085		return(false);
02086	}
02087	
02088	//=============================================================================
02089	//
02090	// SetCrouch
02091	//
02092	//=============================================================================
02093	
02094	function SetCrouch(bool crouch)
02095	{
02096		if(crouch)
02097		{ // Set to explore mode all the time while crouching (with the exception of not rotating the torso)
02098			GroundSpeed = ExploreSpeed;
02099			bRotateTorso = False;
02100			SpeedScale = SS_Circular;		
02101			SetCrouchHeight();
02102			bIsCrouching = true;
02103	
02104			// Play CrouchSound
02105			PlaySound(CrouchSound, SLOT_Interact, 1.0, false, 1200, FRand() * 0.08 + 0.96);
02106		}
02107		else if(bIsCrouching)
02108		{
02109			if(CanStandUp())
02110			{ // Check if standing up is acceptable
02111				SetMovementMode();
02112				SetNormalHeight();
02113				bIsCrouching = false;
02114			}
02115			else
02116			{
02117				bIsCrouching = true;
02118			}
02119		}
02120	}
02121	
02122	//=============================================================================
02123	//
02124	// PlayerCalcView
02125	//
02126	//=============================================================================
02127	
02128	event PlayerCalcView(out actor ViewActor, out vector CameraLocation, out rotator CameraRotation)
02129	{
02130		local vector View,HitLocation,HitNormal;
02131		local float ViewDist, WallOutDist;
02132	
02133		local vector PlayerLocation;
02134		local vector loc;
02135		local rotator rot;
02136		local vector desiredLoc;
02137		local vector currentLoc;
02138		local vector cameraVect, newVect;
02139		local float accel;
02140		local float deltaTime;
02141		local vector startPt;
02142		local vector endPt;
02143		local bool done;
02144		local float desiredDist;
02145		local float diff;
02146		local rotator targetangle;
02147		
02148		local vector extent; // trace extent
02149		
02150		// Calculate time change
02151		deltaTime = CurrentTime - LastTime;
02152	
02153		// View rotation.
02154		ViewActor = Self;
02155	
02156		// Handle view shaking
02157		ViewShake(deltaTime);
02158		targetAngle = ViewRotation + ShakeDelta;
02159		
02160		PlayerLocation = Location + PrePivot;
02161	
02162		if(Region.Zone != None && Region.Zone.bTakeOverCamera)
02163		{
02164			CameraLocation = Region.Zone.Location;
02165			loc = PlayerLocation;
02166			loc.Z += EyeHeight;
02167			CameraRotation = rotator(loc - CameraLocation);
02168			ViewLocation = CameraLocation;
02169			return;
02170		}
02171	
02172		if(RemoteRole != ROLE_AutonomousProxy && (deltaTime < 0.1 && deltaTime > 0))
02173		{ // Local Player Only (deltaTime == 0.0 for remote players on the server)
02174			// Interpolate Yaw
02175			targetAngle.Yaw = targetAngle.Yaw & 65535;
02176			CurrentRotation.Yaw = CurrentRotation.Yaw & 65535;
02177			diff = targetAngle.Yaw - CurrentRotation.Yaw;
02178			if(abs(diff) > 32768)
02179			{ // Handle wrap around case
02180				if(targetAngle.Yaw > 32768)
02181				{
02182					targetAngle.Yaw -= 65536;;
02183				}
02184				else
02185				{
02186					targetAngle.Yaw += 65536;
02187				}
02188				
02189				diff = targetAngle.Yaw - CurrentRotation.Yaw;
02190			}	
02191	
02192			if(abs(diff) < 10)
02193			{
02194				CurrentRotation.Yaw = targetAngle.Yaw;
02195			}
02196			else
02197			{		
02198				CurrentRotation.Yaw += deltaTime * diff * CameraRotSpeed.Yaw;
02199				
02200				if((diff < 0 && CurrentRotation.Yaw < targetAngle.Yaw)
02201					|| (diff > 0 && CurrentRotation.Yaw > targetAngle.Yaw))
02202				{ // Guard against overshooting targetangle
02203					CurrentRotation.Yaw = targetAngle.Yaw;
02204				}		
02205			}
02206	
02207			// Interpolate Pitch
02208			targetAngle.Pitch = targetAngle.Pitch & 65535;
02209			CurrentRotation.Pitch = CurrentRotation.Pitch & 65535;
02210			diff = targetAngle.Pitch - CurrentRotation.Pitch;
02211			if(abs(diff) > 32768)
02212			{ // Handle wrap around case
02213				if(targetAngle.Pitch > 32768)
02214				{
02215					targetAngle.Pitch -= 65536;;
02216				}
02217				else
02218				{
02219					targetAngle.Pitch += 65536;
02220				}
02221				
02222				diff = targetAngle.Pitch - CurrentRotation.Pitch;
02223			}	
02224			if(abs(diff) < 10)
02225			{
02226				CurrentRotation.Pitch = targetAngle.Pitch;
02227			}
02228			else
02229			{		
02230				CurrentRotation.Pitch += deltaTime * diff * CameraRotSpeed.Pitch;
02231				
02232				if((diff < 0 && CurrentRotation.Pitch < targetAngle.Pitch)
02233					|| (diff > 0 && CurrentRotation.Pitch > targetAngle.Pitch))
02234				{ // Guard against overshooting targetangle
02235					CurrentRotation.Pitch = targetAngle.Pitch;
02236				}		
02237			}
02238			
02239			// Interpolate Roll
02240			targetAngle.Roll = targetAngle.Roll & 65535;
02241			CurrentRotation.Roll = CurrentRotation.Roll & 65535;
02242			diff = targetAngle.Roll - CurrentRotation.Roll;
02243			if(abs(diff) > 32768)
02244			{ // Handle wrap around case
02245				if(targetAngle.Roll > 32768)
02246				{
02247					targetAngle.Roll -= 65536;;
02248				}
02249				else
02250				{
02251					targetAngle.Roll += 65536;
02252				}
02253				
02254				diff = targetAngle.Roll - CurrentRotation.Roll;
02255			}	
02256			if(abs(diff) < 10)
02257			{
02258				CurrentRotation.Roll = targetAngle.Roll;
02259			}
02260			else
02261			{		
02262				CurrentRotation.Roll += deltaTime * diff * CameraRotSpeed.Roll;
02263				
02264				if((diff < 0 && CurrentRotation.Roll < targetAngle.Roll)
02265					|| (diff > 0 && CurrentRotation.Roll > targetAngle.Roll))
02266				{ // Guard against overshooting targetangle
02267					CurrentRotation.Roll = targetAngle.Roll;
02268				}		
02269			}
02270		}
02271		else
02272		{ // No interpolation
02273			targetAngle.Yaw = targetAngle.Yaw & 65535;
02274			targetAngle.Pitch = targetAngle.Pitch & 65535;
02275			targetAngle.Roll = targetAngle.Roll & 65535;
02276	
02277			CurrentRotation = targetAngle;
02278		}
02279	
02280		CameraRotation = CurrentRotation;
02281	
02282		if(bBehindView && !bCameraLock && !bCameraOverhead)
02283		{
02284			if(CameraRotation.Pitch < 32768 && CameraRotation.Pitch > 12000)
02285			{ // Clamp the camera to a given set of angles [should be done in control functions?]
02286				CameraRotation.Pitch = 12000;
02287			}
02288	
02289			WallOutDist = 15;
02290			rot = CameraRotation;
02291			endPt = PlayerLocation;
02292	
02293			ViewDist = CameraDist;
02294			if(Region.Zone.MaxCameraDist >= CollisionRadius)
02295			{ // Zone-based camera distance
02296				ViewDist = Region.Zone.MaxCameraDist;
02297			}
02298	
02299			rot.Pitch -= CameraPitch;
02300			endPt.Z += CameraHeight;
02301	
02302			View = vect(1,0,0) >> rot;
02303	
02304		    startPt = PlayerLocation;
02305		    if(Trace(HitLocation, HitNormal, endPt, startPt) != None)
02306			{
02307				loc = HitLocation;
02308			}
02309			else
02310			{
02311				loc = endPt;
02312			}
02313	
02314			if(RemoteRole != ROLE_AutonomousProxy && (deltaTime < 0.1 && deltaTime > 0))
02315			{ // Do interpolation of CurrentDist.  
02316				// Local Player Only (deltaTime == 0.0 for remote players on the server)
02317				diff = abs(CurrentDist - ViewDist);
02318				if(diff > 30)
02319				{
02320					diff = 30;
02321				}
02322				else if(diff < 0.25)
02323				{ // Close enough, force the camera to the desired position
02324					CurrentDist = ViewDist;
02325				}
02326				
02327				if(CurrentDist < ViewDist)
02328				{
02329					CurrentDist += deltaTime * diff * 10;
02330					if(CurrentDist > ViewDist)
02331					{
02332						CurrentDist = ViewDist;
02333					}
02334				}
02335				else if(CurrentDist > ViewDist)
02336				{
02337					CurrentDist -= deltaTime * diff * 10;
02338					if(CurrentDist < ViewDist)
02339					{
02340						CurrentDist = ViewDist;
02341					}
02342				}
02343			}
02344			else
02345			{
02346				CurrentDist = ViewDist;
02347			}
02348	
02349			cameraVect = (loc - OldCameraStart);
02350			accel = (ViewDist / CurrentDist) * CameraAccel;
02351			if(RemoteRole != ROLE_AutonomousProxy && (deltaTime < 0.1 && deltaTime > 0))
02352			{ // Local Player Only (deltaTime == 0.0 for remote players on the server)
02353				newVect = cameraVect * deltaTime * accel;
02354				if(VSize(newVect) < VSize(cameraVect))
02355					cameraVect = newVect;
02356	
02357				loc = OldCameraStart + cameraVect;
02358			}
02359			// Otherwise, loc is not interpolated
02360	
02361		    endPt = loc - (CurrentDist + WallOutDist) * vector(rot);
02362		    startPt = loc;
02363	
02364		    if(Trace(HitLocation, HitNormal, endPt, startPt) != None)
02365			{
02366				CurrentDist = FMin((loc - HitLocation) dot View, CurrentDist);
02367			}
02368	
02369			if(CurrentDist < WallOutDist)
02370			{ // Camera pulled in so close that the view should just go first person
02371				CurrentDist = WallOutDist;
02372	
02373				if(bGotoFP)
02374					bBehindView = false;
02375			}
02376	
02377			CameraLocation = loc - (CurrentDist - WallOutDist) * View;
02378			
02379			OldCameraStart = loc;
02380	
02381			// Set Tranlucency on local player if too close to a wall
02382			if (CurrentDist > TranslucentDist)
02383				SetClientAlpha(1.0);
02384			else
02385				SetClientAlpha(CurrentDist/TranslucentDist);
02386		}
02387		else if(bBehindView && bCameraLock)
02388		{
02389			loc = PlayerLocation;
02390			loc.Z += EyeHeight;
02391			CameraLocation = SavedCameraLoc;
02392			CameraRotation = rotator(loc - CameraLocation) + ShakeDelta;
02393		}
02394		else if(bBehindView && bCameraOverhead)
02395		{
02396			CameraLocation = PlayerLocation;
02397			CameraLocation.Z += (CameraDist - 50) * 10;
02398			
02399			CameraRotation.Pitch = -16384;
02400			CameraRotation.Yaw = Rotation.Yaw;
02401			CameraRotation.Roll = 0;		
02402		}
02403		else
02404		{
02405			// First-person view.
02406			CameraRotation = ViewRotation + ShakeDelta;
02407			CameraLocation = Location;
02408			CameraLocation.Z += EyeHeight;
02409			CameraLocation += WalkBob;
02410	//		CameraRotation = GetJointRot(JointNamed('head'));	// too jerky, but cool
02411	//		CameraLocation = GetJointPos(JointNamed('head'));	// too jerky
02412			OldCameraStart = CameraLocation;
02413	
02414			if(!bGotoFP)
02415			{ // Return from first-person
02416				bBehindView = true;
02417			}
02418		}
02419	
02420		SavedCameraRot = CameraRotation;
02421		SavedCameraLoc = CameraLocation;
02422		
02423		// Handle view target.  Done AFTER other code, so that SavedLoc/Rot are updated
02424		if(ViewTarget != None)
02425		{
02426			SetClientAlpha(1.0);
02427			ViewActor = ViewTarget;
02428			CameraLocation = ViewTarget.Location;
02429			CameraRotation = ViewTarget.Rotation + ShakeDelta; // Add in effect of earthquakes
02430			if(Pawn(ViewTarget) != None)
02431			{
02432				if((Level.NetMode == NM_StandAlone)	&& (ViewTarget.IsA('PlayerPawn')))
02433				{
02434					CameraRotation = Pawn(ViewTarget).ViewRotation;
02435				}
02436	
02437				CameraLocation.Z += Pawn(ViewTarget).EyeHeight;
02438			}
02439		}
02440	
02441		ViewLocation = CameraLocation;
02442	
02443		LastTime = CurrentTime;
02444	}
02445	
02446	//=============================================================================
02447	//
02448	// Touch
02449	//
02450	//=============================================================================
02451	
02452	function Touch(Actor Other)
02453	{
02454		local vector HandPos, pos;
02455		LookTarget = Other;
02456		Super.Touch(Other);
02457	
02458		if(Rope(Other) != None
02459			&& !Rope(Other).bActorAttached
02460			&& (Physics == PHYS_Falling || Physics == PHYS_Swimming)
02461			&& GetStateName() != 'PlayerRopeClimbing')
02462		{ // Only grab the rope if the player can and if the player is in the air/swimming
02463			HandPos = Location;
02464			HandPos.Z += HandOffset;
02465	
02466			TheRope = Rope(Other);
02467			TheRope.ComputeClimbingEndpoints(HandPos.Z);
02468	
02469			if (HandPos.Z < TheRope.RopeClimbBottom.Z)
02470				return;
02471	
02472			TheRope.AttachedToRope(self);
02473	
02474			// Make sure right on rope
02475			pos = TheRope.Location;
02476			pos.Z = Location.Z;
02477			SetLocation(pos);
02478	
02479			Acceleration = vect(0, 0, 0);
02480			Velocity = vect(0, 0, 0);
02481			RopeDist = TheRope.RopeClimbTop.Z - HandPos.Z;
02482	
02483			GotoState('PlayerRopeClimbing');
02484		}	
02485	}
02486	
02487	//=============================================================================
02488	//
02489	// DoJump
02490	//
02491	//=============================================================================
02492	
02493	function DoJump( optional float F )
02494	{	
02495		if(!bIsCrouching && (Physics == PHYS_Walking))
02496		{
02497			if ( Role == ROLE_Authority )
02498				PlaySound(JumpSound, SLOT_Talk, 1.5, true, 1200, 1.0 );
02499			if ( (Level.Game != None) && (Level.Game.Difficulty > 0) )
02500				MakeNoise(0.1 * Level.Game.Difficulty);
02501	
02502			PlayJump();
02503	
02504			Velocity.Z = JumpZ;
02505	
02506			if(Base != None && Base != Level)
02507			{
02508				Velocity.Z += Base.Velocity.Z; 
02509			}
02510	
02511			SetPhysics(PHYS_Falling);
02512	
02513			if(bCountJumps && (Role == ROLE_Authority) && Inventory != None)
02514			{
02515				Inventory.OwnerJumped();
02516			}
02517		}
02518	}
02519	
02520	//=============================================================================
02521	//
02522	// HitWall
02523	//
02524	//=============================================================================
02525	
02526	function HitWall( vector HitNormal, actor HitWall )
02527	{
02528	/*	if (bBounce)
02529		{
02530			// Just landed on tarp: do whatever bounce animation you want
02531		}
02532	*/
02533	}
02534	
02535	//------------------------------------------------------------
02536	//
02537	// BoostStrength
02538	//
02539	//------------------------------------------------------------
02540	
02541	function BoostStrength(int amount)
02542	{
02543		if(bBloodLust)
02544			return;
02545	
02546		Strength += amount;
02547		if (Strength >= MaxStrength)
02548		{
02549			bBloodlust = true;
02550	
02551			PlaySound(BerserkSoundStart, SLOT_None, 1.0);
02552			AmbientSound = BerserkSoundLoop;
02553	
02554			Strength = MaxStrength;
02555			DesiredPolyColorAdjust.X = 255;
02556			DesiredPolyColorAdjust.Y = 128;
02557			DesiredPolyColorAdjust.Z = 128;
02558			Spawn(Class'BloodlustStart', self,, Location, Rotation);
02559	
02560			if(BloodLustEyes != None)
02561				BloodLustEyes.bHidden = false;
02562	
02563			ShakeView(1, 100, 0.25);
02564		}
02565	}
02566	
02567	//------------------------------------------------------------
02568	//
02569	// StrengthDecay
02570	//
02571	//------------------------------------------------------------
02572	
02573	function StrengthDecay(float Time)
02574	{
02575		local float StrengthAtrophy;	// Time to atrophy 1 strength pt
02576	
02577		if (Strength > 0)
02578		{
02579			if(bBloodLust)
02580			{
02581				StrengthAtrophy = 0.2;
02582			}
02583			else
02584			{
02585				StrengthAtrophy = 1;
02586				if ( (Level.NetMode == NM_StandAlone) && (Level.Game != None) )
02587				{
02588					switch(Level.Game.Difficulty)
02589					{
02590						case 0:
02591							StrengthAtrophy = 1;
02592							break;
02593						case 1:
02594							StrengthAtrophy = 1;
02595							break;
02596						case 2:
02597							StrengthAtrophy = 0.5;
02598							break;
02599						case 3:
02600							StrengthAtrophy = 0.5;
02601							break;
02602					}
02603				}
02604			}
02605	
02606			AtrophyTimer += Time;
02607			if (AtrophyTimer > StrengthAtrophy)
02608			{
02609				AtrophyTimer = 0;
02610				Strength--;
02611					
02612				if(bBloodlust && Strength == 0)
02613				{
02614					bBloodlust = false;
02615					DesiredPolyColorAdjust.X = 255;
02616					DesiredPolyColorAdjust.Y = 255;
02617					DesiredPolyColorAdjust.Z = 255;
02618					Spawn(Class'BloodlustStart', self,, Location, Rotation);
02619	
02620					PlaySound(BerserkSoundEnd, SLOT_None, 1.0);
02621					AmbientSound = None;
02622	
02623					if(BloodLustEyes != None)
02624						BloodLustEyes.bHidden = true;
02625				}
02626			}
02627		}
02628	}
02629	
02630	//------------------------------------------------------------
02631	//
02632	// PawnDamageModifier
02633	//
02634	// Returns the modification of the damage amount 
02635	// Used to increase damage for special attacks, or reduce damage
02636	// for simple attack types
02637	//------------------------------------------------------------
02638	
02639	function float PawnDamageModifier(Weapon w)
02640	{
02641		local float ContextBonus, DifficultyBonus, StrengthBonus;
02642	
02643		ContextBonus = 1.0;
02644		if(AnimProxy != None && Weapon != None)
02645		{
02646			if(w.GetStateName() == 'Throw')
02647			{	// Thrown
02648				ContextBonus = 1.5;
02649			}
02650			else if(AnimProxy.AnimSequence == Weapon.A_JumpAttack)
02651			{	// Jump Attack
02652				ContextBonus = 1.25;
02653			}
02654			else if(AnimProxy.AnimSequence == Weapon.A_AttackStrafeRight
02655				|| AnimProxy.AnimSequence == Weapon.A_AttackStrafeLeft)
02656			{	// Strafe Left/Right
02657				ContextBonus = 0.6;
02658			}
02659			else if(AnimProxy.AnimSequence == Weapon.A_AttackBackupA
02660				|| AnimProxy.AnimSequence == Weapon.A_AttackBackupB)
02661			{	// Backup attacks
02662				ContextBonus = 0.6;
02663			}
02664			else if(AnimProxy.AnimSequence == weapon.A_AttackB || AnimProxy.AnimSequence == weapon.A_AttackStandB)
02665			{ // Increase damage for combos
02666				ContextBonus = 1.15;
02667			}
02668			else if(AnimProxy.AnimSequence == weapon.A_AttackC || AnimProxy.AnimSequence == weapon.A_AttackD)
02669			{ // Increase damage much more for more extreme combos
02670				ContextBonus = 1.25;
02671			}
02672		}
02673	
02674		DifficultyBonus	= FClamp(2.0 * (2-Level.Game.Difficulty) * 0.5, 0, 2.0);
02675		if (bBloodLust)
02676			StrengthBonus = 1.0;
02677		else
02678			StrengthBonus = (float(Strength) / float(MaxStrength)) * 0.2;
02679	
02680		return(ContextBonus + DifficultyBonus + StrengthBonus);
02681	}
02682	
02683	//------------------------------------------------------------
02684	//
02685	// ViewShake
02686	//
02687	//------------------------------------------------------------
02688	
02689	function ViewShake(float DeltaTime)
02690	{
02691		if(shaketimer > 0.0)
02692		{	
02693			shaketimer -= DeltaTime;
02694			
02695			if(shaketimer <= 0)
02696			{
02697				ShakeDelta = rot(0, 0, 0);
02698				return;
02699			}
02700	
02701			if(shaketimer <= maxshake)
02702			{		
02703				verttimer -= DeltaTime * (float(shakemag) / maxshake);
02704				if(verttimer <= 0)
02705					verttimer = 0;
02706			}
02707			else
02708			{
02709				verttimer = shakemag;
02710			}
02711				
02712			ShakeDelta.Pitch = (100 * verttimer * (FRand() - 0.5)) * DeltaTime;
02713			ShakeDelta.Yaw = (100 * verttimer * (FRand() - 0.5)) * DeltaTime;
02714			ShakeDelta.Roll = (100 * verttimer * (FRand() - 0.5)) * DeltaTime;
02715		}
02716	}
02717	
02718	
02719	//-----------------------------------------------------------------------------
02720	//	Powerup functions
02721	
02722	function PowerupFire(Pawn EventInstigator)
02723	{
02724		local int i;
02725	
02726		if (Level.Game!=None && Level.Game.bTeamGame && EventInstigator.PlayerReplicationInfo.Team == PlayerReplicationInfo.Team)
02727			return;
02728	
02729		// Set all collision joints on fire
02730		for (i=0; i<NumJoints(); i++)
02731		{
02732			if ((JointFlags[i] & JOINT_FLAG_COLLISION)!=0)
02733				SetOnFire(EventInstigator, i);
02734		}
02735	}
02736	function PowerupBlaze(Pawn EventInstigator)
02737	{
02738		local int i;
02739	
02740		if (Level.Game!=None && Level.Game.bTeamGame && EventInstigator.PlayerReplicationInfo.Team == PlayerReplicationInfo.Team)
02741			return;
02742	
02743		// Set all collision joints on fire
02744		for (i=0; i<NumJoints(); i++)
02745		{
02746			if ((JointFlags[i] & JOINT_FLAG_COLLISION)!=0)
02747			{
02748				SetOnFire(EventInstigator, i);
02749			}
02750		}
02751	}
02752	function PowerupStone(Pawn EventInstigator)
02753	{
02754		if (Level.Game!=None && Level.Game.bTeamGame && EventInstigator.PlayerReplicationInfo.Team == PlayerReplicationInfo.Team)
02755			return;
02756		StatueInstigator = EventInstigator;		// For giving kill credit
02757		PlaySound(Sound'WeaponsSnd.Powerups.atfreezestone01', SLOT_Interface);
02758		GotoState('Statue');
02759	}
02760	function PowerupIce(Pawn EventInstigator)
02761	{
02762		if (Level.Game!=None && Level.Game.bTeamGame && EventInstigator.PlayerReplicationInfo.Team == PlayerReplicationInfo.Team)
02763			return;
02764		
02765		PlaySound(Sound'WeaponsSnd.Powerups.atfreezeice01', SLOT_Interface);
02766		GotoState('IceStatue');
02767	}
02768	function PowerupFriend(Pawn EventInstigator)
02769	{
02770		if (Level.Game!=None && Level.Game.bTeamGame && EventInstigator.PlayerReplicationInfo.Team == PlayerReplicationInfo.Team)
02771			return;
02772	}
02773	function UnPowerupFriend()
02774	{
02775	}
02776	function PowerupElectricity(Pawn EventInstigator)
02777	{
02778		if (Level.Game!=None && Level.Game.bTeamGame && EventInstigator.PlayerReplicationInfo.Team == PlayerReplicationInfo.Team)
02779			return;
02780	}
02781	
02782	
02783	//-----------------------------------------------------------------------------
02784	// Exec functions
02785	
02786	exec function Damage( string parms)
02787	{
02788		local actor A;
02789		local string bp;
02790		local int damage;
02791		local class<actor> aClass;
02792		local string ClassName;
02793		local int BodyPart;
02794	
02795		damage = 10;
02796		ClassName = GetToken(parms);
02797		BodyPart = int(GetToken(parms));
02798	
02799		if( instr(ClassName,".")==-1 )
02800			ClassName = "RuneI." $ ClassName;
02801	
02802		aClass = class<actor>( DynamicLoadObject( ClassName, class'Class' ) );
02803		if (aClass != None)
02804		{
02805			switch(BodyPart)
02806			{
02807				case BODYPART_BODY: bp="Body"; break;
02808				case BODYPART_LARM1: bp="LeftArm1"; break;
02809				case BODYPART_LARM2: bp="LeftArm2"; break;
02810				case BODYPART_RARM1: bp="RightArm1"; break;
02811				case BODYPART_RARM2: bp="RightArm2"; break;
02812				case BODYPART_HEAD: bp="Head"; break;
02813				case BODYPART_LLEG1: bp="LeftLeg1"; break;
02814				case BODYPART_LLEG2: bp="LeftLeg2"; break;
02815				case BODYPART_RLEG1: bp="RightLeg1"; break;
02816				case BODYPART_RLEG2: bp="RightLeg2"; break;
02817				case BODYPART_TORSO: bp="Torso"; break;
02818				case BODYPART_MISC1: bp="Misc1"; break;
02819				case BODYPART_MISC2: bp="Misc2"; break;
02820				case BODYPART_MISC3: bp="Misc3"; break;
02821				case BODYPART_MISC4: bp="Misc4"; break;
02822				default: return;
02823			}
02824	
02825			foreach AllActors(aClass, A)
02826			{
02827				slog("Applying"@damage@"to bodypart"@bp@"of"@A.name);
02828				A.DamageBodyPart(10, self, A.Location, vect(0,0,0), 'sever', BodyPart);
02829			}
02830		}
02831	}
02832	
02833	exec function CheckMatter()
02834	{
02835		local vector X,Y,Z;
02836		local vector HL, HN;
02837		local vector start, end;
02838		local actor A,B;
02839		local texture hitTexture;
02840		local EMatterType matter;
02841		local string mattertext;
02842	
02843		GetAxes(ViewRotation,X,Y,Z);
02844		start = Location;
02845		end = start + X*5000;	
02846		matter = MatterTrace(end, start, 10, hitTexture);
02847	
02848		switch(matter)
02849		{
02850			case MATTER_NONE:				mattertext="MATTER_NONE";				break;
02851			case MATTER_WOOD:				mattertext="MATTER_WOOD";				break;
02852			case MATTER_METAL:				mattertext="MATTER_METAL";				break;
02853			case MATTER_STONE:				mattertext="MATTER_STONE";				break;
02854			case MATTER_FLESH:				mattertext="MATTER_FLESH";				break;
02855			case MATTER_ICE:				mattertext="MATTER_ICE";				break;
02856			case MATTER_WATER:				mattertext="MATTER_WATER";				break;
02857			case MATTER_EARTH:				mattertext="MATTER_EARTH";				break;
02858			case MATTER_SNOW:				mattertext="MATTER_SNOW";				break;
02859			case MATTER_BREAKABLEWOOD:		mattertext="MATTER_BREAKABLEWOOD";		break;
02860			case MATTER_BREAKABLESTONE:		mattertext="MATTER_BREAKABLESTONE";		break;
02861			case MATTER_SHIELD:				mattertext="MATTER_SHIELD";				break;
02862			case MATTER_WEAPON:				mattertext="MATTER_WEAPON";				break;
02863			case MATTER_MUD:				mattertext="MATTER_MUD";				break;
02864			case MATTER_LAVA:				mattertext="MATTER_LAVA";				break;
02865		}
02866	
02867		if (Weapon != None)
02868			Weapon.PlayHitMatterSound(matter);
02869	
02870		slog("Matter for"@hitTexture@"is"@mattertext);
02871	}
02872	
02873	exec function Summon( string ClassName )
02874	{
02875		local class<actor> NewClass;
02876		if( !bAdmin && (Level.Netmode != NM_Standalone) )
02877			return;
02878		if( instr(ClassName,".")==-1 )
02879			ClassName = "RuneI." $ ClassName;
02880		Super.Summon( ClassName );
02881	}
02882	
02883	exec function BehindView( Bool B )
02884	{
02885		// In this function, the bool B is ignored, so that this function acts as a toggle
02886		if(Level.NetMode == NM_Client)
02887			return;
02888	
02889		if (CameraDist == 0)
02890		{	// in first person, zoom out
02891			CameraDist = 120;
02892			bGotoFP = false;
02893			bBehindView = true;
02894		}
02895		else
02896		{	// in third person, zoom in
02897			CameraDist = 0;
02898			bGotoFP = true;
02899		}
02900	}
02901	
02902	exec function CameraIn()
02903	{
02904		if(Level.NetMode == NM_Client)
02905			return;
02906	
02907		bGotoFP = false;
02908		CameraDist -= 60;
02909		if(CameraDist < 120)
02910		{ // Pull into first person
02911			CameraDist = 0;
02912			bGotoFP = true;
02913		}
02914	}
02915	
02916	exec function CameraOut()
02917	{
02918		if(Level.NetMode == NM_Client)
02919			return;
02920	
02921		bGotoFP = false;
02922		CameraDist += 60;
02923		if(CameraDist > 240)
02924		{
02925			CameraDist = 240;
02926		}
02927		else if(CameraDist < 120)
02928		{
02929			bBehindView = true;
02930			CameraDist = 120;
02931		}
02932	}
02933	
02934	exec function ZTargetToggle()
02935	{
02936		local float ZDist;
02937	
02938		if(Level.Netmode != NM_Standalone)
02939			return; // Disallow ztarget in multiplayer
02940	
02941		if(ZTarget == None)
02942		{
02943			if(LookTarget.IsA('Pawn'))
02944			{
02945				ZDist = VSize(LookTarget.Location - Location);
02946				if(ZDist <= ZTARGET_DIST)
02947				{
02948					ZTarget = Pawn(LookTarget);
02949				}
02950			}
02951		}
02952		else
02953		{
02954			ZTarget = None;
02955		}
02956	}
02957	
02958	
02959	exec function DumpWeaponInfo()
02960	{
02961		if(Weapon == None)
02962			return;
02963	
02964		slog("----------------------------");
02965		slog("  WEAPON:  "$Weapon);
02966		slog("  A_Idle: " $Weapon.A_Idle);
02967		slog("  A_Forward: " $Weapon.A_Forward);
02968		slog("  A_Backward: " $Weapon.A_Backward);
02969		slog("  A_Forward45Right: " $Weapon.A_Forward45Right);
02970		slog("  A_Forward45Left: " $Weapon.A_Forward45Left);
02971		slog("  A_Backward45Right: " $Weapon.A_Backward45Right);
02972		slog("  A_Backward45Left: " $Weapon.A_Backward45Left);
02973		slog("  A_StrafeRight: " $Weapon.A_StrafeRight);
02974		slog("  A_StrafeLeft: " $Weapon.A_StrafeLeft);
02975		slog("  A_AttackA: " $Weapon.A_AttackA);
02976		slog("  A_AttackAReturn: " $Weapon.A_AttackAReturn);
02977		slog("  A_AttackB: " $Weapon.A_AttackB);
02978		slog("  A_AttackBReturn: " $Weapon.A_AttackBReturn);
02979		slog("  A_AttackC: " $Weapon.A_AttackC);
02980		slog("  A_AttackCReturn: " $Weapon.A_AttackCReturn);
02981		slog("  A_AttackD: " $Weapon.A_AttackD);
02982		slog("  A_AttackDReturn: " $Weapon.A_AttackDReturn);
02983		slog("  A_AttackStandA: " $Weapon.A_AttackStandA);
02984		slog("  A_AttackStandAReturn: " $Weapon.A_AttackStandAReturn);
02985		slog("  A_AttackStandB: " $Weapon.A_AttackStandB);
02986		slog("  A_AttackStandBReturn: " $Weapon.A_AttackStandBReturn);
02987		slog("  A_AttackBackupA: " $Weapon.A_AttackBackupA);
02988		slog("  A_AttackBackupAReturn: " $Weapon.A_AttackBackupAReturn);
02989		slog("  A_AttackBackupB: " $Weapon.A_AttackBackupB);
02990		slog("  A_AttackBackupBReturn: " $Weapon.A_AttackBackupBReturn);
02991		slog("  A_AttackStrafeRight: " $Weapon.A_AttackStrafeRight);
02992		slog("  A_AttackStrafeLeft: " $Weapon.A_AttackStrafeLeft);
02993		slog("  A_Throw: " $Weapon.A_Throw);
02994		slog("  A_Defend: " $Weapon.A_Defend);
02995		slog("  A_DefendIdle: " $Weapon.A_DefendIdle);
02996		slog("  A_PainFront: " $Weapon.A_PainFront);
02997		slog("  A_PainBack: " $Weapon.A_PainBack);
02998		slog("  A_PainLeft: " $Weapon.A_PainLeft);
02999		slog("  A_PainRight: " $Weapon.A_PainRight);
03000		slog("  A_PickupGroundLeft: " $Weapon.A_PickupGroundLeft);
03001		slog("  A_PickupHighLeft: " $Weapon.A_PickupHighLeft);
03002		slog("  A_Taunt: " $Weapon.A_Taunt);
03003		slog("  A_PumpTrigger: " $Weapon.A_PumpTrigger);
03004	}
03005	
03006	//=============================================================================
03007	//
03008	// DropZ
03009	//
03010	// TEST FUNCTION
03011	//=============================================================================
03012	
03013	exec function DropZ()
03014	{
03015		local vector newLoc;
03016		local vector dropLoc;
03017		local vector HitLocation;
03018		local vector HitNormal;
03019		local vector X, Y, Z;
03020		local vector result;
03021	
03022		dropLoc = Location - vect(0, 0, 200);
03023	
03024		if(Trace(HitLocation, HitNormal, dropLoc, Location, false, vect(0, 0, 0)) != None)
03025		{
03026			Slog("HitZ: " $ HitNormal.Z);
03027		}
03028	
03029		// TEST slope calculation
03030		GetAxes(Rotation, X, Y, Z);
03031	
03032		result = Y cross HitNormal;
03033	
03034		SLog("Rot:  " $ (rotator(result)));
03035	
03036		DropZFloor = HitNormal;
03037		DropZRag = Y;
03038		DropZResult = result;
03039		DropZRoll = result cross HitNormal;
03040	}
03041	
03042	//=============================================================================
03043	//
03044	// TraceTex
03045	//
03046	//=============================================================================
03047	
03048	exec function TraceTex()
03049	{
03050		local vector newLoc;
03051		local vector X, Y, Z;
03052		local texture Tex;
03053		local int flags;
03054		local vector ScrollDir;
03055	
03056		GetAxes(Rotation, X, Y, Z);
03057		newLoc = Location - Z * 100;
03058	
03059		SLog("TraceTex Start:  " $ Location);
03060		SLog("TraceTex End:  " $ newLoc);
03061	
03062		Tex = TraceTexture(newLoc, Location, flags, ScrollDir);
03063		if(Tex != None)
03064		{
03065			Slog("Texture Material: " $ Tex.TextureMaterial);
03066			SLog("ScrollDir:  " $ ScrollDir);
03067		}
03068	}
03069	
03070	//=============================================================================
03071	//
03072	// Throw
03073	//
03074	//=============================================================================
03075	
03076	exec function Throw()
03077	{
03078		if(Weapon == None)
03079			return;
03080	
03081		if( bShowMenu || (Level.Pauser!="")) // || (Role < ROLE_Authority) )
03082			return;
03083	
03084		if(AnimProxy != None && AnimProxy.Throw())
03085			PlayAnim('ATK_ALL_throw1_AA0S', 1.0, 0.1);
03086	}
03087	
03088	//=============================================================================
03089	//
03090	// Use
03091	//
03092	//=============================================================================
03093	
03094	exec function Use()
03095	{
03096		local actor A;
03097		local vector v;
03098		local float dist;
03099		local float bestDist;
03100		local name useAnim;
03101		local int bestPriority;
03102		local int priority;
03103	
03104		if( bShowMenu || (Level.Pauser!="") || (Role < ROLE_Authority) || Health<=0)
03105			return;
03106	
03107		if(AnimProxy != None)
03108		{ // Can only use if the animation proxy is not busy
03109			if(AnimProxy.GetStateName() != 'Idle')
03110				return;
03111		}
03112	
03113		if(Physics != PHYS_Walking || (Velocity.X * Velocity.X + Velocity.Y * Velocity.Y >= 1500))
03114		{ // Test:  Only allow Ragnar to pick things up if he's standing still and on the ground
03115			return;
03116		}
03117	
03118		// See if other actors want the use message
03119		bestDist = 999999.0;
03120		bestPriority = 999;
03121		UseActor = None;
03122		foreach RadiusActors(class'actor', A, 100, Location)
03123		{
03124	/* Pickup Priority
03125			-1. Weapons	- 360 degree pickup
03126			-2. Shields	- 360 degree pickup
03127			-3. Food		- 360 degree pickup
03128			-4. Runes	- 360 degree pickup
03129			-5. Switches - 90 degree usage
03130			-6. Limbs	- 360 degree pickup
03131			-7. Kicking objects - 90 degree usage
03132			-8. Relighting torches - 90 degree usage
03133	*/
03134					
03135			if(A.CanBeUsed(self))
03136			{
03137				priority = A.GetUsePriority();
03138				dist = VSize(A.Location - Location);
03139	
03140				if((priority < bestPriority) 
03141					|| (priority == bestPriority && dist < bestDist))
03142				{
03143					bestPriority = priority;
03144					bestDist = dist;
03145					UseActor = A;
03146				}
03147			}
03148		}
03149	
03150		if(UseActor != None)
03151		{
03152			if(UseActor.IsA('Inventory'))
03153			{ // Inventory item pickup is handled by the animation proxy
03154				if(AnimProxy != None)
03155					AnimProxy.Use();
03156			}
03157			else if(UseActor.IsA('Fire'))
03158			{ // Relight torch, pass the use to the weapon
03159				if(Weapon != None)
03160					Weapon.UseTrigger(self);
03161			}
03162			else
03163			{ // Otherwise, play the animation returned by GetUseAnim	
03164				useAnim = UseActor.GetUseAnim();
03165	
03166				if(useAnim != '')
03167				{
03168					if(useAnim == 'neutral_kick')
03169						PlaySound(KickSound, SLOT_Talk, 1.0, false, 1200, FRand() * 0.08 + 0.96);
03170	
03171					if(useAnim == 'PumpTrigger' && Weapon != None && Weapon.A_PumpTrigger != '')
03172					{ // Weapon-specific pump trigger anims
03173						useAnim = Weapon.A_PumpTrigger;
03174					}
03175	
03176					if(useAnim == 'LeverTrigger' && Weapon != None && Weapon.A_LeverTrigger != '')
03177					{ // Weapon-specific pump trigger anims
03178						useAnim = Weapon.A_LeverTrigger;
03179					}
03180	
03181					PlayUninterruptedAnim(useAnim);
03182				}
03183			}
03184		}
03185	}
03186	
03187	//=============================================================================
03188	//
03189	// Powerup
03190	//
03191	//=============================================================================
03192	
03193	exec function Powerup()
03194	{
03195		local int power;
03196	
03197		if( bShowMenu || (Level.Pauser!="") || (Role < ROLE_Authority) || Health <= 0)
03198			return;
03199	
03200		if(Weapon == None)
03201			return;
03202	
03203		// Don't allow the player to powerup if they are doing something like weapon switching or attacking
03204		if(AnimProxy != None && AnimProxy.GetStateName() != 'Idle')
03205			return;
03206	
03207		if(!Weapon.bCanBePoweredUp || Region.Zone.bWaterZone || Weapon.Region.Zone.bWaterZone
03208			|| Weapon.bPoweredUp)
03209		{
03210			PlaySound(PowerupFail, SLOT_Interface);
03211			return;
03212		}
03213	
03214		if(Weapon.RunePowerRequired > RunePower)
03215		{
03216			PlaySound(PowerupFail, SLOT_Interface);
03217			ClientMessage(NoRunePowerMsg, 'NoRunePower');
03218			return;
03219		}
03220	
03221		PowerUpWeapon();
03222	
03223		// Play powerup-anim
03224		if(Weapon.A_Powerup != '' && GetStateName() == 'PlayerWalking')
03225		{
03226			PlayAnim(Weapon.A_Powerup, 1.0, 0.1);
03227			if(AnimProxy != None)
03228				AnimProxy.PlayAnim(Weapon.A_Powerup, 1.0, 0.1);
03229		}
03230	}
03231	
03232	//------------------------------------------------------------
03233	//
03234	// Taunt
03235	//
03236	//------------------------------------------------------------
03237	
03238	exec function Taunt()
03239	{
03240		local name Sequence;
03241	
03242		if (Physics != PHYS_Walking)	// Disallow while falling
03243			return;
03244	
03245		if( bShowMenu || (Level.Pauser!=""))
03246			return;
03247	
03248		// Don't allow the player to taunt if they are doing something like weapon switching or attacking
03249		if(AnimProxy != None && AnimProxy.GetStateName() != 'Idle')
03250			return;
03251	
03252		if (Weapon != None)
03253			Sequence = Weapon.A_Taunt;
03254		else
03255			Sequence = 'S3_Taunt';
03256	
03257		if(Role < ROLE_Authority)
03258			ServerTaunt(Sequence);
03259		else
03260			PlayUninterruptedAnim(Sequence);
03261	//	PlayUninterruptedAnim(Sequence);
03262	}
03263	
03264	
03265	//-----------------------------------------------------------------------------
03266	// Sound functions
03267	
03268	simulated function PlayBeepSound()
03269	{
03270		PlaySound(Sound'MessageBeep',SLOT_Interface, 1.4);
03271	}
03272	
03273	function PlayDyingSound(name DamageType)
03274	{
03275		local float rnd;
03276	
03277		if ( HeadRegion.Zone.bWaterZone )
03278		{
03279			PlaySound(UnderWaterDeathSound, SLOT_Talk, 1.0, false, 1200, FRand() * 0.08 + 0.96);
03280			return;
03281		}
03282	
03283		if(DamageType == 'fell')
03284		{
03285			PlaySound(FallingDeathSound, SLOT_Talk, 1.0, false, 1200, FRand() * 0.08 + 0.96);
03286			return;
03287		}
03288	
03289		rnd = FRand();
03290		if (rnd < 0.25)
03291			PlaySound(Die, SLOT_Talk);
03292		else if (rnd < 0.5)
03293			PlaySound(Die2, SLOT_Talk);
03294		else if (rnd < 0.75)
03295			PlaySound(Die3, SLOT_Talk);
03296		else 
03297			PlaySound(Die4, SLOT_Talk);
03298	
03299	}
03300	
03301	function PlayTakeHitSound(int damage, name damageType, int Mult)
03302	{
03303		if ( Level.TimeSeconds - LastPainSound < 0.3 )
03304			return;
03305		LastPainSound = Level.TimeSeconds;
03306	
03307		if ( HeadRegion.Zone.bWaterZone )
03308		{
03309			if ( damageType == 'Drowned' )
03310				PlaySound(UnderWaterDeathSound, SLOT_Pain,2.0,,,FRand() * 0.08 + 0.96);
03311			else
03312			{
03313				PlaySound(UnderWaterHitSound[Rand(3)], SLOT_Pain,2.0,,,FRand() * 0.08 + 0.96);
03314			}
03315			return;
03316		}
03317	
03318		if(DamageType == 'fell')
03319		{
03320			PlaySound(FallingDeathSound, SLOT_Talk, 1.0, false, 1200, FRand() * 0.08 + 0.96);
03321			return;
03322		}
03323	
03324		damage *= FRand();
03325	
03326		if(damage < 8)
03327			PlaySound(HitSoundLow[Rand(3)], SLOT_Pain, 2.0,,, Frand() * 0.1 + 0.95);
03328		else if(damage < 25)
03329			PlaySound(HitSoundMed[Rand(3)], SLOT_Pain, 2.0,,, Frand() * 0.1 + 0.95);
03330		else
03331			PlaySound(HitSoundHigh[Rand(3)], SLOT_Pain, 2.0,,, Frand() * 0.1 + 0.95);
03332	}
03333	
03334	function Gasp()
03335	{
03336		if ( Role != ROLE_Authority )
03337			return;
03338		if ( PainTime < 2 )
03339			PlaySound(GaspSound, SLOT_Talk, 2.0);
03340		else
03341			PlaySound(BreathAgain, SLOT_Talk, 2.0);
03342	}
03343	
03344	// ===== Weapon Functions =====
03345	
03346	//=============================================================================
03347	//
03348	// SelectWeapon
03349	//
03350	//=============================================================================
03351	
03352	function SelectWeapon(Weapon newWeapon)
03353	{
03354		local int joint;
03355		
03356		Weapon = newWeapon;
03357		
03358		joint = JointNamed(WeaponJoint);
03359		if(joint != 0)
03360		{
03361			AttachActorToJoint(Weapon, joint);
03362		}
03363	}
03364	
03365	//=============================================================================
03366	//
03367	// GetStowedWeapon
03368	//
03369	//=============================================================================
03370	
03371	function Weapon GetStowedWeapon(int stowindex)
03372	{
03373		if (stowindex>=0 && stowindex<=2)
03374		{
03375			return StowSpot[stowindex];
03376		}
03377		return None;
03378	}
03379	
03380	
03381	//=============================================================================
03382	//
03383	// SetStowedWeapon
03384	//
03385	//=============================================================================
03386	
03387	function SetStowedWeapon(int stowindex, Weapon w)
03388	{
03389		if (stowindex>=0 && stowindex<=2)
03390		{
03391			StowSpot[stowindex] = w;
03392		}
03393	}
03394	
03395	
03396	//=============================================================================
03397	//
03398	// StowWeapon
03399	//
03400	//=============================================================================
03401	
03402	function StowWeapon(Weapon oldWeapon)
03403	{
03404		local int joint;
03405		local int handJoint;
03406		local int stowIndex;
03407		
03408		if(Weapon == None)
03409		{
03410			return;
03411		}
03412	
03413		switch(Weapon.MeleeType)
03414		{
03415		case MELEE_SWORD:	
03416			joint = JointNamed('attatch_sword'); // Compensate for a spelling error...  for now.
03417			break;
03418		case MELEE_AXE:
03419			joint = JointNamed('attach_axe');
03420			break;
03421		case MELEE_HAMMER:
03422			joint = JointNamed('attach_hammer');
03423			break;
03424		default:
03425			joint = 0;
03426			break;
03427		}
03428	
03429		handJoint = JointNamed(WeaponJoint);
03430			
03431		if(joint != 0 && handJoint != 0)
03432		{
03433			DetachActorFromJoint(handJoint);
03434			AttachActorToJoint(Weapon, joint);
03435	
03436			if(RunePlayerProxy(AnimProxy) != None)	
03437				stowIndex = RunePlayerProxy(AnimProxy).GetStowIndex(Weapon);
03438			SetStowedWeapon(stowIndex, Weapon);
03439			Weapon.GotoState('Stow');
03440			Weapon = None;		
03441		}
03442	}
03443	
03444	//=============================================================================
03445	//
03446	// RetrieveWeapon
03447	//
03448	//=============================================================================
03449	
03450	function RetrieveWeapon(int stowIndex)
03451	{
03452		local int joint;
03453		local weapon cur;
03454		local weapon next;
03455			
03456		switch(stowIndex)
03457		{
03458		case 0: // MELEE_SWORD
03459			joint = JointNamed('attatch_sword'); // Compensate for a spelling error...  for now.
03460			break;
03461		case 1: // MELEE_HAMMER
03462			joint = JointNamed('attach_hammer');
03463			break;
03464		case 2: // MELEE_AXE
03465			joint = JointNamed('attach_axe');
03466			break;
03467		default:
03468			joint = 0;
03469			break;
03470		}
03471	
03472		cur = GetStowedWeapon(stowIndex);
03473		if(joint != 0 && cur != None)
03474		{
03475			DetachActorFromJoint(joint);
03476			SelectWeapon(cur);
03477	
03478			// Set the next available weapon to this stow spot
03479			SetStowedWeapon(stowIndex, None);
03480			next = GetNextWeapon(cur);
03481			if(next != None && next != cur)
03482			{
03483				AttachActorToJoint(next, joint);
03484				next.bHidden = false; // Reveal the next weapon
03485				SetStowedWeapon(stowIndex, next);
03486			}
03487		}
03488	}
03489	
03490	
03491	//=============================================================================
03492	//
03493	// SwapStowToNext
03494	//
03495	// Swaps a weapon in a given stow stop with the next available weapon in the inventory
03496	//=============================================================================
03497	
03498	function SwapStowToNext(int stowIndex)
03499	{
03500		local weapon w;
03501		local weapon next;
03502		local int joint;
03503	
03504		w = GetStowedWeapon(stowIndex);
03505		if(w != None)
03506		{		
03507			next = GetNextWeapon(w);
03508			if(next != None && next != w)
03509			{ // No need to do this if there is no next weapon or if the next weapon is the current weapon
03510				w.bHidden = true; // Hide the stowed weapon
03511				next.bHidden = false; // Reveal the next weapon
03512				// Detach the currently stow
03513				switch(stowIndex)
03514				{
03515				case 0: // MELEE_SWORD
03516					joint = JointNamed('attatch_sword'); // Compensate for a spelling error...  for now.
03517					break;
03518				case 1: // MELEE_HAMMER
03519					joint = JointNamed('attach_hammer');
03520					break;
03521				case 2: // MELEE_AXE
03522					joint = JointNamed('attach_axe');
03523					break;
03524				default:
03525					joint = 0;
03526					break;
03527				}
03528					
03529				if(joint != 0)
03530				{
03531					DetachActorFromJoint(joint);
03532					AttachActorToJoint(next, joint);
03533					SetStowedWeapon(stowIndex, next);
03534				}
03535			}
03536		}		
03537	}
03538	
03539	//=============================================================================
03540	//
03541	// GetNextWeapon
03542	//
03543	// Returns the next sequential weapon of a certain type in the inventory.
03544	// This function is circular, so it will wrap around to the first weapon in the
03545	// inventory
03546	//=============================================================================
03547	
03548	function Weapon GetNextWeapon(Weapon current)
03549	{
03550		local Inventory inv;
03551		local Weapon w;
03552		local Weapon higherWeapon, lowestWeapon;
03553		local int lowestRating, higherRating;
03554	
03555		if(current == None || Inventory == None)
03556			return(None);
03557	
03558		higherWeapon = None;
03559		lowestWeapon = None;
03560		lowestRating = 999;
03561		higherRating = 999; 
03562	
03563		// Iterate through inventory, finding the two weapons that match the following criteria:
03564		//	- The weapon of type current with the next higher rating than the current weapon
03565		//	- The weapon of type current with the lowest rating
03566		for(inv = Inventory; inv != None; inv = inv.Inventory)
03567		{
03568			if(inv.IsA('Weapon'))
03569			{
03570				w = Weapon(inv);
03571				if(w != None && w.MeleeType == current.MeleeType)
03572				{ // Same weapon type
03573					if(w.Rating < lowestRating)
03574					{
03575						lowestWeapon = w;
03576						lowestRating = w.Rating;
03577					}
03578					if(w.Rating > current.Rating && w.Rating < higherRating)
03579					{
03580						higherWeapon = w;
03581						higherRating = w.Rating;
03582					}
03583				}
03584			}
03585		}
03586	
03587		// Return the next higher weapon, otherwise, wrap around the list
03588		// NOTE: If only one weapon of type is in the inventory, then this will return the current weapon
03589		if(higherWeapon != None)
03590			return(higherWeapon);
03591		else
03592			return(lowestWeapon);
03593	}
03594	
03595	
03596	//=============================================================================
03597	//
03598	// InstantStow
03599	//
03600	// Instantly stows the current weapon, and properly updates LastHeldWeapon
03601	// for later retrieval
03602	//=============================================================================
03603	
03604	function InstantStow()
03605	{
03606		LastHeldWeapon = None;
03607		if(Weapon != None)
03608		{ // Handle the current weapon (drop it, do nothing, or stow it)		
03609			if(Weapon.IsA('NonStow'))
03610				DropWeapon();
03611			else
03612			{
03613				LastHeldWeapon = Weapon;
03614				WeaponDeactivate();
03615				Weapon.DisableSwipeTrail();
03616				StowWeapon(None);
03617			}
03618	
03619			SetMovementMode(); // Set combat or exploration mode
03620		}
03621	}
03622		
03623	/*
03624	//=============================================================================
03625	//
03626	// DropShield
03627	//
03628	//=============================================================================
03629	function DropShield()
03630	{
03631		local vector X,Y,Z;
03632		local int joint;
03633		
03634		if(Shield == None)
03635			return;
03636	
03637		joint = JointNamed('attach_shielda');
03638		if (joint != 0)
03639		{
03640			DetachActorFromJoint(joint);
03641			
03642			GetAxes(Rotation, X, Y, Z);
03643			Shield.DropFrom(GetJointPos(joint));
03644		
03645			Shield.SetPhysics(PHYS_Falling);
03646			Shield.Velocity = Y * 100 + X * 75;
03647			Shield.Velocity.Z = 50;
03648	
03649			Shield.GotoState('Drop');
03650	
03651			Shield = None; // Remove the shield from the actor
03652		}
03653	}	
03654	*/
03655	
03656	//=============================================================================
03657	//
03658	// ThrowWeapon
03659	//
03660	// RUNE:  Throw the current weapon
03661	//=============================================================================
03662	
03663	function ThrowWeapon()
03664	{
03665		if(Weapon != None)
03666		{
03667			// Play Weapon Throw Sound
03668			PlaySound(WeaponThrowSound, SLOT_Talk, 1.0, false, 1200, FRand() * 0.08 + 0.96);
03669		
03670			Super.ThrowWeapon();
03671	
03672			SetMovementMode(); // Set combat or exploration mode
03673		}
03674	}
03675	
03676	//=============================================================================
03677	//
03678	// ThrowGhost
03679	//
03680	// Notify for Throw powerup
03681	//=============================================================================
03682	
03683	function ThrowGhost()
03684	{
03685		local vector X,Y,Z;
03686		local int joint;
03687		local Weapon theWeapon;
03688	
03689		if(Weapon == None)
03690		{
03691			return;
03692		}
03693		
03694		// Play Weapon Throw Sound
03695		PlaySound(WeaponThrowSound, SLOT_Talk, 1.0, false, 1200, FRand() * 0.08 + 0.96);
03696	
03697		joint = JointNamed(WeaponJoint);
03698		theWeapon = Spawn(class'GoblinAxePowerup',self,,GetJointPos(joint));
03699		if (theWeapon != None)
03700		{
03701			GetAxes(ViewRotation, X, Y, Z);
03702			theWeapon.SetPhysics(PHYS_Falling);
03703			theWeapon.Velocity = X * 750 + Z * 200;
03704			theWeapon.GotoState('Throw');
03705		}
03706	}	
03707	
03708	//=============================================================================
03709	//
03710	// AcquireInventory
03711	//
03712	//=============================================================================
03713	
03714	function AcquireInventory(Inventory item)
03715	{
03716		local int joint;
03717		local Weapon newWeapon;
03718		local actor a;
03719	
03720		if (Skeletal == None)
03721			return;
03722	
03723		if(AnimProxy != None)
03724			AnimProxy.AcquireInventory(item);
03725	
03726		SetMovementMode(); // Set combat or exploration mode
03727	}
03728	
03729	//=============================================================================
03730	//
03731	// SwitchWeapon
03732	//
03733	//=============================================================================
03734	
03735	exec function SwitchWeapon(byte F)
03736	{
03737		local Weapon newWeapon;
03738		local int index;
03739		
03740		if(bShowMenu || Level.Pauser != "")
03741			return;
03742	
03743		if (BodyPartMissing(BODYPART_RARM1))	// Disallow weapon switching when no weapon arm
03744			return;
03745	
03746		if(AnimProxy != None && AnimProxy.GetStateName() == 'Idle' && GetStateName() == 'PlayerWalking')
03747			RunePlayerProxy(AnimProxy).SwitchWeapon(F);
03748	
03749		SetMovementMode(); // Set combat or exploration mode
03750	}
03751	
03752	//=============================================================================
03753	//
03754	// CamPickUp
03755	//
03756	//=============================================================================
03757	
03758	function bool CanPickup(Inventory item)
03759	{
03760		if (item.IsA('Shield') && BodyPartMissing(BODYPART_LARM1))
03761			return false;
03762		if (item.IsA('Weapon') && BodyPartMissing(BODYPART_RARM1))
03763			return false;
03764	
03765		if(RunePlayerProxy(AnimProxy) != None)
03766			return(RunePlayerProxy(AnimProxy).CanPickUp(item));
03767		else
03768			return(false);
03769	}
03770	
03771	//------------------------------------------------------------
03772	//
03773	// WantsToPickup
03774	//
03775	// Returns whether the item is desired
03776	//------------------------------------------------------------
03777	function bool WantsToPickUp(Inventory item)
03778	{
03779		return true;
03780	}
03781	
03782	
03783	// ===== STATES =====
03784	
03785	//-----------------------------------------------------------------------------
03786	//
03787	// STATE PlayerWalking
03788	//
03789	// Player movement.
03790	//-----------------------------------------------------------------------------
03791	
03792	state PlayerWalking
03793	{
03794		function AnimEnd()
03795		{
03796			local actor a;
03797			local rotator r;
03798			local vector l;
03799			local int joint;
03800			local vector X,Y,Z;
03801	
03802			bAnimTransition = false;
03803			
03804			if(Physics == PHYS_Walking)
03805			{
03806				if((Velocity.X * Velocity.X + Velocity.Y * Velocity.Y) < 1000)
03807				{
03808					PlayWaiting(0.2);
03809				}
03810				else
03811				{		
03812					PlayMoving();
03813				}
03814			}
03815		}
03816	
03817		function Landed(vector HitNormal, actor HitActor)
03818		{
03819			Super.Landed(HitNormal, HitActor);
03820			if (Velocity.Z < -1.4 * JumpZ)
03821				ShakeView(0.175 - 0.00007 * Velocity.Z, -0.85 * Velocity.Z, -0.002 * Velocity.Z);
03822		}
03823	
03824		function bool GrabEdge(float grabDistance, vector grabNormal)
03825		{ // RUNE
03826			if(AnimProxy != None && AnimProxy.GetStateName() == 'Idle')
03827			{ // Only grab edges if in the idle state
03828				GrabLocationUp.X = Location.X;
03829				GrabLocationUp.Y = Location.Y;
03830				GrabLocationUp.Z = Location.Z + grabDistance + 8;
03831			
03832				GrabLocationIn.X = Location.X + grabNormal.X * (CollisionRadius + 4);
03833				GrabLocationIn.Y = Location.Y + grabNormal.Y * (CollisionRadius + 4);
03834				GrabLocationIn.Z = GrabLocationUp.Z + CollisionHeight;
03835			
03836				SetRotation(rotator(grabNormal));
03837				ViewRotation.Yaw = Rotation.Yaw; // Align View with Player position while grabbing edge
03838	
03839				// Save the final distance (used for choosing the correct anim)
03840				GrabLocationDist = GrabLocationUp.Z - Location.Z;
03841	
03842				// Final, absolute check if the player can fit in the new location.
03843				// if the player fits, then it is a valid edge grab
03844				if(SetLocation(GrabLocationIn))
03845				{
03846					if(AnimProxy != None)
03847						AnimProxy.GotoState('EdgeHanging');			
03848					GotoState('EdgeHanging');
03849	
03850					return(true);
03851				}
03852			}
03853			
03854			return(false);
03855		}
03856	
03857		function Dodge(eDodgeDir DodgeMove)
03858		{
03859			local vector X,Y,Z;
03860	
03861			if ( bIsCrouching || (Physics != PHYS_Walking) || Weapon==None)
03862				return;
03863	
03864			GetAxes(Rotation,X,Y,Z);
03865			if (DodgeMove == DODGE_Forward)
03866				Velocity = 1.3 * GroundSpeed*X + (Velocity Dot Y)*Y;
03867			else if (DodgeMove == DODGE_Back)
03868				Velocity = -1.3 * GroundSpeed*X + (Velocity Dot Y)*Y; 
03869			else if (DodgeMove == DODGE_Left)
03870				Velocity = 1.3 * GroundSpeed*Y + (Velocity Dot X)*X; 
03871			else if (DodgeMove == DODGE_Right)
03872				Velocity = -1.3 * GroundSpeed*Y + (Velocity Dot X)*X; 
03873	
03874			Velocity.Z = 180;
03875			if ( Role == ROLE_Authority )
03876				PlaySound(JumpSound, SLOT_Talk, 1.0, true, 800, 1.0 );
03877			PlayDodge(DodgeMove);
03878			DodgeDir = DODGE_Active;
03879			SetPhysics(PHYS_Falling);
03880		}
03881		
03882		function ProcessMove(float DeltaTime, vector NewAccel, eDodgeDir DodgeMove, rotator DeltaRot)	
03883		{
03884			local vector OldAccel;
03885	
03886			OldAccel = Acceleration;
03887			Acceleration = NewAccel;
03888			bIsTurning = ( Abs(DeltaRot.Yaw/DeltaTime) > 10000 ); // RUNE:  was 5000
03889	
03890			if ( (DodgeMove == DODGE_Active) && (Physics == PHYS_Falling) )
03891				DodgeDir = DODGE_Active;	
03892			else if ( (DodgeMove != DODGE_None) && (DodgeMove < DODGE_Active) )
03893				Dodge(DodgeMove);
03894	
03895			if(bPressedJump)
03896			{
03897				DoJump();
03898			}
03899	
03900			if((Physics == PHYS_Walking)) // && (GetGroup(AnimSequence) != 'Dodge'))
03901			{
03902				if(!bIsCrouching)
03903				{
03904					if(bDuck != 0)
03905					{
03906						SetCrouch(true);
03907						PlayDuck();
03908					}
03909				}
03910				else if(bDuck == 0)
03911				{
03912					OldAccel = vect(0,0,0);
03913					SetCrouch(false);
03914				}
03915	
03916				if ( !bIsCrouching )
03917				{
03918					if(VSize(Acceleration) >= 1)
03919					{
03920						PlayMoving();
03921					}
03922				 	else if(Velocity.X * Velocity.X + Velocity.Y * Velocity.Y < 1000)
03923				 	{
03924						PlayWaiting(0.2);
03925	/*
03926						if(bIsTurning)
03927						{
03928							PlayTurning();
03929						}
03930				 		else
03931						{
03932							PlayWaiting(0.2);
03933						}
03934	*/
03935					}
03936				}
03937				else
03938				{
03939					if(VSize(Acceleration) >= 1)
03940						PlayCrawling();
03941					else
03942						PlayDuck();
03943				}
03944			}
03945		}
03946	
03947		function UpdateRotation(float DeltaTime, float maxPitch)
03948		{
03949			local rotator newRotation;
03950			local vector ToZTarget;
03951	
03952			if(ZTarget == None)
03953			{ // No ZTarget, so use the normal UpdateRotation
03954				Super.UpdateRotation(DeltaTime, maxPitch);
03955				return;
03956			}
03957			else
03958			{ // ZTarget			
03959				DesiredRotation = ViewRotation; //save old rotation
03960				ViewRotation.Pitch += 32.0 * DeltaTime * aLookUp;
03961				ViewRotation.Pitch = ViewRotation.Pitch & 65535;
03962				If ((ViewRotation.Pitch > 18000) && (ViewRotation.Pitch < 49152))
03963				{
03964					If (aLookUp > 0) 
03965						ViewRotation.Pitch = 18000;
03966					else
03967						ViewRotation.Pitch = 49152;
03968				}
03969	
03970				ToZTarget = ZTarget.Location - Location;
03971				ViewRotation.Yaw = rotator(ToZTarget).Yaw;
03972				ViewFlash(deltaTime);
03973					
03974				newRotation = Rotation;
03975				newRotation.Yaw = ViewRotation.Yaw;
03976				newRotation.Pitch = ViewRotation.Pitch;
03977				If ( (newRotation.Pitch > maxPitch * RotationRate.Pitch) && (newRotation.Pitch < 65536 - maxPitch * RotationRate.Pitch) )
03978				{
03979					If (ViewRotation.Pitch < 32768) 
03980						newRotation.Pitch = maxPitch * RotationRate.Pitch;
03981					else
03982						newRotation.Pitch = 65536 - maxPitch * RotationRate.Pitch;
03983				}
03984				setRotation(newRotation);			
03985			}
03986		}
03987	
03988		event PlayerTick( float DeltaTime )
03989		{
03990			local float ZDist;
03991	
03992			if ( bUpdatePosition )
03993				ClientUpdatePosition();
03994	
03995			PlayerMove(DeltaTime);
03996	
03997			// Check to player falling death scream
03998			if(!bPlayedFallingSound && Physics == PHYS_Falling && Velocity.Z < -1300)
03999			{ // Play death scream
04000				bPlayedFallingSound = true;
04001				PlaySound(FallingScreamSound,SLOT_Talk,,true);
04002			}
04003	
04004			// Update ZTarget (only if in single-player)
04005			if(ZTarget != None && Level.Netmode == NM_Standalone)
04006			{
04007				ZDist = VSize(ZTarget.Location - Location);
04008				if(ZTarget.Health <= 0 || ZDist > ZTARGET_DIST)
04009				{
04010					ZTarget = None;
04011				}
04012				else
04013				{
04014					if(ZTargetDecal == None)
04015					{
04016						ZTargetDecal = Spawn(class'ZTargetDecal', ZTarget,, Location, Rotation);
04017					}
04018	
04019					ZTargetDecal.SetOwner(ZTarget);
04020					ZTargetDecal.Update(None);
04021				}
04022			}
04023		}
04024	
04025		function ZoneChange(ZoneInfo NewZone)
04026		{
04027			if(NewZone.bWaterZone && Physics == PHYS_Falling && Velocity.Z < -1300)
04028			{ // Player is falling and screaming, cut out the scream when he hits the water
04029				bPlayedFallingSound = false;
04030				PlaySound(UnderwaterHitSound[0], SLOT_Talk,, false);			
04031			}
04032	
04033			Super.ZoneChange(NewZone);
04034		}
04035	
04036		function BeginState()
04037		{
04038			WalkBob = vect(0,0,0);
04039			DodgeDir = DODGE_None;
04040			SetCrouch(false);
04041			bIsTurning = false;
04042			bPressedJump = false;
04043			if (Physics != PHYS_Falling) SetPhysics(PHYS_Walking);
04044			if ( !IsAnimating() )
04045				PlayWaiting(0.2);
04046			Enable('Tick');	
04047		}
04048		
04049		function EndState()
04050		{
04051			WalkBob = vect(0,0,0);
04052			SetCrouch(false);
04053			bPlayedFallingSound=false;
04054		}
04055	}
04056	
04057	//=============================================================================
04058	//
04059	// STATE EdgeHanging
04060	//
04061	//=============================================================================
04062	
04063	state EdgeHanging
04064	{
04065	ignores SeePlayer, HearNoise, Bump, Fire, AltFire, GrabEdge, Jump, SwitchWeapon;
04066	
04067		exec function Taunt()	{}
04068		exec function Fly()		{}
04069		exec function Walk()	{}
04070		exec function Ghost()	{}
04071		exec function Powerup()	{}
04072		exec function Throw()	{}
04073	
04074		function EndState()
04075		{
04076			if(Weapon == None)
04077				bRotateTorso = true;
04078	
04079			CameraAccel = Default.CameraAccel;
04080	
04081			if(AnimProxy != None)
04082				AnimProxy.GotoState('Idle');
04083		}
04084	
04085		function AnimEnd()
04086		{
04087			if(AnimSequence == 'intropullupA')
04088			{ // Finished initial pullup, so step up
04089				PlayStepUp(0.1);
04090			}
04091			else if(AnimSequence == 'pullupTest')
04092			{ // Finished step up, so done with edge grab
04093				PlayWaiting(0.2);
04094	
04095				if(AnimProxy != None)
04096					AnimProxy.GotoState('Idle');
04097	
04098				GotoState('PlayerWalking');
04099			}
04100		}
04101	
04102		function BeginState()
04103		{
04104			if (Level.NetMode == NM_Client)
04105			{
04106				if(GrabLocationDist <= 5)
04107				{	// Nothing, possibly re-entered state
04108					GotoState('PlayerWalking');
04109					return;
04110				}
04111				else if(GrabLocationDist < 20)
04112				{	// Step up
04113					PlayStepUp(0.0); // No tween
04114				}
04115				else
04116				{	// Pull up
04117					PlayPullUp(0.0); // No tween
04118				}
04119			}
04120			else
04121			{
04122				// Play Grab Animation
04123				if(GrabLocationDist > 20)
04124				{
04125					PlayPullUp(0.0); // No tween
04126				}
04127				else
04128				{
04129					PlayStepUp(0.0); // No tween
04130				}
04131			}
04132	
04133			// Set up variables on the player
04134			SetPhysics(PHYS_Flying);
04135			Velocity = vect(0, 0, 0);
04136			Acceleration = vect(0, 0, 0);
04137	
04138			SetCrouch(false);
04139			bPressedJump = false;
04140			bRotateTorso = false;
04141			CameraAccel = 1;
04142		}
04143	
04144	begin:
04145	}
04146	
04147	//=============================================================================
04148	//
04149	// StopAttack
04150	//
04151	//=============================================================================
04152	
04153	function StopAttack()
04154	{	
04155		if(AnimProxy != None)
04156			AnimProxy.StopAttack();
04157	}
04158	
04159	//-----------------------------------------------------------------------------
04160	//
04161	// STATE PlayerRopeClimbing
04162	//
04163	//-----------------------------------------------------------------------------
04164	
04165	state PlayerRopeClimbing
04166	{
04167	ignores SeePlayer, HearNoise, Bump, AltFire, GrabEdge, Jump, SwitchWeapon, Touch;
04168	
04169		function PlayRopeClimb()
04170		{
04171			local name anim;
04172	
04173			if(Velocity.Z > 5)
04174				anim = 'ClimbUpRope';
04175			else if(Velocity.Z < -5)
04176				anim = 'ClimbDownRope';
04177			else
04178				anim = 'ClimbIdleRope';
04179	
04180			LoopAnim(anim, 1.0, 0.25);
04181			if(AnimProxy != None)
04182				AnimProxy.LoopAnim(anim, 1.0, 0.25);	
04183		}
04184	
04185		function AnimEnd()
04186		{
04187			PlayRopeClimb();
04188		}
04189	
04190		function BeginState()
04191		{
04192			// Sheath current weapon when climbing ropes
04193			InstantStow();
04194	
04195			if(AnimProxy != None)
04196				AnimProxy.GotoState('PlayerRopeClimbing');
04197	
04198			SetCrouch(false);
04199			bPressedJump = false;
04200			bRotateTorso = false;
04201			bCanFly = true;			// So client's don't simulate the fall
04202	
04203		    CameraAccel = 12;		
04204	
04205			PlayRopeClimb();
04206			Acceleration = vect(0, 0, 0);
04207		}
04208	
04209		function EndState()
04210		{
04211		    CameraAccel = Default.CameraAccel;		
04212	
04213			if (TheRope != None)
04214			{
04215				TheRope.DetachFromRope(self);
04216				TheRope = None;
04217			}
04218			bRotateTorso = Default.bRotateTorso;
04219			bCanFly = Default.bCanFly;
04220	
04221			if(AnimProxy != None)
04222				AnimProxy.GotoState('Idle');
04223		}
04224	
04225		function ZoneChange( ZoneInfo NewZone )
04226		{
04227			if (NewZone.bWaterZone)
04228			{
04229				setPhysics(PHYS_Swimming);
04230				GotoState('PlayerSwimming');
04231			}
04232		}
04233	
04234		exec function Use()
04235		{
04236			LeapOff();
04237		}
04238	
04239		function FallOff()
04240		{ // Release -- Used to drop Ragnar off the rope (when damaged or other reasons)
04241		  // Ragnar falls backwards
04242			local vector X, Y, Z;
04243	
04244			GetAxes(Rotation, X, Y, Z);
04245			Velocity = -X * 50;
04246			SetPhysics(PHYS_Falling);
04247			TheRope.DetachFromRope(self);
04248			TheRope = None;
04249			PlayWaiting(0.2);
04250			if (Region.Zone.bWaterZone)
04251			{
04252				setPhysics(PHYS_Swimming);
04253				NextStateAfterPain = 'PlayerSwimming';
04254			}
04255			else
04256			{
04257				if(AnimProxy != None)
04258					AnimProxy.GotoState('Idle');
04259	
04260				NextStateAfterPain = 'PlayerWalking';
04261			}
04262		}
04263	
04264		function LeapOff()
04265		{ // Release in the direction Ragnar is currently facing (when the Use key is pressed)
04266			local vector X, Y, Z;
04267			local vector deviation;
04268			local float jumpForce;
04269	
04270			deviation = (Location - TheRope.Location);
04271			if (VSize2D(deviation) > 50)
04272				jumpForce = 0.5;
04273			else
04274				jumpForce = 0.25;
04275			GetAxes(Rotation, X, Y, Z);
04276			AddVelocity(X*350 );//+ Z*JumpZ*jumpForce);
04277			SetPhysics(PHYS_Falling);
04278			TheRope.DetachFromRope(self);
04279			TheRope = None;
04280	
04281			PlayRopeLeapOff();
04282	
04283			if (Region.Zone.bWaterZone)
04284			{
04285				setPhysics(PHYS_Swimming);
04286				GotoState('PlayerSwimming');
04287			}
04288			else
04289			{
04290				if(AnimProxy != None)
04291					AnimProxy.GotoState('Idle');
04292	
04293				GotoState('PlayerWalking');
04294			}
04295		}
04296	
04297		function PlayChatting()
04298		{
04299		}
04300	
04301		exec function Taunt()
04302		{
04303		}
04304		
04305		function Landed(vector HitNormal, actor HitActor)
04306		{
04307		}
04308		
04309		function ProcessMove(float DeltaTime, vector NewAccel, eDodgeDir DodgeMove, rotator DeltaRot)	
04310		{
04311			PlayRopeClimb();
04312		}
04313	
04314		event PlayerTick( float DeltaTime )
04315		{
04316			if ( bUpdatePosition )
04317				ClientUpdatePosition();
04318	
04319			PlayerMove(DeltaTime);
04320		}
04321	
04322		function ServerMove
04323		(
04324			float TimeStamp, 
04325			vector Accel, 
04326			vector ClientLoc,
04327			bool NewbRun,
04328			bool NewbDuck,
04329			bool NewbJumpStatus, 
04330			bool bFired,
04331			bool bAltFired,
04332			bool bForceFire,
04333			bool bForceAltFire,
04334			eDodgeDir DodgeMove, 
04335			byte ClientRoll, 
04336			int View,
04337			optional byte OldTimeDelta,
04338			optional int OldAccel
04339		)
04340		{
04341			Global.ServerMove(TimeStamp, Accel, ClientLoc, NewbRun, NewbDuck, NewbJumpStatus,
04342								bFired, bAltFired, bForceFire, bForceAltFire, DodgeMove, ClientRoll, (32767 & (Rotation.Pitch/2)) * 32768 + (32767 & (Rotation.Yaw/2)));
04343		}
04344	
04345		function PlayerMove( float DeltaTime)
04346		{
04347			local vector NewAccel;
04348			local vector HandPos;
04349			local vector X,Y,Z;
04350			local vector RopeVector, VelocityLookahead, RopeDir, NewLocation;
04351	
04352			if(TheRope == None)
04353				return;
04354	
04355			// Mangle controls
04356			aForward *= 0.00;
04357			aStrafe  *= 0.00;
04358			aLookup  *= 0.24;
04359			aTurn    *= 0.24;
04360	
04361			if(aUp > 0)
04362			{ // Move slightly slower going up than going down
04363				aUp *= 0.056;
04364			}
04365			else
04366			{
04367				aUp *= 0.084;
04368			}
04369	
04370			if (Physics != PHYS_Flying)
04371				SetPhysics(PHYS_Flying);
04372	
04373			// Apply controls to velocity and ropedist
04374			Acceleration.X = 0;
04375			Acceleration.Y = 0;
04376			Velocity.X = 0;
04377			Velocity.Y = 0;
04378	
04379			if (aUp == 0)
04380			{	// Stop on a dime
04381				Acceleration.Z = 0;
04382				Velocity.Z = 0;
04383			}
04384	
04385			Velocity.Z += aUp * DeltaTime;
04386	
04387			if (Location.Z <= TheRope.RopeClimbBottom.Z)
04388			{	// Hit Bottom
04389				if (Location.Z < TheRope.RopeClimbBottom.Z)
04390				{
04391					SetLocation(TheRope.RopeClimbBottom);
04392				}
04393				Velocity.Z = Max(0, Velocity.Z);
04394			}
04395			else if (Location.Z >= TheRope.RopeClimbTop.Z)
04396			{	// Hit Top
04397				if (Location.Z > TheRope.RopeClimbTop.Z)
04398				{
04399					SetLocation(TheRope.RopeClimbTop);
04400				}
04401				Velocity.Z = Min(0, Velocity.Z);
04402			}
04403	
04404			// Update view rotation
04405			UpdateRotation(DeltaTime, 1);
04406	
04407			if ( Role < ROLE_Authority ) // then save this move and replicate it
04408				ReplicateMove(DeltaTime, NewAccel, DODGE_None, Rot(0,0,0));
04409			else
04410				ProcessMove(DeltaTime, NewAccel, DODGE_None, Rot(0,0,0));
04411			bPressedJump = false;
04412		}
04413	
04414		function PlayTakeHit(float tweentime, int damage, vector HitLoc, name damageType, vector Momentum, int BodyPart)
04415		{
04416			Super.PlayTakeHit(tweentime, damage, HitLoc, damageType, Momentum, BodyPart);
04417			FallOff();
04418		}
04419		
04420		function PlayDying(name DamageType, vector HitLocation)
04421		{
04422			BaseEyeHeight = Default.BaseEyeHeight;
04423			Super.PlayDying(DamageType, HitLocation);
04424		}
04425		
04426		function ChangedWeapon()
04427		{
04428			Inventory.ChangedWeapon();
04429			Weapon = None;
04430		}
04431	
04432	}
04433	
04434	//-----------------------------------------------------------------------------
04435	//
04436	// STATE PlayerSwimming
04437	//
04438	//-----------------------------------------------------------------------------
04439	
04440	state PlayerSwimming
04441	{
04442		function PlayMoving(optional float tween)
04443		{
04444			PlaySwimming();
04445		}
04446	
04447		function PlayUnderwaterSound()
04448		{
04449			AmbientSound = UnderwaterAmbient[Rand(5)];
04450		}
04451	
04452		function SetSurfaceSwim(bool surface)
04453		{
04454			bSurfaceSwimming = surface;
04455		}
04456	
04457		function StopUnderwaterSound()
04458		{
04459			AmbientSound = None;
04460		}
04461	
04462		function bool CanGotoPainState()
04463		{
04464			return(!bSurfaceSwimming);
04465		}
04466	
04467		function AnimEnd()
04468		{
04469			PlaySwimming();
04470		}
04471	
04472		function BeginState()
04473		{
04474			Super.BeginState();
04475			RotationRate.Pitch = 16000;
04476			PlayUnderwaterSound();
04477			bBurnable=False;
04478	
04479			InstantStow();		
04480			// Sheath current weapon when underwater
04481		}
04482	
04483		function EndState()
04484		{
04485			Super.EndState();
04486			RotationRate.Pitch = 0;
04487			SetSurfaceSwim(false);
04488			bBurnable=Default.bBurnable;
04489	
04490			WaterSpeed = 300;
04491			StopUnderwaterSound();
04492		}
04493	
04494		function HeadZoneChange(ZoneInfo NewZone)
04495		{
04496			local vector HitLocation, HitNormal;
04497			local vector Extent;
04498			
04499			Super.HeadZoneChange(NewZone);
04500	
04501			if(!NewZone.bWaterZone && !bSurfaceSwimming)
04502			{ // Surfaced
04503				SetSurfaceSwim(true);
04504	
04505				// Align the player directy to the surface
04506				GrabLocationUp = FindWaterLine(Location + vect(0, 0, 40), Location + vect(0, 0, -40));
04507				Extent.X = CollisionRadius;
04508				Extent.Y = CollisionRadius;
04509				Extent.Z = CollisionHeight;
04510				if(Trace(HitLocation, HitNormal, GrabLocationUp, Location, true, Extent) == None)
04511				{
04512					SetLocation(GrabLocationUp);
04513					Buoyancy = Mass; // Don't bob in the water!
04514					bNoSurfaceBob = true;
04515					Acceleration = vect(0, 0, 0);
04516					Velocity = vect(0, 0, 0);
04517					RotationRate.Pitch = 0;
04518					WaterSpeed = 200;
04519				}
04520				else
04521				{
04522					SetSurfaceSwim(false);
04523					RotationRate.Pitch = 16000;
04524					WaterSpeed = 300;
04525				}
04526			}
04527			else if(NewZone.bWaterZone && bSurfaceSwimming)
04528			{
04529				SetSurfaceSwim(false);
04530				RotationRate.Pitch = 16000;
04531				WaterSpeed = 300;
04532			}
04533	
04534			if(NewZone.bWaterZone)
04535				PlayUnderwaterSound();
04536			else
04537				StopUnderwaterSound();
04538		}
04539	
04540		function PlayerMove(float DeltaTime)
04541		{
04542			local rotator oldRotation;
04543			local vector X,Y,Z, NewAccel;
04544			local float Speed2D;
04545	
04546			if(bSurfaceSwimming)
04547			{
04548				GetAxes(ViewRotation,X,Y,Z);
04549	
04550				aForward *= 0.2;
04551				aStrafe  *= 0.1;
04552				aLookup  *= 0.24;
04553				aTurn    *= 0.24;
04554				aUp		 *= 0.1;
04555	
04556				if (aUp >= 0)
04557					aUp = 0;
04558				else
04559				{
04560					aForward = 0;
04561					aStrafe = 0;
04562				}
04563				NewAccel = aForward*X + aStrafe*Y + aUp*vect(0,0,1);
04564	//			NewAccel = aForward*X + aStrafe*Y;
04565	
04566				// Update rotation.
04567				oldRotation = Rotation;
04568				UpdateRotation(DeltaTime, 2);
04569	
04570				if ( Role < ROLE_Authority ) // then save this move and replicate it
04571					ReplicateMove(DeltaTime, NewAccel, DODGE_None, OldRotation - Rotation);
04572				else
04573					ProcessMove(DeltaTime, NewAccel, DODGE_None, OldRotation - Rotation);
04574				bPressedJump = false;
04575			}
04576			else
04577			{
04578				Super.PlayerMove(DeltaTime);
04579			}
04580		}
04581	
04582		function bool CheckWaterJump(out vector WallNormal)
04583		{
04584			local actor HitActor;
04585			local vector HitLocation, HitNormal, checkpoint, start, checkNorm, Extent;
04586	
04587			checkpoint = vector(Rotation);
04588			checkpoint.Z = 0.0;
04589			checkNorm = Normal(checkpoint);
04590			checkPoint = Location + CollisionRadius * checkNorm;
04591			Extent = CollisionRadius * vect(1,1,0);
04592			Extent.Z = CollisionHeight;
04593			HitActor = Trace(HitLocation, HitNormal, checkpoint, Location, true, Extent);
04594			if ( (HitActor != None) && (Pawn(HitActor) == None) )
04595			{
04596				WallNormal = -1 * HitNormal;
04597				start = Location;
04598				start.Z += 1.1 * MaxStepHeight;
04599				checkPoint = start + 2 * CollisionRadius * checkNorm;
04600				HitActor = Trace(HitLocation, HitNormal, checkpoint, start, true);
04601				if (HitActor == None)
04602					return true;
04603			}
04604	
04605			return false;
04606		}
04607	
04608		function CheckForSubmerge()
04609		{
04610			local float dp;
04611	
04612	//		if((aUp < 0) || (ViewRotation.Pitch > 32768 && ViewRotation.Pitch < 55000 && aForward > 0))
04613			dp = Normal(Acceleration) dot vect(0,0,-1);
04614			if(Acceleration.Z<0 && dp>0.85)
04615			{
04616				SetSurfaceSwim(false);
04617	
04618				WaterSpeed = 300;
04619				Buoyancy = Default.Buoyancy;
04620				bNoSurfaceBob = false;
04621				Velocity = vect(0, 0, -50);
04622				RotationRate.Pitch = 16000;
04623			}
04624		}
04625	
04626		function ProcessMove(float DeltaTime, vector NewAccel, eDodgeDir DodgeMove, rotator DeltaRot)	
04627		{
04628			local vector X,Y,Z, Temp;
04629		
04630			GetAxes(ViewRotation,X,Y,Z);
04631			Acceleration = NewAccel;
04632	
04633			PlaySwimming();
04634	
04635			if(bSurfaceSwimming)
04636				CheckForSubmerge();
04637	
04638	/*
04639			if(bSurfaceSwimming && CheckWaterJump(Temp)) //check for waterjump
04640			{
04641				velocity.Z = 330 + 2 * CollisionRadius; //set here so physics uses this for remainder of tick
04642	//			PlayDuck();
04643				GotoState('PlayerWalking');
04644			}				
04645	*/
04646			if(bSurfaceSwimming)
04647			{
04648				Acceleration.Z = 0;
04649			}
04650		}
04651	
04652		function UpdateRotation(float DeltaTime, float maxPitch)
04653		{
04654			local rotator newRotation;
04655	
04656			// UpdateRotation to properly rotate Ragnar while swimming (does NOT rotate while surfaceswimming, though)
04657			if(!bSurfaceSwimming)
04658			{
04659				DesiredRotation = ViewRotation; //save old rotation
04660				ViewRotation.Pitch += 32.0 * DeltaTime * aLookUp;
04661				ViewRotation.Pitch = ViewRotation.Pitch & 65535;
04662				If ((ViewRotation.Pitch > 18000) && (ViewRotation.Pitch < 49152))
04663				{
04664					If (aLookUp > 0) 
04665						ViewRotation.Pitch = 18000;
04666					else
04667						ViewRotation.Pitch = 49152;
04668				}
04669				ViewRotation.Yaw += 32.0 * DeltaTime * aTurn;
04670		//		ViewShake(deltaTime); // RUNE:  ViewShake is handled in the Camera code
04671				ViewFlash(deltaTime);
04672					
04673				newRotation = ViewRotation;
04674				If ( (newRotation.Pitch > maxPitch * RotationRate.Pitch) && (newRotation.Pitch < 65536 - maxPitch * RotationRate.Pitch) )
04675				{
04676					If (ViewRotation.Pitch < 32768) 
04677						newRotation.Pitch = maxPitch * RotationRate.Pitch;
04678					else
04679						newRotation.Pitch = 65536 - maxPitch * RotationRate.Pitch;
04680				}
04681				setRotation(newRotation);
04682			}
04683			else
04684			{
04685				Super.UpdateRotation(DeltaTime, maxPitch);
04686			}
04687		}
04688	
04689		function bool GrabEdge(float grabDistance, vector grabNormal)
04690		{ // RUNE	
04691			if(AnimProxy != None && AnimProxy.GetStateName() == 'Idle'
04692				&& !HeadRegion.Zone.bWaterZone)
04693			{ // Only grab edges if in the idle state and head is above water
04694				GrabLocationUp.X = Location.X;
04695				GrabLocationUp.Y = Location.Y;
04696				GrabLocationUp.Z = Location.Z + grabDistance + 8;
04697			
04698				GrabLocationIn.X = Location.X + grabNormal.X * (CollisionRadius + 4);
04699				GrabLocationIn.Y = Location.Y + grabNormal.Y * (CollisionRadius + 4);
04700				GrabLocationIn.Z = GrabLocationUp.Z + CollisionHeight;
04701			
04702				SetRotation(rotator(grabNormal));
04703				ViewRotation.Yaw = Rotation.Yaw; // Align View with Player position while grabbing edge
04704	
04705				// Save the final distance (used for choosing the correct anim)
04706				GrabLocationDist = GrabLocationUp.Z - Location.Z;
04707	
04708				// Final, absolute check if the player can fit in the new location.
04709				// if the player fits, then it is a valid edge grab
04710				if(SetLocation(GrabLocationIn))
04711				{
04712					if(AnimProxy != None)
04713						AnimProxy.GotoState('EdgeHanging');			
04714					GotoState('EdgeHanging');
04715	
04716					return(true);
04717				}
04718			}
04719			
04720			return(false);
04721		}
04722	}
04723	
04724	//------------------------------------------------------------
04725	//
04726	// Dying
04727	//
04728	//------------------------------------------------------------
04729	
04730	state Dying
04731	{
04732	ignores SeePlayer, EnemyNotVisible, HearNoise, KilledBy, Trigger, Bump, HitWall, HeadZoneChange, FootZoneChange, ZoneChange, Falling, WarnTarget, Died, LongFall, PainTimer, /*Landed,*/ SwitchWeapon;
04733	
04734		function ServerReStartPlayer()
04735		{
04736			if(!bCanRestart)
04737				return;
04738	
04739			Super.ServerReStartPlayer();
04740	
04741			PlayerRestart();
04742		}
04743	
04744		function BeginState()
04745		{
04746			local int i;
04747			local int joint;
04748			local vector X, Y, Z;
04749	
04750			Super.BeginState();
04751	
04752			// Drop any stowed weapons
04753			for(i = 0; i < 3; i++)
04754			{
04755				if(StowSpot[i] != None)
04756				{		
04757					switch(StowSpot[i].MeleeType)
04758					{
04759					case MELEE_SWORD:
04760						joint = JointNamed('attatch_sword');
04761						break;
04762					case MELEE_AXE:
04763						joint = JointNamed('attach_axe');
04764						break;
04765					case MELEE_HAMMER:
04766						joint = JointNamed('attach_hammer');
04767						break;
04768					default:
04769						// Unknown or non-stow item
04770						joint = 0;
04771						break;
04772					}
04773	
04774					if(joint != 0)
04775					{
04776						DetachActorFromJoint(joint);
04777							
04778						GetAxes(Rotation, X, Y, Z);
04779						StowSpot[i].DropFrom(GetJointPos(joint));
04780					
04781						StowSpot[i].SetPhysics(PHYS_Falling);
04782						StowSpot[i].Velocity = Y * 100 + X * 75;
04783						StowSpot[i].Velocity.Z = 50;
04784						
04785						StowSpot[i].GotoState('Drop');
04786						StowSpot[i].DisableSwipeTrail();
04787	
04788						StowSpot[i] = None; // Remove the StowWeapon from the actor
04789					}
04790				}		
04791			}
04792	
04793			Buoyancy = Mass + 5;
04794			LookTarget=None;
04795			LookSpot=vect(0,0,0);
04796			SetCollision(true, false, false);
04797			SetPhysics(PHYS_Falling);
04798		}
04799	
04800		function EndState()
04801		{
04802			Buoyancy=Default.Buoyancy;
04803			Super.EndState();
04804		}
04805	
04806	/*	function Done()
04807		{	// Not run on clients
04808			SetPhysics(PHYS_None);
04809			SetCollision(false, false, false);
04810			bCollideWorld = false;
04811			ReplaceWithCarcass();
04812		}*/
04813	
04814		function Landed(vector HitNormal, actor HitActor)
04815		{
04816			SetPhysics(PHYS_None);
04817			SetCollision(false, false, false);
04818			bCollideWorld = true;
04819		}
04820	
04821		function AnimEnd()
04822		{
04823			ReplaceWithCarcass();
04824		}
04825	
04826	Begin:
04827	/* Changed to net friendly events
04828		// Override Pawn label (don't do collision size changes)
04829		WaitForLanding();
04830		FinishAnim();
04831		Done();
04832	*/
04833	}
04834	
04835	//-----------------------------------------------------------------------------
04836	//
04837	// STATE Scripting
04838	//
04839	// This state disallows any player input until the cinema ends
04840	//-----------------------------------------------------------------------------
04841	function ReleaseFromCinematic();
04842	
04843	state Scripting
04844	{
04845	ignores SeePlayer, HearNoise, Bump, GrabEdge, Jump, SwitchWeapon, Fire, AltFire;
04846		
04847		function Landed(vector HitNormal, actor HitActor)
04848		{
04849		}
04850	
04851		exec function Taunt()	{}
04852		exec function Fly()		{}
04853		exec function Walk()	{}
04854		exec function Ghost()	{}
04855		exec function Powerup()	{}
04856		exec function Throw()	{}
04857	
04858		simulated function DetermineLookFocus()	{}
04859	
04860		function bool CanBeStatued()		{	return false;	}
04861		function bool CanGotoPainState()	{	return(false);	}
04862		function bool JointDamaged(int Damage, Pawn EventInstigator, vector HitLoc, vector Momentum, name DamageType, int joint)
04863		{
04864			return false;
04865		}
04866		
04867		function ProcessMove(float DeltaTime, vector NewAccel, eDodgeDir DodgeMove, rotator DeltaRot)	
04868		{
04869			Acceleration = vect(0,0,0);
04870		}
04871	
04872		event PlayerTick( float DeltaTime )
04873		{
04874			if ( bUpdatePosition )
04875				ClientUpdatePosition();
04876			
04877			PlayerMove(DeltaTime);
04878	
04879			if (bScriptMoving)
04880				PlayMoving();
04881		}
04882	
04883		function PlayerMove( float DeltaTime)
04884		{
04885		}
04886	
04887		function PlayTakeHit(float tweentime, int damage, vector HitLoc, name damageType, vector Momentum, int BodyPart)
04888		{
04889		}
04890		
04891		function PlayDying(name DamageType, vector HitLocation)
04892		{
04893			BaseEyeHeight = Default.BaseEyeHeight;
04894			Super.PlayDying(DamageType, HitLocation);
04895		}
04896		
04897		function EndState()
04898		{
04899			bOverrideLookTarget=false;
04900			bScriptMoving = false;
04901			OrderObject = None;
04902		}
04903	
04904		function BeginState()
04905		{
04906			bPressedJump = false;		
04907		}
04908	
04909		function ReleaseFromCinematic()
04910		{	// Release the player/game from Cinema state
04911			CineCamera(ViewTarget).FireLastPointEvent();
04912			CineCamera(ViewTarget).ResetPath();
04913	
04914			ViewTarget = None;
04915			BlendAnimSequence = 'None';
04916	
04917			// Reset view parameters (gamespeed, screenflash, etc)
04918			DesiredFlashScale = Default.DesiredFlashScale;
04919			DesiredFlashFog = Default.DesiredFlashFog;
04920			FlashScale = Default.FlashScale;
04921			FlashFog = Default.FlashFog;
04922			InstantFlash = 0;
04923			InstantFog = vect(0,0,0);
04924			FovAngle = Default.FovAngle;
04925			ServerSetSloMo(1.0); // Reset game speed to normal
04926			bHidden = false;
04927					
04928			if(AnimProxy != None)
04929			{
04930				AnimProxy.BlendAnimSequence = 'None';
04931				AnimProxy.GotoState('Idle');
04932			}
04933	
04934			if(myHud != None)
04935				myHud.GotoState('Cinematic', 'end');
04936	
04937			if (Region.Zone.bWaterZone)
04938				GotoState('PlayerSwimming');
04939			else
04940				GotoState('PlayerWalking');
04941		}
04942	
04943		// Use, Fire, AltFire allow skipping cinematics
04944		exec function Use()
04945		{
04946			if (CineCamera(ViewTarget).bInteruptable)
04947			{
04948				StopAllSound();
04949				ReleaseFromCinematic();
04950			}
04951		}
04952	
04953		//============================================
04954		// ScriptPoint support functions
04955		//============================================
04956	
04957		function ExecuteScriptPoint()
04958		{
04959			local ScriptPoint Dest;
04960			local actor A;
04961	
04962			teststring = "ExecuteScriptPointScript";
04963	
04964			Dest = ScriptPoint(OrderObject);
04965			if (Dest != None)
04966			{
04967				if (Dest.ArriveSound != None)
04968					PlaySound(Dest.ArriveSound,,,true);
04969				
04970				FireEvent(Dest.ArriveEvent);
04971	
04972				NextState = Dest.NextOrder;
04973				NextLabel = '';
04974				NextPoint = ActorTagged( Dest.NextOrderTag );
04975	
04976				if (Dest.ArriveState != '')
04977				{
04978					OrderObject = ActorTagged( Dest.ArriveStateTag );
04979					GotoState( Dest.ArriveState, Dest.ArriveStateLabel );
04980				}
04981				else if (NextState != '')
04982				{
04983					OrderObject = NextPoint;
04984					GotoState(NextState, NextLabel);
04985				}
04986				else if (Dest.bReleaseUponArrival)
04987				{	// Release to normal AI
04988					OrderObject = None;
04989					ReleaseFromCinematic();
04990				}
04991			}
04992		}
04993	
04994		//============================================
04995		// ScriptAction support functions
04996		//============================================
04997	
04998		function ExecuteScriptAction()
04999		{
05000			local ScriptAction Action;
05001	
05002			Action = ScriptAction(OrderObject);
05003			if (Action != None)
05004			{
05005				NextState = Action.NextOrder;
05006				NextLabel = '';
05007				NextPoint = ActorTagged( Action.NextOrderTag );
05008				
05009				if (NextState != '')
05010				{
05011					OrderObject = NextPoint;
05012					GotoState(NextState, NextLabel);
05013				}
05014				else if (Action.bReleaseUponCompletion)
05015				{	// Release to normal AI
05016					OrderObject = None;
05017					ReleaseFromCinematic();
05018				}
05019			}
05020		}
05021	
05022		function SpeechTimer()
05023		{
05024			local string letter;
05025			local float alpha;
05026			local ScriptAction Action;
05027			local ScriptDispatcher Dispatch;
05028	
05029			if (ScriptAction(OrderObject) != None)
05030			{
05031				Action = ScriptAction(OrderObject);
05032	
05033				// parse control strings
05034				if (Len(Action.ControlMouth) > 0)
05035				{
05036					letter = Mid(Action.ControlMouth, SpeechPos, 1);
05037					alpha = float(Asc(letter) - Asc("A"))/25.0;
05038					OpenMouth(FClamp(alpha, 0, 1), 1.0);
05039				}
05040				if (Len(Action.ControlHead) > 0)
05041				{
05042					letter = Mid(Action.ControlHead, SpeechPos, 1);
05043					alpha = float(Asc(letter) - Asc("A"))/25.0;
05044					bOverrideLookTarget=true;
05045					targetangle.Yaw = MaxHeadAngle.Yaw * (alpha*2-1);
05046					targetangle.Pitch = 0;
05047					targetangle.Roll = 0;
05048				}
05049				SpeechTime = Action.ControlTimeGranularity;
05050				SpeechPos++;
05051			}
05052			else if (ScriptDispatcher(OrderObject) != None)
05053			{
05054				Dispatch = ScriptDispatcher(OrderObject);
05055	
05056				// parse control strings
05057				if (Len(Dispatch.ControlMouth[DispatchAction-1]) > 0)
05058				{
05059					letter = Mid(Dispatch.ControlMouth[DispatchAction-1], SpeechPos, 1);
05060				//slog("Speaking letter"@letter);
05061					alpha = float(Asc(letter) - Asc("A"))/25.0;
05062					OpenMouth(FClamp(alpha, 0, 1), 1.0);
05063				}
05064				if (Len(Dispatch.ControlHead[DispatchAction-1]) > 0)
05065				{
05066					letter = Mid(Dispatch.ControlHead[DispatchAction-1], SpeechPos, 1);
05067					alpha = float(Asc(letter) - Asc("A"))/25.0;
05068					bOverrideLookTarget=true;
05069					targetangle.Yaw = MaxHeadAngle.Yaw * (alpha*2-1);
05070					targetangle.Pitch = 0;
05071					targetangle.Roll = 0;
05072				}
05073				SpeechTime = Dispatch.ControlTimeGranularity;
05074				SpeechPos++;
05075			}
05076		}
05077	
05078		function Timer()
05079		{
05080			if (ScriptAction(OrderObject)!=None && ScriptAction(OrderObject).SoundToPlay != None)
05081				PlaySound(ScriptAction(OrderObject).SoundToPlay,SLOT_Talk,,true);
05082		}
05083	
05084		function FinishScriptDispatcher()
05085		{
05086			local ScriptDispatcher SD;
05087	
05088			SD = ScriptDispatcher(OrderObject);
05089			if (SD != None)
05090			{
05091				NextState = SD.NextOrder;
05092				NextLabel = '';
05093				NextPoint = ActorTagged( SD.NextOrderTag );
05094				
05095				if (NextState != '')
05096				{
05097					OrderObject = NextPoint;
05098					GotoState(NextState, NextLabel);
05099				}
05100				else
05101				{	// Release to normal AI
05102					OrderObject = None;
05103					ReleaseFromCinematic();
05104				}
05105			}
05106		}
05107	
05108		function ExecuteScriptDispatcherAction(int i)
05109		{
05110			local ScriptDispatcher SD;
05111	
05112			SD = ScriptDispatcher(OrderObject);
05113	
05114	
05115			if (SD.LookTarget[i] != '' ||
05116				SD.Actions[i].EventToFire != '' ||
05117				SD.Actions[i].AnimToPlay != '' ||
05118				SD.Actions[i].SoundToPlay != None)
05119			{
05120	//			bTaskLocked = SD.Actions[i].bTaskLocked;
05121			}
05122	
05123			if (SD.LookTarget[i] != '')
05124			{	// Look at looktarget
05125				bOverrideLookTarget=false;
05126				LookAt(ActorTagged(SD.LookTarget[i]));
05127				SD.ControlHead[i] = "";
05128			}
05129	
05130			if (SD.ControlTimeGranularity > 0)
05131			{	// Setup for Sync controls
05132				SpeechPos = 0;
05133				SpeechTime = SD.ControlTimeGranularity;
05134				SD.ControlMouth[i] = Caps(SD.ControlMouth[i]);
05135				SD.ControlHead[i] = Caps(SD.ControlHead[i]);
05136			}
05137	
05138			FireEvent(SD.Actions[i].EventToFire);
05139	
05140			if (SD.Actions[i].SoundToPlay != None)
05141				PlaySound(SD.Actions[i].SoundToPlay,SLOT_Talk,,true);
05142	
05143			if (SD.Actions[i].AnimToPlay != '')
05144			{
05145				LoopAnim(SD.Actions[i].AnimToPlay, 1.0, 0.1);
05146				if(AnimProxy != None)
05147					AnimProxy.LoopAnim(SD.Actions[i].AnimToPlay, 1.0, 0.1);
05148			}
05149		}
05150	
05151	HandleScriptDispatcher:
05152		if (ScriptDispatcher(OrderObject)!=None)
05153		{
05154			if (ScriptDispatcher(OrderObject).bWaitToBeTriggered)
05155			{	// Pend until trigger fires
05156				ScriptDispatcher(OrderObject).WaitingScripter = self;
05157				WaitForRelease();
05158			}
05159	
05160			for (DispatchAction=0; DispatchAction<12; DispatchAction++)
05161			{
05162				if (ScriptDispatcher(OrderObject).Actions[DispatchAction].Delay > 0)
05163					Sleep(ScriptDispatcher(OrderObject).Actions[DispatchAction].Delay);
05164	
05165				ExecuteScriptDispatcherAction(DispatchAction);
05166			}
05167	
05168			FinishScriptDispatcher();
05169		}
05170	
05171		Goto('done');
05172	
05173	HandleScriptAction:
05174		teststring = "HandleScriptAction";
05175	
05176		if (ScriptAction(OrderObject)!=None)
05177		{
05178			//slog(name@"scripting"@OrderObject.tag);
05179	
05180			if (ScriptAction(OrderObject).bWaitToBeTriggered)
05181			{	// Pend until trigger fires
05182				ScriptAction(OrderObject).WaitingScripter = self;
05183				
05184				teststring = "WaitingToBeReleased";
05185				WaitForRelease();
05186				teststring = "Released";
05187			}
05188	
05189			if (ScriptAction(OrderObject).LookTarget != '')
05190			{	// Look at looktarget
05191				bOverrideLookTarget=false;
05192				LookAt(ActorTagged(ScriptAction(OrderObject).LookTarget));
05193				ScriptAction(OrderObject).ControlHead = "";
05194			}
05195	
05196			if (ScriptAction(OrderObject).ControlTimeGranularity > 0)
05197			{	// Setup for Sync controls
05198				SpeechPos = 0;
05199				SpeechTime = ScriptAction(OrderObject).ControlTimeGranularity;
05200				ScriptAction(OrderObject).ControlMouth = Caps(ScriptAction(OrderObject).ControlMouth);
05201				ScriptAction(OrderObject).ControlHead = Caps(ScriptAction(OrderObject).ControlHead);
05202			}
05203	
05204			if (ScriptAction(OrderObject).bTurnToRotation)
05205			{	// Turn to ScriptAction's Rotation
05206				DesiredRotation = OrderObject.Rotation;
05207				PlayTurning(0.2);
05208				FinishAnim();
05209			}
05210	
05211			if (ScriptAction(OrderObject).bFireEventImmediately)
05212			{	// Fire pre trigger
05213				//slog("triggering"@OrderObject.event);
05214				FireEvent(OrderObject.Event);
05215			}
05216	
05217			// Queue the sound
05218			if (ScriptAction(OrderObject).SoundToPlay != None)
05219				SetTimer(ScriptAction(OrderObject).PauseBeforeSound, false);
05220	
05221			if (ScriptAction(OrderObject).AnimToPlay != '')
05222			{	// Play/Loop the anim
05223				if (ScriptAction(OrderObject).AnimTimeToLoop > 0)
05224				{
05225					LoopAnim(ScriptAction(OrderObject).AnimToPlay, 1.0, 0.1);
05226					if(AnimProxy != None)
05227						AnimProxy.LoopAnim(ScriptAction(OrderObject).AnimToPlay, 1.0, 0.1);
05228	
05229					Sleep(ScriptAction(OrderObject).AnimTimeToLoop);
05230				}
05231				else
05232				{
05233					PlayAnim(ScriptAction(OrderObject).AnimToPlay, 1.0, 0.1);
05234					if(AnimProxy != None)
05235						AnimProxy.PlayAnim(ScriptAction(OrderObject).AnimToPlay, 1.0, 0.1);
05236	
05237					FinishAnim();
05238				}
05239			}
05240	
05241			if (!ScriptAction(OrderObject).bFireEventImmediately)
05242			{	// Fire post trigger
05243				//slog("triggering"@OrderObject.event);
05244				FireEvent(OrderObject.Event);
05245			}
05246		}
05247	
05248		ExecuteScriptAction();
05249		Goto('done');
05250	
05251	HandleScriptPoint:
05252		teststring = "HandleScriptPoint";
05253		if (ScriptPoint(OrderObject) != None && ScriptPoint(OrderObject).LookTarget != '')
05254		{
05255			bOverrideLookTarget=false;
05256			LookAt(ActorTagged(ScriptPoint(OrderObject).LookTarget));
05257		}
05258		
05259	ContinueScripting:
05260		if (actorReachable(OrderObject))
05261		{
05262		teststring = "reachable";
05263			bScriptMoving = true;
05264			MoveToward(OrderObject, MovementSpeed);
05265			bScriptMoving = false;
05266			PlayWaiting(0.1);
05267	
05268			if (ScriptPoint(OrderObject)!=None)
05269			{
05270				if (ScriptPoint(OrderObject).bTurnToRotation)
05271				{	// Turn to ScriptPoint rotation
05272					DesiredRotation = OrderObject.Rotation;
05273					PlayTurning(0.2);
05274					FinishAnim();
05275				}
05276	
05277				if (ScriptPoint(OrderObject).ArriveAnim != '')
05278				{	// Play anim
05279					if (ScriptPoint(OrderObject).ArrivePause > 0)
05280					{
05281						LoopAnim(ScriptPoint(OrderObject).ArriveAnim, 1.0, 0.1);
05282						if(AnimProxy != None)
05283							AnimProxy.LoopAnim(ScriptPoint(OrderObject).ArriveAnim, 1.0, 0.1);
05284	
05285						Sleep(ScriptPoint(OrderObject).ArrivePause);
05286					}
05287					else
05288					{
05289						PlayAnim(ScriptPoint(OrderObject).ArriveAnim, 1.0, 0.1);
05290						if(AnimProxy != None)
05291							AnimProxy.PlayAnim(ScriptPoint(OrderObject).ArriveAnim, 1.0, 0.1);
05292	
05293						FinishAnim();
05294					}
05295				}
05296			}
05297			ExecuteScriptPoint();
05298		}
05299		else if (FindBestPathToward(OrderObject))
05300		{
05301		teststring = "pathable";
05302			bScriptMoving = true;
05303			MoveToward(MoveTarget, MovementSpeed);
05304			bScriptMoving = false;
05305			PlayWaiting(0.1);
05306			Goto('ContinueScripting');
05307		}
05308		else
05309		{
05310		teststring = Orderobject@"unpathable";
05311			TweenToWaiting(0.2);
05312			FinishAnim();
05313			PlayWaiting();
05314			Sleep(1);
05315			Goto('HandleScriptPoint');
05316		}
05317		Goto('done');
05318	
05319	begin:
05320		Acceleration = vect(0,0,0);
05321		Velocity = vect(0,0,0);
05322		PlayWaiting(0.2);
05323	
05324		if (ScriptPoint(OrderObject) != None)
05325		{
05326			bHurrying = !ScriptPoint(OrderObject).bWalkToThisPoint;
05327			UpdateMovementSpeed();
05328			Goto('HandleScriptPoint');
05329		}
05330		else if (ScriptAction(OrderObject) != None)
05331		{
05332			Goto('HandleScriptAction');
05333		}
05334		else if (ScriptDispatcher(OrderObject) != None)
05335		{
05336			Goto('HandleScriptDispatcher');
05337		}
05338	
05339	Done:
05340	
05341	}
05342	
05343	//------------------------------------------------------------
05344	//
05345	// Pain
05346	//
05347	// Ragnar pain does nothing but cause pain to occur on the torso
05348	//------------------------------------------------------------
05349	
05350	state Pain
05351	{
05352		function bool CanGotoPainState()
05353		{ // Do not allow the actor to enter the painstate when already in pain
05354			return(false);
05355		}
05356	
05357	begin:
05358		if(AnimProxy != None && !bBloodLust)
05359		{
05360			if(AnimProxy.CanGotoPainState())
05361			{
05362				AnimProxy.GotoState('Pain');
05363			}
05364		}
05365	
05366		GotoState(NextStateAfterPain);
05367	}
05368	
05369	
05370	//================================================
05371	//
05372	// Statue
05373	//
05374	//================================================
05375	State() Statue
05376	{
05377	ignores PowerupFire, PowerupBlaze, PowerupStone, PowerupIce, PowerupFriend, SetOnFire, WeaponActivate, SwipeEffectStart;
05378	
05379		exec function Fire( optional float F )		{}
05380		exec function AltFire( optional float F )	{}
05381		exec function Use()							{}
05382		exec function Throw()						{}
05383		exec function Powerup()						{}
05384		exec function Taunt()						{}
05385		exec function SwitchWeapon(byte F)			{}
05386	
05387		function bool CanBeStatued()		{	return false;	}
05388		function bool CanGotoPainState()	{	return(false);	}
05389	
05390		function ZoneChange(ZoneInfo newZone)
05391		{
05392			// don't go to swimming
05393		}
05394	
05395		event Tick(float DeltaTime)
05396		{
05397			local int i;
05398	
05399			// Update Camera Timer
05400			CurrentTime += DeltaTime / Level.TimeDilation;
05401	
05402			// Atrophy Strength
05403			StrengthDecay(DeltaTime);
05404	
05405			// Handle level fade in
05406			if (LevelFadeAlpha > 0)
05407			{
05408				LevelFadeAlpha -= DeltaTime * Level.FadeRate;
05409				if (LevelFadeAlpha < 0)
05410					LevelFadeAlpha = 0;
05411			}
05412		}
05413	
05414		event PlayerTick( float DeltaTime )
05415		{
05416			if ( bUpdatePosition )
05417				ClientUpdatePosition();
05418			
05419			PlayerMove(DeltaTime);
05420		}
05421	
05422		function PlayerMove( float DeltaTime )
05423		{
05424			if ( Role < ROLE_Authority ) // then save this move and replicate it
05425				ReplicateMove(DeltaTime, vect(0,0,0), Dodge_None, rot(0,0,0));
05426		}
05427	
05428		function EMatterType MatterForJoint(int joint)
05429		{
05430			return MATTER_STONE;
05431		}
05432	
05433		function SpawnDebris(vector Momentum)
05434		{
05435			local int numchunks;
05436			local debris d;
05437			local vector loc;
05438			local float scale;
05439			local int i;
05440	
05441			// Spawn cloud
05442			DebrisCloud();
05443	
05444			// Find appropriate size of chunks
05445			numchunks = Clamp(Mass/10, 2, 15);
05446			scale = (CollisionRadius*CollisionRadius*CollisionHeight) / (numchunks*500);
05447			scale = scale ** 0.3333333;
05448	
05449			// Spawn debris
05450			for (i=0; i<numchunks; i++)
05451			{
05452				loc = Location;
05453				loc.X += (FRand()*2-1)*CollisionRadius;
05454				loc.Y += (FRand()*2-1)*CollisionRadius;
05455				loc.Z += (FRand()*2-1)*CollisionHeight;
05456				d = Spawn(class'debrisstone',,,loc);
05457				if (d != None)
05458				{
05459					d.SetSize(scale);
05460					d.SetMomentum(Momentum);
05461				}
05462			}
05463		}
05464	
05465		function PlayDyingSound(name damageType)
05466		{
05467			PlaySound(Sound'WeaponsSnd.impcrashes.crashxstone01', SLOT_Pain);
05468		}
05469	
05470		function bool JointDamaged(int Damage, Pawn EventInstigator, vector HitLoc, vector Momentum, name DamageType, int joint)
05471		{
05472			local actor A;
05473	
05474			if (DamageType=='sever' || DamageType=='thrownweaponsever' ||
05475				DamageType=='fire' || DamageType=='electricity')
05476				return false;
05477	
05478			SpawnDebris(Momentum);
05479			InventoryNormal();
05480			bHidden=true;
05481			Died(EventInstigator, DamageType, HitLoc);
05482	
05483			return false;
05484		}
05485	
05486		function CreatureStatue()
05487		{
05488			local int ix;
05489	
05490			for (ix=0; ix<16; ix++)
05491			{
05492				SkelGroupSkins[ix] = texture'statues.sb_body_stone';
05493			}
05494		}
05495	
05496		function DebrisCloud()
05497		{	// Spawn obscuring cloud
05498			local DebrisCloud c;
05499			c = Spawn(class'DebrisCloud');
05500			c.SetRadius(Max(CollisionRadius,CollisionHeight));
05501		}
05502	
05503		function CreatureNormal()
05504		{
05505			local int ix;
05506	
05507			// Transform creature to default skin
05508			for (ix=0; ix<16; ix++)
05509				SkelGroupSkins[ix] = Default.SkelGroupSkins[ix];
05510			SetDefaultPolygroups();
05511		}
05512	
05513		function InventoryStatue()
05514		{
05515			local Inventory inv;
05516			local int ix;
05517	
05518			// Transform inventory if visible
05519			inv = Inventory;
05520			while (inv != None)
05521			{
05522				if (!inv.bHidden)
05523				{
05524					for (ix=0; ix<16; ix++)
05525					{
05526						if (inv.SkelGroupSkins[ix] != None)
05527						{
05528							inv.SkelGroupSkins[ix] = texture'statues.sb_body_stone';
05529							inv.bSweepable=false;
05530						}
05531					}
05532				}
05533				inv = inv.Inventory;
05534			}
05535		}
05536	
05537		function InventoryNormal()
05538		{
05539			local Inventory inv;
05540			local int ix;
05541	
05542			// Transform inventory if visible
05543			inv = Inventory;
05544			while (inv != None)
05545			{
05546				if (!inv.bHidden)
05547				{
05548					for (ix=0; ix<16; ix++)
05549						inv.SkelGroupSkins[ix] = None;
05550					inv.SetDefaultPolygroups();
05551					inv.bSweepable=inv.Default.bSweepable;
05552				}
05553				inv = inv.Inventory;
05554			}
05555		}
05556	
05557		function Timer()
05558		{	// If no one kills, kill self
05559			SpawnDebris(vect(0,0,0));
05560			InventoryNormal();
05561			bHidden=true;
05562			Died(StatueInstigator, 'blunt', Location);
05563		}
05564	
05565		function BeginState()
05566		{
05567			Acceleration=vect(0,0,0);
05568			SetPhysics(PHYS_Falling);
05569			CreatureStatue();
05570			InventoryStatue();
05571			Buoyancy = 10;
05572	
05573			if (Weapon!=None && Weapon.bPoweredUp)
05574				Weapon.PowerupEnd();
05575	
05576			bCanLook = false;
05577			Target = None;
05578			bProjTarget = false;
05579			if (Weapon!=None)
05580				Weapon.FinishAttack();
05581			SlowAnimation();
05582	
05583			SetTimer(10, false);
05584		}
05585	
05586		function EndState()
05587		{
05588			Buoyancy = Default.Buoyancy;
05589			bCanLook = Default.bCanLook;
05590			SetTimer(0, false);
05591			bMovable = Default.bMovable;
05592			bProjTarget = Default.bProjTarget;
05593			if (AnimProxy != None)
05594				AnimProxy.GotoState('Idle');
05595		}
05596	
05597		function Landed(vector HitNormal, actor HitActor)
05598		{
05599			bMovable = false;
05600			global.Landed(HitNormal, HitActor);
05601		}
05602	
05603		simulated function SlowAnimation()
05604		{
05605			//Should play slowing animation here
05606			PlayAnim('StatueAnim', 1.0, 0.3);
05607			if (AnimProxy != None)
05608			{
05609				AnimProxy.PlayAnim('StatueAnim', 1.0, 0.3);
05610				AnimProxy.GotoState('Dying');
05611			}
05612			bMovable=false;
05613		}
05614	}
05615	
05616	
05617	//================================================
05618	//
05619	// IceStatue
05620	//
05621	// Used only for Ice Powerup
05622	//================================================
05623	State() IceStatue
05624	{
05625	ignores PowerupFire, PowerupBlaze, PowerupStone, PowerupIce, PowerupFriend, SetOnFire, WeaponActivate, SwipeEffectStart;
05626	
05627		exec function Fire( optional float F )		{}
05628		exec function AltFire( optional float F )	{}
05629		exec function Use()							{}
05630		exec function Throw()						{}
05631		exec function Powerup()						{}
05632		exec function Taunt()						{}
05633		exec function SwitchWeapon(byte F)			{}
05634	
05635		function bool CanBeStatued()		{	return false;	}
05636		function bool CanGotoPainState()	{	return(false);	}
05637	
05638		event Tick(float DeltaTime)
05639		{
05640			local int i;
05641	
05642			// Update Camera Timer
05643			CurrentTime += DeltaTime / Level.TimeDilation;
05644	
05645			// Atrophy Strength
05646			StrengthDecay(DeltaTime);
05647	
05648			// Handle level fade in
05649			if (LevelFadeAlpha > 0)
05650			{
05651				LevelFadeAlpha -= DeltaTime * Level.FadeRate;
05652				if (LevelFadeAlpha < 0)
05653					LevelFadeAlpha = 0;
05654			}
05655		}
05656	
05657		event PlayerTick( float DeltaTime )
05658		{
05659			if ( bUpdatePosition )
05660				ClientUpdatePosition();
05661			
05662			PlayerMove(DeltaTime);
05663		}
05664	
05665		function PlayerMove( float DeltaTime )
05666		{
05667			if ( Role < ROLE_Authority ) // then save this move and replicate it
05668				ReplicateMove(DeltaTime, vect(0,0,0), Dodge_None, rot(0,0,0));
05669		}
05670	
05671		function EMatterType MatterForJoint(int joint)
05672		{
05673			return MATTER_ICE;
05674		}
05675	
05676		function SpawnDebris(vector Momentum)
05677		{
05678			local int numchunks;
05679			local debris d;
05680			local vector loc;
05681			local float scale;
05682			local int i;
05683	
05684			// Find appropriate size of chunks
05685			numchunks = Clamp(Mass/10, 2, 15);
05686			scale = (CollisionRadius*CollisionRadius*CollisionHeight) / (numchunks*500);
05687			scale = scale ** 0.3333333;
05688	
05689			// Spawn debris
05690			for (i=0; i<numchunks; i++)
05691			{
05692				loc = Location;
05693				loc.X += (FRand()*2-1)*CollisionRadius;
05694				loc.Y += (FRand()*2-1)*CollisionRadius;
05695				loc.Z += (FRand()*2-1)*CollisionHeight;
05696				d = Spawn(class'debrisice',,,loc);
05697				if (d != None)
05698				{
05699					d.SetSize(scale);
05700					d.SetMomentum(Momentum);
05701				}
05702			}
05703		}
05704	
05705		function PlayDyingSound(name damageType)
05706		{
05707			PlaySound(Sound'WeaponsSnd.impcrashes.crashglass02', SLOT_Pain);
05708		}
05709	
05710		function bool JointDamaged(int Damage, Pawn EventInstigator, vector HitLoc, vector Momentum, name DamageType, int joint)
05711		{
05712			local actor A;
05713	
05714			if (DamageType=='sever' || DamageType=='thrownweaponsever' ||
05715				DamageType=='fire' || DamageType=='electricity')
05716				return false;
05717	
05718			SpawnDebris(Momentum);
05719			InventoryNormal();
05720			bHidden=true;
05721			Died(EventInstigator, DamageType, HitLoc);
05722			return false;
05723		}
05724	
05725		function CreatureStatue()
05726		{
05727			local int ix;
05728	
05729			for (ix=0; ix<16; ix++)
05730			{
05731				SkelGroupSkins[ix] = texture'statues.ice1';
05732			}
05733		}
05734	
05735		function CreatureNormal()
05736		{
05737			local int ix;
05738	
05739			// Transform creature to default skin
05740			for (ix=0; ix<16; ix++)
05741				SkelGroupSkins[ix] = Default.SkelGroupSkins[ix];
05742			SetDefaultPolygroups();
05743		}
05744	
05745		function InventoryStatue()
05746		{
05747			local Inventory inv;
05748			local int ix;
05749	
05750			// Transform inventory if visible
05751			inv = Inventory;
05752			while (inv != None)
05753			{
05754				if (!inv.bHidden)
05755				{
05756					for (ix=0; ix<16; ix++)
05757					{
05758						if (inv.SkelGroupSkins[ix] != None)
05759						{
05760							inv.SkelGroupSkins[ix] = texture'statues.ice1';
05761							inv.bSweepable=false;
05762						}
05763					}
05764				}
05765				inv = inv.Inventory;
05766			}
05767		}
05768	
05769		function InventoryNormal()
05770		{
05771			local Inventory inv;
05772			local int ix;
05773	
05774			// Transform inventory if visible
05775			inv = Inventory;
05776			while (inv != None)
05777			{
05778				if (!inv.bHidden)
05779				{
05780					for (ix=0; ix<16; ix++)
05781						inv.SkelGroupSkins[ix] = None;
05782					inv.SetDefaultPolygroups();
05783					inv.bSweepable=inv.Default.bSweepable;
05784				}
05785				inv = inv.Inventory;
05786			}
05787		}
05788	
05789		function Timer()
05790		{	// After time expires, come back to life (timer set by powerup)
05791			SetTimer(0, false);
05792			SpawnDebris(vect(0,0,0));
05793			PlaySound(Sound'WeaponsSnd.impcrashes.crashglass02', SLOT_Pain);
05794			CreatureNormal();
05795			InventoryNormal();
05796			GotoState('PlayerWalking');
05797		}
05798	
05799		function BeginState()
05800		{
05801			if (Weapon!=None && Weapon.bPoweredUp)
05802				Weapon.PowerupEnd();
05803			if (Weapon!=None)
05804				Weapon.FinishAttack();
05805	
05806			Acceleration=vect(0,0,0);
05807			SetPhysics(PHYS_Falling);
05808			CreatureStatue();
05809			InventoryStatue();
05810	
05811			Buoyancy = 10;
05812			SetTimer(5, false);
05813			bCanLook = false;
05814			bProjTarget = false;
05815			SlowAnimation();
05816		}
05817	
05818		function EndState()
05819		{
05820			Buoyancy = Default.Buoyancy;
05821			bCanLook = Default.bCanLook;
05822			SetTimer(0, false);
05823			bMovable = Default.bMovable;
05824			bProjTarget = Default.bProjTarget;
05825			if (AnimProxy != None)
05826				AnimProxy.GotoState('Idle');
05827		}
05828	
05829		function Landed(vector HitNormal, actor HitActor)
05830		{
05831			bMovable = false;
05832			global.Landed(HitNormal, HitActor);
05833		}
05834	
05835		function SlowAnimation()
05836		{
05837			//Should play slowing animation here
05838			PlayAnim('StatueAnim', 1.0, 0.3);
05839			if (AnimProxy != None)
05840			{
05841				AnimProxy.PlayAnim('StatueAnim', 1.0, 0.3);
05842				AnimProxy.GotoState('Dying');
05843			}
05844			bMovable=false;
05845		}
05846	}
05847	
05848	
05849	//================================================
05850	//
05851	// Unresponsive
05852	//
05853	// State which is used to ignore the user input
05854	//================================================
05855	state Unresponsive
05856	{
05857	ignores SeePlayer, EnemyNotVisible, HearNoise, Trigger, Bump, HitWall, HeadZoneChange, FootZoneChange, ZoneChange, Falling, WarnTarget, LongFall, Landed;
05858	
05859		exec function Taunt()						{}
05860		exec function Powerup()						{}
05861		exec function Throw()						{}
05862		exec function Fire(optional float F)		{}
05863		exec function AltFire(optional float F)		{}
05864		exec function Use()							{}
05865		exec function SwitchWeapon(byte F)			{}
05866		exec function Fly()							{}
05867		exec function Walk()						{}
05868		exec function Ghost()						{}
05869		exec function Suicide()						{}
05870		
05871	
05872		function bool CanBeStatued()		{	return false;	}
05873		function bool CanGotoPainState()	{	return(false);	}
05874		function bool JointDamaged(int Damage, Pawn EventInstigator, vector HitLoc, vector Momentum, name DamageType, int joint)
05875		{
05876			return false;
05877		}
05878		
05879		function ProcessMove(float DeltaTime, vector NewAccel, eDodgeDir DodgeMove, rotator DeltaRot)	
05880		{
05881			Acceleration = vect(0,0,0);
05882		}
05883	
05884		event PlayerTick( float DeltaTime )
05885		{
05886			if ( bUpdatePosition )
05887				ClientUpdatePosition();
05888			
05889			PlayerMove(DeltaTime);
05890		}
05891	
05892		function PlayerMove( float DeltaTime )
05893		{
05894			if ( Role < ROLE_Authority ) // then save this move and replicate it
05895				ReplicateMove(DeltaTime, vect(0,0,0), Dodge_None, rot(0,0,0));
05896		}
05897	
05898		function PlayTakeHit(float tweentime, int damage, vector HitLoc, name damageType, vector Momentum, int BodyPart)
05899		{
05900		}
05901			
05902		function EndState()
05903		{
05904			if(AnimProxy != None)
05905				AnimProxy.GotoState('Idle');
05906		}
05907	
05908		function BeginState()
05909		{
05910			Acceleration = vect(0,0,0);
05911			Velocity = vect(0,0,0);
05912			SetPhysics(PHYS_Falling);
05913	
05914			if (Weapon != None)
05915				Weapon.FinishAttack();
05916	
05917		//	if(AnimProxy != None)
05918		//		AnimProx.GotoState('Idle');
05919		}
05920	
05921		function AnimEnd()
05922		{
05923			PlayWaiting(0.2);
05924		}
05925	}
05926	
05927	
05928	
05929	event ShadowUpdate(int ShadowType)
05930	{
05931		if(ShadowType == 1)
05932		{ // Blob
05933			if(shadow == None)
05934				shadow = Spawn(class'PlayerShadow', self,, Location, Rotation);
05935	
05936			shadow.DrawScale = 1.5 * DrawScale;
05937			if(shadow != None)
05938				shadow.Update(None);
05939		}
05940	/*
05941		else if(ShadowType == 2)
05942		{ // Projected shadow
05943	//		if(ShadowTexture == None)
05944	//			ShadowTexture = Spawn(class'ShadowTex', self,,,);
05945		
05946		}
05947	*/
05948	}
05949	
05950	exec function bool TraceIt()
05951	{
05952		local vector end;
05953		local vector HitLocation, HitNormal;
05954	
05955		end = Location + vector(ViewRotation) * 4000;
05956	
05957		Trace(HitLocation, HitNormal, end, Location);
05958	
05959		Spawn(class'HitMetal',,, HitLocation, Rotator(HitNormal));
05960	}
05961	
05962	
05963	//=============================================================================
05964	//
05965	// Debug
05966	//
05967	//=============================================================================
05968	
05969	simulated function Debug(Canvas canvas, int mode)
05970	{
05971		local vector pos1, pos2;	// testing sweep
05972		local vector offset;
05973		local actor A,BestActor;
05974		local float score,BestScore;
05975		local int X,Y;
05976	
05977		Super.Debug(canvas, mode);
05978	//	Super(Actor).Debug(canvas, mode);
05979	
05980		Canvas.DrawText("RunePlayer:");
05981		Canvas.CurY -= 8;
05982		if(SpeedScale == SS_Circular)
05983			Canvas.DrawText("  SpeedScale: SS_Circular");
05984		else if(SpeedScale == SS_Elliptical)
05985			Canvas.DrawText("  SpeedScale: SS_Elliptical");
05986		else
05987			Canvas.DrawText("  SpeedScale: SS_Other");
05988		Canvas.CurY -= 8;
05989		Canvas.DrawText("  GroundSpeed: "$GroundSpeed);
05990	
05991	/*
05992		Canvas.DrawText("  LevelFadeAlpha:" $ LevelFadeAlpha);
05993		Canvas.CurY -= 8;
05994		Canvas.DrawText("  Vel:         " $ VSize(Velocity));
05995		Canvas.CurY -= 8;
05996		Canvas.DrawText("  GroundSpeed: " $ GroundSpeed);
05997		Canvas.CurY -= 8;
05998		Canvas.DrawText("  ExploreSpeed:" $ ExploreSpeed);
05999		Canvas.CurY -= 8;
06000		Canvas.DrawText("  CombatSpeed: " $ CombatSpeed);
06001		Canvas.CurY -= 8;
06002		Canvas.DrawText("  bSurfaceSwim:" $ bSurfaceSwimming);
06003		Canvas.CurY -= 8;
06004		Canvas.DrawText("  EyeHeight:   " $ EyeHeight);
06005		Canvas.CurY -= 8;
06006	
06007		switch(SpeedScale)
06008		{
06009			case SS_Circular:
06010				Canvas.DrawText("  SpeedScale:  SS_Circular");
06011				break;
06012			case SS_Elliptical:
06013				Canvas.DrawText("  SpeedScale:  SS_Elliptical");
06014				break;
06015			case SS_Other:
06016				Canvas.DrawText("  SpeedScale:  SS_Other");
06017				break;
06018		}
06019		Canvas.CurY -= 8;
06020	
06021		// Camera stuff
06022		Canvas.DrawText("  OldLocation: " $ OldLocation);
06023		Canvas.CurY -= 8;
06024		Canvas.DrawText("  ViewLocation: " $ ViewLocation);
06025		Canvas.CurY -= 8;
06026		Canvas.DrawText("  ViewRotation: " $ ViewRotation);
06027		Canvas.CurY -= 8;
06028		Canvas.DrawText("  CameraDist: " $ CameraDist);
06029		Canvas.CurY -= 8;
06030		Canvas.DrawText("  CameraHeight: " $ CameraHeight);
06031		Canvas.CurY -= 8;
06032		Canvas.DrawText("  CameraAccel: " $ CameraAccel);
06033		Canvas.CurY -= 8;
06034		Canvas.DrawText("  CameraRotSpeed: " $ CameraRotSpeed);
06035		Canvas.CurY -= 8;
06036		Canvas.DrawText("  CurrentDist: " $ CurrentDist);
06037		Canvas.CurY -= 8;
06038		Canvas.DrawText("  OldCameraStart: " $ OldCameraStart);
06039		Canvas.CurY -= 8;
06040		Canvas.DrawText("  CurrentTime[Cam]: " $ CurrentTime);
06041		Canvas.CurY -= 8;
06042		Canvas.DrawText("  bBehindView: " $ bBehindView);
06043	*/
06044	
06045		Canvas.CurY -= 8;
06046		Canvas.DrawText("  OrderObject: " $ OrderObject);
06047		Canvas.CurY -= 8;
06048		Canvas.DrawText("  LastHeldWeapon:  " $ LastHeldWeapon);
06049		Canvas.CurY -= 8;
06050		if(Weapon != None)
06051		{
06052			Canvas.DrawText("  NextWeapon:  " $ GetNextWeapon(Weapon));
06053			Canvas.CurY -= 8;
06054		}
06055		Canvas.DrawText("  PrePivot:  " $ PrePivot);
06056		Canvas.CurY -= 8;
06057		Canvas.DrawText("  RopeDist: " $ RopeDist);
06058		Canvas.CurY -= 8;
06059		Canvas.DrawText("  SubstituteMesh: " $ SubstituteMesh);
06060		Canvas.CurY -= 8;
06061		Canvas.DrawText("  UninterruptedAnim: " $ UninterruptedAnim);
06062		Canvas.CurY -= 8;
06063	
06064		// Draw grab location
06065		offset = GrabLocationIn;
06066	//	offset.Z += CollisionHeight * 0.5;
06067		Canvas.DrawLine3D(offset + vect(10, 0, 0), offset + vect(-10, 0, 0), 0, 255, 0);
06068		Canvas.DrawLine3D(offset + vect(0, 10, 0), offset + vect(0, -10, 0), 0, 255, 0);	
06069		Canvas.DrawLine3D(offset + vect(0, 0, 10), offset+ vect(0, 0, -10), 0, 255, 0);
06070	
06071		// Test:  Draw Light position
06072		offset = Location - ShadowVector;
06073		Canvas.DrawLine3D(offset + vect(10, 0, 0), offset + vect(-10, 0, 0), 0, 0, 255);
06074		Canvas.DrawLine3D(offset + vect(0, 10, 0), offset + vect(0, -10, 0), 0, 0, 255);	
06075		Canvas.DrawLine3D(offset + vect(0, 0, 10), offset+ vect(0, 0, -10), 0, 0, 255);
06076	
06077		// Draw sweep positions
06078		if (Weapon != None)
06079		{
06080			pos1 = Weapon.GetJointPos(0);
06081			pos2 = Weapon.GetJointPos(1);
06082			
06083			Canvas.DrawLine3D(pos1, pos2, 0,   0, 255);
06084			Canvas.DrawBox3D(pos1, vect(5,5,5), 0, 30, 255);
06085			Canvas.DrawBox3D(pos2, vect(5,5,5), 0, 30, 255);
06086		}
06087	
06088		// Draw look focus scores
06089		bestScore = 9999999.0;
06090		bestActor = None;
06091		foreach VisibleActors(class'actor', A, 1000, Location)
06092		{
06093			if(A == self || A.Owner == self)
06094				continue;
06095			
06096			if(A.bLookFocusPlayer)
06097			{
06098				score = ScoreLookActor(A);
06099				if(score < bestScore)
06100				{
06101					bestScore = score;
06102					bestActor = A;
06103				}
06104	
06105				Canvas.SetColor(255,255,0);
06106				Canvas.TransformPoint(A.Location, X, Y);
06107				Canvas.SetPos(X,Y);
06108				Canvas.DrawText(score, false);
06109			}
06110		}
06111		if (BestActor != None)
06112		{
06113			Canvas.SetColor(255,255,255);
06114			Canvas.TransformPoint(BestActor.Location, X, Y);
06115			Canvas.SetPos(X,Y);
06116			Canvas.DrawText(BestScore@"*", false);
06117		}
06118	
06119	
06120		// Test:  Draw DropZ stuff
06121		offset = Location + vect(0, 0, 60);
06122		Canvas.DrawLine3D(offset, offset + DropZFloor * 10, 0, 0, 255);
06123		Canvas.DrawLine3D(offset, offset + DropZRag * 10, 255, 0, 0);
06124		Canvas.DrawLine3D(offset, offset + DropZResult * 10, 0, 255, 0);
06125		Canvas.DrawLine3D(offset, offset + DropZRoll * 10, 255, 255, 255);
06126	}
06127	
06128	defaultproperties
06129	{
06130	     CrouchHeight=25.000000
06131	     ExploreSpeed=315.000000
06132	     CombatSpeed=225.000000
06133	     bBurnable=True
06134	     CameraDist=180.000000
06135	     CameraAccel=7.000000
06136	     CameraHeight=35.000000
06137	     CameraPitch=450.000000
06138	     CameraRotSpeed=(Pitch=20,Yaw=20,Roll=20)
06139	     TranslucentDist=115.000000
06140	     CurrentDist=200.000000
06141	     StatueAnim=cine_vil_kneeldown
06142	     Die4=Sound'CreaturesSnd.Ragnar.ragdeath04'
06143	     UnderWaterHitSound(0)=Sound'CreaturesSnd.Ragnar.gasp01'
06144	     UnderWaterHitSound(1)=Sound'CreaturesSnd.Ragnar.gasp01'
06145	     UnderWaterHitSound(2)=Sound'CreaturesSnd.Ragnar.gasp01'
06146	     PowerupFail=Sound'OtherSnd.Menu.menu01'
06147	     WeaponPickupSound=Sound'CreaturesSnd.Ragnar.ragpickup02'
06148	     WeaponThrowSound=Sound'CreaturesSnd.Ragnar.ragthrow03'
06149	     WeaponDropSound=Sound'CreaturesSnd.Ragnar.ragdrop02'
06150	     JumpGruntSound(0)=Sound'CreaturesSnd.Ragnar.ragjump01'
06151	     JumpGruntSound(1)=Sound'CreaturesSnd.Ragnar.ragjump02'
06152	     JumpGruntSound(2)=Sound'CreaturesSnd.Ragnar.ragjump03'
06153	     FallingDeathSound=Sound'CreaturesSnd.Ragnar.ragland02'
06154	     FallingScreamSound=Sound'CreaturesSnd.Ragnar.ragfall01'
06155	     UnderWaterDeathSound=Sound'CreaturesSnd.Ragnar.drowned'
06156	     EdgeGrabSound=Sound'CreaturesSnd.Ragnar.raggrab02'
06157	     KickSound=Sound'CreaturesSnd.Ragnar.ragkick01'
06158	     HitSoundLow(0)=Sound'CreaturesSnd.Ragnar.raghit01'
06159	     HitSoundLow(1)=Sound'CreaturesSnd.Ragnar.raghit02'
06160	     HitSoundLow(2)=Sound'CreaturesSnd.Ragnar.raghit03'
06161	     HitSoundMed(0)=Sound'CreaturesSnd.Ragnar.raghit04'
06162	     HitSoundMed(1)=Sound'CreaturesSnd.Ragnar.raghit05'
06163	     HitSoundMed(2)=Sound'CreaturesSnd.Ragnar.raghit06'
06164	     HitSoundHigh(0)=Sound'CreaturesSnd.Ragnar.raghit07'
06165	     HitSoundHigh(1)=Sound'CreaturesSnd.Ragnar.raghit08'
06166	     HitSoundHigh(2)=Sound'CreaturesSnd.Ragnar.raghit09'
06167	     UnderwaterAmbient(0)=Sound'EnvironmentalSnd.Water.underwater01L'
06168	     UnderwaterAmbient(1)=Sound'EnvironmentalSnd.Water.underwater02L'
06169	     UnderwaterAmbient(2)=Sound'EnvironmentalSnd.Water.underwater03L'
06170	     UnderwaterAmbient(3)=Sound'EnvironmentalSnd.Water.underwater04L'
06171	     UnderwaterAmbient(4)=Sound'EnvironmentalSnd.Water.underwater06L'
06172	     UnderwaterAmbient(5)=Sound'EnvironmentalSnd.Water.underwater08L'
06173	     BerserkSoundStart=Sound'WeaponsSnd.PowerUps.powerstart44'
06174	     BerserkSoundEnd=Sound'WeaponsSnd.PowerUps.powerend19'
06175	     BerserkSoundLoop=Sound'CreaturesSnd.Ragnar.ragberzerkL'
06176	     BerserkYellSound(0)=Sound'CreaturesSnd.Ragnar.ragattack01'
06177	     BerserkYellSound(1)=Sound'CreaturesSnd.Ragnar.ragattack02'
06178	     BerserkYellSound(2)=Sound'CreaturesSnd.Ragnar.ragattack03'
06179	     BerserkYellSound(3)=Sound'CreaturesSnd.Ragnar.ragattack04'
06180	     BerserkYellSound(4)=Sound'CreaturesSnd.Ragnar.ragattack05'
06181	     BerserkYellSound(5)=Sound'CreaturesSnd.Ragnar.ragattack06'
06182	     CrouchSound=Sound'CreaturesSnd.Ragnar.ragpickup02'
06183	     RopeClimbSound(0)=Sound'OtherSnd.Pickups.grab02'
06184	     RopeClimbSound(1)=Sound'OtherSnd.Pickups.grab01'
06185	     RopeClimbSound(2)=Sound'OtherSnd.Pickups.grab02'
06186	     NoRunePowerMsg="Not enough RUNE POWER"
06187	     bCanRestart=True
06188	     bSinglePlayer=True
06189	     CarcassType=Class'RuneI.PlayerCarcass'
06190	     bBehindView=True
06191	     bCanStrafe=True
06192	     bIsHuman=True
06193	     bCanGrabEdges=True
06194	     MeleeRange=50.000000
06195	     GroundSpeed=315.000000
06196	     WaterSpeed=300.000000
06197	     AirSpeed=400.000000
06198	     AccelRate=2048.000000
06199	     JumpZ=425.000000
06200	     AirControl=0.250000
06201	     PeripheralVision=-0.500000
06202	     BaseEyeHeight=25.000000
06203	     EyeHeight=25.000000
06204	     BodyPartHealth(1)=75
06205	     BodyPartHealth(3)=75
06206	     BodyPartHealth(5)=75
06207	     GibCount=10
06208	     GibClass=Class'RuneI.DebrisFlesh'
06209	     UnderWaterTime=60.000000
06210	     Intelligence=BRAINS_HUMAN
06211	     Die=Sound'CreaturesSnd.Ragnar.ragdeath01'
06212	     Die2=Sound'CreaturesSnd.Ragnar.ragdeath02'
06213	     Die3=Sound'CreaturesSnd.Ragnar.ragdeath03'
06214	     LandGrunt=Sound'CreaturesSnd.Ragnar.ragland01'
06215	     FootStepWood(0)=Sound'FootstepsSnd.Wood.footwood02'
06216	     FootStepWood(1)=Sound'FootstepsSnd.Wood.footlandwood02'
06217	     FootStepWood(2)=Sound'FootstepsSnd.Wood.footwood05'
06218	     FootStepMetal(0)=Sound'FootstepsSnd.Metal.footmetal01'
06219	     FootStepMetal(1)=Sound'FootstepsSnd.Metal.footmetal02'
06220	     FootStepMetal(2)=Sound'FootstepsSnd.Metal.footmetal05'
06221	     FootStepStone(0)=Sound'FootstepsSnd.Earth.footgravel09'
06222	     FootStepStone(1)=Sound'FootstepsSnd.Earth.footgravel10'
06223	     FootStepStone(2)=Sound'FootstepsSnd.Earth.footgravel09'
06224	     FootStepFlesh(0)=Sound'FootstepsSnd.Earth.footsquish02'
06225	     FootStepFlesh(1)=Sound'FootstepsSnd.Earth.footsquish07'
06226	     FootStepFlesh(2)=Sound'FootstepsSnd.Earth.footsquish09'
06227	     FootStepIce(0)=Sound'FootstepsSnd.Ice.footice01'
06228	     FootStepIce(1)=Sound'FootstepsSnd.Ice.footice02'
06229	     FootStepIce(2)=Sound'FootstepsSnd.Ice.footice03'
06230	     FootStepEarth(0)=Sound'FootstepsSnd.Earth.footgravel01'
06231	     FootStepEarth(1)=Sound'FootstepsSnd.Earth.footgravel02'
06232	     FootStepEarth(2)=Sound'FootstepsSnd.Earth.footgravel04'
06233	     FootStepSnow(0)=Sound'FootstepsSnd.Snow.footsnow01'
06234	     FootStepSnow(1)=Sound'FootstepsSnd.Snow.footsnow02'
06235	     FootStepSnow(2)=Sound'FootstepsSnd.Snow.footsnow04'
06236	     FootStepWater(0)=Sound'FootstepsSnd.Water.footwaterwaist01'
06237	     FootStepWater(1)=Sound'FootstepsSnd.Water.footwaterwaist02'
06238	     FootStepWater(2)=Sound'FootstepsSnd.Water.footwaterwaist03'
06239	     FootStepMud(0)=Sound'FootstepsSnd.Mud.footmud01'
06240	     FootStepMud(1)=Sound'FootstepsSnd.Mud.footmud02'
06241	     FootStepMud(2)=Sound'FootstepsSnd.Mud.footmud03'
06242	     FootStepLava(0)=Sound'FootstepsSnd.Lava.footlava02'
06243	     FootStepLava(1)=Sound'FootstepsSnd.Lava.footlava03'
06244	     FootStepLava(2)=Sound'FootstepsSnd.Lava.footlava07'
06245	     LandSoundWood=Sound'FootstepsSnd.Earth.footlandearth01'
06246	     LandSoundMetal=Sound'FootstepsSnd.Metal.footmetal04'
06247	     LandSoundStone=Sound'FootstepsSnd.Earth.footlandearth04'
06248	     LandSoundFlesh=Sound'FootstepsSnd.Earth.footsquish06'
06249	     LandSoundIce=Sound'FootstepsSnd.Earth.footlandearth02'
06250	     LandSoundSnow=Sound'FootstepsSnd.Snow.footlandsnow05'
06251	     LandSoundEarth=Sound'FootstepsSnd.Earth.footlandearth05'
06252	     LandSoundWater=Sound'FootstepsSnd.Water.footlandwater02'
06253	     LandSoundMud=Sound'FootstepsSnd.Mud.footlandmud01'
06254	     LandSoundLava=Sound'FootstepsSnd.Lava.footlava01'
06255	     WeaponJoint=attach_hand
06256	     ShieldJoint=attach_shielda
06257	     bCanLook=True
06258	     MaxBodyAngle=(Yaw=5000)
06259	     MaxHeadAngle=(Yaw=7000)
06260	     bHeadLookUpDouble=True
06261	     LookDegPerSec=360.000000
06262	     FootprintClass=Class'RuneI.footprint'
06263	     WetFootprintClass=Class'RuneI.FootprintWet'
06264	     BloodyFootprintClass=Class'RuneI.FootprintBloody'
06265	     LFootJoint=5
06266	     RFootJoint=9
06267	     bFootsteps=True
06268	     DeathRadius=40.000000
06269	     DeathHeight=8.000000
06270	     AnimSequence=WalkSm
06271	     DrawType=DT_SkeletalMesh
06272	     Sprite=Texture'RuneFX.shadow'
06273	     Texture=Texture'Engine.S_Corpse'
06274	     CollisionRadius=18.000000
06275	     CollisionHeight=42.000000
06276	     Buoyancy=99.000000
06277	     Skeletal=SkelModel'Players.Ragnar'
06278	}

End Source Code