//============================================================================= // KFProj_PinningBullet //============================================================================= // Base class for small arms projectiles that can pin zeds or zed body parts // to walls // Based loosely on UTProj_StingerShard Copyright 1998-2008 Epic Games, Inc. //============================================================================= // Killing Floor 2 // Copyright (C) 2015 Tripwire Interactive LLC // John "Ramm-Jaeger" Gibson //============================================================================= class KFProj_PinningBullet extends KFProj_RicochetBullet abstract; /** The constraint for this projectile pinning a ragdoll or ragdoll body part to a wall */ var RB_ConstraintActor PinConstraint; /** This is true if this projectile is currently pinning a victim */ var bool bPinned; /** Can only create a pin effect if we aren't already being used to pin a dead pawn */ var bool bSpawnedForPin; /** * This function creates the actual pin in the world. A duplicate pinning projectile is spawned * and that projectile is used to pin the pawn. We use a secondary actor in order to avoid * having to wait for replication to occur since this actor is spawned client-side */ static function bool CreatePin(KFPawn DeadPawn, vector InitialHitLocation, vector Direction, name HitBoneName) { local KFProj_PinningBullet PinProjectile; local vector BoneLoc; local class BulletClass; // Do nothing for now until this can be properly implemented return false; if ( DeadPawn != None && DeadPawn.WorldInfo.GRI.ShouldShowGore() && !DeadPawn.bDeleteMe && DeadPawn.Health <= 0 && DeadPawn.Physics == PHYS_RigidBody && DeadPawn.Mesh != None && DeadPawn.Mesh.PhysicsAssetInstance != None && HitBoneName != '') { // Spawn a pinning projectile BoneLoc = DeadPawn.Mesh.GetBoneLocation(HitBoneName); BulletClass = default.Class; PinProjectile = DeadPawn.Spawn(BulletClass,,, BoneLoc, rotator(Direction)); if (PinProjectile != None) { // Send the projectile moving PinProjectile.bSpawnedForPin = True; PinProjectile.Init(Direction); // Attach the victim to this projectile PinProjectile.PinVictim(DeadPawn,HitBoneName); return true; } } return false; } /** * This function is responsible for creating the constraint between the projectile * and the victim. */ simulated function PinVictim(KFPawn Victim, name VictimBone) { // give projectile extent so that it collides the same way the pawn does // (so we don't get the ragdoll stuck in a blocking volume, etc) bSwitchToZeroCollision = false; CylinderComponent.SetCylinderSize(1.0, 1.0); CylinderComponent.SetActorCollision(true, false); // Set the location of the projectile to the bone location to start with SetLocation(Victim.Mesh.GetBoneLocation(VictimBone)); // Spawn the constraint that pins the ragdoll to this projectile PinConstraint = Spawn(class'RB_ConstraintActorSpawnable',,,Location); PinConstraint.SetBase(self); PinConstraint.InitConstraint( self, Victim, '', VictimBone, 2000.f); PinConstraint.LifeSpan = 8.0; LifeSpan = 8.0; bPinned = true; }