95 lines
15 KiB
Markdown
95 lines
15 KiB
Markdown
|
|
# 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é.
|