150 lines
4.4 KiB
C++
150 lines
4.4 KiB
C++
// Copyright Steve Streeting 2022
|
|
// Released under the MIT license https://opensource.org/license/MIT/
|
|
#include "SUDSScriptReimportFactory.h"
|
|
|
|
#include "SUDSEditor.h"
|
|
#include "SUDSMessageLogger.h"
|
|
#include "SUDSScript.h"
|
|
#include "SUDSScriptNodeText.h"
|
|
#include "EditorFramework/AssetImportData.h"
|
|
#include "HAL/FileManager.h"
|
|
#include "Sound/DialogueWave.h"
|
|
|
|
USUDSScriptReimportFactory::USUDSScriptReimportFactory()
|
|
{
|
|
SupportedClass = USUDSScript::StaticClass();
|
|
bCreateNew = false;
|
|
// We need to have a unique priority vs the original factory, so go after
|
|
ImportPriority = DefaultImportPriority - 1;
|
|
}
|
|
|
|
bool USUDSScriptReimportFactory::CanReimport(UObject* Obj, TArray<FString>& OutFilenames)
|
|
{
|
|
USUDSScript* Script = Cast<USUDSScript>(Obj);
|
|
if (Script && Script->AssetImportData)
|
|
{
|
|
Script->AssetImportData->ExtractFilenames(OutFilenames);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void USUDSScriptReimportFactory::SetReimportPaths(UObject* Obj, const TArray<FString>& NewReimportPaths)
|
|
{
|
|
USUDSScript* Script = Cast<USUDSScript>(Obj);
|
|
if (Script && ensure(NewReimportPaths.Num() == 1))
|
|
{
|
|
Script->AssetImportData->UpdateFilenameOnly(NewReimportPaths[0]);
|
|
}
|
|
|
|
}
|
|
|
|
EReimportResult::Type USUDSScriptReimportFactory::Reimport(UObject* Obj)
|
|
{
|
|
USUDSScript* Script = Cast<USUDSScript>(Obj);
|
|
if (!Script)
|
|
{
|
|
return EReimportResult::Failed;
|
|
}
|
|
|
|
// Make sure file is valid and exists
|
|
const FString Filename = Script->AssetImportData->GetFirstFilename();
|
|
if (!Filename.Len() || IFileManager::Get().FileSize(*Filename) == INDEX_NONE)
|
|
{
|
|
return EReimportResult::Failed;
|
|
}
|
|
|
|
// When a new script is created, it actually lives at the same address as the incoming one. UE must re-use objects
|
|
// when you put them back at the same outer & asset name?
|
|
// This means if we want to preserve anything from the previously imported object, such as generated VO asset links,
|
|
// we need to copy those out now.
|
|
TMap<FString, UDialogueVoice*> PrevSpeakerVoices = Script->GetSpeakerVoices();
|
|
// Store the TextID -> DialogueWave, but also store the line text as well so we can detect whether it matches & warn if not
|
|
TMap<FString, TPair<FString, UDialogueWave*> > PrevWaves;
|
|
for (auto Node : Script->GetNodes())
|
|
{
|
|
if (auto TN = Cast<USUDSScriptNodeText>(Node))
|
|
{
|
|
if (auto W = TN->GetWave())
|
|
{
|
|
PrevWaves.Add(TN->GetTextID(), TPair<FString, UDialogueWave*>(TN->GetText().ToString(), W));
|
|
}
|
|
}
|
|
}
|
|
|
|
// Run the import again
|
|
EReimportResult::Type Result = EReimportResult::Failed;
|
|
bool OutCanceled = false;
|
|
|
|
if (ImportObject(Script->GetClass(), Script->GetOuter(), *Script->GetName(), RF_Public | RF_Standalone, Filename, nullptr, OutCanceled) != nullptr)
|
|
{
|
|
UE_LOG(LogSUDSEditor, Log, TEXT("Imported successfully"));
|
|
|
|
FSUDSMessageLogger Logger;
|
|
// Now, try to restore the speaker voice / line wave links from before
|
|
for (auto SpeakerID : Script->GetSpeakers())
|
|
{
|
|
if (auto pVoice = PrevSpeakerVoices.Find(SpeakerID))
|
|
{
|
|
Script->SetSpeakerVoice(SpeakerID, *pVoice);
|
|
}
|
|
}
|
|
for (auto Node : Script->GetNodes())
|
|
{
|
|
if (auto TN = Cast<USUDSScriptNodeText>(Node))
|
|
{
|
|
if (auto pWavePair = PrevWaves.Find(TN->GetTextID()))
|
|
{
|
|
// Set the wave link either way
|
|
TN->SetWave(pWavePair->Value);
|
|
|
|
// Check that the text is the same; if it's not, then lines have potentially changed
|
|
// we still live with the assignment we have (might be a minor edit) but user should be aware
|
|
if (TN->GetText().ToString() != pWavePair->Key)
|
|
{
|
|
Logger.Logf(ELogVerbosity::Error,
|
|
TEXT(
|
|
"TextID %s is linked to Dialogue Wave %s, but text has changed. Check whether this line is linked to the correct wave, and consider Writing String Keys back to script before making more script changes in future."),
|
|
*TN->GetTextID(),
|
|
*pWavePair->Value->GetName());
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
Script->AssetImportData->Update(Filename);
|
|
|
|
// Try to find the outer package so we can dirty it up
|
|
if (Script->GetOuter())
|
|
{
|
|
Script->GetOuter()->MarkPackageDirty();
|
|
}
|
|
else
|
|
{
|
|
Script->MarkPackageDirty();
|
|
}
|
|
Result = EReimportResult::Succeeded;
|
|
}
|
|
else
|
|
{
|
|
if (OutCanceled)
|
|
{
|
|
UE_LOG(LogSUDSEditor, Warning, TEXT("-- import canceled"));
|
|
}
|
|
else
|
|
{
|
|
UE_LOG(LogSUDSEditor, Warning, TEXT("-- import failed"));
|
|
}
|
|
|
|
Result = EReimportResult::Failed;
|
|
}
|
|
|
|
return Result;
|
|
}
|
|
|
|
int32 USUDSScriptReimportFactory::GetPriority() const
|
|
{
|
|
return ImportPriority;
|
|
}
|