diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..27ed978 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "tools"] + path = tools + url = https://github.com/GenZmeY/KF2-BuildTools diff --git a/CustomZeds/Classes/WMAICommand_HuskOmegaFireBallBarrageAttack.uc b/CustomZeds/Classes/WMAICommand_HuskOmegaFireBallBarrageAttack.uc new file mode 100644 index 0000000..3984c38 --- /dev/null +++ b/CustomZeds/Classes/WMAICommand_HuskOmegaFireBallBarrageAttack.uc @@ -0,0 +1,50 @@ +class WMAICommand_HuskOmegaFireBallBarrageAttack extends AICommand_RangedAttack + within WMAIController_ZedHusk_Omega; + +/** Simple constructor that pushes a new instance of the command for the AI */ +static function bool FireBallBarrageAttack(WMAIController_ZedHusk_Omega AI) +{ + local WMAICommand_HuskOmegaFireBallBarrageAttack Cmd; + + if (AI != None) + { + Cmd = new(AI) default.class; + if (Cmd != None) + { + AI.PushCommand(Cmd); + return true; + } + } + + return false; +} + +state Command_SpecialMove +{ + function ESpecialMove GetSpecialMove() + { + return SM_Custom1; + } +} + +function Pushed() +{ + Super.Pushed(); + + `AILog("Beginning fireball barrage" $ Enemy, 'Command_FireBall_Barrage'); + AIActionStatus = "Starting fireball barrage AICommand"; +} + +function Popped() +{ + AIActionStatus = "Finished fireball barrage AICommand"; + LastFireBallBarrageTime = WorldInfo.TimeSeconds; + Super.Popped(); +} + +defaultproperties +{ + SpecialMoveClass=class'CustomZeds.WMSM_Husk_Omega_FireBallBarrageAttack' + + Name="Default__WMAICommand_HuskOmegaFireBallBarrageAttack" +} diff --git a/CustomZeds/Classes/WMAIController_ZedFleshpound_Predator.uc b/CustomZeds/Classes/WMAIController_ZedFleshpound_Predator.uc new file mode 100644 index 0000000..1770635 --- /dev/null +++ b/CustomZeds/Classes/WMAIController_ZedFleshpound_Predator.uc @@ -0,0 +1,19 @@ +class WMAIController_ZedFleshpound_Predator extends KFAIController_ZedFleshpound; + +function InitPlayerReplicationInfo() +{ +} + +simulated event byte ScriptGetTeamNum() +{ + return 0; +} + +defaultproperties +{ + bAllowScriptTeamCheck=True + TeleportCooldown=4.0f + EvadeGrenadeChance=1.0f + + Name="Default__WMAIController_ZedFleshpound_Predator" +} diff --git a/CustomZeds/Classes/WMAIController_ZedGorefast_Omega.uc b/CustomZeds/Classes/WMAIController_ZedGorefast_Omega.uc new file mode 100644 index 0000000..ad87b89 --- /dev/null +++ b/CustomZeds/Classes/WMAIController_ZedGorefast_Omega.uc @@ -0,0 +1,14 @@ +class WMAIController_ZedGorefast_Omega extends KFAIController_ZedGorefast; + +function bool ShouldSprint() +{ + bForceFrustration = True; + return super.ShouldSprint(); +} + +defaultproperties +{ + EvadeGrenadeChance=1.0f + + Name="Default__WMAIController_ZedGorefast_Omega" +} diff --git a/CustomZeds/Classes/WMAIController_ZedHusk_Omega.uc b/CustomZeds/Classes/WMAIController_ZedHusk_Omega.uc new file mode 100644 index 0000000..5349526 --- /dev/null +++ b/CustomZeds/Classes/WMAIController_ZedHusk_Omega.uc @@ -0,0 +1,272 @@ +class WMAIController_ZedHusk_Omega extends KFAIController_ZedHusk; + +var float LastFireBallBarrageTime; +var float BaseTimeBetweenFireBallBarrages; +var float TimeBetweenFireBallBarrages; +var float FireballBarrageRandomizedValue; +var int MinDistanceForFireBallBarrage; +var int MaxDistanceForFireBallBarrage; + +var float BaseHealthPercentForSprint; + +var const float FireballBarrageFireIntervalNormal; +var const float FireballBarrageFireIntervalHard; +var const float FireballBarrageFireIntervalSuicidal; +var const float FireballBarrageFireIntervalHellOnEarth; + +var const float RequiredHealthPercentForSprintNormal; +var const float RequiredHealthPercentForSprintHard; +var const float RequiredHealthPercentForSprintSuicidal; +var const float RequiredHealthPercentForSprintHellOnEarth; + +event PostBeginPlay() +{ + super.PostBeginPlay(); + + if (Skill == class'KFGameDifficultyInfo'.static.GetDifficultyValue(0)) // Normal + { + BaseTimeBetweenFireBallBarrages = FireballBarrageFireIntervalNormal; + BaseHealthPercentForSprint = RequiredHealthPercentForSprintNormal; + } + else if (Skill <= class'KFGameDifficultyInfo'.static.GetDifficultyValue(1)) // Hard + { + BaseTimeBetweenFireBallBarrages = FireballBarrageFireIntervalHard; + BaseHealthPercentForSprint = RequiredHealthPercentForSprintHard; + } + else if (Skill <= class'KFGameDifficultyInfo'.static.GetDifficultyValue(2)) // Suicidal + { + BaseTimeBetweenFireBallBarrages = FireballBarrageFireIntervalSuicidal; + BaseHealthPercentForSprint = RequiredHealthPercentForSprintSuicidal; + } + else // Hell on Earth + { + BaseTimeBetweenFireBallBarrages = FireballBarrageFireIntervalHellOnEarth; + BaseHealthPercentForSprint = RequiredHealthPercentForSprintHellOnEarth; + } +} + +simulated function Tick(float DeltaTime) +{ + local float DistToTargetSq; + + if (Role == ROLE_Authority && Enemy != None && MyKFPawn != None) + { + if (`TimeSince(LastCheckSpecialMoveTime) >= CheckSpecialMoveTime && !MyKFPawn.IsDoingSpecialMove()) + { + if (GetActiveCommand() != None && !GetActiveCommand().IsA('AICommand_SpecialMove')) + { + if (WorldInfo.FastTrace(Enemy.Location, Pawn.Location, , True)) + { + DistToTargetSq = VSizeSq(Enemy.Location - Pawn.Location); + if (!IsSuicidal() && CanDoFireballBarrage(DistToTargetSq)) + { + if (KFGameInfo(WorldInfo.Game) != None && KFGameInfo(WorldInfo.Game).GameConductor != None) + { + KFGameInfo(WorldInfo.Game).GameConductor.UpdateOverallAttackCoolDowns(self); + } + + class'WMAICommand_HuskOmegaFireBallBarrageAttack'.static.FireBallBarrageAttack(self); + TimeBetweenFireBallBarrages = BaseTimeBetweenFireBallBarrages + RandRange(-FireballBarrageRandomizedValue, FireballBarrageRandomizedValue); + } + } + } + } + } + + super.Tick(DeltaTime); +} + +function bool CanDoFireballBarrage(float DistToTargetSq) +{ + if(!CheckOverallCooldownTimer()) + return False; + + return ((LastFireBallBarrageTime == 0 || (`TimeSince(LastFireBallBarrageTime) > TimeBetweenFireBallBarrages)) + && DistToTargetSq >= Square(MinDistanceForFireBallBarrage) + && DistToTargetSq <= Square(MaxDistanceForFireBallBarrage) + && MyKFPawn.CanDoSpecialMove(SM_Custom1)) + && IsCeilingClear(); +} + +function bool IsCeilingClear() +{ + local vector TraceStart, TraceEnd, Extent; + + if (MyKFPawn == None) + { + return False; + } + + TraceStart = MyKFPawn.Location + vect(0,0,1) * MyKFPawn.GetCollisionHeight(); + TraceEnd = TraceStart + vect(0,0,1) * 175.0f; + Extent.X = MyKFPawn.GetCollisionRadius() * 2.0f; + Extent.Y = Extent.X; + Extent.Z = 1.0f; + + return MyKFPawn.FastTrace(TraceEnd, TraceStart, Extent, True); +} + +function bool ShouldSprint() +{ + if (GetHealthPercentage() <= BaseHealthPercentForSprint) + return True; + else + return super.ShouldSprint(); +} + +function ShootRandomFireball(class FireballClass) +{ + local vector SocketLocation, DirToEnemy; + local KFProj_Husk_Fireball MyFireball; + local vector randVectorDraw; + local KFPawn_ZedHusk MyHuskPawn; + + if (MyKFPawn == None) + { + return; + } + + SocketLocation = MyKFPawn.GetPawnViewLocation(); + if (Role == ROLE_Authority) + { + randVectorDraw.X = FRand() * 2.0f - 1.0f; + randVectorDraw.Y = FRand() * 2.0f - 1.0f; + randVectorDraw.Z = FRand() + 0.1f; + DirToEnemy = normal(randVectorDraw); + + MyHuskPawn = KFPawn_ZedHusk(MyKFPawn); + + // Shoot the fireball + MyFireball = Spawn(FireballClass, MyKFPawn, , SocketLocation, Rotator(DirToEnemy)); + MyFireball.Instigator = MyKFPawn; + MyFireball.InstigatorController = self; + + // Set our difficulty setings + MyFireball.ExplosionTemplate.MomentumTransferScale = MyHuskPawn.FireballSettings.ExplosionMomentum * 0.5f; + MyFireball.bSpawnGroundFire = False; + + // Fire + MyFireball.Init(DirToEnemy); + } +} + +function ShootFireballBarrage(class FireballClass, vector FireballOffset) +{ + local vector SocketLocation, DirToEnemy; + local KFProj_Husk_Fireball MyFireball; + local Vector AimLocation, GroundAimLocation; + local float SplashAimChance; + local vector randVectorDraw; + local float randDraw; + local KFPawn_ZedHusk MyHuskPawn; + + if (MyKFPawn == None) + { + return; + } + + SocketLocation = MyKFPawn.GetPawnViewLocation() + (FireballOffset >> Pawn.GetViewRotation()); + if (MyKFPawn.Health > 0.0f && Role == ROLE_Authority) + { + AimLocation = Enemy.Location; + + SplashAimChance = 0.6f; + + randDraw = FRand(); + + if (randDraw < SplashAimChance) + { + // Simple pass at making the Husk try and do splash damage when it shoots at a player rather than just shoot directly at them (and most likely miss) + GroundAimLocation = Enemy.Location - (vect(0,0,1) * Enemy.GetCollisionHeight()); + + if (GroundAimLocation.Z < SocketLocation.Z) + { + AimLocation = GroundAimLocation; + } + } + + randVectorDraw = VRand(); + DirToEnemy = normal(AimLocation - SocketLocation) + randVectorDraw * FireballAimError; + + DirToEnemy.Z = 1.1f + FRand() * 0.3f; + DirToEnemy.X += FRand() * 0.2f - 0.1f; + DirToEnemy.Y += FRand() * 0.2f - 0.1f; + DirToEnemy = normal(DirToEnemy); + + MyHuskPawn = KFPawn_ZedHusk(MyKFPawn); + + // Shoot the fireball + MyFireball = Spawn(FireballClass, MyKFPawn,, SocketLocation, Rotator(DirToEnemy)); + MyFireball.Instigator = MyKFPawn; + MyFireball.InstigatorController = self; + + // Set our difficulty setings + MyFireball.ExplosionTemplate.MomentumTransferScale = MyHuskPawn.FireballSettings.ExplosionMomentum; + MyFireball.bSpawnGroundFire = MyHuskPawn.FireballSettings.bSpawnGroundFire; + + // Fire + MyFireball.Init(DirToEnemy); + + LastFireBallBarrageTime = WorldInfo.TimeSeconds; + } +} + +defaultproperties +{ + bUseDesiredRotationForMelee=False + bCanTeleportCloser=False + + // Behaviors + EvadeGrenadeChance=0.8f + CheckSpecialMoveTime=0.25f + + // Fireball + MinDistanceForFireBall=300 + MaxDistanceForFireBall=3000 + + FireballFireIntervalNormal=4.0f + FireballFireIntervalHard=3.3f + FireballFireIntervalSuicidal=2.8f + FireballFireIntervalHellOnEarth=2.2f + + FireballRandomizedValue=2.5f + + SplashAimChanceNormal=0.25f + SplashAimChanceHard=0.35f + SplashAimChanceSuicidal=0.5f + SplashAimChanceHellOnEarth=0.75f + + FireballSpeed=4100.0f + FireballAimError=0.03f + FireballLeadTargetAimError=0.03f + bDebugAimError=False + bCanLeadTarget=False + + // Fireball Barrage + MinDistanceForFireBallBarrage=600 + MaxDistanceForFireBallBarrage=750 + + FireballBarrageFireIntervalNormal=3.5f + FireballBarrageFireIntervalHard=3.0f + FireballBarrageFireIntervalSuicidal=2.5f + FireballBarrageFireIntervalHellOnEarth=2.0f + + FireballBarrageRandomizedValue=2.0f + + // Sprint + RequiredHealthPercentForSprintNormal=0.7f + RequiredHealthPercentForSprintHard=0.8f + RequiredHealthPercentForSprintSuicidal=0.87f + RequiredHealthPercentForSprintHellOnEarth=0.95f + + // FlameThrower + TimeBetweenFlameThrower=8.0f + MaxDistanceForFlameThrower=450 + LowIntensityAttackScaleOfFireballInterval=1.25f + + // Suicide + MinDistanceToSuicide=425 + RequiredHealthPercentForSuicide=0.2f + + Name="Default__WMAIController_ZedHusk_Omega" +} diff --git a/CustomZeds/Classes/WMDifficulty_Crawler_Big.uc b/CustomZeds/Classes/WMDifficulty_Crawler_Big.uc new file mode 100644 index 0000000..b5b83ec --- /dev/null +++ b/CustomZeds/Classes/WMDifficulty_Crawler_Big.uc @@ -0,0 +1,12 @@ +class WMDifficulty_Crawler_Big extends KFDifficulty_Crawler + abstract; + +defaultproperties +{ + Normal=(EvadeOnDamageSettings=(Chance=0.0f)) + Hard=(EvadeOnDamageSettings=(Chance=0.0f)) + Suicidal=(MovementSpeedMod=1.1f, EvadeOnDamageSettings=(Chance=0.0f)) + HellOnEarth=(MovementSpeedMod=1.15f, EvadeOnDamageSettings=(Chance=0.0f)) + + Name="Default__WMDifficulty_Crawler_Big" +} diff --git a/CustomZeds/Classes/WMDifficulty_Gorefast_Omega.uc b/CustomZeds/Classes/WMDifficulty_Gorefast_Omega.uc new file mode 100644 index 0000000..d1a35dc --- /dev/null +++ b/CustomZeds/Classes/WMDifficulty_Gorefast_Omega.uc @@ -0,0 +1,12 @@ +class WMDifficulty_Gorefast_Omega extends KFDifficulty_Gorefast + abstract; + +defaultproperties +{ + Normal=(HealthMod=0.85f, HeadHealthMod=0.85f, BlockSettings=(Chance=0.75f)) + Hard=(BlockSettings=(Chance=0.80f), RallySettings=(bCanRally=True)) + Suicidal=(BlockSettings=(Chance=0.85f)) + HellOnEarth=(BlockSettings=(Chance=0.9f)) + + Name="Default__WMDifficulty_Gorefast_Omega" +} diff --git a/CustomZeds/Classes/WMDifficulty_Husk_Omega.uc b/CustomZeds/Classes/WMDifficulty_Husk_Omega.uc new file mode 100644 index 0000000..98e0183 --- /dev/null +++ b/CustomZeds/Classes/WMDifficulty_Husk_Omega.uc @@ -0,0 +1,17 @@ +class WMDifficulty_Husk_Omega extends KFDifficulty_Husk + dependsOn(WMPawn_ZedHusk_Omega) + abstract; + +defaultproperties +{ + Normal=(HealthMod=0.85f,HeadHealthMod=0.85f) + Hard=(DamagedSprintChance=0.35f) + Suicidal=(DamagedSprintChance=0.5f) + HellOnEarth=(HealthMod=1.1f,SprintChance=0.65f) + + FireballSettings(`DIFFICULTY_Normal)=(bSpawnGroundFire=True) + FireballSettings(`DIFFICULTY_Hard)=(bSpawnGroundFire=True) + FireballSettings_Versus=(bSpawnGroundFire=True) + + Name="Default__WMDifficulty_Husk_Omega" +} diff --git a/CustomZeds/Classes/WMDifficulty_Scrake_Emperor.uc b/CustomZeds/Classes/WMDifficulty_Scrake_Emperor.uc new file mode 100644 index 0000000..a46b9bf --- /dev/null +++ b/CustomZeds/Classes/WMDifficulty_Scrake_Emperor.uc @@ -0,0 +1,18 @@ +class WMDifficulty_Scrake_Emperor extends KFDifficulty_Scrake + abstract; + +defaultproperties +{ + Normal=(BlockSettings=(Duration=3.0f)) + Hard=(BlockSettings=(Duration=3.0f)) + Suicidal=(BlockSettings=(Duration=3.0f)) + HellOnEarth=(BlockSettings=(Duration=3.0f)) + + NumPlayersScale_BodyHealth=0.195f + NumPlayersScale_HeadHealth=0.14f + + NumPlayersScale_BodyHealth_Versus=0.195f + NumPlayersScale_HeadHealth_Versus=0.14f + + Name="Default__WMDifficulty_Scrake_Emperor" +} diff --git a/CustomZeds/Classes/WMDifficulty_Siren_Omega.uc b/CustomZeds/Classes/WMDifficulty_Siren_Omega.uc new file mode 100644 index 0000000..709922b --- /dev/null +++ b/CustomZeds/Classes/WMDifficulty_Siren_Omega.uc @@ -0,0 +1,12 @@ +class WMDifficulty_Siren_Omega extends KFDifficulty_Siren + abstract; + +defaultproperties +{ + Normal=(DamagedSprintChance=0.5f) + Hard=(DamagedSprintChance=0.65f) + Suicidal=(DamagedSprintChance=0.8f) + HellOnEarth=(DamagedSprintChance=0.9f) + + Name="Default__WMDifficulty_Siren_Omega" +} diff --git a/CustomZeds/Classes/WMDifficulty_Stalker_Omega.uc b/CustomZeds/Classes/WMDifficulty_Stalker_Omega.uc new file mode 100644 index 0000000..96931a1 --- /dev/null +++ b/CustomZeds/Classes/WMDifficulty_Stalker_Omega.uc @@ -0,0 +1,12 @@ +class WMDifficulty_Stalker_Omega extends KFDifficulty_Stalker + abstract; + +defaultproperties +{ + Normal=(DamagedSprintChance=0.2f, EvadeOnDamageSettings=(Chance=0.5f)) + Hard=(DamagedSprintChance=0.4f, EvadeOnDamageSettings=(Chance=0.6f)) + Suicidal=(EvadeOnDamageSettings=(Chance=0.7f)) + HellOnEarth=(EvadeOnDamageSettings=(Chance=0.8f)) + + Name="Default__WMDifficulty_Stalker_Omega" +} diff --git a/CustomZeds/Classes/WMExplosion_TinyHusk.uc b/CustomZeds/Classes/WMExplosion_TinyHusk.uc new file mode 100644 index 0000000..e241896 --- /dev/null +++ b/CustomZeds/Classes/WMExplosion_TinyHusk.uc @@ -0,0 +1,38 @@ +class WMExplosion_TinyHusk extends KFGameExplosion; + +defaultproperties +{ + Begin Object Class=PointLightComponent Name=ExplosionPointLight + LightColor=(R=245, G=190, B=140, A=255) + bCastPerObjectShadows=false + End Object + + Damage=35.0 + DamageRadius=360.0 + DamageFalloffExponent=2.0 + DamageDelay=0.0 + bFullDamageToAttachee=true + + // Damage Effects + MyDamageType=class'KFDT_Explosive_HuskSuicide' + FractureMeshRadius=200.0 + FracturePartVel=500.0 + ExplosionEffects=KFImpactEffectInfo'FX_Impacts_ARCH.Explosions.HuskSuicide_Explosion' + ExplosionSound=AkEvent'WW_WEP_Husk_Cannon.Play_WEP_Husk_Cannon_3P_Fire' + KnockDownStrength=0.0 + MomentumTransferScale=1.0 + + // Dynamic Light + ExploLight=ExplosionPointLight + ExploLightStartFadeOutTime=0.0 + ExploLightFadeOutTime=0.5 + + // Camera Shake + CamShake=CameraShake'FX_CameraShake_Arch.Misc_Explosions.Seeker6' + CamShakeInnerRadius=180.0 + CamShakeOuterRadius=500.0 + CamShakeFalloff=1.5 + bOrientCameraShakeTowardsEpicenter=true + + Name="Default__WMExplosion_TinyHusk" +} diff --git a/CustomZeds/Classes/WMPawn_OmegaConstants.uc b/CustomZeds/Classes/WMPawn_OmegaConstants.uc new file mode 100644 index 0000000..e56cfba --- /dev/null +++ b/CustomZeds/Classes/WMPawn_OmegaConstants.uc @@ -0,0 +1,10 @@ +class WMPawn_OmegaConstants extends Object; + +var const linearColor OmegaColor; +var const linearColor OmegaFresnelColor; + +defaultproperties +{ + OmegaColor=(R=0.5f,G=0.25f,B=1.0f) + OmegaFresnelColor=(R=0.4f,G=0.25f,B=0.7f) +} diff --git a/CustomZeds/Classes/WMPawn_ZedBloatKing.uc b/CustomZeds/Classes/WMPawn_ZedBloatKing.uc new file mode 100644 index 0000000..e8d435c --- /dev/null +++ b/CustomZeds/Classes/WMPawn_ZedBloatKing.uc @@ -0,0 +1,46 @@ +class WMPawn_ZedBloatKing extends KFPawn_ZedBloatKing; + +var AkEvent EntranceSound; + +simulated event PostBeginPlay() +{ + // add entrance sound + SoundGroupArch.EntranceSound = default.EntranceSound; + + Super.PostBeginPlay(); +} + +/** Summon some children */ +function SummonChildren() +{ +} + +/** Play music for this boss (overridden for each boss) */ +function PlayBossMusic() +{ +} + +static simulated event bool IsABoss() +{ + return False; +} + +function bool CanBeGrabbed(KFPawn GrabbingPawn, optional bool bIgnoreFalling, optional bool bAllowSameTeamGrab) +{ + return False; +} + +defaultproperties +{ + EntranceSound=AkEvent'WW_ZED_Abomination.Play_Abomination_Intro_Land' + MinSpawnSquadSizeType=EST_Large + bLargeZed=True + DoshValue=300 + + XPValues(0)=150 + XPValues(1)=150 + XPValues(2)=150 + XPValues(3)=150 + + Name="Default__WMPawn_ZedBloatKing" +} diff --git a/CustomZeds/Classes/WMPawn_ZedClot_Slasher_Omega.uc b/CustomZeds/Classes/WMPawn_ZedClot_Slasher_Omega.uc new file mode 100644 index 0000000..fe15c12 --- /dev/null +++ b/CustomZeds/Classes/WMPawn_ZedClot_Slasher_Omega.uc @@ -0,0 +1,127 @@ +class WMPawn_ZedClot_Slasher_Omega extends KFPawn_ZedClot_Slasher; + +var const AnimSet SlasherOmegaAnimSet; +var const KFPawnAnimInfo SlasherOmegaAnimInfo; + +var transient ParticleSystemComponent SpecialFXPSCs[2]; +var const float ExtraAfflictionResistance, ExtraDamageResistance; + +static function string GetLocalizedName() +{ + return "Slasher Omega"; +} + +simulated function PostBeginPlay() +{ + IntendedBodyScale = 1.125f; + bVersusZed = True; + + Mesh.AnimSets.AddItem(default.SlasherOmegaAnimSet); + PawnAnimInfo = default.SlasherOmegaAnimInfo; + + super.PostBeginPlay(); + + UpdateGameplayMICParams(); + if (WorldInfo.NetMode != NM_DedicatedServer) + ApplySpecialFX(); +} + +simulated function PlayDying(class DamageType, vector HitLoc) +{ + if (WorldInfo.NetMode != NM_DedicatedServer) + EndSpecialFX(); + + super.PlayDying(DamageType, HitLoc); +} + +simulated function ApplySpecialFX() +{ + local Name SocketBoneName; + + SocketBoneName = Mesh.GetSocketBoneName('FX_EYE_L'); + if (SocketBoneName != '' && SocketBoneName != 'None') + SpecialFXPSCs[0] = WorldInfo.MyEmitterPool.SpawnEmitterMeshAttachment(ParticleSystem'ZedternalReborn_Zeds.FX_Omega', Mesh, 'FX_EYE_L', True, vect(0,0,0)); + + SocketBoneName = Mesh.GetSocketBoneName('FX_EYE_R'); + if (SocketBoneName != '' && SocketBoneName != 'None') + SpecialFXPSCs[1] = WorldInfo.MyEmitterPool.SpawnEmitterMeshAttachment(ParticleSystem'ZedternalReborn_Zeds.FX_Omega', Mesh, 'FX_EYE_R', True, vect(0,0,0)); +} + +simulated function EndSpecialFX() +{ + if (SpecialFXPSCs[0] != None && SpecialFXPSCs[0].bIsActive) + { + SpecialFXPSCs[0].DeactivateSystem(); + } + if (SpecialFXPSCs[1] != None && SpecialFXPSCs[1].bIsActive) + { + SpecialFXPSCs[1].DeactivateSystem(); + } +} + +simulated function UpdateGameplayMICParams() +{ + local byte i; + + super.UpdateGameplayMICParams(); + + if (WorldInfo.NetMode != NM_DedicatedServer) + { + for (i = 0; i < CharacterMICs.length; ++i) + { + CharacterMICs[i].SetVectorParameterValue('Vector_GlowColor', class'WMPawn_OmegaConstants'.default.OmegaColor); + CharacterMICs[i].SetVectorParameterValue('Vector_FresnelGlowColor', class'WMPawn_OmegaConstants'.default.OmegaFresnelColor); + } + } +} + +function float GetDamageTypeModifier(class DT) +{ + local float CurrentMod; + + // Omega ZEDs have extra resistance against all damage type + CurrentMod = super.GetDamageTypeModifier(DT); + return FMax(0.025f, CurrentMod - ExtraDamageResistance); +} + +simulated function AdjustAffliction(out float AfflictionPower) +{ + super.AdjustAffliction(AfflictionPower); + AfflictionPower *= 1.0f - ExtraAfflictionResistance; +} + +simulated event bool UsePlayerControlledZedSkin() +{ + return True; +} + +defaultproperties +{ + SlasherOmegaAnimSet=AnimSet'ZedternalReborn_Zeds.Slasher.Slasher_Clot_Omega_AnimSet' + SlasherOmegaAnimInfo=KFPawnAnimInfo'ZedternalReborn_Zeds.Slasher.Slasher_Clot_Omega_AnimGroup' + LocalizationKey="WMPawn_ZedSlasher_Omega" + + bVersusZed=False + DoshValue=15 + Health=250 + GroundSpeed=340.0f + SprintSpeed=580.0f + ParryResistance=1 + ExtraAfflictionResistance=0.15f + ExtraDamageResistance=0.15f + GrabAttackFrequency=0.6f + + Begin Object Name=MeleeHelper_0 + BaseDamage=10.0f + MaxHitRange=180.0f + End Object + + XPValues(0)=16 + XPValues(1)=22 + XPValues(2)=22 + XPValues(3)=22 + + HitZones(0)=(GoreHealth=150) + + Name="Default__WMPawn_ZedClot_Slasher_Omega" +} diff --git a/CustomZeds/Classes/WMPawn_ZedCrawler_Big.uc b/CustomZeds/Classes/WMPawn_ZedCrawler_Big.uc new file mode 100644 index 0000000..25acf8b --- /dev/null +++ b/CustomZeds/Classes/WMPawn_ZedCrawler_Big.uc @@ -0,0 +1,45 @@ +class WMPawn_ZedCrawler_Big extends WMPawn_ZedCrawler_NoElite; + +var const float ExtraDamageResistance; + +static function string GetLocalizedName() +{ + return "Big Crawler"; +} + +simulated function PostBeginPlay() +{ + IntendedBodyScale = 1.2f; + + super.PostBeginPlay(); +} + +function float GetDamageTypeModifier(class DT) +{ + local float CurrentMod; + + CurrentMod = super.GetDamageTypeModifier(DT); + return FMax(0.025f, CurrentMod - ExtraDamageResistance); +} + +defaultproperties +{ + DifficultySettings=Class'CustomZeds.WMDifficulty_Crawler_Big' + + bKnockdownWhenJumpedOn=False + DoshValue=12 + Health=145 + Mass=150.0f + GroundSpeed=485.0f + SprintSpeed=590.0f + ExtraDamageResistance=0.35f + + XPValues(0)=12 + XPValues(1)=15 + XPValues(2)=15 + XPValues(3)=15 + + HitZones(0)=(GoreHealth=125) + + Name="Default__WMPawn_ZedCrawler_Big" +} diff --git a/CustomZeds/Classes/WMPawn_ZedCrawler_Huge.uc b/CustomZeds/Classes/WMPawn_ZedCrawler_Huge.uc new file mode 100644 index 0000000..06063b3 --- /dev/null +++ b/CustomZeds/Classes/WMPawn_ZedCrawler_Huge.uc @@ -0,0 +1,45 @@ +class WMPawn_ZedCrawler_Huge extends WMPawn_ZedCrawler_NoElite; + +var const float ExtraDamageResistance; + +static function string GetLocalizedName() +{ + return "Huge Crawler"; +} + +simulated function PostBeginPlay() +{ + IntendedBodyScale = 1.55f; + + super.PostBeginPlay(); +} + +function float GetDamageTypeModifier(class DT) +{ + local float CurrentMod; + + CurrentMod = super.GetDamageTypeModifier(DT); + return FMax(0.025f, CurrentMod - ExtraDamageResistance); +} + +defaultproperties +{ + DifficultySettings=Class'CustomZeds.WMDifficulty_Crawler_Big' + + bKnockdownWhenJumpedOn=False + DoshValue=24 + Health=375 + Mass=300.0f + GroundSpeed=340.0f + SprintSpeed=420.0f + ExtraDamageResistance=0.55f + + XPValues(0)=16 + XPValues(1)=20 + XPValues(2)=20 + XPValues(3)=20 + + HitZones(0)=(GoreHealth=200) + + Name="Default__WMPawn_ZedCrawler_Huge" +} diff --git a/CustomZeds/Classes/WMPawn_ZedCrawler_Medium.uc b/CustomZeds/Classes/WMPawn_ZedCrawler_Medium.uc new file mode 100644 index 0000000..a1c83cf --- /dev/null +++ b/CustomZeds/Classes/WMPawn_ZedCrawler_Medium.uc @@ -0,0 +1,18 @@ +class WMPawn_ZedCrawler_Medium extends WMPawn_ZedCrawler_NoElite; + +static function string GetLocalizedName() +{ + return "Medium Crawler"; +} + +simulated function PostBeginPlay() +{ + IntendedBodyScale = 1.15f; + + super.PostBeginPlay(); +} + +defaultproperties +{ + Name="Default__WMPawn_ZedCrawler_Medium" +} diff --git a/CustomZeds/Classes/WMPawn_ZedCrawler_Mini.uc b/CustomZeds/Classes/WMPawn_ZedCrawler_Mini.uc new file mode 100644 index 0000000..f38040a --- /dev/null +++ b/CustomZeds/Classes/WMPawn_ZedCrawler_Mini.uc @@ -0,0 +1,29 @@ +class WMPawn_ZedCrawler_Mini extends WMPawn_ZedCrawler_NoElite; + +static function string GetLocalizedName() +{ + return "Baby Crawler"; +} + +simulated function PostBeginPlay() +{ + IntendedBodyScale = 0.65f; + + super.PostBeginPlay(); +} + +defaultproperties +{ + DoshValue=6 + Health=45 + Mass=30.0f + GroundSpeed=575.0f + SprintSpeed=675.0f + + XPValues(0)=6 + XPValues(1)=8 + XPValues(2)=8 + XPValues(3)=8 + + Name="Default__WMPawn_ZedCrawler_Mini" +} diff --git a/CustomZeds/Classes/WMPawn_ZedCrawler_NoElite.uc b/CustomZeds/Classes/WMPawn_ZedCrawler_NoElite.uc new file mode 100644 index 0000000..6a023ad --- /dev/null +++ b/CustomZeds/Classes/WMPawn_ZedCrawler_NoElite.uc @@ -0,0 +1,11 @@ +class WMPawn_ZedCrawler_NoElite extends KFPawn_ZedCrawler; + +static event class GetAIPawnClassToSpawn() +{ + return default.class; +} + +defaultproperties +{ + Name="Default__WMPawn_ZedCrawler_NoElite" +} diff --git a/CustomZeds/Classes/WMPawn_ZedCrawler_Ultra.uc b/CustomZeds/Classes/WMPawn_ZedCrawler_Ultra.uc new file mode 100644 index 0000000..8f2e0da --- /dev/null +++ b/CustomZeds/Classes/WMPawn_ZedCrawler_Ultra.uc @@ -0,0 +1,45 @@ +class WMPawn_ZedCrawler_Ultra extends WMPawn_ZedCrawler_NoElite; + +var const float ExtraDamageResistance; + +static function string GetLocalizedName() +{ + return "Ultra Crawler"; +} + +simulated function PostBeginPlay() +{ + IntendedBodyScale = 2.0f; + + super.PostBeginPlay(); +} + +function float GetDamageTypeModifier(class DT) +{ + local float CurrentMod; + + CurrentMod = super.GetDamageTypeModifier(DT); + return FMax(0.025f, CurrentMod - ExtraDamageResistance); +} + +defaultproperties +{ + DifficultySettings=Class'CustomZeds.WMDifficulty_Crawler_Big' + + bKnockdownWhenJumpedOn=False + DoshValue=48 + Health=530 + Mass=450.0f + GroundSpeed=270.0f + SprintSpeed=325.0f + ExtraDamageResistance=0.65f + + XPValues(0)=20 + XPValues(1)=25 + XPValues(2)=25 + XPValues(3)=25 + + HitZones(0)=(GoreHealth=300) + + Name="Default__WMPawn_ZedCrawler_Ultra" +} diff --git a/CustomZeds/Classes/WMPawn_ZedFleshpoundKing.uc b/CustomZeds/Classes/WMPawn_ZedFleshpoundKing.uc new file mode 100644 index 0000000..e731096 Binary files /dev/null and b/CustomZeds/Classes/WMPawn_ZedFleshpoundKing.uc differ diff --git a/CustomZeds/Classes/WMPawn_ZedFleshpound_Omega.uc b/CustomZeds/Classes/WMPawn_ZedFleshpound_Omega.uc new file mode 100644 index 0000000..53a2099 --- /dev/null +++ b/CustomZeds/Classes/WMPawn_ZedFleshpound_Omega.uc @@ -0,0 +1,209 @@ +class WMPawn_ZedFleshpound_Omega extends KFPawn_ZedFleshpound; + +var const AnimSet FleshpoundOmegaAnimSet; +var const KFPawnAnimInfo FleshpoundOmegaAnimInfo; +var const KFGameExplosion OmegaExplosionTemplate; + +var const float RallyRadius; +var const ParticleSystem RallyEffect, AltRallyEffect; +var const name RallyEffectBoneName; +var const name AltRallyEffectBoneNames[2]; +var const vector RallyEffectOffset, AltRallyEffectOffset; + +var transient ParticleSystemComponent SpecialFXPSCs[2]; +var const float ExtraAfflictionResistance, ExtraDamageResistance; + +static function string GetLocalizedName() +{ + return "Fleshpound Omega"; +} + +simulated function PostBeginPlay() +{ + IntendedBodyScale = 1.15f; + bVersusZed = True; + + Mesh.AnimSets.AddItem(FleshpoundOmegaAnimSet); + PawnAnimInfo = FleshpoundOmegaAnimInfo; + + super.PostBeginPlay(); + + UpdateGameplayMICParams(); + if (WorldInfo.NetMode != NM_DedicatedServer) + ApplySpecialFX(); +} + +simulated function PlayDying(class DamageType, vector HitLoc) +{ + if (WorldInfo.NetMode != NM_DedicatedServer) + EndSpecialFX(); + + super.PlayDying(DamageType, HitLoc); +} + +simulated function ApplySpecialFX() +{ + local Name SocketBoneName; + + SocketBoneName = Mesh.GetSocketBoneName('FX_EYE_L'); + if (SocketBoneName != '' && SocketBoneName != 'None') + SpecialFXPSCs[0] = WorldInfo.MyEmitterPool.SpawnEmitterMeshAttachment(ParticleSystem'ZedternalReborn_Zeds.FX_Omega', Mesh, 'FX_EYE_L', True, vect(0,0,0)); + + SocketBoneName = Mesh.GetSocketBoneName('FX_EYE_R'); + if (SocketBoneName != '' && SocketBoneName != 'None') + SpecialFXPSCs[1] = WorldInfo.MyEmitterPool.SpawnEmitterMeshAttachment(ParticleSystem'ZedternalReborn_Zeds.FX_Omega', Mesh, 'FX_EYE_R', True, vect(0,0,0)); +} + +simulated function EndSpecialFX() +{ + if (SpecialFXPSCs[0] != None && SpecialFXPSCs[0].bIsActive) + { + SpecialFXPSCs[0].DeactivateSystem(); + } + if (SpecialFXPSCs[1] != None && SpecialFXPSCs[1].bIsActive) + { + SpecialFXPSCs[1].DeactivateSystem(); + } +} + +simulated function UpdateGameplayMICParams() +{ + local byte i; + + super.UpdateGameplayMICParams(); + + if (WorldInfo.NetMode != NM_DedicatedServer) + { + for (i = 0; i < CharacterMICs.length; ++i) + { + CharacterMICs[i].SetVectorParameterValue('Vector_GlowColor', class'WMPawn_OmegaConstants'.default.OmegaColor); + CharacterMICs[i].SetVectorParameterValue('Vector_FresnelGlowColor', class'WMPawn_OmegaConstants'.default.OmegaFresnelColor); + } + } +} + +function float GetDamageTypeModifier(class DT) +{ + local float CurrentMod; + + // Omega ZEDs have extra resistance against all damage type + CurrentMod = super.GetDamageTypeModifier(DT); + return FMax(0.025f, CurrentMod - ExtraDamageResistance); +} + +simulated function AdjustAffliction(out float AfflictionPower) +{ + super.AdjustAffliction(AfflictionPower); + AfflictionPower *= 1.0f - ExtraAfflictionResistance; +} + +simulated function ANIMNOTIFY_OmegaKick() +{ + local vector ExploLocation; + + Mesh.GetSocketWorldLocationAndRotation('RightMG3_socket', ExploLocation); + TriggerOmegaExplosion(ExploLocation); +} + +simulated function TriggerOmegaExplosion(vector ExploLocation) +{ + local KFExplosionActor ExploActor; + + // Boom + ExploActor = Spawn(class'KFExplosionActor', self, , ExploLocation); + ExploActor.InstigatorController = Controller; + ExploActor.Instigator = self; + ExploActor.Explode(OmegaExplosionTemplate, vect(0,0,1)); +} + +simulated function bool SetEnraged(bool bNewEnraged) +{ + // Fleshpound Omega will rally nearby zeds (and self) while enraging + if (!bIsEnraged) + RallyZeds(); + + return super.SetEnraged(bNewEnraged); +} + +simulated function RallyZeds() +{ + local KFPawn_Monster KFPM; + local sRallyInfo NewRallyInfo; + local KFGameReplicationInfo KFGRI; + + // Rally nearby zeds + foreach WorldInfo.GRI.VisibleCollidingActors(class'KFPawn_Monster', KFPM, RallyRadius, Location) + { + if (KFPM.IsHeadless() || !KFPM.IsAliveAndWell() || WMPawn_ZedFleshpound_Omega(KFPM) != None) + { + continue; + } + //Force this ZEDs to sprint + // Set Rally setting + KFGRI = KFGameReplicationInfo(class'WorldInfo'.static.GetWorldInfo().GRI); + if (KFGRI != None) + { + NewRallyInfo = KFPM.DifficultySettings.static.GetRallySettings(KFPM, KFGRI); + NewRallyInfo.bCanRally = True; + NewRallyInfo.bCauseSprint = True; + KFPM.SetRallySettings(NewRallyInfo); + } + // Activate buffs and effects + KFPM.Rally(self, + RallyEffect, + RallyEffectBoneName, + RallyEffectOffset, + AltRallyEffect, + AltRallyEffectBoneNames, + AltRallyEffectOffset); + } +} + +simulated event bool UsePlayerControlledZedSkin() +{ + return True; +} + +defaultproperties +{ + FleshpoundOmegaAnimSet=AnimSet'ZedternalReborn_Zeds.Fleshpound.Fleshpound_Omega_AnimSet' + FleshpoundOmegaAnimInfo=KFPawnAnimInfo'ZedternalReborn_Zeds.Fleshpound.Fleshpound_Omega_AnimGroup' + OmegaExplosionTemplate=KFGameExplosion'KFGameContent.Default__KFPawn_ZedFleshpoundKing:ExploTemplate1' + RallyRadius=1750.0f + RallyEffect=ParticleSystem'ZedternalReborn_Zeds.Fleshpound.FX_Fleshpound_Rage_01' + AltRallyEffect=ParticleSystem'ZedternalReborn_Zeds.Fleshpound.FX_Fleshpound_Buff_01' + RallyEffectBoneName="Root" + AltRallyEffectBoneNames(0)="FX_EYE_L" + AltRallyEffectBoneNames(1)="FX_EYE_R" + RallyEffectOffset=(X=0.0f,Y=0.0f,Z=0.0f) + AltRallyEffectOffset=(X=0.0f,Y=0.0f,Z=0.0f) + LocalizationKey="WMPawn_ZedFleshpound_Omega" + + DefaultGlowColor=(G=0.25f) + FootstepCameraShakeInnerRadius=230.0f + FootstepCameraShakeOuterRadius=1035.0f + + bVersusZed=False + DoshValue=400 + Health=4000 + Mass=220.0f + GroundSpeed=460.0f + SprintSpeed=615.0f + ExtraAfflictionResistance=0.35f + ExtraDamageResistance=0.2f + + Begin Object Name=MeleeHelper_0 + BaseDamage=30.0f + MaxHitRange=260.0f + MomentumTransfer=65000.0f + End Object + + XPValues(0)=70 + XPValues(1)=94 + XPValues(2)=126 + XPValues(3)=144 + + HitZones(0)=(GoreHealth=1950) + + Name="Default__WMPawn_ZedFleshpound_Omega" +} diff --git a/CustomZeds/Classes/WMPawn_ZedFleshpound_Predator.uc b/CustomZeds/Classes/WMPawn_ZedFleshpound_Predator.uc new file mode 100644 index 0000000..cbad0ab --- /dev/null +++ b/CustomZeds/Classes/WMPawn_ZedFleshpound_Predator.uc @@ -0,0 +1,70 @@ +class WMPawn_ZedFleshpound_Predator extends KFPawn_ZedFleshpound; + +var linearColor PredatorColor; + +static function string GetLocalizedName() +{ + return "Fleshpound Predator"; +} + +simulated function PostBeginPlay() +{ + IntendedBodyScale = 1.3f; + bVersusZed = True; + + super.PostBeginPlay(); + + UpdateGameplayMICParams(); +} + +simulated function UpdateGameplayMICParams() +{ + local byte i; + + super.UpdateGameplayMICParams(); + + if(IsAliveAndWell() && WorldInfo.NetMode != NM_DedicatedServer) + { + for (i = 0; i < CharacterMICs.length; ++i) + { + CharacterMICs[i].SetVectorParameterValue('Vector_GlowColor', PredatorColor); + CharacterMICs[i].SetVectorParameterValue('Vector_FresnelGlowColor', PredatorColor); + } + } +} + +function bool CanBeGrabbed(KFPawn GrabbingPawn, optional bool bIgnoreFalling, optional bool bAllowSameTeamGrab) +{ + return False; +} + +simulated event bool UsePlayerControlledZedSkin() +{ + return True; +} + +defaultproperties +{ + ControllerClass=Class'CustomZeds.WMAIController_ZedFleshpound_Predator' + + DefaultGlowColor=(G=0.25f) + PredatorColor=(R=0.2f,G=1.0f,B=0.1f,A=1.0f) + FootstepCameraShakeInnerRadius=230.0f + FootstepCameraShakeOuterRadius=1035.0f + + bVersusZed=False + DoshValue=0 + Health=9999 + Mass=250.0f + GroundSpeed=500.0f + SprintSpeed=660.0f + + XPValues(0)=20 + XPValues(1)=25 + XPValues(2)=25 + XPValues(3)=30 + + HitZones(0)=(GoreHealth=9999) + + Name="Default__WMPawn_ZedFleshpound_Predator" +} diff --git a/CustomZeds/Classes/WMPawn_ZedGorefast_NoDualBlade.uc b/CustomZeds/Classes/WMPawn_ZedGorefast_NoDualBlade.uc new file mode 100644 index 0000000..554d051 --- /dev/null +++ b/CustomZeds/Classes/WMPawn_ZedGorefast_NoDualBlade.uc @@ -0,0 +1,11 @@ +class WMPawn_ZedGorefast_NoDualBlade extends KFPawn_ZedGorefast; + +static event class GetAIPawnClassToSpawn() +{ + return default.class; +} + +defaultproperties +{ + Name="WMPawn_ZedGorefast_NoDualBlade" +} diff --git a/CustomZeds/Classes/WMPawn_ZedGorefast_Omega.uc b/CustomZeds/Classes/WMPawn_ZedGorefast_Omega.uc new file mode 100644 index 0000000..9695b4e --- /dev/null +++ b/CustomZeds/Classes/WMPawn_ZedGorefast_Omega.uc @@ -0,0 +1,182 @@ +class WMPawn_ZedGorefast_Omega extends WMPawn_ZedGorefast_NoDualBlade; + +var const AnimSet GorefastOmegaAnimSet; +var const KFPawnAnimInfo GorefastOmegaAnimInfo; +var const KFSkinTypeEffects ShieldImpactEffects; + +var transient ParticleSystemComponent SpecialFXPSCs[2]; +var const float ExtraAfflictionResistance, ExtraDamageResistance; +var bool bShieldOn; + +replication +{ + if (Role == ROLE_Authority) + bShieldOn; +} + +static function string GetLocalizedName() +{ + return "Gorefast Omega"; +} + +simulated function PostBeginPlay() +{ + IntendedBodyScale = 1.14f; + bVersusZed = True; + + Mesh.AnimSets.AddItem(GorefastOmegaAnimSet); + PawnAnimInfo = GorefastOmegaAnimInfo; + + super.PostBeginPlay(); + + UpdateGameplayMICParams(); + if (WorldInfo.NetMode != NM_DedicatedServer) + ApplySpecialFX(); +} + +simulated function PlayDying(class DamageType, vector HitLoc) +{ + if (WorldInfo.NetMode != NM_DedicatedServer) + EndSpecialFX(); + + super.PlayDying(DamageType, HitLoc); +} + +simulated function ApplySpecialFX() +{ + local Name SocketBoneName; + + SocketBoneName = Mesh.GetSocketBoneName('FX_EYE_L'); + if (SocketBoneName != '' && SocketBoneName != 'None') + SpecialFXPSCs[0] = WorldInfo.MyEmitterPool.SpawnEmitterMeshAttachment(ParticleSystem'ZedternalReborn_Zeds.FX_Omega', Mesh, 'FX_EYE_L', True, vect(0,0,0)); + + SocketBoneName = Mesh.GetSocketBoneName('FX_EYE_R'); + if (SocketBoneName != '' && SocketBoneName != 'None') + SpecialFXPSCs[1] = WorldInfo.MyEmitterPool.SpawnEmitterMeshAttachment(ParticleSystem'ZedternalReborn_Zeds.FX_Omega', Mesh, 'FX_EYE_R', True, vect(0,0,0)); +} + +simulated function EndSpecialFX() +{ + if (SpecialFXPSCs[0] != None && SpecialFXPSCs[0].bIsActive) + { + SpecialFXPSCs[0].DeactivateSystem(); + } + if (SpecialFXPSCs[1] != None && SpecialFXPSCs[1].bIsActive) + { + SpecialFXPSCs[1].DeactivateSystem(); + } +} + +simulated function UpdateGameplayMICParams() +{ + local byte i; + + super.UpdateGameplayMICParams(); + + if (WorldInfo.NetMode != NM_DedicatedServer) + { + for (i = 0; i < CharacterMICs.length; ++i) + { + CharacterMICs[i].SetVectorParameterValue('Vector_GlowColor', class'WMPawn_OmegaConstants'.default.OmegaColor); + CharacterMICs[i].SetVectorParameterValue('Vector_FresnelGlowColor', class'WMPawn_OmegaConstants'.default.OmegaFresnelColor); + } + } +} + +function float GetDamageTypeModifier(class DT) +{ + local float CurrentMod; + + // Omega ZEDs have extra resistance against all damage type + CurrentMod = super.GetDamageTypeModifier(DT); + return FMax(0.025f, CurrentMod - ExtraDamageResistance); +} + +simulated function AdjustAffliction(out float AfflictionPower) +{ + super.AdjustAffliction(AfflictionPower); + AfflictionPower *= 1.0f - ExtraAfflictionResistance; +} + +event TakeDamage(int Damage, Controller InstigatedBy, vector HitLocation, vector Momentum, class DamageType, optional TraceHitInfo HitInfo, optional Actor DamageCauser) +{ + local int HitZoneIdx; + + HitZoneIdx = HitZones.Find('ZoneName', HitInfo.BoneName); + + if (bShieldOn && IsIncapacitated()) + bShieldOn = False; + + if (bShieldOn && HitZoneIdx < 9) + { + Damage = Max(0, int(float(Damage) * 0.25f)); + Momentum.X *= 0.15f; + Momentum.Y *= 0.15f; + Momentum.Z *= 0.15f; + } + + super.TakeDamage(Damage, InstigatedBy, HitLocation, Momentum, DamageType, HitInfo, DamageCauser); +} + +/** AnimNotify which turns on half-shield */ +simulated function ANIMNOTIFY_TurnShieldOn() +{ + bShieldOn = True; + SetTimer(1.4f, False, nameof(EndShield)); +} + +simulated function EndShield() +{ + bShieldOn = False; +} + +simulated function KFSkinTypeEffects GetHitZoneSkinTypeEffects(int HitZoneIdx) +{ + if (bShieldOn && HitZoneIdx < 9) + { + return ShieldImpactEffects; + } + else + return super.GetHitZoneSkinTypeEffects(HitZoneIdx); +} + +simulated function ApplyBloodDecals(int HitZoneIndex, vector HitLocation, vector HitDirection, name HitZoneName, name HitBoneName, class DmgType, bool bIsDismemberingHit, bool bWasObliterated) +{ + if (!bShieldOn || HitZoneIndex >= 9) + super.ApplyBloodDecals(HitZoneIndex, HitLocation, HitDirection, HitZoneName, HitBoneName, DmgType, bIsDismemberingHit, bWasObliterated); +} + +simulated event bool UsePlayerControlledZedSkin() +{ + return True; +} + +defaultproperties +{ + GorefastOmegaAnimSet=AnimSet'ZedternalReborn_Zeds.Gorefast.Gorefast_Omega_AnimSet' + GorefastOmegaAnimInfo=KFPawnAnimInfo'ZedternalReborn_Zeds.Gorefast.Gorefast_Omega_AnimGroup' + ShieldImpactEffects=KFSkinTypeEffects_InvulnerabilityShield'KFGameContent.Default__KFPawn_ZedHans:ShieldEffects' + ControllerClass=class'CustomZeds.WMAIController_ZedGorefast_Omega' + DifficultySettings=class'CustomZeds.WMDifficulty_Gorefast_Omega' + LocalizationKey="WMPawn_ZedGorefast_Omega" + + bShieldOn=False + bVersusZed=False + DoshValue=24 + Health=600 + GroundSpeed=285.0f + SprintSpeed=435.0f + ParryResistance=3 + PenetrationResistance=2.25f + ExtraAfflictionResistance=0.25f + ExtraDamageResistance=0.2f + + XPValues(0)=22 + XPValues(1)=28 + XPValues(2)=28 + XPValues(3)=28 + + HitZones(0)=(GoreHealth=400) + + Name="Default__WMPawn_ZedGorefast_Omega" +} diff --git a/CustomZeds/Classes/WMPawn_ZedHans.uc b/CustomZeds/Classes/WMPawn_ZedHans.uc new file mode 100644 index 0000000..8b06c1c --- /dev/null +++ b/CustomZeds/Classes/WMPawn_ZedHans.uc @@ -0,0 +1,46 @@ +class WMPawn_ZedHans extends KFPawn_ZedHans; + +var AkEvent EntranceSound; + +simulated event PostBeginPlay() +{ + // add entrance sound + SoundGroupArch.EntranceSound = default.EntranceSound; + + Super.PostBeginPlay(); +} + +/** Summon some children */ +function SummonChildren() +{ +} + +/** Play music for this boss (overridden for each boss) */ +function PlayBossMusic() +{ +} + +static simulated event bool IsABoss() +{ + return False; +} + +function bool CanBeGrabbed(KFPawn GrabbingPawn, optional bool bIgnoreFalling, optional bool bAllowSameTeamGrab) +{ + return False; +} + +defaultproperties +{ + EntranceSound=AkEvent'WW_ZED_Hans.Play_Hans_Intro_Land' + MinSpawnSquadSizeType=EST_Large + bLargeZed=True + DoshValue=500 + + XPValues(0)=250 + XPValues(1)=250 + XPValues(2)=250 + XPValues(3)=250 + + Name="Default__WMPawn_ZedHans" +} diff --git a/CustomZeds/Classes/WMPawn_ZedHusk_NoDAR.uc b/CustomZeds/Classes/WMPawn_ZedHusk_NoDAR.uc new file mode 100644 index 0000000..7586bd5 --- /dev/null +++ b/CustomZeds/Classes/WMPawn_ZedHusk_NoDAR.uc @@ -0,0 +1,11 @@ +class WMPawn_ZedHusk_NoDAR extends KFPawn_ZedHusk; + +static event class GetAIPawnClassToSpawn() +{ + return default.class; +} + +defaultproperties +{ + Name="Default__WMPawn_ZedHusk_NoDAR" +} diff --git a/CustomZeds/Classes/WMPawn_ZedHusk_Omega.uc b/CustomZeds/Classes/WMPawn_ZedHusk_Omega.uc new file mode 100644 index 0000000..47d35ab --- /dev/null +++ b/CustomZeds/Classes/WMPawn_ZedHusk_Omega.uc @@ -0,0 +1,228 @@ +class WMPawn_ZedHusk_Omega extends WMPawn_ZedHusk_NoDAR; + +var const AnimSet HuskOmegaAnimSet; +var const class SuicideFireballClass; +var const int ProjSuicideAmount; + +var transient ParticleSystemComponent SpecialFXPSCs[2]; +var const float ExtraAfflictionResistance, ExtraDamageResistance; + +static function string GetLocalizedName() +{ + return "Husk Omega"; +} + +function PossessedBy(Controller C, bool bVehicleTransition) +{ + local KFGameReplicationInfo KFGRI; + + super(KFPawn_Monster).PossessedBy(C, bVehicleTransition); + + // Set our difficulty-based settings + KFGRI = KFGameReplicationInfo(WorldInfo.GRI); + if(KFGRI != None) + { + FireballSettings = class(DifficultySettings).static.GetFireballSettings(self, KFGRI); + } +} + +simulated function PostBeginPlay() +{ + IntendedBodyScale = 1.14f; + bVersusZed = True; + Mesh.AnimSets.AddItem(HuskOmegaAnimSet); + + super.PostBeginPlay(); + + UpdateGameplayMICParams(); + if (WorldInfo.NetMode != NM_DedicatedServer) + ApplySpecialFX(); +} + +simulated function PlayDying(class DamageType, vector HitLoc) +{ + if (WorldInfo.NetMode != NM_DedicatedServer) + EndSpecialFX(); + + super.PlayDying(DamageType, HitLoc); +} + +simulated function ApplySpecialFX() +{ + local Name SocketBoneName; + + SocketBoneName = Mesh.GetSocketBoneName('FX_EYE_L'); + if (SocketBoneName != '' && SocketBoneName != 'None') + SpecialFXPSCs[0] = WorldInfo.MyEmitterPool.SpawnEmitterMeshAttachment(ParticleSystem'ZedternalReborn_Zeds.FX_Omega', Mesh, 'FX_EYE_L', True, vect(0,0,0)); + + SocketBoneName = Mesh.GetSocketBoneName('FX_EYE_R'); + if (SocketBoneName != '' && SocketBoneName != 'None') + SpecialFXPSCs[1] = WorldInfo.MyEmitterPool.SpawnEmitterMeshAttachment(ParticleSystem'ZedternalReborn_Zeds.FX_Omega', Mesh, 'FX_EYE_R', True, vect(0,0,0)); +} + +simulated function EndSpecialFX() +{ + if (SpecialFXPSCs[0] != None && SpecialFXPSCs[0].bIsActive) + { + SpecialFXPSCs[0].DeactivateSystem(); + } + if (SpecialFXPSCs[1] != None && SpecialFXPSCs[1].bIsActive) + { + SpecialFXPSCs[1].DeactivateSystem(); + } +} + +simulated function UpdateGameplayMICParams() +{ + local byte i; + + super.UpdateGameplayMICParams(); + + if (WorldInfo.NetMode != NM_DedicatedServer) + { + for (i = 0; i < CharacterMICs.length; ++i) + { + CharacterMICs[i].SetVectorParameterValue('Vector_GlowColor', class'WMPawn_OmegaConstants'.default.OmegaColor); + CharacterMICs[i].SetVectorParameterValue('Vector_FresnelGlowColor', class'WMPawn_OmegaConstants'.default.OmegaFresnelColor); + } + } +} + +function float GetDamageTypeModifier(class DT) +{ + local float CurrentMod; + + // Omega ZEDs have extra resistance against all damage type + CurrentMod = super.GetDamageTypeModifier(DT); + return FMax(0.025f, CurrentMod - ExtraDamageResistance); +} + +simulated function AdjustAffliction(out float AfflictionPower) +{ + super.AdjustAffliction(AfflictionPower); + AfflictionPower *= 1.0f - ExtraAfflictionResistance; +} + +/** AnimNotify which launches the fireball projectile */ +function ANIMNOTIFY_HuskRandomFireballAttack() +{ + local WMAIController_ZedHusk_Omega HuskAIC; + local WMSM_Husk_Omega_FireBallBarrageAttack FireballBarrageSM; + + if (MyKFAIC != None) + { + HuskAIC = WMAIController_ZedHusk_Omega(MyKFAIC); + if (HuskAIC != None) + { + FireballBarrageSM = WMSM_Husk_Omega_FireBallBarrageAttack(SpecialMoves[SpecialMove]); + HuskAIC.ShootFireballBarrage(default.SuicideFireballClass, FireballBarrageSM.GetFireOffset()); + } + } +} + +/** Called when husk backpack is exploded or when husk suicides */ +function TriggerExplosion(optional bool bIgnoreHumans) +{ + local KFExplosionActorReplicated ExploActor; + local Controller DamageInstigator, OldController; + local bool bExplodeOnDeath; + local WMAIController_ZedHusk_Omega HuskAIC; + local byte i; + + bExplodeOnDeath = WorldInfo.TimeSeconds == TimeOfDeath; + + // Only living husks can explode... and only once + if (!bHasExploded && (!bPlayedDeath || bExplodeOnDeath)) + { + OldController = Controller; + bHasExploded = True; + bHasSuicideExploded = !bIgnoreHumans; + + if (Role == ROLE_Authority) + { + // explode using the given template + ExploActor = Spawn(class'KFExplosionActorReplicated', self); + if (ExploActor != None) + { + DamageInstigator = (bIgnoreHumans && LastHitBy != None && KFPlayerController(LastHitBy) != None) ? LastHitBy : MyKFAIC; + ExploActor.InstigatorController = DamageInstigator; + ExploActor.Instigator = self; + + // Force ourselves to get hit. These settings are not replicated, + // but they only really make a difference on the server anyway. + ExploActor.Attachee = self; + if (bIgnoreHumans) + { + ExplosionTemplate.ActorClassToIgnoreForDamage = class'KFPawn_Human'; + } + else + { + ExplosionTemplate.ActorClassToIgnoreForDamage = None; + } + + ExploActor.Explode(ExplosionTemplate, vect(0,0,1)); + } + + HuskAIC = WMAIController_ZedHusk_Omega(MyKFAIC); + if (!bIgnoreHumans && MyKFAIC != None && HuskAIC != None) + { + for (i = 0; i < ProjSuicideAmount; ++i) + { + HuskAIC.ShootRandomFireball(default.SuicideFireballClass); + } + } + + // Make sure we're dead! + if (!bPlayedDeath || bExplodeOnDeath) + { + TakeRadiusDamage(DamageInstigator, 10000, ExplosionTemplate.DamageRadius, ExplosionTemplate.MyDamageType, ExplosionTemplate.MomentumTransferScale, Location, True, self); + } + } + + OnExploded(OldController); + } +} + +simulated event bool UsePlayerControlledZedSkin() +{ + return True; +} + +defaultproperties +{ + HuskOmegaAnimSet=AnimSet'ZedternalReborn_Zeds.Husk.Husk_Omega_AnimSet' + SuicideFireballClass=class'CustomZeds.WMProj_Husk_Fireball_Suicide' + ControllerClass=class'CustomZeds.WMAIController_ZedHusk_Omega' + DifficultySettings=class'CustomZeds.WMDifficulty_Husk_Omega' + LocalizationKey="WMPawn_ZedHusk_Omega" + + bVersusZed=False + DoshValue=34 + Health=820 + GroundSpeed=230.0f + SprintSpeed=580.0f + ParryResistance=3 + PenetrationResistance=3.0f + ExtraAfflictionResistance=0.3f + ExtraDamageResistance=0.2f + ProjSuicideAmount=12 + + Begin Object Name=MeleeHelper_0 + BaseDamage=20.0f + MomentumTransfer=30000.0f + End Object + + Begin Object Name=SpecialMoveHandler_0 + SpecialMoveClasses(SM_Custom1) = class'CustomZeds.WMSM_Husk_Omega_FireBallBarrageAttack' + End Object + + XPValues(0)=30 + XPValues(1)=40 + XPValues(2)=54 + XPValues(3)=62 + + HitZones(0)=(GoreHealth=430) + HitZones(3)=(GoreHealth=180) + + Name="Default__WMPawn_ZedHusk_Omega" +} diff --git a/CustomZeds/Classes/WMPawn_ZedHusk_Tiny.uc b/CustomZeds/Classes/WMPawn_ZedHusk_Tiny.uc new file mode 100644 index 0000000..54abdac --- /dev/null +++ b/CustomZeds/Classes/WMPawn_ZedHusk_Tiny.uc @@ -0,0 +1,55 @@ +class WMPawn_ZedHusk_Tiny extends WMPawn_ZedHusk_NoDAR; + +var linearColor glowColor; + +static function string GetLocalizedName() +{ + return "Tiny Husk"; +} + +function PossessedBy(Controller C, bool bVehicleTransition) +{ + super.PossessedBy(C, bVehicleTransition); + + if (KFAIController_ZedHusk(C) != None) + KFAIController_ZedHusk(C).RequiredHealthPercentForSuicide = 1.0f; +} + +simulated function PostBeginPlay() +{ + IntendedBodyScale = 0.7f; + + super.PostBeginPlay(); + + UpdateGameplayMICParams(); +} + +simulated function UpdateGameplayMICParams() +{ + local byte i; + + super.UpdateGameplayMICParams(); + + if(WorldInfo.NetMode != NM_DedicatedServer) + { + for (i = 0; i < CharacterMICs.length; ++i) + { + CharacterMICs[i].SetVectorParameterValue('Vector_GlowColor', default.glowColor); + } + } +} + +defaultproperties +{ + glowColor=(R=1.0f, G=1.0f, B=1.0f) + + Health=225 + GroundSpeed=480.0f + SprintSpeed=480.0f + + Begin Object Class=WMExplosion_TinyHusk Name=TinyExploTemplate0 + End Object + ExplosionTemplate=TinyExploTemplate0 + + Name="Default__WMPawn_ZedHusk_Tiny" +} diff --git a/CustomZeds/Classes/WMPawn_ZedHusk_Tiny_Blue.uc b/CustomZeds/Classes/WMPawn_ZedHusk_Tiny_Blue.uc new file mode 100644 index 0000000..7bdcaba --- /dev/null +++ b/CustomZeds/Classes/WMPawn_ZedHusk_Tiny_Blue.uc @@ -0,0 +1,23 @@ +class WMPawn_ZedHusk_Tiny_Blue extends WMPawn_ZedHusk_Tiny; + +static function string GetLocalizedName() +{ + return "Blue Tiny Husk"; +} + +defaultproperties +{ + glowColor=(R=0.6f, G=2.5f, B=5.0f) + + Begin Object Class=PointLightComponent Name=ExplosionPointLightBlue + LightColor=(R=31, G=128, B=255, A=255) + bCastPerObjectShadows=False + End Object + + Begin Object Name=TinyExploTemplate0 + ExplosionEffects=KFImpactEffectInfo'ZedternalReborn_Zeds.Husk.FX_Husk_Tiny_Explosion_Blue' + ExploLight=ExplosionPointLightBlue + End Object + + Name="Default__WMPawn_ZedHusk_Tiny_Blue" +} diff --git a/CustomZeds/Classes/WMPawn_ZedHusk_Tiny_Green.uc b/CustomZeds/Classes/WMPawn_ZedHusk_Tiny_Green.uc new file mode 100644 index 0000000..2af2dcc --- /dev/null +++ b/CustomZeds/Classes/WMPawn_ZedHusk_Tiny_Green.uc @@ -0,0 +1,23 @@ +class WMPawn_ZedHusk_Tiny_Green extends WMPawn_ZedHusk_Tiny; + +static function string GetLocalizedName() +{ + return "Green Tiny Husk"; +} + +defaultproperties +{ + glowColor=(R=0.6f, G=5.0f, B=0.6f) + + Begin Object Class=PointLightComponent Name=ExplosionPointLightGreen + LightColor=(R=31, G=255, B=31, A=255) + bCastPerObjectShadows=False + End Object + + Begin Object Name=TinyExploTemplate0 + ExplosionEffects=KFImpactEffectInfo'ZedternalReborn_Zeds.Husk.FX_Husk_Tiny_Explosion_Green' + ExploLight=ExplosionPointLightGreen + End Object + + Name="Default__WMPawn_ZedHusk_Tiny_Green" +} diff --git a/CustomZeds/Classes/WMPawn_ZedHusk_Tiny_Pink.uc b/CustomZeds/Classes/WMPawn_ZedHusk_Tiny_Pink.uc new file mode 100644 index 0000000..2314506 --- /dev/null +++ b/CustomZeds/Classes/WMPawn_ZedHusk_Tiny_Pink.uc @@ -0,0 +1,23 @@ +class WMPawn_ZedHusk_Tiny_Pink extends WMPawn_ZedHusk_Tiny; + +static function string GetLocalizedName() +{ + return "Pink Tiny Husk"; +} + +defaultproperties +{ + glowColor=(R=5.0f, G=0.6f, B=1.8f) + + Begin Object Class=PointLightComponent Name=ExplosionPointLightPink + LightColor=(R=255, G=31, B=92, A=255) + bCastPerObjectShadows=False + End Object + + Begin Object Name=TinyExploTemplate0 + ExplosionEffects=KFImpactEffectInfo'ZedternalReborn_Zeds.Husk.FX_Husk_Tiny_Explosion_Pink' + ExploLight=ExplosionPointLightPink + End Object + + Name="Default__WMPawn_ZedHusk_Tiny_Pink" +} diff --git a/CustomZeds/Classes/WMPawn_ZedMatriarch.uc b/CustomZeds/Classes/WMPawn_ZedMatriarch.uc new file mode 100644 index 0000000..301bb7b --- /dev/null +++ b/CustomZeds/Classes/WMPawn_ZedMatriarch.uc @@ -0,0 +1,46 @@ +class WMPawn_ZedMatriarch extends KFPawn_ZedMatriarch; + +var AkEvent EntranceSound; + +simulated event PostBeginPlay() +{ + // add entrance sound + SoundGroupArch.EntranceSound = default.EntranceSound; + + Super.PostBeginPlay(); +} + +/** Summon some children */ +function SummonChildren() +{ +} + +/** Play music for this boss (overridden for each boss) */ +function PlayBossMusic() +{ +} + +static simulated event bool IsABoss() +{ + return False; +} + +function bool CanBeGrabbed(KFPawn GrabbingPawn, optional bool bIgnoreFalling, optional bool bAllowSameTeamGrab) +{ + return False; +} + +defaultproperties +{ + EntranceSound=AkEvent'WW_ZED_Matriarch.Play_Matriarch_Jump_Land_01' + MinSpawnSquadSizeType=EST_Large + bLargeZed=True + DoshValue=500 + + XPValues(0)=250 + XPValues(1)=250 + XPValues(2)=250 + XPValues(3)=250 + + Name="Default__WMPawn_ZedMatriarch" +} diff --git a/CustomZeds/Classes/WMPawn_ZedPatriarch.uc b/CustomZeds/Classes/WMPawn_ZedPatriarch.uc new file mode 100644 index 0000000..7c14fd5 --- /dev/null +++ b/CustomZeds/Classes/WMPawn_ZedPatriarch.uc @@ -0,0 +1,46 @@ +class WMPawn_ZedPatriarch extends KFPawn_ZedPatriarch; + +var AkEvent EntranceSound; + +simulated event PostBeginPlay() +{ + // add entrance sound + SoundGroupArch.EntranceSound = default.EntranceSound; + + Super.PostBeginPlay(); +} + +/** Summon some children */ +function SummonChildren() +{ +} + +/** Play music for this boss (overridden for each boss) */ +function PlayBossMusic() +{ +} + +static simulated event bool IsABoss() +{ + return False; +} + +function bool CanBeGrabbed(KFPawn GrabbingPawn, optional bool bIgnoreFalling, optional bool bAllowSameTeamGrab) +{ + return False; +} + +defaultproperties +{ + EntranceSound=AkEvent'WW_ZED_Patriarch.Play_Pat_Intro_Roar' + MinSpawnSquadSizeType=EST_Large + bLargeZed=True + DoshValue=500 + + XPValues(0)=250 + XPValues(1)=250 + XPValues(2)=250 + XPValues(3)=250 + + Name="Default__WMPawn_ZedPatriarch" +} diff --git a/CustomZeds/Classes/WMPawn_ZedScrake_Emperor.uc b/CustomZeds/Classes/WMPawn_ZedScrake_Emperor.uc new file mode 100644 index 0000000..4a26c39 --- /dev/null +++ b/CustomZeds/Classes/WMPawn_ZedScrake_Emperor.uc @@ -0,0 +1,60 @@ +class WMPawn_ZedScrake_Emperor extends KFPawn_ZedScrake; + +var const AnimSet ScrakeOmegaAnimSet; +var const KFPawnAnimInfo ScrakeOmegaAnimInfo; + +static function string GetLocalizedName() +{ + return "Scrake Emperor"; +} + +simulated function PostBeginPlay() +{ + IntendedBodyScale = 1.4f; + bVersusZed = True; + + Mesh.AnimSets.AddItem(ScrakeOmegaAnimSet); + PawnAnimInfo = ScrakeOmegaAnimInfo; + + super.PostBeginPlay(); +} + +simulated event bool UsePlayerControlledZedSkin() +{ + return True; +} + +defaultproperties +{ + ScrakeOmegaAnimSet=AnimSet'ZedternalReborn_Zeds.Scrake.Scrake_Omega_AnimSet' + ScrakeOmegaAnimInfo=KFPawnAnimInfo'ZedternalReborn_Zeds.Scrake.Scrake_Omega_AnimGroup' + DifficultySettings=class'CustomZeds.WMDifficulty_Scrake_Emperor' + LocalizationKey="WMPawn_ZedScrake_Emperor" + + RageHealthThresholdNormal=0.2f + RageHealthThresholdHard=0.225f + RageHealthThresholdSuicidal=0.25f + RageHealthThresholdHellOnEarth=0.275f + + bVersusZed=False + DoshValue=400 + Health=4000 + Mass=225.0f + GroundSpeed=180.0f + SprintSpeed=640.0f + + Begin Object Name=MeleeHelper_0 + BaseDamage=20.0f + MomentumTransfer=60000.0f + End Object + + XPValues(0)=75 + XPValues(1)=100 + XPValues(2)=135 + XPValues(3)=150 + + HitZones(0)=(GoreHealth=3000) + HitZones(8)=(GoreHealth=75, DmgScale=0.1f) + + Name="Default__WMPawn_ZedScrake_Emperor" +} diff --git a/CustomZeds/Classes/WMPawn_ZedScrake_Omega.uc b/CustomZeds/Classes/WMPawn_ZedScrake_Omega.uc new file mode 100644 index 0000000..70a1c14 --- /dev/null +++ b/CustomZeds/Classes/WMPawn_ZedScrake_Omega.uc @@ -0,0 +1,173 @@ +class WMPawn_ZedScrake_Omega extends KFPawn_ZedScrake; + +var const AnimSet ScrakeOmegaAnimSet; +var const KFPawnAnimInfo ScrakeOmegaAnimInfo; + +var transient ParticleSystemComponent SpecialFXPSCs[2]; +var const float ExtraAfflictionResistance, ExtraDamageResistance; + +static function string GetLocalizedName() +{ + return "Scrake Omega"; +} + +simulated function PostBeginPlay() +{ + IntendedBodyScale = 1.16f; + bVersusZed = True; + + Mesh.AnimSets.AddItem(ScrakeOmegaAnimSet); + PawnAnimInfo = ScrakeOmegaAnimInfo; + + super.PostBeginPlay(); + + UpdateGameplayMICParams(); + if (WorldInfo.NetMode != NM_DedicatedServer) + ApplySpecialFX(); +} + +simulated function PlayDying(class DamageType, vector HitLoc) +{ + if (WorldInfo.NetMode != NM_DedicatedServer) + EndSpecialFX(); + + super.PlayDying(DamageType, HitLoc); +} + +simulated function ApplySpecialFX() +{ + local Name SocketBoneName; + + SocketBoneName = Mesh.GetSocketBoneName('FX_EYE_L'); + if (SocketBoneName != '' && SocketBoneName != 'None') + SpecialFXPSCs[0] = WorldInfo.MyEmitterPool.SpawnEmitterMeshAttachment(ParticleSystem'ZedternalReborn_Zeds.FX_Omega', Mesh, 'FX_EYE_L', True, vect(0,0,0)); + + SocketBoneName = Mesh.GetSocketBoneName('FX_EYE_R'); + if (SocketBoneName != '' && SocketBoneName != 'None') + SpecialFXPSCs[1] = WorldInfo.MyEmitterPool.SpawnEmitterMeshAttachment(ParticleSystem'ZedternalReborn_Zeds.FX_Omega', Mesh, 'FX_EYE_R', True, vect(0,0,0)); +} + +simulated function EndSpecialFX() +{ + if (SpecialFXPSCs[0] != None && SpecialFXPSCs[0].bIsActive) + { + SpecialFXPSCs[0].DeactivateSystem(); + } + if (SpecialFXPSCs[1] != None && SpecialFXPSCs[1].bIsActive) + { + SpecialFXPSCs[1].DeactivateSystem(); + } +} + +simulated function UpdateGameplayMICParams() +{ + local byte i; + + super.UpdateGameplayMICParams(); + + if (WorldInfo.NetMode != NM_DedicatedServer) + { + for (i = 0; i < CharacterMICs.length; ++i) + { + CharacterMICs[i].SetVectorParameterValue('Vector_GlowColor', class'WMPawn_OmegaConstants'.default.OmegaColor); + CharacterMICs[i].SetVectorParameterValue('Vector_FresnelGlowColor', class'WMPawn_OmegaConstants'.default.OmegaFresnelColor); + } + } +} + +function float GetDamageTypeModifier(class DT) +{ + local float CurrentMod; + + // Omega ZEDs have extra resistance against all damage type + CurrentMod = super.GetDamageTypeModifier(DT); + return FMax(0.025f, CurrentMod - ExtraDamageResistance); +} + +simulated function AdjustAffliction(out float AfflictionPower) +{ + super.AdjustAffliction(AfflictionPower); + AfflictionPower *= 1.0f - ExtraAfflictionResistance; +} + +function CauseHeadTrauma(float BleedOutTime = 5.0f) +{ + if (!bIsHeadless && !bPlayedDeath && !bDisableHeadless) + { + if (MyKFAIC != None && KFGameInfo(WorldInfo.Game) != None && MyKFAIC.TimeFirstSawPlayer >= 0) + { + KFGameInfo(WorldInfo.Game).GameConductor.HandleZedKill(FMax(`TimeSince(MyKFAIC.TimeFirstSawPlayer), 0.0f)); + MyKFAIC.TimeFirstSawPlayer = -1; + } + + bPlayShambling = True; + bIsHeadless = True; + + if (MyKFAIC != None) + { + MyKFAIC.SetSprintingDisabled(True); + } + + bCanBeAdheredTo = False; + bCanBeFrictionedTo = False; + + StopAkEventsOnBone('head'); + + if (IsDoingSpecialMove() && Mesh.RootMotionMode == RMM_Accel) + { + Died(LastHitBy, class'DamageType', Location); + } + + if (IsAliveAndWell() && MyKFAIC != None) + { + if (SpecialMove == SM_None || !SpecialMoves[SpecialMove].bCanOnlyWanderAtEnd) + { + MyKFAIC.DoHeadlessWander(); + } + } + + if (BleedOutTime > 0) + { + SetTimer(FMax(7.0f, BleedOutTime), False, nameof(BleedOutTimer)); + } + } +} + +simulated event bool UsePlayerControlledZedSkin() +{ + return True; +} + +defaultproperties +{ + ScrakeOmegaAnimSet=AnimSet'ZedternalReborn_Zeds.Scrake.Scrake_Omega_AnimSet' + ScrakeOmegaAnimInfo=KFPawnAnimInfo'ZedternalReborn_Zeds.Scrake.Scrake_Omega_AnimGroup' + LocalizationKey="WMPawn_ZedScrake_Omega" + + RageHealthThresholdNormal=0.6f + RageHealthThresholdHard=0.7f + RageHealthThresholdSuicidal=0.75f + RageHealthThresholdHellOnEarth=0.8f + + bVersusZed=False + DoshValue=150 + Health=3800 + Mass=150.0f + GroundSpeed=215.0f + SprintSpeed=700.0f + ExtraAfflictionResistance=0.4f + ExtraDamageResistance=0.3f + + Begin Object Name=MeleeHelper_0 + BaseDamage=50.0f + End Object + + XPValues(0)=68 + XPValues(1)=90 + XPValues(2)=120 + XPValues(3)=138 + + HitZones(0)=(GoreHealth=1800) + + Name="Default__WMPawn_ZedScrake_Omega" +} diff --git a/CustomZeds/Classes/WMPawn_ZedScrake_Tiny.uc b/CustomZeds/Classes/WMPawn_ZedScrake_Tiny.uc new file mode 100644 index 0000000..74bbd60 --- /dev/null +++ b/CustomZeds/Classes/WMPawn_ZedScrake_Tiny.uc @@ -0,0 +1,101 @@ +class WMPawn_ZedScrake_Tiny extends KFPawn_ZedScrake; + +var const AnimSet ScrakeTinyAnimSet; +var const AnimSet ScrakeOmegaAnimSet; +var const KFPawnAnimInfo ScrakeTinyAnimInfo; + +static function string GetLocalizedName() +{ + return "Tiny Scrake"; +} + +simulated function PostBeginPlay() +{ + IntendedBodyScale = 0.75f; + + Mesh.AnimSets.AddItem(ScrakeTinyAnimSet); + Mesh.AnimSets.AddItem(ScrakeOmegaAnimSet); + PawnAnimInfo = ScrakeTinyAnimInfo; + + super.PostBeginPlay(); + + SetEnraged(True); +} + +function CauseHeadTrauma(float BleedOutTime = 5.0f) +{ + if (!bIsHeadless && !bPlayedDeath && !bDisableHeadless) + { + if (MyKFAIC != None && KFGameInfo(WorldInfo.Game) != None && MyKFAIC.TimeFirstSawPlayer >= 0) + { + KFGameInfo(WorldInfo.Game).GameConductor.HandleZedKill(FMax(`TimeSince(MyKFAIC.TimeFirstSawPlayer), 0.0f)); + MyKFAIC.TimeFirstSawPlayer = -1; + } + + bPlayShambling = True; + bIsHeadless = True; + + if (MyKFAIC != None) + { + MyKFAIC.SetSprintingDisabled(True); + } + + bCanBeAdheredTo = False; + bCanBeFrictionedTo = False; + + StopAkEventsOnBone('head'); + + if (IsDoingSpecialMove() && Mesh.RootMotionMode == RMM_Accel) + { + Died(LastHitBy, class'DamageType', Location); + } + + if (IsAliveAndWell() && MyKFAIC != None) + { + if (SpecialMove == SM_None || !SpecialMoves[SpecialMove].bCanOnlyWanderAtEnd) + { + MyKFAIC.DoHeadlessWander(); + } + } + + if (BleedOutTime > 0) + { + SetTimer(FMax(7.0f, BleedOutTime), False, nameof(BleedOutTimer)); + } + } +} + +defaultproperties +{ + ScrakeTinyAnimSet=AnimSet'ZedternalReborn_Zeds.Scrake.Tiny_Scrake_AnimSet' + ScrakeOmegaAnimSet=AnimSet'ZedternalReborn_Zeds.Scrake.Scrake_Omega_AnimSet' + ScrakeTinyAnimInfo=KFPawnAnimInfo'ZedternalReborn_Zeds.Scrake.Tiny_Scrake_AnimGroup' + LocalizationKey="WMPawn_ZedScrake_Omega" + + RageHealthThresholdNormal=0.99f + RageHealthThresholdHard=0.99f + RageHealthThresholdSuicidal=0.99f + RageHealthThresholdHellOnEarth=0.99f + + DoshValue=55 + Health=600 + Mass=150.0f + GroundSpeed=540.0f + SprintSpeed=680.0f + + Begin Object Name=MeleeHelper_0 + BaseDamage=15.0f + MaxHitRange=180.0f + MomentumTransfer=30000.0f + End Object + + XPValues(0)=35 + XPValues(1)=42 + XPValues(2)=45 + XPValues(3)=52 + + HitZones(0)=(GoreHealth=400) + HitZones(8)=(GoreHealth=25) + + Name="Default__WMPawn_ZedScrake_Tiny" +} diff --git a/CustomZeds/Classes/WMPawn_ZedSiren_Omega.uc b/CustomZeds/Classes/WMPawn_ZedSiren_Omega.uc new file mode 100644 index 0000000..1967e35 --- /dev/null +++ b/CustomZeds/Classes/WMPawn_ZedSiren_Omega.uc @@ -0,0 +1,125 @@ +class WMPawn_ZedSiren_Omega extends KFPawn_ZedSiren; + +var transient ParticleSystemComponent SpecialFXPSCs[2]; +var const float ExtraAfflictionResistance, ExtraDamageResistance; + +static function string GetLocalizedName() +{ + return "Siren Omega"; +} + +simulated function PostBeginPlay() +{ + IntendedBodyScale = 0.92f; + bVersusZed = True; + + super.PostBeginPlay(); + + UpdateGameplayMICParams(); + if (WorldInfo.NetMode != NM_DedicatedServer) + ApplySpecialFX(); +} + +simulated function PlayDying(class DamageType, vector HitLoc) +{ + if (WorldInfo.NetMode != NM_DedicatedServer) + EndSpecialFX(); + + super.PlayDying(DamageType, HitLoc); +} + +simulated function ApplySpecialFX() +{ + local Name SocketBoneName; + + SocketBoneName = Mesh.GetSocketBoneName('FX_EYE_L'); + if (SocketBoneName != '' && SocketBoneName != 'None') + SpecialFXPSCs[0] = WorldInfo.MyEmitterPool.SpawnEmitterMeshAttachment(ParticleSystem'ZedternalReborn_Zeds.FX_Omega', Mesh, 'FX_EYE_L', True, vect(0,0,0)); + + SocketBoneName = Mesh.GetSocketBoneName('FX_EYE_R'); + if (SocketBoneName != '' && SocketBoneName != 'None') + SpecialFXPSCs[1] = WorldInfo.MyEmitterPool.SpawnEmitterMeshAttachment(ParticleSystem'ZedternalReborn_Zeds.FX_Omega', Mesh, 'FX_EYE_R', True, vect(0,0,0)); +} + +simulated function EndSpecialFX() +{ + if (SpecialFXPSCs[0] != None && SpecialFXPSCs[0].bIsActive) + { + SpecialFXPSCs[0].DeactivateSystem(); + } + if (SpecialFXPSCs[1] != None && SpecialFXPSCs[1].bIsActive) + { + SpecialFXPSCs[1].DeactivateSystem(); + } +} + +function SetSprinting(bool bNewSprintStatus) +{ + + if (Health == HealthMax) + super.SetSprinting(False); + else + super.SetSprinting(bNewSprintStatus); +} + +simulated function UpdateGameplayMICParams() +{ + local byte i; + + super.UpdateGameplayMICParams(); + + if (WorldInfo.NetMode != NM_DedicatedServer) + { + for (i = 0; i < CharacterMICs.length; ++i) + { + CharacterMICs[i].SetVectorParameterValue('Vector_GlowColor', class'WMPawn_OmegaConstants'.default.OmegaColor); + CharacterMICs[i].SetVectorParameterValue('Vector_FresnelGlowColor', class'WMPawn_OmegaConstants'.default.OmegaFresnelColor); + } + } +} + +function float GetDamageTypeModifier(class DT) +{ + local float CurrentMod; + + // Omega ZEDs have extra resistance against all damage type + CurrentMod = super.GetDamageTypeModifier(DT); + return FMax(0.025f, CurrentMod - ExtraDamageResistance); +} + +simulated function AdjustAffliction(out float AfflictionPower) +{ + super.AdjustAffliction(AfflictionPower); + AfflictionPower *= 1.0f - ExtraAfflictionResistance; +} + +simulated event bool UsePlayerControlledZedSkin() +{ + return True; +} + +defaultproperties +{ + DifficultySettings=Class'CustomZeds.WMDifficulty_Siren_Omega' + + bVersusZed=False + DoshValue=50 + Health=275 + GroundSpeed=180.0f + SprintSpeed=245.0f + ExtraAfflictionResistance=0.2f + ExtraDamageResistance=0.1f + + Begin Object Name=NeckLightComponent0 + LightColor=(R=255,G=64,B=128,A=255) + End Object + + XPValues(0)=22 + XPValues(1)=30 + XPValues(2)=30 + XPValues(3)=30 + + HitZones(0)=(GoreHealth=180) + + Name="Default__WMPawn_ZedSiren_Omega" +} diff --git a/CustomZeds/Classes/WMPawn_ZedStalker_NoDAR.uc b/CustomZeds/Classes/WMPawn_ZedStalker_NoDAR.uc new file mode 100644 index 0000000..11ddadb --- /dev/null +++ b/CustomZeds/Classes/WMPawn_ZedStalker_NoDAR.uc @@ -0,0 +1,11 @@ +class WMPawn_ZedStalker_NoDAR extends KFPawn_ZedStalker; + +static event class GetAIPawnClassToSpawn() +{ + return default.class; +} + +defaultproperties +{ + Name="Default__WMPawn_ZedStalker_NoDAR" +} diff --git a/CustomZeds/Classes/WMPawn_ZedStalker_Omega.uc b/CustomZeds/Classes/WMPawn_ZedStalker_Omega.uc new file mode 100644 index 0000000..9cefd1e --- /dev/null +++ b/CustomZeds/Classes/WMPawn_ZedStalker_Omega.uc @@ -0,0 +1,84 @@ +class WMPawn_ZedStalker_Omega extends WMPawn_ZedStalker_NoDAR; + +var const AnimSet StalkerOmegaAnimSet; +var const float ExtraAfflictionResistance, ExtraDamageResistance; + +static function string GetLocalizedName() +{ + return "Stalker Omega"; +} + +simulated function PostBeginPlay() +{ + bVersusZed = True; + + //Replace the master AnimSet with the omega master AnimSet + Mesh.AnimSets[0] = StalkerOmegaAnimSet; + + super.PostBeginPlay(); + + UpdateGameplayMICParams(); +} + +simulated function UpdateGameplayMICParams() +{ + local byte i; + + super.UpdateGameplayMICParams(); + + if ((!bIsCloaking || bIsGoreMesh) && WorldInfo.NetMode != NM_DedicatedServer) + { + for (i = 0; i < CharacterMICs.length; ++i) + { + CharacterMICs[i].SetVectorParameterValue('Emissive Color', class'WMPawn_OmegaConstants'.default.OmegaColor); + } + } +} + +simulated event bool UsePlayerControlledZedSkin() +{ + if (class'KFGameEngine'.static.GetSeasonalEventID() % 10 == SEI_Fall) + return False; + + return True; +} + +function float GetDamageTypeModifier(class DT) +{ + local float CurrentMod; + + // Omega ZEDs have extra resistance against all damage type + CurrentMod = super.GetDamageTypeModifier(DT); + return FMax(0.025f, CurrentMod - ExtraDamageResistance); +} + +simulated function AdjustAffliction(out float AfflictionPower) +{ + super.AdjustAffliction(AfflictionPower); + AfflictionPower *= 1.0f - ExtraAfflictionResistance; +} + +defaultproperties +{ + StalkerOmegaAnimSet=AnimSet'ZedternalReborn_Zeds.Stalker.Stalker_Omega_AnimSet' + DifficultySettings=class'CustomZeds.WMDifficulty_Stalker_Omega' + + bVersusZed=False + DoshValue=22 + Health=250 + Mass=55.0f + GroundSpeed=425.0f + SprintSpeed=565.0f + PenetrationResistance=0.8f + ExtraAfflictionResistance=0.1f + ExtraDamageResistance=0.05f + + XPValues(0)=12 + XPValues(1)=15 + XPValues(2)=15 + XPValues(3)=15 + + HitZones(0)=(GoreHealth=100) + + Name="Default__WMPawn_ZedStalker_Omega" +} diff --git a/CustomZeds/Classes/WMProj_Husk_Fireball_Suicide.uc b/CustomZeds/Classes/WMProj_Husk_Fireball_Suicide.uc new file mode 100644 index 0000000..f0df626 --- /dev/null +++ b/CustomZeds/Classes/WMProj_Husk_Fireball_Suicide.uc @@ -0,0 +1,24 @@ +class WMProj_Husk_Fireball_Suicide extends KFProj_Husk_Fireball; + +simulated function Tick(float Delta) +{ + SetRotation(rotator(Velocity)); + super.Tick(Delta); +} + +defaultproperties +{ + Physics=PHYS_Falling + Speed=1200.0f + MaxSpeed=1200.0f + + BurnDuration=2.0f + BurnDamageInterval=0.5f + + Begin Object Name=ExploTemplate0 + Damage=13.0f + DamageRadius=250.0f + End Object + + Name="Default__WMProj_Husk_Fireball_Suicide" +} diff --git a/CustomZeds/Classes/WMSM_Husk_Omega_FireBallBarrageAttack.uc b/CustomZeds/Classes/WMSM_Husk_Omega_FireBallBarrageAttack.uc new file mode 100644 index 0000000..524be01 --- /dev/null +++ b/CustomZeds/Classes/WMSM_Husk_Omega_FireBallBarrageAttack.uc @@ -0,0 +1,9 @@ +class WMSM_Husk_Omega_FireBallBarrageAttack extends KFSM_Husk_FireBallAttack; + +defaultproperties +{ + Handle=WMSM_Husk_Omega_FireBallBarrageAttack + AnimNames=(Atk_Random_Shoot_V1) + + Name="Default__WMSM_Husk_Omega_FireBallBarrageAttack" +} diff --git a/CustomZeds/Globals.uci b/CustomZeds/Globals.uci new file mode 100644 index 0000000..e69de29 diff --git a/CustomZeds/ZedternalReborn_Zeds.upk b/CustomZeds/ZedternalReborn_Zeds.upk new file mode 100644 index 0000000..a99723e Binary files /dev/null and b/CustomZeds/ZedternalReborn_Zeds.upk differ diff --git a/builder.cfg b/builder.cfg new file mode 100644 index 0000000..a79fbca --- /dev/null +++ b/builder.cfg @@ -0,0 +1,52 @@ +### Build parameters ### + +# If True - compresses the mutator when compiling +# Scripts will be stored in binary form +# (reduces the size of the output file) +StripSource="True" + +# Mutators to be compiled +# Specify them with a space as a separator, +# Mutators will be compiled in the specified order +PackageBuildOrder="CustomZeds" + + +### Steam Workshop upload parameters ### + +# Mutators that will be uploaded to the workshop +# Specify them with a space as a separator, +# The order doesn't matter +PackageUpload="CustomZeds" + + +### Test parameters ### + +# Map: +Map="KF-Nuked" + +# Game: +# Survival: KFGameContent.KFGameInfo_Survival +# WeeklyOutbreak: KFGameContent.KFGameInfo_WeeklySurvival +# Endless: KFGameContent.KFGameInfo_Endless +# Objective: KFGameContent.KFGameInfo_Objective +# Versus: KFGameContent.KFGameInfo_VersusSurvival +Game="KFGameContent.KFGameInfo_Survival" + +# Difficulty: +# Normal: 0 +# Hard: 1 +# Suicide: 2 +# Hell: 3 +Difficulty="0" + +# GameLength: +# 4 waves: 0 +# 7 waves: 1 +# 10 waves: 2 +GameLength="0" + +# Mutators +Mutators="" + +# Additional parameters +Args="" diff --git a/tools b/tools new file mode 160000 index 0000000..49fcaf6 --- /dev/null +++ b/tools @@ -0,0 +1 @@ +Subproject commit 49fcaf67a29c5b478dc10f1f0ae08ed43017cd36