242 lines
6.9 KiB
Ucode
242 lines
6.9 KiB
Ucode
/**
|
|
* Copyright 1998-2013 Epic Games, Inc. All Rights Reserved.
|
|
*/
|
|
class KAsset extends Actor
|
|
native(Physics)
|
|
nativereplication
|
|
ClassGroup(Physics)
|
|
placeable;
|
|
|
|
var() const editconst SkeletalMeshComponent SkeletalMeshComponent;
|
|
|
|
var() bool bDamageAppliesImpulse;
|
|
var() bool bWakeOnLevelStart;
|
|
|
|
/** Whether this KAsset should block Pawns. */
|
|
var() bool bBlockPawns;
|
|
|
|
/** Used to replicate mesh to clients */
|
|
var repnotify transient SkeletalMesh ReplicatedMesh;
|
|
|
|
/** Used to replicate physics asset to clients */
|
|
var repnotify transient PhysicsAsset ReplicatedPhysAsset;
|
|
|
|
replication
|
|
{
|
|
if ( Role == ROLE_Authority)
|
|
ReplicatedMesh, ReplicatedPhysAsset;
|
|
}
|
|
|
|
cpptext
|
|
{
|
|
public:
|
|
// AActor interface.
|
|
virtual INT* GetOptimizedRepList(BYTE* InDefault, FPropertyRetirement* Retire, INT* Ptr, UPackageMap* Map, UActorChannel* Channel);
|
|
|
|
/**
|
|
* Function that gets called from within Map_Check to allow this actor to check itself
|
|
* for any potential errors and register them with map check dialog.
|
|
*/
|
|
#if WITH_EDITOR
|
|
virtual void CheckForErrors();
|
|
#endif
|
|
|
|
UBOOL ShouldTrace(UPrimitiveComponent* Primitive, AActor *SourceActor, DWORD TraceFlags);
|
|
UBOOL IgnoreBlockingBy(const AActor* Other) const;
|
|
}
|
|
|
|
simulated event PostBeginPlay()
|
|
{
|
|
Super.PostBeginPlay();
|
|
|
|
if (bWakeOnLevelStart)
|
|
{
|
|
SkeletalMeshComponent.WakeRigidBody();
|
|
}
|
|
ReplicatedMesh = SkeletalMeshComponent.SkeletalMesh;
|
|
ReplicatedPhysAsset = SkeletalMeshComponent.PhysicsAsset;
|
|
`if(`__TW_PERFORMANCE_)
|
|
// Added forceskel update to allow us to use bUpdateSkelWhenNotRendered
|
|
if ( !SkeletalMeshComponent.bUpdateSkelWhenNotRendered )
|
|
{
|
|
SkeletalMeshComponent.ForceSkelUpdate();
|
|
}
|
|
`endif
|
|
}
|
|
|
|
/** Sets the new mesh and physics asset, along with the replicated properties for clients. */
|
|
final function SetMeshAndPhysAsset(SkeletalMesh NewMesh, PhysicsAsset NewPhysAsset)
|
|
{
|
|
SkeletalMeshComponent.SetSkeletalMesh(NewMesh);
|
|
ReplicatedMesh = NewMesh;
|
|
SkeletalMeshComponent.SetPhysicsAsset(NewPhysAsset);
|
|
ReplicatedPhysAsset = NewPhysAsset;
|
|
}
|
|
|
|
simulated event ReplicatedEvent( name VarName )
|
|
{
|
|
if (VarName == 'ReplicatedMesh')
|
|
{
|
|
SkeletalMeshComponent.SetSkeletalMesh(ReplicatedMesh);
|
|
}
|
|
else if(VarName == 'ReplicatedPhysAsset')
|
|
{
|
|
SkeletalMeshComponent.SetPhysicsAsset(ReplicatedPhysAsset);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Default behaviour when shot is to apply an impulse and kick the KActor.
|
|
*/
|
|
simulated event TakeDamage(int Damage, Controller EventInstigator, vector HitLocation, vector Momentum, class<DamageType> DamageType, optional TraceHitInfo HitInfo, optional Actor DamageCauser)
|
|
{
|
|
local vector ApplyImpulse;
|
|
|
|
// call Actor's version to handle any SeqEvent_TakeDamage for scripting
|
|
Super.TakeDamage(Damage, EventInstigator, HitLocation, Momentum, DamageType, HitInfo, DamageCauser);
|
|
|
|
if ( bDamageAppliesImpulse && damageType.default.KDamageImpulse > 0 )
|
|
{
|
|
if ( VSize(momentum) < 0.001 )
|
|
{
|
|
`Log("Zero momentum to KActor.TakeDamage");
|
|
return;
|
|
}
|
|
|
|
// Make sure we have a valid TraceHitInfo with our SkeletalMesh
|
|
// we need a bone to apply proper impulse
|
|
CheckHitInfo( HitInfo, SkeletalMeshComponent, Normal(Momentum), hitlocation );
|
|
|
|
ApplyImpulse = Normal(momentum) * damageType.default.KDamageImpulse;
|
|
if ( HitInfo.HitComponent != None )
|
|
{
|
|
HitInfo.HitComponent.AddImpulse(ApplyImpulse, HitLocation, HitInfo.BoneName);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Take Radius Damage
|
|
*
|
|
* @param InstigatedBy, instigator of the damage
|
|
* @param Base Damage
|
|
* @param Damage Radius (from Origin)
|
|
* @param DamageType class
|
|
* @param Momentum (float)
|
|
* @param HurtOrigin, origin of the damage radius.
|
|
* @param DamageCauser the Actor that directly caused the damage (i.e. the Projectile that exploded, the Weapon that fired, etc)
|
|
*/
|
|
simulated function TakeRadiusDamage
|
|
(
|
|
Controller InstigatedBy,
|
|
float BaseDamage,
|
|
float DamageRadius,
|
|
class<DamageType> DamageType,
|
|
float Momentum,
|
|
vector HurtOrigin,
|
|
bool bFullDamage,
|
|
Actor DamageCauser,
|
|
optional float DamageFalloffExponent=1.f,
|
|
optional bool bAdjustRadiusDamage=true
|
|
)
|
|
{
|
|
if ( bDamageAppliesImpulse && damageType.default.RadialDamageImpulse > 0 && (Role == ROLE_Authority) )
|
|
{
|
|
CollisionComponent.AddRadialImpulse(HurtOrigin, DamageRadius, damageType.default.RadialDamageImpulse, RIF_Linear, damageType.default.bRadialDamageVelChange);
|
|
}
|
|
}
|
|
|
|
/** If this KAsset receives a Toggle ON event from Kismet, wake the physics up. */
|
|
simulated function OnToggle(SeqAct_Toggle action)
|
|
{
|
|
if(action.InputLinks[0].bHasImpulse)
|
|
{
|
|
SkeletalMeshComponent.WakeRigidBody();
|
|
}
|
|
}
|
|
|
|
simulated function OnTeleport(SeqAct_Teleport InAction)
|
|
{
|
|
local Actor DestActor;
|
|
|
|
DestActor = Actor(SeqVar_Object(InAction.VariableLinks[1].LinkedVariables[0]).GetObjectValue());
|
|
if (DestActor != None)
|
|
{
|
|
SkeletalMeshComponent.SetRBPosition(DestActor.Location);
|
|
}
|
|
else
|
|
{
|
|
InAction.ScriptLog("No Destination for" @ InAction @ "on" @ self);
|
|
}
|
|
}
|
|
|
|
|
|
/** Performs actual attachment. Can be subclassed for class specific behaviors. */
|
|
function DoKismetAttachment( Actor Attachment, SeqAct_AttachToActor Action )
|
|
{
|
|
Attachment.SetBase( Self,, SkeletalMeshComponent, Action.BoneName );
|
|
}
|
|
|
|
|
|
|
|
defaultproperties
|
|
{
|
|
TickGroup=TG_PostAsyncWork
|
|
|
|
Begin Object Class=DynamicLightEnvironmentComponent Name=MyLightEnvironment
|
|
End Object
|
|
`if(`__TW_LIGHTING_MODIFICATIONS_)
|
|
// Don't add to components list
|
|
`else
|
|
Components.Add(MyLightEnvironment)
|
|
`endif
|
|
|
|
Begin Object Class=SkeletalMeshComponent Name=KAssetSkelMeshComponent
|
|
CollideActors=true
|
|
BlockActors=true
|
|
BlockZeroExtent=true
|
|
BlockNonZeroExtent=false
|
|
BlockRigidBody=true
|
|
bHasPhysicsAssetInstance=true
|
|
bUpdateKinematicBonesFromAnimation=false
|
|
bUseTickOptimization=false
|
|
PhysicsWeight=1.0
|
|
RBChannel=RBCC_GameplayPhysics
|
|
RBCollideWithChannels=(Default=TRUE,BlockingVolume=TRUE,GameplayPhysics=TRUE,EffectPhysics=TRUE)
|
|
LightEnvironment=MyLightEnvironment
|
|
bSkipAllUpdateWhenPhysicsAsleep=TRUE
|
|
bBlockFootPlacement=false
|
|
End Object
|
|
CollisionComponent=KAssetSkelMeshComponent
|
|
SkeletalMeshComponent=KAssetSkelMeshComponent
|
|
Components.Add(KAssetSkelMeshComponent)
|
|
|
|
SupportedEvents.Add(class'SeqEvent_ConstraintBroken')
|
|
SupportedEvents.Add(class'SeqEvent_RigidBodyCollision')
|
|
|
|
bDamageAppliesImpulse=true
|
|
bNetInitialRotation=true
|
|
Physics=PHYS_RigidBody
|
|
bEdShouldSnap=true
|
|
bStatic=false
|
|
bCollideActors=true
|
|
bBlockActors=true
|
|
bWorldGeometry=false
|
|
bCollideWorld=false
|
|
bProjTarget=true
|
|
|
|
bNoDelete=true
|
|
bAlwaysRelevant=true
|
|
bSkipActorPropertyReplication=false
|
|
bUpdateSimulatedPosition=true
|
|
bReplicateMovement=true
|
|
`if(`__TW_NETWORKING_)
|
|
// SimProxy makes sense in KAssetSpawnable, but not in KAsset. TakeDamage is
|
|
// marked simulated and only applies local client damage impulses.
|
|
RemoteRole=ROLE_None
|
|
`else
|
|
RemoteRole=ROLE_SimulatedProxy
|
|
`endif
|
|
bReplicateRigidBodyLocation=FALSE
|
|
}
|