tarinai/js/impact_core_system.js
2026-07-10 16:40:06 +09:00

51 lines
2.2 KiB
JavaScript

"use strict";
// Layer: physics/impact-core
// Shared impact constants and link-attachment helpers used by drop impacts,
// ball collisions, and high-speed tarinai collisions.
(function (global) {
const PHYSICAL_DAMAGE_SPEED_THRESHOLD = 165;
function physicalDamageFromImpactSpeed(speed = 0, { min = 0, max = 58, scale = 8.6 } = {}) {
const v = Math.max(0, Number(speed) || 0);
if (v < PHYSICAL_DAMAGE_SPEED_THRESHOLD) return 0;
const raw = (v - PHYSICAL_DAMAGE_SPEED_THRESHOLD) / Math.max(1, scale);
return clamp(raw, min, max);
}
function linkEndpointMatchesItem(endpoint, item) {
if (!endpoint || !item) return false;
if (endpoint.kind && endpoint.kind !== "item") return false;
if (endpoint.id && item.id && endpoint.id === item.id) return true;
const dx = Number(endpoint.x) - Number(item.x || 0);
const dy = Number(endpoint.y) - Number(item.y || 0);
return Number.isFinite(dx) && Number.isFinite(dy) && Math.hypot(dx, dy) <= Math.max(14, (item.r || 18) * 0.75);
}
function itemHasAttachedLink(worldRef, item) {
if (!worldRef || !item || !item.id) return false;
const pb = global.TarinaiPhysicsBodySystem || null;
const links = [];
if (worldRef.itemsOfType) {
for (const linkType of ["rope", "rod", "spring"]) {
for (const link of worldRef.itemsOfType(linkType) || []) if (link && !link.dead) links.push(link);
}
} else {
for (const link of worldRef.items || []) if (link && !link.dead && ["rope", "rod", "spring"].includes(link.type)) links.push(link);
}
for (const link of links) {
const endpoints = [pb?.endpoint?.(link, 0), pb?.endpoint?.(link, 1)];
const fallback = link.physicsConstraint?.endpoints || link.constraint?.endpoints || [];
if (!endpoints[0] && fallback[0]) endpoints[0] = fallback[0];
if (!endpoints[1] && fallback[1]) endpoints[1] = fallback[1];
if (linkEndpointMatchesItem(endpoints[0], item) || linkEndpointMatchesItem(endpoints[1], item)) return true;
}
return false;
}
global.TarinaiImpactCoreSystem = Object.freeze({
PHYSICAL_DAMAGE_SPEED_THRESHOLD,
physicalDamageFromImpactSpeed,
itemHasAttachedLink,
});
})(typeof window !== "undefined" ? window : globalThis);