1
0
This commit is contained in:
GenZmeY 2021-12-09 19:33:06 +03:00
parent b56d5b0c62
commit 0fe0ac1920
89 changed files with 3362 additions and 245 deletions

View File

@ -857,6 +857,7 @@ function PendingAuthTimer()
if (ClientsPendingAuth[i].AuthRetryCount < MaxAuthRetryCount)
{
// End the auth session first before retrying
`Log("RETRYING CONNECTION - AuthRetryCount: " $ClientsPendingAuth[i].AuthRetryCount $" WHEN MAX CONNECTIONS ARE " $MaxAuthRetryCount);
CachedAuthInt.EndRemoteClientAuthSession(CurClientSession.EndPointUID, CurClientSession.EndPointIP);
// Get the client to end it on his end too (this should execute on client before the new auth request below)
@ -865,11 +866,13 @@ function PendingAuthTimer()
// Start the new auth session
if (CachedAuthInt.SendClientAuthRequest(ClientsPendingAuth[i].ClientConnection, CurClientSession.EndPointUID))
{
`Log("NEW CLIENT AUTH REQUEST SENT - SUCCESS");
ClientsPendingAuth[i].AuthTimestamp = WorldInfo.RealTimeSeconds;
ClientsPendingAuth[i].AuthRetryCount++;
}
else
{
`Log("NEW CLIENT AUTH REQUEST SENT - FAIL");
bFailed = True;
}
}
@ -1111,6 +1114,7 @@ function OnClientAuthComplete(bool bSuccess, UniqueNetId ClientUID, Player Clien
{
`log("Client failed authentication (unauthenticated UID:"@
Class'OnlineSubsystem'.static.UniqueNetIdToString(ClientUID)$"), kicking");
`Log("Client Auth failure info: " $ExtraInfo);
// Kick the client
WorldInfo.Game.RejectLogin(ClientConnection, "Authentication failed");
@ -1201,6 +1205,8 @@ function ProcessServerAuthRetryRequest(Player ClientConnection)
local AuthSession CurClientSession;
local LocalAuthSession CurServerSession;
`Log("PROCESS SERVER AUTH RETRY REQUEST - " $bAuthenticateServer $" - " $ ClientConnection != none);
if (bAuthenticateServer && ClientConnection != none)
{
bFoundAndAuthenticated = CachedAuthInt.FindClientAuthSession(ClientConnection, CurClientSession) &&
@ -1387,6 +1393,8 @@ function EndListenHostAuth()
local int ServerPort;
//@HSL_END_XBOX
`Log("EndListenHostAuth");
if (OnlineSub.PlayerInterface != none)
{
bGotHostInfo = CachedAuthInt.GetServerUniqueId(ServerUID) &&
@ -1489,6 +1497,7 @@ static final function StaticOnClientConnectionClose(Player ClientConnection)
if (CurAuthInt != none && ClientConnection != none)
{
`Log("StaticOnClientConnectionClose");
// If the client is authenticated, end the client auth session
if (CurAuthInt.FindClientAuthSession(ClientConnection, CurClientSession) && CurClientSession.AuthStatus == AUS_Authenticated)
{
@ -1548,6 +1557,7 @@ function OnDestroyOnlineGameComplete(name SessionName, bool bWasSuccessful)
{
if (CurClientSession.AuthStatus == AUS_Authenticated)
{
`Log("OnDestroyOnlineGameComplete");
// End the client auth session
CachedAuthInt.EndRemoteClientAuthSession(CurClientSession.EndPointUID, CurClientSession.EndPointIP);
@ -1638,6 +1648,7 @@ function Cleanup(optional bool bExit)
// If the game is exiting, end all auth sessions
if (bExit)
{
`Log("AccessControl CLEAN UP");
// End all remote client auth sessions
CachedAuthInt.EndAllRemoteClientAuthSessions();

View File

@ -227,6 +227,11 @@ function SetupNextWave(byte NextWaveIndex, int TimeToNextWaveBuffer = 0)
{
local KFGameReplicationInfo KFGRI;
if (OutbreakEvent.ActiveEvent.bBossRushMode)
{
NextWaveIndex = MyKFGRI.WaveMax - 1;
}
if( NextWaveIndex < WaveSettings.Waves.Length )
{
// Recycle special squads on higher difficulties
@ -250,7 +255,7 @@ function SetupNextWave(byte NextWaveIndex, int TimeToNextWaveBuffer = 0)
// Initialize our recycle number
NumSpecialSquadRecycles = 0;
if (MyKFGRI.IsBossWave())
if (MyKFGRI.IsBossWave() || OutbreakEvent.ActiveEvent.bBossRushMode)
{
WaveTotalAI = 1;
}
@ -383,6 +388,7 @@ function GetSpawnListFromSquad(byte SquadIdx, out array< KFAISpawnSquad > Squads
local ESquadType LargestMonsterSquadType;
local array<class<KFPawn_Monster> > TempSpawnList;
local class<KFPawn_Monster> ForcedPawnClass;
local int RandBossIndex;
Squad = SquadsList[SquadIdx];
@ -421,7 +427,17 @@ function GetSpawnListFromSquad(byte SquadIdx, out array< KFAISpawnSquad > Squads
else
`endif
//Always have the squad type be a boss if we're spawning one in case of override
TempSpawnList.AddItem(GetBossAISpawnType());
if (OutbreakEvent.ActiveEvent.bBossRushMode)
{
RandBossIndex = Rand(BossRushEnemies.length);
TempSpawnList.AddItem( default.AIBossClassList[BossRushEnemies[RandBossIndex]]);
BossRushEnemies.Remove(RandBossIndex, 1);
}
else
{
TempSpawnList.AddItem(GetBossAISpawnType());
}
LargestMonsterSquadType = EST_Boss;
}
else

View File

@ -375,17 +375,26 @@ function bool CanUpgrade(STraderItem SelectedItem, out int CanCarryIndex, out in
function PurchaseWeapon(STraderItem ShopItem)
{
local int ItemUpgradeLevel;
local KFPlayerController KFPC;
local int Price;
if(!bCanPurchase(ShopItem, true))
{
return;
}
Price = GetAdjustedBuyPriceFor(ShopItem);
// XMAS 2021 Seasonal Objective
KFPC = Outer;
`Log("ADDING WEAPON PURCHASED");
KFPC.AddWeaponPurchased(ShopItem.WeaponDef, Price);
//
ItemUpgradeLevel = ShopItem.SingleClassName != '' ?
GetItemUpgradeLevelByClassName(ShopItem.SingleClassName) :
INDEX_None;
AddDosh(-GetAdjustedBuyPriceFor(ShopItem));
AddDosh(-Price);
AddBlocks(MyKFIM.GetWeaponBlocks(ShopItem, ItemUpgradeLevel));
AddWeaponToOwnedItemList(ShopItem);
}
@ -1181,7 +1190,7 @@ function SetWeaponInfo(const KFWeapon KFW, STraderItem DefaultItem)
WeaponInfo.AmmoPricePerMagazine = AmmoCostScale * DefaultItem.WeaponDef.default.AmmoPricePerMag;
WeaponInfo.SellPrice = GetAdjustedSellPriceFor(DefaultItem);
WeaponInfo.DefaultItem.bCanBuyAmmo = KFW.CanBuyAmmo();
AddItemByPriority( WeaponInfo );
// if adding a dual, remove the related single

View File

@ -139,6 +139,12 @@ var string ZEDCowboyHatMeshPath;
var transient LinearColor WWLHatMonoChromeValue;
var transient LinearColor WWLHatColorValue;
/************************************************************************/
/* Tiny Skulls Weekly */
/************************************************************************/
var float TinySkullPitchAudio;
/************************************************************************/
/* Script Functions */
/************************************************************************/
@ -167,6 +173,8 @@ simulated function SetCharacterMeshFromArch( KFPawn KFP, optional KFPlayerReplic
if( CharacterMesh != none )
{
KFGRI = KFGameReplicationInfo(KFP.WorldInfo.GRI);
// Clear character customization settings
KFP.DetachComponent(KFP.ThirdPersonHeadMeshComponent);
for( i=0; i < `MAX_COSMETIC_ATTACHMENTS; i++ )
@ -188,7 +196,16 @@ simulated function SetCharacterMeshFromArch( KFPawn KFP, optional KFPlayerReplic
KFP.Mesh.SetSkeletalMesh(CharacterMesh);
}
KFP.Mesh.SetScale(DefaultMeshScale);
KFP.PitchAudio(DefaultMeshScale);
if (KFP != none && KFGRI.bIsWeeklyMode && KFGRI.CurrentWeeklyIndex == 15)
{
KFP.PitchAudio(TinySkullPitchAudio);
}
else
{
KFP.PitchAudio(DefaultMeshScale);
}
// Use material specified in the mesh asset
// @note: need to add this if we allow character swap post-spawn (e.g. customization)
@ -256,7 +273,6 @@ simulated function SetCharacterMeshFromArch( KFPawn KFP, optional KFPlayerReplic
}
}
KFGRI = KFGameReplicationInfo(KFP.WorldInfo.GRI);
if (KFP != none && KFGRI.bIsWeeklyMode && (class'KFGameEngine'.static.GetWeeklyEventIndexMod() == 12))
{
NewAttachment.StaticAttachment = StaticMesh(DynamicLoadObject(ZEDCowboyHatMeshPath, class'StaticMesh'));
@ -325,4 +341,5 @@ defaultproperties
WWLHatColorValue=(R=1.0f,G=0.0f,B=0.0f)
ZEDCowboyHatMeshPath = "CHR_CosmeticSet01_MESH.cowboyhat.CHR_CowboyHat_Alberts_Cosmetic"
TinySkullPitchAudio = 0.5f;
}

View File

@ -764,6 +764,17 @@ exec function DebugShowVoteSkipTrader()
}
}
exec function DebugShowVotePauseGame()
{
local KFPlayerReplicationInfo KFPRI;
KFPRI = KFPlayerReplicationInfo(PlayerReplicationInfo);
if (KFPlayerController(Outer).MyGFxHUD != none && KFPRI != None)
{
KFPlayerController(Outer).RequestPauseGame();
}
}
exec function ToggleForceCrosshair()
{
KFHudBase(MyHud).bForceDrawCrosshair = !KFHudBase(MyHud).bForceDrawCrosshair;

View File

@ -385,6 +385,13 @@ function GiveTo(Pawn P)
local class<KFWeapon> KFWInvClass;
local Inventory NewInventory;
local KFInventoryManager KFIM;
local KFGameReplicationInfo KFGRI;
KFGRI = KFGameReplicationInfo(WorldInfo.GRI);
if (KFGRI != none && KFGRI.bIsEndlessPaused)
{
return;
}
KFIM = KFInventoryManager(P.InvManager);
if (KFIM != None)

View File

@ -0,0 +1,27 @@
class KFGFXSpecialEventObjectivesContainer_Xmas2021 extends KFGFxSpecialEventObjectivesContainer;
function Initialize(KFGFxObject_Menu NewParentMenu)
{
super.Initialize(NewParentMenu);
}
DefaultProperties
{
ObjectiveIconURLs[0] = "Xmas2021_UI.Heads_For_Sale" // Decapitate 1000 Zeds on any map or mode
ObjectiveIconURLs[1] = "Xmas2021_UI.Black_Weekly" // Complete the Weekly on Carillon Hamlet
ObjectiveIconURLs[2] = "Xmas2021_UI.Filthy_Rich" // Earn 75,000 Dosh through kills, rewards and healing on Carillon Hamlet
ObjectiveIconURLs[3] = "Xmas2021_UI.Painful_Payments" // Use the trader to purchase a total of 20 weapons that cost 1500 Dosh or more on Carrion Hamlet.
ObjectiveIconURLs[4] = "Xmas2021_UI.Nonstop_Splurge" // Complete wave 15 on Endless Hard or higher difficulty on Carillon Hamlet
//defaults
AllCompleteRewardIconURL="CHR_CosmeticSet_XMAS_05_Item_TEX.shopping_companion.holidayshoppingcompanion_precious"
ChanceDropIconURLs[0]="CHR_Cosmetic_XMAS_Item_TEX.Tickets.Krampus_Ticket"
ChanceDropIconURLs[1]="CHR_Cosmetic_XMAS_Item_TEX.Tickets.Krampus_Ticket_Golden"
IconURL="Xmas2021_UI.KF2_SmallLogo"
UsesProgressList[0] = true
UsesProgressList[1] = false
UsesProgressList[2] = true
UsesProgressList[3] = true
UsesProgressList[4] = false
}

View File

@ -182,6 +182,15 @@ function UpdateWeapon()
SetInt("backpackStoredAmmo" , CurrentSpareAmmo);
LastSpareAmmo = CurrentSpareAmmo;
}
/**
Reusing this variable for showing the dosh icon for doshinegun.
Only FAMAS uses bUsesSecondaryAmmoAltHUD and for it bUsesSecondaryAmmo is true
*/
if (!bUsesSecondaryAmmo && CurrentWeapon.bUsesSecondaryAmmoAltHUD)
{
SetBool("doshAmmoIcon", true);
}
}
else
{

View File

@ -80,6 +80,7 @@ var GFxObject KFGXHUDManager;
var bool bIsSkipTraderVoteActive;
var bool bIsKickVoteActive;
var bool bUserAlreadyStartASkipTraderVote;
var bool bIsPauseGameVoteActive;
var bool bIsSpectating;
var bool bIsVisible;
@ -1144,7 +1145,7 @@ function OpenChatBox()
}
//==============================================================
// Kick and Skip Trader Vote
// Kick, Skip Trader and Pause Game Vote
//==============================================================
function ShowKickVote(PlayerReplicationInfo PRI, byte VoteDuration, bool bShowChoices)
@ -1152,8 +1153,9 @@ function ShowKickVote(PlayerReplicationInfo PRI, byte VoteDuration, bool bShowCh
if(KickVoteWidget != none)
{
bIsSkipTraderVoteActive = false;
bIsKickVoteActive = true;
KickVoteWidget.ShowVote(PRI, VoteDuration, bShowChoices, bIsSkipTraderVoteActive);
bIsPauseGameVoteActive = false;
bIsKickVoteActive = true;
KickVoteWidget.ShowVote(PRI, VoteDuration, bShowChoices, VT_KICK);
}
}
@ -1163,6 +1165,7 @@ simulated function HideKickVote()
{
bIsSkipTraderVoteActive = false;
bIsKickVoteActive = false;
bIsPauseGameVoteActive = false;
KickVoteWidget.VoteClosed();
}
}
@ -1181,7 +1184,8 @@ function ShowSkipTraderVote(PlayerReplicationInfo PRI, byte VoteDuration, bool b
{
bIsSkipTraderVoteActive = true;
bIsKickVoteActive = false;
KickVoteWidget.ShowVote(PRI, VoteDuration, bShowChoices, bIsSkipTraderVoteActive);
bIsPauseGameVoteActive = false;
KickVoteWidget.ShowVote(PRI, VoteDuration, bShowChoices, VT_SKIP_TRADER);
}
}
@ -1199,6 +1203,7 @@ simulated function HideSkipTraderVote()
{
bIsSkipTraderVoteActive = false;
bIsKickVoteActive = false;
bIsPauseGameVoteActive = false;
KickVoteWidget.VoteClosed();
}
}
@ -1211,6 +1216,49 @@ function UpdateSkipTraderVoteCount(byte YesVotes, byte NoVotes)
}
}
function ShowPauseGameVote(PlayerReplicationInfo PRI, byte VoteDuration, bool bShowChoices)
{
local KFGameReplicationInfo KFGRI;
KFGRI=KFGameReplicationInfo(KFPC.WorldInfo.GRI);
if (KickVoteWidget != none)
{
bIsPauseGameVoteActive = true;
bIsKickVoteActive = false;
bIsSkipTraderVoteActive = false;
KickVoteWidget.ShowVote(PRI, VoteDuration, bShowChoices, (KFGRI != none && KFGRI.bIsEndlessPaused) ? VT_RESUME_GAME : VT_PAUSE_GAME);
}
}
function UpdatePauseGameTime(byte VoteDuration)
{
if(KickVoteWidget != none)
{
KickVoteWidget.UpdateVoteDuration(VoteDuration);
}
}
simulated function HidePauseGameVote()
{
if(KickVoteWidget != none)
{
bIsPauseGameVoteActive = false;
bIsKickVoteActive = false;
bIsSkipTraderVoteActive = false;
KickVoteWidget.VoteClosed();
}
}
function UpdatePauseGameVoteCount(byte YesVotes, byte NoVotes)
{
if(KickVoteWidget != none)
{
`Log("UPDATING PAUSE GAME VOTE COUNT - YES: "$YesVotes);
`Log("UPDATING PAUSE GAME VOTE COUNT - NO: "$NoVotes);
KickVoteWidget.UpdateVoteCount(YesVotes, NoVotes);
}
}
//==============================================================
// Updates
//==============================================================
@ -1347,7 +1395,7 @@ function Callback_VoiceCommsSelection( int CommsIndex )
}
}
function Callback_VoteKick(bool bKickOrSkip)
function Callback_VoteKick(bool Vote)
{
local KFPlayerReplicationInfo KFPRI;
@ -1355,11 +1403,15 @@ function Callback_VoteKick(bool bKickOrSkip)
if(bIsSkipTraderVoteActive)
{
KFPRI.CastSkipTraderVote(KFPRI, bKickOrSkip);
KFPRI.CastSkipTraderVote(KFPRI, Vote);
}
else if(bIsPauseGameVoteActive)
{
KFPRI.CastPauseGameVote(KFPRI, Vote);
}
else
{
KFPRI.CastKickVote(KFPRI, bKickOrSkip);
KFPRI.CastKickVote(KFPRI, Vote);
}
if(KickVoteWidget != none)

View File

@ -44,30 +44,40 @@ function SetMapOptions()
local int i, Counter;
local array<string> ServerMapList;
local KFGameReplicationInfo KFGRI;
local bool IsWeeklyMode;
local bool IsBrokenTrader;
local bool IsBossRush;
KFGRI = KFGameReplicationInfo(GetPC().WorldInfo.GRI);
Counter = 0;
if(KFGRI != none && KFGRI.VoteCollector != none)
{
ServerMapList = KFGRI.VoteCollector.MapList;
IsBrokenTrader = KFGRI.IsA('KFGameReplicationInfo_WeeklySurvival') && class'KFGameEngine'.static.GetWeeklyEventIndexMod() == 11;
ServerMapList = KFGRI.VoteCollector.MapList;
IsWeeklyMode = KFGRI.bIsWeeklyMode;
IsBrokenTrader = KFGRI.CurrentWeeklyIndex == 11;
IsBossRush = KFGRI.CurrentWeeklyIndex == 14;
//gfx
MapList = CreateArray();
for (i = 0; i < ServerMapList.length; i++)
{
if (IsBrokenTrader && ( ServerMapList[i] == "KF-Biolapse" ||
ServerMapList[i] == "KF-Nightmare" ||
ServerMapList[i] == "KF-PowerCore_Holdout" ||
ServerMapList[i] == "KF-TheDescent" ||
ServerMapList[i] == "KF-KrampusLair"))
if ( IsWeeklyMode && (IsBrokenTrader || IsBossRush) && ( ServerMapList[i] == "KF-Biolapse" ||
ServerMapList[i] == "KF-Nightmare" ||
ServerMapList[i] == "KF-PowerCore_Holdout" ||
ServerMapList[i] == "KF-TheDescent" ||
ServerMapList[i] == "KF-KrampusLair"))
{
continue;
}
/* Temporary removal of SteamFrotress for BossRush */
if (IsWeeklyMode && IsBossRush && ServerMapList[i] == "KF-SteamFortress")
{
continue;
}
/**/
MapObject = CreateObject("Object");
MapObject.SetString("label", class'KFCommon_LocalizedStrings'.static.GetFriendlyMapName(ServerMapList[i]) );
MapObject.SetString("mapSource", GetMapSource(ServerMapList[i]) );

View File

@ -182,34 +182,31 @@ function FillWhatsNew()
local SWhatsNew item;
WhatsNewItems.Remove(0, WhatsNewItems.Length);
// Latest Update
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Halloween_DayOfTheZED_Event", "LatestUpdate", "http://www.tripwireinteractive.com/redirect/KF2LatestUpdate/");
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Christmas_ChopTilYouDrop", "LatestUpdate", "http://www.tripwireinteractive.com/redirect/KF2LatestUpdate/");
WhatsNewItems.AddItem(item);
// KF2 Armory Season Pass 2021
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Spring_Armory_Season_Pass", "ArmorySeasonPass", "https://store.steampowered.com/app/1524820/Killing_Floor_2__Armory_Season_Pass");
WhatsNewItems.AddItem(item);
// Featured Time Limited Item
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Halloween_PremiumTicket", "FeaturedEventItem", "https://store.steampowered.com/buyitem/232090/4928");
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Christmas_PremiumTicket", "FeaturedEventItem", "https://store.steampowered.com/buyitem/232090/5588");
WhatsNewItems.AddItem(item);
// Featured Full Gear
item=SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Halloween_FullGearBundle_DoZ", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9119");
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Xmas_Holiday_Shopper", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9262");
WhatsNewItems.AddItem(item);
// Featured Cosmetic Bundle
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Halloween_DoZ_Cosmetics", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9120");
// Featured Outfit Bundle
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Christmas_Shopping_Uniforms", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9263");
WhatsNewItems.AddItem(item);
// Featured Weapon Skin Bundle
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Halloween_Hellmark", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9121");
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Xmas_Christmas", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9264");
WhatsNewItems.AddItem(item);
// Featured Weapon Skin Bundle
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Xmas_Alchemist_Weapon_Skin", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9265");
WhatsNewItems.AddItem(item);
// Featured Cosmetic Bundle
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Halloween_Vietnam","FeaturedItemBundle","https://store.steampowered.com/buyitem/232090/9122");
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Xmas_Alchemist","FeaturedItemBundle","https://store.steampowered.com/buyitem/232090/9266");
WhatsNewItems.AddItem(item);
// Featured Weapon Bundle
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Halloween_PiranhaPistol", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9123");
WhatsNewItems.AddItem(item);
// Featured Weapon Bundle
item=SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Halloween_CorrupterCarbine", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9124");
WhatsNewItems.AddItem(item);
// Featured Weapon Bundle
item=SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_halloween_Weaponsbundle", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9125");
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_XMAS_Doshinegun", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9267");
WhatsNewItems.AddItem(item);
// Misc Community Links
item=SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_CommunityHub", "Jaegorhorn", "https://steamcommunity.com/app/232090");

View File

@ -264,13 +264,17 @@ function InitializeGameOptions()
function FilterWeeklyMaps(out array<string> List)
{
local int WeeklyIndex;
if (ParentMenu.Manager.GetModeIndex(false) != EGameMode_Weekly)
{
return;
}
// Scavenger index = 11
if (class'KFGameEngine'.static.GetWeeklyEventIndexMod() == 11)
// BossRush index = 14
WeeklyIndex = class'KFGameEngine'.static.GetWeeklyEventIndexMod();
if (WeeklyIndex == 11 || WeeklyIndex == 14)
{
List.RemoveItem("KF-Biolapse");
List.RemoveItem("KF-Nightmare");
@ -278,6 +282,14 @@ function FilterWeeklyMaps(out array<string> List)
List.RemoveItem("KF-TheDescent");
List.RemoveItem("KF-KrampusLair");
}
/* Temporary removal of SteamFrotress for BossRush */
if (WeeklyIndex == 14)
{
List.RemoveItem("KF-SteamFortress");
}
/**/
}
function GFxObject CreateList( array<string> TextArray, byte SelectedIndex, bool bAddNoPrefString, optional bool bIsMapList, optional byte MaxLength)

View File

@ -447,23 +447,21 @@ DefaultProperties
XboxFilterExceptions[0]="Wasteland Bundle" // Wasteland Outfit Bundle
FeaturedItemIDs[0]=7619 //Whatsnew Gold Ticket
FeaturedItemIDs[1]=9119
FeaturedItemIDs[2]=9120
FeaturedItemIDs[3]=9121
FeaturedItemIDs[4]=9122
FeaturedItemIDs[5]=9123
FeaturedItemIDs[6]=9124
FeaturedItemIDs[7]=9125
FeaturedItemIDs[0]=7944 //Whatsnew Gold Ticket
FeaturedItemIDs[1]=9262
FeaturedItemIDs[2]=9263
FeaturedItemIDs[3]=9264
FeaturedItemIDs[4]=9265
FeaturedItemIDs[5]=9266
FeaturedItemIDs[6]=9267
ConsoleFeaturedItemIDs[0]=7783 //Whatsnew Gold Ticket PSN
ConsoleFeaturedItemIDs[1]=9119
ConsoleFeaturedItemIDs[2]=9120
ConsoleFeaturedItemIDs[3]=9121
ConsoleFeaturedItemIDs[4]=9122
ConsoleFeaturedItemIDs[5]=9123
ConsoleFeaturedItemIDs[6]=9124
ConsoleFeaturedItemIDs[7]=9125
ConsoleFeaturedItemIDs[0]=7947 //Whatsnew Gold Ticket PSN
ConsoleFeaturedItemIDs[1]=9262
ConsoleFeaturedItemIDs[2]=9263
ConsoleFeaturedItemIDs[3]=9264
ConsoleFeaturedItemIDs[4]=9265
ConsoleFeaturedItemIDs[5]=9266
ConsoleFeaturedItemIDs[6]=9267
MaxFeaturedItems=5
}

View File

@ -117,9 +117,9 @@ function RefreshPlayerInventory()
PricePerRound = ( MagSize > 0 ) ? float(PricePerMag) / float(MagSize) : 0.f;
BlocksRequired = -1; // This will hide the weight and
SetItemInfo( InfoSlot, ItemInfo.DefaultItem.WeaponDef, "SecondaryAmmo", TextureLocation, AmmoCount, MaxAmmoCount, BlocksRequired, true );
SetMagInfo( MagSlot, AmmoCount, MaxAmmoCount, MagSize, PricePerMag, PricePerRound, FillAmmoCost );
SetFillInfo( FillSlot, AmmoCount, MaxAmmoCount, PricePerRound, FillAmmoCost, AutoFillCost );
SetItemInfo( InfoSlot, ItemInfo.DefaultItem.WeaponDef, "SecondaryAmmo", TextureLocation, AmmoCount, MaxAmmoCount, BlocksRequired, true, 0, ItemInfo.DefaultItem.bCanBuyAmmo);
SetMagInfo( MagSlot, AmmoCount, MaxAmmoCount, MagSize, PricePerMag, PricePerRound, FillAmmoCost, ItemInfo.DefaultItem.bCanBuyAmmo);
SetFillInfo( FillSlot, AmmoCount, MaxAmmoCount, PricePerRound, FillAmmoCost, AutoFillCost, ItemInfo.DefaultItem.bCanBuyAmmo );
}
else
{
@ -132,9 +132,9 @@ function RefreshPlayerInventory()
PricePerRound = ( MagSize > 0 ) ? float(PricePerMag) / float(MagSize) : 0.f;
BlocksRequired = MyTraderMenu.GetDisplayedBlocksRequiredFor(ItemInfo.DefaultItem, ItemInfo.ItemUpgradeLevel);
SetItemInfo( InfoSlot, ItemInfo.DefaultItem.WeaponDef, "ItemName", TextureLocation, AmmoCount, MaxAmmoCount, BlocksRequired, false, KFPC.GetPurchaseHelper().GetItemUpgradeLevelByClassName(ItemInfo.DefaultItem.ClassName) );
SetMagInfo( MagSlot, AmmoCount, MaxAmmoCount, MagSize, PricePerMag, PricePerRound, FillAmmoCost );
SetFillInfo( FillSlot, AmmoCount, MaxAmmoCount, PricePerRound, FillAmmoCost, AutoFillCost );
SetItemInfo( InfoSlot, ItemInfo.DefaultItem.WeaponDef, "ItemName", TextureLocation, AmmoCount, MaxAmmoCount, BlocksRequired, false, KFPC.GetPurchaseHelper().GetItemUpgradeLevelByClassName(ItemInfo.DefaultItem.ClassName), ItemInfo.DefaultItem.bCanBuyAmmo );
SetMagInfo( MagSlot, AmmoCount, MaxAmmoCount, MagSize, PricePerMag, PricePerRound, FillAmmoCost, ItemInfo.DefaultItem.bCanBuyAmmo );
SetFillInfo( FillSlot, AmmoCount, MaxAmmoCount, PricePerRound, FillAmmoCost, AutoFillCost, ItemInfo.DefaultItem.bCanBuyAmmo );
}
SetSellInfo(SellSlot, ItemInfo.SellPrice, ItemInfo.SellPrice > 0);
@ -173,7 +173,7 @@ function SetArmorInfo(out SItemInformation ArmorInfo, out int AutoFillCost)
SlotObject.SetString("itemAmmo", ArmorInfo.SpareAmmoCount$"/"$ArmorInfo.MaxSpareAmmo);
SlotObject.SetBool("lowAmmo", (ArmorInfo.MaxSpareAmmo > 0) ? (float(ArmorInfo.SpareAmmoCount) / float(ArmorInfo.MaxSpareAmmo)) <= LowAmmoPercentThreshold : false);
ButtonState = GetButtonState( ArmorInfo.AmmoPricePerMagazine, ArmorInfo.SpareAmmoCount, ArmorInfo.MaxSpareAmmo );
ButtonState = GetButtonState( ArmorInfo.AmmoPricePerMagazine, ArmorInfo.SpareAmmoCount, ArmorInfo.MaxSpareAmmo, true );
SlotObject.Setint("buttonState", ButtonState );
SlotObject.Setint("magButtonState", ButtonState );
@ -201,7 +201,7 @@ function SetGrenadeInfo(out SItemInformation GrenadeInfo, out int AutoFillCost)
SlotObject.SetInt("fillCost", FillCost);
SlotObject.SetBool("lowAmmo", (GrenadeInfo.MaxSpareAmmo > 0) ? (float(GrenadeInfo.SpareAmmoCount) / float(GrenadeInfo.MaxSpareAmmo)) <= LowAmmoPercentThreshold : false);
SlotObject.SetString("itemAmmo", GrenadeInfo.SpareAmmoCount $"/"$GrenadeInfo.MaxSpareAmmo);
ButtonState = GetButtonState(AmmoPricePerMagazine, GrenadeInfo.SpareAmmoCount, GrenadeInfo.MaxSpareAmmo);
ButtonState = GetButtonState(AmmoPricePerMagazine, GrenadeInfo.SpareAmmoCount, GrenadeInfo.MaxSpareAmmo, true);
SlotObject.Setint("magButtonState", ButtonState);
SlotObject.Setint("fillButtonState", ButtonState);
@ -210,12 +210,12 @@ function SetGrenadeInfo(out SItemInformation GrenadeInfo, out int AutoFillCost)
AutoFillCost += FillCost;
}
function SetItemInfo(out GFxObject InfoSlot, class<KFWeaponDefinition> WeaponDef, string ItemKeyString, string TextureLocation, int AmmoCount, int MaxAmmoCount, int BlocksRequired, optional bool bSecondaryAmmo, optional int UpgradeLevel )
function SetItemInfo(out GFxObject InfoSlot, class<KFWeaponDefinition> WeaponDef, string ItemKeyString, string TextureLocation, int AmmoCount, int MaxAmmoCount, int BlocksRequired, optional bool bSecondaryAmmo, optional int UpgradeLevel, optional bool bCanBuyAmmo = true )
{
local string ItemTexPath;
InfoSlot.SetString( "itemName", WeaponDef.static.GetItemLocalization(ItemKeyString) );
InfoSlot.SetString( "itemAmmo", AmmoCount $"/" $MaxAmmoCount);
InfoSlot.SetString( "itemAmmo", AmmoCount $"/" $(bCanBuyAmmo ? MaxAmmoCount : 0 ));
InfoSlot.Setint( "itemWeight", BlocksRequired );
InfoSlot.Setint("weaponTier", UpgradeLevel);
@ -226,7 +226,7 @@ function SetItemInfo(out GFxObject InfoSlot, class<KFWeaponDefinition> WeaponDef
InfoSlot.SetString( "itemSource", ItemTexPath );
}
function SetMagInfo(out GFxObject MagSlot, int AmmoCount, int MaxAmmoCount, byte AmmoMagSize, int PricePerMag, float PricePerRound, int FillAmmoCost)
function SetMagInfo(out GFxObject MagSlot, int AmmoCount, int MaxAmmoCount, byte AmmoMagSize, int PricePerMag, float PricePerRound, int FillAmmoCost, bool bCanBuyAmmo)
{
local int MagCost;
local bool bBuyPartialMag;
@ -236,14 +236,14 @@ function SetMagInfo(out GFxObject MagSlot, int AmmoCount, int MaxAmmoCount, byte
MagSlot.SetString("label", MagString);
MagSlot.SetInt("buttonValue", MagCost);
MagSlot.SetInt("buttonState", GetButtonState( PricePerRound, AmmoCount, MaxAmmoCount));
MagSlot.SetInt("buttonState", GetButtonState( PricePerRound, AmmoCount, MaxAmmoCount, bCanBuyAmmo));
}
function SetFillInfo(out GFxObject FillSlot, int AmmoCount, int MaxAmmoCount, float PricePerRound, int FillAmmoCost, out int AutoFillCost)
function SetFillInfo(out GFxObject FillSlot, int AmmoCount, int MaxAmmoCount, float PricePerRound, int FillAmmoCost, out int AutoFillCost, bool bCanBuyAmmo)
{
FillSlot.SetString("label", FillString);
FillSlot.SetInt("buttonValue", FillAmmoCost);
FillSlot.SetInt("buttonState", GetButtonState( PricePerRound, AmmoCount, MaxAmmoCount ));
FillSlot.SetInt("buttonState", GetButtonState( PricePerRound, AmmoCount, MaxAmmoCount, bCanBuyAmmo ));
AutoFillCost += FillAmmoCost;
}
@ -265,15 +265,15 @@ function SetAutoFill(int AutoFillCost)
AutoFillObject.SetInt("buttonValue", AutoFillCost);
// Only disable this button if we have all the ammo
AutoFillObject.SetInt("buttonState", GetButtonState(0, 0, AutoFillCost));
AutoFillObject.SetInt("buttonState", GetButtonState(0, 0, AutoFillCost, true));
SetObject("autoFillCost", AutoFillObject);
}
// Change the look of the button dependant on if we can afford it, or are at max capacity
function int GetButtonState( float Price, int SpareAmmoCount, int MaxSpareAmmoCount )
function int GetButtonState( float Price, int SpareAmmoCount, int MaxSpareAmmoCount, bool bCanBuyAmmo )
{
if ( SpareAmmoCount >= MaxSpareAmmoCount )
if ( SpareAmmoCount >= MaxSpareAmmoCount || !bCanBuyAmmo)
{
return BS_MaxCapacity;
}

View File

@ -16,6 +16,8 @@ var localized string PartyLeaderSearchingForMatchString, PartyLeaderIsUpdatingMa
var localized string PartHostLeftString, PartyLeaderChangedString;
var localized string DownLoadingString, RemainingString;
var localized string MatchOverString;//text used to tell the player the match is over
var localized string PauseGameString;
var localized string ResumeGameString;
var OnlineSubsystem OnlineSub;
var TWOnlineLobby OnlineLobby;
@ -35,6 +37,7 @@ var GFxObject CreatePartyButton;
var GFxObject SquadHeader;
var GFxObject Notification;
var GFxObject MatchStartContainer;
var GFxObject EndlessPauseButton;
var int PlayerSlots;
@ -80,6 +83,8 @@ function InitializeWidget()
ReadyButton = GetObject("readyButton");
SquadHeader = GetObject("squadHeader");
MatchStartContainer = GetObject("matchStartContainer");
EndlessPauseButton = GetObject("endlessPauseButton");
InitNotificationUI();
LocalizeText();
@ -87,11 +92,15 @@ function InitializeWidget()
UpdateInLobby(Manager.IsInLobby());
RefreshParty();
SetBool("matchOver", false);
SetBool("endlessPauseButtonVisible", false);
}
function LocalizeText()
{
local GFxObject TextObject;
local KFGameReplicationInfo KFGRI;
local WorldInfo TempWorldInfo;
TextObject = CreateObject("Object");
@ -104,6 +113,16 @@ function LocalizeText()
TextObject.SetString("backPromptString", Localize("KFGFxWidget_ButtonPrompt", "CancelString", "KFGame"));
TextObject.SetString("matchOver", MatchOverString);
TempWorldInfo = class'WorldInfo'.static.GetWorldInfo();
if ( TempWorldInfo != none && TempWorldInfo.GRI != none )
{
KFGRI = KFGameReplicationInfo(TempWorldInfo.GRI);
if ( KFGRI != none )
{
SetString("endlessPauseString", KFGRI.bIsEndlessPaused ? ResumeGameString : PauseGameString);
}
}
SetObject("localizedText", TextObject);
}
@ -171,7 +190,6 @@ function CreatePlayerOptions(UniqueNetId PlayerID, int SlotIndex)
}
}
DataProvider = CreateArray();
OptionIndex=0;
DataProvider.SetInt("index", SlotIndex);

View File

@ -13,8 +13,11 @@ class KFGFxWidget_KickVote extends GFxObject;
var localized string VoteKickString;
var localized string VoteSkipTraderString;
var localized string VoteSkipTraderDetailString;
var localized string VotePauseGameString;
var localized string VotePauseGameDetailString;
var localized string VoteResumeGameString;
var localized string VoteResumeGameDetailString;
var bool bIsVoteActive;
var bool bIsSkipTraderVoteActive;
var bool bShowChoicesOnTimerUpdate;
var const string GBA_VoteYes;
@ -22,12 +25,23 @@ var const string GBA_VoteNo;
var GFxObject KickVoteData;
enum EVoteType
{
VT_NONE,
VT_KICK,
VT_SKIP_TRADER,
VT_PAUSE_GAME,
VT_RESUME_GAME
};
var EVoteType CurrentActiveVote;
function InitializeHUD()
{
//LocalizeText();
}
function LocalizeText(bool bIsSkipTraderVote)
function LocalizeText(EVoteType Type)
{
local GFxObject TempObject;
local KFPlayerInput KFInput;
@ -46,14 +60,7 @@ function LocalizeText(bool bIsSkipTraderVote)
TempObject.SetString("yes", Class'KFCommon_LocalizedStrings'.default.YesString);
TempObject.SetString("no", Class'KFCommon_LocalizedStrings'.default.NoString);
if(bIsSkipTraderVote)
{
TempObject.SetString("voteKick", VoteSkipTraderString);
}
else
{
TempObject.SetString("voteKick", VoteKickString);
}
TempObject.SetString("voteKick", GetVoteString(Type));
SetObject("localizedText", TempObject);
}
@ -65,19 +72,20 @@ function ResetVote()
ActionScriptVoid("onNoReleased");
}
function ShowVote(PlayerReplicationInfo PRI, byte VoteDuration, bool bShowChoices, bool bIsSkipTraderVote)
function ShowVote(PlayerReplicationInfo PRI, byte VoteDuration, bool bShowChoices, EVoteType Type)
{
if(PRI != none)
{
LocalizeText(bIsSkipTraderVote); //Added this here if the user changes their keybind, it will update
LocalizeText(Type); //Added this here if the user changes their keybind, it will update
bIsVoteActive = true;
bIsSkipTraderVoteActive = bIsSkipTraderVote;
CurrentActiveVote = Type;
SendVoteToAS3(PRI.PlayerName, VoteDuration, bShowChoices);
}
else
{
bIsVoteActive = false;
bIsSkipTraderVoteActive = false;
CurrentActiveVote = VT_NONE;
}
}
@ -88,14 +96,7 @@ function SendVoteToAS3(string PlayerName, byte VoteDuration, bool bShowChoices)
KickVoteData = CreateObject("Object");
}
if(bIsSkipTraderVoteActive)
{
KickVoteData.SetString("playerName", PlayerName@VoteSkipTraderDetailString);
}
else
{
KickVoteData.SetString("playerName", PlayerName);
}
KickVoteData.SetString("playerName", GetVotePlayerDataString(PlayerName, CurrentActiveVote));
KickVoteData.SetInt("voteDuration", VoteDuration);
KickVoteData.SetBool("bShowChoices", bShowChoices);
bShowChoicesOnTimerUpdate = bShowChoices;
@ -121,7 +122,7 @@ function UpdateUsingGamepad(bool bIsUsingGamepad)
if(!bIsUsingGamepad)
{
//the gamepad text will show on the input so we need to change it back to keyboard, it is simpler to just relocalize
LocalizeText(bIsSkipTraderVoteActive);
LocalizeText(CurrentActiveVote);
}
}
@ -168,9 +169,36 @@ function OnNoReleased()
}
}
function string GetVoteString(EVoteType Type)
{
switch(Type)
{
case VT_KICK: return VoteKickString;
case VT_SKIP_TRADER: return VoteSkipTraderString;
case VT_PAUSE_GAME: return VotePauseGameString;
case VT_RESUME_GAME: return VoteResumeGameString;
case VT_NONE: `Log("None vote type"); return VoteKickString;
default: `Log("Unkown vote type"); return VoteKickString;
}
}
function string GetVotePlayerDataString(string PlayerName, EVoteType Type)
{
switch(Type)
{
case VT_SKIP_TRADER: return PlayerName@VoteSkipTraderDetailString;
case VT_PAUSE_GAME: return PlayerName@VotePauseGameDetailString;
case VT_RESUME_GAME: return PlayerName@VoteResumeGameDetailString;
case VT_KICK: return PlayerName;
case VT_NONE: `Log("None vote type"); return PlayerName;
default: `Log("Unkown vote type"); return PlayerName;
}
}
DefaultProperties
{
//defaults
GBA_VoteYes="GBA_VoteYes"
GBA_VoteNo="GBA_VoteNo"
CurrentActiveVote=VT_NONE
}

View File

@ -20,7 +20,8 @@ function InitializeWidget()
super.InitializeWidget();
SetReadyButtonVisibility(true);
ReadyButton = GetObject("readyButton");
ReadyButton = GetObject("readyButton");
EndlessPauseButton = GetObject("endlessPauseButton");
MyKFPRI = KFPlayerReplicationInfo(GetPC().PlayerReplicationInfo);
@ -31,6 +32,7 @@ function InitializeWidget()
}
RefreshParty();
UpdateReadyButtonVisibility();
UpdateEndlessPauseButtonVisibility();
}
function UpdateReadyButtonText()
@ -52,6 +54,25 @@ function UpdateReadyButtonText()
}
}
function UpdateEndlessPauseButtonText()
{
local bool bIsConsole;
if (EndlessPauseButton != none)
{
bIsConsole = GetPC().WorldInfo.IsConsoleBuild();
if(bIsConsole)
{
EndlessPauseButton.SetString("label", KFGRI.bIsEndlessPaused ? (" "@default.ResumeGameString) : (" "@default.PauseGameString));
}
else
{
EndlessPauseButton.SetString("label", KFGRI.bIsEndlessPaused ? default.ResumeGameString : default.PauseGameString);
}
}
}
function UpdateReadyButtonVisibility()
{
if(KFGRI == none)
@ -107,6 +128,40 @@ function UpdateReadyButtonVisibility()
}
}
function UpdateEndlessPauseButtonVisibility()
{
if(KFGRI == none)
{
return;
}
if (MyKFPRI == none)
{
//sanity check because this is happening
MyKFPRI = KFPlayerReplicationInfo(GetPC().PlayerReplicationInfo);
}
if (GetPC().WorldInfo.NetMode != NM_Standalone && KFGRI.bMatchHasBegun && (MyKFPRI != none && MyKFPRI.bHasSpawnedIn && !KFGRI.bWaveIsActive) && !KFGRI.bMatchIsOver && KFGRI.bEndlessMode)
{
UpdateEndlessPauseButtonText();
// if (!MyKFPRI.bVotedToPauseGame)
// {
SetBool("endlessPauseButtonVisible", true);
// }
}
else
{
SetBool("endlessPauseButtonVisible", false);
}
if (EndlessPauseButton != none)
{
EndlessPauseButton.SetBool("selected", false);
}
}
/****************************************************************************
* Slot Component Updates
****************************************************************************/
@ -118,6 +173,7 @@ function OneSecondLoop()
}
RefreshParty();
UpdateReadyButtonVisibility();
UpdateEndlessPauseButtonVisibility();
}
//==============================================================

View File

@ -437,6 +437,11 @@ enum EMonsterProperties
var int SpawnedMonsterProperties[EMonsterProperties];
/**
Boss Rush
*/
var transient array< byte > BossRushEnemies;
/************************************************************************************
* @name Native
***********************************************************************************/
@ -1636,7 +1641,14 @@ function float GetGameInfoSpawnRateMod()
if (OutbreakEvent != none)
{
SpawnRateMod *= 1.f / OutbreakEvent.ActiveEvent.SpawnRateMultiplier;
if (OutbreakEvent.ActiveEvent.SpawnRateMultiplier > 0.0f)
{
SpawnRateMod *= 1.f / OutbreakEvent.ActiveEvent.SpawnRateMultiplier;
}
else
{
SpawnRateMod = 0.0f;
}
}
if (MyKFGRI != none)
@ -2901,19 +2913,29 @@ function string GetNextMap()
{
MapCycleIndex = MapCycleIndex + 1 < GameMapCycles[ActiveMapCycle].Maps.length ? (MapCycleIndex + 1) : 0;
if ((class'KFGameEngine'.static.GetWeeklyEventIndexMod() == 11 || OutbreakEvent.ActiveEvent == OutbreakEvent.SetEvents[11])
&& MyKFGRI.IsA('KFGameReplicationInfo_WeeklySurvival'))
if (MyKFGRI.IsA('KFGameReplicationInfo_WeeklySurvival'))
{
if (GameMapCycles[ActiveMapCycle].Maps[MapCycleIndex] == "KF-Biolapse" ||
GameMapCycles[ActiveMapCycle].Maps[MapCycleIndex] == "KF-Nightmare" ||
GameMapCycles[ActiveMapCycle].Maps[MapCycleIndex] == "KF-PowerCore_Holdout" ||
GameMapCycles[ActiveMapCycle].Maps[MapCycleIndex] == "KF-TheDescent" ||
GameMapCycles[ActiveMapCycle].Maps[MapCycleIndex] == "KF-KrampusLair")
if ((class'KFGameEngine'.static.GetWeeklyEventIndexMod() == 11 || OutbreakEvent.ActiveEvent == OutbreakEvent.SetEvents[11]) || // Scavenger
(class'KFGameEngine'.static.GetWeeklyEventIndexMod() == 14 || OutbreakEvent.ActiveEvent == OutbreakEvent.SetEvents[14])) // Boss Rush
{
if (GameMapCycles[ActiveMapCycle].Maps[MapCycleIndex] == "KF-Biolapse" ||
GameMapCycles[ActiveMapCycle].Maps[MapCycleIndex] == "KF-Nightmare" ||
GameMapCycles[ActiveMapCycle].Maps[MapCycleIndex] == "KF-PowerCore_Holdout" ||
GameMapCycles[ActiveMapCycle].Maps[MapCycleIndex] == "KF-TheDescent" ||
GameMapCycles[ActiveMapCycle].Maps[MapCycleIndex] == "KF-KrampusLair")
{
continue;
}
}
}
/* Temporary removal of SteamFrotress for BossRush */
if (class'KFGameEngine'.static.GetWeeklyEventIndexMod() == 14 || OutbreakEvent.ActiveEvent == OutbreakEvent.SetEvents[14] &&
GameMapCycles[ActiveMapCycle].Maps[MapCycleIndex] == "KF-SteamFortress")
{
continue;
}
/**/
}
if ( IsMapAllowedInCycle(GameMapCycles[ActiveMapCycle].Maps[MapCycleIndex]) )
{
@ -3262,6 +3284,7 @@ function TimeReservations()
if (bLogReservations)
{
`log("KFGameInfo.TimeReservations player" @ i @ class'OnlineSubsystem'.static.UniqueNetIdToString(stupid)@"="@string(PlayerReservations[i].Timer), bLogReservations);
`log("KFGameInfo.TimeReservations Timeout reservations: " $ReservationTimeout);
}
}
++i;
@ -3771,6 +3794,37 @@ function float GetTraderTime()
function SkipTrader(int TimeAfterSkipTrader);
function ResumeEndlessGame()
{
local KFPawn_Human KFPH;
foreach WorldInfo.AllPawns( class'KFPawn_Human', KFPH )
{
if( KFPH.GetTeamNum() != 0 )
{
KFPH.bCanPickupInventory = true;
}
}
WorldInfo.bPlayersOnly = false;
WorldInfo.bPlayersOnlyPending = false;
}
function PauseEndlessGame()
{
local KFPawn_Human KFPH;
foreach WorldInfo.AllPawns( class'KFPawn_Human', KFPH )
{
if( KFPH.GetTeamNum() != 0 )
{
KFPH.bCanPickupInventory = false;
}
}
// Pause game but allow players to move around.
WorldInfo.bPlayersOnlyPending = true;
}
function bool ShouldOverrideDoshOnKill(class<KFPawn_Monster> KilledPawn, out float DoshGiven)
{
return false;

View File

@ -59,6 +59,8 @@ var class<KFTraderVoiceGroupBase> TraderVoiceGroupClass;
var repnotify bool bTraderIsOpen;
var repnotify bool bWaveIsActive;
var repnotify bool bWaveStarted;
var bool bIsEndlessPaused;
/** Replicates at beginning and end of waves to change track / track type */
var repnotify byte MusicTrackRepCount;
@ -68,6 +70,9 @@ var repnotify byte RepKickNoVotes;
var repnotify byte RepSkipTraderYesVotes;
var repnotify byte RepSkipTraderNoVotes;
var repnotify byte RepPauseGameYesVotes;
var repnotify byte RepPauseGameNoVotes;
/** whether the current game can use stats */
var private const bool bIsUnrankedGame;
@ -348,6 +353,11 @@ var repnotify KFMusicTrackInfo ReplicatedMusicTrackInfo;
************************************/
var transient bool bIsBrokenTrader;
/************************************
* Weekly Events
************************************/
var int CurrentWeeklyIndex;
/************************************
* Steam heartbeat
************************************/
@ -381,7 +391,7 @@ replication
if ( bNetDirty )
TraderVolume, TraderVolumeCheckType, bTraderIsOpen, NextTrader, WaveNum, bWaveIsEndless, AIRemaining, WaveTotalAICount, bWaveIsActive, MaxHumanCount, bGlobalDamage,
CurrentObjective, PreviousObjective, PreviousObjectiveResult, PreviousObjectiveXPResult, PreviousObjectiveVoshResult, MusicIntensity, ReplicatedMusicTrackInfo, MusicTrackRepCount,
bIsUnrankedGame, GameSharedUnlocks, bHidePawnIcons, ConsoleGameSessionGuid, GameDifficulty, GameDifficultyModifier, BossIndex, bWaveStarted, NextObjective, bIsBrokenTrader, bIsWeeklyMode; //@HSL - JRO - 3/21/2016 - PS4 Sessions
bIsUnrankedGame, GameSharedUnlocks, bHidePawnIcons, ConsoleGameSessionGuid, GameDifficulty, GameDifficultyModifier, BossIndex, bWaveStarted, NextObjective, bIsBrokenTrader, bIsWeeklyMode, CurrentWeeklyIndex, bIsEndlessPaused; //@HSL - JRO - 3/21/2016 - PS4 Sessions
if ( bNetInitial )
GameLength, WaveMax, bCustom, bVersusGame, TraderItems, GameAmmoCostScale, bAllowGrenadePurchase, MaxPerkLevel, bTradersEnabled;
if ( bNetInitial || bNetDirty )
@ -393,6 +403,8 @@ replication
RepKickNoVotes, RepKickYesVotes;
if( bNetDirty && VoteCollector != none && VoteCollector.bIsSkipTraderVoteInProgress)
RepSkipTraderNoVotes, RepSkipTraderYesVotes;
if( bNetDirty && VoteCollector != none && VoteCollector.bIsPauseGameVoteInProgress)
RepPauseGameNoVotes, RepPauseGameYesVotes;
// !SHIPPING_PC_GAME && !FINAL_RELEASE in C++
if ( bDebugSpawnManager && bNetDirty )
@ -475,6 +487,10 @@ simulated event ReplicatedEvent(name VarName)
{
VoteCollector.UnPackSkipTraderVotes();
}
else if ( VarName == nameof(RepPauseGameYesVotes) || VarName == nameof(RepPauseGameNoVotes) )
{
VoteCollector.UnPackPauseGameVotes();
}
else if( VarName == 'ServerAdInfo')
{
ShowPreGameServerWelcomeScreen();
@ -1129,7 +1145,12 @@ simulated function bool IsFinalWave()
simulated function bool IsBossWave()
{
return WaveNum == WaveMax || (bIsWeeklyMode && class'KFGameEngine'.static.GetWeeklyEventIndexMod() == 14);
if (bIsWeeklyMode && CurrentWeeklyIndex == 14)
{
return true;
}
return WaveNum == WaveMax;
}
simulated function bool IsInfiniteWave()
@ -1825,6 +1846,22 @@ reliable server function RecieveVoteSkipTrader(PlayerReplicationInfo PRI, bool b
}
}
function ServerStartVotePauseGame(PlayerReplicationInfo PRI)
{
if(VoteCollector != none)
{
VoteCollector.ServerStartVotePauseGame(PRI);
}
}
reliable server function ReceiveVotePauseGame(PlayerReplicationInfo PRI, bool bPauseGame)
{
if(VoteCollector != none)
{
VoteCollector.ReceiveVotePauseGame(PRI, bPauseGame);
}
}
reliable server function ReceiveVoteMap(PlayerReplicationInfo PRI, int MapIndex)
{
if(VoteCollector != none)
@ -1878,6 +1915,9 @@ function ChooseNextObjective(int NextWaveNum)
NextObjective = none;
NextObjectiveIsEndless = false;
if (bIsWeeklyMode && KFGameInfo(WorldInfo.Game).OutbreakEvent.ActiveEvent.bBossRushMode)
return;
KFMI = KFMapInfo(WorldInfo.GetMapInfo());
if (KFMI != none && NextWaveNum != WaveMax)
{
@ -2202,6 +2242,12 @@ simulated function NotifyBrokenTrader()
bNetDirty = true;
}
simulated function NotifyWeeklyEventIndex(int EventIndex)
{
CurrentWeeklyIndex = EventIndex;
bNetDirty = true;
}
defaultproperties
{
TraderItemsPath="GP_Trader_ARCH.DefaultTraderItems"

View File

@ -208,7 +208,7 @@ static function class<KFGFxSpecialeventObjectivesContainer> GetSpecialEventClass
case SEI_Fall:
return class'KFGFxSpecialEventObjectivesContainer_Fall2021';
case SEI_Winter:
return class'KFGFXSpecialEventObjectivesContainer_Xmas2020';
return class'KFGFXSpecialEventObjectivesContainer_Xmas2021';
}
return class'KFGFxSpecialEventObjectivesContainer';

View File

@ -211,6 +211,9 @@ var PlayerReplicationInfo KickVotePRI;
//The target PRI for current skip trader vote
var PlayerReplicationInfo SkipTraderVotePRI;
// The target PRI for current pause vote
var PlayerReplicationInfo PauseGameVotePRI;
/** Cached version of the TWOnlineLobby */
var TWOnlineLobby OnlineLobby;
var UniqueNetId CurrentInviteLobbyId;
@ -239,6 +242,9 @@ var const int MouseInputChangedThreshold;
var bool bKickVotePopupActive;
/** TRUE if the skip trader vote popup is open */
var bool bSkipTraderVotePopupActive;
/** TRUE if the pause game vote popup is open */
var bool bPauseGameVotePopupActive;
var bool bUsingGamepad; // True if we are using a gamepad, otherwise we are using mouse and keyboard
var bool bAfterLobby; // Set to true once we have readied up
var bool bMenusOpen; // true if we're using menus, otherwise we're using the HUD
@ -1144,6 +1150,11 @@ function OpenMenu( byte NewMenuIndex, optional bool bShowWidgets = true )
ShowSkipTraderVote(SkipTraderVotePRI);
}
if(PauseGameVotePRI != none && NewMenuIndex != UI_Trader)
{
ShowPauseGameVote(PauseGameVotePRI);
}
// Close our last menu if we are already in a menu
if (bMenusOpen && NewMenuIndex != CurrentMenuIndex && CurrentMenu != none)
{
@ -2076,6 +2087,70 @@ function CastNoVoteSkipTrader()
}
}
/*********************************************************************************************
* @name Pause Game
********************************************************************************************* */
function ShowPauseGameVote(PlayerReplicationInfo PRI)
{
local KFGameReplicationInfo KFGRI;
KFGRI = KFGameReplicationInfo(GetPC().WorldInfo.GRI);
PauseGameVotePRI = PRI;
if(bMenusOpen && CurrentMenu != TraderMenu)
{
bPauseGameVotePopupActive = true;
DelayedOpenPopup(EConfirmation, EDPPID_Misc, (KFGRI != none && KFGRI.bIsEndlessPaused) ? Class'KFGFxWidget_KickVote'.default.VoteResumeGameString : Class'KFGFxWidget_KickVote'.default.VotePauseGameString,
PauseGameVotePRI.PlayerName@Class'KFGFxWidget_KickVote'.default.VotePauseGameDetailString,
Class'KFCommon_LocalizedStrings'.default.YesString, Class'KFCommon_LocalizedStrings'.default.NoString, CastYesVotePauseGame, CastNoVotePauseGame);
}
}
simulated function HidePauseGameVote()
{
if( bSkipTraderVotePopupActive )
{
bSkipTraderVotePopupActive = false;
UnloadCurrentPopup();
}
SkipTraderVotePRI = none;
}
function CastYesVotePauseGame()
{
local KFplayerReplicationInfo KFPRI;
local KFPlayerController KFPC;
KFPC = KFPlayerController(GetPC());
if(KFPC != none)
{
KFPRI = KFplayerReplicationInfo(KFPC.PlayerReplicationInfo);
if(KFPRI != none)
{
KFPRI.CastPauseGameVote(KFPRI, true);
}
}
}
function CastNoVotePauseGame()
{
local KFplayerReplicationInfo KFPRI;
local KFPlayerController KFPC;
KFPC = KFPlayerController(GetPC());
if(KFPC != none)
{
KFPRI = KFplayerReplicationInfo(KFPC.PlayerReplicationInfo);
if(KFPRI != none)
{
KFPRI.CastPauseGameVote(KFPRI, false);
}
}
}
/*********************************************************************************************
* @name Kick Vote
********************************************************************************************* */

View File

@ -39,11 +39,23 @@ function InitOnlineLobby()
function OnR3Pressed()
{
local KFPlayerController KFPC;
local KFPlayerReplicationInfo KFPRI;
local KFGameReplicationInfo KFGRI;
KFPC = KFPlayerController(GetPC());
if(KFPC != none)
{
KFPRI = KFPlayerReplicationInfo( GetPC().PlayerReplicationInfo );
if (KFPRI != none)
{
KFGRI = KFGameReplicationInfo(KFPRI.WorldInfo.GRI);
if(KFGRI != none || KFGRI.bEndlessMode)
{
KFPC.RequestPauseGame();
return;
}
}
KFPC.RequestSwitchTeam();
}
}
@ -191,6 +203,21 @@ function Callback_RequestTeamSwitch()
}
}
function Callback_RequestEndlessPause()
{
local KFPlayerController KFPC;
local KFPlayerReplicationInfo KFPRI;
KFPC = KFPlayerController(GetPC());
KFPRI = KFPlayerReplicationInfo( KFPC.PlayerReplicationInfo );
if (KFPC != none && KFPRI != none)
{
KFPRI.RequestPauseGame(KFPRI);
KFPC.MyGFxManager.CloseMenus();
}
}
function Callback_ReadyClicked( bool bReady )
{
local KFPlayerReplicationInfo KFPRI;

View File

@ -98,6 +98,8 @@ struct native STraderItem
var int ItemID; //used since the list will be sorted.
var bool bCanBuyAmmo;
StructDefaultProperties
{
AltTraderFilter=FT_None

View File

@ -59,6 +59,7 @@ var bool bAutoswitchWeapon;
var const float StartedWithWeaponPriceModifier; // The selling price reduction for a weapon that we were given at the start of the game
var const float SellPriceModifier; // Multiplied by the original price to get the sell cost
var const float DoshinegunSellModifier;
/** Cost scale for weapons not on the active perk */
var float OffPerkCostScale;
@ -2446,12 +2447,15 @@ simulated function int GetAdjustedSellPriceFor(
local KFWeapon OwnedWeapon;
local TransactionItem TransactionWeapon;
local int OwnedItemIdx, ItemUpgradeLevel;
local float OverridenSellPriceModifier;
if (OwnedItem.WeaponDef == class'KFWeapDef_9mm')
{
return 0;
}
OverridenSellPriceModifier = OwnedItem.WeaponDef == class'KFWeapDef_Doshinegun' ? DoshinegunSellModifier : SellPriceModifier;
GetWeaponFromClass(OwnedWeapon, OwnedItem.ClassName);
if( OwnedWeapon != none && OwnedWeapon.bGivenAtStart )
{
@ -2459,7 +2463,7 @@ simulated function int GetAdjustedSellPriceFor(
}
else
{
AdjustedSellPrice = OwnedItem.WeaponDef.default.BuyPrice * SellPriceModifier;
AdjustedSellPrice = OwnedItem.WeaponDef.default.BuyPrice * OverridenSellPriceModifier;
}
OwnedItemIdx = TraderOwnedItems.Find('DefaultItem', OwnedItem);
@ -2632,4 +2636,5 @@ defaultproperties
SwitchFireModeEvent=AkEvent'WW_UI_PlayerCharacter.Play_WEP_ModeSwitch'
bLogInventory=false
DoshinegunSellModifier=0.167f
}

View File

@ -52,6 +52,29 @@ var localized string SkipTraderThisUserAlreadyStartedAVoteString;
var localized string SkipTraderVoteYesReceivedString;
var localized string SkipTraderVoteNoReceivedString;
var localized string PauseVoteStartedString;
var localized string PauseVoteInProgressString;
var localized string PauseVoteYesReceivedString;
var localized string PauseVoteNoReceivedString;
var localized string PauseVoteNoEnoughTimeString;
var localized string PauseVoteNoSpectatorsString;
var localized string PauseVoteTimeString;
var localized string PauseVoteSuccessString;
var localized string PauseVoteFailedString;
var localized string PauseVoteWaveActiveString;
var localized string PauseVoteWrongModeString;
var localized string ResumeVoteStartedString;
var localized string ResumeVoteInProgressString;
var localized string ResumeVoteYesReceivedString;
var localized string ResumeVoteNoReceivedString;
var localized string ResumeVoteNoEnoughTimeString;
var localized string ResumeVoteNoSpectatorsString;
var localized string ResumeVoteTimeString;
var localized string ResumeVoteSuccessString;
var localized string ResumeVoteFailedString;
var localized string ResumeVoteWaveActiveString;
enum ELocalMessageType
{
LMT_AdminLogin,
@ -84,7 +107,28 @@ enum ELocalMessageType
LMT_SkipTraderVoteYesReceived,
LMT_SkipTraderVoteNoReceived,
LMT_SkipTraderNoEnoughTime,
LMT_SkipTraderThisUserAlreadyStartedAVote
LMT_SkipTraderThisUserAlreadyStartedAVote,
LMT_PauseVoteStarted,
LMT_PauseVoteInProgress,
LMT_PauseVoteYesReceived,
LMT_PauseVoteNoReceived,
LMT_PauseVoteNoEnoughTime,
LMT_PauseVoteNoSpectators,
LMT_PauseVoteTime,
LMT_PauseVoteSuccess,
LMT_PauseVoteFailed,
LMT_PauseVoteWaveActive,
LMT_PauseVoteWrongMode,
LMT_ResumeVoteStarted,
LMT_ResumeVoteInProgress,
LMT_ResumeVoteYesReceived,
LMT_ResumeVoteNoReceived,
LMT_ResumeVoteNoEnoughTime,
LMT_ResumeVoteNoSpectators,
LMT_ResumeVoteTime,
LMT_ResumeVoteSuccess,
LMT_ResumeVoteFailed,
LMT_ResumeVoteWaveActive,
};
/** Message area on HUD (index into UTHUD.MessageOffset[]) */
@ -164,6 +208,69 @@ static function string GetString(
switch (Switch)
{
case LMT_ResumeVoteStarted:
return RelatedPRI_1.PlayerName@Default.ResumeVoteStartedString;
case LMT_ResumeVoteInProgress:
return default.ResumeVoteInProgressString;
case LMT_ResumeVoteYesReceived:
return default.ResumeVoteYesReceivedString;
case LMT_ResumeVoteNoReceived:
return default.ResumeVoteNoReceivedString;
case LMT_ResumeVoteNoEnoughTime:
return default.ResumeVoteNoEnoughTimeString;
case LMT_ResumeVoteNoSpectators:
return default.ResumeVoteNoSpectatorsString;
case LMT_ResumeVoteTime:
return default.ResumeVoteTimeString;
case LMT_ResumeVoteSuccess:
return default.ResumeVoteSuccessString;
case LMT_ResumeVoteFailed:
return default.ResumeVoteFailedString;
case LMT_ResumeVoteWaveActive:
return default.ResumeVoteWaveActiveString;
case LMT_PauseVoteStarted:
return RelatedPRI_1.PlayerName@Default.PauseVoteStartedString;
case LMT_PauseVoteInProgress:
return default.PauseVoteInProgressString;
case LMT_PauseVoteYesReceived:
return default.PauseVoteYesReceivedString;
case LMT_PauseVoteNoReceived:
return default.PauseVoteNoReceivedString;
case LMT_PauseVoteNoEnoughTime:
return default.PauseVoteNoEnoughTimeString;
case LMT_PauseVoteNoSpectators:
return default.PauseVoteNoSpectatorsString;
case LMT_PauseVoteTime:
return default.PauseVoteTimeString;
case LMT_PauseVoteSuccess:
return default.PauseVoteSuccessString;
case LMT_PauseVoteFailed:
return default.PauseVoteFailedString;
case LMT_PauseVoteWaveActive:
return default.PauseVoteWaveActiveString;
case LMT_PauseVoteWrongMode:
return default.PauseVoteWrongModeString;
case LMT_OtherVoteInProgress:
return default.OtherVoteInProgressString;

View File

@ -69,6 +69,7 @@ defaultproperties
ColumnIds.Add(STATID_ACHIEVE_Dystopia2029Collectibles)
ColumnIds.Add(STATID_ACHIEVE_MoonbaseCollectibles)
ColumnIds.Add(STATID_ACHIEVE_NetherholdCollectibles)
ColumnIds.Add(STATID_ACHIEVE_CarillonHamletCollectibles)
ColumnMappings.Add((Id=STATID_ACHIEVE_MrPerky5, Name="AchievementMrPerky5"))
ColumnMappings.Add((Id=STATID_ACHIEVE_MrPerky10, Name = "AchievementMrPerky10"))
@ -126,4 +127,5 @@ defaultproperties
ColumnMappings.Add((Id=STATID_ACHIEVE_Dystopia2029Collectibles,NAme="AchievementCollectDystopia2029"))
ColumnMappings.Add((Id=STATID_ACHIEVE_MoonbaseCollectibles,NAme="AchievementCollectMoonbase"))
ColumnMappings.Add((Id=STATID_ACHIEVE_NetherholdCollectibles,NAme="AchievementCollectNetherhold"))
ColumnMappings.Add((Id=STATID_ACHIEVE_CarillonHamletCollectibles,NAme="AchievementCollectCarillonHamlet"))
}

View File

@ -437,6 +437,10 @@ const KFACHID_NetherholdHard = 286;
const KFACHID_NetherholdHellOnEarth = 287;
const KFACHID_NetherholdCollectibles = 288;
const KFACHID_CarillonHamletHard = 289;
const KFACHID_CarillonHamletHellOnEarth = 290;
const KFACHID_CarillonHamletCollectibles = 291;
/* __TW_ANALYTICS_ */
var int PerRoundWeldXP;
var int PerRoundHealXP;
@ -1165,6 +1169,11 @@ private event AddNonZedKill(class<Pawn> KilledClass, byte Difficulty)
}
}
private event AddToWeaponPurchased( class<KFWeaponDefinition> WeaponDef, int Price )
{
SeasonalEventStats_OnWeaponPurchased(WeaponDef, Price);
}
private native function AddToKillObjectives(class<KFPawn_Monster> ZedClass);
private native function AddToVersusKillObjectives(class<Pawn> KillerClass);
@ -1871,6 +1880,14 @@ final simulated function SeasonalEventStats_OnTryCompleteObjective(int Objective
}
}
final simulated function SeasonalEventStats_OnWeaponPurchased(class<KFWeaponDefinition> WeaponDef, int Price)
{
if (SeasonalEventIsValid())
{
SeasonalEvent.OnWeaponPurchased(WeaponDef, Price);
}
}
/*********************************************************************************************
* @name Dailies and daily-specific tracking
********************************************************************************************* */
@ -2022,7 +2039,8 @@ defaultproperties
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_AssaultRifle_Thompson, KFDT_Ballistic_Thompson,KFDT_Bludgeon_Thompson),CompletionAmount=7000))
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_HRG_Nailgun, KFDT_Ballistic_HRGNailgun, KFDT_Bludgeon_HRGNailgun),CompletionAmount=10000)) //7000
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_SMG_P90, KFDT_Ballistic_P90,KFDT_Bludgeon_P90),CompletionAmount=10000))
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_SMG_Kriss, KFDT_Ballistic_Kriss,KFDT_Bludgeon_Kriss),CompletionAmount=10000))
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_HRG_Stunner, KFDT_Ballistic_HRG_Stunner,KFDT_Ballistic_HRG_Stunner_Alt,KFDT_Explosive_HRG_Stunner,KFDT_Bludgeon_HRG_Stunner),CompletionAmount=10000))
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_SMG_Kriss, KFDT_Ballistic_Kriss,KFDT_Bludgeon_Kriss),CompletionAmount=10000))
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_SMG_HK_UMP, KFDT_Ballistic_HK_UMP,KFDT_Bludgeon_HK_UMP),CompletionAmount=10000))
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_HRG_BarrierRifle, KFDT_Ballistic_HRG_BarrierRifle,KFDT_Bludgeon_HRG_BarrierRifle),CompletionAmount=10000))
@ -2256,6 +2274,9 @@ defaultproperties
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-NETHERHOLD),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-NETHERHOLD),CompletionAmount=2))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-NETHERHOLD),CompletionAmount=3))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-CARILLONHAMLET),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-CARILLONHAMLET),CompletionAmount=2))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-CARILLONHAMLET),CompletionAmount=3))
//Versus Damage
// Per design doc that I have right now, these are x class damage y players, not damage y amount

View File

@ -71,4 +71,5 @@ defaultproperties
Properties.Add((PropertyId = STATID_ACHIEVE_Dystopia2029Collectibles, Data = (Type = SDT_Int32,Value1 = 0)))
Properties.Add((PropertyId = STATID_ACHIEVE_MoonbaseCollectibles, Data = (Type = SDT_Int32, Value1 = 0)))
Properties.Add((PropertyId = STATID_ACHIEVE_NetherholdCollectibles, Data = (Type = SDT_Int32, Value1 = 0)))
Properties.Add((PropertyId = STATID_ACHIEVE_CarillonHamletCollectibles, Data = (Type = SDT_Int32, Value1 = 0)))
}

View File

@ -93,6 +93,12 @@ struct StatAdjustments
/** Speed modifier */
var() float InitialGroundSpeedModifierScale;
/** Override HitZones Information */
var() array<HitZoneInfo> HitZonesOverride;
/** WeakPoints to show special VFX*/
var() array<WeakPoint> WeakPoints;
structdefaultproperties
{
HealthScale = 1.f;
@ -115,6 +121,25 @@ struct StatAdjustments
}
};
struct BossRushOverridesPerWave
{
var() array <StatAdjustments> ZedsToAdjust;
var() array <SpawnReplacement> SpawnReplacementList;
var() float DoshOnKillGlobalModifier;
var() int ExtraDoshGrantedonWaveWon;
structdefaultproperties
{
DoshOnKillGlobalModifier=1.0f
ExtraDoshGrantedonWaveWon=0.0f
}
};
struct BossRushOverrides
{
var() array <BossRushOverridesPerWave> PerWaves;
};
/** Individual property overrides that drive other behavior to allow for
* a large amount of variety in our weekly event mode.
*/
@ -381,6 +406,14 @@ struct WeeklyOverrides
/** If WWL music should be forced */
var() bool bForceWWLMusic;
/** Boss classes availabled for boss rush mode */
var() bool bBossRushMode;
var() BossRushOverrides BossRushOverrideParams;
/** Ignores damage caused by headshots. */
var() bool bInvulnerableHeads;
structdefaultproperties
{
GameLength = GL_Short
@ -437,6 +470,8 @@ struct WeeklyOverrides
JumpZ = -1.f
DroppedItemLifespan=-1.0f
bForceWWLMusic = false;
bBossRushMode = false;
bInvulnerableHeads = false;
}
};
@ -636,9 +671,8 @@ function ModifyGroundSpeed(KFPawn PlayerPawn, out float GroundSpeed)
//In our case, this should be better explained as a GameInfo-facing AdjustDamage. Things are being done here that would be incredibly invasive in other classes given the size of our code base.
function ReduceDamage(out int Damage, Pawn Injured, Controller InstigatedBy, class<DamageType> DamageType, TraceHitInfo HitInfo)
{
local int HitZoneIdx;
local int HitZoneIdx, WaveNum;
local KFPawn InstigatorPawn;
local StatAdjustments ToAdjust;
//Some events can be headshot only. Do this only if the incoming damage is against a monster-derived class
// and it's one of our custom damage types. Keeps things like crush damage from being scaled to 0.
@ -650,6 +684,15 @@ function ReduceDamage(out int Damage, Pawn Injured, Controller InstigatedBy, cla
Damage = 0;
}
}
else if (ActiveEvent.bInvulnerableHeads && KFPawn_Monster(Injured) != none && ClassIsChildOf(DamageType, class'KFDamageType') )
{
HitZoneIdx = KFPawn_Monster(Injured).HitZones.Find('ZoneName', HitInfo.BoneName);
// Apply damage to head armor but not head.
if (HitZoneIdx == HZI_Head && !bool(KFPawn_Monster(Injured).ArmorZoneStatus & 1))
{
Damage = 0;
}
}
if (InstigatedBy != none)
{
@ -665,7 +708,25 @@ function ReduceDamage(out int Damage, Pawn Injured, Controller InstigatedBy, cla
}
}
foreach ActiveEvent.ZedsToAdjust(ToAdjust)
if (!ActiveEvent.bBossRushMode)
{
AdjustDamageReduction(Damage, Injured, InstigatedBy, InstigatorPawn, ActiveEvent.ZedsToAdjust);
}
else
{
WaveNum = Outer.MyKFGRI.WaveNum - 1;
if ( WaveNum < ActiveEvent.BossRushOverrideParams.PerWaves.length )
{
AdjustDamageReduction(Damage, Injured, InstigatedBy, InstigatorPawn, ActiveEvent.BossRushOverrideParams.PerWaves[WaveNum].ZedsToAdjust);
}
}
}
function AdjustDamageReduction(out int Damage, Pawn Injured, Controller InstigatedBy, KFPawn InstigatorPawn, array <StatAdjustments> Adjustments)
{
local StatAdjustments ToAdjust;
foreach Adjustments(ToAdjust)
{
//Injured zed reduction
if (Injured.class == ToAdjust.ClassToAdjust)
@ -772,7 +833,7 @@ function AdjustPawnScale(Pawn Pawn)
function AdjustMonsterDefaults(out KFPawn_Monster P)
{
local StatAdjustments ToAdjust;
local int WaveNum;
if (P == none)
{
@ -796,7 +857,29 @@ function AdjustMonsterDefaults(out KFPawn_Monster P)
}
//Per class overrides
foreach ActiveEvent.ZedsToAdjust(ToAdjust)
if (!ActiveEvent.bBossRushMode)
{
AdjustDefaults(P, ActiveEvent.ZedsToAdjust);
}
else
{
WaveNum = Outer.MyKFGRI.WaveNum - 1;
if ( WaveNum < ActiveEvent.BossRushOverrideParams.PerWaves.length )
{
AdjustDefaults(P, ActiveEvent.BossRushOverrideParams.PerWaves[WaveNum].ZedsToAdjust);
}
}
}
function AdjustDefaults(out KFPawn_Monster P, array <StatAdjustments> Adjustments)
{
local StatAdjustments ToAdjust;
local HitZoneInfo OverrideHitZone;
local array<WeakPoint> OverridenBones;
local WeakPoint WeakPoint;
local int i;
foreach Adjustments(ToAdjust)
{
if (P.class == ToAdjust.ClassToAdjust)
{
@ -833,6 +916,38 @@ function AdjustMonsterDefaults(out KFPawn_Monster P)
{
SpawnManager.SummonBossMinions(ToAdjust.AdditionalSubSpawns.Squads, Lerp(ToAdjust.AdditionalSubSpawnCount.X, ToAdjust.AdditionalSubSpawnCount.Y, FMax(NumPlayers, 1) / float(MaxPlayers)));
}
if (ToAdjust.HitZonesOverride.Length > 0)
{
foreach ToAdjust.HitZonesOverride(OverrideHitZone)
{
for (i = 0; i < P.Hitzones.Length; ++i)
{
if (OverrideHitZone.ZoneName == P.Hitzones[i].ZoneName)
{
P.Hitzones[i].DmgScale = OverrideHitZone.DmgScale;
P.Hitzones[i].GoreHealth = OverrideHitZone.GoreHealth;
P.Hitzones[i].MaxGoreHealth = OverrideHitZone.MaxGoreHealth;
break;
}
}
}
}
if (ToAdjust.WeakPoints.Length > 0)
{
OverridenBones.Length = 0;
foreach ToAdjust.WeakPoints(WeakPoint)
{
OverridenBones.AddItem(WeakPoint);
}
if (OverridenBones.Length > 0)
{
P.ServerSpawnWeakPointVFX(OverridenBones);
}
}
}
}
}
@ -896,12 +1011,32 @@ function SetWorldInfoOverrides()
}
function class<KFPawn_Monster> GetAISpawnOverrirde(EAIType AIType)
{
local int WaveNum;
if (!ActiveEvent.bBossRushMode)
{
return GetAISpawnOverrideInner(ActiveEvent.SpawnReplacementList, AIType);
}
else
{
WaveNum = MyKFGRI.WaveNum - 1;
if ( WaveNum < ActiveEvent.BossRushOverrideParams.PerWaves.length )
{
return GetAISpawnOverrideInner(ActiveEvent.BossRushOverrideParams.PerWaves[WaveNum].SpawnReplacementList, AIType);
}
}
return AIClassList[AIType];
}
function class<KFPawn_Monster> GetAISpawnOverrideInner(array <SpawnReplacement> SpawnReplacementList, EAIType AIType)
{
local SpawnReplacement Replacement;
local float RandF;
//Check if our current weekly event has any overrides available
foreach ActiveEvent.SpawnReplacementList(Replacement)
foreach SpawnReplacementList(Replacement)
{
if (Replacement.SpawnEntry == AIType)
{
@ -925,6 +1060,7 @@ function class<KFPawn_Monster> GetAISpawnOverrirde(EAIType AIType)
return AIClassList[AIType];
}
// This will convert the provided Outbreak Index into an Id that corresponds to the Weekly Event.
static function int GetOutbreakId(int SetEventsIndex);

View File

@ -2461,6 +2461,8 @@ function PostTeleport( Teleporter OutTeleporter )
/** sets whether or not the owner of this pawn can see it */
simulated function SetMeshVisibility(bool bVisible)
{
local bool bIsPlayingEmote;
// Handle the main player mesh
if (Mesh != None)
{
@ -2472,7 +2474,10 @@ simulated function SetMeshVisibility(bool bVisible)
HideHead( !bVisible );
// Handle weapon attachment
SetWeaponAttachmentVisibility(bVisible);
bIsPlayingEmote = KFPlayerController(Controller) != none && KFPlayerController(Controller).PlayerCamera.CameraStyle == 'Emote';
SetWeaponAttachmentVisibility(bVisible && !bIsPlayingEmote);
// Handle any weapons they might have
SetFirstPersonVisibility(!bVisible);
@ -3045,7 +3050,7 @@ function class<KFPerk> GetUsedWeaponPerk( Controller DamagerController, Actor Da
}
}
if( WeaponPerk == none && KFW != none && class'KFPerk'.static.IsBackupWeapon( KFW ) )
if( WeaponPerk == none && KFW != none && ( class'KFPerk'.static.IsBackupWeapon( KFW ) || class'KFPerk'.static.IsDoshinegun( KFW ) ))
{
WeaponPerk = InstigatorPerkClass;
}

View File

@ -156,6 +156,13 @@ var(Combat) float HumanBaseMeleeDamage;
/** Contains balance settings per game difficulty */
var class<KFMonsterDifficultyInfo> DifficultySettings;
struct native WeakPoint
{
var name BoneName;
var vector Offset;
};
/*********************************************************************************************
* @name Player-controlled
********************************************************************************************* */
@ -552,6 +559,15 @@ var array<KFProjectile> ParasiteSeeds;
// Max num of seeds in this character
var byte MaxNumSeeds;
/*********************************************************************************************
* @name Tiny skull Weakly vfx
********************************************************************************************* */
`define TINY_SKULL_MAX_WEAKPOINTS 10
var transient array<ParticleSystemComponent> WeakPointVFXComponents;
var repnotify WeakPoint WeakPoints_TS[`TINY_SKULL_MAX_WEAKPOINTS];
var ParticleSystem WeakPointParticleTemplate;
/*********************************************************************************************
* @name Delegates
********************************************************************************************* */
@ -566,7 +582,7 @@ replication
if (bNetDirty)
bIsHeadless, bIsPoisoned, bPlayPanicked, bPlayShambling, MaxHeadChunkGoreWhileAlive,
RepInflateMatParams, RepInflateMatParam, RepDamageInflateParam, RepBleedInflateMatParam, bDisableGoreMeshWhileAlive,
bDisableHeadless, InflateDeathGravity, InflationExplosionTimer, bUseDamageInflation, bUseExplosiveDeath;
bDisableHeadless, InflateDeathGravity, InflationExplosionTimer, bUseDamageInflation, bUseExplosiveDeath, WeakPoints_TS;
if ( bNetDirty && bCanCloak )
bIsCloakingSpottedByTeam;
if ( bNetDirty && bCanRage )
@ -668,6 +684,10 @@ simulated event ReplicatedEvent(name VarName)
case nameof(bIsEnraged):
SetEnraged(bIsEnraged);
break;
case nameof(WeakPoints_TS):
SpawnWeakpointVFX();
break;
}
super.ReplicatedEvent( VarName );
@ -1845,6 +1865,7 @@ simulated function PlayDying(class<DamageType> DamageType, vector HitLoc)
{
local KFPlayerController KFPC;
local string ClassName;
local ParticleSystemComponent WeakPointPSC;
Timer_EndRallyBoost();
@ -1879,6 +1900,16 @@ simulated function PlayDying(class<DamageType> DamageType, vector HitLoc)
UpdateBleedIncapFX();
StopExtraVFX(`NAME_NONE);
if (WeakPointVFXComponents.Length > 0)
{
foreach WeakPointVFXComponents(WeakPointPSC)
{
WeakPointPSC.DeactivateSystem();
}
WeakPointVFXComponents.Length = 0;
}
}
simulated function PlayInflationDeath()
@ -4778,6 +4809,48 @@ server reliable function AddParasiteSeed(KFProjectile Proj)
ParasiteSeeds.AddItem(Proj);
}
simulated function SpawnWeakPointVFX()
{
local int i;
local ParticleSystemComponent VFXComponent;
if (WeakPointParticleTemplate != none && WeakPointVFXComponents.Length == 0)
{
for (i = 0; i < `TINY_SKULL_MAX_WEAKPOINTS; ++i)
{
if (WeakPoints_TS[i].BoneName == '')
return;
VFXComponent = new(self) class'ParticleSystemComponent';
VFXComponent.SetTemplate( WeakPointParticleTemplate );
Mesh.AttachComponent( VFXComponent, WeakPoints_TS[i].BoneName, WeakPoints_TS[i].Offset );
VFXComponent.ActivateSystem();
WeakPointVFXComponents.AddItem(VFXComponent);
}
}
}
simulated function ServerSpawnWeakPointVFX(array<WeakPoint> WeakPoints)
{
local int i;
if (WeakPoints.Length == 0)
return;
for (i = 0; i < WeakPoints.Length; ++i)
{
WeakPoints_TS[i] = WeakPoints[i];
}
if (WorldInfo.NetMode == NM_Standalone)
{
SpawnWeakPointVFX();
}
else
{
bNetDirty = true;
}
}
/*********************************************************************************************
* @name Achievements
@ -4977,4 +5050,6 @@ DefaultProperties
MaxNumSeeds=1
ZEDCowboyHatAttachName=HEAD_Attach
WeakPointParticleTemplate=ParticleSystem'FX_Gameplay_EMIT.FX_Weak_Indicator'
}

View File

@ -494,6 +494,17 @@ static function bool IsBlastBrawlers( KFWeapon KFW )
return KFW != none && KFW.Class.Name == 'KFWeap_HRG_BlastBrawlers';
}
/**
* @brief Return if a weapon is Doshinegun
*
* @param KFW Weapon to check
* @return true if backup weapon
*/
static function bool IsDoshinegun( KFWeapon KFW )
{
return KFW != none && KFW.Class.Name == 'KFWeap_AssaultRifle_Doshinegun';
}
/*********************************************************************************************
* @name Build / Level Management - Apply and save the updated build and level
********************************************************************************************* */

View File

@ -82,7 +82,7 @@ simulated function ModifyDamageGiven( out int InDamage, optional Actor DamageCau
KFW = GetWeaponFromDamageCauser( DamageCauser );
}
if( (KFW != none && (IsWeaponOnPerk( KFW,, self.class ) || IsDual9mm(KFW) || Is9mm(KFW))) || (DamageType != none && IsDamageTypeOnPerk( DamageType )) )
if( (KFW != none && (IsWeaponOnPerk( KFW,, self.class ) || IsDual9mm(KFW) || Is9mm(KFW))) || IsDoshinegun(KFW) || (DamageType != none && IsDamageTypeOnPerk( DamageType )) )
{
TempDamage += InDamage * GetPassiveValue( WeaponDamage, CurrentLevel );
if( IsRapidFireActive() )
@ -303,8 +303,6 @@ simulated function float GetZedTimeModifier( KFWeapon W )
local name StateName;
StateName = W.GetStateName();
`Log("STATE NAME: " $StateName);
if( IsProfessionalActive() && (IsWeaponOnPerk( W,, self.class ) || IsBackupWeapon( W ) || IsDual9mm( W )) )
{
if( StateName == 'Reloading' ||
@ -318,7 +316,7 @@ simulated function float GetZedTimeModifier( KFWeapon W )
}
}
// FAMAS uses alt fire as common firing. Needs a special case
if( CouldRapidFireActive() && (Is9mm(W) || IsDual9mm( W ) || IsWeaponOnPerk( W,, self.class )) &&
if( CouldRapidFireActive() && (Is9mm(W) || IsDual9mm( W ) || IsDoshinegun(W) || IsWeaponOnPerk( W,, self.class )) &&
(ZedTimeModifyingStates.Find( StateName ) != INDEX_NONE || (IsFAMAS(W) && StateName == 'FiringSecondaryState')) )
{
return RapidFireFiringRate;

View File

@ -550,7 +550,8 @@ function GameExplosion GetExplosionTemplate()
*/
function bool CouldBeZedToxicCloud( class<KFDamageType> KFDT )
{
return IsZedativeActive() && IsDamageTypeOnPerk( KFDT );
// Special case for doshinegun. Only this perk should apply.
return IsZedativeActive() && (IsDamageTypeOnPerk( KFDT ) || KFDT.Name == 'KFDT_Bludgeon_Doshinegun_Shot');
}
static function float GetZedativeExplosionDelay()

View File

@ -234,7 +234,7 @@ simulated private static function float GetQuickSwitchRecoilModifier()
*/
simulated function float GetReloadRateScale( KFWeapon KFW )
{
if( IsWeaponOnPerk( KFW,, self.class ) && WorldInfo.TimeDilation < 1.f && !IsFanFareActive() && IsZedTimeReloadAllowed() )
if( ( IsWeaponOnPerk( KFW,, self.class )) && WorldInfo.TimeDilation < 1.f && !IsFanFareActive() && IsZedTimeReloadAllowed() )
{
return 1.f - GetPassiveValue( ZedTimeReload, GetLevel() );
}
@ -261,7 +261,7 @@ simulated function bool IsZedTimeReloadAllowed()
*/
simulated function bool GetUsingTactialReload( KFWeapon KFW )
{
return IsSpeedReloadActive() && IsWeaponOnPerk( KFW,, self.class );
return IsSpeedReloadActive() && IsWeaponOnPerk( KFW,, self.class ) ;
}
/**
@ -322,7 +322,7 @@ simulated function float GetZedTimeModifier( KFWeapon W )
{
local name StateName;
if( GetFanfareActive() && IsWeaponOnPerk( W,, self.class ) )
if( GetFanfareActive() && ( IsWeaponOnPerk( W,, self.class ) || IsDoshinegun(W) ) )
{
StateName = W.GetStateName();
if( ZedTimeModifyingStates.Find( StateName ) != INDEX_NONE )

View File

@ -137,7 +137,7 @@ simulated function ModifyDamageGiven( out int InDamage, optional Actor DamageCau
KFW = GetWeaponFromDamageCauser( DamageCauser );
}
if( (KFW != none && IsWeaponOnPerk( KFW,, self.class )) || (DamageType != none && IsDamageTypeOnPerk(DamageType)) )
if( (KFW != none && (IsWeaponOnPerk( KFW,, self.class ) || IsDoshinegun(KFW))) || (DamageType != none && IsDamageTypeOnPerk(DamageType)) )
{
if( MyKFPM != none && HitZoneIdx == HZI_HEAD )
{

View File

@ -799,7 +799,7 @@ DefaultProperties
PerkSkills(ESurvivalist_AmmoVest)=(Name="AmmoVest",IconPath="UI_PerkTalent_TEX.Survivalist.UI_Talents_Survivalist_AmmoVest", Increment=0.f,Rank=0,StartingValue=0.15f,MaxValue=0.15f)
PerkSkills(ESurvivalist_BigPockets)=(Name="BigPockets",IconPath="UI_PerkTalent_TEX.Survivalist.UI_Talents_Survivalist_BigPockets", Increment=0.f,Rank=0,StartingValue=5.f,MaxValue=5.f)
PerkSkills(ESurvivalist_Shrapnel)=(Name="ZedShrapnel",IconPath="UI_PerkTalent_TEX.Survivalist.UI_Talents_Survivalist_Shrapnel", Increment=0.f,Rank=0,StartingValue=2.f,MaxValue=2.f)
PerkSkills(ESurvivalist_MakeThingsGoBoom)=(Name="MakeThingsGoBoom",IconPath="UI_PerkTalent_TEX.Survivalist.UI_Talents_Survivalist_Boom", Increment=0.f,Rank=0,StartingValue=1.4f,MaxValue=1.4f)
PerkSkills(ESurvivalist_MakeThingsGoBoom)=(Name="MakeThingsGoBoom",IconPath="UI_PerkTalent_TEX.Survivalist.UI_Talents_Survivalist_Boom", Increment=0.f,Rank=0,StartingValue=1.5f,MaxValue=1.5f) //1.4f
PerkSkills(ESurvivalist_MadMan)=(Name="MadMan",IconPath="UI_PerkTalent_TEX.Survivalist.UI_Talents_Survivalist_Madman", Increment=0.f,Rank=0,StartingValue=0.5f,MaxValue=0.5f)
PerkSkills(ESurvivalist_IncapMaster)=(Name="IncapMaster",IconPath="UI_PerkTalent_TEX.Survivalist.UI_Talents_Survivalist_IncapMaster", Increment=0.f,Rank=0,StartingValue=5000.0f,MaxValue=5000.0f)
@ -876,5 +876,5 @@ DefaultProperties
TacticalReloadAsReloadRateClassNames(0)="KFWeap_GrenadeLauncher_M32"
MakeThingsGoBoomExplosiveResistance=0.4f
MakeThingsGoBoomExplosiveResistance=0.5f //0.4f
}

View File

@ -278,7 +278,8 @@ simulated function ModifyDamageGiven( out int InDamage, optional Actor DamageCau
if( KFW != none )
{
if( IsBackupActive() && (IsBackupWeapon( KFW ) || IsDual9mm( KFW ) || ClassIsChildOf(DamageType, class'KFDT_Bludgeon')) )
// KFDT_Bludgeon_Doshinegun_Shot is a special case of Bludgeon damage that doesn't apply this mod.
if( IsBackupActive() && (IsBackupWeapon( KFW ) || IsDual9mm( KFW ) || ClassIsChildOf(DamageType, class'KFDT_Bludgeon')) && (IsDoshinegun(KFW) && DamageType.Name != 'KFDT_Bludgeon_Doshinegun_Shot' ))
{
`QALog( "Backup Damage" @ KFW @ GetPercentage( InDamage, InDamage * GetSkillValue(PerkSkills[ESWAT_Backup])), bLogPerk );
TempDamage += InDamage * GetSkillValue( PerkSkills[ESWAT_Backup] );

View File

@ -951,6 +951,7 @@ simulated event name GetSeasonalStateName()
{
local int EventId;
local KFMapInfo KFMI;
local bool bIsWWLWeekly; // WWL Weekly should not allow seasonal overrides
EventId = class'KFGameEngine'.static.GetSeasonalEventID();
KFMI = KFMapInfo(WorldInfo.GetMapInfo());
@ -959,20 +960,24 @@ simulated event name GetSeasonalStateName()
KFMI.ModifySeasonalEventId(EventId);
}
bIsWWLWeekly = class'KFGameEngine'.static.GetWeeklyEventIndexMod() == 12 && KFGameReplicationInfo(WorldInfo.GRI) != none && KFGameReplicationInfo(WorldInfo.GRI).bIsWeeklyMode;
if (bIsWWLWeekly)
return 'No_Event';
//Remove any year information, just get 1s digit
switch (EventId % 10)
{
case SEI_Summer:
return 'Summer_Sideshow';
case SEI_Fall:
return 'Fall';
case SEI_Winter:
return 'Winter';
case SEI_Spring:
return 'Spring';
default:
return 'No_Event';
}
switch (EventId % 10)
{
case SEI_Summer:
return 'Summer_Sideshow';
case SEI_Fall:
return 'Fall';
case SEI_Winter:
return 'Winter';
case SEI_Spring:
return 'Spring';
default:
return 'No_Event';
}
return 'No_Event';
}
@ -3596,7 +3601,7 @@ simulated function SetBossCamera( KFInterface_MonsterBoss Boss )
// overridden because to view a dying boss as a client
event ResetCameraMode()
{
if( PlayerCamera != none && PlayerCamera.CameraStyle != 'Boss' )
if( PlayerCamera != none && PlayerCamera.CameraStyle != 'Boss')
{
super.ResetCameraMode();
}
@ -4539,7 +4544,7 @@ simulated function StartAutoTargeting()
if( !PlayerInput.bUsingGamepad )
{
return;
return;
}
KFInput = KFPlayerInput(PlayerInput);
@ -4572,10 +4577,20 @@ static simulated function KFInterface_Usable GetCurrentUsableActor( Pawn P, opti
local KFInterface_Usable BestUsableActor;
local int InteractionIndex, BestInteractionIndex;
local KFGameReplicationInfo KFGRI;
BestInteractionIndex = -1;
if ( P != None )
{
/* On endless mode, if game is paused players can move but not interact with objects. */
KFGRI = KFGameReplicationInfo(P.WorldInfo.GRI);
if(KFGRI != none && KFGRI.bIsEndlessPaused)
{
return none;
}
/* */
// Check touching -- Useful when UsedBy() is implemented by subclass instead of kismet
ForEach P.TouchingActors(class'Actor', A)
{
@ -4633,12 +4648,19 @@ function GetTriggerUseList(float interactDistanceToCheck, float crosshairDist, f
local Trigger checkTrigger;
local SeqEvent_Used UseSeq;
local float aimEpsilon;
local KFGameReplicationInfo KFGRI;
if (Pawn == None)
{
return;
}
KFGRI = KFGameReplicationInfo(WorldInfo.GRI);
if(KFGRI != none && KFGRI.bIsEndlessPaused)
{
return;
}
// search of nearby actors that have use events
foreach Pawn.CollidingActors(class'Trigger',checkTrigger,interactDistanceToCheck)
{
@ -6807,6 +6829,8 @@ reliable server function ServerPause()
function bool PerformedUseAction()
{
local KFGameReplicationInfo KFGRI;
// Intentionally do not trigger Super Class so that we do not close the menu
if(WorldInfo.NetMode != NM_StandAlone)
@ -6826,6 +6850,12 @@ function bool PerformedUseAction()
return false;
}
KFGRI = KFGameReplicationInfo(WorldInfo.GRI);
if(KFGRI != none && KFGRI.bIsEndlessPaused)
{
return false;
}
// leave vehicle if currently in one
if( Vehicle(Pawn) != None )
{
@ -7388,6 +7418,12 @@ function AddNonZedKill(class<Pawn> KilledClass, byte Difficulty)
}
native reliable client private function ClientAddNonZedKill(class<Pawn> KilledClass, byte Difficulty);
function AddWeaponPurchased( class<KFWeaponDefinition> WeaponDef, int Price )
{
ClientAddWeaponPurchased( WeaponDef, Price );
}
native reliable client private function ClientAddWeaponPurchased( class<KFWeaponDefinition> WeaponDef, int Price );
function AddZedAssist(class<KFPawn_Monster> MonsterClass)
{
ClientAddZedAssist(MonsterClass);
@ -10045,6 +10081,34 @@ exec function RequestSkipTrader()
}
}
exec function RequestPauseGame()
{
local KFGameReplicationInfo KFGRI;
local KFPlayerReplicationInfo KFPRI;
KFPRI = KFPlayerReplicationInfo(PlayerReplicationInfo);
KFGRI = KFGameReplicationInfo(KFPRI.WorldInfo.GRI);
if (KFPRI != none)
{
if (KFGRI.bMatchHasBegun)
{
if (KFGRI.bEndlessMode && KFPRI.bHasSpawnedIn)
{
KFPRI.RequestPauseGame(KFPRI);
if (MyGFxManager != none)
{
MyGFxManager.CloseMenus();
if (MyGFxManager.PartyWidget != none)
{
MyGFxManager.PartyWidget.SetReadyButtonVisibility(false);
}
}
}
}
}
}
/*********************************************************************************************
* Networking
*********************************************************************************************/

View File

@ -207,6 +207,27 @@ function ResetGameplayPostProcessFX()
}
}
simulated function SetBossCamera( KFInterface_MonsterBoss Boss )
{
local KFGameReplicationInfo KFGRI;
local bool bIsBossRush;
KFGRI = KFGameReplicationInfo(WorldInfo.GRI);
bIsBossRush = KFGRI.bIsWeeklyMode && KFGRI.CurrentWeeklyIndex == 14;
if (bIsBossRush && Boss.GetHealthPercent() <= 0.0f && KFGRI.WaveNum != KFGRI.WaveMax)
{
SetTimer(5.0f, false, nameof(ResetBossCamera));
}
super.SetBossCamera(Boss);
}
simulated function ResetBossCamera()
{
super(PlayerController).ResetCameraMode();
}
//
defaultProperties
{

View File

@ -210,6 +210,8 @@ var(AutoTarget) float ForceLookAtPawnMinAngle;
var(AutoTarget) float ForceLookAtPawnRotationRate;
/** How fast to rotate towards ForceLookAtPawn location dampened for closer rotation**/
var(AutoTarget) float ForceLookAtPawnDampenedRotationRate;
/** Aim distance of autoaim to set head as target. */
var(AutoTarget) float WeakBoneDistance;
/*********************************************************************************************
* @name Force Feedback
@ -2070,8 +2072,10 @@ function vector GetBestAutoTargetLocation(Pawn CheckTarget, out name outBoneName
for(i = 0; i < WeakBones.Length; ++i)
{
TestLoc = KFP.Mesh.GetBoneLocation(WeakBones[i]);
if ( !IsAutoTargetWithinCone(TestLoc, CamLoc, CamDir, AutoTargetWeakspotCurve) )
if ( !IsAutoTargetWithinCone(TestLoc, CamLoc, CamDir, AutoTargetWeakspotCurve, WeakBoneDistance) )
{
continue; // test each weakspot bone
}
HitActor = Pawn.Trace(HitLoc, HitNorm, TestLoc, CamLoc, TRUE, vect(0,0,0), HitInfo, TRACEFLAG_Bullet);
if( HitActor == none || HitActor == CheckTarget )
@ -2106,7 +2110,7 @@ function vector GetBestAutoTargetLocation(Pawn CheckTarget, out name outBoneName
/**
* Returns true if TargetLoc falls within a given view cone
*/
function bool IsAutoTargetWithinCone(vector TargetLoc, vector CamLoc, vector CamDir, const out InterpCurveFloat Curve)
function bool IsAutoTargetWithinCone(vector TargetLoc, vector CamLoc, vector CamDir, const out InterpCurveFloat Curve, optional float Margin)
{
local float DistToTarget, TargetRadius, TargetHeight;
local float DotDiffToTarget;
@ -2138,7 +2142,7 @@ function bool IsAutoTargetWithinCone(vector TargetLoc, vector CamLoc, vector Cam
}
// Make sure the target is in front of us and close enough
if( UsedTargetAngle > DotDiffToTarget )
if( UsedTargetAngle > (DotDiffToTarget + Margin))
{
`log("Auto-target Cone Angle Exceeded by "$UsedTargetAngle - DotDiffToTarget, bDebugAutoTarget);
return false;
@ -2982,4 +2986,6 @@ defaultproperties
ForceLookAtPawnMinAngle=0.9f
ForceLookAtPawnRotationRate=22
ForceLookAtPawnDampenedRotationRate=8
WeakBoneDistance = 0.02; //0.01;
}

View File

@ -138,6 +138,9 @@ var bool bPerkSecondarySupplyUsed;
var bool bVotedToSkipTraderTime;
var bool bAlreadyStartedASkipTraderVote;
var bool bVotedToPauseGame;
var bool bAlreadyStartedAPauseGameVote;
/************************************
* Not replicated Voice Comms Request
* local client only -ZG
@ -851,6 +854,113 @@ reliable client function RecieveTopMaps(TopVotes VoteObject)
}
}
/*********************************************************************************************
`* Pause Game
********************************************************************************************* */
reliable client function ShowPauseGameVote(PlayerReplicationInfo PRI, byte VoteDuration, bool bShowChoices)
{
local KFPlayerController KFPC;
KFPC = KFPlayerController(Owner);
if(KFPC != none && KFPC.MyGFxHUD != none)
{
KFPC.MyGFxHUD.ShowPauseGameVote(PRI, VoteDuration, bShowChoices);
}
if(KFPC != none && KFPC.MyGFxManager != none && bShowChoices)
{
KFPC.MyGFxManager.ShowPauseGameVote(PRI);
}
}
reliable client function UpdatePauseGameTime(byte CurrentVoteTime)
{
local KFPlayerController KFPC;
KFPC = KFPlayerController(Owner);
if(KFPC != none && KFPC.MyGFxHUD != none)
{
KFPC.MyGFxHUD.UpdatePauseGameTime(CurrentVoteTime);
}
}
reliable client function HidePauseGameVote()
{
local KFPlayerController KFPC;
KFPC = KFPlayerController(Owner);
if(KFPC != none && KFPC.MyGFxHUD != none)
{
KFPC.MyGFxHUD.HidePauseGameVote();
}
if(KFPC != none && KFPC.MyGFxManager != none)
{
KFPC.MyGFxManager.HidePauseGameVote();
}
}
simulated function RequestPauseGame(PlayerReplicationInfo PRI)
{
bVotedToPauseGame = true;
ServerRequestPauseGameVote(self);
}
reliable server function ServerRequestPauseGameVote(PlayerReplicationInfo PRI)
{
local KFGameReplicationInfo KFGRI;
KFGRI = KFGameReplicationInfo(WorldInfo.GRI);
if (KFGRI != none)
{
KFGRI.ServerStartVotePauseGame(PRI);
}
}
simulated function CastPauseGameVote(PlayerReplicationInfo PRI, bool bSkipTrader)
{
local KFPlayerController KFPC;
ServerCastPauseGameVote(self, bSkipTrader);
KFPC = KFPlayerController(Owner);
if(KFPC != none && KFPC.MyGFxManager != none)
{
KFPC.MyGFxManager.HidePauseGameVote();
}
}
reliable server function ServerCastPauseGameVote(PlayerReplicationInfo PRI, bool bSkipTrader)
{
local KFGameReplicationInfo KFGRI;
KFGRI = KFGameReplicationInfo(WorldInfo.GRI);
if(KFGRI != none)
{
KFGRI.ReceiveVotePauseGame(PRI, bSkipTrader);
}
}
reliable server function ResetPauseGame()
{
local KFGameReplicationInfo KFGRI;
KFGRI = KFGameReplicationInfo(WorldInfo.GRI);
if(KFGRI != none && KFGRI.VoteCollector != none)
{
KFGRI.VoteCollector.ConcludeVotePauseGame();
}
bVotedToPauseGame = false;
}
/*********************************************************************************************
`* Character Customization
********************************************************************************************* */
@ -1458,4 +1568,5 @@ defaultproperties
CurrentHeadShotEffectID=-1;
bCarryingCollectible=false;
bVotedToPauseGame=false;
}

View File

@ -55,6 +55,9 @@ var(Projectile) ParticleSystem ProjPickupTemplate;
Allows us to set a much shorter LifeSpan to prevent fly-away projectiles living a long time. */
var float LifeSpanAfterStick;
/** Wether this object can be denied as a pickup or must be always picked. */
var bool bPickupCanBeDenied;
replication
{
if ( bNetDirty )
@ -501,4 +504,5 @@ defaultproperties
{
PickupRadius=250
PickupHeight=250
bPickupCanBeDenied=true
}

View File

@ -125,6 +125,10 @@ function PlayAnimation()
switch (CurrentTheatricType)
{
case THEATRIC_Entrance:
/** Not initialized when playing intro */
KFPOwner.SpecialMoveFlags = PackSMFlags(KFPOwner, THEATRIC_Entrance);
Variant = KFPOwner.SpecialMoveFlags >> 4;
AnimName = KFPOwner.PawnAnimInfo.TheatricBossEntranceAnimInfos[Variant].AnimationName;
CameraAnim = KFPOwner.PawnAnimInfo.TheatricBossEntranceAnimInfos[Variant].CameraAnimation;
CameraAnimOffset = KFPOwner.PawnAnimInfo.TheatricBossEntranceAnimInfos[Variant].CameraAnimOffset;

View File

@ -74,3 +74,4 @@ simulated event OnTriggerUsed(class<Trigger_PawnsOnly> TriggerClass);
simulated event OnTryCompleteObjective(int ObjectiveIndex, int EventIndex);
simulated function OnHitTaken();
simulated function OnHitGiven(class<DamageType> DT);
simulated function OnWeaponPurchased(class<KFWeaponDefinition> WeaponDef, int Price);

View File

@ -31,7 +31,8 @@ enum ESharedContentUnlock
SCU_FAMAS,
SCU_Thermite,
SCU_BladedPistol,
SCU_ParasiteImplanter
SCU_ParasiteImplanter,
SCU_Doshinegun
};
@ -355,4 +356,8 @@ defaultproperties
Name=KFWeap_Rifle_ParasiteImplanter,
IconPath="WEP_UI_ParasiteImplanter_TEX.UI_WeaponSelect_ParasiteImplanter",
ID=9132)}
SharedContentList(SCU_Doshinegun)={(
Name=KFWeap_AssaultRifle_Doshinegun,
IconPath="WEP_UI_Doshinegun_TEX.UI_Weapon_Select_Doshinegun",
ID=9275)}
}

View File

@ -44,6 +44,7 @@ var bool bIsSkipTraderVoteInProgress;
var byte LastSkipTraderYesVoteValue;
var byte LastSkipTraderNoVoteValue;
var int SkipTraderVoteLimit;
var int PauseGameVoteLimit;
var byte CurrentVoteTime;
@ -81,6 +82,16 @@ var TopVotes TopVotesObject;
var array<MapVote> MapVoteList;
var array<string> MapList;
/************************************
* @name Pause Endless Vote Vars
************************************/
var sVoteInfo CurrentPauseGameVote;
var bool bIsPauseGameVoteInProgress;
var byte LastPauseGameYesVoteValue;
var byte LastPauseGameNoVoteValue;
//==============================================================
// @name Kick Vote
//==============================================================
@ -158,7 +169,7 @@ function ServerStartVoteKick(PlayerReplicationInfo PRI_Kickee, PlayerReplication
}
// A kick vote is not allowed while another vote is active
if(bIsSkipTraderVoteInProgress)
if(bIsSkipTraderVoteInProgress || bIsPauseGameVoteInProgress)
{
KFPC.ReceiveLocalizedMessage(class'KFLocalMessage', LMT_OtherVoteInProgress);
return;
@ -430,7 +441,7 @@ function ServerStartVoteSkipTrader(PlayerReplicationInfo PRI)
}
// A skip trader vote is not allowed while another vote is active
if(bIsKickVoteInProgress)
if(bIsKickVoteInProgress || bIsPauseGameVoteInProgress)
{
KFPC.ReceiveLocalizedMessage(class'KFLocalMessage', LMT_OtherVoteInProgress);
return;
@ -874,6 +885,280 @@ function int MapVoteSort(MapVote A, MapVote B)
return Result;
}
//==============================================================
// @name Pause Vote
//==============================================================
function ServerStartVotePauseGame(PlayerReplicationInfo PRI)
{
local int i;
local array<KFPlayerReplicationInfo> PRIs;
local KFGameInfo KFGI;
local KFPlayerController KFPC;
local KFGameReplicationInfo KFGRI;
local byte WaveTimeRemaining;
KFGRI = KFGameReplicationInfo(WorldInfo.GRI);
KFGI = KFGameInfo(WorldInfo.Game);
KFPC = KFPlayerController(PRI.Owner);
// Spectators aren't allowed to vote
if(PRI.bOnlySpectator)
{
KFPC.ReceiveLocalizedMessage(class'KFLocalMessage', KFGRI.bIsEndlessPaused ? LMT_ResumeVoteNoSpectators : LMT_PauseVoteNoSpectators);
return;
}
// Only pause the game if there's no wave active
if(KFGRI.bWaveIsActive)
{
KFPC.ReceiveLocalizedMessage(class'KFLocalMessage', KFGRI.bIsEndlessPaused ? LMT_ResumeVoteWaveActive : LMT_PauseVoteWaveActive);
return;
}
if(!KFGRI.bEndlessMode)
{
KFPC.ReceiveLocalizedMessage(class'KFLocalMessage', LMT_PauseVoteWrongMode);
return;
}
// A pause vote is not allowed while another vote is active
if(bIsKickVoteInProgress || bIsSkipTraderVoteInProgress)
{
KFPC.ReceiveLocalizedMessage(class'KFLocalMessage', LMT_OtherVoteInProgress);
return;
}
WaveTimeRemaining = KFGRI.GetTraderTimeRemaining();
if(WaveTimeRemaining <= PauseGameVoteLimit)
{
KFPC.ReceiveLocalizedMessage(class'KFLocalMessage', KFGRI.bIsEndlessPaused ? LMT_ResumeVoteNoEnoughTime : LMT_PauseVoteNoEnoughTime);
return;
}
if( !bIsPauseGameVoteInProgress )
{
// Clear voter array
PlayersThatHaveVoted.Length = 0;
// Cache off these values in case player leaves before vote ends -- no cheating!
CurrentPauseGameVote.PlayerID = PRI.UniqueId;
CurrentPauseGameVote.PlayerPRI = PRI;
CurrentPauseGameVote.PlayerIPAddress = KFPC.GetPlayerNetworkAddress();
bIsPauseGameVoteInProgress = true;
CurrentVoteTime = min(VoteTime, WaveTimeRemaining - PauseGameVoteLimit);
GetKFPRIArray(PRIs);
for (i = 0; i < PRIs.Length; i++)
{
PRIs[i].ShowPauseGameVote(PRI, CurrentVoteTime, !(PRIs[i] == PRI));
}
KFGI.BroadcastLocalized(KFGI, class'KFLocalMessage', KFGRI.bIsEndlessPaused ? LMT_ResumeVoteStarted : LMT_PauseVoteStarted, CurrentPauseGameVote.PlayerPRI);
SetTimer( CurrentVoteTime, false, nameof(ConcludeVotePauseGame), self );
SetTimer( 1, true, nameof(UpdatePauseGameTimer), self );
// Cast initial vote
ReceiveVotePauseGame(PRI, true);
KFPlayerReplicationInfo(PRI).bAlreadyStartedAPauseGameVote = true;
}
else
{
// Can't start a new vote until current one is over
KFPlayerController(PRI.Owner).ReceiveLocalizedMessage(class'KFLocalMessage', KFGRI.bIsEndlessPaused ? LMT_ResumeVoteInProgress : LMT_PauseVoteInProgress);
}
}
reliable server function UpdatePauseGameTimer()
{
local array<KFPlayerReplicationInfo> PRIs;
local int i;
CurrentVoteTime -= 1;
GetKFPRIArray(PRIs);
for (i = 0; i < PRIs.Length; i++)
{
PRIs[i].UpdatePauseGameTime(CurrentVoteTime);
}
}
reliable server function ReceiveVotePauseGame(PlayerReplicationInfo PRI, bool bSkip)
{
local KFPlayerController KFPC;
local KFGameReplicationInfo KFGRI;
if(PlayersThatHaveVoted.Find(PRI) == INDEX_NONE)
{
//accept their vote
PlayersThatHaveVoted.AddItem(PRI);
if(bSkip)
{
yesVotes++;
}
else
{
noVotes++;
}
KFPC = KFPlayerController(PRI.Owner);
if(KFPC != none)
{
KFGRI = KFGameReplicationInfo(WorldInfo.GRI);
if(bSkip)
{
KFPC.ReceiveLocalizedMessage(class'KFLocalMessage', KFGRI.bIsEndlessPaused ? LMT_ResumeVoteYesReceived : LMT_PauseVoteYesReceived);
}
else
{
KFPC.ReceiveLocalizedMessage(class'KFLocalMessage', KFGRI.bIsEndlessPaused ? LMT_ResumeVoteNoReceived : LMT_PauseVoteNoReceived);
}
}
if( ShouldConcludePauseGameVote() )
{
ConcludeVotePauseGame();
}
else
{
ReplicatePauseGameVotes();
}
}
}
function ReplicatePauseGameVotes()
{
local KFGameReplicationInfo KFGRI;
RepPauseGameYesVotes = YesVotes;
RepPauseGameNoVotes = NoVotes;
KFGRI = Outer;
KFGRI.bForceNetUpdate = true;
if(Role == Role_Authority && WorldInfo.NetMode != NM_DedicatedServer)
{
UnPackPauseGameVotes();
}
}
function UnPackPauseGameVotes()
{
local KFPlayerController KFPC;
if(LastPauseGameYesVoteValue != RepPauseGameYesVotes || LastPauseGameNoVoteValue != RepPauseGameNoVotes)
{
NoVotes = RepPauseGameNoVotes;
YesVotes = RepPauseGameYesVotes;
//Update UI
KFPC = KFPlayerController(GetALocalPlayerController());
if(KFPC != none && KFPC.MyGFxHUD != none)
{
KFPC.MyGFxHUD.UpdatePauseGameVoteCount(YesVotes, NoVotes);
}
LastPauseGameYesVoteValue = RepPauseGameYesVotes;
LastPauseGameNoVoteValue = RepPauseGameNoVotes;
}
}
function bool ShouldConcludePauseGameVote()
{
local array<KFPlayerReplicationInfo> PRIs;
local int NumPRIs;
GetKFPRIArray(PRIs);
NumPRIs = PRIs.Length;
if( YesVotes + NoVotes >= NumPRIs || NoVotes > 0 )
{
return true;
}
return false;
}
reliable server function ConcludeVotePauseGame()
{
local array<KFPlayerReplicationInfo> PRIs;
local int i, NumPRIs;
local KFGameInfo KFGI;
local KFGameReplicationInfo KFGRI;
KFGRI = KFGameReplicationInfo(WorldInfo.GRI);
KFGI = KFGameInfo(WorldInfo.Game);
if(bIsPauseGameVoteInProgress)
{
GetKFPRIArray(PRIs);
for (i = 0; i < PRIs.Length; i++)
{
PRIs[i].HidePauseGameVote();
}
NumPRIs = PRIs.Length;
SetTimer( 0.f, true, nameof(UpdatePauseGameTimer), self );
if( NoVotes > 0)
{
bIsFailedVoteTimerActive=true;
SetTimer( KFGI.TimeBetweenFailedVotes, false, nameof(ClearFailedVoteFlag), self );
KFGI.BroadcastLocalized(KFGI, class'KFLocalMessage', KFGRI.bIsEndlessPaused ? LMT_ResumeVoteFailed : LMT_PauseVoteFailed);
}
else if( YesVotes >= NumPRIs )
{
//pause game
if (KFGRI.bIsEndlessPaused)
{
KFGRI.bIsEndlessPaused = false;
KFGRI.bStopCountDown = false;
KFGI.ResumeEndlessGame();
}
else
{
KFGRI.bIsEndlessPaused = true;
KFGRI.bStopCountDown = true;
KFGI.PauseEndlessGame();
}
//clear everything
ResetPauseGameVote();
//tell server to skip trader
KFGI.BroadcastLocalized(KFGI, class'KFLocalMessage', KFGRI.bIsEndlessPaused ? LMT_PauseVoteSuccess : LMT_ResumeVoteSuccess);
}
else
{
//Set timer so that votes cannot be spammed
bIsFailedVoteTimerActive=true;
SetTimer( KFGI.TimeBetweenFailedVotes, false, nameof(ClearFailedVoteFlag), self );
KFGI.BroadcastLocalized(KFGI, class'KFLocalMessage', KFGRI.bIsEndlessPaused ? LMT_ResumeVoteFailed : LMT_PauseVoteFailed);
}
bIsPauseGameVoteInProgress = false;
CurrentPauseGameVote.PlayerPRI = none;
CurrentPauseGameVote.PlayerID = class'PlayerReplicationInfo'.default.UniqueId;
yesVotes = 0;
noVotes = 0;
}
}
reliable server function ResetPauseGameVote()
{
local array<KFPlayerReplicationInfo> PRIs;
local int i;
GetKFPRIArray(PRIs);
for (i = 0; i < PRIs.Length; i++)
{
PRIs[i].bAlreadyStartedASkipTraderVote = false;
}
}
DefaultProperties
{
VoteTime=30
@ -884,4 +1169,5 @@ DefaultProperties
KickedPlayers=0
TimeAfterSkipTrader=5//seconds
SkipTraderVoteLimit=5//seconds
PauseGameVoteLimit=1
}

View File

@ -0,0 +1,31 @@
//=============================================================================
// KFWeaponDefintion
//=============================================================================
// A lightweight container for basic weapon properties that can be safely
// accessed without a weapon actor (UI, remote clients).
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFWeapDef_Doshinegun extends KFWeaponDefinition
abstract;
DefaultProperties
{
WeaponClassPath="KFGameContent.KFWeap_AssaultRifle_Doshinegun"
BuyPrice=600 //750
ImagePath="WEP_UI_Doshinegun_TEX.UI_Weapon_Select_Doshinegun"
EffectiveRange=68
UpgradePrice[0]=600
UpgradePrice[1]=700
UpgradePrice[2]=1500
UpgradeSellPrice[0]=450
UpgradeSellPrice[1]=975
UpgradeSellPrice[2]=2100
SharedUnlockId=SCU_Doshinegun
}

View File

@ -0,0 +1,25 @@
//=============================================================================
// KFWeaponDefintion
//=============================================================================
//
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFWeapDef_HRG_Stunner extends KFWeaponDefinition
abstract;
DefaultProperties
{
WeaponClassPath="KFGameContent.KFWeap_HRG_Stunner"
BuyPrice=1500
AmmoPricePerMag=36
ImagePath="ui_weaponselect_tex.UI_WeaponSelect_AA12"
EffectiveRange=70
UpgradePrice[0]=1500
UpgradeSellPrice[0]=1125
}

View File

@ -577,6 +577,32 @@ reliable server function ServerSendToReload(byte ClientReloadAmount)
bZoomActive = false;
}
/**
* Detach weapon from skeletal mesh
* Reseting speeds
* @param SkeletalMeshComponent weapon is attached to.
*/
simulated function DetachWeapon()
{
local KFPawn_Human KFPH;
local KFPlayerController KFPC;
super.DetachWeapon();
KFPH = KFPawn_Human(Instigator);
if ( KFPH != None )
{
MovementSpeedMod = 1;
KFPH.UpdateGroundSpeed();
}
KFPC = KFPlayerController(Instigator.Controller);
if (KFPC != none)
{
KFPC.RotationSpeedLimit = class'KFPlayerController'.default.RotationSpeedLimit;
}
}
defaultproperties
{
// Wind Up variables

View File

@ -1025,6 +1025,8 @@ replication
/** Util that makes sure the overlay component is last in the AllComponents/Components array. */
native function EnsureWeaponOverlayComponentLast();
/** Wether the player can purchase ammo for the weapon. Will be true for most of the weapons */
native function bool CanBuyAmmo();
/**
* Handles view rotation and weapon rotation changes for the weapon. Called in script by
@ -1762,7 +1764,14 @@ function bool DenyPickupQuery(class<Inventory> ItemClass, Actor Pickup)
}
else
{
bDenyPickUp = ((SpareAmmoCount[0] + AmmoCount[0]) >= GetMaxAmmoAmount(0));
if (KFProj_RicochetStickBullet(Pickup) == none || KFProj_RicochetStickBullet(Pickup).bPickupCanBeDenied)
{
bDenyPickUp = ((SpareAmmoCount[0] + AmmoCount[0]) >= GetMaxAmmoAmount(0));
}
else
{
bDenyPickUp = false;
}
}
}

View File

@ -3595,6 +3595,24 @@ defaultproperties
//Piranha Rusty
Skins.Add((Id=9131, Weapondef=class'KFWeapDef_BladedPistol', MIC_1P=("wep_skinset50_mat.Wep_Bladed_Rustynightmare_PM"), MIC_3P="wep_skinset50_mat.3rd_Wep_Bladed_Rustynightmare_PM", MIC_Pickup="wep_skinset50_mat.3rd_Wep_Bladed_Pickup_Rustynightmare_PM"));
//Doshinegun Standard
Skins.Add((Id=9275, Weapondef=class'KFWeapDef_Doshinegun', MIC_1P=("WEP_1P_Doshinegun_MAT.Wep_1stP_Doshinegun_MIC", "WEP_1P_Doshinegun_MAT.Wep_1stP_Doshinegun_Mag_MIC"), MIC_3P="wep_3p_doshinegun_mat.WEP_3P_Doshinegun_MIC", MIC_Pickup="wep_3p_doshinegun_mat.WEP_Pickup_Doshinegun_MIC"));
//Doshinegun Baroque
Skins.Add((Id=9279, Weapondef=class'KFWeapDef_Doshinegun', MIC_1P=("wep_skinset53_mat.Wep_Doshinegun_baroque_body_PM", "wep_skinset53_mat.Wep_Doshinegun_baroque_mag_PM"), MIC_3P="WEP_SkinSet53_MAT.Wep_Doshinegun_baroque_3P_PM", MIC_Pickup="WEP_SkinSet53_MAT.Wep_Doshinegun_Baroque_3P_Pickup_MIC"));
//Doshinegun Diamond
Skins.Add((Id=9277, Weapondef=class'KFWeapDef_Doshinegun', MIC_1P=("wep_skinset53_mat.Wep_Doshinegun_diamond_body_PM", "wep_skinset53_mat.Wep_Doshinegun_diamond_mag_PM"), MIC_3P="WEP_SkinSet53_MAT.Wep_Doshinegun_diamond_3P_PM", MIC_Pickup="WEP_SkinSet53_MAT.Wep_Doshinegun_Diamond_3P_Pickup_MIC"));
//Doshinegun Dosh
Skins.Add((Id=9278, Weapondef=class'KFWeapDef_Doshinegun', MIC_1P=("wep_skinset53_mat.Wep_Doshinegun_dosh_body_PM", "wep_skinset53_mat.Wep_Doshinegun_dosh_mag_PM"), MIC_3P="WEP_SkinSet53_MAT.Wep_Doshinegun_dosh_3P_PM", MIC_Pickup="WEP_SkinSet53_MAT.Wep_Doshinegun_Dosh_3P_Pickup_MIC"));
//Doshinegun Golden Tiger
Skins.Add((Id=9280, Weapondef=class'KFWeapDef_Doshinegun', MIC_1P=("wep_skinset53_mat.Wep_Doshinegun_tiger_body_PM", "wep_skinset53_mat.Wep_Doshinegun_tiger_mag_PM"), MIC_3P="WEP_SkinSet53_MAT.Wep_Doshinegun_tiger_3P_PM", MIC_Pickup="WEP_SkinSet53_MAT.Wep_Doshinegun_Tiger_3P_Pickup_MIC"));
//Doshinegun Koi Dream
Skins.Add((Id=9276, Weapondef=class'KFWeapDef_Doshinegun', MIC_1P=("wep_skinset53_mat.Wep_Doshinegun_koidream_body_PM", "wep_skinset53_mat.Wep_Doshinegun_koidream_mag_PM"), MIC_3P="WEP_SkinSet53_MAT.Wep_Doshinegun_koidream_3P_PM", MIC_Pickup="WEP_SkinSet53_MAT.Wep_Doshinegun_koidream_3P_Pickup_MIC"));
//BeyondHorizon AA12
Skins.Add((Id=8845, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_AA12', MIC_1P=("WEP_SkinSet43_MAT.space_aa12.Space_AA12_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.space_aa12.Space_AA12_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.space_aa12.Space_AA12_3P_Pickup_MIC"))
@ -3720,4 +3738,124 @@ defaultproperties
//Hellmark Thunder Hemoclobber
Skins.Add((Id=9010, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_MedicBat', MIC_1P=("WEP_SkinSet48_MAT.thunder_medicbat.Thunder_MedicBat_1P_Mint_MIC"), MIC_3P="WEP_SkinSet48_MAT.thunder_medicbat.Thunder_MedicBat_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet48_MAT.thunder_medicbat.Thunder_MedicBat_3P_Pickup_MIC"))
//Alchemist Toxic Boomstick
Skins.Add((Id=9178, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_DoubleBarrel', MIC_1P=("WEP_SkinSet51_MAT.toxic_doublebarrel.Toxic_DoubleBarrel_1P_Mint_MIC"), MIC_3P="WEP_SkinSet51_MAT.toxic_doublebarrel.Toxic_DoubleBarrel_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet51_MAT.toxic_doublebarrel.Toxic_DoubleBarrel_3P_Pickup_MIC"))
//Alchemist Toxic Caulk n Burn
Skins.Add((Id=9179, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_CaulkBurn', MIC_1P=("WEP_SkinSet51_MAT.toxic_caulkburn.Toxic_CaulkBurn_1P_Mint_MIC"), MIC_3P="WEP_SkinSet51_MAT.toxic_caulkburn.Toxic_CaulkBurn_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet51_MAT.toxic_caulkburn.Toxic_CaulkBurn_3P_Pickup_MIC"))
//Alchemist Toxic Desert Eagle
Skins.Add((Id=9180, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Deagle', MIC_1P=("WEP_SkinSet51_MAT.toxic_deagle.Toxic_Deagle_1P_Mint_MIC"), MIC_3P="WEP_SkinSet51_MAT.toxic_deagle.Toxic_Deagle_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet51_MAT.toxic_deagle.Toxic_Deagle_3P_Pickup_MIC"))
//Alchemist Toxic Flamethrower
Skins.Add((Id=9181, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_FlameThrower', MIC_1P=("WEP_SkinSet51_MAT.toxic_flamethrower.Toxic_Flamethrower_1P_Mint_MIC"), MIC_3P="WEP_SkinSet51_MAT.toxic_flamethrower.Toxic_Flamethrower_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet51_MAT.toxic_flamethrower.Toxic_Flamethrower_3P_Pickup_MIC"))
//Alchemist Toxic HMTech-501 Grenade Rifle
Skins.Add((Id=9182, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_MedicRifleGrenadeLauncher', MIC_1P=("WEP_SkinSet51_MAT.toxic_medicgrenadelauncher.Toxic_MedicGrenadeLauncher_1P_Mint_MIC"), MIC_3P="WEP_SkinSet51_MAT.toxic_medicgrenadelauncher.Toxic_MedicGrenadeLauncher_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet51_MAT.toxic_medicgrenadelauncher.Toxic_MedicGrenadeLauncher_3P_Pickup_MIC"))
//Alchemist Toxic M32
Skins.Add((Id=9183, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_M32', MIC_1P=("WEP_SkinSet51_MAT.toxic_m32.Toxic_M32_1P_Mint_MIC", "WEP_SkinSet51_MAT.toxic_m32.Toxic_M32_Sight_1P_Mint_MIC"), MIC_3P="WEP_SkinSet51_MAT.toxic_m32.Toxic_M32_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet51_MAT.toxic_m32.Toxic_M32_3P_Pickup_MIC"))
//Alchemist Toxic P90
Skins.Add((Id=9184, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_P90', MIC_1P=("WEP_SkinSet51_MAT.toxic_p90.Toxic_P90_1P_Mint_MIC", "WEP_SkinSet51_MAT.toxic_p90.Toxic_P90_Sight_1P_Mint_MIC"), MIC_3P="WEP_SkinSet51_MAT.toxic_p90.Toxic_P90_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet51_MAT.toxic_p90.Toxic_P90_3P_Pickup_MIC"))
//Alchemist Toxic RPG-7
Skins.Add((Id=9185, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_RPG7', MIC_1P=("WEP_SkinSet51_MAT.toxic_rpg7.Toxic_RPG7_1P_Mint_MIC"), MIC_3P="WEP_SkinSet51_MAT.toxic_rpg7.Toxic_RPG7_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet51_MAT.toxic_rpg7.Toxic_RPG7_3P_Pickup_MIC"))
//Alchemist Toxic Scar
Skins.Add((Id=9186, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Scar', MIC_1P=("WEP_SkinSet51_MAT.toxic_scar.Toxic_SCAR_1P_Mint_MIC", "WEP_SkinSet51_MAT.toxic_scar.Toxic_SCAR_Sight_1P_Mint_MIC"), MIC_3P="WEP_SkinSet51_MAT.toxic_scar.Toxic_SCAR_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet51_MAT.toxic_scar.Toxic_SCAR_3P_Pickup_MIC"))
//Alchemist Toxic Spitfire
Skins.Add((Id=9187, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Flaregun', MIC_1P=("WEP_SkinSet51_MAT.toxic_flaregun.Toxic_FlareGun_1P_Mint_MIC"), MIC_3P="WEP_SkinSet51_MAT.toxic_flaregun.Toxic_FlareGun_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet51_MAT.toxic_flaregun.Toxic_FlareGun_3P_Pickup_MIC"))
//Alchemist Blaze Boomstick
Skins.Add((Id=9188, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_DoubleBarrel', MIC_1P=("WEP_SkinSet51_MAT.fire_doublebarrel.Fire_DoubleBarrel_1P_Mint_MIC"), MIC_3P="WEP_SkinSet51_MAT.fire_doublebarrel.Fire_DoubleBarrel_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet51_MAT.fire_doublebarrel.Fire_DoubleBarrel_3P_Pickup_MIC"))
//Alchemist Blaze Caulk n Burn
Skins.Add((Id=9189, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_CaulkBurn', MIC_1P=("WEP_SkinSet51_MAT.fire_caulkburn.Fire_CaulkBurn_1P_Mint_MIC"), MIC_3P="WEP_SkinSet51_MAT.fire_caulkburn.Fire_CaulkBurn_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet51_MAT.fire_caulkburn.Fire_CaulkBurn_3P_Pickup_MIC"))
//Alchemist Blaze Desert Eagle
Skins.Add((Id=9190, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Deagle', MIC_1P=("WEP_SkinSet51_MAT.fire_deagle.Fire_Deagle_1P_Mint_MIC"), MIC_3P="WEP_SkinSet51_MAT.fire_deagle.Fire_Deagle_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet51_MAT.fire_deagle.Fire_Deagle_3P_Pickup_MIC"))
//Alchemist Blaze Flamethrower
Skins.Add((Id=9191, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_FlameThrower', MIC_1P=("WEP_SkinSet51_MAT.fire_flamethrower.Fire_Flamethrower_1P_Mint_MIC"), MIC_3P="WEP_SkinSet51_MAT.fire_flamethrower.Fire_Flamethrower_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet51_MAT.fire_flamethrower.Fire_Flamethrower_3P_Pickup_MIC"))
//Alchemist Blaze HMTech-501 Grenade Rifle
Skins.Add((Id=9192, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_MedicRifleGrenadeLauncher', MIC_1P=("WEP_SkinSet51_MAT.fire_medicgrenadelauncher.Fire_MedicGrenadeLauncher_1P_Mint_MIC"), MIC_3P="WEP_SkinSet51_MAT.fire_medicgrenadelauncher.Fire_MedicGrenadeLauncher_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet51_MAT.fire_medicgrenadelauncher.Fire_MedicGrenadeLauncher_3P_Pickup_MIC"))
//Alchemist Blaze M32
Skins.Add((Id=9193, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_M32', MIC_1P=("WEP_SkinSet51_MAT.fire_m32.Fire_M32_1P_Mint_MIC", "WEP_SkinSet51_MAT.fire_m32.Fire_M32_Sight_1P_Mint_MIC"), MIC_3P="WEP_SkinSet51_MAT.fire_m32.Fire_M32_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet51_MAT.fire_m32.Fire_M32_3P_Pickup_MIC"))
//Alchemist Blaze P90
Skins.Add((Id=9194, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_P90', MIC_1P=("WEP_SkinSet51_MAT.fire_p90.Fire_P90_1P_Mint_MIC", "WEP_SkinSet51_MAT.fire_p90.Fire_P90_Sight_1P_Mint_MIC"), MIC_3P="WEP_SkinSet51_MAT.fire_p90.Fire_P90_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet51_MAT.fire_p90.Fire_P90_3P_Pickup_MIC"))
//Alchemist Blaze RPG-7
Skins.Add((Id=9195, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_RPG7', MIC_1P=("WEP_SkinSet51_MAT.fire_rpg7.Fire_RPG7_1P_Mint_MIC"), MIC_3P="WEP_SkinSet51_MAT.fire_rpg7.Fire_RPG7_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet51_MAT.fire_rpg7.Fire_RPG7_3P_Pickup_MIC"))
//Alchemist Blaze Scar
Skins.Add((Id=9196, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Scar', MIC_1P=("WEP_SkinSet51_MAT.fire_scar.Fire_SCAR_1P_Mint_MIC", "WEP_SkinSet51_MAT.fire_scar.Fire_SCAR_Sight_1P_Mint_MIC"), MIC_3P="WEP_SkinSet51_MAT.fire_scar.Fire_SCAR_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet51_MAT.fire_scar.Fire_SCAR_3P_Pickup_MIC"))
//Alchemist Blaze Spitfire
Skins.Add((Id=9197, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Flaregun', MIC_1P=("WEP_SkinSet51_MAT.fire_flaregun.Fire_FlareGun_1P_Mint_MIC"), MIC_3P="WEP_SkinSet51_MAT.fire_flaregun.Fire_FlareGun_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet51_MAT.fire_flaregun.Fire_FlareGun_3P_Pickup_MIC"))
//XMas Sweet Boomstick
Skins.Add((Id=9198, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_DoubleBarrel', MIC_1P=("WEP_SkinSet52_MAT.sweet_doublebarrel.Sweet_DoubleBarrel_1P_Mint_MIC"), MIC_3P="WEP_SkinSet52_MAT.sweet_doublebarrel.Sweet_DoubleBarrel_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet52_MAT.sweet_doublebarrel.Sweet_DoubleBarrel_3P_Pickup_MIC"))
//XMas Sweet Caulk n Burn
Skins.Add((Id=9199, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_CaulkBurn', MIC_1P=("WEP_SkinSet52_MAT.sweet_caulkburn.Sweet_CaulkBurn_1P_Mint_MIC"), MIC_3P="WEP_SkinSet52_MAT.sweet_caulkburn.Sweet_CaulkBurn_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet52_MAT.sweet_caulkburn.Sweet_CaulkBurn_3P_Pickup_MIC"))
//XMas Sweet Desert Eagle
Skins.Add((Id=9200, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Deagle', MIC_1P=("WEP_SkinSet52_MAT.sweet_deagle.Sweet_Deagle_1P_Mint_MIC"), MIC_3P="WEP_SkinSet52_MAT.sweet_deagle.Sweet_Deagle_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet52_MAT.sweet_deagle.Sweet_Deagle_3P_Pickup_MIC"))
//XMas Sweet Flamethrower
Skins.Add((Id=9201, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_FlameThrower', MIC_1P=("WEP_SkinSet52_MAT.sweet_flamethrower.Sweet_Flamethrower_1P_Mint_MIC"), MIC_3P="WEP_SkinSet52_MAT.sweet_flamethrower.Sweet_Flamethrower_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet52_MAT.sweet_flamethrower.Sweet_Flamethrower_3P_Pickup_MIC"))
//XMas Sweet HMTech-501 Grenade Rifle
Skins.Add((Id=9202, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_MedicRifleGrenadeLauncher', MIC_1P=("WEP_SkinSet52_MAT.sweet_medicgrenadelauncher.Sweet_MedicGrenadeLauncher_1P_Mint_MIC"), MIC_3P="WEP_SkinSet52_MAT.sweet_medicgrenadelauncher.Sweet_MedicGrenadeLauncher_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet52_MAT.sweet_medicgrenadelauncher.Sweet_MedicGrenadeLauncher_3P_Pickup_MIC"))
//XMas Sweet M32
Skins.Add((Id=9203, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_M32', MIC_1P=("WEP_SkinSet52_MAT.sweet_m32.Sweet_M32_1P_Mint_MIC", "WEP_SkinSet52_MAT.sweet_m32.Sweet_M32_Sight_1P_Mint_MIC"), MIC_3P="WEP_SkinSet52_MAT.sweet_m32.Sweet_M32_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet52_MAT.sweet_m32.Sweet_M32_3P_Pickup_MIC"))
//XMas Sweet P90
Skins.Add((Id=9204, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_P90', MIC_1P=("WEP_SkinSet52_MAT.sweet_p90.Sweet_P90_1P_Mint_MIC", "WEP_SkinSet52_MAT.sweet_p90.Sweet_P90_Sight_1P_Mint_MIC"), MIC_3P="WEP_SkinSet52_MAT.sweet_p90.Sweet_P90_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet52_MAT.sweet_p90.Sweet_P90_3P_Pickup_MIC"))
//XMas Sweet RPG-7
Skins.Add((Id=9205, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_RPG7', MIC_1P=("WEP_SkinSet52_MAT.sweet_rpg7.Sweet_RPG7_1P_Mint_MIC"), MIC_3P="WEP_SkinSet52_MAT.sweet_rpg7.Sweet_RPG7_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet52_MAT.sweet_rpg7.Sweet_RPG7_3P_Pickup_MIC"))
//XMas Sweet Scar
Skins.Add((Id=9206, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Scar', MIC_1P=("WEP_SkinSet52_MAT.sweet_scar.Sweet_SCAR_1P_Mint_MIC", "WEP_SkinSet52_MAT.sweet_scar.Sweet_SCAR_Sight_1P_Mint_MIC"), MIC_3P="WEP_SkinSet52_MAT.sweet_scar.Sweet_SCAR_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet52_MAT.sweet_scar.Sweet_SCAR_3P_Pickup_MIC"))
//XMas Sweet Spitfire
Skins.Add((Id=9207, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Flaregun', MIC_1P=("WEP_SkinSet52_MAT.sweet_flaregun.Sweet_FlareGun_1P_Mint_MIC"), MIC_3P="WEP_SkinSet52_MAT.sweet_flaregun.Sweet_FlareGun_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet52_MAT.sweet_flaregun.Sweet_FlareGun_3P_Pickup_MIC"))
//XMas Sour Boomstick
Skins.Add((Id=9208, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_DoubleBarrel', MIC_1P=("WEP_SkinSet52_MAT.sour_doublebarrel.Sour_DoubleBarrel_1P_Mint_MIC"), MIC_3P="WEP_SkinSet52_MAT.sour_doublebarrel.Sour_DoubleBarrel_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet52_MAT.sour_doublebarrel.Sour_DoubleBarrel_3P_Pickup_MIC"))
//XMas Sour Caulk n Burn
Skins.Add((Id=9209, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_CaulkBurn', MIC_1P=("WEP_SkinSet52_MAT.sour_caulkburn.Sour_CaulkBurn_1P_Mint_MIC"), MIC_3P="WEP_SkinSet52_MAT.sour_caulkburn.Sour_CaulkBurn_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet52_MAT.sour_caulkburn.Sour_CaulkBurn_3P_Pickup_MIC"))
//XMas Sour Desert Eagle
Skins.Add((Id=9210, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Deagle', MIC_1P=("WEP_SkinSet52_MAT.sour_deagle.Sour_Deagle_1P_Mint_MIC"), MIC_3P="WEP_SkinSet52_MAT.sour_deagle.Sour_Deagle_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet52_MAT.sour_deagle.Sour_Deagle_3P_Pickup_MIC"))
//XMas Sour Flamethrower
Skins.Add((Id=9211, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_FlameThrower', MIC_1P=("WEP_SkinSet52_MAT.sour_flamethrower.Sour_Flamethrower_1P_Mint_MIC"), MIC_3P="WEP_SkinSet52_MAT.sour_flamethrower.Sour_Flamethrower_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet52_MAT.sour_flamethrower.Sour_Flamethrower_3P_Pickup_MIC"))
//XMas Sour HMTech-501 Grenade Rifle
Skins.Add((Id=9212, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_MedicRifleGrenadeLauncher', MIC_1P=("WEP_SkinSet52_MAT.sour_medicgrenadelauncher.Sour_MedicGrenadeLauncher_1P_Mint_MIC"), MIC_3P="WEP_SkinSet52_MAT.sour_medicgrenadelauncher.Sour_MedicGrenadeLauncher_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet52_MAT.sour_medicgrenadelauncher.Sour_MedicGrenadeLauncher_3P_Pickup_MIC"))
//XMas Sour M32
Skins.Add((Id=9213, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_M32', MIC_1P=("WEP_SkinSet52_MAT.sour_m32.Sour_M32_1P_Mint_MIC", "WEP_SkinSet52_MAT.sour_m32.Sour_M32_Sight_1P_Mint_MIC"), MIC_3P="WEP_SkinSet52_MAT.sour_m32.Sour_M32_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet52_MAT.sour_m32.Sour_M32_3P_Pickup_MIC"))
//XMas Sour P90
Skins.Add((Id=9214, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_P90', MIC_1P=("WEP_SkinSet52_MAT.sour_p90.Sour_P90_1P_Mint_MIC", "WEP_SkinSet52_MAT.sour_p90.Sour_P90_Sight_1P_Mint_MIC"), MIC_3P="WEP_SkinSet52_MAT.sour_p90.Sour_P90_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet52_MAT.sour_p90.Sour_P90_3P_Pickup_MIC"))
//XMas Sour RPG-7
Skins.Add((Id=9215, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_RPG7', MIC_1P=("WEP_SkinSet52_MAT.sour_rpg7.Sour_RPG7_1P_Mint_MIC"), MIC_3P="WEP_SkinSet52_MAT.sour_rpg7.Sour_RPG7_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet52_MAT.sour_rpg7.Sour_RPG7_3P_Pickup_MIC"))
//XMas Sour Scar
Skins.Add((Id=9216, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Scar', MIC_1P=("WEP_SkinSet52_MAT.sour_scar.Sour_SCAR_1P_Mint_MIC", "WEP_SkinSet52_MAT.sour_scar.Sour_SCAR_Sight_1P_Mint_MIC"), MIC_3P="WEP_SkinSet52_MAT.sour_scar.Sour_SCAR_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet52_MAT.sour_scar.Sour_SCAR_3P_Pickup_MIC"))
//XMas Sour Spitfire
Skins.Add((Id=9217, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Flaregun', MIC_1P=("WEP_SkinSet52_MAT.sour_flaregun.Sour_FlareGun_1P_Mint_MIC"), MIC_3P="WEP_SkinSet52_MAT.sour_flaregun.Sour_FlareGun_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet52_MAT.sour_flaregun.Sour_FlareGun_3P_Pickup_MIC"))
}

View File

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

View File

@ -155,4 +155,5 @@ const STATID_ACHIEVE_ElysiumEndlessWaveFifteen = 4057;
const STATID_ACHIEVE_Dystopia2029Collectibles = 4058;
const STATID_ACHIEVE_MoonbaseCollectibles = 4059;
const STATID_ACHIEVE_NetherholdCollectibles = 4060;
const STATID_ACHIEVE_CarillonHamletCollectibles = 4061;
/** `endif */

View File

@ -280,9 +280,9 @@ DefaultProperties
MaxChestBeamHeightOffset=64.f
PhaseThresholds[0]=1
PhaseThresholds[1]=0.65 //0.75
PhaseThresholds[2]=0.5
PhaseThresholds[3]=0.2 //0.25 //0.1
PhaseThresholds[1]=0.75 //0.65 //0.75
PhaseThresholds[2]=0.6 //0.5
PhaseThresholds[3]=0.3 //0.2 //0.25 //0.1
ChestBeamMinPhase=2

View File

@ -0,0 +1,51 @@
//=============================================================================
// KFDT_Ballistic_HRG_Stunner
//=============================================================================
// Damage type class for the HRG Stunner
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFDT_Ballistic_HRG_Stunner extends KFDT_Ballistic_Submachinegun
abstract
hidedropdown;
/** Allows the damage type to customize exactly which hit zones it can dismember */
static simulated function bool CanDismemberHitZone( name InHitZoneName )
{
if( super.CanDismemberHitZone( InHitZoneName ) )
{
return true;
}
switch ( InHitZoneName )
{
case 'lupperarm':
case 'rupperarm':
case 'chest':
case 'heart':
return true;
}
return false;
}
defaultproperties
{
BloodSpread=0.4
BloodScale=0.6
KDamageImpulse=1500 //900
KDeathUpKick=-1000 //-500
KDeathVel=600 //350
GibImpulseScale=1.0
StumblePower=35
KnockdownPower=25
GunHitPower=25
//Perk
ModifierPerkList(0)=class'KFPerk_SWAT'
WeaponDef=class'KFWeapDef_HRG_Stunner'
}

View File

@ -0,0 +1,49 @@
//=============================================================================
// KFDT_Ballistic_HRG_Stunner_Alt
//=============================================================================
// Damage type class for the HRG Stunner alt fire
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFDT_Ballistic_HRG_Stunner_Alt extends KFDT_Ballistic_Submachinegun
abstract
hidedropdown;
/** Allows the damage type to customize exactly which hit zones it can dismember */
static simulated function bool CanDismemberHitZone( name InHitZoneName )
{
if( super.CanDismemberHitZone( InHitZoneName ) )
{
return true;
}
switch ( InHitZoneName )
{
case 'lupperarm':
case 'rupperarm':
case 'chest':
case 'heart':
return true;
}
return false;
}
defaultproperties
{
BloodSpread=0.4
BloodScale=0.6
KDamageImpulse=900
KDeathUpKick=-500
KDeathVel=350
StumblePower=0 //200
GunHitPower=0 //150
//Perk
ModifierPerkList(0)=class'KFPerk_SWAT'
WeaponDef=class'KFWeapDef_HRG_Stunner'
}

View File

@ -0,0 +1,16 @@
//=============================================================================
// KFDT_Bludgeon_Doshinegun
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFDT_Bludgeon_Doshinegun extends KFDT_Bludgeon_RifleButt
abstract
hidedropdown;
DefaultProperties
{
//defaults
WeaponDef=class'KFWeapDef_Doshinegun'
}

View File

@ -0,0 +1,25 @@
//=============================================================================
// KFDT_Bludgeon_Doshinegun_Shot
//=============================================================================
// Bills hit hard
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFDT_Bludgeon_Doshinegun_Shot extends KFDT_Bludgeon
abstract
hidedropdown;
defaultproperties
{
KDamageImpulse=900
KDeathUpKick=-300
KDeathVel=100
StumblePower=120
StunPower=40
GunHitPower=150
WeaponDef=class'KFWeapDef_Doshinegun'
}

View File

@ -12,6 +12,6 @@ class KFDT_Bludgeon_FlareGun extends KFDT_Bludgeon_RifleButt
DefaultProperties
{
WeaponDef=class'KFWeapDef_FlareGun'
ModifierPerkList(0)=class'KFPerk_Gunslinger'
ModifierPerkList(1)=class'KFPerk_Sharpshooter'
ModifierPerkList(1)=class'KFPerk_Gunslinger'
ModifierPerkList(2)=class'KFPerk_Sharpshooter'
}

View File

@ -21,5 +21,5 @@ defaultproperties
MeleeHitPower=100
WeaponDef=class'KFWeapDef_G18'
ModifierPerkList(0)=class'KFPerk_Swat'
ModifierPerkList(1)=class'KFPerk_Swat'
}

View File

@ -12,6 +12,6 @@ class KFDT_Bludgeon_HRGWinterbite extends KFDT_Bludgeon_RifleButt
DefaultProperties
{
WeaponDef=class'KFWeapDef_HRGWinterbite'
ModifierPerkList(0)=class'KFPerk_Gunslinger'
ModifierPerkList(1)=class'KFPerk_Sharpshooter'
ModifierPerkList(1)=class'KFPerk_Gunslinger'
ModifierPerkList(2)=class'KFPerk_Sharpshooter'
}

View File

@ -10,7 +10,7 @@ class KFDT_Bludgeon_HRG_SonicGun extends KFDT_Bludgeon_RifleButt
DefaultProperties
{
ModifierPerkList(0)=class'KFPerk_Survivalist'
ModifierPerkList(1)=class'KFPerk_Survivalist'
//defaults
WeaponDef=class'KFWeapDef_HRG_SonicGun'
}

View File

@ -0,0 +1,16 @@
//=============================================================================
// KFDT_Bludgeon_HRG_Stunner
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFDT_Bludgeon_HRG_Stunner extends KFDT_Bludgeon_RifleButt
abstract
hidedropdown;
DefaultProperties
{
//defaults
WeaponDef=class'KFWeapDef_HRG_Stunner'
}

View File

@ -14,6 +14,6 @@ DefaultProperties
StumblePower=200
MeleeHitPower=100
ModifierPerkList(0)=class'KFPerk_FieldMedic'
ModifierPerkList(1)=class'KFPerk_FieldMedic'
WeaponDef=class'KFWeapDef_HRG_Vampire'
}

View File

@ -0,0 +1,29 @@
//=============================================================================
// KFDT_Explosive_HRG_Stunner
//=============================================================================
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFDT_Explosive_HRG_Stunner extends KFDT_Explosive
abstract
hidedropdown;
defaultproperties
{
bShouldSpawnPersistentBlood=true
// physics impact
RadialDamageImpulse=3000 //5000 //20000
GibImpulseScale=0.15
KDeathUpKick=1000
KDeathVel=300
StunPower=160
StumblePower=40
//Perk
ModifierPerkList(0)=class'KFPerk_SWAT'
WeaponDef=class'KFWeapDef_HRG_Stunner'
}

View File

@ -666,6 +666,17 @@ function SetMonsterDefaults(KFPawn_Monster P)
super.SetMonsterDefaults(P);
}
// Save player's stats on leave
function UnregisterPlayer(PlayerController PC)
{
super.UnregisterPlayer(PC);
if (GetNumPlayers() == 0 && MyKFGRI.bIsEndlessPaused)
{
ResumeEndlessGame();
}
}
defaultproperties
{
bIsEndlessGame = true

View File

@ -107,6 +107,9 @@ function StartMatch()
function PlayWaveStartDialog()
{
if (OutbreakEvent != none && OutbreakEvent.ActiveEvent.bBossRushMode)
return;
`DialogManager.PlayWaveStartDialog(MyKFGRI.IsBossWave());
if (WaveNum == 1)
{

View File

@ -66,9 +66,13 @@ event PreBeginPlay()
OutbreakEvent.UpdateGRI();
if (Role == Role_Authority && MyKFGRI != none && OutbreakEvent.ActiveEvent.bUnlimitedWeaponPickups)
if (Role == Role_Authority && MyKFGRI != none)
{
MyKFGRI.NotifyBrokenTrader();
MyKFGRI.NotifyWeeklyEventIndex(ActiveEventIdx);
if ( OutbreakEvent.ActiveEvent.bUnlimitedWeaponPickups)
{
MyKFGRI.NotifyBrokenTrader();
}
}
}
@ -226,7 +230,19 @@ function ResetPermanentZed()
function float GetAdjustedAIDoshValue( class<KFPawn_Monster> MonsterClass )
{
return super.GetAdjustedAIDoshValue(MonsterClass) * OutbreakEvent.ActiveEvent.DoshOnKillGlobalModifier;
if (!OutbreakEvent.ActiveEvent.bBossRushMode)
{
return super.GetAdjustedAIDoshValue(MonsterClass) * OutbreakEvent.ActiveEvent.DoshOnKillGlobalModifier;
}
else
{
if ((WaveNum-1) < OutbreakEvent.ActiveEvent.BossRushOverrideParams.PerWaves.length)
{
return super.GetAdjustedAIDoshValue(MonsterClass) * OutbreakEvent.ActiveEvent.BossRushOverrideParams.PerWaves[WaveNum-1].DoshOnKillGlobalModifier;
}
}
return super.GetAdjustedAIDoshValue(MonsterClass);
}
protected function ScoreMonsterKill( Controller Killer, Controller Monster, KFPawn_Monster MonsterPawn )
@ -385,24 +401,37 @@ function SetBossIndex()
{
local BossSpawnReplacement Replacement;
local int ReplaceIdx;
local int i;
BossIndex = Rand(default.AIBossClassList.Length);
// Ignore normal events.
if (OutbreakEvent.ActiveEvent.bBossRushMode)
{
if (BossRushEnemies.length == 0)
{
for(i=0; i < default.AIBossClassList.length; ++i)
{
BossRushEnemies.AddItem(i);
}
}
}
//Search in the replacement list for the one that the game type wanted to use
// If we find it, grab the appropriate index into the original AI class list
// so we can properly cache it.
foreach OutbreakEvent.ActiveEvent.BossSpawnReplacementList(Replacement)
{
if (Replacement.SpawnEntry == BossIndex)
{
ReplaceIdx = AIBossClassList.Find(Replacement.NewClass);
if (ReplaceIdx != INDEX_NONE)
{
BossIndex = ReplaceIdx;
break;
}
}
}
BossIndex = Rand(default.AIBossClassList.Length);
//Search in the replacement list for the one that the game type wanted to use
// If we find it, grab the appropriate index into the original AI class list
// so we can properly cache it.
foreach OutbreakEvent.ActiveEvent.BossSpawnReplacementList(Replacement)
{
if (Replacement.SpawnEntry == BossIndex)
{
ReplaceIdx = AIBossClassList.Find(Replacement.NewClass);
if (ReplaceIdx != INDEX_NONE)
{
BossIndex = ReplaceIdx;
break;
}
}
}
MyKFGRI.CacheSelectedBoss(BossIndex);
}
@ -439,6 +468,10 @@ function TickZedTime( float DeltaTime )
function WaveEnded(EWaveEndCondition WinCondition)
{
local KFPawn_Human Pawn;
local bool bWasFirstTime;
// This function is called multiple times in a row. Only apply it once.
bWasFirstTime = bWaveStarted;
super.WaveEnded(WinCondition);
@ -456,9 +489,30 @@ function WaveEnded(EWaveEndCondition WinCondition)
}
}
if (WinCondition == WEC_WaveWon && bWasFirstTime)
{
GrantExtraDoshOnWaveWon();
}
DisableGlobalDamage();
}
/** Grant dosh to every player even no matter it's state when a wave is won. */
function GrantExtraDoshOnWaveWon()
{
local KFPlayerController KFPC;
local int ExtraDosh;
//
if (OutbreakEvent.ActiveEvent.bBossRushMode && (WaveNum-1) < OutbreakEvent.ActiveEvent.BossRushOverrideParams.PerWaves.length)
{
ExtraDosh = OutbreakEvent.ActiveEvent.BossRushOverrideParams.PerWaves[WaveNum-1].ExtraDoshGrantedonWaveWon;
foreach WorldInfo.AllControllers(class'KFPlayerController', KFPC)
{
KFPlayerReplicationInfo(KFPC.PlayerReplicationInfo).AddDosh(ExtraDosh, true);
}
}
}
function ClearZedTimePCTimers()
{
local KFPlayerController_WeeklySurvival KFPC;

View File

@ -10,24 +10,42 @@ class KFOutbreakEvent_Weekly extends KFOutbreakEvent;
function OnScoreKill(Pawn KilledPawn)
{
local StatAdjustments ToAdjust;
local int WaveNum;
foreach ActiveEvent.ZedsToAdjust(ToAdjust)
{
if (ClassIsChildOf(KilledPawn.class, ToAdjust.ClassToAdjust))
{
if (ToAdjust.bExplosiveDeath && ToAdjust.ExplosionTemplate != none)
{
//Skip if we shouldn't do the normal death explosion
if (KFPawn(KilledPawn) != none && !KFPawn(KilledPawn).WeeklyShouldExplodeOnDeath())
{
return;
}
if (!ActiveEvent.bBossRushMode)
{
AdjustScoreKill(KilledPawn, ActiveEvent.ZedsToAdjust);
}
else
{
WaveNum = KFGameInfo_WeeklySurvival(Outer).WaveNum - 1;
if ( WaveNum < ActiveEvent.BossRushOverrideParams.PerWaves.length )
{
AdjustScoreKill(KilledPawn, ActiveEvent.BossRushOverrideParams.PerWaves[WaveNum].ZedsToAdjust);
}
}
}
KFGameInfo_WeeklySurvival(Outer).DoDeathExplosion(KilledPawn, ToAdjust.ExplosionTemplate, ToAdjust.ExplosionIgnoreClass);
}
}
}
function AdjustScoreKill(Pawn KilledPawn, array <StatAdjustments> Adjustments)
{
local StatAdjustments ToAdjust;
foreach Adjustments(ToAdjust)
{
if (ClassIsChildOf(KilledPawn.class, ToAdjust.ClassToAdjust))
{
if (ToAdjust.bExplosiveDeath && ToAdjust.ExplosionTemplate != none)
{
//Skip if we shouldn't do the normal death explosion
if (KFPawn(KilledPawn) != none && !KFPawn(KilledPawn).WeeklyShouldExplodeOnDeath())
{
return;
}
KFGameInfo_WeeklySurvival(Outer).DoDeathExplosion(KilledPawn, ToAdjust.ExplosionTemplate, ToAdjust.ExplosionIgnoreClass);
}
}
}
}
function AdjustScoreDamage(Controller InstigatedBy, Pawn DamagedPawn, class<DamageType> damageType)
@ -626,10 +644,270 @@ defaultproperties
(SpawnEntry=AT_GoreFast,NewClass=(class'KFGameContent.KFPawn_ZedGorefastDualBlade'),PercentChance=0.15),
(SpawnEntry=AT_Crawler,NewClass=(class'KFGameContent.KFPawn_ZedCrawlerKing'),PercentChance=0.15),
(SpawnEntry=AT_Bloat,NewClass=(class'KFGameContent.KFPawn_ZedScrake'),PercentChance=0.05),
(SpawnEntry=AT_FleshpoundMini,NewClass=(class'KFGameContent.KFPawn_ZedFleshpound'),PercentChance=0.2)
(SpawnEntry=AT_FleshpoundMini,NewClass=(class'KFGameContent.KFPawn_ZedFleshpound'),PercentChance=0.2)
)}
)}
// Boss Rush
SetEvents[14]={(
EventDifficulty=2,
GameLength=GL_Short,
SpawnRateMultiplier=0,
bBossRushMode=true,
OverrideAmmoPickupModifier=1,
WaveAmmoPickupModifiers={(
0.99, 0.99, 0.99, 0.99, 0.99, 0.99
)},
BossRushOverrideParams={(PerWaves={(
// WAVE 1
(ZedsToAdjust={(
(ClassToAdjust=class'KFGameContent.KFPawn_ZedMatriarch', HealthScale=0.22,DamageDealtScale=0.7, InitialGroundSpeedModifierScale=0.75,ShieldScale=0.22),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedPatriarch', HealthScale=0.22,DamageDealtScale=0.7, InitialGroundSpeedModifierScale=0.75),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedHans', HealthScale=0.22,DamageDealtScale=0.7, InitialGroundSpeedModifierScale=0.75,ShieldScale=0.22),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedFleshpoundKing', HealthScale=0.22,DamageDealtScale=0.7, InitialGroundSpeedModifierScale=0.75,ShieldScale=0.22),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedBloatKing', HealthScale=0.22,DamageDealtScale=0.7, InitialGroundSpeedModifierScale=0.75,ShieldScale=0.22),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedDAR_EMP', HealthScale=0.6,DamageDealtScale=0.5, InitialGroundSpeedModifierScale=0.7),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedDAR_Laser', HealthScale=0.6,DamageDealtScale=0.5, InitialGroundSpeedModifierScale=0.7),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedDAR_Rocket', HealthScale=0.6,DamageDealtScale=0.5, InitialGroundSpeedModifierScale=0.7),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedFleshpoundMini', HealthScale=0.6,DamageDealtScale=0.5, InitialGroundSpeedModifierScale=0.7),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedBloat', HealthScale=0.6,DamageDealtScale=0.5, InitialGroundSpeedModifierScale=0.7),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedHusk', HealthScale=0.6,DamageDealtScale=0.5, InitialGroundSpeedModifierScale=0.7),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedClot_AlphaKing', HealthScale=0.6,DamageDealtScale=0.5, InitialGroundSpeedModifierScale=0.7),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedGorefastDualBlade',HealthScale=0.6,DamageDealtScale=0.5, InitialGroundSpeedModifierScale=0.7),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedBloatKingSubspawn',HealthScale=0.6,DamageDealtScale=0.3, InitialGroundSpeedModifierScale=0.6)
)},
/*SpawnReplacementList={(
(SpawnEntry=AT_Clot,NewClass=(class'KFGameContent.KFPawn_ZedClot_Alpha'),PercentChance=0.15),
(SpawnEntry=AT_AlphaClot,NewClass=(class'KFGameContent.KFPawn_ZedClot_AlphaKing'),PercentChance=0.15),
(SpawnEntry=AT_GoreFast,NewClass=(class'KFGameContent.KFPawn_ZedGorefastDualBlade'),PercentChance=0.15),
(SpawnEntry=AT_Crawler,NewClass=(class'KFGameContent.KFPawn_ZedCrawlerKing'),PercentChance=0.15),
(SpawnEntry=AT_Bloat,NewClass=(class'KFGameContent.KFPawn_ZedScrake'),PercentChance=0.05),
(SpawnEntry=AT_FleshpoundMini,NewClass=(class'KFGameContent.KFPawn_ZedFleshpound'),PercentChance=0.05)
)},*/
DoshOnKillGlobalModifier=0.0f,
ExtraDoshGrantedonWaveWon=1700),
// WAVE 2
(ZedsToAdjust={(
(ClassToAdjust=class'KFGameContent.KFPawn_ZedMatriarch', HealthScale=0.9,DamageDealtScale=0.9, InitialGroundSpeedModifierScale=1.0,ShieldScale=0.9),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedPatriarch', HealthScale=0.9,DamageDealtScale=0.9, InitialGroundSpeedModifierScale=1.0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedHans', HealthScale=0.9,DamageDealtScale=0.9, InitialGroundSpeedModifierScale=1.0,ShieldScale=0.9),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedFleshpoundKing', HealthScale=0.9,DamageDealtScale=0.9, InitialGroundSpeedModifierScale=1.0,ShieldScale=0.9),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedBloatKing', HealthScale=0.9,DamageDealtScale=0.9, InitialGroundSpeedModifierScale=1.0,ShieldScale=0.9),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedDAR_EMP', HealthScale=0.9,DamageDealtScale=0.9, InitialGroundSpeedModifierScale=1.0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedDAR_Laser', HealthScale=0.9,DamageDealtScale=0.9, InitialGroundSpeedModifierScale=1.0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedDAR_Rocket', HealthScale=0.9,DamageDealtScale=0.9, InitialGroundSpeedModifierScale=1.0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedFleshpoundMini', HealthScale=0.9,DamageDealtScale=0.9, InitialGroundSpeedModifierScale=1.0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedBloat', HealthScale=0.9,DamageDealtScale=0.9, InitialGroundSpeedModifierScale=1.0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedHusk', HealthScale=0.9,DamageDealtScale=0.9, InitialGroundSpeedModifierScale=1.0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedClot_AlphaKing', HealthScale=0.9,DamageDealtScale=0.9, InitialGroundSpeedModifierScale=1.0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedGorefastDualBlade',HealthScale=0.9,DamageDealtScale=0.9, InitialGroundSpeedModifierScale=1.0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedBloatKingSubspawn',HealthScale=0.9,DamageDealtScale=0.9, InitialGroundSpeedModifierScale=1.0)
)},
/*SpawnReplacementList={(
(SpawnEntry=AT_Clot,NewClass=(class'KFGameContent.KFPawn_ZedClot_Alpha'),PercentChance=0.15)
)},*/
DoshOnKillGlobalModifier=0.0f,
ExtraDoshGrantedonWaveWon=2000),
// WAVE 3
(ZedsToAdjust={(
(ClassToAdjust=class'KFGameContent.KFPawn_ZedMatriarch', HealthScale=1.0,DamageDealtScale=1.0, InitialGroundSpeedModifierScale=1.0,ShieldScale=1.0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedPatriarch', HealthScale=1.0,DamageDealtScale=1.0, InitialGroundSpeedModifierScale=1.0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedHans', HealthScale=1.0,DamageDealtScale=1.0, InitialGroundSpeedModifierScale=1.0,ShieldScale=1.0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedFleshpoundKing', HealthScale=1.0,DamageDealtScale=1.0, InitialGroundSpeedModifierScale=1.0,ShieldScale=1.0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedBloatKing', HealthScale=1.0,DamageDealtScale=1.0, InitialGroundSpeedModifierScale=1.0,ShieldScale=1.0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedDAR_EMP', HealthScale=1.0,DamageDealtScale=1.0, InitialGroundSpeedModifierScale=1.0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedDAR_Laser', HealthScale=1.0,DamageDealtScale=1.0, InitialGroundSpeedModifierScale=1.0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedDAR_Rocket', HealthScale=1.0,DamageDealtScale=1.0, InitialGroundSpeedModifierScale=1.0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedFleshpoundMini', HealthScale=1.0,DamageDealtScale=1.0, InitialGroundSpeedModifierScale=1.0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedBloat', HealthScale=1.0,DamageDealtScale=1.0, InitialGroundSpeedModifierScale=1.0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedHusk', HealthScale=1.0,DamageDealtScale=1.0, InitialGroundSpeedModifierScale=1.0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedClot_AlphaKing', HealthScale=1.0,DamageDealtScale=1.0, InitialGroundSpeedModifierScale=1.0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedGorefastDualBlade',HealthScale=1.0,DamageDealtScale=1.0, InitialGroundSpeedModifierScale=1.0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedBloatKingSubspawn',HealthScale=1.0,DamageDealtScale=1.0, InitialGroundSpeedModifierScale=1.0)
)},
/*SpawnReplacementList={(
(SpawnEntry=AT_Clot,NewClass=(class'KFGameContent.KFPawn_ZedClot_Alpha'),PercentChance=0.15)
)},*/
DoshOnKillGlobalModifier=0.0f,
ExtraDoshGrantedonWaveWon=2300),
// WAVE 4
(ZedsToAdjust={(
(ClassToAdjust=class'KFGameContent.KFPawn_ZedMatriarch', HealthScale=1.1,DamageDealtScale=1.1, InitialGroundSpeedModifierScale=1.0,ShieldScale=1.1),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedPatriarch', HealthScale=1.1,DamageDealtScale=1.1, InitialGroundSpeedModifierScale=1.0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedHans', HealthScale=1.1,DamageDealtScale=1.1, InitialGroundSpeedModifierScale=1.0,ShieldScale=1.1),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedFleshpoundKing', HealthScale=1.1,DamageDealtScale=1.1, InitialGroundSpeedModifierScale=1.0,ShieldScale=1.1),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedBloatKing', HealthScale=1.1,DamageDealtScale=1.1, InitialGroundSpeedModifierScale=1.0,ShieldScale=1.1),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedDAR_EMP', HealthScale=1.0,DamageDealtScale=1.0, InitialGroundSpeedModifierScale=1.0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedDAR_Laser', HealthScale=1.0,DamageDealtScale=1.0, InitialGroundSpeedModifierScale=1.0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedDAR_Rocket', HealthScale=1.0,DamageDealtScale=1.0, InitialGroundSpeedModifierScale=1.0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedFleshpoundMini', HealthScale=1.0,DamageDealtScale=1.0, InitialGroundSpeedModifierScale=1.0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedBloat', HealthScale=1.0,DamageDealtScale=1.0, InitialGroundSpeedModifierScale=1.0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedHusk', HealthScale=1.0,DamageDealtScale=1.0, InitialGroundSpeedModifierScale=1.0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedClot_AlphaKing', HealthScale=1.0,DamageDealtScale=1.0, InitialGroundSpeedModifierScale=1.0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedGorefastDualBlade',HealthScale=1.0,DamageDealtScale=1.0, InitialGroundSpeedModifierScale=1.0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedBloatKingSubspawn',HealthScale=1.0,DamageDealtScale=1.0, InitialGroundSpeedModifierScale=1.0)
)},
/*SpawnReplacementList={(
(SpawnEntry=AT_Clot,NewClass=(class'KFGameContent.KFPawn_ZedClot_Alpha'),PercentChance=0.15)
)},*/
DoshOnKillGlobalModifier=0.0f,
ExtraDoshGrantedonWaveWon=3000),
// WAVE 5
(ZedsToAdjust={(
(ClassToAdjust=class'KFGameContent.KFPawn_ZedMatriarch', HealthScale=1.4,DamageDealtScale=1.2, InitialGroundSpeedModifierScale=1.2,ShieldScale=1.4),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedPatriarch', HealthScale=1.4,DamageDealtScale=1.2, InitialGroundSpeedModifierScale=1.2),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedHans', HealthScale=1.4,DamageDealtScale=1.2, InitialGroundSpeedModifierScale=1.2,ShieldScale=1.4),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedFleshpoundKing', HealthScale=1.4,DamageDealtScale=1.2, InitialGroundSpeedModifierScale=1.2,ShieldScale=1.4),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedBloatKing', HealthScale=1.4,DamageDealtScale=1.2, InitialGroundSpeedModifierScale=1.2,ShieldScale=1.4),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedDAR_EMP', HealthScale=1.0,DamageDealtScale=1.2, InitialGroundSpeedModifierScale=1.0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedDAR_Laser', HealthScale=1.0,DamageDealtScale=1.0, InitialGroundSpeedModifierScale=1.0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedDAR_Rocket', HealthScale=1.0,DamageDealtScale=1.0, InitialGroundSpeedModifierScale=1.0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedFleshpoundMini', HealthScale=1.0,DamageDealtScale=1.0, InitialGroundSpeedModifierScale=1.0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedBloat', HealthScale=1.0,DamageDealtScale=1.0, InitialGroundSpeedModifierScale=1.0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedHusk', HealthScale=1.0,DamageDealtScale=1.0, InitialGroundSpeedModifierScale=1.0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedClot_AlphaKing', HealthScale=1.0,DamageDealtScale=1.0, InitialGroundSpeedModifierScale=1.0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedGorefastDualBlade',HealthScale=1.0,DamageDealtScale=1.0, InitialGroundSpeedModifierScale=1.0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedBloatKingSubspawn',HealthScale=1.0,DamageDealtScale=1.0, InitialGroundSpeedModifierScale=1.0)
)},
/*SpawnReplacementList={(
(SpawnEntry=AT_Clot,NewClass=(class'KFGameContent.KFPawn_ZedClot_Alpha'),PercentChance=0.15)
)},*/
DoshOnKillGlobalModifier=0.0f,
ExtraDoshGrantedonWaveWon=0)
)}
)}
)}
//Tiny head
SetEvents[15]={(
EventDifficulty=2,
GameLength=GL_Normal,
ZedSpawnHeadScale=0.3,
PlayerSpawnHeadScale=0.2,
bDisableHeadless=true,
SpawnRateMultiplier=1.5,
WaveAICountScale=(0.8, 0.8, 0.8, 0.8, 0.8, 0.8),
DoshOnKillGlobalModifier=1.2,
//GlobalAmmoCostScale = 0.5,
bInvulnerableHeads = true,
BossSpawnReplacementList={(
(SpawnEntry=BAT_Matriarch,NewClass=class'KFGameContent.KFPawn_ZedHans')
)},
SpawnReplacementList={(
(SpawnEntry=AT_Clot,NewClass=(class'KFGameContent.KFPawn_ZedClot_AlphaKing'),PercentChance=0.2),
(SpawnEntry=AT_AlphaClot,NewClass=(class'KFGameContent.KFPawn_ZedClot_AlphaKing'),PercentChance=0.2),
(SpawnEntry=AT_SlasherClot,NewClass=(class'KFGameContent.KFPawn_ZedClot_AlphaKing'),PercentChance=0.2),
//(SpawnEntry=AT_Crawler,NewClass=(class'KFGameContent.KFPawn_ZedGorefastDualBlade'),PercentChance=0.4),
(SpawnEntry=AT_Stalker,NewClass=(class'KFGameContent.KFPawn_ZedGorefastDualBlade'),PercentChance=1.0),
(SpawnEntry=AT_Bloat,NewClass=(class'KFGameContent.KFPawn_ZedBloat'),PercentChance=1.0),
(SpawnEntry=AT_Siren,NewClass=(class'KFGameContent.KFPawn_ZedSiren'),PercentChance=1.0),
(SpawnEntry=AT_Husk,NewClass=(class'KFGameContent.KFPawn_ZedHusk'),PercentChance=1.0),
(SpawnEntry=AT_GoreFast,NewClass=(class'KFGameContent.KFPawn_ZedGorefastDualBlade'),PercentChance=1.0),
(SpawnEntry=AT_FleshPound,NewClass=(class'KFGameContent.KFPawn_ZedScrake'),PercentChance=0.3),
(SpawnEntry=AT_FleshpoundMini,NewClass=(class'KFGameContent.KFPawn_ZedScrake'),PercentChance=0.3),
//(SpawnEntry=AT_EliteClot,NewClass=(class'KFGameContent.KFPawn_ZedCrawler'),PercentChance=0.6),
//(SpawnEntry=AT_EliteGoreFast,NewClass=(class'KFGameContent.KFPawn_ZedCrawler'),PercentChance=0.6),
(SpawnEntry=AT_EDAR_EMP,NewClass=(class'KFGameContent.KFPawn_ZedBloat'),PercentChance=1.0),
(SpawnEntry=AT_EDAR_Laser,NewClass=(class'KFGameContent.KFPawn_ZedBloat'),PercentChance=1.0),
(SpawnEntry=AT_EDAR_Rocket,NewClass=(class'KFGameContent.KFPawn_ZedBloat'),PercentChance=1.0)
)},
ZedsToAdjust={(
//bosses
(ClassToAdjust=class'KFGameContent.KFPawn_ZedHans', HealthScale=1.2,DamageDealtScale=1.0, HitZonesOverride = {(
(ZoneName=armor, GoreHealth=MaxInt, DmgScale=1.3, MaxGoreHealth=MaxInt)
)}, WeakPoints = {(
(BoneName = Spine2, Offset=(X=-5,Y=45,Z=10))
)}),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedPatriarch', HealthScale=1.2,DamageDealtScale=1.0, HitZonesOverride = {(
(ZoneName=rfoot, GoreHealth=MaxInt, DmgScale=1.3, MaxGoreHealth=MaxInt),
(ZoneName=rcalf, GoreHealth=MaxInt, DmgScale=1.3, MaxGoreHealth=MaxInt)
)}, WeakPoints = {(
(BoneName = RightLeg)
)}),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedFleshpoundKing', HealthScale=1.2,DamageDealtScale=1.0, HitZonesOverride = {(
(ZoneName=heart, GoreHealth=MaxInt, DmgScale=1.3, MaxGoreHealth=MaxInt)
)}, WeakPoints = {(
(BoneName = Spine2, Offset=(X=30,Y=-30,Z=10))
)}),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedBloatKing', HealthScale=1.4,DamageDealtScale=1.0, HitZonesOverride = {(
(ZoneName=rupperarm, GoreHealth=MaxInt, DmgScale=1.5, MaxGoreHealth=MaxInt),
(ZoneName=rforearm, GoreHealth=MaxInt, DmgScale=1.5, MaxGoreHealth=MaxInt),
(ZoneName=rhand, GoreHealth=MaxInt, DmgScale=1.5, MaxGoreHealth=MaxInt),
(ZoneName=lupperarm, GoreHealth=MaxInt, DmgScale=1.5, MaxGoreHealth=MaxInt),
(ZoneName=lforearm, GoreHealth=MaxInt, DmgScale=1.5, MaxGoreHealth=MaxInt),
(ZoneName=lhand, GoreHealth=MaxInt, DmgScale=1.5, MaxGoreHealth=MaxInt)
)}, WeakPoints = {(
(BoneName = RightForearm, Offset=(X=15,Y=0,Z=5)),
(BoneName = LeftForearm, Offset=(X=25,Y=15,Z=15))
)}),
//arms
(ClassToAdjust=class'KFGameContent.KFPawn_ZedHusk',HealthScale=1.0,DamageDealtScale=1.0, HitZonesOverride = {(
(ZoneName=rforearm, GoreHealth=MaxInt, DmgScale=3, MaxGoreHealth=MaxInt),
(ZoneName=rupperarm, GoreHealth=MaxInt, DmgScale=3, MaxGoreHealth=MaxInt)
)}, WeakPoints = {(
(BoneName = RightForearm, Offset=(X=20,Y=0,Z=5))
)}),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedScrake',HealthScale=1.0,DamageDealtScale=1.0, HitZonesOverride = {(
(ZoneName=rforearm, GoreHealth=MaxInt, DmgScale=3, MaxGoreHealth=MaxInt),
(ZoneName=rupperarm, GoreHealth=MaxInt, DmgScale=3, MaxGoreHealth=MaxInt)
)}, WeakPoints = {(
(BoneName=RightForearm, Offset=(X=20,Y=0,Z=10))
)}),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedBloat',HealthScale=1.0,DamageDealtScale=1.0, HitZonesOverride = {(
(ZoneName=rupperarm, GoreHealth=MaxInt, DmgScale=4, MaxGoreHealth=MaxInt),
(ZoneName=rforearm, GoreHealth=MaxInt, DmgScale=4, MaxGoreHealth=MaxInt),
(ZoneName=rhand, GoreHealth=MaxInt, DmgScale=4, MaxGoreHealth=MaxInt),
(ZoneName=lupperarm, GoreHealth=MaxInt, DmgScale=4, MaxGoreHealth=MaxInt),
(ZoneName=lforearm, GoreHealth=MaxInt, DmgScale=4, MaxGoreHealth=MaxInt),
(ZoneName=lhand, GoreHealth=MaxInt, DmgScale=4, MaxGoreHealth=MaxInt)
)}, WeakPoints = {(
(BoneName = RightForearm, Offset=(X=20,Y=0,Z=5)),
(BoneName = LeftForearm, Offset=(X=20,Y=7,Z=5))
)}),
//legs
(ClassToAdjust=class'KFGameContent.KFPawn_ZedSiren',HealthScale=1.0,DamageDealtScale=1.0, HitZonesOverride = {(
(ZoneName=rfoot, GoreHealth=MaxInt, DmgScale=3, MaxGoreHealth=MaxInt),
(ZoneName=lfoot, GoreHealth=MaxInt, DmgScale=3, MaxGoreHealth=MaxInt),
(ZoneName=rcalf, GoreHealth=MaxInt, DmgScale=3, MaxGoreHealth=MaxInt),
(ZoneName=lcalf, GoreHealth=MaxInt, DmgScale=3, MaxGoreHealth=MaxInt),
(ZoneName=rthigh, GoreHealth=MaxInt, DmgScale=3, MaxGoreHealth=MaxInt),
(ZoneName=lthigh, GoreHealth=MaxInt, DmgScale=3, MaxGoreHealth=MaxInt)
)}, WeakPoints = {(
(BoneName = RightLeg, Offset=(X=0,Y=0,Z=10)),
(BoneName = LeftLeg, Offset=(X=50,Y=0,Z=10))
)}),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedClot_AlphaKing',HealthScale=1.5,DamageDealtScale=1.0, HitZonesOverride = {(
(ZoneName=rfoot, GoreHealth=MaxInt, DmgScale=3, MaxGoreHealth=MaxInt),
(ZoneName=rcalf, GoreHealth=MaxInt, DmgScale=3, MaxGoreHealth=MaxInt),
(ZoneName=rthigh, GoreHealth=MaxInt, DmgScale=3, MaxGoreHealth=MaxInt)
)}, WeakPoints = {(
(BoneName = RightLeg, Offset=(X=0,Y=0,Z=15))
)}),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedGorefastDualBlade',HealthScale=1.3,DamageDealtScale=1.0, HitZonesOverride = {(
(ZoneName=lfoot, GoreHealth=MaxInt, DmgScale=3, MaxGoreHealth=MaxInt),
(ZoneName=lcalf, GoreHealth=MaxInt, DmgScale=3, MaxGoreHealth=MaxInt),
(ZoneName=lthigh, GoreHealth=MaxInt, DmgScale=3, MaxGoreHealth=MaxInt)
)}, WeakPoints = {(
(BoneName = LeftLeg, Offset=(X=50,Y=0,Z=10))
)}),
//heart
(ClassToAdjust=class'KFGameContent.KFPawn_ZedFleshpoundMini',HealthScale=1.0,DamageDealtScale=1.0, HitZonesOverride = {(
(ZoneName=heart, GoreHealth=MaxInt, DmgScale=3, MaxGoreHealth=MaxInt)
)}, WeakPoints = {(
(BoneName = Spine2, Offset=(X=25,Y=-25,Z=10))
)}),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedFleshpound',HealthScale=1.0,DamageDealtScale=1.0, HitZonesOverride = {(
(ZoneName=heart, GoreHealth=MaxInt, DmgScale=3, MaxGoreHealth=MaxInt)
)}, WeakPoints = {(
(BoneName = Spine2, Offset=(X=30,Y=-30,Z=10))
)})
)}
)}
//Test events from here down. These don't end up in the regular rotation.
// The override ID starts from one higher than the last SetEvents entry above.
// Ex: Big head = 7, Horde = 8

View File

@ -595,25 +595,25 @@ defaultproperties
//Fart is base timer +/- some random amount of the variance, giving you a range of say 25-35 seconds with a base of 30 and variance of 5
// These values are X = 0 health, Y = 100% health
DifficultyFartAttackTimers(0)=(X=5.0,Y=9.0) // Normal
DifficultyFartAttackTimers(1)=(X=4.5,Y=8.5) // Hard
DifficultyFartAttackTimers(2)=(X=4.0,Y=8.0) // Suicidal
DifficultyFartAttackTimers(3)=(X=4.0,Y=7.0) // Hell On Earth
DifficultyFartAttackTimers(0)=(X=4.0,Y=7.0) // Normal //(X=5.0,Y=9.0)
DifficultyFartAttackTimers(1)=(X=3.5,Y=6.0) // Hard //(X=4.5,Y=8.5)
DifficultyFartAttackTimers(2)=(X=3.0,Y=5.5) // Suicidal //(X=4.0,Y=8.0)
DifficultyFartAttackTimers(3)=(X=3.0,Y=5.0) // Hell On Earth //(X=4.0,Y=7.0)
DifficultyVarianceFartTimers(0)=(X=3.0,Y=4.0) // Normal
DifficultyVarianceFartTimers(1)=(X=2.5,Y=3.5) // Hard
DifficultyVarianceFartTimers(2)=(X=2.0,Y=3.0) // Suicidal
DifficultyVarianceFartTimers(3)=(X=2.0,Y=3.0) // Hell On Earth
DifficultyVarianceFartTimers(0)=(X=2.5,Y=3.5) // Normal //(X=3.0,Y=4.0)
DifficultyVarianceFartTimers(1)=(X=2.0,Y=3.0) // Hard //(X=2.5,Y=3.5)
DifficultyVarianceFartTimers(2)=(X=1.5,Y=2.5) // Suicidal //(X=2.0,Y=3.0)
DifficultyVarianceFartTimers(3)=(X=1.5,Y=2.5) // Hell On Earth //(X=2.0,Y=3.0)
DifficultyRageFartTimers(0)=(X=1.75,Y=2.5) // Normal
DifficultyRageFartTimers(1)=(X=1.25,Y=2.0) // Hard
DifficultyRageFartTimers(2)=(X=0.75,Y=1.5) // Suicidal
DifficultyRageFartTimers(3)=(X=0.75,Y=1.5) // Hell On Earth
DifficultyRageFartTimers(0)=(X=1.5,Y=2.25) // Normal //(X=1.75,Y=2.5)
DifficultyRageFartTimers(1)=(X=1.0,Y=1.75) // Hard //(X=1.25,Y=2.0)
DifficultyRageFartTimers(2)=(X=0.5,Y=1.25) // Suicidal //(X=0.75,Y=1.5)
DifficultyRageFartTimers(3)=(X=0.5,Y=1.25) // Hell On Earth //(X=0.75,Y=1.5)
DifficultyVarianceRageFartTimers(0)=(X=1.65,Y=2.1) // Normal
DifficultyVarianceRageFartTimers(1)=(X=1.15,Y=1.6) // Hard
DifficultyVarianceRageFartTimers(2)=(X=0.65,Y=1.1) // Suicidal
DifficultyVarianceRageFartTimers(3)=(X=0.65,Y=1.1) // Hell On Earth
DifficultyVarianceRageFartTimers(0)=(X=1.65,Y=2.1) // Normal //(X=1.65,Y=2.1)
DifficultyVarianceRageFartTimers(1)=(X=1.15,Y=1.6) // Hard //(X=1.15,Y=1.6)
DifficultyVarianceRageFartTimers(2)=(X=0.65,Y=1.1) // Suicidal //(X=0.65,Y=1.1)
DifficultyVarianceRageFartTimers(3)=(X=0.65,Y=1.1) // Hell On Earth //(X=0.65,Y=1.1)
//Offset from center of the BK to spawn the poop monster
PoopMonsterOffset=-100
@ -622,7 +622,7 @@ defaultproperties
PoopMonsterFXSocket=Poop_Attach
//Amount of time between spawns
PoopMonsterSpawnDelay=2.f
PoopMonsterSpawnDelay=1.5 //2.f
// Used for special crawler gas AOE attack "explosion" template FART ATTACK
Begin Object Class=KFGameExplosion Name=ExploTemplate0
@ -708,9 +708,9 @@ defaultproperties
RotationRate=(Pitch=50000,Yaw=20000,Roll=50000)
GroundSpeed=450.0f //160 //210 //231 //255
SprintSpeed=450.0f //260 //210 410 //315 //330 //345 //380
RageSprintSpeedMultiplier=1.3f //1.25 1.45 //1.55
RageSprintSpeedMultiplier=1.5f //1.3f //1.25 1.45 //1.55
VomitRange=400.f
VomitRange=440.f //400.f
VomitDamage=20
ArmorInfoClass=class'KFZedArmorInfo_BloatKing'
@ -734,7 +734,7 @@ defaultproperties
IncapSettings(AF_Microwave)=(Vulnerability=(0.08), Cooldown=10.0, Duration=3.0)
IncapSettings(AF_FirePanic)=(Vulnerability=(0.65), Cooldown=15.0, Duration=1.2)
IncapSettings(AF_EMP)= (Vulnerability=(0.5), Cooldown=10.0, Duration=2.2)
IncapSettings(AF_Freeze)= (Vulnerability=(0.5), Cooldown=10.0, Duration=1.0)
IncapSettings(AF_Freeze)= (Vulnerability=(0.3), Cooldown=15.0, Duration=1.0)
IncapSettings(AF_Snare)= (Vulnerability=(1.0, 2.0, 1.0, 1.0, 2.0), Cooldown=10.5, Duration=3.0)
IncapSettings(AF_Bleed)= (Vulnerability=(0.15), Cooldown=10.0)

View File

@ -116,7 +116,7 @@ defaultproperties
// Used for special crawler gas AOE attack "explosion" template
Begin Object Class=KFGameExplosion Name=ExploTemplate0
Damage=15 //50 //12 //16
Damage=12 //15 //50 //12 //16
DamageRadius=350 //600 //450 //400 //425
DamageFalloffExponent=0.f
DamageDelay=0.f
@ -179,7 +179,7 @@ defaultproperties
MyDamageType=class'KFDT_Slashing_ZedWeak'
End Object
Health=250 //55 //450 //700 //900 //810
Health=150 //250 //55 //450 //700 //900 //810
DoshValue=10
Mass=50.f
bKnockdownWhenJumpedOn=true

View File

@ -645,7 +645,7 @@ DefaultProperties
ShieldHealthMaxDefaults[1]=2700 //3000
ShieldHealthMaxDefaults[2]=4000//2000 //3000
ShieldHealthMaxDefaults[3]=5000
ShieldHealthScale=1.f
ShieldHealthScale=1.1f //1.f
// Penetration
PenetrationResistance=5.0
@ -686,7 +686,7 @@ DefaultProperties
DamageTypeModifiers.Add((DamageType=class'KFDT_Bleeding_HRG_Vampire_BloodSuck', DamageScale=(0.7)))
Begin Object Class=KFGameExplosion Name=ExploTemplate0
Damage=40 //20
Damage=44 //40 //20
DamageRadius=900 //600 //700
DamageFalloffExponent=2.f
DamageDelay=0.f
@ -714,7 +714,7 @@ DefaultProperties
RagePoundExplosionTemplate=ExploTemplate0
Begin Object Class=KFGameExplosion Name=ExploTemplate1
Damage=50 //30
Damage=55 //50 //30
DamageRadius=900 //600 //700
DamageFalloffExponent=2.f
DamageDelay=0.f
@ -760,8 +760,8 @@ DefaultProperties
CollisionRadius=+0055.000000
End Object
GroundSpeed=300.f //260
SprintSpeed=700.f //600
GroundSpeed=345.f //300.f //260
SprintSpeed=805.f //700.f //600
ReachedEnemyThresholdScale=1.f
PhysRagdollImpulseScale=1.5f
KnockdownImpulseScale=2.0f

View File

@ -42,6 +42,13 @@ simulated event SetInitialState()
function GiveTo( Pawn P )
{
local KFInventoryManager KFIM;
local KFGameReplicationInfo KFGRI;
KFGRI = KFGameReplicationInfo(WorldInfo.GRI);
if(KFGRI != none && KFGRI.bIsEndlessPaused)
{
return;
}
KFIM = KFInventoryManager(P.InvManager);
if ( KFIM != None )

View File

@ -532,8 +532,8 @@ defaultproperties
LifeSpan=0
FuseDuration=300
PostExplosionLifetime=1
Speed=1000 //500
MaxSpeed=1000 //500
Speed=1500 //1000 //500
MaxSpeed=1500 //1000 //500
Physics=PHYS_Falling
bBounce=true
bNetTemporary=false

View File

@ -0,0 +1,48 @@
//=============================================================================
// KFProj_Bullet_Pellet
//=============================================================================
// Shotgun pellet class
//=============================================================================
// Killing Floor 2
// Copyright (C) 2015 Tripwire Interactive LLC
//=============================================================================
class KFProj_Bullet_HRG_Stunner extends KFProj_Bullet
hidedropdown;
/** Cached reference to owner weapon */
var protected KFWeapon OwnerWeapon;
/** Initialize the projectile */
function Init( vector Direction )
{
super.Init( Direction );
OwnerWeapon = KFWeapon( Owner );
if( OwnerWeapon != none )
{
OwnerWeapon.LastPelletFireTime = WorldInfo.TimeSeconds;
}
}
/** Don't allow more than one pellet projectile to perform this check in a single frame */
function bool ShouldWarnAIWhenFired()
{
return super.ShouldWarnAIWhenFired() && OwnerWeapon != none && OwnerWeapon.LastPelletFireTime < WorldInfo.TimeSeconds;
}
defaultproperties
{
MaxSpeed=7000.0
Speed=7000.0
bWarnAIWhenFired=true
DamageRadius=0
ProjFlightTemplate=ParticleSystem'WEP_HRG_Stunner_EMIT.FX_HRG_Stunner_Tracer'
ProjFlightTemplateZedTime=ParticleSystem'WEP_HRG_Stunner_EMIT.FX_HRG_Stunner_Tracer_ZEDTime'
AmbientSoundPlayEvent=none
AmbientSoundStopEvent=none
}

View File

@ -0,0 +1,107 @@
//=============================================================================
// KFProj_Bullet_HRG_Boomy
//=============================================================================
// Class Description
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFProj_Bullet_HRG_Stunner_Alt extends KFProj_BallisticExplosive
hidedropdown;
var protected KFWeapon OwnerWeapon;
/** Initialize the projectile */
function Init( vector Direction )
{
super.Init( Direction );
OwnerWeapon = KFWeapon( Owner );
if( OwnerWeapon != none )
{
OwnerWeapon.LastPelletFireTime = WorldInfo.TimeSeconds;
}
}
/** Don't allow more than one pellet projectile to perform this check in a single frame */
function bool ShouldWarnAIWhenFired()
{
return super.ShouldWarnAIWhenFired() && OwnerWeapon != none && OwnerWeapon.LastPelletFireTime < WorldInfo.TimeSeconds;
}
simulated protected function PrepareExplosionTemplate()
{
super.PrepareExplosionTemplate();
/** Since bIgnoreInstigator is transient, its value must be defined here */
ExplosionTemplate.bIgnoreInstigator = true;
}
simulated function AdjustCanDisintigrate() {}
/** Can be overridden in subclasses to exclude specific projectiles from nuking */
simulated function bool AllowNuke()
{
return false;
}
defaultproperties
{
MaxSpeed=22500.0
Speed=22500.0
DamageRadius=0
ProjDisintegrateTemplate=ParticleSystem'ZED_Siren_EMIT.FX_Siren_grenade_disable_01'
ProjFlightTemplate=ParticleSystem'WEP_HRG_Stunner_EMIT.FX_HRG_Stunner_ALT_Tracer_ZEDTime'
ProjFlightTemplateZedTime=ParticleSystem'WEP_HRG_Stunner_EMIT.FX_HRG_Stunner_ALT_Tracer_ZEDTime'
// Grenade explosion light
Begin Object Class=PointLightComponent Name=ExplosionPointLight
LightColor=(R=252,G=218,B=171,A=255)
Brightness=0.5f
Radius=400.f
FalloffExponent=10.f
CastShadows=False
CastStaticShadows=FALSE
CastDynamicShadows=False
bCastPerObjectShadows=false
bEnabled=FALSE
LightingChannels=(Indoor=TRUE,Outdoor=TRUE,bInitialized=TRUE)
End Object
// explosion
Begin Object Class=KFGameExplosion Name=ExploTemplate0
Damage=40 //50
DamageRadius=300 //250 //150
DamageFalloffExponent=2.f
DamageDelay=0.f
MomentumTransferScale=10000
// Damage Effects
MyDamageType=class'KFDT_Explosive_HRG_Stunner'
KnockDownStrength=150
FractureMeshRadius=200.0
FracturePartVel=500.0
ExplosionSound=AkEvent'WW_WEP_HRG_Stunner.Play_WEP_HRG_Stunner_Alt_Fire_Explosion'
ExplosionEffects=KFImpactEffectInfo'WEP_HRG_Stunner_ARCH.WEB_HRG_Stunner_Impacts'
// Dynamic Light
ExploLight=ExplosionPointLight
ExploLightStartFadeOutTime=0.0
ExploLightFadeOutTime=0.3
bIgnoreInstigator=true
// Camera Shake
CamShake=CameraShake'FX_CameraShake_Arch.Misc_Explosions.Light_Explosion_Rumble'
CamShakeInnerRadius=0
CamShakeOuterRadius=300
CamShakeFalloff=1.5f
bOrientCameraShakeTowardsEpicenter=true
End Object
ExplosionTemplate=ExploTemplate0
}

View File

@ -0,0 +1,240 @@
//=============================================================================
// KFProj_Dosh
//=============================================================================
// Projectile for the doshinegun
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFProj_Dosh extends KFProj_RicochetBullet
hidedropdown;
`define KFPROJ_DOSH_CACHED_LOCATION 20
var PrimitiveComponent DroppedPickupMesh;
/** Dampen amount for every bounce */
var() float DampenFactor;
/** Dampen amount for parallel angle to velocity */
var() float DampenFactorParallel;
var transient Vector PreviousLocations [`KFPROJ_DOSH_CACHED_LOCATION];
var transient rotator PreviousRotations [`KFPROJ_DOSH_CACHED_LOCATION];
// Make sure that last location always exists.
simulated event PostBeginPlay()
{
Super.PostBeginPlay();
}
event Tick( float DeltaTime )
{
local int i;
for (i = `KFPROJ_DOSH_CACHED_LOCATION - 1; i > 0; --i)
{
PreviousLocations[i] = PreviousLocations[i-1];
PreviousRotations[i] = PreviousRotations[i-1];
}
if (`KFPROJ_DOSH_CACHED_LOCATION > 0)
{
PreviousLocations[0] = Location;
PreviousRotations[0] = Rotation;
}
}
/**
* Give a little bounce
*/
simulated event HitWall(vector HitNormal, Actor Wall, PrimitiveComponent WallComp)
{
local TraceHitInfo HitInfo;
// check to make sure we didn't hit a pawn
if( Pawn(Wall) == none )
{
if (!Wall.bStatic && Wall.bCanBeDamaged && (DamageRadius == 0 || bDamageDestructiblesOnTouch) && !CheckRepeatingTouch(Wall) )
{
HitInfo.HitComponent = WallComp;
HitInfo.Item = INDEX_None;
Wall.TakeDamage( Damage, InstigatorController, Location, MomentumTransfer * Normal(Velocity), MyDamageType, HitInfo, self);
}
}
Bounce( HitNormal, Wall );
}
/** Adjusts movement/physics of projectile.
* Returns true if projectile actually bounced / was allowed to bounce */
simulated function bool Bounce( vector HitNormal, Actor BouncedOff)
{
Velocity = DampingFactor * (Velocity - 2.0*HitNormal*(Velocity dot HitNormal));
if( WorldInfo.NetMode != NM_DedicatedServer )
{
// do the impact effects
`ImpactEffectManager.PlayImpactEffects(Location, Instigator, HitNormal, ImpactEffects );
}
// also done from ProcessDestructibleTouchOnBounce. update LastBounced to solve problem with bouncing rapidly between world/non-world geometry
LastBounced.Actor = BouncedOff;
LastBounced.Time = WorldInfo.TimeSeconds;
SpawnDosh(BouncedOff);
Destroy();
return true;
}
function SpawnDosh(Actor BouncedOff)
{
local KFDroppedPickup_Cash P;
local int i;
if ( WorldInfo.NetMode == NM_Client )
return;
if (Pawn(BouncedOff) == none)
{
P = Spawn(class'KFDroppedPickup_Cash',,, Location, Rotation,, false);
if (P == none)
{
for (i = 0; i < `KFPROJ_DOSH_CACHED_LOCATION; ++i)
{
P = Spawn(class'KFDroppedPickup_Cash',,, PreviousLocations[i], PreviousRotations[i],, false);
if (P != none)
{
break;
}
}
}
}
else
{
P = Spawn(class'KFDroppedPickup_Cash',,, Location, Rotation,, true);
}
if( P == None )
{
Destroy();
}
else
{
P.SetPhysics(PHYS_Falling);
P.InventoryClass = class'KFInventory_Money';
P.Inventory = Instigator.CreateInventory(P.InventoryClass);
P.Velocity = Velocity;
P.Instigator = Instigator;
P.SetPickupMesh(DroppedPickupMesh);
P.SetPickupParticles(none);
P.CashAmount = class'KFWeap_AssaultRifle_Doshinegun'.default.DoshCost;
}
}
//==============
// Touching
// Overridden to get bouncing off of destructible meshes
simulated function ProcessTouch(Actor Other, Vector HitLocation, Vector HitNormal)
{
local KFPawn KFP;
local KFPawn_Human KFPH;
local KFPlayerReplicationInfo KFPRI;
KFPH = KFPawn_Human(Other);
if ( KFPH != none && KFPH != Instigator)
{
KFPRI = KFPlayerReplicationInfo(KFPH.PlayerReplicationInfo);
if (KFPRI != none)
{
KFPRI.AddDosh(class'KFWeap_AssaultRifle_Doshinegun'.default.DoshCost);
Destroy();
return;
}
}
else if ( Other != Instigator && Other.bCanBeDamaged && (!Other.bWorldGeometry || !Other.bStatic) )
{
KFP = KFPawn( Other );
if ( KFP != None )
{
// check/ignore repeat touch events
if( CheckRepeatingTouch(Other) )
{
return;
}
ProcessBulletTouch(Other, HitLocation, HitNormal);
Bounce(HitNormal, Other);
return;
}
else
{
ProcessDestructibleTouchOnBounce( Other, HitLocation, HitNormal );
return;
}
}
super.ProcessTouch(Other, HitLocation, HitNormal);
}
simulated function SyncOriginalLocation()
{
local Actor HitActor;
local vector HitLocation, HitNormal;
local TraceHitInfo HitInfo;
if (Role < ROLE_Authority && Instigator != none && Instigator.IsLocallyControlled())
{
HitActor = Trace(HitLocation, HitNormal, OriginalLocation, Location,,, HitInfo, TRACEFLAG_Bullet);
if (HitActor != none)
{
Bounce(HitNormal, HitActor);
}
}
Super.SyncOriginalLocation();
}
defaultproperties
{
MaxSpeed=7500.0 //5000.0
Speed=7500.0 //5000.0
GravityScale=0.57 //0.4
Physics=PHYS_Falling
TossZ=100 //150
MomentumTransfer=50000.0
DamageRadius=0
bWarnAIWhenFired=true
BouncesLeft=1
DampingFactor=0.1
DampenFactor=0.250000
DampenFactorParallel=0.400000
LifeSpan=120 //8
bNetTemporary=False
NetPriority=5
NetUpdateFrequency=200
ProjFlightTemplate=ParticleSystem'WEP_Doshinegun_EMIT.PS_Trail'
ProjFlightTemplateZedTime=ParticleSystem'WEP_Doshinegun_EMIT.PS_Trail'
ImpactEffects=KFImpactEffectInfo'WEP_Doshinegun_ARCH.Dosh_Impact'
Begin Object Class=SkeletalMeshComponent Name=PickupMesh0
SkeletalMesh=SkeletalMesh'GP_Mesh.dosh_SM'
PhysicsAsset=PhysicsAsset'GP_Mesh.dosh_SM_Physics'
BlockNonZeroExtent=false
CastShadow=false
End Object
DroppedPickupMesh=PickupMesh0
}

View File

@ -122,8 +122,8 @@ simulated function Landed( Vector HitNormal, actor FloorActor )
defaultproperties
{
MaxSpeed=14000.0
Speed=14000.0
MaxSpeed=17500.0 //14000.0
Speed=17500.0 //14000.0
bWarnAIWhenFired=true

View File

@ -349,9 +349,9 @@ DefaultProperties
// KFSM_FleshpoundKing_ChestBeam
BeamDamageType=class'KFDT_FleshpoundKing_ChestBeam'
BeamExtent=(X=15.0f, Y=15.0f, Z=15.0f)
MaxBeamLength=2500.0f //1300
MaxBeamLength=3000.0f //2500.0f //1300
DamageInterval=0.1f
DamagePerTick=10 //15 //7
DamagePerTick=12 //10 //15 //7
DamageMomentumImpulse=100.0f
TimeUntilTargetChange=0.75f

View File

@ -0,0 +1,135 @@
//=============================================================================
// KFSeasonalEventStats_Xmas2021
//=============================================================================
// Tracks event-specific challenges/accomplishments for Xmas 2020
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFSeasonalEventStats_Xmas2021 extends KFSeasonalEventStats;
var private int WeaponRequiredPrice;
var transient private const int DecapitationsRequired, DoshRequired, WeaponsRequired, EndlessWaveRequired;
private event Initialize(string MapName)
{
local string CapsMapName;
CapsMapName = Caps(MapName);
bObjectiveIsValidForMap[0] = 1; // Decapitate 1000 Zeds on any map or mode
bObjectiveIsValidForMap[1] = 0; // Complete the Weekly on Carillon Hamlet
bObjectiveIsValidForMap[2] = 0; // Earn 75,000 Dosh through kills, rewards and healing on Carillon Hamlet
bObjectiveIsValidForMap[3] = 0; // Use the trader to purchase a total of 20 weapons that cost 1500 Dosh or more on Carrion Hamlet.
bObjectiveIsValidForMap[4] = 0; // Complete wave 15 on Endless Hard or higher difficulty on Carillon Hamlet
if (CapsMapName == "KF-CARILLONHAMLET")
{
bObjectiveIsValidForMap[1] = 1;
bObjectiveIsValidForMap[2] = 1;
bObjectiveIsValidForMap[3] = 1;
bObjectiveIsValidForMap[4] = 1;
}
SetSeasonalEventStatsMax(DecapitationsRequired, 0, DoshRequired, WeaponsRequired, 0);
}
private event GrantEventItems()
{
if (Outer.IsEventObjectiveComplete(0) &&
Outer.IsEventObjectiveComplete(1) &&
Outer.IsEventObjectiveComplete(2) &&
Outer.IsEventObjectiveComplete(3) &&
Outer.IsEventObjectiveComplete(4))
{
//@TODO: Update me
GrantEventItem(9177);
}
}
simulated function OnZedKilledByHeadshot(class<KFPawn_Monster> MonsterClass, int Difficulty, class<DamageType> DT)
{
local int ObjIdx;
// Hellmark Station decapitate 600 zeds
ObjIdx = 0;
if (bObjectiveIsValidForMap[ObjIdx] != 0)
{
IncrementSeasonalEventStat(ObjIdx, 1);
if (Outer.GetSeasonalEventStatValue(ObjIdx) >= DecapitationsRequired)
{
FinishedObjective(SEI_Winter, ObjIdx);
}
}
}
simulated event OnGameWon(class<GameInfo> GameClass, int Difficulty, int GameLength, bool bCoOp)
{
local int ObjIdx;
ObjIdx = 1;
// Carillon weekly
if (bObjectiveIsValidForMap[ObjIdx] != 0)
{
if (GameClass == class'KFGameInfo_WeeklySurvival')
{
FinishedObjective(SEI_Winter, ObjIdx);
}
}
}
simulated event OnWeaponPurchased(class<KFWeaponDefinition> WeaponDef, int Price)
{
local int ObjIdx;
// Purchase weapons with a price >= 1500
ObjIdx = 3;
if (bObjectiveIsValidForMap[ObjIdx] != 0 && Price >= WeaponRequiredPrice)
{
IncrementSeasonalEventStat(ObjIdx, 1);
if (Outer.GetSeasonalEventStatValue(ObjIdx) >= WeaponsRequired)
{
FinishedObjective(SEI_Winter, ObjIdx);
}
}
}
simulated event OnWaveCompleted(class<GameInfo> GameClass, int Difficulty, int WaveNum)
{
local int ObjIdx;
local int TotalDoshEarned;
// Earn 75,000 Dosh through kills, rewards and healing on Carillon Hamlet
ObjIdx = 2;
if (bObjectiveIsValidForMap[ObjIdx] != 0)
{
TotalDoshEarned = Outer.MyKFPC.MatchStats.TotalDoshEarned + Outer.MyKFPC.MatchStats.GetDoshEarnedInWave();
if(TotalDoshEarned > 0)
{
IncrementSeasonalEventStat(ObjIdx, TotalDoshEarned);
if (Outer.GetSeasonalEventStatValue(ObjIdx) >= DoshRequired)
{
FinishedObjective(SEI_Winter, ObjIdx);
}
}
}
// Complete wave 15 on Endless Hard or higher difficulty on Carillon
ObjIdx = 4;
if (bObjectiveIsValidForMap[ObjIdx] != 0)
{
if (WaveNum >= EndlessWaveRequired && GameClass == class'KFGameInfo_Endless' && Difficulty >= `DIFFICULTY_HARD)
{
FinishedObjective(SEI_Winter, ObjIdx);
}
}
}
defaultproperties
{
DecapitationsRequired=1000
DoshRequired=75000
WeaponsRequired=20
EndlessWaveRequired=15
WeaponRequiredPrice=1500
}

View File

@ -20,12 +20,10 @@ function Activated()
if (KFGI.MyKFGRI != none && KFGI.MyKFGRI.bIsWeeklyMode && class'KFGameEngine'.static.GetWeeklyEventIndexMod() == WeeklyIndex)
{
OutputLinks[0].bHasImpulse = true;
OutputLinks[0].bHasImpulse = false;
}
else
{
OutputLinks[0].bHasImpulse = false;
OutputLinks[0].bHasImpulse = true;
OutputLinks[1].bHasImpulse = true;
}
}
}

View File

@ -0,0 +1,34 @@
//=============================================================================
// KFWeapAttach_Doshinegun
//=============================================================================
//
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFWeapAttach_Doshinegun extends KFWeaponAttachment;
/** Play a melee attack animation */
simulated function float PlayMeleeAtkAnim(EWeaponState NewWeaponState, KFPawn P)
{
local name AnimName;
if( P.IsFirstPerson() )
{
return 0.0f;
}
if (NewWeaponState == WEP_MeleeBasic)
{
AnimName = P.bIsCrouched ? CH_MeleeBasic : MeleeBasic;
return PlayCharacterMeshAnim(P, AnimName, true);
}
return super.PlayMeleeAtkAnim(NewWeaponState, P);
}
defaultproperties
{
}

View File

@ -0,0 +1,249 @@
//=============================================================================
// KFWeap_AssaultRifle_Doshinegun
//=============================================================================
// Like if we were rich...
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFWeap_AssaultRifle_Doshinegun extends KFWeap_RifleBase;
var int DoshCost;
var transient KFPlayerReplicationInfo KFPRI;
var transient bool bIsBeingDropped;
simulated function Activate()
{
local KFPawn KFP;
super.Activate();
if (KFPRI == none)
{
KFP = KFPawn(Instigator);
if (KFP != none)
{
KFPRI = KFPlayerReplicationInfo(KFP.PlayerReplicationInfo);
}
}
}
simulated function bool HasAnyAmmo()
{
return bIsBeingDropped ? AmmoCount[0] > 0 : (AmmoCount[0] > 0 || KFPRI.Score >= DoshCost);
}
/** Returns true if weapon can potentially be reloaded */
simulated function bool CanReload(optional byte FireModeNum)
{
return KFPRI.Score >= DoshCost && AmmoCount[FireModeNum] < MagazineCapacity[FireModeNum];
}
/** Performs actual ammo reloading */
simulated function PerformReload(optional byte FireModeNum)
{
local int ReloadAmount;
local int AmmoType;
AmmoType = GetAmmoType(FireModeNum);
if ( bInfiniteSpareAmmo )
{
AmmoCount[AmmoType] = MagazineCapacity[AmmoType];
ReloadAmountLeft = 0;
return;
}
if ( (Role == ROLE_Authority && !bAllowClientAmmoTracking) || (Instigator.IsLocallyControlled() && bAllowClientAmmoTracking) )
{
ReloadAmount = Min(MagazineCapacity[0] - AmmoCount[0], KFPRI.Score / DoshCost);
AmmoCount[AmmoType] = Min(AmmoCount[AmmoType] + ReloadAmount, MagazineCapacity[AmmoType]);
KFPRI.AddDosh(-ReloadAmount * DoshCost);
}
ReloadAmountLeft = 0;
ShotsHit = 0;
}
function int AddAmmo(int Amount)
{
return 0;
}
simulated function bool CanBuyAmmo()
{
return false;
}
static simulated event bool UsesAmmo()
{
return true;
}
// Overriden to deactivate low ammo dialogue
simulated state Reloading
{
simulated function EndState(Name NextStateName)
{
local int ActualReloadAmount;
ClearZedTimeResist();
ClearTimer(nameof(ReloadStatusTimer));
ClearTimer(nameof(ReloadAmmoTimer));
ClearPendingFire(RELOAD_FIREMODE);
if ( bAllowClientAmmoTracking && Role < ROLE_Authority )
{
// Get how much total ammo was reloaded on the client side over the entire course of the reload.
ActualReloadAmount = InitialReloadAmount - ReloadAmountLeft;
// Sync spare ammo counts using initial spare ammo, and how much ammo has been reloaded since reload began.
ServerSyncReload(InitialReloadSpareAmmo - ActualReloadAmount);
}
CheckBoltLockPostReload();
NotifyEndState();
CurrentFireMode = DEFAULT_FIREMODE;
ReloadStatus = RS_None;
}
}
/**
* Drop this item out in to the world
*/
function DropFrom(vector StartLocation, vector StartVelocity)
{
bIsBeingDropped=true;
super.DropFrom(StartLocation, StartVelocity);
}
function SetOriginalValuesFromPickup( KFWeapon PickedUpWeapon )
{
local KFPawn KFP;
bIsBeingDropped=false;
// Reset the replication info
KFP = KFPawn(Instigator);
if (KFP != none)
{
KFPRI = KFPlayerReplicationInfo(KFP.PlayerReplicationInfo);
}
super.SetOriginalValuesFromPickup(PickedUpWeapon);
}
defaultproperties
{
// FOV
MeshFOV=65
MeshIronSightFOV=45 //52
PlayerIronSightFOV=70
// Depth of field
DOF_FG_FocalRadius=150 //85
DOF_FG_MaxNearBlurSize=1 //2.5
// Content
PackageKey="Doshinegun"
FirstPersonMeshName="WEP_1P_Doshinegun_MESH.Wep_1stP_Doshinegun_Rig"
FirstPersonAnimSetNames(0)="WEP_1P_Doshinegun_ANIM.Wep_1st_Doshinegun_Anim"
PickupMeshName="WEP_3P_Doshinegun_MESH.Wep_Doshinegun_Pickup"
AttachmentArchetypeName="WEP_Doshinegun_ARCH.Wep_Doshinegun_3P"
MuzzleFlashTemplateName="WEP_Doshinegun_ARCH.Wep_Doshinegun_MuzzleFlash"
// Zooming/Position
PlayerViewOffset=(X=1.0,Y=8.5,Z=-3)
IronSightPosition=(X=5.0,Y=0.05,Z=-1.2)
// Ammo
MagazineCapacity[0]=20
SpareAmmoCapacity[0]=0
InitialSpareMags[0]=0
AmmoPickupScale[0]=0.0
bCanBeReloaded=true
bReloadFromMagazine=true
// Recoil
maxRecoilPitch=250 //150
minRecoilPitch=200 //115
maxRecoilYaw=115
minRecoilYaw=-115
RecoilRate=0.085
RecoilMaxYawLimit=500
RecoilMinYawLimit=65035
RecoilMaxPitchLimit=900
RecoilMinPitchLimit=65035
RecoilISMaxYawLimit=75
RecoilISMinYawLimit=65460
RecoilISMaxPitchLimit=375
RecoilISMinPitchLimit=65460
RecoilViewRotationScale=0.25
IronSightMeshFOVCompensationScale=1.5
HippedRecoilModifier=1.5
// Inventory / Grouping
InventorySize=4 //6
GroupPriority=50
WeaponSelectTexture=Texture2D'WEP_UI_Doshinegun_TEX.UI_Weapon_Select_Doshinegun'
//AssociatedPerkClasses(0)=class'KFPerk_Survivalist'
AssociatedPerkClasses(0)=none
// DEFAULT_FIREMODE
FireModeIconPaths(DEFAULT_FIREMODE)=Texture2D'ui_firemodes_tex.UI_FireModeSelect_BulletAuto'
FiringStatesArray(DEFAULT_FIREMODE)=WeaponFiring
WeaponFireTypes(DEFAULT_FIREMODE)=EWFT_Projectile
WeaponProjectiles(DEFAULT_FIREMODE)=class'KFProj_Dosh'
InstantHitDamageTypes(DEFAULT_FIREMODE)=class'KFDT_Bludgeon_Doshinegun_Shot'
FireInterval(DEFAULT_FIREMODE)=+0.2
Spread(DEFAULT_FIREMODE)=0.015
InstantHitDamage(DEFAULT_FIREMODE)=60.0 //55.0 //60.0
FireOffset=(X=30,Y=4.5,Z=-5)
// ALT_FIREMODE
FireModeIconPaths(ALTFIRE_FIREMODE)=Texture2D'ui_firemodes_tex.UI_FireModeSelect_BulletSingle'
FiringStatesArray(ALTFIRE_FIREMODE)=WeaponSingleFiring
WeaponFireTypes(ALTFIRE_FIREMODE)=EWFT_Projectile
WeaponProjectiles(ALTFIRE_FIREMODE)=class'KFProj_Dosh'
InstantHitDamageTypes(ALTFIRE_FIREMODE)=class'KFDT_Bludgeon_Doshinegun_Shot'
FireInterval(ALTFIRE_FIREMODE)=+0.2
InstantHitDamage(ALTFIRE_FIREMODE)=60.0 //55.0 //60.0
Spread(ALTFIRE_FIREMODE)=0.015
// BASH_FIREMODE
InstantHitDamageTypes(BASH_FIREMODE)=class'KFDT_Bludgeon_Doshinegun'
InstantHitDamage(BASH_FIREMODE)=26
// Fire Effects
WeaponFireSnd(DEFAULT_FIREMODE)=(DefaultCue=AkEvent'WW_WEP_Doshinegun.Play_WEP_Doshinegun_Shoot_Fire_3P_Loop', FirstPersonCue=AkEvent'WW_WEP_Doshinegun.Play_WEP_Doshinegun_Shoot_Fire_1P_Loop')
WeaponFireSnd(ALTFIRE_FIREMODE)=(DefaultCue=AkEvent'WW_WEP_Doshinegun.Play_WEP_Doshinegun_Fire_3P', FirstPersonCue=AkEvent'WW_WEP_Doshinegun.Play_WEP_Doshinegun_Fire_1P')
WeaponFireLoopEndSnd(DEFAULT_FIREMODE)=(DefaultCue=AkEvent'WW_WEP_Doshinegun.Play_WEP_Doshinegun_Shoot_Fire_3P_EndLoop', FirstPersonCue=AkEvent'WW_WEP_Doshinegun.Play_WEP_Doshinegun_Shoot_Fire_1P_EndLoop')
WeaponDryFireSnd(DEFAULT_FIREMODE)=AkEvent'WW_WEP_Doshinegun.Play_WEP_Doshinegun_Dry_Fire'
WeaponDryFireSnd(ALTFIRE_FIREMODE)=AkEvent'WW_WEP_Doshinegun.Play_WEP_Doshinegun_Dry_Fire'
// Advanced (High RPM) Fire Effects
bLoopingFireAnim(DEFAULT_FIREMODE)=true
bLoopingFireSnd(DEFAULT_FIREMODE)=true
SingleFireSoundIndex=ALTFIRE_FIREMODE
// Attachments
bHasIronSights=true
bHasFlashlight=false
// Weapon Upgrade stat boosts
//WeaponUpgrades[1]=(IncrementDamage=1.3f,IncrementWeight=1)
//WeaponUpgrades[2]=(IncrementDamage=1.65f,IncrementWeight=2)
//WeaponUpgrades[3]=(IncrementDamage=1.85f,IncrementWeight=3)
WeaponUpgrades[1]=(Stats=((Stat=EWUS_Damage0, Scale=1.23f), (Stat=EWUS_Damage1, Scale=1.2f), (Stat=EWUS_Weight, Add=1)))
WeaponUpgrades[2]=(Stats=((Stat=EWUS_Damage0, Scale=1.47f), (Stat=EWUS_Damage1, Scale=1.4f), (Stat=EWUS_Weight, Add=2)))
WeaponUpgrades[3]=(Stats=((Stat=EWUS_Damage0, Scale=1.70f), (Stat=EWUS_Damage1, Scale=1.6f), (Stat=EWUS_Weight, Add=3)))
DoshCost = 20; //25;
bUsesSecondaryAmmoAltHUD=true
bAllowClientAmmoTracking=false
bIsBeingDropped=false
}

View File

@ -0,0 +1,183 @@
//=============================================================================
// KFWeap_HRG_Stunner
//=============================================================================
// HRG Stunner Weapon Class
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFWeap_HRG_Stunner extends KFWeap_ShotgunBase;
const SecondaryFireAnim = 'Shoot_Secondary';
const SecondaryFireIronAnim = 'Shoot_Secondary_Iron';
/** How much recoil the altfire should do */
var protected const float AltFireRecoilScale;
simulated function ModifyRecoil( out float CurrentRecoilModifier )
{
if( CurrentFireMode == ALTFIRE_FIREMODE )
{
CurrentRecoilModifier *= AltFireRecoilScale;
}
super.ModifyRecoil( CurrentRecoilModifier );
}
simulated function StartFire(byte FireModeNum)
{
if (FireModeNum == DEFAULT_FIREMODE && bUseAltFireMode)
{
if (AmmoCount[FireModeNum] < AmmoCost[ALTFIRE_FIREMODE] && SpareAmmoCount[FireModeNum] > 0)
{
BeginFire(RELOAD_FIREMODE);
return;
}
}
super.StartFire(FireModeNum);
}
simulated function AltFireMode()
{
StartFire(ALTFIRE_FIREMODE);
}
simulated function NotifyAltFireUsage()
{
local KFPawn_Human KFPH;
// Notify 3P to change material.
KFPH = KFPawn_Human(Instigator);
if (KFPH != none)
{
KFPH.SetUsingAltFireMode(bUseAltFireMode, true);
KFPH.bNetDirty = true;
}
}
simulated function name GetWeaponFireAnim(byte FireModeNum)
{
if (FireModeNum == ALTFIRE_FIREMODE)
{
return bUsingSights ? SecondaryFireIronAnim : SecondaryFireAnim;
}
return super.GetWeaponFireAnim(FireModeNum);
}
defaultproperties
{
// Inventory
InventorySize=7 //6
GroupPriority=100
WeaponSelectTexture=Texture2D'wep_ui_hrg_stunner_tex.UI_Weapon_Select_HRG_Stunner'
// Shooting Animations
FireSightedAnims[0]=Shoot_Iron
FireSightedAnims[1]=Shoot_Iron2
FireSightedAnims[2]=Shoot_Iron3
// FOV
MeshFOV=86
MeshIronSightFOV=52
PlayerIronSightFOV=70
// Depth of field
DOF_FG_FocalRadius=85
DOF_FG_MaxNearBlurSize=3.5
// Zooming/Position
PlayerViewOffset=(X=15.0,Y=8.5,Z=0.0)
IronSightPosition=(X=8,Y=0,Z=0)
// Content
PackageKey="HRG_Stunner"
FirstPersonMeshName="Wep_1P_HRG_Stunner_MESH.Wep_1stP_HRG_Stunner_Rig"
FirstPersonAnimSetNames(0)="Wep_1P_HRG_Stunner_ANIM.Wep_1stP_HRG_Stunner_Anim"
PickupMeshName="WEP_3P_HRG_Stunner_MESH.Wep_HRG_Stunner_Pickup"
AttachmentArchetypeName="WEP_HRG_Stunner_ARCH.Wep_AA12_3P"
MuzzleFlashTemplateName="WEP_HRG_Stunner_ARCH.Wep_AA12_MuzzleFlash"
// DEFAULT_FIREMODE
FireModeIconPaths(DEFAULT_FIREMODE)=Texture2D'ui_firemodes_tex.UI_FireModeSelect_ShotgunAuto'
FiringStatesArray(DEFAULT_FIREMODE)=WeaponFiring
WeaponFireTypes(DEFAULT_FIREMODE)=EWFT_Projectile
WeaponProjectiles(DEFAULT_FIREMODE)=class'KFProj_Bullet_HRG_Stunner'
InstantHitDamage(DEFAULT_FIREMODE)=60.0 //65.0
InstantHitDamageTypes(DEFAULT_FIREMODE)=class'KFDT_Ballistic_HRG_Stunner'
PenetrationPower(DEFAULT_FIREMODE)=2.0
FireInterval(DEFAULT_FIREMODE)=0.15
Spread(DEFAULT_FIREMODE)=0.005
FireOffset=(X=30,Y=5,Z=-4)
// Shotgun
NumPellets(DEFAULT_FIREMODE)=1
// ALT_FIREMODE
FireModeIconPaths(ALTFIRE_FIREMODE)=Texture2D'ui_firemodes_tex.UI_FireModeSelect_ShotgunSingle'
FiringStatesArray(ALTFIRE_FIREMODE)=WeaponSingleFiring
WeaponFireTypes(ALTFIRE_FIREMODE)=EWFT_Projectile
WeaponProjectiles(ALTFIRE_FIREMODE)=class'KFProj_Bullet_HRG_Stunner_Alt'
InstantHitDamage(ALTFIRE_FIREMODE)=20.0 //50.0
InstantHitDamageTypes(ALTFIRE_FIREMODE)=class'KFDT_Ballistic_HRG_Stunner_Alt'
PenetrationPower(ALTFIRE_FIREMODE)=0
FireInterval(ALTFIRE_FIREMODE)=0.5
Spread(ALTFIRE_FIREMODE)=0.025
AmmoCost(ALTFIRE_FIREMODE)=5 //3
// Shotgun
NumPellets(ALTFIRE_FIREMODE)=1
// BASH_FIREMODE
InstantHitDamageTypes(BASH_FIREMODE)=class'KFDT_Bludgeon_HRG_Stunner'
InstantHitDamage(BASH_FIREMODE)=26
// Fire Effects
WeaponFireSnd(DEFAULT_FIREMODE)=(DefaultCue=AkEvent'WW_WEP_HRG_Stunner.Play_WEP_HRG_Stunner_Fire_3P', FirstPersonCue=AkEvent'WW_WEP_HRG_Stunner.Play_WEP_HRG_Stunner_Fire_1P')
WeaponFireSnd(ALTFIRE_FIREMODE)=(DefaultCue=AkEvent'WW_WEP_HRG_Stunner.Play_WEP_HRG_Stunner_Alt_Fire_3P', FirstPersonCue=AkEvent'WW_WEP_HRG_Stunner.Play_WEP_HRG_Stunner_Alt_Fire_1P')
WeaponDryFireSnd(DEFAULT_FIREMODE)=AkEvent'WW_WEP_HRG_Stunner.Play_WEP_HRG_Stunner_Dry_Fire'
WeaponDryFireSnd(ALTFIRE_FIREMODE)=AkEvent'WW_WEP_HRG_Stunner.Play_WEP_HRG_Stunner_Dry_Fire'
// Attachments
bHasIronSights=true
bHasFlashlight=false
// Ammo
MagazineCapacity[0]=25
SpareAmmoCapacity[0]=225 //250
InitialSpareMags[0]=1
bCanBeReloaded=true
bReloadFromMagazine=true
bHasFireLastAnims=false
// Recoil
maxRecoilPitch=150
minRecoilPitch=125
maxRecoilYaw=75
minRecoilYaw=-75
RecoilRate=0.075
RecoilBlendOutRatio=0.25
RecoilMaxYawLimit=500
RecoilMinYawLimit=65035
RecoilMaxPitchLimit=900
RecoilMinPitchLimit=64785
RecoilISMaxYawLimit=75
RecoilISMinYawLimit=65460
RecoilISMaxPitchLimit=375
RecoilISMinPitchLimit=65460
RecoilViewRotationScale=0.7
FallingRecoilModifier=1.5
HippedRecoilModifier=1.75
AssociatedPerkClasses(0)=class'KFPerk_SWAT'
WeaponFireWaveForm=ForceFeedbackWaveform'FX_ForceFeedback_ARCH.Gunfire.Heavy_Recoil'
// Weapon Upgrade stat boosts
//WeaponUpgrades[1]=(IncrementDamage=1.15f,IncrementWeight=1)
WeaponUpgrades[1]=(Stats=((Stat=EWUS_Damage0, Scale=1.15f), (Stat=EWUS_Damage1, Scale=1.15f), (Stat=EWUS_Weight, Add=1)))
AltFireRecoilScale=3.0f //2.0f
}

View File

@ -71,7 +71,7 @@ simulated function StartFire(byte FireModeNum)
}
}
super.StartFire(FireModeNum);
super(KFWeapon).StartFire(FireModeNum);
}
/*********************************************************************************************
@ -94,6 +94,13 @@ simulated function ProcessInstantHitEx(byte FiringMode, ImpactInfo Impact, optio
super.ProcessInstantHitEx( FiringMode, Impact, NumHits, out_PenetrationVal, ImpactNum );
}
/** process local player impact for clientside hit detection */
event RecieveClientImpact(byte FiringMode, const out ImpactInfo Impact, optional out float PenetrationValue, optional int ImpactNum)
{
// skip KFWeap_MeleeBase because it does melee stuff
super(KFWeapon).RecieveClientImpact(FiringMode, Impact, PenetrationValue, ImpactNum);
}
defaultproperties
{
// MeleeBase

View File

@ -334,7 +334,7 @@ defaultproperties
// Zooming/Position
PlayerViewOffset=(X=3.0,Y=8,Z=-1.8)
//IronSightPosition=(X=0,Y=-0.07,Z=1.03)
IronSightPosition=(X=0,Y=-0.115,Z=1.0425)
IronSightPosition=(X=0,Y=-0.09,Z=1.042)
// AI warning system
bWarnAIWhenAiming=true

View File

@ -150,7 +150,7 @@ defaultproperties
WeaponProjectiles(ALTFIRE_FIREMODE)=class'KFProj_Nail_Nailgun'
InstantHitDamage(ALTFIRE_FIREMODE)=35
InstantHitDamageTypes(ALTFIRE_FIREMODE)=class'KFDT_Ballistic_NailShotgun'
Spread(ALTFIRE_FIREMODE)=0.02
Spread(ALTFIRE_FIREMODE)=0.01 //0.02
PenetrationPower(ALTFIRE_FIREMODE)=3.0
FireInterval(ALTFIRE_FIREMODE)=0.2 // 300 RPM
AltFireRecoilModifier=0.5
@ -174,7 +174,7 @@ defaultproperties
// Ammo
MagazineCapacity[0]=42
SpareAmmoCapacity[0]=336
SpareAmmoCapacity[0]=378 //336
InitialSpareMags[0]=3
bCanBeReloaded=true
bReloadFromMagazine=true