# CAM-B2p-H-IMPL : pose sur le lit (G-e), surfaces admises (G-f), clic molette (G-g), maillage dans les refus, `Reach` (2026-10-14) GO : Big Boss, 2026-10-14 (« ajoute d'abord, en C++ seul, G-e, G-f, le clic molette pour le panneau, le nom du maillage dans les refus et le renommage de `Reach` » ; un instantané et une VAL statique par point ; rien hors du sexe pour le clic molette). SPEC : `CAM-B2p-G-SPEC.md` § 5.2 à 5.4 ; VAL `CAM-B2p-G-VAL.md` (N7). Écriture sans compilation (build COMMUN-12 chez STG). Seuls `LPCameraModeSubsystem.cpp` et `.h` sont touchés ; rien chez STG ni STE. ## 0. Instantanés et empreintes (un par point, `D:\Game\LifePlay_Backup_5.5\`) | Point | Instantané | `.cpp` avant | `.h` avant | |---|---|---|---| | H1 `Reach` → `ObstacleReach` (N7) | `CAM-B2p-H1` | `A5F041FFA8562F9E75560EAD01725E2B` | `00D439937DBCEAB44F459C4A834F34F0` | | H2 nom du maillage dans les refus | `CAM-B2p-H2` | `747FA007E6F0E7B86A945CF03FFF0437` | `00D43993…` | | H3 G-e, pose sur le lit | `CAM-B2p-H3` | `756C95F0BA774E92E2D26695DEDD279B` | `00D43993…` | | H4 G-f, surfaces admises | `CAM-B2p-H4` | `91FD48F0FC438D97FF1C2126B51433D6` | `BBB45AD04440286B4076349A1CC0052A` | | H5 G-g, clic molette | `CAM-B2p-H5` | `48F20ED7AC623D5ADC92F14FA8D0698D` | `924B63F8EA320D18C27FDF60B95508CD` | | **Final** | — | **`210B665AA8D5D628B8C1AC429A339B74`**, 1687 lignes | **`239DA6094E7401E0E3B3699A635A8150`**, 152 lignes | Fins de ligne : LF (0 CR). Retour arrière d'un point : `.\Tools\Restore.ps1 -Lot CAM-B2p-H` remet l'état d'avant ce point (et défait les points suivants). ## 1. Écritures ### H1 : `Reach` (N7) - STG : `LPDirectControlSubsystem.cpp:58`, espace de noms **anonyme**, `const float Reach = 150.f;` (utilisé l. 1357 et 1379). Lu, rien écrit. - CAM : le local `Reach` de `RecenterSceneCamera` devient `ObstacleReach` (commentaire en place). Aucun autre usage. ### H2 : nom du maillage dans les refus - Nouvelles fonctions de `LPCameraModeLocal` : - `ComponentMesh` (maillage statique ou nul) ; - `IsAdmittedBed` (règle `IsBedMesh` de STE recopiée : « bed » sans casse, `fnt_ext011`, `fnt_new045`, `fnt_new235` ; l'original est dans un espace anonyme de STE) ; - `DescribeComponent` → `Propriétaire/composant (maillage)`, ou `(sans maillage statique)`. - `CoupleSpotFree` utilise `IsAdmittedBed` (même règle qu'avant) et rend `DescribeComponent` : la ligne `Sexe : place refusee, recouvre Room_C_0/NODE_…_60 (SM_…)` donne le maillage. ### H3 : G-e, pose sur le lit - `CoupleLowestRoot` (namespace) : Z de la racine du maillage la plus basse du couple. - Constante `CoupleRootAboveSurface` = 3 cm. - `TraceDown` (lambda de `TickCoupleMouse`) : - canal **`ECC_Pawn`** au lieu de `ECC_Visibility` (même requête : couple, vue, `Wall`, `CamRoom` ignorés) ; - rend aussi `OutSurface`, le composant touché, nul pour le sol (impact sous le dessus du sol ou `Room.Box`) ; - règle E2 inchangée (au-dessus du sol, jamais plus bas que son dessus). - Glisser : `Target.Z = Pivot.Z + (surface + 3 − racine la plus basse)`. La racine la plus basse est posée à 3 cm au-dessus de la surface visée. Écart avec la formulation de la SPEC (« surface + écart racine-acteur + 3 cm ») : même résultat pour un couple à plat, mais la référence est la racine la plus basse du couple (comme E3 et `RecenterSceneCamera`) plutôt que celle du meneur. L'écart pris à la prise ne joue plus ; le garde `bGrabHasHeight` du glisser est retiré (un couple qui flottait retombe au premier glisser). - Ligne de prise : `Sexe : couple pris (deplacement) a (x, y, z), racine a +N cm de la surface `. - `.h` : commentaire de `GrabHeight` (journal seulement). ### H4 : G-f, surfaces admises - Au glisser, pièce connue (sol `Room.Box`, Room non cachée) : si la surface visée n'est ni le sol ni un lit (`IsAdmittedBed`), le couple ne bouge pas (il reste à la dernière place admise) ; une ligne par changement : `Sexe : surface refusee Propriétaire/composant (maillage)`. Une personne touchée (capsule sur Pawn) est refusée aussi. - Sinon, test G1 (`CoupleSpotFree`) comme avant. - Pièce cachée (extérieur) : pas de G-f ; G-e s'applique si le tracé touche. - `.h` : `LastSurfaceRefused`, remis à vide à chaque prise. ### H5 : G-g, clic molette - Constantes : `PCLeftMouseSexOn`, `PanelClickMaxHold` = 0,2 s, `PanelClickMaxMove` = 5 px. - `TickPanelClick(PC, DeltaTime)` (nouveau, `.h` + 5 membres), appelé dans `TickSexCamera` **après** le retour « hors sexe ou menu », donc seulement pendant le sexe, hors menu : - appui : durée 0, position du curseur ; - tenu : durée réelle (DeltaTime non borné), mouvement > 5 px si le curseur a une position au départ et à l'image ; - relâcher en 0,2 s au plus sans mouvement : `PC->FindFunction("LeftMouseSexOn")`, 0 paramètre → `ProcessEvent` ; ligne `Sexe : panneau bascule (clic molette, 0.12 s)` ; sinon `Sexe : panneau non bascule, evenement LeftMouseSexOn absent du PC`. - `bMiddleWasDown` remis à faux hors sexe et sur le retour « hors sexe ou menu » : un appui commencé dans un menu ne bascule rien. - **H1 étendu** : le clic molette rend aussi le focus clavier à la vue (pendant le sexe seulement). Sans cela, le filtre du panneau, qui a le focus, fait voir un menu à `MenuOnScreen` et le clic molette ne fermerait jamais le panneau. - **Hors sexe : rien ne change** (aucun appel de `TickPanelClick`, H1 n'est évalué que pendant le sexe). ## 2. Contrôles faits - Noms nouveaux cherchés dans tout `Source/LifePlay` (`grep -lw`) : seuls `Toggle` (`LPModInfoSubsystem.cpp`, locaux l. 113 et 288), `Refused` (`LPHairstyleSubsystem.cpp:230`, local) et `Lowest` (`LPDebugSubsystem.cpp:508`, local) existent ailleurs, tous dans des fonctions : pas de C4459. Aucun membre de la classe n'est masqué (C4458). - Ordre des unités unifiées (`Module.LifePlay.cpp`) : `LPDirectControlSubsystem.cpp` y est inclus ; `ObstacleReach` supprime le risque N7. ## 3. Risques et points à voir à l'essai - R1 : sur le canal Pawn, le tracé vertical peut toucher la tête de lit (même maillage que le lit) : le couple serait posé dessus. À voir en CAM-81 ; un plafond de hauteur pour les lits serait un ajout de règle (non fait). - R2 : le canal Pawn voit les capsules des PNJ : une personne sous la place visée est refusée (voulu, ligne `surface refusee`). - R3 : si le curseur n'a pas de position pendant le clic molette (souris capturée par l'orbite), seul le délai de 0,2 s compte. - R4 : `ProcessEvent` de `LeftMouseSexOn` hors de la boucle du monde (FTSTicker, fil de jeu) : même contexte que les autres écritures de CAM par réflexion. ## 4. Essais (V7, build COMMUN-12) - CAM-81 : glisser sur le lit, de face et d'en haut : posé sur le matelas ; ligne `couple pris … racine a +N cm`. - CAM-82 : glisser sur une commode : refusé, ligne `surface refusee … (maillage)`. - CAM-83 : clics gauche et droit sans bascule ; Espace et clic molette basculent ; ligne `panneau bascule (clic molette)`. - CAM-84 : hors sexe, Espace met en pause, clics et molette comme avant. - CAM-85 : ligne `place refusee` avec maillage ; compilation sans C4456/C4458/C4459. ## 4 bis. Décisions de Big Boss (2026-10-14, après la VAL) - Écart H3 accepté : la référence de hauteur reste la racine la plus basse du couple (personne ne s'enfonce). - N2 de la VAL (`LastSurfaceRefused` non vidé sur une place admise) attend COMMUN-12 : ce n'est qu'une ligne de journal en moins. - Sources gelées jusqu'à la fin du build COMMUN-12 (STG) : `.cpp` `210B665A…`, `.h` `239DA609…`, PC `B07F16A9…`. ## 5. Fichiers à commiter A `Source/LifePlay/LPCameraModeSubsystem.cpp` et `.h` (non suivis), A `CAM-B2p-H-IMPL.md`, A `CAM-B2p-H-VAL.md`.