1
0
This commit is contained in:
GenZmeY 2022-10-30 02:52:58 +03:00
parent 670ad3af13
commit 23d1ca3a9a
85 changed files with 2389 additions and 371 deletions

View File

@ -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;

View File

@ -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> DamageType, Actor DamageCauser);
/*
* Queries the PRI and returns our current team index.
*/

View File

@ -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<KFPawn_Monster> MyMonster;
KFGI = KFGameInfo(WorldInfo.Game);
if(KFGI != none && KFGI.OutbreakEvent != none && KFGI.OutbreakEvent.ActiveEvent.bVIPGameMode)
{
MyMonster = class<KFPawn_Monster>(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,6 +1336,9 @@ event bool FindNewEnemy()
}
BestEnemy = none;
if (BestEnemy == none)
{
foreach WorldInfo.AllPawns( class'Pawn', PotentialEnemy )
{
if( !PotentialEnemy.IsAliveAndWell() || Pawn.IsSameTeam( PotentialEnemy ) ||
@ -1339,6 +1378,8 @@ event bool FindNewEnemy()
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

View File

@ -96,6 +96,10 @@ event bool FindNewEnemy()
local Controller C;
local Pawn PotentialEnemy;
BestEnemy = none;
if (BestEnemy == none)
{
foreach WorldInfo.AllControllers( class'Controller', C )
{
if( C.Pawn == none || !C.Pawn.IsAliveAndWell() || Pawn.IsSameTeam( C.Pawn ) ||
@ -122,6 +126,7 @@ event bool FindNewEnemy()
}
}
}
}
if( Enemy != none && BestEnemy != none && BestEnemy == Enemy )
{

View File

@ -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<KFPawn_Monster>
{
local int VolumeIndex, ControllerIndex;
local Controller RateController;
local KFGameReplicationInfo KFGRI;
if( OverrideController != none )
{
@ -1250,6 +1301,13 @@ function KFSpawnVolume GetBestSpawnVolume( optional array< class<KFPawn_Monster>
// 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
}

View File

@ -19,8 +19,15 @@ var localized string FailedToReachInventoryServerString;
var localized array<string> DifficultyStrings;
var localized array<string> 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<string> ServerTypeStrings;
var localized array<string> PermissionStrings;
var localized array<string> ConsolePermissionStrings;

View File

@ -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
}

View File

@ -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;
}

View File

@ -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;

View File

@ -26,6 +26,8 @@ var class<KFDamageType> ZedativeDamageType;
var class<KFDamageType> ZedativeHealingType;
var int ZedativeEffectRadius;
var array<KFPawn_Human> AffectedHumans;
replication
{
if(bNetInitial)
@ -79,16 +81,16 @@ protected simulated function AffectsPawn(Pawn Victim, float DamageScale)
local Actor HitActor;
local bool bDamageBlocked;
if( Victim != none && Victim.IsAliveAndWell() )
{
MonsterVictim = KFPawn_Monster(Victim);
if( MonsterVictim != none )
{
if( bWasFadedOut|| bDeleteMe || bPendingDelete )
{
return;
}
if( Victim != none && Victim.IsAliveAndWell() )
{
MonsterVictim = KFPawn_Monster(Victim);
if( MonsterVictim != none )
{
Victim.GetComponentsBoundingBox(BBox);
BBoxCenter = (BBox.Min + BBox.Max) * 0.5f;
HitActor = TraceExplosive(BBoxCenter, Location + vect(0, 0, 20));
@ -109,11 +111,16 @@ protected simulated function AffectsPawn(Pawn Victim, float DamageScale)
HumanVictim = KFPawn_Human(Victim);
if( HumanVictim != none && HumanVictim.GetExposureTo(Location) > 0 )
{
if (AffectedHumans.Find(HumanVictim) == INDEX_NONE)
{
AffectedHumans.AddItem(HumanVictim);
HumanVictim.HealDamage(ZedativeHealth, InstigatorController, ZedativeHealingType, false);
}
}
}
}
}
simulated function SpawnExplosionParticleSystem(ParticleSystem Template)
{

View File

@ -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) )
{
@ -104,8 +115,19 @@ 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();
}

View File

@ -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<string> IconPathStrings )
function ShowActiveIndicators( array<ActiveSkill> ActiveSkills )
{
local byte i;
local GFxObject DataProvider;
@ -58,11 +62,14 @@ function ShowActiveIndicators( array<string> 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;
}

View File

@ -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<InventoryHelper> SkinListWeaponsSearchCache;
var array<InventoryHelper> SkinListOrderedCache;
var bool NeedToRegenerateSkinList;
struct ByTypeItemsHelper
{
var() array<InventoryHelper> 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<InventoryHelper> ActiveItems, ValidSkinItems, FailedSkinItems;
local ByTypeItemsHelper ByTypeItems[7];
local InventoryHelper HelperItem;
local array<ExchangeRuleSets> ExchangeRules;
local class<KFWeaponDefinition> 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,20 +362,23 @@ 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);
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;
@ -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;
}
}
for (i = 0; i < SkinListOrderedCache.length; i++)
if (CurrentInventoryFilter == EInv_All || CurrentInventoryFilter == EInv_Consumables)
{
ItemArray.SetElementObject(i, SkinListOrderedCache[i].GfxItemObject);
}
// 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
{
for (i = 0; i < ActiveItems.length; i++)
ByTypeItems[ITP_KeyCrate].ItemsOnType[i].IsKey = false;
}
}
ByTypeItems[ITP_KeyCrate].ItemsOnType.Sort(SortItemList);
}
//`Log("--------------------------------");
z = 0;
for (i = 0; i < ArrayCount(ByTypeItems); i++)
{
ItemArray.SetElementObject(i, ActiveItems[i].GfxItemObject);
for (j = 0 ; j < ByTypeItems[i].ItemsOnType.Length; j++)
{
ItemArray.SetElementObject(z, ByTypeItems[i].ItemsOnType[j].GfxItemObject);
++z;
}
}

View File

@ -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"

View File

@ -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<string> 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'))

View File

@ -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");

View File

@ -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
}

