1
0
KF2-Dev-Scripts/KFGame/Classes/KFOnlineStatsWrite.uc
2021-06-02 23:06:18 +03:00

2279 lines
109 KiB
Ucode

//=============================================================================
// KFOnlineStatsWrite
//=============================================================================
// The KF2 game stats writer
//=============================================================================
// Killing Floor 2
// Copyright (C) 2015 Tripwire Interactive LLC
// - Joshua Rowan 3/4/2014
//=============================================================================
class KFOnlineStatsWrite extends OnlineStatsWrite
native
config(game);
`include(KFOnlineStats.uci)
`include(KFGame\KFMatchStats.uci);
const WeldingPointsRequired = 510;
const HealingPointsRequired = 10;
const MaxPerkLevel = `MAX_PERK_LEVEL;
const MaxPrestigeLevel = `MAX_PRESTIGE_LEVEL;
//Event consts
const SpecialEventObjectiveCountMax = 8;
/** Cached PC */
var KFPlayerController MyKFPC;
/** Cached general stats */
var private int Kills;
var private int StalkerKills;
var private int CrawlerKills;
var private int FleshPoundKills;
var private int WeldingPoints;
var private int HealingPoints;
/** Cached perk XP and build stats */
var private int CommandoXP, CommandoLVL, CommandoPSG;
var private int CommandoBuild;
var private int BerserkerXP, BerserkerLVL, BerserkerPSG;
var private int BerserkerBuild;
var private int SupportXP, SupportLVL, SupportPSG;
var private int SupportBuild;
var private int MedicXP, MedicLVL, MedicPSG;
var private int MedicBuild;
var private int FirebugXP, FirebugLVL, FirebugPSG;
var private int FirebugBuild;
var private int DemoXP, DemoLVL, DemoPSG;
var private int DemoBuild;
var private int GunslingerXP, GunslingerLVL, GunslingerPSG;
var private int GunslingerBuild;
var private int SharpshooterXP, SharpshooterLVL, SharpshooterPSG;
var private int SharpshooterBuild;
var private int SwatXP, SwatLVL, SwatPSG;
var private int SwatBuild;
var private int SurvXP, SurvLVL, SurvPSG;
var private int SurvBuild;
// XP is calculated as a float but stored as an integer, so we need to keep track of the remainders
// and award them as integers so the player gets his full XP amount
// Keep size in-sync with size of KFPlayerController::PerkList
var private float BonusXPRemainder[10];
var private int PersonalBest_KnifeKills;
var private int PersonalBest_PistolKills;
var private int PersonalBest_HeadShots;
var private int PersonalBest_Healing;
var private int PersonalBest_Kills;
var private int PersonalBest_Assists;
var private int PersonalBest_LargeZedKil;
var private int PersonalBest_Dosh;
/** Cached Event Stats */
//Seasonal event tracking
var private int SpecialEventInfo;
var private int InitialSpecialEventInfo;
//Weekly Outbreak tracking
var private int WeeklyEventInfo;
var private int InitialWeeklyEventInfo;
//Daily event completion/date tracking
var private int DailyEventInfo;
//Whether or not to ignore reading of other daily event stats. Allows for clearing of data if stats come in out of order.
var private bool bIgnoreDailyStatReads;
//Selected IDs that the user is completing for their daily events
var private int DailyEventIDs;
//Bit fields holding the persistent current stat for each daily objective. Reserving 16 bit per objective
var private int DailyEventStats1;
var private int DailyEventStats2;
var private int SpecialEventKills_DEPRECATED;
var private int SeasonalEventStats1, SeasonalEventStatsMax1;
var private int SeasonalEventStats2, SeasonalEventStatsMax2;
var private int SeasonalEventStats3, SeasonalEventStatsMax3;
var private int SeasonalEventStats4, SeasonalEventStatsMax4;
var private int SeasonalEventStats5, SeasonalEventStatsMax5;
/** Achievement IDs **/
// ids must be sequential (no gaps)
const KFACHID_ParisNormal = 0;
const KFACHID_ParisHard = 1;
const KFACHID_ParisSuicidal = 2;
const KFACHID_ParisHellOnEarth = 3;
const KFACHID_OutpostNormal = 4;
const KFACHID_OutpostHard = 5;
const KFACHID_OutpostSuicidal = 6;
const KFACHID_OutpostHellOnEarth = 7;
const KFACHID_BioticsNormal = 8;
const KFACHID_BioticsHard = 9;
const KFACHID_BioticsSuicidal = 10;
const KFACHID_BioticsHellOnEarth = 11;
const KFACHID_ManorNormal = 12;
const KFACHID_ManorHard = 13;
const KFACHID_ManorSuicidal = 14;
const KFACHID_ManorHellOnEarth = 15;
const KFACHID_ParisCollectibles = 16;
const KFACHID_OutpostCollectibles = 17;
const KFACHID_BioticsCollectibles = 18;
const KFACHID_ManorCollectibles = 19;
const KFACHID_EvacNormal = 20;
const KFACHID_EvacHard = 21;
const KFACHID_EvacSuicidal = 22;
const KFACHID_EvacHellOnEarth = 23;
const KFACHID_CatacombsNormal = 24;
const KFACHID_CatacombsHard = 25;
const KFACHID_CatacombsSuicidal = 26;
const KFACHID_CatacombsHellOnEarth = 27;
const KFACHID_EvacsCollectibles = 28;
const KFACHID_CatacombsCollectibles = 29;
const KFACHID_Berserker_Lvl5 = 30;
const KFACHID_Berserker_Lvl10 = 31;
const KFACHID_Berserker_Lvl15 = 32;
const KFACHID_Berserker_Lvl20 = 33;
const KFACHID_Berserker_Lvl25 = 34;
const KFACHID_FieldMedic_Lvl5 = 35;
const KFACHID_FieldMedic_Lvl10 = 36;
const KFACHID_FieldMedic_Lvl15 = 37;
const KFACHID_FieldMedic_Lvl20 = 38;
const KFACHID_FieldMedic_Lvl25 = 39;
const KFACHID_Commando_Lvl5 = 40;
const KFACHID_Commando_Lvl10 = 41;
const KFACHID_Commando_Lvl15 = 42;
const KFACHID_Commando_Lvl20 = 43;
const KFACHID_Commando_Lvl25 = 44;
const KFACHID_Support_Lvl5 = 45;
const KFACHID_Support_Lvl10 = 46;
const KFACHID_Support_Lvl15 = 47;
const KFACHID_Support_Lvl20 = 48;
const KFACHID_Support_Lvl25 = 49;
const KFACHID_Firebug_Lvl5 = 50;
const KFACHID_Firebug_Lvl10 = 51;
const KFACHID_Firebug_Lvl15 = 52;
const KFACHID_Firebug_Lvl20 = 53;
const KFACHID_Firebug_Lvl25 = 54;
const KFACHID_Demolitionist_Lvl5 = 55;
const KFACHID_Demolitionist_Lvl10 = 56;
const KFACHID_Demolitionist_Lvl15 = 57;
const KFACHID_Demolitionist_Lvl20 = 58;
const KFACHID_Demolitionist_Lvl25 = 59;
const KFACHID_Gunslinger_Lvl5 = 60;
const KFACHID_Gunslinger_Lvl10 = 61;
const KFACHID_Gunslinger_Lvl15 = 62;
const KFACHID_Gunslinger_Lvl20 = 63;
const KFACHID_Gunslinger_Lvl25 = 64;
const KFACHID_BerserkerNormal = 65;
const KFACHID_BerserkerHard = 66;
const KFACHID_BerserkerSuicidal = 67;
const KFACHID_BerserkerHellOnEarth = 68;
const KFACHID_FieldMedicNormal = 69;
const KFACHID_FieldMedicHard = 70;
const KFACHID_FieldMedicSuicidal = 71;
const KFACHID_FieldMedicHellOnEarth = 72;
const KFACHID_CommandoNormal = 73;
const KFACHID_CommandoHard = 74;
const KFACHID_CommandoSuicidal = 75;
const KFACHID_CommandoHellOnEarth = 76;
const KFACHID_SupportNormal = 77;
const KFACHID_SupportHard = 78;
const KFACHID_SupportSuicidal = 79;
const KFACHID_SupportHellOnEarth = 80;
const KFACHID_FirebugNormal = 81;
const KFACHID_FirebugHard = 82;
const KFACHID_FirebugSuicidal = 83;
const KFACHID_FirebugHellOnEarth = 84;
const KFACHID_DemolitionistNormal = 85;
const KFACHID_DemolitionistHard = 86;
const KFACHID_DemolitionistSuicidal = 87;
const KFACHID_DemolitionistHellOnEarth = 88;
const KFACHID_GunslingerNormal = 89;
const KFACHID_GunslingerHard = 90;
const KFACHID_GunslingerSuicidal = 91;
const KFACHID_GunslingerHellOnEarth = 92;
const KFACHID_All_Lvl25 = 93;
const KFACHID_BlackForestNormal = 94;
const KFACHID_BlackForestHard = 95;
const KFACHID_BlackForestSuicidal = 96;
const KFACHID_BlackForestHellOnEarth = 97;
const KFACHID_BlackForestCollectibles = 98;
const KFACHID_FarmhouseNormal = 99;
const KFACHID_FarmhouseHard = 100;
const KFACHID_FarmhouseSuicidal = 101;
const KFACHID_FarmhouseHellOnEarth = 102;
const KFACHID_FarmhouseCollectibles = 103;
const KFACHID_PrisonNormal = 104;
const KFACHID_PrisonHard = 105;
const KFACHID_PrisonSuicidal = 106;
const KFACHID_PrisonHellOnEarth = 107;
const KFACHID_PrisonCollectibles = 108;
const KFACHID_TutorialComplete = 109;
const KFACHID_Sharpshooter_Lvl5 = 110;
const KFACHID_Sharpshooter_Lvl10 = 111;
const KFACHID_Sharpshooter_Lvl15 = 112;
const KFACHID_Sharpshooter_Lvl20 = 113;
const KFACHID_Sharpshooter_Lvl25 = 114;
const KFACHID_SharpshooterNormal = 115;
const KFACHID_SharpshooterHard = 116;
const KFACHID_SharpshooterSuicidal = 117;
const KFACHID_SharpshooterHellOnEarth = 118;
const KFACHID_ContainmentStationNormal = 119;
const KFACHID_ContainmentStationHard = 120;
const KFACHID_ContainmentStationSuicidal = 121;
const KFACHID_ContainmentStationHellOnEarth = 122;
const KFACHID_ContainmentStationCollectibles = 123;
const KFACHID_HostileGroundsNormal = 124;
const KFACHID_HostileGroundsHard = 125;
const KFACHID_HostileGroundsSuicidal = 126;
const KFACHID_HostileGroundsHellOnEarth = 127;
const KFACHID_HostileGroundsCollectibles = 128;
const KFACHID_DeadSilence = 129;
const KFACHID_QuickOnTheTrigger = 130;
const KFACHID_ItsOnlyAFleshWound = 131;
const KFACHID_HackAndSlash = 132;
const KFACHID_DieVolter = 133;
const KFACHID_WinHard = 134;
const KFACHID_WinSuicidal = 135;
const KFACHID_WinHellOnEarth = 136;
const KFACHID_MrPerky5 = 137;
const KFACHID_MrPerky10 = 138;
const KFACHID_MrPerky15 = 139;
const KFACHID_MrPerky20 = 140;
const KFACHID_MrPerky25 = 141;
const KFACHID_Win1 = 142;
const KFACHID_Win10 = 143;
const KFACHID_Win25 = 144;
const KFACHID_VsZedWin = 145;
const KFACHID_VsHumanWin = 146;
const KFACHID_HoldOut = 147;
const KFACHID_IGotYourBack = 148;
const KFACHID_Benefactor = 149;
const KFACHID_InfernalRealmNormal = 150;
const KFACHID_InfernalRealmHard = 151;
const KFACHID_InfernalRealmSuicidal = 152;
const KFACHID_InfernalRealmHellOnEarth = 153;
const KFACHID_InfernalRealmCollectibles = 154;
const KFACHID_SWAT_Lvl5 = 155;
const KFACHID_SWAT_Lvl10 = 156;
const KFACHID_SWAT_Lvl15 = 157;
const KFACHID_SWAT_Lvl20 = 158;
const KFACHID_SWAT_Lvl25 = 159;
const KFACHID_SWATNormal = 160;
const KFACHID_SWATHard = 161;
const KFACHID_SWATSuicidal = 162;
const KFACHID_SWATHellOnEarth = 163;
const KFACHID_Surv_Lvl5 = 164;
const KFACHID_Surv_Lvl10 = 165;
const KFACHID_Surv_Lvl15 = 166;
const KFACHID_Surv_Lvl20 = 167;
const KFACHID_Surv_Lvl25 = 168;
const KFACHID_SurvNormal = 169;
const KFACHID_SurvHard = 170;
const KFACHID_SurvSuicidal = 171;
const KFACHID_SurvHellOnEarth = 172;
const KFACHID_ZedLandingNormal = 173;
const KFACHID_ZedLandingHard = 174;
const KFACHID_ZedLandingSuicidal = 175;
const KFACHID_ZedLandingHellOnEarth = 176;
const KFACHID_ZedLandingCollectibles = 177;
const KFACHID_DescentNormal = 178;
const KFACHID_DescentHard = 179;
const KFACHID_DescentSuicidal = 180;
const KFACHID_DescentHellOnEarth = 181;
const KFACHID_DescentCollectibles = 182;
const KFACHID_NukedNormal = 183;
const KFACHID_NukedHard = 184;
const KFACHID_NukedSuicidal = 185;
const KFACHID_NukedHellOnEarth = 186;
const KFACHID_NukedCollectibles = 187;
const KFACHID_TragicKingdomNormal = 188;
const KFACHID_TragicKingdomHard = 189;
const KFACHID_TragicKingdomSuicidal = 190;
const KFACHID_TragicKingdomHellOnEarth = 191;
const KFACHID_TragicKingdomCollectibles = 192;
const KFACHID_NightmareNormal = 193;
const KFACHID_NightmareHard = 194;
const KFACHID_NightmareSuicidal = 195;
const KFACHID_NightmareHellOnEarth = 196;
const KFACHID_NightmareCollectibles = 197;
const KFACHID_KrampusNormal = 198;
const KFACHID_KrampusHard = 199;
const KFACHID_KrampusSuicidal = 200;
const KFACHID_KrampusHellOnEarth = 201;
const KFACHID_KrampusCollectibles = 202;
const KFACHID_ArenaNormal = 203;
const KFACHID_ArenaHard = 204;
const KFACHID_ArenaSuicidal = 205;
const KFACHID_ArenaHellOnEarth = 206;
const KFACHID_ArenaCollectibles = 207;
const KFACHID_PowercoreNormal = 208;
const KFACHID_PowercoreHard = 209;
const KFACHID_PowercoreSuicidal = 210;
const KFACHID_PowercoreHellOnEarth = 211;
const KFACHID_PowercoreCollectibles = 212;
const KFACHID_AirshipNormal = 213;
const KFACHID_AirshipHard = 214;
const KFACHID_AirshipSuicidal = 215;
const KFACHID_AirshipHellOnEarth = 216;
const KFACHID_AirshipCollectibles = 217;
const KFACHID_LockdownNormal = 218;
const KFACHID_LockdownHard = 219;
const KFACHID_LockdownSuicidal = 220;
const KFACHID_LockdownHellOnEarth = 221;
const KFACHID_LockdownCollectibles = 222;
const KFACHID_MonsterBallNormal = 223;
const KFACHID_MonsterBallHard = 224;
const KFACHID_MonsterBallSuicidal = 225;
const KFACHID_MonsterBallHellOnEarth = 226;
const KFACHID_MonsterBallCollectibles = 227;
const KFACHID_MonsterBallSecretRoom = 228;
const KFACHID_SantasWorkshopNormal = 229;
const KFACHID_SantasWorkshopHard = 230;
const KFACHID_SantasWorkshopSuicidal = 231;
const KFACHID_SantasWorkshopHellOnEarth = 232;
const KFACHID_SantasWorkshopCollectibles = 233;
const KFACHID_ShoppingSpreeNormal = 234;
const KFACHID_ShoppingSpreeHard = 235;
const KFACHID_ShoppingSpreeSuicidal = 236;
const KFACHID_ShoppingSpreeHellOnEarth = 237;
const KFACHID_ShoppingSpreeCollectibles = 238;
const KFACHID_SpillwayNormal = 239;
const KFACHID_SpillwayHard = 240;
const KFACHID_SpillwaySuicidal = 241;
const KFACHID_SpillwayHellOnEarth = 242;
const KFACHID_SpillwayCollectibles = 243;
const KFACHID_SteamFortressObjectiveNormal = 244;
const KFACHID_SteamFortressObjectiveHard = 245;
const KFACHID_SteamFortressObjectiveSuicidal = 246;
const KFACHID_SteamFortressObjectiveHellOnEarth = 247;
const KFACHID_SteamFortressCollectibles = 248;
const KFACHID_ZedLandingObjectiveNormal = 249;
const KFACHID_ZedLandingObjectiveHard = 250;
const KFACHID_ZedLandingObjectiveSuicidal = 251;
const KFACHID_ZedLandingObjectiveHellOnEarth = 252;
const KFACHID_OutpostObjectiveNormal = 253;
const KFACHID_OutpostObjectiveHard = 254;
const KFACHID_OutpostObjectiveSuicidal = 255;
const KFACHID_OutpostObjectiveHellOnEarth = 256;
const KFACHID_AsylumHard = 257;
const KFACHID_AsylumHellOnEarth = 258;
const KFACHID_AsylumCollectibles = 259;
const KFACHID_NukedObjectiveHard = 260;
const KFACHID_NukedObjectiveHellOnEarth = 261;
const KFACHID_BioticsLabObjectiveHard = 262;
const KFACHID_BioticsLabObjectiveHellOnEarth = 263;
const KFACHID_SanitariumHard = 264;
const KFACHID_SanitariumHellOnEarth = 265;
const KFACHID_SanitariumCollectibles = 266;
const KFACHID_DefeatMatriarch = 267;
const KFACHID_BiolapseHard = 268;
const KFACHID_BiolapseHellOnEarth = 269;
const KFACHID_BiolapseCollectibles = 270;
const KFACHID_DesolationHard = 271;
const KFACHID_DesolationHellOnEarth = 272;
const KFACHID_DesolationCollectibles = 273;
const KFACHID_HellmarkStationHard = 274;
const KFACHID_HellmarkStationHellOnEarth = 275;
const KFACHID_HellmarkStationCollectibles = 276;
const KFACHID_ElysiumHard = 277;
const KFACHID_ElysiumHellOnEarth = 278;
const KFACHID_ElysiumEndlessWaveFifteen = 279;
const KFACHID_Dystopia2029Hard = 280;
const KFACHID_Dystopia2029HellOnEarth = 281;
const KFACHID_Dystopia2029Collectibles = 282;
const KFACHID_MoonbaseHard = 283;
const KFACHID_MoonbaseHellOnEarth = 284;
const KFACHID_MoonbaseCollectibles = 285;
/* __TW_ANALYTICS_ */
var int PerRoundWeldXP;
var int PerRoundHealXP;
//Cache of achievements information
var array<AchievementDetails> Achievements;
//var private const InterpCurveFloat LevelXPCurve;
var const int XPTable[`MAX_PERK_LEVEL];
/** Stats state */
var private const bool bFailedToRead;
var private const bool bReadSuccessful;
/** Dev cheats */
var config bool bAllowPerkCheats;
var private const bool bDisabled;
/** Max reward if users (theoretically) did the objective perfectly */
var int VoshRewards[11];
/** Vosh Multiplier based on game difficulty */
var array<float> VoshDifficultyScalar;
/** Reward if user kills a zed. */
var native map{ FName, INT } KillZedRewards;
/** Keeps track of how many times player killed each zed. */
var native map{ FName, INT } ZedsKilled;
/** Daily Event Information */
enum eDailyObjectiveType
{
DOT_WeaponDamage,
DOT_PerkXP,
DOT_Maps,
};
enum eDailyObjectiveSecondaryType
{
DOST_PlayPerk,
DOST_KillZeds,
DOST_KillBoss,
DOST_MapCompletion,
DOST_VersusDamage,
DOST_VersusKills,
DOST_CharacterCompletion,
DOST_KnifeDamage
};
struct native DailyEventInformation
{
//Category of the objective.
var eDailyObjectiveType ObjectiveType;
//Secondary category for ones that share information (Ex: Versus kills / Versus damage)
var eDailyObjectiveSecondaryType SecondaryType;
//Any classes tied to this objective
var array<name> ObjectiveClasses;
//Amount of stat necessary to complete this objective
var int CompletionAmount;
};
var array<DailyEventInformation> DailyEvents;
/** Debugging */
var bool bLogStatsWrite;
var int SeasonalKillsObjectiveThreshold;
var const private KFSeasonalEventStats SeasonalEvent;
cpptext
{
void InitializeKillZedRewards();
void InitializeVoshRewards();
UBOOL IsValidProgressStatId(INT StatId);
void GrantTutorialLevel(class UClass* PerkClass);
//Event calls
void GrantWeeklyOutbreakItems();
void GrantEventItems();
void GrantDoshVaultItem();
//Daily calls
void ForceDailyObjectives(INT ObjectiveIndex, INT UIIndex);
void ResetDailyObjectives();
void SetDailyEventIDs();
INT GetObjectiveID(INT Index);
void AddToObjective(INT Index, INT Amount);
void MarkObjectiveComplete(INT Index);
//Dosh Vault Calls
void AddToDoshVault(INT Amount);
UBOOL IsDamageTypeChildOf(class UClass* DamageType, const TArray<FName>& ObjectiveClasses);
void CalculateZedKillsDoshReward();
void IncrementZedsKilled(class UClass* MonsterType);
void InitializeSeasonalEventStats();
}
/*********************************************************************************************
* @name Native stat functions
********************************************************************************************* */
native function OnStatsInitialized(bool bWasSuccessful);
native function IncrementIntStat(int StatId,optional int IncBy = 1);
native function IncrementFloatStat( int StatId, optional float IncBy = 1.0 );
native function SetIntStat( int StatId, int Value );
native function SetFloatStat( int StatId, float Value );
native final function bool HasCheated();
native final function NotifyCheats(optional bool bSaveToConfig);
native final function bool HasReadFailure();
native final function NotifyReadFailure();
native final function bool HasReadStats();
native final function NotifyReadSucceeded();
native final private function int LogSubsystemIntStat( int StatId );
/*********************************************************************************************
* @name Saving & Loading
********************************************************************************************* */
simulated function LogStats()
{
`log( "###############################################################" );
`log( "CACHED VALUES:" );
`log( "CommandoXP, CommandoLVL " @ " =" @ CommandoXP @ CommandoLVL );
`log( "BerserkerXP, BerserkerLVL " @ " =" @ BerserkerXP @ BerserkerLVL );
`log( "SupportXP, SupportLVL " @ " =" @ SupportXP @ SupportLVL );
`log( "MedicXP, MedicLVL " @ " =" @ MedicXP @ MedicLVL );
`log( "---------------------------------------------------------------" );
`log( "STEAM VALUES:" );
`log( "CommandoXP, CommandoLVL " @ " =" @ GetXPFromProgress( LogSubsystemIntStat( STATID_Cmdo_Progress ) ) @ GetLVLFromProgress( LogSubsystemIntStat( STATID_Cmdo_Progress ) ) );
`log( "BerserkerXP, BerserkerLVL " @ " =" @ GetXPFromProgress( LogSubsystemIntStat( STATID_Bsrk_Progress ) ) @ GetLVLFromProgress( LogSubsystemIntStat( STATID_Bsrk_Progress ) ) );
`log( "SupportXP, SupportLVL " @ " =" @ GetXPFromProgress( LogSubsystemIntStat( STATID_Sup_Progress ) ) @ GetLVLFromProgress( LogSubsystemIntStat( STATID_Sup_Progress ) ) );
`log( "MedicXP, MedicLVL " @ " =" @ GetXPFromProgress( LogSubsystemIntStat( STATID_Medic_Progress ) ) @ GetLVLFromProgress( LogSubsystemIntStat( STATID_Medic_Progress ) ) );
`log( " " );
`log( "CommandoProgress " @ " =" @ LogSubsystemIntStat( STATID_Cmdo_Progress ) );
`log( "BerserkerProgress " @ " =" @ LogSubsystemIntStat( STATID_Bsrk_Progress ) );
`log( "SupportProgress " @ " =" @ LogSubsystemIntStat( STATID_Sup_Progress ) );
`log( "MedicProgress " @ " =" @ LogSubsystemIntStat( STATID_Medic_Progress ) );
`log( "###############################################################" );
}
simulated function LogStatValue(int StatId)
{
`log("*** Stat value for ID" @ StatId @ ": " @ LogSubsystemIntStat(StatId));
}
//In case we ever use this?
event CacheFloatStatsValue(int StatID, float Value)
{
`log("*** Not caching float value, please do something with this:" @ StatID @ Value);
}
//Steam stats -> the gameplay variables
event CacheStatsValue(int StatID, int Value)
{
switch( StatID )
{
// Perk XPs and builds
case STATID_Cmdo_Progress:
CommandoXP = GetXPFromProgress( Value );
CommandoLVL = GetLVLFromProgress( Value );
CommandoPSG = GetPSGFromProgress( Value );
CheckPerkLvlAchievement( class'KFPerk_Commando', CommandoLVL );
`log(GetFuncName() @ "CommandoXP:" @ CommandoXP @CommandoLVL @ "VALUE:" @ Round( value ), bLogStatsWrite);
break;
case STATID_Cmdo_Build:
CommandoBuild = Value;
`log(GetFuncName() @ "CommandoBuild:" @ CommandoBuild, bLogStatsWrite);
break;
case STATID_Bsrk_Progress:
BerserkerXP = GetXPFromProgress( Value );
BerserkerLVL = GetLVLFromProgress( Value );
BerserkerPSG = GetPSGFromProgress( Value );
CheckPerkLvlAchievement( class'KFPerk_Berserker', BerserkerLVL );
`log(GetFuncName() @ "BerserkerXP:" @ BerserkerXP @ BerserkerLVL @ "VALUE:" @ Round( value ), bLogStatsWrite);
break;
case STATID_Bsrk_Build:
BerserkerBuild = Value;
`log(GetFuncName() @ "BerserkerBuild:" @ BerserkerBuild, bLogStatsWrite);
break;
case STATID_Sup_Progress:
SupportXP = GetXPFromProgress( Value );
SupportLVL = GetLVLFromProgress( Value );
SupportPSG = GetPSGFromProgress( Value );
CheckPerkLvlAchievement( class'KFPerk_Support', SupportLVL );
`log(GetFuncName() @ "SupportXP:" @ SupportXP @ SupportLVL @ "VALUE:" @ Round( value ), bLogStatsWrite);
break;
case STATID_Sup_Build:
SupportBuild = Value;
`log(GetFuncName() @ "SupportBuild:" @ SupportBuild, bLogStatsWrite);
break;
case STATID_Medic_Progress:
MedicXP = GetXPFromProgress( Value );
MedicLVL = GetLVLFromProgress( Value );
MedicPSG = GetPSGFromProgress( Value );
CheckPerkLvlAchievement( class'KFPerk_FieldMedic', MedicLVL );
`log(GetFuncName() @ "MedicXP:" @ MedicXP @ MedicLVL @ "VALUE:" @ Round( value ), bLogStatsWrite);
break;
case STATID_Medic_Build:
MedicBuild = Value;
`log(GetFuncName() @ "MedicBuild:" @ MedicBuild, bLogStatsWrite);
break;
case STATID_Fire_Progress:
FirebugXP = GetXPFromProgress( Value );
FirebugLVL = GetLVLFromProgress( Value );
FirebugPSG = GetPSGFromProgress( Value );
CheckPerkLvlAchievement( class'KFPerk_Firebug', FirebugLVL );
`log(GetFuncName() @ "FirebugXP:" @ FirebugXP @ FirebugLVL @ "VALUE:" @ Round( value ), bLogStatsWrite);
break;
case STATID_Fire_Build:
FirebugBuild = Value;
`log(GetFuncName() @ "FirebugBuild:" @ FirebugBuild, bLogStatsWrite);
break;
case STATID_Demo_Progress:
DemoXP = GetXPFromProgress( Value );
DemoLVL = GetLVLFromProgress( Value );
DemoPSG = GetPSGFromProgress( Value );
CheckPerkLvlAchievement( class'KFPerk_Demolitionist', DemoLVL );
`log(GetFuncName() @ "DemoXP:" @ DemoXP @ DemoLVL @ "VALUE:" @ Round( value ), bLogStatsWrite);
break;
case STATID_Demo_Build:
DemoBuild = Value;
`log(GetFuncName() @ "DemoBuild:" @ DemoBuild, bLogStatsWrite);
break;
case STATID_Guns_Progress:
GunslingerXP = GetXPFromProgress( Value );
GunslingerLVL = GetLVLFromProgress( Value );
GunslingerPSG = GetPSGFromProgress( Value );
CheckPerkLvlAchievement( class'KFPerk_Gunslinger', GunslingerLVL );
`log(GetFuncName() @ "GunslingerXP:" @ GunslingerXP @ GunslingerLVL @ "VALUE:" @ Round( value ), bLogStatsWrite);
break;
case STATID_Guns_Build:
GunslingerBuild = Value;
`log(GetFuncName() @ "GunslingerBuild:" @ GunslingerBuild, bLogStatsWrite);
break;
case STATID_Shrp_Progress:
SharpshooterXP = GetXPFromProgress( Value );
SharpshooterLVL = GetLVLFromProgress( Value );
SharpshooterPSG = GetPSGFromProgress( Value );
CheckPerkLvlAchievement( class'KFPerk_Sharpshooter', SharpshooterLVL );
`log(GetFuncName() @ "SharpshooterXP:" @ SharpshooterXP @ SharpshooterLVL @ "VALUE:" @ Round( value ), bLogStatsWrite);
break;
case STATID_Shrp_Build:
SharpshooterBuild = Value;
`log(GetFuncName() @ "SharpshooterBuild:" @ SharpshooterBuild, bLogStatsWrite);
break;
case STATID_Swat_Progress:
SwatXP = GetXPFromProgress( Value );
SwatLVL = GetLVLFromProgress( Value );
SwatPSG = GetPSGFromProgress( Value );
CheckPerkLvlAchievement( class'KFPerk_Swat', SwatLVL );
`log(GetFuncName() @ "SwatXP:" @ SwatXP @ SwatLVL @ "VALUE:" @ Round( value ), bLogStatsWrite);
break;
case STATID_Swat_Build:
SwatBuild = Value;
`log(GetFuncName() @ "SwatBuild:" @ SwatBuild, bLogStatsWrite);
break;
case STATID_Surv_Progress:
SurvXP = GetXPFromProgress( Value );
SurvLVL = GetLVLFromProgress( Value );
SurvPSG = GetPSGFromProgress( Value );
CheckPerkLvlAchievement( class'KFPerk_Survivalist', SurvLVL );
`log(GetFuncName() @ "SurvXP:" @ SurvXP @ SurvLVL @ "VALUE:" @ Round( value ), bLogStatsWrite);
break;
case STATID_Surv_Build:
SurvBuild = Value;
`log(GetFuncName() @ "SurvBuild:" @ SurvBuild, bLogStatsWrite);
break;
// end of perk progress stats
case STATID_Kills:
Kills = Value;
`log(GetFuncName() @ "Kills:" @ Kills, bLogStatsWrite);
break;
case STATID_StalkerKills:
StalkerKills = Value;
`log(GetFuncName() @ "Stalker Kills:" @ StalkerKills, bLogStatsWrite);
break;
case STATID_Sup_WeldPoints:
WeldingPoints = Value;
`log(GetFuncName() @ "Welding points:" @ WeldingPoints, bLogStatsWrite);
break;
case STATID_Medic_HealPoints:
HealingPoints = Value;
`log(GetFuncName() @ "Healing points:" @ HealingPoints, bLogStatsWrite);
break;
case STATID_CrawlerKills:
CrawlerKills = Value;
`log(GetFuncName() @ "Crawler kills:" @ CrawlerKills, bLogStatsWrite);
break;
case STATID_FleshpoundKills:
FleshpoundKills = Value;
`log(GetFuncName() @ "Fleshpound kills:" @ FleshpoundKills, bLogStatsWrite);
break;
case STATID_SpecialEventProgress:
InitialSpecialEventInfo = Value;
`log(GetFuncName() @ "Special Event: " @ SpecialEventInfo, bLogStatsWrite);
break;
case STATID_WeeklyEventProgress:
InitialWeeklyEventInfo = Value;
`log(GetFuncName() @ "Weekly Event:" @ WeeklyEventInfo, bLogStatsWrite);
break;
case STATID_DailyEventInfo:
CacheDailyEventProgress(Value);
`log(GetFuncName() @ "Daily Event:" @ DailyEventInfo, bLogStatsWrite);
break;
case STATID_DailyEventIDs:
//Ignore if we've flagged to not read these values. If we've done that, we're getting new IDs.
if (!bIgnoreDailyStatReads)
{
DailyEventIDs = Value;
}
`log(GetFuncName() @ "Daily Event IDs:" @ DailyEventIDs, bLogStatsWrite);
break;
case STATID_DailyEventStats1:
if (bIgnoreDailyStatReads)
{
DailyEventStats1 = 0;
}
else
{
DailyEventStats1 = Value;
}
`log(GetFuncName() @ "Daily Event Stats 1:" @ DailyEventStats1, bLogStatsWrite);
break;
case STATID_DailyEventStats2:
if (bIgnoreDailyStatReads)
{
DailyEventStats2 = 0;
}
else
{
DailyEventStats2 = Value;
}
`log(GetFuncName() @ "Daily Event Stats 2:" @ DailyEventStats2, bLogStatsWrite);
break;
case STATID_SpecialEventKills_DEPRECATED:
SpecialEventKills_DEPRECATED = Value;
`log(GetFuncName() @ "SpecialEventKills_DEPRECATED:" @ SpecialEventKills_DEPRECATED, bLogStatsWrite);
break;
case STATID_SeasonalEventStats1:
SeasonalEventStats1 = Value;
`log(GetFuncName() @ "SeasonalEventStats1:" @ SeasonalEventStats1, bLogStatsWrite);
break;
case STATID_SeasonalEventStats2:
SeasonalEventStats2 = Value;
`log(GetFuncName() @ "SeasonalEventStats2:" @ SeasonalEventStats2, bLogStatsWrite);
break;
case STATID_SeasonalEventStats3:
SeasonalEventStats3 = Value;
`log(GetFuncName() @ "SeasonalEventStats3:" @ SeasonalEventStats3, bLogStatsWrite);
break;
case STATID_SeasonalEventStats4:
SeasonalEventStats4 = Value;
`log(GetFuncName() @ "SeasonalEventStats4:" @ SeasonalEventStats4, bLogStatsWrite);
break;
case STATID_SeasonalEventStats5:
SeasonalEventStats5 = Value;
`log(GetFuncName() @ "SeasonalEventStats5:" @ SeasonalEventStats5, bLogStatsWrite);
break;
case STATID_DoshVaultProgress:
VerifyDoshVaultCrates();
break;
case STATID_PersonalBest_KnifeKills:
PersonalBest_KnifeKills = Value;
`log(GetFuncName() @ "PersonalBest_KnifeKills:" @ PersonalBest_KnifeKills, bLogStatsWrite);
break;
case STATID_PersonalBest_PistolKills:
PersonalBest_PistolKills = Value;
`log(GetFuncName() @ "PersonalBest_PistolKills:" @ PersonalBest_PistolKills, bLogStatsWrite);
break;
case STATID_PersonalBest_HeadShots:
PersonalBest_HeadShots = Value;
`log(GetFuncName() @ "PersonalBest_HeadShots:" @ PersonalBest_HeadShots, bLogStatsWrite);
break;
case STATID_PersonalBest_Healing:
PersonalBest_Healing = Value;
`log(GetFuncName() @ "PersonalBest_Healing:" @ PersonalBest_Healing, bLogStatsWrite);
break;
case STATID_PersonalBest_Kills:
PersonalBest_Kills = Value;
`log(GetFuncName() @ "PersonalBest_Kills:" @ PersonalBest_Kills, bLogStatsWrite);
break;
case STATID_PersonalBest_Assists:
PersonalBest_Assists = Value;
`log(GetFuncName() @ "PersonalBest_Assists:" @ PersonalBest_Assists, bLogStatsWrite);
break;
case STATID_PersonalBest_LargeZedKill:
PersonalBest_LargeZedKil = Value;
`log(GetFuncName() @ "PersonalBest_LargeZedKil:" @ PersonalBest_LargeZedKil, bLogStatsWrite);
break;
case STATID_PersonalBest_Dosh:
PersonalBest_Dosh = Value;
`log(GetFuncName() @ "PersonalBest_Dosh:" @ PersonalBest_Dosh, bLogStatsWrite);
break;
}
}
/** returns cached stats value */
private event GetPerkBuildFromStats( class<KFPerk> PerkClass, out int Build )
{
switch( PerkClass )
{
case class'KFPerk_Commando':
Build = CommandoBuild;
break;
case class'KFPerk_Berserker':
Build = BerserkerBuild;
break;
case class'KFPerk_Support':
Build = SupportBuild;
break;
case class'KFPerk_FieldMedic':
Build = MedicBuild;
break;
case class'KFPerk_Firebug':
Build = FirebugBuild;
break;
case class'KFPerk_Demolitionist':
Build = DemoBuild;
break;
case class'KFPerk_Gunslinger':
Build = GunslingerBuild;
break;
case class'KFPerk_Sharpshooter':
Build = SharpshooterBuild;
break;
case class'KFPerk_Swat':
Build = SwatBuild;
break;
case class'KFPerk_Survivalist':
Build = SurvBuild;
break;
}
}
/** returns cached stats value */
private event SaveBuildToStats(class<KFPerk> InPerk, int Build)
{
local int StatID;
StatId = InPerk.static.GetPerkBuildStatID();
// save and update cached var
SetIntStat(StatId, Build);
CacheStatsValue(StatId, Build);
`log(GetFuncName() @ "Saving build for perk:" @ InPerk @ "Build:" @ Build, bLogStatsWrite);
}
/*********************************************************************************************
* @name Perk Progression
********************************************************************************************* */
// External get functions
native final function int GetPerkPrestigeLevel(class<KFPerk> Perk);
native final function int GetPerkLevel( class<KFPerk> Perk );
native final function int GetPerkBuild( class<KFPerk> Perk );
native final static function int GetXPNeededAt( int Level );
// Use these instead of IncrementIntStat, etc...
native final private function IncrementXPStat( class<KFPerk> PerkClass, optional int IncBy = 1 );
native final private function bool IncrementPSGStat(class<KFPerk> PerkClass);
native final private function int GetXPFromProgress( int PerkProgress );
native final private function int GetLVLFromProgress( int PerkProgress );
native final private function int GetPSGFromProgress( int PerkProgress );
/** Called when some game event awards XP */
private event AddXP( class<KFPerk> PerkClass, int dXP, bool bApplyPrestigeBonus = false )
{
local float XPMultiplier;
local float BonusXP;
local int PerkIndex, BonusXPTruncated, BonusXPOverflow;
XPMultiplier = 0;
if( PerkClass == None )
{
return;
}
if (MyKFPC != none && bApplyPrestigeBonus)
{
XPMultiplier = MYKFPC.GetPerkPrestigeXPMultiplier(PerkClass);
if (XPMultiplier > 0.f)
{
// apply integer bonus
BonusXP = float(dXP) * XPMultiplier;
BonusXPTruncated = int(BonusXP);
// accumulate remainder
PerkIndex = MyKFPC.GetPerkIndexFromClass(PerkClass);
BonusXPRemainder[PerkIndex] += BonusXP - BonusXPTruncated;
// apply accumulated remainder if necessary
if (BonusXPRemainder[PerkIndex] >= 1.f)
{
BonusXPOverflow = int(BonusXPRemainder[PerkIndex]);
BonusXPTruncated += BonusXPOverflow;
BonusXPRemainder[PerkIndex] -= BonusXPOverflow;
}
dXP += BonusXPTruncated;
}
}
IncrementXPStat( PerkClass, dXP );
if( MyKFPC != none )
{
MyKFPC.NotifyXPGain(PerkClass, dXP, BonusXPTruncated);
}
`log("AddXP Perk: "$PerkClass$"; dXP: "$dXP$"; BonusXP: "$BonusXPTruncated, bLogStatsWrite);
}
/** Called by IncrementXPStat when new level is achieved */
private event NotifyLevelUp(class<KFPerk> PerkClass, int NewLVL, int NewPrestigeLevel)
{
if( MyKFPC != None )
{
MyKFPC.NotifyLevelUp( PerkClass, NewLVL, NewPrestigeLevel);
`log(GetFuncName() @ "PerkClass:" @ PerkClass @ "New LVL:" @ NewLVL @ "NewPrestigeLevel" @NewPrestigeLevel, bLogStatsWrite);
if( NewLVL % 5 == 0 )
{
CheckPerkLvlAchievement( PerkCLass, NewLVL );
}
}
}
/** returns cached value for xp */
private event int GetPerkXP( int StatID )
{
switch( StatID )
{
case STATID_Cmdo_Progress: return CommandoXP;
case STATID_Bsrk_Progress: return BerserkerXP;
case STATID_Sup_Progress: return SupportXP;
case STATID_Medic_Progress: return MedicXP;
case STATID_Fire_Progress: return FirebugXP;
case STATID_Demo_Progress: return DemoXP;
case STATID_Guns_Progress: return GunslingerXP;
case STATID_Shrp_Progress: return SharpshooterXP;
case STATID_Swat_Progress: return SwatXP;
case STATID_Surv_Progress: return SurvXP;
}
return 0;
}
/** returns cached value for lvl */
private event int GetPerkLVLInternal( int StatID )
{
switch( StatID )
{
case STATID_Cmdo_Progress: return CommandoLVL;
case STATID_Bsrk_Progress: return BerserkerLVL;
case STATID_Sup_Progress: return SupportLVL;
case STATID_Medic_Progress: return MedicLVL;
case STATID_Fire_Progress: return FirebugLVL;
case STATID_Demo_Progress: return DemoLVL;
case STATID_Guns_Progress: return GunslingerLVL;
case STATID_Shrp_Progress: return SharpshooterLVL;
case STATID_Swat_Progress: return SwatLVL;
case STATID_Surv_Progress: return SurvLVL;
}
return 0;
}
/** returns cached value for lvl */
private event int GetPerkPSG( int StatID )
{
switch( StatID )
{
case STATID_Cmdo_Progress: return CommandoPSG;
case STATID_Bsrk_Progress: return BerserkerPSG;
case STATID_Sup_Progress: return SupportPSG;
case STATID_Medic_Progress: return MedicPSG;
case STATID_Fire_Progress: return FirebugPSG;
case STATID_Demo_Progress: return DemoPSG;
case STATID_Guns_Progress: return GunslingerPSG;
case STATID_Shrp_Progress: return SharpshooterPSG;
case STATID_Swat_Progress: return SwatPSG;
case STATID_Surv_Progress: return SurvPSG;
}
return 0;
}
private event int GetPerkLVLByClass(class<KFPerk> PerkClass)
{
local int StatID;
StatID = PerkClass.static.GetProgressStatID();
return GetPerkLVLInternal(StatID);
}
private event int GetPerkPrestigeLVLByClass(class<KFPerk> PerkClass)
{
local int StatID;
StatID = PerkClass.static.GetProgressStatID();
return GetPerkPSG(StatID);
}
/*********************************************************************************************
* @name Personal Bests (AAR)
********************************************************************************************* */
function int GetPersonalBest( EPersonalBests PersonalBestID )
{
switch( PersonalBestID )
{
case EPB_KnifeKills: return PersonalBest_KnifeKills;
case EPB_PistolKills: return PersonalBest_PistolKills;
case EPB_HeadShots: return PersonalBest_HeadShots;
case EPB_Healing: return PersonalBest_Healing;
case EPB_Kills: return PersonalBest_Kills;
case EPB_Assists: return PersonalBest_Assists;
case EPB_LargeZedKill: return PersonalBest_LargeZedKil;
case EPB_Dosh: return PersonalBest_Dosh;
}
return 0;
}
function SavePersonalBest( EPersonalBests PersonalBestID, int Value )
{
switch( PersonalBestID )
{
case EPB_KnifeKills: SetIntStat(STATID_PersonalBest_KnifeKills, Value); break;
case EPB_PistolKills: SetIntStat(STATID_PersonalBest_PistolKills, Value); break;
case EPB_HeadShots: SetIntStat(STATID_PersonalBest_HeadShots, Value); break;
case EPB_Healing: SetIntStat(STATID_PersonalBest_Healing, Value); break;
case EPB_Kills: SetIntStat(STATID_PersonalBest_Kills, Value); break;
case EPB_Assists: SetIntStat(STATID_PersonalBest_Assists, Value); break;
case EPB_LargeZedKill: SetIntStat(STATID_PersonalBest_LargeZedKill, Value); break;
case EPB_Dosh: SetIntStat(STATID_PersonalBest_Dosh, Value); break;
}
}
/*********************************************************************************************
* @name Gameplay
********************************************************************************************* */
private event AddToHitsTaken()
{
SeasonalEventStats_OnHitTaken();
}
private event AddToHitsGiven(class<DamageType> DT)
{
SeasonalEventStats_OnHitGiven(DT);
}
/**
* @brief Add a kill and give some EXP tp the player
* @param MonsterClass The killed monster's class
* @param Difficulty The current game difficulty
* @param DT The damagetype used to kill the zed
* @return [description]
*/
private event AddToKills( class<KFPawn_Monster> MonsterClass, byte Difficulty, class<DamageType> DT, bool bKiller )
{
// seasonal event hook
SeasonalEventStats_OnZedKilled(MonsterClass, Difficulty, DT);
if (!bKiller)
{
return;
}
IncrementIntStat( STATID_Kills, 1 );
Kills++;
if(!MonsterClass.default.bVersusZed)
{
MyKFPC.ReceiveLocalizedMessage(Class'KFLocalMessage_PlayerKills', KMT_PLayerKillZed, MyKFPC.PlayerReplicationInfo, none, MonsterClass);
}
if( IsStalkerKill( MonsterClass, DT ) )
{
AddStalkerKill( Difficulty );
}
else if( IsCrawlerKill( MonsterClass, DT ) )
{
AddCrawlerKill( Difficulty );
}
else if( IsFleshPoundKill( MonsterClass, DT ) )
{
AddFleshpoundKill( Difficulty );
}
else if( IsClotKill( MonsterClass, DT ) )
{
AddClotKill( Difficulty );
}
else if( IsClotSurvivalistKill( MonsterClass ) )
{
AddClotSurvivalistKill( Difficulty );
}
else if( IsBloatKill( MonsterClass, DT ) )
{
AddBloatKill( Difficulty );
}
`RecordAARZedKill(MyKFPC, MonsterClass, DT);
AddToKillObjectives(MonsterClass);
}
private event AddToHeadshotKills( class<KFPawn_Monster> MonsterClass, byte Difficulty, class<DamageType> DT )
{
// seasonal event hook
SeasonalEventStats_OnZedKilledByHeadshot(MonsterClass, Difficulty, DT);
}
private event AddNonZedKill(class<Pawn> KilledClass, byte Difficulty)
{
if (MyKFPC != none && MyKFPC.Pawn != none && (KilledClass.Name == 'KFPawn_Human_Versus' || KilledClass.Name == 'KFPawn_Human'))
{
AddToVersusKillObjectives(MyKFPC.Pawn.class);
}
}
private native function AddToKillObjectives(class<KFPawn_Monster> ZedClass);
private native function AddToVersusKillObjectives(class<Pawn> KillerClass);
/**
* @brief Adds EXP for a qualified stalker kill
* @details The commando perk only receives extra EXP when a stalker is killed
* with a commando weapon. The currently slected skill does not matter
* @param Difficulty current game difficulty
*/
private function AddStalkerKill( byte Difficulty )
{
StalkerKills++;
IncrementIntStat( STATID_StalkerKills, 1 );
AddXP( class'KFPerk_Commando', class'KFPerk_Commando'.static.GetStalkerKillXP( Difficulty ) );
`log(GetFuncName() @ "Adding stalker kill, IncrementIntStat STATID_StalkerKills by:" @ class'KFPerk_Commando'.static.GetStalkerKillXP(Difficulty), bLogStatsWrite);
//AAR
`RecordSecondaryXPGain( MyKFPC, class'KFPerk_Commando', class'KFPerk_Commando'.static.GetStalkerKillXP( Difficulty ) );
KFGameReplicationInfo(MyKFPC.WorldInfo.GRI).SecondaryXPAccumulator += class'KFPerk_Commando'.static.GetStalkerKillXP( Difficulty );
}
/**
* @brief Adds EXP for a small radius kill
* @details Berserker gains XP when killing a zed close to another player
*
* @param Difficulty current game difficulty
*/
private event AddSmallRadiusKill( byte Difficulty, class<KFPerk> PerkClass )
{
if(PerkClass == class'KFPerk_Berserker'.static.GetPerkClass())
{
AddXP( class'KFPerk_Berserker', class'KFPerk_Berserker'.static.GetSmallRadiusKillXP(Difficulty) );
//AAR
`RecordSecondaryXPGain( MyKFPC, class'KFPerk_Berserker', class'KFPerk_Berserker'.static.GetSmallRadiusKillXP(Difficulty) );
KFGameReplicationInfo(MyKFPC.WorldInfo.GRI).SecondaryXPAccumulator += class'KFPerk_Berserker'.static.GetSmallRadiusKillXP(Difficulty);
}
else if(PerkClass == class'KFPerk_Survivalist'.static.GetPerkClass())
{
AddXP( class'KFPerk_Survivalist', class'KFPerk_Survivalist'.static.GetSmallRadiusKillXP(Difficulty) );
//AAR
`RecordSecondaryXPGain( MyKFPC, class'KFPerk_Survivalist', class'KFPerk_Survivalist'.static.GetSmallRadiusKillXP(Difficulty) );
KFGameReplicationInfo(MyKFPC.WorldInfo.GRI).SecondaryXPAccumulator += class'KFPerk_Survivalist'.static.GetSmallRadiusKillXP(Difficulty);
}
}
/**
* @brief Adds EXP for a qualified crawler kill
* @details The Firebug perk only receives extra EXP when a crawler is killed
* with a Firebug weapon. The currently selected skill does not matter
* @param Difficulty current game difficulty
*/
private function AddCrawlerKill( byte Difficulty )
{
CrawlerKills++;
IncrementIntStat( STATID_CrawlerKills, 1 );
AddXP( class'KFPerk_Firebug', class'KFPerk_Firebug'.static.GetCrawlerKillXP( Difficulty ) );
`log(GetFuncName() @ "Adding crawler kill, IncrementIntStat STATID_CrawlerKills by:" @ class'KFPerk_Firebug'.static.GetCrawlerKillXP(Difficulty), bLogStatsWrite);
//AAR
`RecordSecondaryXPGain( MyKFPC, class'KFPerk_Firebug', class'KFPerk_Firebug'.static.GetCrawlerKillXP( Difficulty ) );
KFGameReplicationInfo(MyKFPC.WorldInfo.GRI).SecondaryXPAccumulator += class'KFPerk_Firebug'.static.GetCrawlerKillXP( Difficulty );
}
/**
* @brief Adds EXP for a qualified Fleshpound kill
* @details The Demolitionist perk only receives extra EXP when a Fleshpound is killed
* with a demo weapon. The currently selected skill does not matter
* @param Difficulty current game difficulty
*/
private function AddFleshpoundKill( byte Difficulty )
{
FleshpoundKills++;
IncrementIntStat( STATID_FleshpoundKills, 1 );
AddXP( class'KFPerk_Demolitionist', class'KFPerk_Demolitionist'.static.GetFleshpoundKillXP( Difficulty ) );
`log(GetFuncName() @ "Adding crawler kill, IncrementIntStat STATID_CrawlerKills by:" @ class'KFPerk_Firebug'.static.GetCrawlerKillXP(Difficulty), bLogStatsWrite);
//AAR
`RecordSecondaryXPGain( MyKFPC, class'KFPerk_Demolitionist', class'KFPerk_Demolitionist'.static.GetFleshpoundKillXP( Difficulty ) );
KFGameReplicationInfo(MyKFPC.WorldInfo.GRI).SecondaryXPAccumulator += class'KFPerk_Demolitionist'.static.GetFleshpoundKillXP( Difficulty );
}
/**
* @brief Adds EXP for a qualified clot kill
* @details The SWAT perk only receives extra EXP when a Fleshpound is killed
* with a demo weapon. The currently selected skill does not matter
* @param Difficulty current game difficulty
*/
private function AddClotKill( byte Difficulty )
{
AddXP( class'KFPerk_SWAT', class'KFPerk_SWAT'.static.GetClotKillXP( Difficulty ) );
//AAR
`RecordSecondaryXPGain( MyKFPC, class'KFPerk_SWAT', class'KFPerk_SWAT'.static.GetClotKillXP( Difficulty ) );
KFGameReplicationInfo(MyKFPC.WorldInfo.GRI).SecondaryXPAccumulator += class'KFPerk_SWAT'.static.GetClotKillXP( Difficulty );
}
/**
* @brief Adds EXP for a qualified clot kill
* @details The Survivalist perk receives extra EXP when a clot is killed
* with any weapon
* @param Difficulty current game difficulty
*/
private function AddClotSurvivalistKill( byte Difficulty )
{
AddXP( class'KFPerk_Survivalist', class'KFPerk_Survivalist'.static.GetClotKillXP( Difficulty ) );
//AAR
`RecordSecondaryXPGain( MyKFPC, class'KFPerk_Survivalist', class'KFPerk_Survivalist'.static.GetClotKillXP( Difficulty ) );
KFGameReplicationInfo(MyKFPC.WorldInfo.GRI).SecondaryXPAccumulator += class'KFPerk_Survivalist'.static.GetClotKillXP( Difficulty );
}
/**
* @brief Adds EXP for a qualified bloat kill
* @details The Firebug perk only receives extra EXP when a bloat is killed
* with a Firebug weapon. The currently selected skill does not matter
* @param Difficulty current game difficulty
*/
private function AddBloatKill( byte Difficulty )
{
AddXP( class'KFPerk_Firebug', class'KFPerk_Firebug'.static.GetBloatKillXP( Difficulty ) );
//AAR
`RecordSecondaryXPGain( MyKFPC, class'KFPerk_Firebug', class'KFPerk_Firebug'.static.GetBloatKillXP( Difficulty ) );
KFGameReplicationInfo(MyKFPC.WorldInfo.GRI).SecondaryXPAccumulator += class'KFPerk_Firebug'.static.GetBloatKillXP( Difficulty );
}
/**
* @brief Checks if a crawler kill qualifies for Firebug EXP
*
* @param DT Used damage type
* @param MonsterClass the killed zed's class
* @return true if the zed was a crawler and the damage type is on perk
*/
private final function bool IsCrawlerKill( class<KFPawn_Monster> MonsterClass, class<DamageType> DT )
{
return MonsterClass.static.IsCrawlerClass() &&
class'KFPerk'.static.IsDamageTypeOnThisPerk( class<KFDamageType>(DT), class'KFPerk_Firebug'.static.GetPerkClass() );
}
/**
* @brief Checks if a stalker kill qualifies for Commando EXP
*
* @param DT Used damage type
* @param MonsterClass the killed zed's class
* @return true if the zed was a stalker and the damage type is on perk
*/
private final function bool IsStalkerKill( class<KFPawn_Monster> MonsterClass, class<DamageType> DT )
{
return MonsterClass.static.IsStalkerClass() &&
class'KFPerk'.static.IsDamageTypeOnThisPerk( class<KFDamageType>(DT), class'KFPerk_Commando'.static.GetPerkClass() );
}
/**
* @brief Checks if a fleshpund kill qualifies for demo EXP
*
* @param DT Used damage type
* @param MonsterClass the killed zed's class
* @return true if the zed was a stalker and the damage type is on perk
*/
private final function bool IsFleshPoundKill( class<KFPawn_Monster> MonsterClass, class<DamageType> DT )
{
return MonsterClass.static.IsFleshpoundClass() &&
class'KFPerk'.static.IsDamageTypeOnThisPerk( class<KFDamageType>(DT), class'KFPerk_Demolitionist'.static.GetPerkClass() );
}
/**
* @brief Checks if a clot kill qualifies for swat EXP
*
* @param DT Used damage type
* @param MonsterClass the killed zed's class
* @return true if the zed was a stalker and the damage type is on perk
*/
private final function bool IsClotKill( class<KFPawn_Monster> MonsterClass, class<DamageType> DT )
{
return MonsterClass.static.IsClotClass() &&
class'KFPerk'.static.IsDamageTypeOnThisPerk(class<KFDamageType>(DT), class'KFPerk_SWAT'.static.GetPerkClass());
}
/**
* @brief Checks if a clot kill qualifies for survivalist EXP
*
* @param MonsterClass the killed zed's class
* @return true if the zed was a clot
*/
private final function bool IsClotSurvivalistKill( class<KFPawn_Monster> MonsterClass )
{
return MonsterClass.static.IsClotClass();
}
/**
* @brief Checks if a bloat kill qualifies for Firebug EXP
*
* @param DT Used damage type
* @param MonsterClass the killed zed's class
* @return true if the zed was a crawler and the damage type is on perk
*/
private final function bool IsBloatKill( class<KFPawn_Monster> MonsterClass, class<DamageType> DT )
{
return MonsterClass.static.IsBloatClass() &&
class'KFPerk'.static.IsDamageTypeOnThisPerk( class<KFDamageType>(DT), class'KFPerk_Firebug'.static.GetPerkClass() );
}
/*
* Calculates the perk XP reward for a certain number of points
* Split from AddWeldingPoints so analytics can log XP earned.
*/
private function int ComputeWeldingXP( int Points )
{
local int XPEarned;
local KFGameReplicationInfo KFGRI;
XPEarned = FFloor( float(Points) / float(WeldingPointsRequired) );
if( XPEarned >= 1 )
{
KFGRI = KFGameReplicationInfo(MyKFPC.WorldInfo.GRI);
class'KFPerk_Support'.static.MultiplySecondaryXPPoints( XPEarned, KFGRI.GameDifficulty);
}
return XPEarned;
}
/** Welding does not earn XP directly, WeldingPointsRequired have to be earned first */
private event int AddWeldingPoints( int PointsWelded )
{
local int XPEarned;
WeldingPoints += PointsWelded;
`log(GetFuncName() @ "WeldingPoints are now:" @ WeldingPoints, bLogStatsWrite);
XPEarned = ComputeWeldingXP( WeldingPoints ); //FFloor( float(WeldingPoints) / float(WeldingPointsRequired) );
if( XPEarned >= 1 )
{
AddXP(class'KFPerk_Support', XPEarned);
//AAR
`RecordSecondaryXPGain( MyKFPC, class'KFPerk_Support', XPEarned );
KFGameReplicationInfo(MyKFPC.WorldInfo.GRI).SecondaryXPAccumulator += XPEarned;
// keep a running tally for analytics at the end of the match
PerRoundWeldXP += XPEarned;
// reset/rollover points needed for next xp gain
WeldingPoints = WeldingPoints % WeldingPointsRequired;
`log(GetFuncName() @ "Welding XP earned :" @ XPEarned, bLogStatsWrite);
}
// We need the welding points to be persistent
SetIntStat( STATID_Sup_WeldPoints, WeldingPoints );
return XPEarned;
}
/** Repairing doors is another source of secondary XP for the Support class. It uses different
* values for the XP earned, and is only earned on completion. However, it tallies into
* the same end stat.
*/
private event int DoorRepaired()
{
local int XPEarned;
local KFGameReplicationInfo KFGRI;
KFGRI = KFGameReplicationInfo(MyKFPC.WorldInfo.GRI);
if (KFGRI != none)
{
class'KFPerk_Support'.static.GetDoorRepairXP(XPEarned, KFGRI.GameDifficulty);
if (XPEarned > 0)
{
AddXP(class'KFPerk_Support', XPEarned);
`RecordSecondaryXPGain(MyKFPC, class'KFPerk_Support', XPEarned);
KFGRI.SecondaryXPAccumulator += XPEarned;
PerRoundWeldXP += XPEarned;
`log(GetFuncName() @ "Door Repair XP earned :" @ XPEarned);
}
}
return XPEarned;
}
/*
* Calculates the perk XP reward for a certain number of points
* Split from AddHealingPoints so analytics can log XP earned.
*/
private function int ComputeHealingXP( int Points )
{
local int XPEarned;
local KFGameReplicationInfo KFGRI;
XPEarned = FFloor( float(Points) / float(HealingPointsRequired) );
if( XPEarned >= 1 )
{
KFGRI = KFGameReplicationInfo(MyKFPC.WorldInfo.GRI);
class'KFPerk_FieldMedic'.static.MultiplySecondaryXPPoints( XPEarned, KFGRI.GameDifficulty);
}
return XPEarned;
}
/** Healing does not earn XP directly, HealingPointsRequired have to be earned first */
private event int AddHealingPoints( int PointsHealed )
{
local int XPEarned;
HealingPoints += PointsHealed;
`log(GetFuncName() @ "HealingPoints are now:" @ HealingPointsRequired, bLogStatsWrite);
XPEarned = ComputeHealingXP( HealingPoints );
if( XPEarned >= 1 )
{
AddXP(class'KFPerk_FieldMedic', XPEarned);
//AAR
`RecordSecondaryXPGain( MyKFPC, class'KFPerk_FieldMedic', XPEarned );
KFGameReplicationInfo(MyKFPC.WorldInfo.GRI).SecondaryXPAccumulator += XPEarned;
// keep a running tally for analytics at the end of the match
PerRoundHealXP += XPEarned;
// reset/rollover points needed for next xp gain
HealingPoints = HealingPoints % HealingPointsRequired;
`log(GetFuncName() @ "Healing XP earned :" @ XPEarned, bLogStatsWrite);
}
// We need the welding points to be persistent
SetIntStat( STATID_Medic_HealPoints, HealingPoints );
if( MyKFPC != none )
{
MyKFPC.ClientUnlockAchievement( KFACHID_IGotYourBack );
}
return XPEarned;
}
/**
* @brief Add a headshot and give some EXP tp the player
* @param Difficulty The current game difficulty
* @param DT The damagetype used to headshot the zed
* @return [description]
*/
private event AddToHeadshots( byte Difficulty, class<DamageType> DT )
{
//Do both separately to allow for multi-perk pass through (Ex: single flare uses both)
if( IsGunslingerHeadshot( DT ) )
{
AddGunslingerHeadshot( Difficulty );
}
if( IsSharpshooterHeadshot(DT) )
{
AddSharpshooterHeadshot( Difficulty );
}
}
/**
* @brief Adds EXP for a gunslinger headshot
* @details The Gunslinger perk only receives extra EXP when a headshot is achieved with a Gunslinger weapon.
* @param Difficulty current game difficulty
*/
private function AddGunslingerHeadshot( byte Difficulty )
{
AddXP( class'KFPerk_Gunslinger', class'KFPerk_Gunslinger'.static.GetHeadshotXP(Difficulty) );
//AAR
`RecordSecondaryXPGain( MyKFPC, class'KFPerk_Gunslinger', class'KFPerk_Gunslinger'.static.GetHeadshotXP(Difficulty) );
KFGameReplicationInfo(MyKFPC.WorldInfo.GRI).SecondaryXPAccumulator += class'KFPerk_Gunslinger'.static.GetHeadshotXP(Difficulty);
}
/**
* @brief Adds EXP for a sharpshooter headshot
* @details The Sharpshooter perk only receives extra EXP when a headshot is achieved with a Sharpshooter weapon.
* @param Difficulty current game difficulty
*/
private function AddSharpshooterHeadshot( byte Difficulty )
{
AddXP( class'KFPerk_Sharpshooter', class'KFPerk_Sharpshooter'.static.GetHeadshotXP(Difficulty) );
//AAR
`RecordSecondaryXPGain( MyKFPC, class'KFPerk_Sharpshooter', class'KFPerk_Sharpshooter'.static.GetHeadshotXP(Difficulty) );
KFGameReplicationInfo(MyKFPC.WorldInfo.GRI).SecondaryXPAccumulator += class'KFPerk_Sharpshooter'.static.GetHeadshotXP(Difficulty);
}
/**
* @brief Checks if a headshot qualifies for gunslinger EXP
*
* @param DT Used damage type
* @return true if damage type is on perk
*/
private final function bool IsGunslingerHeadshot( class<DamageType> DT )
{
return (class'KFPerk_Gunslinger'.static.IsDamageTypeOnPerk( class<KFDamageType>(DT) ));
}
/**
* @brief Checks if a headshot qualifies for sharpshooter EXP
*
* @param DT Used damage type
* @return true if damage type is on perk
*/
private final function bool IsSharpshooterHeadshot( class<DamageType> DT )
{
return (class'KFPerk'.static.IsDamageTypeOnThisPerk( class<KFDamageType>(DT), class'KFPerk_Sharpshooter'.static.GetPerkClass() ));
}
final function int GetSeasonalEventStatValue(int StatIdx)
{
switch (StatIdx)
{
case 0:
return SeasonalEventStats1;
case 1:
return SeasonalEventStats2;
case 2:
return SeasonalEventStats3;
case 3:
return SeasonalEventStats4;
case 4:
return SeasonalEventStats5;
};
return -1;
}
final function int GetSeasonalEventStatMaxValue(int StatIdx)
{
switch (StatIdx)
{
case 0:
return SeasonalEventStatsMax1;
case 1:
return SeasonalEventStatsMax2;
case 2:
return SeasonalEventStatsMax3;
case 3:
return SeasonalEventStatsMax4;
case 4:
return SeasonalEventStatsMax5;
};
return -1;
}
/*********************************************************************************************
* @name Achievements
********************************************************************************************* */
function GetAchievements()
{
if( MyKFPC.IsLocalPlayerController() )
{
Achievements.Remove( 0, Achievements.length );
MyKFPC.OnlineSub.PlayerInterface.GetAchievements( 0, Achievements );
}
}
final function bool IsAchievementUnlocked( int AchievementIndex )
{
return ( AchievementIndex < Achievements.length ) && Achievements[AchievementIndex].bWasAchievedOnline;
}
function OnUnlockAchievement( int AchievementIndex )
{
//Reload the achievement list to get the change
GetAchievements();
}
native function UnlockDingoAchievement(int AchievementId, optional int Value = 1);
/**
* @brief Call into native to determine if we achieved anything
*
* @param MapName The name of the map played
* @param Difficulty The game's difficulty
* @param GameLength short/medium/long
* @param bCoop multiplayer or not
*/
native final function OnGameWon( string MapName, byte Difficulty, byte GameLength, byte bCoop, class<KFPerk> PerkClass );
/** Used for Versus. */
native final function OnRoundEnd( byte WinningTeam );
/** Whenever the game end, calculate general acheivements. */
native final function OnGameEnd( string MapName, byte Difficulty, byte GameLength, byte EndingWaveNum, byte bCoop, class<KFPerk> PerkClass );
/**
* @brief Check for map specific achievements on game end
*
* @param MapName The name of the map played
* @param Difficulty The game's difficulty
* @param GameLength short/medium/long
* @param bCoop multiplayer or not
*/
native final function CheckMapEndAchievements( string MapName, byte Difficulty, byte bCoop, byte bObjectiveMode );
/**
* @brief Check for any additional behavior on collectible achievements
*/
native final function CheckCollectibleAchievement( string MapName );
/**
* @brief Check for any additional behavior on collectible achievements
*/
native final function CheckEndWaveObjective(int CurrentWave);
/**
* @brief Check if a new perk tier has been reached
*
* @param PerkClass Perk leveled up
* @param NewLVL The new perk level
*/
native final private function CheckPerkLvlAchievement( class<KFPerk> PerkClass, int NewLVL );
/**
* @brief Check if a new difficulty with the selected perk was won
*
* @param PerkClass Selected perk class
* @param Difficulty Difficulty played
*/
native final private function CheckPerkDifficultyAchievements( class<KFPerk> PerkClass, byte Difficulty );
/**
* @brief Check if all perks reached lvl 25 and unlock achievement
*/
native final private function CheckAllPerksLvl25();
/**
* @brief Unlocks the tutorial achievement
*/
native final function UnlockTutorialAchievement();
native final function CheckForRoundTeamWinAchievements( byte WinningTeam );
/**
* @brief Grant any perk prestige inventory rewards if necessary
*/
native final function CheckPerkPSGRewards(class<KFPerk> PSGPerkClass);
/*********************************************************************************************
* @name Events
********************************************************************************************* */
final function bool CanCacheSpecialEvent()
{
return InitialSpecialEventInfo > 0;
}
/** Verify what event we're in and cache local event state. If we've changed to a new event,
* clear out the status flags before caching new date value.
*/
native final private function CacheSpecialEventState(int Value, int Year, int Month);
native final function int GetSpecialEventRewardValue();
/** Triggered by KF PC when the special event ID is passed through as a valid value */
final function UpdateSpecialEventState()
{
local int year, month, dayofweek, day, hour, minute, second, msec;
GetSystemTime(year, month, dayofweek, day, hour, minute, second, msec);
CacheSpecialEventState(InitialSpecialEventInfo, year, month);
if( InitialSpecialEventInfo != SpecialEventInfo )
{
// Flush stats write if we did a reset
MyKFPC.ClientWriteAndFlushStats();
}
}
/** Update the state of a special event. If the passed in EventIndex doesn't match our current
* special event index, do not update the stat. Also, if the map name passed doesn't match
* the list of allowed maps in native, don't record.
*/
native final function UpdateSpecialEvent(int EventIndex, int ObjectiveIndex, int Year, int Month);
/** Grab the state of a special event objective at a specific index. */
native final function bool IsEventObjectiveComplete(int ObjectiveIndex);
final function bool CanCacheWeeklyEvent()
{
return InitialWeeklyEventInfo > 0;
}
/** Cache the state of the weekly event.If the cached week/year combo in the stored
* value don't match, everything is cleared.
*/
native final private function CacheWeeklyEventState(int Value);
/** Triggered by KF PC when the weekly event ID is passed through as a valid value */
final function UpdateWeeklyEventState()
{
CacheWeeklyEventState(InitialWeeklyEventInfo);
// Flush stats write if we did a reset
if (InitialWeeklyEventInfo != WeeklyEventInfo)
{
MyKFPC.ClientWriteAndFlushStats();
}
}
/** Update the state of the weekly event. Called via game type. */
native final function WeeklyEventComplete();
/** Whether or not the current weekly has been finished */
native final function bool IsWeeklyEventComplete();
/** Get a list of IDs associated with the prizes given out for completing a weekly */
native static final function array<int> GetWeeklyOutbreakRewards(int Index = -1);
/** Get the amount of Vosh a player would earn by completeting a map objective. */
native static final function int GetMapObjectiveVoshReward(byte Difficulty, byte WaveNum);
/** Award the player the Vosh for completeting a map objective. */
native final function MapObjectiveCompleted();
/*********************************************************************************************
* @name Seasonal Events
********************************************************************************************* */
final native simulated function bool SeasonalEventIsValid();
final simulated function SeasonalEventStats_OnMapObjectiveDeactivated(Actor ObjectiveInterfaceActor)
{
if (SeasonalEventIsValid())
{
SeasonalEvent.OnMapObjectiveDeactivated(ObjectiveInterfaceActor);
}
}
final simulated function SeasonalEventStats_OnMapCollectibleFound(PlayerReplicationInfo FinderPRI, int CollectibleID)
{
if (SeasonalEventIsValid())
{
SeasonalEvent.OnMapCollectibleFound(FinderPRI, CollectibleID);
}
}
final native simulated event SeasonalEventStats_OnGameWon(class<GameInfo> GameClass, int Difficulty, int GameLength, bool bCoOp);
final native simulated event SeasonalEventStats_OnGameEnd(class<GameInfo> GameClass);
final simulated function SeasonalEventStats_OnHitTaken()
{
if (SeasonalEventIsValid())
{
SeasonalEvent.OnHitTaken();
}
}
final simulated function SeasonalEventStats_OnHitGiven(class<DamageType> DT)
{
if (SeasonalEventIsValid())
{
SeasonalEvent.OnHitGiven(DT);
}
}
final simulated function SeasonalEventStats_OnZedKilled(class<KFPawn_Monster> MonsterClass, int Difficulty, class<DamageType> DT)
{
if (SeasonalEventIsValid())
{
SeasonalEvent.OnZedKilled(MonsterClass, Difficulty, DT);
}
}
final simulated function SeasonalEventStats_OnZedKilledByHeadshot(class<KFPawn_Monster> MonsterClass, int Difficulty, class<DamageType> DT)
{
if (SeasonalEventIsValid())
{
SeasonalEvent.OnZedKilledByHeadshot(MonsterClass, Difficulty, DT);
}
}
final simulated function SeasonalEventStats_OnBossDied()
{
if (SeasonalEventIsValid())
{
SeasonalEvent.OnBossDied();
}
}
final simulated function SeasonalEventStats_OnTriggerUsed(class<Trigger_PawnsOnly> TriggerClass)
{
if (SeasonalEventIsValid())
{
SeasonalEvent.OnTriggerUsed(TriggerClass);
}
}
final simulated function SeasonalEventStats_OnTryCompleteObjective(int ObjectiveIndex, int EventIndex)
{
if (SeasonalEventIsValid())
{
SeasonalEvent.OnTryCompleteObjective(ObjectiveIndex, EventIndex);
}
}
/*********************************************************************************************
* @name Dailies and daily-specific tracking
********************************************************************************************* */
/** Cache the state of our daily event progress. If we find a day change while doing so, clear progress */
native final function CacheDailyEventProgress(int Value);
/** Tracking for DOT_WeaponDamage type events */
native final function AddTrackedDamage(int Amount, class<DamageType> DamageType);
/** Tracking for DOT_Versus damage type events */
native final function AddTrackedVsDamage(int Amount, class<KFPawn> DamagerClass);
/** Tracking for DOT_PerkXP daily objectives */
native private final function AddTrackedXP(class<KFPerk> PerkClass, int XPGain);
/** Tracking for DOT_MapCompletion daily objectives */
native private final function AddTrackedMapCompletion(string MapName, byte Difficulty);
/** Tracking for DOT_Versus objectives that use round end for completion */
native private final function AddTrackedRoundEnd(byte WinningTeam);
/** Get a copy of the struct for the requested daily event */
native final function DailyEventInformation GetDailyEventStruct(int Index);
/** Whether or not a specific daily is complete */
native final function bool IsDailyObjectiveComplete(int Index);
/** Accessor for objective current value */
native final function int GetCurrentDailyValue(int Index);
/** Accessor for objective max value */
native final function int GetMaxDailyValue(int Index);
/** Accessor for objective reward value */
native static final function int GetDailyEventReward();
/** Accessor for objective reward value */
native static final function int GetWeeklyEventReward();
/*********************************************************************************************
* @name Dosh Vault
********************************************************************************************* */
native final function int GetTotalDoshCount();
native final function int GetLastSeenDoshCount();
native final function int GetUnseenDoshCount();
native final function MarkDoshVaultSeen();
native static final function int GetDoshVaultTierValue();
native static final function int GetPreStigeValueDoshRewardValue();
native final function CheckUnlockDoshVaultReward();
native final function CheckHasViewedDoshVault();
native final function VerifyDoshVaultCrates();
defaultproperties
{
bLogStatsWrite=false
PerRoundWeldXP = 0
PerRoundHealXP = 0
// These are the stats we are collecting
Properties.Add((PropertyId=STATID_Cmdo_Progress,Data=(Type=SDT_Int32,Value1=0))
Properties.Add((PropertyId=STATID_Cmdo_Build,Data=(Type=SDT_Int32,Value1=0))
Properties.Add((PropertyId=STATID_Bsrk_Progress,Data=(Type=SDT_Int32,Value1=0))
Properties.Add((PropertyId=STATID_Bsrk_Build,Data=(Type=SDT_Int32,Value1=0))
Properties.Add((PropertyId=STATID_Sup_Progress,Data=(Type=SDT_Int32,Value1=0))
Properties.Add((PropertyId=STATID_Sup_Build,Data=(Type=SDT_Int32,Value1=0))
Properties.Add((PropertyId=STATID_Fire_Progress,Data=(Type=SDT_Int32,Value1=0))
Properties.Add((PropertyId=STATID_Fire_Build,Data=(Type=SDT_Int32,Value1=0))
Properties.Add((PropertyId=STATID_Medic_Progress,Data=(Type=SDT_Int32,Value1=0))
Properties.Add((PropertyId=STATID_Medic_Build,Data=(Type=SDT_Int32,Value1=0))
Properties.Add((PropertyId=STATID_Shrp_Progress,Data=(Type=SDT_Int32,Value1=0))
Properties.Add((PropertyId=STATID_Shrp_Build,Data=(Type=SDT_Int32,Value1=0))
Properties.Add((PropertyId=STATID_Demo_Progress,Data=(Type=SDT_Int32,Value1=0))
Properties.Add((PropertyId=STATID_Demo_Build,Data=(Type=SDT_Int32,Value1=0))
Properties.Add((PropertyId=STATID_Surv_Progress,Data=(Type=SDT_Int32,Value1=0))
Properties.Add((PropertyId=STATID_Surv_Build,Data=(Type=SDT_Int32,Value1=0))
Properties.Add((PropertyId=STATID_Guns_Progress,Data=(Type=SDT_Int32,Value1=0))
Properties.Add((PropertyId=STATID_Guns_Build,Data=(Type=SDT_Int32,Value1=0))
Properties.Add((PropertyId=STATID_SWAT_Progress,Data=(Type=SDT_Int32,Value1=0))
Properties.Add((PropertyId=STATID_SWAT_Build,Data=(Type=SDT_Int32,Value1=0))
Properties.Add((PropertyId=STATID_Kills,Data=(Type=SDT_Int32,Value1=0))
Properties.Add((PropertyId=STATID_StalkerKills,Data=(Type=SDT_Int32,Value1=0))
Properties.Add((PropertyId=STATID_Sup_WeldPoints,Data=(Type=SDT_Int32,Value1=0))
Properties.Add((PropertyId=STATID_Medic_HealPoints,Data=(Type=SDT_Int32,Value1=0))
Properties.Add((PropertyId=STATID_CrawlerKills,Data=(Type=SDT_Int32,Value1=0))
Properties.Add((PropertyId=STATID_FleshpoundKills,Data=(Type=SDT_Int32,Value1=0))
Properties.Add((PropertyId=STATID_SpecialEventProgress,Data=(Type=SDT_Int32,Value1=0))
Properties.Add((PropertyId=STATID_WeeklyEventProgress,Data=(Type=SDT_Int32,Value1=0))
Properties.Add((PropertyId=STATID_DailyEventInfo,Data=(Type=SDT_Int32,Value1=0))
Properties.Add((PropertyId=STATID_DailyEventIDs,Data=(Type=SDT_Int32,Value1=0))
Properties.Add((PropertyId=STATID_DailyEventStats1,Data=(Type=SDT_Int32,Value1=0))
Properties.Add((PropertyId=STATID_DailyEventStats2,Data=(Type=SDT_Int32,Value1=0))
Properties.Add((PropertyId=STATID_SpecialEventKills_DEPRECATED,Data=(Type=SDT_Int32,Value1=0))
Properties.Add((PropertyId=STATID_SeasonalEventStats1,Data=(Type=SDT_Int32,Value1=0))
Properties.Add((PropertyId=STATID_SeasonalEventStats2,Data=(Type=SDT_Int32,Value1=0))
Properties.Add((PropertyId=STATID_SeasonalEventStats3,Data=(Type=SDT_Int32,Value1=0))
Properties.Add((PropertyId=STATID_SeasonalEventStats4,Data=(Type=SDT_Int32,Value1=0))
Properties.Add((PropertyId=STATID_SeasonalEventStats5,Data=(Type=SDT_Int32,Value1=0))
Properties.Add((PropertyId=STATID_PersonalBest_KnifeKills,Data=(Type=SDT_Int32,Value1=0))
Properties.Add((PropertyId=STATID_PersonalBest_PistolKills,Data=(Type=SDT_Int32,Value1=0))
Properties.Add((PropertyId=STATID_PersonalBest_HeadShots,Data=(Type=SDT_Int32,Value1=0))
Properties.Add((PropertyId=STATID_PersonalBest_Healing,Data=(Type=SDT_Int32,Value1=0))
Properties.Add((PropertyId=STATID_PersonalBest_Kills,Data=(Type=SDT_Int32,Value1=0))
Properties.Add((PropertyId=STATID_PersonalBest_Assists,Data=(Type=SDT_Int32,Value1=0))
Properties.Add((PropertyId=STATID_PersonalBest_LargeZedKill,Data=(Type=SDT_Int32,Value1=0))
Properties.Add((PropertyId=STATID_PersonalBest_Dosh,Data=(Type=SDT_Int32,Value1=0))
Properties.Add((PropertyId=STATID_MatchWins,Data=(Type=SDT_Int32,Value1=0))
Properties.Add((PropertyId=STATID_DoshVaultTotal,Data=(Type=SDT_Int32,Value1=0))
Properties.Add((PropertyId=STATID_LastViewedDoshVaultTotal,Data=(Type=SDT_Int32,Value1=0))
Properties.Add((PropertyId=STATID_DoshVaultProgress,Data=(Type=SDT_Int32,Value1=0))
Properties.Add((PropertyId=STATID_DoshVaultRecovered,Data=(Type=SDT_Int32,Value1=0))
// These are the views we are writing to
ViewIds(0)=VIEWID_KFGameStats
XPTable(0)=795
XPTable(1)=940
XPTable(2)=1112
XPTable(3)=1315
XPTable(4)=1556
XPTable(5)=1841
XPTable(6)=2178
XPTable(7)=2576
XPTable(8)=3047
XPTable(9)=3604
XPTable(10)=4263
XPTable(11)=5043
XPTable(12)=5965
XPTable(13)=7056
XPTable(14)=8347
XPTable(15)=9874
XPTable(16)=11680
XPTable(17)=13816
XPTable(18)=16343
XPTable(19)=19332
XPTable(20)=22868
XPTable(21)=27051
XPTable(22)=31999
XPTable(23)=37852
XPTable(24)=44775
//Base Weapons
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,SecondaryType=DOST_KnifeDamage,ObjectiveClasses=(KFWeap_Edged_Knife,KFDT_Slashing_Knife,KFDT_Slashing_Knife_Berserker,KFDT_Slashing_Knife_Medic,KFDT_Slashing_Knife_SWAT,KFDT_Slashing_KnifeHeavy,KFDT_Slashing_KnifeHeavy_Berserker,KFDT_Slashing_KnifeHeavy_Medic,KFDT_Slashing_KnifeHeavy_SWAT,KFDT_Piercing_KnifeStab,KFDT_Piercing_KnifeStab_Berserker,KFDT_Piercing_KnifeStab_FieldMedic,KFDT_Piercing_KnifeStab_SWAT,KFDT_Slashing_Knife_Survivalist,KFDT_Piercing_KnifeStab_Survivalist,KFDT_Slashing_KnifeHeavy_Survivalist),CompletionAmount=2500))
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Pistol_9mm, KFDT_Ballistic_9mm,KFDT_Bludgeon_9mm),CompletionAmount=4000)) //2500
//Swat Weapons
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_SMG_MP7, KFDT_Ballistic_MP7,KFDT_Bludgeon_MP7),CompletionAmount=5000)) //3000
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_SMG_MP5RAS, KFDT_Ballistic_MP5RAS,KFDT_Bludgeon_MP5RAS),CompletionAmount=7000)) //5000
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_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))
//Commando Weapons
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_AssaultRifle_AR15, KFDT_Ballistic_AR15,KFDT_Bludgeon_AR15),CompletionAmount=5000)) //3000
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_AssaultRifle_Bullpup, KFDT_Ballistic_Bullpup,KFDT_Bludgeon_Bullpup),CompletionAmount=7000)) //5000
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_AssaultRifle_AK12, KFDT_Ballistic_AK12,KFDT_Bludgeon_AK12),CompletionAmount=10000)) //7000
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_AssaultRifle_SCAR, KFDT_Ballistic_SCAR,KFDT_Bludgeon_SCAR),CompletionAmount=10000))
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_AssaultRifle_MKB42, KFDT_Ballistic_MKB42,KFDT_Bludgeon_MKB42),CompletionAmount=10000))
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_LMG_Stoner63A, KFDT_Ballistic_Stoner63A,KFDT_Bludgeon_Stoner63A),CompletionAmount=10000))
//Support Weapons
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Shotgun_MB500, KFDT_Ballistic_MB500,KFDT_Bludgeon_MB500),CompletionAmount=5000)) //3000
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Shotgun_DoubleBarrel, KFDT_Ballistic_DBShotgun,KFDT_Bludgeon_DBShotgun),CompletionAmount=7000)) //5000
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_HRG_Revolver_Buckshot, KFDT_Ballistic_HRGBuckshot, KFDT_Bludgeon_HRGBuckshot),CompletionAmount=10000))
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Shotgun_HZ12, KFDT_Ballistic_HZ12,KFDT_Bludgeon_HZ12),CompletionAmount=10000)) //7000
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Shotgun_M4, KFDT_Ballistic_M4Shotgun,KFDT_Bludgeon_M4Shotgun),CompletionAmount=10000)) //7000
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Shotgun_AA12, KFDT_Ballistic_AA12Shotgun,KFDT_Bludgeon_AA12Shotgun),CompletionAmount=10000))
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Shotgun_ElephantGun, KFDT_Ballistic_ElephantGun,KFDT_Bludgeon_ElephantGun),CompletionAmount=10000))
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_HRG_BlastBrawlers, KFDT_Ballistic_BlastBrawlersShotgun,KFDT_Bludgeon_BlastBrawlers,KFDT_Bludgeon_BlastBrawlersHeavy,KFDT_Bludgeon_BlastBrawlersBash),CompletionAmount=10000))
//Medic Weapons
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Pistol_Medic, KFDT_Ballistic_Pistol_Medic,KFDT_Bludgeon_Pistol_Medic),CompletionAmount=5000)) //3000
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_SMG_Medic, KFDT_Ballistic_SMG_Medic,KFDT_Bludgeon_SMG_Medic),CompletionAmount=7000)) //5000
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Shotgun_Medic, KFDT_Ballistic_Shotgun_Medic,KFDT_Bludgeon_Shotgun_Medic),CompletionAmount=9000)) //7000
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_HRG_Healthrower, KFDT_Toxic_HRGHealthrower, KFDT_Bludgeon_HRGHealthrower),CompletionAmount=9000))
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Rifle_Hemogoblin, KFDT_Ballistic_Hemogoblin, KFDT_Bludgeon_Hemogoblin),CompletionAmount=9000)) //7000
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_AssaultRifle_Medic, KFDT_Ballistic_Assault_Medic,KFDT_Bludgeon_Assault_Medic),CompletionAmount=9000))
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Rifle_HRGIncision, KFDT_Ballistic_HRGIncisionHurt, KFDT_Ballistic_HRGIncisionHeal,KFDT_Bludgeon_HRGIncision),CompletionAmount=5000))
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_HRG_Vampire, KFDT_Bleeding_HRG_Vampire_BloodSuck, KFDT_Ballistic_HRG_Vampire_BloodBallImpact, KFDT_Ballistic_HRG_Vampire_BloodBallHeavyImpact, KFDT_Toxic_HRG_Vampire_BloodBall, KFDT_Piercing_HRG_Vampire_CrystalSpike, KFDT_Bludgeon_HRG_Vampire),CompletionAmount=9000))
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_AssaultRifle_MedicRifleGrenadeLauncher, KFDT_Ballistic_MedicRifleGrenadeLauncher, KFDT_Bludgeon_MedicRifleGrenadeLauncher, KFDT_Toxic_MedicGrenadeLauncher, KFDT_Ballistic_MedicRifleGrenadeLauncherImpact),CompletionAmount=10000))
//Demo Weapons
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_GrenadeLauncher_HX25, KFDT_ExplosiveSubmunition_HX25,KFDT_Ballistic_HX25Impact,KFDT_Ballistic_HX25SubmunitionImpact,KFDT_Bludgeon_HX25),CompletionAmount=5000)) //3000
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Thrown_C4, KFDT_Explosive_C4,KFDT_Bludgeon_C4),CompletionAmount=2500))
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_GrenadeLauncher_M79, KFDT_Ballistic_M79Impact,KFDT_Explosive_M79,KFDT_Bludgeon_M79),CompletionAmount=7000))
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Shotgun_HRG_Kaboomstick, KFDT_Ballistic_HRG_Kaboomstick,KFDT_Explosive_HRG_Kaboomstick,KFDT_Bludgeon_HRG_Kaboomstick),CompletionAmount=9000))
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_RocketLauncher_RPG7, KFDT_Ballistic_RPG7Impact,KFDT_Explosive_RPG7,KFDT_Explosive_RPG7BackBlast,KFDT_Bludgeon_RPG7),CompletionAmount=7500))
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_AssaultRifle_M16M203, KFDT_Ballistic_M16M203,KFDT_Bludgeon_M16M203,KFDT_Ballistic_M203Impact,KFDT_Explosive_M16M203),CompletionAmount=9000)) //7000
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_RocketLauncher_SealSqueal, KFDT_Bludgeon_SealSqueal, KFDT_Explosive_SealSqueal, KFDT_Ballistic_SealSquealImpact),CompletionAmount=7500))
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_RocketLauncher_Seeker6, KFDT_Explosive_Seeker6, KFDT_Bludgeon_Seeker6, KFDT_Ballistic_Seeker6Impact),CompletionAmount=7500))
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_GrenadeLauncher_M32, KFDT_Bludgeon_M32, KFDT_Explosive_M32, KFDT_Ballistic_M32Impact),CompletionAmount=10000))
//Firebug Weapons
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Flame_CaulkBurn, KFDT_Bludgeon_CaulkBurn,KFDT_Fire_CaulkBurn,KFDT_Fire_Ground_CaulkNBurn),CompletionAmount=5000)) //3000
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Pistol_Flare, KFDT_Bludgeon_FlareGun,KFDT_Fire_FlareGun,KFDT_Fire_FlareGun_Dual,KFDT_Fire_FlareGunDoT),CompletionAmount=7000)) //5000
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Shotgun_DragonsBreath, KFDT_Ballistic_DragonsBreath,KFDT_Bludgeon_DragonsBreath,KFDT_Fire_DragonsBreathDoT),CompletionAmount=7000)) //5000
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_SMG_Mac10, KFDT_Bludgeon_Mac10,KFDT_Fire_Mac10,KFDT_Fire_Mac10DoT),CompletionAmount=9000)) //7000
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Flame_Flamethrower, KFDT_Bludgeon_Flamethrower,KFDT_Fire_FlameThrower,KFDT_Fire_Ground_FlameThrower),CompletionAmount=9000)) //7000
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_AssaultRifle_HRGIncendiaryRifle, KFDT_Bludgeon_HRGIncendiaryRifle,KFDT_Ballistic_HRGIncendiaryRifle,KFDT_Explosive_HRGIncendiaryRifle,KFDT_Ballistic_HRGIncendiaryRifleGrenadeImpact,KFDT_Fire_HRGIncendiaryRifleBulletDoT,KFDT_Fire_HRGIncendiaryRifleGrenadeDoT,KFDT_Fire_Ground_HRGIncendiaryRifle),CompletionAmount=9000))
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Pistol_HRGScorcher, KFDT_Bludgeon_HRGScorcher,KFDT_Ballistic_HRGScorcherLightingImpact,KFDT_Fire_HRGScorcherDoT,KFDT_Ballistic_HRGScorcherBrokenImpact,KFDT_Fire_Ground_HRGScorcher),CompletionAmount=9000))
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Beam_Microwave, KFDT_Bludgeon_MicrowaveGun,KFDT_Fire_Ground_MicrowaveGun,KFDT_Microwave,KFDT_Microwave_Beam,KFDT_Microwave_Blast),CompletionAmount=10000))
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_HuskCannon, KFDT_Bludgeon_HuskCannon, KFDT_Explosive_HuskCannon, KFDT_HuskCannonDot, KFDT_Explosive_HuskCannonImpact),CompletionAmount=10000))
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_AssaultRifle_Microwave, KFDT_Ballistic_MicrowaveRifle, KFDT_Fire_MicrowaveRifleDoT, KFDT_Bludgeon_MicrowaveRifle),CompletionAmount=10000))
//Berserker Weapons
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Blunt_Crovel, KFDT_Bludgeon_Crovel,KFDT_Bludgeon_CrovelBash,KFDT_Slashing_Crovel),CompletionAmount=5000)) //3000
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Shotgun_Nailgun, KFDT_Ballistic_NailShotgun,KFDT_Bludgeon_NailShotgun),CompletionAmount=7000)) //5000
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Edged_Katana, KFDT_Slashing_Katana,KFDT_Piercing_KatanaStab, KFDT_Slashing_KatanaHeavy),CompletionAmount=7000)) //5000
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Edged_FireAxe, KFDT_Bludgeon_FireAxeBash,KFDT_Slashing_FireAxe,KFDT_Slashing_FireAxeHeavy),CompletionAmount=7000))
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Blunt_Pulverizer, KFDT_Bludgeon_Pulverizer,KFDT_Bludgeon_PulverizerBash,KFDT_Bludgeon_PulverizerHeavy,KFDT_Explosive_Pulverizer),CompletionAmount=10000)) //7000
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Blunt_MedicBat, KFDT_Bludgeon_MedicBatBash,KFDT_Bludgeon_MedicBatHeavy,KFDT_Bludgeon_MedicBatLight,KFDT_Toxic_MedicBatGas,KFDT_Toxic_MedicBatDoT),CompletionAmount=10000))
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Eviscerator, KFDT_Slashing_Eviscerator,KFDT_Slashing_EvisceratorProj),CompletionAmount=10000))
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Blunt_MaceAndShield, KFDT_Bludgeon_MaceAndShield,KFDT_Bludgeon_MaceAndShield_Bash,KFDT_Bludgeon_MaceAndShield_MaceHeavy,KFDT_Bludgeon_MaceAndShield_ShieldHeavy,KFDT_Bludgeon_MaceAndShield_ShieldLight),CompletionAmount=10000))
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Blunt_PowerGloves, KFDT_Bludgeon_PowerGloves,KFDT_Bludgeon_PowerGlovesBash,KFDT_Bludgeon_PowerGlovesHeavy),CompletionAmount=10000))
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_AssaultRifle_HRGTeslauncher, KFDT_Ballistic_HRGTeslauncher, KFDT_Fire_HRGTeslauncherDoT, KFDT_Ballistic_HRGTeslauncherGrenadeImpact, KFDT_Bludgeon_HRGTeslauncher, KFDT_EMP_TeslauncherEMPGrenade),CompletionAmount=10000))
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Edged_AbominationAxe, KFDT_Slashing_AbominationAxe,KFDT_Piercing_AbominationAxeStab,KFDT_Slashing_AbominationAxeHeavy),CompletionAmount=10000))
//Gunslinger Weapons
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Revolver_Rem1858, KFDT_Bludgeon_Rem1858,KFDT_Ballistic_Rem1858,KFDT_Ballistic_Rem1858_Dual),CompletionAmount=5000)) //3000
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Pistol_Colt1911, KFDT_Bludgeon_Colt1911,KFDT_Ballistic_Colt1911),CompletionAmount=7000)) //5000
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Pistol_HRGWinterbite, KFDT_Bludgeon_HRGWinterbite,KFDT_Freeze_HRGWinterbiteImpact,KFDT_Explosive_HRGWinterbite),CompletionAmount=7000))
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Pistol_Deagle, KFDT_Bludgeon_Deagle,KFDT_Ballistic_Deagle),CompletionAmount=10000)) // 7000
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Revolver_SW500, KFDT_Bludgeon_SW500,KFDT_Ballistic_SW500,KFDT_Ballistic_SW500_Dual),CompletionAmount=10000))
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Pistol_AF2011, KFDT_Bludgeon_AF2011,KFDT_Ballistic_AF2011),CompletionAmount=10000))
//Sharpshooter Weapons
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Rifle_Winchester1894, KFDT_Bludgeon_Winchester,KFDT_Ballistic_Winchester),CompletionAmount=5000)) //2000
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Bow_Crossbow, KFDT_Bludgeon_Crossbow,KFDT_Piercing_Crossbow),CompletionAmount=7000)) //5000
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Rifle_M14EBR, KFDT_Bludgeon_M14EBR,KFDT_Ballistic_M14EBR),CompletionAmount=9000)) //7000
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_HRG_SonicGun, KFDT_Bludgeon_HRG_SonicGun, KFDT_Ballistic_HRG_SonicGun_SonicBlastUncharged, KFDT_Ballistic_HRG_SonicGun_SonicBlastHalfCharged, KFDT_Ballistic_HRG_SonicGun_SonicBlastFullyCharged),CompletionAmount=7000))
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Rifle_RailGun, KFDT_Bludgeon_RailGun,KFDT_Ballistic_RailGun),CompletionAmount=5000))
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Rifle_CenterfireMB464, KFDT_Bludgeon_CenterfireMB464,KFDT_Ballistic_CenterfireMB464),CompletionAmount=7000)) //5000
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Rifle_M99, KFDT_Bludgeon_M99,KFDT_Ballistic_M99),CompletionAmount=5000))
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_AssaultRifle_FNFal, KFDT_Ballistic_FNFal,KFDT_Bludgeon_FNFal),CompletionAmount=10000))
//Survivalist Weapons
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Ice_FreezeThrower, KFDT_Bludgeon_Freezethrower, KFDT_Freeze_FreezeThrower, KFDT_Freeze_FreezeThrower_IceShards, KFDT_Freeze_Ground_FreezeThrower),CompletionAmount=7000))
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_HRG_EMP_ArcGenerator, KFDT_Bludgeon_ArcGenerator, KFDT_EMP_ArcGenerator_Beam, KFDT_EMP_ArcGeneratorSphereImpact, KFDT_EMP_ArcGenerator_DefaultFiremodeZapDamage, KFDT_EMP_ArcGenerator_AltFiremodeZapDamage),CompletionAmount=9000))
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_AssaultRifle_LazerCutter, KFDT_Ballistic_LazerCutter, KFDT_LazerCutter_Beam, KFDT_Bludgeon_LazerCutter),CompletionAmount=10000))
//Kills
DailyEvents.Add((ObjectiveType=DOT_PerkXP,SecondaryType=DOST_KillZeds,ObjectiveClasses=(KFPawn_ZedClot_Alpha),CompletionAmount=20))
DailyEvents.Add((ObjectiveType=DOT_PerkXP,SecondaryType=DOST_KillZeds,ObjectiveClasses=(KFPawn_ZedClot_AlphaKing),CompletionAmount=5))
DailyEvents.Add((ObjectiveType=DOT_PerkXP,SecondaryType=DOST_KillZeds,ObjectiveClasses=(KFPawn_ZedClot_Cyst),CompletionAmount=30))
DailyEvents.Add((ObjectiveType=DOT_PerkXP,SecondaryType=DOST_KillZeds,ObjectiveClasses=(KFPawn_ZedClot_Slasher),CompletionAmount=25))
DailyEvents.Add((ObjectiveType=DOT_PerkXP,SecondaryType=DOST_KillZeds,ObjectiveClasses=(KFPawn_ZedCrawler),CompletionAmount=30))
DailyEvents.Add((ObjectiveType=DOT_PerkXP,SecondaryType=DOST_KillZeds,ObjectiveClasses=(KFPawn_ZedCrawlerKing),CompletionAmount=5))
DailyEvents.Add((ObjectiveType=DOT_PerkXP,SecondaryType=DOST_KillZeds,ObjectiveClasses=(KFPawn_ZedStalker),CompletionAmount=10))
DailyEvents.Add((ObjectiveType=DOT_PerkXP,SecondaryType=DOST_KillZeds,ObjectiveClasses=(KFPawn_ZedBloat),CompletionAmount=5))
DailyEvents.Add((ObjectiveType=DOT_PerkXP,SecondaryType=DOST_KillZeds,ObjectiveClasses=(KFPawn_ZedSiren),CompletionAmount=5))
DailyEvents.Add((ObjectiveType=DOT_PerkXP,SecondaryType=DOST_KillZeds,ObjectiveClasses=(KFPawn_ZedHusk),CompletionAmount=3))
DailyEvents.Add((ObjectiveType=DOT_PerkXP,SecondaryType=DOST_KillZeds,ObjectiveClasses=(KFPawn_ZedGorefast),CompletionAmount=20))
DailyEvents.Add((ObjectiveType=DOT_PerkXP,SecondaryType=DOST_KillZeds,ObjectiveClasses=(KFPawn_ZedGorefastDualBlade),CompletionAmount=8))
DailyEvents.Add((ObjectiveType=DOT_PerkXP,SecondaryType=DOST_KillZeds,ObjectiveClasses=(KFPawn_ZedScrake),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_PerkXP,SecondaryType=DOST_KillZeds,ObjectiveClasses=(KFPawn_ZedFleshpound),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_PerkXP,SecondaryType=DOST_KillZeds,ObjectiveClasses=(KFPawn_ZedFleshpoundMini),CompletionAmount=2))
DailyEvents.Add((ObjectiveType=DOT_PerkXP,SecondaryType=DOST_KillZeds,ObjectiveClasses=(KFPawn_ZedDAR_EMP),CompletionAmount=5))
DailyEvents.Add((ObjectiveType=DOT_PerkXP,SecondaryType=DOST_KillZeds,ObjectiveClasses=(KFPawn_ZedDAR_Laser),CompletionAmount=5))
DailyEvents.Add((ObjectiveType=DOT_PerkXP,SecondaryType=DOST_KillZeds,ObjectiveClasses=(KFPawn_ZedDAR_Rocket),CompletionAmount=5))
DailyEvents.Add((ObjectiveType=DOT_PerkXP,SecondaryType=DOST_KillBoss,CompletionAmount=1)
//Perk XP
DailyEvents.Add((ObjectiveType=DOT_PerkXP,SecondaryType=DOST_PlayPerk,ObjectiveClasses=(KFPerk_Berserker),CompletionAmount=1500))
DailyEvents.Add((ObjectiveType=DOT_PerkXP,SecondaryType=DOST_PlayPerk,ObjectiveClasses=(KFPerk_Commando),CompletionAmount=1500))
DailyEvents.Add((ObjectiveType=DOT_PerkXP,SecondaryType=DOST_PlayPerk,ObjectiveClasses=(KFPerk_Demolitionist),CompletionAmount=1500))
DailyEvents.Add((ObjectiveType=DOT_PerkXP,SecondaryType=DOST_PlayPerk,ObjectiveClasses=(KFPerk_FieldMedic),CompletionAmount=1500))
DailyEvents.Add((ObjectiveType=DOT_PerkXP,SecondaryType=DOST_PlayPerk,ObjectiveClasses=(KFPerk_Firebug),CompletionAmount=1500))
DailyEvents.Add((ObjectiveType=DOT_PerkXP,SecondaryType=DOST_PlayPerk,ObjectiveClasses=(KFPerk_Gunslinger),CompletionAmount=1500))
DailyEvents.Add((ObjectiveType=DOT_PerkXP,SecondaryType=DOST_PlayPerk,ObjectiveClasses=(KFPerk_Sharpshooter),CompletionAmount=1500))
DailyEvents.Add((ObjectiveType=DOT_PerkXP,SecondaryType=DOST_PlayPerk,ObjectiveClasses=(KFPerk_Support),CompletionAmount=1500))
DailyEvents.Add((ObjectiveType=DOT_PerkXP,SecondaryType=DOST_PlayPerk,ObjectiveClasses=(KFPerk_Survivalist),CompletionAmount=1500))
DailyEvents.Add((ObjectiveType=DOT_PerkXP,SecondaryType=DOST_PlayPerk,ObjectiveClasses=(KFPerk_SWAT),CompletionAmount=1500))
//Map Completion
//Note: completion amount for these is the map difficulty
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-BURNINGPARIS),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-BURNINGPARIS),CompletionAmount=2))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-BURNINGPARIS),CompletionAmount=3))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-OUTPOST),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-OUTPOST),CompletionAmount=2))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-OUTPOST),CompletionAmount=3))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-BIOTICSLAB),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-BIOTICSLAB),CompletionAmount=2))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-BIOTICSLAB),CompletionAmount=3))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-VOLTERMANOR),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-VOLTERMANOR),CompletionAmount=2))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-VOLTERMANOR),CompletionAmount=3))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-EVACUATIONPOINT),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-EVACUATIONPOINT),CompletionAmount=2))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-EVACUATIONPOINT),CompletionAmount=3))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-CATACOMBS),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-CATACOMBS),CompletionAmount=2))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-CATACOMBS),CompletionAmount=3))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-BLACKFOREST),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-BLACKFOREST),CompletionAmount=2))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-BLACKFOREST),CompletionAmount=3))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-FARMHOUSE),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-FARMHOUSE),CompletionAmount=2))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-FARMHOUSE),CompletionAmount=3))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-PRISON),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-PRISON),CompletionAmount=2))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-PRISON),CompletionAmount=3))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-CONTAINMENTSTATION),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-CONTAINMENTSTATION),CompletionAmount=2))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-CONTAINMENTSTATION),CompletionAmount=3))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-HOSTILEGROUNDS),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-HOSTILEGROUNDS),CompletionAmount=2))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-HOSTILEGROUNDS),CompletionAmount=3))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-INFERNALREALM),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-INFERNALREALM),CompletionAmount=2))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-INFERNALREALM),CompletionAmount=3))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-ZEDLANDING),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-ZEDLANDING),CompletionAmount=2))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-ZEDLANDING),CompletionAmount=3))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-THEDESCENT),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-THEDESCENT),CompletionAmount=2))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-THEDESCENT),CompletionAmount=3))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-NUKED),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-NUKED),CompletionAmount=2))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-NUKED),CompletionAmount=3))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-TRAGICKINGDOM),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-TRAGICKINGDOM),CompletionAmount=2))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-TRAGICKINGDOM),CompletionAmount=3))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-NIGHTMARE),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-NIGHTMARE),CompletionAmount=2))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-NIGHTMARE),CompletionAmount=3))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-KRAMPUSLAIR),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-KRAMPUSLAIR),CompletionAmount=2))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-KRAMPUSLAIR),CompletionAmount=3))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-POWERCORE_HOLDOUT),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-POWERCORE_HOLDOUT),CompletionAmount=2))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-POWERCORE_HOLDOUT),CompletionAmount=3))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-AIRSHIP),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-AIRSHIP),CompletionAmount=2))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-AIRSHIP),CompletionAmount=3))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-LOCKDOWN),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-LOCKDOWN),CompletionAmount=2))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-LOCKDOWN),CompletionAmount=3))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-MONSTERBALL),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-MONSTERBALL),CompletionAmount=2))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-MONSTERBALL),CompletionAmount=3))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-SHOPPINGSPREE),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-SHOPPINGSPREE),CompletionAmount=2))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-SHOPPINGSPREE),CompletionAmount=3))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-SANTASWORKSHOP),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-SANTASWORKSHOP),CompletionAmount=2))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-SANTASWORKSHOP),CompletionAmount=3))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-SPILLWAY),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-SPILLWAY),CompletionAmount=2))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-SPILLWAY),CompletionAmount=3))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-STEAMFORTRESS),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-STEAMFORTRESS),CompletionAmount=2))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-STEAMFORTRESS),CompletionAmount=3))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-ASHWOODASYLUM),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-ASHWOODASYLUM),CompletionAmount=2))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-ASHWOODASYLUM),CompletionAmount=3))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-SANITARIUM),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-SANITARIUM),CompletionAmount=2))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-SANITARIUM),CompletionAmount=3))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-BIOLAPSE),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-BIOLAPSE),CompletionAmount=2))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-BIOLAPSE),CompletionAmount=3))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-DESOLATION),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-DESOLATION),CompletionAmount=2))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-DESOLATION),CompletionAmount=3))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-HELLMARKSTATION),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-HELLMARKSTATION),CompletionAmount=2))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-HELLMARKSTATION),CompletionAmount=3))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-ELYSIUM),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-ELYSIUM),CompletionAmount=2))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-ELYSIUM),CompletionAmount=3))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-DYSTOPIA2029),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-DYSTOPIA2029),CompletionAmount=2))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-DYSTOPIA2029),CompletionAmount=3))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-MOONBASE),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-MOONBASE),CompletionAmount=2))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-MOONBASE),CompletionAmount=3))
//Versus Damage
// Per design doc that I have right now, these are x class damage y players, not damage y amount
/*DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_VersusDamage,ObjectiveClasses=(KFPawn_ZedClot_Alpha, KFPawn_ZedClot_Alpha_Versus),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_VersusDamage,ObjectiveClasses=(KFPawn_ZedClot_Slasher, KFPawn_ZedClot_Slasher_Versus),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_VersusDamage,ObjectiveClasses=(KFPawn_ZedCrawler, KFPawn_ZedCrawler_Versus),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_VersusDamage,ObjectiveClasses=(KFPawn_ZedStalker, KFPawn_ZedStalker_Versus),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_VersusDamage,ObjectiveClasses=(KFPawn_ZedBloat, KFPawn_ZedBloat_Versus),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_VersusDamage,ObjectiveClasses=(KFPawn_ZedSiren, KFPawn_ZedSiren_Versus),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_VersusDamage,ObjectiveClasses=(KFPawn_ZedHusk, KFPawn_ZedHusk_Versus),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_VersusDamage,ObjectiveClasses=(KFPawn_ZedGorefast, KFPawn_ZedGorefast_Versus),CompletionAmount=1))*/
//Versus Kills
/*DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_VersusKills,ObjectiveClasses=(KFPawn_ZedScrake, KFPawn_ZedScrake_Versus),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_VersusKills,ObjectiveClasses=(KFPawn_ZedFleshPound, KFPawn_ZedFleshPound_Versus),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_VersusKills,ObjectiveClasses=(KFPawn_ZedPatriarch, KFPawn_ZedPatriarch_Versus),CompletionAmount=1))*/
//Character Completions
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_CharacterCompletion,ObjectiveClasses=(chr_briar_archetype),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_CharacterCompletion,ObjectiveClasses=(CHR_MrFoster_archetype),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_CharacterCompletion,ObjectiveClasses=(CHR_Coleman_archetype),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_CharacterCompletion,ObjectiveClasses=(CHR_Alberts_archetype),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_CharacterCompletion,ObjectiveClasses=(CHR_Masterson_archetype),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_CharacterCompletion,ObjectiveClasses=(CHR_Tanaka_Archetype),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_CharacterCompletion,ObjectiveClasses=(CHR_Ana_Archetype),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_CharacterCompletion,ObjectiveClasses=(chr_rockabilly_archetype),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_CharacterCompletion,ObjectiveClasses=(CHR_DAR_archetype),CompletionAmount=1))
SeasonalKillsObjectiveThreshold=2500
}