15 KiB
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) :
lp-mcp (lecture) : appel refuse - script : mot interdit « Exec ».(type de broche testé par chaîne ; remplacé par le nom de brocheexecute)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)lp-mcp (lecture) : appel refuse - script : mot interdit « vars ».(nom de clé de résultat ; renommé)lp-mcp (lecture) : appel refuse - script : mot interdit « Input ».(test sur le préfixe du type de nœud ; remplacé parMapping/Axis)
7. Ce qui n'a pas pu être lu
- Corps de
LeftMouseInput(cibleStreetMap_Static) : la recherche par titre ne renvoie que l'événementActualLeftMouseInput;LeftMouseInputest 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énementsRoom(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_21dans PC (widget testé parIsVisibledans les gardes d'axes) ; appelants des événementsRoomLeftRight/DownUp/ScrollDownUp. - Texte de
BuildControlsHelpdans 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.TickPanelClickappellePC.LeftMouseSexOnparProcessEventsur 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_35sans source dans PC (§ 7) :LeftMouseSexOnest appelé depuis le C++. BuildControlsHelpn'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,
ActionPanelpeut appelerPC.LeftMouseSexOncomme le fait déjàTickPanelClick(événement sans paramètre,NumParms == 0vérifié). Hors scène,UI/Actions'ouvre au clic gauche sur le monde (StreetMap_Static.ActualLeftMouseInput, § 2) ; aucun point d'entrée sans clic n'a été trouvé.