233 lines
9.2 KiB
C++
233 lines
9.2 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "NiagaraConvertInPlaceEmitterAndSystemState.h"
|
|
#include "NiagaraClipboard.h"
|
|
#include "ViewModels/Stack/NiagaraStackValueCollection.h"
|
|
#include "ViewModels/Stack/NiagaraStackScriptHierarchyRoot.h"
|
|
|
|
#include UE_INLINE_GENERATED_CPP_BY_NAME(NiagaraConvertInPlaceEmitterAndSystemState)
|
|
|
|
bool UNiagaraConvertInPlaceEmitterAndSystemState::Convert(UNiagaraScript* InOldScript, UNiagaraClipboardContent* InOldClipboardContent, UNiagaraScript* InNewScript, UNiagaraStackScriptHierarchyRoot* InHierarchyRoot, UNiagaraClipboardContent* InNewClipboardContent, UNiagaraNodeFunctionCall* InCallingNode, FText& OutMessage)
|
|
{
|
|
UE_LOG(LogNiagaraEditor, Log, TEXT("%s to %s"), *InOldScript->GetPathName(), *InNewScript->GetPathName());
|
|
|
|
if (InOldScript->GetPathName() == TEXT("/Niagara/Modules/Emitter/EmitterLifeCycle.EmitterLifeCycle") && InNewScript->GetPathName() == TEXT("/Niagara/Modules/Emitter/EmitterState.EmitterState"))
|
|
{
|
|
if (InOldClipboardContent->Functions.Num() == 1 && InNewClipboardContent->Functions.Num() == 1 &&
|
|
InOldClipboardContent->Functions[0] && InNewClipboardContent->Functions[0])
|
|
{
|
|
int32 OldMaxLoopCount = 0;
|
|
const UNiagaraClipboardFunctionInput* InputOldLoopDuration = nullptr;
|
|
const UNiagaraClipboardFunctionInput* InputOldMaxLoopCount = nullptr;
|
|
const UNiagaraClipboardFunctionInput* InputOldDurationRecalcEachLoop = nullptr;
|
|
const UNiagaraClipboardFunctionInput* InputOldNextLoopDelay = nullptr;
|
|
const UNiagaraClipboardFunctionInput* InputOldDelayFirstLoopOnly = nullptr;
|
|
int32 AutoComplete = 0;
|
|
int32 CompleteOnInactive = 0;
|
|
bool bAutoCompleteWasLocal = false;
|
|
bool bCompleteOnInactiveWasLocal = false;
|
|
|
|
for (const UNiagaraClipboardFunctionInput* Input : InOldClipboardContent->Functions[0]->Inputs)
|
|
{
|
|
if (Input)
|
|
{
|
|
UE_LOG(LogNiagaraEditor, Log, TEXT("OldInput \"%s\""), *Input->InputName.ToString());
|
|
|
|
bool bSuccess = false;
|
|
if (Input->InputName == TEXT("MaxLoopCount"))
|
|
{
|
|
InputOldMaxLoopCount = Input;
|
|
UNiagaraClipboardEditorScriptingUtilities::TryGetLocalValueAsInt(Input, bSuccess, OldMaxLoopCount);
|
|
}
|
|
else if (Input->InputName == TEXT("NextLoopDuration"))
|
|
{
|
|
InputOldLoopDuration = Input;
|
|
}
|
|
else if (Input->InputName == TEXT("DurationRecalcEachLoop"))
|
|
{
|
|
InputOldDurationRecalcEachLoop = Input;
|
|
}
|
|
else if (Input->InputName == TEXT("NextLoopDelay"))
|
|
{
|
|
InputOldNextLoopDelay = Input;
|
|
}
|
|
else if (Input->InputName == TEXT("AutoComplete"))
|
|
{
|
|
UNiagaraClipboardEditorScriptingUtilities::TryGetLocalValueAsInt(Input, bAutoCompleteWasLocal, AutoComplete);
|
|
}
|
|
else if (Input->InputName == TEXT("CompleteOnInactive"))
|
|
{
|
|
UNiagaraClipboardEditorScriptingUtilities::TryGetLocalValueAsInt(Input, bCompleteOnInactiveWasLocal, CompleteOnInactive);
|
|
}
|
|
else if (Input->InputName == TEXT("DelayFirstLoopOnly"))
|
|
{
|
|
InputOldDelayFirstLoopOnly = Input;
|
|
}
|
|
}
|
|
}
|
|
|
|
TArray<const UNiagaraClipboardFunctionInput*> NewInputs;
|
|
bool bMultipleLoopsFound = false;
|
|
bool bUseLoopDelay = false;
|
|
TArray<FName> ConvertedItems;
|
|
|
|
for (const UNiagaraClipboardFunctionInput* Input : InNewClipboardContent->Functions[0]->Inputs)
|
|
{
|
|
if (Input)
|
|
{
|
|
UE_LOG(LogNiagaraEditor, Log, TEXT("New Input \"%s\""), *Input->InputName.ToString());
|
|
bool bSuccess = false;
|
|
if (Input->InputName == TEXT("Life Cycle Mode"))
|
|
{
|
|
// When converting old Emitter Life Cycle, always assume that new type is Self
|
|
UNiagaraClipboardFunctionInput* NewInput = Cast< UNiagaraClipboardFunctionInput>(StaticDuplicateObject(Input, GetTransientPackage()));
|
|
UNiagaraClipboardEditorScriptingUtilities::TrySetLocalValueAsInt(NewInput, bSuccess, 1);
|
|
NewInputs.Add(NewInput);
|
|
if (bSuccess)
|
|
ConvertedItems.Add(Input->InputName);
|
|
}
|
|
else if (Input->InputName == TEXT("Loop Behavior"))
|
|
{
|
|
UNiagaraClipboardFunctionInput* NewInput = Cast< UNiagaraClipboardFunctionInput>(StaticDuplicateObject(Input, GetTransientPackage()));
|
|
int32 NewValue = -1;
|
|
if (InputOldMaxLoopCount && InputOldMaxLoopCount->ValueMode == ENiagaraClipboardFunctionInputValueMode::Local)
|
|
{
|
|
if (OldMaxLoopCount == 0)
|
|
NewValue = 0; // Infinite
|
|
else if (OldMaxLoopCount == 1)
|
|
NewValue = 1; // Once
|
|
else if (OldMaxLoopCount > 1)
|
|
NewValue = 2; // Multiple
|
|
}
|
|
|
|
// Force to multiple if anything other than local
|
|
if (NewValue < 0)
|
|
NewValue = 2; // Multiple
|
|
|
|
if (NewValue == 2)
|
|
bMultipleLoopsFound = true;
|
|
|
|
UNiagaraClipboardEditorScriptingUtilities::TrySetLocalValueAsInt(NewInput, bSuccess, NewValue);
|
|
NewInputs.Add(NewInput);
|
|
if (bSuccess)
|
|
ConvertedItems.Add(Input->InputName);
|
|
}
|
|
else if (Input->InputName == TEXT("Inactive Response"))
|
|
{
|
|
|
|
UNiagaraClipboardFunctionInput* NewInput = Cast< UNiagaraClipboardFunctionInput>(StaticDuplicateObject(Input, GetTransientPackage()));
|
|
NewInputs.Add(NewInput);
|
|
|
|
int32 NewValue = -1;
|
|
if (AutoComplete && bAutoCompleteWasLocal)
|
|
NewValue = 0; // Complete
|
|
else if (CompleteOnInactive && bCompleteOnInactiveWasLocal)
|
|
NewValue = 1; // Kill
|
|
|
|
// Force to complete if anything else
|
|
if (NewValue < 0)
|
|
NewValue = 0; // Complete
|
|
|
|
UNiagaraClipboardEditorScriptingUtilities::TrySetLocalValueAsInt(NewInput, bSuccess, NewValue);
|
|
if (bSuccess)
|
|
ConvertedItems.Add(Input->InputName);
|
|
}
|
|
else if (Input->InputName == TEXT("Loop Duration"))
|
|
{
|
|
if (InputOldLoopDuration)
|
|
{
|
|
UNiagaraClipboardFunctionInput* NewInput = Cast< UNiagaraClipboardFunctionInput>(StaticDuplicateObject(InputOldLoopDuration, GetTransientPackage()));
|
|
NewInput->InputName = Input->InputName;
|
|
NewInputs.Add(NewInput);
|
|
ConvertedItems.Add(Input->InputName);
|
|
}
|
|
}
|
|
else if (Input->InputName == TEXT("Recalculate Duration Each Loop"))
|
|
{
|
|
if (InputOldDurationRecalcEachLoop)
|
|
{
|
|
UNiagaraClipboardFunctionInput* NewInput = Cast< UNiagaraClipboardFunctionInput>(StaticDuplicateObject(InputOldDurationRecalcEachLoop, GetTransientPackage()));
|
|
NewInput->InputName = Input->InputName;
|
|
NewInputs.Add(NewInput);
|
|
ConvertedItems.Add(Input->InputName);
|
|
}
|
|
}
|
|
else if (Input->InputName == TEXT("Loop Delay"))
|
|
{
|
|
if (InputOldNextLoopDelay)
|
|
{
|
|
UNiagaraClipboardFunctionInput* NewInput = Cast< UNiagaraClipboardFunctionInput>(StaticDuplicateObject(InputOldNextLoopDelay, GetTransientPackage()));
|
|
NewInput->InputName = Input->InputName;
|
|
NewInputs.Add(NewInput);
|
|
ConvertedItems.Add(Input->InputName);
|
|
}
|
|
}
|
|
else if (Input->InputName == TEXT("UseLoopDelay"))
|
|
{
|
|
if (InputOldNextLoopDelay)
|
|
{
|
|
float OutFloat = 0.0f;
|
|
bool bLoopDelayFound = false;
|
|
UNiagaraClipboardEditorScriptingUtilities::TryGetLocalValueAsFloat(InputOldNextLoopDelay, bLoopDelayFound, OutFloat);
|
|
if ((bLoopDelayFound && OutFloat != 0.0f) || InputOldNextLoopDelay->ValueMode != ENiagaraClipboardFunctionInputValueMode::Local)
|
|
{
|
|
bUseLoopDelay = true;
|
|
int32 NewValue = -1;
|
|
UNiagaraClipboardFunctionInput* NewInput = Cast< UNiagaraClipboardFunctionInput>(StaticDuplicateObject(Input, GetTransientPackage())); UNiagaraClipboardEditorScriptingUtilities::TrySetLocalValueAsInt(NewInput, bSuccess, NewValue);
|
|
NewInputs.Add(NewInput);
|
|
if (bSuccess)
|
|
ConvertedItems.Add(Input->InputName);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
InHierarchyRoot->SetValuesFromClipboardFunctionInputs(NewInputs);
|
|
//InCallingNode->RefreshFromExternalChanges();
|
|
|
|
// We have to do this as a second pass as Loop Count is behind a static switch set above.
|
|
NewInputs.Empty();
|
|
if (InputOldMaxLoopCount && bMultipleLoopsFound)
|
|
{
|
|
UNiagaraClipboardFunctionInput* NewInput = Cast< UNiagaraClipboardFunctionInput>(StaticDuplicateObject(InputOldMaxLoopCount, GetTransientPackage()));
|
|
NewInput->InputName = TEXT("Loop Count");
|
|
NewInputs.Add(NewInput);
|
|
ConvertedItems.Add(NewInput->InputName);
|
|
|
|
InHierarchyRoot->SetValuesFromClipboardFunctionInputs(NewInputs);
|
|
}
|
|
|
|
// Use first frame delay is behind a static switch set above.
|
|
NewInputs.Empty();
|
|
if (bUseLoopDelay && InputOldDelayFirstLoopOnly)
|
|
{
|
|
UNiagaraClipboardFunctionInput* NewInput = Cast< UNiagaraClipboardFunctionInput>(StaticDuplicateObject(InputOldDelayFirstLoopOnly, GetTransientPackage()));
|
|
NewInput->InputName = TEXT("Delay First Loop Only");
|
|
NewInputs.Add(NewInput);
|
|
ConvertedItems.Add(NewInput->InputName);
|
|
|
|
InHierarchyRoot->SetValuesFromClipboardFunctionInputs(NewInputs);
|
|
}
|
|
|
|
FString ConcatString = FString::Printf(TEXT("Copied over %d properties\nPlease double-check for correctness\n"), ConvertedItems.Num());
|
|
for (int32 i = 0; i < ConvertedItems.Num(); i++)
|
|
{
|
|
ConcatString += ConvertedItems[i].ToString();
|
|
|
|
if (i < ConvertedItems.Num() - 1)
|
|
ConcatString += TEXT(",\n");
|
|
else
|
|
ConcatString += TEXT("\n");
|
|
|
|
}
|
|
OutMessage = FText::FromString(ConcatString);
|
|
if (ConvertedItems.Num() > 0)
|
|
return true;
|
|
else
|
|
return false;
|
|
}
|
|
}
|
|
return false;
|
|
};
|