|
|
|
@ -3792,44 +3792,15 @@ export async function loadOverlayArtMap(
|
|
|
|
* Render a Diablo II 1.13c character cast overlay effect:
|
|
|
|
* Render a Diablo II 1.13c character cast overlay effect:
|
|
|
|
* - Uses authentic baked DCC sprite atlas with additive blending (Trans === 3) when available.
|
|
|
|
* - Uses authentic baked DCC sprite atlas with additive blending (Trans === 3) when available.
|
|
|
|
* - Respects frame anchorX and anchorY offsets to align with caster's origin.
|
|
|
|
* - Respects frame anchorX and anchorY offsets to align with caster's origin.
|
|
|
|
* - Projects a dynamic point light with authentic 1.13c light colors and radius.
|
|
|
|
|
|
|
|
* - Falls back to procedural magic glow in test/offline environments.
|
|
|
|
* - Falls back to procedural magic glow in test/offline environments.
|
|
|
|
|
|
|
|
* - Dynamic lighting/light mask rendering deferred to issue #395.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
export function drawCastOverlay(
|
|
|
|
export function drawCastOverlay(
|
|
|
|
renderer: SpriteRenderer,
|
|
|
|
renderer: SpriteRenderer,
|
|
|
|
overlay: ActiveOverlay,
|
|
|
|
overlay: ActiveOverlay,
|
|
|
|
overlayArt?: LoadedOverlayArt,
|
|
|
|
overlayArt?: LoadedOverlayArt,
|
|
|
|
): void {
|
|
|
|
): void {
|
|
|
|
// 1. Dynamic point light halo (1.13c colors & radius)
|
|
|
|
// 1. Sprite animation with additive blending
|
|
|
|
const [r255, g255, b255] = overlay.lightColor
|
|
|
|
|
|
|
|
const r = r255 / 255
|
|
|
|
|
|
|
|
const g = g255 / 255
|
|
|
|
|
|
|
|
const b = b255 / 255
|
|
|
|
|
|
|
|
const radius = overlay.lightRadius > 0 ? overlay.lightRadius * 5 : 45
|
|
|
|
|
|
|
|
const progress = Math.min(1, Math.max(0, overlay.frame / overlay.maxFrames))
|
|
|
|
|
|
|
|
const intensity = Math.sin(progress * Math.PI) * 0.35 + 0.15
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (intensity > 0.01) {
|
|
|
|
|
|
|
|
renderer.drawSolid(
|
|
|
|
|
|
|
|
overlay.x - radius,
|
|
|
|
|
|
|
|
overlay.y - radius,
|
|
|
|
|
|
|
|
radius * 2,
|
|
|
|
|
|
|
|
radius * 2,
|
|
|
|
|
|
|
|
[r, g, b, intensity * 0.25],
|
|
|
|
|
|
|
|
{ blendMode: 'additive' },
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
const coreRadius = radius * 0.5
|
|
|
|
|
|
|
|
renderer.drawSolid(
|
|
|
|
|
|
|
|
overlay.x - coreRadius,
|
|
|
|
|
|
|
|
overlay.y - coreRadius,
|
|
|
|
|
|
|
|
coreRadius * 2,
|
|
|
|
|
|
|
|
coreRadius * 2,
|
|
|
|
|
|
|
|
[r, g, b, intensity * 0.5],
|
|
|
|
|
|
|
|
{ blendMode: 'additive' },
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 2. Sprite animation with additive blending
|
|
|
|
|
|
|
|
if (overlayArt !== undefined) {
|
|
|
|
if (overlayArt !== undefined) {
|
|
|
|
const frameCount = Math.max(1, overlayArt.meta.framesPerDirection || overlayArt.meta.frames)
|
|
|
|
const frameCount = Math.max(1, overlayArt.meta.framesPerDirection || overlayArt.meta.frames)
|
|
|
|
const frameIndex = Math.min(Math.max(0, Math.floor(overlay.frame)), frameCount - 1)
|
|
|
|
const frameIndex = Math.min(Math.max(0, Math.floor(overlay.frame)), frameCount - 1)
|
|
|
|
@ -3844,7 +3815,11 @@ export function drawCastOverlay(
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 3. Fallback procedural representation in test/offline environments
|
|
|
|
// 2. Fallback procedural representation in test/offline environments
|
|
|
|
|
|
|
|
const [r255, g255, b255] = overlay.lightColor
|
|
|
|
|
|
|
|
const r = r255 / 255
|
|
|
|
|
|
|
|
const g = g255 / 255
|
|
|
|
|
|
|
|
const b = b255 / 255
|
|
|
|
const fallbackRadius = 16
|
|
|
|
const fallbackRadius = 16
|
|
|
|
renderer.drawSolid(
|
|
|
|
renderer.drawSolid(
|
|
|
|
overlay.x - fallbackRadius,
|
|
|
|
overlay.x - fallbackRadius,
|
|
|
|
|