upload
This commit is contained in:
parent
670ad3af13
commit
3e3e8af04f
@ -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;
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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,45 +1336,50 @@ event bool FindNewEnemy()
|
||||
}
|
||||
|
||||
BestEnemy = none;
|
||||
foreach WorldInfo.AllPawns( class'Pawn', PotentialEnemy )
|
||||
{
|
||||
if( !PotentialEnemy.IsAliveAndWell() || Pawn.IsSameTeam( PotentialEnemy ) ||
|
||||
!PotentialEnemy.CanAITargetThisPawn(self) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
NewDist = VSizeSq( PotentialEnemy.Location - Pawn.Location );
|
||||
if( BestEnemy == none || BestDist > NewDist )
|
||||
if (BestEnemy == none)
|
||||
{
|
||||
foreach WorldInfo.AllPawns( class'Pawn', PotentialEnemy )
|
||||
{
|
||||
// New best enemies do not care about the number of zeds around us yet
|
||||
BestEnemyZedCount = INDEX_None;
|
||||
bUpdateBestEnemy = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Only update NumZedsTargetingBestEnemy if it's a new best enemy and the best enemy is further
|
||||
if(BestEnemyZedCount == INDEX_None)
|
||||
if( !PotentialEnemy.IsAliveAndWell() || Pawn.IsSameTeam( PotentialEnemy ) ||
|
||||
!PotentialEnemy.CanAITargetThisPawn(self) )
|
||||
{
|
||||
// Cache BestEnemyZedCount so we don't need to calculate it again
|
||||
BestEnemyZedCount = NumberOfZedsTargetingPawn( BestEnemy );
|
||||
continue;
|
||||
}
|
||||
|
||||
PotentialEnemyZedCount = NumberOfZedsTargetingPawn( PotentialEnemy );
|
||||
if( PotentialEnemyZedCount < BestEnemyZedCount )
|
||||
NewDist = VSizeSq( PotentialEnemy.Location - Pawn.Location );
|
||||
if( BestEnemy == none || BestDist > NewDist )
|
||||
{
|
||||
BestEnemyZedCount = PotentialEnemyZedCount;
|
||||
// New best enemies do not care about the number of zeds around us yet
|
||||
BestEnemyZedCount = INDEX_None;
|
||||
bUpdateBestEnemy = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Only update NumZedsTargetingBestEnemy if it's a new best enemy and the best enemy is further
|
||||
if(BestEnemyZedCount == INDEX_None)
|
||||
{
|
||||
// Cache BestEnemyZedCount so we don't need to calculate it again
|
||||
BestEnemyZedCount = NumberOfZedsTargetingPawn( BestEnemy );
|
||||
}
|
||||
|
||||
if( bUpdateBestEnemy )
|
||||
{
|
||||
BestEnemy = PotentialEnemy;
|
||||
BestDist = NewDist;
|
||||
bUpdateBestEnemy = false;
|
||||
PotentialEnemyZedCount = NumberOfZedsTargetingPawn( PotentialEnemy );
|
||||
if( PotentialEnemyZedCount < BestEnemyZedCount )
|
||||
{
|
||||
BestEnemyZedCount = PotentialEnemyZedCount;
|
||||
bUpdateBestEnemy = true;
|
||||
}
|
||||
}
|
||||
|
||||
if( bUpdateBestEnemy )
|
||||
{
|
||||
BestEnemy = PotentialEnemy;
|
||||
BestDist = NewDist;
|
||||
bUpdateBestEnemy = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( Enemy != none && BestEnemy != none && BestEnemy == Enemy )
|
||||
{
|
||||
return false;
|
||||
@ -1536,10 +1577,37 @@ event bool SetEnemy( Pawn NewEnemy )
|
||||
|
||||
function ChangeEnemy( Pawn NewEnemy, optional bool bCanTaunt = true )
|
||||
{
|
||||
local Pawn OldEnemy;
|
||||
local Pawn OldEnemy, NewForcedEnemy;
|
||||
|
||||
local KFGameInfo KFGI;
|
||||
|
||||
if (CanForceEnemy)
|
||||
{
|
||||
NewForcedEnemy = FindForcedEnemy();
|
||||
}
|
||||
else if (NewEnemy == LastForcedEnemy)
|
||||
{
|
||||
return; // Don't allow to change to the ForcedEnemy while we can't (we reenable that again from outside)
|
||||
}
|
||||
|
||||
if (NewForcedEnemy != none)
|
||||
{
|
||||
ForcedEnemy = NewForcedEnemy;
|
||||
|
||||
if (Enemy != ForcedEnemy)
|
||||
{
|
||||
LastForcedEnemy = ForcedEnemy;
|
||||
|
||||
ForcedEnemyLastTime = WorldInfo.TimeSeconds;
|
||||
}
|
||||
|
||||
NewEnemy = NewForcedEnemy;
|
||||
}
|
||||
else
|
||||
{
|
||||
ForcedEnemy = none;
|
||||
}
|
||||
|
||||
// gameinfo hook that calls mutator hook
|
||||
KFGI = KFGameInfo( WorldInfo.Game );
|
||||
if( KFGI != none )
|
||||
@ -7626,6 +7694,13 @@ DefaultProperties
|
||||
LastFrustrationCheckTime=0.f
|
||||
LowIntensityAttackCooldown=2.0
|
||||
//bUseOldAttackDecisions=true
|
||||
CanForceEnemy=true
|
||||
ForcedEnemy=none
|
||||
LastForcedEnemy=none
|
||||
ForcedEnemyLastTime=0.f
|
||||
DamageRatioToChangeForcedEnemy=0.5f
|
||||
TimeCanRestartForcedEnemy=10.f
|
||||
TimeCannotChangeFromForcedEnemy=10.f
|
||||
|
||||
// ---------------------------------------------
|
||||
// AI / Navigation
|
||||
|
@ -96,30 +96,35 @@ event bool FindNewEnemy()
|
||||
local Controller C;
|
||||
local Pawn PotentialEnemy;
|
||||
|
||||
foreach WorldInfo.AllControllers( class'Controller', C )
|
||||
BestEnemy = none;
|
||||
|
||||
if (BestEnemy == none)
|
||||
{
|
||||
if( C.Pawn == none || !C.Pawn.IsAliveAndWell() || Pawn.IsSameTeam( C.Pawn ) ||
|
||||
!C.Pawn.CanAITargetThisPawn(self) )
|
||||
foreach WorldInfo.AllControllers( class'Controller', C )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if( C.Pawn == none || !C.Pawn.IsAliveAndWell() || Pawn.IsSameTeam( C.Pawn ) ||
|
||||
!C.Pawn.CanAITargetThisPawn(self) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
PotentialEnemy = C.Pawn;
|
||||
NewDist = VSizeSq( PotentialEnemy.Location - Pawn.Location );
|
||||
PotentialEnemy = C.Pawn;
|
||||
NewDist = VSizeSq( PotentialEnemy.Location - Pawn.Location );
|
||||
|
||||
if( BestEnemy == none )
|
||||
{
|
||||
BestEnemy = PotentialEnemy;
|
||||
BestDist = NewDist;
|
||||
}
|
||||
|
||||
else if( BestEnemy != none )
|
||||
{
|
||||
if( (BestDist > NewDist) || (NumberOfZedsTargetingPawn( PotentialEnemy ) < NumberOfZedsTargetingPawn( BestEnemy )) )
|
||||
if( BestEnemy == none )
|
||||
{
|
||||
BestEnemy = PotentialEnemy;
|
||||
BestDist = NewDist;
|
||||
}
|
||||
|
||||
else if( BestEnemy != none )
|
||||
{
|
||||
if( (BestDist > NewDist) || (NumberOfZedsTargetingPawn( PotentialEnemy ) < NumberOfZedsTargetingPawn( BestEnemy )) )
|
||||
{
|
||||
BestEnemy = PotentialEnemy;
|
||||
BestDist = NewDist;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
36
KFGame/Classes/KFDT_Toxic_HRG_Locust.uc
Normal file
36
KFGame/Classes/KFDT_Toxic_HRG_Locust.uc
Normal file
@ -0,0 +1,36 @@
|
||||
//=============================================================================
|
||||
// KFDT_Ballistic_HRG_Locust
|
||||
//=============================================================================
|
||||
// HRG Locust bullet impact
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
class KFDT_Toxic_HRG_Locust extends KFDT_Bleeding
|
||||
abstract
|
||||
hidedropdown;
|
||||
|
||||
// Damage dealt when zeds touch each other and spread the afflictions
|
||||
var int SpreadOnTouchDamage;
|
||||
|
||||
static function int GetSpreadOnTouchDamage()
|
||||
{
|
||||
return default.SpreadOnTouchDamage;
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
DoT_Type=DOT_Bleeding
|
||||
DoT_Duration=3.0
|
||||
DoT_Interval=0.5
|
||||
DoT_DamageScale=1.0
|
||||
|
||||
BleedPower = 20
|
||||
PoisonPower = 25
|
||||
|
||||
ModifierPerkList(0)=class'KFPerk_Survivalist'
|
||||
|
||||
WeaponDef=class'KFWeapDef_HRG_Locust'
|
||||
|
||||
SpreadOnTouchDamage=40
|
||||
}
|
@ -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
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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( bWasFadedOut|| bDeleteMe || bPendingDelete )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if( Victim != none && Victim.IsAliveAndWell() )
|
||||
{
|
||||
MonsterVictim = KFPawn_Monster(Victim);
|
||||
if( MonsterVictim != none )
|
||||
{
|
||||
if( bWasFadedOut|| bDeleteMe || bPendingDelete )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Victim.GetComponentsBoundingBox(BBox);
|
||||
BBoxCenter = (BBox.Min + BBox.Max) * 0.5f;
|
||||
HitActor = TraceExplosive(BBoxCenter, Location + vect(0, 0, 20));
|
||||
@ -109,7 +111,12 @@ protected simulated function AffectsPawn(Pawn Victim, float DamageScale)
|
||||
HumanVictim = KFPawn_Human(Victim);
|
||||
if( HumanVictim != none && HumanVictim.GetExposureTo(Location) > 0 )
|
||||
{
|
||||
HumanVictim.HealDamage(ZedativeHealth, InstigatorController, ZedativeHealingType, false);
|
||||
if (AffectedHumans.Find(HumanVictim) == INDEX_NONE)
|
||||
{
|
||||
AffectedHumans.AddItem(HumanVictim);
|
||||
|
||||
HumanVictim.HealDamage(ZedativeHealth, InstigatorController, ZedativeHealingType, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -31,6 +31,10 @@ 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;
|
||||
|
||||
@ -61,6 +65,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 +116,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 +175,23 @@ 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.LookUpScale = KFPI.MouseLookUpScale;
|
||||
class'PlayerInput'.default.LookUpScale = KFPI.MouseLookUpScale;
|
||||
|
||||
KFPI.MouseLookRightScale = ControlsMenu.Manager.CachedProfile.GetDefaultFloat(KFID_MouseLookRightScale);
|
||||
ControlsMenu.Manager.CachedProfile.SetProfileSettingValueFloat(KFID_MouseLookRightScale, KFPI.MouseLookRightScale);
|
||||
KFPI.LookRightScale = KFPI.MouseLookRightScale;
|
||||
class'PlayerInput'.default.LookRightScale = KFPI.MouseLookRightScale;
|
||||
class'PlayerInput'.static.StaticSaveConfig();
|
||||
|
||||
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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,22 +362,25 @@ function InitInventory()
|
||||
{
|
||||
TempItemDetailsHolder = OnlineSub.ItemPropertiesList[ItemIndex];
|
||||
|
||||
if (((CurrentInventoryFilter == EInv_All || Int(CurrentInventoryFilter) == Int(TempItemDetailsHolder.Type)) && DoesMatchFilter(TempItemDetailsHolder)) || bool(OnlineSub.CurrentInventory[i].NewlyAdded))
|
||||
if (((CurrentInventoryFilter == EInv_All || Int(CurrentInventoryFilter) == Int(TempItemDetailsHolder.Type))
|
||||
&& DoesMatchFilter(TempItemDetailsHolder))
|
||||
|| bool(OnlineSub.CurrentInventory[i].NewlyAdded))
|
||||
{
|
||||
ItemObject = CreateObject("Object");
|
||||
HelperIndex = ActiveItems.Find('ItemDefinition', onlineSub.CurrentInventory[i].Definition);
|
||||
ItemObject = CreateObject("Object");
|
||||
HelperIndex = ByTypeItems[TempItemDetailsHolder.Type].ItemsOnType.Find('ItemDefinition', onlineSub.CurrentInventory[i].Definition);
|
||||
|
||||
if (HelperIndex == INDEX_NONE)
|
||||
{
|
||||
HelperItem.Type = TempItemDetailsHolder.Type;
|
||||
//HelperItem.FullName = TempItemDetailsHolder.Name;
|
||||
HelperItem.ItemDefinition = onlineSub.CurrentInventory[i].Definition;
|
||||
HelperItem.ItemCount = onlineSub.CurrentInventory[i].Quantity;
|
||||
|
||||
if (TempItemDetailsHolder.Type == ITP_WeaponSkin)
|
||||
{
|
||||
// Copy required stuff
|
||||
//HelperItem.FullName = TempItemDetailsHolder.Name;
|
||||
HelperItem.Rarity = TempItemDetailsHolder.Rarity;
|
||||
HelperItem.Quality = TempItemDetailsHolder.Quality;
|
||||
HelperItem.Rarity = TempItemDetailsHolder.Rarity;
|
||||
HelperItem.Quality = TempItemDetailsHolder.Quality;
|
||||
|
||||
if (bool(OnlineSub.CurrentInventory[i].NewlyAdded))
|
||||
{
|
||||
@ -397,6 +404,7 @@ function InitInventory()
|
||||
|
||||
// Get the left part of the string without the next "| "
|
||||
SearchWeaponSkinIndex = InStr(SkinType, "|");
|
||||
// Store as CRC, that speeds up comparisons later
|
||||
HelperItem.SkinType = CrC(Left(SkinType, SearchWeaponSkinIndex));
|
||||
|
||||
WeaponItemID = class'KFWeaponSkinList'.default.Skins.Find('Id', HelperItem.ItemDefinition);
|
||||
@ -406,6 +414,7 @@ function InitInventory()
|
||||
WeaponDef = class'KFWeaponSkinList'.default.Skins[WeaponItemID].WeaponDef;
|
||||
|
||||
// All Weapons start by KFGameContent.KFWeap_ Skip that prefix.
|
||||
// Store as CRC, that speeds up comparisons later
|
||||
HelperItem.WeaponDef = CrC(Mid(WeaponDef.default.WeaponClassPath, 21));
|
||||
HelperItem.Price = WeaponDef.default.BuyPrice;
|
||||
}
|
||||
@ -418,18 +427,22 @@ function InitInventory()
|
||||
SkinListWeaponsSearchCache.AddItem(HelperItem);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
HelperItem.KeyName = TempItemDetailsHolder.KeyName;
|
||||
}
|
||||
|
||||
ActiveItems.AddItem(HelperItem);
|
||||
HelperIndex = ActiveItems.length - 1;
|
||||
ByTypeItems[TempItemDetailsHolder.Type].ItemsOnType.AddItem(HelperItem);
|
||||
HelperIndex = ByTypeItems[TempItemDetailsHolder.Type].ItemsOnType.Length - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
ActiveItems[HelperIndex].ItemCount += onlineSub.CurrentInventory[i].Quantity;
|
||||
ByTypeItems[TempItemDetailsHolder.Type].ItemsOnType[HelperIndex].ItemCount += onlineSub.CurrentInventory[i].Quantity;
|
||||
}
|
||||
|
||||
OnlineSub.IsExchangeable(onlineSub.CurrentInventory[i].Definition, ExchangeRules);
|
||||
|
||||
ItemObject.SetInt("count", ActiveItems[HelperIndex].ItemCount);
|
||||
ItemObject.SetInt("count", ByTypeItems[TempItemDetailsHolder.Type].ItemsOnType[HelperIndex].ItemCount);
|
||||
ItemObject.SetString("label", TempItemDetailsHolder.Name);
|
||||
ItemObject.SetString("price", TempItemDetailsHolder.price);
|
||||
ItemObject.Setstring("typeRarity", TempItemDetailsHolder.ShortDescription);
|
||||
@ -445,7 +458,7 @@ function InitInventory()
|
||||
ItemObject.SetInt("definition", TempItemDetailsHolder.Definition);
|
||||
ItemObject.SetBool("newlyAdded", bool(OnlineSub.CurrentInventory[i].NewlyAdded) );
|
||||
|
||||
ActiveItems[HelperIndex].GfxItemObject = ItemObject;
|
||||
ByTypeItems[TempItemDetailsHolder.Type].ItemsOnType[HelperIndex].GfxItemObject = ItemObject;
|
||||
|
||||
if(onlineSub.CurrentInventory[i].Definition == Manager.SelectIDOnOpen)
|
||||
{
|
||||
@ -465,86 +478,84 @@ function InitInventory()
|
||||
|
||||
OnlineSub.ClearNewlyAdded();
|
||||
|
||||
if (CurrentInventoryFilter == EInv_WeaponSkins)
|
||||
if (CurrentInventoryFilter == EInv_All || CurrentInventoryFilter == EInv_WeaponSkins)
|
||||
{
|
||||
// If need to refresh... we regenerate the list, if not reuse our Cache
|
||||
NeedToRegenerateSkinList = NeedToRegenerateSkinList || ActiveItems.Length != SkinListOrderedCache.Length;
|
||||
NeedToRegenerateSkinList = NeedToRegenerateSkinList || ByTypeItems[ITP_WeaponSkin].ItemsOnType.Length != SkinListOrderedCache.Length;
|
||||
|
||||
if (NeedToRegenerateSkinList)
|
||||
{
|
||||
NeedToRegenerateSkinList = false;
|
||||
|
||||
/*`Log("START ORDERING!!!");
|
||||
`Log("----------");*/
|
||||
|
||||
for (i = 0 ; i < ActiveItems.Length; i++)
|
||||
{
|
||||
// If doesn't have weapon definition, don't consider, only add as FailedItem to be added at the end
|
||||
if (ActiveItems[i].WeaponDef != -1)
|
||||
{
|
||||
ValidSkinItems.AddItem(ActiveItems[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
FailedSkinItems.AddItem(ActiveItems[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Now we have all valid weapons
|
||||
|
||||
// We want to order by Price - Weapon Def - Rarity - Quality
|
||||
// So we order inverse that way we keep the final list with the design intention
|
||||
|
||||
ValidSkinItems.Sort(SortByAll);
|
||||
ByTypeItems[ITP_WeaponSkin].ItemsOnType.Sort(SortSkinList);
|
||||
|
||||
SkinListOrderedCache = ValidSkinItems;
|
||||
SkinListOrderedCache = ByTypeItems[ITP_WeaponSkin].ItemsOnType;
|
||||
|
||||
/*`Log("----------");*/
|
||||
|
||||
/*for (i = 0 ; i < SkinListOrderedCache.Length; i++)
|
||||
{
|
||||
`Log("ID : " $SkinListOrderedCache[i].ItemDefinition);
|
||||
`Log("Weapon Def : " $SkinListOrderedCache[i].WeaponDef);
|
||||
`Log("Price : " $SkinListOrderedCache[i].Price);
|
||||
//`Log("Full Name : " $SkinListOrderedCache[i].FullName);
|
||||
`Log("Full Name : " $SkinListOrderedCache[i].FullName);
|
||||
`Log("Skin : " $SkinListOrderedCache[i].SkinType);
|
||||
`Log("Rarity : " $SkinListOrderedCache[i].Rarity);
|
||||
`Log("Quality : " $SkinListOrderedCache[i].Quality);
|
||||
`Log("----------");
|
||||
}*/
|
||||
|
||||
// FailedItems are weapons that don't have a Weapon Definition, this might be a case with old unsupported content?
|
||||
for (i = 0; i < FailedSkinItems.Length; i++)
|
||||
{
|
||||
/*if (FailedSkinItems[i].FullName != "")
|
||||
{
|
||||
`Log("FailedSkinItems ID : " $FailedSkinItems[i].ItemDefinition);
|
||||
`Log("FailedSkinItems Price : " $FailedSkinItems[i].Price);
|
||||
`Log("FailedSkinItems Full Name : " $FailedSkinItems[i].FullName);
|
||||
`Log("FailedSkinItems Skin : " $FailedSkinItems[i].SkinType);
|
||||
`Log("FailedSkinItems Rarity : " $FailedSkinItems[i].Rarity);
|
||||
`Log("FailedFailedSkinItemsItems Quality : " $FailedSkinItems[i].Quality);
|
||||
`Log("----------");
|
||||
}*/
|
||||
|
||||
SkinListOrderedCache.AddItem(FailedSkinItems[i]);
|
||||
}
|
||||
|
||||
/*`Log("FINISH ORDERING!!!");
|
||||
`Log("----------");*/
|
||||
}
|
||||
else
|
||||
{
|
||||
//`Log("USING SKIN LIST CACHE!!!");
|
||||
}
|
||||
|
||||
for (i = 0; i < SkinListOrderedCache.length; i++)
|
||||
{
|
||||
ItemArray.SetElementObject(i, SkinListOrderedCache[i].GfxItemObject);
|
||||
ByTypeItems[ITP_WeaponSkin].ItemsOnType = SkinListOrderedCache;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
if (CurrentInventoryFilter == EInv_All || CurrentInventoryFilter == EInv_Consumables)
|
||||
{
|
||||
for (i = 0; i < ActiveItems.length; i++)
|
||||
// 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++)
|
||||
{
|
||||
ItemArray.SetElementObject(i, ActiveItems[i].GfxItemObject);
|
||||
// KeyName is something like : "NameItem:KeyCrate", we first remove the part from the : to the right
|
||||
SearchKeyKeywordIndex = InStr(ByTypeItems[ITP_KeyCrate].ItemsOnType[i].KeyName, ":");
|
||||
ByTypeItems[ITP_KeyCrate].ItemsOnType[i].KeyName = Left(ByTypeItems[ITP_KeyCrate].ItemsOnType[i].KeyName, SearchKeyKeywordIndex);
|
||||
|
||||
// Then we search if the name of the Item contains "Key"
|
||||
SearchKeyKeywordIndex = InStr(ByTypeItems[ITP_KeyCrate].ItemsOnType[i].KeyName, "Key");
|
||||
|
||||
if (SearchKeyKeywordIndex != -1)
|
||||
{
|
||||
ByTypeItems[ITP_KeyCrate].ItemsOnType[i].IsKey = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ByTypeItems[ITP_KeyCrate].ItemsOnType[i].IsKey = false;
|
||||
}
|
||||
}
|
||||
|
||||
ByTypeItems[ITP_KeyCrate].ItemsOnType.Sort(SortItemList);
|
||||
}
|
||||
|
||||
//`Log("--------------------------------");
|
||||
|
||||
z = 0;
|
||||
|
||||
for (i = 0; i < ArrayCount(ByTypeItems); i++)
|
||||
{
|
||||
for (j = 0 ; j < ByTypeItems[i].ItemsOnType.Length; j++)
|
||||
{
|
||||
ItemArray.SetElementObject(z, ByTypeItems[i].ItemsOnType[j].GfxItemObject);
|
||||
|
||||
++z;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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,55 @@ function CallBack_ResetInputOptions()
|
||||
}
|
||||
}
|
||||
|
||||
function Callback_MouseLookUpScale(float NewValue)
|
||||
{
|
||||
local KFPlayerInput KFPI;
|
||||
|
||||
NewValue = -NewValue;
|
||||
|
||||
KFPI = KFPlayerInput(GetPC().PlayerInput);
|
||||
KFPI.MouseLookUpScale = NewValue;
|
||||
KFPI.LookUpScale = NewValue;
|
||||
class'PlayerInput'.default.LookUpScale = KFPI.MouseLookUpScale;
|
||||
class'PlayerInput'.static.StaticSaveConfig();
|
||||
|
||||
Manager.CachedProfile.SetProfileSettingValueFloat(KFID_MouseLookUpScale, NewValue);
|
||||
}
|
||||
|
||||
function Callback_MouseLookRightScale(float NewValue)
|
||||
{
|
||||
local KFPlayerInput KFPI;
|
||||
|
||||
KFPI = KFPlayerInput(GetPC().PlayerInput);
|
||||
KFPI.MouseLookRightScale = NewValue;
|
||||
KFPI.LookRightScale = NewValue;
|
||||
class'PlayerInput'.default.LookRightScale = KFPI.MouseLookRightScale;
|
||||
class'PlayerInput'.static.StaticSaveConfig();
|
||||
|
||||
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 +398,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'))
|
||||
|
@ -0,0 +1,27 @@
|
||||
class KFGFXSpecialEventObjectivesContainer_Fall2022 extends KFGFxSpecialEventObjectivesContainer;
|
||||
|
||||
function Initialize(KFGFxObject_Menu NewParentMenu)
|
||||
{
|
||||
super.Initialize(NewParentMenu);
|
||||
}
|
||||
|
||||
DefaultProperties
|
||||
{
|
||||
ObjectiveIconURLs[0] = "Halloween2022_UI.UI_Objectives_Halloween2022_CreaturesInDarkness" // Kill 15 Bosses on any map or mode
|
||||
ObjectiveIconURLs[1] = "Spring_UI.UI_Objectives_Spring_Weekly" // Complete the Weekly on BarmwichTown
|
||||
ObjectiveIconURLs[2] = "Halloween2022_UI.UI_Objetives_Halloween2022_ElementalMedallions" // Open the Weapon Room
|
||||
ObjectiveIconURLs[3] = "Halloween2022_UI.UI_Objectives_Halloween2022_ZedOnFire" // Make 50 Zeds to pass through the bonfires of Barmwitch Town
|
||||
ObjectiveIconURLs[4] = "Halloween2022_UI.UI_Objetives_Halloween2022_LongNightofWitches" // Complete wave 15 on Endless Hard or higher difficulty on Barmwitch Town
|
||||
|
||||
//defaults
|
||||
AllCompleteRewardIconURL="CHR_PlagueDoctorUniform_Item_TEX.potionbackpack.plaguedoctorbackpack_precious_large"
|
||||
ChanceDropIconURLs[0]="CHR_CosmeticSet14_Item_TEX.Tickets.CyberPunk_ticket"
|
||||
ChanceDropIconURLs[1]="CHR_CosmeticSet14_Item_TEX.Tickets.CyberPunk_ticket_golden"
|
||||
IconURL="halloween2022_ui.KF2_Halloween_BloodandBonfires_SmallLogo"
|
||||
|
||||
UsesProgressList[0] = true
|
||||
UsesProgressList[1] = false
|
||||
UsesProgressList[2] = false
|
||||
UsesProgressList[3] = true
|
||||
UsesProgressList[4] = false
|
||||
}
|
@ -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");
|
||||
|
@ -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
|
||||
}
|
@ -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);
|
||||
|
49
KFGame/Classes/KFGFxWidget_VIP.uc
Normal file
49
KFGame/Classes/KFGFxWidget_VIP.uc
Normal file
@ -0,0 +1,49 @@
|
||||
//=============================================================================
|
||||
// KFGFxWidget_VIP
|
||||
//=============================================================================
|
||||
// HUD Widget that displays VIP messages to the player
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
class KFGFxWidget_VIP extends GFxObject;
|
||||
|
||||
function SetVIP()
|
||||
{
|
||||
SetString("VIPSetLocalised", Class'KFCommon_LocalizedStrings'.default.VIPString);
|
||||
SetString("VIPObjectiveSetLocalised", Class'KFCommon_LocalizedStrings'.default.VIPObjectiveBString);
|
||||
SetString("VIPPlayerSet", Class'KFCommon_LocalizedStrings'.default.VIPObjectiveCString);
|
||||
|
||||
SetBool("VIPPlayerNameSetVisibility", true);
|
||||
SetBool("VIPHideHealthBar", true);
|
||||
}
|
||||
|
||||
function SetNOVIP(string VIPPlayerName, int VIPCurrentHealth, int VIPMaxHealth)
|
||||
{
|
||||
SetString("VIPSetLocalised", Class'KFCommon_LocalizedStrings'.default.VIPString);
|
||||
SetString("VIPObjectiveSetLocalised", Class'KFCommon_LocalizedStrings'.default.VIPObjectiveAString);
|
||||
SetString("VIPPlayerSet", VIPPlayerName);
|
||||
|
||||
SetBool("VIPPlayerNameSetVisibility", true);
|
||||
|
||||
UpdateHealth(VIPCurrentHealth, VIPMaxHealth);
|
||||
}
|
||||
|
||||
function UpdateVIPVisibility(bool visible)
|
||||
{
|
||||
if (visible)
|
||||
{
|
||||
SetBool("VIPSetVisibility", true);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetBool("VIPSetVisibility", false);
|
||||
}
|
||||
}
|
||||
|
||||
function UpdateHealth(int VIPCurrentHealth, int VIPMaxHealth)
|
||||
{
|
||||
SetFloat("VIPHealthBarPercentage", VIPMaxHealth != 0 ? (float(VIPCurrentHealth) / VIPMaxHealth) : 0.0f);
|
||||
}
|
@ -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
|
||||
**********************************************/
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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';
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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 )
|
||||
|
@ -57,6 +57,8 @@ var() float AnimBlendRate;
|
||||
var transient float LaserSightAimStrength;
|
||||
var transient float DesiredAimStrength;
|
||||
|
||||
var transient bool IsVisible;
|
||||
|
||||
/** Create/Attach lasersight components */
|
||||
function AttachLaserSight(SkeletalMeshComponent OwnerMesh, bool bFirstPerson, optional name SocketNameOverride)
|
||||
{
|
||||
@ -135,6 +137,8 @@ simulated function SetMeshLightingChannels(LightingChannelContainer NewLightingC
|
||||
|
||||
simulated event ChangeVisibility(bool bVisible)
|
||||
{
|
||||
IsVisible = bVisible;
|
||||
|
||||
LaserDotMeshComp.SetHidden(!bVisible);
|
||||
LaserSightMeshComp.SetHidden(!bVisible);
|
||||
LaserBeamMeshComp.SetHidden(!bVisible);
|
||||
@ -159,6 +163,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 &&
|
||||
@ -409,4 +418,6 @@ defaultproperties
|
||||
LaserDotLerpEndDistance=6000.f
|
||||
LaserDotMaxScale=10.f
|
||||
LaserDotDepthBias=0.95f
|
||||
|
||||
IsVisible=true
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ var localized string ScavengeMessage;
|
||||
var localized string YouLostMessage;
|
||||
var localized string YouWonMessage;
|
||||
var localized string SquadWipedOutMessage;
|
||||
var localized string SquadWipedOutVIPMessage;
|
||||
var localized string SquadSurvivedMessage;
|
||||
var localized string ObjectiveStartMessage;
|
||||
var localized string ObjectiveWonMessage;
|
||||
@ -231,6 +232,8 @@ static function ClientReceive(
|
||||
|
||||
static function string GetMessageString(int Switch, optional out String SecondaryString, optional byte TeamIndex)
|
||||
{
|
||||
local KFGameReplicationInfo KFGRI;
|
||||
|
||||
SecondaryString = "";
|
||||
|
||||
switch ( Switch )
|
||||
@ -281,7 +284,16 @@ static function string GetMessageString(int Switch, optional out String Secondar
|
||||
case GMT_MatchLost:
|
||||
if(class'WorldInfo'.static.GetWorldInfo().NetMode != NM_Standalone)
|
||||
{
|
||||
SecondaryString = default.SquadWipedOutMessage;
|
||||
KFGRI = KFGameReplicationInfo(class'WorldInfo'.static.GetWorldInfo().GRI);
|
||||
|
||||
if (KFGRI != none && KFGRI.bIsWeeklyMode && KFGRI.CurrentWeeklyIndex == 17)
|
||||
{
|
||||
SecondaryString = default.SquadWipedOutVIPMessage;
|
||||
}
|
||||
else
|
||||
{
|
||||
SecondaryString = default.SquadWipedOutMessage;
|
||||
}
|
||||
}
|
||||
|
||||
return default.YouLostMessage;
|
||||
|
@ -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"))
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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)))
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
@ -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,19 +2994,40 @@ function UpdateDamageHistory( Controller DamagerController, int Damage, Actor Da
|
||||
DamageHistory[KFAIC.CurrentEnemysHistoryIndex].Damage = 0;
|
||||
}
|
||||
|
||||
if( KFAIC.IsAggroEnemySwitchAllowed()
|
||||
&& DamagerController.Pawn != KFAIC.Enemy
|
||||
&& Info.Damage >= DamageThreshold
|
||||
&& Info.Damage > DamageHistory[KFAIC.CurrentEnemysHistoryIndex].Damage )
|
||||
// If we have a forced Enemy break it only if we fulfill the minimum health value
|
||||
if (KFAIC.ForcedEnemy != none)
|
||||
{
|
||||
BlockerPawn = KFAIC.GetPawnBlockingPathTo( DamagerController.Pawn, true );
|
||||
if( BlockerPawn == none )
|
||||
if (GetHealthPercentage() < KFAIC.DamageRatioToChangeForcedEnemy)
|
||||
{
|
||||
bChangedEnemies = KFAIC.SetEnemy(DamagerController.Pawn);
|
||||
// Only if X seconds passed since last time we choose the ForcedEnemy
|
||||
if ((WorldInfo.TimeSeconds - KFAIC.ForcedEnemyLastTime) > KFAIC.TimeCannotChangeFromForcedEnemy)
|
||||
{
|
||||
KFAIC.CanForceEnemy = false; // The timer we will reenable this to allow selection again
|
||||
|
||||
// If we have forced enemy, reactivate ForcedEnemy after X seconds, so it can default to the ForcedEnemy again
|
||||
ClearTimer('TimerRestartForceEnemy');
|
||||
SetTimer(KFAIC.TimeCanRestartForcedEnemy, false, 'TimerRestartForceEnemy');
|
||||
|
||||
KFAIC.ChangeEnemy(DamagerController.Pawn);
|
||||
}
|
||||
}
|
||||
else
|
||||
}
|
||||
else
|
||||
{
|
||||
if (KFAIC.IsAggroEnemySwitchAllowed()
|
||||
&& DamagerController.Pawn != KFAIC.Enemy
|
||||
&& Info.Damage >= DamageThreshold
|
||||
&& Info.Damage > DamageHistory[KFAIC.CurrentEnemysHistoryIndex].Damage)
|
||||
{
|
||||
bChangedEnemies = KFAIC.SetEnemy( BlockerPawn );
|
||||
BlockerPawn = KFAIC.GetPawnBlockingPathTo( DamagerController.Pawn, true );
|
||||
if( BlockerPawn == none )
|
||||
{
|
||||
bChangedEnemies = KFAIC.SetEnemy(DamagerController.Pawn);
|
||||
}
|
||||
else
|
||||
{
|
||||
bChangedEnemies = KFAIC.SetEnemy( BlockerPawn );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3403,6 +3475,8 @@ simulated function bool IsHeadless();
|
||||
/** Clean up function to terminate any effects on death */
|
||||
simulated function TerminateEffectsOnDeath()
|
||||
{
|
||||
local int i;
|
||||
|
||||
// Destroy our weapon attachment
|
||||
if( WeaponAttachment != None && !WeaponAttachment.bPendingDelete )
|
||||
{
|
||||
@ -3420,11 +3494,18 @@ simulated function TerminateEffectsOnDeath()
|
||||
|
||||
AfflictionHandler.Shutdown();
|
||||
|
||||
StopLocustVFX();
|
||||
|
||||
// send a special stop event to the audio system
|
||||
if ( SoundGroupArch.OnDeathStopEvent != None )
|
||||
{
|
||||
PostAkEvent( SoundGroupArch.OnDeathStopEvent );
|
||||
}
|
||||
|
||||
for (i = 0 ; i < DamageOverTimeArray.Length; i++)
|
||||
{
|
||||
OnEndDamageType(DamageOverTimeArray[i].DamageType);
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************************************
|
||||
@ -4043,12 +4124,12 @@ simulated function KFSkinTypeEffects GetHitZoneSkinTypeEffects( int HitZoneIdx )
|
||||
*/
|
||||
simulated function AdjustAffliction(out float AfflictionPower);
|
||||
|
||||
function HandleAfflictionsOnHit(Controller DamageInstigator, vector HitDir, class<DamageType> 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
|
||||
}
|
||||
|
@ -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,8 +1338,14 @@ function AdjustDamage(out int InDamage, out vector Momentum, Controller Instigat
|
||||
}
|
||||
}
|
||||
`endif
|
||||
|
||||
if (KFPlayerController_WeeklySurvival(Controller) != none)
|
||||
{
|
||||
KFPlayerController_WeeklySurvival(Controller).UpdateVIPDamage();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
event TakeDamage(int Damage, Controller InstigatedBy, vector HitLocation, vector Momentum, class<DamageType> DamageType, optional TraceHitInfo HitInfo, optional Actor DamageCauser)
|
||||
{
|
||||
local int ActualDamageTaken, OldHealth, OldArmor;
|
||||
@ -1451,12 +1493,17 @@ function StartAirBorneAgentEvent()
|
||||
simulated function UpdateHealingSpeedBoost()
|
||||
{
|
||||
HealingSpeedBoost = Min( HealingSpeedBoost + class'KFPerk_FieldMedic'.static.GetHealingSpeedBoost(), class'KFPerk_FieldMedic'.static.GetMaxHealingSpeedBoost() );
|
||||
|
||||
SetTimer( class'KFPerk_FieldMedic'.static.GetHealingSpeedBoostDuration(),, nameOf(ResetHealingSpeedBoost) );
|
||||
|
||||
if ( WorldInfo.NetMode == NM_STANDALONE)
|
||||
if (WorldInfo.NetMode == NM_STANDALONE)
|
||||
{
|
||||
NotifyHealingSpeedBoostBuff(HealingSpeedBoost);
|
||||
}
|
||||
else
|
||||
{
|
||||
ClientNotifyHealingSpeedBoostBuff(HealingSpeedBoost);
|
||||
}
|
||||
}
|
||||
|
||||
simulated function ResetHealingSpeedBoost()
|
||||
@ -1482,12 +1529,17 @@ simulated function float GetHealingDamageBoostModifier()
|
||||
simulated function UpdateHealingDamageBoost()
|
||||
{
|
||||
HealingDamageBoost = Min( HealingDamageBoost + class'KFPerk_FieldMedic'.static.GetHealingDamageBoost(), class'KFPerk_FieldMedic'.static.GetMaxHealingDamageBoost() );
|
||||
|
||||
SetTimer( class'KFPerk_FieldMedic'.static.GetHealingDamageBoostDuration(),, nameOf(ResetHealingDamageBoost) );
|
||||
|
||||
if ( WorldInfo.NetMode == NM_STANDALONE)
|
||||
if (WorldInfo.NetMode == NM_STANDALONE)
|
||||
{
|
||||
NotifyHealingDamageBoostBuff(HealingDamageBoost);
|
||||
}
|
||||
else
|
||||
{
|
||||
ClientNotifyHealingDamageBoostBuff(HealingDamageBoost);
|
||||
}
|
||||
}
|
||||
|
||||
simulated function ResetHealingDamageBoost()
|
||||
@ -1513,12 +1565,17 @@ simulated function float GetHealingShieldModifier()
|
||||
simulated function UpdateHealingShield()
|
||||
{
|
||||
HealingShield = Min( HealingShield + class'KFPerk_FieldMedic'.static.GetHealingShield(), class'KFPerk_FieldMedic'.static.GetMaxHealingShield() );
|
||||
|
||||
SetTimer( class'KFPerk_FieldMedic'.static.GetHealingShieldDuration(),, nameOf(ResetHealingShield) );
|
||||
|
||||
if ( WorldInfo.NetMode == NM_STANDALONE)
|
||||
if (WorldInfo.NetMode == NM_STANDALONE)
|
||||
{
|
||||
NotifyHealingShieldBoostBuff(HealingShield);
|
||||
}
|
||||
else
|
||||
{
|
||||
ClientNotifyHealingShieldBoostBuff(HealingShield);
|
||||
}
|
||||
}
|
||||
|
||||
simulated function ResetHealingShield()
|
||||
@ -1574,11 +1631,6 @@ function float GetPerkDoTScaler( optional Controller InstigatedBy, optional clas
|
||||
return DoTScaler;
|
||||
}
|
||||
|
||||
function array<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 (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)
|
||||
|
@ -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
|
||||
*
|
||||
@ -3287,7 +3320,10 @@ simulated function PlayTakeHitEffects( vector HitDirection, vector HitLocation,
|
||||
|
||||
if ( bPlayedDeath )
|
||||
{
|
||||
PlayDeadHitEffects(HitLocation, HitDirection, HitZoneIndex, HitZoneName, HitBoneName, DmgType, bUseHitImpulse);
|
||||
if (DmgType.static.CanPlayDeadHitEffects())
|
||||
{
|
||||
PlayDeadHitEffects(HitLocation, HitDirection, HitZoneIndex, HitZoneName, HitBoneName, DmgType, bUseHitImpulse);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -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 )
|
||||
{
|
||||
|
@ -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 )
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -380,7 +380,7 @@ static function PrepareExplosive( Pawn ProjOwner, KFProjectile Proj, optional fl
|
||||
Proj.ExplosionTemplate.DamageRadius = Proj.default.ExplosionTemplate.DamageRadius * class'KFPerk_Demolitionist'.static.GetNukeRadiusModifier() * AuxRadiusMod;
|
||||
Proj.ExplosionTemplate.DamageFalloffExponent = Proj.default.ExplosionTemplate.DamageFalloffExponent;
|
||||
}
|
||||
else if( InstigatorPRI.bConcussiveActive && Proj.AltExploEffects != none )
|
||||
else if( InstigatorPRI.bConcussiveActive && Proj.AltExploEffects != none && class'KFPerk_Demolitionist'.static.ProjectileShouldConcussive(Proj) )
|
||||
{
|
||||
Proj.ExplosionTemplate.ExplosionEffects = Proj.AltExploEffects;
|
||||
Proj.ExplosionTemplate.ExplosionSound = class'KFPerk_Demolitionist'.static.GetConcussiveExplosionSound();
|
||||
@ -394,8 +394,13 @@ static function PrepareExplosive( Pawn ProjOwner, KFProjectile Proj, optional fl
|
||||
KFPC = KFPlayerController( ProjOwner.Controller );
|
||||
if( KFPC != none )
|
||||
{
|
||||
InstigatorPerk = KFPC.GetPerk();
|
||||
Proj.ExplosionTemplate.DamageRadius *= InstigatorPerk.GetAoERadiusModifier() * AuxRadiusMod;
|
||||
Proj.ExplosionTemplate.DamageRadius *= AuxRadiusMod;
|
||||
|
||||
if (class'KFPerk_Demolitionist'.static.ProjectileShouldExplosionChangeRadius(Proj))
|
||||
{
|
||||
InstigatorPerk = KFPC.GetPerk();
|
||||
Proj.ExplosionTemplate.DamageRadius *= InstigatorPerk.GetAoERadiusModifier();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -686,6 +691,16 @@ simulated static function bool ProjectileShouldNuke( KFProjectile Proj )
|
||||
return Proj.AllowNuke();
|
||||
}
|
||||
|
||||
simulated static function bool ProjectileShouldConcussive( KFProjectile Proj )
|
||||
{
|
||||
return Proj.AllowDemolitionistConcussive();
|
||||
}
|
||||
|
||||
simulated static function bool ProjectileShouldExplosionChangeRadius( KFProjectile Proj )
|
||||
{
|
||||
return Proj.AllowDemolitionistExplosionChangeRadius();
|
||||
}
|
||||
|
||||
simulated function bool DoorShouldNuke()
|
||||
{
|
||||
return IsNukeActive() && WorldInfo.TimeDilation < 1.f;
|
||||
|
@ -213,11 +213,15 @@ simulated function ModifyMagSizeAndNumber( KFWeapon KFW, out int MagazineCapacit
|
||||
|
||||
TempCapacity = MagazineCapacity;
|
||||
|
||||
if( IsWeaponOnPerk( KFW, WeaponPerkClass, self.class ) && (KFW == none || !KFW.bNoMagazine) && !bSecondary )
|
||||
// Fix this function on the trader because KFW is None and the check cannot look for bNoMagazine = true
|
||||
if(WeaponClassname != 'KFWeap_Rifle_HRGIncision')
|
||||
{
|
||||
if( IsCombatantActive() )
|
||||
if( IsWeaponOnPerk( KFW, WeaponPerkClass, self.class ) && (KFW == none || !KFW.bNoMagazine) && !bSecondary )
|
||||
{
|
||||
TempCapacity += MagazineCapacity * GetSkillValue( PerkSkills[EMedicCombatant] );
|
||||
if( IsCombatantActive() )
|
||||
{
|
||||
TempCapacity += MagazineCapacity * GetSkillValue( PerkSkills[EMedicCombatant] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -273,13 +273,12 @@ simulated function ModifyMagSizeAndNumber( KFWeapon KFW, out int MagazineCapacit
|
||||
TempCapacity = MagazineCapacity;
|
||||
|
||||
// Fix this function on the trader because KFW is None and the check cannot look for bNoMagazine = true
|
||||
if(WeaponClassname == 'KFWeap_Pistol_HRGScorcher')
|
||||
if(WeaponClassname != 'KFWeap_Pistol_HRGScorcher' && WeaponClassname != 'KFWeap_HRG_Dragonbreath')
|
||||
{
|
||||
TempCapacity = TempCapacity;
|
||||
}
|
||||
else if( IsWeaponOnPerk( KFW, WeaponPerkClass, self.class ) && IsHighCapFuelTankActive() && (KFW == none || !KFW.bNoMagazine) )
|
||||
{
|
||||
TempCapacity += MagazineCapacity * GetSkillValue( PerkSkills[EFirebugHighCapFuelTank] );
|
||||
if( IsWeaponOnPerk( KFW, WeaponPerkClass, self.class ) && IsHighCapFuelTankActive() && (KFW == none || !KFW.bNoMagazine) )
|
||||
{
|
||||
TempCapacity += MagazineCapacity * GetSkillValue( PerkSkills[EFirebugHighCapFuelTank] );
|
||||
}
|
||||
}
|
||||
|
||||
MagazineCapacity = Round(TempCapacity);
|
||||
|
@ -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 )
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -241,6 +241,12 @@ var bool bVersusInput;
|
||||
/** Cached value of bUsingGamepad so we can handle button releases across devices */
|
||||
var bool bUsingVersusGamepadScheme;
|
||||
|
||||
/*********************************************************************************************
|
||||
* @name QoL: Mouse input options
|
||||
********************************************************************************************* */
|
||||
var float MouseLookUpScale;
|
||||
var float MouseLookRightScale;
|
||||
|
||||
cpptext
|
||||
{
|
||||
/** Searches the bind and skips the mainCommand */
|
||||
@ -405,6 +411,7 @@ function EDoubleClickDir CheckForDoubleClickMove(float DeltaTime)
|
||||
event PlayerInput( float DeltaTime )
|
||||
{
|
||||
local float FOVScale, TimeScale;
|
||||
local float MouseYScale, MouseXScale;
|
||||
local vector RawJoyVector;
|
||||
|
||||
// Save Raw values
|
||||
@ -437,8 +444,12 @@ event PlayerInput( float DeltaTime )
|
||||
aBaseY *= TimeScale * MoveForwardSpeed;
|
||||
aStrafe *= TimeScale * MoveStrafeSpeed;
|
||||
aUp *= TimeScale * MoveStrafeSpeed;
|
||||
aTurn *= TimeScale * LookRightScale;
|
||||
aLookUp *= TimeScale * LookUpScale;
|
||||
|
||||
if (class'WorldInfo'.static.IsConsoleBuild() || bUsingGamepad)
|
||||
{
|
||||
aTurn *= TimeScale * LookRightScale;
|
||||
aLookUp *= TimeScale * LookUpScale;
|
||||
}
|
||||
|
||||
PostProcessInput( DeltaTime );
|
||||
|
||||
@ -462,14 +473,16 @@ event PlayerInput( float DeltaTime )
|
||||
aLookUp *= FOVScale;
|
||||
aTurn *= FOVScale;
|
||||
|
||||
MouseXScale = (TimeScale * -MouseLookUpScale / 100.0f);
|
||||
// Turning and strafing share the same axis.
|
||||
if( bStrafe > 0 )
|
||||
aStrafe += aBaseX + aMouseX;
|
||||
aStrafe += aBaseX + aMouseX * ( MouseXScale > 0.0f ? MouseXScale : 1.0f);
|
||||
else
|
||||
aTurn += aBaseX + aMouseX;
|
||||
aTurn += aBaseX + aMouseX * ( MouseXScale > 0.0f ? MouseXScale : 1.0f);
|
||||
|
||||
// Look up/down.
|
||||
aLookup += aMouseY;
|
||||
MouseYScale = (TimeScale * -MouseLookUpScale / 100.0f);
|
||||
aLookup += aMouseY * ( MouseYScale > 0.0f ? MouseYScale : 1.0f);
|
||||
if ( (!bUsingGamepad && bInvertMouse) || (bInvertController && bUsingGamepad) )
|
||||
{
|
||||
aLookup *= -1.f;
|
||||
|
@ -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;
|
||||
|
@ -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))))
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -85,13 +85,20 @@ cpptext
|
||||
virtual void PostLoad();
|
||||
}
|
||||
|
||||
function PlayImpactParticleEffect(
|
||||
KFPawn P, vector HitLocation, vector HitDirection, byte HitZoneIndex, EEffectDamageGroup EffectGroup)
|
||||
function PlayImpactParticleEffect(KFPawn P, vector HitLocation, vector HitDirection, byte HitZoneIndex, EEffectDamageGroup EffectGroup, optional ParticleSystem ForceParticleTemplate)
|
||||
{
|
||||
local ParticleSystem ParticleTemplate;
|
||||
local name HitBoneName;
|
||||
|
||||
ParticleTemplate = GetImpactParticleEffect(EffectGroup);
|
||||
if (ForceParticleTemplate != none)
|
||||
{
|
||||
ParticleTemplate = ForceParticleTemplate;
|
||||
}
|
||||
else
|
||||
{
|
||||
ParticleTemplate = GetImpactParticleEffect(EffectGroup);
|
||||
}
|
||||
|
||||
if (ParticleTemplate == None)
|
||||
{
|
||||
return;
|
||||
@ -212,7 +219,7 @@ function ParticleSystem GetImpactParticleEffect(EEffectDamageGroup EffectGroup)
|
||||
}
|
||||
|
||||
/** Play an impact sound on taking damage */
|
||||
function PlayTakeHitSound(KFPawn P, vector HitLocation, Pawn DamageCauser, EEffectDamageGroup EffectGroup)
|
||||
function PlayTakeHitSound(KFPawn P, vector HitLocation, Pawn DamageCauser, EEffectDamageGroup EffectGroup, optional AKEvent ForceImpactSound)
|
||||
{
|
||||
local AKEvent ImpactSound;
|
||||
local float ArmorPct;
|
||||
@ -225,7 +232,14 @@ function PlayTakeHitSound(KFPawn P, vector HitLocation, Pawn DamageCauser, EEffe
|
||||
return;
|
||||
}
|
||||
|
||||
ImpactSound = GetImpactSound(EffectGroup, DamageCauser, P);
|
||||
if (ForceImpactSound != none)
|
||||
{
|
||||
ImpactSound = ForceImpactSound;
|
||||
}
|
||||
else
|
||||
{
|
||||
ImpactSound = GetImpactSound(EffectGroup, DamageCauser, P);
|
||||
}
|
||||
|
||||
if (ShouldSetArmorValue(P, ArmorPct))
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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)}
|
||||
}
|
||||
|
29
KFGame/Classes/KFWeapDef_G36C.uc
Normal file
29
KFGame/Classes/KFWeapDef_G36C.uc
Normal file
@ -0,0 +1,29 @@
|
||||
//=============================================================================
|
||||
// KFWeaponDefintion
|
||||
//=============================================================================
|
||||
// A lightweight container for basic weapon properties that can be safely
|
||||
// accessed without a weapon actor (UI, remote clients).
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
class KFWeapDef_G36C extends KFWeaponDefinition
|
||||
abstract;
|
||||
|
||||
DefaultProperties
|
||||
{
|
||||
WeaponClassPath="KFGameContent.KFWeap_AssaultRifle_G36C"
|
||||
|
||||
BuyPrice=1600
|
||||
AmmoPricePerMag=36
|
||||
ImagePath="wep_ui_g36c_tex.UI_WeaponSelect_G36C"
|
||||
|
||||
EffectiveRange=70
|
||||
|
||||
UpgradePrice[0]=1500
|
||||
|
||||
UpgradeSellPrice[0]=1125
|
||||
|
||||
SharedUnlockId=SCU_G36C
|
||||
|
||||
}
|
24
KFGame/Classes/KFWeapDef_HRG_Dragonbreath.uc
Normal file
24
KFGame/Classes/KFWeapDef_HRG_Dragonbreath.uc
Normal file
@ -0,0 +1,24 @@
|
||||
//=============================================================================
|
||||
// KFWeapDef_Dragonbreath
|
||||
// This is the Doomstick
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2017 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
class KFWeapDef_HRG_Dragonbreath extends KFWeaponDefinition
|
||||
abstract;
|
||||
|
||||
DefaultProperties
|
||||
{
|
||||
WeaponClassPath="KFGameContent.KFWeap_HRG_Dragonbreath"
|
||||
|
||||
BuyPrice=1400
|
||||
AmmoPricePerMag=25
|
||||
ImagePath="WEP_UI_Quad_Barrel_TEX.UI_WeaponSelect_QuadBarrel"
|
||||
|
||||
EffectiveRange=25
|
||||
|
||||
UpgradePrice[0]=1500
|
||||
|
||||
UpgradeSellPrice[0]=1125
|
||||
}
|
28
KFGame/Classes/KFWeapDef_HRG_Locust.uc
Normal file
28
KFGame/Classes/KFWeapDef_HRG_Locust.uc
Normal file
@ -0,0 +1,28 @@
|
||||
//=============================================================================
|
||||
// KFWeapDef_HRG_Locust
|
||||
//=============================================================================
|
||||
// A lightweight container for basic weapon properties that can be safely
|
||||
// accessed without a weapon actor (UI, remote clients).
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
class KFWeapDef_HRG_Locust extends KFWeaponDefinition
|
||||
abstract;
|
||||
|
||||
DefaultProperties
|
||||
{
|
||||
WeaponClassPath="KFGameContent.KFWeap_HRG_Locust"
|
||||
|
||||
BuyPrice=900
|
||||
AmmoPricePerMag=40
|
||||
ImagePath="wep_ui_hrg_locust_tex.UI_WeaponSelect_HRG_Locust"
|
||||
|
||||
EffectiveRange=100
|
||||
|
||||
UpgradePrice[0]=700
|
||||
UpgradePrice[1]=1500
|
||||
|
||||
UpgradeSellPrice[0]=525
|
||||
UpgradeSellPrice[1]=1650
|
||||
}
|
26
KFGame/Classes/KFWeapDef_Scythe.uc
Normal file
26
KFGame/Classes/KFWeapDef_Scythe.uc
Normal file
@ -0,0 +1,26 @@
|
||||
//=============================================================================
|
||||
// KFWeapDef_Scythe
|
||||
//=============================================================================
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
class KFWeapDef_Scythe extends KFWeaponDefinition
|
||||
abstract;
|
||||
|
||||
DefaultProperties
|
||||
{
|
||||
WeaponClassPath="KFGameContent.KFWeap_Edged_Scythe"
|
||||
|
||||
BuyPrice=1500
|
||||
ImagePath="WEP_UI_Scythe_TEX.UI_WeaponSelect_Scythe"
|
||||
|
||||
EffectiveRange=5
|
||||
|
||||
UpgradePrice[0]=1500
|
||||
|
||||
UpgradeSellPrice[0]=1125
|
||||
|
||||
SharedUnlockId=SCU_Scythe
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
@ -1618,7 +1618,7 @@ simulated function AttachLaserSight()
|
||||
}
|
||||
}
|
||||
|
||||
function GunGameRemove()
|
||||
function RemoveGun()
|
||||
{
|
||||
if (Instigator != none && Instigator.InvManager != none)
|
||||
{
|
||||
|
@ -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"))
|
||||
}
|
@ -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
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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
|
77
KFGameContent/Classes/KFBarmwichBonfireVolume.uc
Normal file
77
KFGameContent/Classes/KFBarmwichBonfireVolume.uc
Normal file
@ -0,0 +1,77 @@
|
||||
//=============================================================================
|
||||
// KFBarmwichBonfireVolume
|
||||
//=============================================================================
|
||||
// Barmwich volume used for bonfires. Triggers seasonal progression.
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFBarmwichBonfireVolume extends KFPhysicsDamageByPawnVolume
|
||||
placeable;
|
||||
|
||||
/** Objective index for the event this is tied to */
|
||||
var() int ObjectiveIndex;
|
||||
|
||||
/** Index of the event this is tied to */
|
||||
var() int EventIndex;
|
||||
|
||||
var array<Actor> AffectedActors;
|
||||
|
||||
var transient bool bIsDataValid;
|
||||
|
||||
simulated event PostBeginPlay()
|
||||
{
|
||||
Super.PostBeginPlay();
|
||||
|
||||
bIsDataValid = IsObjectiveDataValid();
|
||||
}
|
||||
|
||||
function CausePainTo(Actor Other)
|
||||
{
|
||||
Super.CausePainTo(Other);
|
||||
|
||||
if (bIsDataValid && KFPawn_Monster(Other) != none && KFPawn_Monster(Other).IsAliveAndWell())
|
||||
{
|
||||
if (AffectedActors.Find(Other) == INDEX_NONE)
|
||||
{
|
||||
AffectedActors.AddItem(Other);
|
||||
NotifyProgression();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function NotifyProgression()
|
||||
{
|
||||
local KFPlayerController KFPC;
|
||||
|
||||
if (!bIsDataValid)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach WorldInfo.AllControllers(class'KFPlayerController', KFPC)
|
||||
{
|
||||
KFPC.ClientOnTryCompleteObjective(ObjectiveIndex, EventIndex);
|
||||
}
|
||||
}
|
||||
|
||||
function ClearAllActors()
|
||||
{
|
||||
AffectedActors.Remove(0, AffectedActors.Length);
|
||||
}
|
||||
|
||||
function ClearActor(Actor Other)
|
||||
{
|
||||
AffectedActors.RemoveItem(Other);
|
||||
}
|
||||
|
||||
simulated function bool IsObjectiveDataValid()
|
||||
{
|
||||
return ObjectiveIndex >= 0 && ObjectiveIndex < 5 && EventIndex > SEI_None && EventIndex < SEI_MAX;
|
||||
}
|
||||
|
||||
DefaultProperties
|
||||
{
|
||||
bIsDataValid = false;
|
||||
}
|
@ -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'
|
||||
|
87
KFGameContent/Classes/KFDT_Ballistic_G36C.uc
Normal file
87
KFGameContent/Classes/KFDT_Ballistic_G36C.uc
Normal file
@ -0,0 +1,87 @@
|
||||
//=============================================================================
|
||||
// KFDT_Ballistic_G36C
|
||||
//=============================================================================
|
||||
// Class Description
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
class KFDT_Ballistic_G36C extends KFDT_Ballistic_AssaultRifle
|
||||
abstract
|
||||
hidedropdown;
|
||||
|
||||
/** G36C has still to play a metal effect if impacting metal. (and we demoted to impact on Flesh) */
|
||||
var ParticleSystem MetalImpactEffect;
|
||||
var AkEvent MetalImpactSound;
|
||||
|
||||
static function PlayImpactHitEffects( KFPawn P, vector HitLocation, vector HitDirection, byte HitZoneIndex, optional Pawn HitInstigator )
|
||||
{
|
||||
local KFSkinTypeEffects SkinType, OriginalSkinType, FleshSkinType;
|
||||
local int i;
|
||||
|
||||
if ( P.CharacterArch != None && default.EffectGroup < FXG_Max )
|
||||
{
|
||||
// Search if affected target has Flesh skin type
|
||||
for (i = 0; i < P.CharacterArch.ImpactSkins.Length ; ++i)
|
||||
{
|
||||
if (P.CharacterArch.ImpactSkins[i].Name == 'Flesh'
|
||||
|| P.CharacterArch.ImpactSkins[i].Name == 'Tough_Flesh')
|
||||
{
|
||||
FleshSkinType = P.CharacterArch.ImpactSkins[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SkinType = P.GetHitZoneSkinTypeEffects( HitZoneIndex );
|
||||
OriginalSkinType = SkinType;
|
||||
|
||||
// If we don't hit flesh or shield, try to demote to Flesh
|
||||
if (SkinType != none && SkinType.Name != 'Flesh' && SkinType.Name != 'Tough_Flesh' && SkinType.Name != 'ShieldEffects')
|
||||
{
|
||||
// We default to none as we don't want bullet to ricochet if any
|
||||
SkinType = none;
|
||||
|
||||
// Demote to flesh skin hit
|
||||
if (FleshSkinType != none)
|
||||
{
|
||||
SkinType = FleshSkinType;
|
||||
}
|
||||
}
|
||||
|
||||
// If we hit metal we have to make sure we play it's Metal impact effect (this effect doesn't contain bullet ricochet) (don't play sound though!)
|
||||
if (OriginalSkinType != none && (OriginalSkinType.Name == 'Metal' || OriginalSkinType.Name == 'Machine'))
|
||||
{
|
||||
OriginalSkinType.PlayImpactParticleEffect(P, HitLocation, HitDirection, HitZoneIndex, default.EffectGroup, default.MetalImpactEffect);
|
||||
OriginalSkinType.PlayTakeHitSound(P, HitLocation, HitInstigator, default.EffectGroup, default.MetalImpactSound);
|
||||
}
|
||||
|
||||
if (SkinType != none)
|
||||
{
|
||||
SkinType.PlayImpactParticleEffect(P, HitLocation, HitDirection, HitZoneIndex, default.EffectGroup);
|
||||
SkinType.PlayTakeHitSound(P, HitLocation, HitInstigator, default.EffectGroup);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
KDamageImpulse=900
|
||||
KDeathUpKick=-300
|
||||
KDeathVel=100
|
||||
|
||||
DamageModifierAP=0.8f
|
||||
ArmorDamageModifier=15.0f
|
||||
|
||||
StumblePower=15
|
||||
GunHitPower=15
|
||||
|
||||
WeaponDef=class'KFWeapDef_G36C'
|
||||
|
||||
//Perk
|
||||
ModifierPerkList(0)=class'KFPerk_Swat'
|
||||
|
||||
MetalImpactEffect=ParticleSystem'FX_Impacts_EMIT.FX_Wep_Impact_MetalArmor_E'
|
||||
MetalImpactSound=AkEvent'WW_Skin_Impacts.Play_Slashing_Metal_3P'
|
||||
}
|
82
KFGameContent/Classes/KFDT_Ballistic_HRG_Dragonbreath.uc
Normal file
82
KFGameContent/Classes/KFDT_Ballistic_HRG_Dragonbreath.uc
Normal file
@ -0,0 +1,82 @@
|
||||
//=============================================================================
|
||||
// KFDT_Ballistic_HRG_Dragonbreath
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFDT_Ballistic_HRG_Dragonbreath extends KFDT_Ballistic_Shotgun
|
||||
abstract
|
||||
hidedropdown;
|
||||
|
||||
// Damage type to use for the burning damage over time
|
||||
var class<KFDamageType> BurnDamageType;
|
||||
|
||||
/** Allows the damage type to customize exactly which hit zones it can dismember */
|
||||
static simulated function bool CanDismemberHitZone( name InHitZoneName )
|
||||
{
|
||||
if( super.CanDismemberHitZone( InHitZoneName ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
switch ( InHitZoneName )
|
||||
{
|
||||
case 'lupperarm':
|
||||
case 'rupperarm':
|
||||
case 'chest':
|
||||
case 'heart':
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Play damage type specific impact effects when taking damage */
|
||||
static function PlayImpactHitEffects( KFPawn P, vector HitLocation, vector HitDirection, byte HitZoneIndex, optional Pawn HitInstigator )
|
||||
{
|
||||
// Play burn effect when dead
|
||||
if( P.bPlayedDeath && P.WorldInfo.TimeSeconds > P.TimeOfDeath )
|
||||
{
|
||||
default.BurnDamageType.static.PlayImpactHitEffects(P, HitLocation, HitDirection, HitZoneIndex, HitInstigator);
|
||||
return;
|
||||
}
|
||||
|
||||
super.PlayImpactHitEffects(P, HitLocation, HitDirection, HitZoneIndex, HitInstigator);
|
||||
}
|
||||
|
||||
/** Called when damage is dealt to apply additional damage type (e.g. Damage Over Time) */
|
||||
static function ApplySecondaryDamage( KFPawn Victim, int DamageTaken, optional Controller InstigatedBy )
|
||||
{
|
||||
// Overriden to specific a different damage type to do the burn damage over
|
||||
// time. We do this so we don't get shotgun pellet impact sounds/fx during
|
||||
// the DOT burning.
|
||||
if ( default.BurnDamageType.default.DoT_Type != DOT_None )
|
||||
{
|
||||
Victim.ApplyDamageOverTime(DamageTaken, InstigatedBy, default.BurnDamageType);
|
||||
}
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
GoreDamageGroup=DGT_Shotgun
|
||||
BloodSpread=0.4
|
||||
BloodScale=0.6
|
||||
|
||||
KDamageImpulse=3500
|
||||
KDeathUpKick=800
|
||||
KDeathVel=650
|
||||
GibImpulseScale=1.0
|
||||
|
||||
BurnPower=40
|
||||
StumblePower=40
|
||||
GunHitPower=50
|
||||
|
||||
WeaponDef=class'KFWeapDef_HRG_Dragonbreath'
|
||||
|
||||
BurnDamageType=class'KFDT_Fire_HRG_DragonsBreathDoT'
|
||||
|
||||
EffectGroup=FXG_IncendiaryRound
|
||||
|
||||
ModifierPerkList(0)=class'KFPerk_Firebug'
|
||||
}
|
18
KFGameContent/Classes/KFDT_Ballistic_HRG_Locust.uc
Normal file
18
KFGameContent/Classes/KFDT_Ballistic_HRG_Locust.uc
Normal file
@ -0,0 +1,18 @@
|
||||
//=============================================================================
|
||||
// KFDT_Ballistic_HRG_Locust
|
||||
//=============================================================================
|
||||
// HRG Locust bullet impact
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
class KFDT_Ballistic_HRG_Locust extends KFDamageType
|
||||
abstract
|
||||
hidedropdown;
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
ModifierPerkList(0)=class'KFPerk_Survivalist'
|
||||
|
||||
WeaponDef=class'KFWeapDef_HRG_Locust'
|
||||
}
|
16
KFGameContent/Classes/KFDT_Bludgeon_G36C.uc
Normal file
16
KFGameContent/Classes/KFDT_Bludgeon_G36C.uc
Normal file
@ -0,0 +1,16 @@
|
||||
//=============================================================================
|
||||
// KFDT_Bludgeon_G36C
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFDT_Bludgeon_G36C extends KFDT_Bludgeon_RifleButt
|
||||
abstract
|
||||
hidedropdown;
|
||||
|
||||
DefaultProperties
|
||||
{
|
||||
//defaults
|
||||
WeaponDef=class'KFWeapDef_G36C'
|
||||
}
|
16
KFGameContent/Classes/KFDT_Bludgeon_HRG_Dragonbreath.uc
Normal file
16
KFGameContent/Classes/KFDT_Bludgeon_HRG_Dragonbreath.uc
Normal file
@ -0,0 +1,16 @@
|
||||
//=============================================================================
|
||||
// KFDT_Bludgeon_HRG_Dragonbreath
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2017 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFDT_Bludgeon_HRG_Dragonbreath extends KFDT_Bludgeon_RifleButt
|
||||
abstract
|
||||
hidedropdown;
|
||||
|
||||
DefaultProperties
|
||||
{
|
||||
//defaults
|
||||
WeaponDef=class'KFWeapDef_HRG_Dragonbreath'
|
||||
}
|
15
KFGameContent/Classes/KFDT_Bludgeon_HRG_Locust.uc
Normal file
15
KFGameContent/Classes/KFDT_Bludgeon_HRG_Locust.uc
Normal file
@ -0,0 +1,15 @@
|
||||
//=============================================================================
|
||||
// KFDT_Bludgeon_HRG_Locust
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
class KFDT_Bludgeon_HRG_Locust extends KFDT_Bludgeon_RifleButt
|
||||
abstract
|
||||
hidedropdown;
|
||||
|
||||
DefaultProperties
|
||||
{
|
||||
//defaults
|
||||
WeaponDef=class'KFWeapDef_HRG_Locust'
|
||||
}
|
40
KFGameContent/Classes/KFDT_Explosive_HRG_Locust.uc
Normal file
40
KFGameContent/Classes/KFDT_Explosive_HRG_Locust.uc
Normal file
@ -0,0 +1,40 @@
|
||||
//=============================================================================
|
||||
// KFDT_Explosive_HRG_Locust
|
||||
//=============================================================================
|
||||
// Explosive damage type for the HRG Locust
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
class KFDT_Explosive_HRG_Locust extends KFDT_Explosive
|
||||
abstract
|
||||
hidedropdown;
|
||||
|
||||
// Damage type to use for the damage over time effect
|
||||
var class<KFDamageType> DoTDamageType;
|
||||
|
||||
/** Called when damage is dealt to apply additional damage type (e.g. Damage Over Time) */
|
||||
static function ApplySecondaryDamage(KFPawn Victim, int DamageTaken, optional Controller InstigatedBy)
|
||||
{
|
||||
if (Victim.Controller == InstigatedBy)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (default.DoTDamageType.default.DoT_Type != DOT_None)
|
||||
{
|
||||
Victim.ApplyDamageOverTime(class'KFDT_Toxic_HRG_Locust'.default.SpreadOnTouchDamage, InstigatedBy, default.DoTDamageType);
|
||||
}
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
//Perk
|
||||
ModifierPerkList(0)=class'KFPerk_Survivalist'
|
||||
WeaponDef=class'KFWeapDef_HRG_Locust'
|
||||
|
||||
DoTDamageType=class'KFDT_Toxic_HRG_Locust'
|
||||
|
||||
bCausesFracture=false
|
||||
bCanPlayDeadHitEffects=false
|
||||
}
|
39
KFGameContent/Classes/KFDT_Fire_Ground_HRG_DragonBreath.uc
Normal file
39
KFGameContent/Classes/KFDT_Fire_Ground_HRG_DragonBreath.uc
Normal file
@ -0,0 +1,39 @@
|
||||
//=============================================================================
|
||||
// KFDT_Fire_Ground_HRG_DragonBreath
|
||||
//=============================================================================
|
||||
// Damage caused by burning from being hit by a HRG dragon breath ground fire
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFDT_Fire_Ground_HRG_DragonBreath extends KFDT_Fire_Ground
|
||||
abstract;
|
||||
|
||||
static function int GetKillerDialogID()
|
||||
{
|
||||
return 86;//KILL_Fire
|
||||
}
|
||||
|
||||
static function int GetDamagerDialogID()
|
||||
{
|
||||
return 102;//DAMZ_Fire
|
||||
}
|
||||
|
||||
static function int GetDamageeDialogID()
|
||||
{
|
||||
return 116;//DAMP_Fire
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
WeaponDef=class'KFWeapDef_HRG_Dragonbreath'
|
||||
|
||||
DoT_Type=DOT_Fire
|
||||
DoT_Duration=2.7
|
||||
DoT_Interval=0.5
|
||||
DoT_DamageScale=0.7
|
||||
|
||||
BurnPower=10
|
||||
}
|
||||
|
41
KFGameContent/Classes/KFDT_Fire_HRG_DragonsBreathDoT.uc
Normal file
41
KFGameContent/Classes/KFDT_Fire_HRG_DragonsBreathDoT.uc
Normal file
@ -0,0 +1,41 @@
|
||||
//=============================================================================
|
||||
// KFDT_Fire_HRG_DragonsBreathDoT
|
||||
//=============================================================================
|
||||
// Damage caused by burning from being hit by an HRG dragon's breath round
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
class KFDT_Fire_HRG_DragonsBreathDoT extends KFDT_Fire
|
||||
abstract
|
||||
hidedropdown;
|
||||
|
||||
static function int GetKillerDialogID()
|
||||
{
|
||||
return 86;//KILL_Fire
|
||||
}
|
||||
|
||||
static function int GetDamagerDialogID()
|
||||
{
|
||||
return 102;//DAMZ_Fire
|
||||
}
|
||||
|
||||
static function int GetDamageeDialogID()
|
||||
{
|
||||
return 116;//DAMP_Fire
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
WeaponDef=class'KFWeapDef_HRG_Dragonbreath'
|
||||
|
||||
DoT_Type=DOT_Fire
|
||||
DoT_Duration=2.7 //5.0 //1.0
|
||||
DoT_Interval=0.5
|
||||
DoT_DamageScale=0.7 //1.0
|
||||
|
||||
BurnPower=10 //1.0 //18.5
|
||||
}
|
||||
|
23
KFGameContent/Classes/KFDT_Piercing_ScytheStab.uc
Normal file
23
KFGameContent/Classes/KFDT_Piercing_ScytheStab.uc
Normal file
@ -0,0 +1,23 @@
|
||||
//=============================================================================
|
||||
// KFDT_Piercing_ScytheStab
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFDT_Piercing_ScytheStab extends KFDT_Piercing
|
||||
abstract
|
||||
hidedropdown;
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
KDamageImpulse=200
|
||||
KDeathUpKick=250
|
||||
|
||||
StumblePower=50
|
||||
MeleeHitPower=100
|
||||
|
||||
WeaponDef=class'KFWeapDef_Scythe'
|
||||
|
||||
ModifierPerkList(0)=class'KFPerk_Berserker'
|
||||
}
|
140
KFGameContent/Classes/KFDT_Slashing_ScytheLong.uc
Normal file
140
KFGameContent/Classes/KFDT_Slashing_ScytheLong.uc
Normal file
@ -0,0 +1,140 @@
|
||||
//=============================================================================
|
||||
// KFDT_Slashing_ScytheLong
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFDT_Slashing_ScytheLong extends KFDT_Slashing
|
||||
abstract
|
||||
hidedropdown;
|
||||
|
||||
/** Allows the damage type to customize exactly which hit zones it can dismember */
|
||||
static simulated function bool CanDismemberHitZone( name InHitZoneName )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Allows the damage type to map a hit zone to a different bone for dismemberment purposes */
|
||||
static simulated function GetBoneToDismember(KFPawn_Monster InPawn, vector HitDirection, name InHitZoneName, out name OutBoneName)
|
||||
{
|
||||
local EPawnOctant SlashDir;
|
||||
local KFCharacterInfo_Monster MonsterInfo;
|
||||
|
||||
MonsterInfo = InPawn.GetCharacterMonsterInfo();
|
||||
if ( MonsterInfo == none )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SlashDir = GetLastSlashDirection(InPawn, HitDirection);
|
||||
|
||||
if( SlashDir == DIR_Forward || SlashDir == DIR_Backward )
|
||||
{
|
||||
if( InHitZoneName == 'chest' || InHitZoneName == 'head' )
|
||||
{
|
||||
if( MonsterInfo.SpecialMeleeDismemberment.bAllowVerticalSplit )
|
||||
{
|
||||
// Randomly pick the left or right shoulder bone and split the guy in half vertically
|
||||
OutBoneName = Rand(2) == 0
|
||||
? MonsterInfo.SpecialMeleeDismemberment.LeftShoulderBoneName
|
||||
: MonsterInfo.SpecialMeleeDismemberment.RightShoulderBoneName;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( SlashDir == DIR_Left || SlashDir == DIR_Right )
|
||||
{
|
||||
if( InHitZoneName == 'chest' || InHitZoneName == 'abdomen' || InHitZoneName == 'stomach' )
|
||||
{
|
||||
if( MonsterInfo.SpecialMeleeDismemberment.bAllowHorizontalSplit )
|
||||
{
|
||||
// Split the guy in half horizontally
|
||||
OutBoneName = MonsterInfo.SpecialMeleeDismemberment.SpineBoneName;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( SlashDir == DIR_ForwardLeft || SlashDir == DIR_BackwardRight )
|
||||
{
|
||||
if( InHitZoneName == 'chest' )
|
||||
{
|
||||
if( MonsterInfo.SpecialMeleeDismemberment.bAllowVerticalSplit )
|
||||
{
|
||||
OutBoneName = MonsterInfo.SpecialMeleeDismemberment.RightShoulderBoneName;
|
||||
}
|
||||
}
|
||||
else if( InHitZoneName == 'head' )
|
||||
{
|
||||
if( MonsterInfo.SpecialMeleeDismemberment.bAllowVerticalSplit )
|
||||
{
|
||||
// Use a random chance to decide whether to dismember the head or the shoulder constraints
|
||||
if( Rand(2) == 0 )
|
||||
{
|
||||
// ... and choose one of the shoulder constraints at random
|
||||
OutBoneName = MonsterInfo.SpecialMeleeDismemberment.RightShoulderBoneName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( SlashDir == DIR_ForwardRight || SlashDir == DIR_BackwardLeft )
|
||||
{
|
||||
if( InHitZoneName == 'chest' )
|
||||
{
|
||||
if( MonsterInfo.SpecialMeleeDismemberment.bAllowVerticalSplit )
|
||||
{
|
||||
OutBoneName = MonsterInfo.SpecialMeleeDismemberment.LeftShoulderBoneName;
|
||||
}
|
||||
}
|
||||
else if( InHitZoneName == 'head' )
|
||||
{
|
||||
if( MonsterInfo.SpecialMeleeDismemberment.bAllowVerticalSplit )
|
||||
{
|
||||
// Use a random chance to decide whether to dismember the head or the shoulder constraints
|
||||
if( Rand(2) == 0 )
|
||||
{
|
||||
OutBoneName = MonsterInfo.SpecialMeleeDismemberment.LeftShoulderBoneName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Allows the damage type to modify the impulse when a specified hit zone is dismembered */
|
||||
static simulated function ModifyDismembermentHitImpulse(KFPawn_Monster InPawn, name InHitZoneName, vector HitDirection,
|
||||
out vector OutImpulseDir, out vector OutParentImpulseDir,
|
||||
out float OutImpulseScale, out float OutParentImpulseScale)
|
||||
{
|
||||
local EPawnOctant SlashDir;
|
||||
|
||||
SlashDir = GetLastSlashDirection(InPawn, HitDirection);
|
||||
|
||||
// Apply upward impulse on decapitation from a clean horizontal slash
|
||||
if( InHitZoneName == 'head' &&
|
||||
( SlashDir == DIR_Left || SlashDir == DIR_Right ) )
|
||||
{
|
||||
OutImpulseDir += 10*vect(0,0,1);
|
||||
OutImpulseDir = Normal(OutImpulseDir);
|
||||
OutParentImpulseScale = 0.f;
|
||||
}
|
||||
// Do not apply any impulse on split in half from a vertical slash
|
||||
else if( (InHitZoneName == 'head' || InHitZoneName == 'chest' ) &&
|
||||
( SlashDir == DIR_Forward || SlashDir == DIR_Backward) )
|
||||
{
|
||||
OutImpulseScale = 0.f;
|
||||
OutParentImpulseScale = 0.f;
|
||||
}
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
KDamageImpulse=10000 //1500
|
||||
KDeathUpKick=2000 //200
|
||||
KDeathVel=3750 //375
|
||||
|
||||
KnockdownPower=0
|
||||
StunPower=0
|
||||
StumblePower=100
|
||||
MeleeHitPower=100
|
||||
|
||||
WeaponDef=class'KFWeapDef_Scythe'
|
||||
ModifierPerkList(0)=class'KFPerk_Berserker'
|
||||
}
|
38
KFGameContent/Classes/KFDT_Slashing_ScytheLongAlt.uc
Normal file
38
KFGameContent/Classes/KFDT_Slashing_ScytheLongAlt.uc
Normal file
@ -0,0 +1,38 @@
|
||||
//=============================================================================
|
||||
// KFDT_Slashing_ScytheLongAlt
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFDT_Slashing_ScytheLongAlt extends KFDT_Slashing_ZweihanderHeavy
|
||||
abstract
|
||||
hidedropdown;
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
KDamageImpulse=3600 //1600
|
||||
KDeathUpKick=400 //200
|
||||
KDeathVel=750 //500
|
||||
|
||||
KnockdownPower=50
|
||||
StunPower=0
|
||||
StumblePower=200
|
||||
MeleeHitPower=100
|
||||
|
||||
// Obliteration
|
||||
GoreDamageGroup = DGT_Explosive
|
||||
RadialDamageImpulse = 8000.f // This controls how much impulse is applied to gibs when exploding
|
||||
bUseHitLocationForGibImpulses = true // This will make the impulse origin where the victim was hit for directional gibs
|
||||
bPointImpulseTowardsOrigin = true // This creates an impulse direction aligned along hitlocation and pawn location -- this will push all gibs in the same direction
|
||||
ImpulseOriginScale = 100.f // Higher means more directional gibbing, lower means more outward (and upward) gibbing
|
||||
ImpulseOriginLift = 150.f
|
||||
MaxObliterationGibs = 12 // Maximum number of gibs that can be spawned by obliteration, 0=MAX
|
||||
bCanGib = true
|
||||
bCanObliterate = true
|
||||
ObliterationHealthThreshold = 0
|
||||
ObliterationDamageThreshold = 100
|
||||
|
||||
WeaponDef=class'KFWeapDef_Scythe'
|
||||
ModifierPerkList(0)=class'KFPerk_Berserker'
|
||||
}
|
140
KFGameContent/Classes/KFDT_Slashing_ScytheShort.uc
Normal file
140
KFGameContent/Classes/KFDT_Slashing_ScytheShort.uc
Normal file
@ -0,0 +1,140 @@
|
||||
//=============================================================================
|
||||
// KFDT_Slashing_ScytheShort
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFDT_Slashing_ScytheShort extends KFDT_Slashing
|
||||
abstract
|
||||
hidedropdown;
|
||||
|
||||
/** Allows the damage type to customize exactly which hit zones it can dismember */
|
||||
static simulated function bool CanDismemberHitZone( name InHitZoneName )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Allows the damage type to map a hit zone to a different bone for dismemberment purposes */
|
||||
static simulated function GetBoneToDismember(KFPawn_Monster InPawn, vector HitDirection, name InHitZoneName, out name OutBoneName)
|
||||
{
|
||||
local EPawnOctant SlashDir;
|
||||
local KFCharacterInfo_Monster MonsterInfo;
|
||||
|
||||
MonsterInfo = InPawn.GetCharacterMonsterInfo();
|
||||
if ( MonsterInfo == none )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SlashDir = GetLastSlashDirection(InPawn, HitDirection);
|
||||
|
||||
if( SlashDir == DIR_Forward || SlashDir == DIR_Backward )
|
||||
{
|
||||
if( InHitZoneName == 'chest' || InHitZoneName == 'head' )
|
||||
{
|
||||
if( MonsterInfo.SpecialMeleeDismemberment.bAllowVerticalSplit )
|
||||
{
|
||||
// Randomly pick the left or right shoulder bone and split the guy in half vertically
|
||||
OutBoneName = Rand(2) == 0
|
||||
? MonsterInfo.SpecialMeleeDismemberment.LeftShoulderBoneName
|
||||
: MonsterInfo.SpecialMeleeDismemberment.RightShoulderBoneName;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( SlashDir == DIR_Left || SlashDir == DIR_Right )
|
||||
{
|
||||
if( InHitZoneName == 'chest' || InHitZoneName == 'abdomen' || InHitZoneName == 'stomach' )
|
||||
{
|
||||
if( MonsterInfo.SpecialMeleeDismemberment.bAllowHorizontalSplit )
|
||||
{
|
||||
// Split the guy in half horizontally
|
||||
OutBoneName = MonsterInfo.SpecialMeleeDismemberment.SpineBoneName;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( SlashDir == DIR_ForwardLeft || SlashDir == DIR_BackwardRight )
|
||||
{
|
||||
if( InHitZoneName == 'chest' )
|
||||
{
|
||||
if( MonsterInfo.SpecialMeleeDismemberment.bAllowVerticalSplit )
|
||||
{
|
||||
OutBoneName = MonsterInfo.SpecialMeleeDismemberment.RightShoulderBoneName;
|
||||
}
|
||||
}
|
||||
else if( InHitZoneName == 'head' )
|
||||
{
|
||||
if( MonsterInfo.SpecialMeleeDismemberment.bAllowVerticalSplit )
|
||||
{
|
||||
// Use a random chance to decide whether to dismember the head or the shoulder constraints
|
||||
if( Rand(2) == 0 )
|
||||
{
|
||||
// ... and choose one of the shoulder constraints at random
|
||||
OutBoneName = MonsterInfo.SpecialMeleeDismemberment.RightShoulderBoneName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( SlashDir == DIR_ForwardRight || SlashDir == DIR_BackwardLeft )
|
||||
{
|
||||
if( InHitZoneName == 'chest' )
|
||||
{
|
||||
if( MonsterInfo.SpecialMeleeDismemberment.bAllowVerticalSplit )
|
||||
{
|
||||
OutBoneName = MonsterInfo.SpecialMeleeDismemberment.LeftShoulderBoneName;
|
||||
}
|
||||
}
|
||||
else if( InHitZoneName == 'head' )
|
||||
{
|
||||
if( MonsterInfo.SpecialMeleeDismemberment.bAllowVerticalSplit )
|
||||
{
|
||||
// Use a random chance to decide whether to dismember the head or the shoulder constraints
|
||||
if( Rand(2) == 0 )
|
||||
{
|
||||
OutBoneName = MonsterInfo.SpecialMeleeDismemberment.LeftShoulderBoneName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Allows the damage type to modify the impulse when a specified hit zone is dismembered */
|
||||
static simulated function ModifyDismembermentHitImpulse(KFPawn_Monster InPawn, name InHitZoneName, vector HitDirection,
|
||||
out vector OutImpulseDir, out vector OutParentImpulseDir,
|
||||
out float OutImpulseScale, out float OutParentImpulseScale)
|
||||
{
|
||||
local EPawnOctant SlashDir;
|
||||
|
||||
SlashDir = GetLastSlashDirection(InPawn, HitDirection);
|
||||
|
||||
// Apply upward impulse on decapitation from a clean horizontal slash
|
||||
if( InHitZoneName == 'head' &&
|
||||
( SlashDir == DIR_Left || SlashDir == DIR_Right ) )
|
||||
{
|
||||
OutImpulseDir += 10*vect(0,0,1);
|
||||
OutImpulseDir = Normal(OutImpulseDir);
|
||||
OutParentImpulseScale = 0.f;
|
||||
}
|
||||
// Do not apply any impulse on split in half from a vertical slash
|
||||
else if( (InHitZoneName == 'head' || InHitZoneName == 'chest' ) &&
|
||||
( SlashDir == DIR_Forward || SlashDir == DIR_Backward) )
|
||||
{
|
||||
OutImpulseScale = 0.f;
|
||||
OutParentImpulseScale = 0.f;
|
||||
}
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
KDamageImpulse=10000 //1500
|
||||
KDeathUpKick=2000 //200
|
||||
KDeathVel=3750 //375
|
||||
|
||||
KnockdownPower=0
|
||||
StunPower=0
|
||||
StumblePower=50
|
||||
MeleeHitPower=100
|
||||
|
||||
WeaponDef=class'KFWeapDef_Scythe'
|
||||
ModifierPerkList(0)=class'KFPerk_Berserker'
|
||||
}
|
38
KFGameContent/Classes/KFDT_Slashing_ScytheShortAlt.uc
Normal file
38
KFGameContent/Classes/KFDT_Slashing_ScytheShortAlt.uc
Normal file
@ -0,0 +1,38 @@
|
||||
//=============================================================================
|
||||
// KFDT_Slashing_ScytheShortAlt
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFDT_Slashing_ScytheShortAlt extends KFDT_Slashing_ZweihanderHeavy
|
||||
abstract
|
||||
hidedropdown;
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
KDamageImpulse=3600 //1600
|
||||
KDeathUpKick=400 //200
|
||||
KDeathVel=750 //500
|
||||
|
||||
KnockdownPower=0
|
||||
StunPower=0
|
||||
StumblePower=150
|
||||
MeleeHitPower=100
|
||||
|
||||
// Obliteration
|
||||
GoreDamageGroup = DGT_Explosive
|
||||
RadialDamageImpulse = 8000.f // This controls how much impulse is applied to gibs when exploding
|
||||
bUseHitLocationForGibImpulses = true // This will make the impulse origin where the victim was hit for directional gibs
|
||||
bPointImpulseTowardsOrigin = true // This creates an impulse direction aligned along hitlocation and pawn location -- this will push all gibs in the same direction
|
||||
ImpulseOriginScale = 100.f // Higher means more directional gibbing, lower means more outward (and upward) gibbing
|
||||
ImpulseOriginLift = 150.f
|
||||
MaxObliterationGibs = 12 // Maximum number of gibs that can be spawned by obliteration, 0=MAX
|
||||
bCanGib = true
|
||||
bCanObliterate = true
|
||||
ObliterationHealthThreshold = 0
|
||||
ObliterationDamageThreshold = 100
|
||||
|
||||
WeaponDef=class'KFWeapDef_Scythe'
|
||||
ModifierPerkList(0)=class'KFPerk_Berserker'
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
//=============================================================================
|
||||
// KFExplosion_HRG_Dragonbreath_GroundFire
|
||||
//=============================================================================
|
||||
// Explosion actor class for ground fire
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFExplosion_HRG_Dragonbreath_GroundFire extends KFExplosionActorLingering;
|
||||
|
||||
|
||||
simulated function SpawnExplosionParticleSystem(ParticleSystem Template)
|
||||
{
|
||||
// If the template is none, grab the default
|
||||
if( !ExplosionTemplate.bAllowPerMaterialFX && Template == none )
|
||||
{
|
||||
Template = KFGameExplosion(ExplosionTemplate).ExplosionEffects.DefaultImpactEffect.ParticleTemplate;
|
||||
}
|
||||
|
||||
// Use custom pool
|
||||
WorldInfo.GroundFireEmitterPool.SpawnEmitter(Template, Location, rotator(ExplosionTemplate.HitNormal), None);
|
||||
}
|
||||
|
||||
DefaultProperties
|
||||
{
|
||||
//Interval=0.25f INTERVAL IS OVERRIDDEN BY ITS PROJECTILE
|
||||
MaxTime=2.0
|
||||
|
||||
ExplosionLightPriority=LPP_Low
|
||||
LoopStartEvent=AkEvent'ww_wep_hrg_megadragonbreath.Play_WEP_HRG_MegaDragonbreath_Flame_LP'
|
||||
LoopStopEvent=AkEvent'ww_wep_hrg_megadragonbreath.Stop_WEP_HRG_MegaDragonbreath_End_Flame_LP'
|
||||
}
|
43
KFGameContent/Classes/KFExplosion_HRG_Locust.uc
Normal file
43
KFGameContent/Classes/KFExplosion_HRG_Locust.uc
Normal file
@ -0,0 +1,43 @@
|
||||
//=============================================================================
|
||||
// KFExplosion_HRG_Locust
|
||||
//=============================================================================
|
||||
// Explosion actor class for HRG Locust
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFExplosion_HRG_Locust extends KFExplosionActorLingering;
|
||||
|
||||
var private bool bFirstExplosion;
|
||||
|
||||
protected simulated function bool DoExplosionDamage(bool bCauseDamage, bool bCauseEffects)
|
||||
{
|
||||
local bool bReturnValue;
|
||||
|
||||
// Only does explosion damage one time
|
||||
if (bCauseDamage && bFirstExplosion == false)
|
||||
{
|
||||
bCauseDamage = false;
|
||||
}
|
||||
|
||||
bReturnValue = super.DoExplosionDamage(bCauseDamage, bCauseEffects);
|
||||
|
||||
bFirstExplosion = false;
|
||||
|
||||
return bReturnValue;
|
||||
}
|
||||
|
||||
DefaultProperties
|
||||
{
|
||||
Interval=0.5f
|
||||
MaxTime=3.0
|
||||
|
||||
bOnlyDamagePawns=true
|
||||
bDoFullDamage=false
|
||||
|
||||
bFirstExplosion=true
|
||||
|
||||
LoopStartEvent=AkEvent'WW_WEP_HRG_Locust.Play_WEP_HRG_Locust_Insects'
|
||||
LoopStopEvent=AkEvent'WW_WEP_HRG_Locust.Stop_WEP_HRG_Locust_Insect'
|
||||
}
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -62,7 +62,7 @@ function UpdateHealer(Optional bool bForce)
|
||||
}
|
||||
|
||||
|
||||
function ShowActiveIndicators( array<string> IconPathStrings )
|
||||
function ShowActiveIndicators( array<ActiveSkill> ActiveSkills )
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
KFPM = KFPawn_Monster(KilledPawn);
|
||||
KFPC_WS_Killer = KFPlayerController_WeeklySurvival(Killer);
|
||||
KFPC_WS_Killed = KFPlayerController_WeeklySurvival(Killed);
|
||||
|
||||
if (OutbreakEvent.ActiveEvent.bGunGameMode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// If pawn is monster increase gun game score for that monster
|
||||
|
||||
// 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 (KFPC_WS.Pawn.Health > 0)
|
||||
if (KFPM != none && KFPC_WS_Killer != none)
|
||||
{
|
||||
KFPC_WS.GunGameData.Score += KFPM.GunGameKilledScore;
|
||||
UpdateGunGameLevel(KFPC_WS);
|
||||
if (KFPC_WS_Killer.Pawn.Health > 0)
|
||||
{
|
||||
KFPC_WS_Killer.GunGameData.Score += KFPM.GunGameKilledScore;
|
||||
UpdateGunGameLevel(KFPC_WS_Killer);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// If pawn is human reset game score (we can just check Killed exists as Controller
|
||||
if (KFPC_WS_Killed != none)
|
||||
{
|
||||
ResetGunGame(KFPC_WS_Killed);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
if (OutbreakEvent.ActiveEvent.bVIPGameMode)
|
||||
{
|
||||
// If pawn is human reset game score (we can just check Killed exists as Controller)
|
||||
|
||||
KFPC_WS = KFPlayerController_WeeklySurvival(Killed);
|
||||
|
||||
if (KFPC_WS != none)
|
||||
if (KFPC_WS_Killed != none && KFPC_WS_Killed.VIPGameData.isVIP)
|
||||
{
|
||||
ResetGunGame(KFPC_WS);
|
||||
// UnregisterPlayer is done on the same frame but this function comes first..
|
||||
// we queue a petition to end the game if no vip is found
|
||||
SetTimer(1.5f, false, 'OnVIPDiesEndMatch');
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1240,7 +1246,7 @@ function UpdateGunGameLevel(KFPlayerController_WeeklySurvival KFPC_WS)
|
||||
{
|
||||
// To prevent audio/vfx lock, while firing when removing the equipped weapon we do a proper gun remove
|
||||
// This new function manages it's state internally
|
||||
CurrentWeapon.GunGameRemove();
|
||||
CurrentWeapon.RemoveGun();
|
||||
}
|
||||
|
||||
if (class'KFPerk_SWAT'.static.Is9mm(CurrentWeapon))
|
||||
@ -1278,6 +1284,222 @@ function UpdateGunGameLevel(KFPlayerController_WeeklySurvival KFPC_WS)
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function UnregisterPlayer(PlayerController PC)
|
||||
{
|
||||
local KFPlayerController_WeeklySurvival KFPC_WS;
|
||||
|
||||
super.UnregisterPlayer(PC);
|
||||
|
||||
KFPC_WS = KFPlayerController_WeeklySurvival(PC);
|
||||
if (OutbreakEvent.ActiveEvent.bVIPGameMode)
|
||||
{
|
||||
if (KFPC_WS != none && KFPC_WS.VIPGameData.IsVIP)
|
||||
{
|
||||
ChooseVIP(false, KFPC_WS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function WaveStarted()
|
||||
{
|
||||
Super.WaveStarted();
|
||||
|
||||
if (OutbreakEvent.ActiveEvent.bVIPGameMode)
|
||||
{
|
||||
if (WaveNum <= 1)
|
||||
{
|
||||
ChooseVIP(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function OnVIPDiesEndMatch()
|
||||
{
|
||||
local KFPlayerController KFPC;
|
||||
|
||||
foreach WorldInfo.AllControllers(class'KFPlayerController', KFPC)
|
||||
{
|
||||
KFPC.SetCameraMode('ThirdPerson');
|
||||
}
|
||||
|
||||
WaveEnded(WEC_TeamWipedOut);
|
||||
}
|
||||
|
||||
function ChooseVIP_SetupVIP()
|
||||
{
|
||||
local KFPlayerController_WeeklySurvival KFPC_WS, NewVIP;
|
||||
local KFGameReplicationInfo KFGRI;
|
||||
|
||||
NewVIP = none;
|
||||
KFGRI = KFGameReplicationInfo(WorldInfo.GRI);
|
||||
|
||||
foreach WorldInfo.AllControllers(class'KFPlayerController_WeeklySurvival', KFPC_WS)
|
||||
{
|
||||
if (KFPC_WS != none)
|
||||
{
|
||||
if (KFPC_WS.VIPGameData.IsVIP)
|
||||
{
|
||||
NewVIP = KFPC_WS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (NewVIP != none)
|
||||
{
|
||||
//`Log("Setup new VIP: " $NewVIP);
|
||||
|
||||
if (NewVIP.Pawn != none)
|
||||
{
|
||||
//`Log("Finished setup new VIP: " $NewVIP);
|
||||
|
||||
NewVIP.GetPerk().PerkSetOwnerHealthAndArmor(false);
|
||||
|
||||
if (NewVIP.VIPGameData.PendingHealthReset)
|
||||
{
|
||||
NewVIP.VIPGameData.PendingHealthReset = false;
|
||||
|
||||
// Change current health directly, Pawn.HealDamage does a lot of other stuff that can block the healing
|
||||
NewVIP.Pawn.Health = NewVIP.Pawn.HealthMax;
|
||||
}
|
||||
|
||||
// Replicate new data to clients
|
||||
KFGRI.UpdateVIPPlayer(KFPlayerReplicationInfo(NewVIP.PlayerReplicationInfo));
|
||||
KFGRI.UpdateVIPMaxHealth(NewVIP.Pawn.HealthMax);
|
||||
KFGRI.UpdateVIPCurrentHealth(NewVIP.Pawn.Health);
|
||||
|
||||
NewVIP.PlayVIPGameChosenSound(3.5f);
|
||||
|
||||
ClearTimer('ChooseVIP_SetupVIP');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function ChooseVIP(bool ForceAddHealth, optional KFPlayerController_WeeklySurvival PlayerJustLeft = none)
|
||||
{
|
||||
local int RandomNumber;
|
||||
local KFPlayerController_WeeklySurvival KFPC_WS, CurrentVIP, NewVIP;
|
||||
local array<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
|
||||
|
@ -198,19 +198,32 @@ simulated function bool CanActivateObjectiveByWeekly()
|
||||
{
|
||||
if (Role == Role_Authority)
|
||||
{
|
||||
if (KFGameInfo(WorldInfo.Game).OutbreakEvent != none
|
||||
&& KFGameInfo(WorldInfo.Game).OutbreakEvent.ActiveEvent.bGunGameMode)
|
||||
if (KFGameInfo(WorldInfo.Game).OutbreakEvent != none)
|
||||
{
|
||||
return false;
|
||||
if (KFGameInfo(WorldInfo.Game).OutbreakEvent.ActiveEvent.bGunGameMode)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (KFGameInfo(WorldInfo.Game).OutbreakEvent.ActiveEvent.bVIPGameMode)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (KFGameReplicationInfo(WorldInfo.GRI) != none
|
||||
&& KFGameReplicationInfo(WorldInfo.GRI).bIsWeeklyMode
|
||||
&& KFGameReplicationInfo(WorldInfo.GRI).CurrentWeeklyIndex == 16)
|
||||
if (KFGameReplicationInfo(WorldInfo.GRI) != none && KFGameReplicationInfo(WorldInfo.GRI).bIsWeeklyMode)
|
||||
{
|
||||
return false;
|
||||
if (KFGameReplicationInfo(WorldInfo.GRI).CurrentWeeklyIndex == 16)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (KFGameReplicationInfo(WorldInfo.GRI).CurrentWeeklyIndex == 17)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
25
KFGameContent/Classes/KFProj_HRG_Dragonbreath_Splash.uc
Normal file
25
KFGameContent/Classes/KFProj_HRG_Dragonbreath_Splash.uc
Normal file
@ -0,0 +1,25 @@
|
||||
//=============================================================================
|
||||
// KFProj_HRG_DragonBreath_Splash
|
||||
//=============================================================================
|
||||
// Projectile class for hrg dragonbreath gun splash. Handles a few overrides.
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFProj_HRG_DragonBreath_Splash extends KFProj_FlareGunSplash;
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
PostExplosionLifetime=2.5
|
||||
ExplosionActorClass=class'KFExplosion_HRG_Dragonbreath_GroundFire'
|
||||
|
||||
Begin Object Name=ExploTemplate0
|
||||
Damage=8
|
||||
DamageRadius=150.0
|
||||
MyDamageType=class'KFDT_Fire_Ground_HRG_DragonBreath'
|
||||
ExplosionEffects=KFImpactEffectInfo'WEP_Flamethrower_ARCH.GroundFire_Impacts'
|
||||
End Object
|
||||
|
||||
AssociatedPerkClass=none
|
||||
}
|
171
KFGameContent/Classes/KFProj_HRG_Locust.uc
Normal file
171
KFGameContent/Classes/KFProj_HRG_Locust.uc
Normal file
@ -0,0 +1,171 @@
|
||||
//=============================================================================
|
||||
// KFProj_HRG_Locust
|
||||
//=============================================================================
|
||||
// HRG Locust projectile
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//
|
||||
//=============================================================================
|
||||
class KFProj_HRG_Locust extends KFProj_BallisticExplosive
|
||||
hidedropdown;
|
||||
|
||||
/** Our intended target actor */
|
||||
var private KFPawn LockedTarget;
|
||||
|
||||
/** How much 'stickyness' when seeking toward our target. Determines how accurate rocket is */
|
||||
var const float SeekStrength;
|
||||
|
||||
replication
|
||||
{
|
||||
if( bNetInitial )
|
||||
LockedTarget;
|
||||
}
|
||||
|
||||
function SetLockedTarget( KFPawn NewTarget )
|
||||
{
|
||||
LockedTarget = NewTarget;
|
||||
}
|
||||
|
||||
simulated function bool AllowNuke()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
simulated function bool AllowDemolitionistConcussive()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
simulated function bool AllowDemolitionistExplosionChangeRadius()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
simulated event Tick( float DeltaTime )
|
||||
{
|
||||
local vector TargetImpactPos, DirToTarget;
|
||||
|
||||
super.Tick( DeltaTime );
|
||||
|
||||
// Skip the first frame, then start seeking
|
||||
if( !bHasExploded
|
||||
&& LockedTarget != none
|
||||
&& Physics == PHYS_Projectile
|
||||
&& Velocity != vect(0,0,0)
|
||||
&& LockedTarget.IsAliveAndWell()
|
||||
&& `TimeSince(CreationTime) > 0.03f )
|
||||
{
|
||||
// Grab our desired relative impact location from the weapon class
|
||||
TargetImpactPos = class'KFWeap_HRG_Locust'.static.GetLockedTargetLoc( LockedTarget );
|
||||
|
||||
// Seek towards target
|
||||
Speed = VSize( Velocity );
|
||||
DirToTarget = Normal( TargetImpactPos - Location );
|
||||
Velocity = Normal( Velocity + (DirToTarget * (SeekStrength * DeltaTime)) ) * Speed;
|
||||
|
||||
// Aim rotation towards velocity every frame
|
||||
SetRotation( rotator(Velocity) );
|
||||
}
|
||||
}
|
||||
|
||||
simulated protected function PrepareExplosionTemplate()
|
||||
{
|
||||
local Weapon OwnerWeapon;
|
||||
local Pawn OwnerPawn;
|
||||
local KFPerk_Survivalist Perk;
|
||||
|
||||
super(KFProjectile).PrepareExplosionTemplate();
|
||||
|
||||
OwnerWeapon = Weapon(Owner);
|
||||
if (OwnerWeapon != none)
|
||||
{
|
||||
OwnerPawn = Pawn(OwnerWeapon.Owner);
|
||||
if (OwnerPawn != none)
|
||||
{
|
||||
Perk = KFPerk_Survivalist(KFPawn(OwnerPawn).GetPerk());
|
||||
if (Perk != none)
|
||||
{
|
||||
ExplosionTemplate.DamageRadius *= KFPawn(OwnerPawn).GetPerk().GetAoERadiusModifier();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
Physics=PHYS_Projectile
|
||||
Speed=4000 //6000
|
||||
MaxSpeed=4000 //6000
|
||||
TossZ=0
|
||||
GravityScale=1.0
|
||||
MomentumTransfer=0.0f
|
||||
|
||||
Damage=10
|
||||
DamageRadius=0
|
||||
|
||||
SeekStrength=928000.0f // 128000.0f
|
||||
|
||||
bWarnAIWhenFired=true
|
||||
|
||||
ProjFlightTemplate=ParticleSystem'WEP_HRG_Locust_EMIT.FX_HRG_Locust_Projectile'
|
||||
ProjFlightTemplateZedTime=ParticleSystem'WEP_HRG_Locust_EMIT.FX_HRG_Locust_Projectile_ZED_TIME'
|
||||
ProjDisintegrateTemplate=ParticleSystem'WEP_HRG_Locust_EMIT.FX_Flying_Bugs_dispersion'
|
||||
|
||||
AmbientSoundPlayEvent=AkEvent'WW_WEP_Seeker_6.Play_WEP_Seeker_6_Projectile'
|
||||
AmbientSoundStopEvent=AkEvent'WW_WEP_Seeker_6.Stop_WEP_Seeker_6_Projectile'
|
||||
|
||||
ExplosionActorClass=class'KFExplosion_HRG_Locust'
|
||||
|
||||
AltExploEffects=KFImpactEffectInfo'WEP_HRG_Locust_ARCH.FX_HRG_Locust_Explosion_Concussive_force'
|
||||
|
||||
// Grenade explosion light
|
||||
Begin Object Class=PointLightComponent Name=ExplosionPointLight
|
||||
LightColor=(R=252,G=218,B=171,A=255)
|
||||
Brightness=4.f
|
||||
Radius=2000.f
|
||||
FalloffExponent=10.f
|
||||
CastShadows=False
|
||||
CastStaticShadows=FALSE
|
||||
CastDynamicShadows=False
|
||||
bCastPerObjectShadows=false
|
||||
bEnabled=FALSE
|
||||
LightingChannels=(Indoor=TRUE,Outdoor=TRUE,bInitialized=TRUE)
|
||||
End Object
|
||||
|
||||
// explosion
|
||||
Begin Object Class=KFGameExplosion Name=ExploTemplate0
|
||||
Damage=80
|
||||
DamageRadius=300
|
||||
DamageFalloffExponent=0.5f
|
||||
DamageDelay=0.f
|
||||
|
||||
//Impulse applied to Zeds
|
||||
MomentumTransferScale=1
|
||||
|
||||
// Damage Effects
|
||||
MyDamageType=class'KFDT_Explosive_HRG_Locust'
|
||||
KnockDownStrength=0
|
||||
FractureMeshRadius=0.0
|
||||
FracturePartVel=0.0
|
||||
ExplosionEffects=KFImpactEffectInfo'WEP_HRG_Locust_ARCH.FX_HRG_Locust_Explosion_Concussive_force'
|
||||
ExplosionSound=AkEvent'WW_WEP_Seeker_6.Play_WEP_Seeker_6_Explosion'
|
||||
|
||||
// Dynamic Light
|
||||
ExploLight=ExplosionPointLight
|
||||
ExploLightStartFadeOutTime=0.0
|
||||
ExploLightFadeOutTime=0.2
|
||||
|
||||
// Camera Shake
|
||||
CamShake=CameraShake'FX_CameraShake_Arch.Misc_Explosions.Light_Explosion_Rumble'
|
||||
CamShakeInnerRadius=0
|
||||
CamShakeOuterRadius=500
|
||||
CamShakeFalloff=3.f
|
||||
bOrientCameraShakeTowardsEpicenter=true
|
||||
|
||||
bIgnoreInstigator=true
|
||||
End Object
|
||||
ExplosionTemplate=ExploTemplate0
|
||||
|
||||
bCanDisintegrate=false
|
||||
}
|
@ -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
|
||||
|
85
KFGameContent/Classes/KFProj_Pellet_HRG_Dragonbreath.uc
Normal file
85
KFGameContent/Classes/KFProj_Pellet_HRG_Dragonbreath.uc
Normal file
@ -0,0 +1,85 @@
|
||||
//=============================================================================
|
||||
// KFProj_Pellet_HRG_Dragonbreath
|
||||
//=============================================================================
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFProj_Pellet_HRG_Dragonbreath extends KFProj_Bullet_Pellet
|
||||
hidedropdown;
|
||||
|
||||
|
||||
/** Last hit normal from Touch() or HitWall() */
|
||||
var vector LastHitNormal;
|
||||
|
||||
var float GroundFireChance;
|
||||
|
||||
|
||||
simulated function ProcessTouch(Actor Other, Vector HitLocation, Vector HitNormal)
|
||||
{
|
||||
LastHitNormal = HitNormal;
|
||||
Super.ProcessTouch(Other, HitLocation, HitNormal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Explode this Projectile
|
||||
*/
|
||||
simulated function TriggerExplosion(Vector HitLocation, Vector HitNormal, Actor HitActor)
|
||||
{
|
||||
LastHitNormal = HitNormal;
|
||||
Super.TriggerExplosion(HitLocation, HitNormal, HitActor);
|
||||
}
|
||||
|
||||
|
||||
simulated protected function StopSimulating()
|
||||
{
|
||||
local vector FlameSpawnVel;
|
||||
|
||||
if (Role == ROLE_Authority && Physics == PHYS_Falling && FRand() < GroundFireChance)
|
||||
{
|
||||
//SpawnGroundFire();
|
||||
FlameSpawnVel = 0.25f * CalculateResidualFlameVelocity(LastHitNormal, Normal(Velocity), VSize(Velocity));
|
||||
SpawnResidualFlame(class'KFProj_HRG_DragonBreath_Splash', Location + (LastHitNormal * 10.f), FlameSpawnVel);
|
||||
}
|
||||
|
||||
super.StopSimulating();
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
GroundFireChance=1.f
|
||||
Physics=PHYS_Falling
|
||||
|
||||
MaxSpeed=7000.0
|
||||
Speed=7000.0
|
||||
TerminalVelocity=7000.0
|
||||
|
||||
bWarnAIWhenFired=true
|
||||
|
||||
DamageRadius=0
|
||||
GravityScale=0.35
|
||||
TossZ=0
|
||||
|
||||
Begin Object Class=PointLightComponent Name=PointLight0
|
||||
LightColor=(R=252,G=218,B=171,A=255)
|
||||
Brightness=0.5f
|
||||
Radius=500.f
|
||||
FalloffExponent=10.f
|
||||
CastShadows=False
|
||||
CastStaticShadows=FALSE
|
||||
CastDynamicShadows=False
|
||||
bCastPerObjectShadows=false
|
||||
bEnabled=true
|
||||
LightingChannels=(Indoor=TRUE,Outdoor=TRUE,bInitialized=TRUE)
|
||||
End Object
|
||||
ProjFlightLight=PointLight0
|
||||
|
||||
ImpactEffects=KFImpactEffectInfo'WEP_DragonsBreath_ARCH.DragonsBreath_bullet_impact'
|
||||
ProjFlightTemplate=ParticleSystem'WEP_DragonsBreath_EMIT.Tracer.FX_DragonsBreath_Tracer'
|
||||
ProjFlightTemplateZedTime=ParticleSystem'WEP_DragonsBreath_EMIT.Tracer.FX_DragonsBreath_Tracer_ZEDTime'
|
||||
|
||||
AmbientSoundPlayEvent=AkEvent'WW_WEP_SA_DragonsBreath.Play_SA_DragonsBreath_Projectile_Loop'
|
||||
AmbientSoundStopEvent=AkEvent'WW_WEP_SA_DragonsBreath.Stop_SA_DragonsBreath_Projectile_Loop'
|
||||
}
|
||||
|
128
KFGameContent/Classes/KFSeasonalEventStats_Fall2022.uc
Normal file
128
KFGameContent/Classes/KFSeasonalEventStats_Fall2022.uc
Normal file
@ -0,0 +1,128 @@
|
||||
//=============================================================================
|
||||
// KFSeasonalEventStats_Fall2022
|
||||
//=============================================================================
|
||||
// Tracks event-specific challenges/accomplishments for Fall 2022
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2021 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
class KFSeasonalEventStats_Fall2022 extends KFSeasonalEventStats;
|
||||
|
||||
var transient private const int BossKillsRequired, ZedsInBonfiresRequired, EndlessWaveRequired;
|
||||
|
||||
private event Initialize(string MapName)
|
||||
{
|
||||
local string CapsMapName;
|
||||
CapsMapName = Caps(MapName);
|
||||
|
||||
bObjectiveIsValidForMap[0] = 1; // Kill 15 Bosses on any map or mode
|
||||
bObjectiveIsValidForMap[1] = 0; // Complete the Weekly on BarmwichTown
|
||||
bObjectiveIsValidForMap[2] = 0; // Open the Weapon Room
|
||||
bObjectiveIsValidForMap[3] = 0; // Make 50 Zeds to pass through the bonfires of Barmwitch Town
|
||||
bObjectiveIsValidForMap[4] = 0; // Complete wave 15 on Endless Hard or higher difficulty on Barmwitch Town
|
||||
|
||||
if (CapsMapName == "KF-BARMWICHTOWN")
|
||||
{
|
||||
bObjectiveIsValidForMap[1] = 1;
|
||||
bObjectiveIsValidForMap[2] = 1;
|
||||
bObjectiveIsValidForMap[3] = 1;
|
||||
bObjectiveIsValidForMap[4] = 1;
|
||||
}
|
||||
|
||||
SetSeasonalEventStatsMax(BossKillsRequired, 0, 0, ZedsInBonfiresRequired, EndlessWaveRequired);
|
||||
}
|
||||
|
||||
private event GrantEventItems()
|
||||
{
|
||||
if (Outer.IsEventObjectiveComplete(0) &&
|
||||
Outer.IsEventObjectiveComplete(1) &&
|
||||
Outer.IsEventObjectiveComplete(2) &&
|
||||
Outer.IsEventObjectiveComplete(3) &&
|
||||
Outer.IsEventObjectiveComplete(4))
|
||||
{
|
||||
GrantEventItem(9424);
|
||||
}
|
||||
}
|
||||
|
||||
// Kill 15 Bosses on any map or mode
|
||||
simulated function OnBossDied()
|
||||
{
|
||||
local int ObjIdx;
|
||||
ObjIdx = 0;
|
||||
|
||||
// Boss kills in any map
|
||||
if (bObjectiveIsValidForMap[ObjIdx] != 0)
|
||||
{
|
||||
IncrementSeasonalEventStat(ObjIdx, 1);
|
||||
if (Outer.GetSeasonalEventStatValue(ObjIdx) >= BossKillsRequired)
|
||||
{
|
||||
FinishedObjective(SEI_Fall, ObjIdx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Complete the Weekly on Netherhold
|
||||
simulated event OnGameWon(class<GameInfo> GameClass, int Difficulty, int GameLength, bool bCoOp)
|
||||
{
|
||||
local int ObjIdx;
|
||||
ObjIdx = 1;
|
||||
|
||||
if (bObjectiveIsValidForMap[ObjIdx] != 0)
|
||||
{
|
||||
if (GameClass == class'KFGameInfo_WeeklySurvival')
|
||||
{
|
||||
FinishedObjective(SEI_Fall, ObjIdx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Complete wave 15 on Endless Hard or higher difficulty on Netherhold
|
||||
simulated event OnWaveCompleted(class<GameInfo> GameClass, int Difficulty, int WaveNum)
|
||||
{
|
||||
local int ObjIdx;
|
||||
ObjIdx = 4;
|
||||
|
||||
if (bObjectiveIsValidForMap[ObjIdx] != 0)
|
||||
{
|
||||
if (WaveNum >= EndlessWaveRequired && GameClass == class'KFGameInfo_Endless' && Difficulty >= `DIFFICULTY_HARD)
|
||||
{
|
||||
FinishedObjective(SEI_Fall, ObjIdx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
simulated function OnTryCompleteObjective(int ObjectiveIndex, int EventIndex)
|
||||
{
|
||||
local int WeaponRoomIdx, BonfireIdx;
|
||||
WeaponRoomIdx = 2;
|
||||
BonfireIdx = 3;
|
||||
|
||||
if(EventIndex == SEI_Fall)
|
||||
{
|
||||
if (ObjectiveIndex == WeaponRoomIdx)
|
||||
{
|
||||
if (bObjectiveIsValidForMap[ObjectiveIndex] != 0)
|
||||
{
|
||||
FinishedObjective(SEI_Fall, ObjectiveIndex);
|
||||
}
|
||||
}
|
||||
else if (ObjectiveIndex == BonfireIdx)
|
||||
{
|
||||
if (bObjectiveIsValidForMap[ObjectiveIndex] != 0)
|
||||
{
|
||||
IncrementSeasonalEventStat(ObjectiveIndex, 1);
|
||||
if (Outer.GetSeasonalEventStatValue(ObjectiveIndex) >= ZedsInBonfiresRequired)
|
||||
{
|
||||
FinishedObjective(SEI_Fall, ObjectiveIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
BossKillsRequired=15
|
||||
EndlessWaveRequired=15
|
||||
ZedsInBonfiresRequired=50
|
||||
}
|
83
KFGameContent/Classes/KFWeapAttach_HRG_Dragonbreath.uc
Normal file
83
KFGameContent/Classes/KFWeapAttach_HRG_Dragonbreath.uc
Normal file
@ -0,0 +1,83 @@
|
||||
//=============================================================================
|
||||
// KFWeapAttach_HRG_Dragonbreath
|
||||
//=============================================================================
|
||||
//
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFWeapAttach_HRG_Dragonbreath extends KFWeaponAttachment;
|
||||
|
||||
`define HRGDRAGONBREATH_MIC_BARREL_INDEX 0
|
||||
|
||||
var transient float BarrelHeatPerProjectile;
|
||||
var transient float MaxBarrelHeat;
|
||||
var transient float BarrelCooldownRate;
|
||||
var transient float CurrentBarrelHeat;
|
||||
var transient float LastBarrelHeat;
|
||||
var transient int NumPelletsDefault;
|
||||
var transient int NumPelletsAlt;
|
||||
|
||||
simulated event PreBeginPlay()
|
||||
{
|
||||
Super.PreBeginPlay();
|
||||
|
||||
BarrelHeatPerProjectile = class'KFWeap_HRG_Dragonbreath'.default.BarrelHeatPerProjectile;
|
||||
MaxBarrelHeat = class'KFWeap_HRG_Dragonbreath'.default.MaxBarrelHeat;
|
||||
BarrelCooldownRate = class'KFWeap_HRG_Dragonbreath'.default.BarrelCooldownRate;
|
||||
NumPelletsDefault = class'KFWeap_HRG_Dragonbreath'.default.NumPellets[0];
|
||||
NumPelletsAlt = class'KFWeap_HRG_Dragonbreath'.default.NumPellets[1];
|
||||
}
|
||||
|
||||
simulated event PostBeginPlay()
|
||||
{
|
||||
Super.PostBeginPlay();
|
||||
|
||||
// Force start with "Glow_Intensity" of 0.0f
|
||||
LastBarrelHeat = MaxBarrelHeat;
|
||||
ChangeBarrelMaterial();
|
||||
}
|
||||
|
||||
simulated function ChangeBarrelMaterial()
|
||||
{
|
||||
if( CurrentBarrelHeat != LastBarrelHeat )
|
||||
{
|
||||
if ( WeaponMIC == None && WeapMesh != None )
|
||||
{
|
||||
WeaponMIC = WeapMesh.CreateAndSetMaterialInstanceConstant(`HRGDRAGONBREATH_MIC_BARREL_INDEX);
|
||||
}
|
||||
|
||||
WeaponMIC.SetScalarParameterValue('Barrel_intensity', CurrentBarrelHeat);
|
||||
}
|
||||
}
|
||||
|
||||
simulated function Tick(float Delta)
|
||||
{
|
||||
Super.Tick(Delta);
|
||||
|
||||
CurrentBarrelHeat = fmax(CurrentBarrelHeat - BarrelCooldownRate * Delta, 0.0f);
|
||||
ChangeBarrelMaterial();
|
||||
}
|
||||
|
||||
/** Override to update emissive in weapon's barrel after firing */
|
||||
simulated function PlayWeaponFireAnim()
|
||||
{
|
||||
local float BarrelHeatPerShot;
|
||||
local KFPawn OwnerPawn;
|
||||
|
||||
Super.PlayWeaponFireAnim();
|
||||
|
||||
OwnerPawn = KFPawn(Owner);
|
||||
|
||||
BarrelHeatPerShot = BarrelHeatPerProjectile * (OwnerPawn.FiringMode == 0 ? NumPelletsDefault : NumPelletsAlt);
|
||||
CurrentBarrelHeat = fmin(CurrentBarrelHeat + BarrelHeatPerShot, MaxBarrelHeat);
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
CurrentBarrelHeat=0.0f
|
||||
LastBarrelHeat=0.0f
|
||||
NumPelletsDefault=0
|
||||
NumPelletsAlt=0
|
||||
}
|
144
KFGameContent/Classes/KFWeapAttach_Scythe.uc
Normal file
144
KFGameContent/Classes/KFWeapAttach_Scythe.uc
Normal file
@ -0,0 +1,144 @@
|
||||
//=============================================================================
|
||||
// KFWeapAttach_Scythe
|
||||
//=============================================================================
|
||||
//
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFWeapAttach_Scythe extends KFWeaponAttachment;
|
||||
|
||||
var const float UnfoldBlendingDuration;
|
||||
var const float UnfoldedAnimRateModifier;
|
||||
const FoldAnim = 'Clean_NoBlood';
|
||||
|
||||
var AnimTree CustomAnimTree;
|
||||
var AnimNodeBlendPerBone FoldBlendNode;
|
||||
|
||||
var transient bool bIsFolded;
|
||||
|
||||
event PreBeginPlay()
|
||||
{
|
||||
Super.PreBeginPlay();
|
||||
|
||||
// Override the animtree. Doing this here (before AttachTo) instead of in defaultprops
|
||||
// avoids an undesired call to our owning Pawn's PostInitAnimTree
|
||||
if ( CustomAnimTree != None )
|
||||
{
|
||||
WeapMesh.SetAnimTreeTemplate(CustomAnimTree);
|
||||
|
||||
WeapAnimNode = AnimNodeSequence(WeapMesh.FindAnimNode('WeaponSeq'));
|
||||
FoldBlendNode = AnimNodeBlendPerBone(WeapMesh.FindAnimNode('FoldBlendNode'));
|
||||
|
||||
// The special event might have arrived before the attachment is created, but it's updated in the owner, so copy the state here...
|
||||
if (KFPawn(Owner) != none && FoldBlendNode != none)
|
||||
{
|
||||
bIsFolded = KFPawn(Owner).WeaponSpecialAction == 0;
|
||||
FoldBlendNode.SetBlendTarget(bIsFolded ? 1.0f : 0.0f, 0.f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
simulated function ChangeMode()
|
||||
{
|
||||
bIsFolded = !bIsFolded;
|
||||
|
||||
// FoldControl = SkelControlSingleBone( WeapMesh.FindSkelControl('FoldControl') );
|
||||
if( FoldBlendNode != none )
|
||||
{
|
||||
FoldBlendNode.SetBlendTarget( bIsFolded ? 1.0f : 0.0f, 0.0f );
|
||||
}
|
||||
}
|
||||
|
||||
/** Called from the pawn when our first person weapon changes states */
|
||||
simulated function UpdateThirdPersonWeaponAction(EWeaponState NewWeaponState, KFPawn P, byte ThirdPersonAnimRateByte )
|
||||
{
|
||||
Super.UpdateThirdPersonWeaponAction(NewWeaponState, P, ThirdPersonAnimRate);
|
||||
|
||||
if (NewWeaponState == WEP_Cleaning)
|
||||
{
|
||||
if (WeapAnimNode != none)
|
||||
{
|
||||
if (WeapAnimNode.AnimSeq == none)
|
||||
{
|
||||
WeapAnimNode.SetAnim(FoldAnim);
|
||||
}
|
||||
|
||||
WeapAnimNode.PlayAnim();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
simulated function ANIMNOTIFY_ShellEject()
|
||||
{
|
||||
ChangeMode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Plays a split (upper and lower body) animation on the owning pawn
|
||||
* Network: All but dedicated
|
||||
*
|
||||
* @param P Owning pawn to play animation on
|
||||
* @param AnimName Anim to play
|
||||
* @param bPlaySynchronizedWeaponAnim If true, try to play the same animation on the weapon mesh
|
||||
*/
|
||||
simulated function float PlayCharacterMeshAnim(KFPawn P, name AnimName, optional bool bPlaySynchedWeaponAnim, optional bool bLooping)
|
||||
{
|
||||
local float AnimRate;
|
||||
local float Duration;
|
||||
local EAnimSlotStance Stance;
|
||||
local string AnimStr;
|
||||
|
||||
// skip weapon anims while in a special move
|
||||
if( P.IsDoingSpecialMove() && !P.SpecialMoves[P.SpecialMove].bAllowThirdPersonWeaponAnims )
|
||||
{
|
||||
return 0.f;
|
||||
}
|
||||
|
||||
Stance = (!P.bIsCrouched) ? EAS_UpperBody : EAS_CH_UpperBody;
|
||||
|
||||
AnimRate = ThirdPersonAnimRate;
|
||||
AnimStr = Caps(string(AnimName));
|
||||
|
||||
if (!bIsFolded && (InStr(AnimStr, "ATK") != INDEX_NONE || InStr(AnimName, "COMB") != INDEX_NONE))
|
||||
{
|
||||
AnimRate *= UnfoldedAnimRateModifier;
|
||||
}
|
||||
|
||||
Duration = P.PlayBodyAnim(AnimName, Stance, AnimRate, DefaultBlendInTime, DefaultBlendOutTime, bLooping);
|
||||
|
||||
if ( Duration > 0 && bPlaySynchedWeaponAnim )
|
||||
{
|
||||
PlayWeaponMeshAnim(AnimName, P.BodyStanceNodes[Stance], bLooping);
|
||||
}
|
||||
|
||||
`log(GetFuncName()@"called on:"$P@"Anim:"$AnimName@"Duration:"$Duration, bDebug);
|
||||
|
||||
return Duration;
|
||||
}
|
||||
|
||||
/** Special event added for weap attachments. Free for use */
|
||||
function OnSpecialEvent(int Arg)
|
||||
{
|
||||
bIsFolded = Arg == 0;
|
||||
|
||||
// FoldControl = SkelControlSingleBone( WeapMesh.FindSkelControl('FoldControl') );
|
||||
if( FoldBlendNode != none )
|
||||
{
|
||||
FoldBlendNode.SetBlendTarget( bIsFolded ? 1.0f : 0.0f, 0.0f );
|
||||
}
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
CustomAnimTree=AnimTree'WEP_Scythe_ARCH.3P_Scythe_Animtree'
|
||||
bIsFolded=true;
|
||||
UnfoldBlendingDuration=0.25f
|
||||
UnfoldedAnimRateModifier=0.7f;
|
||||
|
||||
// Weapon SkeletalMesh
|
||||
Begin Object Name=SkeletalMeshComponent0
|
||||
bForceRefPose=0
|
||||
End Object
|
||||
}
|
159
KFGameContent/Classes/KFWeap_AssaultRifle_G36C.uc
Normal file
159
KFGameContent/Classes/KFWeap_AssaultRifle_G36C.uc
Normal file
@ -0,0 +1,159 @@
|
||||
//=============================================================================
|
||||
// KFWeap_AssaultRifle_G36C
|
||||
//=============================================================================
|
||||
// Class Description
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFWeap_AssaultRifle_G36C extends KFWeap_SMGBase;
|
||||
|
||||
simulated function ZoomIn(bool bAnimateTransition, float ZoomTimeToGo)
|
||||
{
|
||||
super.ZoomIn(bAnimateTransition, ZoomTimeToGo);
|
||||
|
||||
if (LaserSight != none)
|
||||
{
|
||||
LaserSight.ChangeVisibility(false);
|
||||
}
|
||||
}
|
||||
|
||||
simulated function ZoomOut( bool bAnimateTransition, float ZoomTimeToGo )
|
||||
{
|
||||
super.ZoomOut( bAnimateTransition, ZoomTimeToGo );
|
||||
|
||||
if (LaserSight != none)
|
||||
{
|
||||
LaserSight.ChangeVisibility(true);
|
||||
}
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
bHasFireLastAnims=true
|
||||
BonesToLockOnEmpty=(RW_Bolt, RW_Charging_Handle)
|
||||
|
||||
// Shooting Animations
|
||||
FireSightedAnims[0]=Shoot_Iron
|
||||
FireSightedAnims[1]=Shoot_Iron2
|
||||
FireSightedAnims[2]=Shoot_Iron3
|
||||
|
||||
// FOV
|
||||
MeshFOV=70
|
||||
MeshIronSightFOV=20
|
||||
PlayerIronSightFOV=70
|
||||
|
||||
// Depth of field
|
||||
DOF_FG_FocalRadius=150
|
||||
DOF_FG_MaxNearBlurSize=3
|
||||
|
||||
// Zooming/Position
|
||||
IronSightPosition=(X=40,Y=0.1,Z=-4.57)
|
||||
PlayerViewOffset=(X=14,Y=11,Z=-5)
|
||||
|
||||
// Content
|
||||
PackageKey="G36C"
|
||||
FirstPersonMeshName="WEP_1P_G36C_MESH.Wep_1stP_G36C_Rig"
|
||||
FirstPersonAnimSetNames(0)="WEP_1P_G36C_ANIM.Wep_1stP_G36C_Anim"
|
||||
PickupMeshName="WEP_3P_G36C_MESH.Wep_G36C_Pickup"
|
||||
AttachmentArchetypeName="WEP_G36C_ARCH.Wep_G36C_3P"
|
||||
MuzzleFlashTemplateName="WEP_G36C_ARCH.Wep_G36C_MuzzleFlash"
|
||||
|
||||
LaserSightTemplate=KFLaserSightAttachment'FX_LaserSight_ARCH.LaserSight_WithAttachment_1P'
|
||||
|
||||
// Ammo
|
||||
MagazineCapacity[0]=30
|
||||
SpareAmmoCapacity[0]=450
|
||||
InitialSpareMags[0]=3
|
||||
bCanBeReloaded=true
|
||||
bReloadFromMagazine=true
|
||||
|
||||
// Recoil
|
||||
maxRecoilPitch=90
|
||||
minRecoilPitch=80
|
||||
maxRecoilYaw=80
|
||||
minRecoilYaw=-80
|
||||
RecoilRate=0.085
|
||||
RecoilMaxYawLimit=500
|
||||
RecoilMinYawLimit=65035
|
||||
RecoilMaxPitchLimit=900
|
||||
RecoilMinPitchLimit=65035
|
||||
RecoilISMaxYawLimit=100
|
||||
RecoilISMinYawLimit=65460
|
||||
RecoilISMaxPitchLimit=350
|
||||
RecoilISMinPitchLimit=65460
|
||||
IronSightMeshFOVCompensationScale=4.0
|
||||
|
||||
// Old Recoil Data
|
||||
// maxRecoilPitch=80
|
||||
// minRecoilPitch=65
|
||||
// maxRecoilYaw=60
|
||||
// minRecoilYaw=-60
|
||||
// RecoilRate=0.063
|
||||
// RecoilMaxYawLimit=400
|
||||
// RecoilMinYawLimit=65135
|
||||
// RecoilMaxPitchLimit=800
|
||||
// RecoilMinPitchLimit=65035
|
||||
// RecoilISMaxYawLimit=150
|
||||
// RecoilISMinYawLimit=65385
|
||||
// RecoilISMaxPitchLimit=350
|
||||
// RecoilISMinPitchLimit=65435
|
||||
// IronSightMeshFOVCompensationScale=1.5
|
||||
|
||||
// Inventory
|
||||
InventorySize=7
|
||||
GroupPriority=100
|
||||
WeaponSelectTexture=Texture2D'wep_ui_g36c_tex.UI_WeaponSelect_G36C'
|
||||
|
||||
// DEFAULT_FIREMODE
|
||||
FireModeIconPaths(DEFAULT_FIREMODE)=Texture2D'ui_firemodes_tex.UI_FireModeSelect_BulletAuto'
|
||||
FiringStatesArray(DEFAULT_FIREMODE)=WeaponFiring
|
||||
WeaponFireTypes(DEFAULT_FIREMODE)=EWFT_InstantHit
|
||||
WeaponProjectiles(DEFAULT_FIREMODE)=class'KFProj_Bullet_AssaultRifle'
|
||||
InstantHitDamageTypes(DEFAULT_FIREMODE)=class'KFDT_Ballistic_G36C'
|
||||
PenetrationPower(DEFAULT_FIREMODE)=4.0
|
||||
FireInterval(DEFAULT_FIREMODE)=+0.08 // 750 RPM
|
||||
Spread(DEFAULT_FIREMODE)=0.005
|
||||
InstantHitDamage(DEFAULT_FIREMODE)=45.0
|
||||
FireOffset=(X=30,Y=4.5,Z=-5)
|
||||
|
||||
// ALT_FIREMODE
|
||||
FireModeIconPaths(ALTFIRE_FIREMODE)=Texture2D'ui_firemodes_tex.UI_FireModeSelect_BulletSingle'
|
||||
FiringStatesArray(ALTFIRE_FIREMODE)=WeaponSingleFiring
|
||||
WeaponFireTypes(ALTFIRE_FIREMODE)=EWFT_InstantHit
|
||||
WeaponProjectiles(ALTFIRE_FIREMODE)=class'KFProj_Bullet_AssaultRifle'
|
||||
InstantHitDamageTypes(ALTFIRE_FIREMODE)=class'KFDT_Ballistic_G36C'
|
||||
PenetrationPower(ALTFIRE_FIREMODE)=4.0
|
||||
FireInterval(ALTFIRE_FIREMODE)=+0.08 // 750 RPM
|
||||
InstantHitDamage(ALTFIRE_FIREMODE)=45.0
|
||||
Spread(ALTFIRE_FIREMODE)=0.005
|
||||
|
||||
// BASH_FIREMODE
|
||||
InstantHitDamageTypes(BASH_FIREMODE)=class'KFDT_Bludgeon_G36C'
|
||||
InstantHitDamage(BASH_FIREMODE)=26
|
||||
|
||||
// Fire Effects
|
||||
WeaponFireSnd(DEFAULT_FIREMODE)=(DefaultCue=AkEvent'WW_WEP_G36C.Play_WEP_G36C_3P_Shoot_LP', FirstPersonCue=AkEvent'WW_WEP_G36C.Play_WEP_G36C_1P_Shoot_LP')
|
||||
WeaponFireSnd(ALTFIRE_FIREMODE)=(DefaultCue=AkEvent'WW_WEP_G36C.Play_WEP_G36C_3P_Shoot_Single', FirstPersonCue=AkEvent'WW_WEP_G36C.Play_WEP_G36C_1P_Shoot_Single')
|
||||
WeaponDryFireSnd(DEFAULT_FIREMODE)=AkEvent'WW_WEP_SA_AK12.Play_WEP_SA_AK12_Handling_DryFire' //@TODO: Replace me
|
||||
WeaponDryFireSnd(ALTFIRE_FIREMODE)=AkEvent'WW_WEP_SA_AK12.Play_WEP_SA_AK12_Handling_DryFire' //@TODO: Replace me
|
||||
// WeaponDryFireSnd(DEFAULT_FIREMODE)=AkEvent'WW_WEP_G36C.Play_WEP_G36C_Dry_Fire'
|
||||
// WeaponDryFireSnd(ALTFIRE_FIREMODE)=AkEvent'WW_WEP_G36C.Play_WEP_G36C_Dry_Fire'
|
||||
|
||||
// Advanced (High RPM) Fire Effects
|
||||
bLoopingFireAnim(DEFAULT_FIREMODE)=true
|
||||
bLoopingFireSnd(DEFAULT_FIREMODE)=true
|
||||
WeaponFireLoopEndSnd(DEFAULT_FIREMODE)=(DefaultCue=AkEvent'WW_WEP_G36C.Play_WEP_G36C_3P_End_LP', FirstPersonCue=AkEvent'WW_WEP_G36C.Play_WEP_G36C_1P_End_LP')
|
||||
SingleFireSoundIndex=ALTFIRE_FIREMODE
|
||||
|
||||
// Attachments
|
||||
bHasIronSights=true
|
||||
bHasFlashlight=false
|
||||
bHasLaserSight=true
|
||||
|
||||
AssociatedPerkClasses(0)=class'KFPerk_Swat'
|
||||
|
||||
// Weapon Upgrade stat boosts
|
||||
WeaponUpgrades[1]=(Stats=((Stat=EWUS_Damage0, Scale=1.15f), (Stat=EWUS_Damage1, Scale=1.15f), (Stat=EWUS_Weight, Add=1)))
|
||||
}
|
@ -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
|
||||
|
@ -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
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user