//============================================================================= // KFGameInfo_Entry //============================================================================= // The main menu's game info class //============================================================================= // Killing Floor 2 // Copyright (C) 2015 Tripwire Interactive LLC // - Christian "schneidzekk" Schneider //============================================================================= class KFGameInfo_Entry extends KFGameInfo; var bool bInitialized; var int LastSystemTimeMinutes; var array DoshVaultStacks; var array TierLights; var bool bInitPiles; var int FrontPilesInWorld; var int FrontPilesActive; var array TierThreshold; var string LightMICTagName; var string LightConeTagName; var string LightBulbTagName; var string DoshLitterMICTagName; var string CustomPawnSpawnPointTagName; var int FilledPalletCount; var int LastUpdateDoshAmount; var() LinearColor WhiteColor; var() LinearColor OffColor; var KFPawn_Customization VaultCustomPawn; var int CalcultedTierValue; static function PreloadContentClasses(); function bool NeedPlayers(); function Pawn SpawnDefaultPawnFor(Controller NewPlayer, NavigationPoint StartSpot) {} function InitSpawnManager(); function InitTraderList(); function InitVault() { local KFPlayerController KFPC; local LocalPlayer LP; local int i; // To fix custom post processing effect not showing up in main menu KFPC = KFPlayerController(WorldInfo.GetALocalPlayerController()); if (KFPC == none) { return; } LP = LocalPlayer(KFPC.Player); if (LP != None) { LP.RemoveAllPostProcessingChains(); LP.InsertPostProcessingChain(LP.Outer.GetWorldPostProcessChain(), INDEX_NONE, true); } if (KFPC.myHUD != None) { KFPC.myHUD.NotifyBindPostProcessEffects(); } SetDoshTier(GetTotalDoshTier(KFPC)); InitDoshPiles(KFPC); SpawnVaultCustomizationPawn(KFPC); if(!bInitialized) { for (i = 0; i < TierThreshold.length; i++) { ActiveLightActorsForTier(i, i == 0); } } } function SpawnVaultCustomizationPawn(KFPlayerController KFPC) { local KFGameInfo KFGI; local NavigationPoint BestStart; if(VaultCustomPawn != none) { return; } KFGI = KFGameInfo( WorldInfo.Game ); if( KFGI == none || KFGI.bRestartLevel && WorldInfo.NetMode!=NM_DedicatedServer && WorldInfo.NetMode!=NM_ListenServer ) { `warn("bRestartLevel && !server, abort from RestartPlayer"@WorldInfo.NetMode); return; } BestStart = GetVaultCustomizationSpawnPoint( KFGI ); VaultCustomPawn = KFPawn_Customization( KFGI.SpawnCustomizationPawn( BestStart ) ); if ( VaultCustomPawn != none ) { VaultCustomPawn.InitializeCustomizationPawn( KFPC, BestStart ); } } function NavigationPoint GetVaultCustomizationSpawnPoint( KFGameInfo KFGI ) { local NavigationPoint BestStartSpot; foreach AllActors(class'NavigationPoint', BestStartSpot) { if(string(BestStartSpot.Tag) == CustomPawnSpawnPointTagName) { return BestStartSpot; } } return BestStartSpot; } event InitDoshPiles(KFPlayerController KFPC) { if (KFPC == none) { return; } CalcultedTierValue = GetTotalDoshTier(KFPC); CollectDoshPiles(); SortDoshPiles(); SpawnDoshPilesForAmount(KFPC.GetLastSeenDoshCount()); InitDoshLitter(CalcultedTierValue); bInitPiles = true; } function InitDoshLitter(int DoshTier) { local MaterialInstanceActor DoshLitterMICActor; local MaterialInstanceConstant MICInst; foreach AllActors(class'MaterialInstanceActor', DoshLitterMICActor) { if (string(DoshLitterMICActor.Tag) == (DoshLitterMICTagName)) { //DoshLitterMICActor.StaticMeshComponent.CreateAndSetMaterialInstanceConstant(0); //MaterialInstanceConstant(DoshLitterMICActor.StaticMeshComponent.GetMaterial(0)).SetScalarParameterValue('Dosh_Amount', (float(CalcultedTierValue) / float(TierThreshold.length - 1))); MICInst = new(self) class'MaterialInstanceConstant'; MICInst.SetParent(DoshLitterMICActor.MatInst); MICInst.SetScalarParameterValue('Dosh_Amount', (float(CalcultedTierValue)/float(TierThreshold.length-1)) ); DoshLitterMICActor.MatInst = MICInst; } } //DoshLitterMIC.SetScalarParameterValue('Dosh_Amount', 1); } function CollectDoshPiles() { local KFActor_DoshPile DoshPile; local int Index; Index = 0; DoshVaultStacks.length = 0; foreach AllActors(class'KFActor_DoshPile', DoshPile) { DoshVaultStacks.AddItem(DoshPile); DoshPile.SetHidden(true); DoshPile.PileIndexID = Index; DoshPile.SetValue(0); Index++; } } function SortDoshPiles() { DoshVaultStacks.Sort(CompareItemTags); } function int CompareItemTags(Actor Actor1, Actor Actor2) { local string Tag1, Tag2; Tag1 = string(Actor1.Tag); Tag2 = string(Actor2.Tag); if(Tag1 == Tag2) { return 0; } if( Len(Tag1) != Len(Tag2) ) { return Len(Tag1) > Len(Tag2) ? -1 : 1; } return Tag1 > Tag2 ? -1 : 1; } function int GetTotalDoshTier(KFPlayerController KFPC) { local int TierValue; local int NumPiles; local int i; NumPiles = int(KFPC.GetTotalDoshCount() / class'KFActor_DoshPile'.default.DoshPileMax); for (i = 0; i < TierThreshold.length; i++) { if(NumPiles >= TierThreshold[i]) { TierValue = i; } } return TierValue; } function FinalAnimationPlayed(KFPlayerController KFPC) { SetDoshTier(GetTotalDoshTier(KFPC), true); } function SetDoshTier(int TierValue, optional bool bFinalAnimation = false) { local array ActivationEvents; local KFSeqEvent_DoshVault ActivationEvent; local int i; /*for (i = 0; i < TierValue; i++)//Giving this back to kismet for now. -ZG { ActiveLightActorsForTier(i, i <= TierValue); }*/ /*if (bFinalAnimation) {*/ WorldInfo.GetGameSequence().FindSeqObjectsByClass(class'KFSeqEvent_DoshVault', true, ActivationEvents); for (i = 0; i < ActivationEvents.Length; i++) { ActivationEvent = KFSeqEvent_DoshVault(ActivationEvents[i]); if (ActivationEvent != none) { ActivationEvent.SetDoshTier(TierValue); } } //} } //spawn crates up to remaining value function SpawnDoshPilesForAmount(int LastSeenDoshAmount) { local int NumPiles; local int DoshAccountedFor; local int i, UpdateID; local KFActor_DoshPile DoshPile; NumPiles = int(LastSeenDoshAmount / class'KFActor_DoshPile'.default.DoshPileMax); FrontPilesActive = (NumPiles % FrontPilesInWorld) + 1; //Initial dosh count that we have to visually set. DoshAccountedFor = LastSeenDoshAmount; //make front piles always visible and give their values first for (i = 0; i < DoshVaultStacks.length; i++) { if(i < FrontPilesInWorld) { DoshVaultStacks[i].SetHidden(false); } else { DoshVaultStacks[i].SetHidden(true); } DoshVaultStacks[i].SetValue(0); } UpdateID = FrontPilesInWorld; //fill back rows while(DoshAccountedFor >= (FrontPilesActive * class'KFActor_DoshPile'.default.DoshPileMax) && DoshAccountedFor > 0 ) { DoshPile = DoshVaultStacks[UpdateID]; DoshPile.SetHidden(false); DoshPile.SetValue(FMin(DoshAccountedFor, class'KFActor_DoshPile'.default.DoshPileMax) / class'KFActor_DoshPile'.default.DoshPileMax); //Remove accounted for dosh so future piles get the correct amount. If we go under 0, set it to 0 and we'll start with a bunch of empty piles DoshAccountedFor -= class'KFActor_DoshPile'.default.DoshPileMax; DoshAccountedFor = FMax(DoshAccountedFor, 0.f); UpdateID++; } //front piles UpdateID = 1; while(DoshAccountedFor > 0) { if(DoshAccountedFor >= class'KFActor_DoshPile'.default.DoshPileMax) { DoshPile = DoshVaultStacks[UpdateID]; } else { DoshPile = DoshVaultStacks[0]; } DoshPile.SetValue(FMin(DoshAccountedFor, class'KFActor_DoshPile'.default.DoshPileMax) / class'KFActor_DoshPile'.default.DoshPileMax); //Remove accounted for dosh so future piles get the correct amount. If we go under 0, set it to 0 and we'll start with a bunch of empty piles DoshAccountedFor -= class'KFActor_DoshPile'.default.DoshPileMax; DoshAccountedFor = FMax(DoshAccountedFor, 0.f); UpdateID++; } } exec function ActiveLightActorsForTier(int LightTier, optional bool bActive = true) { local Light LightActor; local MaterialInstanceActor LightMIC; local StaticMeshActor LightCone; local MaterialInstanceConstant MICInst; //emissive (MIC) foreach AllActors(class'MaterialInstanceActor', LightMIC) { if(string(LightMIC.Tag) == (LightMICTagName $ LightTier) ) { MICInst = new(self) class'MaterialInstanceConstant'; MICInst.SetParent(LightMIC.MatInst); MICInst.SetVectorParameterValue('Emissive_Color', bActive ? WhiteColor : OffColor); LightMIC.MatInst = MICInst; } } //cones foreach AllActors(class'StaticMeshActor', LightCone) { if(string(LightCone.Tag) == (LightConeTagName $ LightTier) ) { LightCone.SetHidden(!bActive); } } //lights foreach AllActors(class'Light', LightActor) { if (string(LightActor.Tag) == (LightBulbTagName $ LightTier)) { LightActor.LightComponent.SetEnabled(bActive); } } } function UpdateDoshPiles(int NewDoshAmount) { local int UpdateID, Idx, i; local int ValueMultiple; if(!bInitPiles) { InitVault(); } if(LastUpdateDoshAmount == NewDoshAmount) { return; } //return; if(NewDoshAmount <= 0) { return; //no reason to update } ValueMultiple = int(NewDoshAmount / class'KFActor_DoshPile'.default.DoshPileMax); UpdateID = (ValueMultiple % FrontPilesInWorld) + 1; //can never be 0 //check for complete row if(NewDoshAmount % (class'KFActor_DoshPile'.default.DoshPileMax * FrontPilesInWorld) == 0 && LastUpdateDoshAmount != INDEX_NONE) { //reset the rows because we are starting a new row for (i = 0; i < FrontPilesInWorld; i++) { DoshVaultStacks[i].SpawnCompleteParticleEffects(false); } VaultCustomPawn.PlayEmoteAnimation(); //add the reset row the back piles <-maybe SpawnDoshPilesForAmount(NewDoshAmount); } //check for complete stack else if( NewDoshAmount % class'KFActor_DoshPile'.default.DoshPileMax == 0 && LastUpdateDoshAmount != INDEX_NONE) { if( UpdateID > 1 ) { //fill the last id up! DoshVaultStacks[0].SetValue(0); DoshVaultStacks[0].SpawnCompleteParticleEffects(false); DoshVaultStacks[UpdateID - 1].SpawnCompleteParticleEffects(); VaultCustomPawn.PlayEmoteAnimation(); } } for (Idx = 0; Idx <= UpdateID; ++Idx) { if (Idx == (UpdateID) ) { DoshVaultStacks[0].SetValue( (NewDoshAmount % class'KFActor_DoshPile'.default.DoshPileMax) / class'KFActor_DoshPile'.default.DoshPileMax); } else { DoshVaultStacks[Idx].SetValue(1.0); } } LastUpdateDoshAmount = NewDoshAmount; } // Parse options for this game... event InitGame( string Options, out string ErrorMessage ) { if ( ParseOption( Options, "PerformUnitTests" ) ~= "1" ) { if ( MyAutoTestManager == None ) { MyAutoTestManager = spawn(AutoTestManagerClass); } MyAutoTestManager.InitializeOptions(Options); } // Refresh online game data when returning to main menu // Leaving main menu, aka GameEnded(), happening too late if ( HasOption( Options, "Closed" ) ) { class'KFGameEngine'.static.RefreshOnlineGameData(); } LastSystemTimeMinutes = GetSystemTimeMinutes(); BroadcastHandler = spawn(BroadcastHandlerClass); InitVault(); } /** * Helper for periodic online game data update * note: Not 100% precise, because we don't bother with days rolling into months */ private function int GetSystemTimeMinutes() { local int year,month,dayofweek,day,hour,minute,second,msec; GetSystemTime(year,month,dayofweek,day,hour,minute,second,msec); return minute + (hour * 60) + (day * 60 * 24); } function Tick( float DeltaTime ) { super.Tick(DeltaTime); // Quick fix to get the music playing after the startup movies if( !bInitialized ) { ForceMenuMusicTrack(); bInitialized = true; } } exec function FinishCraft () { local KFPlayerController KFPC; foreach LocalPlayerControllers(class'KFPlayerController', KFPC) { if(KFPC.MyGfxManager != none && KFPC.MyGFxManager.InventoryMenu != none) { KFPC.MyGFxManager.InventoryMenu.FinishCraft(); } } } auto State PendingMatch { function RestartPlayer(Controller aPlayer) { } function Timer() { local int SystemTimeMinutes; // Update every 30 minutes using system clock for suspend mode. // Originally tried using GameEnding(), but the TitleData response // doesn't come back in time for the new map. SystemTimeMinutes = GetSystemTimeMinutes(); if ( (SystemTimeMinutes - LastSystemTimeMinutes) >= 30 ) { class'KFGameEngine'.static.RefreshOnlineGameData(); LastSystemTimeMinutes = SystemTimeMinutes; } } function BeginState(Name PreviousStateName) { bWaitingToStartMatch = true; } function EndState(Name NextStateName) { } } DefaultProperties { LastUpdateDoshAmount=INDEX_NONE LightMICTagName="TierMIC_" LightConeTagName="TierCone_" LightBulbTagName="TierLight_" DoshLitterMICTagName="DoshLitter" CustomPawnSpawnPointTagName="KFCustomizationPoint_Vault" FrontPilesInWorld=10 TierThreshold(0)=0 TierThreshold(1)=30 TierThreshold(2)=70 TierThreshold(3)=100 TierThreshold(4)=130 WhiteColor=(R=1.0f,G=1.0f,B=1.0f) OffColor=(R=0f,G=0f,B=0f) SupportedEvents.Empty SupportedEvents.Add(class'KFSeqEvent_DoshVault') }