//============================================================================= // KFWeldableComponent //============================================================================= // Actor that encapsulates the management and replication of welding info. // Enables any object to be weldable (used along with KFWeldableTrigger). //============================================================================= // Killing Floor 2 // Copyright (C) 2018 Tripwire Interactive LLC //============================================================================= class KFWeldableComponent extends Actor native; /** Amount of damage a welded door can take */ var int MaxWeldIntegrity; /** Current integrity of a welded door */ var repnotify transient int WeldIntegrity; /** Percent of repair complete from 0-255 */ var repnotify byte RepairProgress; /** Amount of "explosive" weld needed */ var int DemoWeldRequired; /** Current amount of "explosive" weld */ var transient int DemoWeld; /** True if the door has health less than 0 and is off its hinges */ var transient bool bIsDestroyed; var bool bWeldable, bUnweldable, bRepairable; delegate Delegate_AdjustWeldAmount(out int Amount); delegate Delegate_OnWeldIntegrityChanged(optional int Amount, optional KFPawn Welder); delegate Delegate_OnRepairProgressChanged(optional float Amount, optional KFPawn Welder); replication { if (bNetDirty && Role == ROLE_Authority) WeldIntegrity, DemoWeld, RepairProgress, bIsDestroyed; } cpptext { UBOOL IsOverlapping(AActor *Other, FCheckResult* Hit = NULL, UPrimitiveComponent* OtherPrimitiveComponent = NULL, UPrimitiveComponent* MyPrimitiveComponent = NULL); }; simulated event ReplicatedEvent(name VarName) { if (VarName == nameof(WeldIntegrity)) { if (Delegate_OnWeldIntegrityChanged != none) { Delegate_OnWeldIntegrityChanged(0, None); } } else if (VarName == nameof(RepairProgress)) { if (Delegate_OnRepairProgressChanged != none) { Delegate_OnRepairProgressChanged(0, None); } } else { super.ReplicatedEvent(VarName); } } function Weld(int Amount, optional KFPawn Welder) { local int OriginalAmount; local KFPerk WelderPerk; local bool bCanExplosiveWelded; if (Welder != none && Amount > 0) { WelderPerk = KFPlayerController(Welder.Controller).GetPerk(); if (WelderPerk != none && WelderPerk.CanExplosiveWeld()) { bCanExplosiveWelded = true; } } if ((Amount > 0 && !CanBeWelded() && !bCanExplosiveWelded) || (Amount < 0 && !CanBeUnwelded())) { return; } OriginalAmount = Amount; if (Delegate_AdjustWeldAmount != none) { Delegate_AdjustWeldAmount(Amount); } UpdateWeldIntegrity(Amount); if (Welder != none && Amount > 0) { if (bCanExplosiveWelded) { UpdateDemoWeld(Amount); } } if (Delegate_OnWeldIntegrityChanged != none) { Delegate_OnWeldIntegrityChanged(OriginalAmount, Welder); } } function UpdateWeldIntegrity(int Amount) { SetWeldIntegrity(WeldIntegrity + Amount); } function SetWeldIntegrity(int Amount) { WeldIntegrity = Clamp(Amount, 0, MaxWeldIntegrity); bForceNetUpdate = true; } function SetRepairProgress(int Amount) { RepairProgress = Clamp(Amount, 0, 255); bForceNetUpdate = true; } function UpdateDemoWeld(int Amount) { SetDemoWeld(DemoWeld + Amount); } function SetDemoWeld(int Amount) { DemoWeld = Clamp(Amount, 0, DemoWeldRequired); bForceNetUpdate = true; } function SetDestroyed(bool bDestroyed) { bIsDestroyed = bDestroyed; } /** Increase the weld integrity - Network: Server only */ function Repair(float Amount, optional KFPawn Welder) { local byte ByteAmount; if (!CanBeRepaired()) { return; } ByteAmount = FloatToByte(Amount); if (RepairProgress + ByteAmount >= 255) { RepairProgress = 255; } else { RepairProgress += ByteAmount; } bForceNetUpdate = true; if (Delegate_OnRepairProgressChanged != none) { Delegate_OnRepairProgressChanged(Amount, Welder); } } simulated function bool CanBeWelded() { return bWeldable && WeldIntegrity < MaxWeldIntegrity; } simulated function bool CanBeUnwelded() { return bUnweldable && WeldIntegrity > 0; } simulated function bool CanBeRepaired() { return bRepairable; } simulated function bool CanBeDemoWelded() { return DemoWeldRequired > 0 && DemoWeld < DemoWeldRequired; } simulated function float GetWeldPct() { return (float(WeldIntegrity) / float(MaxWeldIntegrity)) * 100.f; } simulated function SetCollisionCylinderSize(float Radius, float Height) { CylinderComponent(CollisionComponent).SetCylinderSize(Radius, Height); } simulated function float GetCollisionCylinderRadius() { return CylinderComponent(CollisionComponent).CollisionRadius; } simulated function float GetCollisionCylinderHeight() { return CylinderComponent(CollisionComponent).CollisionHeight; } defaultproperties { RemoteRole=ROLE_SimulatedProxy bAlwaysRelevant=true Begin Object Class=CylinderComponent NAME=CollisionCylinder CollideActors=true CollisionRadius=+00100.000000 CollisionHeight=+00200.000000 bAlwaysRenderIfSelected=true End Object CollisionComponent=CollisionCylinder Components.Add(CollisionCylinder) bHidden=true bCollideActors=true bProjTarget=false bStatic=false bNoDelete=false }