// Portage UE 5.5 - lots H1 et H2 (Docs/Migration/11_Audit_Optimisation.md §16.7 et §16.9). // // La liste des coiffures du jeu est la valeur par defaut de GI.HairstyleTable (126 entrees ecrites dans le Blueprint), // avec GI.MorphableHairs (morph d'ajustement par coiffure) : un mod ne pouvait pas y toucher. Ce sous-systeme lit les // fichiers texte Modules//**/*.lphair. Un fichier peut decrire plusieurs coiffures : chaque ligne HAIRSTYLE // ouvre une entree, les lignes suivantes la completent. // // HAIRSTYLE: /Game/Heavy/New5/Hairs/Exemple.Exemple chemin complet d'un SkeletalMesh (squelette Genesis 8), // ou NONE (option "sans cheveux") // SEX: F F ou M (defaut F) // DAZ: true defaut true ; false = coiffure "legacy", chargee seulement // si GI.LegacyPercentage > 0 // FIT_MORPH: Exemple__AllExpand 0.45 facultatif : morph applique par Person.FitMorphableHair // MORPHABLE: Cle [Morph Valeur] entree brute de GI.MorphableHairs (fichier de base) // MODE: BASE fichier de base (H2) : la table est reconstruite a partir de // ce fichier, dans son ordre, avant l'ajout des autres modules // // Pilosite (textures appliquees a la peau par Person.setBHairstyle, lot H2b) : listes de noms de textures, dans le // dossier impose par le Blueprint (prefixe + nom) : // FACIAL_HAIR: Facial_Hair__1_ GI.FHairstyles (barbe ; /Game/Heavy/Daz/Michael/hairs/other/) // BODY_HAIR_M: JPBH78-TorsoNG-01 GI.BHairstyles_M (torse masculin ; meme dossier) // BODY_HAIR_F: Pubes01 GI.BHairstyles (pubis feminin ; /Game/Heavy/Daz/Bridget/Hairs/Pubic/) // Le fichier de base reconstruit chaque liste qu'il decrit ; les autres modules y ajoutent des noms (texture verifiee). // // Sans fichier de base, les coiffures sont ajoutees en fin de la table du Blueprint (H1). Les coiffures des modules // sont controlees (SkeletalMesh present, pas de doublon) ; celles du fichier de base sont reprises telles quelles, // comme dans le Blueprint (35 coiffures "legacy" absentes du projet depuis 4.27 y figurent). // Les modules desactives dans GI.ModEnableds sont ignores ; la table est reconstruite quand cette liste change. // Option -LPVerifyHairstyles : la table et les morphs construits depuis le fichier de base sont compares a ceux du // Blueprint (texte exporte), avant l'ajout des modules. #pragma once #include "CoreMinimal.h" #include "Containers/Ticker.h" #include "Subsystems/GameInstanceSubsystem.h" #include "LPHairstyleSubsystem.generated.h" UCLASS() class LIFEPLAY_API ULPHairstyleSubsystem : public UGameInstanceSubsystem { GENERATED_BODY() public: virtual void Initialize(FSubsystemCollectionBase& Collection) override; virtual void Deinitialize() override; private: struct FHairDef { FString File; FString Module; FString Path; bool bNone = false; bool bMale = false; bool bDaz = true; FString FitMorph; FString FitValue; }; struct FTextureDef { int32 List = 0; FString Name; FString File; FString Module; }; struct FMorphDef { FString Key; FString Morph; FString Value; }; bool Tick(float DeltaTime); /** Releve des fichiers .lphair (une fois : les fichiers de Modules ne changent pas en cours de partie). */ void ScanFiles(); void ParseFile(const FString& Relative, const FString& Module, const FString& Text); /** Reconstruit la table : base (fichier MODE: BASE ou Blueprint) puis coiffures des modules actifs. */ void Sync(); /** Listes de pilosite : base (fichier ou Blueprint) puis noms des modules actifs. */ void SyncTextureLists(UObject* GI); FString EnabledSignature() const; bool IsModuleEnabled(const FString& Module) const; FTSTicker::FDelegateHandle TickHandle; double NextCheck = 0.0; FString LastSignature; /** Coiffures et morphs du fichier de base, dans l'ordre. */ FString BaseFile; TArray BaseDefs; TArray BaseMorphs; /** Coiffures des autres fichiers. */ TArray Defs; /** Noms de textures de pilosite : fichier de base et autres fichiers ; listes du Blueprint (texte exporte). */ TArray BaseTextures; TArray Textures; TArray BlueprintListTexts; /** Table et morphs du Blueprint, captures au premier passage (texte exporte, pour revenir a la base sans fichier). */ FString BlueprintTableText; FString BlueprintMorphsText; bool bCaptured = false; };