View File

@ -70,17 +70,24 @@ 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);
@ -91,7 +98,11 @@ function SetPerkList()
PerkObject.SetInt("perkXP", PerkPercent);
DataProvider.SetElementObject(i, PerkObject);
PerkObject.SetInt("perkIndex", i);
DataProvider.SetElementObject(counter, PerkObject);
++counter;
}
SetObject("perkList", DataProvider);

View File

@ -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
**********************************************/

View File

@ -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;

View File

@ -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
}

View File

@ -206,7 +206,7 @@ static function class<KFGFxSpecialeventObjectivesContainer> 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';
}

View File

@ -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<PlayerReplicationInfo> 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<PlayerReplicationInfo> 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
{
@ -1372,6 +1478,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
CurrentVoiceCommsHighlightAlpha=255

View File

@ -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 )

View File

@ -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,6 +324,14 @@ 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
{
@ -409,4 +444,8 @@ defaultproperties
LaserDotLerpEndDistance=6000.f
LaserDotMaxScale=10.f
LaserDotDepthBias=0.95f
IsVisible=true
bForceDotToMatch=false
}

View File

@ -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 )
@ -280,9 +283,18 @@ static function string GetMessageString(int Switch, optional out String Secondar
return default.YouWonMessage;
case GMT_MatchLost:
if(class'WorldInfo'.static.GetWorldInfo().NetMode != NM_Standalone)
{
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;
case GMT_ObjectiveStart:

View File

@ -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"))
}

View File

@ -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,13 +2097,14 @@ 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
@ -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

View File

@ -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)))
}

View File

@ -450,6 +450,11 @@ struct WeeklyOverrides
/** Information about each level in Gun Game Mode */
var() GunGamePerkData GunGamePerksData;
/** VIP targetting */
var() const array< class<KFPawn_Monster> > 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;
}
};

View File

