From 23d1ca3a9a2f62692741e77039f03fe0a913be1d Mon Sep 17 00:00:00 2001 From: GenZmeY Date: Sun, 30 Oct 2022 02:52:58 +0300 Subject: [PATCH] upload --- Engine/Classes/OnlineSubsystem.uc | 1 + Engine/Classes/Pawn.uc | 9 - KFGame/Classes/KFAIController.uc | 133 +++++++-- .../Classes/KFAIController_ZedFleshpound.uc | 37 +-- KFGame/Classes/KFAISpawnManager.uc | 65 ++++- KFGame/Classes/KFCommon_LocalizedStrings.uc | 7 + KFGame/Classes/KFDamageType.uc | 15 + KFGame/Classes/KFExplosionActorLingering.uc | 9 +- KFGame/Classes/KFExplosion_Nuke.uc | 2 +- KFGame/Classes/KFExplosion_ZedativeCloud.uc | 21 +- .../Classes/KFGFxControlsContainer_Input.uc | 41 ++- KFGame/Classes/KFGFxHUD_PlayerStatus.uc | 15 +- KFGame/Classes/KFGFxMenu_Inventory.uc | 193 +++++++------ KFGame/Classes/KFGFxMoviePlayer_HUD.uc | 53 +++- KFGame/Classes/KFGFxOptionsMenu_Controls.uc | 53 ++++ .../KFGFxStartGameContainer_FindGame.uc | 20 +- KFGame/Classes/KFGFxStoreContainer_Main.uc | 36 +-- .../KFGFxTraderContainer_PlayerInfo.uc | 21 +- KFGame/Classes/KFGameInfo.uc | 5 + KFGame/Classes/KFGameInfo_Entry.uc | 4 +- KFGame/Classes/KFGameReplicationInfo.uc | 127 +++++++- KFGame/Classes/KFGfxMenu_StartGame.uc | 2 +- KFGame/Classes/KFHUDBase.uc | 127 +++++++- KFGame/Classes/KFInventoryManager.uc | 15 + KFGame/Classes/KFLaserSightAttachment.uc | 41 ++- KFGame/Classes/KFLocalMessage_Priority.uc | 14 +- KFGame/Classes/KFOnlineStatsReadDingo.uc | 2 + KFGame/Classes/KFOnlineStatsWrite.uc | 13 +- KFGame/Classes/KFOnlineStatsWriteDingo.uc | 2 + KFGame/Classes/KFOutbreakEvent.uc | 12 +- KFGame/Classes/KFPawn.uc | 172 ++++++++++- KFGame/Classes/KFPawn_Human.uc | 170 +++++++++-- KFGame/Classes/KFPawn_Monster.uc | 38 ++- KFGame/Classes/KFPerk.uc | 61 +++- KFGame/Classes/KFPerk_Berserker.uc | 11 + KFGame/Classes/KFPerk_Commando.uc | 2 +- KFGame/Classes/KFPerk_Demolitionist.uc | 21 +- KFGame/Classes/KFPerk_FieldMedic.uc | 10 +- KFGame/Classes/KFPerk_Firebug.uc | 11 +- KFGame/Classes/KFPlayerController.uc | 35 +++ .../KFPlayerController_WeeklySurvival.uc | 271 +++++++++++++++++ KFGame/Classes/KFPlayerInput.uc | 36 ++- KFGame/Classes/KFPlayerReplicationInfo.uc | 2 +- KFGame/Classes/KFProfileSettings.uc | 13 + KFGame/Classes/KFProj_Grenade.uc | 13 + KFGame/Classes/KFProjectile.uc | 12 + KFGame/Classes/KFSkinTypeEffects.uc | 24 +- KFGame/Classes/KFSpawnVolume.uc | 2 +- KFGame/Classes/KFUnlockManager.uc | 12 +- KFGame/Classes/KFWeap_HealerBase.uc | 10 + KFGame/Classes/KFWeapon.uc | 2 +- KFGame/Classes/KFWeaponSkinList.uc | 217 ++++++++++++++ KFGame/Classes/KFWeeklyOutbreakInformation.uc | 2 +- KFGame/Classes/KFZedArmorInfo.uc | 18 ++ KFGame/KFOnlineStats.uci | 1 + KFGame/KFProfileSettings.uci | 4 + .../KFDT_Ballistic_BlastBrawlersShotgun.uc | 2 +- .../Classes/KFExplosion_MedicGrenade.uc | 1 + .../Classes/KFExplosion_MineReconstructor.uc | 2 +- .../Classes/KFGFxHUD_PlayerStatusVersus.uc | 2 +- KFGameContent/Classes/KFGameInfo_Survival.uc | 61 ++-- .../Classes/KFGameInfo_WeeklySurvival.uc | 272 ++++++++++++++++-- .../Classes/KFMapObjective_AreaDefense.uc | 27 +- .../Classes/KFOutbreakEvent_Weekly.uc | 32 ++- .../Classes/KFPawn_ZedFleshpoundKing.uc | 2 +- .../KFProj_Grenade_HRG_CranialPopper.uc | 13 +- .../Classes/KFProj_Mine_Reconstructor.uc | 8 +- .../KFWeap_AssaultRifle_LazerCutter.uc | 2 +- .../Classes/KFWeap_AssaultRifle_Microwave.uc | 2 +- KFGameContent/Classes/KFWeap_AutoTurret.uc | 21 +- .../Classes/KFWeap_Beam_Microwave.uc | 2 +- .../Classes/KFWeap_Blunt_MedicBat.uc | 8 + .../Classes/KFWeap_Blunt_Pulverizer.uc | 2 + .../Classes/KFWeap_HRG_CranialPopper.uc | 4 +- .../Classes/KFWeap_HRG_EMP_ArcGenerator.uc | 2 +- .../Classes/KFWeap_Mine_Reconstructor.uc | 6 +- .../Classes/KFWeap_Pistol_Blunderbuss.uc | 2 +- KFGameContent/Classes/KFWeap_Pistol_G18C.uc | 2 +- .../Classes/KFWeap_Rifle_Hemogoblin.uc | 2 +- KFGameContent/Classes/KFWeap_Rifle_M14EBR.uc | 2 +- KFGameContent/Classes/KFWeap_Rifle_RailGun.uc | 2 +- .../Classes/KFWeap_RocketLauncher_Seeker6.uc | 8 +- KFGameContent/Classes/KFWeap_SMG_Kriss.uc | 2 +- KFGameContent/Classes/KFWeap_SMG_Medic.uc | 2 +- KFGameContent/Classes/KFWeap_Shotgun_Medic.uc | 2 +- 85 files changed, 2389 insertions(+), 371 deletions(-) diff --git a/Engine/Classes/OnlineSubsystem.uc b/Engine/Classes/OnlineSubsystem.uc index 643d6c7..5444ea8 100644 --- a/Engine/Classes/OnlineSubsystem.uc +++ b/Engine/Classes/OnlineSubsystem.uc @@ -1498,6 +1498,7 @@ struct native ItemProperties /** Key ID used to open this item (used for playfab locked containers) */ var string RequiredKeyId; var string Name; + var string KeyName; var ItemType Type; var ItemRarity Rarity; var string ShortDescription; diff --git a/Engine/Classes/Pawn.uc b/Engine/Classes/Pawn.uc index e5dceca..6c8ddda 100644 --- a/Engine/Classes/Pawn.uc +++ b/Engine/Classes/Pawn.uc @@ -2596,17 +2596,10 @@ event TakeDamage(int Damage, Controller InstigatedBy, vector HitLocation, vector Killer = SetKillInstigator(InstigatedBy, DamageType); TearOffMomentum = momentum; Died(Killer, damageType, HitLocation); - - // using the passed in damage type instead of the hitfxinfo since that doesn't get updated when zero damage is done - HandleAfflictionsOnHit(InstigatedBy, Normal(Momentum), DamageType, DamageCauser); } else { HandleMomentum( momentum, HitLocation, DamageType, HitInfo ); - - // using the passed in damage type instead of the hitfxinfo since that doesn't get updated when zero damage is done - HandleAfflictionsOnHit(InstigatedBy, Normal(Momentum), DamageType, DamageCauser); - NotifyTakeHit(InstigatedBy, HitLocation, ActualDamage, DamageType, Momentum, DamageCauser); if (DrivenVehicle != None) { @@ -2626,8 +2619,6 @@ event TakeDamage(int Damage, Controller InstigatedBy, vector HitLocation, vector `endif } -function HandleAfflictionsOnHit(Controller DamageInstigator, vector HitDir, class DamageType, Actor DamageCauser); - /* * Queries the PRI and returns our current team index. */ diff --git a/KFGame/Classes/KFAIController.uc b/KFGame/Classes/KFAIController.uc index 03b1d48..12f5c28 100644 --- a/KFGame/Classes/KFAIController.uc +++ b/KFGame/Classes/KFAIController.uc @@ -508,6 +508,15 @@ var const int ZedBumpEffectThreshold; /** The chance of obliterating a zed on an enraged bump */ var const float ZedBumpObliterationEffectChance; +// Only enabled while we didn't receive damage and we use Aggro for choosing Enemy +var bool CanForceEnemy; +var Pawn ForcedEnemy; +var Pawn LastForcedEnemy; +var float ForcedEnemyLastTime; +var float DamageRatioToChangeForcedEnemy; +var float TimeCanRestartForcedEnemy; +var float TimeCannotChangeFromForcedEnemy; + /********************************************************************************************* Evasion / Blocking ********************************************************************************************* */ @@ -1282,6 +1291,33 @@ native function StopAllLatentMoveExecution(); /** Am I being targeted by a player (optionally returns first found) */ native function bool IsTargetedByPlayer( optional out KFPawn outThreateningPlayer ); +function Pawn FindForcedEnemy() +{ + local KFGameInfo KFGI; + local KFPlayerController_WeeklySurvival KFPC_WS; + local class MyMonster; + + KFGI = KFGameInfo(WorldInfo.Game); + if(KFGI != none && KFGI.OutbreakEvent != none && KFGI.OutbreakEvent.ActiveEvent.bVIPGameMode) + { + MyMonster = class(Pawn.Class); + + // If this monster is included on the vip targetting, force VIP as enemy + if (KFGI.OutbreakEvent.ActiveEvent.VIPTargetting.Find(MyMonster) != INDEX_NONE) + { + foreach WorldInfo.AllControllers(class'KFPlayerController_WeeklySurvival', KFPC_WS) + { + if (KFPC_WS.VIPGameData.IsVIP && KFPC_WS.Pawn.IsAliveAndWell() && KFPC_WS.Pawn.CanAITargetThisPawn(self)) + { + return KFPC_WS.Pawn; + } + } + } + } + + return none; +} + /** * Originally from KF1, KFMonsterController.uc, added check to take # of Zeds targeting * the threat into account. @@ -1300,45 +1336,50 @@ event bool FindNewEnemy() } BestEnemy = none; - foreach WorldInfo.AllPawns( class'Pawn', PotentialEnemy ) - { - if( !PotentialEnemy.IsAliveAndWell() || Pawn.IsSameTeam( PotentialEnemy ) || - !PotentialEnemy.CanAITargetThisPawn(self) ) - { - continue; - } - NewDist = VSizeSq( PotentialEnemy.Location - Pawn.Location ); - if( BestEnemy == none || BestDist > NewDist ) + if (BestEnemy == none) + { + foreach WorldInfo.AllPawns( class'Pawn', PotentialEnemy ) { - // New best enemies do not care about the number of zeds around us yet - BestEnemyZedCount = INDEX_None; - bUpdateBestEnemy = true; - } - else - { - // Only update NumZedsTargetingBestEnemy if it's a new best enemy and the best enemy is further - if(BestEnemyZedCount == INDEX_None) + if( !PotentialEnemy.IsAliveAndWell() || Pawn.IsSameTeam( PotentialEnemy ) || + !PotentialEnemy.CanAITargetThisPawn(self) ) { - // Cache BestEnemyZedCount so we don't need to calculate it again - BestEnemyZedCount = NumberOfZedsTargetingPawn( BestEnemy ); + continue; } - PotentialEnemyZedCount = NumberOfZedsTargetingPawn( PotentialEnemy ); - if( PotentialEnemyZedCount < BestEnemyZedCount ) + NewDist = VSizeSq( PotentialEnemy.Location - Pawn.Location ); + if( BestEnemy == none || BestDist > NewDist ) { - BestEnemyZedCount = PotentialEnemyZedCount; + // New best enemies do not care about the number of zeds around us yet + BestEnemyZedCount = INDEX_None; bUpdateBestEnemy = true; } - } + else + { + // Only update NumZedsTargetingBestEnemy if it's a new best enemy and the best enemy is further + if(BestEnemyZedCount == INDEX_None) + { + // Cache BestEnemyZedCount so we don't need to calculate it again + BestEnemyZedCount = NumberOfZedsTargetingPawn( BestEnemy ); + } - if( bUpdateBestEnemy ) - { - BestEnemy = PotentialEnemy; - BestDist = NewDist; - bUpdateBestEnemy = false; + PotentialEnemyZedCount = NumberOfZedsTargetingPawn( PotentialEnemy ); + if( PotentialEnemyZedCount < BestEnemyZedCount ) + { + BestEnemyZedCount = PotentialEnemyZedCount; + bUpdateBestEnemy = true; + } + } + + if( bUpdateBestEnemy ) + { + BestEnemy = PotentialEnemy; + BestDist = NewDist; + bUpdateBestEnemy = false; + } } } + if( Enemy != none && BestEnemy != none && BestEnemy == Enemy ) { return false; @@ -1536,10 +1577,37 @@ event bool SetEnemy( Pawn NewEnemy ) function ChangeEnemy( Pawn NewEnemy, optional bool bCanTaunt = true ) { - local Pawn OldEnemy; + local Pawn OldEnemy, NewForcedEnemy; local KFGameInfo KFGI; + if (CanForceEnemy) + { + NewForcedEnemy = FindForcedEnemy(); + } + else if (NewEnemy == LastForcedEnemy) + { + return; // Don't allow to change to the ForcedEnemy while we can't (we reenable that again from outside) + } + + if (NewForcedEnemy != none) + { + ForcedEnemy = NewForcedEnemy; + + if (Enemy != ForcedEnemy) + { + LastForcedEnemy = ForcedEnemy; + + ForcedEnemyLastTime = WorldInfo.TimeSeconds; + } + + NewEnemy = NewForcedEnemy; + } + else + { + ForcedEnemy = none; + } + // gameinfo hook that calls mutator hook KFGI = KFGameInfo( WorldInfo.Game ); if( KFGI != none ) @@ -7626,6 +7694,13 @@ DefaultProperties LastFrustrationCheckTime=0.f LowIntensityAttackCooldown=2.0 //bUseOldAttackDecisions=true + CanForceEnemy=true + ForcedEnemy=none + LastForcedEnemy=none + ForcedEnemyLastTime=0.f + DamageRatioToChangeForcedEnemy=0.5f + TimeCanRestartForcedEnemy=10.f + TimeCannotChangeFromForcedEnemy=10.f // --------------------------------------------- // AI / Navigation diff --git a/KFGame/Classes/KFAIController_ZedFleshpound.uc b/KFGame/Classes/KFAIController_ZedFleshpound.uc index be317d9..1faf425 100644 --- a/KFGame/Classes/KFAIController_ZedFleshpound.uc +++ b/KFGame/Classes/KFAIController_ZedFleshpound.uc @@ -96,30 +96,35 @@ event bool FindNewEnemy() local Controller C; local Pawn PotentialEnemy; - foreach WorldInfo.AllControllers( class'Controller', C ) + BestEnemy = none; + + if (BestEnemy == none) { - if( C.Pawn == none || !C.Pawn.IsAliveAndWell() || Pawn.IsSameTeam( C.Pawn ) || - !C.Pawn.CanAITargetThisPawn(self) ) + foreach WorldInfo.AllControllers( class'Controller', C ) { - continue; - } + if( C.Pawn == none || !C.Pawn.IsAliveAndWell() || Pawn.IsSameTeam( C.Pawn ) || + !C.Pawn.CanAITargetThisPawn(self) ) + { + continue; + } - PotentialEnemy = C.Pawn; - NewDist = VSizeSq( PotentialEnemy.Location - Pawn.Location ); + PotentialEnemy = C.Pawn; + NewDist = VSizeSq( PotentialEnemy.Location - Pawn.Location ); - if( BestEnemy == none ) - { - BestEnemy = PotentialEnemy; - BestDist = NewDist; - } - - else if( BestEnemy != none ) - { - if( (BestDist > NewDist) || (NumberOfZedsTargetingPawn( PotentialEnemy ) < NumberOfZedsTargetingPawn( BestEnemy )) ) + if( BestEnemy == none ) { BestEnemy = PotentialEnemy; BestDist = NewDist; } + + else if( BestEnemy != none ) + { + if( (BestDist > NewDist) || (NumberOfZedsTargetingPawn( PotentialEnemy ) < NumberOfZedsTargetingPawn( BestEnemy )) ) + { + BestEnemy = PotentialEnemy; + BestDist = NewDist; + } + } } } diff --git a/KFGame/Classes/KFAISpawnManager.uc b/KFGame/Classes/KFAISpawnManager.uc index 18f63aa..e9c54b1 100644 --- a/KFGame/Classes/KFAISpawnManager.uc +++ b/KFGame/Classes/KFAISpawnManager.uc @@ -143,6 +143,8 @@ var const int ForcedBossNum; var bool bTemporarilyEndless; +var int VIP_CurrentSpawnCounter; +var int VIP_MaxSpawnCounter; /************************************************************************************ * Debugging @@ -154,6 +156,51 @@ var config bool bLogRateVolume; /** Builds a sorted list of spawn volumes based on distance to a specific player */ native function bool SortSpawnVolumes(Controller C, bool bTeleporting, float MinDistSquared); +delegate int SortVIPSpawnVolumesDelegate(KFSpawnVolume A, KFSpawnVolume B) +{ + if (A.CurrentRating == B.CurrentRating) + { + return 0; + } + + if (A.CurrentRating < B.CurrentRating) + { + return 1; + } + + return -1; +} + +function SortVIPSpawnVolumes() +{ + local KFGameReplicationInfo KFGRI; + local int VolumeIndex; + + if (VIP_CurrentSpawnCounter < VIP_MaxSpawnCounter) + { + ++VIP_CurrentSpawnCounter; + return; + } + + VIP_CurrentSpawnCounter = 0; + + KFGRI = KFGameReplicationInfo(WorldInfo.GRI); + if (KFGRI != none && KFGRI.VIPRepPlayer != none) + { + // Recalculate rating based on the distance to VIP player + for (VolumeIndex = 0; VolumeIndex < SpawnVolumes.Length; VolumeIndex++) + { + if (SpawnVolumes[VolumeIndex].CurrentRating > 0) + { + SpawnVolumes[VolumeIndex].CurrentRating = VSizeSq( SpawnVolumes[VolumeIndex].Location - KFGRI.VIPRepPlayer.Location ); + } + } + } + + // Sort vector based on closest + SpawnVolumes.Sort(SortVIPSpawnVolumesDelegate); +} + static function string ZedTypeToString(EAIType AiTypeToConvert) { `if(`notdefined(ShippingPC)) @@ -226,8 +273,11 @@ function RegisterSpawnVolumes() function SetupNextWave(byte NextWaveIndex, int TimeToNextWaveBuffer = 0) { local KFGameReplicationInfo KFGRI; + local bool bIsBossRush; - if (OutbreakEvent.ActiveEvent.bBossRushMode) + bIsBossRush = OutbreakEvent != none && OutbreakEvent.ActiveEvent.bBossRushMode; + + if (bIsBossRush) { NextWaveIndex = MyKFGRI.WaveMax - 1; } @@ -255,7 +305,7 @@ function SetupNextWave(byte NextWaveIndex, int TimeToNextWaveBuffer = 0) // Initialize our recycle number NumSpecialSquadRecycles = 0; - if (MyKFGRI.IsBossWave() || OutbreakEvent.ActiveEvent.bBossRushMode) + if (MyKFGRI.IsBossWave() || bIsBossRush) { WaveTotalAI = 1; } @@ -1208,6 +1258,7 @@ function KFSpawnVolume GetBestSpawnVolume( optional array< class { local int VolumeIndex, ControllerIndex; local Controller RateController; + local KFGameReplicationInfo KFGRI; if( OverrideController != none ) { @@ -1250,6 +1301,13 @@ function KFSpawnVolume GetBestSpawnVolume( optional array< class // pre-sort the list to reduce the number of line checks performed by IsValidForSpawn SortSpawnVolumes(RateController, bTeleporting, MinDistSquared); + KFGRI = KFGameReplicationInfo(WorldInfo.GRI); + + if (KFGRI != none && KFGRI.IsVIPMode()) + { + SortVIPSpawnVolumes(); + } + for ( VolumeIndex = 0; VolumeIndex < SpawnVolumes.Length; VolumeIndex++ ) { if ( SpawnVolumes[VolumeIndex].IsValidForSpawn(DesiredSquadType, OtherController) @@ -1396,5 +1454,8 @@ defaultproperties MaxBossMinionScaleByPlayers(5)=2.0 // 6 players bForceRequiredSquad=false + + VIP_CurrentSpawnCounter = 0 + VIP_MaxSpawnCounter = 5 } diff --git a/KFGame/Classes/KFCommon_LocalizedStrings.uc b/KFGame/Classes/KFCommon_LocalizedStrings.uc index 8b38c9d..6c0b448 100644 --- a/KFGame/Classes/KFCommon_LocalizedStrings.uc +++ b/KFGame/Classes/KFCommon_LocalizedStrings.uc @@ -19,8 +19,15 @@ var localized string FailedToReachInventoryServerString; var localized array DifficultyStrings; var localized array LengthStrings; var localized string SpecialLengthString; + var localized string WeaponLevelString; var localized string GunPointsString; + +var localized string VIPString; +var localized string VIPObjectiveAString; +var localized string VIPObjectiveBString; +var localized string VIPObjectiveCString; + var localized array ServerTypeStrings; var localized array PermissionStrings; var localized array ConsolePermissionStrings; diff --git a/KFGame/Classes/KFDamageType.uc b/KFGame/Classes/KFDamageType.uc index 87e8d12..ce94a48 100644 --- a/KFGame/Classes/KFDamageType.uc +++ b/KFGame/Classes/KFDamageType.uc @@ -40,6 +40,9 @@ var bool bConsideredIndirectOrAoE; /** If true, this damagetype will destroy a door if closed and unwelded */ var bool bAllowAIDoorDestruction; +/** If true can PlayDeadHitEffects the Zeds when killing them */ +var bool bCanPlayDeadHitEffects; + /********************************************************************************************* Damage over time ********************************************************************************************* */ @@ -233,6 +236,9 @@ var AKEvent OverrideImpactSound; //For use on in world trap damage types var bool bIsTrapDamage; +//When doing armour piercing damage (this is a % of total damage received, the rest is considered as base if defined) +var float DamageModifierAP; + /** * Take the primary HitDirection and modify it to add more spread. * Use the BloodSpread property to calculate the spread amount @@ -421,6 +427,11 @@ static function bool AlwaysPoisons() /** Do anything related to killing a pawn */ static function ApplyKillResults(KFPawn KilledPawn); +static function bool CanPlayDeadHitEffects() +{ + return default.bCanPlayDeadHitEffects; +} + Defaultproperties { bNoPain=false @@ -444,4 +455,8 @@ Defaultproperties bCanObliterate=false; bHasToSpawnMicrowaveFire=true + + DamageModifierAP=0.f + + bCanPlayDeadHitEffects=true } diff --git a/KFGame/Classes/KFExplosionActorLingering.uc b/KFGame/Classes/KFExplosionActorLingering.uc index 5629cc3..e54e22a 100644 --- a/KFGame/Classes/KFExplosionActorLingering.uc +++ b/KFGame/Classes/KFExplosionActorLingering.uc @@ -121,14 +121,14 @@ protected simulated function bool DoExplosionDamage(bool bCauseDamage, bool bCau if(bOnlyDamagePawns) { - return ExplodePawns(); + return ExplodePawns(bCauseDamage); } return super.DoExplosionDamage(bCauseDamage, bCauseEffects); } /** Stripped down and optimized version of DoExplosionDamage that only checks for pawns */ -protected simulated function bool ExplodePawns() +protected simulated function bool ExplodePawns(bool bCauseDamage) { local Pawn Victim; local float CheckRadius; @@ -171,6 +171,11 @@ protected simulated function bool ExplodePawns() DamageScale = (DamageScalePerStack < 1.f) ? CalcStackingDamageScale(KFPawn(Victim), Interval) : 1.f; if ( DamageScale > 0.f ) { + if (bCauseDamage == false) + { + DamageScale = 0.f; // We still want effects + } + AffectsPawn(Victim, DamageScale); bHitPawn = true; } diff --git a/KFGame/Classes/KFExplosion_Nuke.uc b/KFGame/Classes/KFExplosion_Nuke.uc index 089aa8d..5db63d5 100644 --- a/KFGame/Classes/KFExplosion_Nuke.uc +++ b/KFGame/Classes/KFExplosion_Nuke.uc @@ -38,7 +38,7 @@ simulated function Explode(GameExplosion NewExplosionTemplate, optional vector D ExplosionTemplate.MyDamageType = class'KFPerk_Demolitionist'.static.GetLingeringDamageType(); } -protected simulated function bool ExplodePawns() +protected simulated function bool ExplodePawns(bool bCauseDamage) { local Pawn Victim; local float CheckRadius; diff --git a/KFGame/Classes/KFExplosion_ZedativeCloud.uc b/KFGame/Classes/KFExplosion_ZedativeCloud.uc index 780d053..527fe58 100644 --- a/KFGame/Classes/KFExplosion_ZedativeCloud.uc +++ b/KFGame/Classes/KFExplosion_ZedativeCloud.uc @@ -26,6 +26,8 @@ var class ZedativeDamageType; var class ZedativeHealingType; var int ZedativeEffectRadius; +var array AffectedHumans; + replication { if(bNetInitial) @@ -79,16 +81,16 @@ protected simulated function AffectsPawn(Pawn Victim, float DamageScale) local Actor HitActor; local bool bDamageBlocked; + if( bWasFadedOut|| bDeleteMe || bPendingDelete ) + { + return; + } + if( Victim != none && Victim.IsAliveAndWell() ) { MonsterVictim = KFPawn_Monster(Victim); if( MonsterVictim != none ) - { - if( bWasFadedOut|| bDeleteMe || bPendingDelete ) - { - return; - } - + { Victim.GetComponentsBoundingBox(BBox); BBoxCenter = (BBox.Min + BBox.Max) * 0.5f; HitActor = TraceExplosive(BBoxCenter, Location + vect(0, 0, 20)); @@ -109,7 +111,12 @@ protected simulated function AffectsPawn(Pawn Victim, float DamageScale) HumanVictim = KFPawn_Human(Victim); if( HumanVictim != none && HumanVictim.GetExposureTo(Location) > 0 ) { - HumanVictim.HealDamage(ZedativeHealth, InstigatorController, ZedativeHealingType, false); + if (AffectedHumans.Find(HumanVictim) == INDEX_NONE) + { + AffectedHumans.AddItem(HumanVictim); + + HumanVictim.HealDamage(ZedativeHealth, InstigatorController, ZedativeHealingType, false); + } } } } diff --git a/KFGame/Classes/KFGFxControlsContainer_Input.uc b/KFGame/Classes/KFGFxControlsContainer_Input.uc index 45275ee..fc52366 100644 --- a/KFGame/Classes/KFGFxControlsContainer_Input.uc +++ b/KFGame/Classes/KFGFxControlsContainer_Input.uc @@ -31,10 +31,13 @@ var localized string AimAssistLockOnString; var localized string AimAssistRotationString; var localized string AimAssistSlowDownString; var localized string ForceFeedbackString; +var localized string MouseLookUpScaleString; +var localized string MouseLookRightScaleString; +var localized string ViewSmoothingString; +var localized string ViewAccelerationString; var KFGFxOptionsMenu_Controls ControlsMenu; - function Initialize( KFGFxObject_Menu NewParentMenu ) { super.Initialize( NewParentMenu ); @@ -61,6 +64,14 @@ function LocalizeText() LocalizedObject.SetString("controllerDeadzoneLabel" , ControllerDeadzoneString); LocalizedObject.SetString("controllerAccelerationJumpLabel" , ControllerAccelerationJumpString); + if(!class'WorldInfo'.static.IsConsoleBuild() ) + { + LocalizedObject.SetString("lookUpScaleLabel", MouseLookUpScaleString); + LocalizedObject.SetString("lookRightScaleLabel", MouseLookRightScaleString); + LocalizedObject.SetString("viewSmoothingLabel", ViewSmoothingString); + LocalizedObject.SetString("viewAccelerationLabel", ViewAccelerationString); + } + // Localization alternative for Xbox if( class'WorldInfo'.static.IsConsoleBuild(CONSOLE_Durango) ) { @@ -103,9 +114,20 @@ function InitializeOptions() ValuesObject.SetBool("invertedValue" , KFPI.bInvertMouse); ValuesObject.SetBool("mouseSmoothingLabel" , KFPI.bEnableMouseSmoothing); - + + ValuesObject.SetFloat("lookUpScaleValue" , -KFPI.MouseLookUpScale); + ValuesObject.SetFloat("lookUpScaleMin" , ControlsMenu.MinMouseLookUpScale); + ValuesObject.SetFloat("lookUpScaleMax" , ControlsMenu.MaxMouseLookUpScale); + + ValuesObject.SetFloat("lookRightScaleValue" , KFPI.MouseLookRightScale); + ValuesObject.SetFloat("lookRightScaleMin" , ControlsMenu.MinMouseLookRightScale); + ValuesObject.SetFloat("lookRightScaleMax" , ControlsMenu.MaxMouseLookRightScale); + + ValuesObject.SetBool("viewSmoothingValue" , KFPI.bViewSmoothingEnabled); + ValuesObject.SetBool("viewAccelerationValue" , KFPI.bViewAccelerationEnabled); } + ValuesObject.SetBool("forceFeedbackValue" , KFPI.bForceFeedbackEnabled); ValuesObject.SetFloat("controllerSensitivityValue" , 100 * KFPI.GamepadSensitivityScale); @@ -152,6 +174,20 @@ function ResetInputOptions() KFPI.bEnableMouseSmoothing = ControlsMenu.Manager.CachedProfile.GetDefaultBool(KFID_EnableMouseSmoothing); ControlsMenu.Manager.CachedProfile.SetProfileSettingValueBool(KFID_EnableMouseSmoothing, KFPI.bEnableMouseSmoothing); + + KFPI.MouseLookUpScale = ControlsMenu.Manager.CachedProfile.GetDefaultFloat(KFID_MouseLookUpScale); + ControlsMenu.Manager.CachedProfile.SetProfileSettingValueFloat(KFID_MouseLookUpScale, KFPI.MouseLookUpScale); + + KFPI.MouseLookRightScale = ControlsMenu.Manager.CachedProfile.GetDefaultFloat(KFID_MouseLookRightScale); + ControlsMenu.Manager.CachedProfile.SetProfileSettingValueFloat(KFID_MouseLookRightScale, KFPI.MouseLookRightScale); + + KFPI.ResetLookScales(); + + KFPI.bViewSmoothingEnabled = ControlsMenu.Manager.CachedProfile.GetDefaultBool(KFID_ViewSmoothingEnabled); + ControlsMenu.Manager.CachedProfile.SetProfileSettingValueBool(KFID_ViewSmoothingEnabled, KFPI.bViewSmoothingEnabled); + + KFPI.bViewAccelerationEnabled = ControlsMenu.Manager.CachedProfile.GetDefaultBool(KFID_ViewAccelerationEnabled); + ControlsMenu.Manager.CachedProfile.SetProfileSettingValueBool(KFID_ViewAccelerationEnabled, KFPI.bViewAccelerationEnabled); } //durango @@ -187,4 +223,3 @@ function ResetInputOptions() InitializeOptions(); } - diff --git a/KFGame/Classes/KFGFxHUD_PlayerStatus.uc b/KFGame/Classes/KFGFxHUD_PlayerStatus.uc index 9e510a0..d8a30ec 100644 --- a/KFGame/Classes/KFGFxHUD_PlayerStatus.uc +++ b/KFGame/Classes/KFGFxHUD_PlayerStatus.uc @@ -30,6 +30,8 @@ var int LastEXPValue; var localized string EXPString; +var float LastUpdateTime; + function InitializeHUD() { MyPC = KFPlayerController(GetPC()); @@ -48,9 +50,11 @@ function TickHud(float DeltaTime) UpdateArmor(); UpdateHealer(); UpdateGlobalDamage(); + + LastUpdateTime = MyPC.WorldInfo.TimeSeconds; } -function ShowActiveIndicators( array IconPathStrings ) +function ShowActiveIndicators( array ActiveSkills ) { local byte i; local GFxObject DataProvider; @@ -58,11 +62,14 @@ function ShowActiveIndicators( array IconPathStrings ) DataProvider = CreateArray(); - for (i = 0; i < IconPathStrings.length; i++) + for (i = 0; i < ActiveSkills.length; i++) { //Corresponding AS3 class reads string off of the object to load in icon TempObj = CreateObject( "Object" ); - TempObj.SetString( "iconPath", "img://"$IconPathStrings[i] ); + TempObj.SetString( "iconPath", "img://" $ActiveSkills[i].IconPath ); + TempObj.SetInt( "Multiplier", ActiveSkills[i].Multiplier ); + TempObj.SetFloat( "MaxDuration", ActiveSkills[i].MaxDuration ); + TempObj.SetFloat( "Duration", ActiveSkills[i].Duration ); DataProvider.SetElementObject( i, TempObj ); } @@ -229,5 +236,5 @@ function UpdateGlobalDamage() DefaultProperties { - + LastUpdateTime = 0.f; } diff --git a/KFGame/Classes/KFGFxMenu_Inventory.uc b/KFGame/Classes/KFGFxMenu_Inventory.uc index b99867f..4595cdb 100644 --- a/KFGame/Classes/KFGFxMenu_Inventory.uc +++ b/KFGame/Classes/KFGFxMenu_Inventory.uc @@ -141,12 +141,21 @@ struct InventoryHelper var int SkinType; var ItemRarity Rarity; var int Quality; + + // For ordering items + var string KeyName; + var bool IsKey; }; var array SkinListWeaponsSearchCache; var array SkinListOrderedCache; var bool NeedToRegenerateSkinList; +struct ByTypeItemsHelper +{ + var() array ItemsOnType; +}; + var EInventoryWeaponType_Filter CurrentWeaponTypeFilter; var int CurrentPerkIndexFilter; var ItemRarity CurrentRarityFilter; @@ -282,41 +291,12 @@ final function int Crc(coerce string Text) return CrcValue; } -delegate int SortByWeaponTypeDefinition(InventoryHelper A, InventoryHelper B) +delegate int SortSkinList(InventoryHelper A, InventoryHelper B) { - return A.WeaponDef < B.WeaponDef ? -1 : +1; -} - -delegate int SortByPrice(InventoryHelper A, InventoryHelper B) -{ - return A.Price > B.Price ? -1 : +1; -} - -delegate int SortByRarity(InventoryHelper A, InventoryHelper B) -{ - return A.Rarity > B.Rarity ? -1 : +1; -} - -delegate int SortBySkinType(InventoryHelper A, InventoryHelper B) -{ - return A.SkinType > B.SkinType ? -1 : +1; -} - -delegate int SortByQuality(InventoryHelper A, InventoryHelper B) -{ - return A.Quality < B.Quality ? -1 : +1; -} - -delegate int SortByAll(InventoryHelper A, InventoryHelper B) -{ - //local int WeapDefValue, SkinTypeValue; - /** Format: Compare lower ? -1 : (Compare upper) : 1 : (Equal case, repeat formula with the next sort condition) */ return A.Price > B.Price ? -1 : (A.Price < B.Price ? 1 : ( - //STRCompare(A.WeaponDef, B.WeaponDef, WeapDefValue) < 0 ? -1 : ( WeapDefValue != 0 ? 1 : ( A.WeaponDef < B.WeaponDef ? -1 : (A.WeaponDef > B.WeaponDef ? 1 : ( A.Rarity > B.Rarity ? -1 : (A.Rarity < B.Rarity ? 1 : ( - //STRCompare(A.SkinType, B.SkinType, SkinTypeValue) > 0 ? -1 : ( SkinTypeValue != 0 ? 1 : ( A.SkinType > B.SkinType ? -1 : (A.SkinType < B.SkinType ? 1 : ( A.Quality < B.Quality ? -1 : 1 )) @@ -325,13 +305,33 @@ delegate int SortByAll(InventoryHelper A, InventoryHelper B) )); } +delegate int SortItemList(InventoryHelper A, InventoryHelper B) +{ + if (A.IsKey && B.IsKey) + { + return 0; + } + + if (A.IsKey == false && B.IsKey == false) + { + return 0; + } + + if (A.IsKey) + { + return 1; + } + + return -1; +} + function InitInventory() { - local int i, ItemIndex, HelperIndex, WeaponItemID, SearchWeaponSkinIndex; + local int i, j, z, ItemIndex, HelperIndex, WeaponItemID, SearchWeaponSkinIndex, SearchKeyKeywordIndex; local ItemProperties TempItemDetailsHolder; local GFxObject ItemArray, ItemObject; local bool bActiveItem; - local array ActiveItems, ValidSkinItems, FailedSkinItems; + local ByTypeItemsHelper ByTypeItems[7]; local InventoryHelper HelperItem; local array ExchangeRules; local class WeaponDef; @@ -348,6 +348,10 @@ function InitInventory() return; } + // While reading from the profile we also order by type, then we might want to order again some stuff that's inside the same item type later + + //`Log("NEW MENU OPEN: " $CurrentInventoryFilter); + for (i = 0; i < OnlineSub.CurrentInventory.length; i++) { //look item up to get info on it. @@ -358,22 +362,25 @@ function InitInventory() { TempItemDetailsHolder = OnlineSub.ItemPropertiesList[ItemIndex]; - if (((CurrentInventoryFilter == EInv_All || Int(CurrentInventoryFilter) == Int(TempItemDetailsHolder.Type)) && DoesMatchFilter(TempItemDetailsHolder)) || bool(OnlineSub.CurrentInventory[i].NewlyAdded)) + if (((CurrentInventoryFilter == EInv_All || Int(CurrentInventoryFilter) == Int(TempItemDetailsHolder.Type)) + && DoesMatchFilter(TempItemDetailsHolder)) + || bool(OnlineSub.CurrentInventory[i].NewlyAdded)) { - ItemObject = CreateObject("Object"); - HelperIndex = ActiveItems.Find('ItemDefinition', onlineSub.CurrentInventory[i].Definition); + ItemObject = CreateObject("Object"); + HelperIndex = ByTypeItems[TempItemDetailsHolder.Type].ItemsOnType.Find('ItemDefinition', onlineSub.CurrentInventory[i].Definition); if (HelperIndex == INDEX_NONE) { + HelperItem.Type = TempItemDetailsHolder.Type; + //HelperItem.FullName = TempItemDetailsHolder.Name; HelperItem.ItemDefinition = onlineSub.CurrentInventory[i].Definition; HelperItem.ItemCount = onlineSub.CurrentInventory[i].Quantity; if (TempItemDetailsHolder.Type == ITP_WeaponSkin) { // Copy required stuff - //HelperItem.FullName = TempItemDetailsHolder.Name; - HelperItem.Rarity = TempItemDetailsHolder.Rarity; - HelperItem.Quality = TempItemDetailsHolder.Quality; + HelperItem.Rarity = TempItemDetailsHolder.Rarity; + HelperItem.Quality = TempItemDetailsHolder.Quality; if (bool(OnlineSub.CurrentInventory[i].NewlyAdded)) { @@ -397,6 +404,7 @@ function InitInventory() // Get the left part of the string without the next "| " SearchWeaponSkinIndex = InStr(SkinType, "|"); + // Store as CRC, that speeds up comparisons later HelperItem.SkinType = CrC(Left(SkinType, SearchWeaponSkinIndex)); WeaponItemID = class'KFWeaponSkinList'.default.Skins.Find('Id', HelperItem.ItemDefinition); @@ -406,6 +414,7 @@ function InitInventory() WeaponDef = class'KFWeaponSkinList'.default.Skins[WeaponItemID].WeaponDef; // All Weapons start by KFGameContent.KFWeap_ Skip that prefix. + // Store as CRC, that speeds up comparisons later HelperItem.WeaponDef = CrC(Mid(WeaponDef.default.WeaponClassPath, 21)); HelperItem.Price = WeaponDef.default.BuyPrice; } @@ -418,18 +427,22 @@ function InitInventory() SkinListWeaponsSearchCache.AddItem(HelperItem); } } + else + { + HelperItem.KeyName = TempItemDetailsHolder.KeyName; + } - ActiveItems.AddItem(HelperItem); - HelperIndex = ActiveItems.length - 1; + ByTypeItems[TempItemDetailsHolder.Type].ItemsOnType.AddItem(HelperItem); + HelperIndex = ByTypeItems[TempItemDetailsHolder.Type].ItemsOnType.Length - 1; } else { - ActiveItems[HelperIndex].ItemCount += onlineSub.CurrentInventory[i].Quantity; + ByTypeItems[TempItemDetailsHolder.Type].ItemsOnType[HelperIndex].ItemCount += onlineSub.CurrentInventory[i].Quantity; } OnlineSub.IsExchangeable(onlineSub.CurrentInventory[i].Definition, ExchangeRules); - ItemObject.SetInt("count", ActiveItems[HelperIndex].ItemCount); + ItemObject.SetInt("count", ByTypeItems[TempItemDetailsHolder.Type].ItemsOnType[HelperIndex].ItemCount); ItemObject.SetString("label", TempItemDetailsHolder.Name); ItemObject.SetString("price", TempItemDetailsHolder.price); ItemObject.Setstring("typeRarity", TempItemDetailsHolder.ShortDescription); @@ -445,7 +458,7 @@ function InitInventory() ItemObject.SetInt("definition", TempItemDetailsHolder.Definition); ItemObject.SetBool("newlyAdded", bool(OnlineSub.CurrentInventory[i].NewlyAdded) ); - ActiveItems[HelperIndex].GfxItemObject = ItemObject; + ByTypeItems[TempItemDetailsHolder.Type].ItemsOnType[HelperIndex].GfxItemObject = ItemObject; if(onlineSub.CurrentInventory[i].Definition == Manager.SelectIDOnOpen) { @@ -465,86 +478,84 @@ function InitInventory() OnlineSub.ClearNewlyAdded(); - if (CurrentInventoryFilter == EInv_WeaponSkins) + if (CurrentInventoryFilter == EInv_All || CurrentInventoryFilter == EInv_WeaponSkins) { // If need to refresh... we regenerate the list, if not reuse our Cache - NeedToRegenerateSkinList = NeedToRegenerateSkinList || ActiveItems.Length != SkinListOrderedCache.Length; + NeedToRegenerateSkinList = NeedToRegenerateSkinList || ByTypeItems[ITP_WeaponSkin].ItemsOnType.Length != SkinListOrderedCache.Length; + if (NeedToRegenerateSkinList) { NeedToRegenerateSkinList = false; - /*`Log("START ORDERING!!!"); - `Log("----------");*/ - - for (i = 0 ; i < ActiveItems.Length; i++) - { - // If doesn't have weapon definition, don't consider, only add as FailedItem to be added at the end - if (ActiveItems[i].WeaponDef != -1) - { - ValidSkinItems.AddItem(ActiveItems[i]); - } - else - { - FailedSkinItems.AddItem(ActiveItems[i]); - } - } - - // Now we have all valid weapons - // We want to order by Price - Weapon Def - Rarity - Quality // So we order inverse that way we keep the final list with the design intention - ValidSkinItems.Sort(SortByAll); + ByTypeItems[ITP_WeaponSkin].ItemsOnType.Sort(SortSkinList); - SkinListOrderedCache = ValidSkinItems; + SkinListOrderedCache = ByTypeItems[ITP_WeaponSkin].ItemsOnType; + + /*`Log("----------");*/ /*for (i = 0 ; i < SkinListOrderedCache.Length; i++) { `Log("ID : " $SkinListOrderedCache[i].ItemDefinition); `Log("Weapon Def : " $SkinListOrderedCache[i].WeaponDef); `Log("Price : " $SkinListOrderedCache[i].Price); - //`Log("Full Name : " $SkinListOrderedCache[i].FullName); + `Log("Full Name : " $SkinListOrderedCache[i].FullName); `Log("Skin : " $SkinListOrderedCache[i].SkinType); `Log("Rarity : " $SkinListOrderedCache[i].Rarity); `Log("Quality : " $SkinListOrderedCache[i].Quality); `Log("----------"); - }*/ - - // FailedItems are weapons that don't have a Weapon Definition, this might be a case with old unsupported content? - for (i = 0; i < FailedSkinItems.Length; i++) - { - /*if (FailedSkinItems[i].FullName != "") - { - `Log("FailedSkinItems ID : " $FailedSkinItems[i].ItemDefinition); - `Log("FailedSkinItems Price : " $FailedSkinItems[i].Price); - `Log("FailedSkinItems Full Name : " $FailedSkinItems[i].FullName); - `Log("FailedSkinItems Skin : " $FailedSkinItems[i].SkinType); - `Log("FailedSkinItems Rarity : " $FailedSkinItems[i].Rarity); - `Log("FailedFailedSkinItemsItems Quality : " $FailedSkinItems[i].Quality); - `Log("----------"); - }*/ - - SkinListOrderedCache.AddItem(FailedSkinItems[i]); } - /*`Log("FINISH ORDERING!!!"); `Log("----------");*/ } else { //`Log("USING SKIN LIST CACHE!!!"); + + ByTypeItems[ITP_WeaponSkin].ItemsOnType = SkinListOrderedCache; + } + } + + if (CurrentInventoryFilter == EInv_All || CurrentInventoryFilter == EInv_Consumables) + { + // Consumables is the type for the "Items" category on the UI + + // First we have to distinguish if the Item is a KEY or not + for (i = 0; i < ByTypeItems[ITP_KeyCrate].ItemsOnType.Length; i++) + { + // KeyName is something like : "NameItem:KeyCrate", we first remove the part from the : to the right + SearchKeyKeywordIndex = InStr(ByTypeItems[ITP_KeyCrate].ItemsOnType[i].KeyName, ":"); + ByTypeItems[ITP_KeyCrate].ItemsOnType[i].KeyName = Left(ByTypeItems[ITP_KeyCrate].ItemsOnType[i].KeyName, SearchKeyKeywordIndex); + + // Then we search if the name of the Item contains "Key" + SearchKeyKeywordIndex = InStr(ByTypeItems[ITP_KeyCrate].ItemsOnType[i].KeyName, "Key"); + + if (SearchKeyKeywordIndex != -1) + { + ByTypeItems[ITP_KeyCrate].ItemsOnType[i].IsKey = true; + } + else + { + ByTypeItems[ITP_KeyCrate].ItemsOnType[i].IsKey = false; + } } - for (i = 0; i < SkinListOrderedCache.length; i++) - { - ItemArray.SetElementObject(i, SkinListOrderedCache[i].GfxItemObject); - } + ByTypeItems[ITP_KeyCrate].ItemsOnType.Sort(SortItemList); } - else + + //`Log("--------------------------------"); + + z = 0; + + for (i = 0; i < ArrayCount(ByTypeItems); i++) { - for (i = 0; i < ActiveItems.length; i++) + for (j = 0 ; j < ByTypeItems[i].ItemsOnType.Length; j++) { - ItemArray.SetElementObject(i, ActiveItems[i].GfxItemObject); + ItemArray.SetElementObject(z, ByTypeItems[i].ItemsOnType[j].GfxItemObject); + + ++z; } } diff --git a/KFGame/Classes/KFGFxMoviePlayer_HUD.uc b/KFGame/Classes/KFGFxMoviePlayer_HUD.uc index cb22f53..253a7eb 100644 --- a/KFGame/Classes/KFGFxMoviePlayer_HUD.uc +++ b/KFGame/Classes/KFGFxMoviePlayer_HUD.uc @@ -72,7 +72,8 @@ var KFGFxWidget_MapText MapTextWidget; var KFGFxWidget_MapCounterText MapCounterTextWidget; // Widget that displays gun mode texts var KFGFxWidget_GunGame GunGameWidget; - +// Widget that displays vip mode texts +var KFGFxWidget_VIP VIPWidget; var KFPlayerController KFPC; @@ -108,6 +109,9 @@ var string PendingKickPlayerName; // Gun game variables var transient bool bLastGunGameVisibility; +// VIP variables +var transient bool bLastVIPVisibility; + /** On creation of the HUD */ function Init(optional LocalPlayer LocPlay) { @@ -361,6 +365,13 @@ event bool WidgetInitialized(name WidgetName, name WidgetPath, GFxObject Widget) SetWidgetPathBinding( Widget, WidgetPath ); } break; + case 'VIPContainer': + if (VIPWidget == none) + { + VIPWidget=KFGFxWidget_VIP(Widget); + SetWidgetPathBinding( Widget, WidgetPath ); + } + break; } return true; @@ -389,7 +400,7 @@ function UpdateWeaponSelect() /** Update all the unique HUD pieces */ function TickHud(float DeltaTime) { - local bool bGunGameVisibility; + local bool bGunGameVisibility, bVIPModeVisibility; if(KFPC == none || KFPC.WorldInfo.TimeSeconds - LastUpdateTime < UpdateInterval ) { @@ -456,8 +467,6 @@ function TickHud(float DeltaTime) TraderCompassWidget.TickHUD( DeltaTime); } - - if(GfxScoreBoardPlayer != none) { GfxScoreBoardPlayer.TickHud(DeltaTime); @@ -478,6 +487,17 @@ function TickHud(float DeltaTime) bLastGunGameVisibility = bGunGameVisibility; } } + + if (VIPWidget != none) + { + bVIPModeVisibility = KFPC.CanUseVIP(); + + if (bVIPModeVisibility != bLastVIPVisibility) + { + VIPWidget.UpdateVIPVisibility(bVIPModeVisibility); + bLastVIPVisibility = bVIPModeVisibility; + } + } } function UpdateObjectiveActive() @@ -1141,6 +1161,26 @@ function UpdateGunGameWidget(int score, int max_score, int level, int max_level) } } +function UpdateVIP(ReplicatedVIPGameInfo VIPInfo, bool bIsVIP) +{ + local KFGameReplicationInfo KFGRI; + KFGRI=KFGameReplicationInfo(KFPC.WorldInfo.GRI); + + if (VipWidget == none || KFGRI == none || !KFGRI.IsVIPMode()) + { + return; + } + + if (bIsVIP) + { + VIPWidget.SetVIP(); + } + else if (VipInfo.VIPPlayer != none) + { + VIPWidget.SetNOVIP(VIPInfo.VIPPlayer.PlayerName, VIPInfo.CurrentHealth, VIPInfo.MaxHealth); + } +} + //============================================================== // Input //============================================================== @@ -1303,8 +1343,6 @@ function UpdatePauseGameVoteCount(byte YesVotes, byte NoVotes) { if(KickVoteWidget != none) { - `Log("UPDATING PAUSE GAME VOTE COUNT - YES: "$YesVotes); - `Log("UPDATING PAUSE GAME VOTE COUNT - NO: "$NoVotes); KickVoteWidget.UpdateVoteCount(YesVotes, NoVotes); } } @@ -1492,6 +1530,7 @@ DefaultProperties bIsSpectating=false bLastGunGameVisibility=true + bLastVIPVisibility=true WidgetBindings.Add((WidgetName="ObjectiveContainer",WidgetClass=class'KFGFxHUD_ObjectiveConatiner')) WidgetBindings.Add((WidgetName="SpectatorInfoWidget",WidgetClass=class'KFGFxHUD_SpectatorInfo')) @@ -1518,7 +1557,7 @@ DefaultProperties WidgetBindings.Add((WidgetName="mapTextWidget", WidgetClass=class'KFGFxWidget_MapText')) WidgetBindings.Add((WidgetName="counterMapTextWidget", WidgetClass=class'KFGFxWidget_MapCounterText')) WidgetBindings.ADD((WidgetName="GunGameContainer", WidgetClass=class'KFGFxWidget_GunGame')); - + WidgetBindings.ADD((WidgetName="VIPContainer", WidgetClass=class'KFGFxWidget_VIP')); SpecialWaveIconPath(AT_Clot)="UI_Endless_TEX.ZEDs.UI_ZED_Endless_Cyst" SpecialWaveIconPath(AT_SlasherClot)="UI_Endless_TEX.ZEDs.UI_ZED_Endless_Slasher" diff --git a/KFGame/Classes/KFGFxOptionsMenu_Controls.uc b/KFGame/Classes/KFGFxOptionsMenu_Controls.uc index dbafca6..a11f487 100644 --- a/KFGame/Classes/KFGFxOptionsMenu_Controls.uc +++ b/KFGame/Classes/KFGFxOptionsMenu_Controls.uc @@ -28,6 +28,10 @@ var const float MinMouseLookSensitivity; var const float MaxMouseLookSensitivity; var const float MinMouseLookZoomSensitivity; var const float MaxMouseLookZoomSensitivity; +var const float MinMouseLookUpScale; +var const float MaxMouseLookUpScale; +var const float MinMouseLookRightScale; +var const float MaxMouseLookRightScale; var localized array TabStrings; var localized string HeaderText; @@ -330,6 +334,50 @@ function CallBack_ResetInputOptions() } } +function Callback_MouseLookUpScale(float NewValue) +{ + local KFPlayerInput KFPI; + + NewValue = -NewValue; + + KFPI = KFPlayerInput(GetPC().PlayerInput); + KFPI.MouseLookUpScale = NewValue; + KFPI.SaveConfig(); + + //Manager.CachedProfile.SetProfileSettingValueFloat(KFID_MouseLookUpScale, NewValue); +} + +function Callback_MouseLookRightScale(float NewValue) +{ + local KFPlayerInput KFPI; + + KFPI = KFPlayerInput(GetPC().PlayerInput); + KFPI.MouseLookRightScale = NewValue; + KFPI.SaveConfig(); + + // Manager.CachedProfile.SetProfileSettingValueFloat(KFID_MouseLookRightScale, NewValue); +} + +function Callback_ViewSmoothingChanged(bool bActive) +{ + local KFPlayerInput KFPI; + + KFPI = KFPlayerInput(GetPC().PlayerInput); + KFPI.bViewSmoothingEnabled = bActive; + + Manager.CachedProfile.SetProfileSettingValueInt(KFID_ViewSmoothingEnabled, bActive ? 1 : 0); +} + +function Callback_ViewAccelerationChanged(bool bActive) +{ + local KFPlayerInput KFPI; + + KFPI = KFPlayerInput(GetPC().PlayerInput); + KFPI.bViewAccelerationEnabled = bActive; + + Manager.CachedProfile.SetProfileSettingValueInt(KFID_ViewAccelerationEnabled, bActive ? 1 : 0); +} + defaultproperties { MinControllerLookSensitivity=.4 @@ -345,6 +393,11 @@ defaultproperties MinMouseLookZoomSensitivity=.2 MaxMouseLookZoomSensitivity=1 + MinMouseLookUpScale=20 + MaxMouseLookUpScale=500 + MinMouseLookRightScale=20 + MaxMouseLookRightScale=500 + SubWidgetBindings.Add((WidgetName="keybindingsContainer",WidgetClass=class'KFGFxControlsContainer_Keybinding')) SubWidgetBindings.Add((WidgetName="inputContainer",WidgetClass=class'KFGFxControlsContainer_Input')) SubWidgetBindings.Add((WidgetName="controllerPresetsContainer",WidgetClass=class'KFGFxControlsContainer_ControllerPresets')) diff --git a/KFGame/Classes/KFGFxStartGameContainer_FindGame.uc b/KFGame/Classes/KFGFxStartGameContainer_FindGame.uc index 0812078..a9b76d4 100644 --- a/KFGame/Classes/KFGFxStartGameContainer_FindGame.uc +++ b/KFGame/Classes/KFGFxStartGameContainer_FindGame.uc @@ -182,7 +182,7 @@ function FillWhatsNew() local SWhatsNew item; WhatsNewItems.Remove(0, WhatsNewItems.Length); // Latest Update - item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Summer2022_TidalTerror", "LatestUpdate", "http://www.tripwireinteractive.com/redirect/KF2LatestUpdate/"); + item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Halloween2022_BloodBonfire", "LatestUpdate", "http://www.tripwireinteractive.com/redirect/KF2LatestUpdate/"); WhatsNewItems.AddItem(item); // Featured Ultimate Edition item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Summer2022_UltimateEdition_Upgrade", "FeaturedItemBundle", "https://store.steampowered.com/app/1914560/KF2__Ultimate_Edition_Upgrade_DLC/"); @@ -194,31 +194,31 @@ function FillWhatsNew() item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Spring_Armory_Season_Pass", "ArmorySeasonPass", "https://store.steampowered.com/app/1524820/Killing_Floor_2__Armory_Season_Pass"); WhatsNewItems.AddItem(item); // Featured Weapon Bundle - item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Summer2022_Weaponsbundle", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9369"); + item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Blodd_Bornfires_Weapon_Bundle", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9471"); WhatsNewItems.AddItem(item); // Featured Weapon - item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Summer2022_ReductoRay", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9367"); + item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Blood_Sickle_Weapon_bundle", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9469"); WhatsNewItems.AddItem(item); // Featured Weapon - item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Summer2022_Sentinel","FeaturedItemBundle","https://store.steampowered.com/buyitem/232090/9368"); + item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_G36C_Weapon_Bundle","FeaturedItemBundle","https://store.steampowered.com/buyitem/232090/9467"); WhatsNewItems.AddItem(item); // Featured Outfit Bundle - item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Summer2022_DeepSea_Explorer_Uniforms", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9366"); + item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Halloween2022_PlagueDoctor_Uniforms", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9465"); WhatsNewItems.AddItem(item); // Featured Time Limited Item - item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_SS_PremiumTicket", "FeaturedEventItem", "https://store.steampowered.com/buyitem/232090/4928"); + item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Halloween_PremiumTicket", "FeaturedEventItem", "https://store.steampowered.com/buyitem/232090/5246"); WhatsNewItems.AddItem(item); // Featured Weapon Skin Bundle - item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Summer2022_DeepSea_Weapon_Skin", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9364"); + item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Halloween2022_Plague_Weapon_Skin", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9457"); WhatsNewItems.AddItem(item); // Featured Weapon Skin Bundle - item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Summer2022_NeonMKVIII_Weapon_Skin", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9362"); + item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Halloween2022_Weapon_skins_XenoPack", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9459"); WhatsNewItems.AddItem(item); // Featured Weapon Skin Bundle - item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Summer2022_Classic_Weapon_Skin", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9363"); + item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Halloween2022_Classic2_Weapon_Skin", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9461"); WhatsNewItems.AddItem(item); // Featured Weapon Skin Bundle - item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Summer2022_Chameleon_Weapon_Skin", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9365"); + item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Halloween2022_Chamaleon2_Weapon_Skin", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9463"); WhatsNewItems.AddItem(item); // Misc Community Links item=SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_CommunityHub", "Jaegorhorn", "https://steamcommunity.com/app/232090"); diff --git a/KFGame/Classes/KFGFxStoreContainer_Main.uc b/KFGame/Classes/KFGFxStoreContainer_Main.uc index f8c1b8c..19195b3 100644 --- a/KFGame/Classes/KFGFxStoreContainer_Main.uc +++ b/KFGame/Classes/KFGFxStoreContainer_Main.uc @@ -447,25 +447,25 @@ DefaultProperties XboxFilterExceptions[0]="Wasteland Bundle" // Wasteland Outfit Bundle - FeaturedItemIDs[0]=8178 //Whatsnew Gold Ticket - FeaturedItemIDs[1]=9369 - FeaturedItemIDs[2]=9367 - FeaturedItemIDs[3]=9368 - FeaturedItemIDs[4]=9366 - FeaturedItemIDs[5]=9364 - FeaturedItemIDs[6]=9362 - FeaturedItemIDs[7]=9363 - FeaturedItemIDs[8]=9365 + FeaturedItemIDs[0]=7944 //Whatsnew Gold Ticket + FeaturedItemIDs[1]=9471 + FeaturedItemIDs[2]=9469 + FeaturedItemIDs[3]=9467 + FeaturedItemIDs[4]=9465 + FeaturedItemIDs[5]=9457 + FeaturedItemIDs[6]=9459 + FeaturedItemIDs[7]=9461 + FeaturedItemIDs[8]=9463 - ConsoleFeaturedItemIDs[0]=8181 //Whatsnew Gold Ticket PSN - ConsoleFeaturedItemIDs[1]=9369 - ConsoleFeaturedItemIDs[2]=9367 - ConsoleFeaturedItemIDs[3]=9368 - ConsoleFeaturedItemIDs[4]=9366 - ConsoleFeaturedItemIDs[5]=9364 - ConsoleFeaturedItemIDs[6]=9362 - ConsoleFeaturedItemIDs[7]=9363 - ConsoleFeaturedItemIDs[8]=9365 + ConsoleFeaturedItemIDs[0]=7947 //Whatsnew Gold Ticket PSN + ConsoleFeaturedItemIDs[1]=9471 + ConsoleFeaturedItemIDs[2]=9469 + ConsoleFeaturedItemIDs[3]=9467 + ConsoleFeaturedItemIDs[4]=9465 + ConsoleFeaturedItemIDs[5]=9457 + ConsoleFeaturedItemIDs[6]=9459 + ConsoleFeaturedItemIDs[7]=9461 + ConsoleFeaturedItemIDs[8]=9463 MaxFeaturedItems=5 } \ No newline at end of file diff --git a/KFGame/Classes/KFGFxTraderContainer_PlayerInfo.uc b/KFGame/Classes/KFGFxTraderContainer_PlayerInfo.uc index bc6d04b..f4cd9c8 100644 --- a/KFGame/Classes/KFGFxTraderContainer_PlayerInfo.uc +++ b/KFGame/Classes/KFGFxTraderContainer_PlayerInfo.uc @@ -70,18 +70,25 @@ function SetPerkList() local GFxObject PerkObject; local GFxObject DataProvider; local KFPlayerController KFPC; - local byte i; + local byte i, counter; local int PerkPercent; + local KFGameReplicationInfo KFGRI; KFPC = KFPlayerController(GetPC()); if (KFPC != none) { DataProvider = CreateArray(); + KFGRI = KFGameReplicationInfo(KFPC.WorldInfo.GRI); + + counter = 0; for (i = 0; i < KFPC.PerkList.Length; i++) - { - - + { + if (KFGRI != none && !KFGRI.IsPerkAllowed(KFPC.PerkList[i].PerkClass)) + { + continue; + } + PerkObject = CreateObject( "Object" ); PerkObject.SetString("name", KFPC.PerkList[i].PerkClass.default.PerkName); PerkObject.SetString("perkIconSource", "img://"$KFPC.PerkList[i].PerkClass.static.GetPerkIconPath()); @@ -90,8 +97,12 @@ function SetPerkList() PerkPercent = KFPC.GetPerkLevelProgressPercentage(KFPC.PerkList[i].PerkClass); PerkObject.SetInt("perkXP", PerkPercent); + + PerkObject.SetInt("perkIndex", i); - DataProvider.SetElementObject(i, PerkObject); + DataProvider.SetElementObject(counter, PerkObject); + + ++counter; } SetObject("perkList", DataProvider); diff --git a/KFGame/Classes/KFGameInfo.uc b/KFGame/Classes/KFGameInfo.uc index 42128de..ea2c024 100644 --- a/KFGame/Classes/KFGameInfo.uc +++ b/KFGame/Classes/KFGameInfo.uc @@ -3902,6 +3902,11 @@ simulated function AddWeaponsFromSpawnList(KFPawn P); simulated function OverrideHumanDefaults(KFPawn_Human P); +/*********************************************** + * @name Helper for halloween 2022 barmwich bonfire seasonal objective + **********************************************/ +function ClearActorFromBonfire(Actor Other); + /*********************************************** * @name Damage Modifier for Event **********************************************/ diff --git a/KFGame/Classes/KFGameInfo_Entry.uc b/KFGame/Classes/KFGameInfo_Entry.uc index b151a8e..53ba891 100644 --- a/KFGame/Classes/KFGameInfo_Entry.uc +++ b/KFGame/Classes/KFGameInfo_Entry.uc @@ -484,11 +484,11 @@ auto State PendingMatch { local int SystemTimeMinutes; - // Update every 30 minutes using system clock for suspend mode. + // Update every minute using system clock for suspend mode. // Originally tried using GameEnding(), but the TitleData response // doesn't come back in time for the new map. SystemTimeMinutes = GetSystemTimeMinutes(); - if ( (SystemTimeMinutes - LastSystemTimeMinutes) >= 30 ) + if ( (SystemTimeMinutes - LastSystemTimeMinutes) >= 1 ) { class'KFGameEngine'.static.RefreshOnlineGameData(); LastSystemTimeMinutes = SystemTimeMinutes; diff --git a/KFGame/Classes/KFGameReplicationInfo.uc b/KFGame/Classes/KFGameReplicationInfo.uc index 6cfcea7..57291f7 100644 --- a/KFGame/Classes/KFGameReplicationInfo.uc +++ b/KFGame/Classes/KFGameReplicationInfo.uc @@ -364,6 +364,28 @@ var int CurrentWeeklyIndex; /** If true, force show skip time between waves ready button */ var bool bForceShowSkipTrader; +/** Struct with replicated information about the VIP mode */ +struct native ReplicatedVIPGameInfo +{ + var int CurrentHealth; + var int MaxHealth; + var KFPlayerReplicationInfo VIPPlayer; + + structdefaultproperties + { + VIPPlayer = none + CurrentHealth = 0 + MaxHealth = 0 + } +}; +var transient ReplicatedVIPGameInfo VIPModeData; + +/** Structs are sent as a pack through the network. Split it in variables for optimization. */ +var repnotify int VIPRepCurrentHealth; +var repnotify int VIPRepMaxHealth; +var repnotify KFPlayerReplicationInfo VIPRepPlayer; + + /************************************ * Steam heartbeat ************************************/ @@ -398,7 +420,7 @@ replication TraderVolume, TraderVolumeCheckType, bTraderIsOpen, NextTrader, WaveNum, bWaveIsEndless, GunGameWavesCurrent, bWaveGunGameIsFinal, AIRemaining, WaveTotalAICount, bWaveIsActive, MaxHumanCount, bGlobalDamage, CurrentObjective, PreviousObjective, PreviousObjectiveResult, PreviousObjectiveXPResult, PreviousObjectiveVoshResult, MusicIntensity, ReplicatedMusicTrackInfo, MusicTrackRepCount, bIsUnrankedGame, GameSharedUnlocks, bHidePawnIcons, ConsoleGameSessionGuid, GameDifficulty, GameDifficultyModifier, BossIndex, bWaveStarted, NextObjective, bIsBrokenTrader, bIsWeeklyMode, - CurrentWeeklyIndex, bIsEndlessPaused, bForceSkipTraderUI; //@HSL - JRO - 3/21/2016 - PS4 Sessions + CurrentWeeklyIndex, bIsEndlessPaused, bForceSkipTraderUI, VIPRepCurrentHealth, VIPRepMaxHealth, VIPRepPlayer; //@HSL - JRO - 3/21/2016 - PS4 Sessions if ( bNetInitial ) GameLength, WaveMax, bCustom, bVersusGame, TraderItems, GameAmmoCostScale, bAllowGrenadePurchase, MaxPerkLevel, bTradersEnabled, bForceShowSkipTrader; if ( bNetInitial || bNetDirty ) @@ -550,14 +572,26 @@ simulated event ReplicatedEvent(name VarName) { UpdatePerksAvailable(); } - else if (VarName == 'GunGameWavesCurrent') + else if (VarName == nameof(GunGameWavesCurrent)) { UpdateHUDWaveCount(); } - else if (VarName == 'bWaveGunGameIsFinal') + else if (VarName == nameof(bWaveGunGameIsFinal)) { UpdateHUDWaveCount(); } + else if (VarName == nameof(VIPRepCurrentHealth)) + { + UpdateVIPCurrentHealth(VIPRepCurrentHealth); + } + else if (VarName == nameof(VIPRepMaxHealth)) + { + UpdateVIPMaxHealth(VIPRepMaxHealth); + } + else if (VarName == nameof(VIPRepPlayer)) + { + UpdateVIPPlayer(VIPRepPlayer); + } else { super.ReplicatedEvent(VarName); @@ -2269,11 +2303,95 @@ simulated function NotifyWeeklyEventIndex(int EventIndex) } +/** VIP weekly */ +simulated function UpdateVIPMaxHealth(int NewMaxHealth) +{ + if (NewMaxHealth != VIPModeData.MaxHealth) + { + VIPModeData.MaxHealth = NewMaxHealth; + + if (Role == ROLE_Authority) + { + VIPRepMaxHealth = NewMaxHealth; + bNetDirty = true; + } + + if (WorldInfo.NetMode != NM_DedicatedServer) + { + UpdateVIPUI(); + } + } +} + +simulated function UpdateVIPCurrentHealth(int NewCurrentHealth) +{ + if (NewCurrentHealth != VIPModeData.CurrentHealth) + { + VIPModeData.CurrentHealth = NewCurrentHealth; + + if (Role == ROLE_Authority) + { + VIPRepCurrentHealth = NewCurrentHealth; + bNetDirty = true; + } + + if (WorldInfo.NetMode != NM_DedicatedServer) + { + UpdateVIPUI(); + } + } +} + +simulated function UpdateVIPPlayer(KFPlayerReplicationInfo NewVIPPlayer) +{ + if (NewVIPPlayer == none) + { + return; + } + + if (NewVIPPlayer != VIPModeData.VIPPlayer) + { + VIPModeData.VIPPlayer = NewVIPPlayer; + + if (Role == ROLE_Authority) + { + VIPRepPlayer = NewVIPPlayer; + bNetDirty = true; + } + + if (WorldInfo.NetMode != NM_DedicatedServer) + { + UpdateVIPUI(); + } + } +} + +simulated function UpdateVIPUI() +{ + local KFPlayerController_WeeklySurvival KFPC_WS; + + if( WorldInfo.NetMode == NM_DedicatedServer ) + { + return; + } + + KFPC_WS = KFPlayerController_WeeklySurvival(GetALocalPlayerController()); + if (KFPC_WS != none) + { + KFPC_WS.UpdateVIPWidget(VIPModeData); + } +} + simulated function bool IsGunGameMode() { return bIsWeeklyMode && CurrentWeeklyIndex == 16; } +simulated function bool IsVIPMode() +{ + return bIsWeeklyMode && CurrentWeeklyIndex == 17; +} + defaultproperties { TraderItemsPath="GP_Trader_ARCH.DefaultTraderItems" @@ -2298,4 +2416,7 @@ defaultproperties bForceSkipTraderUI=false GunGameWavesCurrent=1 bWaveGunGameIsFinal=false + VIPRepCurrentHealth=0 + VIPRepMaxHealth=0 + VIPRepPlayer=none } diff --git a/KFGame/Classes/KFGfxMenu_StartGame.uc b/KFGame/Classes/KFGfxMenu_StartGame.uc index bda8db5..ec61629 100644 --- a/KFGame/Classes/KFGfxMenu_StartGame.uc +++ b/KFGame/Classes/KFGfxMenu_StartGame.uc @@ -206,7 +206,7 @@ static function class GetSpecialEventClass case SEI_Summer: return class'KFGFxSpecialEventObjectivesContainer_Summer2022'; case SEI_Fall: - return class'KFGFxSpecialEventObjectivesContainer_Fall2021'; + return class'KFGFxSpecialEventObjectivesContainer_Fall2022'; case SEI_Winter: return class'KFGFXSpecialEventObjectivesContainer_Xmas2021'; } diff --git a/KFGame/Classes/KFHUDBase.uc b/KFGame/Classes/KFHUDBase.uc index 6daa52e..8e352f0 100644 --- a/KFGame/Classes/KFHUDBase.uc +++ b/KFGame/Classes/KFHUDBase.uc @@ -126,6 +126,10 @@ var const Texture2D GenericHumanIconTexture; /** Texture used for the generic zed icon */ var const Texture2D GenericZedIconTexture; +/** Texture used for the VIP representation over a player */ +var const Texture2D VIPIconTexture; +var const float OriginalVIPIconSize; + /** * Draw a glowing string */ @@ -772,7 +776,7 @@ simulated function bool DrawFriendlyHumanPlayerInfo( KFPawn_Human KFPH ) local float ResModifier; local float PerkIconPosX, PerkIconPosY, SupplyIconPosX, SupplyIconPosY, PerkIconSize; local color CurrentArmorColor, CurrentHealthColor; - + local float VIPIconSize, VIPIconPosX, VIPIconPosY; ResModifier = WorldInfo.static.GetResolutionBasedHUDScale() * FriendlyHudScale; @@ -812,14 +816,11 @@ simulated function bool DrawFriendlyHumanPlayerInfo( KFPawn_Human KFPH ) CurrentArmorColor = ClassicPlayerInfo ? ClassicArmorColor : ArmorColor; DrawKFBar(Percentage, BarLength, BarHeight, ScreenPos.X - (BarLength * 0.5f), ScreenPos.Y + BarHeight + (36 * FontScale * ResModifier), CurrentArmorColor); - - //Draw health bar PercentageHealth = FMin(float(KFPH.Health) / float(KFPH.HealthMax), 100); CurrentHealthColor = ClassicPlayerInfo ? ClassicHealthColor : HealthColor; DrawKFBar(PercentageHealth, BarLength, BarHeight, ScreenPos.X - (BarLength * 0.5f), ScreenPos.Y + BarHeight * 2 + (36 * FontScale * ResModifier), CurrentHealthColor); - //Draw health being regenerated bar PercentageHealthToRegen = FMin(float(KFPH.HealthToRegen) / float(KFPH.HealthMax), 100); PercentageHealthMissing = FMin((float(KFPH.HealthMax) - float(KFPH.Health)) / float(KFPH.HealthMax), 100); @@ -827,6 +828,19 @@ simulated function bool DrawFriendlyHumanPlayerInfo( KFPawn_Human KFPH ) CurrentHealthColor = HealthBeingRegeneratedColor; DrawKFBar(1, PercentageHealthToRegen * BarLength, BarHeight, ScreenPos.X + BarLength * (PercentageHealth - 0.5f), ScreenPos.Y + BarHeight * 2 + (36 * FontScale * ResModifier), HealthBeingRegeneratedColor); + if (KFGRI != none + && KFGRI.IsVIPMode() + && KFPH.PlayerReplicationInfo != none + && KFGRI.VIPModeData.VIPPlayer != none + && KFPH.PlayerReplicationInfo == KFGRI.VIPModeData.VIPPlayer) + { + // Draw VIP Icon + VIPIconSize = OriginalVIPIconSize * ResModifier; + VIPIconPosX = ScreenPos.X - VIPIconSize * 0.5f; + VIPIconPosY = ScreenPos.Y - 2.5f * BarHeight + (36 * FontScale * ResModifier) - 20.f * ResModifier - VIPIconSize * 0.5f - 1.f; + DrawVIPIcon(VIPIconSize , VIPIconPosX, VIPIconPosY); + } + if( KFPRI.CurrentPerkClass == none ) { return false; @@ -862,6 +876,12 @@ simulated function bool DrawFriendlyHumanPlayerInfo( KFPawn_Human KFPH ) return true; } +simulated function DrawVIPIcon(float VIPIconSize, float VIPIconPosX, float VIPIconPosY) +{ + Canvas.SetPos(VIPIconPosX, VIPIconPosY); + Canvas.DrawTile(VIPIconTexture, VIPIconSize, VIPIconSize, 0, 0, 256, 256); +} + simulated function bool DrawScriptedPawnInfo(KFPawn_Scripted KFPS, float NormalizedAngle, bool bRendered) { local float Percentage; @@ -1088,7 +1108,7 @@ simulated function CheckAndDrawHiddenPlayerIcons( array V } } - DrawHiddenHumanPlayerIcon( PRI, PawnLocation, Normal((PawnLocation + (class'KFPawn_Human'.default.CylinderComponent.CollisionHeight * vect(0, 0, 2))) - ViewLocation) dot ViewVector); + DrawHiddenHumanPlayerIcon(PRI, PawnLocation, ViewLocation, ViewVector); } } @@ -1099,13 +1119,15 @@ simulated function CheckAndDrawHiddenPlayerIcons( array V * @param IconWorldLocation The "player's" location in the world * @Note:This is the one we want to clamp */ -function DrawHiddenHumanPlayerIcon( PlayerReplicationInfo PRI, vector IconWorldLocation, float NormalizedAngle) +function DrawHiddenHumanPlayerIcon(PlayerReplicationInfo PRI, vector IconWorldLocation, vector ViewLocation, vector ViewVector) { - local vector ScreenPos; + local vector ReferencePosition, UpVector, ScreenPos, VIPIconPos, ViewLeftVector; local float IconSizeMult; local KFPlayerReplicationInfo KFPRI; local Texture2D PlayerIcon; local float ResModifier; + local float VIPIconSize; + local float NormalizedAngle, NormalizedAngleWithLeftView; ResModifier = WorldInfo.static.GetResolutionBasedHUDScale() * FriendlyHudScale; @@ -1115,7 +1137,91 @@ function DrawHiddenHumanPlayerIcon( PlayerReplicationInfo PRI, vector IconWorldL return; } - ScreenPos = Canvas.Project(IconWorldLocation + class'KFPawn_Human'.default.CylinderComponent.CollisionHeight * vect(0, 0, 2)); + ReferencePosition = IconWorldLocation + (class'KFPawn_Human'.default.CylinderComponent.CollisionHeight * vect(0, 0, 2)); + + NormalizedAngle = Normal(ReferencePosition - ViewLocation) dot ViewVector; + + ScreenPos = Canvas.Project(ReferencePosition); + + if (KFGRI != none + && KFGRI.IsVIPMode() + && KFGRI.VIPModeData.VIPPlayer != none + && PRI != none + && PRI == KFGRI.VIPModeData.VIPPlayer) + { + VIPIconSize = OriginalVIPIconSize * ResModifier; + + VIPIconPos = ScreenPos; + VIPIconPos.X -= VIPIconSize * 0.5f; + + // If the player is on front of you + if (NormalizedAngle > 0) + { + // Adjust on X + if (ScreenPos.X < 0 || ScreenPos.X > (Canvas.ClipX - VIPIconSize)) + { + if (ScreenPos.X < 0) + { + VIPIconPos.X = 0; + } + else + { + VIPIconPos.X = Canvas.ClipX - VIPIconSize; + } + } + + // Adjust on Y + if (ScreenPos.Y < 0 || ScreenPos.Y > (Canvas.ClipY - VIPIconSize)) + { + if (ScreenPos.Y < 0) + { + VIPIconPos.Y = 0; + } + else + { + VIPIconPos.Y = Canvas.ClipY - VIPIconSize; + } + } + } + // If the player is behind you + else + { + // New to know if Player is on your left or on your right side.. + UpVector.Z = 1; + ViewLeftVector = ViewVector cross UpVector; + NormalizedAngleWithLeftView = Normal(ReferencePosition - ViewLocation) dot ViewLeftVector; + + // The X position clamps between minimum and maximum, we don't interpolate in the middle as it makes more difficult for the player to understand + // Where the VIP is + + // Adjust on X + if (NormalizedAngleWithLeftView > 0) + { + VIPIconPos.X = 0; + } + else + { + VipIconPos.X = Canvas.ClipX - VIPIconSize; + } + + // Adjust on Y + if (ScreenPos.Y < 0 || ScreenPos.Y > (Canvas.ClipY - VIPIconSize)) + { + if (ScreenPos.Y < 0) + { + VIPIconPos.Y = 0; + } + else + { + VIPIconPos.Y = Canvas.ClipY - VIPIconSize; + } + } + } + + Canvas.SetDrawColorStruct(PlayerBarIconColor); + DrawVIPIcon(VIPIconSize, VIPIconPos.X, VIPIconPos.Y); + } + // Fudge by icon size IconSizeMult = (PlayerStatusIconSize * 0.8) * ResModifier; ScreenPos.X -= IconSizeMult; @@ -1135,6 +1241,7 @@ function DrawHiddenHumanPlayerIcon( PlayerReplicationInfo PRI, vector IconWorldL { CurrentAlphaDelta = 5; } + ScreenPos.X = Canvas.ClipX - ScreenPos.x; ScreenPos = GetClampedScreenPosition(ScreenPos); CurrentVoiceCommsHighlightAlpha += CurrentAlphaDelta; @@ -1142,7 +1249,6 @@ function DrawHiddenHumanPlayerIcon( PlayerReplicationInfo PRI, vector IconWorldL Canvas.SetDrawColor(255, 255, 255, CurrentVoiceCommsHighlightAlpha); Canvas.SetPos(ScreenPos.X - (IconSizeMult * VoiceCommsIconHighlightScale / 2), ScreenPos.Y - (IconSizeMult * VoiceCommsIconHighlightScale / 2)); Canvas.DrawTile(IconHighLightTexture, IconSizeMult + (IconSizeMult * VoiceCommsIconHighlightScale), IconSizeMult + (IconSizeMult * VoiceCommsIconHighlightScale), 0, 0, 128, 128); - } else { @@ -1371,6 +1477,9 @@ defaultproperties GenericHumanIconTexture = Texture2D'UI_PerkIcons_TEX.UI_Horzine_H_Logo' GenericZedIconTexture = Texture2D'UI_PerkIcons_TEX.UI_PerkIcon_ZED' + + VIPIConTexture = Texture2D'UI_PerkIcons_TEX.UI_Overscreen_vip_icon_' + OriginalVIPIconSize = 64; IconHighLightTexture = Texture2D'UI_World_TEX.VoicCommsCircleHighlight' VoiceCommsIconHighlightScale = 0.5f diff --git a/KFGame/Classes/KFInventoryManager.uc b/KFGame/Classes/KFInventoryManager.uc index 69947d4..596143e 100644 --- a/KFGame/Classes/KFInventoryManager.uc +++ b/KFGame/Classes/KFInventoryManager.uc @@ -21,6 +21,7 @@ var transient KFWeap_HealerBase HealerWeapon; /** Localized message for quick heal */ var localized string FullHealthMsg; +var localized string CannotHealthMsg; /** The number of grenades the character is carrying */ var byte GrenadeCount; @@ -1270,6 +1271,20 @@ simulated function AttemptQuickHeal() { local KFWeap_HealerBase W; local KFPlayerController KFPC; + local KFPlayerController_WeeklySurvival KFPCWS; + local KFGameReplicationInfo KFGRI; + + KFGRI = KFGameReplicationInfo(WorldInfo.GRI); + KFPCWS = KFPlayerController_WeeklySurvival(Instigator.Owner); + + // VIP cannot heal + if (KFGRI != none + && KFGRI.VIPRepPlayer != none + && KFGRI.VIPRepPlayer == KFPlayerReplicationInfo(KFPCWS.PlayerReplicationInfo)) + { + KFPCWS.MyGFxHUD.ShowNonCriticalMessage(CannotHealthMsg); + return; + } // Do not heal if we have full health if ( Instigator.Health >= Instigator.HealthMax ) diff --git a/KFGame/Classes/KFLaserSightAttachment.uc b/KFGame/Classes/KFLaserSightAttachment.uc index cbc50fb..cd70b6a 100644 --- a/KFGame/Classes/KFLaserSightAttachment.uc +++ b/KFGame/Classes/KFLaserSightAttachment.uc @@ -57,6 +57,11 @@ var() float AnimBlendRate; var transient float LaserSightAimStrength; var transient float DesiredAimStrength; +// Use for automatic weapons, then the Laser Dot will always steer to the hit location no matter what +var transient bool bForceDotToMatch; + +var transient bool IsVisible; + /** Create/Attach lasersight components */ function AttachLaserSight(SkeletalMeshComponent OwnerMesh, bool bFirstPerson, optional name SocketNameOverride) { @@ -135,6 +140,8 @@ simulated function SetMeshLightingChannels(LightingChannelContainer NewLightingC simulated event ChangeVisibility(bool bVisible) { + IsVisible = bVisible; + LaserDotMeshComp.SetHidden(!bVisible); LaserSightMeshComp.SetHidden(!bVisible); LaserBeamMeshComp.SetHidden(!bVisible); @@ -159,6 +166,11 @@ simulated function Update(float DeltaTime, KFWeapon OwningWeapon) local Quat Q; local TraceHitInfo HitInfo; + if (IsVisible == false) + { + return; + } + if( OwningWeapon != None && OwningWeapon.Instigator != None && OwningWeapon.Instigator.Weapon == OwningWeapon && @@ -287,6 +299,21 @@ simulated function Update(float DeltaTime, KFWeapon OwningWeapon) } } +function bool IsIdleFidgetAnimation(KFWeapon W, name AnimationName) +{ + local int i; + + for (i = 0; i < W.IdleFidgetAnims.Length; ++i) + { + if (AnimationName == W.IdleFidgetAnims[i]) + { + return true; + } + } + + return false; +} + /** Determine how much to weigh screen center versus weapon socket */ function UpdateFirstPersonAImStrength(float DeltaTime, KFWeapon W) { @@ -297,8 +324,16 @@ function UpdateFirstPersonAImStrength(float DeltaTime, KFWeapon W) { DesiredAimStrength = 1.f - AnimWeight; } + // we are forcing the dot to match, don't do while reloading though + else if (bForceDotToMatch + && (W.IsInstate('Reloading') == false + && W.IsInState('WeaponSprinting') == false + && IsIdleFidgetAnimation(W, W.WeaponAnimSeqNode.AnimSeqName) == false)) + { + DesiredAimStrength = 1.f - AnimWeight; + } // follow weapon - else + else { DesiredAimStrength = 0.f; } @@ -409,4 +444,8 @@ defaultproperties LaserDotLerpEndDistance=6000.f LaserDotMaxScale=10.f LaserDotDepthBias=0.95f + + IsVisible=true + + bForceDotToMatch=false } diff --git a/KFGame/Classes/KFLocalMessage_Priority.uc b/KFGame/Classes/KFLocalMessage_Priority.uc index 3f1c474..ecaa856 100644 --- a/KFGame/Classes/KFLocalMessage_Priority.uc +++ b/KFGame/Classes/KFLocalMessage_Priority.uc @@ -17,6 +17,7 @@ var localized string ScavengeMessage; var localized string YouLostMessage; var localized string YouWonMessage; var localized string SquadWipedOutMessage; +var localized string SquadWipedOutVIPMessage; var localized string SquadSurvivedMessage; var localized string ObjectiveStartMessage; var localized string ObjectiveWonMessage; @@ -231,6 +232,8 @@ static function ClientReceive( static function string GetMessageString(int Switch, optional out String SecondaryString, optional byte TeamIndex) { + local KFGameReplicationInfo KFGRI; + SecondaryString = ""; switch ( Switch ) @@ -281,7 +284,16 @@ static function string GetMessageString(int Switch, optional out String Secondar case GMT_MatchLost: if(class'WorldInfo'.static.GetWorldInfo().NetMode != NM_Standalone) { - SecondaryString = default.SquadWipedOutMessage; + KFGRI = KFGameReplicationInfo(class'WorldInfo'.static.GetWorldInfo().GRI); + + if (KFGRI != none && KFGRI.bIsWeeklyMode && KFGRI.CurrentWeeklyIndex == 17) + { + SecondaryString = default.SquadWipedOutVIPMessage; + } + else + { + SecondaryString = default.SquadWipedOutMessage; + } } return default.YouLostMessage; diff --git a/KFGame/Classes/KFOnlineStatsReadDingo.uc b/KFGame/Classes/KFOnlineStatsReadDingo.uc index 5b29a48..e98d807 100644 --- a/KFGame/Classes/KFOnlineStatsReadDingo.uc +++ b/KFGame/Classes/KFOnlineStatsReadDingo.uc @@ -71,6 +71,7 @@ defaultproperties ColumnIds.Add(STATID_ACHIEVE_NetherholdCollectibles) ColumnIds.Add(STATID_ACHIEVE_CarillonHamletCollectibles) ColumnIds.Add(STATID_ACHIEVE_RigCollectibles) + ColumnIds.Add(STATID_ACHIEVE_BarmwichCollectibles) ColumnMappings.Add((Id=STATID_ACHIEVE_MrPerky5, Name="AchievementMrPerky5")) ColumnMappings.Add((Id=STATID_ACHIEVE_MrPerky10, Name = "AchievementMrPerky10")) @@ -130,4 +131,5 @@ defaultproperties ColumnMappings.Add((Id=STATID_ACHIEVE_NetherholdCollectibles,Name="AchievementCollectNetherhold")) ColumnMappings.Add((Id=STATID_ACHIEVE_CarillonHamletCollectibles,Name="AchievementCollectCarillonHamlet")) ColumnMappings.Add((Id=STATID_ACHIEVE_RigCollectibles,Name="AchievementCollectRig")) + ColumnMappings.Add((Id=STATID_ACHIEVE_BarmwichCollectibles,Name="AchievementCollectBarmwichTown")) } diff --git a/KFGame/Classes/KFOnlineStatsWrite.uc b/KFGame/Classes/KFOnlineStatsWrite.uc index 637e6b4..8a1259e 100644 --- a/KFGame/Classes/KFOnlineStatsWrite.uc +++ b/KFGame/Classes/KFOnlineStatsWrite.uc @@ -445,6 +445,10 @@ const KFACHID_RigHard = 292; const KFACHID_RigHellOnEarth = 293; const KFACHID_RigCollectibles = 294; +const KFACHID_BarmwichHard = 295; +const KFACHID_BarmwichHellOnEarth = 296; +const KFACHID_BarmwichCollectibles = 297; + /* __TW_ANALYTICS_ */ var int PerRoundWeldXP; var int PerRoundHealXP; @@ -2093,15 +2097,16 @@ defaultproperties //Firebug Weapons DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Flame_CaulkBurn, KFDT_Bludgeon_CaulkBurn,KFDT_Fire_CaulkBurn,KFDT_Fire_Ground_CaulkNBurn),CompletionAmount=5000)) //3000 DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Pistol_Flare, KFDT_Bludgeon_FlareGun,KFDT_Fire_FlareGun,KFDT_Fire_FlareGun_Dual,KFDT_Fire_FlareGunDoT),CompletionAmount=7000)) //5000 - DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Shotgun_DragonsBreath, KFDT_Ballistic_DragonsBreath,KFDT_Bludgeon_DragonsBreath,KFDT_Fire_DragonsBreathDoT),CompletionAmount=7000)) //5000 + DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Shotgun_DragonsBreath, KFDT_Ballistic_DragonsBreath,KFDT_Bludgeon_DragonsBreath,KFDT_Fire_DragonsBreathDoT, KFDT_Fire_Ground_DragonsBreath),CompletionAmount=7000)) //5000 DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_SMG_Mac10, KFDT_Bludgeon_Mac10,KFDT_Fire_Mac10,KFDT_Fire_Mac10DoT),CompletionAmount=9000)) //7000 DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Flame_Flamethrower, KFDT_Bludgeon_Flamethrower,KFDT_Fire_FlameThrower,KFDT_Fire_Ground_FlameThrower),CompletionAmount=9000)) //7000 DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_AssaultRifle_HRGIncendiaryRifle, KFDT_Bludgeon_HRGIncendiaryRifle,KFDT_Ballistic_HRGIncendiaryRifle,KFDT_Explosive_HRGIncendiaryRifle,KFDT_Ballistic_HRGIncendiaryRifleGrenadeImpact,KFDT_Fire_HRGIncendiaryRifleBulletDoT,KFDT_Fire_HRGIncendiaryRifleGrenadeDoT,KFDT_Fire_Ground_HRGIncendiaryRifle),CompletionAmount=9000)) DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Pistol_HRGScorcher, KFDT_Bludgeon_HRGScorcher,KFDT_Ballistic_HRGScorcherLightingImpact,KFDT_Fire_HRGScorcherDoT,KFDT_Ballistic_HRGScorcherBrokenImpact,KFDT_Fire_Ground_HRGScorcher),CompletionAmount=9000)) DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Beam_Microwave, KFDT_Bludgeon_MicrowaveGun,KFDT_Fire_Ground_MicrowaveGun,KFDT_Microwave,KFDT_Microwave_Beam,KFDT_Microwave_Blast),CompletionAmount=10000)) DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_HuskCannon, KFDT_Bludgeon_HuskCannon, KFDT_Explosive_HuskCannon, KFDT_HuskCannonDot, KFDT_Explosive_HuskCannonImpact),CompletionAmount=10000)) + DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_HRG_Dragonbreath, KFDT_Ballistic_HRG_Dragonbreath, KFDT_Bludgeon_HRG_Dragonbreath, KFDT_Fire_HRG_DragonsBreathDoT, KFDT_Fire_HRG_DragonsBreathDoT, KFDT_Fire_Ground_HRG_DragonBreath),CompletionAmount=10000)) DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_AssaultRifle_Microwave, KFDT_Ballistic_MicrowaveRifle, KFDT_Fire_MicrowaveRifleDoT, KFDT_Bludgeon_MicrowaveRifle),CompletionAmount=10000)) - + //Berserker Weapons DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Blunt_Crovel, KFDT_Bludgeon_Crovel,KFDT_Bludgeon_CrovelBash,KFDT_Slashing_Crovel),CompletionAmount=5000)) //3000 DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Shotgun_Nailgun, KFDT_Ballistic_NailShotgun,KFDT_Bludgeon_NailShotgun),CompletionAmount=7000)) //5000 @@ -2136,6 +2141,7 @@ defaultproperties DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_AssaultRifle_FNFal, KFDT_Ballistic_FNFal,KFDT_Bludgeon_FNFal),CompletionAmount=10000)) //Survivalist Weapons + DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_HRG_Locust, KFDT_Bludgeon_HRG_Locust, KFDT_Toxic_HRG_Locust, KFDT_Ballistic_HRG_Locust),CompletionAmount=7000)) DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Ice_FreezeThrower, KFDT_Bludgeon_Freezethrower, KFDT_Freeze_FreezeThrower, KFDT_Freeze_FreezeThrower_IceShards, KFDT_Freeze_Ground_FreezeThrower),CompletionAmount=7000)) DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_HRG_EMP_ArcGenerator, KFDT_Bludgeon_ArcGenerator, KFDT_EMP_ArcGenerator_Beam, KFDT_EMP_ArcGeneratorSphereImpact, KFDT_EMP_ArcGenerator_DefaultFiremodeZapDamage, KFDT_EMP_ArcGenerator_AltFiremodeZapDamage),CompletionAmount=9000)) DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_AssaultRifle_LazerCutter, KFDT_Ballistic_LazerCutter, KFDT_LazerCutter_Beam, KFDT_Bludgeon_LazerCutter),CompletionAmount=10000)) @@ -2286,6 +2292,9 @@ defaultproperties DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-RIG),CompletionAmount=1)) DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-RIG),CompletionAmount=2)) DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-RIG),CompletionAmount=3)) + DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-BARMWICHTOWN),CompletionAmount=1)) + DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-BARMWICHTOWN),CompletionAmount=2)) + DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-BARMWICHTOWN),CompletionAmount=3)) //Versus Damage // Per design doc that I have right now, these are x class damage y players, not damage y amount diff --git a/KFGame/Classes/KFOnlineStatsWriteDingo.uc b/KFGame/Classes/KFOnlineStatsWriteDingo.uc index 65ce0d3..61857f6 100644 --- a/KFGame/Classes/KFOnlineStatsWriteDingo.uc +++ b/KFGame/Classes/KFOnlineStatsWriteDingo.uc @@ -73,4 +73,6 @@ defaultproperties Properties.Add((PropertyId = STATID_ACHIEVE_NetherholdCollectibles, Data = (Type = SDT_Int32, Value1 = 0))) Properties.Add((PropertyId = STATID_ACHIEVE_CarillonHamletCollectibles, Data = (Type = SDT_Int32, Value1 = 0))) Properties.Add((PropertyId = STATID_ACHIEVE_RigCollectibles, Data = (Type = SDT_Int32, Value1 = 0))) + Properties.Add((PropertyId = STATID_ACHIEVE_BarmwichCollectibles, Data = (Type = SDT_Int32, Value1 = 0))) + } diff --git a/KFGame/Classes/KFOutbreakEvent.uc b/KFGame/Classes/KFOutbreakEvent.uc index a879439..f29ec57 100644 --- a/KFGame/Classes/KFOutbreakEvent.uc +++ b/KFGame/Classes/KFOutbreakEvent.uc @@ -448,7 +448,12 @@ struct WeeklyOverrides var() bool bGunGameMode; /** Information about each level in Gun Game Mode */ - var() GunGamePerkData GunGamePerksData; + var() GunGamePerkData GunGamePerksData; + + /** VIP targetting */ + var() const array< class > VIPTargetting; + + var() bool bVIPGameMode; /** Ignores damage caused by headshots. */ var() bool bInvulnerableHeads; @@ -459,9 +464,6 @@ struct WeeklyOverrides /** Time between waves override. */ var() float TimeBetweenWaves; - /** Wether or not we only can spawn Armor on the Item pickups */ - var() bool bOnlyArmorItemPickup; - structdefaultproperties { GameLength = GL_Short @@ -522,10 +524,10 @@ struct WeeklyOverrides bDisableAddDosh = false; bDisableThrowWeapon = false; bGunGameMode = false; + bVIPGameMode = false; bInvulnerableHeads = false; TraderTimeModifier = 1.f; TimeBetweenWaves = -1.f; - bOnlyArmorItemPickup=false; bForceShowSkipTrader = false; } }; diff --git a/KFGame/Classes/KFPawn.uc b/KFGame/Classes/KFPawn.uc index aead556..55084f8 100644 --- a/KFGame/Classes/KFPawn.uc +++ b/KFGame/Classes/KFPawn.uc @@ -178,6 +178,10 @@ struct native DamageInfo var array > DamageTypes; }; +// VFX that need to linger when a specific DamageType starts (those should loop), we stop them when the DamageType ends affecting +var() ParticleSystem Toxic_HRG_Locust_LoopingParticleEffect; +var transient ParticleSystemComponent Toxic_HRG_Locust_LoopingPSC; + /** List of PRIs who damaged the specimen */ var array DamageHistory; @@ -885,6 +889,7 @@ var transient byte LastHitZoneIndex; */ var const bool bIsTurret; +var repnotify bool bEnableSwarmVFX; replication { @@ -893,7 +898,8 @@ replication AmbientSound, WeaponClassForAttachmentTemplate, bIsSprinting, InjuredHitZones, KnockdownImpulse, ReplicatedSpecialMove, bEmpDisrupted, bEmpPanicked, bFirePanicked, RepFireBurnedAmount, bUnaffectedByZedTime, bMovesFastInZedTime, IntendedBodyScale, - IntendedHeadScale, AttackSpeedModifier, bHasStartedFire, PowerUpAmbientSound, BodyScaleChangePerSecond; + IntendedHeadScale, AttackSpeedModifier, bHasStartedFire, PowerUpAmbientSound, BodyScaleChangePerSecond, + bEnableSwarmVFX; if ( bNetDirty && WorldInfo.TimeSeconds < LastTakeHitTimeout ) HitFxInfo, HitFxRadialInfo, HitFxInstigator, HitFxAddedRelativeLocs, HitFxAddedHitCount; if ( Physics == PHYS_RigidBody && !bTearOff ) @@ -1171,6 +1177,18 @@ simulated event ReplicatedEvent(name VarName) break; case nameof(WeaponSpecialAction): OnWeaponSpecialAction(WeaponSpecialAction); + break; + + case nameof(bEnableSwarmVFX): + if (bEnableSwarmVFX) + { + StartLocustVFX(); + } + else + { + StopLocustVFX(); + } + break; } Super.ReplicatedEvent(VarName); @@ -2709,7 +2727,7 @@ event TakeDamage(int Damage, Controller InstigatedBy, vector HitLocation, vector Super.TakeDamage(Damage, InstigatedBy, HitLocation, Momentum, DamageType, HitInfo, DamageCauser); // using the passed in damage type instead of the hitfxinfo since that doesn't get updated when zero damage is done - // HandleAfflictionsOnHit(InstigatedBy, Normal(Momentum), class(DamageType), DamageCauser); + HandleAfflictionsOnHit(InstigatedBy, Normal(Momentum), class(DamageType), DamageCauser); ActualDamage = OldHealth - Health; if( ActualDamage > 0 ) @@ -2811,6 +2829,15 @@ function AdjustDamage(out int InDamage, out vector Momentum, Controller Instigat InDamage *= VolumeDamageScale; + if (KFPlayerController(Controller) != none) + { + KFPlayerController(Controller).AdjustDamage(InDamage, InstigatedBy, DamageType, DamageCauser, self); + } + else if (KFPlayerController(InstigatedBy) != none) + { + KFPlayerController(InstigatedBy).AdjustDamage(InDamage, InstigatedBy, DamageType, DamageCauser, self); + } + // Check non lethal damage KFDT = class(DamageType); if ( InDamage >= Health && KFDT != none && KFDT.default.bNonLethalDamage ) @@ -2915,6 +2942,30 @@ function AddTakenDamage( Controller DamagerController, int Damage, Actor DamageC } } +function TimerRestartForceEnemy() +{ + local KFAIController KFAIC; + local Pawn ForcedEnemy; + + if (Controller != none) + { + KFAIC = KFAIController( Controller ); + if (KFAIC != none) + { + // Forces the ForcedEnemy again + + KFAIC.CanForceEnemy = true; + + ForcedEnemy = KFAIC.FindForcedEnemy(); + + if (ForcedEnemy != none) + { + KFAIC.ChangeEnemy(ForcedEnemy); + } + } + } +} + function UpdateDamageHistory( Controller DamagerController, int Damage, Actor DamageCauser, class DamageType ) { local DamageInfo Info; @@ -2943,19 +2994,40 @@ function UpdateDamageHistory( Controller DamagerController, int Damage, Actor Da DamageHistory[KFAIC.CurrentEnemysHistoryIndex].Damage = 0; } - if( KFAIC.IsAggroEnemySwitchAllowed() - && DamagerController.Pawn != KFAIC.Enemy - && Info.Damage >= DamageThreshold - && Info.Damage > DamageHistory[KFAIC.CurrentEnemysHistoryIndex].Damage ) + // If we have a forced Enemy break it only if we fulfill the minimum health value + if (KFAIC.ForcedEnemy != none) { - BlockerPawn = KFAIC.GetPawnBlockingPathTo( DamagerController.Pawn, true ); - if( BlockerPawn == none ) + if (GetHealthPercentage() < KFAIC.DamageRatioToChangeForcedEnemy) { - bChangedEnemies = KFAIC.SetEnemy(DamagerController.Pawn); + // Only if X seconds passed since last time we choose the ForcedEnemy + if ((WorldInfo.TimeSeconds - KFAIC.ForcedEnemyLastTime) > KFAIC.TimeCannotChangeFromForcedEnemy) + { + KFAIC.CanForceEnemy = false; // The timer we will reenable this to allow selection again + + // If we have forced enemy, reactivate ForcedEnemy after X seconds, so it can default to the ForcedEnemy again + ClearTimer('TimerRestartForceEnemy'); + SetTimer(KFAIC.TimeCanRestartForcedEnemy, false, 'TimerRestartForceEnemy'); + + KFAIC.ChangeEnemy(DamagerController.Pawn); + } } - else + } + else + { + if (KFAIC.IsAggroEnemySwitchAllowed() + && DamagerController.Pawn != KFAIC.Enemy + && Info.Damage >= DamageThreshold + && Info.Damage > DamageHistory[KFAIC.CurrentEnemysHistoryIndex].Damage) { - bChangedEnemies = KFAIC.SetEnemy( BlockerPawn ); + BlockerPawn = KFAIC.GetPawnBlockingPathTo( DamagerController.Pawn, true ); + if( BlockerPawn == none ) + { + bChangedEnemies = KFAIC.SetEnemy(DamagerController.Pawn); + } + else + { + bChangedEnemies = KFAIC.SetEnemy( BlockerPawn ); + } } } } @@ -3403,6 +3475,8 @@ simulated function bool IsHeadless(); /** Clean up function to terminate any effects on death */ simulated function TerminateEffectsOnDeath() { + local int i; + // Destroy our weapon attachment if( WeaponAttachment != None && !WeaponAttachment.bPendingDelete ) { @@ -3420,11 +3494,18 @@ simulated function TerminateEffectsOnDeath() AfflictionHandler.Shutdown(); + StopLocustVFX(); + // send a special stop event to the audio system if ( SoundGroupArch.OnDeathStopEvent != None ) { PostAkEvent( SoundGroupArch.OnDeathStopEvent ); } + + for (i = 0 ; i < DamageOverTimeArray.Length; i++) + { + OnEndDamageType(DamageOverTimeArray[i].DamageType); + } } /********************************************************************************************* @@ -4043,12 +4124,12 @@ simulated function KFSkinTypeEffects GetHitZoneSkinTypeEffects( int HitZoneIdx ) */ simulated function AdjustAffliction(out float AfflictionPower); -function HandleAfflictionsOnHit(Controller DamageInstigator, vector HitDir, class DamageType, Actor DamageCauser) +function HandleAfflictionsOnHit(Controller DamageInstigator, vector HitDir, class DamageType, Actor DamageCauser) { //Handle afflictions if (AfflictionHandler != None) { - AfflictionHandler.NotifyTakeHit(DamageInstigator, HitDir, class(DamageType), DamageCauser); + AfflictionHandler.NotifyTakeHit(DamageInstigator, HitDir, DamageType, DamageCauser); } } @@ -4084,6 +4165,8 @@ function ApplyDamageOverTime(int Damage, Controller InstigatedBy, class DamageType) +{ + switch (DamageType.Name) + { + case 'KFDT_Toxic_HRG_Locust': + StartLocustVFX(); + break; + } +} + +simulated function OnEndDamageType(class DamageType) +{ + switch (DamageType.Name) + { + case 'KFDT_Toxic_HRG_Locust': + StopLocustVFX(); + break; + } +} + /********************************************************************************************* * @name Animation ********************************************************************************************* */ @@ -5408,6 +5513,43 @@ simulated function StopExtraVFX(Name FXLabel) simulated function SetTurretWeaponAttachment(class WeaponClass) {} +simulated function StartLocustVFX() +{ + if ( WorldInfo.NetMode == NM_DedicatedServer ) + { + bEnableSwarmVFX=true; + bNetDirty = true; + return; + } + + if (Toxic_HRG_Locust_LoopingParticleEffect != none) + { + if (Toxic_HRG_Locust_LoopingPSC == none) + { + Toxic_HRG_Locust_LoopingPSC = WorldInfo.MyEmitterPool.SpawnEmitter(Toxic_HRG_Locust_LoopingParticleEffect, Location, Rotation, self); + } + else + { + Toxic_HRG_Locust_LoopingPSC.SetStopSpawning(-1, false); + } + } +} + +simulated function StopLocustVFX() +{ + if ( WorldInfo.NetMode == NM_DedicatedServer ) + { + bEnableSwarmVFX=false; + bForceNetUpdate = true; + return; + } + + if (Toxic_HRG_Locust_LoopingPSC != none) + { + Toxic_HRG_Locust_LoopingPSC.SetStopSpawning(-1, true); + } +} + defaultproperties { InventoryManagerClass=class'KFInventoryManager' @@ -5674,4 +5816,8 @@ defaultproperties // --------------------------------------------- // AutoTurret bIsTurret=false + + Toxic_HRG_Locust_LoopingParticleEffect=ParticleSystem'WEP_HRG_Locust_EMIT.FX_Flying_Bugs_attacking' + Toxic_HRG_Locust_LoopingPSC=none + bEnableSwarmVFX=false } diff --git a/KFGame/Classes/KFPawn_Human.uc b/KFGame/Classes/KFPawn_Human.uc index 7c6bf68..bd724a8 100644 --- a/KFGame/Classes/KFPawn_Human.uc +++ b/KFGame/Classes/KFPawn_Human.uc @@ -157,7 +157,16 @@ var float MinHealthPctToTriggerSurrounded; /********************************************************************************************* * @name Perk @ToDo: Move stuff to PRI and combine in a byte/INT ********************************************************************************************* */ -var array ActiveSkillIconPaths; + +struct native ActiveSkill +{ + var string IconPath; + var int Multiplier; + var float MaxDuration; + var float Duration; +}; + +var private array ActiveSkills; var repnotify private byte HealingSpeedBoost; var repnotify private byte HealingDamageBoost; @@ -632,6 +641,7 @@ function float GetHealthMod() simulated function WeaponStateChanged(byte NewState, optional bool bViaReplication) { CurrentWeaponState = NewState; + bForceNetUpdate=true; // skip if this pawn was recently spawned, so we don't play out-of-date anims when pawns become relevant if( `TimeSince(CreationTime) < 1.f ) @@ -711,6 +721,18 @@ event bool HealDamage(int Amount, Controller Healer, class DamageTyp local KFPlayerController KFPC; local KFPowerUp KFPowerUp; local KFGameInfo GameInfo; + local KFPlayerController_WeeklySurvival KFPCWS; + + KFPCWS = KFPlayerController_WeeklySurvival(Healer); + + if (Controller != none && KFPCWS != none && KFPCWS.VIPGameData.IsVIP) + { + // VIP can't heal itself + if (Controller == KFPCWS) + { + return false; + } + } KFPC = KFPlayerController(Controller); if ( KFPC != none ) @@ -896,6 +918,11 @@ function GiveHealthOverTime() KFPRI.PlayerHealth = Health; KFPRI.PlayerHealthPercent = FloatToByte( float(Health) / float(HealthMax) ); } + + if (KFPlayerController_WeeklySurvival(Controller) != none) + { + KFPlayerController_WeeklySurvival(Controller).UpdateVIPDamage(); + } } else { @@ -1272,6 +1299,15 @@ function AdjustDamage(out int InDamage, out vector Momentum, Controller Instigat } } + if (KFPlayerController_WeeklySurvival(Controller) != none) + { + KFPlayerController_WeeklySurvival(Controller).AdjustVIPDamage(InDamage, InstigatedBy); + } + else if (KFPlayerController_WeeklySurvival(InstigatedBy) != none) + { + KFPlayerController_WeeklySurvival(InstigatedBy).AdjustVIPDamage(InDamage, InstigatedBy); + } + if( bHasSacrificeSkill && Health >= 5 && Health - InDamage < 5 ) { Health = InDamage + 5; @@ -1302,8 +1338,14 @@ function AdjustDamage(out int InDamage, out vector Momentum, Controller Instigat } } `endif + + if (KFPlayerController_WeeklySurvival(Controller) != none) + { + KFPlayerController_WeeklySurvival(Controller).UpdateVIPDamage(); + } } + event TakeDamage(int Damage, Controller InstigatedBy, vector HitLocation, vector Momentum, class DamageType, optional TraceHitInfo HitInfo, optional Actor DamageCauser) { local int ActualDamageTaken, OldHealth, OldArmor; @@ -1451,12 +1493,17 @@ function StartAirBorneAgentEvent() simulated function UpdateHealingSpeedBoost() { HealingSpeedBoost = Min( HealingSpeedBoost + class'KFPerk_FieldMedic'.static.GetHealingSpeedBoost(), class'KFPerk_FieldMedic'.static.GetMaxHealingSpeedBoost() ); + SetTimer( class'KFPerk_FieldMedic'.static.GetHealingSpeedBoostDuration(),, nameOf(ResetHealingSpeedBoost) ); - if ( WorldInfo.NetMode == NM_STANDALONE) + if (WorldInfo.NetMode == NM_STANDALONE) { NotifyHealingSpeedBoostBuff(HealingSpeedBoost); } + else + { + ClientNotifyHealingSpeedBoostBuff(HealingSpeedBoost); + } } simulated function ResetHealingSpeedBoost() @@ -1482,12 +1529,17 @@ simulated function float GetHealingDamageBoostModifier() simulated function UpdateHealingDamageBoost() { HealingDamageBoost = Min( HealingDamageBoost + class'KFPerk_FieldMedic'.static.GetHealingDamageBoost(), class'KFPerk_FieldMedic'.static.GetMaxHealingDamageBoost() ); + SetTimer( class'KFPerk_FieldMedic'.static.GetHealingDamageBoostDuration(),, nameOf(ResetHealingDamageBoost) ); - if ( WorldInfo.NetMode == NM_STANDALONE) + if (WorldInfo.NetMode == NM_STANDALONE) { NotifyHealingDamageBoostBuff(HealingDamageBoost); } + else + { + ClientNotifyHealingDamageBoostBuff(HealingDamageBoost); + } } simulated function ResetHealingDamageBoost() @@ -1513,12 +1565,17 @@ simulated function float GetHealingShieldModifier() simulated function UpdateHealingShield() { HealingShield = Min( HealingShield + class'KFPerk_FieldMedic'.static.GetHealingShield(), class'KFPerk_FieldMedic'.static.GetMaxHealingShield() ); + SetTimer( class'KFPerk_FieldMedic'.static.GetHealingShieldDuration(),, nameOf(ResetHealingShield) ); - if ( WorldInfo.NetMode == NM_STANDALONE) + if (WorldInfo.NetMode == NM_STANDALONE) { NotifyHealingShieldBoostBuff(HealingShield); } + else + { + ClientNotifyHealingShieldBoostBuff(HealingShield); + } } simulated function ResetHealingShield() @@ -1574,11 +1631,6 @@ function float GetPerkDoTScaler( optional Controller InstigatedBy, optional clas return DoTScaler; } -function array GetUpdatedSkillIndicators() -{ - return ActiveSkillIconPaths; -} - /********************************************************************************************* * @name Dialog ********************************************************************************************* */ @@ -2060,10 +2112,30 @@ simulated function NotifyHealingSpeedBoostBuff(byte Speed) if( IsLocallyControlled() ) { - UpdateActiveSkillsPath(class'KFPerk_FieldMedic'.default.PerkSkills[EMedicHealingSpeedBoost].IconPath, Speed > 0.0f); + UpdateHealingSpeedBoostBuff(Speed); } } +reliable client function ClientNotifyHealingSpeedBoostBuff(byte Speed) +{ + UpdateHealingSpeedBoostBuff(Speed); +} + +simulated function UpdateHealingSpeedBoostBuff(byte Speed) +{ + local float TotalTimes, Multiplier; + + TotalTimes = class'KFPerk_FieldMedic'.static.GetMaxHealingSpeedBoost() / float(class'KFPerk_FieldMedic'.static.GetHealingSpeedBoost()); + + Multiplier = Speed / float(class'KFPerk_FieldMedic'.static.GetMaxHealingSpeedBoost()); + Multiplier *= TotalTimes; + + UpdateActiveSkillsPath(class'KFPerk_FieldMedic'.default.PerkSkills[EMedicHealingSpeedBoost].IconPath + , Multiplier + , Speed > 0 + , class'KFPerk_FieldMedic'.static.GetHealingSpeedBoostDuration()); +} + simulated function NotifyHealingDamageBoostBuff(byte Damage) { if( Role == ROLE_Authority ) @@ -2074,10 +2146,30 @@ simulated function NotifyHealingDamageBoostBuff(byte Damage) if( IsLocallyControlled() ) { - UpdateActiveSkillsPath(class'KFPerk_FieldMedic'.default.PerkSkills[EMedicHealingDamageBoost].IconPath, Damage > 0.0f); + UpdateHealingDamageBoostBuff(Damage); } } +reliable client function ClientNotifyHealingDamageBoostBuff(byte Damage) +{ + UpdateHealingDamageBoostBuff(Damage); +} + +simulated function UpdateHealingDamageBoostBuff(byte Damage) +{ + local float TotalTimes, Multiplier; + + TotalTimes = class'KFPerk_FieldMedic'.static.GetMaxHealingDamageBoost() / float(class'KFPerk_FieldMedic'.static.GetHealingDamageBoost()); + + Multiplier = Damage / float(class'KFPerk_FieldMedic'.static.GetMaxHealingDamageBoost()); + Multiplier *= TotalTimes; + + UpdateActiveSkillsPath(class'KFPerk_FieldMedic'.default.PerkSkills[EMedicHealingDamageBoost].IconPath + , Multiplier + , Damage > 0 + , class'KFPerk_FieldMedic'.static.GetHealingDamageBoostDuration()); +} + simulated function NotifyHealingShieldBoostBuff(byte Shield) { if( Role == ROLE_Authority ) @@ -2088,28 +2180,70 @@ simulated function NotifyHealingShieldBoostBuff(byte Shield) if( IsLocallyControlled() ) { - UpdateActiveSkillsPath(class'KFPerk_FieldMedic'.default.PerkSkills[EMedicHealingShield].IconPath, Shield > 0.0f); + UpdateHealingShieldBoostBuff(Shield); } } -function UpdateActiveSkillsPath(string IconPath, bool Active) +reliable client function ClientNotifyHealingShieldBoostBuff(byte Shield) +{ + UpdateHealingShieldBoostBuff(Shield); +} + +simulated function UpdateHealingShieldBoostBuff(byte Shield) +{ + local float TotalTimes, Multiplier; + + TotalTimes = class'KFPerk_FieldMedic'.static.GetMaxHealingShield() / float(class'KFPerk_FieldMedic'.static.GetHealingShield()); + + Multiplier = Shield / float(class'KFPerk_FieldMedic'.static.GetMaxHealingShield()); + Multiplier *= TotalTimes; + + UpdateActiveSkillsPath(class'KFPerk_FieldMedic'.default.PerkSkills[EMedicHealingShield].IconPath + , Multiplier + , Shield > 0 + , class'KFPerk_FieldMedic'.static.GetHealingShieldDuration()); +} + +function UpdateActiveSkillsPath(string IconPath, int Multiplier, bool Active, float MaxDuration) { local KFPlayerController KFPC; + local int i, IndexSearch; + local ActiveSkill active_Skill; - if(Active) + if (Active) { - if (ActiveSkillIconPaths.Find(IconPath) == INDEX_NONE) + IndexSearch = ActiveSkills.Find('IconPath', IconPath); + + if (IndexSearch == INDEX_NONE) { - ActiveSkillIconPaths.AddItem(IconPath); + active_Skill.IconPath = IconPath; + active_Skill.Multiplier = Multiplier; + active_Skill.MaxDuration = MaxDuration; + active_Skill.Duration = MaxDuration; + + ActiveSkills.AddItem(active_Skill); + } + else + { + ActiveSkills[IndexSearch].Multiplier = Multiplier; + ActiveSkills[IndexSearch].MaxDuration = MaxDuration; + ActiveSkills[IndexSearch].Duration = MaxDuration; } } else { - ActiveSkillIconPaths.RemoveItem(IconPath); + for (i=0; i < ActiveSkills.Length; ++i) + { + if (ActiveSkills[i].IconPath == IconPath) + { + ActiveSkills.Remove(i, 1); + break; + } + } } KFPC = KFPlayerController(Controller); - KFPC.MyGFxHUD.PlayerStatusContainer.ShowActiveIndicators(ActiveSkillIconPaths); + KFPC.MyGFxHUD.PlayerStatusContainer.ShowActiveIndicators(ActiveSkills); } event Landed(vector HitNormal, actor FloorActor) diff --git a/KFGame/Classes/KFPawn_Monster.uc b/KFGame/Classes/KFPawn_Monster.uc index 267f775..fc17e50 100644 --- a/KFGame/Classes/KFPawn_Monster.uc +++ b/KFGame/Classes/KFPawn_Monster.uc @@ -1170,11 +1170,18 @@ simulated event Bump( Actor Other, PrimitiveComponent OtherComp, Vector HitNorma function HandleMonsterBump( KFPawn_Monster Other, Vector HitNormal ) { local KFPlayerController KFPC; + local int LocustDoTIndex; + local int IgnoredIndex; if( !Other.IsNapalmInfected() && CanNapalmInfect(KFPC) ) { InfectWithNapalm( Other, KFPC ); } + + if (IsLocustInfected(LocustDoTIndex) && !Other.IsLocustInfected(IgnoredIndex)) + { + InfectWithLocust(Other, KFPlayerController(DamageOverTimeArray[LocustDoTIndex].InstigatedBy)); + } } /** Override to handle special berserker functionality */ @@ -2648,12 +2655,19 @@ simulated function int GetRallyBoostResistance( int NewDamage ) function bool Died(Controller Killer, class DamageType, vector HitLocation) { + local KFGameInfo KFGI; local KFPlayerController KFPC; local KFPerk InstigatorPerk; local int i; if ( super.Died(Killer, damageType, HitLocation) ) { + KFGI = KFGameInfo(WorldInfo.Game); + if (KFGI != none) + { + KFGI.ClearActorFromBonfire(self); + } + if( Killer != none && Killer.Pawn != none && KFPawn_Human(Killer.Pawn) != none ) { `DialogManager.PlayKilledZedDialog( KFPawn_Human(Killer.Pawn), self, DamageType, IsDoingSpecialMove(SM_Knockdown) || IsDoingSpecialMove(SM_RecoverFromRagdoll) ); @@ -2761,6 +2775,12 @@ simulated function bool IsNapalmInfected() return DamageOverTimeArray.Find('DamageType', class'KFDT_Fire_Napalm') != INDEX_NONE; } +simulated function bool IsLocustInfected(out int OutDoTIndex) +{ + OutDoTIndex = DamageOverTimeArray.Find('DamageType', class'KFDT_Toxic_HRG_Locust'); + return OutDoTIndex != INDEX_NONE; +} + function bool CanNapalmInfect( out KFPlayerController NapalmInstigator ) { local int DoTIndex; @@ -2802,6 +2822,19 @@ function InfectWithNapalm( KFPawn_Monster KFPM, KFPlayerController KFPC ) } } +function InfectWithLocust( KFPawn_Monster KFPM, KFPlayerController KFPC ) +{ + if( KFPC != none ) + { + KFPM.TakeDamage( class'KFDT_Toxic_HRG_Locust'.static.GetSpreadOnTouchDamage(), + KFPC, + vect(0,0,0), + vect(0,0,0), + class'KFDT_Toxic_HRG_Locust',, + KFPC ); + } +} + /** * @brief Spawns a radioactive cloud that hurts other Zeds * @@ -3287,7 +3320,10 @@ simulated function PlayTakeHitEffects( vector HitDirection, vector HitLocation, if ( bPlayedDeath ) { - PlayDeadHitEffects(HitLocation, HitDirection, HitZoneIndex, HitZoneName, HitBoneName, DmgType, bUseHitImpulse); + if (DmgType.static.CanPlayDeadHitEffects()) + { + PlayDeadHitEffects(HitLocation, HitDirection, HitZoneIndex, HitZoneName, HitBoneName, DmgType, bUseHitImpulse); + } } else { diff --git a/KFGame/Classes/KFPerk.uc b/KFGame/Classes/KFPerk.uc index cdc6caa..94ededc 100644 --- a/KFGame/Classes/KFPerk.uc +++ b/KFGame/Classes/KFPerk.uc @@ -889,7 +889,7 @@ event NotifyPerkModified() PostLevelUp(); } -private simulated final function PerkSetOwnerHealthAndArmor( optional bool bModifyHealth ) +simulated final function PerkSetOwnerHealthAndArmor( optional bool bModifyHealth ) { // don't allow clients to set health, since health/healthmax/playerhealth/playerhealthpercent is replicated if( Role != ROLE_Authority ) @@ -906,7 +906,15 @@ private simulated final function PerkSetOwnerHealthAndArmor( optional bool bModi } OwnerPawn.HealthMax = OwnerPawn.default.Health; + ModifyHealth( OwnerPawn.HealthMax ); + + if (ModifyHealthMaxWeekly(OwnerPawn.HealthMax)) + { + // Change current health directly, Pawn.HealDamage does a lot of other stuff that can block the healing + OwnerPawn.Health = OwnerPawn.HealthMax; + } + OwnerPawn.Health = Min( OwnerPawn.Health, OwnerPawn.HealthMax ); if( OwnerPC == none ) @@ -927,6 +935,49 @@ private simulated final function PerkSetOwnerHealthAndArmor( optional bool bModi } } +function bool ModifyHealthMaxWeekly(out int InHealth) +{ + local KFGameReplicationInfo KFGRI; + local KFPlayerController_WeeklySurvival KFPC_WS; + local bool bNeedToFullyHeal; + + KFGRI = KFGameReplicationInfo(Owner.WorldInfo.GRI); + + bNeedToFullyHeal = false; + + //`Log("PerkSetOwnerHealthAndArmor: Max Health Before Weekly " $OwnerPawn.HealthMax); + + if (KFGRI.IsVIPMode()) + { + KFPC_WS = KFPlayerController_WeeklySurvival(Owner); + + if (KFPC_WS != none && OwnerPawn != none) + { + if (KFPC_WS.VIPGameData.isVIP) + { + // We don't need to check if already applied as this function resets the HealthMax to the value the Perk says + + InHealth += KFPC_WS.VIPGameData.ExtraHealth; + + // Heal if we are on trader time + if (KFGRI != none && KFGRI.bWaveIsActive == false) + { + bNeedToFullyHeal = true; + } + } + else + { + // We don't need to check if already applied as this function resets the HealthMax to the value the Perk says + // So no need to further reduce + } + } + } + + //`Log("PerkSetOwnerHealthAndArmor: Max Health " $OwnerPawn.HealthMax); + + return bNeedToFullyHeal; +} + /** (Server) Modify Instigator settings based on selected perk */ function ApplySkillsToPawn() { @@ -1419,6 +1470,7 @@ function TickRegen( float DeltaTime ) local int OldHealth; local KFPlayerReplicationInfo KFPRI; local KFPlayerController KFPC; + local KFPlayerController_WeeklySurvival KFPCWS; local KFPowerUp PowerUp; local bool bCannotBeHealed; local KFGameInfo GameInfo; @@ -1438,6 +1490,13 @@ function TickRegen( float DeltaTime ) GameInfo = KFGameInfo(WorldInfo.Game); bCannotBeHealed = bCannotBeHealed || (GameInfo.OutbreakEvent != none && GameInfo.OutbreakEvent.ActiveEvent.bCannotBeHealed); + // VIP cannot heal + KFPCWS = KFPlayerController_WeeklySurvival(OwnerPawn.Controller); + if (KFPCWS != none && KFPCWS.VIPGameData.IsVIP) + { + bCannotBeHealed = true; + } + // If the Pawn cannot be healed return... if( bCannotBeHealed ) { diff --git a/KFGame/Classes/KFPerk_Berserker.uc b/KFGame/Classes/KFPerk_Berserker.uc index f236255..d8bbe22 100644 --- a/KFGame/Classes/KFPerk_Berserker.uc +++ b/KFGame/Classes/KFPerk_Berserker.uc @@ -552,10 +552,12 @@ function NotifyZedTimeStarted() local KFGameInfo GameInfo; local bool bScaredAI; local bool bCannotBeHealed; + local KFGameReplicationInfo KFGRI; if( IsRageActive() && OwnerPawn != none ) { KFPC = KFPlayerController(OwnerPawn.Controller); + if( KFPC != none ) { PowerUp = KFPC.GetPowerUp(); @@ -566,6 +568,15 @@ function NotifyZedTimeStarted() { bCannotBeHealed = bCannotBeHealed ||(GameInfo.OutbreakEvent != none && GameInfo.OutbreakEvent.ActiveEvent.bCannotBeHealed); } + + // VIP cannot heal + KFGRI = KFGameReplicationInfo(WorldInfo.GRI); + if (KFGRI != none + && KFGRI.VIPRepPlayer != none + && KFGRI.VIPRepPlayer == KFPlayerReplicationInfo(KFPC.PlayerReplicationInfo)) + { + bCannotBeHealed = true; + } } if( bCannotBeHealed == false ) diff --git a/KFGame/Classes/KFPerk_Commando.uc b/KFGame/Classes/KFPerk_Commando.uc index 3221592..1b77c41 100644 --- a/KFGame/Classes/KFPerk_Commando.uc +++ b/KFGame/Classes/KFPerk_Commando.uc @@ -504,7 +504,7 @@ final private function bool IsHealthIncreaseActive() * * @return true/false */ -final private function bool IsEatLeadActive() +simulated final private function bool IsEatLeadActive() { return PerkSkills[ECommandoEatLead].bActive && IsPerkLevelAllowed(ECommandoEatLead); } diff --git a/KFGame/Classes/KFPerk_Demolitionist.uc b/KFGame/Classes/KFPerk_Demolitionist.uc index 6a69548..7d31312 100644 --- a/KFGame/Classes/KFPerk_Demolitionist.uc +++ b/KFGame/Classes/KFPerk_Demolitionist.uc @@ -380,7 +380,7 @@ static function PrepareExplosive( Pawn ProjOwner, KFProjectile Proj, optional fl Proj.ExplosionTemplate.DamageRadius = Proj.default.ExplosionTemplate.DamageRadius * class'KFPerk_Demolitionist'.static.GetNukeRadiusModifier() * AuxRadiusMod; Proj.ExplosionTemplate.DamageFalloffExponent = Proj.default.ExplosionTemplate.DamageFalloffExponent; } - else if( InstigatorPRI.bConcussiveActive && Proj.AltExploEffects != none ) + else if( InstigatorPRI.bConcussiveActive && Proj.AltExploEffects != none && class'KFPerk_Demolitionist'.static.ProjectileShouldConcussive(Proj) ) { Proj.ExplosionTemplate.ExplosionEffects = Proj.AltExploEffects; Proj.ExplosionTemplate.ExplosionSound = class'KFPerk_Demolitionist'.static.GetConcussiveExplosionSound(); @@ -394,8 +394,13 @@ static function PrepareExplosive( Pawn ProjOwner, KFProjectile Proj, optional fl KFPC = KFPlayerController( ProjOwner.Controller ); if( KFPC != none ) { - InstigatorPerk = KFPC.GetPerk(); - Proj.ExplosionTemplate.DamageRadius *= InstigatorPerk.GetAoERadiusModifier() * AuxRadiusMod; + Proj.ExplosionTemplate.DamageRadius *= AuxRadiusMod; + + if (class'KFPerk_Demolitionist'.static.ProjectileShouldExplosionChangeRadius(Proj)) + { + InstigatorPerk = KFPC.GetPerk(); + Proj.ExplosionTemplate.DamageRadius *= InstigatorPerk.GetAoERadiusModifier(); + } } } } @@ -686,6 +691,16 @@ simulated static function bool ProjectileShouldNuke( KFProjectile Proj ) return Proj.AllowNuke(); } +simulated static function bool ProjectileShouldConcussive( KFProjectile Proj ) +{ + return Proj.AllowDemolitionistConcussive(); +} + +simulated static function bool ProjectileShouldExplosionChangeRadius( KFProjectile Proj ) +{ + return Proj.AllowDemolitionistExplosionChangeRadius(); +} + simulated function bool DoorShouldNuke() { return IsNukeActive() && WorldInfo.TimeDilation < 1.f; diff --git a/KFGame/Classes/KFPerk_FieldMedic.uc b/KFGame/Classes/KFPerk_FieldMedic.uc index f82ab66..76add66 100644 --- a/KFGame/Classes/KFPerk_FieldMedic.uc +++ b/KFGame/Classes/KFPerk_FieldMedic.uc @@ -213,11 +213,15 @@ simulated function ModifyMagSizeAndNumber( KFWeapon KFW, out int MagazineCapacit TempCapacity = MagazineCapacity; - if( IsWeaponOnPerk( KFW, WeaponPerkClass, self.class ) && (KFW == none || !KFW.bNoMagazine) && !bSecondary ) + // Fix this function on the trader because KFW is None and the check cannot look for bNoMagazine = true + if(WeaponClassname != 'KFWeap_Rifle_HRGIncision') { - if( IsCombatantActive() ) + if( IsWeaponOnPerk( KFW, WeaponPerkClass, self.class ) && (KFW == none || !KFW.bNoMagazine) && !bSecondary ) { - TempCapacity += MagazineCapacity * GetSkillValue( PerkSkills[EMedicCombatant] ); + if( IsCombatantActive() ) + { + TempCapacity += MagazineCapacity * GetSkillValue( PerkSkills[EMedicCombatant] ); + } } } diff --git a/KFGame/Classes/KFPerk_Firebug.uc b/KFGame/Classes/KFPerk_Firebug.uc index 51268e4..7cda5ca 100644 --- a/KFGame/Classes/KFPerk_Firebug.uc +++ b/KFGame/Classes/KFPerk_Firebug.uc @@ -273,13 +273,12 @@ simulated function ModifyMagSizeAndNumber( KFWeapon KFW, out int MagazineCapacit TempCapacity = MagazineCapacity; // Fix this function on the trader because KFW is None and the check cannot look for bNoMagazine = true - if(WeaponClassname == 'KFWeap_Pistol_HRGScorcher') + if(WeaponClassname != 'KFWeap_Pistol_HRGScorcher' && WeaponClassname != 'KFWeap_HRG_Dragonbreath') { - TempCapacity = TempCapacity; - } - else if( IsWeaponOnPerk( KFW, WeaponPerkClass, self.class ) && IsHighCapFuelTankActive() && (KFW == none || !KFW.bNoMagazine) ) - { - TempCapacity += MagazineCapacity * GetSkillValue( PerkSkills[EFirebugHighCapFuelTank] ); + if( IsWeaponOnPerk( KFW, WeaponPerkClass, self.class ) && IsHighCapFuelTankActive() && (KFW == none || !KFW.bNoMagazine) ) + { + TempCapacity += MagazineCapacity * GetSkillValue( PerkSkills[EFirebugHighCapFuelTank] ); + } } MagazineCapacity = Round(TempCapacity); diff --git a/KFGame/Classes/KFPlayerController.uc b/KFGame/Classes/KFPlayerController.uc index 442eadc..40c255c 100644 --- a/KFGame/Classes/KFPlayerController.uc +++ b/KFGame/Classes/KFPlayerController.uc @@ -1631,6 +1631,13 @@ function OnReadProfileSettingsComplete(byte LocalUserNum,bool bWasSuccessful) KFInput.SetGamepadLayout(Profile.GetProfileInt(KFID_CurrentLayoutIndex)); KFInput.bToggleToRun = Profile.GetProfileBool(KFID_ToggleToRun); KFInput.bAllowSwapTo9mm = Profile.GetProfileBool(KFID_AllowSwapTo9mm); + + // Console?? PC?? + //KFInput.MouseLookUpScale = Profile.GetProfileFloat(KFID_MouseLookUpScale); + //KFInput.MouseLookRightScale = Profile.GetProfileFloat(KFID_MouseLookRightScale); + KFInput.bViewSmoothingEnabled = Profile.GetProfileBool(KFID_ViewSmoothingEnabled); + KFInput.bViewAccelerationEnabled = Profile.GetProfileBool(KFID_ViewAccelerationEnabled); + KFInput.ReInitializeControlsUI(); } @@ -2758,6 +2765,30 @@ public function bool CanUseGunGame() return false; } +public function bool CanUseVIP() +{ + /** If this is run in Server or Standalone, GameInfo exists so can access to the OutbreakEvent */ + if (Role == Role_Authority) + { + return KFGameInfo(WorldInfo.Game).OutbreakEvent != none + && KFGameInfo(WorldInfo.Game).OutbreakEvent.ActiveEvent.bVIPGameMode; + } + /** But in client, GameInfo doesn't exist, so needs to be checked in a different way. */ + else + { + /** + In client there's a kfgame replication info that contains if the mode is a weekly, and the index. + This way would also work in server, but will need to be in code rather than using the weekly variables. + */ + /** Another option is to use instead a variable replicated just with that value */ + return KFGameReplicationInfo(WorldInfo.GRI) != none + && KFGameReplicationInfo(WorldInfo.GRI).bIsWeeklyMode + && KFGameReplicationInfo(WorldInfo.GRI).CurrentWeeklyIndex == 17; + } + + return false; +} + /********************************************************************************************* * @name Skill Tracking ********************************************************************************************* */ @@ -10516,6 +10547,10 @@ protected function MotivatePlayerToMove() SetTimer( class'KFVersusNoGoVolume'.static.GetNoGoHurtInterval(), true, nameOf(MotivatePlayerToMove) ); } +function AdjustDamage(out int InDamage, Controller InstigatedBy, class DamageType, Actor DamageCauser, Actor DamageReceiver) +{ +} + exec function GCF() { if ( MyGFxManager != None ) diff --git a/KFGame/Classes/KFPlayerController_WeeklySurvival.uc b/KFGame/Classes/KFPlayerController_WeeklySurvival.uc index cb7fa5a..a3cc9ce 100644 --- a/KFGame/Classes/KFPlayerController_WeeklySurvival.uc +++ b/KFGame/Classes/KFPlayerController_WeeklySurvival.uc @@ -41,6 +41,10 @@ var protected const AkEvent AracnoStompSoundEvent; var protected const AKEvent GunGameLevelUpSoundEvent; var protected const AKEvent GunGameLevelUpFinalWeaponSoundEvent; +var protected const AKEvent VIPChosenSoundEvent; +var protected const AKEvent VIPLowHealthSoundEvent; +var protected float VIPLowHealthLastTimePlayed; + struct native GunGameInfo { var transient byte Level; @@ -59,6 +63,49 @@ structdefaultproperties }; var transient GunGameInfo GunGameData; +struct native VIPGameInfo +{ + var bool IsVIP; + var bool WasVIP; + var bool PendingHealthReset; + + var int ExtraHealth; + + var int DamageHealthLimit; + var int DamageHealthTop; + var int DamageHealthBottom; + + var float DamageLimitModifier; + + var float OutputDamageTopModifier; + var float InputDamageTopModifier; + + var float OutputDamageBottomModifier; + var float InputDamageBottomModifier; + + structdefaultproperties + { + IsVIP = false + WasVIP = false + PendingHealthReset = false + + ExtraHealth = 100 + + DamageHealthLimit = 100 + DamageHealthTop = 50 + DamageHealthBottom = 25 + + DamageLimitModifier = 1.0 + + OutputDamageTopModifier = 1.5 + InputDamageTopModifier = 0.75 + + OutputDamageBottomModifier = 1.75 + InputDamageBottomModifier = 0.5 + } +}; +var transient VIPGameInfo VIPGameData; + cpptext { virtual UBOOL TestZedTimeVisibility(APawn* P, UNetConnection* Connection, UBOOL bLocalPlayerTest) override; @@ -148,6 +195,31 @@ reliable client function UpdateGunGameWidget(int score, int max_score, int level } } +simulated function UpdateVIPWidget(ReplicatedVIPGameInfo VIPInfo) +{ + if (MyGFxHUD != none) + { + MyGFxHUD.UpdateVIP(VIPInfo, VIPInfo.VIPPlayer == PlayerReplicationInfo); + } +} + +function bool CanUseHealObject() +{ + local KFGameReplicationInfo KFGRI; + + KFGRI = KFGameReplicationInfo(WorldInfo.GRI); + + // VIP cannot heal + if (KFGRI != none + && KFGRI.VIPRepPlayer != none + && KFGRI.VIPRepPlayer == KFPlayerReplicationInfo(PlayerReplicationInfo)) + { + return false; + } + + return super.CanUseHealObject(); +} + /** Arachnophobia Goompa Stomp Streak functions */ @@ -247,6 +319,34 @@ reliable client function PlayGunGameMessage(bool isLastLevel) } } +reliable client function PlayVIPSound_ChosenInternal() +{ + if (VIPChosenSoundEvent != none) + { + PlaySoundBase(VIPChosenSoundEvent); + } +} + +reliable client function PlayVIPGameChosenSound(float delay) +{ + // Put a timer because the sound happens at the same time as end wave and it's difficult to distinguish + SetTimer(delay, false, nameof(PlayVIPSound_ChosenInternal)); +} + +reliable client function PlayVIPGameLowHealthSound() +{ + if (VIPLowHealthSoundEvent != none) + { + if (WorldInfo.TimeSeconds - VIPLowHealthLastTimePlayed > 8.f) + { + VIPLowHealthLastTimePlayed = WorldInfo.TimeSeconds; + + PlaySoundBase(VIPLowHealthSoundEvent); + } + } +} + + /** Resets all gameplay FX to initial state. Append to this list if additional effects are added. */ function ResetGameplayPostProcessFX() @@ -333,6 +433,174 @@ function UpdateInitialHeldWeapon() } } +function AdjustDamage(out int InDamage, Controller InstigatedBy, class DamageType, Actor DamageCauser, Actor DamageReceiver) +{ + local KFGameInfo KFGI; + local float Multiplier, ModifierRange, HealthTop, HealthRange; + local KFGameReplicationInfo KFGRI; + + super.AdjustDamage(InDamage, InstigatedBy, DamageType, DamageCauser, DamageReceiver); + + KFGI = KFGameInfo(WorldInfo.Game); + + if (Pawn != None && KFGI != none && KFGI.OutbreakEvent != none && KFGI.OutbreakEvent.ActiveEvent.bVIPGameMode) + { + KFGRI = KFGameReplicationInfo(WorldInfo.GRI); + + // If I am the VIP doing the damage, and I am NOT doing damage to myself + if (KFGRI != none + && KFGRI.VIPRepPlayer != none + && KFGRI.VIPRepPlayer == KFPlayerReplicationInfo(PlayerReplicationInfo) + && InstigatedBy == self + && DamageReceiver != self.Pawn) + { + Multiplier = 1.0; + + //`Log("Current health for VIP OUTPUT DAMAGE: " $Pawn.Health); + + if (Pawn.Health < VIPGameData.DamageHealthLimit) + { + if (Pawn.Health <= VIPGameData.DamageHealthBottom) + { + Multiplier = VIPGameData.OutputDamageBottomModifier; + } + else + { + if (Pawn.Health > VIPGameData.DamageHealthTop) + { + Multiplier = VIPGameData.DamageLimitModifier; + + // From 1.0 to 1.5 on the range of 100 - 50 + ModifierRange = VIPGameData.OutputDamageTopModifier - VIPGameData.DamageLimitModifier; + + HealthTop = VIPGameData.DamageHealthLimit; + HealthRange = Abs(HealthTop - VIPGameData.DamageHealthTop); + } + else + { + // From 1.5 to 1.75 on the range of 50 - 25 + Multiplier = VIPGameData.OutputDamageTopModifier; + + ModifierRange = VIPGameData.OutputDamageBottomModifier - VIPGameData.OutputDamageTopModifier; + + HealthTop = VIPGameData.DamageHealthTop; + HealthRange = Abs(HealthTop - VIPGameData.DamageHealthBottom); + } + + Multiplier += ModifierRange * ((HealthTop - Pawn.Health) / HealthRange); + } + } + else + { + Multiplier = VIPGameData.DamageLimitModifier; + } + + //`Log("Multiplier for VIP OUTPUT DAMAGE: Output: " $Multiplier); + + InDamage = int(float(InDamage) * Multiplier); + } + } +} + +function AdjustVIPDamage(out int InDamage, Controller InstigatedBy) +{ + local KFGameInfo KFGI; + local float Multiplier, ModifierRange, HealthTop, HealthRange; + local KFGameReplicationInfo KFGRI; + + KFGI = KFGameInfo(WorldInfo.Game); + if (Pawn != None && KFGI != none && KFGI.OutbreakEvent != none && KFGI.OutbreakEvent.ActiveEvent.bVIPGameMode) + { + KFGRI = KFGameReplicationInfo(WorldInfo.GRI); + + // If I am the VIP + // We do it on a different step as don't want to scale InDamage to VIP Armour when receiving damage + if (KFGRI != none + && KFGRI.VIPRepPlayer != none + && KFGRI.VIPRepPlayer == KFPlayerReplicationInfo(PlayerReplicationInfo)) + { + Multiplier = 1.0; + + //`Log("Current health for VIP INPUT DAMAGE: " $Pawn.Health); + + if (Pawn.Health < VIPGameData.DamageHealthLimit) + { + if (Pawn.Health <= VIPGameData.DamageHealthBottom) + { + Multiplier = VIPGameData.InputDamageBottomModifier; + } + else + { + if (Pawn.Health > VIPGameData.DamageHealthTop) + { + Multiplier = VIPGameData.DamageLimitModifier; + + // From 1.0 to 0.5 on the range of 100 - 50 + ModifierRange = VIPGameData.InputDamageTopModifier - VIPGameData.DamageLimitModifier; + + HealthTop = VIPGameData.DamageHealthLimit; + HealthRange = Abs(HealthTop - VIPGameData.DamageHealthTop); + } + else + { + // From 0.5 to 0.25 on the range of 50 - 25 + Multiplier = VIPGameData.InputDamageTopModifier; + + ModifierRange = VIPGameData.InputDamageBottomModifier - VIPGameData.InputDamageTopModifier; + + HealthTop = VIPGameData.DamageHealthTop; + HealthRange = Abs(HealthTop - VIPGameData.DamageHealthBottom); + } + + Multiplier += ModifierRange * ((HealthTop - Pawn.Health) / HealthRange); + } + } + else + { + Multiplier = VIPGameData.DamageLimitModifier; + } + + //`Log("Multiplier for VIP INPUT DAMAGE: Output: " $Multiplier); + + InDamage = int(float(InDamage) * Multiplier); + } + } +} + +function NotifyTakeHit(Controller InstigatedBy, vector HitLocation, int Damage, class damageType, vector Momentum) +{ + local KFPlayerController_WeeklySurvival KFPC_WS; + + Super.NotifyTakeHit(InstigatedBy,HitLocation,Damage,damageType,Momentum); + + if (VIPGameData.IsVIP) + { + // Only sound once we pass down 50, sound again if recovered health and go down again + if (Pawn.Health < 50 && Pawn.Health + Damage >= 50) + { + foreach WorldInfo.AllControllers(class'KFPlayerController_WeeklySurvival', KFPC_WS) + { + KFPC_WS.PlayVIPGameLowHealthSound(); + } + } + } +} + +function UpdateVIPDamage() +{ + local KFGameReplicationInfo KFGRI; + + if (VIPGameData.IsVIP) + { + KFGRI = KFGameReplicationInfo(WorldInfo.GRI); + + if (KFGRI != none) + { + KFGRI.UpdateVIPCurrentHealth(Pawn.Health); + } + } +} + // defaultProperties { @@ -346,4 +614,7 @@ defaultProperties AracnoStompSoundEvent =AkEvent'WW_GLO_Runtime.WeeklyArcno' GunGameLevelUpSoundEvent=AkEvent'WW_GLO_Runtime.WeeklyAALevelUp' GunGameLevelUpFinalWeaponSoundEvent=AkEvent'WW_GLO_Runtime.WeeklyAALevelFinal' + VIPChosenSoundEvent=AkEvent'WW_UI_Menu.Play_AAR_TOPWEAPON_SLIDEIN_B' + VIPLowHealthSoundEvent=AkEvent'WW_GLO_Runtime.WeeklyVIPAlarm' + VIPLowHealthLastTimePlayed = 0.f } diff --git a/KFGame/Classes/KFPlayerInput.uc b/KFGame/Classes/KFPlayerInput.uc index 85de67d..2b0b781 100644 --- a/KFGame/Classes/KFPlayerInput.uc +++ b/KFGame/Classes/KFPlayerInput.uc @@ -241,6 +241,16 @@ var bool bVersusInput; /** Cached value of bUsingGamepad so we can handle button releases across devices */ var bool bUsingVersusGamepadScheme; +/********************************************************************************************* + * @name QoL: Mouse input options +********************************************************************************************* */ +var config float MouseLookUpScale; +var config float MouseLookRightScale; +var config bool bUseDefaultLookScales; + +var const float DefaultLookRightScale; +var const float DefaultLookUpScale; + cpptext { /** Searches the bind and skips the mainCommand */ @@ -335,6 +345,17 @@ function ClientInitInputSystem() } } +simulated function ResetLookScales() +{ + LookRightScale = DefaultLookRightScale; + LookUpScale = DefaultLookUpScale; + SaveConfig(); + + class'PlayerInput'.default.LookRightScale = DefaultLookRightScale; + class'PlayerInput'.default.LookUpScale = DefaultLookUpScale; + class'PlayerInput'.static.StaticSaveConfig(); +} + function UpdatePushToTalk(bool bValue) { if(bValue != bRequiresPushToTalk) @@ -407,6 +428,14 @@ event PlayerInput( float DeltaTime ) local float FOVScale, TimeScale; local vector RawJoyVector; + /** For checking if init values needs to be reset */ + if (bUseDefaultLookScales) + { + bUseDefaultLookScales = false; + ResetLookScales(); + } + /** */ + // Save Raw values RawJoyUp = aBaseY; RawJoyRight = aStrafe; @@ -574,6 +603,8 @@ function AdjustMouseSensitivity(float FOVScale) } Super.AdjustMouseSensitivity(FOVScale); + aMouseX *= MouseLookRightScale / 100.0f; + aMouseY *= MouseLookUpScale / -100.0f; } @@ -2989,5 +3020,8 @@ defaultproperties ForceLookAtPawnRotationRate=22 ForceLookAtPawnDampenedRotationRate=8 - WeakBoneDistance = 0.02; //0.01; + WeakBoneDistance = 0.02 //0.01; + + DefaultLookRightScale=300 + DefaultLookUpScale=-250 } diff --git a/KFGame/Classes/KFPlayerReplicationInfo.uc b/KFGame/Classes/KFPlayerReplicationInfo.uc index 13472cc..f612933 100644 --- a/KFGame/Classes/KFPlayerReplicationInfo.uc +++ b/KFGame/Classes/KFPlayerReplicationInfo.uc @@ -113,7 +113,7 @@ var private byte ActivePerkLevel; var private byte ActivePerkPrestigeLevel; /** Kill assists. Need an integer here because it is very easy to exceed 255 assists. */ var int Assists; -var byte PlayerHealth; //represented as a percentage +var int PlayerHealth; var byte PlayerHealthPercent; //represented as a percentage /** The firebug range skill increases the range of fire weapons we need to tell other clients if it is on */ var bool bExtraFireRange; diff --git a/KFGame/Classes/KFProfileSettings.uc b/KFGame/Classes/KFProfileSettings.uc index 73e8428..5d06255 100644 --- a/KFGame/Classes/KFProfileSettings.uc +++ b/KFGame/Classes/KFProfileSettings.uc @@ -386,4 +386,17 @@ defaultproperties DefaultSettings.Add((Owner=OPPO_Game,ProfileSetting=(PropertyId=KFID_SurvivalStartingWeapIdx,Data=(Type=SDT_Int32,Value1=0)))) ProfileMappings.Add((Id=KFID_SurvivalStartingGrenIdx, Name="Survival Starting Grenade Index", MappingType=PVMT_RawValue)) DefaultSettings.Add((Owner=OPPO_Game,ProfileSetting=(PropertyId=KFID_SurvivalStartingGrenIdx,Data=(Type=SDT_Int32,Value1=0)))) + + // Added 07/06/2022 - QoL: Add mouse options to menu + ProfileMappings.Add((Id=KFID_MouseLookUpScale, Name="Mouse_Look_Up_Scale", MappingType=PVMT_RawValue)) + DefaultSettings.Add((Owner=OPPO_Game,ProfileSetting=(PropertyId=KFID_MouseLookUpScale,Data=(Type=SDT_Float,Value1=0xc2c80000)))) // -100 + + ProfileMappings.Add((Id=KFID_MouseLookRightScale, Name="Mouse_Look_Right_Scale", MappingType=PVMT_RawValue)) + DefaultSettings.Add((Owner=OPPO_Game,ProfileSetting=(PropertyId=KFID_MouseLookRightScale,Data=(Type=SDT_Float,Value1=0x42c80000)))) //100 + + ProfileMappings.Add((Id=KFID_ViewSmoothingEnabled, Name="View_Smoothing_Enabled", MappingType=PVMT_RawValue)) + DefaultSettings.Add((Owner=OPPO_Game,ProfileSetting=(PropertyId=KFID_ViewSmoothingEnabled,Data=(Type=SDT_Int32,Value1=0)))) + + ProfileMappings.Add((Id=KFID_ViewAccelerationEnabled, Name="View_Acceleration_Enabled", MappingType=PVMT_RawValue)) + DefaultSettings.Add((Owner=OPPO_Game,ProfileSetting=(PropertyId=KFID_ViewAccelerationEnabled,Data=(Type=SDT_Int32,Value1=1)))) } diff --git a/KFGame/Classes/KFProj_Grenade.uc b/KFGame/Classes/KFProj_Grenade.uc index 44e4d72..2e74822 100644 --- a/KFGame/Classes/KFProj_Grenade.uc +++ b/KFGame/Classes/KFProj_Grenade.uc @@ -254,6 +254,9 @@ simulated event GrenadeIsAtRest() /** Overriding so that the grenade doesn't take on the */ simulated protected function PrepareExplosionTemplate() { + local Weapon OwnerWeapon; + local KFPawn_Human OwnerPawn; + if (bUpgradable) { super.PrepareExplosionTemplate(); @@ -261,6 +264,16 @@ simulated protected function PrepareExplosionTemplate() else { GetRadialDamageValues(ExplosionTemplate.Damage, ExplosionTemplate.DamageRadius, ExplosionTemplate.DamageFalloffExponent); + + OwnerWeapon = Weapon(Owner); + if (OwnerWeapon != none) + { + OwnerPawn = KFPawn_Human(OwnerWeapon.Owner); + if (OwnerPawn != none) + { + ExplosionTemplate.DamageRadius *= OwnerPawn.GetPerk().GetAoERadiusModifier(); + } + } } } diff --git a/KFGame/Classes/KFProjectile.uc b/KFGame/Classes/KFProjectile.uc index 378add2..80e42b1 100644 --- a/KFGame/Classes/KFProjectile.uc +++ b/KFGame/Classes/KFProjectile.uc @@ -1117,6 +1117,18 @@ simulated function bool AllowNuke() return true; } +/** Can be overridden in subclasses to exclude specific projectiles from using changing explosion radius */ +simulated function bool AllowDemolitionistExplosionChangeRadius() +{ + return true; +} + +/** Can be overridden in subclasses to exclude specific projectiles from using concussive */ +simulated function bool AllowDemolitionistConcussive() +{ + return true; +} + /** * Give the projectiles a chance to situationally customize/tweak any explosion parameters. * We will also copy in any data we exposed here for .ini file access. diff --git a/KFGame/Classes/KFSkinTypeEffects.uc b/KFGame/Classes/KFSkinTypeEffects.uc index 8bbbf8c..8b4aedd 100644 --- a/KFGame/Classes/KFSkinTypeEffects.uc +++ b/KFGame/Classes/KFSkinTypeEffects.uc @@ -85,13 +85,20 @@ cpptext virtual void PostLoad(); } -function PlayImpactParticleEffect( - KFPawn P, vector HitLocation, vector HitDirection, byte HitZoneIndex, EEffectDamageGroup EffectGroup) +function PlayImpactParticleEffect(KFPawn P, vector HitLocation, vector HitDirection, byte HitZoneIndex, EEffectDamageGroup EffectGroup, optional ParticleSystem ForceParticleTemplate) { local ParticleSystem ParticleTemplate; local name HitBoneName; - ParticleTemplate = GetImpactParticleEffect(EffectGroup); + if (ForceParticleTemplate != none) + { + ParticleTemplate = ForceParticleTemplate; + } + else + { + ParticleTemplate = GetImpactParticleEffect(EffectGroup); + } + if (ParticleTemplate == None) { return; @@ -212,7 +219,7 @@ function ParticleSystem GetImpactParticleEffect(EEffectDamageGroup EffectGroup) } /** Play an impact sound on taking damage */ -function PlayTakeHitSound(KFPawn P, vector HitLocation, Pawn DamageCauser, EEffectDamageGroup EffectGroup) +function PlayTakeHitSound(KFPawn P, vector HitLocation, Pawn DamageCauser, EEffectDamageGroup EffectGroup, optional AKEvent ForceImpactSound) { local AKEvent ImpactSound; local float ArmorPct; @@ -225,7 +232,14 @@ function PlayTakeHitSound(KFPawn P, vector HitLocation, Pawn DamageCauser, EEffe return; } - ImpactSound = GetImpactSound(EffectGroup, DamageCauser, P); + if (ForceImpactSound != none) + { + ImpactSound = ForceImpactSound; + } + else + { + ImpactSound = GetImpactSound(EffectGroup, DamageCauser, P); + } if (ShouldSetArmorValue(P, ArmorPct)) { diff --git a/KFGame/Classes/KFSpawnVolume.uc b/KFGame/Classes/KFSpawnVolume.uc index e0ca618..0d7f9d7 100644 --- a/KFGame/Classes/KFSpawnVolume.uc +++ b/KFGame/Classes/KFSpawnVolume.uc @@ -129,7 +129,7 @@ var() float MaxDistanceToPlayer; var() bool bOutOfSight; /** Result of last time this volume was rated & sorted */ -var const transient float CurrentRating; +var transient float CurrentRating; /** Cached visibility for performance */ var const transient bool bCachedVisibility; diff --git a/KFGame/Classes/KFUnlockManager.uc b/KFGame/Classes/KFUnlockManager.uc index 1c3cd59..b5b4324 100644 --- a/KFGame/Classes/KFUnlockManager.uc +++ b/KFGame/Classes/KFUnlockManager.uc @@ -34,7 +34,9 @@ enum ESharedContentUnlock SCU_ParasiteImplanter, SCU_Doshinegun, SCU_AutoTurret, - SCU_ShrinkRayGun + SCU_ShrinkRayGun, + SCU_Scythe, + SCU_G36C }; @@ -373,4 +375,12 @@ defaultproperties Name=KFWeap_ShrinkRayGun, IconPath="WEP_UI_ShrinkRay_Gun_TEX.UI_Weapon_Select_Shrink_Ray_Gun", ID=9290)} + SharedContentList(SCU_Scythe)={( + Name=KFWeap_Edged_Scythe, + IconPath="WEP_UI_Scythe_TEX.UI_WeaponSelect_Scythe", + ID=9478)} + SharedContentList(SCU_G36C)={( + Name=KFWeap_AssaultRifle_G36C, + IconPath="WEP_UI_G36C_TEX.UI_WeaponSelect_G36C", + ID=9484)} } diff --git a/KFGame/Classes/KFWeap_HealerBase.uc b/KFGame/Classes/KFWeap_HealerBase.uc index 39030f9..0297720 100644 --- a/KFGame/Classes/KFWeap_HealerBase.uc +++ b/KFGame/Classes/KFWeap_HealerBase.uc @@ -228,11 +228,21 @@ simulated function bool CanReload(optional byte FireModeNum); /** Instead of switch fire mode use as immediate alt fire */ simulated function AltFireMode() { + local KFPlayerController_WeeklySurvival Instigator_KFPC_WS; + if ( !Instigator.IsLocallyControlled() ) { return; } + Instigator_KFPC_WS = KFPlayerController_WeeklySurvival(Instigator.Controller); + + if (Instigator_KFPC_WS != none && Instigator_KFPC_WS.VIPGameData.IsVIP) + { + // VIP can't heal himself + return; + } + // StartFire - StopFire called from KFPlayerInput StartFire(ALTFIRE_FIREMODE); } diff --git a/KFGame/Classes/KFWeapon.uc b/KFGame/Classes/KFWeapon.uc index e403c73..38da260 100644 --- a/KFGame/Classes/KFWeapon.uc +++ b/KFGame/Classes/KFWeapon.uc @@ -1618,7 +1618,7 @@ simulated function AttachLaserSight() } } -function GunGameRemove() +function RemoveGun() { if (Instigator != none && Instigator.InvManager != none) { diff --git a/KFGame/Classes/KFWeaponSkinList.uc b/KFGame/Classes/KFWeaponSkinList.uc index 068e8e1..80fd17f 100644 --- a/KFGame/Classes/KFWeaponSkinList.uc +++ b/KFGame/Classes/KFWeaponSkinList.uc @@ -3675,6 +3675,42 @@ defaultproperties //Reducto Ray Lucky Strike Skins.Add((Id=9295, Weapondef=class'KFWeapDef_ShrinkRayGun', MIC_1P=("wep_skinset55_mat.Wep_1P_LuckyStrike_ShrinkRay_Gun_MIC","WEP_1P_ShrinkRay_Gun_MAT.WEP_ShrinkRay_Glass_MIC"), MIC_3P="wep_skinset55_mat.Wep_3P_LuckyStrike_ShrinkRay_Gun_MIC", MIC_Pickup="wep_skinset55_mat.Wep_3P_LuckyStrike_ShrinkRay_Pickup_MIC")) +//Blood Sickle Standard + Skins.Add((Id=9478, Weapondef=class'KFWeapDef_Scythe', MIC_1P=("wep_1p_scythe_mat.Wep_1stP_Scythe_MIC"), MIC_3P="WEP_3P_Scythe_MAT.WEP_3P_Scythe_MIC", MIC_Pickup="wep_3p_scythe_mat.WEP_3P_ScythePickup_MIC")) + +//Blood Sickle Bloodbath + Skins.Add((Id=9473, Weapondef=class'KFWeapDef_Scythe', MIC_1P=("WEP_SkinSet65_MAT.Wep_1P_Bloodbath_Scythe_MIC"), MIC_3P="WEP_SkinSet65_MAT.Wep_3P_Bloodbath_Scythe_MIC", MIC_Pickup="WEP_SkinSet65_MAT.Wep_3P_Bloodbath_Scythe_Pickup_MIC")) + +//Blood Sickle Butchery + Skins.Add((Id=9474, Weapondef=class'KFWeapDef_Scythe', MIC_1P=("WEP_SkinSet65_MAT.Wep_1P_Butchery_Scythe_MIC"), MIC_3P="WEP_SkinSet65_MAT.Wep_3P_Butchery_Scythe_MIC", MIC_Pickup="WEP_SkinSet65_MAT.Wep_3P_Butchery_Scythe_Pickup_MIC")) + +//Blood Sickle Carousel + Skins.Add((Id=9475, Weapondef=class'KFWeapDef_Scythe', MIC_1P=("WEP_SkinSet65_MAT.Wep_1P_Carousel_Scythe_MIC"), MIC_3P="WEP_SkinSet65_MAT.Wep_3P_Carousel_Scythe_MIC", MIC_Pickup="WEP_SkinSet65_MAT.Wep_3P_Caurel_Scythe_Pickup_MIC")) + +//Blood Sickle Hunter + Skins.Add((Id=9477, Weapondef=class'KFWeapDef_Scythe', MIC_1P=("WEP_SkinSet65_MAT.Wep_1P_Hunter_Scythe_MIC"), MIC_3P="WEP_SkinSet65_MAT.Wep_3P_Hunter_Scythe_MIC", MIC_Pickup="WEP_SkinSet65_MAT.Wep_3P_Hunter_Scythe_Pickup_MIC")) + +//Blood Sickle Reaper + Skins.Add((Id=9476, Weapondef=class'KFWeapDef_Scythe', MIC_1P=("WEP_SkinSet65_MAT.Wep_1P_Reaper_Scythe_MIC"), MIC_3P="WEP_SkinSet65_MAT.Wep_3P_Reaper_Scythe_MIC", MIC_Pickup="WEP_SkinSet65_MAT.Wep_3P_Reaper_Scythe_Pickup_MIC")) + +//G36C Standard + Skins.Add((Id=9484, Weapondef=class'KFWeapDef_G36C', MIC_1P=("wep_1p_g36c_mat.Wep_1stP_G36C_MIC","wep_1p_g36c_mat.Wep_1stP_G36C_Scope_MIC"), MIC_3P="wep_3p_g36c_mat.Wep_3rdP_G36C_MIC", MIC_Pickup="wep_3p_g36c_mat.3P_Pickup_G36C_MIC")) + +//G36C Aftermath + Skins.Add((Id=9481, Weapondef=class'KFWeapDef_G36C', MIC_1P=("wep_skinset64_mat.Wep_1P_Aftermatch_G36C_MIC","wep_skinset64_mat.Wep_1P_Aftermatch_Scope_G36C_MIC"), MIC_3P="wep_skinset64_mat.Wep_3P_Aftermatch_G36C_MIC", MIC_Pickup="wep_skinset64_mat.Wep_3P_Aftermatch_G36C_Pickup_MIC")) + +//G36C Dazzle + Skins.Add((Id=9483, Weapondef=class'KFWeapDef_G36C', MIC_1P=("wep_skinset64_mat.Wep_1P_Dazzle_G36C_MIC","wep_skinset64_mat.Wep_1P_Dazzle_Scope_G36C_MIC"), MIC_3P="wep_skinset64_mat.Wep_3P_Dazzle_G36C_MIC", MIC_Pickup="wep_skinset64_mat.Wep_3P_Dazzle_G36C_Pickup_MIC")) + +//G36C Icepack + Skins.Add((Id=9480, Weapondef=class'KFWeapDef_G36C', MIC_1P=("wep_skinset64_mat.Wep_1P_Icepack_G36C_MIC","wep_skinset64_mat.Wep_1P_Icepack_Scope_G36C_MIC"), MIC_3P="wep_skinset64_mat.Wep_3P_Icepack_G36C_MIC", MIC_Pickup="wep_skinset64_mat.Wep_3P_Icepack_G36C_Pickup_MIC")) + +//G36C Jungle + Skins.Add((Id=9482, Weapondef=class'KFWeapDef_G36C', MIC_1P=("wep_skinset64_mat.Wep_1P_Jungle_G36C_MIC","wep_skinset64_mat.Wep_1P_Jungle_Scope_G36C_MIC"), MIC_3P="wep_skinset64_mat.Wep_3P_Jungle_G36C_MIC", MIC_Pickup="wep_skinset64_mat.Wep_3P_Jungle_G36C_Pickup_MIC")) + +//G36C Sahara + Skins.Add((Id=9479, Weapondef=class'KFWeapDef_G36C', MIC_1P=("wep_skinset64_mat.Wep_1P_Sahara_G36C_MIC","wep_skinset64_mat.Wep_1P_Sahara_Scope_G36C_MIC"), MIC_3P="wep_skinset64_mat.Wep_3P_Sahara_G36C_MIC", MIC_Pickup="wep_skinset64_mat.Wep_3P_Sahara_G36C_Pickup_MIC")) + //BeyondHorizon AA12 Skins.Add((Id=8845, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_AA12', MIC_1P=("WEP_SkinSet43_MAT.space_aa12.Space_AA12_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.space_aa12.Space_AA12_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.space_aa12.Space_AA12_3P_Pickup_MIC")) @@ -3992,6 +4028,7 @@ defaultproperties //Chameleon Dynamic RGB RPG-7 Skins.Add((Id=9358, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_RPG7', MIC_1P=("wep_skinset58_mat.chameleonrgb_rpg7.ChameleonRGB_RPG7_1P_Mint_MIC"), MIC_3P="WEP_SkinSet58_MAT.chameleonrgb_rpg7.ChameleonRGB_RPG7_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet58_MAT.chameleonrgb_rpg7.ChameleonRGB_RPG7_3P_Pickup_MIC")) + //Deep Sea Antique AA12 Skins.Add((Id=9298, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_AA12', MIC_1P=("WEP_SkinSet59_MAT.deepsea_aa12.DeepSea_AA12_1P_Mint_MIC"), MIC_3P="WEP_SkinSet59_MAT.deepsea_aa12.DeepSea_AA12_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet59_MAT.deepsea_aa12.DeepSea_AA12_3P_Pickup_MIC")) @@ -4099,4 +4136,184 @@ defaultproperties //Deep Sea Precious RPG-7 Skins.Add((Id=9333, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_RPG7', MIC_1P=("WEP_SkinSet59_MAT.deepsea_rpg7.DeepSeaPrecious_RPG7_1P_Mint_MIC"), MIC_3P="WEP_SkinSet59_MAT.deepsea_rpg7.DeepSeaPrecious_RPG7_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet59_MAT.deepsea_rpg7.DeepSeaPrecious_RPG7_3P_Pickup_MIC")) + +//Plague Doctor Mint Tommy Gun + Skins.Add((Id=9388, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Thompson', MIC_1P=("WEP_SkinSet62_MAT.plague_tommygun.Plague_TommyGun_1P_Mint_MIC"), MIC_3P="WEP_SkinSet62_MAT.plague_tommygun.Plague_TommyGun_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet62_MAT.plague_tommygun.Plague_TommyGun_3P_Pickup_MIC")) + +//Plague Doctor Sterling Tommy Gun + Skins.Add((Id=9389, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Thompson', MIC_1P=("WEP_SkinSet62_MAT.plague_tommygun.PlagueSterling_TommyGun_1P_Mint_MIC"), MIC_3P="WEP_SkinSet62_MAT.plague_tommygun.PlagueSterling_TommyGun_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet62_MAT.plague_tommygun.PlagueSterling_TommyGun_3P_Pickup_MIC")) + +//Plague Doctor Obsidian Tommy Gun + Skins.Add((Id=9390, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Thompson', MIC_1P=("WEP_SkinSet62_MAT.plague_tommygun.PlagueObsidian_TommyGun_1P_Mint_MIC"), MIC_3P="WEP_SkinSet62_MAT.plague_tommygun.PlagueObsidian_TommyGun_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet62_MAT.plague_tommygun.PlagueObsidian_TommyGun_3P_Pickup_MIC")) + +//Plague Doctor Volcanic Tommy Gun + Skins.Add((Id=9391, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Thompson', MIC_1P=("WEP_SkinSet62_MAT.plague_tommygun.PlagueVolcanic_TommyGun_1P_Mint_MIC"), MIC_3P="WEP_SkinSet62_MAT.plague_tommygun.PlagueVolcanic_TommyGun_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet62_MAT.plague_tommygun.PlagueVolcanic_TommyGun_3P_Pickup_MIC")) + +//Plague Doctor Emerald Tommy Gun + Skins.Add((Id=9392, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Thompson', MIC_1P=("WEP_SkinSet62_MAT.plague_tommygun.PlagueEmerald_TommyGun_1P_Mint_MIC"), MIC_3P="WEP_SkinSet62_MAT.plague_tommygun.PlagueEmerald_TommyGun_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet62_MAT.plague_tommygun.PlagueEmerald_TommyGun_3P_Pickup_MIC")) + +//Plague Doctor Precious Tommy Gun + Skins.Add((Id=9393, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Thompson', MIC_1P=("WEP_SkinSet62_MAT.plague_tommygun.PlaguePrecious_TommyGun_1P_Mint_MIC"), MIC_3P="WEP_SkinSet62_MAT.plague_tommygun.PlaguePrecious_TommyGun_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet62_MAT.plague_tommygun.PlaguePrecious_TommyGun_3P_Pickup_MIC")) + +//Plague Doctor Mint M79 + Skins.Add((Id=9394, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_M79', MIC_1P=("WEP_SkinSet62_MAT.plague_m79.Plague_M79_1P_Mint_MIC"), MIC_3P="WEP_SkinSet62_MAT.plague_m79.Plague_M79_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet62_MAT.plague_m79.Plague_M79_3P_Pickup_MIC")) + +//Plague Doctor Sterling M79 + Skins.Add((Id=9395, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_M79', MIC_1P=("WEP_SkinSet62_MAT.plague_m79.PlagueSterling_M79_1P_Mint_MIC"), MIC_3P="WEP_SkinSet62_MAT.plague_m79.PlagueSterling_M79_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet62_MAT.plague_m79.PlagueSterling_M79_3P_Pickup_MIC")) + +//Plague Doctor Obsidian M79 + Skins.Add((Id=9396, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_M79', MIC_1P=("WEP_SkinSet62_MAT.plague_m79.PlagueObsidian_M79_1P_Mint_MIC"), MIC_3P="WEP_SkinSet62_MAT.plague_m79.PlagueObsidian_M79_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet62_MAT.plague_m79.PlagueObsidian_M79_3P_Pickup_MIC")) + +//Plague Doctor Volcanic M79 + Skins.Add((Id=9397, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_M79', MIC_1P=("WEP_SkinSet62_MAT.plague_m79.PlagueVolcanic_M79_1P_Mint_MIC"), MIC_3P="WEP_SkinSet62_MAT.plague_m79.PlagueVolcanic_M79_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet62_MAT.plague_m79.PlagueVolcanic_M79_3P_Pickup_MIC")) + +//Plague Doctor Emerald M79 + Skins.Add((Id=9398, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_M79', MIC_1P=("WEP_SkinSet62_MAT.plague_m79.PlagueEmerald_M79_1P_Mint_MIC"), MIC_3P="WEP_SkinSet62_MAT.plague_m79.PlagueEmerald_M79_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet62_MAT.plague_m79.PlagueEmerald_M79_3P_Pickup_MIC")) + +//Plague Doctor Precious M79 + Skins.Add((Id=9399, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_M79', MIC_1P=("WEP_SkinSet62_MAT.plague_m79.PlaguePrecious_M79_1P_Mint_MIC"), MIC_3P="WEP_SkinSet62_MAT.plague_m79.PlaguePrecious_M79_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet62_MAT.plague_m79.PlaguePrecious_M79_3P_Pickup_MIC")) + +//Plague Doctor Mint Desert Eagle + Skins.Add((Id=9400, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Deagle', MIC_1P=("WEP_SkinSet62_MAT.plague_deagle.Plague_Deagle_1P_Mint_MIC"), MIC_3P="WEP_SkinSet62_MAT.plague_deagle.Plague_Deagle_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet62_MAT.plague_deagle.Plague_Deagle_3P_Pickup_MIC")) + +//Plague Doctor Sterling Desert Eagle + Skins.Add((Id=9401, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Deagle', MIC_1P=("WEP_SkinSet62_MAT.plague_deagle.PlagueSterling_Deagle_1P_Mint_MIC"), MIC_3P="WEP_SkinSet62_MAT.plague_deagle.PlagueSterling_Deagle_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet62_MAT.plague_deagle.PlagueSterling_Deagle_3P_Pickup_MIC")) + +//Plague Doctor Obsidian Desert Eagle + Skins.Add((Id=9402, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Deagle', MIC_1P=("WEP_SkinSet62_MAT.plague_deagle.PlagueObsidian_Deagle_1P_Mint_MIC"), MIC_3P="WEP_SkinSet62_MAT.plague_deagle.PlagueObsidian_Deagle_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet62_MAT.plague_deagle.PlagueObsidian_Deagle_3P_Pickup_MIC")) + +//Plague Doctor Volcanic Desert Eagle + Skins.Add((Id=9403, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Deagle', MIC_1P=("WEP_SkinSet62_MAT.plague_deagle.PlagueVolcanic_Deagle_1P_Mint_MIC"), MIC_3P="WEP_SkinSet62_MAT.plague_deagle.PlagueVolcanic_Deagle_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet62_MAT.plague_deagle.PlagueVolcanic_Deagle_3P_Pickup_MIC")) + +//Plague Doctor Emerald Desert Eagle + Skins.Add((Id=9404, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Deagle', MIC_1P=("WEP_SkinSet62_MAT.plague_deagle.PlagueEmerald_Deagle_1P_Mint_MIC"), MIC_3P="WEP_SkinSet62_MAT.plague_deagle.PlagueEmerald_Deagle_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet62_MAT.plague_deagle.PlagueEmerald_Deagle_3P_Pickup_MIC")) + +//Plague Doctor Precious Desert Eagle + Skins.Add((Id=9405, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Deagle', MIC_1P=("WEP_SkinSet62_MAT.plague_deagle.PlaguePrecious_Deagle_1P_Mint_MIC"), MIC_3P="WEP_SkinSet62_MAT.plague_deagle.PlaguePrecious_Deagle_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet62_MAT.plague_deagle.PlaguePrecious_Deagle_3P_Pickup_MIC")) + +//Plague Doctor Mint Crossbow + Skins.Add((Id=9406, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Crossbow', MIC_1P=("WEP_SkinSet62_MAT.plague_crossbow.Plague_Crossbow_1P_Mint_MIC", "WEP_SkinSet62_MAT.plague_crossbow.Plague_Crossbow_Scope_1P_Mint_MIC"), MIC_3P="WEP_SkinSet62_MAT.plague_crossbow.Plague_Crossbow_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet62_MAT.plague_crossbow.Plague_Crossbow_3P_Pickup_MIC")) + +//Plague Doctor Sterling Crossbow + Skins.Add((Id=9407, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Crossbow', MIC_1P=("WEP_SkinSet62_MAT.plague_crossbow.PlagueSterling_Crossbow_1P_Mint_MIC", "WEP_SkinSet62_MAT.plague_crossbow.PlagueSterling_Crossbow_Scope_1P_Mint_MIC"), MIC_3P="WEP_SkinSet62_MAT.plague_crossbow.PlagueSterling_Crossbow_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet62_MAT.plague_crossbow.PlagueSterling_Crossbow_3P_Pickup_MIC")) + +//Plague Doctor Obsidian Crossbow + Skins.Add((Id=9408, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Crossbow', MIC_1P=("WEP_SkinSet62_MAT.plague_crossbow.PlagueObsidian_Crossbow_1P_Mint_MIC", "WEP_SkinSet62_MAT.plague_crossbow.PlagueObsidian_Crossbow_Scope_1P_Mint_MIC"), MIC_3P="WEP_SkinSet62_MAT.plague_crossbow.PlagueObsidian_Crossbow_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet62_MAT.plague_crossbow.PlagueObsidian_Crossbow_3P_Pickup_MIC")) + +//Plague Doctor Volcanic Crossbow + Skins.Add((Id=9409, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Crossbow', MIC_1P=("WEP_SkinSet62_MAT.plague_crossbow.PlagueVolcanic_Crossbow_1P_Mint_MIC", "WEP_SkinSet62_MAT.plague_crossbow.PlagueVolcanic_Crossbow_Scope_1P_Mint_MIC"), MIC_3P="WEP_SkinSet62_MAT.plague_crossbow.PlagueVolcanic_Crossbow_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet62_MAT.plague_crossbow.PlagueVolcanic_Crossbow_3P_Pickup_MIC")) + +//Plague Doctor Emerald Crossbow + Skins.Add((Id=9410, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Crossbow', MIC_1P=("WEP_SkinSet62_MAT.plague_crossbow.PlagueEmerald_Crossbow_1P_Mint_MIC", "WEP_SkinSet62_MAT.plague_crossbow.PlagueEmerald_Crossbow_Scope_1P_Mint_MIC"), MIC_3P="WEP_SkinSet62_MAT.plague_crossbow.PlagueEmerald_Crossbow_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet62_MAT.plague_crossbow.PlagueEmerald_Crossbow_3P_Pickup_MIC")) + +//Plague Doctor Precious Crossbow + Skins.Add((Id=9411, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Crossbow', MIC_1P=("WEP_SkinSet62_MAT.plague_crossbow.PlaguePrecious_Crossbow_1P_Mint_MIC", "WEP_SkinSet62_MAT.plague_crossbow.PlaguePrecious_Crossbow_Scope_1P_Mint_MIC"), MIC_3P="WEP_SkinSet62_MAT.plague_crossbow.PlaguePrecious_Crossbow_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet62_MAT.plague_crossbow.PlaguePrecious_Crossbow_3P_Pickup_MIC")) + +//Plague Doctor Mint Doomstick + Skins.Add((Id=9412, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_ElephantGun', MIC_1P=("WEP_SkinSet62_MAT.plague_quadbarrel.Plague_QuadBarrel_Main_1P_Mint_MIC", "WEP_SkinSet62_MAT.plague_quadbarrel.Plague_QuadBarrel_Barrel_1P_Mint_MIC"), MIC_3P="WEP_SkinSet62_MAT.plague_quadbarrel.Plague_QuadBarrel_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet62_MAT.plague_quadbarrel.Plague_QuadBarrel_3P_Pickup_MIC")) + +//Plague Doctor Sterling Doomstick + Skins.Add((Id=9413, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_ElephantGun', MIC_1P=("WEP_SkinSet62_MAT.plague_quadbarrel.PlagueSterling_QuadBarrel_Main_1P_Mint_MIC", "WEP_SkinSet62_MAT.plague_quadbarrel.PlagueSterling_QuadBarrel_Barrel_1P_Mint_MIC"), MIC_3P="WEP_SkinSet62_MAT.plague_quadbarrel.PlagueSterling_QuadBarrel_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet62_MAT.plague_quadbarrel.PlagueSterling_QuadBarrel_3P_Pickup_MIC")) + +//Plague Doctor Obsidian Doomstick + Skins.Add((Id=9414, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_ElephantGun', MIC_1P=("WEP_SkinSet62_MAT.plague_quadbarrel.PlagueObsidian_QuadBarrel_Main_1P_Mint_MIC", "WEP_SkinSet62_MAT.plague_quadbarrel.PlagueObsidian_QuadBarrel_Barrel_1P_Mint_MIC"), MIC_3P="WEP_SkinSet62_MAT.plague_quadbarrel.PlagueObsidian_QuadBarrel_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet62_MAT.plague_quadbarrel.PlagueObsidian_QuadBarrel_3P_Pickup_MIC")) + +//Plague Doctor Volcanic Doomstick + Skins.Add((Id=9415, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_ElephantGun', MIC_1P=("WEP_SkinSet62_MAT.plague_quadbarrel.PlagueVolcanic_QuadBarrel_Main_1P_Mint_MIC", "WEP_SkinSet62_MAT.plague_quadbarrel.PlagueVolcanic_QuadBarrel_Barrel_1P_Mint_MIC"), MIC_3P="WEP_SkinSet62_MAT.plague_quadbarrel.PlagueVolcanic_QuadBarrel_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet62_MAT.plague_quadbarrel.PlagueVolcanic_QuadBarrel_3P_Pickup_MIC")) + +//Plague Doctor Emerald Doomstick + Skins.Add((Id=9416, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_ElephantGun', MIC_1P=("WEP_SkinSet62_MAT.plague_quadbarrel.PlagueEmerald_QuadBarrel_Main_1P_Mint_MIC", "WEP_SkinSet62_MAT.plague_quadbarrel.PlagueEmerald_QuadBarrel_Barrel_1P_Mint_MIC"), MIC_3P="WEP_SkinSet62_MAT.plague_quadbarrel.PlagueEmerald_QuadBarrel_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet62_MAT.plague_quadbarrel.PlagueEmerald_QuadBarrel_3P_Pickup_MIC")) + +//Plague Doctor Precious Doomstick + Skins.Add((Id=9417, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_ElephantGun', MIC_1P=("WEP_SkinSet62_MAT.plague_quadbarrel.PlaguePrecious_QuadBarrel_Main_1P_Mint_MIC", "WEP_SkinSet62_MAT.plague_quadbarrel.PlaguePrecious_QuadBarrel_Barrel_1P_Mint_MIC"), MIC_3P="WEP_SkinSet62_MAT.plague_quadbarrel.PlaguePrecious_QuadBarrel_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet62_MAT.plague_quadbarrel.PlaguePrecious_QuadBarrel_3P_Pickup_MIC")) + +//Plague Doctor Mint Dragonsbreath + Skins.Add((Id=9418, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Dragonsbreath', MIC_1P=("WEP_SkinSet62_MAT.plague_dragonsbreath.Plague_Dragonsbreath_1P_Mint_MIC"), MIC_3P="WEP_SkinSet62_MAT.plague_dragonsbreath.Plague_Dragonsbreath_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet62_MAT.plague_dragonsbreath.Plague_Dragonsbreath_3P_Pickup_MIC")) + +//Plague Doctor Sterling Dragonsbreath + Skins.Add((Id=9419, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Dragonsbreath', MIC_1P=("WEP_SkinSet62_MAT.plague_dragonsbreath.PlagueSterling_Dragonsbreath_1P_Mint_MIC"), MIC_3P="WEP_SkinSet62_MAT.plague_dragonsbreath.PlagueSterling_Dragonsbreath_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet62_MAT.plague_dragonsbreath.PlagueSterling_Dragonsbreath_3P_Pickup_MIC")) + +//Plague Doctor Obsidian Dragonsbreath + Skins.Add((Id=9420, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Dragonsbreath', MIC_1P=("WEP_SkinSet62_MAT.plague_dragonsbreath.PlagueObsidian_Dragonsbreath_1P_Mint_MIC"), MIC_3P="WEP_SkinSet62_MAT.plague_dragonsbreath.PlagueObsidian_Dragonsbreath_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet62_MAT.plague_dragonsbreath.PlagueObsidian_Dragonsbreath_3P_Pickup_MIC")) + +//Plague Doctor Volcanic Dragonsbreath + Skins.Add((Id=9421, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Dragonsbreath', MIC_1P=("WEP_SkinSet62_MAT.plague_dragonsbreath.PlagueVolcanic_Dragonsbreath_1P_Mint_MIC"), MIC_3P="WEP_SkinSet62_MAT.plague_dragonsbreath.PlagueVolcanic_Dragonsbreath_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet62_MAT.plague_dragonsbreath.PlagueVolcanic_Dragonsbreath_3P_Pickup_MIC")) + +//Plague Doctor Emerald Dragonsbreath + Skins.Add((Id=9422, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Dragonsbreath', MIC_1P=("WEP_SkinSet62_MAT.plague_dragonsbreath.PlagueEmerald_Dragonsbreath_1P_Mint_MIC"), MIC_3P="WEP_SkinSet62_MAT.plague_dragonsbreath.PlagueEmerald_Dragonsbreath_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet62_MAT.plague_dragonsbreath.PlagueEmerald_Dragonsbreath_3P_Pickup_MIC")) + +//Plague Doctor Precious Dragonsbreath + Skins.Add((Id=9423, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Dragonsbreath', MIC_1P=("WEP_SkinSet62_MAT.plague_dragonsbreath.PlaguePrecious_Dragonsbreath_1P_Mint_MIC"), MIC_3P="WEP_SkinSet62_MAT.plague_dragonsbreath.PlaguePrecious_Dragonsbreath_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet62_MAT.plague_dragonsbreath.PlaguePrecious_Dragonsbreath_3P_Pickup_MIC")) + +//Chameleon Dynamic AA12 + Skins.Add((Id=9441, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_AA12', MIC_1P=("WEP_SkinSet60_MAT.chameleon_aa12.Chameleon_AA12_1P_Mint_MIC"), MIC_3P="WEP_SkinSet60_MAT.chameleon_aa12.Chameleon_AA12_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet60_MAT.chameleon_aa12.Chameleon_AA12_3P_Pickup_MIC")) + +//Chameleon Dynamic Flamethrower + Skins.Add((Id=9442, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_FlameThrower', MIC_1P=("WEP_SkinSet60_MAT.chameleon_flamethrower.Chameleon_Flamethrower_1P_Mint_MIC"), MIC_3P="WEP_SkinSet60_MAT.chameleon_flamethrower.Chameleon_Flamethrower_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet60_MAT.chameleon_flamethrower.Chameleon_Flamethrower_3P_Pickup_MIC")) + +//Chameleon Dynamic M99 + Skins.Add((Id=9443, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_M99', MIC_1P=("WEP_SkinSet60_MAT.chameleon_m99.Chameleon_M99_1P_Mint_MIC", "WEP_SkinSet60_MAT.chameleon_m99.Chameleon_M99_Scope_1P_Mint_MIC"), MIC_3P="WEP_SkinSet60_MAT.chameleon_m99.Chameleon_M99_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet60_MAT.chameleon_m99.Chameleon_M99_3P_Pickup_MIC")) + +//Chameleon Dynamic SCAR + Skins.Add((Id=9444, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_SCAR', MIC_1P=("WEP_SkinSet60_MAT.chameleon_scar.Chameleon_SCAR_1P_Mint_MIC", "WEP_SkinSet60_MAT.chameleon_scar.Chameleon_SCAR_Scope_1P_Mint_MIC"), MIC_3P="WEP_SkinSet60_MAT.chameleon_scar.Chameleon_SCAR_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet60_MAT.chameleon_scar.Chameleon_SCAR_3P_Pickup_MIC")) + +//Chameleon Dynamic RGB AA12 + Skins.Add((Id=9445, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_AA12', MIC_1P=("WEP_SkinSet60_MAT.chameleonrgb_aa12.ChameleonRGB_AA12_1P_Mint_MIC"), MIC_3P="WEP_SkinSet60_MAT.chameleonrgb_aa12.ChameleonRGB_AA12_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet60_MAT.chameleonrgb_aa12.ChameleonRGB_AA12_3P_Pickup_MIC")) + +//Chameleon Dynamic RGB Flamethrower + Skins.Add((Id=9446, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_FlameThrower', MIC_1P=("WEP_SkinSet60_MAT.chameleonrgb_flamethrower.ChameleonRGB_Flamethrower_1P_Mint_MIC"), MIC_3P="WEP_SkinSet60_MAT.chameleonrgb_flamethrower.ChameleonRGB_Flamethrower_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet60_MAT.chameleonrgb_flamethrower.ChameleonRGB_Flamethrower_3P_Pickup_MIC")) + +//Chameleon Dynamic RGB M99 + Skins.Add((Id=9447, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_M99', MIC_1P=("WEP_SkinSet60_MAT.chameleonrgb_m99.ChameleonRGB_M99_1P_Mint_MIC", "WEP_SkinSet60_MAT.chameleonrgb_m99.ChameleonRGB_M99_Scope_1P_Mint_MIC"), MIC_3P="WEP_SkinSet60_MAT.chameleonrgb_m99.ChameleonRGB_M99_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet60_MAT.chameleonrgb_m99.ChameleonRGB_M99_3P_Pickup_MIC")) + +//Chameleon Dynamic RGB SCAR + Skins.Add((Id=9448, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_SCAR', MIC_1P=("WEP_SkinSet60_MAT.chameleonrgb_scar.ChameleonRGB_SCAR_1P_Mint_MIC", "WEP_SkinSet60_MAT.chameleonrgb_scar.ChameleonRGB_SCAR_Scope_1P_Mint_MIC"), MIC_3P="WEP_SkinSet60_MAT.chameleonrgb_scar.ChameleonRGB_SCAR_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet60_MAT.chameleonrgb_scar.ChameleonRGB_SCAR_3P_Pickup_MIC")) + +//Classic Mint AK12 + Skins.Add((Id=9433, Weapondef=class'KFWeapDef_Ak12', MIC_1P=("WEP_SkinSet61_MAT.classic_ak12.Classic_AK12_1P_Mint_MIC"), MIC_3P="WEP_SkinSet61_MAT.classic_ak12.Classic_AK12_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet61_MAT.classic_ak12.Classic_AK12_3P_Pickup_MIC")) + +//Classic Mint Desert Eagle + Skins.Add((Id=9434, Weapondef=class'KFWeapDef_Deagle', MIC_1P=("WEP_SkinSet61_MAT.classic_deagle.Classic_Deagle_1P_Mint_MIC"), MIC_3P="WEP_SkinSet61_MAT.classic_deagle.Classic_Deagle_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet61_MAT.classic_deagle.Classic_Deagle_3P_Pickup_MIC")) + +//Classic Mint M14EBR + Skins.Add((Id=9435, Weapondef=class'KFWeapDef_M14EBR', MIC_1P=("WEP_SkinSet61_MAT.classic_m14ebr.Classic_M14EBR_1P_Mint_MIC"), MIC_3P="WEP_SkinSet61_MAT.classic_m14ebr.Classic_M14EBR_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet61_MAT.classic_m14ebr.Classic_M14EBR_3P_Pickup_MIC")) + +//Classic Mint Kriss + Skins.Add((Id=9436, Weapondef=class'KFWeapDef_Kriss', MIC_1P=("WEP_SkinSet61_MAT.classic_kriss.Classic_Kriss_1P_Mint_MIC"), MIC_3P="WEP_SkinSet61_MAT.classic_kriss.Classic_Kriss_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet61_MAT.classic_kriss.Classic_Kriss_3P_Pickup_MIC")) + +//Classic Precious AK12 + Skins.Add((Id=9437, Weapondef=class'KFWeapDef_Ak12', MIC_1P=("WEP_SkinSet61_MAT.standard_ak12.Standard_AK12_1P_Mint_MIC"), MIC_3P="WEP_SkinSet61_MAT.standard_ak12.Standard_AK12_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet61_MAT.standard_ak12.Standard_AK12_3P_Pickup_MIC")) + +//Classic Precious Desert Eagle + Skins.Add((Id=9438, Weapondef=class'KFWeapDef_Deagle', MIC_1P=("WEP_SkinSet61_MAT.standard_deagle.Standard_Deagle_1P_Mint_MIC"), MIC_3P="WEP_SkinSet61_MAT.standard_deagle.Standard_Deagle_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet61_MAT.standard_deagle.Standard_Deagle_3P_Pickup_MIC")) + +//Classic Precious M14EBR + Skins.Add((Id=9439, Weapondef=class'KFWeapDef_M14EBR', MIC_1P=("WEP_SkinSet61_MAT.standard_m14ebr.Standard_M14EBR_1P_Mint_MIC"), MIC_3P="WEP_SkinSet61_MAT.standard_m14ebr.Standard_M14EBR_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet61_MAT.standard_m14ebr.Standard_M14EBR_3P_Pickup_MIC")) + +//Classic Precious Kriss + Skins.Add((Id=9440, Weapondef=class'KFWeapDef_Kriss', MIC_1P=("WEP_SkinSet61_MAT.standard_kriss.Standard_Kriss_1P_Mint_MIC"), MIC_3P="WEP_SkinSet61_MAT.standard_kriss.Standard_Kriss_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet61_MAT.standard_kriss.Standard_Kriss_3P_Pickup_MIC")) + +//Xeno Dynamic M4 + Skins.Add((Id=9425, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_M4', MIC_1P=("wep_skinset63_mat.xeno_m4.Xeno_M4_1P_Mint_MIC"), MIC_3P="WEP_SkinSet63_MAT.xeno_m4.Xeno_M4_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet63_MAT.xeno_m4.Xeno_M4_3P_Pickup_MIC")) + +//Xeno Dynamic Heckler & Koch UMP + Skins.Add((Id=9426, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_HK_UMP', MIC_1P=("WEP_SkinSet63_MAT.xeno_hk_ump.Xeno_HK_UMP_1P_Mint_MIC", "WEP_SkinSet63_MAT.xeno_hk_ump.Xeno_HK_UMP_Sight_1P_Mint_MIC"), MIC_3P="WEP_SkinSet63_MAT.xeno_hk_ump.Xeno_HK_UMP_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet63_MAT.xeno_hk_ump.Xeno_HK_UMP_3P_Pickup_MIC")) + +//Xeno Dynamic Centerfire + Skins.Add((Id=9427, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_CenterfireMB464', MIC_1P=("WEP_SkinSet63_MAT.xeno_centerfire.Xeno_Centerfire_1P_Mint_MIC"), MIC_3P="WEP_SkinSet63_MAT.xeno_centerfire.Xeno_Centerfire_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet63_MAT.xeno_centerfire.Xeno_Centerfire_3P_Pickup_MIC")) + +//Xeno Dynamic Hemoclobber + Skins.Add((Id=9428, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_MedicBat', MIC_1P=("WEP_SkinSet63_MAT.xeno_medicbat.Xeno_MedicBat_1P_Mint_MIC"), MIC_3P="WEP_SkinSet63_MAT.xeno_medicbat.Xeno_MedicBat_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet63_MAT.xeno_medicbat.Xeno_MedicBat_3P_Pickup_MIC")) + +//Xeno Dynamic RGB M4 + Skins.Add((Id=9429, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_M4', MIC_1P=("WEP_SkinSet63_MAT.xenorgb_m4.XenoRGB_M4_1P_Mint_MIC"), MIC_3P="WEP_SkinSet63_MAT.xenorgb_m4.XenoRGB_M4_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet63_MAT.xenorgb_m4.XenoRGB_M4_3P_Pickup_MIC")) + +//Xeno Dynamic RGB Heckler & Koch UMP + Skins.Add((Id=9430, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_HK_UMP', MIC_1P=("WEP_SkinSet63_MAT.xenorgb_hk_ump.XenoRGB_HK_UMP_1P_Mint_MIC", "WEP_SkinSet63_MAT.xenorgb_hk_ump.XenoRGB_HK_UMP_Sight_1P_Mint_MIC"), MIC_3P="WEP_SkinSet63_MAT.xenorgb_hk_ump.XenoRGB_HK_UMP_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet63_MAT.xenorgb_hk_ump.XenoRGB_HK_UMP_3P_Pickup_MIC")) + +//Xeno Dynamic RGB Centerfire + Skins.Add((Id=9431, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_CenterfireMB464', MIC_1P=("WEP_SkinSet63_MAT.xenorgb_centerfire.XenoRGB_Centerfire_1P_Mint_MIC"), MIC_3P="WEP_SkinSet63_MAT.xenorgb_centerfire.XenoRGB_Centerfire_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet63_MAT.xenorgb_centerfire.XenoRGB_Centerfire_3P_Pickup_MIC")) + +//Xeno Dynamic RGB Hemoclobber + Skins.Add((Id=9432, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_MedicBat', MIC_1P=("WEP_SkinSet63_MAT.xenorgb_medicbat.XenoRGB_MedicBat_1P_Mint_MIC"), MIC_3P="WEP_SkinSet63_MAT.xenorgb_medicbat.XenoRGB_MedicBat_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet63_MAT.xenorgb_medicbat.XenoRGB_MedicBat_3P_Pickup_MIC")) } \ No newline at end of file diff --git a/KFGame/Classes/KFWeeklyOutbreakInformation.uc b/KFGame/Classes/KFWeeklyOutbreakInformation.uc index a8427bc..60185cd 100644 --- a/KFGame/Classes/KFWeeklyOutbreakInformation.uc +++ b/KFGame/Classes/KFWeeklyOutbreakInformation.uc @@ -27,7 +27,7 @@ var localized array ModifierDescriptions; cpptext { /** Num of Weekly events available */ - static const int NumWeeklyEvents = 17; + static const int NumWeeklyEvents = 18; } DefaultProperties { diff --git a/KFGame/Classes/KFZedArmorInfo.uc b/KFGame/Classes/KFZedArmorInfo.uc index f74a182..fbb2040 100644 --- a/KFGame/Classes/KFZedArmorInfo.uc +++ b/KFGame/Classes/KFZedArmorInfo.uc @@ -242,6 +242,9 @@ function AdjustBoneDamage(out int InDamage, name BoneName, Vector DamagerSource, { local int ArmorZoneIdx, ModDmgMax, ModDmgRem, ObliterateDamage; local float Modifier; + local class mykfDamageType; + + mykfDamageType = class(DamageType); // modify damage done and apply to armor Modifier = GetArmorDamageTypeModifier(DamageType); @@ -259,7 +262,22 @@ function AdjustBoneDamage(out int InDamage, name BoneName, Vector DamagerSource, } else { + // If we have armour penetration damage, we calculate the Damage % that is base (and applied to armor) + // And we calculate the AP one, that's applied as minimum always + if (mykfDamageType != none && mykfDamageType.default.DamageModifierAP > 0.f) + { + ModDmgRem = (1.0 - mykfDamageType.default.DamageModifierAP) * ModDmgRem; + } + TakeArmorZoneDamage(ArmorZoneIdx, ModDmgRem, ModDmgRem); + + // Apply to Zed: % AP (unmodified InDamage) + what's left of base after armor applied (unmodified ModDmgRem) + if (mykfDamageType != none && mykfDamageType.default.DamageModifierAP > 0.f) + { + InDamage = InDamage * mykfDamageType.default.DamageModifierAP; + InDamage += float(ModDmgRem) / Modifier; + return; + } } } diff --git a/KFGame/KFOnlineStats.uci b/KFGame/KFOnlineStats.uci index fdf2ff3..20d17fe 100644 --- a/KFGame/KFOnlineStats.uci +++ b/KFGame/KFOnlineStats.uci @@ -157,4 +157,5 @@ const STATID_ACHIEVE_MoonbaseCollectibles = 4059; const STATID_ACHIEVE_NetherholdCollectibles = 4060; const STATID_ACHIEVE_CarillonHamletCollectibles = 4061; const STATID_ACHIEVE_RigCollectibles = 4062; +const STATID_ACHIEVE_BarmwichCollectibles = 4063; /** `endif */ diff --git a/KFGame/KFProfileSettings.uci b/KFGame/KFProfileSettings.uci index f7410ff..6a9c423 100644 --- a/KFGame/KFProfileSettings.uci +++ b/KFGame/KFProfileSettings.uci @@ -76,3 +76,7 @@ const KFID_HasTabbedToStore = 177; const KFID_AllowSwapTo9mm = 178; // Halloween 2021 QoL: added option to quick switch weapons to 9mm const KFID_SurvivalStartingWeapIdx=179; // Summer 2022 QoL: added option to choose starting weapon for survival perk const KFID_SurvivalStartingGrenIdx=180; // Summer 2022 QoL: added option to choose starting grenade for survival perk +const KFID_MouseLookUpScale=181; // Halloweeen 2022 QoL: added mouse options to menu +const KFID_MouseLookRightScale=182; // Halloweeen 2022 QoL: added mouse options to menu +const KFID_ViewSmoothingEnabled=183; // Halloweeen 2022 QoL: added mouse options to menu +const KFID_ViewAccelerationEnabled=184; // Halloweeen 2022 QoL: added mouse options to menu \ No newline at end of file diff --git a/KFGameContent/Classes/KFDT_Ballistic_BlastBrawlersShotgun.uc b/KFGameContent/Classes/KFDT_Ballistic_BlastBrawlersShotgun.uc index db71db0..bd15df2 100644 --- a/KFGameContent/Classes/KFDT_Ballistic_BlastBrawlersShotgun.uc +++ b/KFGameContent/Classes/KFDT_Ballistic_BlastBrawlersShotgun.uc @@ -43,7 +43,7 @@ defaultproperties //KDeathUpKick=120 //KDeathVel=10 - StumblePower=12 + StumblePower=48 //12 GunHitPower=12 OverrideImpactEffect=ParticleSystem'WEP_HRG_BlastBrawlers_EMIT.FX_BlastBrawlers_Impact' diff --git a/KFGameContent/Classes/KFExplosion_MedicGrenade.uc b/KFGameContent/Classes/KFExplosion_MedicGrenade.uc index 5a2ffbf..7434f7f 100644 --- a/KFGameContent/Classes/KFExplosion_MedicGrenade.uc +++ b/KFGameContent/Classes/KFExplosion_MedicGrenade.uc @@ -87,6 +87,7 @@ protected simulated function AffectsPawn(Pawn Victim, float DamageScale) if( HumanVictim != none && HumanVictim.GetExposureTo(Location) > 0 ) { OwnerProjectile = KFProj_MedicGrenade(Owner); + if( OwnerProjectile != none ) { bCanRepairArmor = OwnerProjectile.HealedPawns.Find( HumanVictim ) == INDEX_NONE; diff --git a/KFGameContent/Classes/KFExplosion_MineReconstructor.uc b/KFGameContent/Classes/KFExplosion_MineReconstructor.uc index 7a6f138..4fe71a8 100644 --- a/KFGameContent/Classes/KFExplosion_MineReconstructor.uc +++ b/KFGameContent/Classes/KFExplosion_MineReconstructor.uc @@ -180,7 +180,7 @@ protected simulated function bool DoExplosionDamage(bool bCauseDamage, bool bCau if( bOnlyDamagePawns ) { - return ExplodePawns(); + return ExplodePawns(bCauseDamage); } return super(KFExplosionActor).DoExplosionDamage(bCauseDamage, bCauseEffects); diff --git a/KFGameContent/Classes/KFGFxHUD_PlayerStatusVersus.uc b/KFGameContent/Classes/KFGFxHUD_PlayerStatusVersus.uc index 2571c54..3ee5a9e 100644 --- a/KFGameContent/Classes/KFGFxHUD_PlayerStatusVersus.uc +++ b/KFGameContent/Classes/KFGFxHUD_PlayerStatusVersus.uc @@ -62,7 +62,7 @@ function UpdateHealer(Optional bool bForce) } -function ShowActiveIndicators( array IconPathStrings ) +function ShowActiveIndicators( array ActiveSkills ) { } diff --git a/KFGameContent/Classes/KFGameInfo_Survival.uc b/KFGameContent/Classes/KFGameInfo_Survival.uc index 92f09cd..20bff2d 100644 --- a/KFGameContent/Classes/KFGameInfo_Survival.uc +++ b/KFGameContent/Classes/KFGameInfo_Survival.uc @@ -48,6 +48,8 @@ var protected transient bool bWaveStarted; // When this is true next wave will be last var protected bool bGunGamePlayerOnLastGun; +var transient array BonfireVolumes; + /** Whether this game mode should play music from the get-go (lobby) */ static function bool ShouldPlayMusicAtStart() { @@ -75,6 +77,8 @@ event PostBeginPlay() TimeBetweenWaves = GetTraderTime(); bGunGamePlayerOnLastGun = false; + + UpdateBonfires(); } /** Set up the spawning */ @@ -1144,6 +1148,8 @@ function WaveEnded(EWaveEndCondition WinCondition) return; } + ClearAllActorsFromBonfire(); + if (WorldInfo.NetMode == NM_DedicatedServer) { scripttrace(); @@ -1202,28 +1208,9 @@ function WaveEnded(EWaveEndCondition WinCondition) } } - if (OutbreakEvent != none && OutbreakEvent.ActiveEvent.bGunGameMode) + if (OutbreakEvent != none) { - MyKFGRI.GunGameWavesCurrent += 1; - - // If we unlocked last weapon we only finish if we completed the boss wave - // If we didn't unlock to last weapon and we just finished last wave (before BOSS), repeat - if (bGunGamePlayerOnLastGun) - { - MyKFGRI.bWaveGunGameIsFinal = true; - - if (WaveNum < WaveMax) - { - WaveNum = WaveMax - 1; - } - } - else if (WaveNum >= WaveMax - 1) - { - // Repeat wave before BOSS till forever - WaveNum = WaveMax - 2; - } - - MyKFGRI.bNetDirty = true; + OnOutbreakWaveWon(); } if (WaveNum < WaveMax) @@ -1873,6 +1860,38 @@ function DebugKillZeds() } } +function OnOutbreakWaveWon() {} + +function UpdateBonfires() +{ + local KFBarmwichBonfireVolume BonfireVolume; + + foreach AllActors(class'KFBarmwichBonfireVolume', BonfireVolume) + { + BonfireVolumes.AddItem(BonfireVolume); + } +} + +function ClearAllActorsFromBonfire() +{ + local KFBarmwichBonfireVolume BonfireVolume; + + foreach BonfireVolumes(BonfireVolume) + { + BonfireVolume.ClearAllActors(); + } +} + +function ClearActorFromBonfire(Actor Other) +{ + local KFBarmwichBonfireVolume BonfireVolume; + + foreach BonfireVolumes(BonfireVolume) + { + BonfireVolume.ClearActor(Other); + } +} + DefaultProperties { TimeBetweenWaves=60 //This is going to be a difficulty setting later diff --git a/KFGameContent/Classes/KFGameInfo_WeeklySurvival.uc b/KFGameContent/Classes/KFGameInfo_WeeklySurvival.uc index 655c65a..aaccebd 100644 --- a/KFGameContent/Classes/KFGameInfo_WeeklySurvival.uc +++ b/KFGameContent/Classes/KFGameInfo_WeeklySurvival.uc @@ -607,7 +607,7 @@ function EndOfMatch(bool bVictory) KFPC.CompletedWeeklySurvival(); } } - + super.EndOfMatch(bVictory); } @@ -988,7 +988,7 @@ function LoadGunGameWeapons(Controller NewPlayer) Weapon = KFWeapon(Inv); if (Weapon != none) { - Weapon.GunGameRemove(); + Weapon.RemoveGun(); } } } @@ -1108,37 +1108,43 @@ function ResetGunGame(KFPlayerController_WeeklySurvival KFPC_WS) function NotifyKilled(Controller Killer, Controller Killed, Pawn KilledPawn, class damageType ) { local KFPawn_Monster KFPM; - local KFPlayerController_WeeklySurvival KFPC_WS; + local KFPlayerController_WeeklySurvival KFPC_WS_Killer, KFPC_WS_Killed; super.NotifyKilled(Killer, Killed, KilledPawn, damageType); - - if (!OutbreakEvent.ActiveEvent.bGunGameMode) - { - return; - } - - // If pawn is monster increase gun game score for that monster - KFPM = KFPawn_Monster(KilledPawn); - KFPC_WS = KFPlayerController_WeeklySurvival(Killer); + KFPM = KFPawn_Monster(KilledPawn); + KFPC_WS_Killer = KFPlayerController_WeeklySurvival(Killer); + KFPC_WS_Killed = KFPlayerController_WeeklySurvival(Killed); - if (KFPM != none && KFPC_WS != none) - { - if (KFPC_WS.Pawn.Health > 0) + if (OutbreakEvent.ActiveEvent.bGunGameMode) + { + // If pawn is monster increase gun game score for that monster + + if (KFPM != none && KFPC_WS_Killer != none) { - KFPC_WS.GunGameData.Score += KFPM.GunGameKilledScore; - UpdateGunGameLevel(KFPC_WS); + if (KFPC_WS_Killer.Pawn.Health > 0) + { + KFPC_WS_Killer.GunGameData.Score += KFPM.GunGameKilledScore; + UpdateGunGameLevel(KFPC_WS_Killer); + } + } + else + { + // If pawn is human reset game score (we can just check Killed exists as Controller + if (KFPC_WS_Killed != none) + { + ResetGunGame(KFPC_WS_Killed); + } } } - else + + if (OutbreakEvent.ActiveEvent.bVIPGameMode) { - // If pawn is human reset game score (we can just check Killed exists as Controller) - - KFPC_WS = KFPlayerController_WeeklySurvival(Killed); - - if (KFPC_WS != none) + if (KFPC_WS_Killed != none && KFPC_WS_Killed.VIPGameData.isVIP) { - ResetGunGame(KFPC_WS); + // UnregisterPlayer is done on the same frame but this function comes first.. + // we queue a petition to end the game if no vip is found + SetTimer(1.5f, false, 'OnVIPDiesEndMatch'); } } } @@ -1240,7 +1246,7 @@ function UpdateGunGameLevel(KFPlayerController_WeeklySurvival KFPC_WS) { // To prevent audio/vfx lock, while firing when removing the equipped weapon we do a proper gun remove // This new function manages it's state internally - CurrentWeapon.GunGameRemove(); + CurrentWeapon.RemoveGun(); } if (class'KFPerk_SWAT'.static.Is9mm(CurrentWeapon)) @@ -1278,6 +1284,222 @@ function UpdateGunGameLevel(KFPlayerController_WeeklySurvival KFPC_WS) } } +/////////////////////////////////////////////////////////////////////////////////// + +function UnregisterPlayer(PlayerController PC) +{ + local KFPlayerController_WeeklySurvival KFPC_WS; + + super.UnregisterPlayer(PC); + + KFPC_WS = KFPlayerController_WeeklySurvival(PC); + if (OutbreakEvent.ActiveEvent.bVIPGameMode) + { + if (KFPC_WS != none && KFPC_WS.VIPGameData.IsVIP) + { + ChooseVIP(false, KFPC_WS); + } + } +} + +function WaveStarted() +{ + Super.WaveStarted(); + + if (OutbreakEvent.ActiveEvent.bVIPGameMode) + { + if (WaveNum <= 1) + { + ChooseVIP(true); + } + } +} + +function OnVIPDiesEndMatch() +{ + local KFPlayerController KFPC; + + foreach WorldInfo.AllControllers(class'KFPlayerController', KFPC) + { + KFPC.SetCameraMode('ThirdPerson'); + } + + WaveEnded(WEC_TeamWipedOut); +} + +function ChooseVIP_SetupVIP() +{ + local KFPlayerController_WeeklySurvival KFPC_WS, NewVIP; + local KFGameReplicationInfo KFGRI; + + NewVIP = none; + KFGRI = KFGameReplicationInfo(WorldInfo.GRI); + + foreach WorldInfo.AllControllers(class'KFPlayerController_WeeklySurvival', KFPC_WS) + { + if (KFPC_WS != none) + { + if (KFPC_WS.VIPGameData.IsVIP) + { + NewVIP = KFPC_WS; + break; + } + } + } + + if (NewVIP != none) + { + //`Log("Setup new VIP: " $NewVIP); + + if (NewVIP.Pawn != none) + { + //`Log("Finished setup new VIP: " $NewVIP); + + NewVIP.GetPerk().PerkSetOwnerHealthAndArmor(false); + + if (NewVIP.VIPGameData.PendingHealthReset) + { + NewVIP.VIPGameData.PendingHealthReset = false; + + // Change current health directly, Pawn.HealDamage does a lot of other stuff that can block the healing + NewVIP.Pawn.Health = NewVIP.Pawn.HealthMax; + } + + // Replicate new data to clients + KFGRI.UpdateVIPPlayer(KFPlayerReplicationInfo(NewVIP.PlayerReplicationInfo)); + KFGRI.UpdateVIPMaxHealth(NewVIP.Pawn.HealthMax); + KFGRI.UpdateVIPCurrentHealth(NewVIP.Pawn.Health); + + NewVIP.PlayVIPGameChosenSound(3.5f); + + ClearTimer('ChooseVIP_SetupVIP'); + } + } +} + +function ChooseVIP(bool ForceAddHealth, optional KFPlayerController_WeeklySurvival PlayerJustLeft = none) +{ + local int RandomNumber; + local KFPlayerController_WeeklySurvival KFPC_WS, CurrentVIP, NewVIP; + local array PotentialVIP; + local KFGameReplicationInfo KFGRI; + + //`Log("ChooseVIP!!!!!"); + + ClearTimer('ChooseVIP_SetupVIP'); + + KFGRI = KFGameReplicationInfo(WorldInfo.GRI); + + foreach WorldInfo.AllControllers(class'KFPlayerController_WeeklySurvival', KFPC_WS) + { + if (KFPC_WS != none) + { + if (KFPC_WS.VIPGameData.IsVIP == false && KFPC_WS.VIPGameData.WasVIP == false) + { + PotentialVIP.AddItem(KFPC_WS); + } + + if (KFPC_WS.VIPGameData.IsVIP) + { + CurrentVIP = KFPC_WS; + } + } + } + + if (CurrentVIP != none) + { + //`Log("Remove old VIP: " $CurrentVIP); + + CurrentVIP.VIPGameData.IsVIP = false; + + CurrentVIP.GetPerk().PerkSetOwnerHealthAndArmor(false); + } + + // If there's no potential VIP we restart + if (PotentialVIP.Length == 0) + { + foreach WorldInfo.AllControllers(class'KFPlayerController_WeeklySurvival', KFPC_WS) + { + if (KFPC_WS != none) + { + KFPC_WS.VIPGameData.WasVIP = false; + + if (PlayerJustLeft == none + || PlayerJustLeft != KFPC_WS) + { + PotentialVIP.AddItem(KFPC_WS); + } + } + } + } + + if (PotentialVIP.Length > 0) + { + RandomNumber = Rand(PotentialVIP.Length); + + NewVIP = PotentialVIP[RandomNumber]; + + NewVIP.VIPGameData.IsVIP = true; + NewVIP.VIPGameData.WasVIP = true; + } + + if (NewVIP != none) + { + if (ForceAddHealth || (KFGRI != none && KFGRI.bWaveIsActive == false)) + { + NewVIP.VIPGameData.PendingHealthReset = true; + } + + // If there's no Pawn we have to wait on a Timer function + if (NewVIP.Pawn != none) + { + ChooseVIP_SetupVIP(); + } + else + { + SetTimer(0.25f, true, 'ChooseVIP_SetupVIP'); + } + + ClearTimer('OnVIPDiesEndMatch'); + } +} + +function OnOutbreakWaveWon() +{ + Super.OnOutbreakWaveWon(); + + // GunGame Mode + if (OutbreakEvent.ActiveEvent.bGunGameMode) + { + MyKFGRI.GunGameWavesCurrent += 1; + + // If we unlocked last weapon we only finish if we completed the boss wave + // If we didn't unlock to last weapon and we just finished last wave (before BOSS), repeat + if (bGunGamePlayerOnLastGun) + { + MyKFGRI.bWaveGunGameIsFinal = true; + + if (WaveNum < WaveMax) + { + WaveNum = WaveMax - 1; + } + } + else if (WaveNum >= WaveMax - 1) + { + // Repeat wave before BOSS till forever + WaveNum = WaveMax - 2; + } + + MyKFGRI.bNetDirty = true; + } + + // VIP Mode + if (OutbreakEvent.ActiveEvent.bVIPGameMode) + { + ChooseVIP(true); + } +} + defaultproperties { //Overrides diff --git a/KFGameContent/Classes/KFMapObjective_AreaDefense.uc b/KFGameContent/Classes/KFMapObjective_AreaDefense.uc index bdecf21..b69d947 100644 --- a/KFGameContent/Classes/KFMapObjective_AreaDefense.uc +++ b/KFGameContent/Classes/KFMapObjective_AreaDefense.uc @@ -198,19 +198,32 @@ simulated function bool CanActivateObjectiveByWeekly() { if (Role == Role_Authority) { - if (KFGameInfo(WorldInfo.Game).OutbreakEvent != none - && KFGameInfo(WorldInfo.Game).OutbreakEvent.ActiveEvent.bGunGameMode) + if (KFGameInfo(WorldInfo.Game).OutbreakEvent != none) { - return false; + if (KFGameInfo(WorldInfo.Game).OutbreakEvent.ActiveEvent.bGunGameMode) + { + return false; + } + + if (KFGameInfo(WorldInfo.Game).OutbreakEvent.ActiveEvent.bVIPGameMode) + { + return false; + } } } else { - if (KFGameReplicationInfo(WorldInfo.GRI) != none - && KFGameReplicationInfo(WorldInfo.GRI).bIsWeeklyMode - && KFGameReplicationInfo(WorldInfo.GRI).CurrentWeeklyIndex == 16) + if (KFGameReplicationInfo(WorldInfo.GRI) != none && KFGameReplicationInfo(WorldInfo.GRI).bIsWeeklyMode) { - return false; + if (KFGameReplicationInfo(WorldInfo.GRI).CurrentWeeklyIndex == 16) + { + return false; + } + + if (KFGameReplicationInfo(WorldInfo.GRI).CurrentWeeklyIndex == 17) + { + return false; + } } } diff --git a/KFGameContent/Classes/KFOutbreakEvent_Weekly.uc b/KFGameContent/Classes/KFOutbreakEvent_Weekly.uc index 7fc8ab6..71122c5 100644 --- a/KFGameContent/Classes/KFOutbreakEvent_Weekly.uc +++ b/KFGameContent/Classes/KFOutbreakEvent_Weekly.uc @@ -920,7 +920,6 @@ defaultproperties bSpawnWeaponListAffectsSecondaryWeapons=true, OverrideItemPickupModifier= 0.5f, //1.0f, //2.0f, // 0.f, OverrideAmmoPickupModifier= 1.0f, //2.0f, //3.0f, // 0.01f, - bOnlyArmorItemPickup=true, TraderTimeModifier=1.0f, // 0.1f, TimeBetweenWaves=30.f, bDisableAddDosh=true, @@ -1190,6 +1189,37 @@ defaultproperties )} + // VIP + SetEvents[17]={( + EventDifficulty=2, + GameLength=GL_Normal, + bVIPGameMode=true, + VIPTargetting=(class'KFGameContent.KFPawn_ZedScrake' + , class'KFGameContent.KFPawn_ZedFleshpound' + , class'KFGameContent.KFPawn_ZedFleshpoundMini' + , class'KFGameContent.KFPawn_ZedGorefast' + , class'KFGameContent.KFPawn_ZedGorefastDualBlade' + , class'KFGameContent.KFPawn_ZedClot_Cyst' + , class'KFGameContent.KFPawn_ZedClot_Slasher' + , class'KFGameContent.KFPawn_ZedClot_Alpha' + , class'KFGameContent.KFPawn_ZedClot_AlphaKing' + , class'KFGameContent.KFPawn_ZedBloat' + , class'KFGameContent.KFPawn_ZedHusk' + , class'KFGameContent.KFPawn_ZedSiren' + , class'KFGameContent.KFPawn_ZedCrawler' + , class'KFGameContent.KFPawn_ZedCrawlerKing' + , class'KFGameContent.KFPawn_ZedStalker' + , class'KFGameContent.KFPawn_ZedDAR_EMP' + , class'KFGameContent.KFPawn_ZedDAR_Laser' + , class'KFGameContent.KFPawn_ZedDAR_Rocket' + , class'KFGameContent.KFPawn_ZedMatriarch' + , class'KFGameContent.KFPawn_ZedPatriarch' + , class'KFGameContent.KFPawn_ZedBloatKing' + , class'KFGameContent.KFPawn_ZedBloatKingSubspawn' + , class'KFGameContent.KFPawn_ZedFleshpoundKing' + , class'KFGameContent.KFPawn_ZedHans'), + )} + //Test events from here down. These don't end up in the regular rotation. // The override ID starts from one higher than the last SetEvents entry above. // Ex: Big head = 7, Horde = 8 diff --git a/KFGameContent/Classes/KFPawn_ZedFleshpoundKing.uc b/KFGameContent/Classes/KFPawn_ZedFleshpoundKing.uc index 1909671..6fdd425 100644 --- a/KFGameContent/Classes/KFPawn_ZedFleshpoundKing.uc +++ b/KFGameContent/Classes/KFPawn_ZedFleshpoundKing.uc @@ -440,7 +440,7 @@ function AdjustDamage(out int InDamage, out vector Momentum, Controller Instigat } } -function HandleAfflictionsOnHit(Controller DamageInstigator, vector HitDir, class DamageType, Actor DamageCauser) +function HandleAfflictionsOnHit(Controller DamageInstigator, vector HitDir, class DamageType, Actor DamageCauser) { if (ShieldHealthPctByte == 0) { diff --git a/KFGameContent/Classes/KFProj_Grenade_HRG_CranialPopper.uc b/KFGameContent/Classes/KFProj_Grenade_HRG_CranialPopper.uc index fff0862..e30c6d2 100644 --- a/KFGameContent/Classes/KFProj_Grenade_HRG_CranialPopper.uc +++ b/KFGameContent/Classes/KFProj_Grenade_HRG_CranialPopper.uc @@ -39,6 +39,7 @@ state WaveState local TraceHitInfo HitInfo; local float Radius; local float DamageHead; + local name HitBoneName; if(bWaveActive) { @@ -54,9 +55,17 @@ state WaveState if(DamageHead > 0) { //`Log("Take: "$Victim); - //HitInfo.BoneName = 'head'; + + HitBoneName = Victim.HeadBoneName; + + if(HitBoneName != `NAME_NONE) + { + HitInfo.BoneName = HitBoneName; + } + + //`Log("HitInfo.BoneName: "$HitInfo.BoneName); + Victim.TakeDamage(DamageHead * UpgradeDamageMod, InstigatorController, Victim.Location, Normal(Victim.Location - Instigator.Location), MyDamageType, HitInfo, (Owner != None) ? Owner : self); - //Monster.PlayDismemberment(0, MyDamageType, WaveImpactMomentum); if (Victim.Health <= 0) { diff --git a/KFGameContent/Classes/KFProj_Mine_Reconstructor.uc b/KFGameContent/Classes/KFProj_Mine_Reconstructor.uc index 91929a1..647cfdf 100644 --- a/KFGameContent/Classes/KFProj_Mine_Reconstructor.uc +++ b/KFGameContent/Classes/KFProj_Mine_Reconstructor.uc @@ -886,8 +886,8 @@ defaultproperties // Camera Shake CamShake=CameraShake'WEP_Mine_Reconstructor_Arch.Camera_Shake' - CamShakeInnerRadius=200 - CamShakeOuterRadius=400 + CamShakeInnerRadius=0 + CamShakeOuterRadius=0 CamShakeFalloff=1.f bOrientCameraShakeTowardsEpicenter=true End Object @@ -905,8 +905,8 @@ defaultproperties MaxDamageRadiusPerPercentage=340 MinDamageRadiusPerPercentage=160 - MaxDamagePerPercentage=350 //300 - MinDamagePerPercentage=35 //30 + MaxDamagePerPercentage=400 //350 //300 + MinDamagePerPercentage=40 //35 //30 MaxCollisionRadius=20 MinCollisionRadius=10 diff --git a/KFGameContent/Classes/KFWeap_AssaultRifle_LazerCutter.uc b/KFGameContent/Classes/KFWeap_AssaultRifle_LazerCutter.uc index e178831..eece2a4 100644 --- a/KFGameContent/Classes/KFWeap_AssaultRifle_LazerCutter.uc +++ b/KFGameContent/Classes/KFWeap_AssaultRifle_LazerCutter.uc @@ -998,7 +998,7 @@ defaultproperties // Zooming/Position PlayerViewOffset = (X = 3.0, Y = 10, Z = -1) - IronSightPosition = (X = 0, Y = 0, Z = 0) + IronSightPosition = (X = 0, Y = 0.037, Z = 0.11) // Ammo MagazineCapacity[0] = 50 diff --git a/KFGameContent/Classes/KFWeap_AssaultRifle_Microwave.uc b/KFGameContent/Classes/KFWeap_AssaultRifle_Microwave.uc index 5693bfc..0d13cba 100644 --- a/KFGameContent/Classes/KFWeap_AssaultRifle_Microwave.uc +++ b/KFGameContent/Classes/KFWeap_AssaultRifle_Microwave.uc @@ -73,7 +73,7 @@ defaultproperties DOF_FG_MaxNearBlurSize=2.5 // Zooming/Position - IronSightPosition=(X=10,Y=0,Z=0) //x20 + IronSightPosition=(X=10,Y=-0.015,Z=0.09) //x20 PlayerViewOffset=(X=30.0,Y=10,Z=-2.5) //x18 y9 z0 // Content diff --git a/KFGameContent/Classes/KFWeap_AutoTurret.uc b/KFGameContent/Classes/KFWeap_AutoTurret.uc index 76019c6..7f62937 100644 --- a/KFGameContent/Classes/KFWeap_AutoTurret.uc +++ b/KFGameContent/Classes/KFWeap_AutoTurret.uc @@ -176,7 +176,7 @@ simulated function GetTurretSpawnLocationAndDir(out vector SpawnLocation, out ve } /** Detonates the oldest turret */ -simulated function Detonate() +simulated function Detonate(optional bool bKeepTurret = false) { local int i; local array TurretsCopy; @@ -187,10 +187,15 @@ simulated function Detonate() TurretsCopy = KFPC.DeployedTurrets; for (i = 0; i < TurretsCopy.Length; i++) { + if (bKeepTurret && i == 0) + { + continue; + } + KFPawn_AutoTurret(TurretsCopy[i]).SetTurretState(ETS_Detonate); } - KFPC.DeployedTurrets.Remove(0, KFPC.DeployedTurrets.Length); + KFPC.DeployedTurrets.Remove(bKeepTurret ? 1 : 0, KFPC.DeployedTurrets.Length); SetReadyToUse(true); @@ -231,7 +236,17 @@ function SetOriginalValuesFromPickup( KFWeapon PickedUpWeapon ) if (PickedUpWeapon.KFPlayer != none && PickedUpWeapon.KFPlayer != KFPC) { - KFPC.DeployedTurrets = PickedUpWeapon.KFPlayer.DeployedTurrets; + for (i = 0; i < PickedUpWeapon.KFPlayer.DeployedTurrets.Length; i++) + { + KFPC.DeployedTurrets.AddItem(PickedUpWeapon.KFPlayer.DeployedTurrets[i]); + } + + PickedUpWeapon.KFPlayer.DeployedTurrets.Remove(0, PickedUpWeapon.KFPlayer.DeployedTurrets.Length); + } + + if (KFPC.DeployedTurrets.Length > 1) + { + Detonate(true); } PickedUpWeapon.KFPlayer = none; diff --git a/KFGameContent/Classes/KFWeap_Beam_Microwave.uc b/KFGameContent/Classes/KFWeap_Beam_Microwave.uc index fb6cd61..d67a5f2 100644 --- a/KFGameContent/Classes/KFWeap_Beam_Microwave.uc +++ b/KFGameContent/Classes/KFWeap_Beam_Microwave.uc @@ -184,7 +184,7 @@ defaultproperties PlayerIronSightFOV=80 // Zooming/Position - IronSightPosition=(X=3,Y=0,Z=0) + IronSightPosition=(X=3,Y=-0.032,Z=-0.03) PlayerViewOffset=(X=5.0,Y=9,Z=-3) // Depth of field diff --git a/KFGameContent/Classes/KFWeap_Blunt_MedicBat.uc b/KFGameContent/Classes/KFWeap_Blunt_MedicBat.uc index 4f48058..b00c40e 100644 --- a/KFGameContent/Classes/KFWeap_Blunt_MedicBat.uc +++ b/KFGameContent/Classes/KFWeap_Blunt_MedicBat.uc @@ -396,8 +396,13 @@ simulated protected function PrepareExplosion() KFPC = KFPlayerController(Instigator.Controller); if (KFPC != none) { + `Log("RADIUS BEFORE: " $ExplosionTemplate.DamageRadius); + InstigatorPerk = KFPC.GetPerk(); ExplosionTemplate.DamageRadius *= InstigatorPerk.GetAoERadiusModifier(); + + `Log("RADIUS BEFORE: " $ExplosionTemplate.DamageRadius); + } } @@ -448,6 +453,9 @@ simulated function SpawnExplosionFromTemplate(KFGameExplosion Template) ExploActor.Explode(Template, vector(SpawnRot)); } + + // Reset damage radius + ExplosionTemplate.DamageRadius = StartingDamageRadius; } simulated function CustomFire() diff --git a/KFGameContent/Classes/KFWeap_Blunt_Pulverizer.uc b/KFGameContent/Classes/KFWeap_Blunt_Pulverizer.uc index 17d3229..5ad9da5 100644 --- a/KFGameContent/Classes/KFWeap_Blunt_Pulverizer.uc +++ b/KFGameContent/Classes/KFWeap_Blunt_Pulverizer.uc @@ -138,6 +138,8 @@ simulated function CustomFire() // tell remote clients that we fired, to trigger effects in third person IncrementFlashCount(); + ExplosionTemplate.DamageRadius = StartingDamageRadius; + if ( bDebug ) { DrawDebugCone(SpawnLoc, vector(SpawnRot), ExplosionTemplate.DamageRadius, ExplosionTemplate.DirectionalExplosionAngleDeg * DegToRad, diff --git a/KFGameContent/Classes/KFWeap_HRG_CranialPopper.uc b/KFGameContent/Classes/KFWeap_HRG_CranialPopper.uc index b16e1e6..afa003a 100644 --- a/KFGameContent/Classes/KFWeap_HRG_CranialPopper.uc +++ b/KFGameContent/Classes/KFWeap_HRG_CranialPopper.uc @@ -366,8 +366,8 @@ defaultproperties //WeaponUpgrades[1]=(IncrementDamage=1.4f,IncrementWeight=1, IncrementHealFullRecharge=.8) //WeaponUpgrades[2]=(IncrementDamage=1.8f,IncrementWeight=2, IncrementHealFullRecharge=.6) - WeaponUpgrades[1]=(Stats=((Stat=EWUS_Damage0, Scale=1.15f), (Stat=EWUS_Weight, Add=1), (Stat=EWUS_HealFullRecharge, Scale=0.9f))) - WeaponUpgrades[2]=(Stats=((Stat=EWUS_Damage0, Scale=1.3f), (Stat=EWUS_Weight, Add=2), (Stat=EWUS_HealFullRecharge, Scale=0.8f))) + WeaponUpgrades[1]=(Stats=((Stat=EWUS_Damage0, Scale=1.15f), (Stat=EWUS_Weight, Add=1))) + WeaponUpgrades[2]=(Stats=((Stat=EWUS_Damage0, Scale=1.3f), (Stat=EWUS_Weight, Add=2))) // From original KFWeap_RifleBase base class AimCorrectionSize=40.f diff --git a/KFGameContent/Classes/KFWeap_HRG_EMP_ArcGenerator.uc b/KFGameContent/Classes/KFWeap_HRG_EMP_ArcGenerator.uc index b00358c..8735661 100644 --- a/KFGameContent/Classes/KFWeap_HRG_EMP_ArcGenerator.uc +++ b/KFGameContent/Classes/KFWeap_HRG_EMP_ArcGenerator.uc @@ -746,7 +746,7 @@ defaultproperties PlayerIronSightFOV=80 // Zooming/Position - IronSightPosition=(X=3,Y=0,Z=0) + IronSightPosition=(X=3,Y=-0.032,Z=-0.03) PlayerViewOffset=(X=5.0,Y=9,Z=-3) // Depth of field diff --git a/KFGameContent/Classes/KFWeap_Mine_Reconstructor.uc b/KFGameContent/Classes/KFWeap_Mine_Reconstructor.uc index d5e202a..35db31e 100644 --- a/KFGameContent/Classes/KFWeap_Mine_Reconstructor.uc +++ b/KFGameContent/Classes/KFWeap_Mine_Reconstructor.uc @@ -842,8 +842,8 @@ defaultproperties ValueIncreaseTime=0.2 //FOR LERPING DAMANGE - MaxDamageByCharge=300 //250 //200 //120 - MinDamageByCharge=30 //25 //30 + MaxDamageByCharge=350 //300 //250 //200 //120 + MinDamageByCharge=35 //30 //25 //30 // FOV Meshfov=80 MeshIronSightFOV=65 //52 @@ -895,7 +895,7 @@ defaultproperties HippedRecoilModifier=1.5 // Inventory - InventorySize=8 + InventorySize=7 //8 GroupPriority=80 //75 WeaponSelectTexture=Texture2D'WEP_UI_Mine_Reconstructor_TEX.UI_WeaponSelect_HMTechMineReconstructor' //@TODO: Replace me diff --git a/KFGameContent/Classes/KFWeap_Pistol_Blunderbuss.uc b/KFGameContent/Classes/KFWeap_Pistol_Blunderbuss.uc index 4eca1cb..15b891f 100644 --- a/KFGameContent/Classes/KFWeap_Pistol_Blunderbuss.uc +++ b/KFGameContent/Classes/KFWeap_Pistol_Blunderbuss.uc @@ -492,7 +492,7 @@ defaultproperties // Zooming/Position PlayerViewOffset=(X=-15,Y=12,Z=-6) - IronSightPosition=(X=-3,Y=0,Z=0) + IronSightPosition=(X=-3,Y=0.145,Z=0) // Content PackageKey="Blunderbuss" diff --git a/KFGameContent/Classes/KFWeap_Pistol_G18C.uc b/KFGameContent/Classes/KFWeap_Pistol_G18C.uc index b74eeb0..4190163 100644 --- a/KFGameContent/Classes/KFWeap_Pistol_G18C.uc +++ b/KFGameContent/Classes/KFWeap_Pistol_G18C.uc @@ -121,7 +121,7 @@ defaultproperties // Zooming/Position [FFERRANDO NEEDS TO BE UPDATED TO G18] PlayerViewOffset=(X=-15,Y=12,Z=-6) - IronSightPosition=(X=0,Y=0,Z=0) //(X=-3,Y=-0.38,Z=-0.2) + IronSightPosition=(X=0,Y=-0.12,Z=-0.1) //(X=-3,Y=-0.38,Z=-0.2) // Content [FFERRANDO NEEDS TO BE UPDATED TO G18] PackageKey="G18C" diff --git a/KFGameContent/Classes/KFWeap_Rifle_Hemogoblin.uc b/KFGameContent/Classes/KFWeap_Rifle_Hemogoblin.uc index 250276d..475bde3 100644 --- a/KFGameContent/Classes/KFWeap_Rifle_Hemogoblin.uc +++ b/KFGameContent/Classes/KFWeap_Rifle_Hemogoblin.uc @@ -91,7 +91,7 @@ defaultproperties // Zooming/Position PlayerViewOffset=(X=20.0,Y=11.0,Z=-2) //(X=15.0,Y=11.5,Z=-4) - IronSightPosition=(X=30.0,Y=0,Z=0) + IronSightPosition=(X=30.0,Y=-0.035,Z=-0.07) // AI warning system bWarnAIWhenAiming=true diff --git a/KFGameContent/Classes/KFWeap_Rifle_M14EBR.uc b/KFGameContent/Classes/KFWeap_Rifle_M14EBR.uc index a16fb9a..e302c01 100644 --- a/KFGameContent/Classes/KFWeap_Rifle_M14EBR.uc +++ b/KFGameContent/Classes/KFWeap_Rifle_M14EBR.uc @@ -57,7 +57,7 @@ defaultproperties // Zooming/Position PlayerViewOffset=(X=15.0,Y=11.5,Z=-4) - IronSightPosition=(X=0.0,Y=0,Z=0) + IronSightPosition=(X=0.0,Y=-0.016,Z=-0.016) // AI warning system bWarnAIWhenAiming=true diff --git a/KFGameContent/Classes/KFWeap_Rifle_RailGun.uc b/KFGameContent/Classes/KFWeap_Rifle_RailGun.uc index 85c8d57..32a2cfe 100644 --- a/KFGameContent/Classes/KFWeap_Rifle_RailGun.uc +++ b/KFGameContent/Classes/KFWeap_Rifle_RailGun.uc @@ -509,7 +509,7 @@ defaultproperties // Zooming/Position PlayerViewOffset=(X=3.0,Y=7,Z=-2) - IronSightPosition=(X=-0.25,Y=0,Z=0) // any further back along X and the scope clips through the camera during firing + IronSightPosition=(X=-0.25,Y=0.005,Z=-0.005) // any further back along X and the scope clips through the camera during firing // AI warning system bWarnAIWhenAiming=true diff --git a/KFGameContent/Classes/KFWeap_RocketLauncher_Seeker6.uc b/KFGameContent/Classes/KFWeap_RocketLauncher_Seeker6.uc index 7e0d212..6491766 100644 --- a/KFGameContent/Classes/KFWeap_RocketLauncher_Seeker6.uc +++ b/KFGameContent/Classes/KFWeap_RocketLauncher_Seeker6.uc @@ -137,7 +137,7 @@ simulated function bool FindTargets( out Pawn RecentlyLocked ) local byte TeamNum; local vector AimStart, AimDir, TargetLoc, Projection, DirToPawn, LinePoint; local Actor HitActor; - local float PointDistSQ, Score, BestScore; + local float PointDistSQ, Score, BestScore, TargetSizeSQ; TeamNum = Instigator.GetTeamNum(); AimStart = GetSafeStartTraceLocation(); @@ -172,7 +172,11 @@ simulated function bool FindTargets( out Pawn RecentlyLocked ) // Check to make sure target isn't too far from center PointDistToLine( TargetLoc, AimDir, AimStart, LinePoint ); PointDistSQ = VSizeSQ( LinePoint - P.Location ); - if( PointDistSQ > MinTargetDistFromCrosshairSQ ) + + TargetSizeSQ = P.GetCollisionRadius() * 2.f; + TargetSizeSQ *= TargetSizeSQ; + + if( PointDistSQ > (TargetSizeSQ + MinTargetDistFromCrosshairSQ) ) { continue; } diff --git a/KFGameContent/Classes/KFWeap_SMG_Kriss.uc b/KFGameContent/Classes/KFWeap_SMG_Kriss.uc index 57bd7f7..84cfe44 100644 --- a/KFGameContent/Classes/KFWeap_SMG_Kriss.uc +++ b/KFGameContent/Classes/KFWeap_SMG_Kriss.uc @@ -23,7 +23,7 @@ defaultproperties PlayerIronSightFOV=75 // Zooming/Position - IronSightPosition=(X=15.f,Y=0.f,Z=0.0f) + IronSightPosition=(X=15.f,Y=0.03f,Z=0.1f) PlayerViewOffset=(X=20.f,Y=9.5f,Z=-3.0f) // Content diff --git a/KFGameContent/Classes/KFWeap_SMG_Medic.uc b/KFGameContent/Classes/KFWeap_SMG_Medic.uc index 0bf3660..f90a521 100644 --- a/KFGameContent/Classes/KFWeap_SMG_Medic.uc +++ b/KFGameContent/Classes/KFWeap_SMG_Medic.uc @@ -38,7 +38,7 @@ defaultproperties PlayerIronSightFOV=70 // Zooming/Position - IronSightPosition=(X=8,Y=0,Z=0) + IronSightPosition=(X=8,Y=0.01,Z=-0.04) PlayerViewOffset=(X=22,Y=10,Z=-4.5) // Content diff --git a/KFGameContent/Classes/KFWeap_Shotgun_Medic.uc b/KFGameContent/Classes/KFWeap_Shotgun_Medic.uc index d2d21ad..a3e7da1 100644 --- a/KFGameContent/Classes/KFWeap_Shotgun_Medic.uc +++ b/KFGameContent/Classes/KFWeap_Shotgun_Medic.uc @@ -72,7 +72,7 @@ defaultproperties // Zooming/Position PlayerViewOffset=(X=14.0,Y=6.5,Z=-3.5) - IronSightPosition=(X=12.0,Y=0,Z=0) + IronSightPosition=(X=12.0,Y=-0.03,Z=-0.07) // Content PackageKey="Medic_Shotgun"