From 5a2829ebd99f22e0acaeeb101abfaedba5f54142 Mon Sep 17 00:00:00 2001 From: edujiro5972 <336072401+edujiro5972@users.noreply.github.com> Date: Sat, 3 Oct 2026 10:14:37 +0200 Subject: [PATCH] H3d : metadonnees des mods, avertissement de version, paquet lpr_hair_pocolov (12 coiffures) - LPModInfoSubsystem : metadonnees des .lpmod ; fenetre d'avertissement quand un mod actif a ete construit pour une autre version du jeu (Slate, sans Blueprint). - NewMod/BuildMod : MODULE_VERSION, _CREATED, _LICENSE, _AUTHOR_LINK, _PRICE, _PACKAGED, _GAME_VERSION ; ordre des 3 premieres lignes controle ; prix et licences controles. - lpr_hair_pocolov 1.0 : les 12 coiffures Pocolov CC BY ; lp_Revival et les 6 Pocolov retires du jeu de base ; mod d'essai LPHairSample retire. Valide en jeu le 2026-10-03 (CHG-106, CHG-107). Co-Authored-By: Claude Opus 5.5 --- Docs/Migration/09_Commandes_Utiles.md | 3 +- Docs/Migration/16_H3_Mods_Paquets.md | 29 ++ Docs/Migration/Journal_Modifications.md | 2 + Docs/Migration/README.md | 2 +- .../Modding/FullGuides/Creating_Asset_Mods.md | 21 +- Docs/Modding/ShortGuides/explanation.lpmod | 6 +- Licenses/Free_3D_Models_Credits.txt | 7 +- ModSources/LPHairSample/LPHairSample.uplugin | 12 - ModSources/LPHairSample/Module/CREDITS.txt | 1 - .../LPHairSample/Module/LPHairSample.lpmod | 6 - .../lpr_hair_pocolov/Module/CREDITS.txt | 13 + .../Module/Hairstyles/pocolov03.lphair | 6 + .../Module/Hairstyles/pocolov05.lphair | 2 +- .../Module/Hairstyles/pocolov06.lphair | 6 + .../Module/Hairstyles/pocolov07.lphair | 6 + .../Module/Hairstyles/pocolov09.lphair | 6 + .../Module/Hairstyles/pocolov10.lphair | 6 + .../Module/Hairstyles/pocolov11.lphair | 6 + .../Module/Hairstyles/pocolov13.lphair | 6 + .../Module/Hairstyles/pocolov14.lphair | 6 + .../Module/Hairstyles/pocolov15.lphair | 6 + .../Module/Hairstyles/pocolov16.lphair | 6 + .../Module/Hairstyles/pocolov17.lphair | 6 + .../Module/lpr_hair_pocolov.lpmod | 12 + .../lpr_hair_pocolov/lpr_hair_pocolov.uplugin | 13 + Source/LifePlay/LPModInfoSubsystem.cpp | 202 ++++++++++++ Source/LifePlay/LPModInfoSubsystem.h | 48 +++ Source/LifePlay/LifePlay.Build.cs | 4 + Tools/BuildMod.ps1 | 40 ++- Tools/EditMod.ps1 | 2 +- Tools/NewMod.ps1 | 19 +- Tools/mods/LPHairSample.json | 32 -- Tools/mods/lpr_hair_pocolov.json | 296 ++++++++++++++++++ Tools/modules/next.json | 5 + 34 files changed, 769 insertions(+), 74 deletions(-) delete mode 100644 ModSources/LPHairSample/LPHairSample.uplugin delete mode 100644 ModSources/LPHairSample/Module/CREDITS.txt delete mode 100644 ModSources/LPHairSample/Module/LPHairSample.lpmod create mode 100644 ModSources/lpr_hair_pocolov/Module/CREDITS.txt create mode 100644 ModSources/lpr_hair_pocolov/Module/Hairstyles/pocolov03.lphair rename ModSources/{LPHairSample => lpr_hair_pocolov}/Module/Hairstyles/pocolov05.lphair (85%) create mode 100644 ModSources/lpr_hair_pocolov/Module/Hairstyles/pocolov06.lphair create mode 100644 ModSources/lpr_hair_pocolov/Module/Hairstyles/pocolov07.lphair create mode 100644 ModSources/lpr_hair_pocolov/Module/Hairstyles/pocolov09.lphair create mode 100644 ModSources/lpr_hair_pocolov/Module/Hairstyles/pocolov10.lphair create mode 100644 ModSources/lpr_hair_pocolov/Module/Hairstyles/pocolov11.lphair create mode 100644 ModSources/lpr_hair_pocolov/Module/Hairstyles/pocolov13.lphair create mode 100644 ModSources/lpr_hair_pocolov/Module/Hairstyles/pocolov14.lphair create mode 100644 ModSources/lpr_hair_pocolov/Module/Hairstyles/pocolov15.lphair create mode 100644 ModSources/lpr_hair_pocolov/Module/Hairstyles/pocolov16.lphair create mode 100644 ModSources/lpr_hair_pocolov/Module/Hairstyles/pocolov17.lphair create mode 100644 ModSources/lpr_hair_pocolov/Module/lpr_hair_pocolov.lpmod create mode 100644 ModSources/lpr_hair_pocolov/lpr_hair_pocolov.uplugin create mode 100644 Source/LifePlay/LPModInfoSubsystem.cpp create mode 100644 Source/LifePlay/LPModInfoSubsystem.h delete mode 100644 Tools/mods/LPHairSample.json create mode 100644 Tools/mods/lpr_hair_pocolov.json create mode 100644 Tools/modules/next.json diff --git a/Docs/Migration/09_Commandes_Utiles.md b/Docs/Migration/09_Commandes_Utiles.md index 6efcc55..dc54df2 100644 --- a/Docs/Migration/09_Commandes_Utiles.md +++ b/Docs/Migration/09_Commandes_Utiles.md @@ -155,6 +155,7 @@ cmd /c '"\Build\BatchFiles\RunUAT.bat" BuildCookRun -project="\LifeP Get-FileHash Releases\\Windows\LifePlay-Windows.utoc, \Windows\LifePlay\Content\Paks\LifePlay-Windows.utoc # 5. Releases\ ne garde que la version publiée (les précédentes vers LifePlay_Backup_5.5\Releases) : l'archive des # sources la contient (≈ 1,3 Go) ; exclure aussi les produits de cuisson des mods : -x!ModSources\*\Saved -# 6. Mod d'essai recuit contre la nouvelle version (contrôle de la chaîne) : .\Tools\BuildMod.ps1 -Name LPHairSample +# 6. Mods officiels recuits contre la nouvelle version : .\Tools\BuildMod.ps1 -Name lpr_hair_pocolov +# Modules livrés à part : Tools\modules\next.json (essentiels : vin_Base, vin_VanillaRealistic ; lp_Revival retiré en H3d) # 7. README : section de la version avec le lien vers Docs/Modding/FullGuides/Creating_Asset_Mods.md ``` diff --git a/Docs/Migration/16_H3_Mods_Paquets.md b/Docs/Migration/16_H3_Mods_Paquets.md index b3328b1..a98c54b 100644 --- a/Docs/Migration/16_H3_Mods_Paquets.md +++ b/Docs/Migration/16_H3_Mods_Paquets.md @@ -166,3 +166,32 @@ Corrections du lot : sont donc possibles pour les moddeurs à partir de la publication suivante (la V1.4 reste jouable avec des mods cuits ici contre `Releases/2026.10.4`). - Ne pas faire de build complet destiné à la publication sans recréer la version de référence correspondante. + +## 8. Métadonnées, avertissement de version et paquet Pocolov (H3d, 2026-10-03) + +Validé en jeu le 2026-10-03 (build `LifePlay_Build_5.5_H3d`). + +- **Lecture des `.lpmod` par le jeu** (vérifiée dans `GI`) : seules les lignes 1 à 3 sont lues, **par position** + (`MODULE_UNIQUEID`, `MODULE_NAME`, `MODULE_AUTHOR`) ; le gestionnaire de mods affiche le fichier entier + (`ModuleTick.FullString`). Toute ligne ajoutée après la troisième est donc sans risque et visible des joueurs. +- **Clés ajoutées** : `MODULE_VERSION`, `MODULE_CREATED`, `MODULE_LICENSE`, `MODULE_AUTHOR_LINK`, `MODULE_PRICE` + (écrites par `Tools/NewMod.ps1`), `MODULE_PACKAGED`, `MODULE_GAME_VERSION` (écrites par `Tools/BuildMod.ps1` dans la + copie livrée). `BuildMod.ps1` contrôle l'ordre des trois premières lignes, reporte la version et le lien de l'auteur + dans le `.uplugin` livré (`VersionName`, `CreatedByURL`), nomme l'archive `--for-LifePlay-.zip` + et refuse un mod payant dont `CREDITS.txt` cite une licence non commerciale ou de magasin. +- **Avertissement** : `ULPModInfoSubsystem` (C++, `Source/LifePlay`) lit les `.lpmod` et, toutes les 2 s, compare le + `MODULE_GAME_VERSION` des modules **actifs** à `ProjectVersion` ; un écart ouvre une fenêtre Slate « Mod version + warning » (indépendante des Blueprints, aussi sur l'écran titre), une fois par module et par session. Testé avec un + module texte déclaré pour 2026.9.1 (déplacé ensuite vers `LifePlay_Backup_5.5\H3d`). Métadonnées accessibles aux + Blueprints : `GetModuleMetadata(Module, Key)`. +- **Paquet `lpr_hair_pocolov` 1.0** : sur 192 produits Pocolov (Fab), les 12 coiffures CC BY (03, 05, 06, 07, 09, 10, + 11, 13, 14, 15, 16, 17) ; exclus : 5 coiffures payantes (licence standard Fab : redistribution interdite), vêtements + « Avatall » (autre squelette), objets, armes, véhicules. Configuration `Tools/mods/lpr_hair_pocolov.json` (réglages + HAIRS1 repris ; détection identique aux choix validés). Pocolov 07, 09, 10, 13, 14 téléchargées (CC BY 4.0, accord du + 2026-10-03). La Pocolov 09 a sa calotte en maillage séparé, non convertie : rendu jugé correct en jeu. + `MODULE_DEFAULT_ENABLED: true` (les sauvegardes qui utilisaient les anciennes coiffures du jeu les retrouvent dès que + le paquet est installé). Archive `lpr_hair_pocolov-1.0-for-LifePlay-2026.10.4.zip` (3,8 Mo, 70 paquets cuits). +- **Jeu de base allégé** : les 6 Pocolov de `/Game/Heavy/New5/Hairs` et le module `lp_Revival` sont retirés du jeu + (déplacés vers `LifePlay_Backup_5.5\H3d\retires`), leurs crédits passent dans le `CREDITS.txt` du paquet ; le mod + d'essai `LPHairSample` est retiré (même dossier). Modules essentiels de la prochaine publication : + `Tools/modules/next.json`. diff --git a/Docs/Migration/Journal_Modifications.md b/Docs/Migration/Journal_Modifications.md index f7fff6a..ba16dc6 100644 --- a/Docs/Migration/Journal_Modifications.md +++ b/Docs/Migration/Journal_Modifications.md @@ -950,3 +950,5 @@ Validation L7c/L7d (2026-10-02, parc, même cadrage) : la nuit reste claire (sol | CHG-103 | 2026-10-03 | UI15 | `Content/UI/MainMenu.uasset`, `Content/UI/ModManager.uasset` (snapshot `LifePlay_Backup_5.5\UI15`) ; nouveaux `Source/LifePlayEditorTools/LPTitleModManagerCommandlet.h/.cpp`, `Source/LifePlay/LPModSettingsLibrary.h/.cpp`, `Docs/Migration/17_Mods_Ecran_Titre.md` ; build `LifePlay_Build_5.5_UI15b` | demande utilisateur : gestionnaire de mods dès l'écran titre, puis choix entre nouvelle partie et partie sauvegardée. Entrée dédiée sur l'écran titre (copie de « Load »), fermeture vers le menu titre avec relecture des données et enregistrement du choix (`SaveModSelection`, sans toucher à la dernière sauvegarde) ; entrée d'origine inchangée en partie. Première version (entrée d'origine rendue visible) remplacée après retour (alignement). **Validé en jeu le 2026-10-03** | `.\Tools\Restore.ps1 -Lot UI15` ; `git revert` du commit | | CHG-104 | 2026-10-03 | H3b | nouveaux `Tools/BuildMod.ps1`, `Tools/ModSource.ps1` ; `Tools/HairPipeline.ps1` (mode `mod` : montage temporaire, `.lphair` et crédits dans `ModSources//Module`, `-Rebuild` déplace aussi les textures) ; `Tools/HairMaterials.py` (analyse synchrone du dossier, réutilisation des textures) ; `Tools/mods/LPHairSample.json` (`mod`) ; `Source/LifePlay/LPHairstyleSubsystem.cpp` (repli `DoesPackageExist`) ; Pocolov 05 reconstruite (précédente dans `LifePlay_Backup_5.5\H3a\Pocolov05\precedente_*`) ; build `LifePlay_Build_5.5_H3b` ; archive `D:\Game\LifePlay_Publication\Mods\LPHairSample-for-LifePlay-2026.10.4.zip` (334 473 octets, SHA-256 `8F6A45ED…CBC8`) | lot H3b : un mod d'assets en une commande ; plantage de `HairMaterials.py` dans un plugin expliqué (registre de la commandlet sans les assets du plugin) et corrigé ; build de base sans rien du mod par construction. **Validé en jeu le 2026-10-03** (16_H3_Mods_Paquets.md §6) | `git revert` du commit, recompiler | | CHG-105 | 2026-10-03 | H3c | nouveaux `Docs/Modding/FullGuides/Creating_Asset_Mods.md`, `Docs/Modding/ShortGuides/explanation.lphair`, `Tools/NewMod.ps1`, `Tools/EditMod.ps1` ; `Docs/Modding/ShortGuides/explanation.lpmod` (`MODULE_DEFAULT_ENABLED`) ; `Docs/Migration/10_Protocole_Operations.md` §6, `09_Commandes_Utiles.md` §7 (liste de contrôle de publication), `16_H3_Mods_Paquets.md` §7 | lot H3c : guide des moddeurs en anglais, outils de création et d'édition d'un mod, version de référence intégrée à la procédure de publication (livrée dans l'archive des sources ; `Mods/` vide au build) | `git revert` du commit | +| CHG-106 | 2026-10-03 | H3d | nouveaux `Source/LifePlay/LPModInfoSubsystem.h/.cpp` ; `Source/LifePlay/LifePlay.Build.cs` (`Slate`, `SlateCore`) ; `Tools/NewMod.ps1` (métadonnées), `Tools/BuildMod.ps1` (ordre des lignes 1 à 3, `MODULE_PACKAGED`, `MODULE_GAME_VERSION`, `.uplugin` livré, contrôle prix et licences, nom d'archive) ; `Docs/Modding/FullGuides/Creating_Asset_Mods.md` §4b, `explanation.lpmod` | demande utilisateur : métadonnées extensibles (dates, licence, lien de l'auteur, prix) et avertissement en jeu quand un mod a été construit pour une autre version. Le jeu ne lit que les 3 premières lignes d'un `.lpmod`, par position ; fenêtre Slate C++, sans Blueprint. **Validé en jeu le 2026-10-03** | `git revert` du commit, recompiler | +| CHG-107 | 2026-10-03 | H3d | nouveau mod `ModSources/lpr_hair_pocolov` (`.uplugin`, `Module/` : `.lpmod`, 12 `.lphair`, `CREDITS.txt` ; assets non versionnés), `Tools/mods/lpr_hair_pocolov.json` ; retirés : `Content/Modules/lp_Revival` (6 `.lphair`, `.lpmod`), assets `Content/Heavy/New5/Hairs/Pocolov*` (non versionnés), `ModSources/LPHairSample`, `Tools/mods/LPHairSample.json` (tous vers `LifePlay_Backup_5.5\H3d\retires`) ; `Licenses/Free_3D_Models_Credits.txt` (lignes Pocolov remplacées par un renvoi ; snapshot `H3d`) ; nouveau `Tools/modules/next.json` ; builds `LifePlay_Build_5.5_H3d` ; archive `D:\Game\LifePlay_Publication\Mods\lpr_hair_pocolov-1.0-for-LifePlay-2026.10.4.zip` (3 807 460 octets, SHA-256 `4E9420E5…2B8F`) | demande utilisateur : module `lpr_hair_pocolov` regroupant les assets Pocolov ; choix utilisateur : les 12 coiffures CC BY, les 6 du jeu de base déplacées dans le paquet, mod d'essai retiré ; 5 archives téléchargées (accord). **Validé en jeu le 2026-10-03** | remettre les dossiers de `LifePlay_Backup_5.5\H3d\retires` ; `.\Tools\Restore.ps1 -Lot H3d` ; `git revert` du commit | diff --git a/Docs/Migration/README.md b/Docs/Migration/README.md index a43b8ee..11968c0 100644 --- a/Docs/Migration/README.md +++ b/Docs/Migration/README.md @@ -26,7 +26,7 @@ La migration a été reprise le 2026-09-29, après l'échec d'un premier portage | [13_Protocole_Coiffure.md](13_Protocole_Coiffure.md) | protocole | ajouter une coiffure (FBX statique, Fab) : import, ajustement sur la tête de Bridget, matériaux, fichier `.lphair`, contrôles | | [14_Interface_V1.4.md](14_Interface_V1.4.md) | lot | menu principal : version année.mois.publication, crédits (Vinfamy, auteur original), liens Donate et Discord, bouton Commission masqué | | [15_Modules_Optionnels.md](15_Modules_Optionnels.md) | lot | build Shipping réduite aux modules essentiels, modules optionnels dans une archive séparée (`Tools/SplitModules.ps1`) | -| [16_H3_Mods_Paquets.md](16_H3_Mods_Paquets.md) | étude, prototype | H3 : assets apportés par les mods (plugins `Mods/`, cuisson DLC contre la version publiée) ; constats, architecture, risques, lots H3a à H3c ; §5 résultats du prototype H3a, §6 outillage H3b (`ModSources/`, `Tools/BuildMod.ps1`), validés ; §7 guide des moddeurs (`Docs/Modding/FullGuides/Creating_Asset_Mods.md`) et publication | +| [16_H3_Mods_Paquets.md](16_H3_Mods_Paquets.md) | étude, prototype | H3 : assets apportés par les mods (plugins `Mods/`, cuisson DLC contre la version publiée) ; constats, architecture, risques, lots H3a à H3c ; §5 résultats du prototype H3a, §6 outillage H3b (`ModSources/`, `Tools/BuildMod.ps1`), validés ; §7 guide des moddeurs (`Docs/Modding/FullGuides/Creating_Asset_Mods.md`) et publication ; §8 métadonnées, avertissement de version, paquet `lpr_hair_pocolov` (H3d) | | [17_Mods_Ecran_Titre.md](17_Mods_Ecran_Titre.md) | lot | UI15 : gestionnaire de mods depuis l'écran titre (entrée dédiée, retour au menu titre, choix enregistré) | | [Journal_Modifications.md](Journal_Modifications.md) | traçabilité | `CHG-001` à `CHG-057`, chacune avec son retour arrière | | [Registre_Erreurs.md](Registre_Erreurs.md) | traçabilité | `ERR-001` à `ERR-037`, statut et lot | diff --git a/Docs/Modding/FullGuides/Creating_Asset_Mods.md b/Docs/Modding/FullGuides/Creating_Asset_Mods.md index 86ab4ab..94445eb 100644 --- a/Docs/Modding/FullGuides/Creating_Asset_Mods.md +++ b/Docs/Modding/FullGuides/Creating_Asset_Mods.md @@ -68,8 +68,8 @@ it fits the hair to the default head, transfers skin weights from the body (head the character without cutting through the skin, and creates `DazHair` material instances. 1. Download the hairstyle archives (zip/rar/7z with an FBX and its textures). -2. Add one entry per hairstyle in `Tools/mods/MyHairPack.json` (see `Tools/mods/LPHairSample.json` for a complete - example): +2. Add one entry per hairstyle in `Tools/mods/MyHairPack.json` (see `Tools/mods/lpr_hair_pocolov.json`, the 12 Pocolov + hairstyles, for a complete example): ```json { @@ -109,6 +109,23 @@ SEX: F DAZ: true ``` +## 4b. Mod metadata + +The first three lines of `.lpmod` are read **by position** by the game and must stay first, in this order: +`MODULE_UNIQUEID`, `MODULE_NAME`, `MODULE_AUTHOR`. The other lines are free; the Mod Manager shows the whole file in its +detail panel, so every line below is visible to players. + +| Key | Written by | Meaning | +|---|---|---| +| `MODULE_VERSION` | you (`NewMod.ps1 -ModVersion`, default 1.0) | version of the mod; also in the archive name and the plugin `VersionName` | +| `MODULE_CREATED` | `NewMod.ps1` | creation date (YYYY-MM-DD) | +| `MODULE_LICENSE` | you (`-License`) | license of the mod as a whole (each asset's license stays in `CREDITS.txt`) | +| `MODULE_AUTHOR_LINK` | you (`-AuthorLink`) | author page; also the plugin `CreatedByURL` | +| `MODULE_PRICE` | you (`-Price`, default Free) | information only, the game sells nothing. A non-free mod is refused by `BuildMod.ps1` if `CREDITS.txt` mentions a non-commercial or store license (`NC`, `Standard License`, `Personal`) | +| `MODULE_DEFAULT_ENABLED` | you | `true`: enabled the first time the game finds it; otherwise a new mod starts disabled | +| `MODULE_PACKAGED` | `BuildMod.ps1` (shipped copy only) | packaging date | +| `MODULE_GAME_VERSION` | `BuildMod.ps1` (shipped copy only) | game version the assets were cooked for. If an **enabled** mod declares another version than the game, the game shows a "Mod version warning" window (once per session) | + ## 5. Edit the mod in the editor ```powershell diff --git a/Docs/Modding/ShortGuides/explanation.lpmod b/Docs/Modding/ShortGuides/explanation.lpmod index 60ea3d3..adc7d2f 100644 --- a/Docs/Modding/ShortGuides/explanation.lpmod +++ b/Docs/Modding/ShortGuides/explanation.lpmod @@ -11,4 +11,8 @@ MODULE_LINK: www.loverslab.com MODULE_DESCRIPTION: Netorare, cuckoldry, being cheated on - aka the most divisive fetish on the internet MODULE_REQUIREMENTS: vin_VanillaRealistic // unique IDs of the prerequisite mods, without all these mods enabled, this mod cannot be enabled. LifePlay Revival addition: -MODULE_DEFAULT_ENABLED: true // optional: the mod is enabled the first time the game finds it (otherwise a new mod starts disabled until the player ticks it in the Mod Manager). Used by lp_Revival, shipped with the game. +MODULE_DEFAULT_ENABLED: true // optional: the mod is enabled the first time the game finds it (otherwise a new mod starts disabled until the player ticks it in the Mod Manager). Used by lpr_hair_pocolov. +The first three lines (MODULE_UNIQUEID, MODULE_NAME, MODULE_AUTHOR) are read by position: keep them first, in this order. +Other optional keys, shown as-is in the Mod Manager: MODULE_VERSION, MODULE_CREATED, MODULE_LICENSE, MODULE_AUTHOR_LINK, MODULE_PRICE, +MODULE_PACKAGED and MODULE_GAME_VERSION (written by Tools/BuildMod.ps1; the game warns when an enabled mod was built for another +game version). See Docs/Modding/FullGuides/Creating_Asset_Mods.md, section 4b. diff --git a/Licenses/Free_3D_Models_Credits.txt b/Licenses/Free_3D_Models_Credits.txt index a5665c4..207068a 100644 --- a/Licenses/Free_3D_Models_Credits.txt +++ b/Licenses/Free_3D_Models_Credits.txt @@ -26,9 +26,4 @@ In no particular order, these are the authors of the original (most have been he - Joel Palmius LifePlay Revival (UE 5.5) additions: -- Pocolov Hair 17 by Pocolov (Pocolov Studio 2019, artist Thang), Creative Commons Attribution 4.0 (CC BY 4.0), https://www.fab.com/listings/7f6f687d-bb13-40c6-8b69-64044ededc1d . Changes: skinned to the Genesis 8 skeleton by weight transfer from the body (head, neck, chest), fitted to the Bridget head, DazHair materials (Content/Heavy/New5/Hairs/Pocolov17*, declared by Content/Modules/lp_Revival/Hairstyles/pocolov17.lphair). -- Pocolov Hair 03 by Pocolov (Pocolov Studio, artist Thang), CC BY 4.0, https://www.fab.com/listings/2257098d-b77c-4eef-9132-85f1454f0ae3 . Changes: skinned to the Genesis 8 skeleton by weight transfer from the body (head, neck, chest), fitted to the Bridget head, DazHair materials (/Game/Heavy/New5/Hairs/Pocolov03*). -- Pocolov Hair 06 by Pocolov (Pocolov Studio, artist Thang), CC BY 4.0, https://www.fab.com/listings/14c3cd52-02f9-4bfe-bb40-b5c3acb1f428 . Changes: skinned to the Genesis 8 skeleton by weight transfer from the body (head, neck, chest), fitted to the Bridget head, DazHair materials (/Game/Heavy/New5/Hairs/Pocolov06*). -- Pocolov Hair 11 by Pocolov (Pocolov Studio, artist Thang), CC BY 4.0, https://www.fab.com/listings/c31c219e-bc62-4957-91c5-720440375f79 . Changes: skinned to the Genesis 8 skeleton by weight transfer from the body (head, neck, chest), fitted to the Bridget head, DazHair materials (/Game/Heavy/New5/Hairs/Pocolov11*). -- Pocolov Hair 15 by Pocolov (Pocolov Studio, artist Thang), CC BY 4.0, https://www.fab.com/listings/ed8e016a-0bf0-4a6c-94b0-2760083b879d . Changes: skinned to the Genesis 8 skeleton by weight transfer from the body (head, neck, chest), fitted to the Bridget head, DazHair materials (/Game/Heavy/New5/Hairs/Pocolov15*). -- Pocolov Hair 16 by Pocolov (Pocolov Studio, artist Thang), CC BY 4.0, https://www.fab.com/listings/802dc956-6211-4b83-8ba1-37beb3cb338f . Changes: skinned to the Genesis 8 skeleton by weight transfer from the body (head, neck, chest), fitted to the Bridget head, DazHair materials (/Game/Heavy/New5/Hairs/Pocolov16*). +- The Pocolov hairstyles (Pocolov Studio, artist Thang, CC BY 4.0) are no longer part of the game: they are in the optional mod lpr_hair_pocolov, credited in its CREDITS.txt (ModSources/lpr_hair_pocolov/Module/CREDITS.txt in the source archive, Content/Modules/lpr_hair_pocolov/CREDITS.txt once installed). diff --git a/ModSources/LPHairSample/LPHairSample.uplugin b/ModSources/LPHairSample/LPHairSample.uplugin deleted file mode 100644 index 0f345ed..0000000 --- a/ModSources/LPHairSample/LPHairSample.uplugin +++ /dev/null @@ -1,12 +0,0 @@ -{ - "FileVersion": 3, - "Version": 1, - "VersionName": "1.0", - "FriendlyName": "LifePlay Hair Sample", - "Description": "Sample LifePlay mod: one hairstyle (Pocolov Hair 05, CC BY 4.0) cooked as a separate package.", - "Category": "LifePlay Mods", - "CreatedBy": "LifePlay Revival", - "CanContainContent": true, - "IsBetaVersion": false, - "Installed": false -} diff --git a/ModSources/LPHairSample/Module/CREDITS.txt b/ModSources/LPHairSample/Module/CREDITS.txt deleted file mode 100644 index d4ab565..0000000 --- a/ModSources/LPHairSample/Module/CREDITS.txt +++ /dev/null @@ -1 +0,0 @@ -- Pocolov Hair 05 by Pocolov (Pocolov Studio, artist Thang), CC BY 4.0, https://www.fab.com/listings/4025749f-d597-4332-91aa-16e355b94974 . Changes: skinned to the Genesis 8 skeleton by weight transfer from the body (head, neck, chest), fitted to the Bridget head, DazHair materials (/LPHairSample/Hairs/Pocolov05*). diff --git a/ModSources/LPHairSample/Module/LPHairSample.lpmod b/ModSources/LPHairSample/Module/LPHairSample.lpmod deleted file mode 100644 index 4092b48..0000000 --- a/ModSources/LPHairSample/Module/LPHairSample.lpmod +++ /dev/null @@ -1,6 +0,0 @@ -MODULE_UNIQUEID: LPHairSample -MODULE_NAME: LifePlay Hair Sample -MODULE_AUTHOR: LifePlay Revival -MODULE_LINK: https://github.com/edujiro5972/LifePlay-Revival -MODULE_DESCRIPTION: Sample mod: one hairstyle (Pocolov Hair 05, CC BY 4.0) shipped as a cooked package in Mods/LPHairSample. Disabling this module removes the hairstyle from the game list. -MODULE_REQUIREMENTS: vin_Base diff --git a/ModSources/lpr_hair_pocolov/Module/CREDITS.txt b/ModSources/lpr_hair_pocolov/Module/CREDITS.txt new file mode 100644 index 0000000..70ac928 --- /dev/null +++ b/ModSources/lpr_hair_pocolov/Module/CREDITS.txt @@ -0,0 +1,13 @@ +Credits and licenses of the assets in Pocolov Hairstyles (one line per asset: title, author, license, source URL, changes). +- Pocolov Hair 03 by Pocolov (Pocolov Studio, artist Thang), CC BY 4.0, https://www.fab.com/listings/2257098d-b77c-4eef-9132-85f1454f0ae3 . Changes: skinned to the Genesis 8 skeleton by weight transfer from the body (head, neck, chest), fitted to the Bridget head, DazHair materials (/lpr_hair_pocolov/Hairs/Pocolov03*). +- Pocolov Hair 05 by Pocolov (Pocolov Studio, artist Thang), CC BY 4.0, https://www.fab.com/listings/4025749f-d597-4332-91aa-16e355b94974 . Changes: skinned to the Genesis 8 skeleton by weight transfer from the body (head, neck, chest), fitted to the Bridget head, DazHair materials (/lpr_hair_pocolov/Hairs/Pocolov05*). +- Pocolov Hair 06 by Pocolov (Pocolov Studio, artist Thang), CC BY 4.0, https://www.fab.com/listings/14c3cd52-02f9-4bfe-bb40-b5c3acb1f428 . Changes: skinned to the Genesis 8 skeleton by weight transfer from the body (head, neck, chest), fitted to the Bridget head, DazHair materials (/lpr_hair_pocolov/Hairs/Pocolov06*). +- Pocolov Hair 11 by Pocolov (Pocolov Studio, artist Thang), CC BY 4.0, https://www.fab.com/listings/c31c219e-bc62-4957-91c5-720440375f79 . Changes: skinned to the Genesis 8 skeleton by weight transfer from the body (head, neck, chest), fitted to the Bridget head, DazHair materials (/lpr_hair_pocolov/Hairs/Pocolov11*). +- Pocolov Hair 15 by Pocolov (Pocolov Studio, artist Thang), CC BY 4.0, https://www.fab.com/listings/ed8e016a-0bf0-4a6c-94b0-2760083b879d . Changes: skinned to the Genesis 8 skeleton by weight transfer from the body (head, neck, chest), fitted to the Bridget head, DazHair materials (/lpr_hair_pocolov/Hairs/Pocolov15*). +- Pocolov Hair 16 by Pocolov (Pocolov Studio, artist Thang), CC BY 4.0, https://www.fab.com/listings/802dc956-6211-4b83-8ba1-37beb3cb338f . Changes: skinned to the Genesis 8 skeleton by weight transfer from the body (head, neck, chest), fitted to the Bridget head, DazHair materials (/lpr_hair_pocolov/Hairs/Pocolov16*). +- Pocolov Hair 17 by Pocolov (Pocolov Studio 2019, artist Thang), CC BY 4.0, https://www.fab.com/listings/7f6f687d-bb13-40c6-8b69-64044ededc1d . Changes: skinned to the Genesis 8 skeleton by weight transfer from the body (head, neck, chest), fitted to the Bridget head, DazHair materials (/lpr_hair_pocolov/Hairs/Pocolov17*). +- Pocolov Hair 07 by Pocolov (Pocolov Studio, artist Thang), CC BY 4.0, https://www.fab.com/listings/4d1ba957-b420-4bdc-8984-b528a73b1d58 . Changes: skinned to the Genesis 8 skeleton by weight transfer from the body (head, neck, chest), fitted to the Bridget head, DazHair materials (/lpr_hair_pocolov/Hairs/Pocolov07*). +- Pocolov Hair 09 by Pocolov (Pocolov Studio, artist Thang), CC BY 4.0, https://www.fab.com/listings/80383c46-f491-4db2-a63d-48d279f35782 . Changes: skinned to the Genesis 8 skeleton by weight transfer from the body (head, neck, chest), fitted to the Bridget head, DazHair materials (/lpr_hair_pocolov/Hairs/Pocolov09*). +- Pocolov Hair 10 by Pocolov (Pocolov Studio, artist Thang), CC BY 4.0, https://www.fab.com/listings/40a91685-76dc-4384-91f1-0040f44e8958 . Changes: skinned to the Genesis 8 skeleton by weight transfer from the body (head, neck, chest), fitted to the Bridget head, DazHair materials (/lpr_hair_pocolov/Hairs/Pocolov10*). +- Pocolov Hair 13 by Pocolov (Pocolov Studio, artist Thang), CC BY 4.0, https://www.fab.com/listings/a3933681-f5e3-4d93-99f0-c5fff444d405 . Changes: skinned to the Genesis 8 skeleton by weight transfer from the body (head, neck, chest), fitted to the Bridget head, DazHair materials (/lpr_hair_pocolov/Hairs/Pocolov13*). +- Pocolov Hair 14 by Pocolov (Pocolov Studio, artist Thang), CC BY 4.0, https://www.fab.com/listings/4911f6b9-d548-45d7-86be-a6971da97c54 . Changes: skinned to the Genesis 8 skeleton by weight transfer from the body (head, neck, chest), fitted to the Bridget head, DazHair materials (/lpr_hair_pocolov/Hairs/Pocolov14*). diff --git a/ModSources/lpr_hair_pocolov/Module/Hairstyles/pocolov03.lphair b/ModSources/lpr_hair_pocolov/Module/Hairstyles/pocolov03.lphair new file mode 100644 index 0000000..e88195a --- /dev/null +++ b/ModSources/lpr_hair_pocolov/Module/Hairstyles/pocolov03.lphair @@ -0,0 +1,6 @@ +// Pocolov Hair 03 - Pocolov (Pocolov Studio, artist Thang) - licence CC BY 4.0 +// Source : https://www.fab.com/listings/2257098d-b77c-4eef-9132-85f1454f0ae3 +// Modifications (Tools/HairPipeline.ps1) : liee au squelette Genesis 8 par transfert de poids depuis le corps (tete, cou, poitrine), ajustee a la tete de Bridget, materiaux DazHair. +HAIRSTYLE: /lpr_hair_pocolov/Hairs/Pocolov03.Pocolov03 +SEX: F +DAZ: true diff --git a/ModSources/LPHairSample/Module/Hairstyles/pocolov05.lphair b/ModSources/lpr_hair_pocolov/Module/Hairstyles/pocolov05.lphair similarity index 85% rename from ModSources/LPHairSample/Module/Hairstyles/pocolov05.lphair rename to ModSources/lpr_hair_pocolov/Module/Hairstyles/pocolov05.lphair index 5bda587..b09af4a 100644 --- a/ModSources/LPHairSample/Module/Hairstyles/pocolov05.lphair +++ b/ModSources/lpr_hair_pocolov/Module/Hairstyles/pocolov05.lphair @@ -1,6 +1,6 @@ // Pocolov Hair 05 - Pocolov (Pocolov Studio, artist Thang) - licence CC BY 4.0 // Source : https://www.fab.com/listings/4025749f-d597-4332-91aa-16e355b94974 // Modifications (Tools/HairPipeline.ps1) : liee au squelette Genesis 8 par transfert de poids depuis le corps (tete, cou, poitrine), ajustee a la tete de Bridget, materiaux DazHair. -HAIRSTYLE: /LPHairSample/Hairs/Pocolov05.Pocolov05 +HAIRSTYLE: /lpr_hair_pocolov/Hairs/Pocolov05.Pocolov05 SEX: F DAZ: true diff --git a/ModSources/lpr_hair_pocolov/Module/Hairstyles/pocolov06.lphair b/ModSources/lpr_hair_pocolov/Module/Hairstyles/pocolov06.lphair new file mode 100644 index 0000000..0cd4faa --- /dev/null +++ b/ModSources/lpr_hair_pocolov/Module/Hairstyles/pocolov06.lphair @@ -0,0 +1,6 @@ +// Pocolov Hair 06 - Pocolov (Pocolov Studio, artist Thang) - licence CC BY 4.0 +// Source : https://www.fab.com/listings/14c3cd52-02f9-4bfe-bb40-b5c3acb1f428 +// Modifications (Tools/HairPipeline.ps1) : liee au squelette Genesis 8 par transfert de poids depuis le corps (tete, cou, poitrine), ajustee a la tete de Bridget, materiaux DazHair. +HAIRSTYLE: /lpr_hair_pocolov/Hairs/Pocolov06.Pocolov06 +SEX: F +DAZ: true diff --git a/ModSources/lpr_hair_pocolov/Module/Hairstyles/pocolov07.lphair b/ModSources/lpr_hair_pocolov/Module/Hairstyles/pocolov07.lphair new file mode 100644 index 0000000..ae55be6 --- /dev/null +++ b/ModSources/lpr_hair_pocolov/Module/Hairstyles/pocolov07.lphair @@ -0,0 +1,6 @@ +// Pocolov Hair 07 - Pocolov (Pocolov Studio, artist Thang) - licence CC BY 4.0 +// Source : https://www.fab.com/listings/4d1ba957-b420-4bdc-8984-b528a73b1d58 +// Modifications (Tools/HairPipeline.ps1) : liee au squelette Genesis 8 par transfert de poids depuis le corps (tete, cou, poitrine), ajustee a la tete de Bridget, materiaux DazHair. +HAIRSTYLE: /lpr_hair_pocolov/Hairs/Pocolov07.Pocolov07 +SEX: F +DAZ: true diff --git a/ModSources/lpr_hair_pocolov/Module/Hairstyles/pocolov09.lphair b/ModSources/lpr_hair_pocolov/Module/Hairstyles/pocolov09.lphair new file mode 100644 index 0000000..d19a8f2 --- /dev/null +++ b/ModSources/lpr_hair_pocolov/Module/Hairstyles/pocolov09.lphair @@ -0,0 +1,6 @@ +// Pocolov Hair 09 - Pocolov (Pocolov Studio, artist Thang) - licence CC BY 4.0 +// Source : https://www.fab.com/listings/80383c46-f491-4db2-a63d-48d279f35782 +// Modifications (Tools/HairPipeline.ps1) : liee au squelette Genesis 8 par transfert de poids depuis le corps (tete, cou, poitrine), ajustee a la tete de Bridget, materiaux DazHair. +HAIRSTYLE: /lpr_hair_pocolov/Hairs/Pocolov09.Pocolov09 +SEX: F +DAZ: true diff --git a/ModSources/lpr_hair_pocolov/Module/Hairstyles/pocolov10.lphair b/ModSources/lpr_hair_pocolov/Module/Hairstyles/pocolov10.lphair new file mode 100644 index 0000000..838d8c8 --- /dev/null +++ b/ModSources/lpr_hair_pocolov/Module/Hairstyles/pocolov10.lphair @@ -0,0 +1,6 @@ +// Pocolov Hair 10 - Pocolov (Pocolov Studio, artist Thang) - licence CC BY 4.0 +// Source : https://www.fab.com/listings/40a91685-76dc-4384-91f1-0040f44e8958 +// Modifications (Tools/HairPipeline.ps1) : liee au squelette Genesis 8 par transfert de poids depuis le corps (tete, cou, poitrine), ajustee a la tete de Bridget, materiaux DazHair. +HAIRSTYLE: /lpr_hair_pocolov/Hairs/Pocolov10.Pocolov10 +SEX: F +DAZ: true diff --git a/ModSources/lpr_hair_pocolov/Module/Hairstyles/pocolov11.lphair b/ModSources/lpr_hair_pocolov/Module/Hairstyles/pocolov11.lphair new file mode 100644 index 0000000..b44e24d --- /dev/null +++ b/ModSources/lpr_hair_pocolov/Module/Hairstyles/pocolov11.lphair @@ -0,0 +1,6 @@ +// Pocolov Hair 11 - Pocolov (Pocolov Studio, artist Thang) - licence CC BY 4.0 +// Source : https://www.fab.com/listings/c31c219e-bc62-4957-91c5-720440375f79 +// Modifications (Tools/HairPipeline.ps1) : liee au squelette Genesis 8 par transfert de poids depuis le corps (tete, cou, poitrine), ajustee a la tete de Bridget, materiaux DazHair. +HAIRSTYLE: /lpr_hair_pocolov/Hairs/Pocolov11.Pocolov11 +SEX: F +DAZ: true diff --git a/ModSources/lpr_hair_pocolov/Module/Hairstyles/pocolov13.lphair b/ModSources/lpr_hair_pocolov/Module/Hairstyles/pocolov13.lphair new file mode 100644 index 0000000..b7cc1b5 --- /dev/null +++ b/ModSources/lpr_hair_pocolov/Module/Hairstyles/pocolov13.lphair @@ -0,0 +1,6 @@ +// Pocolov Hair 13 - Pocolov (Pocolov Studio, artist Thang) - licence CC BY 4.0 +// Source : https://www.fab.com/listings/a3933681-f5e3-4d93-99f0-c5fff444d405 +// Modifications (Tools/HairPipeline.ps1) : liee au squelette Genesis 8 par transfert de poids depuis le corps (tete, cou, poitrine), ajustee a la tete de Bridget, materiaux DazHair. +HAIRSTYLE: /lpr_hair_pocolov/Hairs/Pocolov13.Pocolov13 +SEX: F +DAZ: true diff --git a/ModSources/lpr_hair_pocolov/Module/Hairstyles/pocolov14.lphair b/ModSources/lpr_hair_pocolov/Module/Hairstyles/pocolov14.lphair new file mode 100644 index 0000000..33de7b5 --- /dev/null +++ b/ModSources/lpr_hair_pocolov/Module/Hairstyles/pocolov14.lphair @@ -0,0 +1,6 @@ +// Pocolov Hair 14 - Pocolov (Pocolov Studio, artist Thang) - licence CC BY 4.0 +// Source : https://www.fab.com/listings/4911f6b9-d548-45d7-86be-a6971da97c54 +// Modifications (Tools/HairPipeline.ps1) : liee au squelette Genesis 8 par transfert de poids depuis le corps (tete, cou, poitrine), ajustee a la tete de Bridget, materiaux DazHair. +HAIRSTYLE: /lpr_hair_pocolov/Hairs/Pocolov14.Pocolov14 +SEX: F +DAZ: true diff --git a/ModSources/lpr_hair_pocolov/Module/Hairstyles/pocolov15.lphair b/ModSources/lpr_hair_pocolov/Module/Hairstyles/pocolov15.lphair new file mode 100644 index 0000000..16b1e20 --- /dev/null +++ b/ModSources/lpr_hair_pocolov/Module/Hairstyles/pocolov15.lphair @@ -0,0 +1,6 @@ +// Pocolov Hair 15 - Pocolov (Pocolov Studio, artist Thang) - licence CC BY 4.0 +// Source : https://www.fab.com/listings/ed8e016a-0bf0-4a6c-94b0-2760083b879d +// Modifications (Tools/HairPipeline.ps1) : liee au squelette Genesis 8 par transfert de poids depuis le corps (tete, cou, poitrine), ajustee a la tete de Bridget, materiaux DazHair. +HAIRSTYLE: /lpr_hair_pocolov/Hairs/Pocolov15.Pocolov15 +SEX: F +DAZ: true diff --git a/ModSources/lpr_hair_pocolov/Module/Hairstyles/pocolov16.lphair b/ModSources/lpr_hair_pocolov/Module/Hairstyles/pocolov16.lphair new file mode 100644 index 0000000..6faf91a --- /dev/null +++ b/ModSources/lpr_hair_pocolov/Module/Hairstyles/pocolov16.lphair @@ -0,0 +1,6 @@ +// Pocolov Hair 16 - Pocolov (Pocolov Studio, artist Thang) - licence CC BY 4.0 +// Source : https://www.fab.com/listings/802dc956-6211-4b83-8ba1-37beb3cb338f +// Modifications (Tools/HairPipeline.ps1) : liee au squelette Genesis 8 par transfert de poids depuis le corps (tete, cou, poitrine), ajustee a la tete de Bridget, materiaux DazHair. +HAIRSTYLE: /lpr_hair_pocolov/Hairs/Pocolov16.Pocolov16 +SEX: F +DAZ: true diff --git a/ModSources/lpr_hair_pocolov/Module/Hairstyles/pocolov17.lphair b/ModSources/lpr_hair_pocolov/Module/Hairstyles/pocolov17.lphair new file mode 100644 index 0000000..eba9f0a --- /dev/null +++ b/ModSources/lpr_hair_pocolov/Module/Hairstyles/pocolov17.lphair @@ -0,0 +1,6 @@ +// Pocolov Hair 17 - Pocolov (Pocolov Studio 2019, artist Thang) - licence CC BY 4.0 +// Source : https://www.fab.com/listings/7f6f687d-bb13-40c6-8b69-64044ededc1d +// Modifications (Tools/HairPipeline.ps1) : liee au squelette Genesis 8 par transfert de poids depuis le corps (tete, cou, poitrine), ajustee a la tete de Bridget, materiaux DazHair. +HAIRSTYLE: /lpr_hair_pocolov/Hairs/Pocolov17.Pocolov17 +SEX: F +DAZ: true diff --git a/ModSources/lpr_hair_pocolov/Module/lpr_hair_pocolov.lpmod b/ModSources/lpr_hair_pocolov/Module/lpr_hair_pocolov.lpmod new file mode 100644 index 0000000..970b81f --- /dev/null +++ b/ModSources/lpr_hair_pocolov/Module/lpr_hair_pocolov.lpmod @@ -0,0 +1,12 @@ +MODULE_UNIQUEID: lpr_hair_pocolov +MODULE_NAME: Pocolov Hairstyles +MODULE_AUTHOR: LifePlay Revival (hairstyles by Pocolov) +MODULE_LINK: https://github.com/edujiro5972/LifePlay-Revival +MODULE_DESCRIPTION: 12 free hairstyles by Pocolov (Pocolov Studio, artist Thang), CC BY 4.0, converted for LifePlay +MODULE_REQUIREMENTS: vin_Base +MODULE_VERSION: 1.0 +MODULE_CREATED: 2026-10-03 +MODULE_LICENSE: CC BY 4.0 +MODULE_AUTHOR_LINK: https://www.fab.com/sellers/Pocolov +MODULE_PRICE: Free +MODULE_DEFAULT_ENABLED: true diff --git a/ModSources/lpr_hair_pocolov/lpr_hair_pocolov.uplugin b/ModSources/lpr_hair_pocolov/lpr_hair_pocolov.uplugin new file mode 100644 index 0000000..742e565 --- /dev/null +++ b/ModSources/lpr_hair_pocolov/lpr_hair_pocolov.uplugin @@ -0,0 +1,13 @@ +{ + "FileVersion": 3, + "Version": 1, + "VersionName": "1.0", + "FriendlyName": "Pocolov Hairstyles", + "Description": "12 free hairstyles by Pocolov (Pocolov Studio, artist Thang), CC BY 4.0, converted for LifePlay", + "Category": "LifePlay Mods", + "CreatedBy": "LifePlay Revival (hairstyles by Pocolov)", + "CanContainContent": true, + "IsBetaVersion": false, + "Installed": false, + "CreatedByURL": "https://www.fab.com/sellers/Pocolov" +} diff --git a/Source/LifePlay/LPModInfoSubsystem.cpp b/Source/LifePlay/LPModInfoSubsystem.cpp new file mode 100644 index 0000000..4c2e267 --- /dev/null +++ b/Source/LifePlay/LPModInfoSubsystem.cpp @@ -0,0 +1,202 @@ +// Portage UE 5.5 - voir LPModInfoSubsystem.h + +#include "LPModInfoSubsystem.h" + +#include "Engine/Engine.h" +#include "Engine/GameInstance.h" +#include "Engine/GameViewportClient.h" +#include "GeneralProjectSettings.h" +#include "HAL/FileManager.h" +#include "HAL/PlatformTime.h" +#include "LifePlay.h" +#include "Misc/FileHelper.h" +#include "Misc/Paths.h" +#include "Styling/CoreStyle.h" +#include "UObject/UnrealType.h" +#include "Widgets/Input/SButton.h" +#include "Widgets/Layout/SBorder.h" +#include "Widgets/Layout/SBox.h" +#include "Widgets/SBoxPanel.h" +#include "Widgets/SOverlay.h" +#include "Widgets/Text/STextBlock.h" + +namespace +{ + constexpr double CheckInterval = 2.0; + + FString FieldText(const UStruct* Struct, const void* Data, const TCHAR* AuthoredName) + { + for (TFieldIterator It(Struct); It; ++It) + { + if (It->GetAuthoredName() == AuthoredName) + { + FString Out; + It->ExportTextItem_InContainer(Out, Data, nullptr, nullptr, PPF_None); + return Out.TrimQuotes(); + } + } + return FString(); + } +} + +void ULPModInfoSubsystem::Initialize(FSubsystemCollectionBase& Collection) +{ + Super::Initialize(Collection); + GameVersion = GetDefault()->ProjectVersion; + + // Modules//.lpmod (meme regle que le jeu : un fichier par dossier de module, a sa racine). + const FString ModulesDir = FPaths::ConvertRelativePathToFull(FPaths::ProjectContentDir() / TEXT("Modules")); + TArray Dirs; + IFileManager::Get().FindFiles(Dirs, *(ModulesDir / TEXT("*")), false, true); + int32 WithGameVersion = 0; + for (const FString& Dir : Dirs) + { + FString Text; + if (!FFileHelper::LoadFileToString(Text, *(ModulesDir / Dir / Dir + TEXT(".lpmod")))) + { + continue; + } + TMap& Keys = Metadata.Add(Dir); + TArray Lines; + Text.ParseIntoArrayLines(Lines, true); + for (const FString& Line : Lines) + { + FString Key, Value; + if (!Line.TrimStart().StartsWith(TEXT("//")) && Line.Split(TEXT(":"), &Key, &Value)) + { + Keys.Add(Key.TrimStartAndEnd().ToUpper(), Value.TrimStartAndEnd()); + } + } + WithGameVersion += Keys.Contains(TEXT("MODULE_GAME_VERSION")) ? 1 : 0; + } + UE_LOG(LogLifePlay, Display, TEXT("Modules : %d .lpmod lu(s), %d avec MODULE_GAME_VERSION (jeu %s)"), Metadata.Num(), WithGameVersion, *GameVersion); + if (WithGameVersion > 0) + { + TickHandle = FTSTicker::GetCoreTicker().AddTicker(FTickerDelegate::CreateUObject(this, &ULPModInfoSubsystem::Tick)); + } +} + +void ULPModInfoSubsystem::Deinitialize() +{ + FTSTicker::GetCoreTicker().RemoveTicker(TickHandle); + CloseWarning(); + Super::Deinitialize(); +} + +FString ULPModInfoSubsystem::GetModuleMetadata(const FString& Module, const FString& Key) const +{ + for (const TPair>& Pair : Metadata) + { + if (Pair.Key.Equals(Module, ESearchCase::IgnoreCase)) + { + const FString* Value = Pair.Value.Find(Key.ToUpper()); + return Value ? *Value : FString(); + } + } + return FString(); +} + +bool ULPModInfoSubsystem::IsModuleEnabled(const FString& Module) const +{ + // Meme regle que GI.IsModEnabled : un module absent de GI.ModEnableds est inactif. + const UObject* GI = GetGameInstance(); + const FArrayProperty* Prop = GI ? CastField(GI->GetClass()->FindPropertyByName(TEXT("ModEnableds"))) : nullptr; + const FStructProperty* Inner = Prop ? CastField(Prop->Inner) : nullptr; + if (!Inner) + { + return false; + } + FScriptArrayHelper Helper(Prop, Prop->ContainerPtrToValuePtr(GI)); + for (int32 i = 0; i < Helper.Num(); ++i) + { + if (FieldText(Inner->Struct, Helper.GetRawPtr(i), TEXT("UniqueID")).Equals(Module, ESearchCase::IgnoreCase)) + { + return FieldText(Inner->Struct, Helper.GetRawPtr(i), TEXT("IsEnabled")).Equals(TEXT("True"), ESearchCase::IgnoreCase); + } + } + return false; +} + +bool ULPModInfoSubsystem::Tick(float DeltaTime) +{ + const double Now = FPlatformTime::Seconds(); + if (Now < NextCheck || !GEngine || !GEngine->GameViewport || Popup.IsValid()) + { + return true; + } + NextCheck = Now + CheckInterval; + TArray Lines; + for (const TPair>& Pair : Metadata) + { + const FString* Built = Pair.Value.Find(TEXT("MODULE_GAME_VERSION")); + if (!Built || Built->IsEmpty() || *Built == GameVersion || Warned.Contains(Pair.Key) || !IsModuleEnabled(Pair.Key)) + { + continue; + } + Warned.Add(Pair.Key); + const FString* Name = Pair.Value.Find(TEXT("MODULE_NAME")); + Lines.Add(FString::Printf(TEXT("- %s (%s) : built for LifePlay %s"), Name ? **Name : *Pair.Key, *Pair.Key, **Built)); + UE_LOG(LogLifePlay, Warning, TEXT("Modules : %s construit pour LifePlay %s, jeu %s"), *Pair.Key, **Built, *GameVersion); + } + if (Lines.Num() > 0) + { + ShowWarning(Lines); + } + return true; +} + +void ULPModInfoSubsystem::ShowWarning(const TArray& Lines) +{ + const FString Body = FString::Printf(TEXT("This game is LifePlay %s. The following enabled mod(s) were built for another version:\n\n%s\n\n") + TEXT("Their 3D assets may fail to load (missing hair, clothes...) or look wrong. Update the mod, or ask its author for a ") + TEXT("version built for LifePlay %s. You can disable it in the Mod Manager."), *GameVersion, *FString::Join(Lines, TEXT("\n")), *GameVersion); + + Popup = SNew(SOverlay) + + SOverlay::Slot().HAlign(HAlign_Center).VAlign(VAlign_Center) + [ + SNew(SBox).WidthOverride(760.f) + [ + SNew(SBorder) + .BorderImage(FCoreStyle::Get().GetBrush("WhiteBrush")) + .BorderBackgroundColor(FLinearColor(0.02f, 0.02f, 0.03f, 0.94f)) + .Padding(24.f) + [ + SNew(SVerticalBox) + + SVerticalBox::Slot().AutoHeight().Padding(0.f, 0.f, 0.f, 12.f) + [ + SNew(STextBlock) + .Text(FText::FromString(TEXT("Mod version warning"))) + .Font(FCoreStyle::GetDefaultFontStyle("Bold", 22)) + .ColorAndOpacity(FLinearColor(1.f, 0.75f, 0.2f)) + ] + + SVerticalBox::Slot().AutoHeight().Padding(0.f, 0.f, 0.f, 18.f) + [ + SNew(STextBlock) + .Text(FText::FromString(Body)) + .Font(FCoreStyle::GetDefaultFontStyle("Regular", 14)) + .ColorAndOpacity(FLinearColor(0.92f, 0.92f, 0.92f)) + .AutoWrapText(true) + ] + + SVerticalBox::Slot().AutoHeight().HAlign(HAlign_Right) + [ + SNew(SButton) + .ContentPadding(FMargin(28.f, 6.f)) + .OnClicked_Lambda([this]() { CloseWarning(); return FReply::Handled(); }) + [ + SNew(STextBlock).Text(FText::FromString(TEXT("OK"))).Font(FCoreStyle::GetDefaultFontStyle("Bold", 16)) + ] + ] + ] + ] + ]; + GEngine->GameViewport->AddViewportWidgetContent(Popup.ToSharedRef(), 1000); +} + +void ULPModInfoSubsystem::CloseWarning() +{ + if (Popup.IsValid() && GEngine && GEngine->GameViewport) + { + GEngine->GameViewport->RemoveViewportWidgetContent(Popup.ToSharedRef()); + } + Popup.Reset(); +} diff --git a/Source/LifePlay/LPModInfoSubsystem.h b/Source/LifePlay/LPModInfoSubsystem.h new file mode 100644 index 0000000..204aaf2 --- /dev/null +++ b/Source/LifePlay/LPModInfoSubsystem.h @@ -0,0 +1,48 @@ +// Portage UE 5.5 - lot H3d (metadonnees des modules, Docs/Migration/16_H3_Mods_Paquets.md §8). +// +// Lit les metadonnees de chaque module (Content/Modules//.lpmod, lignes "CLE: valeur"). Le jeu (GI) ne lit que +// les trois premieres lignes, par position (MODULE_UNIQUEID, MODULE_NAME, MODULE_AUTHOR) ; le gestionnaire de mods +// affiche le fichier entier. Cles ajoutees (facultatives, apres la ligne 3) : +// MODULE_VERSION, MODULE_CREATED, MODULE_PACKAGED (dates AAAA-MM-JJ), MODULE_LICENSE, MODULE_AUTHOR_LINK, +// MODULE_PRICE, MODULE_GAME_VERSION (version du jeu contre laquelle les assets du mod ont ete cuits, ecrite par +// Tools/BuildMod.ps1), MODULE_DEFAULT_ENABLED (lu par LPHairstyleSubsystem). +// +// Avertissement : un module ACTIF dont MODULE_GAME_VERSION differe de la version du jeu (ProjectVersion) declenche une +// fenetre (Slate, independante des Blueprints, aussi sur l'ecran titre), une fois par module et par session. + +#pragma once + +#include "CoreMinimal.h" +#include "Containers/Ticker.h" +#include "Subsystems/GameInstanceSubsystem.h" +#include "LPModInfoSubsystem.generated.h" + +class SWidget; + +UCLASS() +class LIFEPLAY_API ULPModInfoSubsystem : public UGameInstanceSubsystem +{ + GENERATED_BODY() + +public: + virtual void Initialize(FSubsystemCollectionBase& Collection) override; + virtual void Deinitialize() override; + + /** Valeur d'une cle du .lpmod d'un module (vide si absente). */ + UFUNCTION(BlueprintCallable, Category = "LifePlay|Mods") + FString GetModuleMetadata(const FString& Module, const FString& Key) const; + +private: + bool Tick(float DeltaTime); + bool IsModuleEnabled(const FString& Module) const; + void ShowWarning(const TArray& Lines); + void CloseWarning(); + + /** Module -> (cle en majuscules -> valeur). */ + TMap> Metadata; + FString GameVersion; + TSet Warned; + TSharedPtr Popup; + FTSTicker::FDelegateHandle TickHandle; + double NextCheck = 0.0; +}; diff --git a/Source/LifePlay/LifePlay.Build.cs b/Source/LifePlay/LifePlay.Build.cs index 1eafee7..74d0c38 100644 --- a/Source/LifePlay/LifePlay.Build.cs +++ b/Source/LifePlay/LifePlay.Build.cs @@ -27,6 +27,10 @@ public class LifePlay : ModuleRules // Portage 5.5 (L3) : ULPSessionLogSubsystem lit UGeneralProjectSettings (nom et version du jeu) PrivateDependencyModuleNames.AddRange(new string[] { "EngineSettings" }); + // H3d : ULPModInfoSubsystem affiche un avertissement (fenetre Slate) quand un mod a ete construit pour une + // autre version du jeu + PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" }); + // Uncomment if you are using Slate UI // PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" }); diff --git a/Tools/BuildMod.ps1 b/Tools/BuildMod.ps1 index 0d750b7..7981f5b 100644 --- a/Tools/BuildMod.ps1 +++ b/Tools/BuildMod.ps1 @@ -15,8 +15,8 @@ 5. -Install : copie le mod dans un jeu de test (dossier contenant LifePlay.exe). .EXAMPLE - .\Tools\BuildMod.ps1 -Name LPHairSample - .\Tools\BuildMod.ps1 -Name LPHairSample -Install D:\Game\LifePlay_Build_5.5_H3b\Windows + .\Tools\BuildMod.ps1 -Name lpr_hair_pocolov + .\Tools\BuildMod.ps1 -Name lpr_hair_pocolov -Install D:\Game\LifePlay_Build_5.5_H3d\Windows #> param( [Parameter(Mandatory)] [string] $Name, @@ -44,6 +44,23 @@ if (-not (Test-Path $lpmod)) { throw "ModSources\$Name\Module\$Name.lpmod introu $id = (Select-String -Path $lpmod -Pattern '^MODULE_UNIQUEID:\s*(.+)$' | Select-Object -First 1).Matches[0].Groups[1].Value.Trim() if ($id -ne $Name) { throw "MODULE_UNIQUEID ($id) different du nom du mod ($Name)" } $title = (Select-String -Path $lpmod -Pattern '^MODULE_NAME:\s*(.+)$' | Select-Object -First 1).Matches[0].Groups[1].Value.Trim() +# Metadonnees (H3d) : le jeu lit les trois premieres lignes par position. +$lpmodLines = @(Get-Content $lpmod -Encoding utf8) +$expected = 'MODULE_UNIQUEID:', 'MODULE_NAME:', 'MODULE_AUTHOR:' +for ($i = 0; $i -lt 3; $i++) { + if ($lpmodLines.Count -le $i -or -not $lpmodLines[$i].StartsWith($expected[$i])) { throw "$Name.lpmod : la ligne $($i + 1) doit commencer par $($expected[$i]) (le jeu lit ces lignes par position)" } +} +function Get-LpmodValue([string] $Key) { + $m = $lpmodLines | Select-String -Pattern "^$([regex]::Escape($Key)):\s*(.*)$" | Select-Object -First 1 + if ($m) { $m.Matches[0].Groups[1].Value.Trim() } else { '' } +} +$modVersion = Get-LpmodValue 'MODULE_VERSION' +# Mod payant : aucune licence d'asset non commerciale ou de magasin dans les credits. +$price = Get-LpmodValue 'MODULE_PRICE' +if ($price -and $price -notmatch '^(free|gratuit|0+([.,]0+)?)$') { + $blocking = Select-String -Path (Join-Path $src 'Module\CREDITS.txt') -Pattern '\bNC\b|NonCommercial|Non-Commercial|Standard License|Personal' -ErrorAction SilentlyContinue + if ($blocking) { throw "MODULE_PRICE '$price' : licence(s) incompatible(s) avec la vente dans CREDITS.txt ($($blocking[0].Line.Trim()))" } +} $release = Join-Path $Root "Releases\$Version\Windows" if (-not (Test-Path (Join-Path $release 'AssetRegistry.bin'))) { throw "Version de reference absente : $release (build de publication avec -createreleaseversion=$Version)" } $stray = Get-StrayMods $Root @@ -79,7 +96,7 @@ try { # 4. Assemblage. New-Item -ItemType Directory -Force $Out | Out-Null - $base = "$Name-for-LifePlay-$Version" + $base = if ($modVersion) { "$Name-$modVersion-for-LifePlay-$Version" } else { "$Name-for-LifePlay-$Version" } $stage = Join-Path $Out $base $zip = "$stage.zip" $stamp = Get-Date -Format 'yyyyMMdd_HHmmss' @@ -90,8 +107,19 @@ try { Copy-Item $uplugin $modDir $files | Copy-Item -Destination (Join-Path $modDir 'Content\Paks\Windows') Copy-Item (Join-Path $mounted 'Module') (Join-Path $stage "LifePlay\Content\Modules\$Name") -Recurse + # Copie livree (pas les sources) : date de paquet et version du jeu visee (avertissement en jeu si elle differe). + $stagedLpmod = Join-Path $stage "LifePlay\Content\Modules\$Name\$Name.lpmod" + $stamped = @($lpmodLines | Where-Object { $_ -notmatch '^MODULE_(PACKAGED|GAME_VERSION):' }) + "MODULE_PACKAGED: $(Get-Date -Format 'yyyy-MM-dd')" + "MODULE_GAME_VERSION: $Version" + [IO.File]::WriteAllText($stagedLpmod, ($stamped -join "`r`n") + "`r`n", (New-Object Text.UTF8Encoding $false)) + # Descripteur livre : version du mod et lien de l'auteur dans les champs natifs du plugin. + $stagedPlugin = Join-Path $modDir "$Name.uplugin" + $desc = Get-Content $stagedPlugin -Raw | ConvertFrom-Json + if ($modVersion) { $desc.VersionName = $modVersion } + $authorLink = Get-LpmodValue 'MODULE_AUTHOR_LINK' + if ($authorLink) { $desc | Add-Member CreatedByURL $authorLink -Force } + [IO.File]::WriteAllText($stagedPlugin, ($desc | ConvertTo-Json) + "`r`n", (New-Object Text.UTF8Encoding $false)) $readme = @( - "$title ($Name) - built for LifePlay $Version", + "$title ($Name)$(if ($modVersion) { " $modVersion" }) - built for LifePlay $Version", '', 'INSTALL: extract this archive into the game folder (the one containing LifePlay.exe), merging the LifePlay folder.', "Then open `"Mod Manager`" on the title screen and enable the mod. To uninstall, delete LifePlay\Mods\$Name", @@ -128,5 +156,5 @@ if ($Install) { if ($LASTEXITCODE -ge 8) { throw "Copie vers $Install en echec (robocopy $LASTEXITCODE)" } Write-Host "Installe dans $Install" } -# Code de sortie : succes (robocopy renvoie 1 a 7 quand il a copie). -exit 0 +# Code de sortie : succes (robocopy renvoie 1 a 7 quand il a copie). +exit 0 diff --git a/Tools/EditMod.ps1 b/Tools/EditMod.ps1 index 9d271a2..867ebf7 100644 --- a/Tools/EditMod.ps1 +++ b/Tools/EditMod.ps1 @@ -8,7 +8,7 @@ sous " Content" (chemin //) ; un editeur deja ouvert ne voit pas le mod : le fermer d'abord. .EXAMPLE - .\Tools\EditMod.ps1 -Name LPHairSample + .\Tools\EditMod.ps1 -Name lpr_hair_pocolov #> param( [Parameter(Mandatory)] [string] $Name diff --git a/Tools/NewMod.ps1 b/Tools/NewMod.ps1 index f21de06..69afd20 100644 --- a/Tools/NewMod.ps1 +++ b/Tools/NewMod.ps1 @@ -12,7 +12,7 @@ Refuse un nom deja pris (sources, module du jeu ou plugin). .EXAMPLE - .\Tools\NewMod.ps1 -Name MyHairPack -Title "My Hair Pack" -Author "Me" -Hairs + .\Tools\NewMod.ps1 -Name MyHairPack -Title "My Hair Pack" -Author "Me" -License "CC BY 4.0" -AuthorLink https://example.org -Hairs #> param( [Parameter(Mandatory)] [ValidatePattern('^[A-Za-z][A-Za-z0-9_]{2,40}$')] [string] $Name, @@ -20,6 +20,10 @@ param( [Parameter(Mandatory)] [string] $Author, [string] $Description = '', [string] $Link = '', + [string] $ModVersion = '1.0', + [string] $License = '', + [string] $AuthorLink = '', + [string] $Price = 'Free', [switch] $Hairs ) @@ -33,12 +37,13 @@ $utf8 = New-Object Text.UTF8Encoding $false New-Item -ItemType Directory -Force (Join-Path $src 'Content'), (Join-Path $src 'Module') | Out-Null $plugin = [ordered]@{ - FileVersion = 3; Version = 1; VersionName = '1.0' + FileVersion = 3; Version = 1; VersionName = $ModVersion FriendlyName = $Title Description = $(if ($Description) { $Description } else { "LifePlay mod: $Title" }) Category = 'LifePlay Mods'; CreatedBy = $Author CanContainContent = $true; IsBetaVersion = $false; Installed = $false } +if ($AuthorLink) { $plugin.CreatedByURL = $AuthorLink } [IO.File]::WriteAllText((Join-Path $src "$Name.uplugin"), ($plugin | ConvertTo-Json) + "`r`n", $utf8) $lpmod = @( @@ -47,7 +52,13 @@ $lpmod = @( "MODULE_AUTHOR: $Author", "MODULE_LINK: $Link", "MODULE_DESCRIPTION: $(if ($Description) { $Description } else { $Title })", - 'MODULE_REQUIREMENTS: vin_Base') + 'MODULE_REQUIREMENTS: vin_Base', + # Metadonnees (H3d) ; MODULE_PACKAGED et MODULE_GAME_VERSION sont ecrites par BuildMod.ps1 dans la copie livree. + "MODULE_VERSION: $ModVersion", + "MODULE_CREATED: $(Get-Date -Format 'yyyy-MM-dd')", + "MODULE_LICENSE: $License", + "MODULE_AUTHOR_LINK: $AuthorLink", + "MODULE_PRICE: $Price") [IO.File]::WriteAllText((Join-Path $src "Module\$Name.lpmod"), ($lpmod -join "`r`n") + "`r`n", $utf8) [IO.File]::WriteAllText((Join-Path $src 'Module\CREDITS.txt'), "Credits and licenses of the assets in $Title (one line per asset: title, author, license, source URL, changes).`r`n", $utf8) @@ -61,7 +72,7 @@ if ($Hairs) { } New-Item -ItemType Directory -Force (Split-Path $cfgPath -Parent) | Out-Null [IO.File]::WriteAllText($cfgPath, ($cfg | ConvertTo-Json -Depth 4) + "`r`n", $utf8) - Write-Host "Configuration des coiffures : $cfgPath (ajouter les entrees de 'hairs', voir Tools/mods/LPHairSample.json)" + Write-Host "Configuration des coiffures : $cfgPath (ajouter les entrees de 'hairs', voir Tools/mods/lpr_hair_pocolov.json)" } Write-Host "Mod cree : $src" Write-Host "Suite : .\Tools\EditMod.ps1 -Name $Name (assets dans l'editeur), puis .\Tools\BuildMod.ps1 -Name $Name" diff --git a/Tools/mods/LPHairSample.json b/Tools/mods/LPHairSample.json deleted file mode 100644 index 5f2c2eb..0000000 --- a/Tools/mods/LPHairSample.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "mod": "LPHairSample", - "module": "LPHairSample", - "folder": "/LPHairSample/Hairs", - "backup": "D:/Game/LifePlay_Backup_5.5/H3a", - "hairs": [ - { - "name": "Pocolov05", - "archive": "D:/Game/pocolov-hair-05.zip", - "title": "Pocolov Hair 05", - "url": "https://www.fab.com/listings/4025749f-d597-4332-91aa-16e355b94974", - "mesh": "/LPHairSample/Hairs/_Work_Pocolov05/Box001", - "head": "/LPHairSample/Hairs/_Work_Pocolov05/Head", - "cap_slots": "Hair_Base", - "diffuse": "D:/Game/LifePlay_Backup_5.5/H3a/Pocolov05/norm/tex01_Hair_01_Gray.png", - "strands_opacity": "D:/Game/LifePlay_Backup_5.5/H3a/Pocolov05/norm/tex02_Hair_01A1.jpg", - "cap_opacity": "white", - "thicken": 1, - "sex": "F", - "license": "CC BY 4.0", - "author": "Pocolov (Pocolov Studio, artist Thang)", - "auto_fields": [ - "mesh", - "head", - "cap_slots", - "diffuse", - "strands_opacity" - ], - "inspected": true - } - ] -} diff --git a/Tools/mods/lpr_hair_pocolov.json b/Tools/mods/lpr_hair_pocolov.json new file mode 100644 index 0000000..9d0e2ca --- /dev/null +++ b/Tools/mods/lpr_hair_pocolov.json @@ -0,0 +1,296 @@ +{ + "mod": "lpr_hair_pocolov", + "module": "lpr_hair_pocolov", + "folder": "/lpr_hair_pocolov/Hairs", + "backup": "D:/Game/LifePlay_Backup_5.5/mods/lpr_hair_pocolov", + "hairs": [ + { + "name": "Pocolov03", + "archive": "D:/Game/pocolov-hair-03.zip", + "title": "Pocolov Hair 03", + "url": "https://www.fab.com/listings/2257098d-b77c-4eef-9132-85f1454f0ae3", + "mesh": "/lpr_hair_pocolov/Hairs/_Work_Pocolov03/Box001", + "head": "/lpr_hair_pocolov/Hairs/_Work_Pocolov03/Head", + "cap_slots": "Hair_Base", + "diffuse": "D:/Game/LifePlay_Backup_5.5/mods/lpr_hair_pocolov/Pocolov03/norm/tex10_Hair_01_Gray.png", + "strands_opacity": "D:/Game/LifePlay_Backup_5.5/mods/lpr_hair_pocolov/Pocolov03/norm/tex12_Hair_01A1.jpg", + "cap_opacity": "white", + "thicken": 1, + "sex": "F", + "license": "CC BY 4.0", + "author": "Pocolov (Pocolov Studio, artist Thang)", + "auto_fields": [ + "mesh", + "head", + "cap_slots", + "diffuse", + "strands_opacity" + ], + "inspected": true + }, + { + "name": "Pocolov05", + "archive": "D:/Game/pocolov-hair-05.zip", + "title": "Pocolov Hair 05", + "url": "https://www.fab.com/listings/4025749f-d597-4332-91aa-16e355b94974", + "mesh": "/lpr_hair_pocolov/Hairs/_Work_Pocolov05/Box001", + "head": "/lpr_hair_pocolov/Hairs/_Work_Pocolov05/Head", + "cap_slots": "Hair_Base", + "diffuse": "D:/Game/LifePlay_Backup_5.5/mods/lpr_hair_pocolov/Pocolov05/norm/tex01_Hair_01_Gray.png", + "strands_opacity": "D:/Game/LifePlay_Backup_5.5/mods/lpr_hair_pocolov/Pocolov05/norm/tex02_Hair_01A1.jpg", + "cap_opacity": "white", + "thicken": 1, + "sex": "F", + "license": "CC BY 4.0", + "author": "Pocolov (Pocolov Studio, artist Thang)", + "auto_fields": [ + "mesh", + "head", + "cap_slots", + "diffuse", + "strands_opacity" + ], + "inspected": true + }, + { + "name": "Pocolov06", + "archive": "D:/Game/pocolov-hair-06.zip", + "title": "Pocolov Hair 06", + "url": "https://www.fab.com/listings/14c3cd52-02f9-4bfe-bb40-b5c3acb1f428", + "mesh": "/lpr_hair_pocolov/Hairs/_Work_Pocolov06/Hair_06", + "head": "/lpr_hair_pocolov/Hairs/_Work_Pocolov06/Head", + "cap_slots": "Hair_Base", + "diffuse": "D:/Game/LifePlay_Backup_5.5/mods/lpr_hair_pocolov/Pocolov06/norm/tex01_Hair_01_Gray.png", + "strands_opacity": "D:/Game/LifePlay_Backup_5.5/mods/lpr_hair_pocolov/Pocolov06/norm/tex02_Hair_01A1.jpg", + "cap_opacity": "white", + "thicken": 1, + "sex": "F", + "license": "CC BY 4.0", + "author": "Pocolov (Pocolov Studio, artist Thang)", + "auto_fields": [ + "mesh", + "head", + "cap_slots", + "diffuse", + "strands_opacity" + ], + "inspected": true + }, + { + "name": "Pocolov07", + "archive": "D:/Game/pocolov-hair-07.zip", + "title": "Pocolov Hair 07", + "url": "https://www.fab.com/listings/4d1ba957-b420-4bdc-8984-b528a73b1d58", + "mesh": "/lpr_hair_pocolov/Hairs/_Work_Pocolov07/Hair_07", + "head": "/lpr_hair_pocolov/Hairs/_Work_Pocolov07/Head", + "cap_slots": "Hair_Base", + "diffuse": "D:/Game/LifePlay_Backup_5.5/mods/lpr_hair_pocolov/Pocolov07/norm/tex01_Hair_01_Gray.png", + "strands_opacity": "D:/Game/LifePlay_Backup_5.5/mods/lpr_hair_pocolov/Pocolov07/norm/tex02_Hair_01A1.jpg", + "cap_opacity": "white", + "thicken": 1, + "sex": "F", + "license": "CC BY 4.0", + "author": "Pocolov (Pocolov Studio, artist Thang)", + "auto_fields": [ + "mesh", + "head", + "cap_slots", + "diffuse", + "strands_opacity" + ], + "inspected": true + }, + { + "name": "Pocolov09", + "archive": "D:/Game/pocolov-hair-09.zip", + "title": "Pocolov Hair 09", + "url": "https://www.fab.com/listings/80383c46-f491-4db2-a63d-48d279f35782", + "mesh": "/lpr_hair_pocolov/Hairs/_Work_Pocolov09/Hair_09", + "head": "/lpr_hair_pocolov/Hairs/_Work_Pocolov09/Head", + "cap_slots": "", + "diffuse": "D:/Game/LifePlay_Backup_5.5/mods/lpr_hair_pocolov/Pocolov09/norm/tex01_Hair_01_Gray.png", + "strands_opacity": "D:/Game/LifePlay_Backup_5.5/mods/lpr_hair_pocolov/Pocolov09/norm/tex04_Hair_Texture_A.jpg", + "cap_opacity": "white", + "thicken": 1, + "sex": "F", + "license": "CC BY 4.0", + "author": "Pocolov (Pocolov Studio, artist Thang)", + "auto_fields": [ + "mesh", + "head", + "cap_slots", + "diffuse", + "strands_opacity" + ], + "inspected": true + }, + { + "name": "Pocolov10", + "archive": "D:/Game/pocolov-hair-10.zip", + "title": "Pocolov Hair 10", + "url": "https://www.fab.com/listings/40a91685-76dc-4384-91f1-0040f44e8958", + "mesh": "/lpr_hair_pocolov/Hairs/_Work_Pocolov10/Hair_10", + "head": "/lpr_hair_pocolov/Hairs/_Work_Pocolov10/Head", + "cap_slots": "Hair_Base", + "diffuse": "D:/Game/LifePlay_Backup_5.5/mods/lpr_hair_pocolov/Pocolov10/norm/tex01_Hair_01_Gray.png", + "strands_opacity": "D:/Game/LifePlay_Backup_5.5/mods/lpr_hair_pocolov/Pocolov10/norm/tex02_Hair_01A1.jpg", + "cap_opacity": "white", + "thicken": 1, + "sex": "F", + "license": "CC BY 4.0", + "author": "Pocolov (Pocolov Studio, artist Thang)", + "auto_fields": [ + "mesh", + "head", + "cap_slots", + "diffuse", + "strands_opacity" + ], + "inspected": true + }, + { + "name": "Pocolov11", + "archive": "D:/Game/pocolov-hair-11.zip", + "title": "Pocolov Hair 11", + "url": "https://www.fab.com/listings/c31c219e-bc62-4957-91c5-720440375f79", + "mesh": "/lpr_hair_pocolov/Hairs/_Work_Pocolov11/Hair_11", + "head": "/lpr_hair_pocolov/Hairs/_Work_Pocolov11/Head", + "cap_slots": "", + "diffuse": "D:/Game/LifePlay_Backup_5.5/mods/lpr_hair_pocolov/Pocolov11/norm/tex01_Hair_01_Gray.png", + "strands_opacity": "D:/Game/LifePlay_Backup_5.5/mods/lpr_hair_pocolov/Pocolov11/norm/tex04_Hair_Texture_A.jpg", + "cap_opacity": "white", + "thicken": 1, + "sex": "F", + "license": "CC BY 4.0", + "author": "Pocolov (Pocolov Studio, artist Thang)", + "auto_fields": [ + "mesh", + "head", + "cap_slots", + "diffuse", + "strands_opacity" + ], + "inspected": true + }, + { + "name": "Pocolov13", + "archive": "D:/Game/pocolov-hair-13.zip", + "title": "Pocolov Hair 13", + "url": "https://www.fab.com/listings/a3933681-f5e3-4d93-99f0-c5fff444d405", + "mesh": "/lpr_hair_pocolov/Hairs/_Work_Pocolov13/Hair_13", + "head": "/lpr_hair_pocolov/Hairs/_Work_Pocolov13/Head", + "cap_slots": "Hair_Base", + "diffuse": "D:/Game/LifePlay_Backup_5.5/mods/lpr_hair_pocolov/Pocolov13/norm/tex01_Hair_01_Gray.png", + "strands_opacity": "D:/Game/LifePlay_Backup_5.5/mods/lpr_hair_pocolov/Pocolov13/norm/tex02_Hair_01A1.jpg", + "cap_opacity": "white", + "thicken": 1, + "sex": "F", + "license": "CC BY 4.0", + "author": "Pocolov (Pocolov Studio, artist Thang)", + "auto_fields": [ + "mesh", + "head", + "cap_slots", + "diffuse", + "strands_opacity" + ], + "inspected": true + }, + { + "name": "Pocolov14", + "archive": "D:/Game/pocolov-hair-14.zip", + "title": "Pocolov Hair 14", + "url": "https://www.fab.com/listings/4911f6b9-d548-45d7-86be-a6971da97c54", + "mesh": "/lpr_hair_pocolov/Hairs/_Work_Pocolov14/Hair_14", + "head": "/lpr_hair_pocolov/Hairs/_Work_Pocolov14/Head", + "cap_slots": "Hair_Base", + "diffuse": "D:/Game/LifePlay_Backup_5.5/mods/lpr_hair_pocolov/Pocolov14/norm/tex01_Hair_01_Gray.png", + "strands_opacity": "D:/Game/LifePlay_Backup_5.5/mods/lpr_hair_pocolov/Pocolov14/norm/tex02_Hair_01A1.jpg", + "cap_opacity": "white", + "thicken": 1, + "sex": "F", + "license": "CC BY 4.0", + "author": "Pocolov (Pocolov Studio, artist Thang)", + "auto_fields": [ + "mesh", + "head", + "cap_slots", + "diffuse", + "strands_opacity" + ], + "inspected": true + }, + { + "name": "Pocolov15", + "archive": "D:/Game/pocolov-hair-15.zip", + "title": "Pocolov Hair 15", + "url": "https://www.fab.com/listings/ed8e016a-0bf0-4a6c-94b0-2760083b879d", + "mesh": "/lpr_hair_pocolov/Hairs/_Work_Pocolov15/Hair_15", + "head": "/lpr_hair_pocolov/Hairs/_Work_Pocolov15/Head", + "cap_slots": "Hair_Base", + "diffuse": "D:/Game/LifePlay_Backup_5.5/mods/lpr_hair_pocolov/Pocolov15/norm/tex01_Hair_01_Gray.png", + "strands_opacity": "D:/Game/LifePlay_Backup_5.5/mods/lpr_hair_pocolov/Pocolov15/norm/tex02_Hair_01A1.jpg", + "cap_opacity": "white", + "thicken": 1, + "sex": "F", + "license": "CC BY 4.0", + "author": "Pocolov (Pocolov Studio, artist Thang)", + "auto_fields": [ + "mesh", + "head", + "cap_slots", + "diffuse", + "strands_opacity" + ], + "inspected": true + }, + { + "name": "Pocolov16", + "archive": "D:/Game/pocolov-hair-16.zip", + "title": "Pocolov Hair 16", + "url": "https://www.fab.com/listings/802dc956-6211-4b83-8ba1-37beb3cb338f", + "mesh": "/lpr_hair_pocolov/Hairs/_Work_Pocolov16/Hair_16", + "head": "/lpr_hair_pocolov/Hairs/_Work_Pocolov16/Head", + "cap_slots": "Hair_Base", + "diffuse": "D:/Game/LifePlay_Backup_5.5/mods/lpr_hair_pocolov/Pocolov16/norm/tex01_Hair_01_Gray.png", + "strands_opacity": "D:/Game/LifePlay_Backup_5.5/mods/lpr_hair_pocolov/Pocolov16/norm/tex04_Hair_01A.jpg", + "cap_opacity": "white", + "thicken": 1, + "sex": "F", + "license": "CC BY 4.0", + "author": "Pocolov (Pocolov Studio, artist Thang)", + "auto_fields": [ + "mesh", + "head", + "cap_slots", + "diffuse", + "strands_opacity" + ], + "inspected": true + }, + { + "name": "Pocolov17", + "archive": "D:/Game/pocolov-hair-17.zip", + "title": "Pocolov Hair 17", + "url": "https://www.fab.com/listings/7f6f687d-bb13-40c6-8b69-64044ededc1d", + "mesh": "/lpr_hair_pocolov/Hairs/_Work_Pocolov17/Hair_17", + "head": "/lpr_hair_pocolov/Hairs/_Work_Pocolov17/Head", + "cap_slots": "Hair_Base", + "diffuse": "D:/Game/LifePlay_Backup_5.5/mods/lpr_hair_pocolov/Pocolov17/norm/tex01_Hair_01_Gray.png", + "strands_opacity": "D:/Game/LifePlay_Backup_5.5/mods/lpr_hair_pocolov/Pocolov17/norm/tex02_Hair_01A1.jpg", + "cap_opacity": "white", + "thicken": 1, + "sex": "F", + "license": "CC BY 4.0", + "author": "Pocolov (Pocolov Studio 2019, artist Thang)", + "auto_fields": [ + "mesh", + "head", + "cap_slots", + "diffuse", + "strands_opacity" + ], + "inspected": true + } + ] +} diff --git a/Tools/modules/next.json b/Tools/modules/next.json new file mode 100644 index 0000000..80114f9 --- /dev/null +++ b/Tools/modules/next.json @@ -0,0 +1,5 @@ +{ + "version": "next", + "essential": ["vin_Base", "vin_VanillaRealistic"], + "zip": "LifePlay_Revival_Optional_Modules.zip" +}