LifePlay-Revival/Docs/Migration/etat/sandbox/SB2/SB2-CART.md
2026-10-07 15:50:06 +02:00

171 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# SB2-CART — Carte de découpe (SB2-T1)
- **Fiche** : SB2-T1 — **Agent** : A-CART — **Modèle** : prévu opus (M3) | utilisé opus (session principale)
- **Dépôt** : addon `D:\Game\LifePlay-Sandbox`, branche `lot/SB2-bibliotheques`, tag d'entrée `lot-SB2-avant` = `b8fe6b3`
- **Entrée** : `Docs/SB0-conception.md` § 2, 3 et 5 (addon) ; `SB1-SPEC.md`, `SB1-IMPL.md` ; sources lues en entier :
`LPPairSandbox.h/.cpp`, `LPCoupleSim.cpp`, `LPSandboxInteraction.cpp`, `LPSandboxRoomBuilder.cpp`, début de
`LPSandboxMeasure.cpp` ; relevés par recherche : `LPSandboxMeasure.cpp`, `LPSandboxMeasureTour.cpp`, `LPSandboxActionVM.cpp`.
## 1. Principe
Comportement inchangé : le code des méthodes est **déplacé**, pas réécrit. Seuls changent le propriétaire (classe) et
les accès à l'état partagé, qui passent par des services du contexte. Les écarts inévitables sont listés en § 7.
## 2. Classes cibles
| Classe (fichier) | Module | Nature | Rôle |
|---|---|---|---|
| `ALPSandboxScene` (`LPSandboxScene.h/.cpp`, ex-`LPSandboxRoomBuilder.cpp`) | `lps_lib_scene` | `AActor` (ex-`ALPPairSandboxStage`) | pièce, mobilier, coque, sol, lumières, ciel ; points de départ ; **hôte des composants** des mods (outer et racine d'attache, comme la scène aujourd'hui) |
| `FLPSandboxActors` (`LPSandboxActors.h/.cpp`) | `lps_lib_actors` | C++ (instance unique par session, possédée par le GameMode) | joueur et partenaire, capsule copiée de Person, scan Quaternius, corps, lecture de clips, masquage des personnages |
| `FLPSandboxCamera` (`LPSandboxCamera.h/.cpp`) | `lps_system_core` | C++, enveloppe du bras et de la caméra du pion | longueur et décalage du bras, focale, rotation de contrôle, bornes de tangage, `ResetView` |
| `ALPPairSandboxCharacter` (`LPPairSandbox.h/.cpp`) | core (pion) + actors (corps) | `ACharacter`, garde son nom (GameMode, config) | composants `Arm`/`Camera` ; menu (barre des mods, rangée Corps, emplacement du panneau du mod ouvert) ; `Tick` réduit à l'aiguillage |
| `ALPPairSandboxGameMode` | core | inchangé de nom | crée scène, acteurs, contexte |
| `ULPSandboxCoupleMod` (`LPSandboxCoupleMod.h/.cpp`, ex-partie de `LPCoupleSim.cpp`) | `lps_couple` | `UObject` (outer : la scène) | couple : soudure, boîte, déplacement, animations de paire, interrupteurs 1/2, messages du mode Pair |
| `ULPSandboxInteractionMod` (`LPSandboxInteractionMod.h/.cpp`, ex-`LPSandboxInteraction.cpp`) | `lps_interaction` | `UObject` | filtres, chat, pastille de touche, vues, marche |
| `ULPSandboxMeasureMod` (`LPSandboxMeasure.cpp`, `LPSandboxMeasureTour.cpp`, nouveau `LPSandboxMeasureMod.h`) | `lps_asset_integration` | `UObject` | tout l'état Mesure (≈ 70 membres) ; `AddUObject` des captures conservé |
Les enveloppes `ILPSandboxMod` (`LPSandboxModWrappers.cpp`) tiennent chacune un `TStrongObjectPtr` vers l'objet du mod,
créé à la première ouverture (outer = scène). `UObject` plutôt que C++ pur : `OnScreenshotCaptured().AddUObject` et
les `TObjectPtr` (composants, caméras) gardent leur sémantique actuelle.
### 2.1 Contexte et interface (révision de `LPSandboxMod.h`)
```cpp
struct FLPSandboxContext
{
UWorld* World = nullptr;
ALPPairSandboxCharacter* Player = nullptr; // pion (lecture des touches, menu)
FLPSandboxCamera* Camera = nullptr; // core
ALPSandboxScene* Scene = nullptr; // lps_lib_scene, nul si non requis
FLPSandboxActors* Actors = nullptr; // lps_lib_actors, nul si non requis
};
struct FLPSandboxInput // rempli par le Tick du pion, une fois par image
{
APlayerController* PC = nullptr;
float DeltaSeconds = 0.f;
float MouseX = 0.f, MouseY = 0.f; // clic droit tenu, sinon 0
FVector Direction = FVector::ZeroVector; // ZQSD/WASD dans le repère de la caméra (non normalisé)
};
class ILPSandboxMod
{
// existants : GetId, Activate, Deactivate
virtual TSharedPtr<SWidget> BuildPanel(); // construit une fois, mis en cache par l'enveloppe
virtual void TickInput(const FLPSandboxInput& Input); // remplace l'aiguillage du Tick du pion
virtual void OnFellOff(); // pion sous z = -50
virtual void OnBodyChanged(ACharacter* Who); // choix MC / PNJ dans la rangée Corps
};
```
Remplissage selon `MODULE_REQUIREMENTS` : `lps_asset_integration` ne requiert pas `lps_lib_scene` dans son descripteur
actuel mais **utilise la scène comme hôte de ses composants** et masque la pièce → ajouter `lps_lib_scene` à ses
prérequis (décision D2, § 6). Pas d'accès de mod à mod : les seuls points de contact sont scène, acteurs, caméra.
## 3. Destination de chaque membre
### 3.1 `ALPPairSandboxStage` → `ALPSandboxScene`, `FLPSandboxActors`, mods
| Membre / méthode (lignes `LPPairSandbox.h`) | Destination |
|---|---|
| `Build` (RoomBuilder 105–316), `LoadWorldFile`, `Token`, `FProp` | Scene ; la lecture de la capsule Person (119–127) part dans Actors (`ReadPersonCapsule`) ; `Build(World, Radius, Half, bCopied)` reçoit la capsule pour la recherche du départ et le journal (texte inchangé) ; l'appel final `LoadChat()` + `PairSandbox::LoadActions()` (314–315) part dans le mod interaction |
| `Furniture`, `RoomShell` (124–125), `bFurnitureBlocks` (104) | Scene ; services `SetFurnitureBlocksPawn(bool)` (boucle de `Apply` 74–77), `HideRoom()` / `ShowRoom()` (copies exactes des boucles de `BeginMeasure` 172–187 et `EndMeasure` 85–98) |
| `PlayerSpot`, `PartnerSpot` (205–206) | Scene (`GetPlayerSpot`, `GetPartnerSpot`) |
| `Possess` (cpp 43–72) | GameMode / Actors : `Actors.Spawn(Scene, PlayerPawn)` ; l'appel `Apply()` (67) devient « ouvrir le mod initial » ; `ShowAnimMenu` reste appelé |
| `Player`, `Partner` (201–202), `GetPartner` | Actors (`GetPlayer`, `GetPartner`) |
| `CapsuleRadius`, `CapsuleHalf`, `bCopiedPerson` (207–209), `ConfigureCapsule` | Actors |
| `PlayIdle` | aucun appelant : supprimé (vérifié par recherche) |
| `bCapsulesOn` (105), `CoupleBox` (129), `CurrentPair` (203), `Apply`, `Weld`, `FitCoupleBox`, `MoveCouple`, `PlayPair`, `ToggleFurniture`, `ToggleCapsules` | `ULPSandboxCoupleMod` ; `Apply` appelle `Scene->SetFurnitureBlocksPawn(bFurnitureBlocks)` où `bFurnitureBlocks` reste lu dans la scène (l'interrupteur 1 bascule l'état de la scène) |
| `BeginInteraction`, `LoadChat`, `ChatLabel` | `ULPSandboxInteractionMod` |
| `BeginMeasure` … `WritePlanche`, `MeasureBodies` … `AutoStatus`, `FTourStep`, `FLPMeasureFigure`, `bShowMannequin` (106) | `ULPSandboxMeasureMod` (substitutions § 4) |
### 3.2 `ALPPairSandboxCharacter`
| Membre / méthode | Destination |
|---|---|
| `Arm`, `Camera`, `ResetView`, `SavedArmLength` | composants : pion ; manipulation : `FLPSandboxCamera` ; `SavedArmLength` → mod Mesure |
| `SetStage`, `Stage` | remplacés par le contexte ; réglage souris/caméra de `SetStage` (109–121) → `FLPSandboxCamera::Init` |
| `ApplyBody`, `BodyLabel`, `SelectBody`, `QuaterniusMesh`, `QuaterniusClips`, `LoadQuaternius` | Actors (scan unique par session ; `ApplyBody(Who, Label)`) ; `SelectBody` reste dans le menu du pion puis appelle `OpenMod->OnBodyChanged(Who)` |
| `RefreshPose` | coupé en deux services Actors : `PlayClip(Who, Clip)` (branche Quaternius B_/M_, 315–349) et `PlayPairClip(Who, Pair)` (branche paire 352–371) ; la logique de choix part dans couple (paire / Idle_Loop) et interaction (marche / Idle_Loop) |
| `PlayWalk`, `WalkLabel`, `SelectWalk`, `bWasMoving`, `EyesIdle`, `bResumeEyes`, `CurrentView`, `SelectView`, `ApplyInteractionView`, `ApplyFilters`, `ShowChat`, `HideChat`, `ChatLine`, `bChatOpen`, `RefreshInteractKey`, `ShowKeyMark`, `HideKeyMark`, `PlaceKeyMark`, `KeyMark`, `bKeyVisible`, `InteractKey`, `InteractLetter`, `bInteract*`, `bPrevE`, `Who1Name` … `bSpouses`, `ListedActions`, `BuildFilterPanel` | `ULPSandboxInteractionMod` (pointeurs sur membre de `Flag` : `bool ULPSandboxInteractionMod::*`) |
| `SelectAnim`, `CurrentAnim`, liste des 38 noms (`ShowAnimMenu` 290–313), `bPrevOne`, `bPrevTwo` | `ULPSandboxCoupleMod` (panneau : liste des paires) |
| `BuildMeasurePanel`, `TickMeasureInput` | `ULPSandboxMeasureMod` (`BuildPanel`, `TickInput`) |
| `SelectMode`, `ModeLabel`, `bMeasure`, `bInteraction`, `IsInteraction`, `IsMeasure`, `GetModeLabel`, `ModeCombo`, `Menu->Modes/Mode/AnimRow/ViewRow/FilterRow/MeasureRow` | **supprimés** : le registre et `Activate`/`Deactivate` les remplacent ; `OpenModeLabel` / `IdForModeLabel` gardés pour `sandbox_mode.txt` et `[Sandbox.Mode]` |
| `OpenNeutral` | scène neutre = aucun mod : personnages à l'arrêt, pas de `TickInput` (D3) |
| `Menu` (`FPairSandboxMenu`) | réduit à `Widget`, `BodyRow`, `ModPanel` (emplacement), `Bodies` ; `Views`, `Walks`, `Who1/2`, `Places`, `Whens`, `Races` → interaction ; `Options/Selected` → couple |
| `Tick` (638–855) | pion : chute (653–668) → `OnFellOff`, souris (676–682), direction (684–703), Échap (818–821) ; le reste → `TickInput` du mod ouvert (tableau 3.3) |
### 3.3 Découpe du `Tick` du pion
| Lignes | Condition actuelle | Destination |
|---|---|---|
| 645–652 boîte de débogage | Pair | couple `TickInput` |
| 653–668 chute | interaction / sinon | `OnFellOff` : interaction (`BeginInteraction` + `PlayWalk`), couple (`Apply`), Mesure : rien (D4) |
| 704–714 déplacement | Pair : `MoveCouple` ; Interaction : `AddMovementInput` | couple / interaction |
| 715–749 marche, yeux | Interaction | interaction |
| 750–764 touches 1, 2 | Pair | couple |
| 765–817 pastille, chat | Interaction | interaction |
| 823–835 touches Mesure, étiquettes | Mesure | Mesure |
| 836–854 messages à l'écran | Pair | couple |
### 3.4 Transitions (`SelectMode` 175–257) → `Activate` / `Deactivate`
| Bloc actuel | Destination |
|---|---|
| `HideChat`, `HideKeyMark`, `SetOwnerNoSee(false)` (189–191) | interaction `Deactivate` + `Camera`/Actors au besoin (`SetOwnerNoSee(false)` dans chaque `Activate`, comme aujourd'hui à chaque changement) |
| sortie de Mesure (216–223) | Mesure `Deactivate` |
| entrée Mesure (224–239) | Mesure `Activate` |
| entrée Interaction (241–251) | interaction `Activate` |
| entrée Pair (252–256) | couple `Activate` (`PlayPair(CurrentAnim)` + `ResetView`) |
| `BeginInteraction` 97–100 et `BeginMeasure` 188–192 (boîte du couple coupée) | couple `Deactivate` (collision coupée et boîte masquée) : un mod ne touche plus l'état d'un autre |
## 4. Substitutions mécaniques dans les fichiers Mesure
| Avant (membre de la scène) | Après (dans `ULPSandboxMeasureMod`) |
|---|---|
| `ALPPairSandboxStage::` | `ULPSandboxMeasureMod::` |
| `Player.Get()` / `Partner.Get()` | `Actors->GetPlayer()` / `Actors->GetPartner()` |
| `PlayerSpot`, `CapsuleHalf` | `Scene->GetPlayerSpot()`, `Actors->GetCapsuleHalf()` |
| boucles `Furniture` / `RoomShell` | `Scene->HideRoom()` / `Scene->ShowRoom()` |
| `CoupleBox` (188–192) | supprimé (couple `Deactivate`) |
| `NewObject<T>(this…)`, `GetRootComponent()`, `GetWorld()`, `GetActorLocation()` | `NewObject<T>(Scene…)`, `Scene->GetRootComponent()`, `Scene->GetWorld()`, `Scene->GetActorLocation()` |
| `AddUObject(this, &ALPPairSandboxStage::…)` | `AddUObject(this, &ULPSandboxMeasureMod::…)` |
| `Room->…` dans `TickMeasureInput`, `Who->Stage` dans `BuildMeasurePanel` | `this->…` ; `Arm`/`GetMesh()` du pion via `Camera` / `Player` |
Mêmes substitutions pour couple (`LPCoupleSim.cpp`) et interaction (`Player`/`Partner`, `PlayerSpot`, `Arm`, `Camera`, `GetController`).
## 5. Ordre de déplacement (fiches IMPL)
1. **SB2-T2** (socle et bibliothèques) : `LPSandboxMod.h` (contexte, entrée, 3 crochets), `ALPSandboxScene`,
`FLPSandboxActors`, `FLPSandboxCamera`, GameMode, pion (menu réduit, aiguillage) ; enveloppes adaptées.
2. **SB2-T3a** couple, **T3b** interaction, **T3c** Mesure (≈ 1 600 lignes, substitutions § 4).
3. Une compilation (SB2-T4) après T3c : le code intermédiaire ne compile pas seul (la scène perd ses membres en T2).
Points d'appel croisés à casser : `Build → LoadChat/LoadActions` ; `BeginInteraction → CoupleBox` ;
`BeginMeasure → CoupleBox` ; `Possess → Apply` ; `RefreshPose → Stage->CurrentPair / Stage->Player->WalkLabel` ;
`SelectBody → bInteraction, bWasMoving, CurrentView` ; `ShowAnimMenu → PairSandbox::PlaceChoices/WhenChoices` ;
`Tick → Stage->CoupleBox, bCapsulesOn, bFurnitureBlocks`.
## 6. Décisions proposées
| # | Décision | Motif |
|---|---|---|
| D1 | Les mods sont des `UObject` (outer = scène) tenus par l'enveloppe | captures d'écran par `AddUObject`, composants en `TObjectPtr` |
| D2 | `lps_asset_integration` requiert `lps_lib_scene` (descripteur) et `lps_lib_actors` | il masque la pièce et les personnages et accroche ses composants à la scène ; sinon contexte nul |
| D3 | Scène neutre (aucun mod) : pas de comportement de couple | l'état neutre de SB1 (« Pair sans liste ») dépendait du couple ; un mod ne peut plus servir de défaut |
| D4 | Chute du pion en Mesure : rien | aujourd'hui `Apply()` du couple ; le pion est figé et à l'intérieur de la pièce pendant la Mesure, cas non atteint |
| D5 | Panneau du mod ouvert placé sous la rangée Corps (MC, PNJ) | aujourd'hui le panneau Mesure est au-dessus de MC/PNJ et les autres en dessous ; un seul emplacement |
| D6 | `EndSession` vide aussi les instances de mods | l'état des mods vit dans le monde (outer = scène), comme celui de la scène aujourd'hui |
| D7 | Les instances persistent entre deux ouvertures dans la session | l'état actuel (clip Mesure, filtres, paire choisie) survit aux changements de mode |
## 7. Écarts visibles attendus
- Ordre du panneau (D5) ; scène neutre sans couple (D3) ; chargement de `chat.lpaction` et des actions à la première
ouverture d'interaction, plus au démarrage (journal déplacé) ; un seul scan Quaternius par session au lieu de trois
(lignes « Sandbox Quaternius » moins nombreuses).
## 8. Observation hors périmètre (comportement actuel, non corrigé en SB2)
- **O1** : `EndMeasure` (`LPSandboxMeasure.cpp` 85–98) remet `SetVisibility(true)` sur meubles et murs sans
`SetHiddenInGame(false)`, alors que `BeginMeasure` a mis `SetHiddenInGame(true)` : après Mesure, la pièce devrait
rester invisible en Couple et Interaction. À confirmer à l'écran ; correction proposée hors SB2 (registre des reports).