// Zombie Monster for KF Invasion gametype // GOREFAST. // He's speedy, and swings with a Single enlongated arm, affording him slightly more range class NiceZombieGoreFast extends NiceZombieGoreFastBase; #exec OBJ LOAD FILE= //---------------------------------------------------------------------------- // NOTE: All Variables are declared in the base class to eliminate hitching //---------------------------------------------------------------------------- simulated function PostNetReceive(){ if(bRunning) MovementAnims[0] = 'ZombieRun'; else MovementAnims[0] = default.MovementAnims[0]; } // This zed has been taken control of. Boost its health and speed function SetMindControlled(bool bNewMindControlled) { if( bNewMindControlled ) { NumZCDHits++; // if we hit him a couple of times, make him rage! if( NumZCDHits > 1 ) { if( !IsInState('RunningToMarker') ) { GotoState('RunningToMarker'); } else { NumZCDHits = 1; if( IsInState('RunningToMarker') ) { GotoState(''); } } } else { if( IsInState('RunningToMarker') ) { GotoState(''); } } if( bNewMindControlled != bZedUnderControl ) { Health *= 1.25; HealthMax *= 1.25; } } else { NumZCDHits=0; } bZedUnderControl = bNewMindControlled; } // Handle the zed being commanded to move to a new location function GivenNewMarker() { if( bRunning && NumZCDHits > 1 ) { GotoState('RunningToMarker'); } else { GotoState(''); } } function RangedAttack(Actor A){ super.RangedAttack(A); if(!bShotAnim && !bDecapitated && VSize(A.Location - Location) <= 700) GoToState('RunningState'); } state RunningState{ // Set the zed to the zapped behavior simulated function SetZappedBehavior(){ Global.SetZappedBehavior(); GoToState(''); } // Don't override speed in this state function bool CanSpeedAdjust(){ return false; } simulated function BeginState(){ if(bZapped) GoToState(''); else{ bRunning = true; if(Level.NetMode != NM_DedicatedServer) PostNetReceive(); NetUpdateTime = Level.TimeSeconds - 1; } } function EndState(){ bRunning = false; if(Level.NetMode != NM_DedicatedServer) PostNetReceive(); RunAttackTimeout=0; NetUpdateTime = Level.TimeSeconds - 1; } simulated function UpdateGroundSpeed() { super.UpdateGroundSpeed(); groundSpeed *= 1.875; } function RemoveHead(){ GoToState(''); Global.RemoveHead(); } function RangedAttack(Actor A){ if(bShotAnim || Physics == PHYS_Swimming) return; else if (CanAttack(A)){ bShotAnim = true; // Randomly do a moving attack so the player can't kite the zed if(FRand() < 0.4){ SetAnimAction('ClawAndMove'); RunAttackTimeout = GetAnimDuration('GoreAttack1', 1.0); } else{ SetAnimAction('Claw'); Controller.bPreparingMove = true; Acceleration = vect(0,0,0); // Once we attack stop running GoToState(''); } return; } } simulated function Tick(float DeltaTime){ // Keep moving toward the target until the timer runs out (anim finishes) if(RunAttackTimeout > 0){ RunAttackTimeout -= DeltaTime; if(RunAttackTimeout <= 0 && !bZedUnderControl){ RunAttackTimeout = 0; GoToState(''); } } // Keep the gorefast moving toward its target when attacking if(Role == ROLE_Authority && bShotAnim && !bWaitForAnim){ if(LookTarget != none) Acceleration = AccelRate * Normal(LookTarget.Location - Location); } global.Tick(DeltaTime); } Begin: GoTo('CheckCharge'); CheckCharge: if( Controller!=none && Controller.Target!=none && VSize(Controller.Target.Location-Location)<700 ) { Sleep(0.5+ FRand() * 0.5); //log("Still charging"); GoTo('CheckCharge'); } else { //log("Done charging"); GoToState(''); } } // State where the zed is charging to a marked location. state RunningToMarker extends RunningState { simulated function Tick(float DeltaTime) { // Keep moving toward the target until the timer runs out (anim finishes) if( RunAttackTimeout > 0 ) { RunAttackTimeout -= DeltaTime; if( RunAttackTimeout <= 0 && !bZedUnderControl ) { RunAttackTimeout = 0; GoToState(''); } } // Keep the gorefast moving toward its target when attacking if( Role == ROLE_Authority && bShotAnim && !bWaitForAnim ) { if( LookTarget!=none ) { Acceleration = AccelRate * Normal(LookTarget.Location - Location); } } global.Tick(DeltaTime); } Begin: GoTo('CheckCharge'); CheckCharge: if( bZedUnderControl || (Controller!=none && Controller.Target!=none && VSize(Controller.Target.Location-Location)<700) ) { Sleep(0.5+ FRand() * 0.5); GoTo('CheckCharge'); } else { GoToState(''); } } // Overridden to handle playing upper body only attacks when moving simulated event SetAnimAction(name NewAction) { local int meleeAnimIndex; local bool bWantsToAttackAndMove; if( NewAction=='' ) Return; bWantsToAttackAndMove = NewAction == 'ClawAndMove'; if( NewAction == 'Claw' ) { meleeAnimIndex = Rand(3); NewAction = meleeAnims[meleeAnimIndex]; } if( bWantsToAttackAndMove ) { ExpectingChannel = AttackAndMoveDoAnimAction(NewAction); } else { ExpectingChannel = DoAnimAction(NewAction); } if( !bWantsToAttackAndMove && AnimNeedsWait(NewAction) ) { bWaitForAnim = true; } else { bWaitForAnim = false; } if( Level.NetMode!=NM_Client ) { AnimAction = NewAction; bResetAnimAct = True; ResetAnimActTime = Level.TimeSeconds+0.3; } } // Handle playing the anim action on the upper body only if we're attacking and moving simulated function int AttackAndMoveDoAnimAction( name AnimName ) { local int meleeAnimIndex; if( AnimName == 'ClawAndMove' ) { meleeAnimIndex = Rand(3); AnimName = meleeAnims[meleeAnimIndex]; } if( AnimName=='GoreAttack1' || AnimName=='GoreAttack2' ) { AnimBlendParams(1, 1.0, 0.0,, FireRootBone); PlayAnim(AnimName,, 0.1, 1); return 1; } return super.DoAnimAction( AnimName ); } simulated function HideBone(name boneName) { // Gorefast does not have a left arm and does not need it to be hidden if (boneName != LeftFArmBone) { super.HideBone(boneName); } } static simulated function PreCacheMaterials(LevelInfo myLevel) {//should be derived and used. myLevel.AddPrecacheMaterial(Combiner'KF_Specimens_Trip_T.gorefast_cmb'); myLevel.AddPrecacheMaterial(Combiner'KF_Specimens_Trip_T.gorefast_env_cmb'); myLevel.AddPrecacheMaterial(Texture'KF_Specimens_Trip_T.gorefast_diff'); } defaultproperties { stunLoopStart=0.287500 stunLoopEnd=0.637500 idleInsertFrame=0.750000 EventClasses(0)="NicePack.NiceZombieGorefast" MoanVoice=SoundGroup'KF_EnemiesFinalSnd.GoreFast.Gorefast_Talk' MeleeAttackHitSound=SoundGroup'KF_EnemiesFinalSnd.GoreFast.Gorefast_HitPlayer' JumpSound=SoundGroup'KF_EnemiesFinalSnd.GoreFast.Gorefast_Jump' DetachedArmClass=Class'KFChar.SeveredArmGorefast' DetachedLegClass=Class'KFChar.SeveredLegGorefast' DetachedHeadClass=Class'KFChar.SeveredHeadGorefast' bLeftArmGibbed=True HitSound(0)=SoundGroup'KF_EnemiesFinalSnd.GoreFast.Gorefast_Pain' DeathSound(0)=SoundGroup'KF_EnemiesFinalSnd.GoreFast.Gorefast_Death' ChallengeSound(0)=SoundGroup'KF_EnemiesFinalSnd.GoreFast.Gorefast_Challenge' ChallengeSound(1)=SoundGroup'KF_EnemiesFinalSnd.GoreFast.Gorefast_Challenge' ChallengeSound(2)=SoundGroup'KF_EnemiesFinalSnd.GoreFast.Gorefast_Challenge' ChallengeSound(3)=SoundGroup'KF_EnemiesFinalSnd.GoreFast.Gorefast_Challenge' ControllerClass=class'NiceZombieGorefastController' AmbientSound=Sound'KF_BaseGorefast.Gorefast_Idle' Mesh=SkeletalMesh'KF_Freaks_Trip.GoreFast_Freak' Skins(0)=Combiner'KF_Specimens_Trip_T.gorefast_cmb' }