Commit Graph

40 Commits

Author SHA1 Message Date
Tom Boullay d29b01e398 feat(repair): broken parts spawn from exploded model node positions
🔍 Lint / 🪄 Check lint (push) Has been cancelled
🔍 Lint / 🎨 Check format (push) Has been cancelled
🔍 Lint / 🔎 Typecheck (push) Has been cancelled
📊 Quality / 🔒 Security Audit (push) Has been cancelled
📊 Quality / 📋 Dependency Freshness (push) Has been cancelled
📊 Quality / 📦 Bundle Size (push) Has been cancelled
🔍 Lint / 🏗 Build (push) Has been cancelled
Render the exploded mission model during the repairing step so broken
nodes (e.g. ebike refroidisseur) stay visible in the world, and surface
their world positions to RepairRepairingStep so broken pieces spawn
from where they belong on the model rather than from a static offset.

- ExplodableModel: add hideNodeNames (mesh visibility off, restored on
  unmount) and nodeAnchorNames + onNodeAnchorsChange (per-frame world
  positions debounced via signature so React state updates only when
  the values actually move).
- RepairGame: render ExplodableModel during 'repairing' with the broken
  node names hidden + anchors forwarded; threads brokenAnchors state
  to RepairRepairingStep.
- RepairScanSequence + RepairRepairingStep: propagate targetNodeName
  through scanned and fallback broken-part lists.
- RepairRepairingStep: broken parts spawn at brokenAnchors[targetNodeName]
  when set, falling back to legacy BROKEN_PART_START_OFFSETS otherwise.
2026-06-02 19:12:38 +02:00
Tom Boullay 5b123f9704 feat(repair): soft-lock mutually exclusive replacement parts
When a replacement part with a caseLockGroup is grabbed, sibling parts
sharing the same group become non-interactable and ghosted (35% opacity)
until the held part is released. This implements the pylon cable choice
where the player picks either cable1 or cable2 (both valid) without
being able to grab both simultaneously.

- GrabbableObject: add disabled prop (skips interaction frame logic and
  unmounts InteractableObject so it does not register with the manager)
  and onGrabChange callback fired on press, release, hand grab, and hand
  release. Force-releases when disabled becomes true mid-grab.
- SimpleModel: add opacity prop, traversed onto cloned mesh materials
  (safe because cloneResources clones materials per instance).
- RepairObjectModel: forward ghosted prop as opacity 0.35.
- RepairRepairingStep: track heldPartByLockGroup and pass disabled +
  ghosted to siblings of the currently held part.
2026-06-02 18:46:34 +02:00
Tom Boullay d1bf438465 feat(repair): inject ebike + pylon parts at packderelance anchors
- Ebike replacement parts: cooling core (correct, anchored at refroidisseur)
  + four distractors anchored at cabledroit/cablegauche/pucehaut/pucebas.
  Removes the ad-hoc gant_l/talkie distractors in favor of consistent
  case-anchored visuals.
- Pylon replacement parts: cable1 + cable2 (alternative correct, both with
  caseLockGroup 'pylon-cable' for upcoming soft-lock) + refroidisseur and
  two puce distractors anchored to packderelance.
- Farm replacement parts kept as-is (caseAnchor undefined falls back to
  placeholder slot positions for backward compatibility).
- RepairGame threads anchors from RepairCaseModel through RepairMissionCase
  to RepairRepairingStep; replacement-part initial position now resolves
  to the anchor world position when caseAnchor is set, falling back to the
  legacy slot index otherwise.
2026-06-02 18:37:12 +02:00
Tom Boullay d2ce990165 feat(repair): support multiple required parts and per-part case anchor
- RepairMissionConfig.requiredReplacementPartId (string) is replaced by
  requiredReplacementPartIds (readonly string[]) so a mission can accept
  several alternative correct parts (e.g. pylon will accept either cable).
- RepairMissionPartConfig gains optional caseAnchor (where the standalone
  spawns inside packderelance), caseLockGroup (mutually exclusive parts),
  and targetNodeName (snap onto a node of the broken model rather than a
  placeholder slot in the case).
- RepairScannedBrokenPart gains targetNodeName so scan results can carry
  this hint through to the repairing step.
- RepairRepairingStep validation logic (placed/wrong/feedback) now matches
  any id in requiredReplacementPartIds. Existing data is migrated mechanically
  (single-element arrays); part-level new fields are wired in subsequent
  commits.
2026-06-02 18:26:45 +02:00
Tom Boullay 7d2a257e84 feat(repair): expose case part anchors and fix lid node name
- Fix REPAIR_CASE_LID_NODE_NAME from "partiesup" to "partsup" (the actual
  node name in packderelance.gltf), restoring the lid open/close animation
  that was silently no-oping since introduction.
- Add REPAIR_CASE_PART_ANCHOR_NAMES (cabledroit, cablegauche, pucehaut,
  pucebas, refroidisseur) and REPAIR_CASE_PART_ANCHOR_FALLBACKS for
  case-local positions used when the GLTF lacks a node (refroidisseur).
- RepairCaseModel now resolves these anchor nodes on mount, hides existing
  meshes underneath them, and creates lightweight Object3D placeholders for
  missing names so the anchoring pipeline is uniform.
- Each frame, anchor world positions are converted to step-local space and
  emitted via the new onAnchorsChange callback (debounced via signature like
  placeholders). Consumers added in subsequent commits.
