Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- class UEX_TestPawn extends UDKPawn;
- /** when we entered feign death; used to increase FeignDeathBodyAtRestSpeed over time so we get up in a reasonable amount of time */
- var float FeignDeathStartTime;
- /** When feign death recovery started. Used to pull feign death camera into body during recovery */
- var float FeignDeathRecoveryStartTime;
- /** anim node used for feign death recovery animations */
- var AnimNodeBlend FeignDeathBlend;
- var float FeignDeathBodyAtRestSpeed; /** when a body in feign death's velocity is less than this, it is considered to be at rest (allowing the player to get up) */
- var name HeadBone;
- /** Set when pawn died on listen server, but was hidden rather than ragdolling (for replication purposes) */
- var bool bHideOnListenServer;
- /** bones to set fixed when doing the physics take hit effects */
- var array<name> TakeHitPhysicsFixedBones;
- /** Array of bodies that should not have joint drive applied. */
- var array<name> NoDriveBodies;
- /** Slot node used for playing full body anims. */
- var AnimNodeSlot FullBodyAnimSlot;
- /** Slot node used for playing animations only on the top half. */
- var AnimNodeSlot TopHalfAnimSlot;
- var(DeathAnim) float DeathHipLinSpring;
- var(DeathAnim) float DeathHipLinDamp;
- var(DeathAnim) float DeathHipAngSpring;
- var(DeathAnim) float DeathHipAngDamp;
- var float RagdollLifespan;
- /** World time that we started the death animation */
- var float StartDeathAnimTime;
- /** Time that we took damage of type DeathAnimDamageType. */
- var float TimeLastTookDeathAnimDamage;
- /** count of failed unfeign attempts - kill pawn if too many */
- var int UnfeignFailedCount;
- /** true when feign death activation forced (e.g. knocked off hoverboard) */
- var bool bForcedFeignDeath;
- simulated event ReplicatedEvent(name VarName)
- {
- if (VarName == 'bFeigningDeath')
- {
- `Log(self@"REPLICATED"@VarName@bFeigningDeath);
- PlayFeignDeath();
- }
- else
- {
- Super.ReplicatedEvent(VarName);
- }
- }
- reliable server function ServerFeignDeath()
- {
- if (Role == ROLE_Authority && !WorldInfo.Game.IsInState('MatchOver') && DrivenVehicle == None && Controller != None && !bFeigningDeath)
- {
- bFeigningDeath = true;
- PlayFeignDeath();
- }
- }
- exec simulated function FeignDeath()
- {
- ServerFeignDeath();
- }
- simulated function PlayFeignDeath(optional bool Permanent)
- {
- if (bFeigningDeath){
- PlayPhys(Permanent);
- }
- else
- PlayGetUp();
- }
- simulated event PostInitAnimTree(SkeletalMeshComponent SkelComp)
- {
- if (SkelComp == Mesh)
- {
- FeignDeathBlend = AnimNodeBlend(Mesh.FindAnimNode('FeignDeathBlend'));
- }
- `Log(self@"SkelComp="@SkelComp@"Mesh="@Mesh@"FeignDeathBlend="@FeignDeathBlend);
- if (Role == Role_Authority && Controller == None)
- {
- bFeigningDeath=TRUE;
- SetTimer(1.0, false, 'PlayFeignDeath');
- }
- }
- simulated function PlayPhys(optional bool Permanent)
- {
- `Log(Self@"PlayPhys");
- StartFallImpactTime = WorldInfo.TimeSeconds;
- bCanPlayFallingImpacts=true;
- GotoState('FeigningDeath');
- // if we had some other rigid body thing going on, cancel it
- if (Physics == PHYS_RigidBody)
- {
- //@note: Falling instead of None so Velocity/Acceleration don't get cleared
- setPhysics(PHYS_Falling);
- }
- // Ensure we are always updating kinematic
- Mesh.MinDistFactorForKinematicUpdate = 0.0;
- SetPawnRBChannels(TRUE);
- Mesh.ForceSkelUpdate();
- // Move into post so that we are hitting physics from last frame, rather than animated from this
- Mesh.SetTickGroup(TG_PostAsyncWork);
- bBlendOutTakeHitPhysics = false;
- PreRagdollCollisionComponent = CollisionComponent;
- CollisionComponent = Mesh;
- // Turn collision on for skelmeshcomp and off for cylinder
- CylinderComponent.SetActorCollision(false, false);
- Mesh.SetActorCollision(true, true);
- Mesh.SetTraceBlocking(true, true);
- SetPhysics(PHYS_RigidBody);
- Mesh.PhysicsWeight = 1.0;
- // If we had stopped updating kinematic bodies on this character due to distance from camera, force an update of bones now.
- if( Mesh.bNotUpdatingKinematicDueToDistance )
- {
- Mesh.UpdateRBBonesFromSpaceBases(TRUE, TRUE);
- }
- Mesh.PhysicsAssetInstance.SetAllBodiesFixed(FALSE);
- Mesh.bUpdateKinematicBonesFromAnimation=FALSE;
- // Set all kinematic bodies to the current root velocity, since they may not have been updated during normal animation
- // and therefore have zero derived velocity (this happens in 1st person camera mode).
- Mesh.SetRBLinearVelocity(Velocity, false);
- FeignDeathStartTime = WorldInfo.TimeSeconds;
- // reset mesh translation since adjustment code isn't executed on the server
- // but the ragdoll code uses the translation so we need them to match up for the
- // most accurate simulation
- Mesh.SetTranslation(vect(0,0,1) * BaseTranslationOffset);
- // we'll use the rigid body collision to check for falling damage
- Mesh.ScriptRigidBodyCollisionThreshold = MaxFallSpeed;
- Mesh.SetNotifyRigidBodyCollision(true);
- Mesh.WakeRigidBody();
- if (Role == ROLE_Authority)
- {
- SetTimer(0.15, true, 'FeignDeathDelayTimer');
- }
- }
- state FeigningDeath
- {
- ignores FaceRotation, SetMovementPhysics;
- exec simulated function FeignDeath()
- {
- if (bFeigningDeath)
- {
- Global.FeignDeath();
- }
- }
- reliable server function ServerFeignDeath()
- {
- if (Role == ROLE_Authority && !WorldInfo.GRI.bMatchIsOver && !IsTimerActive('FeignDeathDelayTimer') && bFeigningDeath)
- {
- bFeigningDeath = false;
- PlayFeignDeath();
- }
- }
- event bool EncroachingOn(Actor Other)
- {
- // don't abort moves in ragdoll
- return false;
- }
- simulated function bool CanThrowWeapon()
- {
- return false;
- }
- simulated function Tick(float DeltaTime)
- {
- local rotator NewRotation;
- if (bPlayingFeignDeathRecovery && PlayerController(Controller) != None)
- {
- // interpolate Controller yaw to our yaw so that we don't get our rotation snapped around when we get out of feign death
- NewRotation = Controller.Rotation;
- NewRotation.Yaw = RInterpTo(NewRotation, Rotation, DeltaTime, 2.0).Yaw;
- Controller.SetRotation(NewRotation);
- }
- }
- simulated event OnAnimEnd(AnimNodeSequence SeqNode, float PlayedTime, float ExcessTime)
- {
- if (Physics != PHYS_RigidBody && !bPlayingFeignDeathRecovery)
- {
- // blend out of feign death animation
- if (FeignDeathBlend != None)
- {
- FeignDeathBlend.SetBlendTarget(0.0, 0.5);
- }
- GotoState('Auto');
- }
- }
- simulated event BeginState(name PreviousStateName)
- {
- }
- simulated function EndState(name NextStateName)
- {
- local Actor A;
- if (NextStateName != 'Dying')
- {
- bNoWeaponFiring = default.bNoWeaponFiring;
- bCanPickupInventory = default.bCanPickupInventory;
- Global.SetMovementPhysics();
- bForcedFeignDeath = false;
- bPlayingFeignDeathRecovery = false;
- }
- }
- }
- // prevents player from getting out of feign death until the body has come to rest
- function FeignDeathDelayTimer()
- {
- if (Role != Role_Authority)
- return;
- //WorldInfo.Game.Broadcast(self,self@" FeignDeathDelayTimer ");
- if ( /*Controller != none && */
- (WorldInfo.TimeSeconds - FeignDeathStartTime > 1.0) &&
- (PhysicsVolume.bWaterVolume || (VSize(Velocity) < 4.0 * FeignDeathBodyAtRestSpeed * (WorldInfo.TimeSeconds - FeignDeathStartTime))) )
- {
- // clear timer, so we can come out of feign death
- //ClearTimer('FeignDeathDelayTimer');
- // automatically get up if we were forced into it
- ClearTimer('FeignDeathDelayTimer');
- PlayGetUp();
- }
- }
- simulated function PlayGetUp()
- {
- local vector FeignLocation, HitLocation, HitNormal, TraceEnd, Impulse;
- local rotator NewRotation;
- //local UTWeapon UTWeap;
- local Vehicle V;
- local Controller Killer;
- local float UnFeignZAdjust;
- `Log(self@"PlayGetUp"@PreRagdollCollisionComponent);
- bFeigningDeath=FALSE;
- // fit cylinder collision into location, crouching if necessary
- FeignLocation = Location;
- CollisionComponent = PreRagdollCollisionComponent;
- TraceEnd = Location + vect(0,0,1) * GetCollisionHeight();
- if (Trace(HitLocation, HitNormal, TraceEnd, Location, true, GetCollisionExtent()) == None )
- {
- HitLocation = TraceEnd;
- }
- if ( !SetFeignEndLocation(HitLocation, FeignLocation) )
- {
- CollisionComponent = Mesh;
- SetLocation(FeignLocation);
- bFeigningDeath = true;
- Impulse = VRand();
- Impulse.Z = 0.5;
- Mesh.AddImpulse(800.0*Impulse, Location);
- UnfeignFailedCount++;
- if ( UnFeignfailedCount > 4 )
- {
- Suicide();
- }
- return;
- }
- // Calculate how far we just moved the actor up.
- UnFeignZAdjust = Location.Z - FeignLocation.Z;
- // If its positive, move back down by that amount until it hits the floor
- if(UnFeignZAdjust > 0.0)
- {
- moveSmooth(vect(0,0,-1) * UnFeignZAdjust);
- }
- UnfeignFailedCount = 0;
- CollisionComponent = Mesh;
- bPlayingFeignDeathRecovery = true;
- FeignDeathRecoveryStartTime = WorldInfo.TimeSeconds;
- // don't need collision events anymore
- Mesh.SetNotifyRigidBodyCollision(false);
- // don't allow player to move while animation is in progress
- SetPhysics(PHYS_None);
- `Log(self@"FeignDeathBlend="@FeignDeathBlend);
- // find getup animation, and freeze it at the first frame
- if ( (FeignDeathBlend != None) && !bIsCrouched )
- {
- // physics weight interpolated to 0 in C++, then StartFeignDeathRecoveryAnim() is called
- Mesh.PhysicsWeight = 1.0;
- FeignDeathBlend.SetBlendTarget(1.0, 0.0);
- StartFeignDeathRecoveryAnim();
- // force rotation to match the body's direction so the blend to the getup animation looks more natural
- NewRotation = Rotation;
- NewRotation.Yaw = rotator(Mesh.GetBoneAxis('b_Hips', AXIS_X)).Yaw;
- // flip it around if the head is facing upwards, since the animation for that makes the character
- // end up facing in the opposite direction that its body is pointing on the ground
- // FIXME: generalize this somehow (stick it in the AnimNode, I guess...)
- if (Mesh.GetBoneAxis(HeadBone, AXIS_Y).Z < 0.0)
- {
- NewRotation.Yaw += 32768;
- }
- SetRotation(NewRotation);
- }
- else
- {
- // failed to find recovery node, so just pop out of ragdoll
- RestorePreRagdollCollisionComponent();
- Mesh.PhysicsWeight = 0.f;
- Mesh.PhysicsAssetInstance.SetAllBodiesFixed(TRUE);
- Mesh.bUpdateKinematicBonesFromAnimation=TRUE;
- Mesh.MinDistFactorForKinematicUpdate = default.Mesh.MinDistFactorForKinematicUpdate;
- SetPawnRBChannels(FALSE);
- if (Physics == PHYS_RigidBody)
- {
- setPhysics(PHYS_Falling);
- }
- GotoState('Auto');
- }
- }
- //Установки, чтоб не проваливаться сквозь геометрию
- simulated function SetPawnRBChannels(bool bRagdollMode)
- {
- if(bRagdollMode)
- {
- Mesh.SetRBChannel(RBCC_Pawn);
- Mesh.SetRBCollidesWithChannel(RBCC_Default,TRUE);
- Mesh.SetRBCollidesWithChannel(RBCC_Pawn,false);
- Mesh.SetRBCollidesWithChannel(RBCC_Vehicle,TRUE);
- Mesh.SetRBCollidesWithChannel(RBCC_Untitled3,FALSE);
- Mesh.SetRBCollidesWithChannel(RBCC_BlockingVolume,TRUE);
- }
- else
- {
- Mesh.SetRBChannel(RBCC_Untitled3);
- Mesh.SetRBCollidesWithChannel(RBCC_Default,FALSE);
- Mesh.SetRBCollidesWithChannel(RBCC_Pawn,FALSE);
- Mesh.SetRBCollidesWithChannel(RBCC_Vehicle,FALSE);
- Mesh.SetRBCollidesWithChannel(RBCC_Untitled3,TRUE);
- Mesh.SetRBCollidesWithChannel(RBCC_BlockingVolume,FALSE);
- }
- }
- simulated function bool SetFeignEndLocation(vector HitLocation, vector FeignLocation)
- {
- local vector NewDest;
- if ( SetLocation(HitLocation) && CheckValidLocation(FeignLocation) )
- {
- return true;
- }
- // try crouching
- ForceCrouch();
- if ( SetLocation(HitLocation) && CheckValidLocation(FeignLocation) )
- {
- return true;
- }
- newdest = HitLocation + GetCollisionRadius() * vect(1,1,0);
- if ( SetLocation(newdest) && CheckValidLocation(FeignLocation) )
- return true;
- newdest = HitLocation + GetCollisionRadius() * vect(1,-1,0);
- if ( SetLocation(newdest) && CheckValidLocation(FeignLocation) )
- return true;
- newdest = HitLocation + GetCollisionRadius() * vect(-1,1,0);
- if ( SetLocation(newdest) && CheckValidLocation(FeignLocation) )
- return true;
- newdest = HitLocation + GetCollisionRadius() * vect(-1,-1,0);
- if ( SetLocation(newdest) && CheckValidLocation(FeignLocation) )
- return true;
- return false;
- }
- /**
- * Make sure location pawn ended up at out of feign death is valid (not through a wall)
- */
- simulated function bool CheckValidLocation(vector FeignLocation)
- {
- local vector HitLocation, HitNormal, DestFinalZ;
- // try trace down to dest
- if (Trace(HitLocation, HitNormal, Location, FeignLocation, false, vect(10,10,10),, TRACEFLAG_Bullet) == None)
- {
- return true;
- }
- // try trace straight up, then sideways to final location
- DestFinalZ = FeignLocation;
- FeignLocation.Z = Location.Z;
- if ( Trace(HitLocation, HitNormal, DestFinalZ, FeignLocation, false, vect(10,10,10)) == None &&
- Trace(HitLocation, HitNormal, Location, DestFinalZ, false, vect(10,10,10),, TRACEFLAG_Bullet) == None )
- {
- return true;
- }
- return false;
- }
- /** called when bPlayingFeignDeathRecovery and interpolating our Mesh's PhysicsWeight to 0 has completed
- * starts the recovery anim playing
- */
- simulated event StartFeignDeathRecoveryAnim()
- {
- // we're done with the ragdoll, so get rid of it
- RestorePreRagdollCollisionComponent();
- Mesh.PhysicsWeight = 0.f;
- Mesh.MinDistFactorForKinematicUpdate = default.Mesh.MinDistFactorForKinematicUpdate;
- Mesh.PhysicsAssetInstance.SetAllBodiesFixed(TRUE);
- Mesh.PhysicsAssetInstance.SetFullAnimWeightBonesFixed(FALSE, Mesh);
- SetPawnRBChannels(FALSE);
- Mesh.bUpdateKinematicBonesFromAnimation=TRUE;
- // Turn collision on for cylinder and off for skelmeshcomp
- CylinderComponent.SetActorCollision(true, true);
- Mesh.SetActorCollision(false, false);
- Mesh.SetTraceBlocking(false, false);
- Mesh.SetTickGroup(TG_PreAsyncWork);
- if (Physics == PHYS_RigidBody)
- {
- setPhysics(PHYS_Falling);
- }
- if (FeignDeathBlend != None && FeignDeathBlend.Children[1].Anim != None)
- {
- FeignDeathBlend.Children[1].Anim.PlayAnim(false, 1.1);
- }
- else
- {
- // failed to find recovery node, so just pop out of ragdoll
- bNoWeaponFiring = default.bNoWeaponFiring;
- GotoState('Auto');
- }
- }
- defaultproperties
- {
- Begin Object Class=SkeletalMeshComponent Name=PawnMesh
- SkeletalMesh = SkeletalMesh'CH_IronGuard_Male.Mesh.SK_CH_IronGuard_MaleA'
- AnimTreeTemplate=AnimTree'CH_AnimHuman_Tree.AT_CH_Human'
- AnimSets(0) = AnimSet'CH_AnimHuman.Anims.K_AnimHuman_BaseMale'
- PhysicsAsset = PhysicsAsset'CH_AnimCorrupt.Mesh.SK_CH_Corrupt_Male_Physics'
- bHasPhysicsAssetInstance=TRUE
- bCacheAnimSequenceNodes=false
- AlwaysLoadOnClient=TRUE
- AlwaysLoadOnServer=TRUE
- bOwnerNoSee=false
- CastShadow=true
- bUpdateSkelWhenNotRendered=true
- bIgnoreControllersWhenNotRendered=false
- bUpdateKinematicBonesFromAnimation=TRUE
- bCastDynamicShadow=TRUE
- BlockNonZeroExtent=true
- BlockZeroExtent=true
- BlockActors=true
- CollideActors=true
- BlockRigidBody=true
- AlwaysCheckCollision=true
- //bIgnoreEncroachers=true
- RBChannel=RBCC_Pawn
- RBCollideWithChannels=(Pawn=TRUE, Default=TRUE,GameplayPhysics=TRUE,EffectPhysics=TRUE,Cloth=FALSE)
- bOverrideAttachmentOwnerVisibility=TRUE
- bAcceptsDynamicDecals=TRUE
- TickGroup=TG_PreAsyncWork
- MinDistFactorForKinematicUpdate=0.2
- bChartDistanceFactor=TRUE
- //bSkipAllUpdateWhenPhysicsAsleep=TRUE
- RBDominanceGroup=20
- Scale=1
- //MotionBlurScale=0.0
- bAllowAmbientOcclusion=TRUE
- // Nice lighting for hair
- bUseOnePassLightingOnTranslucency=TRUE
- bPerBoneMotionBlur=TRUE
- End Object
- Mesh=PawnMesh
- Components.Add(PawnMesh)
- HeadBone=b_Head
- FeignDeathBodyAtRestSpeed=12.0
- AlwaysRelevantDistanceSquared=+1960000.0
- bPhysRigidBodyOutOfWorldCheck=TRUE
- bRunPhysicsWithNoController=true
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement