LifePlay-Revival/Source/LifePlayEditorTools/LPConvertAtmosphericFogCommandlet.cpp

172 lines
5.9 KiB
C++
Raw Normal View History

// Portage UE 5.5 - voir LPConvertAtmosphericFogCommandlet.h
#include "LPConvertAtmosphericFogCommandlet.h"
#include "Atmosphere/AtmosphericFog.h"
#include "Atmosphere/AtmosphericFogComponent.h"
#include "Components/SkyAtmosphereComponent.h"
#include "Engine/Level.h"
#include "Engine/World.h"
#include "Misc/PackageName.h"
#include "UObject/Package.h"
#include "UObject/SavePackage.h"
#include "UObject/UnrealType.h"
DEFINE_LOG_CATEGORY_STATIC(LogLPConvertAtmo, Log, All);
namespace
{
FString ExportProp(const FProperty* Prop, const UObject* Obj)
{
FString Text;
Prop->ExportTextItem_Direct(Text, Prop->ContainerPtrToValuePtr<void>(Obj), nullptr, nullptr, PPF_None);
return Text;
}
}
ULPConvertAtmosphericFogCommandlet::ULPConvertAtmosphericFogCommandlet()
{
IsClient = false;
IsServer = false;
IsEditor = true;
LogToConsole = true;
}
int32 ULPConvertAtmosphericFogCommandlet::Main(const FString& Params)
{
TArray<FString> Tokens, Switches;
TMap<FString, FString> ParamsMap;
ParseCommandLine(*Params, Tokens, Switches, ParamsMap);
const bool bDryRun = Switches.Contains(TEXT("DryRun"));
const FString MapPath = ParamsMap.FindRef(TEXT("Map"));
if (MapPath.IsEmpty())
{
UE_LOG(LogLPConvertAtmo, Error, TEXT("Usage : -Map=/Game/Scenes/X [-DryRun]"));
return 1;
}
const FString WorldPath = MapPath + TEXT(".") + FPackageName::GetShortName(MapPath);
UWorld* World = LoadObject<UWorld>(nullptr, *WorldPath);
if (!World || !World->PersistentLevel)
{
UE_LOG(LogLPConvertAtmo, Error, TEXT("Carte introuvable : %s"), *WorldPath);
return 1;
}
World->AddToRoot();
if (!World->bIsWorldInitialized)
{
World->InitWorld(UWorld::InitializationValues().AllowAudioPlayback(false).CreatePhysicsScene(false).CreateNavigation(false).CreateAISystem(false).ShouldSimulatePhysics(false).EnableTraceCollision(false).SetTransactional(false).CreateFXSystem(false));
}
UE_LOG(LogLPConvertAtmo, Warning, TEXT("=== AtmosphericFog -> SkyAtmosphere : %s%s ==="), *MapPath, bDryRun ? TEXT(" [DRY RUN]") : TEXT(""));
PRAGMA_DISABLE_DEPRECATION_WARNINGS
TArray<AAtmosphericFog*> Fogs;
for (AActor* Actor : World->PersistentLevel->Actors)
{
if (AAtmosphericFog* Fog = Cast<AAtmosphericFog>(Actor))
{
Fogs.Add(Fog);
}
}
int32 Mismatches = 0;
int32 Converted = 0;
for (AAtmosphericFog* Fog : Fogs)
{
UAtmosphericFogComponent* OldComp = Fog->GetAtmosphericFogComponent();
UE_LOG(LogLPConvertAtmo, Warning, TEXT(" %s (%s), transformation %s"), *Fog->GetName(), *Fog->GetActorLabel(), *Fog->GetActorTransform().ToString());
if (!OldComp)
{
++Mismatches;
UE_LOG(LogLPConvertAtmo, Error, TEXT(" composant absent"));
continue;
}
if (bDryRun)
{
for (TFieldIterator<FProperty> It(USkyAtmosphereComponent::StaticClass(), EFieldIteratorFlags::ExcludeSuper); It; ++It)
{
UE_LOG(LogLPConvertAtmo, Display, TEXT(" %s = %s"), *It->GetName(), *ExportProp(*It, OldComp));
}
continue;
}
FActorSpawnParameters SpawnParams;
SpawnParams.OverrideLevel = World->PersistentLevel;
SpawnParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
ASkyAtmosphere* Sky = World->SpawnActor<ASkyAtmosphere>(ASkyAtmosphere::StaticClass(), Fog->GetActorTransform(), SpawnParams);
USkyAtmosphereComponent* NewComp = Sky ? Sky->GetComponent() : nullptr;
if (!NewComp)
{
++Mismatches;
UE_LOG(LogLPConvertAtmo, Error, TEXT(" creation du SkyAtmosphere impossible"));
continue;
}
// Valeurs effectives de toutes les proprietes declarees par USkyAtmosphereComponent.
int32 Copied = 0;
for (TFieldIterator<FProperty> It(USkyAtmosphereComponent::StaticClass(), EFieldIteratorFlags::ExcludeSuper); It; ++It)
{
It->CopyCompleteValue_InContainer(NewComp, OldComp);
++Copied;
}
NewComp->SetRelativeTransform(OldComp->GetRelativeTransform());
NewComp->SetMobility(OldComp->Mobility);
// Hors monde enregistre (commandlet), la transformation monde n'est pas recalculee d'elle-meme.
NewComp->UpdateComponentToWorld();
OldComp->UpdateComponentToWorld();
Sky->SetActorLabel(Fog->GetActorLabel());
Sky->SetFolderPath(Fog->GetFolderPath());
for (TFieldIterator<FProperty> It(USkyAtmosphereComponent::StaticClass(), EFieldIteratorFlags::ExcludeSuper); It; ++It)
{
const FString A = ExportProp(*It, OldComp);
const FString B = ExportProp(*It, NewComp);
if (A != B)
{
++Mismatches;
UE_LOG(LogLPConvertAtmo, Error, TEXT(" ECART %s : %s / %s"), *It->GetName(), *A, *B);
}
}
if (!NewComp->GetRelativeTransform().Equals(OldComp->GetRelativeTransform())
|| !NewComp->GetComponentTransform().Equals(OldComp->GetComponentTransform()))
{
++Mismatches;
UE_LOG(LogLPConvertAtmo, Error, TEXT(" ECART transformation : %s / %s"), *OldComp->GetComponentTransform().ToString(), *NewComp->GetComponentTransform().ToString());
}
UE_LOG(LogLPConvertAtmo, Warning, TEXT(" -> %s : %d propriete(s) copiee(s) et verifiee(s)"), *Sky->GetName(), Copied);
World->DestroyActor(Fog);
++Converted;
}
PRAGMA_ENABLE_DEPRECATION_WARNINGS
int32 Result = 0;
if (!bDryRun && Converted > 0 && Mismatches == 0)
{
UPackage* Package = World->GetOutermost();
const FString Filename = FPackageName::LongPackageNameToFilename(Package->GetName(), FPackageName::GetMapPackageExtension());
FSavePackageArgs SaveArgs;
SaveArgs.TopLevelFlags = RF_Standalone;
SaveArgs.Error = GWarn;
if (!UPackage::SavePackage(Package, World, *Filename, SaveArgs))
{
UE_LOG(LogLPConvertAtmo, Error, TEXT(" ECHEC de sauvegarde de %s"), *Filename);
Result = 1;
}
else
{
UE_LOG(LogLPConvertAtmo, Warning, TEXT(" -> %s sauvegardee"), *Filename);
}
}
else if (Mismatches > 0)
{
UE_LOG(LogLPConvertAtmo, Error, TEXT(" %d ecart(s) : carte NON sauvegardee"), Mismatches);
Result = 1;
}
UE_LOG(LogLPConvertAtmo, Warning, TEXT("=== Termine : %d AtmosphericFog trouve(s), %d converti(s), %d ecart(s) ==="), Fogs.Num(), Converted, Mismatches);
World->RemoveFromRoot();
return Result;
}