Deferred feel items: true enemy body hit-flash, co-op remote swing arcs, near-impact strike beep

Clears the three follow-ups deferred by the combat-overhaul pass (c3b53cef2) + the
DR-041 "needs its own ShaderGraph slice" note. All client-only, observe-only presentation
(PresentationSystemGroup; no sim mutation, no [GhostField], no server work).

- Item 1: EnemyHitFlashSystem flashes the ACTUAL enemy body by driving the stock
  Entities-Graphics URPMaterialPropertyBaseColor override on the Rukhanka render-entity
  LEG children (root has no MaterialMeshInfo) -- NO ShaderGraph edit, no new component type.
  Lerp white->BodyFlashColor on a Health-decrease edge, decay back to white. Verified on
  screen (the AnimatedLitShader honors the per-instance _BaseColor override).
- Item 2: per-remote-player slash-arc pool in CombatFeedbackSystem, edge-detected from the
  replicated MeleeCombo on interpolated teammates (.WithDisabled<GhostOwnerIsLocal>());
  BuildSlashMesh -> BuildSlashInto(mesh,...) refactor; local player keeps _slashMr.
- Item 3: once-per-windup near-impact strike beep folded into the danger-cone loop, gated
  to a resolved local player.
- 9 new FeelConfig knobs (+ ResetDefaults).

390/390 EditMode, clean compile, zero Play exceptions. 3-lens adversarial review
(wf_8a998c6c-af9) -- no critical/major; fixed 4 minors: spurious beep at base origin before
the local player resolves, frozen tint if BodyFlashEnabled toggles off mid-flash, render-child
capture with no recovery, OnDestroy GO symmetry.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-27 10:51:58 -07:00
parent c3b53cef28
commit 8f96b520d6
5 changed files with 336 additions and 11 deletions
@@ -135,6 +135,27 @@ namespace ProjectM.Client
/// <summary>Seconds a rumble pulse lasts before it auto-stops.</summary>
public static float RumbleDurationSec;
// ---- Deferred-items pass (2026-06): true body hit-flash, remote co-op swings, near-impact strike beep ----
/// <summary>Master gate for the enemy material BODY hit-flash (drives URPMaterialPropertyBaseColor on render children).</summary>
public static bool BodyFlashEnabled;
/// <summary>Peak _BaseColor the enemy body flashes to on a hit (HDR; lerps from the baked white base and decays back).</summary>
public static Color BodyFlashColor;
/// <summary>Seconds the body flash decays from peak back to the baked white base.</summary>
public static float BodyFlashDurationSec;
/// <summary>Master gate for rendering REMOTE teammates' melee cleave arcs (co-op readability).</summary>
public static bool RemoteSwingEnabled;
/// <summary>Tint of a remote teammate's slash arc (cooler/friendlier than the local warm arc).</summary>
public static Color RemoteSlashColor;
/// <summary>Master gate for the near-impact \"dodge NOW\" strike beep on a winding-up enemy.</summary>
public static bool StrikeBeepEnabled;
/// <summary>Volume of the near-impact strike beep.</summary>
public static float StrikeBeepVolume;
/// <summary>Ticks before the strike lands that the beep fires (the dodge-reaction lead).</summary>
public static int StrikeBeepLeadTicks;
/// <summary>Squared world-distance from the local player beyond which the strike beep is suppressed (avoids a distant cacophony).</summary>
public static float StrikeBeepMaxDistSq;
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
public static void ResetDefaults()
{
@@ -201,6 +222,18 @@ namespace ProjectM.Client
RumbleKill = 0.45f;
RumbleHeavy = 0.6f;
RumbleDurationSec = 0.12f;
// Deferred-items pass (2026-06)
BodyFlashEnabled = true;
BodyFlashColor = new Color(3.2f, 2.8f, 2.2f, 1f); // hot near-white overdrive (multiplies the Synty atlas base map)
BodyFlashDurationSec = 0.16f;
RemoteSwingEnabled = true;
RemoteSlashColor = new Color(1.4f, 2.2f, 2.8f, 1f); // cool teammate arc
StrikeBeepEnabled = true;
StrikeBeepVolume = 0.40f;
StrikeBeepLeadTicks = 8;
StrikeBeepMaxDistSq = 225f; // 15 m
}
}
}