211 lines
5.9 KiB
Ucode
211 lines
5.9 KiB
Ucode
class ZombieJason extends ZombieScrake;
|
|
|
|
#exec load obj file=ScrnZedPack_T.utx
|
|
#exec load obj file=ScrnZedPack_S.uax
|
|
#exec load obj file=ScrnZedPack_A.ukx
|
|
|
|
var int OriginalMeleeDamage; // default melee damage, adjusted by game's difficulty
|
|
var transient bool bFlippedOver;
|
|
var transient float LastFlipOverTime;
|
|
var float FlipOverDuration;
|
|
var bool bWasRaged; // set to true, if Jason is raged or was raged before
|
|
var float RageHealthPct;
|
|
|
|
|
|
|
|
simulated function PostBeginPlay()
|
|
{
|
|
super.PostBeginPlay();
|
|
OriginalMeleeDamage = MeleeDamage;
|
|
FlipOverDuration = GetAnimDuration('KnockDown');
|
|
}
|
|
|
|
simulated function Tick(float DeltaTime)
|
|
{
|
|
super.Tick(DeltaTime);
|
|
|
|
if ( bFlippedOver && Level.TimeSeconds > LastFlipOverTime + FlipOverDuration )
|
|
bFlippedOver = false;
|
|
}
|
|
|
|
// Machete has no Exhaust ;)
|
|
simulated function SpawnExhaustEmitter() {}
|
|
simulated function UpdateExhaustEmitter() {}
|
|
|
|
function bool FlipOver()
|
|
{
|
|
bFlippedOver= super.FlipOver();
|
|
if ( bFlippedOver ) {
|
|
LastFlipOverTime = Level.TimeSeconds;
|
|
// do not rotate while stunned
|
|
Controller.Focus = none;
|
|
Controller.FocalPoint = Location + 512*vector(Rotation);
|
|
}
|
|
return bFlippedOver;
|
|
}
|
|
|
|
function bool CanGetOutOfWay()
|
|
{
|
|
return !bFlippedOver; // can't dodge husk fireballs while stunned
|
|
}
|
|
|
|
function TakeDamage(int Damage, Pawn InstigatedBy, Vector HitLocation, Vector Momentum, class<DamageType> DamType, optional int HitIndex)
|
|
{
|
|
local bool bIsHeadShot;
|
|
local float headShotCheckScale;
|
|
local class<KFWeaponDamageType> KFDamType;
|
|
local int OldHealth, DamageDone;
|
|
|
|
KFDamType = class<KFWeaponDamageType>(DamType);
|
|
|
|
if ( InstigatedBy != none && KFDamType != none ) {
|
|
if ( KFDamType.default.bCheckForHeadShots ) {
|
|
headShotCheckScale= 1.0;
|
|
if (class<DamTypeMelee>(DamType) != none) {
|
|
headShotCheckScale*= 1.25;
|
|
}
|
|
bIsHeadShot = IsHeadShot(Hitlocation, normal(Momentum), 1.0);
|
|
}
|
|
|
|
if ( ClassIsChildOf(DamType, class'DamTypePipeBomb') )
|
|
Damage *= 1.5;
|
|
else if ( bIsHeadShot && Level.Game.GameDifficulty >= 5.0 && class<DamTypeCrossbow>(DamType) != none )
|
|
Damage *= 0.5;
|
|
|
|
OldHealth = Health;
|
|
super(KFMonster).TakeDamage(Damage, instigatedBy, hitLocation, momentum, DamType);
|
|
DamageDone = OldHealth - Health;
|
|
|
|
if ( !bDecapitated ) {
|
|
if( bFlippedOver ) {
|
|
if ( Level.Game.GameDifficulty >= 7.0 && Health>0 && !bIsHeadShot && DamageDone<800
|
|
&& Level.TimeSeconds - LastFlipOverTime > 0.1
|
|
&& (DamageDone > 300 || (Damage > 50 && KFDamType.default.bSniperWeapon)) )
|
|
{
|
|
// [HoE only] Break stun if Jason is hit with sniper weapon to the body
|
|
bFlippedOver = false;
|
|
bWaitForAnim = false;
|
|
bShotAnim = false;
|
|
if ( Controller != none )
|
|
Controller.GoToState('ZombieHunt');
|
|
GoToState('RunningState');
|
|
}
|
|
}
|
|
else {
|
|
if ( Level.Game.GameDifficulty >= 5.0 && !IsInState('SawingLoop') && !IsInState('RunningState') && float(Health) / HealthMax < RageHealthPct )
|
|
RangedAttack(InstigatedBy);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
Super(Monster).TakeDamage(Damage, instigatedBy, hitLocation, momentum, DamType); // skip NONE-reference error
|
|
}
|
|
|
|
}
|
|
|
|
function RangedAttack(Actor A)
|
|
{
|
|
if ( bShotAnim || Physics == PHYS_Swimming)
|
|
return;
|
|
else if ( CanAttack(A) )
|
|
{
|
|
bShotAnim = true;
|
|
SetAnimAction(MeleeAnims[Rand(2)]);
|
|
CurrentDamType = ZombieDamType[0];
|
|
//PlaySound(sound'Claw2s', SLOT_None); KFTODO: Replace this
|
|
GoToState('SawingLoop');
|
|
}
|
|
|
|
if( !bShotAnim && !bDecapitated ) {
|
|
if ( bWasRaged || float(Health)/HealthMax < 0.5
|
|
|| (Level.Game.GameDifficulty >= 5.0 && float(Health)/HealthMax < RageHealthPct) )
|
|
GoToState('RunningState');
|
|
}
|
|
}
|
|
|
|
State SawingLoop
|
|
{
|
|
function RangedAttack(Actor A)
|
|
{
|
|
if ( bShotAnim )
|
|
return;
|
|
else if ( CanAttack(A) )
|
|
{
|
|
Acceleration = vect(0,0,0);
|
|
bShotAnim = true;
|
|
MeleeDamage = OriginalMeleeDamage*0.6; // fixed difficulty multiplier -- PooSH
|
|
SetAnimAction('SawImpaleLoop');
|
|
CurrentDamType = ZombieDamType[0];
|
|
if( AmbientSound != SawAttackLoopSound )
|
|
{
|
|
AmbientSound=SawAttackLoopSound;
|
|
}
|
|
}
|
|
else GoToState('');
|
|
}
|
|
}
|
|
|
|
simulated function float GetOriginalGroundSpeed()
|
|
{
|
|
local float result;
|
|
|
|
result = OriginalGroundSpeed;
|
|
if ( bWasRaged || bCharging )
|
|
result *= 3.5;
|
|
else if( bZedUnderControl )
|
|
result *= 1.25;
|
|
|
|
if ( bBurnified )
|
|
result *= 0.8;
|
|
|
|
return result;
|
|
}
|
|
|
|
state RunningState
|
|
{
|
|
function BeginState()
|
|
{
|
|
bWasRaged = true;
|
|
|
|
if( bZapped )
|
|
GoToState('');
|
|
else {
|
|
bCharging = true;
|
|
SetGroundSpeed(GetOriginalGroundSpeed());
|
|
if( Level.NetMode!=NM_DedicatedServer )
|
|
PostNetReceive();
|
|
NetUpdateTime = Level.TimeSeconds - 1;
|
|
}
|
|
}
|
|
|
|
function EndState()
|
|
{
|
|
bCharging = False;
|
|
if( !bZapped )
|
|
SetGroundSpeed(GetOriginalGroundSpeed());
|
|
if( Level.NetMode!=NM_DedicatedServer )
|
|
PostNetReceive();
|
|
}
|
|
|
|
}
|
|
|
|
defaultproperties
|
|
{
|
|
RageHealthPct=0.750000
|
|
SawAttackLoopSound=Sound'KF_BaseGorefast.Attack.Gorefast_AttackSwish3'
|
|
StunsRemaining=5
|
|
BleedOutDuration=7.000000
|
|
MeleeDamage=25
|
|
MeleeAttackHitSound=SoundGroup'KF_EnemiesFinalSnd.GoreFast.Gorefast_HitPlayer'
|
|
HeadHealth=800.000000
|
|
ScoringValue=300
|
|
HealthMax=1500.000000
|
|
Health=1500
|
|
MenuName="Jason.se"
|
|
AmbientSound=Sound'ScrnZedPack_S.Jason.Jason_Sound'
|
|
Mesh=SkeletalMesh'ScrnZedPack_A.JasonMesh'
|
|
Skins(0)=Shader'ScrnZedPack_T.Jason.Jason__FB'
|
|
Skins(1)=Texture'ScrnZedPack_T.Jason.JVMaskB'
|
|
Skins(2)=Combiner'ScrnZedPack_T.Jason.Machete_cmb'
|
|
}
|