@ -178,6 +178,10 @@ struct native DamageInfo
var array<class<KFDamageType> > 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<DamageInfo> 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<KFDamageType>(DamageType), DamageCauser);
HandleAfflictionsOnHit(InstigatedBy, Normal(Momentum), class<KFDamageType>(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<KFDamageType>(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<KFDamageType> DamageType )
{
local DamageInfo Info;
@ -2943,6 +2994,26 @@ function UpdateDamageHistory( Controller DamagerController, int Damage, Actor Da
DamageHistory[KFAIC.CurrentEnemysHistoryIndex].Damage = 0;
}
// If we have a forced Enemy break it only if we fulfill the minimum health value
if (KFAIC.ForcedEnemy != none)
{
if (GetHealthPercentage() < KFAIC.DamageRatioToChangeForcedEnemy)
{
// 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
{
if (KFAIC.IsAggroEnemySwitchAllowed()
&& DamagerController.Pawn != KFAIC.Enemy
&& Info.Damage >= DamageThreshold
@ -2960,6 +3031,7 @@ function UpdateDamageHistory( Controller DamagerController, int Damage, Actor Da
}
}
}
}
else
{
UpdateDamageHistoryValues( DamagerController, Damage, DamageCauser, 0, Info, DamageType );
@ -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> DamageType, Actor DamageCauser)
function HandleAfflictionsOnHit(Controller DamageInstigator, vector HitDir, class<KFDamageType> DamageType, Actor DamageCauser)
{
//Handle afflictions
if (AfflictionHandler != None)
{
AfflictionHandler.NotifyTakeHit(DamageInstigator, HitDir, class<KFDamageType>(DamageType), DamageCauser);
AfflictionHandler.NotifyTakeHit(DamageInstigator, HitDir, DamageType, DamageCauser);
}
}
@ -4084,6 +4165,8 @@ function ApplyDamageOverTime(int Damage, Controller InstigatedBy, class<KFDamage
DoTInfo.InstigatedBy = InstigatedBy;
DoTInfo.TimeUntilNextDamage = KFDT.default.DoT_Interval;
OnStartDamageType(KFDT);
DamageOverTimeArray[DamageOverTimeArray.Length] = DoTInfo;
}
}
@ -4129,12 +4212,34 @@ function TickDamageOverTime(float DeltaTime)
// Remove damage over time elements from the array when they have timed out
if( DamageOverTimeArray[i].Duration <= 0 || DamageOverTimeArray[i].Duration < DamageOverTimeArray[i].Interval )
{
OnEndDamageType(DamageOverTimeArray[i].DamageType);
DamageOverTimeArray.Remove(i,1);
continue;
}
}
}
simulated function OnStartDamageType(class<KFDamageType> DamageType)
{
switch (DamageType.Name)
{
case 'KFDT_Toxic_HRG_Locust':
StartLocustVFX();
break;
}
}
simulated function OnEndDamageType(class<KFDamageType> 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<KFWeapon> 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
}

View File

@ -157,7 +157,16 @@ var float MinHealthPctToTriggerSurrounded;
/*********************************************************************************************
* @name Perk @ToDo: Move stuff to PRI and combine in a byte/INT
********************************************************************************************* */
var array<string> ActiveSkillIconPaths;
struct native ActiveSkill
{
var string IconPath;
var int Multiplier;
var float MaxDuration;
var float Duration;
};
var private array<ActiveSkill> 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<DamageType> 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,7 +1338,13 @@ 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> DamageType, optional TraceHitInfo HitInfo, optional Actor DamageCauser)
{
@ -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)
{
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)
{
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)
{
NotifyHealingShieldBoostBuff(HealingShield);
}
else
{
ClientNotifyHealingShieldBoostBuff(HealingShield);
}
}
simulated function ResetHealingShield()
@ -1574,11 +1631,6 @@ function float GetPerkDoTScaler( optional Controller InstigatedBy, optional clas
return DoTScaler;
}
function array<string> 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 (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)

View File

@ -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> 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
*
@ -3286,9 +3319,12 @@ simulated function PlayTakeHitEffects( vector HitDirection, vector HitLocation,
}
if ( bPlayedDeath )
{
if (DmgType.static.CanPlayDeadHitEffects())
{
PlayDeadHitEffects(HitLocation, HitDirection, HitZoneIndex, HitZoneName, HitBoneName, DmgType, bUseHitImpulse);
}
}
else
{
PlayLivingHitEffects(HitLocation, HitDirection, HitZoneIndex, HitZoneName, HitBoneName, DmgType, bUseHitImpulse);

View File

@ -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 )
{

View File

@ -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 )

View File

@ -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);
}

View File

@ -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();
@ -393,9 +393,14 @@ static function PrepareExplosive( Pawn ProjOwner, KFProjectile Proj, optional fl
{
KFPC = KFPlayerController( ProjOwner.Controller );
if( KFPC != none )
{
Proj.ExplosionTemplate.DamageRadius *= AuxRadiusMod;
if (class'KFPerk_Demolitionist'.static.ProjectileShouldExplosionChangeRadius(Proj))
{
InstigatorPerk = KFPC.GetPerk();
Proj.ExplosionTemplate.DamageRadius *= InstigatorPerk.GetAoERadiusModifier() * AuxRadiusMod;
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;

View File

@ -213,6 +213,9 @@ 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_Rifle_HRGIncision')
{
if( IsWeaponOnPerk( KFW, WeaponPerkClass, self.class ) && (KFW == none || !KFW.bNoMagazine) && !bSecondary )
{
if( IsCombatantActive() )
@ -220,6 +223,7 @@ simulated function ModifyMagSizeAndNumber( KFWeapon KFW, out int MagazineCapacit
TempCapacity += MagazineCapacity * GetSkillValue( PerkSkills[EMedicCombatant] );
}
}
}
MagazineCapacity = Round( TempCapacity );
}

View File

@ -273,14 +273,13 @@ 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) )
if( IsWeaponOnPerk( KFW, WeaponPerkClass, self.class ) && IsHighCapFuelTankActive() && (KFW == none || !KFW.bNoMagazine) )
{
TempCapacity += MagazineCapacity * GetSkillValue( PerkSkills[EFirebugHighCapFuelTank] );
}
}
MagazineCapacity = Round(TempCapacity);
}

