Deleted32045420User Posted April 16, 2016 Share Posted April 16, 2016 (edited) Ok this is 100% a problem with the UI if someone can give me a few notes of the XCOM 2 UI system and how to build UI screens for it i would thank them very much, and if someone wants to jump in and help me make those i'll be more than happy to list them as a creator and contributor for this mod When loading a save with my mod after playing another save already(so play a save, move a couple of turns and try to load that save again) it get's stuck on the loading screen for no apparent reason(if you load a different save it will crash!)- this only happens when loading a save after already being in another one,now i've been able to narrow it down to the UI version of the code only which suggests that the problem lies somewhere in the UI code but i cant figure it out. HERE is the compressed mod file (including Src) it's just gonna be too much to get in here but the short of it is that i am using a UIDataStore and a gamestate component (on XComGameState_Headquarters) to save and load the data.the log: [0219.38] ScriptLog: Created New Ability Template [0219.38] ScriptLog: Created New Ability Template [0219.38] ScriptLog: Activated RedFog Medikit Gremlin Heal [0219.38] ScriptLog: Activated RedFog Medikit Restore Mist Heal [0219.38] ScriptLog: Replaced Soul Steal For RedFog [0219.38] ScriptLog: Activated RedFog Regeneration Heal [0219.38] ScriptLog: Activated RedFog Regeneration Heal [0219.38] ScriptLog: Activated RedFog Regeneration Heal [0219.38] ScriptLog: Activated RedFog Stasis Vest Regeneration Heal [0219.38] ScriptLog: Mod OnReceiveFocus() UIAvengerHUD ScreenListener triggered [0219.43] Warning: Unable to determine destructible actor dimensions for "Plot_CTY_MdObj_Civic_01.TheWorld:md_Monument_01_14.XComDestructibleActor_1" [0219.61] Log: ###### OnlineEventMgr waited 0.00 seconds for saves to complete [0219.61] Log: LoadMap: Plot_CTY_MdObj_Civic_01?Name=Player?Team=255?game=XComGame.XComTacticalGame?LoadingSave [0219.70] Log: --- LOADING MOVIE START --- [0219.71] Log: Movie Started Event: 1080_Black [0220.02] Log: [0221.05] Log: Bringing up level for play took: 0.022406 [0221.08] Log: ########### Finished loading level: 1.470186 seconds [0221.10] Log: Initializing world volume info. min: -3265.000000 -2497.000000 -65.000000 dim: 8067.000000 5763.000000 1091.000000 the log when using the non UI version of the mod: [0146.86] ScriptLog: Mod OnReceiveFocus() UIAvengerHUD ScreenListener triggered [0146.91] Warning: Blueprint CTY_Street_TBlvd_08x16_02.TheWorld:PersistentLevel.XComBlueprint_7 does not have a valid map reference! Bug an LD. [0146.91] Warning: Blueprint Plot_CTY_MdObj_Mixed_02.TheWorld:CTY_Street_TBlvd_08x16_02_44.XComBlueprint_7 does not have a valid map reference! Bug an LD. [0146.91] Warning: Unable to determine destructible actor dimensions for "Plot_CTY_MdObj_Mixed_02.TheWorld:md_Monument_01_14.XComDestructibleActor_1" [0147.06] Log: ###### OnlineEventMgr waited 0.00 seconds for saves to complete [0147.06] Log: LoadMap: Plot_CTY_MdObj_Mixed_02?Name=Player?Team=255?game=XComGame.XComTacticalGame?LoadingSave [0147.14] Log: --- LOADING MOVIE START --- [0147.15] Log: Movie Started Event: 1080_Black [0147.67] Log: [0149.31] Log: Game class is 'XComTacticalGame' [0149.32] Log: Bringing World Plot_CTY_MdObj_Mixed_02.TheWorld up for play (0) at 2016.04.16-21.14.05 [0149.32] Log: Bringing up level for play took: 0.012713 [0149.35] Log: ########### Finished loading level: 2.293459 seconds [0149.37] Log: Initializing world volume info. min: -3265.000000 -2497.000000 -65.000000 dim: 8067.000000 4995.000000 1091.000000 [0149.64] Error: (AddNetObject) Objects SkeletalMeshSocket BaseHead.Meshes.SM_Head_F:SkeletalMeshSocket_37 and SkeletalMeshSocket BaseHead.Meshes.SM_Head_F:SkeletalMeshSocket_20 have duplicate NetIndex 556 [0149.64] Error: (AddNetObject) Objects SkeletalMeshSocket BaseHead.Meshes.SM_Head_F:SkeletalMeshSocket_38 and SkeletalMeshSocket BaseHead.Meshes.SM_Head_F:SkeletalMeshSocket_21 have duplicate NetIndex 557 [0149.64] Error: (AddNetObject) Objects SkeletalMeshSocket BaseHead.Meshes.SM_Head_F:SkeletalMeshSocket_39 and SkeletalMeshSocket BaseHead.Meshes.SM_Head_F:SkeletalMeshSocket_22 have duplicate NetIndex 558 [0149.64] Error: (AddNetObject) Objects SkeletalMeshSocket BaseHead.Meshes.SM_Head_F:SkeletalMeshSocket_40 and SkeletalMeshSocket BaseHead.Meshes.SM_Head_F:SkeletalMeshSocket_24 have duplicate NetIndex 560 [0149.64] Error: (AddNetObject) Objects SkeletalMeshSocket BaseHead.Meshes.SM_Head_F:SkeletalMeshSocket_41 and SkeletalMeshSocket BaseHead.Meshes.SM_Head_F:SkeletalMeshSocket_25 have duplicate NetIndex 561 [0149.64] Error: (AddNetObject) Objects SkeletalMeshSocket BaseHead.Meshes.SM_Head_F:SkeletalMeshSocket_42 and SkeletalMeshSocket BaseHead.Meshes.SM_Head_F:SkeletalMeshSocket_26 have duplicate NetIndex 562 [0149.64] Error: (AddNetObject) Objects SkeletalMeshSocket BaseHead.Meshes.SM_Head_F:SkeletalMeshSocket_43 and SkeletalMeshSocket BaseHead.Meshes.SM_Head_F:SkeletalMeshSocket_27 have duplicate NetIndex 563 [0149.64] Error: (AddNetObject) Objects SkeletalMeshSocket BaseHead.Meshes.SM_Head_F:SkeletalMeshSocket_44 and SkeletalMeshSocket BaseHead.Meshes.SM_Head_F:SkeletalMeshSocket_28 have duplicate NetIndex 564 [0149.64] Error: (AddNetObject) Objects SkeletalMeshSocket BaseHead.Meshes.SM_Head_F:SkeletalMeshSocket_46 and SkeletalMeshSocket BaseHead.Meshes.SM_Head_F:SkeletalMeshSocket_3 have duplicate NetIndex 565 [0149.64] Error: (AddNetObject) Objects SkeletalMeshSocket BaseHead.Meshes.SM_Head_F:SkeletalMeshSocket_47 and SkeletalMeshSocket BaseHead.Meshes.SM_Head_F:SkeletalMeshSocket_4 have duplicate NetIndex 566 [0150.33] Warning: Redscreen: Blueprint CTY_Street_TBlvd_08x16_02.TheWorld:PersistentLevel.XComBlueprint_7 does not have a valid map reference! Bug an LD. [0150.33] Warning: Redscreen: Blueprint Plot_CTY_MdObj_Mixed_02.TheWorld:CTY_Street_TBlvd_08x16_02_423.XComBlueprint_7 does not have a valid map reference! Bug an LD. ------regular log stuff without any problems from here.---------- Important code samples SWOptionDataManager: class SWOptionDataManager extends UIDataStore; struct SecondWaveOption { var string OptionName; var bool Value; }; var array<SecondWaveOption> Options; function bool GetValue( string OptionName ) { local int i; for( i=0; i<Options.length; i++) { if( Options[i].OptionName == OptionName ) { //`log("Returning a value of:"@OptionName @"="@ string(Options[i].Value)); return Options[i].Value; } } return false; } function SetValue( string OptionName, bool value ) { local int i; local SecondWaveOption pair; for( i=0; i<Options.length; i++ ) { if( Options[i].OptionName == OptionName ) { Options[i].Value = Value; return; } } pair.OptionName = OptionName; pair.Value = value; Options.AddItem(pair); } public static function SWOptionDataManager GetInstance() { local SWOptionDataManager instance; local DataStoreClient dataStoreManager; dataStoreManager = class'UIInteraction'.static.GetDataStoreClient(); instance = SWOptionDataManager( dataStoreManager.FindDataStore( class'SWOptionDataManager'.default.Tag ) ); if( instance == none ) { instance = dataStoreManager.CreateDataStore( class'SWOptionDataManager' ); dataStoreManager.RegisterDataStore(instance); } return instance; } DefaultProperties { Tag=SecondWaveOptionTag } a GetActive() sample (they are all pretty much the same) function GetActive() { local XComGameState_SecondWaveOptions CampaignSettingsStateObject; local int k; local XComGameState_Unit_RedFog RedFogActor; if(XComGameState_SecondWaveOptions(XComGameState_HeadquartersXCom(`XCOMHistory.GetSingleGameStateObjectForClass(class'XComGameState_HeadquartersXCom')).FindComponentObject(class'XComGameState_SecondWaveOptions'))!=none) { CampaignSettingsStateObject= XComGameState_SecondWaveOptions(XComGameState_HeadquartersXCom(`XCOMHistory.GetSingleGameStateObjectForClass(class'XComGameState_HeadquartersXCom')).FindComponentObject(class'XComGameState_SecondWaveOptions'));; for(k=0;k<8;k++) { class'SWOptionDataManager'.static.GetInstance().SetValue( CampaignSettingsStateObject.SecondWaveOptionNames[k], CampaignSettingsStateObject.GetAnOption(CampaignSettingsStateObject.SecondWaveOptionNames[k]) ); } bIsRedFogActive=CampaignSettingsStateObject.GetAnOption("Red Fog"); bIncludeRoboticEnemies=CampaignSettingsStateObject.GetAnOption("Fragile Hardware (Requires Red Fog ,Robotic Red Fog)"); //`log("------------------------- Successfuly Found SecondWaveOptions!! -----------------------------------------"); `log("Red Fog:"@bIsRedFogActive @"IncludeRoboticEnemies:"@bIncludeRoboticEnemies); `log("-----Instance Provided!---------"); } } The UI options Screen: // This is an Unreal Script Class UISecondWaveOptions extends UIScreen config(SecondWave); var UIMechaListItem SecondWaveOptionsMecha[8]; var array<bool> SecondWaveOptionsBools; var config array<string> SecondWaveOptionName; var config array<string> SecondWaveOptionDescription; var int i,k,Check; var XComGameState_SecondWaveOptions CampaignSettingsStateObject; var Bool Once; simulated function InitScreen(XComPlayerController InitController, UIMovie InitMovie, optional name InitName) { super.InitScreen(InitController, InitMovie, InitName); } simulated function OnInit() { InitOptions(); for(k=0;k<8;k++) { class'SWOptionDataManager'.static.GetInstance().SetValue( SecondWaveOptionName[k], False ); } } simulated function OnRemoved() { `log("SECOND WAVE OPTIONS REMOVED!"); for(k=0;k<8;k++) { SecondWaveOptionsMecha[k].Remove(); } super.OnRemoved(); } function SubmitSecondWaveState() { local XComGameState NewGameState; //NewGameState = class'XComGameStateContext_ChangeContainer'.static.CreateChangeState("Applying Second Wave Options"); //CampaignSettingsStateObject = XComGameState_SecondWaveOptions(NewGameState.CreateStateObject(class 'XComGameState_SecondWaveOptions')); for(k=0;k<8;k++) { //CampaignSettingsStateObject.AddNewOption(SecondWaveOptionName[k],SecondWaveOptionsBools[k],k); class'SWOptionDataManager'.static.GetInstance().SetValue( SecondWaveOptionName[k], SecondWaveOptionsBools[k] ); } //NewGameState.AddStateObject(CampaignSettingsStateObject); //`XCOMHISTORY.AddGameStateToHistory(NewGameState); `log("Submitted Object"); } simulated function UpdateSecondWave(UICheckbox CheckboxControl) { local int k; for(k=0;k<8;k++) { if(CheckboxControl==SecondWaveOptionsMecha[k].Checkbox) i=k; } SecondWaveOptionsBools[i]= CheckboxControl.bChecked; class'SWOptionDataManager'.static.GetInstance().SetValue( SecondWaveOptionName[i], SecondWaveOptionsBools[i] ); `log("Added:"@ SecondWaveOptionName[i]); if((i==6||i==7)&& (SecondWaveOptionsBools[6]||SecondWaveOptionsBools[7])) { SecondWaveOptionsBools[5]= true; SecondWaveOptionsMecha[5].Checkbox.SetChecked(true,true); class'SWOptionDataManager'.static.GetInstance().SetValue( "Red Fog", SecondWaveOptionsBools[5] ); } } simulated function InitOptions(optional UIScreen Screen=Self) { `log("UI Options Activated."); for(i=0;i<8;i++) { SecondWaveOptionsMecha[i]= Spawn(Class'UIMechaListItem',Screen); SecondWaveOptionsMecha[i].InitListItem(); if(i<4) SecondWaveOptionsMecha[i].SetPosition(-430, 480+(i*35)); else SecondWaveOptionsMecha[i].SetPosition(20, 480+((i-4)*35)); SecondWaveOptionsMecha[i].UpdateDataCheckbox(SecondWaveOptionName[i], "", false, UpdateSecondWave, none); SecondWaveOptionsMecha[i].BG.SetTooltipText(SecondWaveOptionDescription[i],,, 10,,,, 0.0f); SecondWaveOptionsMecha[i].Checkbox.SetReadOnly(false); SecondWaveOptionsMecha[i].SetDisabled(false); SecondWaveOptionsMecha[i].AnimateIn(0); } } Edited April 16, 2016 by Guest Link to comment Share on other sites More sharing options...
Amineri Posted April 17, 2016 Share Posted April 17, 2016 This sounds a lot like you've got some persistent reference to UITacticalHUD (or possibly a sub-element of it), which is preventing garbage collection on the re-load process. The simplest example of how this can occur is if a UIScreenListener maintains a class reference to UITacticalHUD. Link to comment Share on other sites More sharing options...
Deleted32045420User Posted April 17, 2016 Author Share Posted April 17, 2016 (edited) This sounds a lot like you've got some persistent reference to UITacticalHUD (or possibly a sub-element of it), which is preventing garbage collection on the re-load process. The simplest example of how this can occur is if a UIScreenListener maintains a class reference to UITacticalHUD.there is a listener for that, I'll look on how I can change that thanks amineri! EDIT: Ok i solved it, and it wasnt the UITacticalHUD (on a second though it wouldnt make sense as the non UI version has that listener too) but it was a reference to the Pause menu UI i saved in a listener(i put a global var there instead of using local vars), changed that to local and now it all works perfectly, thank you for the tip Amineri! Edited April 17, 2016 by Guest Link to comment Share on other sites More sharing options...
Recommended Posts