rott/kf_sources/ScrnBalanceSrv/Classes/ScrnCrossbuzzsawBlade.uc
2026-07-14 20:27:09 +07:00

219 lines
6.6 KiB
Ucode

class ScrnCrossbuzzsawBlade extends CrossbuzzsawBlade;
var Actor ImpactActorFixed; // original ImpactActor isn't replicated corectly
var float ShutMeUpTime;
replication
{
reliable if ( Role==ROLE_Authority )
ImpactActorFixed;
}
simulated function PostBeginPlay()
{
super.PostBeginPlay();
ShutMeUpTime += Level.TimeSeconds;
}
simulated function PostNetReceive()
{
if ( Role < ROLE_Authority ){
if ( bHidden )
Destroy();
else if( ImpactActorFixed!=None && Base != ImpactActorFixed )
GoToState('OnWall');
}
}
// destroy an actor and make sure it will be destroyed on clients too
simulated function ReplicatedDestroy()
{
if ( Level.NetMode == NM_Client || Level.NetMode == NM_StandAlone ) {
Destroy();
}
else {
bHidden = true;
SetCollision(false, false);
SetPhysics(PHYS_None);
Velocity = vect(0,0,0);
Speed = 0;
NetUpdateTime = Level.TimeSeconds - 1;
SetTimer(1.0, false);
}
}
function Timer()
{
Destroy();
}
simulated function Tick( float Delta )
{
super.Tick(Delta);
if ( AmbientSound != None && ShutMeUpTime > Level.TimeSeconds )
AmbientSound = None; // make sure I'll shutup
}
// overrided to change calss to ReplicatedDestroy()
simulated state OnWall
{
Ignores HitWall;
simulated function BeginState()
{
bCollideWorld = False;
AmbientSound = None;
if( Trail!=None )
Trail.mRegen = False;
if( Corona != none )
{
Corona.Kill();
}
SetCollisionSize(75,50);
UV2Texture=FadeColor'PatchTex.Common.PickupOverlay';
NetUpdateFrequency = 2.0;
}
function ProcessTouch (Actor Other, vector HitLocation)
{
local Inventory inv;
if( !bHidden && Pawn(Other)!=None && Pawn(Other).Inventory!=None )
{
for( inv=Pawn(Other).Inventory; inv!=None; inv=inv.Inventory )
{
if( Crossbuzzsaw(Inv)!=None && Weapon(inv).AmmoAmount(0)<Weapon(inv).MaxAmmo(0) )
{
KFweapon(Inv).AddAmmo(1,0) ;
PlaySound(Sound'KF_InventorySnd.Ammo_GenericPickup', SLOT_Pain,2*TransientSoundVolume,,400);
if( PlayerController(Instigator.Controller)!=none )
{
PlayerController(Instigator.Controller).ReceiveLocalizedMessage(class'KFmod.ProjectilePickupMessage',1);
}
ReplicatedDestroy();
}
}
}
}
simulated function Tick( float Delta )
{
if( Base==None )
ReplicatedDestroy();
}
}
simulated function ProcessTouch (Actor Other, vector HitLocation)
{
local vector X;
local Vector TempHitLocation, HitNormal;
local array<int> HitPoints;
local KFPawn HitPawn;
local bool bHitWhipAttachment;
local Pawn P;
if ( bHidden || Other == none || Other == Instigator || Other.Base == Instigator || !Other.bBlockHitPointTraces || Other==IgnoreImpactPawn ||
(IgnoreImpactPawn != none && Other.Base == IgnoreImpactPawn) )
return;
X = Vector(Rotation);
if( ROBulletWhipAttachment(Other) != none )
{
bHitWhipAttachment=true;
if(!Other.Base.bDeleteMe)
{
Other = Instigator.HitPointTrace(TempHitLocation, HitNormal, HitLocation + (65535 * X), HitPoints, HitLocation,, 1);
if( Other == none || HitPoints.Length == 0 )
return;
HitPawn = KFPawn(Other);
if (Role == ROLE_Authority)
{
if ( HitPawn != none )
{
// Hit detection debugging
/*log("Bullet hit "$HitPawn.PlayerReplicationInfo.PlayerName);
HitPawn.HitStart = HitLocation;
HitPawn.HitEnd = HitLocation + (65535 * X);*/
if( !HitPawn.bDeleteMe )
HitPawn.ProcessLocationalDamage(Damage, Instigator, TempHitLocation, MomentumTransfer * X, MyDamageType,HitPoints);
Damage *= 0.80;
Velocity *= 0.85;
IgnoreImpactPawn = HitPawn;
if( Level.NetMode!=NM_Client )
PlayhitNoise(Pawn(Other)!=none && Pawn(Other).ShieldStrength>0);
}
}
}
return;
}
if ( Pawn(Other)!=None && Vehicle(Other)==None )
P = Pawn(Other);
else if ( ExtendedZCollision(Other)!=None && Pawn(Other.Owner)!=None )
P = Pawn(Other.Owner);
if( Level.NetMode!=NM_Client )
PlayhitNoise(P != none && P.ShieldStrength>0 );
if( P != none ) {
IgnoreImpactPawn = P;
if( P.IsHeadShot(HitLocation, X, 1.0) )
P.TakeDamage(Damage * HeadShotDamageMult, Instigator, HitLocation, MomentumTransfer * X, DamageTypeHeadShot);
else
P.TakeDamage(Damage, Instigator, HitLocation, MomentumTransfer * X, MyDamageType);
// If blade kills pawn, decatipates it or it was already decapitated,
// then apply lower damage and speed reduction
// -- PooSH
if ( Physics==PHYS_Projectile && (P == none || P.Health <= 0 || (KFMonster(P) != none && KFMonster(P).bDecapitated)) ) {
Damage *= 0.85; // vanilla = 0.8
Velocity *= 0.9; // vanilla = 0.85
}
else {
Damage *= 0.60; // vanilla = 0.8
Velocity *= 0.75; // vanilla = 0.85
if ( Damage < default.Damage * 0.50 ) {
if ( Bounces > 0 )
Bounces--; // lower amount of bounces, if blade hit many zeds already
if ( Role == ROLE_Authority && Bounces == 0 && Damage < default.Damage * 0.20 )
ReplicatedDestroy();
}
}
}
else {
Other.TakeDamage(Damage, Instigator, HitLocation, MomentumTransfer * X, MyDamageType);
}
}
simulated function Stick(actor HitActor, vector HitLocation)
{
super.Stick(HitActor, HitLocation);
ImpactActorFixed = ImpactActor; // replicate properly
NetUpdateTime = Level.TimeSeconds - 1;
}
defaultproperties
{
ShutMeUpTime=10.000000
HeadShotDamageMult=2.500000
Damage=400.000000
DamageRadius=0.000000
MyDamageType=Class'ScrnBalanceSrv.ScrnDamTypeCrossbuzzsaw'
LifeSpan=60.000000
}