View File

@ -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> DamageType, Actor DamageCauser, Actor DamageReceiver)
{
}
exec function GCF()
{
if ( MyGFxManager != None )

View File

@ -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> 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> 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
}

View File

@ -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
}

View File

@ -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;

View File

@ -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))))
}

View File

@ -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();
}
}
}
}

View File

@ -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.

View File

@ -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;
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;
}
if (ForceImpactSound != none)
{
ImpactSound = ForceImpactSound;
}
else
{
ImpactSound = GetImpactSound(EffectGroup, DamageCauser, P);
}
if (ShouldSetArmorValue(P, ArmorPct))
{

View File

@ -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;

View File

@ -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)}
}

View File

@ -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);
}

View File

@ -1618,7 +1618,7 @@ simulated function AttachLaserSight()
}
}
function GunGameRemove()
function RemoveGun()
{
if (Instigator != none && Instigator.InvManager != none)
{

View File

@ -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"))
}

View File

@ -27,7 +27,7 @@ var localized array<string> ModifierDescriptions;
cpptext
{
/** Num of Weekly events available */
static const int NumWeeklyEvents = 17;
static const int NumWeeklyEvents = 18;
}
DefaultProperties
{

View File

@ -242,6 +242,9 @@ function AdjustBoneDamage(out int InDamage, name BoneName, Vector DamagerSource,
{
local int ArmorZoneIdx, ModDmgMax, ModDmgRem, ObliterateDamage;
local float Modifier;
local class<KFDamageType> mykfDamageType;
mykfDamageType = class<KFDamageType>(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;
}
}
}

View File

@ -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 */

View File

@ -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

View File

@ -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'

View File

@ -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;

View File

@ -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);

View File

@ -62,7 +62,7 @@ function UpdateHealer(Optional bool bForce)
}
function ShowActiveIndicators( array<string> IconPathStrings )
function ShowActiveIndicators( array<ActiveSkill> ActiveSkills )
{
}

View File

@ -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<KFBarmwichBonfireVolume> 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

View File

@ -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> 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;
}
KFPM = KFPawn_Monster(KilledPawn);
KFPC_WS_Killer = KFPlayerController_WeeklySurvival(Killer);
KFPC_WS_Killed = KFPlayerController_WeeklySurvival(Killed);
if (OutbreakEvent.ActiveEvent.bGunGameMode)
{
// If pawn is monster increase gun game score for that monster
KFPM = KFPawn_Monster(KilledPawn);
KFPC_WS = KFPlayerController_WeeklySurvival(Killer);
if (KFPM != none && KFPC_WS != none)
if (KFPM != none && KFPC_WS_Killer != none)
{
if (KFPC_WS.Pawn.Health > 0)
if (KFPC_WS_Killer.Pawn.Health > 0)
{
KFPC_WS.GunGameData.Score += KFPM.GunGameKilledScore;
UpdateGunGameLevel(KFPC_WS);
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)
KFPC_WS = KFPlayerController_WeeklySurvival(Killed);
if (KFPC_WS != none)
// If pawn is human reset game score (we can just check Killed exists as Controller
if (KFPC_WS_Killed != none)
{
ResetGunGame(KFPC_WS);
ResetGunGame(KFPC_WS_Killed);
}
}
}
if (OutbreakEvent.ActiveEvent.bVIPGameMode)
{
if (KFPC_WS_Killed != none && KFPC_WS_Killed.VIPGameData.isVIP)
{
// 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<KFPlayerController_WeeklySurvival> 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

View File

@ -198,20 +198,33 @@ 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)
{
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)
{
if (KFGameReplicationInfo(WorldInfo.GRI).CurrentWeeklyIndex == 16)
{
return false;
}
if (KFGameReplicationInfo(WorldInfo.GRI).CurrentWeeklyIndex == 17)
{
return false;
}
}
}
return true;

View File

@ -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

View File

@ -440,7 +440,7 @@ function AdjustDamage(out int InDamage, out vector Momentum, Controller Instigat
}
}
function HandleAfflictionsOnHit(Controller DamageInstigator, vector HitDir, class<DamageType> DamageType, Actor DamageCauser)
function HandleAfflictionsOnHit(Controller DamageInstigator, vector HitDir, class<KFDamageType> DamageType, Actor DamageCauser)
{
if (ShieldHealthPctByte == 0)
{

View File

@ -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)
{

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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<Actor> 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;

View File

@ -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

View File

@ -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()

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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"