class xPawn extends UnrealPawn config(User) dependsOn(xUtil) dependsOn(xPawnSoundGroup); // if _RO_ //dependsOn(xPawnGibGroup); // ifndef _RO_ //#exec OBJ LOAD FILE=GameSounds.uax //#exec OBJ LOAD FILE=PlayerSounds.uax //#exec OBJ LOAD FILE=PlayerFootSteps.uax //#exec OBJ LOAD FILE=DanFX.utx // ifndef _RO_ //#exec OBJ LOAD FILE=GeneralAmbience.uax //#exec OBJ LOAD FILE=GeneralImpacts.uax //#exec OBJ LOAD FILE=DeRez.utx //#exec OBJ LOAD FILE=WeaponSounds.uax var int RepeaterDeathCount; var Combo CurrentCombo; var bool bBerserk; var bool bInvis; var bool bOldInvis; var bool bGibbed; var bool bCanDodgeDoubleJump; var bool bCanBoostDodge; var bool bAlreadySetup; var bool bSpawnIn; var bool bSpawnDone; var bool bFrozenBody; var bool bFlaming; var bool bRubbery; var bool bClearWeaponOffsets; // for certain custom player models var(UDamage) Material UDamageWeaponMaterial; // Weapon overlay material var(UDamage) Sound UDamageSound; var UDamageTimer UDamageTimer; var float UDamageTime; var float LastUDamageSoundTime; var Material InvisMaterial; var(Shield) float ShieldStrengthMax; // max strength var float SmallShieldStrength; // for preventing shieldstacking var(Shield) Material ShieldHitMat; var(Shield) float ShieldHitMatTime; var class Species; var(Sounds) float GruntVolume; var(Sounds) float FootstepVolume; var transient int SimHitFxTicker; // if _RO_ //var(Gib) class GibGroupClass; //var(Gib) int GibCountCalf; //var(Gib) int GibCountForearm; //var(Gib) int GibCountHead; //var(Gib) int GibCountTorso; //var(Gib) int GibCountUpperArm; var float MinTimeBetweenPainSounds; var localized string HeadShotMessage; // Common sounds //var(Sounds) sound SoundFootsteps[11]; // Indexed by ESurfaceTypes (sorry about the literal). var(Sounds) class SoundGroupClass; var class TeleportFXClass; var class TransEffects[2]; var WeaponAttachment WeaponAttachment; var ShadowProjector PlayerShadow; var int MultiJumpRemaining; var int MaxMultiJump; var int MultiJumpBoost; // depends on the tolerance (100) var name WallDodgeAnims[4]; var name IdleHeavyAnim; var name IdleRifleAnim; var name FireHeavyRapidAnim; var name FireHeavyBurstAnim; var name FireRifleRapidAnim; var name FireRifleBurstAnim; var name FireRootBone; var enum EFireAnimState { FS_None, FS_PlayOnce, FS_Looping, FS_Ready } FireState; var Mesh SkeletonMesh; var bool bSkeletized; var bool bDeRes; var float DeResTime; var Emitter DeResFX; var Material DeResMat0, DeResMat1; var(DeRes) InterpCurve DeResLiftVel; // speed (over time) at which body rises var(DeRes) InterpCurve DeResLiftSoftness; // vertical 'sprinyness' (over time) of bone lifters var(DeRes) float DeResGravScale; // reduce gravity on corpse during de-res var(DeRes) float DeResLateralFriction; // sideways friction while lifting var(Karma) float RagdollLifeSpan; // MAXIMUM time the ragdoll will be around. De-res's early if it comes to rest. var(Karma) float RagInvInertia; // Use to work out how much 'spin' ragdoll gets on death. var(Karma) float RagDeathVel; // How fast ragdoll moves upon death var(Karma) float RagShootStrength; // How much effect shooting ragdolls has. Be careful! var(Karma) float RagSpinScale; // Increase propensity to spin around Z (up). var(Karma) float RagDeathUpKick; // Amount of upwards kick ragdolls get when they die var(Karma) float RagGravScale; var(Karma) material RagConvulseMaterial; // Ragdoll impact sounds. var(Karma) array RagImpactSounds; var(Karma) float RagImpactSoundInterval; var(Karma) float RagImpactVolume; var transient float RagLastSoundTime; var string RagdollOverride; // translocate effect var class TransOutEffect[2]; var Controller OldController; var Material RealSkins[4]; var class VoiceClass; var(AI) globalconfig string PlacedCharacterName; var globalconfig string PlacedFemaleCharacterName; var byte TeamSkin; // what team's skin is currently set replication { reliable if( Role==ROLE_Authority ) bInvis; reliable if( bNetOwner && (Role==ROLE_Authority) ) bBerserk, MaxMultiJump, MultiJumpBoost, bCanDodgeDoubleJump, bCanBoostDodge; reliable if( Role==ROLE_Authority ) ClientSetUDamageTime; } simulated function Fire( optional float F ) { if ( (Weapon != None) && (Weapon.bBerserk != bBerserk) ) { if ( bBerserk ) Weapon.StartBerserk(); else Weapon.StopBerserk(); } Super.Fire(F); } simulated function AltFire( optional float F ) { if ( (Weapon != None) && (Weapon.bBerserk != bBerserk) ) { if ( bBerserk ) Weapon.StartBerserk(); else Weapon.StopBerserk(); } Super.AltFire(F); } simulated function PlayWaiting() {} function RosterEntry GetPlacedRoster() { PlayerReplicationInfo.CharacterName = PlacedCharacterName; return class'xRosterEntry'.static.CreateRosterEntryCharacter(PlacedCharacterName); } function PossessedBy(Controller C) { Super.PossessedBy(C); if ( Controller != None ) OldController = Controller; } // return true if was controlled by a Player (AI or human) simulated function bool WasPlayerPawn() { return ( (OldController != None) && OldController.bIsPlayer ); } function DoTranslocateOut(Vector PrevLocation) { if ( (PlayerReplicationInfo == None) || (PlayerReplicationInfo.Team == None) || (PlayerReplicationInfo.Team.TeamIndex == 0) ) Spawn(TransOutEffect[0], self,, PrevLocation, rotator(Location - PrevLocation)); else Spawn(TransOutEffect[1], self,, PrevLocation, rotator(Location - PrevLocation)); } // Set up default blending parameters and pose. Ensures the mesh doesn't have only a T-pose whenever it first springs into view. simulated function AssignInitialPose() { if ( DrivenVehicle != None ) { if ( HasAnim(DrivenVehicle.DriveAnim) ) LoopAnim(DrivenVehicle.DriveAnim,, 0.1); else LoopAnim('Vehicle_Driving',, 0.1); } else TweenAnim(MovementAnims[0],0.0); AnimBlendParams(1, 1.0, 0.2, 0.2, 'Bip01 Spine1'); BoneRefresh(); } simulated function Destroyed() { if( PlayerShadow != None ) PlayerShadow.Destroy(); if( DeResFX != None ) { DeResFX.Emitters[0].SkeletalMeshActor = None; DeResFX.Kill(); } Super.Destroyed(); } simulated function RemoveFlamingEffects() { local int i; if( Level.NetMode == NM_DedicatedServer ) return; for( i=0; i EmitterClass, Name BoneName, Vector Location, Rotator Rotation ) { local Actor a; local int i; if( bSkeletized || (BoneName == 'None') ) return; for( i = 0; i < Attached.Length; i++ ) { if( Attached[i] == None ) continue; if( Attached[i].AttachmentBone != BoneName ) continue; if( ClassIsChildOf( EmitterClass, Attached[i].Class ) ) return; } a = Spawn( EmitterClass,,, Location, Rotation ); if( !AttachToBone( a, BoneName ) ) { log( "Couldn't attach "$EmitterClass$" to "$BoneName, 'Error' ); a.Destroy(); return; } for( i = 0; i < Attached.length; i++ ) { if( Attached[i] == a ) break; } a.SetRelativeRotation( Rotation ); } simulated event SetHeadScale(float NewScale) { HeadScale = NewScale; SetBoneScale(4,HeadScale,'head'); } //simulated function SpawnGiblet( class GibClass, Vector Location, Rotator Rotation, float GibPerterbation ) //{ // local Gib Giblet; // local Vector Direction, Dummy; // // if( (GibClass == None) || class'GameInfo'.static.UseLowGore() ) // return; // // Instigator = self; // Giblet = Spawn( GibClass,,, Location, Rotation ); // if( Giblet == None ) // return; // // Temp commented out - Ramm // //Giblet.bFlaming = bFlaming; // Giblet.SpawnTrail(); // // GibPerterbation *= 32768.0; // Rotation.Pitch += ( FRand() * 2.0 * GibPerterbation ) - GibPerterbation; // Rotation.Yaw += ( FRand() * 2.0 * GibPerterbation ) - GibPerterbation; // Rotation.Roll += ( FRand() * 2.0 * GibPerterbation ) - GibPerterbation; // // GetAxes( Rotation, Dummy, Dummy, Direction ); // // Giblet.Velocity = Velocity + Normal(Direction) * (250 + 260 * FRand()); // Giblet.LifeSpan = Giblet.LifeSpan + 2 * FRand() - 1; //} simulated function ProcessHitFX() { local Coords boneCoords; local class HitEffects[4]; local int i,j; local float GibPerterbation; if( (Level.NetMode == NM_DedicatedServer) || bSkeletized || (Mesh == SkeletonMesh) ) { SimHitFxTicker = HitFxTicker; return; } for ( SimHitFxTicker = SimHitFxTicker; SimHitFxTicker != HitFxTicker; SimHitFxTicker = (SimHitFxTicker + 1) % ArrayCount(HitFX) ) { j++; if ( j > 30 ) { SimHitFxTicker = HitFxTicker; return; } if( (HitFX[SimHitFxTicker].damtype == None) || (Level.bDropDetail && (Level.TimeSeconds - LastRenderTime > 3) && !IsHumanControlled()) ) continue; boneCoords = GetBoneCoords( HitFX[SimHitFxTicker].bone ); if ( !Level.bDropDetail && !bSkeletized ) { // if _RO_ //AttachEffect( GibGroupClass.static.GetBloodEmitClass(), HitFX[SimHitFxTicker].bone, boneCoords.Origin, HitFX[SimHitFxTicker].rotDir ); HitFX[SimHitFxTicker].damtype.static.GetHitEffects( HitEffects, Health ); if( !PhysicsVolume.bWaterVolume ) // don't attach effects under water { for( i = 0; i < ArrayCount(HitEffects); i++ ) { if( HitEffects[i] == None ) continue; AttachEffect( HitEffects[i], HitFX[SimHitFxTicker].bone, boneCoords.Origin, HitFX[SimHitFxTicker].rotDir ); } } } if ( class'GameInfo'.static.UseLowGore() ) HitFX[SimHitFxTicker].bSever = false; if( HitFX[SimHitFxTicker].bSever ) { GibPerterbation = HitFX[SimHitFxTicker].damtype.default.GibPerterbation; bFlaming = HitFX[SimHitFxTicker].DamType.Default.bFlaming; switch( HitFX[SimHitFxTicker].bone ) { case 'lthigh': case 'rthigh': //SpawnGiblet( GetGibClass(EGT_Calf), boneCoords.Origin, HitFX[SimHitFxTicker].rotDir, GibPerterbation ); //SpawnGiblet( GetGibClass(EGT_Calf), boneCoords.Origin, HitFX[SimHitFxTicker].rotDir, GibPerterbation ); //GibCountCalf -= 2; break; case 'rfarm': case 'lfarm': //SpawnGiblet( GetGibClass(EGT_UpperArm), boneCoords.Origin, HitFX[SimHitFxTicker].rotDir, GibPerterbation ); //SpawnGiblet( GetGibClass(EGT_Forearm), boneCoords.Origin, HitFX[SimHitFxTicker].rotDir, GibPerterbation ); //GibCountForearm--; //GibCountUpperArm--; break; case 'head': //SpawnGiblet( GetGibClass(EGT_Head), boneCoords.Origin, HitFX[SimHitFxTicker].rotDir, GibPerterbation ); //GibCountTorso--; break; case 'spine': case 'none': //SpawnGiblet( GetGibClass(EGT_Torso), boneCoords.Origin, HitFX[SimHitFxTicker].rotDir, GibPerterbation ); //GibCountTorso--; bGibbed = true; //while( GibCountHead-- > 0 ) //SpawnGiblet( GetGibClass(EGT_Head), boneCoords.Origin, HitFX[SimHitFxTicker].rotDir, GibPerterbation ); //while( GibCountForearm-- > 0 ) //SpawnGiblet( GetGibClass(EGT_UpperArm), boneCoords.Origin, HitFX[SimHitFxTicker].rotDir, GibPerterbation ); //while( GibCountUpperArm-- > 0 ) //SpawnGiblet( GetGibClass(EGT_Forearm), boneCoords.Origin, HitFX[SimHitFxTicker].rotDir, GibPerterbation ); if ( !bFlaming && !Level.bDropDetail && (Level.DetailMode != DM_Low) && PlayerCanSeeMe() ) { // extra gibs!!! GibPerterbation = FMin(1.0, 1.5 * GibPerterbation); //SpawnGiblet( GetGibClass(EGT_Calf), boneCoords.Origin, HitFX[SimHitFxTicker].rotDir, GibPerterbation ); //SpawnGiblet( GetGibClass(EGT_Calf), boneCoords.Origin, HitFX[SimHitFxTicker].rotDir, GibPerterbation ); //SpawnGiblet( GetGibClass(EGT_UpperArm), boneCoords.Origin, HitFX[SimHitFxTicker].rotDir, GibPerterbation ); //SpawnGiblet( GetGibClass(EGT_Forearm), boneCoords.Origin, HitFX[SimHitFxTicker].rotDir, GibPerterbation ); } break; } HideBone(HitFX[SimHitFxTicker].bone); } } } simulated function HideBone(name boneName) { local int BoneScaleSlot; if( boneName == 'lthigh' ) boneScaleSlot = 0; else if ( boneName == 'rthigh' ) boneScaleSlot = 1; else if( boneName == 'rfarm' ) boneScaleSlot = 2; else if ( boneName == 'lfarm' ) boneScaleSlot = 3; else if ( boneName == 'head' ) boneScaleSlot = 4; else if ( boneName == 'spine' ) boneScaleSlot = 5; SetBoneScale(BoneScaleSlot, 0.0, BoneName); } function CalcHitLoc( Vector hitLoc, Vector hitRay, out Name boneName, out float dist ) { boneName = GetClosestBone( hitLoc, hitRay, dist ); } function DoDamageFX( Name boneName, int Damage, class DamageType, Rotator r ) { local float DismemberProbability; local bool bExtraGib; if ( FRand() > 0.3f || Damage > 30 || Health <= 0 ) { HitFX[HitFxTicker].damtype = DamageType; if( Health <= 0 ) { switch( boneName ) { case 'lfoot': boneName = 'lthigh'; break; case 'rfoot': boneName = 'rthigh'; break; case 'rhand': boneName = 'rfarm'; break; case 'lhand': boneName = 'lfarm'; break; case 'rshoulder': case 'lshoulder': boneName = 'spine'; break; } if( DamageType.default.bAlwaysSevers || (Damage == 1000) ) { HitFX[HitFxTicker].bSever = true; if ( boneName == 'None' ) { boneName = 'spine'; bExtraGib = true; } } else if( (Damage*DamageType.Default.GibModifier > 50+120*FRand()) && (Damage + Health > 0) ) // total gib prob { HitFX[HitFxTicker].bSever = true; boneName = 'spine'; bExtraGib = true; } else { DismemberProbability = Abs( (Health - Damage*DamageType.Default.GibModifier) / 130.0f ); switch( boneName ) { case 'lthigh': case 'rthigh': case 'rfarm': case 'lfarm': case 'head': if( FRand() < DismemberProbability ) HitFX[HitFxTicker].bSever = true; break; case 'None': boneName = 'spine'; case 'spine': if( FRand() < DismemberProbability * 0.3 ) { HitFX[HitFxTicker].bSever = true; if ( FRand() < 0.65 ) bExtraGib = true; } break; } } } if ( DamageType.default.bNeverSevers || class'GameInfo'.static.UseLowGore() || (Level.Game != None && Level.Game.PreventSever(self, boneName, Damage, DamageType)) ) { HitFX[HitFxTicker].bSever = false; bExtraGib = false; } HitFX[HitFxTicker].bone = boneName; HitFX[HitFxTicker].rotDir = r; HitFxTicker = HitFxTicker + 1; if( HitFxTicker > ArrayCount(HitFX)-1 ) HitFxTicker = 0; if ( bExtraGib ) { if ( FRand() < 0.25 ) { DoDamageFX('lthigh',1000,DamageType,r); DoDamageFX('rthigh',1000,DamageType,r); } else if ( FRand() < 0.35 ) DoDamageFX('lthigh',1000,DamageType,r); else if ( FRand() < 0.5 ) DoDamageFX('rthigh',1000,DamageType,r); } } } simulated function StartDeRes() { local KarmaParamsSkel skelParams; local int i; if( Level.NetMode == NM_DedicatedServer ) return; AmbientGlow=254; MaxLights=0; // if _RO_ //DeResFX = Spawn(class'DeResPart', self, , Location); if ( DeResFX != None ) { DeResFX.Emitters[0].SkeletalMeshActor = self; DeResFX.SetBase(self); } Skins[0] = DeResMat0; Skins[1] = DeResMat1; if ( Skins.Length > 2 ) { for ( i=2; i 100 ) { Interval = ShieldStrength - 100; if ( Interval >= damage ) { ShieldStrength -= damage; return 0; } else { ShieldStrength = 100; damage -= Interval; } } if ( ShieldStrength > SmallShieldStrength ) { Interval = ShieldStrength - SmallShieldStrength; if ( Interval >= 0.75 * damage ) { ShieldStrength -= 0.75 * damage; if ( ShieldStrength < SmallShieldStrength ) SmallShieldStrength = ShieldStrength; return (0.25 * Damage); } else { ShieldStrength = SmallShieldStrength; damage -= Interval; Remaining = 0.33 * Interval; if ( Remaining <= damage ) return damage; damage -= Remaining; } } if ( ShieldStrength >= 0.5 * damage ) { ShieldStrength -= 0.5 * damage; SmallShieldStrength = ShieldStrength; return Remaining + (0.5 * damage); } else { damage -= ShieldStrength; ShieldStrength = 0; SmallShieldStrength = 0; } return damage + Remaining; } function PlayHit(float Damage, Pawn InstigatedBy, vector HitLocation, class damageType, vector Momentum, optional int HitIndex) { local Vector HitNormal; local Vector HitRay; local Name HitBone; local float HitBoneDist; local PlayerController PC; local bool bShowEffects, bRecentHit; //local BloodSpurt BloodHit; bRecentHit = Level.TimeSeconds - LastPainTime < 0.5; Super.PlayHit(Damage,InstigatedBy,HitLocation,DamageType,Momentum); if ( Damage <= 0 ) return; PC = PlayerController(Controller); bShowEffects = ( (Level.NetMode != NM_Standalone) || (Level.TimeSeconds - LastRenderTime < 2.5) || ((InstigatedBy != None) && (PlayerController(InstigatedBy.Controller) != None)) || (PC != None) ); if ( !bShowEffects ) return; HitRay = vect(0,0,0); if( InstigatedBy != None ) HitRay = Normal(HitLocation-(InstigatedBy.Location+(vect(0,0,1)*InstigatedBy.EyeHeight))); if( DamageType.default.bLocationalHit ) CalcHitLoc( HitLocation, HitRay, HitBone, HitBoneDist ); else { HitLocation = Location; HitBone = 'None'; HitBoneDist = 0.0f; } if( DamageType.default.bAlwaysSevers && DamageType.default.bSpecial ) HitBone = 'head'; if( InstigatedBy != None ) HitNormal = Normal( Normal(InstigatedBy.Location-HitLocation) + VRand() * 0.2 + vect(0,0,2.8) ); else HitNormal = Normal( Vect(0,0,1) + VRand() * 0.2 + vect(0,0,2.8) ); if ( DamageType.Default.bCausesBlood ) { // if _RO_ // if ( class'GameInfo'.static.UseLowGore() ) // { // if ( class'GameInfo'.static.NoBlood() ) // BloodHit = BloodSpurt(Spawn( GibGroupClass.default.NoBloodHitClass,InstigatedBy,, HitLocation )); // else // BloodHit = BloodSpurt(Spawn( GibGroupClass.default.LowGoreBloodHitClass,InstigatedBy,, HitLocation )); // } // else // BloodHit = BloodSpurt(Spawn(GibGroupClass.default.BloodHitClass,InstigatedBy,, HitLocation, Rotator(HitNormal))); // if ( BloodHit != None ) // { // BloodHit.bMustShow = !bRecentHit; // if ( Momentum != vect(0,0,0) ) // BloodHit.HitDir = Momentum; // else // { // if ( InstigatedBy != None ) // BloodHit.HitDir = Location - InstigatedBy.Location; // else // BloodHit.HitDir = Location - HitLocation; // BloodHit.HitDir.Z = 0; // } // } } // hack for flak cannon gibbing if ( (DamageType.name == 'DamTypeFlakChunk') && (Health < 0) && (InstigatedBy != None) && (VSize(InstigatedBy.Location - Location) < 350) ) DoDamageFX( HitBone, 8*Damage, DamageType, Rotator(HitNormal) ); else DoDamageFX( HitBone, Damage, DamageType, Rotator(HitNormal) ); if (DamageType.default.DamageOverlayMaterial != None && Damage > 0 ) // additional check in case shield absorbed SetOverlayMaterial( DamageType.default.DamageOverlayMaterial, DamageType.default.DamageOverlayTime, false ); } function bool CheckReflect( Vector HitLocation, out Vector RefNormal, int Damage ) { if (Weapon != None) return Weapon.CheckReflect( HitLocation, RefNormal, Damage ); else return false; } function name GetWeaponBoneFor(Inventory I) { return 'righthand'; } function name GetOffhandBoneFor(Inventory I) { return 'bip01 l hand'; } event Landed(vector HitNormal) { super.Landed( HitNormal ); MultiJumpRemaining = MaxMultiJump; if ( (Health > 0) && !bHidden && (Level.TimeSeconds - SplashTime > 0.25) ) PlayOwnedSound(GetSound(EST_Land), SLOT_Interact, FMin(1,-0.3 * Velocity.Z/JumpZ)); } // ----- animation ----- // simulated function name GetAnimSequence() { local name anim; local float frame, rate; GetAnimParams(0, anim, frame, rate); return anim; } simulated function PlayDoubleJump() { local name Anim; Anim = DoubleJumpAnims[Get4WayDirection()]; if ( PlayAnim(Anim, 1.0, 0.1) ) bWaitForAnim = true; AnimAction = Anim; } simulated function bool FindValidTaunt( out name Sequence ) { local int i,j; for( i=0; i= TauntAnims.Length) ) return false; Sequence = TauntAnims[j]; return (Sequence != '' ); } simulated event SetAnimAction(name NewAction) { if (!bWaitForAnim) { AnimAction = NewAction; if ( AnimAction == 'Weapon_Switch' ) { AnimBlendParams(1, 1.0, 0.0, 0.2, FireRootBone); PlayAnim(NewAction,, 0.0, 1); } else if ( ((Physics == PHYS_None)|| ((Level.Game != None) && Level.Game.IsInState('MatchOver'))) && (DrivenVehicle == None) ) { PlayAnim(AnimAction,,0.1); AnimBlendToAlpha(1,0.0,0.05); } else if ( (DrivenVehicle != None) || (Physics == PHYS_Falling) || ((Physics == PHYS_Walking) && (Velocity.Z != 0)) ) { if ( CheckTauntValid(AnimAction) ) { if (FireState == FS_None || FireState == FS_Ready) { AnimBlendParams(1, 1.0, 0.0, 0.2, FireRootBone); PlayAnim(NewAction,, 0.1, 1); FireState = FS_Ready; } } else if ( PlayAnim(AnimAction) ) { if ( Physics != PHYS_None ) bWaitForAnim = true; } else AnimAction = ''; } else if (bIsIdle && !bIsCrouched && (Bot(Controller) == None) ) // standing taunt { PlayAnim(AnimAction,,0.1); AnimBlendToAlpha(1,0.0,0.05); } else // running taunt { if (FireState == FS_None || FireState == FS_Ready) { AnimBlendParams(1, 1.0, 0.0, 0.2, FireRootBone); PlayAnim(NewAction,, 0.1, 1); FireState = FS_Ready; } } } } simulated function StartFiring(bool bHeavy, bool bRapid) { local name FireAnim; if ( HasUDamage() && (Level.TimeSeconds - LastUDamageSoundTime > 0.25) ) { LastUDamageSoundTime = Level.TimeSeconds; PlaySound(UDamageSound, SLOT_None, 1.5*TransientSoundVolume,,700); } if (Physics == PHYS_Swimming) return; if (bHeavy) { if (bRapid) FireAnim = FireHeavyRapidAnim; else FireAnim = FireHeavyBurstAnim; } else { if (bRapid) FireAnim = FireRifleRapidAnim; else FireAnim = FireRifleBurstAnim; } AnimBlendParams(1, 1.0, 0.0, 0.2, FireRootBone); if (bRapid) { if (FireState != FS_Looping) { LoopAnim(FireAnim,, 0.0, 1); FireState = FS_Looping; } } else { PlayAnim(FireAnim,, 0.0, 1); FireState = FS_PlayOnce; } IdleTime = Level.TimeSeconds; } simulated function StopFiring() { if (FireState == FS_Looping) { FireState = FS_PlayOnce; } IdleTime = Level.TimeSeconds; } simulated function AnimEnd(int Channel) { if (Channel == 1) { if (FireState == FS_Ready) { AnimBlendToAlpha(1, 0.0, 0.12); FireState = FS_None; } else if (FireState == FS_PlayOnce) { PlayAnim(IdleWeaponAnim,, 0.2, 1); FireState = FS_Ready; IdleTime = Level.TimeSeconds; } else AnimBlendToAlpha(1, 0.0, 0.12); } else if ( bKeepTaunting && (Channel == 0) ) PlayVictoryAnimation(); } function PlayWeaponSwitch(Weapon NewWeapon) { SetAnimAction('Weapon_Switch'); } function PlayVictoryAnimation() { local int tauntNum; // First 4 taunts are 'order' anims. Don't pick them. tauntNum = Rand(TauntAnims.Length - 3); SetAnimAction(TauntAnims[3 + tauntNum]); } simulated function SetWeaponAttachment(WeaponAttachment NewAtt) { WeaponAttachment = NewAtt; if (xWeaponAttachment(WeaponAttachment).bHeavy) IdleWeaponAnim = IdleHeavyAnim; else IdleWeaponAnim = IdleRifleAnim; } // Event called whenever ragdoll convulses event KSkelConvulse() { if(RagConvulseMaterial != None) SetOverlayMaterial(RagConvulseMaterial, 0.4, true); } simulated final function RandSpin(float spinRate) { DesiredRotation = RotRand(true); RotationRate.Yaw = spinRate * 2 *FRand() - spinRate; RotationRate.Pitch = spinRate * 2 *FRand() - spinRate; RotationRate.Roll = spinRate * 2 *FRand() - spinRate; bFixedRotationDir = true; bRotateToDesired = false; } simulated function PlayDying(class DamageType, vector HitLoc) { local float frame, rate; local name seq; // if _RO_ //local LavaDeath LD; local BodyEffect BE; AmbientSound = None; bCanTeleport = false; // sjs - fix karma going crazy when corpses land on teleporters bReplicateMovement = false; bTearOff = true; bPlayedDeath = true; if (CurrentCombo != None) CurrentCombo.Destroy(); HitDamageType = DamageType; // these are replicated to other clients TakeHitLocation = HitLoc; if ( DamageType != None ) { if ( DamageType.default.bSkeletize ) { SetOverlayMaterial(DamageType.Default.DamageOverlayMaterial, 4.0, true); if (!bSkeletized) { if ( (Level.NetMode != NM_DedicatedServer) && (SkeletonMesh != None) ) { if ( DamageType.default.bLeaveBodyEffect ) { BE = spawn(class'BodyEffect',self); if ( BE != None ) { BE.DamageType = DamageType; BE.HitLoc = HitLoc; bFrozenBody = true; } } GetAnimParams( 0, seq, frame, rate ); LinkMesh(SkeletonMesh, true); Skins.Length = 0; PlayAnim(seq, 0, 0); SetAnimFrame(frame); } if (Physics == PHYS_Walking) Velocity = Vect(0,0,0); TearOffMomentum *= 0.25; bSkeletized = true; if ( (Level.NetMode != NM_DedicatedServer) && (DamageType == class'FellLava') ) { // if _RO_ //LD = spawn(class'LavaDeath', , , Location + vect(0, 0, 10), Rotation ); //if ( LD != None ) // LD.SetBase(self); //PlaySound( sound'WeaponSounds.BExplosion5', SLOT_None, 1.5*TransientSoundVolume ); } } } else if ( DamageType.Default.DeathOverlayMaterial != None ) SetOverlayMaterial(DamageType.Default.DeathOverlayMaterial, DamageType.default.DeathOverlayTime, true); else if ( (DamageType.Default.DamageOverlayMaterial != None) && (Level.DetailMode != DM_Low) && !Level.bDropDetail ) SetOverlayMaterial(DamageType.Default.DamageOverlayMaterial, 2*DamageType.default.DamageOverlayTime, true); } // stop shooting AnimBlendParams(1, 0.0); FireState = FS_None; LifeSpan = RagdollLifeSpan; GotoState('Dying'); if ( BE != None ) return; PlayDyingAnimation(DamageType, HitLoc); } function PlayDyingAnimation(class DamageType, vector HitLoc) { local vector shotDir, hitLocRel, deathAngVel, shotStrength; local float maxDim; local string RagSkelName; local KarmaParamsSkel skelParams; local bool PlayersRagdoll; local PlayerController pc; if ( Level.NetMode != NM_DedicatedServer ) { // Is this the local player's ragdoll? if(OldController != None) pc = PlayerController(OldController); if( pc != None && pc.ViewTarget == self ) PlayersRagdoll = true; // In low physics detail, if we were not just controlling this pawn, // and it has not been rendered in 3 seconds, just destroy it. if( (Level.PhysicsDetailLevel != PDL_High) && !PlayersRagdoll && (Level.TimeSeconds - LastRenderTime > 3) ) { Destroy(); return; } // Try and obtain a rag-doll setup. Use optional 'override' one out of player record first, then use the species one. if( RagdollOverride != "") RagSkelName = RagdollOverride; else if(Species != None) RagSkelName = Species.static.GetRagSkelName( GetMeshName() ); else Log("xPawn.PlayDying: No Species"); // If we managed to find a name, try and make a rag-doll slot availbale. if( RagSkelName != "" ) { KMakeRagdollAvailable(); } if( KIsRagdollAvailable() && RagSkelName != "" ) { skelParams = KarmaParamsSkel(KParams); skelParams.KSkeleton = RagSkelName; // Stop animation playing. StopAnimating(true); if( DamageType != None ) { if ( DamageType.default.bLeaveBodyEffect ) TearOffMomentum = vect(0,0,0); if( DamageType.default.bKUseOwnDeathVel ) { RagDeathVel = DamageType.default.KDeathVel; RagDeathUpKick = DamageType.default.KDeathUpKick; } } // Set the dude moving in direction he was shot in general shotDir = Normal(TearOffMomentum); shotStrength = RagDeathVel * shotDir; // Calculate angular velocity to impart, based on shot location. hitLocRel = TakeHitLocation - Location; // We scale the hit location out sideways a bit, to get more spin around Z. hitLocRel.X *= RagSpinScale; hitLocRel.Y *= RagSpinScale; // If the tear off momentum was very small for some reason, make up some angular velocity for the pawn if( VSize(TearOffMomentum) < 0.01 ) { //Log("TearOffMomentum magnitude of Zero"); deathAngVel = VRand() * 18000.0; } else { deathAngVel = RagInvInertia * (hitLocRel Cross shotStrength); } // Set initial angular and linear velocity for ragdoll. // Scale horizontal velocity for characters - they run really fast! if ( DamageType.Default.bRubbery ) skelParams.KStartLinVel = vect(0,0,0); if ( Damagetype.default.bKUseTearOffMomentum ) skelParams.KStartLinVel = TearOffMomentum + Velocity; else { skelParams.KStartLinVel.X = 0.6 * Velocity.X; skelParams.KStartLinVel.Y = 0.6 * Velocity.Y; skelParams.KStartLinVel.Z = 1.0 * Velocity.Z; skelParams.KStartLinVel += shotStrength; } // If not moving downwards - give extra upward kick if( !DamageType.default.bLeaveBodyEffect && !DamageType.Default.bRubbery && (Velocity.Z > -10) ) skelParams.KStartLinVel.Z += RagDeathUpKick; if ( DamageType.Default.bRubbery ) { Velocity = vect(0,0,0); skelParams.KStartAngVel = vect(0,0,0); } else { skelParams.KStartAngVel = deathAngVel; // Set up deferred shot-bone impulse maxDim = Max(CollisionRadius, CollisionHeight); skelParams.KShotStart = TakeHitLocation - (1 * shotDir); skelParams.KShotEnd = TakeHitLocation + (2*maxDim*shotDir); skelParams.KShotStrength = RagShootStrength; } // If this damage type causes convulsions, turn them on here. if(DamageType != None && DamageType.default.bCauseConvulsions) { RagConvulseMaterial=DamageType.default.DamageOverlayMaterial; skelParams.bKDoConvulsions = true; } // Turn on Karma collision for ragdoll. KSetBlockKarma(true); // Set physics mode to ragdoll. // This doesn't actaully start it straight away, it's deferred to the first tick. SetPhysics(PHYS_KarmaRagdoll); // If viewing this ragdoll, set the flag to indicate that it is 'important' if( PlayersRagdoll ) skelParams.bKImportantRagdoll = true; skelParams.bRubbery = DamageType.Default.bRubbery; bRubbery = DamageType.Default.bRubbery; skelParams.KActorGravScale = RagGravScale; return; } // jag } // non-ragdoll death fallback Velocity += TearOffMomentum; BaseEyeHeight = Default.BaseEyeHeight; SetTwistLook(0, 0); SetInvisibility(0.0); PlayDirectionalDeath(HitLoc); SetPhysics(PHYS_Falling); } simulated function SpawnGibs(Rotator HitRotation, float ChunkPerterbation) { bGibbed = true; PlayDyingSound(); // IF _RO_ return; // if( GibCountTorso+GibCountHead+GibCountForearm+GibCountUpperArm > 3 ) // { // if ( class'GameInfo'.static.UseLowGore() ) // { // if ( !class'GameInfo'.static.NoBlood() ) // Spawn( GibGroupClass.default.LowGoreBloodGibClass,,,Location ); // } // else // Spawn( GibGroupClass.default.BloodGibClass,,,Location ); // } // if ( class'GameInfo'.static.UseLowGore() ) // return; // // SpawnGiblet( GetGibClass(EGT_Torso), Location, HitRotation, ChunkPerterbation ); // GibCountTorso--; // // while( GibCountTorso-- > 0 ) // SpawnGiblet( GetGibClass(EGT_Torso), Location, HitRotation, ChunkPerterbation ); // while( GibCountHead-- > 0 ) // SpawnGiblet( GetGibClass(EGT_Head), Location, HitRotation, ChunkPerterbation ); // while( GibCountForearm-- > 0 ) // SpawnGiblet( GetGibClass(EGT_UpperArm), Location, HitRotation, ChunkPerterbation ); // while( GibCountUpperArm-- > 0 ) // SpawnGiblet( GetGibClass(EGT_Forearm), Location, HitRotation, ChunkPerterbation ); } function ClientDying(class DamageType, vector HitLocation) { } function PlayTakeHit(vector HitLocation, int Damage, class DamageType) { PlayDirectionalHit(HitLocation); if( Level.TimeSeconds - LastPainSound < MinTimeBetweenPainSounds ) return; LastPainSound = Level.TimeSeconds; if( HeadVolume.bWaterVolume ) { if( DamageType.IsA('Drowned') ) PlaySound( GetSound(EST_Drown), SLOT_Pain,1.5*TransientSoundVolume ); else PlaySound( GetSound(EST_HitUnderwater), SLOT_Pain,1.5*TransientSoundVolume ); return; } PlaySound(SoundGroupClass.static.GetHitSound(), SLOT_Pain,2*TransientSoundVolume,,200); } // jag // Called when in Ragdoll when we hit something over a certain threshold velocity // Used to play impact sounds. event KImpact(actor other, vector pos, vector impactVel, vector impactNorm) { local int numSounds, soundNum; numSounds = RagImpactSounds.Length; //log("ouch! iv:"$VSize(impactVel)); if(numSounds > 0 && Level.TimeSeconds > RagLastSoundTime + RagImpactSoundInterval) { soundNum = Rand(numSounds); //Log("Play Sound:"$soundNum); PlaySound(RagImpactSounds[soundNum], SLOT_Pain, RagImpactVolume); RagLastSoundTime = Level.TimeSeconds; } } //jag simulated function PlayDirectionalDeath(Vector HitLoc) { local Vector X,Y,Z, Dir; GetAxes(Rotation, X,Y,Z); HitLoc.Z = Location.Z; // random if ( VSize(Velocity) < 10.0 && VSize(Location - HitLoc) < 1.0 ) { Dir = VRand(); } // velocity based else if ( VSize(Velocity) > 0.0 ) { Dir = Normal(Velocity*Vect(1,1,0)); } // hit location based else { Dir = -Normal(Location - HitLoc); } if ( Dir Dot X > 0.7 || Dir == vect(0,0,0)) PlayAnim('DeathB',, 0.2); else if ( Dir Dot X < -0.7 ) PlayAnim('DeathF',, 0.2); else if ( Dir Dot Y > 0 ) PlayAnim('DeathL',, 0.2); else if ( HasAnim('DeathR') ) PlayAnim('DeathR',, 0.2); else PlayAnim('DeathF',, 0.2); } simulated function PlayDirectionalHit(Vector HitLoc) { local Vector X,Y,Z, Dir; if ( DrivenVehicle != None ) return; GetAxes(Rotation, X,Y,Z); HitLoc.Z = Location.Z; // random if ( VSize(Location - HitLoc) < 1.0 ) { Dir = VRand(); } // hit location based else { Dir = -Normal(Location - HitLoc); } if ( Dir Dot X > 0.7 || Dir == vect(0,0,0)) { PlayAnim('HitF',, 0.1); } else if ( Dir Dot X < -0.7 ) { PlayAnim('HitB',, 0.1); } else if ( Dir Dot Y > 0 ) { PlayAnim('HitR',, 0.1); } else { PlayAnim('HitL',, 0.1); } } simulated function FootStepping(int Side) { local int SurfaceNum, i; local actor A; local material FloorMat; local vector HL,HN,Start,End/*,HitLocation,HitNormal*/; SurfaceNum = 0; for ( i=0; i ComboClass; ComboClass = class( DynamicLoadObject( ComboClassName, class'Class' ) ); if ( ComboClass != None ) DoCombo( ComboClass ); else log("WARNING - Couldn't create combo "$ComboClassName); } function DoCombo( class ComboClass ) { local int i; if ( ComboClass != None ) { if (CurrentCombo == None) { CurrentCombo = Spawn( ComboClass, self ); // Record stats for using the combo UnrealMPGameInfo(Level.Game).SpecialEvent(PlayerReplicationInfo,""$CurrentCombo.Class); if ( ComboClass.Name == 'ComboSpeed' ) i = 0; else if ( ComboClass.Name == 'ComboBerserk' ) i = 1; else if ( ComboClass.Name == 'ComboDefensive' ) i = 2; else if ( ComboClass.Name == 'ComboInvis' ) i = 3; else i = 4; TeamPlayerReplicationInfo(PlayerReplicationInfo).Combos[i] += 1; } } } simulated function bool HasUDamage() { return (UDamageTime > Level.TimeSeconds); } function ClientSetUDamageTime(float NewUDam) { UDamageTime = Level.TimeSeconds + NewUDam; } function EnableUDamage(float amount) { UDamageTime = FMax(UDamageTime, Level.TimeSeconds+amount); ClientSetUDamageTime(UDamageTime - Level.TimeSeconds); if ( UDamageTimer == None ) UDamageTimer = Spawn(class'UDamageTimer',self); UDamageTimer.SetTimer(UDamageTime - Level.TimeSeconds - 3,false); LightType = LT_Steady; bDynamicLight = true; SetWeaponOverlay(UDamageWeaponMaterial, UDamageTime - Level.TimeSeconds, false); } function DisableUDamage() { LightType = LT_None; bDynamicLight = false; UDamageTime = Level.TimeSeconds - 1; ClientSetUDamageTime(-1); SetWeaponOverlay(UDamageWeaponMaterial, UDamageTime - Level.TimeSeconds, false); } function SetWeaponOverlay(Material mat, float time, bool override) { if (Weapon != None) { Weapon.SetOverlayMaterial(mat, time, override); if (WeaponAttachment(Weapon.ThirdPersonActor) != None) WeaponAttachment(Weapon.ThirdPersonActor).SetOverlayMaterial(mat, time, override); } } function ChangedWeapon() { Super.ChangedWeapon(); if (Weapon != None && Role < ROLE_Authority) { if (bBerserk) Weapon.StartBerserk(); else if ( Weapon.bBerserk ) Weapon.StopBerserk(); } } function ServerChangedWeapon(Weapon OldWeapon, Weapon NewWeapon) { local float InvisTime; if ( bInvis ) { if ( (OldWeapon != None) && (OldWeapon.OverlayMaterial == InvisMaterial) ) InvisTime = OldWeapon.ClientOverlayCounter; else InvisTime = 20000; } if (HasUDamage() || bInvis) SetWeaponOverlay(None, 0.f, true); Super.ServerChangedWeapon(OldWeapon, NewWeapon); if (bInvis) SetWeaponOverlay(InvisMaterial, InvisTime, true); else if (HasUDamage()) SetWeaponOverlay(UDamageWeaponMaterial, UDamageTime - Level.TimeSeconds, false); if (bBerserk) Weapon.StartBerserk(); else if ( Weapon.bBerserk ) Weapon.StopBerserk(); } function SetInvisibility(float time) { bInvis = (time > 0.0); if (Role == ROLE_Authority) { if (bInvis) { if ( (time == 2000000.0) && Level.Game.IsA('xMutantGame') ) // for mutant game Visibility = Default.Visibility; else Visibility = 1; SetWeaponOverlay(InvisMaterial, time, true); } else { Visibility = Default.Visibility; if (HasUDamage()) SetWeaponOverlay(UDamageWeaponMaterial, UDamageTime - Level.TimeSeconds, true); else SetWeaponOverlay(None, 0.0, true); } } } /* BotDodge() returns appropriate vector for dodge in direction Dir (which should be normalized) */ function vector BotDodge(Vector Dir) { local vector Vel; Vel = DodgeSpeedFactor*GroundSpeed*Dir; Vel.Z = DodgeSpeedZ; return Vel; } function bool Dodge(eDoubleClickDir DoubleClickMove) { local vector X,Y,Z, TraceStart, TraceEnd, Dir, Cross, HitLocation, HitNormal; local Actor HitActor; local rotator TurnRot; if ( bIsCrouched || bWantsToCrouch || (Physics != PHYS_Walking && Physics != PHYS_Falling) ) return false; TurnRot.Yaw = Rotation.Yaw; GetAxes(TurnRot,X,Y,Z); if ( Physics == PHYS_Falling ) { if ( !bCanWallDodge ) return false; if (DoubleClickMove == DCLICK_Forward) TraceEnd = -X; else if (DoubleClickMove == DCLICK_Back) TraceEnd = X; else if (DoubleClickMove == DCLICK_Left) TraceEnd = Y; else if (DoubleClickMove == DCLICK_Right) TraceEnd = -Y; TraceStart = Location - CollisionHeight*Vect(0,0,1) + TraceEnd*CollisionRadius; TraceEnd = TraceStart + TraceEnd*32.0; HitActor = Trace(HitLocation, HitNormal, TraceEnd, TraceStart, false, vect(1,1,1)); if ( (HitActor == None) || (!HitActor.bWorldGeometry && (Mover(HitActor) == None)) ) return false; } if (DoubleClickMove == DCLICK_Forward) { Dir = X; Cross = Y; } else if (DoubleClickMove == DCLICK_Back) { Dir = -1 * X; Cross = Y; } else if (DoubleClickMove == DCLICK_Left) { Dir = -1 * Y; Cross = X; } else if (DoubleClickMove == DCLICK_Right) { Dir = Y; Cross = X; } if ( AIController(Controller) != None ) Cross = vect(0,0,0); return PerformDodge(DoubleClickMove, Dir,Cross); } function bool PerformDodge(eDoubleClickDir DoubleClickMove, vector Dir, vector Cross) { local float VelocityZ; local name Anim; if ( Physics == PHYS_Falling ) { if (DoubleClickMove == DCLICK_Forward) Anim = WallDodgeAnims[0]; else if (DoubleClickMove == DCLICK_Back) Anim = WallDodgeAnims[1]; else if (DoubleClickMove == DCLICK_Left) Anim = WallDodgeAnims[2]; else if (DoubleClickMove == DCLICK_Right) Anim = WallDodgeAnims[3]; if ( PlayAnim(Anim, 1.0, 0.1) ) bWaitForAnim = true; AnimAction = Anim; TakeFallingDamage(); if (Velocity.Z < -DodgeSpeedZ*0.5) Velocity.Z += DodgeSpeedZ*0.5; } VelocityZ = Velocity.Z; Velocity = DodgeSpeedFactor*GroundSpeed*Dir + (Velocity Dot Cross)*Cross; if ( !bCanDodgeDoubleJump ) MultiJumpRemaining = 0; if ( bCanBoostDodge || (Velocity.Z < -100) ) Velocity.Z = VelocityZ + DodgeSpeedZ; else Velocity.Z = DodgeSpeedZ; CurrentDir = DoubleClickMove; SetPhysics(PHYS_Falling); PlayOwnedSound(GetSound(EST_Dodge), SLOT_Pain, GruntVolume,,80); return true; } function DoDoubleJump( bool bUpdating ) { PlayDoubleJump(); if ( !bIsCrouched && !bWantsToCrouch ) { if ( !IsLocallyControlled() || (AIController(Controller) != None) ) MultiJumpRemaining -= 1; Velocity.Z = JumpZ + MultiJumpBoost; SetPhysics(PHYS_Falling); if ( !bUpdating ) PlayOwnedSound(GetSound(EST_DoubleJump), SLOT_Pain, GruntVolume,,80); } } function bool CanDoubleJump() { return ( (MultiJumpRemaining > 0) && (Physics == PHYS_Falling) ); } function bool CanMultiJump() { return ( MaxMultiJump > 0 ); } function bool DoJump( bool bUpdating ) { // This extra jump allows a jumping or dodging pawn to jump again mid-air // (via thrusters). The pawn must be within +/- 100 velocity units of the // apex of the jump to do this special move. if ( !bUpdating && CanDoubleJump()&& (Abs(Velocity.Z) < 100) && IsLocallyControlled() ) { if ( PlayerController(Controller) != None ) PlayerController(Controller).bDoubleJump = true; DoDoubleJump(bUpdating); MultiJumpRemaining -= 1; return true; } if ( Super.DoJump(bUpdating) ) { if ( !bUpdating ) PlayOwnedSound(GetSound(EST_Jump), SLOT_Pain, GruntVolume,,80); return true; } return false; } simulated function NotifyTeamChanged() { // my PRI now has a new team PostNetReceive(); } simulated event PostNetReceive() { if ( ForceDefaultCharacter() ) { Setup(class'xUtil'.static.FindPlayerRecord(GetDefaultCharacter())); bNetNotify = false; } else if ( PlayerReplicationInfo != None ) { Setup(class'xUtil'.static.FindPlayerRecord(PlayerReplicationInfo.CharacterName)); bNetNotify = false; } else if ( (DrivenVehicle != None) && (DrivenVehicle.PlayerReplicationInfo != None) ) { Setup(class'xUtil'.static.FindPlayerRecord(DrivenVehicle.PlayerReplicationInfo.CharacterName)); bNetNotify = false; } } simulated function ClientRestart() { Super.ClientRestart(); if ( Controller != None ) OldController = Controller; } simulated function bool CheckValidFemaleDefault() { return ( (PlacedFemaleCharacterName ~= "Tamika") || (PlacedFemaleCharacterName ~= "Sapphire") || (PlacedFemaleCharacterName ~= "Enigma") || (PlacedFemaleCharacterName ~= "Cathode") || (PlacedFemaleCharacterName ~= "Rylisa") || (PlacedFemaleCharacterName ~= "Ophelia") || (PlacedFemaleCharacterName ~= "Zarina") ); } simulated function bool CheckValidMaleDefault() { return ( (PlacedCharacterName ~= "Jakob") || (PlacedCharacterName ~= "Gorge") || (PlacedCharacterName ~= "Malcolm") || (PlacedCharacterName ~= "Xan") || (PlacedCharacterName ~= "Brock") || (PlacedCharacterName ~= "Gaargod") || (PlacedCharacterName ~= "Axon") ); } simulated function bool ForceDefaultCharacter() { local PlayerController P; if ( !class'DeathMatch'.default.bForceDefaultCharacter ) return false; // validate and use player's model for enemies of same sex P = Level.GetLocalPlayerController(); if ( (P != None) && (P.PlayerReplicationInfo != None) ) { if ( P.PlayerReplicationInfo.bIsFemale ) { PlacedFemaleCharacterName = P.PlayerReplicationInfo.CharacterName; if ( !CheckValidFemaleDefault() ) { PlacedFemaleCharacterName = "Tamika"; return false; } } else { PlacedCharacterName = P.PlayerReplicationInfo.CharacterName; if ( !CheckValidMaleDefault() ) { PlacedCharacterName = "Jakob"; return false; } } } return true; } simulated function string GetDefaultCharacter() { if ( Level.IsDemoBuild() ) { PlacedFemaleCharacterName = "Tamika"; PlacedCharacterName = "Jakob"; } else { // make sure picking from valid default characters if ( !CheckValidFemaleDefault() ) PlacedFemaleCharacterName = "Tamika"; if ( !CheckValidMaleDefault() ) PlacedCharacterName = "Jakob"; } // return appropriate character based on this pawn's sex if ( (PlayerReplicationInfo != None) && PlayerReplicationInfo.bIsFemale ) return PlacedFemaleCharacterName; else return PlacedCharacterName; } simulated function Setup(xUtil.PlayerRecord rec, optional bool bLoadNow) { if ( (rec.Species == None) || ForceDefaultCharacter() ) rec = class'xUtil'.static.FindPlayerRecord(GetDefaultCharacter()); Species = rec.Species; RagdollOverride = rec.Ragdoll; if ( !Species.static.Setup(self,rec) ) { rec = class'xUtil'.static.FindPlayerRecord(GetDefaultCharacter()); if ( !Species.static.Setup(self,rec) ) return; } ResetPhysicsBasedAnim(); } simulated function ResetPhysicsBasedAnim() { bIsIdle = false; bWaitForAnim = false; } function Sound GetSound(xPawnSoundGroup.ESoundType soundType) { return SoundGroupClass.static.GetSound(soundType); } //function class GetGibClass(xPawnGibGroup.EGibType gibType) //{ // return GibGroupClass.static.GetGibClass(gibType); //} simulated function DoDerezEffect() { Spawn(TeleportFXClass); } State Dying { simulated function AnimEnd( int Channel ) { ReduceCylinder(); } event FellOutOfWorld(eKillZType KillType) { // if _RO_ //local LavaDeath LD; // If we fall past a lava killz while dead- burn off skin. if( KillType == KILLZ_Lava ) { if ( !bSkeletized ) { if ( SkeletonMesh != None ) { LinkMesh(SkeletonMesh, true); Skins.Length = 0; } bSkeletized = true; // if _RO_ //LD = spawn(class'LavaDeath', , , Location + vect(0, 0, 10), Rotation ); //if ( LD != None ) // LD.SetBase(self); // This should destroy itself once its finished. //PlaySound( sound'WeaponSounds.BExplosion5', SLOT_None, 1.5*TransientSoundVolume ); } return; } Super.FellOutOfWorld(KillType); } function LandThump() { // animation notify - play sound if actually landed, and animation also shows it if ( Physics == PHYS_None) { bThumped = true; PlaySound(GetSound(EST_CorpseLanded)); } } simulated function TakeDamage( int Damage, Pawn InstigatedBy, Vector Hitlocation, Vector Momentum, class damageType, optional int HitIndex) { local Vector SelfToHit, SelfToInstigator, CrossPlaneNormal; local float W; local float YawDir; local Vector HitNormal, shotDir; local Vector PushLinVel, PushAngVel; local Name HitBone; local float HitBoneDist; local int MaxCorpseYawRate; if ( bFrozenBody || bRubbery ) return; if( Physics == PHYS_KarmaRagdoll ) { // Can't shoot corpses during de-res if( bDeRes || bRubbery ) return; // Throw the body if its a rocket explosion or shock combo if( damageType.Default.bThrowRagdoll ) { shotDir = Normal(Momentum); PushLinVel = (RagDeathVel * shotDir) + vect(0, 0, 250); PushAngVel = Normal(shotDir Cross vect(0, 0, 1)) * -18000; KSetSkelVel( PushLinVel, PushAngVel ); } else if( damageType.Default.bRagdollBullet ) { if ( Momentum == vect(0,0,0) ) Momentum = HitLocation - InstigatedBy.Location; if ( FRand() < 0.65 ) { if ( Velocity.Z <= 0 ) PushLinVel = vect(0,0,40); PushAngVel = Normal(Normal(Momentum) Cross vect(0, 0, 1)) * -8000 ; PushAngVel.X *= 0.5; PushAngVel.Y *= 0.5; PushAngVel.Z *= 4; KSetSkelVel( PushLinVel, PushAngVel ); } PushLinVel = RagShootStrength*Normal(Momentum); KAddImpulse(PushLinVel, HitLocation); if ( (LifeSpan > 0) && (LifeSpan < DeResTime + 2) ) LifeSpan += 0.2; } else { PushLinVel = RagShootStrength*Normal(Momentum); KAddImpulse(PushLinVel, HitLocation); } if ( (DamageType.Default.DamageOverlayMaterial != None) && (Level.DetailMode != DM_Low) && !Level.bDropDetail ) SetOverlayMaterial(DamageType.Default.DamageOverlayMaterial, DamageType.default.DamageOverlayTime, true); return; } if ( DamageType.default.bFastInstantHit && GetAnimSequence() == 'Death_Spasm' && RepeaterDeathCount < 6) { PlayAnim('Death_Spasm',, 0.2); RepeaterDeathCount++; } else if (Damage > 0) { if ( InstigatedBy != None ) { if ( InstigatedBy.IsA('xPawn') && xPawn(InstigatedBy).bBerserk ) Damage *= 2; // Figure out which direction to spin: if( InstigatedBy.Location != Location ) { SelfToInstigator = InstigatedBy.Location - Location; SelfToHit = HitLocation - Location; CrossPlaneNormal = Normal( SelfToInstigator cross Vect(0,0,1) ); W = CrossPlaneNormal dot Location; if( HitLocation dot CrossPlaneNormal < W ) YawDir = -1.0; else YawDir = 1.0; } } if( VSize(Momentum) < 10 ) { Momentum = - Normal(SelfToInstigator) * Damage * 1000.0; Momentum.Z = Abs( Momentum.Z ); } SetPhysics(PHYS_Falling); Momentum = Momentum / Mass; AddVelocity( Momentum ); bBounce = true; RotationRate.Pitch = 0; RotationRate.Yaw += VSize(Momentum) * YawDir; MaxCorpseYawRate = 150000; RotationRate.Yaw = Clamp( RotationRate.Yaw, -MaxCorpseYawRate, MaxCorpseYawRate ); RotationRate.Roll = 0; bFixedRotationDir = true; bRotateToDesired = false; Health -= Damage; CalcHitLoc( HitLocation, vect(0,0,0), HitBone, HitBoneDist ); if( InstigatedBy != None ) HitNormal = Normal( Normal(InstigatedBy.Location-HitLocation) + VRand() * 0.2 + vect(0,0,2.8) ); else HitNormal = Normal( Vect(0,0,1) + VRand() * 0.2 + vect(0,0,2.8) ); DoDamageFX( HitBone, Damage, DamageType, Rotator(HitNormal) ); } } simulated function BeginState() { Super.BeginState(); AmbientSound = None; } simulated function Timer() { local KarmaParamsSkel skelParams; if ( !PlayerCanSeeMe() ) { Destroy(); } // If we are running out of life, bute we still haven't come to rest, force the de-res. // unless pawn is the viewtarget of a player who used to own it else if ( LifeSpan <= DeResTime && bDeRes == false ) { skelParams = KarmaParamsSkel(KParams); // check not viewtarget if ( (PlayerController(OldController) != None) && (PlayerController(OldController).ViewTarget == self) && (Viewport(PlayerController(OldController).Player) != None) ) { skelParams.bKImportantRagdoll = true; LifeSpan = FMax(LifeSpan,DeResTime + 2.0); SetTimer(1.0, false); return; } else { skelParams.bKImportantRagdoll = false; } // spawn derez StartDeRes(); } else { SetTimer(1.0, false); } } // We shorten the lifetime when the guys comes to rest. event KVelDropBelow() { local float NewLifeSpan; if(bDeRes == false) { //Log("Low Vel - Reducing LifeSpan!"); NewLifeSpan = DeResTime + 3.5; if(NewLifeSpan < LifeSpan) LifeSpan = NewLifeSpan; } } } defaultproperties { bNetNotify=true // if _RO_ // Default everything to Characters_anm.ger_rifleman_tunic //Mesh=SkeletalMesh'Characters_anm.ger_rifleman_tunic' //Skins(0)=Texture'Characters_tex.ger_uniforms.ger_rifleman_tunic' //Skins(1)=Texture'Characters_tex.ger_heads.ger_face01' // else // default everything to ThunderCrash.Jakob // Mesh=Mesh'ThunderCrash.JakobM' // Skins(0)=Texture'DemoPlayerSkins.Jakob_Body' // Skins(1)=Texture'DemoPlayerSkins.Jakob_NewHead' Species=class'SPECIES_Human' // Temp commented out - Ramm SoundGroupClass=none//class'xMercMaleSoundGroup' // if _RO_ //GibGroupClass=class'xPawnGibGroup' bStatic=False DrawScale=1.0 Buoyancy=+00099.000000 UnderWaterTime=+00020.000000 bCanStrafe=True DrawType=DT_Mesh Style=STY_Normal LightBrightness=255 LightHue=204 LightSaturation=0 LightRadius=3 RotationRate=(Pitch=3072,Yaw=20000,Roll=2048) //BloodEffect=class'BloodJet' //LowGoreBlood=class'AlienSmallHit' AirControl=+0.35 bStasis=false bCanCrouch=true bCanClimbLadders=True bCanPickupInventory=True WalkingPct=+0.4 CrouchedPct=+0.4 BaseEyeHeight=38.0 EyeHeight=38.0 CollisionRadius=25.0 CollisionHeight=44.0 GroundSpeed=440.0 AirSpeed=440.0 WaterSpeed=220.0 DodgeSpeedFactor=1.5 DodgeSpeedZ=210.0 AccelRate=2048.0 JumpZ=340.0 CrouchHeight=29.0 CrouchRadius=25.0 LODBias=1.8 ShieldStrengthMax=150.0 PrePivot=(X=0.0,Y=0.0,Z=-5.0); ControllerClass=class'XGame.xBot' // ifndef _RO_ // SoundFootsteps(0)=Sound'PlayerSounds.Final.FootstepDefault' // SoundFootsteps(1)=Sound'PlayerSounds.Final.FootstepRock' // SoundFootsteps(2)=Sound'PlayerSounds.Final.FootstepDirt' // SoundFootsteps(3)=Sound'PlayerSounds.Final.FootStepMetal' // SoundFootsteps(4)=Sound'PlayerSounds.Final.FootstepWood' // SoundFootsteps(5)=Sound'PlayerSounds.Final.FootstepPlant' // SoundFootsteps(6)=Sound'PlayerSounds.Final.FootstepFlesh' // SoundFootsteps(7)=Sound'PlayerSounds.Final.FootstepIce' // SoundFootsteps(8)=Sound'PlayerSounds.Final.FootstepSnow' // SoundFootsteps(9)=Sound'PlayerSounds.Final.FootstepWater' // SoundFootsteps(10)=Sound'PlayerSounds.Final.FootstepGlass' RequiredEquipment(0)="XWeapons.AssaultRifle" RequiredEquipment(1)="XWeapons.ShieldGun" MinTimeBetweenPainSounds=0.35 ScaleGlow=1.0 AmbientGlow=40 // Temp commented out - Ramm TeleportFXClass=none//class'TransEffect' // GibCountCalf=4 // GibCountForearm=2 // GibCountHead=2 // GibCountTorso=2 // GibCountUpperArm=2 bDoTorsoTwist=true bActorShadows=true bPlayerShadows=true // ifndef _RO_ //ShieldHitMat=Material'XGameShaders.PlayerShaders.PlayerShieldSh' ShieldHitMatTime=1.0 // ifndef _RO_ //UDamageWeaponMaterial=Material'XGameShaders.PlayerShaders.WeaponUDamageShader' //InvisMaterial=FinalBlend'XEffectMat.InvisOverlayFB' bPhysicsAnimUpdate=true MovementAnims(0)=RunF MovementAnims(1)=RunB MovementAnims(2)=RunL MovementAnims(3)=RunR SwimAnims(0)=SwimF SwimAnims(1)=SwimB SwimAnims(2)=SwimL SwimAnims(3)=SwimR CrouchAnims(0)=CrouchF CrouchAnims(1)=CrouchB CrouchAnims(2)=CrouchL CrouchAnims(3)=CrouchR WalkAnims(0)=WalkF WalkAnims(1)=WalkB WalkAnims(2)=WalkL WalkAnims(3)=WalkR AirStillAnim=Jump_Mid AirAnims(0)=JumpF_Mid AirAnims(1)=JumpB_Mid AirAnims(2)=JumpL_Mid AirAnims(3)=JumpR_Mid TakeoffStillAnim=Jump_Takeoff TakeoffAnims(0)=JumpF_Takeoff TakeoffAnims(1)=JumpB_Takeoff TakeoffAnims(2)=JumpL_Takeoff TakeoffAnims(3)=JumpR_Takeoff LandAnims(0)=JumpF_Land LandAnims(1)=JumpB_Land LandAnims(2)=JumpL_Land LandAnims(3)=JumpR_Land DoubleJumpAnims(0)=DoubleJumpF DoubleJumpAnims(1)=DoubleJumpB DoubleJumpAnims(2)=DoubleJumpL DoubleJumpAnims(3)=DoubleJumpR DodgeAnims(0)=DodgeF DodgeAnims(1)=DodgeB DodgeAnims(2)=DodgeL DodgeAnims(3)=DodgeR WallDodgeAnims(0)=WallDodgeF WallDodgeAnims(1)=WallDodgeB WallDodgeAnims(2)=WallDodgeL WallDodgeAnims(3)=WallDodgeR TurnRightAnim=TurnR TurnLeftAnim=TurnL CrouchTurnRightAnim=Crouch_TurnR CrouchTurnLeftAnim=Crouch_TurnL IdleRestAnim=Idle_Rest IdleCrouchAnim=Crouch IdleSwimAnim=Swim_Tread IdleWeaponAnim=Idle_Rifle IdleHeavyAnim=Idle_Biggun IdleRifleAnim=Idle_Rifle IdleChatAnim=Idle_Chat FireHeavyRapidAnim=Biggun_Burst FireHeavyBurstAnim=Biggun_Aimed FireRifleRapidAnim=Rifle_Burst FireRifleBurstAnim=Rifle_Aimed MaxMultiJump=1 MultiJumpRemaining=1 MultiJumpBoost=25 RagdollLifeSpan=13 RagDeathVel=200 RagInvInertia=4 RagShootStrength=8000 RagSpinScale=2.5 RagDeathUpKick=150 RagGravScale=1.0 Begin Object Class=KarmaParamsSkel Name=PawnKParams KFriction=0.6 KRestitution=0.3 KAngularDamping=0.05 KLinearDamping=0.15 KBuoyancy=1 KStartEnabled=True KImpactThreshold=500 KVelDropBelowThreshold=50 KConvulseSpacing=(Min=0.5,Max=2.2) bHighDetailOnly=False Name="PawnKParams" End Object KParams=KarmaParams'PawnKParams' // ifndef _RO_ //RagImpactSounds(0)=sound'GeneralImpacts.Breakbone_01' //RagImpactSounds(1)=sound'GeneralImpacts.Breakbone_02' //RagImpactSounds(2)=sound'GeneralImpacts.Breakbone_03' RagImpactVolume=2.5 RagImpactSoundInterval=0.5 VoiceType="xGame.MercMaleVoice" RootBone="Bip01" HeadBone="Bip01 Head" SpineBone1="Bip01 Spine1" SpineBone2="Bip01 Spine2" FireRootBone="Bip01 Spine" // ifndef _RO_ //UDamageSound=Sound'GameSounds.UDamageFire' GruntVolume=0.18 FootstepVolume=0.15 DeResTime=6.0 // ifndef _RO_ //DeResMat0=FinalBlend'DeRez.DeRezFinalBody' //DeResMat1=FinalBlend'DeRez.DeRezFinalHead' DeResLiftVel=(Points=((InVal=0,OutVal=0),(InVal=2.5,OutVal=32),(InVal=100,OutVal=32))) DeResLiftSoftness=(Points=((InVal=0,OutVal=0.3),(InVal=2.5,OutVal=0.05),(InVal=100,OutVal=0.05))) DeResGravScale=0.0 DeResLateralFriction=0.3 // Temp commented out - Ramm TransOutEffect(0)=none//class'NewTransDeResRed' TransOutEffect(1)=none//class'NewTransDeResBlue' TransEffects(0)=none//class'NewTransEffect' TransEffects(1)=none//class'NewTransEffectBlue' PlacedCharacterName="Jakob" PlacedFemaleCharacterName="Tamika" MaxLights=8 bDramaticLighting=true bCanDodgeDoubleJump=true bCanWallDodge=true bNoCoronas=false // Temp commented out - Ramm Texture=none//Texture'RedMarker_t' }