404 lines
18 KiB
C++
404 lines
18 KiB
C++
|
|
// Portage UE 5.5 - voir LPTitleModManagerCommandlet.h
|
||
|
|
|
||
|
|
#include "LPTitleModManagerCommandlet.h"
|
||
|
|
|
||
|
|
#include "Blueprint/WidgetBlueprintLibrary.h"
|
||
|
|
#include "Blueprint/WidgetTree.h"
|
||
|
|
#include "Components/Button.h"
|
||
|
|
#include "Components/Image.h"
|
||
|
|
#include "Components/PanelWidget.h"
|
||
|
|
#include "Components/TextBlock.h"
|
||
|
|
#include "Components/Widget.h"
|
||
|
|
#include "Engine/Texture2D.h"
|
||
|
|
#include "EdGraph/EdGraph.h"
|
||
|
|
#include "EdGraphSchema_K2.h"
|
||
|
|
#include "K2Node_CallFunction.h"
|
||
|
|
#include "K2Node_ComponentBoundEvent.h"
|
||
|
|
#include "K2Node_IfThenElse.h"
|
||
|
|
#include "K2Node_Self.h"
|
||
|
|
#include "K2Node_VariableGet.h"
|
||
|
|
#include "K2Node_VariableSet.h"
|
||
|
|
#include "LPModSettingsLibrary.h"
|
||
|
|
#include "Kismet/GameplayStatics.h"
|
||
|
|
#include "Kismet/KismetSystemLibrary.h"
|
||
|
|
#include "Kismet2/BlueprintEditorUtils.h"
|
||
|
|
#include "Kismet2/KismetEditorUtilities.h"
|
||
|
|
#include "Misc/PackageName.h"
|
||
|
|
#include "UObject/Package.h"
|
||
|
|
#include "UObject/SavePackage.h"
|
||
|
|
#include "WidgetBlueprint.h"
|
||
|
|
#include "WidgetBlueprintEditorUtils.h"
|
||
|
|
|
||
|
|
DEFINE_LOG_CATEGORY_STATIC(LogLPTitleMods, Log, All);
|
||
|
|
|
||
|
|
namespace
|
||
|
|
{
|
||
|
|
const FName TitleMenuName(TEXT("TitleMenu"));
|
||
|
|
const FName TitleButtonName(TEXT("ModManagerTitleButton"));
|
||
|
|
|
||
|
|
/** Noeud cree a cote d'un noeud de reference ; Init renseigne la fonction ou la variable avant la creation des broches. */
|
||
|
|
template <class T>
|
||
|
|
T* MakeNode(UEdGraph* Graph, const UEdGraphNode* Anchor, int32 Column, int32 Row, TFunctionRef<void(T*)> Init)
|
||
|
|
{
|
||
|
|
FGraphNodeCreator<T> Creator(*Graph);
|
||
|
|
T* Node = Creator.CreateNode(false);
|
||
|
|
Init(Node);
|
||
|
|
Node->NodePosX = Anchor->NodePosX + 300 * Column;
|
||
|
|
Node->NodePosY = Anchor->NodePosY + 400 + 160 * Row;
|
||
|
|
Creator.Finalize();
|
||
|
|
return Node;
|
||
|
|
}
|
||
|
|
|
||
|
|
struct FEditor
|
||
|
|
{
|
||
|
|
const UEdGraphSchema_K2* Schema = GetDefault<UEdGraphSchema_K2>();
|
||
|
|
int32 Errors = 0;
|
||
|
|
|
||
|
|
void Link(UEdGraphPin* A, UEdGraphPin* B, const TCHAR* What)
|
||
|
|
{
|
||
|
|
if (!A || !B || !Schema->TryCreateConnection(A, B))
|
||
|
|
{
|
||
|
|
UE_LOG(LogLPTitleMods, Error, TEXT(" liaison impossible : %s"), What);
|
||
|
|
++Errors;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void Default(UEdGraphPin* Pin, const TCHAR* Value, const TCHAR* What)
|
||
|
|
{
|
||
|
|
if (!Pin)
|
||
|
|
{
|
||
|
|
UE_LOG(LogLPTitleMods, Error, TEXT(" broche introuvable : %s"), What);
|
||
|
|
++Errors;
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
Schema->TrySetDefaultValue(*Pin, Value);
|
||
|
|
if (Pin->DefaultValue != Value)
|
||
|
|
{
|
||
|
|
UE_LOG(LogLPTitleMods, Error, TEXT(" %s : valeur relue '%s', attendue '%s'"), What, *Pin->DefaultValue, Value);
|
||
|
|
++Errors;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
UFunction* Function(UClass* Class, const TCHAR* Name)
|
||
|
|
{
|
||
|
|
UFunction* F = Class ? Class->FindFunctionByName(Name) : nullptr;
|
||
|
|
if (!F)
|
||
|
|
{
|
||
|
|
UE_LOG(LogLPTitleMods, Error, TEXT(" fonction introuvable : %s::%s"), Class ? *Class->GetName() : TEXT("?"), Name);
|
||
|
|
++Errors;
|
||
|
|
}
|
||
|
|
return F;
|
||
|
|
}
|
||
|
|
|
||
|
|
UK2Node_CallFunction* Call(UEdGraph* Graph, const UEdGraphNode* Anchor, int32 Column, int32 Row, UFunction* F)
|
||
|
|
{
|
||
|
|
return MakeNode<UK2Node_CallFunction>(Graph, Anchor, Column, Row, [F](UK2Node_CallFunction* N) { if (F) { N->SetFromFunction(F); } });
|
||
|
|
}
|
||
|
|
|
||
|
|
UK2Node_VariableGet* GetSelf(UEdGraph* Graph, const UEdGraphNode* Anchor, int32 Column, int32 Row, FName Name)
|
||
|
|
{
|
||
|
|
return MakeNode<UK2Node_VariableGet>(Graph, Anchor, Column, Row, [Name](UK2Node_VariableGet* N) { N->VariableReference.SetSelfMember(Name); });
|
||
|
|
}
|
||
|
|
|
||
|
|
/** Evenement de clic d'un element, et le noeud qu'il execute aujourd'hui. */
|
||
|
|
UK2Node_ComponentBoundEvent* BoundEvent(UBlueprint* BP, FName Component, const TCHAR* FirstCall, UEdGraphNode*& OutFirst)
|
||
|
|
{
|
||
|
|
TArray<UK2Node_ComponentBoundEvent*> Events;
|
||
|
|
FBlueprintEditorUtils::GetAllNodesOfClass(BP, Events);
|
||
|
|
for (UK2Node_ComponentBoundEvent* Event : Events)
|
||
|
|
{
|
||
|
|
UEdGraphPin* Then = Event->FindPin(UEdGraphSchema_K2::PN_Then);
|
||
|
|
if (Event->ComponentPropertyName != Component || !Then || Then->LinkedTo.Num() != 1)
|
||
|
|
{
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
const UK2Node_CallFunction* Call = Cast<UK2Node_CallFunction>(Then->LinkedTo[0]->GetOwningNode());
|
||
|
|
if (Call && Call->FunctionReference.GetMemberName() == FirstCall)
|
||
|
|
{
|
||
|
|
OutFirst = Then->LinkedTo[0]->GetOwningNode();
|
||
|
|
return Event;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
UE_LOG(LogLPTitleMods, Error, TEXT(" %s : evenement de %s suivi de %s introuvable"), *BP->GetName(), *Component.ToString(), FirstCall);
|
||
|
|
++Errors;
|
||
|
|
return nullptr;
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
bool Save(UBlueprint* BP)
|
||
|
|
{
|
||
|
|
UPackage* Package = BP->GetOutermost();
|
||
|
|
Package->MarkPackageDirty();
|
||
|
|
const FString Filename = FPackageName::LongPackageNameToFilename(Package->GetName(), FPackageName::GetAssetPackageExtension());
|
||
|
|
FSavePackageArgs SaveArgs;
|
||
|
|
SaveArgs.TopLevelFlags = RF_Public | RF_Standalone;
|
||
|
|
SaveArgs.Error = GWarn;
|
||
|
|
const bool bOk = UPackage::SavePackage(Package, nullptr, *Filename, SaveArgs);
|
||
|
|
UE_LOG(LogLPTitleMods, Warning, TEXT("%s : %s"), bOk ? TEXT("sauvegarde") : TEXT("ECHEC de sauvegarde"), *Filename);
|
||
|
|
return bOk;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
ULPTitleModManagerCommandlet::ULPTitleModManagerCommandlet()
|
||
|
|
{
|
||
|
|
IsClient = false;
|
||
|
|
IsEditor = true;
|
||
|
|
IsServer = false;
|
||
|
|
LogToConsole = true;
|
||
|
|
}
|
||
|
|
|
||
|
|
int32 ULPTitleModManagerCommandlet::Main(const FString& Params)
|
||
|
|
{
|
||
|
|
TArray<FString> Tokens, Switches;
|
||
|
|
TMap<FString, FString> P;
|
||
|
|
ParseCommandLine(*Params, Tokens, Switches, P);
|
||
|
|
const bool bDryRun = Switches.Contains(TEXT("DryRun"));
|
||
|
|
|
||
|
|
UWidgetBlueprint* MainMenu = LoadObject<UWidgetBlueprint>(nullptr, TEXT("/Game/UI/MainMenu.MainMenu"));
|
||
|
|
UWidgetBlueprint* ModManager = LoadObject<UWidgetBlueprint>(nullptr, TEXT("/Game/UI/ModManager.ModManager"));
|
||
|
|
UClass* GIClass = LoadObject<UClass>(nullptr, TEXT("/Game/BPs/GI.GI_C"));
|
||
|
|
if (!MainMenu || !ModManager || !GIClass)
|
||
|
|
{
|
||
|
|
UE_LOG(LogLPTitleMods, Error, TEXT("MainMenu, ModManager ou GI introuvable"));
|
||
|
|
return 1;
|
||
|
|
}
|
||
|
|
const bool bModManagerDone = FBlueprintEditorUtils::FindNewVariableIndex(ModManager, TitleMenuName) != INDEX_NONE;
|
||
|
|
const bool bMainMenuDone = MainMenu->WidgetTree->FindWidget(TitleButtonName) != nullptr;
|
||
|
|
if (bModManagerDone && bMainMenuDone)
|
||
|
|
{
|
||
|
|
UE_LOG(LogLPTitleMods, Warning, TEXT("Deja applique (ModManager.TitleMenu et MainMenu.%s existent) : rien a faire"), *TitleButtonName.ToString());
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
FEditor E;
|
||
|
|
|
||
|
|
// GI.ModManager doit etre type ModManager_C (cible de TitleMenu).
|
||
|
|
const FObjectProperty* GIModManager = CastField<FObjectProperty>(GIClass->FindPropertyByName(TEXT("ModManager")));
|
||
|
|
if (!GIModManager || !ModManager->GeneratedClass || !GIModManager->PropertyClass->IsChildOf(ModManager->GeneratedClass))
|
||
|
|
{
|
||
|
|
UE_LOG(LogLPTitleMods, Error, TEXT("GI.ModManager absent ou de type %s (ModManager_C attendu)"), GIModManager ? *GIModManager->PropertyClass->GetName() : TEXT("?"));
|
||
|
|
return 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 1. ModManager.TitleMenu (reference au menu titre qui l'a ouvert), compile pour que MainMenu puisse l'affecter.
|
||
|
|
if (!bModManagerDone)
|
||
|
|
{
|
||
|
|
FEdGraphPinType MenuType;
|
||
|
|
MenuType.PinCategory = UEdGraphSchema_K2::PC_Object;
|
||
|
|
MenuType.PinSubCategoryObject = MainMenu->GeneratedClass;
|
||
|
|
if (!FBlueprintEditorUtils::AddMemberVariable(ModManager, TitleMenuName, MenuType))
|
||
|
|
{
|
||
|
|
UE_LOG(LogLPTitleMods, Error, TEXT("Ajout de ModManager.TitleMenu impossible"));
|
||
|
|
return 1;
|
||
|
|
}
|
||
|
|
FKismetEditorUtilities::CompileBlueprint(ModManager);
|
||
|
|
UE_LOG(LogLPTitleMods, Warning, TEXT("ModManager.TitleMenu (%s) ajoutee"), *MainMenu->GeneratedClass->GetName());
|
||
|
|
}
|
||
|
|
|
||
|
|
// 2. MainMenu : entree "Mod Manager" de l'ecran titre, copie de LoadButton (meme taille, meme style) placee juste
|
||
|
|
// apres lui, visible seulement sur l'ecran titre (liaison OnlyVisibleForTitleScreen, comme NewGameButton...).
|
||
|
|
// L'entree d'origine ModManagerButton (sous-entree du menu en partie) n'est pas modifiee.
|
||
|
|
if (!bMainMenuDone)
|
||
|
|
{
|
||
|
|
UWidgetTree* Tree = MainMenu->WidgetTree;
|
||
|
|
UWidget* Load = Tree->FindWidget(TEXT("LoadButton"));
|
||
|
|
UPanelWidget* Options = Load ? Load->GetParent() : nullptr;
|
||
|
|
const FDelegateEditorBinding* TitleOnly = MainMenu->Bindings.FindByPredicate([](const FDelegateEditorBinding& B) { return B.PropertyName == TEXT("Visibility") && B.FunctionName == TEXT("OnlyVisibleForTitleScreen"); });
|
||
|
|
const UTexture2D* ModIcon = LoadObject<UTexture2D>(nullptr, TEXT("/Game/Heavy/New/mod.mod"));
|
||
|
|
if (!Options || !TitleOnly || !ModIcon)
|
||
|
|
{
|
||
|
|
UE_LOG(LogLPTitleMods, Error, TEXT("LoadButton, sa boite, une liaison OnlyVisibleForTitleScreen ou l'icone mod introuvable"));
|
||
|
|
return 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Copie du sous-arbre de LoadButton (export/import texte, comme le copier-coller de l'editeur).
|
||
|
|
TArray<UWidget*> Source;
|
||
|
|
Source.Add(Load);
|
||
|
|
UWidgetTree::GetChildWidgets(Load, Source);
|
||
|
|
FString Text;
|
||
|
|
FWidgetBlueprintEditorUtils::ExportWidgetsToText(Source, Text);
|
||
|
|
TSet<UWidget*> Imported;
|
||
|
|
TMap<FName, UWidgetSlotPair*> SlotData;
|
||
|
|
FWidgetBlueprintEditorUtils::ImportWidgetsFromText(MainMenu, Text, Imported, SlotData);
|
||
|
|
UButton* Button = nullptr;
|
||
|
|
for (UWidget* W : Imported)
|
||
|
|
{
|
||
|
|
if (!W->Slot && Cast<UButton>(W))
|
||
|
|
{
|
||
|
|
Button = Cast<UButton>(W);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (!Button || Imported.Num() != Source.Num())
|
||
|
|
{
|
||
|
|
UE_LOG(LogLPTitleMods, Error, TEXT("Copie de LoadButton : %d element(s) importe(s) pour %d"), Imported.Num(), Source.Num());
|
||
|
|
return 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
Button->Rename(*TitleButtonName.ToString(), Tree);
|
||
|
|
Button->SetDisplayLabel(TitleButtonName.ToString());
|
||
|
|
Button->bIsVariable = true;
|
||
|
|
Button->SetToolTipText(FText::FromString(TEXT("Choose which mods (modules) are enabled, then start or load a game")));
|
||
|
|
UPanelSlot* Slot = Options->InsertChildAt(Options->GetChildIndex(Load) + 1, Button);
|
||
|
|
// Proprietes d'emplacement (marges) : celles de LoadButton.
|
||
|
|
TMap<FName, FString> SlotProps;
|
||
|
|
FWidgetBlueprintEditorUtils::ExportPropertiesToText(Load->Slot, SlotProps);
|
||
|
|
FWidgetBlueprintEditorUtils::ImportPropertiesFromText(Slot, SlotProps);
|
||
|
|
int32 Icons = 0, Texts = 0;
|
||
|
|
for (UWidget* W : Imported)
|
||
|
|
{
|
||
|
|
if (UImage* Image = Cast<UImage>(W))
|
||
|
|
{
|
||
|
|
if (Image->GetBrush().GetResourceObject() && Image->GetBrush().GetResourceObject()->GetName() == TEXT("loadgame"))
|
||
|
|
{
|
||
|
|
Image->SetBrushResourceObject(const_cast<UTexture2D*>(ModIcon));
|
||
|
|
++Icons;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else if (UTextBlock* Label = Cast<UTextBlock>(W))
|
||
|
|
{
|
||
|
|
Label->SetText(FText::FromString(TEXT("Mod Manager")));
|
||
|
|
++Texts;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (Icons != 1 || Texts != 1)
|
||
|
|
{
|
||
|
|
UE_LOG(LogLPTitleMods, Error, TEXT("Copie de LoadButton : %d icone(s) loadgame et %d texte(s) (1 et 1 attendus)"), Icons, Texts);
|
||
|
|
return 1;
|
||
|
|
}
|
||
|
|
FDelegateEditorBinding Binding = *TitleOnly;
|
||
|
|
Binding.ObjectName = TitleButtonName.ToString();
|
||
|
|
MainMenu->Bindings.Add(Binding);
|
||
|
|
UE_LOG(LogLPTitleMods, Warning, TEXT("MainMenu.%s : copie de LoadButton (%d elements), apres Load, icone mod, visible sur l'ecran titre (%s)"),
|
||
|
|
*TitleButtonName.ToString(), Imported.Num(), *Binding.FunctionName.ToString());
|
||
|
|
|
||
|
|
// La variable du bouton doit exister dans la classe generee pour y lier l'evenement de clic.
|
||
|
|
FBlueprintEditorUtils::MarkBlueprintAsStructurallyModified(MainMenu);
|
||
|
|
FKismetEditorUtilities::CompileBlueprint(MainMenu);
|
||
|
|
const FObjectProperty* ButtonProp = CastField<FObjectProperty>(MainMenu->GeneratedClass->FindPropertyByName(TitleButtonName));
|
||
|
|
const FMulticastDelegateProperty* OnClicked = FindFProperty<FMulticastDelegateProperty>(UButton::StaticClass(), TEXT("OnClicked"));
|
||
|
|
UEdGraph* G = FBlueprintEditorUtils::FindEventGraph(MainMenu);
|
||
|
|
if (!ButtonProp || !OnClicked || !G)
|
||
|
|
{
|
||
|
|
UE_LOG(LogLPTitleMods, Error, TEXT("Variable %s, OnClicked ou graphe d'evenements introuvable"), *TitleButtonName.ToString());
|
||
|
|
return 1;
|
||
|
|
}
|
||
|
|
// Ancre : l'evenement de clic de l'entree d'origine (les nouveaux noeuds sont poses en dessous).
|
||
|
|
UEdGraphNode* Ignored = nullptr;
|
||
|
|
const UK2Node_ComponentBoundEvent* Anchor = E.BoundEvent(MainMenu, TEXT("ModManagerButton"), TEXT("CloseSelf"), Ignored);
|
||
|
|
if (!Anchor)
|
||
|
|
{
|
||
|
|
return 1;
|
||
|
|
}
|
||
|
|
auto* Click = MakeNode<UK2Node_ComponentBoundEvent>(G, Anchor, 0, 3, [ButtonProp, OnClicked](UK2Node_ComponentBoundEvent* N) { N->InitializeComponentBoundEventParams(ButtonProp, OnClicked); });
|
||
|
|
auto* Hide = E.Call(G, Anchor, 1, 3, E.Function(UWidget::StaticClass(), TEXT("SetVisibility")));
|
||
|
|
E.Default(Hide->FindPin(TEXT("InVisibility")), TEXT("Collapsed"), TEXT("SetVisibility.InVisibility"));
|
||
|
|
auto* GI = E.GetSelf(G, Anchor, 1, 4, TEXT("GI"));
|
||
|
|
auto* Open = E.Call(G, Anchor, 2, 3, E.Function(GIClass, TEXT("CreateModManagerWidget")));
|
||
|
|
E.Default(Open->FindPin(TEXT("GameStart")), TEXT("false"), TEXT("CreateModManagerWidget.GameStart"));
|
||
|
|
auto* GetMM = MakeNode<UK2Node_VariableGet>(G, Anchor, 2, 4, [GIClass](UK2Node_VariableGet* N) { N->VariableReference.SetExternalMember(TEXT("ModManager"), GIClass); });
|
||
|
|
auto* SetTitle = MakeNode<UK2Node_VariableSet>(G, Anchor, 3, 3, [ModManager](UK2Node_VariableSet* N) { N->VariableReference.SetExternalMember(TitleMenuName, ModManager->GeneratedClass); });
|
||
|
|
auto* Self = MakeNode<UK2Node_Self>(G, Anchor, 3, 4, [](UK2Node_Self*) {});
|
||
|
|
|
||
|
|
E.Link(Click->FindPin(UEdGraphSchema_K2::PN_Then), Hide->GetExecPin(), TEXT("clic -> masquer le menu"));
|
||
|
|
E.Link(Hide->GetThenPin(), Open->GetExecPin(), TEXT("-> CreateModManagerWidget"));
|
||
|
|
E.Link(GI->GetValuePin(), Open->FindPin(UEdGraphSchema_K2::PN_Self), TEXT("GI -> CreateModManagerWidget"));
|
||
|
|
E.Link(Open->GetThenPin(), SetTitle->GetExecPin(), TEXT("-> TitleMenu"));
|
||
|
|
E.Link(GI->GetValuePin(), GetMM->FindPin(UEdGraphSchema_K2::PN_Self), TEXT("GI -> GI.ModManager"));
|
||
|
|
E.Link(GetMM->GetValuePin(), SetTitle->FindPin(UEdGraphSchema_K2::PN_Self), TEXT("GI.ModManager -> cible de TitleMenu"));
|
||
|
|
E.Link(Self->FindPin(UEdGraphSchema_K2::PN_Self), SetTitle->FindPin(TitleMenuName), TEXT("self -> TitleMenu"));
|
||
|
|
UE_LOG(LogLPTitleMods, Warning, TEXT("MainMenu : clic %s -> menu masque, CreateModManagerWidget, TitleMenu = self (7 noeuds)"), *TitleButtonName.ToString());
|
||
|
|
}
|
||
|
|
|
||
|
|
// 3. ModManager : fermeture.
|
||
|
|
if (!bModManagerDone)
|
||
|
|
{
|
||
|
|
UEdGraphNode* CloseMM = nullptr;
|
||
|
|
UK2Node_ComponentBoundEvent* Close = nullptr;
|
||
|
|
TArray<UK2Node_ComponentBoundEvent*> Events;
|
||
|
|
FBlueprintEditorUtils::GetAllNodesOfClass(ModManager, Events);
|
||
|
|
for (UK2Node_ComponentBoundEvent* Event : Events)
|
||
|
|
{
|
||
|
|
UEdGraphPin* Then = Event->FindPin(UEdGraphSchema_K2::PN_Then);
|
||
|
|
if (Then && Then->LinkedTo.Num() == 1)
|
||
|
|
{
|
||
|
|
const UK2Node_CallFunction* Call = Cast<UK2Node_CallFunction>(Then->LinkedTo[0]->GetOwningNode());
|
||
|
|
if (Call && Call->FunctionReference.GetMemberName() == TEXT("CloseModManager"))
|
||
|
|
{
|
||
|
|
Close = Event;
|
||
|
|
CloseMM = Then->LinkedTo[0]->GetOwningNode();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (!Close)
|
||
|
|
{
|
||
|
|
UE_LOG(LogLPTitleMods, Error, TEXT("ModManager : evenement suivi de CloseModManager introuvable"));
|
||
|
|
++E.Errors;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
UEdGraph* G = Close->GetGraph();
|
||
|
|
UEdGraphPin* Then = Close->FindPin(UEdGraphSchema_K2::PN_Then);
|
||
|
|
Then->BreakAllPinLinks();
|
||
|
|
auto* Branch = MakeNode<UK2Node_IfThenElse>(G, Close, 1, 0, [](UK2Node_IfThenElse*) {});
|
||
|
|
auto* Menu = E.GetSelf(G, Close, 0, 1, TitleMenuName);
|
||
|
|
auto* Valid = E.Call(G, Close, 0, 2, E.Function(UKismetSystemLibrary::StaticClass(), TEXT("IsValid")));
|
||
|
|
E.Link(Then, Branch->GetExecPin(), TEXT("fermeture -> branche"));
|
||
|
|
E.Link(Menu->GetValuePin(), Valid->FindPin(TEXT("Object")), TEXT("TitleMenu -> IsValid"));
|
||
|
|
E.Link(Valid->GetReturnValuePin(), Branch->GetConditionPin(), TEXT("IsValid -> condition"));
|
||
|
|
E.Link(Branch->GetElsePin(), CloseMM->FindPin(UEdGraphSchema_K2::PN_Execute), TEXT("sinon -> CloseModManager"));
|
||
|
|
|
||
|
|
auto* Show = E.Call(G, Close, 2, 0, E.Function(UWidget::StaticClass(), TEXT("SetVisibility")));
|
||
|
|
E.Default(Show->FindPin(TEXT("InVisibility")), TEXT("Visible"), TEXT("SetVisibility.InVisibility"));
|
||
|
|
auto* PC = E.Call(G, Close, 2, 1, E.Function(UGameplayStatics::StaticClass(), TEXT("GetPlayerController")));
|
||
|
|
auto* Focus = E.Call(G, Close, 3, 0, E.Function(UWidgetBlueprintLibrary::StaticClass(), TEXT("SetInputMode_UIOnlyEx")));
|
||
|
|
auto* GI = E.GetSelf(G, Close, 3, 1, TEXT("GI"));
|
||
|
|
auto* Clear = E.Call(G, Close, 4, 0, E.Function(GIClass, TEXT("ClearModManagerWidget")));
|
||
|
|
auto* Populate = E.Call(G, Close, 5, 0, E.Function(GIClass, TEXT("PopulateRaws")));
|
||
|
|
auto* SaveSelection = E.Call(G, Close, 6, 0, E.Function(ULPModSettingsLibrary::StaticClass(), TEXT("SaveModSelection")));
|
||
|
|
|
||
|
|
E.Link(Branch->GetThenPin(), Show->GetExecPin(), TEXT("titre -> reafficher le menu"));
|
||
|
|
E.Link(Menu->GetValuePin(), Show->FindPin(UEdGraphSchema_K2::PN_Self), TEXT("TitleMenu -> SetVisibility"));
|
||
|
|
E.Link(Show->GetThenPin(), Focus->GetExecPin(), TEXT("-> SetInputMode_UIOnlyEx"));
|
||
|
|
E.Link(PC->GetReturnValuePin(), Focus->FindPin(TEXT("PlayerController")), TEXT("GetPlayerController -> PlayerController"));
|
||
|
|
E.Link(Menu->GetValuePin(), Focus->FindPin(TEXT("InWidgetToFocus")), TEXT("TitleMenu -> InWidgetToFocus"));
|
||
|
|
E.Link(Focus->GetThenPin(), Clear->GetExecPin(), TEXT("-> ClearModManagerWidget"));
|
||
|
|
E.Link(Clear->GetThenPin(), Populate->GetExecPin(), TEXT("-> PopulateRaws"));
|
||
|
|
E.Link(Populate->GetThenPin(), SaveSelection->GetExecPin(), TEXT("-> SaveModSelection"));
|
||
|
|
E.Link(GI->GetValuePin(), SaveSelection->FindPin(TEXT("GameInstance")), TEXT("GI -> SaveModSelection"));
|
||
|
|
for (UK2Node_CallFunction* N : { Clear, Populate })
|
||
|
|
{
|
||
|
|
E.Link(GI->GetValuePin(), N->FindPin(UEdGraphSchema_K2::PN_Self), TEXT("GI -> appel"));
|
||
|
|
}
|
||
|
|
UE_LOG(LogLPTitleMods, Warning, TEXT("ModManager : fermeture -> branche TitleMenu valide (%d noeuds ajoutes)"), 10);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (E.Errors > 0)
|
||
|
|
{
|
||
|
|
UE_LOG(LogLPTitleMods, Error, TEXT("%d erreur(s) : rien n'est sauvegarde"), E.Errors);
|
||
|
|
return 1;
|
||
|
|
}
|
||
|
|
FKismetEditorUtilities::CompileBlueprint(ModManager);
|
||
|
|
FKismetEditorUtilities::CompileBlueprint(MainMenu);
|
||
|
|
if (ModManager->Status == BS_Error || MainMenu->Status == BS_Error)
|
||
|
|
{
|
||
|
|
UE_LOG(LogLPTitleMods, Error, TEXT("Compilation en erreur (ModManager %d, MainMenu %d) : rien n'est sauvegarde"), int32(ModManager->Status), int32(MainMenu->Status));
|
||
|
|
return 1;
|
||
|
|
}
|
||
|
|
UE_LOG(LogLPTitleMods, Warning, TEXT("ModManager et MainMenu compiles sans erreur (etat ModManager %d, MainMenu %d)"), int32(ModManager->Status), int32(MainMenu->Status));
|
||
|
|
if (bDryRun)
|
||
|
|
{
|
||
|
|
UE_LOG(LogLPTitleMods, Warning, TEXT("Essai a blanc : rien n'est sauvegarde"));
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
bool bOk = true;
|
||
|
|
if (!bModManagerDone)
|
||
|
|
{
|
||
|
|
bOk &= Save(ModManager);
|
||
|
|
}
|
||
|
|
if (!bMainMenuDone)
|
||
|
|
{
|
||
|
|
bOk &= Save(MainMenu);
|
||
|
|
}
|
||
|
|
return bOk ? 0 : 1;
|
||
|
|
}
|