LifePlay-Revival/Docs/Migration/etat/REL/KEY2/KEY2-CART-02.md
edujiro5972 56dfcfc3d2 LifePlay UE 5.8 : état de développement au 2026-10-20
Tickets : PUB-20261020-T1

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 17:35:10 +02:00

94 lines
15 KiB
Markdown
Raw Permalink 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.

# KEY2-CART-02 : lecture MCP des Blueprints pour K3, K6 et § 8b
Fiche KEY2-CART-02 — Niveau N1 — Modèle prévu sonnet | utilisé sonnet (Sonnet 5.5) — Agent lp-mcp (lecture seule) — Skills sk-protocol, lp-mcp — 2026-10-20.
Contenu adulte (doc 27) : noms techniques de nœuds et de variables seulement, aucun libellé ni texte d'interface repris.
## 1. Résultat
Partiel mais les 4 questions ont une réponse établie par lecture de graphe ; deux points restent non lus (§ 7). Lecture seule : 11 scripts `execute_tool_script` du `ProgrammaticToolset` (`editor_toolset.toolsets.programmatic.ProgrammaticToolset`), enveloppant `AssetTools.load_asset`, `BlueprintTools.list_graphs / find_nodes / get_node_infos / get_connected_subgraph`. Aucun appel d'écriture, aucune PIE, éditeur laissé ouvert.
Constat majeur : **`/Game/BPs/Room` ne lit aucun axe** ; les nœuds d'axe `LeftRight`, `DownUp`, `ScrollDownUp` sont dans **`/Game/BPs/PC.PC:EventGraph`** (Q4). Les événements `LeftRight`, `DownUp`, `ScrollDownUp` de `Room` existent mais pilotent la caméra de scène.
## 2. Question 1 : ce qui ouvre les panneaux `UI/Action` et `UI/SexAction`
Deux panneaux distincts, créés dans deux Blueprints différents. Niveau : établi (graphe), effet à confirmer en jeu.
| refPath | Constat | Niveau |
|---|---|---|
| `/Game/BPs/StreetMap_Static.StreetMap_Static:EventGraph.K2Node_CustomEvent_11` (`ActualLeftMouseInput`) | contient les `CreateWidget` de `/Game/UI/Action.Action_C` : `K2Node_CreateWidget_4`, `_6`, `_9`, `_18` ; chaque instance est ajoutée par `AddChild` à `GetActionBox` de `GI.Cursor` (`VariableGet_2842`, `VariableGet_1583`, `VariableGet_77`) ; juste avant : `SetGamePaused` true (`VariableSet_2`), `CloseHover`, `SetVisibility` Visible (`CallFunction_61`) ; après : `SetInputModeGameAndUI` (`CallFunction_9426`) et `FocusOnFilterBox` (`CallFunction_40`) | établi |
| `/Game/BPs/StreetMap_Static…K2Node_CustomEvent_743` (`OpenLeftMouse`) | `ClickCount` à 0, `Gate`, puis `ActualLeftMouseInput` (`CallFunction_85`) après `SetTimerbyEvent` 0.3 s (`CloseLeftMouseIfNoSecondClick`, `CustomEvent_12`) ; le double clic appelle `ExitActionMenu`, `InterruptAnyCurrentAction`, `PlayerGoHere` | établi (lu avec coupure à 90 nœuds sur 340) |
| `/Game/BPs/PC.PC:EventGraph.K2Node_CustomEvent_11` (`LeftMouseSexOn`, aucun paramètre) | ouvre le panneau de scène : `Branch` `IfThenElse_10` sur `IsVisible(GetBelowCursor)` (`CallFunction_79`) ; vrai : `ExitSexActions` (`CallFunction_1524`) ; faux : `SetVisibility` Visible sur `GetTextBlock_1` (`CallFunction_154`), `MoveCursorToMouse` (`CallFunction_124`), `SetVisibility` Visible sur `GetBelowCursor` de `GetCursorREF` (`CallFunction_116`), `SetInputModeGameAndUI` (`CallFunction_117`), `FocusOnFilterBox` (`CallFunction_1`), puis les `CreateWidget` de `/Game/UI/SexAction.SexAction_C` (14 nœuds dans PC : `CreateWidget_1, 2, 5 à 13, 46, 51` ; plus `Cursor.EventGraph.K2Node_CreateWidget_7`) ajoutés par `AddChild` à `GetActionBox` de `CursorREF` | établi |
| `/Game/BPs/PC…K2Node_CustomEvent_4` (`OpenActionXY`), `_13` (`CloseActionXY`), `_0` (`ExitSexActions`), `_3` (`MouseCheck`) | événements personnalisés sans paramètre (`OpenActionXY` règle le minuteur de `MouseCheck`) ; appelants de `OpenActionXY` : `CallFunction_393`, `CallFunction_266` ; de `ExitSexActions` : `CallFunction_37`, `_1524` ; de `LeftMouseSexOn` dans PC : `CallFunction_35` seulement | établi |
| `Room`, `TopRight`, `Person`, `GI`, `UI/Action`, `UI/SexAction`, `UI/SexInterface`, `UI/Bubble`, `UI/SexLight`, `UI/Builder` | aucun `CreateWidget` de `Action` ni de `SexAction` (recherche `K2Node_CreateWidget`, filtre sur la classe) ; `UI/Action` contient 1 `CreateWidget` (classe non filtrée) | établi pour les classes cherchées |
Réponse : le panneau `UI/Action` s'ouvre depuis `StreetMap_Static` (événement `ActualLeftMouseInput`, après `OpenLeftMouse`), pas depuis PC, Person, Room, TopRight ni GI. Le panneau `UI/SexAction` s'ouvre depuis `PC` par l'événement personnalisé **`LeftMouseSexOn`** (sans paramètre). Ce sont des **événements personnalisés** de Blueprint (UFunction appelable par nom, ex. `ProcessEvent` / `FindFunction`), pas des fonctions publiques à signature C++ ; aucune variable de visibilité unique : la visibilité se lit sur `GetBelowCursor` / `GetTextBlock_1` du widget `Cursor`. Les deux panneaux remplissent le même conteneur `ActionBox` du widget `/Game/UI/Cursor`.
## 3. Question 2 : panneau d'aide d'Alt / clic du milieu (`BuildControlsHelp`)
Réponse : **distinct** (estimé). Preuves : (a) aucun nœud de PC, TopRight, Room, StreetMap_Static, Cursor ne crée un widget d'aide ; les seuls `CreateWidget` liés aux actions sont ceux du § 2 (`Action`, `SexAction`) ; (b) KEY1-CART-01 § 12.3 : le libellé du menu des raccourcis vient du C++ seul (recherche par titre dans les graphes) ; (c) le texte de `BuildControlsHelp` n'a pas été relu dans le C++ (hors périmètre de la fiche). Les panneaux d'action sont des menus de choix (`AddChild` de boutons dans `ActionBox`), pas un bloc de texte d'aide. Niveau : estimé ; à confirmer en jeu ou en lisant quel widget `LPCameraModeSubsystem.cpp:2051-2052` affiche.
## 4. Question 3 : `PC.PC:EventGraph.K2Node_InputKey_14` (bouton gauche) pendant une scène
Sous-graphe lu (`get_connected_subgraph` sur `K2Node_InputKey_14`, 78 nœuds, type `Input|MouseEvents|LeftMouseButton`). Niveau : établi pour le câblage ; effet à confirmer en jeu.
| refPath (`PC…EventGraph.`) | Constat |
|---|---|
| `K2Node_IfThenElse_106` (Pressed) | `Condition` = `CommutativeAssociativeBinaryOperator_37` = OR(`GI.JournalOn`, `GI.ContactsOn`, `GI.MainMenuOn`). Vrai : rien (broche `then` non reliée). Faux : `SetIsCharging` true (`VariableSet_34`), `SetCameraChanged` false (`VariableSet_31`), `StartMoveCamera` (`CallFunction_26`). Indépendant de `SexOn` |
| `K2Node_IfThenElse_107` (Released) | même condition OR(JournalOn, ContactsOn, MainMenuOn). Vrai : rien. Faux : `SetIsCharging` false, `StopMoveCamera` (`CallFunction_27`), puis `IfThenElse_7` |
| `IfThenElse_7` | `Condition` = AND(`CameraChanged`, `HoldTime` > 0.2) : vrai : rien (glissement de caméra, pas de clic) ; faux : `PlayClick` (`CallFunction_220`) puis `IfThenElse_43` |
| `IfThenElse_43` | `Condition` = `GI.BuilderOn` : vrai : `Room.SelectUnderCursor` (`CallFunction_145`) ; faux : `IfThenElse_111` |
| `IfThenElse_111` | `Condition` = OR(`GI.CharGenOn`, `GI.InventoryOn`) : vrai : rien ; faux : `IfThenElse_19` |
| `IfThenElse_19` | `Condition` = `GI.ToCum` < 100 : vrai : `IfThenElse_15` ; faux : rien |
| `IfThenElse_15` | `Condition` = **`GI.SexOn`** : **faux (pas de scène)** : `LeftMouseInput` (`CallFunction_160`, cible `GI.StreetMapStatic`, `FromTopRight` = false) ; **vrai (scène active) : broche `then` non reliée, aucune action** |
Constat pour une scène active (`SexOn` vrai) : le relâchement du bouton gauche ne déclenche **ni `LeftMouseInput`, ni `OpenLeftMouse`, ni `CheckMouseForUI`** par ce chemin ; seuls `StartMoveCamera` / `StopMoveCamera` et `PlayClick` sont exécutés (si menus fermés, pas de glissement). `OpenLeftMouse` n'est pas dans ce sous-graphe (appelé par `TopRight` et d'autres : KEY1-CART-01 § 12.2). `CheckMouseForUI` (`CallFunction_185`) est atteint seulement par le minuteur `MouseCheck` (`PC…K2Node_CustomEvent_3`, 0.1 s en boucle, armé par `OpenActionXY`) : il appelle `Cursor.CheckMouseForUI` (événement du `Cursor`, minuteur de 0.5 s : `CheckTR`, `CheckBottomRight`, `CheckSear`, `SetInteractingUI`, `SetInputModeGameAndUI`), qui décide si la souris est sur une zone d'interface. `LeftMouseInput` : l'appel cible `StreetMap_Static` et aboutit à l'événement `ActualLeftMouseInput` (§ 2) ; le corps de `LeftMouseInput` lui-même n'a pas été isolé (voir § 7). La route du clic en scène vers `LeftMouseSexOn` est `PC…K2Node_CallFunction_35` (appel de `LeftMouseSexOn`) : **cet appel n'a aucun lien d'entrée dans PC** (marche arrière : zéro source), appelant externe non trouvé dans PC, TopRight, Room, Person, GI.
## 5. Question 4 : déplacement du couple au clavier ("B2p-R")
Réponse : le code est dans **`PC`**, pas dans `Room`. Niveau : établi (graphe) ; effet à confirmer en jeu.
| refPath | Constat |
|---|---|
| `/Game/BPs/PC.PC:EventGraph.K2Node_InputAxisEvent_4` (`InputAxisLeftRight`) | `Branch` `IfThenElse_12`, condition AND(`LeftRight` ≠ 0, `GI.SexOn`, NOT `IsVisible(VariableGet_21)`) ; vrai : `IfThenElse_59` sur `GI.Room.bHidden` : vrai → événement PC **`CircleSexPersons(AxisValue = LeftRight * 3.0)`** (`CallFunction_42`) ; faux → `GI.Birdview.LeftRightBirdView(AxisValue)` (`CallFunction_40`) ; condition fausse : `LeftRightBirdView` |
| `PC…K2Node_CustomEvent_10` (`CircleSexPersons`, paramètre `AxisValue:Float`) | `Setleftright`, puis `AddWorldRotation` (Yaw, `CallFunction_204`) et `AddRelativeRotation` (`CallFunction_951`) sur `FirstPersonSM` d'une personne du couple, plus `AddWorldRotation` en Pitch lié à l'axe `CursorY` ; lu avec coupure (111 nœuds) |
| `PC…K2Node_InputAxisEvent_3` (`InputAxisDownUp`) et `K2Node_InputAxisEvent_7` (`InputAxisScrollDownUp`) | gardes AND(axe ≠ 0, `GI.SexOn`, NOT `IsVisible(VariableGet_21)`) puis `Setdownup` (`VariableSet_24` / `_22`). Si `GI.Room.bHidden` vrai : `ForEachLoop` `MacroInstance_8` sur **`GI.SexPersons`** (`VariableGet_535`) avec **`SetActorLocation`** (`CallFunction_810`, `bSweep` false, `bTeleport` false). Sinon : `GI.Birdview.DownUpBirdview` / `GI.Birdview.ScrollDownUp` |
| calcul de `CallFunction_810` | `NewLocation` = `MakeVector` (`CallFunction_811`) : **X = `Clamp(X + downup * 5, Min = -3131470.0, Max = 0)`** (`CallFunction_44`/`_45`/`_1199`), **Y et Z = `GetActorLocation` inchangés** (`BreakVector` `CallFunction_812`) |
Réponses : (1) nœuds d'axe `InputAxisLeftRight` (`_4`), `InputAxisDownUp` (`_3`), `InputAxisScrollDownUp` (`_7`), tous dans `PC.EventGraph`. (2) Repère : **monde** (`GetActorLocation` / `SetActorLocation` sur chaque acteur de `GI.SexPersons`), aucune base caméra dans ce chemin ; la rotation (`CircleSexPersons`) est `AddWorldRotation` en Yaw. (3) L'axe écrit est **X** (monde), pas Y ; Y et Z conservés ; le « monter » du couple n'est pas un Z : DownUp et la molette font tous deux varier X, borné à [-3131470, 0]. (4) Variable de position : la position des acteurs de `GI.SexPersons` (aucune variable intermédiaire) ; `downup` et `leftright` sont des variables de PC. (5) Point d'entrée appelable depuis le C++ : **`CircleSexPersons(AxisValue: float)`** (événement personnalisé de PC) pour la rotation ; **pour la translation, aucun point d'entrée** : le calcul est en ligne dans les nœuds d'axe `_3` et `_7` ; le C++ doit soit recopier la formule (X = clamp(X + valeur × 5, -3131470, 0) sur chaque acteur de `GI.SexPersons`), soit alimenter l'axe de jeu. Variante `Room` : `Room.EventGraph` porte les événements `LeftRight` (`CustomEvent_4`), `DownUp` (`CustomEvent_8`), `ScrollDownUp` (`CustomEvent_55`) ; leur corps (`SetControlRotation`, `SetC2Height` borné à [-40, 150], `SetC2Dist` borné à [-75, 125], `SetActorLocation` sur `GetSceneCamera`) déplace la **caméra de scène**, pas le couple. Aucun appelant de ces événements n'a été cherché.
## 6. Scripts envoyés et refus de garde
Scripts (tous `execute_tool_script`, un `try/except` par Blueprint, `execute_tool` avec nom littéral) : (1) sous-graphe de `InputKey_14` ; (2) `CreateWidget` dans PC, Room, TopRight ; (3) idem dans Person, GI, Action, SexAction, SexInterface, Bubble, SexLight, Builder (filtre classe) ; (4) remontée d'exécution depuis chaque `CreateWidget` de PC + liste des événements personnalisés de PC ; (5) sous-graphe de `PC…CustomEvent_11` ; (6) résolution de variables et recherche des appelants (`LeftMouseSexOn`, `OpenActionXY`, `ExitSexActions`, `CloseActionXY`) dans PC, TopRight, Room, Person, GI ; (7) `CreateWidget` de Cursor et recherche de graphes ; (8) événements de `StreetMap_Static`, `Cursor`, `TopRight` par titre ; (9) axes de PC, remontée de `CallFunction_35`, événements de `Room` ; (10) `CircleSexPersons` et événements `Room` `LeftRight` / `DownUp` / `ScrollDownUp`. Les sous-graphes sont des composantes connexes entières (340 à 434 nœuds) : lus avec coupure et filtre, jamais recopiés.
Refus de la garde (messages exacts, scripts corrigés sans contournement) :
1. `lp-mcp (lecture) : appel refuse - script : mot interdit « Exec ».` (type de broche testé par chaîne ; remplacé par le nom de broche `execute`)
2. `lp-mcp (lecture) : appel refuse - script : execute_tool sans nom d'outil litteral (alias ou nom calcule).` (fonction d'appel générique ; remplacée par une aide par outil)
3. `lp-mcp (lecture) : appel refuse - script : mot interdit « vars ».` (nom de clé de résultat ; renommé)
4. `lp-mcp (lecture) : appel refuse - script : mot interdit « Input ».` (test sur le préfixe du type de nœud ; remplacé par `Mapping` / `Axis`)
## 7. Ce qui n'a pas pu être lu
- Corps de `LeftMouseInput` (cible `StreetMap_Static`) : la recherche par titre ne renvoie que l'événement `ActualLeftMouseInput` ; `LeftMouseInput` est une fonction ou macro non dumpée ici.
- Corps de `ActualLeftMouseInput`, `OpenLeftMouse` (coupés à 70-90 lignes sur 340 nœuds), `CircleSexPersons` (coupé à 22/111), et événements `Room` (coupés à 26/434) : lus en partie.
- Appelant externe de `PC…CallFunction_35` (`LeftMouseSexOn`) : non cherché dans Cursor, StreetMap_Static, les autres UI.
- Identité de `VariableGet_21` dans PC (widget testé par `IsVisible` dans les gardes d'axes) ; appelants des événements `Room` `LeftRight` / `DownUp` / `ScrollDownUp`.
- Texte de `BuildControlsHelp` dans le C++ (Q2) ; effets en jeu (aucune PIE).
## 8. Contrôles
MD5 avant (`md5sum`, 2026-10-20, avant les lectures MCP) : `PC.uasset` 707220a6794e8e5469dd8f84437720cd ; `Room.uasset` 931387479e2d15f80bc4f36398907712 ; `GI.uasset` 32fc0a970ab194626e8dc07df3a9633d ; `Person.uasset` 8668a47c627f7a5254910cf0ac33b12a ; `TopRight.uasset` cb8353603cf95849b4f778a33b4bfbd2. Les MD5 après et PubCheck sont cités dans le compte rendu.
## 9. Fichiers à commiter
A `Docs/Migration/etat/REL/KEY2/KEY2-CART-02.md`.
Tours : 19 / 20 (estimé par l'agent ; `FicheStats.py` fait foi).
## 10. Relecture de l'orchestratrice (2026-10-20, après le tour MCP)
Relu dans le C++ de la copie de travail (`LPCameraModeSubsystem.cpp`, modifié et non commité par CAM2 : les numéros de ligne peuvent bouger) :
- **Question 2, corrigée** : en scène, le panneau d'action (`UI/SexAction`) **est** le panneau d'Alt et du clic du milieu.
- `TickPanelClick` appelle `PC.LeftMouseSexOn` par `ProcessEvent` sur un appui bref (0,2 s au plus, 5 px au plus) d'Alt ou du bouton du milieu : `LPCameraModeSubsystem.cpp:189-193`, `:1265-1300` ; `LPCameraModeSubsystem.h:139-141`.
- Cela explique l'appel `PC…CallFunction_35` sans source dans PC (§ 7) : `LeftMouseSexOn` est appelé depuis le C++.
- `BuildControlsHelp` n'est que le texte d'aide ; sa ligne « Alt or middle click » décrit cette même bascule. Le niveau passe de « estimé, distinct » à **établi, même panneau en scène**.
- **Point d'entrée de K3 (établi)** : en scène, `ActionPanel` peut appeler `PC.LeftMouseSexOn` comme le fait déjà `TickPanelClick` (événement sans paramètre, `NumParms == 0` vérifié). Hors scène, `UI/Action` s'ouvre au clic gauche sur le monde (`StreetMap_Static.ActualLeftMouseInput`, § 2) ; aucun point d'entrée sans clic n'a été trouvé.