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

182 lines
5.6 KiB
Ucode

class stub_Z_Boss extends ZombieBoss;
//=============================================================================
// ammo class == none fix
//=============================================================================
state FireMissile
{
function AnimEnd( int Channel )
{
local vector Start;
local Rotator R;
Start = GetBoneCoords('tip').Origin;
// at least shoot at someone, not walls
if (Controller.Target == none)
Controller.Target = Controller.Enemy;
// fix MyAmmo none logs
if (!SavedFireProperties.bInitialized)
{
SavedFireProperties.AmmoClass = class'SkaarjAmmo';
SavedFireProperties.ProjectileClass = class'BossLAWProj';
SavedFireProperties.WarnTargetPct = 0.15;
SavedFireProperties.MaxRange = 10000;
SavedFireProperties.bTossed = false;
SavedFireProperties.bTrySplash = false;
SavedFireProperties.bLeadTarget = true;
SavedFireProperties.bInstantHit = true;
SavedFireProperties.bInitialized = true;
}
R = AdjustAim(SavedFireProperties,Start,100);
PlaySound(RocketFireSound,SLOT_Interact,2.0,,TransientSoundRadius,,false);
// added projectile owner
spawn(class'BossLAWProj',self,,Start,R);
bShotAnim = true;
Acceleration = vect(0,0,0);
SetAnimAction('FireEndMissile');
HandleWaitForAnim('FireEndMissile');
// Randomly send out a message about Patriarch shooting a rocket(5% chance)
if ( FRand() < 0.05 && Controller.Enemy != none && PlayerController(Controller.Enemy.Controller) != none )
{
PlayerController(Controller.Enemy.Controller).Speech('AUTO', 10, "");
}
GoToState('');
}
}
//=============================================================================
// ctrl == none fixes
//=============================================================================
function bool MeleeDamageTarget(int hitdamage, vector pushdir)
{
// added 'Controller != none' check
if (Controller != none && Controller.Target != none && Controller.Target.IsA('NetKActor'))
pushdir = Normal(Controller.Target.Location-Location)*100000;
return super(KFMonster).MeleeDamageTarget(hitdamage, pushdir);
}
// non-state one
function ClawDamageTarget()
{
local vector PushDir;
local name Anim;
local float frame,rate;
local float UsedMeleeDamage;
local bool bDamagedSomeone;
local KFHumanPawn P;
local Actor OldTarget;
// check this from the very start to prevent any log spam
if (Controller == none || IsInState('ZombieDying'))
return;
if (MeleeDamage > 1)
UsedMeleeDamage = (MeleeDamage - (MeleeDamage * 0.05)) + (MeleeDamage * (FRand() * 0.1));
else
UsedMeleeDamage = MeleeDamage;
GetAnimParams(1, Anim,frame,rate);
if (Controller != none && Controller.Target != none)
PushDir = (damageForce * Normal(Controller.Target.Location - Location));
else
PushDir = damageForce * vector(Rotation);
// merging 2 similar checks
// dick animation
if (Anim == 'MeleeImpale')
{
MeleeRange = ImpaleMeleeDamageRange;
bDamagedSomeone = MeleeDamageTarget(UsedMeleeDamage, PushDir);
}
// the hand animation
else
{
MeleeRange = ClawMeleeDamageRange;
OldTarget = Controller.Target;
foreach DynamicActors(class'KFHumanPawn', P)
{
if ( (P.Location - Location) dot PushDir > 0.0 ) // Added dot Product check in Balance Round 3
{
Controller.Target = P;
bDamagedSomeone = bDamagedSomeone || MeleeDamageTarget(UsedMeleeDamage, damageForce * Normal(P.Location - Location)); // Always pushing players away added in Balance Round 3
}
}
Controller.Target = OldTarget;
}
MeleeRange = default.MeleeRange;
if (bDamagedSomeone)
{
if (Anim == 'MeleeImpale')
PlaySound(MeleeImpaleHitSound, SLOT_Interact, 2.0);
else
PlaySound(MeleeAttackHitSound, SLOT_Interact, 2.0);
}
}
//=============================================================================
// headshot fix while he is machinegunning
//=============================================================================
state FireChaingun
{
function TakeDamage( int Damage, Pawn InstigatedBy, Vector Hitlocation, Vector Momentum, class<DamageType> damageType, optional int HitIndex)
{
local float EnemyDistSq, DamagerDistSq;
// changed vect(0,0,0) with Momentum
global.TakeDamage(Damage,instigatedBy,hitlocation,Momentum,damageType);
// if someone close up is shooting us, just charge them
if (InstigatedBy != none)
{
DamagerDistSq = VSizeSquared(Location - InstigatedBy.Location);
if ( (ChargeDamage > 200 && DamagerDistSq < (500 * 500)) || DamagerDistSq < (100 * 100) )
{
SetAnimAction('transition');
GoToState('Charging');
return;
}
}
if (Controller.Enemy != none && InstigatedBy != none && InstigatedBy != Controller.Enemy)
{
EnemyDistSq = VSizeSquared(Location - Controller.Enemy.Location);
DamagerDistSq = VSizeSquared(Location - InstigatedBy.Location);
}
if (InstigatedBy != none && (DamagerDistSq < EnemyDistSq || Controller.Enemy == none) )
{
MonsterController(Controller).ChangeEnemy(InstigatedBy,Controller.CanSee(InstigatedBy));
Controller.Target = InstigatedBy;
Controller.Focus = InstigatedBy;
if( DamagerDistSq < (500 * 500) )
{
SetAnimAction('transition');
GoToState('Charging');
}
}
}
}
defaultproperties{}