2026-06-02 18:20:43 +02:00
Tom Boullay bff8a16290 feat(intro): add ebike onboarding sequence
🔍 Lint / 🪄 Check lint (pull_request) Has been cancelled
🔍 Lint / 🎨 Check format (pull_request) Has been cancelled
🔍 Lint / 🔎 Typecheck (pull_request) Has been cancelled
📊 Quality / 🔒 Security Audit (pull_request) Has been cancelled
📊 Quality / 📋 Dependency Freshness (pull_request) Has been cancelled
📊 Quality / 📦 Bundle Size (pull_request) Has been cancelled
🔍 Lint / 🏗 Build (pull_request) Has been cancelled
2026-05-31 10:42:46 +02:00
tom-boullay d9cf87d2d6 feat: launch ebike repair from map interaction
🔍 Lint / 🪄 Check lint (pull_request) Has been cancelled
🔍 Lint / 🎨 Check format (pull_request) Has been cancelled
🔍 Lint / 🔎 Typecheck (pull_request) Has been cancelled
📊 Quality / 🔒 Security Audit (pull_request) Has been cancelled
📊 Quality / 📋 Dependency Freshness (pull_request) Has been cancelled
📊 Quality / 📦 Bundle Size (pull_request) Has been cancelled
🔍 Lint / 🏗 Build (pull_request) Has been cancelled
2026-05-28 10:13:59 +02:00
Tom Boullay d654565f87 chore: address code quality audit findings
🔍 Lint / 🪄 Check lint (pull_request) Has been cancelled
🔍 Lint / 🎨 Check format (pull_request) Has been cancelled
🔍 Lint / 🔎 Typecheck (pull_request) Has been cancelled
📊 Quality / 🔒 Security Audit (pull_request) Has been cancelled
📊 Quality / 📋 Dependency Freshness (pull_request) Has been cancelled
📊 Quality / 📦 Bundle Size (pull_request) Has been cancelled
🔍 Lint / 🏗 Build (pull_request) Has been cancelled
2026-05-28 08:31:42 +02:00
Tom Boullay 8088e67625 fix: a pb with octree 2026-05-11 16:41:11 +02:00
Tom Boullay cec4d6ad0d update: reset repair runtime state 2026-05-11 13:01:32 +02:00
Tom Boullay 202ac4628d fix: sequence repair case completion exit 2026-05-11 12:58:37 +02:00
Tom Boullay 40368c22fc add: blocked repair install feedback 2026-05-11 12:56:54 +02:00
Tom Boullay 788e9f0fb3 update: feedback repair model and improve repair case interaction feedback 2026-05-11 12:54:54 +02:00
Tom Boullay 72f8acb61c Update RepairCaseModel.tsx 2026-05-11 12:48:38 +02:00
Tom Boullay 7036b7b0f9 fix: preload repair mission assets 2026-05-11 11:47:20 +02:00
Tom Boullay e16d6e15fa fix repair game suspense boundaries 2026-05-11 11:37:54 +02:00
Tom Boullay 33524f8409 add: reusable world video prompt billboard 2026-05-09 01:28:06 +01:00
Tom Boullay e0eae67ace fix repair game interaction coordinate spaces 2026-05-09 01:19:16 +01:00
Tom Boullay 6d9eac291e big clean up 2026-05-08 03:02:26 +01:00
Tom Boullay e4f6ec211c add: configure mission-specific repair variants 2026-05-08 02:41:57 +01:00
Tom Boullay ead3634aab add: animate repair reassembly 2026-05-08 02:40:31 +01:00
Tom Boullay 19a83982a9 add: require broken part deposit before repair 2026-05-08 02:36:14 +01:00
Tom Boullay bebb9ac5a3 add: snap repair parts to case placeholders 2026-05-08 02:33:06 +01:00
Tom Boullay d02ef54bdc add: focus repair case view 2026-05-08 02:22:15 +01:00
Tom Boullay 0256dfa812 add: show broken part prompt during scan 2026-05-08 02:18:00 +01:00
Tom Boullay 5c688fdaf7 add: highlight broken repair parts during scan 2026-05-08 02:16:13 +01:00
Tom Boullay 7a3baa4c0b add: scan fragmented repair parts sequentially 2026-05-08 02:12:58 +01:00
Tom Boullay 95d9bd4f3e add: animation on repair case 2026-05-08 02:10:19 +01:00
Tom Boullay eee69825c6 clean: remove obsolete repair debug code + unused core utilities 2026-05-08 02:07:03 +01:00
Tom Boullay 15c3d1858f add: repair mission completion step 2026-05-08 01:48:40 +01:00
Tom Boullay 7ee842c535 update: validate correct repair replacement part 2026-05-08 01:47:07 +01:00
Tom Boullay d4f215a948 update: require replacement placement before repair completion 2026-05-08 01:45:00 +01:00
Tom Boullay 7bbcf4359e add: repair install completion step 2026-05-08 01:41:29 +01:00
Tom Boullay eed0077dd1 add: repair fragmentation and scan flow 2026-05-08 01:39:23 +01:00
Tom Boullay ed60114d06 add: repair game inspection sub state 2026-05-08 01:27:32 +01:00
Tom Boullay 1d64582383 feat add model loading diagnostics 2026-05-02 00:14:47 +02:00
Tom Boullay bb08054722 connect repair gameplay to zustand progression 2026-04-30 16:25:54 +02:00
Tom Boullay cfb1eaf39a refactor: clean architecture and remove unused code 2026-04-30 13:33:28 +02:00
Tom Boullay b1187b68ae refactor: split hooks types and utils by domain 2026-04-30 11:49:18 +02:00
Tom Boullay 9ac5844182 refactor: organize three components by domain 2026-04-30 11:35:53 +02:00