26 KiB
Fiche CAM-B2p-D-VAL — Niveau N1 — Modèle prévu sonnet | utilisé Sonnet 5.5 (claude-sonnet-5-5) — Agent lp-validator — Skills sk-protocol, sk-recount, debug-verification, lp-validate
CAM-B2p-D-VAL : couple à la souris pendant le sexe, VAL statique (2026-10-14, reprise D-1 incluse)
Hors gabarit : section « 7. Reprise » ajoutée en fin de livrable (revérification de la seule modification faite après la VAL initiale). Périmètre : VAL statique (lecture seule). Aucune compilation, aucun éditeur, aucun commandlet, aucun MCP, aucun jeu, aucune écriture git. Seul fichier écrit : ce livrable.
Numéros de ligne des sections 2 à 6 : ils se rapportent au .cpp de la VAL initiale (MD5 3DB310DC…, 1042 lignes).
Après la reprise (MD5 D6063264…, 1044 lignes), toute ligne à partir de la 660 est décalée de + 2 (§ 7).
1. Fiches amont relues
| Fiche | Lue | Remarque |
|---|---|---|
Docs/Migration/etat/CAM/CAM-B2p-SPEC.md § 7 à § 7.11 (l. 161-331) |
oui, en entier | § 7.3 (hauteur) et § 7.4 (rotation) remplacés par § 7.11 |
Docs/Migration/etat/CAM/CAM-B2p-D-IMPL.md |
oui, en entier, y compris le paragraphe « Reprise après la VAL (D-1) » (l. 66-77) | seule IMPL du lot B2p-D ; § 3 = points à confirmer repris en § 2 |
Instantané D:\Game\LifePlay_Backup_5.5\CAM-B2p-D\ (manifest.csv, sous-arbre Source\LifePlay) |
oui | MD5 du manifeste = MD5 annoncés « avant » |
Source/LifePlay/LPCameraModeSubsystem.cpp et .h (état actuel) |
oui, en entier pour les zones modifiées (l. 1-260, 470-790 du .cpp ; .h entier) |
B2r et B2p-C (validés) ne sont pas rouverts : seul leur inchangé hors points déclarés est contrôlé (§ 3, contrôle 2).
2. Points à confirmer des IMPL
Source : CAM-B2p-D-IMPL.md § 3.
| Id | Point (IMPL § 3) | Résultat | Preuve ou motif |
|---|---|---|---|
| PC-1 | Compilation : signature GetMousePosition(float&, float&) |
PASS-STATIC | PlayerController.h:1623 (surcharge double& en 1624, la float& du code est exacte) ; implémentation PlayerController.cpp:6166 |
| PC-2 | DeprojectMousePositionToWorld(FVector&, FVector&) const |
PASS-STATIC | PlayerController.h:731 |
| PC-3 | ProjectWorldLocationToScreen(FVector, FVector2D&, bool) const |
PASS-STATIC | PlayerController.h:742 ; même espace de coordonnées que la souris (pixels de vue : GameplayStatics.cpp:3319-3343, GameViewportClient.cpp:1094-1110) |
| PC-4 | FCollisionQueryParams::AddIgnoredActors(TArray<AActor*>) |
PASS-STATIC | CollisionQueryParams.h:257 : const TArray<AActor*>&, correspondance exacte avec Couple (const ref) |
| PC-5 | FMath::PointDistToSegment |
PASS-STATIC | UnrealMathUtility.h:2017 : (const FVector&, const FVector&, const FVector&) rend float ; FVector(FVector2D, T) explicite en Vector.h:176, appelé en initialisation directe |
| PC-6 | Compilation réelle (COMMUN-8) | BLOCKED-compilation (reporté COMMUN-8) | VAL statique, jeton UE tenu par STE |
| PC-7 | En jeu : position du curseur en mode Scene ; clic gauche sur le couple et SelectUnderCursor ; menu au clic droit d'un widget de scène ; hauteur sur le lit juste ; borne au sol ; aucune ligne Accessed None nouvelle |
reporté V7 (COMMUN-8) | non vérifiable sans jeu ; la ligne « curseur sans position » (l. 666-670) répondra à la première question |
| PC-8 | Essais CAM-58 à CAM-63 (SPEC § 7.11) | reporté V7 | non rejoués ; chaque essai est relié à son code en § 3, contrôle 4 |
| PC-9 | Reprise D-1 (IMPL l. 66-68) : avec Maj tenu, aucune prise | PASS-STATIC | § 7 |
3. Critères rejoués (VAL initiale, .cpp 3DB310DC…)
Contrôle 1 : empreintes, lignes, fins de ligne
Commande : md5sum, wc -l, tr -cd '\r' | wc -c (actuel et instantané), puis Tools/FileCheck.ps1 -Path ....
3db310dc025f50b9bc5b0681be84b15e *LPCameraModeSubsystem.cpp 1042 CR=0
6585d7f67a7be3aea377b8e93cfa14d8 *LPCameraModeSubsystem.h 112 CR=0
instantané : 8e35e07ae08f3f208a24dc4cf2b3338f .cpp 820 CR=0 ; 9e20981f8c768371a0935e2c7ce9e134 .h 84 CR=0
FileCheck : LF 0 1042 0 - 3DB310DC... alertes=0 (.cpp) ; LF 0 112 0 - 6585D7F6... alertes=0 (.h) ; fichiers=2 LF=2 alertes=0
| Élément | IMPL | Recompté | Verdict |
|---|---|---|---|
| MD5 .cpp après | 3DB310DC025F50B9BC5B0681BE84B15E |
3DB310DC025F50B9BC5B0681BE84B15E |
confirmé (état initial ; état final : § 7) |
| MD5 .h après | 6585D7F67A7BE3AEA377B8E93CFA14D8 |
6585D7F67A7BE3AEA377B8E93CFA14D8 |
confirmé |
| MD5 .cpp / .h avant | 8E35E07A… / 9E20981F… |
identiques au manifest.csv et au sous-arbre de l'instantané |
confirmé |
| Lignes | 820 → 1042 ; 84 → 112 | 820 → 1042 ; 84 → 112 | confirmé |
| CR / BOM | 0 CR, LF | 0 CR, pas de BOM, aucune alerte FileCheck | confirmé |
| Suivi git | « non suivis jusqu'ici » | git status --short : ?? pour les deux ; git ls-files : vide |
confirmé (A) |
Contrôle 2 : diff complet instantané → actuel, périmètre
Commandes : diff -u (lu en entier, .h puis .cpp) ; git diff --no-index --numstat.
228 6 LPCameraModeSubsystem.cpp (820 + 228 - 6 = 1042)
28 0 LPCameraModeSubsystem.h (84 + 28 = 112)
diff -q rend 1 (différent), comme attendu. Hunks du .cpp : 7 (constantes ; garde début de TickSexCamera ; PC non
const ; ReleaseCoupleGrab si vue invalide ; bGrabbing + 2 conditions !bGrabbing ; témoin ; deux fonctions
nouvelles). Hunks du .h : 2 (déclarations anticipées, bloc de membres).
| Hunk | Dans le périmètre de l'IMPL § 1 |
|---|---|
Constantes PelvisSocket, RoomFloor, 120 px, 5 px, 0,3, 30 cm, 5000, +150, −400 (l. 119-129) |
oui |
TickSexCamera : ReleaseCoupleGrab (l. 503, 515), remise de bCursorWarned (l. 504-507), PC non const (l. 511), TickCoupleMouse avant ZQSD (l. 535), !bGrabbing sur les deux branches (l. 537, 559) |
oui |
Témoin : bButtons, G, D, prise, lacet, ligne quand seul un bouton est tenu (l. 576-587) |
oui |
ReleaseCoupleGrab (l. 590-596), TickCoupleMouse (l. 598-786) |
oui |
.h : class AActor;, class UGameInstance;, 2 fonctions, 14 membres |
oui |
Inchangé : toutes les autres lignes de B2r (CharGen, témoins C1, C2, occlusion, touche C) et de B2p-C (formules d'orbite,
distances, POV) ; les deux seules modifications de leurs branches sont les !bGrabbing déclarés. Aucun ajout non
demandé : Query.AddIgnoredActor(View) (l. 620), en plus de la liste de la SPEC (couple, Wall, CamRoom), est
inoffensif et cohérent (la caméra en vue ne doit pas être touchée par son propre tracé).
Contrôle 3 : relecture C++ UE 5.8
Sources lues : D:\Game\Launcher\Engine\UE_5.8\Engine\Source\Runtime\….
| Élément | Preuve moteur | Verdict |
|---|---|---|
GetMousePosition(float&, float&) const |
PlayerController.h:1623 |
PASS-STATIC |
DeprojectMousePositionToWorld(FVector&, FVector&) const |
PlayerController.h:731 |
PASS-STATIC |
ProjectWorldLocationToScreen(FVector, FVector2D&, bool) const |
PlayerController.h:742 |
PASS-STATIC |
AddIgnoredActors(const TArray<AActor*>&) |
CollisionQueryParams.h:257 (autres surcharges : const AActor*, TWeakObjectPtr<const AActor>, sans ambiguïté) |
PASS-STATIC |
AddIgnoredActor(const AActor*) avec View, Wall, CamRoom |
CollisionQueryParams.h:243 |
PASS-STATIC |
SCENE_QUERY_STAT(LPCoupleDrag) + true |
CollisionQueryParams.h:39 : deux arguments (FName, TStatId) ; même forme que LPDirectControlSubsystem.cpp:1024 |
PASS-STATIC |
UWorld::LineTraceSingleByChannel(...) const |
World.h:2161, appelé via const UWorld* |
PASS-STATIC |
FMath::PointDistToSegment |
UnrealMathUtility.h:2017 (rend float, comparé à const float) |
PASS-STATIC |
FVector(FVector2D, 0.f) |
Vector.h:176 explicite, 0.f → double |
PASS-STATIC |
FVector MousePoint(float, float, float) |
Vector.h:168 TVector(T,T,T) |
PASS-STATIC |
FVector2D::Distance |
Vector2D.h:397 statique, rend T |
PASS-STATIC |
EKeys::LeftMouseButton/RightMouseButton |
InputCoreTypes.h via GameFramework/PlayerInput.h (déjà inclus, l. 17 ; LeftShift déjà utilisé de la même façon) |
PASS-STATIC |
UPrimitiveComponent / Bounds / FBox |
Bounds est public (SceneComponent.h:127-129) ; GetBox() const (BoxSphereBounds.h:226) ; PrimitiveComponent.h arrive par Components/SkeletalMeshComponent.h (l. 9) ; Box est un UBoxComponent (LPOutdoorRoomSubsystem.cpp:32, 233) |
PASS-STATIC |
Cast<ACharacter>(const AActor*) |
Casts.h:89 : qualificatifs recopiés, rend const ACharacter* ; précédent LPSecondScreenSubsystem.cpp:36 |
PASS-STATIC |
Os pelvis |
existe dans le squelette (STD-SCN-DIAG.md l. 50 ; LPDebugSubsystem.cpp:523) ; sinon GetSocketLocation rend l'origine du maillage (pas de plantage) |
PASS-STATIC |
.h sans include d'AActor |
TWeakObjectPtr<AActor> avec déclaration anticipée : même schéma que TWeakObjectPtr<UGameViewportClient> Viewport (.h l. 108, déjà compilé en B2c) ; GrabCamera.Get/Reset/= sont dans le .cpp où AActor est complet (GameFramework/Actor.h, l. 13) |
PASS-STATIC |
Membre non UPROPERTY dans UCLASS + GENERATED_BODY |
accepté : UHT ignore ce qui n'est pas balisé ; tous les membres de ce .h sont déjà dans ce cas (Root, Viewport, bShown…) |
PASS-STATIC |
UGameInstance / UObject dans une signature privée |
class UGameInstance; ajoutée ; UObject vient de Subsystems/GameInstanceSubsystem.h |
PASS-STATIC |
Lambdas [&] |
captures World, PC, Query, Pivot (référence const) : durée de vie ≥ lambda, jamais stockées ; Out, OutZ en référence ; -> bool explicite |
PASS-STATIC |
| Types float/double | GrabHeight, SurfaceZ, Target, Delta en double ; MouseX/Y, GrabTurned, GrabLastMouseX en float ; FMath::Clamp aux 3 arguments double (Target.X, Box.Min.X + Margin, Box.Max.X - Margin) ; ternaire du témoin double : double |
PASS-STATIC |
| Const-correctness | PC passe non const (nécessaire pour WriteBool(UObject*), l. 784) ; Room const UObject* vers ReadObject(const UObject*) ; boucle de déplacement AActor* sur const TArray<AActor*>& (éléments AActor* const) ; Mesh const : GetSocketLocation est const |
PASS-STATIC |
| Ombrages de noms (C4456/C4458) | SurfaceZ, Aim, Rotation, Person, Hit redéclarés seulement dans des portées sœurs, jamais imbriquées ; aucun local ne porte le nom d'un membre |
PASS-STATIC |
Aides de LPCameraModeLocal qualifiées |
Grep des noms d'aides et de constantes précédés d'autre chose que :: : seules l. 43-253 (définitions dans l'espace) et l. 673 (commentaire) ; aucun appel non qualifié ; PelvisSocket, RoomFloor, CursorTraceLength, CoupleSelectRadius n'existent dans aucun autre fichier de Source/ ; namespace LPCameraModeLocal défini une seule fois (l. 30) : pas d'ambiguïté en compilation unitaire avec LPDirectControlSubsystem.cpp |
PASS-STATIC |
Formats UE_LOG (spécificateurs comptés dans la chaîne, arguments comptés dans l'appel) :
| Ligne du journal | Spécificateurs | Arguments | |
|---|---|---|---|
| « Sexe : touches … » (l. 581-587) | 17 (%+.0f×4, %d×6, %s, %d×2, %.0f×4 ; le lacet est le 17e) |
17 : Forward, Right, 2 AxisValue, bShift, MoveObject, MoveCamera, bLeftWasDown, bRightWasDown, CoupleGrabMode, *GetNameSafe, ReadInt, Couple.Num(), Pivot.X/Y/Z, Yaw |
égal |
| « couple pris (%s) a (%.0f ×3), hauteur … %s » | 5 | 5 : ternaire TEXT, X, Y, Z, ternaire *FString::Printf(...) / TEXT |
égal ; le temporaire FString vit jusqu'à la fin de l'expression complète de l'appel de journal ; les deux branches du ternaire sont const TCHAR* |
| « couple pose a (%.0f ×3), lacet %.0f » | 4 | 4 | égal |
| « couple tourne de %+.0f degres, lacet %.0f » | 2 | 2 (GrabTurned float, Yaw double) |
égal |
| « curseur sans position … (vue %s) » | 1 | 1 | égal |
Contrôle 4 : logique et gardes de Big Boss
| Id | Garde | Preuve (ligne) | Verdict |
|---|---|---|---|
| (a) | Rien hors sexe ou pendant un menu, prise levée | TickSexCamera l. 500-509 : !SexOn ou bMenuOnScreen → ReleaseCoupleGrab() puis retour (aucune lecture de la souris) ; vue invalide l. 513-517 idem. ReleaseCoupleGrab (l. 590-596) remet mode, caméra figée, bLeftWasDown, bRightWasDown à zéro ; bCursorWarned remis à faux hors sexe seulement (l. 504-507) : « une ligne par scène » |
PASS-STATIC |
| (b) | Mode Scene seulement | l. 609 : Couple.Num() > 0 && !Couple.Contains(View) && !ReadBool(PC, POVOn) ; sinon CoupleGrabMode = 0, caméra relâchée, return false (l. 610-614). L'état des boutons est mis à jour avant ce test (l. 603-606) : passer de POV à Scene bouton tenu ne crée pas de front |
PASS-STATIC |
| (c) | Aucun clic consommé | TickCoupleMouse ne lit que PlayerInput->IsPressed (l. 599-602) ; la seule écriture sur le PC est WriteBool(PC, MoveCamera, false) (l. 784), jamais exécutée hors prise (tous les return false de la fonction la précèdent : l. 614, 662, 671, 693, 727). Aucun Consume, SetInputMode, SetIgnore… |
PASS-STATIC |
| (d) | Borne au sol de Room.Box avec marge |
l. 737-749 : AABB de Floor->Bounds (l. 741), marge 30 cm, Clamp en X et Y ; Floor absent ou trop petit (≤ 2 marges) → pas de borne. Réserve D-3 |
PASS-STATIC |
| (e) | Rien avant 5 px | l. 732 : `bGrabMoved | = Distance(début, souris) >= 5(verrou une fois franchi) ; le déplacement exigebGrabMoved && TraceCursor` (l. 734) |
| (f) | Hauteur par tracé vertical, garde si pas d'impact | à la prise : TraceDown(Pivot, SurfaceZ) → bGrabHasHeight, GrabHeight = Pivot.Z - SurfaceZ (l. 704-705) ; au glisser : Target.Z = SurfaceZ + GrabHeight seulement si bGrabHasHeight && TraceDown(Target, …) (l. 751-754) ; sinon Z actuel gardé. Rayon du curseur sans impact → TraceCursor faux → le couple ne bouge pas à cette image (SPEC § 7.11a) |
PASS-STATIC |
| (g) | Rotation autour du pivot | l. 762-775 : Offset.RotateAngleAxis(Turn, UpVector) autour de Pivot (moyenne des positions, invariante par rotation) et Yaw += Turn pour chaque personne, Turn = ΔX × 0,3 ; sens cohérent avec le lacet (rotation positive autour de Z = lacet positif) |
PASS-STATIC |
| (h) | Caméra figée pendant la prise, libérée au relâcher et hors sexe | l. 780-783 : pose mémorisée (l. 700-702) remise à chaque image tant que la prise dure ; relâcher : GrabCamera.Reset() (l. 726) ; hors sexe, hors Scene, vue invalide : Reset (l. 593, 613) ; ZQSD coupé par !bGrabbing (l. 537, 559). Réserves D-5 (ordre d'image) et D-6 (caméra remplacée en cours de prise) |
PASS-STATIC |
| (i) | Aucune déréférence nulle | PC->PlayerInput testé (Input &&, l. 599-601) ; GI non nul par l'appelant (l. 500) ; World testé (l. 610) ; View valide par l'appelant (l. 513) ; Room nul accepté par ReadObject ; Mesh testé (l. 679-681) ; Floor par IsValid (l. 739) ; GrabCamera.Get() testé (l. 780). Couple[0] : l. 716 (branche « relâcher ») n'est atteinte qu'après le return false de l. 610-614, donc bScene vrai, donc Couple.Num() > 0 (l. 609) ; l. 587 gardé par Couple.Num() > 0 ?. Les éléments de Couple sont déjà filtrés IsValid par ReadActors (l. 191). Les boucles l. 676, 756 et 769 n'itèrent qu'un tableau non vide. Wall et CamRoom testés par if (AActor* … = Cast<AActor>(…)) (l. 621, 625) |
PASS-STATIC |
| (j) | Conflits avec flèches (P2) et Maj + molette seulement pendant une prise | aucun code ne touche aux flèches ni à la molette (bSexWheelZoom reste faux) ; pendant un glisser, la position est réécrite à chaque image, donc remplace un appui de flèche (déclaré, IMPL § 2). Hors prise : aucune écriture. Réserve D-1 (Maj + clic) levée à la reprise : § 7 |
PASS-STATIC |
Rattachement aux essais V7 (non rejoués) : CAM-58 = (e)(f) ; CAM-59 = (g)(h) ; CAM-60 = (d) ; CAM-61 = clic hors couple (l. 691-693 : return false sans prise, aucune écriture) ; CAM-62 = (b) ; CAM-63 = (a) (aucun mouvement après la sortie : le déplacement n'est atteint que dans TickCoupleMouse, que TickSexCamera n'appelle plus hors sexe).
Contrôle 5 : cohérence SPEC / IMPL
| Exigence SPEC § 7.11 | IMPL / code | Verdict |
|---|---|---|
| Sélection par projection, 120 px, segment bassin-tête, sans tracé de collision | l. 673-694 ; Mesh absent → position de l'acteur |
conforme |
Tracé vertical à la prise (Visibility, complexe ; couple, Wall, CamRoom ignorés), dz gardé |
l. 618-627, 704-705 | conforme (View ignoré en plus) |
| Glisser : rayon du curseur, nouveau XY = impact + décalage, borné, Z = surface + dz | l. 706-707, 730-757 | conforme |
| Pas de mouvement sans impact | l. 734 | conforme |
| Clic droit = rotation 0,3°/px autour du pivot, caméra figée | l. 762-775, 780-784 | conforme |
| Clic hors couple : comportement actuel inchangé | l. 691-693 | conforme |
| Maj + molette reste disponible | IMPL § 2 : non joué pendant une prise de déplacement | écart déclaré, acceptable |
| « La rotation d'origine (Maj + bouton + souris) reste » (§ 7.11b) | initialement : MoveCamera forcé à faux sans test de Maj (D-1) ; après reprise : conforme (§ 7) |
levé |
| Retour automatique à la sortie, sélection levée sans pose | l. 500-509 | conforme |
| Volume ≈ 200 lignes | +228 / −6 (.cpp), +28 (.h) | conforme |
4. Diff lu en entier
| Fichier | Compte | Statut git | Lecture |
|---|---|---|---|
Source/LifePlay/LPCameraModeSubsystem.cpp |
VAL initiale : +228 / −6 ; 820 → 1042. Après reprise : +230 / −6 ; 820 → 1044 | ?? (à ajouter, A) |
diff -u entier lu, 7 hunks, aucun hors périmètre |
Source/LifePlay/LPCameraModeSubsystem.h |
+28 / −0 ; 84 → 112 (inchangé par la reprise) | ?? (A) |
diff -u entier lu, 2 hunks |
Recompte par une seconde méthode (git diff --no-index --numstat) égal au recompte wc -l : 228 − 6 = +222 = 1042 − 820 ;
28 = 112 − 84. Fins de ligne LF identiques à l'instantané ; aucune trace de modification par script dans le diff.
5. Verdict
PASS-STATIC (final, après reprise). Aucun défaut bloquant. D-1 est levé (§ 7). Réserves non bloquantes D-2 à D-9 ci-dessous ; la compilation (COMMUN-8) et les essais CAM-58 à CAM-63 restent à faire, aucun n'est compté comme passé.
Défauts bloquants : aucun.
Défauts non bloquants :
| Id | Ligne (état initial) | Constat | Suite proposée (non appliquée) |
|---|---|---|---|
| D-1 | 598-786, 784 | LEVÉ à la reprise (§ 7). Maj + bouton tenu sur le couple déclenchait aussi une prise et mettait MoveCamera à faux : la rotation d'origine (Maj + bouton + souris, SPEC § 7.1) était masquée près du couple, contre § 7.11b |
sans objet |
| D-2 | 784 | MoveCamera forcé à faux : la voie « Manual + souris → AnimatingSpeed quand MoveCamera est faux » (SPEC § 7.11b) est morte au dump, mais n'a pas été revérifiée |
V7 : AnimatingSpeed inchangé pendant un glisser |
| D-3 | 737-749 | Si le couple part hors de l'AABB de Room.Box, le premier pas le ramène d'un coup au bord (− 30 cm) |
V7 CAM-60, dans une pièce et dans l'extérieur |
| D-4 | 707 | Rayon du curseur sans impact à la prise : décalage nul, puis le couple saute sous le curseur au premier pas | cas rare (viser le ciel) ; V7 |
| D-5 | 535, 780-783 | Le ticker passe avant le tick du monde : le PC peut tourner la caméra une image avant que la pose soit remise (image de décalage possible au clic) | V7 CAM-58/59 : tremblement de caméra à l'appui |
| D-6 | 700, 780-783 | Si la vue change de caméra sans passer par POV pendant une prise, la caméra mémorisée est remise à sa pose, pas la nouvelle vue | négligeable ; levée au relâcher |
| D-7 | 590-596, 603-606 | ReleaseCoupleGrab remet les « était enfoncé » à faux : un bouton déjà tenu à la fermeture d'un menu compte comme un nouveau front |
négligeable (les boutons de menu agissent au relâcher) |
| D-8 | 618-627, 704, 733-734 | Tracés Visibility complexes : le rayon du curseur et le départ du tracé vertical (pivot + 150) peuvent toucher un plafond ou un baldaquin avant le lit |
V7 CAM-58 ; la ligne « hauteur sur la surface N cm » donne dz |
| D-9 | 576-587 | Le témoin écrit une ligne par seconde dès qu'un bouton de souris est tenu pendant le sexe, même hors couple | déclaré (IMPL § 1) ; bruit de journal seulement |
Établi / estimé / incertain :
- Établi : MD5, lignes, CR, périmètre du diff, signatures et surcharges du moteur 5.8 (lignes citées), comptes de spécificateurs, absence d'appel non qualifié, gardes (a) à (j) par lecture, reprise D-1 (§ 7).
- Estimé : compilation propre (aucune erreur trouvée par lecture ; MSVC non lancé) ; sens de rotation du lacet.
- Incertain : tout comportement en jeu (D-2 à D-8), absence de collision de la sélection avec un clic d'interface,
Room.Boxcouvrant le sol des pièces jouées. Essai qui trancherait : COMMUN-8 puis CAM-58 à CAM-63.
6. Points à confirmer par l'utilisateur
- D-1 : Maj + clic sur le couple : levé (aucune prise avec Maj ; la rotation d'origine garde la main). À observer tout de même en V7 : Maj + bouton + souris tourne le couple près du couple.
- V7 : « curseur sans position » absent du journal en mode Scene (PC-7).
- V7 : un clic gauche sur le couple ouvre-t-il aussi une interaction de Room ? Un clic droit ouvre-t-il un menu de widget ?
- V7 : CAM-58 (hauteur sur le lit, caméra immobile), CAM-59 (rotation sur place), CAM-60 (arrêt à 30 cm du bord), CAM-61 (orbite hors couple), CAM-62 (touche C), CAM-63 (sortie bouton tenu).
- COMMUN-8 : compilation (0 erreur, avertissements nouveaux listés) avant tout essai en jeu.
7. Reprise : revérification de D-1 (Maj + clic), 2026-10-14
Annonce du coordinateur : .cpp D60632646BF1CF7D200E3BEA833D8D72, 1044 lignes ; .h inchangé 6585D7F6….
Recompte (md5sum, wc -l, tr -cd '\r' | wc -c, git diff --no-index --numstat) :
d60632646bf1cf7d200e3bea833d8d72 *LPCameraModeSubsystem.cpp 1044 CR=0
6585d7f67a7be3aea377b8e93cfa14d8 *LPCameraModeSubsystem.h 112 CR=0
numstat instantané → actuel : .cpp 230 / 6 (VAL initiale : 228 / 6, soit + 2) ; .h : diff -u de 45 lignes, MD5 inchangé
| Élément | Annoncé | Recompté | Verdict |
|---|---|---|---|
| MD5 .cpp | D60632646BF1CF7D200E3BEA833D8D72 |
D60632646BF1CF7D200E3BEA833D8D72 |
confirmé |
| Lignes .cpp | 1044 (avant 1042) | 1044 | confirmé |
| MD5 / lignes .h | 6585D7F6…, 112 |
6585D7F67A7BE3AEA377B8E93CFA14D8, 112 |
confirmé |
| CR | 0 | 0 (.cpp et .h) | confirmé |
Le diff ne diffère du précédent que par ces lignes : preuve par reconstruction. Sur le fichier actuel, retrait des
l. 660-661 et remise de la l. 662 à if (!bLeftPressed && !bRightPressed) (sed en lecture, sortie vers md5sum,
aucun fichier écrit) :
3db310dc025f50b9bc5b0681be84b15e *- (= MD5 de la VAL initiale, 3DB310DC…)
La reprise se réduit donc exactement à ces trois lignes (l. 660-662) ; tout le reste, y compris le diff lu en § 4, est identique octet pour octet à l'état déjà validé.
Lignes ajoutées (cat -A, tabulations seules, pas de CR), dans TickCoupleMouse, branche CoupleGrabMode == 0 :
660 // Maj tenu : la voie d'origine (Maj + bouton + souris, Room) garde la main, aucune prise.
661 const bool bShiftHeld = Input && (Input->IsPressed(EKeys::LeftShift) || Input->IsPressed(EKeys::RightShift));
662 if ((!bLeftPressed && !bRightPressed) || bShiftHeld)
Conforme à l'annonce (commentaire, bShiftHeld, condition).
Compilation à l'œil (PASS-STATIC) :
Inputest leUPlayerInput*déclaré en tête de fonction (l. 599) : dans la portée.UPlayerInput::IsPressed(FKey) constetEKeys::LeftShift/RightShift: mêmes appels queTickSexCameral. 575 (déjà compilés en B2p-C).Input && (bool || bool): pointeur converti enboolpar&&, résultatboolpour unconst bool. Pas de macro, pas de virgule exposée.- Parenthèses de la condition équilibrées ;
bShiftHeldn'est déclaré qu'une fois dansTickCoupleMouse(aucun ombrage : lebShiftdeTickSexCameraest une autre fonction). - Variable utilisée : pas d'avertissement « variable inutilisée ».
D-1 levé (lecture de la fonction, état final) :
- Maj tenu et front montant d'un bouton avec
CoupleGrabMode == 0: lereturn falsede la l. 664 est pris avant toute écriture. Aucune prise, donc niCoupleGrabMode, niGrabCamera, ni mémorisation de la pose de la caméra. MoveCameran'est écrit qu'à la fin de la fonction (l. 786 après décalage), après lesreturn false: il n'est donc pas touché. La chaîne d'origine (bouton →StartMoveCamera→MoveCamera→ Room avec Maj → rotation) reste intacte.- La caméra n'est pas figée. ZQSD n'est pas coupé (
bGrabbingfaux). - Les « était enfoncé » sont mis à jour avant (l. 603-606) : relâcher Maj bouton tenu ne crée pas de front tardif, donc pas de prise en cours de geste.
- Maj + clic hors couple : inchangé (aucune prise, comme avant).
- Sans Maj : comportement identique à la VAL initiale (le test ajouté vaut faux).
- Cas limite (V7, non bloquant) : Maj appuyé après le début d'une prise. Le test n'existe que pour
CoupleGrabMode == 0, donc la prise continue (le glisser reste cohérent,MoveCamerareste à faux). La rotation d'origine ne démarre alors pas, ce qui est le comportement voulu pour un geste commencé sans Maj.
Section « Reprise » de CAM-B2p-D-IMPL.md (l. 66-77) relue : elle décrit « deux lignes de plus dans la sélection »
et liste D-2 à D-9 comme laissés en l'état. Cohérent avec le diff : 2 lignes de plus (la condition est modifiée en
place), D-2 à D-9 non touchés (leurs lignes sont identiques, décalées de + 2 après la l. 660). Le tableau MD5 en tête
de l'IMPL n'a pas été recontrôlé au-delà de ce qui est donné ici.
Numéros de ligne : après la l. 660, les lignes citées en §§ 2 à 6 sont à lire + 2 (ex. WriteBool(PC, MoveCamera, false)
l. 784 devient l. 786, fin de TickCoupleMouse l. 786 devient 788).
Verdict de la reprise : PASS-STATIC. D-1 levé. Verdict final du lot : PASS-STATIC, aucun défaut bloquant ; D-2 à D-9 non bloquants à observer en V7 ; compilation (COMMUN-8) et essais CAM-58 à CAM-63 à faire.
Fichiers à commiter (dépôt : jeu, branche ue5.8) :
- A
Source/LifePlay/LPCameraModeSubsystem.cpp(MD5D6063264…) - A
Source/LifePlay/LPCameraModeSubsystem.h - A
Docs/Migration/etat/CAM/CAM-B2p-D-IMPL.md - A
Docs/Migration/etat/CAM/CAM-B2p-D-VAL.md(ce livrable)
Tours : 28 / 40