Added perk changing without dying

Fixed scoreboard avatars not working
Added the ServerExt perk menu to the lobby
Made the perk buttons look better (Reset, Unload, Prestige)
Added a better damage popup system
Added a better pet info hud system
Made player info bars fade out with distance
Added missing traits from most of the perks
Made lobby menu support 12 players
Medic Pistol from the trait can't be dropped, sold and has infinite ammo
9mm Pistol now has infinite ammo
Pet sirens do not blow up grenades
Unlocked all cosmetics and emotes
Hide bad cosmetics that were debug
Hans pet no longer forces the camera on his death
Custom weapons in the trader now support the proper weapon names
Updated character info system to support alot of added items
This commit is contained in:
Forrest Keller 2017-10-20 02:02:53 -05:00
parent 830a70436e
commit 88f2c71e54
70 changed files with 4874 additions and 343 deletions

View File

@ -191,13 +191,15 @@ static final function SetHeadMeshAndSkin( KFCharacterInfo_Human C,
byte CurrentHeadSkinIndex,
KFPawn KFP )
{
local string CharHeadMeshName;
local SkeletalMesh CharHeadMesh;
if ( C.HeadVariants.length > 0 )
{
CurrentHeadMeshIndex = (CurrentHeadMeshIndex < C.HeadVariants.length) ? CurrentHeadMeshIndex : 0;
CharHeadMesh = SkeletalMesh(SafeLoadObject(C.HeadVariants[CurrentHeadMeshIndex].MeshName, class'SkeletalMesh'));
CharHeadMeshName = C.HeadVariants[CurrentHeadMeshIndex].MeshName;
CharHeadMesh = SkeletalMesh(DynamicLoadObject(CharHeadMeshName, class'SkeletalMesh'));
// Parent the third person head mesh to the body mesh
KFP.ThirdPersonHeadMeshComponent.SetSkeletalMesh(CharHeadMesh);
@ -223,17 +225,16 @@ static final function SetAttachmentSkinMaterial( KFCharacterInfo_Human C,
KFPawn KFP)
{
local int i;
if (KFP.WorldInfo.NetMode != NM_DedicatedServer)
{
if( CurrentVariant.SkinVariations.length > 0 )
if( CurrentVariant.AttachmentItem.SkinVariations.length > 0 )
{
// Assign a skin to the attachment mesh as a material override
if ( NewSkinIndex < CurrentVariant.SkinVariations.length )
if ( NewSkinIndex < CurrentVariant.AttachmentItem.SkinVariations.length )
{
KFP.ThirdPersonAttachments[PawnAttachmentIndex].SetMaterial(
CurrentVariant.SkinMaterialID,
CurrentVariant.SkinVariations[NewSkinIndex].Skin);
CurrentVariant.AttachmentItem.SkinMaterialID,
CurrentVariant.AttachmentItem.SkinVariations[NewSkinIndex].Skin);
}
else
{
@ -273,7 +274,9 @@ static final function SetAttachmentMeshAndSkin( KFCharacterInfo_Human C,
local int AttachmentSlotIndex;
if (KFP.WorldInfo.NetMode == NM_DedicatedServer)
{
return;
}
// Clear any previously attachments for the same slot
//DetachConflictingAttachments(CurrentAttachmentMeshIndex, KFP, KFPRI);
@ -282,22 +285,18 @@ static final function SetAttachmentMeshAndSkin( KFCharacterInfo_Human C,
// Since cosmetic attachments are optional, do not choose index 0 if none is
// specified unlike the the head and body meshes
if ( C.CosmeticVariants.length > 0 && CurrentAttachmentMeshIndex < C.CosmeticVariants.length )
if ( C.CosmeticVariants.length > 0 &&
CurrentAttachmentMeshIndex < C.CosmeticVariants.length )
{
// Cache values from character info
CharAttachmentMeshName = C.CosmeticVariants[CurrentAttachmentMeshIndex].MeshName;
CharAttachmentSocketName = C.CosmeticVariants[CurrentAttachmentMeshIndex].SocketName;
MaxDrawDistance = C.CosmeticVariants[CurrentAttachmentMeshIndex].MaxDrawDistance;
CharAttachmentMeshName = C.GetMeshByIndex(CurrentAttachmentMeshIndex);
CharAttachmentSocketName = C.CosmeticVariants[CurrentAttachmentMeshIndex].AttachmentItem.SocketName;
MaxDrawDistance = C.CosmeticVariants[CurrentAttachmentMeshIndex].AttachmentItem.MaxDrawDistance;
AttachmentLocationRelativeToSocket = C.CosmeticVariants[CurrentAttachmentMeshIndex].RelativeTranslation;
AttachmentRotationRelativeToSocket = C.CosmeticVariants[CurrentAttachmentMeshIndex].RelativeRotation;
AttachmentScaleRelativeToSocket = C.CosmeticVariants[CurrentAttachmentMeshIndex].RelativeScale;
bIsSkeletalAttachment = C.CosmeticVariants[CurrentAttachmentMeshIndex].bIsSkeletalAttachment;
bIsSkeletalAttachment = C.CosmeticVariants[CurrentAttachmentMeshIndex].AttachmentItem.bIsSkeletalAttachment;
// If it is a skeletal attachment, parent anim it to the body mesh
if( bIsSkeletalAttachment )
{
if( SkeletalMeshComponent(KFP.ThirdPersonAttachments[AttachmentSlotIndex]) != none )
{
// If previously attached and we could have changed outfits (e.g. local player UI) then re-validate
// required skeletal mesh socket. Must be after body mesh DLO, but before AttachComponent.
if ( KFP.IsLocallyControlled() )
@ -309,6 +308,12 @@ static final function SetAttachmentMeshAndSkin( KFCharacterInfo_Human C,
}
}
//`log("AttachmentLocationRelativeToSocket: x="$AttachmentLocationRelativeToSocket.x@"y="$AttachmentLocationRelativeToSocket.y@"z="$AttachmentLocationRelativeToSocket.z);
// If it is a skeletal attachment, parent anim it to the body mesh
if( bIsSkeletalAttachment )
{
if( SkeletalMeshComponent(KFP.ThirdPersonAttachments[AttachmentSlotIndex]) != none )
{
SkeletalAttachment = SkeletalMeshComponent(KFP.ThirdPersonAttachments[AttachmentSlotIndex]);
}
else
@ -319,7 +324,7 @@ static final function SetAttachmentMeshAndSkin( KFCharacterInfo_Human C,
}
// Load and assign skeletal mesh
CharacterAttachmentSkelMesh = SkeletalMesh(SafeLoadObject(CharAttachmentMeshName, class'SkeletalMesh'));
CharacterAttachmentSkelMesh = SkeletalMesh(DynamicLoadObject(CharAttachmentMeshName, class'SkeletalMesh'));
SkeletalAttachment.SetSkeletalMesh(CharacterAttachmentSkelMesh);
// Parent animation and LOD transitions to body mesh
@ -348,7 +353,7 @@ static final function SetAttachmentMeshAndSkin( KFCharacterInfo_Human C,
}
// Load and assign static mesh
CharAttachmentStaticMesh = StaticMesh(SafeLoadObject(CharAttachmentMeshName, class'StaticMesh'));
CharAttachmentStaticMesh = StaticMesh(DynamicLoadObject(CharAttachmentMeshName, class'StaticMesh'));
StaticAttachment.SetStaticMesh(CharAttachmentStaticMesh);
// Set properties
@ -371,7 +376,8 @@ static final function SetAttachmentMeshAndSkin( KFCharacterInfo_Human C,
KFP.ThirdPersonAttachmentBitMask = KFP.ThirdPersonAttachmentBitMask | (1 << AttachmentSlotIndex);
KFP.ThirdPersonAttachmentSocketNames[AttachmentSlotIndex] = CharAttachmentSocketName;
SetAttachmentSkinMaterial(C,
SetAttachmentSkinMaterial(
C,
AttachmentSlotIndex,
C.CosmeticVariants[CurrentAttachmentMeshIndex],
CurrentAttachmentSkinIndex,

View File

@ -0,0 +1,110 @@
class ExtEmoteList extends Object
abstract;
var const array<Emote> Emotes;
static final function name GetUnlockedEmote( int ItemId, ExtPlayerController PC )
{
local int i;
local name Anim;
local ExtPlayerReplicationInfo PRI;
i = default.Emotes.Find('Id', ItemId);
if( i > -1 )
{
Anim = default.Emotes[i].AnimName;
PRI = ExtPlayerReplicationInfo(PC.PlayerReplicationInfo);
if( PRI == None )
return Anim;
/*
if( InStr(string(Anim), "Deluxe") != INDEX_NONE && PRI.AdminType == 255 )
return 'NONE';
*/
else return Anim;
}
return 'NONE';
}
static final function SaveEquippedEmote( int ItemId, ExtPlayerController PC )
{
if( PC == None )
return;
PC.SelectedEmoteIndex = ItemId;
PC.SaveConfig();
}
static final function array<Emote> GetEmoteArray()
{
return default.Emotes;
}
static final function byte GetEmoteIndex( int ItemId )
{
local int i;
i = default.Emotes.Find('Id', ItemId);
if( i > -1 )
return i;
return -1;
}
static final function int GetEquippedEmoteId(ExtPlayerController PC)
{
if( PC == None )
return -1;
return PC.SelectedEmoteIndex;
}
static final function name GetEmoteFromIndex(byte EmoteIndex)
{
return default.Emotes[EmoteIndex].AnimName;
}
defaultproperties
{
Emotes.Add((Id=4515, ItemName = "LetsGetCrazy", AnimName="Emote_01_LetsGetCrazy", IconPath="EMOTE_TEX.Emote_LetsGoCrazy_512"))
Emotes.Add((Id=4516, ItemName = "ThunderClap", AnimName="Emote_02_ThunderClap", IconPath="EMOTE_TEX.Emote_Thunderclap_512"))
Emotes.Add((Id=4517, ItemName = "UncleCharlie", AnimName="Emote_03_UncleCharlie", IconPath="EMOTE_TEX.Emote_UncleCharlie_512"))
Emotes.Add((Id=4518, ItemName = "WackyWave", AnimName="Emote_04_WackyWave", IconPath="EMOTE_TEX.Emote_WackyWave_512"))
Emotes.Add((Id=4519, ItemName = "RainingDosh", AnimName="Emote_05_RainingDosh", IconPath="EMOTE_TEX.Emote_RainingDosh_512"))
Emotes.Add((Id=4520, ItemName = "LionUppercut", AnimName="Emote_06_LionUppercut", IconPath="EMOTE_TEX.Emote_Uppercut_512"))
Emotes.Add((Id=0, ItemName = "MatingRitual", AnimName="Emote_07_MatingRitual", IconPath="EMOTE_TEX.Emote_MatingRitual_512"))
Emotes.Add((Id=4522, ItemName = "KickinIt", AnimName="Emote_08_KickinIt", IconPath="EMOTE_TEX.Emote_KicknIt_512"))
Emotes.Add((Id=4523, ItemName = "Fireball", AnimName="Emote_09_Fireball", IconPath="EMOTE_TEX.Emote_Fireball_512"))
Emotes.Add((Id=4524, ItemName = "Makeitrain", AnimName="Emote_10_Makeitrain", IconPath="EMOTE_TEX.Emote_MknRain_512"))
Emotes.Add((Id=4744, ItemName = "TheCossack", AnimName="Emote_01_Dance", IconPath="EMOTE_TEX_02.Emote_02_Squat_Dance_512"))
Emotes.Add((Id=4745, ItemName = "TheWave", AnimName="Emote_02_Dance", IconPath="EMOTE_TEX_02.Emote_02_The_Wave_512"))
Emotes.Add((Id=4746, ItemName = "Breakin", AnimName="Emote_03_Dance", IconPath="EMOTE_TEX_02.Emote_02_Handstand_512"))
Emotes.Add((Id=4747, ItemName = "NoHands", AnimName="Emote_04_Dance", IconPath="EMOTE_TEX_02.Emote_02_Kap_Kick_512"))
Emotes.Add((Id=4748, ItemName = "HealClick", AnimName="Emote_05_Dance", IconPath="EMOTE_TEX_02.Emote_02_Click_It_512"))
Emotes.Add((Id=4749, ItemName = "TheSprinkler", AnimName="Emote_06_Dance", IconPath="EMOTE_TEX_02.Emote_02_The_Sprinkler_512"))
Emotes.Add((Id=4750, ItemName = "Maniac", AnimName="Emote_07_Dance", IconPath="EMOTE_TEX_02.Emote_02_Running_Dosh_512"))
Emotes.Add((Id=4751, ItemName = "RunningMan", AnimName="Emote_08_Dance", IconPath="EMOTE_TEX_02.Emote_02_Running_Man_512"))
Emotes.Add((Id=4752, ItemName = "TheRobot", AnimName="Emote_09_Dance", IconPath="EMOTE_TEX_02.Emote_02_The_Robot_512"))
Emotes.Add((Id=4753, ItemName = "AirMetal", AnimName="Emote_10_Dance", IconPath="EMOTE_TEX_02.Emote_02_Guitar_Solo_512"))
Emotes.Add((Id=4525, ItemName = "Fireball_Deluxe", AnimName="Emote_09_Fireball_Deluxe", IconPath="EMOTE_TEX.Emote_Fireball_DLX_512"))
Emotes.Add((Id=4526, ItemName = "Makeitrain_Deluxe", AnimName="Emote_10_Makeitrain_Deluxe", IconPath="EMOTE_TEX.Emote_MknRain_DLX_512"))
Emotes.Add((Id=4527, ItemName = "ThunderClap_Deluxe", AnimName="Emote_02_ThunderClap_Deluxe", IconPath="EMOTE_TEX.Emote_Thunderclap_DLX_512"))
Emotes.Add((Id=4528, ItemName = "UncleCharlie_Deluxe", AnimName="Emote_03_UncleCharlie_Deluxe",IconPath="EMOTE_TEX.Emote_UncleCharlie_DLX_512"))
Emotes.Add((Id=4529, ItemName = "LetsGetCrazy_Deluxe", AnimName="Emote_01_LetsGetCrazy_Deluxe",IconPath="EMOTE_TEX.Emote_LetsGoCrazy_DLX_512"))
Emotes.Add((Id=4530, ItemName = "WackyWave_Deluxe", AnimName="Emote_04_WackyWave_Deluxe", IconPath="EMOTE_TEX.Emote_WackyWave_DLX_512"))
Emotes.Add((Id=4531, ItemName = "RainingDosh_Deluxe", AnimName="Emote_05_RainingDosh_Deluxe", IconPath="EMOTE_TEX.Emote_RainingDosh_DLX_512"))
Emotes.Add((Id=4532, ItemName = "LionUppercut_Deluxe", AnimName="Emote_06_LionUppercut_Deluxe",IconPath="EMOTE_TEX.Emote_Uppercut_DLX_512"))
Emotes.Add((Id=4533, ItemName = "MatingRitual_Deluxe", AnimName="Emote_07_MatingRitual_Deluxe",IconPath="EMOTE_TEX.Emote_MatingRitual_DLX_512"))
Emotes.Add((Id=4534, ItemName = "KickinIt_Deluxe", AnimName="Emote_08_KickinIt_Deluxe", IconPath="EMOTE_TEX.Emote_KicknIt_DLX_512"))
Emotes.Add((Id=4754, ItemName = "TheCossack_Deluxe", AnimName="Emote_01_Dance_Deluxe", IconPath="EMOTE_TEX_02.Emote_02_Squat_Dance_DLX_512"))
Emotes.Add((Id=4755, ItemName = "TheWave_Deluxe", AnimName="Emote_02_Dance_Deluxe", IconPath="EMOTE_TEX_02.Emote_02_The_Wave_DLX_512"))
Emotes.Add((Id=4756, ItemName = "Breakin_Deluxe", AnimName="Emote_03_Dance_Deluxe", IconPath="EMOTE_TEX_02.Emote_02_Handstand_DLX_512"))
Emotes.Add((Id=4757, ItemName = "NoHands_Deluxe", AnimName="Emote_04_Dance_Deluxe", IconPath="EMOTE_TEX_02.Emote_02_Kap_Kick_DLX_512"))
Emotes.Add((Id=4758, ItemName = "HealClick_Deluxe", AnimName="Emote_05_Dance_Deluxe", IconPath="EMOTE_TEX_02.Emote_02_Click_It_DLX_512"))
Emotes.Add((Id=4759, ItemName = "TheSprinkler_Deluxe", AnimName="Emote_06_Dance_Deluxe", IconPath="EMOTE_TEX_02.Emote_02_The_Sprinkler_DLX_512"))
Emotes.Add((Id=4760, ItemName = "Maniac_Deluxe", AnimName="Emote_07_Dance_Deluxe", IconPath="EMOTE_TEX_02.Emote_02_Running_Dosh_DLX_512"))
Emotes.Add((Id=4761, ItemName = "RunningMan_Deluxe", AnimName="Emote_08_Dance_Deluxe", IconPath="EMOTE_TEX_02.Emote_02_Running_Man_DLX_512"))
Emotes.Add((Id=4762, ItemName = "TheRobot_Deluxe", AnimName="Emote_09_Dance_Deluxe", IconPath="EMOTE_TEX_02.Emote_02_The_Robot_DLX_512"))
Emotes.Add((Id=4763, ItemName = "AirMetal_Deluxe", AnimName="Emote_10_Dance_Deluxe", IconPath="EMOTE_TEX_02.Emote_02_Guitar_Solo_DLX_512"))
}

View File

@ -0,0 +1,10 @@
class ExtExplosion_SirenScream extends KFExplosion_SirenScream;
protected function SpecialCringeEffectsFor(Actor Victim, float VictimDist)
{
return;
}
DefaultProperties
{
}

View File

@ -0,0 +1,59 @@
Class ExtGUI_PerkSelectionPage extends UI_MidGameMenu;
function InitMenu()
{
local byte i;
local KFGUI_Button B;
PageSwitcher = KFGUI_SwitchMenuBar(FindComponentID('Pager'));
Super(KFGUI_Page).InitMenu();
for( i=0; i<Pages.Length; ++i )
{
PageSwitcher.AddPage(Pages[i].PageClass,Pages[i].Caption,Pages[i].Hint,B).InitMenu();
}
}
function ShowMenu()
{
Super(KFGUI_FloatingWindow).ShowMenu();
}
function PreDraw()
{
local GameViewportClient Viewport;
local ExtMoviePlayer_Manager MovieManager;
Super.PreDraw();
Viewport = LocalPlayer(GetPlayer().Player).ViewportClient;
MovieManager = ExtMoviePlayer_Manager(KFPlayerController(GetPlayer()).MyGFxManager);
if( CaptureMouse() )
{
Viewport.bDisplayHardwareMouseCursor = true;
Viewport.ForceUpdateMouseCursor(true);
MovieManager.SetMovieCanReceiveInput(false);
}
else if( Viewport.bDisplayHardwareMouseCursor )
{
Viewport.bDisplayHardwareMouseCursor = false;
Viewport.ForceUpdateMouseCursor(true);
MovieManager.SetMovieCanReceiveInput(true);
}
}
function UserPressedEsc();
defaultproperties
{
WindowTitle=""
XPosition=0.01
XSize=0.73
YSize=0.73
Pages.Empty
Pages.Add((PageClass=Class'UIP_PerkSelectionLobby',Caption="Perk",Hint="Select and upgrade your perks"))
}

View File

@ -0,0 +1,90 @@
class ExtHUD_WeaponSelectWidget extends KFGFxHUD_WeaponSelectWidget;
var transient array< class<KFWeaponDefinition> > WeaponGroup;
simulated function UpdateWeaponGroupOnHUD( byte GroupIndex )
{
local Inventory Inv;
local KFWeapon KFW;
local byte i;
local int Index;
local array<KFWeapon> WeaponsList;
local KFGFxObject_TraderItems TraderItems;
local Pawn P;
local array< class<KFWeaponDefinition> > WPGroup;
P = GetPC().Pawn;
if ( P == none || P.InvManager == none )
return;
for ( Inv = P.InvManager.InventoryChain; Inv != none; Inv = Inv.Inventory )
{
KFW = KFWeapon( Inv );
if ( KFW != none && KFW.InventoryGroup == GroupIndex )
WeaponsList.AddItem(KFW);
}
WPGroup.Length = WeaponsList.Length;
TraderItems = KFGameReplicationInfo( P.WorldInfo.GRI ).TraderItems;
for ( i = 0; i < WeaponsList.Length; i++ )
{
Index = TraderItems.SaleItems.Find('ClassName', WeaponsList[i].Class.Name);
if( Index != -1 )
WPGroup[i] = TraderItems.SaleItems[Index].WeaponDef;
}
WeaponGroup = WPGroup;
SetWeaponGroupList(WeaponsList, GroupIndex);
}
simulated function SetWeaponGroupList(out array<KFWeapon> WeaponList, byte GroupIndex)
{
local byte i;
local GFxObject DataProvider;
local GFxObject TempObj;
local bool bUsesAmmo;
DataProvider = CreateArray();
if ( DataProvider == None )
return; // gfx has been shut down
for (i = 0; i < WeaponList.length; i++)
{
TempObj = CreateObject( "Object" );
if( WeaponGroup[i] != None )
{
TempObj.SetString( "weaponName", WeaponGroup[i].static.GetItemLocalization("ItemName") );
TempObj.SetString( "texturePath", "img://"$WeaponGroup[i].static.GetImagePath() );
}
else
{
TempObj.SetString( "weaponName", WeaponList[i].ItemName );
TempObj.SetString( "texturePath", "img://"$PathName(WeaponList[i].WeaponSelectTexture));
}
TempObj.SetInt( "ammoCount", WeaponList[i].AmmoCount[0]);
TempObj.SetInt( "spareAmmoCount", WeaponList[i].SpareAmmoCount[0]);
//secondary ammo shenanigans
TempObj.SetBool("bUsesSecondaryAmmo", WeaponList[i].UsesSecondaryAmmo()&&WeaponList[i].bCanRefillSecondaryAmmo);
TempObj.SetBool("bEnabled", WeaponList[i].HasAnyAmmo());
if(WeaponList[i].UsesSecondaryAmmo() && WeaponList[i].bCanRefillSecondaryAmmo)
{
TempObj.SetBool("bCanRefillSecondaryAmmo", WeaponList[i].SpareAmmoCapacity[1] > 0);
TempObj.SetInt( "secondaryAmmoCount", WeaponList[i].AmmoCount[1]);
TempObj.SetInt( "secondarySpareAmmoCount", WeaponList[i].SpareAmmoCount[1]);
}
TempObj.SetBool( "throwable", WeaponList[i].CanThrow());
bUsesAmmo = (WeaponList[i].static.UsesAmmo());
TempObj.SetBool( "bUsesAmmo", bUsesAmmo);
DataProvider.SetElementObject( i, TempObj );
}
SetWeaponList(DataProvider, GroupIndex);
}
DefaultProperties
{
}

View File

@ -14,12 +14,16 @@ var byte UnfeignFailedCount,RepRegenHP,BHopAccelSpeed;
var repnotify bool bFeigningDeath;
var bool bPlayingFeignDeathRecovery,bRagdollFromFalling,bRagdollFromBackhit,bRagdollFromMomentum,bCanBecomeRagdoll,bRedeadMode,bPendingRedead,bHasBunnyHop,bOnFirstPerson,bFPLegsAttached,bFPLegsInit;
var byte HealingShieldMod,HealingSpeedBoostMod,HealingDamageBoostMod;
replication
{
if( true )
bFeigningDeath,RepRegenHP,BackpackWeaponClass;
if( bNetOwner )
bHasBunnyHop;
if( bNetDirty )
HealingSpeedBoostMod, HealingDamageBoostMod, HealingShieldMod;
}
function TakeDamage(int Damage, Controller InstigatedBy, vector HitLocation, vector Momentum, class<DamageType> DamageType, optional TraceHitInfo HitInfo, optional Actor DamageCauser)
@ -111,16 +115,32 @@ event bool HealDamage(int Amount, Controller Healer, class<DamageType> DamageTyp
local ExtPlayerController InstigatorPC, KFPC;
local KFPerk InstigatorPerk;
local class<KFDamageType> KFDT;
local int i,OldHealth;
local int i;
local bool bRepairedArmor;
local ExtPlayerReplicationInfo EPRI;
local Ext_PerkBase InstigatorExtPerk;
OldHealth = Health;
InstigatorPC = ExtPlayerController(Healer);
InstigatorPerk = InstigatorPC != None ? InstigatorPC.GetPerk() : None;
InstigatorPerk = InstigatorPC.GetPerk();
if( InstigatorPerk != None && bCanRepairArmor )
bRepairedArmor = InstigatorPC.GetPerk().RepairArmor( self );
EPRI = ExtPlayerReplicationInfo(InstigatorPC.PlayerReplicationInfo);
if( EPRI != none )
{
// Instigator might be able to repair some armomr
bRepairedArmor = InstigatorPerk.RepairArmor( self );
InstigatorExtPerk = ExtPlayerController(Controller).ActivePerkManager.CurrentPerk;
if( InstigatorExtPerk != none && Ext_PerkFieldMedic(InstigatorExtPerk) != none )
{
if( Ext_PerkFieldMedic(InstigatorExtPerk).bHealingBoost )
UpdateHealingSpeedBoostMod(InstigatorPC);
if( Ext_PerkFieldMedic(InstigatorExtPerk).bHealingDamageBoost )
UpdateHealingDamageBoostMod(InstigatorPC);
if( Ext_PerkFieldMedic(InstigatorExtPerk).bHealingShield )
UpdateHealingShieldMod(InstigatorPC);
}
}
if( Amount > 0 && IsAliveAndWell() && Health < HealthMax )
@ -151,10 +171,6 @@ event bool HealDamage(int Amount, Controller Healer, class<DamageType> DamageTyp
if( !IsTimerActive('GiveHealthOverTime') )
SetTimer(HealthRegenRate, true, 'GiveHealthOverTime');
// Airborne agent hack.
if( ExtPerkManager(InstigatorPerk)!= none && DamageType!=Class'KFDT_Healing' )
ExtPerkManager(InstigatorPerk).CheckForAirborneAgent(Self,DamageType,UsedHealAmount);
// Give the healer money/XP for helping a teammate
if( Healer.Pawn != none && Healer.Pawn != self )
{
@ -171,18 +187,14 @@ event bool HealDamage(int Amount, Controller Healer, class<DamageType> DamageTyp
{
if( InstigatorPC!=None )
{
//`RecordAARIntStat(InstigatorPC, HEAL_GIVEN, UsedHealAmount);
if( !InstigatorPC.bClientHideNumbers )
InstigatorPC.ClientNumberMsg(UsedHealAmount,Location,DMG_Heal);
InstigatorPC.ReceiveLocalizedMessage( class'KFLocalMessage_Game', GMT_HealedPlayer, PlayerReplicationInfo );
}
KFPC = ExtPlayerController(Controller);
if( KFPC!=None )
{
//`RecordAARIntStat(KFPC, HEAL_RECEIVED, UsedHealAmount);
KFPC.ReceiveLocalizedMessage( class'KFLocalMessage_Game', GMT_HealedBy, Healer.PlayerReplicationInfo );
}
}
else if( bMessageHealer && InstigatorPC!=None )
InstigatorPC.ReceiveLocalizedMessage( class'KFLocalMessage_Game', GMT_HealedSelf, PlayerReplicationInfo );
}
@ -204,9 +216,6 @@ event bool HealDamage(int Amount, Controller Healer, class<DamageType> DamageTyp
}
}
if (Health - OldHealth > 0)
WorldInfo.Game.ScoreHeal(Health - OldHealth, OldHealth, Healer, self, DamageType);
return true;
}
}
@ -1063,6 +1072,7 @@ simulated final function SetBackpackWeapon( class<KFWeapon> WC )
local Rotator MyRot;
local Vector MyPos;
local name WM,B;
local int i;
BackpackWeaponClass = WC;
if( WorldInfo.NetMode==NM_DedicatedServer )
@ -1077,47 +1087,47 @@ simulated final function SetBackpackWeapon( class<KFWeapon> WC )
AttachedBackItem.SetLightingChannels(PawnLightingChannel);
}
AttachedBackItem.SetSkeletalMesh(WC.Default.AttachmentArchetype.SkelMesh);
for( i=0; i<WC.Default.AttachmentArchetype.SkelMesh.Materials.length; i++ )
{
AttachedBackItem.SetMaterial(i, WC.Default.AttachmentArchetype.SkelMesh.Materials[i]);
}
Mesh.DetachComponent(AttachedBackItem);
MyCharacter = KFPlayerReplicationInfo(PlayerReplicationInfo).CharacterArchetypes[KFPlayerReplicationInfo(PlayerReplicationInfo).RepCustomizationInfo.CharacterIndex];
WM = WC.Default.AttachmentArchetype.SkelMesh.Name;
switch( WM )
if( ClassIsChildOf(WC, class'KFWeap_Edged_Knife') )
{
MyPos = vect(0,0,10);
MyRot = rot(-16384,-8192,0);
B = 'LeftUpLeg';
}
else if( class<KFWeap_Welder>(WC) != none || class<KFWeap_Healer_Syringe>(WC) != none || class<KFWeap_Pistol_Medic>(WC) != none || class<KFWeap_SMG_Medic>(WC) != none || ClassIsChildOf(WC, class'KFWeap_PistolBase') || ClassIsChildOf(WC, class'KFWeap_SMGBase') || ClassIsChildOf(WC, class'KFWeap_ThrownBase') )
{
case 'Wep_3rdP_Welder_Rig':
case 'Wep_3rdP_Healer_Rig':
case 'Wep_3rdP_Medic_SMG_Rig':
case 'Wep_3rdP_9mm_Rig':
case 'Wep_3rdP_Medic_Pistol_Rig':
MyPos = vect(0,0,10);
MyRot = rot(0,0,16384);
B = 'LeftUpLeg';
break;
case 'Wep_3rdP_Katana_Rig':
case 'Wep_3rdP_Crovel_Rig':
case 'Wep_3rdP_Pulverizer_Rig':
}
else if( ClassIsChildOf(WC, class'KFWeap_MeleeBase') )
{
MyPos = vect(-5,15,0);
MyRot = rot(0,0,0);
switch( WM )
{
case 'Wep_3rdP_Katana_Rig':
if( class<KFWeap_Edged_Katana>(WC) != none || class<KFWeap_Edged_Zweihander>(WC) != none )
MyPos.Z = -20;
break;
}
B = 'Spine';
break;
case 'Wep_3rdP_CommandoKnife_Rig':
MyPos = vect(0,0,10);
MyRot = rot(-16384,-8192,0);
B = 'LeftUpLeg';
break;
default:
}
else
{
MyPos = vect(-18.5,16.5,-18);
MyRot = rot(0,0,0);
if( MyCharacter == KFCharacterInfo_Human'CHR_Playable_ARCH.chr_DJSkully_archetype' )
MyRot.Roll = 8192;
switch( WM )
{
case 'Wep_3rdP_MB500_Rig':
@ -1130,7 +1140,11 @@ simulated final function SetBackpackWeapon( class<KFWeapon> WC )
MyPos.X = -75;
MyRot.Roll = 16384;
break;
case 'Wep_3rdP_RPG7_Rig':
MyPos.X = 10;
break;
}
B = 'Spine2';
}
@ -1179,6 +1193,104 @@ simulated function PlayWeaponSwitch(Weapon OldWeapon, Weapon NewWeapon)
}
}
simulated function UpdateHealingSpeedBoostMod(ExtPlayerController Healer)
{
local Ext_PerkFieldMedic MedPerk;
MedPerk = GetMedicPerk(Healer);
if( MedPerk == None )
return;
HealingSpeedBoostMod = Min( HealingSpeedBoostMod + MedPerk.GetHealingSpeedBoost(), MedPerk.GetMaxHealingSpeedBoost() );
SetTimer( MedPerk.GetHealingSpeedBoostDuration(),, nameOf(ResetHealingSpeedBoost) );
UpdateGroundSpeed();
}
simulated function float GetHealingSpeedModifier()
{
return 1 + (float(HealingSpeedBoostMod) / 100);
}
simulated function ResetHealingSpeedBoost()
{
HealingSpeedBoostMod = 0;
UpdateGroundSpeed();
if( IsTimerActive( nameOf( ResetHealingSpeedBoost ) ) )
ClearTimer( nameOf( ResetHealingSpeedBoost ) );
}
simulated function UpdateHealingDamageBoostMod(ExtPlayerController Healer)
{
local Ext_PerkFieldMedic MedPerk;
MedPerk = GetMedicPerk(Healer);
if( MedPerk == None )
return;
HealingDamageBoostMod = Min( HealingDamageBoostMod + MedPerk.GetHealingDamageBoost(), MedPerk.GetMaxHealingDamageBoost() );
SetTimer( MedPerk.GetHealingDamageBoostDuration(),, nameOf(ResetHealingDamageBoost) );
}
simulated function float GetHealingDamageBoostModifier()
{
return 1 + (float(HealingDamageBoostMod) / 100);
}
simulated function ResetHealingDamageBoost()
{
HealingDamageBoostMod = 0;
if( IsTimerActive( nameOf( ResetHealingDamageBoost ) ) )
ClearTimer( nameOf( ResetHealingDamageBoost ) );
}
simulated function UpdateHealingShieldMod(ExtPlayerController Healer)
{
local Ext_PerkFieldMedic MedPerk;
MedPerk = GetMedicPerk(Healer);
if( MedPerk == None )
return;
HealingShieldMod = Min( HealingShieldMod + MedPerk.GetHealingShield(), MedPerk.GetMaxHealingShield() );
SetTimer( MedPerk.GetHealingShieldDuration(),, nameOf(ResetHealingShield) );
}
simulated function float GetHealingShieldModifier()
{
return 1 - (float(HealingShieldMod) / 100);
}
simulated function ResetHealingShield()
{
HealingShieldMod = 0;
if( IsTimerActive( nameOf( ResetHealingShield ) ) )
ClearTimer( nameOf( ResetHealingShield ) );
}
function SacrificeExplode()
{
local Ext_PerkDemolition DemoPerk;
Super.SacrificeExplode();
DemoPerk = Ext_PerkDemolition(ExtPlayerController(Controller).ActivePerkManager.CurrentPerk);
if( DemoPerk != none )
DemoPerk.bUsedSacrifice = true;
}
simulated function Ext_PerkFieldMedic GetMedicPerk(ExtPlayerController Healer)
{
local Ext_PerkFieldMedic MedPerk;
MedPerk = Ext_PerkFieldMedic(ExtPlayerController(Controller).ActivePerkManager.CurrentPerk);
if( MedPerk != None )
return MedPerk;
return None;
}
defaultproperties
{
KnockbackResist=1
@ -1189,8 +1301,12 @@ defaultproperties
InventoryManagerClass=class'ExtInventoryManager'
WakeUpAnimSet=AnimSet'ZED_Clot_Anim.Alpha_Clot_Master'
Begin Object Name=SpecialMoveHandler_0
SpecialMoveClasses(SM_Emote)=class'ServerExt.ExtSM_Player_Emote'
End Object
DefaultInventory.Empty()
DefaultInventory.Add(class'KFWeap_Pistol_9mm')
DefaultInventory.Add(class'ExtWeap_Pistol_9mm')
DefaultInventory.Add(class'KFWeap_Healer_Syringe')
DefaultInventory.Add(class'KFWeap_Welder')
DefaultInventory.Add(class'KFInventory_Money')

View File

@ -20,3 +20,66 @@ reliable server function ServerThrowMoney()
}
Super.ServerThrowMoney();
}
simulated function Inventory CreateInventory(class<Inventory> NewInventoryItemClass, optional bool bDoNotActivate)
{
local KFWeapon Wep;
local Inventory SupClass;
SupClass = Super.CreateInventory(NewInventoryItemClass, bDoNotActivate);
Wep = KFWeapon(SupClass);
if( Wep != none )
{
if( KFWeap_Pistol_Dual9mm(Wep) != None && ExtWeap_Pistol_Dual9mm(Wep) == None )
{
Wep.Destroy();
return Super.CreateInventory(class'ExtWeap_Pistol_Dual9mm', bDoNotActivate);
}
Switch(Wep.Class.Name)
{
Case 'KFWeap_GrenadeLauncher_M79':
Wep.WeaponProjectiles[0] = class'ExtProj_HighExplosive_M79';
break;
Case 'KFWeap_RocketLauncher_RPG7':
Wep.WeaponProjectiles[0] = class'ExtProj_Rocket_RPG7';
break;
Case 'KFWeap_AssaultRifle_M16M203':
Wep.WeaponProjectiles[1] = class'ExtProj_HighExplosive_M16M203';
break;
Case 'KFWeap_Thrown_C4':
Wep.WeaponProjectiles[0] = class'ExtProj_Thrown_C4';
break;
Case 'KFWeap_RocketLauncher_Seeker6':
Wep.WeaponProjectiles[0] = class'ExtProj_Rocket_Seeker6';
break;
default:
break;
}
return Wep;
}
return SupClass;
}
simulated function CheckForExcessRemoval(KFWeapon NewWeap)
{
local Inventory RemoveInv, Inv;
if( KFWeap_Pistol_Dual9mm(NewWeap) != None )
{
for (Inv = InventoryChain; Inv != None; Inv = Inv.Inventory)
{
if (Inv.Class == class'ExtWeap_Pistol_9mm')
{
RemoveInv = Inv;
Inv = Inv.Inventory;
RemoveFromInventory(RemoveInv);
}
}
}
Super.CheckForExcessRemoval(NewWeap);
}

View File

@ -16,7 +16,7 @@ function InitializeMenu( KFGFxMoviePlayer_Manager InManager )
{
super(KFGFxObject_Menu).InitializeMenu(InManager);
LocalizeText();
EmoteList = class'KFEmoteList'.static.GetEmoteArray();
EmoteList = class'ExtEmoteList'.static.GetEmoteArray();
InitCharacterMenu();
TraderItems = KFGameReplicationInfo( GetPC().WorldInfo.GRI ).TraderItems;
}
@ -113,7 +113,7 @@ function UpdateEmoteList()
for (i = 0; i < EmoteList.length; i++)
{
if ( class'KFEmoteList'.static.GetUnlockedEmote(EmoteList[i].Id) != 'NONE')
if ( class'ExtEmoteList'.static.GetUnlockedEmote(EmoteList[i].Id, ExtPlayerController(GetPC())) != 'NONE')
{
SlotObject = CreateObject( "Object" );
SlotObject.SetInt("ItemIndex", i);
@ -210,56 +210,86 @@ function UpdateMeshList(string OutfitKey, string SkinKey, array<OutfitVariants>
{
local byte i, ItemIndex;
local GFxObject DataProvider, SlotObject;
local string TexturePath;
local string TexturePath, OutfitName;
local OutfitVariants Outfit;
local SkinVariant FirstSkin;
ItemIndex = 0;
DataProvider = CreateArray();
for (i = 0; i < Outfits.length; i++)
{
Outfit = Outfits[i];
OutfitName = Localize(CharInfoPath, OutfitKey$i, class'KFGFxMenu_Gear'.Default.KFCharacterInfoString);
if( bIsCustomChar )
{
OutfitName = GetMenuNameStr(Outfit.MeshName);
if ( InStr(OutfitName, "?INT?") != -1 )
continue;
SlotObject = CreateObject( "Object" );
SlotObject.SetInt("ItemIndex", i);
SlotObject.SetString("label", GetMenuNameStr(Outfit.MeshName));
SlotObject.SetString("label", OutfitName);
SlotObject.SetBool("enabled", true);
FirstSkin = UpdateOutfitVariants( OutfitKey, SkinKey, Outfit.SkinVariations, i, SlotObject );
if( string(FirstSkin.UITexture) == "Bad" )
continue;
TexturePath = "img://"$PathName(Outfit.UITexture);
TexturePath = "img://"$PathName(FirstSkin.UITexture);
SlotObject.SetString("source", TexturePath);
UpdateVariants( OutfitKey, SkinKey, Outfit.SkinVariations, i, SlotObject );
DataProvider.SetElementObject(ItemIndex, SlotObject);
ItemIndex++;
}
else
{
SlotObject = CreateObject( "Object" );
SlotObject.SetInt("ItemIndex", i);
SlotObject.SetString("label", Localize(CharInfoPath, OutfitKey$i, class'KFGFxMenu_Gear'.Default.KFCharacterInfoString));
SlotObject.SetBool("enabled", true);
TexturePath = "img://"$PathName(Outfit.UITexture);
SlotObject.SetString("source", TexturePath);
UpdateVariants( OutfitKey, SkinKey, Outfit.SkinVariations, i, SlotObject );
DataProvider.SetElementObject(ItemIndex, SlotObject);
ItemIndex++;
}
}
SetObject(DataArrayString, DataProvider);
}
function SkinVariant UpdateOutfitVariants(string OutfitKey, string KeyName, out array<SkinVariant> SkinVariations, int OutfitIndex, out GFxObject MeshObject)
{
local byte i, ItemIndex;
local GFxObject DataProvider, SlotObject;
local SkinVariant Skin;
local SkinVariant FirstSkin;
local string SectionPath;
local string TexturePath;
local bool bFoundFirst;
ItemIndex = 0;
DataProvider = CreateArray();
SectionPath = CharInfoPath$"."$OutfitKey$OutfitIndex;
for (i = 0; i < SkinVariations.length; i++)
{
Skin = SkinVariations[i];
if(!bFoundFirst)
{
FirstSkin = Skin;
bFoundFirst = true;
}
SlotObject = CreateObject( "Object" );
SlotObject.SetInt("ItemIndex", i);
SlotObject.SetString("label", Localize(SectionPath, KeyName$i, class'KFGFxMenu_Gear'.Default.KFCharacterInfoString));
TexturePath = "img://"$PathName(Skin.UITexture);
SlotObject.SetBool("enabled", true);
SlotObject.SetString("source", TexturePath);
DataProvider.SetElementObject(ItemIndex, SlotObject);
ItemIndex++;
}
MeshObject.SetObject("skinInfo", DataProvider);
return FirstSkin;
}
function UpdateAttachmentsList(array<AttachmentVariants> Attachments)
{
local byte i, ItemIndex;
local GFxObject DataProvider, SlotObject;
local string TexturePath;
local AttachmentVariants Variant;
local SkinVariant FirstSkin;
local string AttachmentName;
ItemIndex = 0;
DataProvider = CreateArray();
@ -275,80 +305,67 @@ function UpdateAttachmentsList(array<AttachmentVariants> Attachments)
for (i = 0; i < Attachments.length; i++)
{
Variant = Attachments[i];
AttachmentName = Localize(string(Variant.AttachmentItem.Name), class'KFGFxMenu_Gear'.Default.AttachmentKey, class'KFGFxMenu_Gear'.Default.KFCharacterInfoString);
if( bIsCustomChar )
{
AttachmentName = GetMenuNameStr(Variant.MeshName);
if ( InStr(AttachmentName, "?INT?") != -1 )
continue;
SlotObject = CreateObject( "Object" );
SlotObject.SetInt("ItemIndex", i);
SlotObject.SetString("label", GetMenuNameStr(Variant.MeshName));
SlotObject.SetBool("enabled", true);
FirstSkin = UpdateCosmeticVariants( class'KFGFxMenu_Gear'.Default.AttachmentKey, class'KFGFxMenu_Gear'.Default.AttachmentSkinKey, Variant.AttachmentItem, i, SlotObject );
if( string(FirstSkin.UITexture) == "Bad" )
continue;
TexturePath = "img://"$PathName(Variant.UITexture);
SlotObject.SetString("label", AttachmentName);
SlotObject.SetBool("enabled", true);
TexturePath = "img://"$PathName(FirstSkin.UITexture);
SlotObject.SetString("source", TexturePath);
UpdateVariants( class'KFGFxMenu_Gear'.Default.AttachmentKey, class'KFGFxMenu_Gear'.Default.AttachmentSkinKey, Variant.SkinVariations, i, SlotObject );
DataProvider.SetElementObject(ItemIndex, SlotObject);
ItemIndex++;
}
else
{
SlotObject = CreateObject( "Object" );
SlotObject.SetInt("ItemIndex", i);
SlotObject.SetString("label", Localize(CharInfoPath, class'KFGFxMenu_Gear'.Default.AttachmentKey$i, class'KFGFxMenu_Gear'.Default.KFCharacterInfoString));
SlotObject.SetBool("enabled", true);
TexturePath = "img://"$PathName(Variant.UITexture);
SlotObject.SetString("source", TexturePath);
UpdateVariants( class'KFGFxMenu_Gear'.Default.AttachmentKey, class'KFGFxMenu_Gear'.Default.AttachmentSkinKey, Variant.SkinVariations, i, SlotObject );
DataProvider.SetElementObject(ItemIndex, SlotObject);
ItemIndex++;
}
}
SetObject("attachmentsArray", DataProvider);
}
function UpdateVariants(string OutfitKey, string KeyName, out array<SkinVariant> SkinVariations, int OutfitIndex, out GFxObject MeshObject)
function SkinVariant UpdateCosmeticVariants(string OutfitKey, string KeyName, KFCharacterAttachment Attachment, int OutfitIndex, out GFxObject MeshObject)
{
local byte i, ItemIndex;
local GFxObject DataProvider, SlotObject;
local SkinVariant Skin;
local string SectionPath;
local SkinVariant FirstSkin;
local string TexturePath;
local bool bFoundFirst;
local string SkinName;
ItemIndex = 0;
DataProvider = CreateArray();
SectionPath = CharInfoPath$"."$OutfitKey$OutfitIndex;
for (i = 0; i < SkinVariations.length; i++)
for (i = 0; i < Attachment.SkinVariations.length; i++)
{
Skin = SkinVariations[i];
if( bIsCustomChar )
Skin = Attachment.SkinVariations[i];
if(!bFoundFirst)
{
FirstSkin = Skin;
bFoundFirst = true;
}
SlotObject = CreateObject( "Object" );
SlotObject.SetInt("ItemIndex", i);
SlotObject.SetString("label", GetMenuName(Skin.Skin));
SlotObject.SetBool("enabled", true);
SkinName = Localize(string(Attachment.Name), KeyName$i, class'KFGFxMenu_Gear'.Default.KFCharacterInfoString);
SlotObject.SetString("label", SkinName);
TexturePath = "img://"$PathName(Skin.UITexture);
SlotObject.SetBool("enabled", true);
SlotObject.SetString("source", TexturePath);
DataProvider.SetElementObject(ItemIndex, SlotObject);
ItemIndex++;
}
else
{
SlotObject = CreateObject( "Object" );
SlotObject.SetInt("ItemIndex", i);
SlotObject.SetString("label", Localize(SectionPath, KeyName$i, class'KFGFxMenu_Gear'.Default.KFCharacterInfoString));
SlotObject.SetBool("enabled", true);
TexturePath = "img://"$PathName(Skin.UITexture);
SlotObject.SetString("source", TexturePath);
DataProvider.SetElementObject(ItemIndex, SlotObject);
ItemIndex++;
}
}
MeshObject.SetObject("skinInfo", DataProvider);
return FirstSkin;
}
function SetCurrentCharacterButtons()
@ -380,7 +397,7 @@ function SetEmoteButton()
local GFxObject DataObject;
local int EmoteIndex;
EmoteIndex = class'KFEmoteList'.static.GetEmoteIndex( class'KFEmoteList'.static.GetEquippedEmoteId());
EmoteIndex = class'ExtEmoteList'.static.GetEmoteIndex( class'ExtEmoteList'.static.GetEquippedEmoteId(ExtPlayerController(GetPC())));
DataObject = CreateObject("Object");
if(EmoteIndex == 255)
@ -448,7 +465,7 @@ function SetGearButtons(byte MeshIndex, byte SkinIndex, string MeshKey, string S
/** Update the labels for our currently equipped attachments */
function SetAttachmentButtons(string AttachmentMeshKey, string sectionFunctionName)
{
local string CurrentMesh, FinishedString;
local string FinishedString;
local GFxObject DataObject;
local byte i, AttachmentIndex;
local bool bCustom;
@ -468,8 +485,7 @@ function SetAttachmentButtons(string AttachmentMeshKey, string sectionFunctionNa
}
else
{
CurrentMesh = AttachmentMeshKey$AttachmentIndex;
FinishedString $= (bIsCustomChar ? GetMenuNameStr(CurrentCharInfo.CosmeticVariants[AttachmentIndex].MeshName) : Localize(CharInfoPath, CurrentMesh, class'KFGFxMenu_Gear'.Default.KFCharacterInfoString))$"\n";
FinishedString $= (bIsCustomChar ? GetMenuNameStr(CurrentCharInfo.CosmeticVariants[AttachmentIndex].MeshName) : Localize(string(CurrentCharInfo.CosmeticVariants[AttachmentIndex].AttachmentItem.Name), AttachmentMeshKey, class'KFGFxMenu_Gear'.Default.KFCharacterInfoString)$"\n");
}
}
@ -522,11 +538,11 @@ function Callback_Emote(byte Index)
KFPC = KFPlayerController(GetPC());
if( KFPC != none )
{
class'KFEmoteList'.static.SaveEquippedEmote(EmoteList[Index].ID);
class'ExtEmoteList'.static.SaveEquippedEmote(EmoteList[Index].ID, ExtPlayerController(KFPC));
if ( KFPawn_Customization(KFPC.Pawn) != none )
if ( ExtPawn_Customization(KFPC.Pawn) != none )
{
KFPawn_Customization(KFPC.Pawn).PlayEmoteAnimation();
ExtPawn_Customization(KFPC.Pawn).PlayEmoteAnimation();
}
}

View File

@ -0,0 +1,65 @@
class ExtMenu_Inventory extends KFGFxMenu_Inventory;
function bool IsItemActive(int ItemDefinition)
{
local class<KFWeaponDefinition> WeaponDef;
local int ItemIndex;
ItemIndex = class'ExtWeaponSkinList'.default.Skins.Find('Id', ItemDefinition);
if(ItemIndex == INDEX_NONE)
{
return false;
}
WeaponDef = class'ExtWeaponSkinList'.default.Skins[ItemIndex].WeaponDef;
if(WeaponDef != none)
{
return class'ExtWeaponSkinList'.Static.IsSkinEquip(WeaponDef, ItemDefinition, ExtPlayerController(KFPC));
}
return false;
}
function Callback_Equip( int ItemDefinition )
{
local class<KFWeaponDefinition> WeaponDef;
local int ItemIndex;
ItemIndex = class'ExtWeaponSkinList'.default.Skins.Find('Id', ItemDefinition);
if(ItemIndex == INDEX_NONE)
{
return;
}
WeaponDef = class'ExtWeaponSkinList'.default.Skins[ItemIndex].WeaponDef;
if(WeaponDef != none)
{
if(IsItemActive(ItemDefinition))
{
class'ExtWeaponSkinList'.Static.SaveWeaponSkin(WeaponDef, 0, ExtPlayerController(KFPC));
if(class'WorldInfo'.static.IsConsoleBuild( ))
{
Manager.CachedProfile.ClearWeaponSkin(WeaponDef.default.WeaponClassPath);
}
}
else
{
class'ExtWeaponSkinList'.Static.SaveWeaponSkin(WeaponDef, ItemDefinition, ExtPlayerController(KFPC));
if(class'WorldInfo'.static.IsConsoleBuild( ))
{
Manager.CachedProfile.SaveWeaponSkin(WeaponDef.default.WeaponClassPath, ItemDefinition);
}
}
}
InitInventory();
}
defaultproperties
{
}

View File

@ -105,4 +105,6 @@ defaultproperties
WidgetBindings.Add((WidgetName="WaveInfoContainer",WidgetClass=class'ExtHUD_WaveInfo'))
WidgetBindings.Remove((WidgetName="bossHealthBar", WidgetClass=class'KFGFxWidget_BossHealthBar'))
WidgetBindings.Add((WidgetName="bossHealthBar", WidgetClass=class'ExtWidget_BossHealthBar'))
WidgetBindings.Remove((WidgetName="WeaponSelectContainer",WidgetClass=class'KFGFxHUD_WeaponSelectWidget'))
WidgetBindings.Add((WidgetName="WeaponSelectContainer",WidgetClass=class'ExtHUD_WeaponSelectWidget'))
}

View File

@ -1,7 +1,7 @@
Class ExtMoviePlayer_Manager extends KFGFxMoviePlayer_Manager;
var ExtMenu_Gear EGearMenu;
var KF2GUIController MyGUIController;
var transient KFGUI_Page PerksPage;
event bool WidgetInitialized(name WidgetName, name WidgetPath, GFxObject Widget)
{
@ -69,12 +69,60 @@ function LaunchMenus( optional bool bForceSkipLobby )
}
}
function OpenMenu( byte NewMenuIndex, optional bool bShowWidgets = true )
{
local KF2GUIController GUIController;
GUIController = class'KF2GUIController'.Static.GetGUIController(GetPC());
Super.OpenMenu(NewMenuIndex, bShowWidgets);
if( bAfterLobby )
return;
if( NewMenuIndex == UI_Perks )
{
PerksPage = GUIController.OpenMenu(class'ExtGUI_PerkSelectionPage');
SetMovieCanReceiveInput(false);
PerksMenu.ActionScriptVoid("closeContainer");
}
else GUIController.CloseMenu(class'ExtGUI_PerkSelectionPage');
}
function CloseMenus(optional bool bForceClose=false)
{
local KF2GUIController GUIController;
if( PerksPage != None )
{
GUIController = class'KF2GUIController'.Static.GetGUIController(GetPC());
GUIController.CloseMenu(class'ExtGUI_PerkSelectionPage');
}
Super.CloseMenus(bForceClose);
}
function OnMenuOpen( name WidgetPath, KFGFxObject_Menu Widget )
{
Super.OnMenuOpen(WidgetPath, Widget);
if( !bAfterLobby && Widget == PerksMenu )
PerksMenu.ActionScriptVoid("closeContainer");
}
defaultproperties
{
InGamePartyWidgetClass=class'ExtWidget_PartyInGame'
WidgetPaths.Remove("../UI_Widgets/PartyWidget_SWF.swf")
WidgetPaths.Add("../UI_Widgets/VersusLobbyWidget_SWF.swf")
WidgetBindings.Remove((WidgetName="PerksMenu",WidgetClass=class'KFGFxMenu_Perks'))
WidgetBindings.Add((WidgetName="PerksMenu",WidgetClass=class'ExtMenu_Perks'))
WidgetBindings.Remove((WidgetName="gearMenu",WidgetClass=class'KFGFxMenu_Gear'))
WidgetBindings.Add((WidgetName="gearMenu",WidgetClass=class'ExtMenu_Gear'))
WidgetBindings.Remove((WidgetName="traderMenu",WidgetClass=class'KFGFxMenu_Trader'))
WidgetBindings.Add((WidgetName="traderMenu",WidgetClass=class'ExtMenu_Trader'))
//WidgetBindings.Remove((WidgetName="inventoryMenu",WidgetClass=class'KFGFxMenu_Inventory'))
//WidgetBindings.Add((WidgetName="inventoryMenu",WidgetClass=class'ExtMenu_Inventory'))
}

View File

@ -49,6 +49,58 @@ function bool Died(Controller Killer, class<DamageType> DamageType, vector HitLo
return true;
}
simulated function PlayEmoteAnimation(optional bool bNewCharacter)
{
local name AnimName;
local float BlendInTime;
AnimName = class'ExtEmoteList'.static.GetUnlockedEmote( class'ExtEmoteList'.static.GetEquippedEmoteId(ExtPlayerController(Controller)), ExtPlayerController(Controller) );
BlendInTime = (bNewCharacter) ? 0.f : 0.4;
// Briefly turn off notify so that PlayCustomAnim won't call OnAnimEnd (e.g. character swap)
BodyStanceNodes[EAS_FullBody].SetActorAnimEndNotification( FALSE );
BodyStanceNodes[EAS_FullBody].PlayCustomAnim(AnimName, 1.f, BlendInTime, 0.4, false, true);
BodyStanceNodes[EAS_FullBody].SetActorAnimEndNotification( TRUE );
}
function AttachWeaponByItemDefinition( int ItemDefinition )
{
local class<KFWeaponDefinition> WeaponDef;
local int ItemINdex;
local KFWeaponAttachment WeaponPreview;
//find weapon def
ItemIndex = class'ExtWeaponSkinList'.default.Skins.Find('Id', ItemDefinition);
if(ItemIndex == INDEX_NONE)
{
`log("Could not find item" @ItemDefinition);
return;
}
WeaponDef = class'ExtWeaponSkinList'.default.Skins[ItemIndex].WeaponDef;
if(WeaponDef == none)
{
`log("Weapon def NONE for : " @ItemDefinition);
return;
}
//load in and add object .
WeaponPreview = KFWeaponAttachment ( DynamicLoadObject( WeaponDef.default.AttachmentArchtypePath, class'KFWeaponAttachment' ) );
//attatch it to player
WeaponAttachmentTemplate = WeaponPreview;
WeaponAttachmentChanged();
//setweapon skin
WeaponAttachment.SetWeaponSkin(ItemDefinition);
}
defaultproperties
{
bCollideActors=false

View File

@ -0,0 +1,10 @@
class ExtPawn_ZedHans_Pet extends KFPawn_ZedHansFriendlyTest;
static simulated event bool IsABoss()
{
return false;
}
defaultproperties
{
}

View File

@ -77,19 +77,70 @@ function bool ApplyPerkName( string S )
}
function ApplyPerk( Ext_PerkBase P )
{
local KFPawn_Human HP;
local KFInventoryManager InvMan;
local Ext_T_ZEDHelper H;
local int i;
if( P==None )
return;
if( PlayerOwner.Pawn != None )
{
InvMan = KFInventoryManager(PlayerOwner.Pawn.InvManager);
if( InvMan != None )
InvMan.MaxCarryBlocks = InvMan.Default.MaxCarryBlocks;
foreach PlayerOwner.Pawn.ChildActors(class'Ext_T_ZEDHelper',H)
{
H.Destroy();
}
HP = KFPawn_Human(PlayerOwner.Pawn);
if( HP != None )
HP.DefaultInventory = HP.Default.DefaultInventory;
}
if( CurrentPerk != None )
{
CurrentPerk.DeactivateTraits();
for( i=0; i<CurrentPerk.PerkTraits.Length; ++i )
{
CurrentPerk.PerkTraits[i].TraitType.Static.CancelEffectOn(KFPawn_Human(PlayerOwner.Pawn),CurrentPerk,CurrentPerk.PerkTraits[i].CurrentLevel,CurrentPerk.PerkTraits[i].Data);
}
}
bStatsDirty = true;
CurrentPerk = P;
if( PRIOwner!=None )
{
PRIOwner.ECurrentPerk = P.Class;
PRIOwner.FCurrentPerk = P;
P.UpdatePRILevel();
}
if( CurrentPerk!=None )
{
CurrentPerk.ActivateTraits();
if( PlayerOwner.Pawn != None )
{
HP = KFPawn_Human(PlayerOwner.Pawn);
if( HP != None )
{
HP.HealthMax = HP.default.Health;
HP.MaxArmor = HP.default.MaxArmor;
ModifyHealth(HP.HealthMax);
ModifyArmor(HP.MaxArmor);
if( HP.Health > HP.HealthMax ) HP.Health = HP.HealthMax;
if( HP.Armor > HP.MaxArmor ) HP.Armor = HP.MaxArmor;
}
}
}
}
simulated final function Ext_PerkBase FindPerk( class<Ext_PerkBase> P )
{
@ -620,6 +671,20 @@ function GameExplosion GetExplosionTemplate()
return class'KFPerk_Firebug'.Default.ExplosionTemplate;
}
// Additional functions
function OnWaveEnded()
{
CurrentPerk.OnWaveEnded();
}
function NotifyZedTimeStarted()
{
CurrentPerk.NotifyZedTimeStarted();
}
simulated function float GetZedTimeExtensions( byte Level )
{
return CurrentPerk.GetZedTimeExtensions(Level);
}
// SWAT:
simulated function bool HasHeavyArmor()
{
@ -638,6 +703,76 @@ simulated function bool ShouldKnockDownOnBump()
return (CurrentPerk!=None && CurrentPerk.bHasSWATEnforcer);
}
// DEMO:
simulated function bool ShouldRandSirenResist()
{
return (Ext_PerkDemolition(CurrentPerk)!=None ? Ext_PerkDemolition(CurrentPerk).bSirenResistance : false);
}
simulated function bool IsAoEActive()
{
return (Ext_PerkDemolition(CurrentPerk)!=None ? Ext_PerkDemolition(CurrentPerk).AOEMult > 1.0f : false);
}
simulated function bool ShouldSacrifice()
{
return (Ext_PerkDemolition(CurrentPerk)!=None ? (Ext_PerkDemolition(CurrentPerk).bCanUseSacrifice && !Ext_PerkDemolition(CurrentPerk).bUsedSacrifice) : false);
}
simulated function bool ShouldNeverDud()
{
return (Ext_PerkDemolition(CurrentPerk)!=None ? Ext_PerkDemolition(CurrentPerk).bProfessionalActive : false);
}
function NotifyPerkSacrificeExploded()
{
if( Ext_PerkDemolition(CurrentPerk) != none ) Ext_PerkDemolition(CurrentPerk).bUsedSacrifice = true;
}
simulated function float GetAoERadiusModifier()
{
return (Ext_PerkDemolition(CurrentPerk)!=None ? Ext_PerkDemolition(CurrentPerk).GetAoERadiusModifier() : 1.0);
}
// MEDIC:
simulated function bool GetHealingSpeedBoostActive()
{
return (Ext_PerkFieldMedic(CurrentPerk)!=None ? Ext_PerkFieldMedic(CurrentPerk).GetHealingSpeedBoostActive() : false);
}
simulated function bool GetHealingDamageBoostActive()
{
return (Ext_PerkFieldMedic(CurrentPerk)!=None ? Ext_PerkFieldMedic(CurrentPerk).GetHealingDamageBoostActive() : false);
}
simulated function bool GetHealingShieldActive()
{
return (Ext_PerkFieldMedic(CurrentPerk)!=None ? Ext_PerkFieldMedic(CurrentPerk).GetHealingShieldActive() : false);
}
simulated function float GetSelfHealingSurgePct()
{
return (Ext_PerkFieldMedic(CurrentPerk)!=None ? Ext_PerkFieldMedic(CurrentPerk).GetSelfHealingSurgePct() : 0.f);
}
function bool IsToxicDmgActive()
{
return (Ext_PerkFieldMedic(CurrentPerk)!=None ? Ext_PerkFieldMedic(CurrentPerk).bUseToxicDamage : false);
}
static function class<KFDamageType> GetToxicDmgTypeClass()
{
return class'Ext_PerkFieldMedic'.static.GetToxicDmgTypeClass();
}
static function ModifyToxicDmg( out int ToxicDamage )
{
ToxicDamage = class'Ext_PerkFieldMedic'.static.ModifyToxicDmg(ToxicDamage);
}
simulated function float GetSnarePower( optional class<DamageType> DamageType, optional byte HitZoneIdx )
{
return (Ext_PerkFieldMedic(CurrentPerk)!=None ? Ext_PerkFieldMedic(CurrentPerk).GetSnarePower(DamageType, HitZoneIdx) : 0.f);
}
// SUPPORT:
function bool CanRepairDoors()
{
return (Ext_PerkSupport(CurrentPerk)!=None ? Ext_PerkSupport(CurrentPerk).CanRepairDoors() : false);
}
simulated function float GetPenetrationModifier( byte Level, class<KFDamageType> DamageType, optional bool bForce )
{
return (Ext_PerkSupport(CurrentPerk)!=None ? Ext_PerkSupport(CurrentPerk).GetPenetrationModifier(Level, DamageType, bForce) : 0.f);
}
defaultproperties
{
bTickIsDisabled=false

View File

@ -36,7 +36,15 @@ var transient float EndGameCamTimer,LastPlayerCalcView;
var transient bool bEndGameCamFocus;
var globalconfig bool bShowFPLegs,bHideNameBeacons,bHideKillMsg,bHideDamageMsg,bHideNumberMsg,bNoMonsterPlayer,bNoScreenShake,bRenderModes,bUseKF2DeathMessages,bUseKF2KillMessages;
var bool bMOTDReceived,bNamePlateShown,bNamePlateHidden,bClientHideKillMsg,bClientHideDamageMsg,bClientHideNumbers,bNoDamageTracking,bClientNoZed;
var globalconfig int SelectedEmoteIndex;
var bool bMOTDReceived,bNamePlateShown,bNamePlateHidden,bClientHideKillMsg,bClientHideDamageMsg,bClientHideNumbers,bNoDamageTracking,bClientNoZed,bSetPerk;
struct SavedSkins
{
var int ID;
var class<KFWeaponDefinition> WepDef;
};
var globalconfig array<SavedSkins> SavedWeaponSkins;
replication
{

View File

@ -31,6 +31,7 @@ var bool bIsMuted,bInitialPT,bIsDev,bHiddenUser,bClientUseCustom,bClientFirstCha
var int RespawnCounter;
var byte AdminType;
var class<Ext_PerkBase> ECurrentPerk;
var Ext_PerkBase FCurrentPerk;
var int ECurrentPerkLevel,ECurrentPerkPrestige;
var ExtPerkManager PerkManager;
/* AdminTypes:
@ -48,6 +49,10 @@ var transient color HUDPerkColor;
var byte FixedData;
var int RepPlayTime,RepKills,RepEXP;
// Perk related
var bool bNukeIsOn,bConcussiveIsOn,bForScienceOn,bHasSciEMP;
var float NukeTimeMult;
// Custom character stuff.
var array<FCustomCharEntry> CustomCharList;
var repnotify FMyCustomChar CustomCharacter;
@ -73,6 +78,8 @@ replication
RespawnCounter,AdminType,ECurrentPerk,ECurrentPerkLevel,ECurrentPerkPrestige,RepKills,RepEXP,RepLevelProgress,bIsDev,NameTag,FixedData,bHiddenUser,CustomCharacter,HasSupplier;
if (bNetInitial || bInitialPT)
RepPlayTime;
if ( true )
bNukeIsOn, bConcussiveIsOn, NukeTimeMult;
}
simulated function PostBeginPlay()

View File

@ -0,0 +1,161 @@
class ExtProj_DynamiteGrenade extends KFProj_DynamiteGrenade;
simulated protected function PrepareExplosionTemplate()
{
local ExtPlayerReplicationInfo MyPRI;
local Ext_PerkDemolition DemoPerk;
Super(KFProjectile).PrepareExplosionTemplate();
if(Instigator == None)
return;
MyPRI = ExtPlayerReplicationInfo(Instigator.PlayerReplicationInfo);
if( MyPRI != none )
{
if( bWasTimeDilated && MyPRI.bNukeIsOn && class'KFPerk_Demolitionist'.static.ProjectileShouldNuke( self ) )
{
ExplosionTemplate = class'KFPerk_Demolitionist'.static.GetNukeExplosionTemplate();
ExplosionTemplate.Damage = default.ExplosionTemplate.Damage * class'KFPerk_Demolitionist'.static.GetNukeDamageModifier();
ExplosionTemplate.DamageRadius = default.ExplosionTemplate.DamageRadius * class'KFPerk_Demolitionist'.static.GetNukeRadiusModifier();
ExplosionTemplate.DamageFalloffExponent = default.ExplosionTemplate.DamageFalloffExponent;
}
else if( MyPRI.bConcussiveIsOn )
{
ExplosionTemplate.ExplosionEffects = AltExploEffects;
ExplosionTemplate.ExplosionSound = class'KFPerk_Demolitionist'.static.GetConcussiveExplosionSound();
}
DemoPerk = Ext_PerkDemolition(MyPRI.FCurrentPerk);
if( DemoPerk == none )
return;
ExplosionTemplate.DamageRadius *= DemoPerk.GetAoERadiusModifier();
}
}
simulated protected function SetExplosionActorClass()
{
local ExtPlayerReplicationInfo MyPRI;
Super(KFProjectile).SetExplosionActorClass();
if(Instigator == None)
return;
MyPRI = ExtPlayerReplicationInfo(Instigator.PlayerReplicationInfo);
if( MyPRI != none )
{
if( bWasTimeDilated && MyPRI.bNukeIsOn && class'KFPerk_Demolitionist'.static.ProjectileShouldNuke( self ) )
ExplosionActorClass = class'KFPerk_Demolitionist'.static.GetNukeExplosionActorClass();
}
}
simulated function TriggerExplosion(Vector HitLocation, Vector HitNormal, Actor HitActor)
{
local vector NudgedHitLocation, ExplosionDirection;
local Pawn P;
local ExtPlayerReplicationInfo MyPRI;
if( bHasDisintegrated )
{
return;
}
if (!bHasExploded)
{
// On local player or server, we cache off our time dilation setting here
if( WorldInfo.NetMode == NM_ListenServer || WorldInfo.NetMode == NM_DedicatedServer || InstigatorController != None )
{
bWasTimeDilated = WorldInfo.TimeDilation < 1.f;
}
// Stop ambient sounds when this projectile explodes
if( bStopAmbientSoundOnExplode )
{
StopAmbientSound();
}
if (ExplosionTemplate != None)
{
StopSimulating();
// using a hit location slightly away from the impact point is nice for certain things
NudgedHitLocation = HitLocation + (HitNormal * 32.f);
SetExplosionActorClass();
if( ExplosionActorClass == class'KFPerk_Demolitionist'.static.GetNukeExplosionActorClass() )
{
P = Pawn(HitActor);
if( P != none )
{
NudgedHitLocation = P.Location - vect(0,0,1) * P.GetCollisionHeight();
}
}
ExplosionActor = Spawn(ExplosionActorClass, self,, NudgedHitLocation, rotator(HitNormal));
if (ExplosionActor != None)
{
ExplosionActor.Instigator = Instigator;
ExplosionActor.InstigatorController = InstigatorController;
PrepareExplosionTemplate();
// If the locations are zero (probably because this exploded in the air) set defaults
if( IsZero(HitLocation) )
{
HitLocation = Location;
}
if( IsZero(HitNormal) )
{
HitNormal = vect(0,0,1);
}
// these are needed for the decal tracing later in GameExplosionActor.Explode()
ExplosionTemplate.HitLocation = HitLocation;// NudgedHitLocation
ExplosionTemplate.HitNormal = HitNormal;
// If desired, attach to mover if we hit one
if(bAttachExplosionToHitMover && InterpActor(HitActor) != None)
{
ExplosionActor.Attachee = HitActor;
ExplosionTemplate.bAttachExplosionEmitterToAttachee = TRUE;
ExplosionActor.SetBase(HitActor);
}
// directional?
if (ExplosionTemplate.bDirectionalExplosion)
{
ExplosionDirection = GetExplosionDirection(HitNormal);
//DrawDebugLine(ExplosionActor.Location, ExplosionActor.Location+ExplosionDirection*64, 255, 255, 0, TRUE);
}
// @todo: make this function responsible for setting explosion instance parameters, and take instance parameters
// out of GearExplosion (e.g. Attachee)
PrepareExplosionActor(ExplosionActor);
MyPRI = ExtPlayerReplicationInfo(Instigator.PlayerReplicationInfo);
if( MyPRI != none && KFExplosionActorLingering(ExplosionActor) != None )
{
KFExplosionActorLingering(ExplosionActor).MaxTime *= MyPRI.NukeTimeMult;
KFExplosionActorLingering(ExplosionActor).LifeSpan *= MyPRI.NukeTimeMult;
}
ExplosionActor.Explode(ExplosionTemplate, ExplosionDirection); // go bewm
}
// done with it
if (!bPendingDelete && !bDeleteMe)
{
// defer destruction so any replication of explosion stuff can happen if necessary
DeferredDestroy(PostExplosionLifetime);
}
}
bHasExploded = true;
}
}
defaultproperties
{
}

View File

@ -0,0 +1,161 @@
class ExtProj_HighExplosive_M16M203 extends KFProj_HighExplosive_M16M203;
simulated protected function PrepareExplosionTemplate()
{
local ExtPlayerReplicationInfo MyPRI;
local Ext_PerkDemolition DemoPerk;
Super(KFProjectile).PrepareExplosionTemplate();
if(Instigator == None)
return;
MyPRI = ExtPlayerReplicationInfo(Instigator.PlayerReplicationInfo);
if( MyPRI != none )
{
if( bWasTimeDilated && MyPRI.bNukeIsOn && class'KFPerk_Demolitionist'.static.ProjectileShouldNuke( self ) )
{
ExplosionTemplate = class'KFPerk_Demolitionist'.static.GetNukeExplosionTemplate();
ExplosionTemplate.Damage = default.ExplosionTemplate.Damage * class'KFPerk_Demolitionist'.static.GetNukeDamageModifier();
ExplosionTemplate.DamageRadius = default.ExplosionTemplate.DamageRadius * class'KFPerk_Demolitionist'.static.GetNukeRadiusModifier();
ExplosionTemplate.DamageFalloffExponent = default.ExplosionTemplate.DamageFalloffExponent;
}
else if( MyPRI.bConcussiveIsOn )
{
ExplosionTemplate.ExplosionEffects = AltExploEffects;
ExplosionTemplate.ExplosionSound = class'KFPerk_Demolitionist'.static.GetConcussiveExplosionSound();
}
DemoPerk = Ext_PerkDemolition(MyPRI.FCurrentPerk);
if( DemoPerk == none )
return;
ExplosionTemplate.DamageRadius *= DemoPerk.GetAoERadiusModifier();
}
}
simulated protected function SetExplosionActorClass()
{
local ExtPlayerReplicationInfo MyPRI;
Super(KFProjectile).SetExplosionActorClass();
if(Instigator == None)
return;
MyPRI = ExtPlayerReplicationInfo(Instigator.PlayerReplicationInfo);
if( MyPRI != none )
{
if( bWasTimeDilated && MyPRI.bNukeIsOn && class'KFPerk_Demolitionist'.static.ProjectileShouldNuke( self ) )
ExplosionActorClass = class'KFPerk_Demolitionist'.static.GetNukeExplosionActorClass();
}
}
simulated function TriggerExplosion(Vector HitLocation, Vector HitNormal, Actor HitActor)
{
local vector NudgedHitLocation, ExplosionDirection;
local Pawn P;
local ExtPlayerReplicationInfo MyPRI;
if( bHasDisintegrated )
{
return;
}
if (!bHasExploded)
{
// On local player or server, we cache off our time dilation setting here
if( WorldInfo.NetMode == NM_ListenServer || WorldInfo.NetMode == NM_DedicatedServer || InstigatorController != None )
{
bWasTimeDilated = WorldInfo.TimeDilation < 1.f;
}
// Stop ambient sounds when this projectile explodes
if( bStopAmbientSoundOnExplode )
{
StopAmbientSound();
}
if (ExplosionTemplate != None)
{
StopSimulating();
// using a hit location slightly away from the impact point is nice for certain things
NudgedHitLocation = HitLocation + (HitNormal * 32.f);
SetExplosionActorClass();
if( ExplosionActorClass == class'KFPerk_Demolitionist'.static.GetNukeExplosionActorClass() )
{
P = Pawn(HitActor);
if( P != none )
{
NudgedHitLocation = P.Location - vect(0,0,1) * P.GetCollisionHeight();
}
}
ExplosionActor = Spawn(ExplosionActorClass, self,, NudgedHitLocation, rotator(HitNormal));
if (ExplosionActor != None)
{
ExplosionActor.Instigator = Instigator;
ExplosionActor.InstigatorController = InstigatorController;
PrepareExplosionTemplate();
// If the locations are zero (probably because this exploded in the air) set defaults
if( IsZero(HitLocation) )
{
HitLocation = Location;
}
if( IsZero(HitNormal) )
{
HitNormal = vect(0,0,1);
}
// these are needed for the decal tracing later in GameExplosionActor.Explode()
ExplosionTemplate.HitLocation = HitLocation;// NudgedHitLocation
ExplosionTemplate.HitNormal = HitNormal;
// If desired, attach to mover if we hit one
if(bAttachExplosionToHitMover && InterpActor(HitActor) != None)
{
ExplosionActor.Attachee = HitActor;
ExplosionTemplate.bAttachExplosionEmitterToAttachee = TRUE;
ExplosionActor.SetBase(HitActor);
}
// directional?
if (ExplosionTemplate.bDirectionalExplosion)
{
ExplosionDirection = GetExplosionDirection(HitNormal);
//DrawDebugLine(ExplosionActor.Location, ExplosionActor.Location+ExplosionDirection*64, 255, 255, 0, TRUE);
}
// @todo: make this function responsible for setting explosion instance parameters, and take instance parameters
// out of GearExplosion (e.g. Attachee)
PrepareExplosionActor(ExplosionActor);
MyPRI = ExtPlayerReplicationInfo(Instigator.PlayerReplicationInfo);
if( MyPRI != none && KFExplosionActorLingering(ExplosionActor) != None )
{
KFExplosionActorLingering(ExplosionActor).MaxTime *= MyPRI.NukeTimeMult;
KFExplosionActorLingering(ExplosionActor).LifeSpan *= MyPRI.NukeTimeMult;
}
ExplosionActor.Explode(ExplosionTemplate, ExplosionDirection); // go bewm
}
// done with it
if (!bPendingDelete && !bDeleteMe)
{
// defer destruction so any replication of explosion stuff can happen if necessary
DeferredDestroy(PostExplosionLifetime);
}
}
bHasExploded = true;
}
}
defaultproperties
{
}

View File

@ -0,0 +1,161 @@
class ExtProj_HighExplosive_M79 extends KFProj_HighExplosive_M79;
simulated protected function PrepareExplosionTemplate()
{
local ExtPlayerReplicationInfo MyPRI;
local Ext_PerkDemolition DemoPerk;
Super(KFProjectile).PrepareExplosionTemplate();
if(Instigator == None)
return;
MyPRI = ExtPlayerReplicationInfo(Instigator.PlayerReplicationInfo);
if( MyPRI != none )
{
if( bWasTimeDilated && MyPRI.bNukeIsOn && class'KFPerk_Demolitionist'.static.ProjectileShouldNuke( self ) )
{
ExplosionTemplate = class'KFPerk_Demolitionist'.static.GetNukeExplosionTemplate();
ExplosionTemplate.Damage = default.ExplosionTemplate.Damage * class'KFPerk_Demolitionist'.static.GetNukeDamageModifier();
ExplosionTemplate.DamageRadius = default.ExplosionTemplate.DamageRadius * class'KFPerk_Demolitionist'.static.GetNukeRadiusModifier();
ExplosionTemplate.DamageFalloffExponent = default.ExplosionTemplate.DamageFalloffExponent;
}
else if( MyPRI.bConcussiveIsOn )
{
ExplosionTemplate.ExplosionEffects = AltExploEffects;
ExplosionTemplate.ExplosionSound = class'KFPerk_Demolitionist'.static.GetConcussiveExplosionSound();
}
DemoPerk = Ext_PerkDemolition(MyPRI.FCurrentPerk);
if( DemoPerk == none )
return;
ExplosionTemplate.DamageRadius *= DemoPerk.GetAoERadiusModifier();
}
}
simulated protected function SetExplosionActorClass()
{
local ExtPlayerReplicationInfo MyPRI;
Super(KFProjectile).SetExplosionActorClass();
if(Instigator == None)
return;
MyPRI = ExtPlayerReplicationInfo(Instigator.PlayerReplicationInfo);
if( MyPRI != none )
{
if( bWasTimeDilated && MyPRI.bNukeIsOn && class'KFPerk_Demolitionist'.static.ProjectileShouldNuke( self ) )
ExplosionActorClass = class'KFPerk_Demolitionist'.static.GetNukeExplosionActorClass();
}
}
simulated function TriggerExplosion(Vector HitLocation, Vector HitNormal, Actor HitActor)
{
local vector NudgedHitLocation, ExplosionDirection;
local Pawn P;
local ExtPlayerReplicationInfo MyPRI;
if( bHasDisintegrated )
{
return;
}
if (!bHasExploded)
{
// On local player or server, we cache off our time dilation setting here
if( WorldInfo.NetMode == NM_ListenServer || WorldInfo.NetMode == NM_DedicatedServer || InstigatorController != None )
{
bWasTimeDilated = WorldInfo.TimeDilation < 1.f;
}
// Stop ambient sounds when this projectile explodes
if( bStopAmbientSoundOnExplode )
{
StopAmbientSound();
}
if (ExplosionTemplate != None)
{
StopSimulating();
// using a hit location slightly away from the impact point is nice for certain things
NudgedHitLocation = HitLocation + (HitNormal * 32.f);
SetExplosionActorClass();
if( ExplosionActorClass == class'KFPerk_Demolitionist'.static.GetNukeExplosionActorClass() )
{
P = Pawn(HitActor);
if( P != none )
{
NudgedHitLocation = P.Location - vect(0,0,1) * P.GetCollisionHeight();
}
}
ExplosionActor = Spawn(ExplosionActorClass, self,, NudgedHitLocation, rotator(HitNormal));
if (ExplosionActor != None)
{
ExplosionActor.Instigator = Instigator;
ExplosionActor.InstigatorController = InstigatorController;
PrepareExplosionTemplate();
// If the locations are zero (probably because this exploded in the air) set defaults
if( IsZero(HitLocation) )
{
HitLocation = Location;
}
if( IsZero(HitNormal) )
{
HitNormal = vect(0,0,1);
}
// these are needed for the decal tracing later in GameExplosionActor.Explode()
ExplosionTemplate.HitLocation = HitLocation;// NudgedHitLocation
ExplosionTemplate.HitNormal = HitNormal;
// If desired, attach to mover if we hit one
if(bAttachExplosionToHitMover && InterpActor(HitActor) != None)
{
ExplosionActor.Attachee = HitActor;
ExplosionTemplate.bAttachExplosionEmitterToAttachee = TRUE;
ExplosionActor.SetBase(HitActor);
}
// directional?
if (ExplosionTemplate.bDirectionalExplosion)
{
ExplosionDirection = GetExplosionDirection(HitNormal);
//DrawDebugLine(ExplosionActor.Location, ExplosionActor.Location+ExplosionDirection*64, 255, 255, 0, TRUE);
}
// @todo: make this function responsible for setting explosion instance parameters, and take instance parameters
// out of GearExplosion (e.g. Attachee)
PrepareExplosionActor(ExplosionActor);
MyPRI = ExtPlayerReplicationInfo(Instigator.PlayerReplicationInfo);
if( MyPRI != none && KFExplosionActorLingering(ExplosionActor) != None )
{
KFExplosionActorLingering(ExplosionActor).MaxTime *= MyPRI.NukeTimeMult;
KFExplosionActorLingering(ExplosionActor).LifeSpan *= MyPRI.NukeTimeMult;
}
ExplosionActor.Explode(ExplosionTemplate, ExplosionDirection); // go bewm
}
// done with it
if (!bPendingDelete && !bDeleteMe)
{
// defer destruction so any replication of explosion stuff can happen if necessary
DeferredDestroy(PostExplosionLifetime);
}
}
bHasExploded = true;
}
}
defaultproperties
{
}

View File

@ -0,0 +1,161 @@
class ExtProj_Rocket_RPG7 extends KFProj_Rocket_RPG7;
simulated protected function PrepareExplosionTemplate()
{
local ExtPlayerReplicationInfo MyPRI;
local Ext_PerkDemolition DemoPerk;
Super(KFProjectile).PrepareExplosionTemplate();
if(Instigator == None)
return;
MyPRI = ExtPlayerReplicationInfo(Instigator.PlayerReplicationInfo);
if( MyPRI != none )
{
if( bWasTimeDilated && MyPRI.bNukeIsOn && class'KFPerk_Demolitionist'.static.ProjectileShouldNuke( self ) )
{
ExplosionTemplate = class'KFPerk_Demolitionist'.static.GetNukeExplosionTemplate();
ExplosionTemplate.Damage = default.ExplosionTemplate.Damage * class'KFPerk_Demolitionist'.static.GetNukeDamageModifier();
ExplosionTemplate.DamageRadius = default.ExplosionTemplate.DamageRadius * class'KFPerk_Demolitionist'.static.GetNukeRadiusModifier();
ExplosionTemplate.DamageFalloffExponent = default.ExplosionTemplate.DamageFalloffExponent;
}
else if( MyPRI.bConcussiveIsOn )
{
ExplosionTemplate.ExplosionEffects = AltExploEffects;
ExplosionTemplate.ExplosionSound = class'KFPerk_Demolitionist'.static.GetConcussiveExplosionSound();
}
DemoPerk = Ext_PerkDemolition(MyPRI.FCurrentPerk);
if( DemoPerk == none )
return;
ExplosionTemplate.DamageRadius *= DemoPerk.GetAoERadiusModifier();
}
}
simulated protected function SetExplosionActorClass()
{
local ExtPlayerReplicationInfo MyPRI;
Super(KFProjectile).SetExplosionActorClass();
if(Instigator == None)
return;
MyPRI = ExtPlayerReplicationInfo(Instigator.PlayerReplicationInfo);
if( MyPRI != none )
{
if( bWasTimeDilated && MyPRI.bNukeIsOn && class'KFPerk_Demolitionist'.static.ProjectileShouldNuke( self ) )
ExplosionActorClass = class'KFPerk_Demolitionist'.static.GetNukeExplosionActorClass();
}
}
simulated function TriggerExplosion(Vector HitLocation, Vector HitNormal, Actor HitActor)
{
local vector NudgedHitLocation, ExplosionDirection;
local Pawn P;
local ExtPlayerReplicationInfo MyPRI;
if( bHasDisintegrated )
{
return;
}
if (!bHasExploded)
{
// On local player or server, we cache off our time dilation setting here
if( WorldInfo.NetMode == NM_ListenServer || WorldInfo.NetMode == NM_DedicatedServer || InstigatorController != None )
{
bWasTimeDilated = WorldInfo.TimeDilation < 1.f;
}
// Stop ambient sounds when this projectile explodes
if( bStopAmbientSoundOnExplode )
{
StopAmbientSound();
}
if (ExplosionTemplate != None)
{
StopSimulating();
// using a hit location slightly away from the impact point is nice for certain things
NudgedHitLocation = HitLocation + (HitNormal * 32.f);
SetExplosionActorClass();
if( ExplosionActorClass == class'KFPerk_Demolitionist'.static.GetNukeExplosionActorClass() )
{
P = Pawn(HitActor);
if( P != none )
{
NudgedHitLocation = P.Location - vect(0,0,1) * P.GetCollisionHeight();
}
}
ExplosionActor = Spawn(ExplosionActorClass, self,, NudgedHitLocation, rotator(HitNormal));
if (ExplosionActor != None)
{
ExplosionActor.Instigator = Instigator;
ExplosionActor.InstigatorController = InstigatorController;
PrepareExplosionTemplate();
// If the locations are zero (probably because this exploded in the air) set defaults
if( IsZero(HitLocation) )
{
HitLocation = Location;
}
if( IsZero(HitNormal) )
{
HitNormal = vect(0,0,1);
}
// these are needed for the decal tracing later in GameExplosionActor.Explode()
ExplosionTemplate.HitLocation = HitLocation;// NudgedHitLocation
ExplosionTemplate.HitNormal = HitNormal;
// If desired, attach to mover if we hit one
if(bAttachExplosionToHitMover && InterpActor(HitActor) != None)
{
ExplosionActor.Attachee = HitActor;
ExplosionTemplate.bAttachExplosionEmitterToAttachee = TRUE;
ExplosionActor.SetBase(HitActor);
}
// directional?
if (ExplosionTemplate.bDirectionalExplosion)
{
ExplosionDirection = GetExplosionDirection(HitNormal);
//DrawDebugLine(ExplosionActor.Location, ExplosionActor.Location+ExplosionDirection*64, 255, 255, 0, TRUE);
}
// @todo: make this function responsible for setting explosion instance parameters, and take instance parameters
// out of GearExplosion (e.g. Attachee)
PrepareExplosionActor(ExplosionActor);
MyPRI = ExtPlayerReplicationInfo(Instigator.PlayerReplicationInfo);
if( MyPRI != none && KFExplosionActorLingering(ExplosionActor) != None )
{
KFExplosionActorLingering(ExplosionActor).MaxTime *= MyPRI.NukeTimeMult;
KFExplosionActorLingering(ExplosionActor).LifeSpan *= MyPRI.NukeTimeMult;
}
ExplosionActor.Explode(ExplosionTemplate, ExplosionDirection); // go bewm
}
// done with it
if (!bPendingDelete && !bDeleteMe)
{
// defer destruction so any replication of explosion stuff can happen if necessary
DeferredDestroy(PostExplosionLifetime);
}
}
bHasExploded = true;
}
}
defaultproperties
{
}

View File

@ -0,0 +1,161 @@
class ExtProj_Rocket_Seeker6 extends KFProj_Rocket_Seeker6;
simulated protected function PrepareExplosionTemplate()
{
local ExtPlayerReplicationInfo MyPRI;
local Ext_PerkDemolition DemoPerk;
Super(KFProjectile).PrepareExplosionTemplate();
if(Instigator == None)
return;
MyPRI = ExtPlayerReplicationInfo(Instigator.PlayerReplicationInfo);
if( MyPRI != none )
{
if( bWasTimeDilated && MyPRI.bNukeIsOn && class'KFPerk_Demolitionist'.static.ProjectileShouldNuke( self ) )
{
ExplosionTemplate = class'KFPerk_Demolitionist'.static.GetNukeExplosionTemplate();
ExplosionTemplate.Damage = default.ExplosionTemplate.Damage * class'KFPerk_Demolitionist'.static.GetNukeDamageModifier();
ExplosionTemplate.DamageRadius = default.ExplosionTemplate.DamageRadius * class'KFPerk_Demolitionist'.static.GetNukeRadiusModifier();
ExplosionTemplate.DamageFalloffExponent = default.ExplosionTemplate.DamageFalloffExponent;
}
else if( MyPRI.bConcussiveIsOn )
{
ExplosionTemplate.ExplosionEffects = AltExploEffects;
ExplosionTemplate.ExplosionSound = class'KFPerk_Demolitionist'.static.GetConcussiveExplosionSound();
}
DemoPerk = Ext_PerkDemolition(MyPRI.FCurrentPerk);
if( DemoPerk == none )
return;
ExplosionTemplate.DamageRadius *= DemoPerk.GetAoERadiusModifier();
}
}
simulated protected function SetExplosionActorClass()
{
local ExtPlayerReplicationInfo MyPRI;
Super(KFProjectile).SetExplosionActorClass();
if(Instigator == None)
return;
MyPRI = ExtPlayerReplicationInfo(Instigator.PlayerReplicationInfo);
if( MyPRI != none )
{
if( bWasTimeDilated && MyPRI.bNukeIsOn && class'KFPerk_Demolitionist'.static.ProjectileShouldNuke( self ) )
ExplosionActorClass = class'KFPerk_Demolitionist'.static.GetNukeExplosionActorClass();
}
}
simulated function TriggerExplosion(Vector HitLocation, Vector HitNormal, Actor HitActor)
{
local vector NudgedHitLocation, ExplosionDirection;
local Pawn P;
local ExtPlayerReplicationInfo MyPRI;
if( bHasDisintegrated )
{
return;
}
if (!bHasExploded)
{
// On local player or server, we cache off our time dilation setting here
if( WorldInfo.NetMode == NM_ListenServer || WorldInfo.NetMode == NM_DedicatedServer || InstigatorController != None )
{
bWasTimeDilated = WorldInfo.TimeDilation < 1.f;
}
// Stop ambient sounds when this projectile explodes
if( bStopAmbientSoundOnExplode )
{
StopAmbientSound();
}
if (ExplosionTemplate != None)
{
StopSimulating();
// using a hit location slightly away from the impact point is nice for certain things
NudgedHitLocation = HitLocation + (HitNormal * 32.f);
SetExplosionActorClass();
if( ExplosionActorClass == class'KFPerk_Demolitionist'.static.GetNukeExplosionActorClass() )
{
P = Pawn(HitActor);
if( P != none )
{
NudgedHitLocation = P.Location - vect(0,0,1) * P.GetCollisionHeight();
}
}
ExplosionActor = Spawn(ExplosionActorClass, self,, NudgedHitLocation, rotator(HitNormal));
if (ExplosionActor != None)
{
ExplosionActor.Instigator = Instigator;
ExplosionActor.InstigatorController = InstigatorController;
PrepareExplosionTemplate();
// If the locations are zero (probably because this exploded in the air) set defaults
if( IsZero(HitLocation) )
{
HitLocation = Location;
}
if( IsZero(HitNormal) )
{
HitNormal = vect(0,0,1);
}
// these are needed for the decal tracing later in GameExplosionActor.Explode()
ExplosionTemplate.HitLocation = HitLocation;// NudgedHitLocation
ExplosionTemplate.HitNormal = HitNormal;
// If desired, attach to mover if we hit one
if(bAttachExplosionToHitMover && InterpActor(HitActor) != None)
{
ExplosionActor.Attachee = HitActor;
ExplosionTemplate.bAttachExplosionEmitterToAttachee = TRUE;
ExplosionActor.SetBase(HitActor);
}
// directional?
if (ExplosionTemplate.bDirectionalExplosion)
{
ExplosionDirection = GetExplosionDirection(HitNormal);
//DrawDebugLine(ExplosionActor.Location, ExplosionActor.Location+ExplosionDirection*64, 255, 255, 0, TRUE);
}
// @todo: make this function responsible for setting explosion instance parameters, and take instance parameters
// out of GearExplosion (e.g. Attachee)
PrepareExplosionActor(ExplosionActor);
MyPRI = ExtPlayerReplicationInfo(Instigator.PlayerReplicationInfo);
if( MyPRI != none && KFExplosionActorLingering(ExplosionActor) != None )
{
KFExplosionActorLingering(ExplosionActor).MaxTime *= MyPRI.NukeTimeMult;
KFExplosionActorLingering(ExplosionActor).LifeSpan *= MyPRI.NukeTimeMult;
}
ExplosionActor.Explode(ExplosionTemplate, ExplosionDirection); // go bewm
}
// done with it
if (!bPendingDelete && !bDeleteMe)
{
// defer destruction so any replication of explosion stuff can happen if necessary
DeferredDestroy(PostExplosionLifetime);
}
}
bHasExploded = true;
}
}
defaultproperties
{
}

View File

@ -0,0 +1,161 @@
class ExtProj_Thrown_C4 extends KFProj_Thrown_C4;
simulated protected function PrepareExplosionTemplate()
{
local ExtPlayerReplicationInfo MyPRI;
local Ext_PerkDemolition DemoPerk;
Super(KFProjectile).PrepareExplosionTemplate();
if(Instigator == None)
return;
MyPRI = ExtPlayerReplicationInfo(Instigator.PlayerReplicationInfo);
if( MyPRI != none )
{
if( bWasTimeDilated && MyPRI.bNukeIsOn && class'KFPerk_Demolitionist'.static.ProjectileShouldNuke( self ) )
{
ExplosionTemplate = class'KFPerk_Demolitionist'.static.GetNukeExplosionTemplate();
ExplosionTemplate.Damage = default.ExplosionTemplate.Damage * class'KFPerk_Demolitionist'.static.GetNukeDamageModifier();
ExplosionTemplate.DamageRadius = default.ExplosionTemplate.DamageRadius * class'KFPerk_Demolitionist'.static.GetNukeRadiusModifier();
ExplosionTemplate.DamageFalloffExponent = default.ExplosionTemplate.DamageFalloffExponent;
}
else if( MyPRI.bConcussiveIsOn )
{
ExplosionTemplate.ExplosionEffects = AltExploEffects;
ExplosionTemplate.ExplosionSound = class'KFPerk_Demolitionist'.static.GetConcussiveExplosionSound();
}
DemoPerk = Ext_PerkDemolition(MyPRI.FCurrentPerk);
if( DemoPerk == none )
return;
ExplosionTemplate.DamageRadius *= DemoPerk.GetAoERadiusModifier();
}
}
simulated protected function SetExplosionActorClass()
{
local ExtPlayerReplicationInfo MyPRI;
Super(KFProjectile).SetExplosionActorClass();
if(Instigator == None)
return;
MyPRI = ExtPlayerReplicationInfo(Instigator.PlayerReplicationInfo);
if( MyPRI != none )
{
if( bWasTimeDilated && MyPRI.bNukeIsOn && class'KFPerk_Demolitionist'.static.ProjectileShouldNuke( self ) )
ExplosionActorClass = class'KFPerk_Demolitionist'.static.GetNukeExplosionActorClass();
}
}
simulated function TriggerExplosion(Vector HitLocation, Vector HitNormal, Actor HitActor)
{
local vector NudgedHitLocation, ExplosionDirection;
local Pawn P;
local ExtPlayerReplicationInfo MyPRI;
if( bHasDisintegrated )
{
return;
}
if (!bHasExploded)
{
// On local player or server, we cache off our time dilation setting here
if( WorldInfo.NetMode == NM_ListenServer || WorldInfo.NetMode == NM_DedicatedServer || InstigatorController != None )
{
bWasTimeDilated = WorldInfo.TimeDilation < 1.f;
}
// Stop ambient sounds when this projectile explodes
if( bStopAmbientSoundOnExplode )
{
StopAmbientSound();
}
if (ExplosionTemplate != None)
{
StopSimulating();
// using a hit location slightly away from the impact point is nice for certain things
NudgedHitLocation = HitLocation + (HitNormal * 32.f);
SetExplosionActorClass();
if( ExplosionActorClass == class'KFPerk_Demolitionist'.static.GetNukeExplosionActorClass() )
{
P = Pawn(HitActor);
if( P != none )
{
NudgedHitLocation = P.Location - vect(0,0,1) * P.GetCollisionHeight();
}
}
ExplosionActor = Spawn(ExplosionActorClass, self,, NudgedHitLocation, rotator(HitNormal));
if (ExplosionActor != None)
{
ExplosionActor.Instigator = Instigator;
ExplosionActor.InstigatorController = InstigatorController;
PrepareExplosionTemplate();
// If the locations are zero (probably because this exploded in the air) set defaults
if( IsZero(HitLocation) )
{
HitLocation = Location;
}
if( IsZero(HitNormal) )
{
HitNormal = vect(0,0,1);
}
// these are needed for the decal tracing later in GameExplosionActor.Explode()
ExplosionTemplate.HitLocation = HitLocation;// NudgedHitLocation
ExplosionTemplate.HitNormal = HitNormal;
// If desired, attach to mover if we hit one
if(bAttachExplosionToHitMover && InterpActor(HitActor) != None)
{
ExplosionActor.Attachee = HitActor;
ExplosionTemplate.bAttachExplosionEmitterToAttachee = TRUE;
ExplosionActor.SetBase(HitActor);
}
// directional?
if (ExplosionTemplate.bDirectionalExplosion)
{
ExplosionDirection = GetExplosionDirection(HitNormal);
//DrawDebugLine(ExplosionActor.Location, ExplosionActor.Location+ExplosionDirection*64, 255, 255, 0, TRUE);
}
// @todo: make this function responsible for setting explosion instance parameters, and take instance parameters
// out of GearExplosion (e.g. Attachee)
PrepareExplosionActor(ExplosionActor);
MyPRI = ExtPlayerReplicationInfo(Instigator.PlayerReplicationInfo);
if( MyPRI != none && KFExplosionActorLingering(ExplosionActor) != None )
{
KFExplosionActorLingering(ExplosionActor).MaxTime *= MyPRI.NukeTimeMult;
KFExplosionActorLingering(ExplosionActor).LifeSpan *= MyPRI.NukeTimeMult;
}
ExplosionActor.Explode(ExplosionTemplate, ExplosionDirection); // go bewm
}
// done with it
if (!bPendingDelete && !bDeleteMe)
{
// defer destruction so any replication of explosion stuff can happen if necessary
DeferredDestroy(PostExplosionLifetime);
}
}
bHasExploded = true;
}
}
defaultproperties
{
}

View File

@ -0,0 +1,50 @@
class ExtSM_Player_Emote extends KFSM_Player_Emote;
static function byte PackFlagsBase( KFPawn P )
{
return class'ExtEmoteList'.static.GetEmoteIndex( class'ExtEmoteList'.static.GetEquippedEmoteId(ExtPlayerController(P.Controller)) );
}
function PlayAnimation()
{
AnimName = class'ExtEmoteList'.static.GetEmoteFromIndex( KFPOwner.SpecialMoveFlags );
PlaySpecialMoveAnim( AnimName, AnimStance, BlendInTime, BlendOutTime, 1.f );
if( KFPOwner.Role == ROLE_Authority )
{
KFGameInfo(KFPOwner.WorldInfo.Game).DialogManager.PlayDialogEvent( KFPOwner, 31 );
}
// Store camera mode for restoration after move ends
LastCameraMode = 'FirstPerson';
if( PCOwner != none && PCOwner.PlayerCamera != none )
{
LastCameraMode = PCOwner.PlayerCamera.CameraStyle;
}
// Set camera to emote third person camera
if( PCOwner == none || !PawnOwner.IsLocallyControlled() )
{
KFPOwner.SetWeaponAttachmentVisibility( false );
return;
}
if( PCOwner.CanViewCinematics() )
{
PCOwner.ClientSetCameraFade( true, FadeInColor, vect2d(1.f, 0.f), FadeInTime, true );
PCOwner.PlayerCamera.CameraStyle = 'Emote';
// Switch camera modes immediately in single player or on client
if( PCOwner.WorldInfo.NetMode != NM_DedicatedServer )
{
PCOwner.ClientSetCameraMode( 'Emote' );
}
KFPOwner.SetWeaponAttachmentVisibility( false );
}
}
DefaultProperties
{
}

View File

@ -1,7 +1,14 @@
class ExtSM_Siren_Scream extends KFSM_Siren_Scream;
function SpawnProjectileShield()
{
return;
}
DefaultProperties
{
ExplosionActorClass=class'ExtExplosion_SirenScream'
// explosion
Begin Object Name=ExploTemplate0
ActorClassToIgnoreForDamage=class'KFPawn_ZedSirenX'

View File

@ -0,0 +1,11 @@
class ExtWeapDef_Grenade_Demo extends KFWeapDef_Grenade_Demo;
static function string GetItemLocalization(string KeyName)
{
return class'KFWeapDef_Grenade_Demo'.Static.GetItemLocalization(KeyName);
}
DefaultProperties
{
WeaponClassPath="ServerExt.ExtProj_DynamiteGrenade"
}

View File

@ -0,0 +1,12 @@
class ExtWeap_Pistol_9mm extends KFWeap_Pistol_9mm;
defaultproperties
{
SpareAmmoCapacity[0]=-1
InitialSpareMags[0]=0
bInfiniteSpareAmmo=True
DualClass=class'ExtWeap_Pistol_Dual9mm'
}

View File

@ -0,0 +1,7 @@
class ExtWeap_Pistol_Dual9mm extends KFWeap_Pistol_Dual9mm;
defaultproperties
{
SingleClass=class'ExtWeap_Pistol_9mm'
}

View File

@ -0,0 +1,12 @@
class ExtWeap_Pistol_MedicS extends KFWeap_Pistol_Medic;
defaultproperties
{
AssociatedPerkClasses(0)=none
bCanThrow=false
SpareAmmoCapacity[0]=-1
InitialSpareMags[0]=0
bInfiniteSpareAmmo=True
}

File diff suppressed because it is too large Load Diff

View File

@ -3,85 +3,78 @@ class ExtWidget_PartyInGame extends KFGFxWidget_PartyInGame;
var class<Ext_PerkBase> PPerkSlots[6];
var byte PPerkLevels[6];
struct ExtMemberSlotStruct
{
var class<Ext_PerkBase> PerkClass;
structdefaultproperties
{
PerkClass=none
}
};
var ExtMemberSlotStruct ExtMemberSlots[13];
function GFxObject RefreshSlot( int SlotIndex, KFPlayerReplicationInfo KFPRI )
{
local string PlayerName;
local UniqueNetId AdminId;
local bool bIsLeader;
local bool bIsMyPlayer;
local PlayerController PC;
local ExtPlayerController EPC;
local GFxObject PlayerInfoObject;
local class<Ext_PerkBase> CurrentPerkClass;
local int CurrentPerkLevel;
local ExtPlayerReplicationInfo EPRI;
PlayerInfoObject = CreateObject("Object");
EPRI = ExtPlayerReplicationInfo(KFPRI);
PC = GetPC();
EPC = ExtPlayerController(GetPC());
if( KFPRI != none )
{
EPRI = ExtPlayerReplicationInfo(KFPRI);
}
if( OnlineLobby != none )
{
OnlineLobby.GetLobbyAdmin( OnlineLobby.GetCurrentLobbyId(), AdminId);
}
//leader
bIsLeader = (KFPRI.UniqueId == AdminId);
bIsLeader = EPRI.UniqueId == AdminId;
PlayerInfoObject.SetBool("bLeader", bIsLeader);
//my player
bIsMyPlayer = PC.PlayerReplicationInfo.UniqueId == KFPRI.UniqueId;
MemberSlots[SlotIndex].PlayerUID = KFPRI.UniqueId;
MemberSlots[SlotIndex].PRI = KFPRI;
bIsMyPlayer = EPC.PlayerReplicationInfo.UniqueId == KFPRI.UniqueId;
ExtMemberSlots[SlotIndex].PerkClass = EPRI.ECurrentPerk;
PlayerInfoObject.SetBool("myPlayer", bIsMyPlayer);
// Update this players perk information
CurrentPerkClass = (EPRI!=None ? EPRI.ECurrentPerk : None);
CurrentPerkLevel = (EPRI!=None ? EPRI.ECurrentPerkLevel : 0);
if ( PPerkSlots[SlotIndex] != CurrentPerkClass || PPerkLevels[SlotIndex] != CurrentPerkLevel )
if( ExtMemberSlots[SlotIndex].PerkClass != none )
{
PPerkSlots[SlotIndex] = CurrentPerkClass;
PPerkLevels[SlotIndex] = CurrentPerkLevel;
PlayerInfoObject.SetString("perkLevel", string(CurrentPerkLevel) @ CurrentPerkClass.default.PerkName);
PlayerInfoObject.SetString("perkIconPath", CurrentPerkClass.Static.GetPerkIconPath(CurrentPerkLevel));
PlayerInfoObject.SetString("perkLevel", string(EPRI.ECurrentPerkLevel));
PlayerInfoObject.SetString("perkIconPath", ExtMemberSlots[SlotIndex].PerkClass.static.GetPerkIconPath(EPRI.ECurrentPerkLevel));
}
//perk info
if(MemberSlots[SlotIndex].PerkClass != none)
{
PlayerInfoObject.SetString("perkLevel", MemberSlots[SlotIndex].PerkLevel @MemberSlots[SlotIndex].PerkClass.default.PerkName);
PlayerInfoObject.SetString("perkIconPath", "img://"$MemberSlots[SlotIndex].PerkClass.static.GetPerkIconPath());
}
//perk info
if( !bIsMyPlayer )
{
PlayerInfoObject.SetBool("muted", PC.IsPlayerMuted(KFPRI.UniqueId));
PlayerInfoObject.SetBool("muted", EPC.IsPlayerMuted(EPRI.UniqueId));
}
// E3 build force update of player name
if( class'WorldInfo'.static.IsE3Build() )
{
// Update this slots player name
PlayerName = KFPRI.PlayerName;
PlayerName = EPRI.PlayerName;
}
else
{
PlayerName = KFPRI.PlayerName;
PlayerName = EPRI.PlayerName;
}
PlayerInfoObject.SetString("playerName", PlayerName);
//player icon
if( class'WorldInfo'.static.IsConsoleBuild(CONSOLE_Orbis) )
{
PlayerInfoObject.SetString("profileImageSource", KFPC.GetPS4Avatar(PlayerName));
PlayerInfoObject.SetString("profileImageSource", "img://"$KFPC.GetPS4Avatar(PlayerName));
}
else
{
PlayerInfoObject.SetString("profileImageSource", KFPC.GetSteamAvatar(KFPRI.UniqueId));
PlayerInfoObject.SetString("profileImageSource", "img://"$KFPC.GetSteamAvatar(EPRI.UniqueId));
}
if( KFGRI != none )
{
PlayerInfoObject.SetBool("ready", KFPRI.bReadyToPlay && !KFGRI.bMatchHasBegun);
PlayerInfoObject.SetBool("ready", EPRI.bReadyToPlay && !KFGRI.bMatchHasBegun);
}
return PlayerInfoObject;
}
DefaultProperties
{
PlayerSlots=12
}

View File

@ -1346,6 +1346,14 @@ simulated function float GetIronSightSpeedModifier( KFWeapon KFW )
return 1.f;
}
function OnWaveEnded();
function NotifyZedTimeStarted();
simulated function float GetZedTimeExtensions( byte Level )
{
return 1.f;
}
defaultproperties
{
CurrentConfigVer=13

View File

@ -1,20 +1,70 @@
Class Ext_PerkCommando extends Ext_PerkBase;
var bool bUseProfessional,bUseMachineGunner;
var float ZTExtCount;
replication
{
// Things the server should send to the client.
if ( true )
bUseProfessional,bUseMachineGunner;
}
simulated function bool GetUsingTactialReload( KFWeapon KFW )
{
return (IsWeaponOnPerk(KFW) ? Modifiers[5]<0.65 : false);
}
simulated function ModifyDamageGiven( out int InDamage, optional Actor DamageCauser, optional KFPawn_Monster MyKFPM, optional KFPlayerController DamageInstigator, optional class<KFDamageType> DamageType, optional int HitZoneIdx )
{
if( (DamageType!=None && DamageType.Default.ModifierPerkList.Find(BasePerk)>=0) || (KFWeapon(DamageCauser)!=None && IsWeaponOnPerk(KFWeapon(DamageCauser))) )
{
if( bUseMachineGunner && WorldInfo.TimeDilation < 1.f )
InDamage += InDamage * 0.03;
}
Super.ModifyDamageGiven(InDamage, DamageCauser, MyKFPM, DamageInstigator, DamageType, HitZoneIdx);
}
simulated function float GetZedTimeModifier( KFWeapon W )
{
local name StateName;
StateName = W.GetStateName();
if( bUseProfessional && IsWeaponOnPerk( W ) )
{
if( StateName == 'Reloading' || StateName == 'AltReloading' )
return 1.f;
else if( StateName == 'WeaponPuttingDown' || StateName == 'WeaponEquipping' )
return 0.3f;
}
if( bUseMachineGunner && IsWeaponOnPerk( W ) && BasePerk.Default.ZedTimeModifyingStates.Find( StateName ) != INDEX_NONE )
return 0.5f;
return 0.f;
}
simulated function float GetZedTimeExtensions( byte Level )
{
return ZTExtCount;
}
defaultproperties
{
PerkName="Commando"
PerkIcon=Texture2D'UI_PerkIcons_TEX.UI_PerkIcon_Commando'
DefTraitList.Add(class'Ext_TraitWPComm')
DefTraitList.Add(class'Ext_TraitUnCloak')
DefTraitList.Add(class'Ext_TraitZedTExt')
DefTraitList.Add(class'Ext_TraitEnemyHP')
DefTraitList.Add(class'Ext_TraitEliteReload')
DefTraitList.Add(class'Ext_TraitTactician')
DefTraitList.Add(class'Ext_TraitMachineGunner')
BasePerk=class'KFPerk_Commando'
ZTExtCount=1.f;
PrimaryMelee=class'KFWeap_Knife_Commando'
PrimaryWeapon=class'KFWeap_AssaultRifle_AR15'
PerkGrenade=class'KFProj_HEGrenade'

View File

@ -1,5 +1,86 @@
Class Ext_PerkDemolition extends Ext_PerkBase;
var bool bSirenResistance,bCanUseSacrifice,bDirectHit,bCriticalHit,bProfessionalActive;
var bool bUsedSacrifice;
var float AOEMult, NukeDamageMult;
replication
{
// Things the server should send to the client.
if ( true )
NukeDamageMult,bDirectHit,bCriticalHit,bProfessionalActive;
}
function float GetAoERadiusModifier()
{
return AOEMult;
}
simulated function bool GetUsingTactialReload( KFWeapon KFW )
{
return (IsWeaponOnPerk(KFW) ? Modifiers[5]<0.85 : false);
}
simulated function bool IsConcussiveForceActive()
{
return Modifiers[7] > 1.5;
}
simulated function float ApplyEffect( name Type, float Value, float Progress )
{
local ExtPlayerReplicationInfo MyPRI;
MyPRI = ExtPlayerReplicationInfo(PlayerOwner.PlayerReplicationInfo);
switch( Type )
{
case 'KnockDown':
if( MyPRI != none )
MyPRI.bConcussiveIsOn = IsConcussiveForceActive();
break;
}
return Super.ApplyEffect(Type, Value, Progress);
}
function OnWaveEnded()
{
bUsedSacrifice = false;
}
simulated function ModifyDamageGiven( out int InDamage, optional Actor DamageCauser, optional KFPawn_Monster MyKFPM, optional KFPlayerController DamageInstigator, optional class<KFDamageType> DamageType, optional int HitZoneIdx )
{
if( BasePerk==None || (DamageType!=None && DamageType.Default.ModifierPerkList.Find(BasePerk)>=0) || (KFWeapon(DamageCauser)!=None && IsWeaponOnPerk(KFWeapon(DamageCauser))) )
{
if( bDirectHit && class<KFDT_Ballistic_Shell>(DamageType) != none )
InDamage *= 0.25;
if( bCriticalHit && MyKFPM != none && IsCriticalHitZone( MyKFPM, HitZoneIdx ) )
InDamage *= 0.5f;
}
if( class<KFDT_DemoNuke_Toxic_Lingering>(DamageType) != None )
InDamage *= NukeDamageMult;
Super.ModifyDamageGiven(InDamage, DamageCauser, MyKFPM, DamageInstigator, DamageType, HitZoneIdx);
}
function bool IsCriticalHitZone( KFPawn TestPawn, int HitZoneIndex )
{
if( TestPawn != none && HitzoneIndex >= 0 && HitzoneIndex < TestPawn.HitZones.length )
return TestPawn.HitZones[HitZoneIndex].DmgScale > 1.f;
return false;
}
simulated function ModifySpareAmmoAmount( KFWeapon KFW, out int PrimarySpareAmmo, optional const out STraderItem TraderItem, optional bool bSecondary )
{
if( KFW != None && KFWeap_Thrown_C4(KFW) != None )
PrimarySpareAmmo += (1 + Modifiers[11]);
Super.ModifySpareAmmoAmount( KFW, PrimarySpareAmmo, TraderItem, bSecondary );
}
defaultproperties
{
PerkName="Demolitionist"
@ -8,15 +89,22 @@ defaultproperties
DefTraitList.Add(class'Ext_TraitBoomWeld')
DefTraitList.Add(class'Ext_TraitContactNade')
DefTraitList.Add(class'Ext_TraitSupplyGren')
DefTraitList.Add(class'Ext_TraitSirenResistance')
DefTraitList.Add(class'Ext_TraitDemoDirectHit')
DefTraitList.Add(class'Ext_TraitDemoCriticalHit')
DefTraitList.Add(class'Ext_TraitDemoAOE')
DefTraitList.Add(class'Ext_TraitDemoReactiveArmor')
DefTraitList.Add(class'Ext_TraitDemoNuke')
DefTraitList.Add(class'Ext_TraitDemoProfessional')
BasePerk=class'KFPerk_Demolitionist'
PrimaryMelee=class'KFWeap_Knife_Demolitionist'
PrimaryWeapon=class'KFWeap_GrenadeLauncher_HX25'
PerkGrenade=class'KFProj_DynamiteGrenade'
PerkGrenade=class'ExtProj_DynamiteGrenade'
PrimaryWeaponDef=class'KFWeapDef_HX25'
KnifeWeaponDef=class'KFWeapDef_Knife_Demo'
GrenadeWeaponDef=class'KFWeapDef_Grenade_Demo'
GrenadeWeaponDef=class'ExtWeapDef_Grenade_Demo'
AutoBuyLoadOutPath=(class'KFWeapDef_HX25', class'KFWeapDef_M79', class'KFWeapDef_M16M203', class'KFWeapDef_RPG7')

View File

@ -3,6 +3,35 @@ Class Ext_PerkFieldMedic extends Ext_PerkBase;
var float RepairArmorRate,AirborneAgentHealRate;
var byte AirborneAgentLevel;
var bool bHealingBoost,bHealingDamageBoost,bHealingShield;
var byte HealingShield;
var const float SelfHealingSurgePct,MaxHealingSpeedBoost,HealingSpeedBoostDuration,MaxHealingDamageBoost,HealingDamageBoostDuration,MaxHealingShield,HealingShieldDuration;
var float HealingSpeedBoostPct, HealingDamageBoostPct, HealingShieldPct;
var bool bUseToxicDamage,bUseSlug,bUseAirborneAgent;
var const class<KFDamageType> ToxicDmgTypeClass;
simulated function ModifyDamageGiven( out int InDamage, optional Actor DamageCauser, optional KFPawn_Monster MyKFPM, optional KFPlayerController DamageInstigator, optional class<KFDamageType> DamageType, optional int HitZoneIdx )
{
local float TempDamage;
TempDamage = InDamage;
if( bUseSlug && WorldInfo.TimeDilation < 1.f && DamageType != none && ClassIsChildOf( DamageType, class'KFDT_Toxic' ) )
TempDamage += InDamage * 100;
InDamage = Round(TempDamage);
Super.ModifyDamageGiven(InDamage, DamageCauser, MyKFPM, DamageInstigator, DamageType, HitZoneIdx);
}
simulated function ModifyMagSizeAndNumber( KFWeapon KFW, out byte MagazineCapacity, optional array< Class<KFPerk> > WeaponPerkClass, optional bool bSecondary=false, optional name WeaponClassname )
{
if( MagazineCapacity>2 && (KFW==None ? WeaponPerkClass.Find(BasePerk)>=0 : IsWeaponOnPerk(KFW)) ) // Skip boomstick for this.
MagazineCapacity = Min(MagazineCapacity*Modifiers[10], bSecondary ? 150 : 255);
}
function bool RepairArmor( Pawn HealTarget )
{
local KFPawn_Human KFPH;
@ -25,7 +54,7 @@ function bool ModifyHealAmount( out float HealAmount )
}
simulated function ModifyHealerRechargeTime( out float RechargeRate )
{
RechargeRate/=Modifiers[9];
RechargeRate /= Clamp(Modifiers[9] * 2, 1.f, 3.f);
}
function CheckForAirborneAgent( KFPawn HealTarget, class<DamageType> DamType, int HealAmount )
@ -52,6 +81,90 @@ function GiveMedicAirborneAgentHealth( KFPawn HealTarget, class<DamageType> DamT
}
}
static function class<KFDamageType> GetToxicDmgTypeClass()
{
return default.ToxicDmgTypeClass;
}
static function int ModifyToxicDmg(int ToxicDamage)
{
local float TempDamage;
TempDamage = float(ToxicDamage) * 1.2;
return FCeil( TempDamage );
}
function NotifyZedTimeStarted()
{
local KFPawn_Human HPawn;
HPawn = KFPawn_Human(PlayerOwner.Pawn);
if( bUseAirborneAgent && HPawn != none && HPawn.IsAliveAndWell() )
HPawn.StartAirBorneAgentEvent();
}
simulated function float GetSnarePower( optional class<DamageType> DamageType, optional byte HitZoneIdx )
{
if( bUseSlug && WorldInfo.TimeDilation < 1.f && class<KFDamageType>(DamageType)!=None && class<KFDamageType>(DamageType).Default.ModifierPerkList.Find(BasePerk)>=0 )
return 100;
return 0.f;
}
simulated function bool GetHealingSpeedBoostActive()
{
return bHealingBoost;
}
simulated function byte GetHealingSpeedBoost()
{
return byte(HealingSpeedBoostPct);
}
simulated function byte GetMaxHealingSpeedBoost()
{
return MaxHealingSpeedBoost;
}
simulated function float GetHealingSpeedBoostDuration()
{
return HealingSpeedBoostDuration;
}
simulated function bool GetHealingDamageBoostActive()
{
return bHealingDamageBoost;
}
simulated function byte GetHealingDamageBoost()
{
return byte(HealingDamageBoostPct);
}
simulated function byte GetMaxHealingDamageBoost()
{
return MaxHealingDamageBoost;
}
simulated function float GetHealingDamageBoostDuration()
{
return HealingDamageBoostDuration;
}
simulated function bool GetHealingShieldActive()
{
return bHealingShield;
}
simulated function byte GetHealingShield()
{
return byte(HealingShieldPct);
}
simulated function byte GetMaxHealingShield()
{
return MaxHealingShield;
}
simulated function float GetHealingShieldDuration()
{
return HealingShieldDuration;
}
simulated function float GetSelfHealingSurgePct()
{
return SelfHealingSurgePct;
}
defaultproperties
{
PerkName="Field Medic"
@ -59,11 +172,32 @@ defaultproperties
DefTraitList.Remove(class'Ext_TraitMedicPistol')
DefTraitList.Add(class'Ext_TraitAirborne')
DefTraitList.Add(class'Ext_TraitWPMedic')
DefTraitList.Add(class'Ext_TraitArmorRep')
DefTraitList.Add(class'Ext_TraitToxicDart')
DefTraitList.Add(class'Ext_TraitAcidicCompound')
DefTraitList.Add(class'Ext_TraitMedBoost')
DefTraitList.Add(class'Ext_TraitMedDamBoost')
DefTraitList.Add(class'Ext_TraitMedShield')
DefTraitList.Add(class'Ext_TraitZedative')
DefTraitList.Add(class'Ext_TraitAirborneAgent')
BasePerk=class'KFPerk_FieldMedic'
HealExpUpNum=3
HealingSpeedBoostPct = 10.0f
HealingDamageBoostPct = 5.0f
HealingShieldPct = 10.0f
ToxicDmgTypeClass=class'KFDT_Toxic_AcidicRounds'
SelfHealingSurgePct=0.1f
MaxHealingSpeedBoost=30
HealingSpeedBoostDuration=5.f
MaxHealingDamageBoost=20
HealingDamageBoostDuration=5.f
MaxHealingShield=30
HealingShieldDuration=5.0f
DefPerkStats(0)=(MaxValue=70)
DefPerkStats(9)=(bHiddenConfig=false) // Heal efficiency
DefPerkStats(15)=(bHiddenConfig=false) // Toxic resistance

View File

@ -9,6 +9,11 @@ replication
bHasUberAmmo,bHasFanfire;
}
simulated function bool GetUsingTactialReload( KFWeapon KFW )
{
return (IsWeaponOnPerk(KFW) ? Modifiers[5]<0.8 : false);
}
simulated function bool GetIsUberAmmoActive( KFWeapon KFW )
{
return bHasUberAmmo && IsWeaponOnPerk(KFW) && WorldInfo.TimeDilation < 1.f;
@ -16,8 +21,15 @@ simulated function bool GetIsUberAmmoActive( KFWeapon KFW )
simulated function float GetZedTimeModifier( KFWeapon W )
{
if( bHasFanfire && WorldInfo.TimeDilation<1.f && IsWeaponOnPerk(W) && BasePerk.Default.ZedTimeModifyingStates.Find(W.GetStateName()) != INDEX_NONE )
return 0.9f;
local name StateName;
if( bHasFanfire && IsWeaponOnPerk( W ) )
{
StateName = W.GetStateName();
if( BasePerk.Default.ZedTimeModifyingStates.Find( StateName ) != INDEX_NONE || StateName == 'Reloading' )
return 1.f;
}
return 0.f;
}

View File

@ -2,12 +2,13 @@ Class Ext_PerkSWAT extends Ext_PerkBase;
var byte RepTacticalMove;
var float MoveSpeedMods[3];
var bool bRapidAssault;
replication
{
// Things the server should send to the client.
if ( true )
RepTacticalMove;
RepTacticalMove, bRapidAssault;
}
simulated function float GetIronSightSpeedModifier( KFWeapon KFW )
@ -15,6 +16,18 @@ simulated function float GetIronSightSpeedModifier( KFWeapon KFW )
return ((RepTacticalMove>0 && IsWeaponOnPerk(KFW)) ? MoveSpeedMods[RepTacticalMove-1] : 1.f);
}
simulated function bool GetIsUberAmmoActive( KFWeapon KFW )
{
return bRapidAssault && IsWeaponOnPerk(KFW) && WorldInfo.TimeDilation < 1.f;
}
simulated function float GetZedTimeModifier( KFWeapon W )
{
if( bRapidAssault && WorldInfo.TimeDilation<1.f && IsWeaponOnPerk(W) && BasePerk.Default.ZedTimeModifyingStates.Find(W.GetStateName()) != INDEX_NONE )
return 0.51f;
return 0.f;
}
defaultproperties
{
PerkName="SWAT"
@ -23,6 +36,7 @@ defaultproperties
DefTraitList.Add(class'Ext_TraitHeavyArmor')
DefTraitList.Add(class'Ext_TraitTacticalMove')
DefTraitList.Add(class'Ext_TraitSWATEnforcer')
DefTraitList.Add(class'Ext_TraitRapidAssault')
BasePerk=class'KFPerk_SWAT'
PrimaryMelee=class'KFWeap_Knife_SWAT'

View File

@ -1,12 +1,45 @@
Class Ext_PerkSupport extends Ext_PerkBase;
var bool bUseAPShot,bUsePerforate,bCanRepairDoors;
var float APShotMul;
simulated function bool GetUsingTactialReload( KFWeapon KFW )
{
return (IsWeaponOnPerk(KFW) ? Modifiers[5]<0.75 : false);
}
function bool CanRepairDoors()
{
return bCanRepairDoors;
}
simulated function float GetPenetrationModifier( byte Level, class<KFDamageType> DamageType, optional bool bForce )
{
local float PenetrationPower;
if( !bForce && (DamageType == none || ( DamageType!=None && DamageType.Default.ModifierPerkList.Find(BasePerk) == INDEX_NONE )))
return 0;
PenetrationPower = bUseAPShot ? APShotMul : 0.f;
PenetrationPower = IsPerforateActive() ? 40.f : PenetrationPower;
return PenetrationPower;
}
simulated function bool IsPerforateActive()
{
return bUsePerforate && WorldInfo.TimeDilation < 1.f;
}
defaultproperties
{
PerkName="Support"
PerkIcon=Texture2D'UI_PerkIcons_TEX.UI_PerkIcon_Support'
DefTraitList.Add(class'Ext_TraitGrenadeSUpg')
DefTraitList.Add(class'Ext_TraitWPSupp')
DefTraitList.Add(class'Ext_TraitSupply')
DefTraitList(0)=class'Ext_TraitGrenadeSUpg'
DefTraitList.Add(class'Ext_TraitAPShots')
DefTraitList.Add(class'Ext_TraitDoorRepair')
DefTraitList.Add(class'Ext_TraitPenetrator')
BasePerk=class'KFPerk_Support'
WeldExpUpNum=80

View File

@ -0,0 +1,6 @@
class Ext_TGroupZEDTime extends Ext_TGroupBase;
defaultproperties
{
GroupInfo="ZED Time"
}

View File

@ -0,0 +1,34 @@
Class Ext_TraitAPShots extends Ext_TraitBase;
static function ApplyEffectOn( KFPawn_Human Player, Ext_PerkBase Perk, byte Level, optional Ext_TraitDataStore Data )
{
Ext_PerkSupport(Perk).APShotMul = 1 + (0.25 + (((float(Level) - 1.f) * 5.f) / 100.f));
}
static function CancelEffectOn( KFPawn_Human Player, Ext_PerkBase Perk, byte Level, optional Ext_TraitDataStore Data )
{
Ext_PerkSupport(Perk).APShotMul = 0.f;
}
static function TraitActivate( Ext_PerkBase Perk, byte Level, optional Ext_TraitDataStore Data )
{
Ext_PerkSupport(Perk).bUseAPShot = true;
}
static function TraitDeActivate( Ext_PerkBase Perk, byte Level, optional Ext_TraitDataStore Data )
{
Ext_PerkSupport(Perk).bUseAPShot = false;
}
defaultproperties
{
SupportedPerk=class'Ext_PerkSupport'
TraitName="Armor Piercing Rounds"
NumLevels=4
DefLevelCosts(0)=15
DefLevelCosts(1)=30
DefLevelCosts(2)=40
DefLevelCosts(3)=50
DefMinLevel=15
Description="Greatly increases penetration with perk weapons! The penetration strength is increased by every level in:|Lv1-4: 25%, 30%, 35%, 40%"
}

View File

@ -0,0 +1,19 @@
Class Ext_TraitAcidicCompound extends Ext_TraitBase;
static function TraitActivate( Ext_PerkBase Perk, byte Level, optional Ext_TraitDataStore Data )
{
Ext_PerkFieldMedic(Perk).bUseToxicDamage = true;
}
static function TraitDeActivate( Ext_PerkBase Perk, byte Level, optional Ext_TraitDataStore Data )
{
Ext_PerkFieldMedic(Perk).bUseToxicDamage = false;
}
defaultproperties
{
SupportedPerk=class'Ext_PerkFieldMedic'
TraitName="Acidic Compound"
DefLevelCosts(0)=15
DefMinLevel=5
Description="When activated medic weapons have a chance to poison zeds."
}

View File

@ -0,0 +1,50 @@
Class Ext_TraitAirborneAgent extends Ext_TraitBase;
static function string GetPerkDescription()
{
local string S;
S = Super.GetPerkDescription();
S $= "|Trait requires prestige level: #{FF4000}1";
return S;
}
static function bool MeetsRequirements( byte Lvl, Ext_PerkBase Perk )
{
local int i;
if( Perk.CurrentLevel<Default.MinLevel || Perk.CurrentPrestige<1 )
return false;
for( i=0; i<Perk.PerkTraits.Length; ++i )
{
if( Perk.PerkTraits[i].TraitType==Class'Ext_TraitGrenadeUpg' )
{
if( Perk.PerkTraits[i].CurrentLevel <= 0 )
return false;
else break;
}
}
return true;
}
static function TraitActivate( Ext_PerkBase Perk, byte Level, optional Ext_TraitDataStore Data )
{
Ext_PerkFieldMedic(Perk).bUseAirborneAgent = true;
}
static function TraitDeActivate( Ext_PerkBase Perk, byte Level, optional Ext_TraitDataStore Data )
{
Ext_PerkFieldMedic(Perk).bUseAirborneAgent = false;
}
defaultproperties
{
SupportedPerk=class'Ext_PerkFieldMedic'
TraitGroup=class'Ext_TGroupZEDTime'
TraitName="ZED TIME - Airborne Agent"
NumLevels=1
DefLevelCosts(0)=60
DefMinLevel=75
Description="You release a healing gas during Zed time, healing teammates close by. ||-REQUIREMENT: Grenade Upgrade trait needs to be level 1!"
}

View File

@ -0,0 +1,24 @@
Class Ext_TraitDemoAOE extends Ext_TraitBase;
static function ApplyEffectOn( KFPawn_Human Player, Ext_PerkBase Perk, byte Level, optional Ext_TraitDataStore Data )
{
Ext_PerkDemolition(Perk).AOEMult = 1 + (0.15 + (((float(Level) - 1.f) * 5.f) / 100.f));
}
static function CancelEffectOn( KFPawn_Human Player, Ext_PerkBase Perk, byte Level, optional Ext_TraitDataStore Data )
{
Ext_PerkDemolition(Perk).AOEMult = 1.0f;
}
defaultproperties
{
SupportedPerk=class'Ext_PerkDemolition'
TraitName="Area Of Damage"
NumLevels=4
DefLevelCosts(0)=25
DefLevelCosts(1)=15
DefLevelCosts(2)=30
DefLevelCosts(3)=40
DefMinLevel=15
Description="Increases the AOE of your demo weapons. The distance is increased by every level in:|Lv1-4: 15%, 20%, 25%, 30%"
}

View File

@ -0,0 +1,19 @@
Class Ext_TraitDemoCriticalHit extends Ext_TraitBase;
static function TraitActivate( Ext_PerkBase Perk, byte Level, optional Ext_TraitDataStore Data )
{
Ext_PerkDemolition(Perk).bCriticalHit = true;
}
static function TraitDeActivate( Ext_PerkBase Perk, byte Level, optional Ext_TraitDataStore Data )
{
Ext_PerkDemolition(Perk).bCriticalHit = false;
}
defaultproperties
{
SupportedPerk=class'Ext_PerkDemolition'
TraitName="Armor Piercing Rounds"
DefLevelCosts(0)=100
DefMinLevel=50
Description="Demo weapons will do 50% more damage when hitting a critical point!"
}

View File

@ -0,0 +1,19 @@
Class Ext_TraitDemoDirectHit extends Ext_TraitBase;
static function TraitActivate( Ext_PerkBase Perk, byte Level, optional Ext_TraitDataStore Data )
{
Ext_PerkDemolition(Perk).bDirectHit = true;
}
static function TraitDeActivate( Ext_PerkBase Perk, byte Level, optional Ext_TraitDataStore Data )
{
Ext_PerkDemolition(Perk).bDirectHit = false;
}
defaultproperties
{
SupportedPerk=class'Ext_PerkDemolition'
TraitName="High Impact"
DefLevelCosts(0)=65
DefMinLevel=35
Description="Demo weapons will do 25% more damage on a direct hit!"
}

View File

@ -0,0 +1,69 @@
Class Ext_TraitDemoNuke extends Ext_TraitBase;
static function string GetPerkDescription()
{
local string S;
S = Super.GetPerkDescription();
S $= "|Trait requires prestige level: #{FF4000}3";
return S;
}
static function bool MeetsRequirements( byte Lvl, Ext_PerkBase Perk )
{
local int i;
if( Perk.CurrentLevel<Default.MinLevel || Perk.CurrentPrestige<3 )
return false;
if( Lvl==0 )
{
i = Perk.PerkStats.Find('StatType','Damage');
if( i>=0 )
return (Perk.PerkStats[i].CurrentValue>=30);
}
return true;
}
static function TraitActivate( Ext_PerkBase Perk, byte Level, optional Ext_TraitDataStore Data )
{
local ExtPlayerReplicationInfo MyPRI;
MyPRI = ExtPlayerReplicationInfo(Perk.PlayerOwner.PlayerReplicationInfo);
if( MyPRI == None )
return;
MyPRI.bNukeIsOn = true;
MyPRI.NukeTimeMult = 1.0 + (((float(Level) - 1.f) * 2.f) / 100.f);
Ext_PerkDemolition(Perk).NukeDamageMult = 1.0 + (((float(Level) - 1.f) * 5.f) / 100.f);
}
static function TraitDeActivate( Ext_PerkBase Perk, byte Level, optional Ext_TraitDataStore Data )
{
local ExtPlayerReplicationInfo MyPRI;
MyPRI = ExtPlayerReplicationInfo(Perk.PlayerOwner.PlayerReplicationInfo);
if( MyPRI == None )
return;
MyPRI.bNukeIsOn = false;
MyPRI.NukeTimeMult = 1.0;
Ext_PerkDemolition(Perk).NukeDamageMult = 1.0;
}
defaultproperties
{
SupportedPerk=class'Ext_PerkDemolition'
TraitGroup=class'Ext_TGroupZEDTime'
TraitName="ZED Time - Nuke"
NumLevels=4
DefLevelCosts(0)=100
DefLevelCosts(1)=150
DefLevelCosts(2)=200
DefLevelCosts(3)=250
DefMinLevel=100
Description="Demo weapons will spawn a nuke during ZED time. |Each level increases the damage & time of the nuke field. ||-REQUIREMENT: Damage bonus trait needs to have at least 30 points!"
}

View File

@ -0,0 +1,46 @@
Class Ext_TraitDemoProfessional extends Ext_TraitBase;
static function string GetPerkDescription()
{
local string S;
S = Super.GetPerkDescription();
S $= "|Trait requires prestige level: #{FF4000}1";
return S;
}
static function bool MeetsRequirements( byte Lvl, Ext_PerkBase Perk )
{
local int i;
if( Perk.CurrentLevel<Default.MinLevel || Perk.CurrentPrestige<3 )
return false;
if( Lvl==0 )
{
i = Perk.PerkStats.Find('StatType','Reload');
if( i>=0 )
return (Perk.PerkStats[i].CurrentValue>=30);
}
return true;
}
static function TraitActivate( Ext_PerkBase Perk, byte Level, optional Ext_TraitDataStore Data )
{
Ext_PerkDemolition(Perk).bProfessionalActive = true;
}
static function TraitDeActivate( Ext_PerkBase Perk, byte Level, optional Ext_TraitDataStore Data )
{
Ext_PerkDemolition(Perk).bProfessionalActive = false;
}
defaultproperties
{
SupportedPerk=class'Ext_PerkDemolition'
TraitName="Demolitions Specialist"
DefLevelCosts(0)=100
DefMinLevel=100
Description="Projectiles from demo weapons will never be duds. ||-REQUIREMENT: Reload bonus trait needs to have at least 30 points!"
}

View File

@ -0,0 +1,19 @@
Class Ext_TraitDemoReactiveArmor extends Ext_TraitBase;
static function TraitActivate( Ext_PerkBase Perk, byte Level, optional Ext_TraitDataStore Data )
{
Ext_PerkDemolition(Perk).bCanUseSacrifice = true;
}
static function TraitDeActivate( Ext_PerkBase Perk, byte Level, optional Ext_TraitDataStore Data )
{
Ext_PerkDemolition(Perk).bCanUseSacrifice = false;
}
defaultproperties
{
SupportedPerk=class'Ext_PerkDemolition'
TraitName="Reactive Armor"
DefLevelCosts(0)=25
DefMinLevel=45
Description="When near death you will explode and leave yourself with 5 health"
}

View File

@ -0,0 +1,21 @@
Class Ext_TraitDoorRepair extends Ext_TraitBase;
static function TraitActivate( Ext_PerkBase Perk, byte Level, optional Ext_TraitDataStore Data )
{
Ext_PerkSupport(Perk).bCanRepairDoors = true;
}
static function TraitDeActivate( Ext_PerkBase Perk, byte Level, optional Ext_TraitDataStore Data )
{
Ext_PerkSupport(Perk).bCanRepairDoors = false;
}
defaultproperties
{
SupportedPerk=class'Ext_PerkSupport'
TraitName="Door Repair"
NumLevels=1
DefLevelCosts(0)=30
DefMinLevel=25
Description="Allows you to repair doors using the welder."
}

View File

@ -12,6 +12,7 @@ static function TraitDeActivate( Ext_PerkBase Perk, byte Level, optional Ext_Tra
defaultproperties
{
SupportedPerk=class'Ext_PerkGunslinger'
TraitGroup=class'Ext_TGroupZEDTime'
TraitName="ZED TIME - Fanfire"
DefLevelCosts(0)=30
Description="Make perked weapons fire at normal firerate during ZED-time."

View File

@ -0,0 +1,39 @@
Class Ext_TraitMachineGunner extends Ext_TraitBase;
static function string GetPerkDescription()
{
local string S;
S = Super.GetPerkDescription();
S $= "|Trait requires prestige level: #{FF4000}2";
return S;
}
static function bool MeetsRequirements( byte Lvl, Ext_PerkBase Perk )
{
if( Perk.CurrentLevel<Default.MinLevel || Perk.CurrentPrestige<2 )
return false;
return true;
}
static function TraitActivate( Ext_PerkBase Perk, byte Level, optional Ext_TraitDataStore Data )
{
Ext_PerkCommando(Perk).bUseMachineGunner = true;
}
static function TraitDeActivate( Ext_PerkBase Perk, byte Level, optional Ext_TraitDataStore Data )
{
Ext_PerkCommando(Perk).bUseMachineGunner = false;
}
defaultproperties
{
SupportedPerk=class'Ext_PerkCommando'
TraitGroup=class'Ext_TGroupZEDTime'
TraitName="ZED TIME - Machine Gunner"
NumLevels=1
DefLevelCosts(0)=60
DefMinLevel=55
Description="During Zed time, you do 3% more damage with perks weapons and shoot 3x faster with all guns!"
}

View File

@ -0,0 +1,35 @@
Class Ext_TraitMedBoost extends Ext_TraitBase;
static function ApplyEffectOn( KFPawn_Human Player, Ext_PerkBase Perk, byte Level, optional Ext_TraitDataStore Data )
{
Ext_PerkFieldMedic(Perk).HealingSpeedBoostPct = 10.0f + (5.f + ((float(Level) - 1.f) * 5.f));
}
static function CancelEffectOn( KFPawn_Human Player, Ext_PerkBase Perk, byte Level, optional Ext_TraitDataStore Data )
{
Ext_PerkFieldMedic(Perk).HealingSpeedBoostPct = 10.0f;
}
static function TraitActivate( Ext_PerkBase Perk, byte Level, optional Ext_TraitDataStore Data )
{
Ext_PerkFieldMedic(Perk).bHealingBoost = true;
}
static function TraitDeActivate( Ext_PerkBase Perk, byte Level, optional Ext_TraitDataStore Data )
{
Ext_PerkFieldMedic(Perk).bHealingBoost = false;
}
defaultproperties
{
SupportedPerk=class'Ext_PerkFieldMedic'
TraitName="Adrenaline Shot"
NumLevels=5
DefLevelCosts(0)=35
DefLevelCosts(1)=10
DefLevelCosts(2)=20
DefLevelCosts(3)=30
DefLevelCosts(4)=40
DefMinLevel=25
Description="Healing players will increase there speed 10% up to 30%. The percent is increased by every level in:|Lv1-5: 10%, 15%, 20%, 25%, 30%"
}

View File

@ -0,0 +1,33 @@
Class Ext_TraitMedDamBoost extends Ext_TraitBase;
static function ApplyEffectOn( KFPawn_Human Player, Ext_PerkBase Perk, byte Level, optional Ext_TraitDataStore Data )
{
Ext_PerkFieldMedic(Perk).HealingDamageBoostPct = 5.0f + (5.f + ((float(Level) - 1.f) * 5.f));
}
static function CancelEffectOn( KFPawn_Human Player, Ext_PerkBase Perk, byte Level, optional Ext_TraitDataStore Data )
{
Ext_PerkFieldMedic(Perk).HealingDamageBoostPct = 5.0f;
}
static function TraitActivate( Ext_PerkBase Perk, byte Level, optional Ext_TraitDataStore Data )
{
Ext_PerkFieldMedic(Perk).bHealingDamageBoost = true;
}
static function TraitDeActivate( Ext_PerkBase Perk, byte Level, optional Ext_TraitDataStore Data )
{
Ext_PerkFieldMedic(Perk).bHealingDamageBoost = false;
}
defaultproperties
{
SupportedPerk=class'Ext_PerkFieldMedic'
TraitName="Focus Injection"
NumLevels=3
DefLevelCosts(0)=40
DefLevelCosts(1)=50
DefLevelCosts(2)=60
DefMinLevel=85
Description="Healing players will increase there damage up to 15%. The percent is increased by every level in:|Lv1-3: 5%, 10%, 15%"
}

View File

@ -0,0 +1,35 @@
Class Ext_TraitMedShield extends Ext_TraitBase;
static function ApplyEffectOn( KFPawn_Human Player, Ext_PerkBase Perk, byte Level, optional Ext_TraitDataStore Data )
{
Ext_PerkFieldMedic(Perk).HealingShieldPct = 10.0f + (5.f + ((float(Level) - 1.f) * 5.f));
}
static function CancelEffectOn( KFPawn_Human Player, Ext_PerkBase Perk, byte Level, optional Ext_TraitDataStore Data )
{
Ext_PerkFieldMedic(Perk).HealingShieldPct = 10.0f;
}
static function TraitActivate( Ext_PerkBase Perk, byte Level, optional Ext_TraitDataStore Data )
{
Ext_PerkFieldMedic(Perk).bHealingShield = true;
}
static function TraitDeActivate( Ext_PerkBase Perk, byte Level, optional Ext_TraitDataStore Data )
{
Ext_PerkFieldMedic(Perk).bHealingShield = false;
}
defaultproperties
{
SupportedPerk=class'Ext_PerkFieldMedic'
TraitName="Coagulant Booster"
NumLevels=5
DefLevelCosts(0)=35
DefLevelCosts(1)=10
DefLevelCosts(2)=20
DefLevelCosts(3)=30
DefLevelCosts(4)=40
DefMinLevel=100
Description="Healing players will increase there damage resistance up to 30%. The percent is increased by every level in:|Lv1-5: 10%, 15%, 20%, 25%, 30%"
}

View File

@ -2,8 +2,8 @@ Class Ext_TraitMedicPistol extends Ext_TraitBase;
static function AddDefaultInventory( KFPawn Player, Ext_PerkBase Perk, byte Level, optional Ext_TraitDataStore Data )
{
Player.DefaultInventory.RemoveItem(class'KFWeap_Pistol_9mm');
Player.DefaultInventory.AddItem(class'KFWeap_Pistol_Medic');
Player.DefaultInventory.RemoveItem(class'ExtWeap_Pistol_9mm');
Player.DefaultInventory.AddItem(class'ExtWeap_Pistol_MedicS');
}
defaultproperties

View File

@ -0,0 +1,51 @@
Class Ext_TraitPenetrator extends Ext_TraitBase;
static function string GetPerkDescription()
{
local string S;
S = Super.GetPerkDescription();
S $= "|Trait requires prestige level: #{FF4000}2";
return S;
}
static function bool MeetsRequirements( byte Lvl, Ext_PerkBase Perk )
{
local int i;
if( Perk.CurrentLevel<Default.MinLevel || Perk.CurrentPrestige<2 )
return false;
for( i=0; i<Perk.PerkTraits.Length; ++i )
{
if( Perk.PerkTraits[i].TraitType==Class'Ext_TraitAPShots' )
{
if( Perk.PerkTraits[i].CurrentLevel <= 0 )
return false;
else break;
}
}
return true;
}
static function TraitActivate( Ext_PerkBase Perk, byte Level, optional Ext_TraitDataStore Data )
{
Ext_PerkSupport(Perk).bUsePerforate = true;
}
static function TraitDeActivate( Ext_PerkBase Perk, byte Level, optional Ext_TraitDataStore Data )
{
Ext_PerkSupport(Perk).bUsePerforate = false;
}
defaultproperties
{
SupportedPerk=class'Ext_PerkSupport'
TraitGroup=class'Ext_TGroupZEDTime'
TraitName="ZED TIME - Penetrator"
NumLevels=1
DefLevelCosts(0)=50
DefMinLevel=65
Description="During Zed time, your perk weapons penetrate through any targets they hit! ||-REQUIREMENT: Armor Piercing Shots trait needs to be level 1!"
}

View File

@ -12,6 +12,7 @@ static function TraitDeActivate( Ext_PerkBase Perk, byte Level, optional Ext_Tra
defaultproperties
{
SupportedPerk=class'Ext_PerkSharpshooter'
TraitGroup=class'Ext_TGroupZEDTime'
TraitName="ZED TIME - Ranger"
DefLevelCosts(0)=40
Description="This will make you effectively stun enemies with headshots during ZED-time."

View File

@ -0,0 +1,19 @@
Class Ext_TraitRapidAssault extends Ext_TraitBase;
static function TraitActivate( Ext_PerkBase Perk, byte Level, optional Ext_TraitDataStore Data )
{
Ext_PerkSWAT(Perk).bRapidAssault = true;
}
static function TraitDeActivate( Ext_PerkBase Perk, byte Level, optional Ext_TraitDataStore Data )
{
Ext_PerkSWAT(Perk).bRapidAssault = false;
}
defaultproperties
{
SupportedPerk=class'Ext_PerkSWAT'
TraitGroup=class'Ext_TGroupZEDTime'
TraitName="ZED TIME - Rapid Assault"
DefLevelCosts(0)=30
Description="Gives player unlimited ammunition for perked weapons during ZED-time and allows them to fire in realtime."
}

View File

@ -22,6 +22,7 @@ static function TraitDeActivate( Ext_PerkBase Perk, byte Level, optional Ext_Tra
defaultproperties
{
TraitName="ZED TIME - SWAT Enforcer"
TraitGroup=class'Ext_TGroupZEDTime'
DefLevelCosts(0)=50
Description="This trait makes you move at normal speed and allows you to knock down zeds by bumping into them during ZED-time."
}

View File

@ -0,0 +1,18 @@
Class Ext_TraitSirenResistance extends Ext_TraitBase;
static function TraitActivate( Ext_PerkBase Perk, byte Level, optional Ext_TraitDataStore Data )
{
Ext_PerkDemolition(Perk).bSirenResistance = true;
}
static function TraitDeActivate( Ext_PerkBase Perk, byte Level, optional Ext_TraitDataStore Data )
{
Ext_PerkDemolition(Perk).bSirenResistance = false;
}
defaultproperties
{
TraitName="Siren Resistance"
DefLevelCosts(0)=50
DefMinLevel=75
Description="Make all your projectiles resistant to siren screams."
}

View File

@ -18,6 +18,7 @@ static function CancelEffectOn( KFPawn_Human Player, Ext_PerkBase Perk, byte Lev
defaultproperties
{
SupportedPerk=class'Ext_PerkBerserker'
TraitGroup=class'Ext_TGroupZEDTime'
TraitName="ZED TIME - Spartan!"
NumLevels=3
DefLevelCosts(0)=50

View File

@ -0,0 +1,48 @@
Class Ext_TraitTactician extends Ext_TraitBase;
static function string GetPerkDescription()
{
local string S;
S = Super.GetPerkDescription();
S $= "|Trait requires prestige level: #{FF4000}1";
return S;
}
static function bool MeetsRequirements( byte Lvl, Ext_PerkBase Perk )
{
local int i;
if( Perk.CurrentLevel<Default.MinLevel || Perk.CurrentPrestige<1 )
return false;
if( Lvl==0 )
{
i = Perk.PerkStats.Find('StatType','Damage');
if( i>=0 )
return (Perk.PerkStats[i].CurrentValue>=30);
}
return true;
}
static function TraitActivate( Ext_PerkBase Perk, byte Level, optional Ext_TraitDataStore Data )
{
Ext_PerkCommando(Perk).bUseProfessional = true;
}
static function TraitDeActivate( Ext_PerkBase Perk, byte Level, optional Ext_TraitDataStore Data )
{
Ext_PerkCommando(Perk).bUseProfessional = false;
}
defaultproperties
{
SupportedPerk=class'Ext_PerkCommando'
TraitGroup=class'Ext_TGroupZEDTime'
TraitName="ZED TIME - Tactician"
NumLevels=1
DefLevelCosts(0)=30
DefMinLevel=35
Description="During Zed time, you reload perk weapons at full speed and switch perk weapons twice as fast! ||-REQUIREMENT: Damage bonus trait needs to have at least 30 points!"
}

View File

@ -12,6 +12,7 @@ static function TraitDeActivate( Ext_PerkBase Perk, byte Level, optional Ext_Tra
defaultproperties
{
SupportedPerk=class'Ext_PerkGunslinger'
TraitGroup=class'Ext_TGroupZEDTime'
TraitName="ZED TIME - Uber Ammo"
DefLevelCosts(0)=30
Description="Gives player unlimited ammunition for perked weapons during ZED-time."

View File

@ -176,7 +176,7 @@ defaultproperties
DefZedTypes.Add((Zeds=(Class'KFPawn_ZedBloat',Class'KFPawn_ZedStalker',Class'KFPawn_ZedGorefast')))
DefZedTypes.Add((Zeds=(Class'KFPawn_ZedHusk',Class'KFPawn_ZedSirenX',Class'KFPawn_ZedScrake')))
DefZedTypes.Add((Zeds=(Class'KFPawn_ZedSirenX',Class'KFPawn_ZedFleshpound',Class'KFPawn_ZedScrake')))
DefZedTypes.Add((Zeds=(Class'KFPawn_ZedHansFriendlyTest')))
DefZedTypes.Add((Zeds=(Class'ExtPawn_ZedHans_Pet')))
WebConfigs.Add((PropType=2,PropName="ZedTypes",UIName="Zed Types",UIDesc="Type of zeds each level can spawn (separate types with a comma)",NumElements=-1))
WebConfigs.Add((PropType=0,PropName="ZedRespawnTime",UIName="Zed RespawnTime",UIDesc="Time in seconds it takes for zeds to respawn"))

View File

@ -0,0 +1,26 @@
Class Ext_TraitZedTExt extends Ext_TraitBase;
static function ApplyEffectOn( KFPawn_Human Player, Ext_PerkBase Perk, byte Level, optional Ext_TraitDataStore Data )
{
Ext_PerkCommando(Perk).ZTExtCount = Level;
}
static function CancelEffectOn( KFPawn_Human Player, Ext_PerkBase Perk, byte Level, optional Ext_TraitDataStore Data )
{
Ext_PerkCommando(Perk).ZTExtCount = Level;
}
defaultproperties
{
SupportedPerk=class'Ext_PerkCommando'
TraitName="ZED Time Extensions"
NumLevels=6
DefLevelCosts(0)=15
DefLevelCosts(1)=25
DefLevelCosts(2)=35
DefLevelCosts(3)=45
DefLevelCosts(4)=55
DefLevelCosts(5)=65
DefMinLevel=15
Description="Adds ZED Time extensions to your perk. The amount of extensions is increased by 1 every level"
}

View File

@ -0,0 +1,48 @@
Class Ext_TraitZedative extends Ext_TraitBase;
static function string GetPerkDescription()
{
local string S;
S = Super.GetPerkDescription();
S $= "|Trait requires prestige level: #{FF4000}2";
return S;
}
static function bool MeetsRequirements( byte Lvl, Ext_PerkBase Perk )
{
local int i;
if( Perk.CurrentLevel<Default.MinLevel || Perk.CurrentPrestige<2 )
return false;
if( Lvl==0 )
{
i = Perk.PerkStats.Find('StatType','Heal');
if( i>=0 )
return (Perk.PerkStats[i].CurrentValue>=25);
}
return true;
}
static function TraitActivate( Ext_PerkBase Perk, byte Level, optional Ext_TraitDataStore Data )
{
Ext_PerkFieldMedic(Perk).bUseSlug = true;
}
static function TraitDeActivate( Ext_PerkBase Perk, byte Level, optional Ext_TraitDataStore Data )
{
Ext_PerkFieldMedic(Perk).bUseSlug = false;
}
defaultproperties
{
SupportedPerk=class'Ext_PerkFieldMedic'
TraitGroup=class'Ext_TGroupZEDTime'
TraitName="ZED TIME - Zedative"
NumLevels=1
DefLevelCosts(0)=50
DefMinLevel=65
Description="During Zed time, damaging Zeds with perk weapons will slow them 30% and do massive amounts of poison damage. ||-REQUIREMENT: Healing bonus trait needs to have at least 25 points!"
}

View File

@ -23,6 +23,23 @@ struct FKillMessageType
};
var transient array<FKillMessageType> KillMessages;
var int HealthBarFullVisDist, HealthBarCutoffDist;
var transient float BestPetXL, BestPetYL;
struct DamageInfo
{
var int Damage;
var float HitTime;
var Vector HitLocation;
var byte Type;
var float RandX, RandY;
var color FontColor;
};
const DAMAGEPOPUP_COUNT = 32;
var DamageInfo DamagePopups[32];
var int NextDamagePopupIndex;
var float DamagePopupFadeOutTime;
struct FNewItemEntry
{
var Texture2D Icon;
@ -31,14 +48,6 @@ struct FNewItemEntry
};
var transient array<FNewItemEntry> NewItems;
struct FNumberedMsg
{
var int Amount;
var vector Pos;
var float Time;
var byte Type;
};
var array<FNumberedMsg> Numbers;
var ExtPlayerReplicationInfo EPRI;
var transient KF2GUIController GUIController;
var transient GUIStyleBase GUIStyle;
@ -150,10 +159,15 @@ final function ShowProgressMsg( string S, optional bool bDis )
static final function string GetNameOf( class<Pawn> Other )
{
local string S;
local class<KFPawn_Monster> KFM;
if( Class<VSZombie>(Other)!=None )
return Class<VSZombie>(Other).Default.ZombieName;
KFM = class<KFPawn_Monster>(Other);
if( KFM!=None && KFM.default.LocalizationKey != '' )
return Localize("Zeds", string(KFM.default.LocalizationKey), "KFGame");
if( Other.Default.MenuName!="" )
return Other.Default.MenuName;
S = string(Other.Name);
@ -242,8 +256,7 @@ event PostRender()
GUIStyle.Canvas = Canvas;
GUIStyle.PickDefaultFontSize(Canvas.ClipY);
if( Numbers.Length>0 )
DrawNumberMsg();
DrawDamage();
//RenderKFHUD(); // TODO later...
super.PostRender();
@ -439,12 +452,19 @@ function DrawHUD()
local KFPawn_Monster M;
local vector V;
local bool bSpec;
local array<PlayerReplicationInfo> VisibleHumanPlayers;
local array<sHiddenHumanPawnInfo> HiddenHumanPlayers;
local vector ViewLocation,PawnLocation;
local rotator ViewRotation;
Super(HUD).DrawHUD();
// Draw the crosshair for casual mode
if( bDrawCrosshair || bForceDrawCrosshair )
if( bDrawCrosshair || bForceDrawCrosshair || (KFPlayerOwner != none && KFPlayerOwner.GetTeamNum() == 255) )
{
if( KFPlayerOwner != none && !KFPlayerOwner.bCinematicMode )
DrawCrosshair();
}
bSpec = (PlayerOwner.PlayerReplicationInfo!=None && PlayerOwner.PlayerReplicationInfo.bOnlySpectator);
if( bSpec || PlayerOwner.GetTeamNum()==0 )
@ -452,9 +472,18 @@ function DrawHUD()
//Friendly player status
if( !class'ExtPlayerController'.Default.bHideNameBeacons )
{
if( KFPlayerOwner != none )
{
KFPlayerOwner.GetPlayerViewPoint( ViewLocation, ViewRotation );
}
Canvas.EnableStencilTest(true);
foreach WorldInfo.AllPawns(class'KFPawn', KFPH)
{
if( KFPH == None )
continue;
H = KFPawn_Human(KFPH);
if( KFPH.PlayerReplicationInfo!=None && KFPH.PlayerReplicationInfo.Team!=None && KFPH.PlayerReplicationInfo.Team.TeamIndex==0 )
{
V = KFPH.Location + KFPH.MTO_PhysSmoothOffset + KFPH.CylinderComponent.CollisionHeight * vect(0,0,1);
@ -464,13 +493,29 @@ function DrawHUD()
{
if((WorldInfo.TimeSeconds - KFPH.Mesh.LastRenderTime) < 0.4f && (ThisDot > 0 && ThisDot < 1.0) )
{
if( KFPawn_Human(KFPH)!=None )
DrawFriendlyHUD(KFPawn_Human(KFPH));
if( H!=None )
{
DrawFriendlyHUD(H);
VisibleHumanPlayers.AddItem( H.PlayerReplicationInfo );
}
else DrawMonsterHUD(KFPH);
}
else if( H != None )
{
HiddenHumanPlayers.Insert( 0, 1 );
HiddenHumanPlayers[0].HumanPawn = H;
HiddenHumanPlayers[0].HumanPRI = H.PlayerReplicationInfo;
}
}
}
}
// Draw hidden players
CheckAndDrawHiddenPlayerIcons( VisibleHumanPlayers, HiddenHumanPlayers );
// Draw last remaining zeds
CheckAndDrawRemainingZedIcons();
Canvas.EnableStencilTest(false);
if( bSpec )
@ -491,14 +536,21 @@ function DrawHUD()
DotScale = Canvas.ClipX*0.2f;
foreach WorldInfo.AllPawns(class'KFPawn_Human', H)
{
ThisDot = (PLCameraDir Dot H.Location) - PLCameraDot;
PawnLocation = H.Location;
if( IsZero( PawnLocation ) )
{
continue;
}
ThisDot = (PLCameraDir Dot PawnLocation) - PLCameraDot;
if( H.IsAliveAndWell() && ThisDot>0.f && ThisDot<10000.f )
{
V = Canvas.Project(H.Location);
V = Canvas.Project(PawnLocation);
if( V.X<-100 || V.X>(Canvas.SizeX+100) || V.Y<-100 || V.Y>(Canvas.SizeY+100) )
continue;
Canvas.DrawColor = GetHPColorScale(H);
if( PlayerOwner.FastTrace(H.Location,PLCameraLoc) )
if( PlayerOwner.FastTrace(PawnLocation,PLCameraLoc) )
ThisDot*=1.75f;
ThisDot = (DotScale/ThisDot)*350.f;
Canvas.SetPos(V.X-ThisDot*0.25f,V.Y-ThisDot*0.5f);
@ -521,6 +573,48 @@ function DrawHUD()
Canvas.Font = GetFontSizeIndex(0);
DrawActorOverlays(PLCameraLoc, PLCameraRot);
}
function DrawHiddenHumanPlayerIcon( PlayerReplicationInfo PRI, vector IconWorldLocation )
{
local vector ScreenPos;
local float IconSizeMult;
local KFPlayerReplicationInfo KFPRI;
local Texture2D PlayerIcon;
local Color PerkColor;
local ExtPlayerReplicationInfo ExtPRI;
local Texture2D HumanIcon;
KFPRI = KFPlayerReplicationInfo(PRI);
if( KFPRI == None )
return;
// Project world pos to canvas
ScreenPos = Canvas.Project( IconWorldLocation + vect(0,0,2.2f) * class'KFPAwn_Human'.default.CylinderComponent.CollisionHeight );
// Fudge by icon size
IconSizeMult = PlayerStatusIconSize * FriendlyHudScale * 0.5f;
ScreenPos.X -= IconSizeMult;
ScreenPos.Y -= IconSizeMult;
if( ScreenPos.X < 0 || ScreenPos.X > Canvas.SizeX || ScreenPos.Y < 0 || ScreenPos.Y > Canvas.SizeY )
{
return;
}
ExtPRI = ExtPlayerReplicationInfo(KFPRI);
if( ExtPRI == None )
return;
HumanIcon = ExtPRI.ECurrentPerk != None ? ExtPRI.ECurrentPerk.Default.PerkIcon : GenericHumanIconTexture;
PlayerIcon = PlayerOwner.GetTeamNum() == 0 ? HumanIcon : GenericHumanIconTexture;
PerkColor = ExtPRI.HUDPerkColor;
// Draw human icon
Canvas.SetDrawColor( PerkColor.R, PerkColor.G, PerkColor.B, PerkColor.A );
Canvas.SetPos( ScreenPos.X, ScreenPos.Y );
Canvas.DrawTile( PlayerIcon, PlayerStatusIconSize * FriendlyHudScale, PlayerStatusIconSize * FriendlyHudScale, 0, 0, 256, 256 );
}
simulated static final function color GetHPColorScale( Pawn P )
{
local color C;
@ -562,12 +656,12 @@ simulated function DrawFriendlyHUDZ( KFPawn_Monster KFPH )
//Draw health bar
Percentage = float(KFPH.Health) / float(KFPH.HealthMax);
DrawKFBar(Percentage, BarLength, BarHeight, ScreenPos.X - (BarLength *0.5f), ScreenPos.Y, HealthColor);
DrawPlayerInfoBar(KFPH, Percentage, BarLength, BarHeight, ScreenPos.X - (BarLength *0.5f), ScreenPos.Y, HealthColor);
//Draw player name (Top)
FontScale = class'KFGameEngine'.Static.GetKFFontScale() * FriendlyHudScale;
Canvas.Font = class'KFGameEngine'.Static.GetKFCanvasFont();
Canvas.SetDrawColorStruct(PlayerBarTextColor);
Canvas.SetDrawColorStruct(DrawToDistance(KFPH, PlayerBarTextColor));
Canvas.SetPos(ScreenPos.X - (BarLength *0.5f), ScreenPos.Y - BarHeight * 2);
Canvas.DrawText( KFPH.PlayerReplicationInfo.PlayerName,,FontScale,FontScale, MyFontRenderInfo );
}
@ -598,17 +692,12 @@ simulated function DrawFriendlyHUD( KFPawn_Human KFPH )
return;
//Draw health bar
if( ExtHumanPawn(KFPH)!=None )
DrawKFHealthBar(ExtHumanPawn(KFPH), BarLength, BarHeight, ScreenPos.X - (BarLength *0.5f), ScreenPos.Y);
else
{
Percentage = FMin(float(KFPH.Health) / float(KFPH.HealthMax),1.f);
DrawKFBar(Percentage, BarLength, BarHeight, ScreenPos.X - (BarLength *0.5f), ScreenPos.Y, HealthColor);
}
DrawPlayerInfoBar(KFPH, Percentage, BarLength, BarHeight, ScreenPos.X - (BarLength *0.5f), ScreenPos.Y, HealthColor, true);
//Draw armor bar
Percentage = FMin(float(KFPH.Armor) / float(KFPH.MaxArmor),1.f);
DrawKFBar(Percentage, BarLength, BarHeight, ScreenPos.X - (BarLength *0.5f), ScreenPos.Y - BarHeight, ArmorColor);
DrawPlayerInfoBar(KFPH, Percentage, BarLength, BarHeight, ScreenPos.X - (BarLength *0.5f), ScreenPos.Y - BarHeight, ArmorColor);
//Draw player name (Top)
FontScale = class'KFGameEngine'.Static.GetKFFontScale() * FriendlyHudScale;
@ -624,20 +713,22 @@ simulated function DrawFriendlyHUD( KFPawn_Human KFPH )
S = S$" ("$KFPRI.GetAdminNameAbr()$")";
Canvas.DrawColor = KFPRI.GetAdminColorC();
}
else Canvas.DrawColor = KFPRI.HUDPerkColor;
else Canvas.DrawColor = WhiteColor;
if( bMeAdmin && KFPRI.FixedData>0 )
{
Canvas.SetDrawColor(255,0,0,255);
S $= " -"$KFPRI.GetDesc();
}
Canvas.DrawColor = DrawToDistance(KFPH, Canvas.DrawColor);
Canvas.SetPos(ScreenPos.X - (BarLength *0.5f), ScreenPos.Y - BarHeight * 3);
Canvas.DrawText( S,,FontScale,FontScale, MyFontRenderInfo );
if( KFPRI.ECurrentPerk!=none )
{
//draw perk icon
Canvas.DrawColor = KFPRI.HUDPerkColor;
Canvas.DrawColor = DrawToDistance(KFPH, KFPRI.HUDPerkColor);
Canvas.SetPos(ScreenPos.X - (BarLength * 0.75), ScreenPos.Y - BarHeight * 2);
Canvas.DrawRect(PlayerStatusIconSize*FriendlyHudScale,PlayerStatusIconSize*FriendlyHudScale,KFPRI.ECurrentPerk.default.PerkIcon);
@ -647,7 +738,7 @@ simulated function DrawFriendlyHUD( KFPawn_Human KFPH )
if( KFPRI.HasSupplier!=None )
{
Canvas.DrawColor = (KFPlayerOwner.Pawn==None || KFPRI.CanUseSupply(KFPlayerOwner.Pawn)) ? SupplierUsableColor : SupplierActiveColor;
Canvas.DrawColor = DrawToDistance(KFPH, (KFPlayerOwner.Pawn==None || KFPRI.CanUseSupply(KFPlayerOwner.Pawn)) ? SupplierUsableColor : SupplierActiveColor);
Canvas.SetPos( ScreenPos.X + BarLength * 0.5f, ScreenPos.Y - BarHeight * 2 );
Canvas.DrawRect( PlayerStatusIconSize*FriendlyHudScale, PlayerStatusIconSize*FriendlyHudScale, KFPRI.HasSupplier.Default.SupplyIcon);
}
@ -663,12 +754,10 @@ simulated function DrawFriendlyHUD( KFPawn_Human KFPH )
Canvas.DrawText( KFPRI.CurrentPerkClass.default.PerkName,,FontScale,FontScale, MyFontRenderInfo );
}
}
simulated final function DrawKFHealthBar( ExtHumanPawn P, float BarLength, float BarHeight, float XPos, float YPos )
simulated final function DrawPlayerInfoBar( KFPawn P, float BarPercentage, float BarLength, float BarHeight, float XPos, float YPos, Color BarColor, optional bool bDrawingHealth )
{
local float BarPercentage;
//background for status bar
Canvas.SetDrawColorStruct(PlayerBarBGColor);
Canvas.SetDrawColorStruct(DrawToDistance(P, PlayerBarBGColor));
Canvas.SetPos(XPos, YPos);
Canvas.DrawTileStretched(PlayerStatusBarBGTexture, BarLength, BarHeight, 0, 0, 32, 32);
@ -678,18 +767,17 @@ simulated final function DrawKFHealthBar( ExtHumanPawn P, float BarLength, float
BarHeight-=2;
//Forground for status bar.
BarPercentage = FMin(float(P.Health) / float(P.HealthMax),1.f);
Canvas.SetDrawColorStruct(HealthColor);
Canvas.SetDrawColorStruct(DrawToDistance(P, BarColor));
Canvas.SetPos(XPos, YPos);
Canvas.DrawTileStretched(PlayerStatusBarBGTexture, BarLength * BarPercentage, BarHeight, 0, 0, 32, 32);
if( P.Health<P.HealthMax && P.RepRegenHP>0 )
if( bDrawingHealth && ExtHumanPawn(P) != None && P.Health<P.HealthMax && ExtHumanPawn(P).RepRegenHP>0 )
{
// Draw to-regen bar.
XPos+=(BarLength * BarPercentage);
BarPercentage = FMin(float(P.RepRegenHP) / float(P.HealthMax),1.f-BarPercentage);
BarPercentage = FMin(float(ExtHumanPawn(P).RepRegenHP) / float(P.HealthMax),1.f-BarPercentage);
Canvas.SetDrawColor(255,128,128,255);
Canvas.DrawColor = DrawToDistance(P, MakeColor(255,128,128,255));
Canvas.SetPos(XPos, YPos);
Canvas.DrawTileStretched(PlayerStatusBarBGTexture, BarLength * BarPercentage, BarHeight, 0, 0, 32, 32);
}
@ -720,12 +808,12 @@ simulated function DrawMonsterHUD( KFPawn KFPH )
//Draw health bar
Percentage = FMin(float(KFPH.Health) / float(KFPH.HealthMax),1.f);
DrawKFBar(Percentage, BarLength, BarHeight, ScreenPos.X - (BarLength *0.5f), ScreenPos.Y, HealthColor);
DrawPlayerInfoBar(KFPH, Percentage, BarLength, BarHeight, ScreenPos.X - (BarLength *0.5f), ScreenPos.Y, HealthColor);
//Draw player name (Top)
FontScale = class'KFGameEngine'.Static.GetKFFontScale() * FriendlyHudScale;
Canvas.Font = class'KFGameEngine'.Static.GetKFCanvasFont();
Canvas.DrawColor = (PRI.OwnerPRI==PlayerOwner.PlayerReplicationInfo ? MakeColor(32,250,32,255) : MakeColor(250,32,32,255));
Canvas.DrawColor = DrawToDistance(KFPH, (PRI.OwnerPRI==PlayerOwner.PlayerReplicationInfo ? MakeColor(32,250,32,255) : MakeColor(250,32,32,255)));
Canvas.SetPos(ScreenPos.X - (BarLength *0.5f), ScreenPos.Y - BarHeight * 3);
Canvas.DrawText( PRI.PlayerName,,FontScale,FontScale, MyFontRenderInfo );
@ -739,17 +827,25 @@ simulated function DrawPetInfo()
local string S;
local int i;
Canvas.DrawColor = MakeColor(32,250,32,255);
X = Canvas.ClipX*0.99;
Y = Canvas.ClipY*0.74;
X = Canvas.ClipX*0.165;
Y = Canvas.ClipY*0.925;
Canvas.Font = GUIStyle.PickFont(GUIStyle.DefaultFontSize,Sc);
Canvas.TextSize("ABC",XL,YS,Sc,Sc);
S = "Current Pet:";
S = "Current Pet(s)";
Canvas.TextSize(S,XL,YL,Sc,Sc);
Y-=(YS*MyCurrentPet.Length);
Canvas.SetPos(X-XL,Y);
Canvas.SetDrawColor(120,0,0,145);
GUIStyle.DrawRectBox( X, Y, BestPetXL * 1.04, YL, 4 );
Canvas.DrawColor = MakeColor(255,255,255,255);
Canvas.SetPos(X,Y);
Canvas.DrawText(S,,Sc,Sc);
Canvas.SetDrawColor(8,8,8,145);
GUIStyle.DrawRectBox( X, Y + YS, BestPetXL * 1.04, YL * MyCurrentPet.Length, 4 );
Canvas.DrawColor = MakeColor(32,250,32,255);
for( i=0; i<MyCurrentPet.Length; ++i )
{
if( MyCurrentPet[i]==None )
@ -760,75 +856,135 @@ simulated function DrawPetInfo()
Y+=YS;
S = MyCurrentPet[i].MonsterName$" ("$MyCurrentPet[i].HealthStatus$"/"$MyCurrentPet[i].HealthMax$"HP)";
Canvas.TextSize(S,XL,YL,Sc,Sc);
Canvas.SetPos(X-XL,Y);
Canvas.SetPos(X,Y);
Canvas.DrawText(S,,Sc,Sc);
if( XL > BestPetXL )
BestPetXL = XL;
if( YL > BestPetYL )
BestPetYL = YL;
}
}
function Color DrawToDistance(KFPawn Pawn, Color DrawColor)
{
local float Dist, fZoom;
Dist = VSize(Pawn.Location - PLCameraLoc) * 0.5;
if ( Dist <= HealthBarFullVisDist || PlayerOwner.PlayerReplicationInfo.bOnlySpectator )
fZoom = 1.0;
else fZoom = FMax(1.0 - (Dist - HealthBarFullVisDist) / (HealthBarCutoffDist - HealthBarFullVisDist), 0.0);
DrawColor.A = Clamp(255 * fZoom, 90, 255);
return DrawColor;
}
final function AddNumberMsg( int Amount, vector Pos, byte Type )
{
local int i;
local Color C;
i = Numbers.Length;
if( i>15 ) // don't overflow this that much...
{
Numbers.Remove(0,1);
i = Numbers.Length;
DamagePopups[NextDamagePopupIndex].Damage = Amount;
DamagePopups[NextDamagePopupIndex].HitTime = WorldInfo.TimeSeconds;
DamagePopups[NextDamagePopupIndex].Type = Type;
DamagePopups[NextDamagePopupIndex].HitLocation = Pos;
//ser random speed of fading out, so multiple damages in the same hit location don't overlap each other
DamagePopups[NextDamagePopupIndex].RandX = 2.0 * FRand();
DamagePopups[NextDamagePopupIndex].RandY = 1.0 + FRand();
C.A = 255;
if ( Type == 0 && Amount < 100 ) {
C.R = 220;
C.G = 0;
C.B = 0;
}
Numbers.Length = i+1;
Numbers[i].Amount = Amount;
Numbers[i].Pos = Pos;
Numbers[i].Time = WorldInfo.TimeSeconds;
Numbers[i].Type = Type;
else if ( Type == 1 ) {
C.R = 255;
C.G = 255;
C.B = 25;
}
final function DrawNumberMsg()
else if ( Type == 2 ) {
C.R = 32;
C.G = 240;
C.B = 32;
}
else if ( Amount >= 300 ) {
C.R = 0;
C.G = 206;
C.B = 0;
}
else if ( Amount >= 100 ) {
C.R = 206;
C.G = 206;
C.B = 0;
}
else {
C.R = 127;
C.G = 127;
C.B = 127;
}
DamagePopups[NextDamagePopupIndex].FontColor = C;
if( ++NextDamagePopupIndex >= DAMAGEPOPUP_COUNT)
NextDamagePopupIndex=0;
}
final function DrawDamage()
{
local int i;
local float T,ThisDot,FontScale,XS,YS;
local vector V;
local float TimeSinceHit;
local vector CameraLocation, CamDir;
local rotator CameraRotation;
local vector HBScreenPos;
local float TextWidth, TextHeight, x, Sc;
local string S;
FontScale = Canvas.ClipY / 5.f;
Canvas.Font = class'KFGameEngine'.Static.GetKFCanvasFont();
Canvas.Font = class'Engine'.Static.GetMediumFont();
Sc = 1;
for( i=0; i<Numbers.Length; ++i )
KFPlayerController(Owner).GetPlayerViewPoint(CameraLocation, CameraRotation);
CamDir = vector(CameraRotation);
for( i=0; i < DAMAGEPOPUP_COUNT ; i++ )
{
T = WorldInfo.TimeSeconds-Numbers[i].Time;
if( T>3.f )
{
Numbers.Remove(i--,1);
TimeSinceHit = WorldInfo.TimeSeconds - DamagePopups[i].HitTime;
if( TimeSinceHit > DamagePopupFadeOutTime
|| ( Normal(DamagePopups[i].HitLocation - CameraLocation) dot Normal(CamDir) < 0.1 ) ) //don't draw if player faced back to the hit location
continue;
}
V = Numbers[i].Pos+vect(0,0,10.f)*T;
ThisDot = (PLCameraDir Dot V) - PLCameraDot;
if( ThisDot>0.f && ThisDot<1500.f )
{
V = Canvas.Project(V);
if( V.X>0 && V.Y>0 && V.X<Canvas.ClipX && V.Y<Canvas.ClipY )
{
ThisDot = (FontScale/ThisDot);
switch( Numbers[i].Type )
switch( DamagePopups[i].Type )
{
case 0: // Pawn damage.
S = "-"$string(Numbers[i].Amount);
Canvas.SetDrawColor(220,0,0,255);
S = "-"$string(DamagePopups[i].Damage);
break;
case 1: // EXP.
S = "+"$string(Numbers[i].Amount)$" XP";
Canvas.SetDrawColor(255,255,25,255);
S = "+"$string(DamagePopups[i].Damage)$" XP";
break;
case 2: // Health.
S = "+"$string(Numbers[i].Amount)$" HP";
Canvas.SetDrawColor(32,240,32,255);
S = "+"$string(DamagePopups[i].Damage)$" HP";
break;
}
if( T>2.f )
Canvas.DrawColor.A = (3.f-T)*255.f;
Canvas.TextSize(S,XS,YS,ThisDot,ThisDot);
Canvas.SetPos(V.X-XS*0.5,V.Y-YS*0.5);
Canvas.DrawText(S,,ThisDot,ThisDot);
}
}
HBScreenPos = Canvas.Project(DamagePopups[i].HitLocation);
Canvas.TextSize(S,TextWidth,TextHeight,Sc,Sc);
//draw just on the hit location
HBScreenPos.Y -= TextHeight/2;
HBScreenPos.X -= TextWidth/2;
//let numbers to fly up
HBScreenPos.Y -= TimeSinceHit * TextHeight * DamagePopups[i].RandY;
x = Sin(2*Pi * TimeSinceHit/DamagePopupFadeOutTime) * TextWidth * DamagePopups[i].RandX;
// odd numbers start to flying to the right side, even - left
// So in situations of decapitaion player could see both damages
if ( i % 2 == 0)
x *= -1.0;
HBScreenPos.X += x;
Canvas.DrawColor = DamagePopups[i].FontColor;
Canvas.DrawColor.A = 255 * Cos(0.5*Pi * TimeSinceHit/DamagePopupFadeOutTime);
Canvas.SetPos( HBScreenPos.X, HBScreenPos.Y);
Canvas.DrawText( S );
}
}
@ -943,5 +1099,9 @@ defaultproperties
HUDTextColor=(R=250,G=250,B=250,A=186)
HUDClass=class'ExtMoviePlayer_HUD'
HealthBarFullVisDist=350
HealthBarCutoffDist=3500
DamagePopupFadeOutTime=3.000000
BadConnectionStr="Warning: Connection problem!"
}

View File

@ -308,7 +308,7 @@ defaultproperties
XPosition=0.25
YPosition=0.025
XSize=0.074
YSize=0.07
YSize=0.045
OnClickLeft=ButtonClicked
OnClickRight=ButtonClicked
ExtravDir=1
@ -320,7 +320,8 @@ defaultproperties
XPosition=0.325
YPosition=0.025
XSize=0.074
YSize=0.07
YSize=0.045
ExtravDir=1
OnClickLeft=ButtonClicked
OnClickRight=ButtonClicked
End Object
@ -331,7 +332,7 @@ defaultproperties
XPosition=0.4
YPosition=0.025
XSize=0.074
YSize=0.07
YSize=0.045
OnClickLeft=ButtonClicked
OnClickRight=ButtonClicked
bDisabled=true

View File

@ -0,0 +1,87 @@
Class UIP_PerkSelectionLobby extends UIP_PerkSelection;
function Timer()
{
local int i;
CurrentManager = ExtPlayerController(GetPlayer()).ActivePerkManager;
if( CurrentManager!=None )
{
if( PrevPendingPerk!=None )
{
PendingPerk = CurrentManager.FindPerk(PrevPendingPerk);
PrevPendingPerk = None;
}
PerkList.ChangeListSize(CurrentManager.UserPerks.Length);
if( PendingPerk!=None && !PendingPerk.bPerkNetReady )
return;
// Huge code block to handle stat updating, but actually pretty well optimized.
if( PendingPerk!=OldUsedPerk )
{
OldUsedPerk = PendingPerk;
if( PendingPerk!=None )
{
OldPerkPoints = -1;
if( StatsList.ItemComponents.Length!=PendingPerk.PerkStats.Length )
{
if( StatsList.ItemComponents.Length<PendingPerk.PerkStats.Length )
{
for( i=StatsList.ItemComponents.Length; i<PendingPerk.PerkStats.Length; ++i )
{
if( i>=StatBuyers.Length )
{
StatBuyers[StatBuyers.Length] = UIR_PerkStat(StatsList.AddListComponent(class'UIR_PerkStat'));
StatBuyers[i].StatIndex = i;
StatBuyers[i].InitMenu();
}
else
{
StatsList.ItemComponents.Length = i+1;
StatsList.ItemComponents[i] = StatBuyers[i];
}
}
}
else if( StatsList.ItemComponents.Length>PendingPerk.PerkStats.Length )
{
for( i=PendingPerk.PerkStats.Length; i<StatsList.ItemComponents.Length; ++i )
StatBuyers[i].CloseMenu();
StatsList.ItemComponents.Length = PendingPerk.PerkStats.Length;
}
}
OldPerkPoints = PendingPerk.CurrentSP;
PerkLabel.SetText("Lv"$PendingPerk.GetLevelString()@PendingPerk.PerkName$" (Points: "$PendingPerk.CurrentSP$")");
for( i=0; i<StatsList.ItemComponents.Length; ++i ) // Just make sure perk stays the same.
{
StatBuyers[i].SetActivePerk(PendingPerk);
StatBuyers[i].CheckBuyLimit();
}
UpdateTraits();
}
else // Empty out if needed.
{
for( i=0; i<StatsList.ItemComponents.Length; ++i )
StatBuyers[i].CloseMenu();
StatsList.ItemComponents.Length = 0;
PerkLabel.SetText("<No perk selected>");
}
}
else if( PendingPerk!=None && OldPerkPoints!=PendingPerk.CurrentSP )
{
OldPerkPoints = PendingPerk.CurrentSP;
PerkLabel.SetText("Lv"$PendingPerk.GetLevelString()@PendingPerk.PerkName$" (Points: "$PendingPerk.CurrentSP$")");
for( i=0; i<StatsList.ItemComponents.Length; ++i ) // Just make sure perk stays the same.
StatBuyers[i].CheckBuyLimit();
// Update traits list.
UpdateTraits();
}
}
}
defaultproperties
{
Components.Remove(UnloadPerkButton)
Components.Remove(PrestigePerkButton)
Components.Remove(ResetPerkButton)
}

View File

@ -250,7 +250,7 @@ final function Texture2D FindAvatar( UniqueNetId ClientID )
S = KFPlayerController(GetPlayer()).GetSteamAvatar(ClientID);
if( S=="" )
return None;
return Texture2D(FindObject(Mid(S,6),class'Texture2D'));
return Texture2D(FindObject(S,class'Texture2D'));
}
final function DrawCenteredText( string S, float X, float Y, optional float Scale=1.f )

View File

@ -290,6 +290,8 @@ function CheckWave()
}
function NotifyWaveChange()
{
local ExtPlayerController ExtPC;
if( bRespawnCheck )
{
bIsPostGame = (KF.WaveMax<KF.WaveNum);
@ -302,6 +304,12 @@ function NotifyWaveChange()
NumWaveSwitches = 0;
SaveAllPerks();
}
if( !KF.bTraderIsOpen )
{
foreach WorldInfo.AllControllers(class'ExtPlayerController',ExtPC)
ExtPC.bSetPerk = false;
}
}
function SetupWebAdmin()
{
@ -350,6 +358,9 @@ function AddMutator(Mutator M)
}
function ScoreKill(Controller Killer, Controller Killed)
{
local KFPlayerController KFPC;
local ExtPerkManager KillersPerk;
if( bRespawnCheck && Killed.bIsPlayer )
CheckRespawn(Killed);
if( KFPawn_Monster(Killed.Pawn)!=None && Killed.GetTeamNum()!=0 && Killer.bIsPlayer && Killer.GetTeamNum()==0 )
@ -361,6 +372,19 @@ function ScoreKill(Controller Killer, Controller Killed)
//else if( Killer!=None && Killer!=Killed && Killer.GetTeamNum()==0 && Ext_T_MonsterPRI(Killer.PlayerReplicationInfo)!=None )
// BroadcastKillMessage(Killed.Pawn,Ext_T_MonsterPRI(Killer.PlayerReplicationInfo).OwnerController);
}
if ( MyKFGI != None && MyKFGI.IsZedTimeActive() && KFPawn_Monster(Killed.Pawn) != None )
{
KFPC = KFPlayerController(Killer);
if ( KFPC != none )
{
KillersPerk = ExtPerkManager(KFPC.GetPerk());
if ( MyKFGI.ZedTimeRemaining > 0.f && KillersPerk != none && KillersPerk.GetZedTimeExtensions( KFPC.GetLevel() ) > MyKFGI.ZedTimeExtensionsUsed )
{
MyKFGI.DramaticEvent(1.0);
MyKFGI.ZedTimeExtensionsUsed++;
}
}
}
if( ExtPlayerController(Killed)!=None )
CheckPerkChange(ExtPlayerController(Killed));
if (NextMutator != None)
@ -468,7 +492,9 @@ function NetDamage(int OriginalDamage, out int Damage, Pawn Injured, Controller
}
if( Damage>0 && InstigatedBy!=None )
{
if( KFPawn_Monster(Injured)!=None && Injured.GetTeamNum()!=0 )
if( KFPawn_Monster(Injured)!=None )
{
if( Injured.GetTeamNum()!=0 )
{
LastDamageDealer = ExtPlayerController(InstigatedBy);
if( bDamageMessages && LastDamageDealer!=None && !LastDamageDealer.bNoDamageTracking )
@ -487,6 +513,12 @@ function NetDamage(int OriginalDamage, out int Damage, Pawn Injured, Controller
HackSetHistory(KFPawn(Injured),Injured,Ext_T_MonsterPRI(InstigatedBy.PlayerReplicationInfo).OwnerController,Damage,HitLocation);
}
}
else if( KFPawn(InstigatedBy.Pawn).GetTeamNum() != KFPawn(Injured).GetTeamNum() )
{
Momentum = vect(0,0,0);
Damage = 0;
}
}
else if( bDamageMessages && KFPawn_Human(Injured)!=None && Injured.GetTeamNum()==0 && InstigatedBy.GetTeamNum()!=0 && ExtPlayerController(InstigatedBy)!=None )
{
LastDamageDealer = ExtPlayerController(InstigatedBy);
@ -1026,15 +1058,20 @@ function PlayerChangePerk( ExtPlayerController PC, class<Ext_PerkBase> NewPerk )
PC.PendingPerkClass = None;
}
}
else if( PC.ActivePerkManager.CurrentPerk==None || PC.Pawn==None || !PC.Pawn.IsAliveAndWell() )
else if( PC.ActivePerkManager.CurrentPerk==None || KFPawn_Customization(PC.Pawn)!=None || (!PC.bSetPerk && KFGameReplicationInfo(WorldInfo.GRI).bTraderIsOpen) )
{
if( PC.ActivePerkManager.ApplyPerkClass(NewPerk) )
{
PC.ClientMessage("You have changed your perk to "$NewPerk.Default.PerkName);
PC.bSetPerk = true;
}
else PC.ClientMessage("Invalid perk "$NewPerk.Default.PerkName);
}
else if( PC.bSetPerk )
PC.ClientMessage("Can only change perks once per wave");
else
{
PC.ClientMessage("You will change to perk '"$NewPerk.Default.PerkName$"' next time you have died.");
PC.ClientMessage("You will change to perk '"$NewPerk.Default.PerkName$"' during trader time.");
PC.PendingPerkClass = NewPerk;
}
}
@ -1043,11 +1080,29 @@ function CheckPerkChange( ExtPlayerController PC )
if( PC.PendingPerkClass!=None )
{
if( PC.ActivePerkManager.ApplyPerkClass(PC.PendingPerkClass) )
{
PC.ClientMessage("You have changed your perk to "$PC.PendingPerkClass.Default.PerkName);
PC.bSetPerk = true;
}
else PC.ClientMessage("Invalid perk "$PC.PendingPerkClass.Default.PerkName);
PC.PendingPerkClass = None;
}
}
function Tick(float DeltaTime)
{
local bool bCheckedWave;
local ExtPlayerController ExtPC;
if( KFGameReplicationInfo(WorldInfo.GRI).bTraderIsOpen && !bCheckedWave )
{
foreach WorldInfo.AllControllers(class'ExtPlayerController',ExtPC)
CheckPerkChange(ExtPC);
bCheckedWave = true;
}
else if( bCheckedWave )
bCheckedWave = false;
}
function PlayerBoughtTrait( ExtPlayerController PC, class<Ext_PerkBase> PerkClass, class<Ext_TraitBase> Trait )
{
local Ext_PerkBase P;