254 lines
6.6 KiB
Ucode
254 lines
6.6 KiB
Ucode
/*
|
|
--------------------------------------------------------------
|
|
KF_StoryNPC_Static
|
|
--------------------------------------------------------------
|
|
|
|
Repairable breaker box NPC for use in Objective missions.
|
|
Has support for different visual damage states.
|
|
|
|
Author : Alex Quick
|
|
|
|
--------------------------------------------------------------
|
|
*/
|
|
|
|
|
|
class KF_BreakerBoxNPC extends KF_StoryNPC_Static;
|
|
|
|
var float LastTriggerEventTime;
|
|
|
|
var Material BrokenMat,FixedMat;
|
|
|
|
var () bool bWeldable;
|
|
|
|
var(Events) name Event_FullHealth,Event_NoHealth;
|
|
|
|
var bool bRepaired,SavedbFullhealth,bDestroyed,SavedbNoHealth;
|
|
|
|
var(Display) StaticMesh HealthyMesh,DestroyedMesh;
|
|
|
|
var class<Emitter> HitEmitter;
|
|
|
|
replication
|
|
{
|
|
reliable if(Role == Role_Authority && bNetDirty)
|
|
bRepaired;
|
|
}
|
|
|
|
|
|
function Reset()
|
|
{
|
|
Super.Reset();
|
|
if(bCheckPointed)
|
|
{
|
|
bRepaired = SavedbFullHealth;
|
|
bDestroyed = SavedbNoHealth;
|
|
}
|
|
|
|
CheckHealthCondition(self);
|
|
}
|
|
|
|
simulated function PostBeginPlay()
|
|
{
|
|
Super.PostbeginPlay();
|
|
|
|
CheckHealthCondition(self);
|
|
bHidden = true; // breaker boxes start out hidden and non-interactable.
|
|
SetCollision(false,false);
|
|
}
|
|
|
|
function SetActive(bool On)
|
|
{
|
|
Super.SetActive(On);
|
|
|
|
if(bActive)
|
|
{
|
|
bHidden = false;
|
|
SetCollision(true,true);
|
|
}
|
|
}
|
|
|
|
simulated function Tick(float DeltaTime)
|
|
{
|
|
Super.Tick(DeltaTime);
|
|
|
|
if(!bDestroyed && Level.TimeSeconds -LastTriggerEventTime > 1.0)
|
|
{
|
|
LastTriggerEventTime = Level.TimeSeconds;
|
|
TriggerEvent('IncrementPower',self,self);
|
|
}
|
|
}
|
|
|
|
function TakeDamage( int Damage, Pawn InstigatedBy, Vector Hitlocation, Vector Momentum, class<DamageType> damageType, optional int HitIndex)
|
|
{
|
|
local bool bHealed;
|
|
|
|
if ( bWeldable && damageType == class 'DamTypeWelder' )
|
|
{
|
|
Health = Min(Health + Damage, NPCHealth);
|
|
bHealed = true;
|
|
}
|
|
|
|
CheckHealthCondition(InstigatedBy);
|
|
|
|
if(bHealed)
|
|
{
|
|
return; // can skip the rest of the takedamage stuff.
|
|
}
|
|
|
|
Super.TakeDamage(Damage,InstigatedBy,HitLocation,Momentum,damageType,HitIndex);
|
|
|
|
CheckhealthCondition(InstigatedBy);
|
|
}
|
|
|
|
|
|
simulated function CheckHealthCondition(Pawn InstigatedBy)
|
|
{
|
|
if(!bRepaired && Health >= NPCHealth)
|
|
{
|
|
bRepaired = true;
|
|
bDestroyed = false;
|
|
|
|
TriggerEvent(Event_FullHealth,self,InstigatedBy);
|
|
|
|
if(HealthyMesh != none)
|
|
{
|
|
SetStaticMesh(HealthyMesh);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(!bDestroyed && Health <= 0 )
|
|
{
|
|
bDestroyed = true;
|
|
bRepaired = false;
|
|
|
|
TriggerEvent(Event_NoHealth,self,InstigatedBy);
|
|
|
|
if(DestroyedMesh != none)
|
|
{
|
|
SetStaticMesh(DestroyedMesh);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Draw additional icons for Breaker boxes */
|
|
|
|
simulated event PostRender2D(Canvas C, float ScreenLocX, float ScreenLocY) // called if bScriptPostRender is true, overrides native team beacon drawing code
|
|
{
|
|
local PlayerController PC;
|
|
local float Opacity;
|
|
// local float Dist;
|
|
local HUDKillingFloor KFHUD;
|
|
local float IconSize;
|
|
local float XCentre,YCentre;
|
|
local vector ScreenPos;
|
|
local float HealthPct;
|
|
local Material RenderMat;
|
|
local vector CameraLocation,CamDir;
|
|
local rotator CameraRotation;
|
|
|
|
if(!bShowHealthBar ||
|
|
!bActive ||
|
|
GetStateName() == 'Dying' )
|
|
{
|
|
return;
|
|
}
|
|
|
|
IconSize = 64.f * (C.SizeX/1920.f);
|
|
|
|
PC = Level.GetLocalPlayerController();
|
|
if ( PC != None )
|
|
{
|
|
KFHUD = HUDKillingFloor(PC.myHUD);
|
|
if(KFHUD != none)
|
|
{
|
|
C.GetCameraLocation(CameraLocation, CameraRotation);
|
|
CamDir = vector(CameraRotation);
|
|
|
|
/* Dont render stuff behind the camera */
|
|
if ( (Normal(Location - CameraLocation) dot vector(CameraRotation)) < 0 )
|
|
{
|
|
return;
|
|
}
|
|
|
|
if(bRepaired)
|
|
{
|
|
RenderMat = FixedMat ;
|
|
}
|
|
else
|
|
{
|
|
RenderMat = BrokenMat;
|
|
}
|
|
|
|
ScreenPos = C.WorldToScreen(Location);
|
|
XCentre = ScreenPos.X;
|
|
YCentre = ScreenPos.Y;
|
|
|
|
Opacity = FClamp(1.f - (VSize(PC.CalcViewLocation - Location) / 3000.f),0.4f,1.f) ;
|
|
HealthPct = FClamp(float(Health) / NPCHealth,0.f,1.f);
|
|
|
|
C.DrawColor.R = Lerp(HealthPct,255,0);
|
|
C.DrawColor.G = Lerp(HealthPct,0,255);
|
|
C.DrawColor.B = 50;
|
|
C.DrawColor.A = Opacity * 255;
|
|
|
|
C.SetPos(XCentre - (0.5 * IconSize) + 1.0, YCentre - (0.5 * IconSize) + 1.0);
|
|
C.DrawTileScaled(RenderMat, IconSize/ RenderMat.MaterialVSize() ,IconSize/ RenderMat.MaterialVSize() );
|
|
}
|
|
}
|
|
}
|
|
|
|
// Breaker boxes should never spawn gibs even if it looks cool
|
|
simulated function SpawnGibs(Rotator HitRotation, float ChunkPerterbation)
|
|
{}
|
|
|
|
// Replace the damage type hit emitter with a custom one
|
|
function SpawnHitEmitter( float Damage, Pawn InstigatedBy, vector HitLocation, class<DamageType> damageType, vector Momentum )
|
|
{
|
|
local Vector HitNormal;
|
|
|
|
// Play any set effect
|
|
if ( EffectIsRelevant(Location,true) )
|
|
{
|
|
if (HitEmitter != None)
|
|
{
|
|
if( InstigatedBy != none )
|
|
HitNormal = Normal((InstigatedBy.Location+(vect(0,0,1)*InstigatedBy.EyeHeight))-HitLocation);
|
|
|
|
Spawn(HitEmitter,,,HitLocation+HitNormal + (-HitNormal * CollisionRadius), Rotator(HitNormal));
|
|
}
|
|
}
|
|
}
|
|
|
|
defaultproperties
|
|
{
|
|
NotThreateningTo(0)= class 'ZombieFleshPound'
|
|
NotThreateningTo(1)= class 'ZombieScrake'
|
|
|
|
DrawScale = 0.5
|
|
Skins(0) = none
|
|
|
|
FixedMat = Texture 'KFStoryGame_Tex.HUD.Electricity_Icon_64'
|
|
BrokenMat = Texture 'KFStoryGame_Tex.HUD.Repair_Icon_64_BW'
|
|
StaticMesh = StaticMesh'Props_ObjectiveMode.Breaker_Box'
|
|
DestroyedMesh = StaticMesh 'Props_ObjectiveMode.Breaker_Box_DMG'
|
|
HealthyMesh = StaticMesh'Props_ObjectiveMode.Breaker_Box'
|
|
|
|
BaseAIThreatRating = 0.010000
|
|
FriendlyFireDamageScale = 0
|
|
NPCHealth = 200.000000
|
|
NPCName = "Breaker Box"
|
|
StartingHealthPct = 0
|
|
bStartActive = false
|
|
bShowHealthBar = true
|
|
bIndestructible = true
|
|
bWeldable = true
|
|
|
|
HitEmitter=class 'kfmod.Breaker_Damaged_OneOff'
|
|
ProjectileBloodSplatClass=none
|
|
|
|
CollisionRadius=30
|
|
PrePivot=(X=0,Y=0,Z=30)
|
|
}
|