This commit is contained in:
33333-33333 2026-06-26 19:04:32 +09:00
commit 077d4ab9ac
71 changed files with 2905 additions and 1063 deletions

View file

@ -2,12 +2,16 @@
// Layer: entity-runtime/items/dynamic-system
// Owns zunchi item motion, high-speed collision, and lifecycle stage ticking.
// Prototype methods remain as compatibility facades.
// Prototype methods delegate here.
(function (global) {
function updateMotion(item, dt, worldRef) {
if (!item || item.dead || item.type !== "zunchi") return false;
const speed = Math.hypot(item.vx || 0, item.vy || 0);
if (speed < 0.08) { item.vx = 0; item.vy = 0; return true; }
if (speed < 0.08) {
item.vx = 0; item.vy = 0;
global.TarinaiItemDynamicBallSystem?.resolveObstacleCollisions?.(item, dt, worldRef);
return true;
}
if (global.TarinaiPhysics?.applyKinematicItemMotion) {
global.TarinaiPhysics.applyKinematicItemMotion(item, worldRef, dt, { bounce: 0.34, frictionBase: 0.68, frictionRate: 2.4, spin: false, stopSpeed: 0.08 });
} else {
@ -25,6 +29,7 @@
item.vy *= slow;
worldRef.drawListDirty = true;
}
global.TarinaiItemDynamicBallSystem?.resolveObstacleCollisions?.(item, dt, worldRef);
resolveHighSpeedTarinaiCollision(item, dt, worldRef, speed);
item.spin = (item.spin || 0) + speed * dt / Math.max(8, item.r || 14);
return true;
@ -46,6 +51,10 @@
const impulse = clamp(speed * 1.15, 150, 620);
t.vx = (t.vx || 0) + nx * impulse + rand(-20, 20);
t.vy = (t.vy || 0) + ny * impulse * 0.72 + rand(-18, 10);
if (speed >= 185) {
const damage = Math.min(18, Math.max(1, (speed - 185) / 22));
worldRef.applyImpactDamage?.(t, damage, "衝突", { source: item }) || t.damage?.(damage, "衝突");
}
t.fallTimer = Math.max(t.fallTimer || 0, 0.85);
t.fallMax = Math.max(t.fallMax || 0.85, t.fallTimer);
t.fallDir = nx < 0 ? -1 : 1;
@ -68,15 +77,18 @@
if (!item || item.dead || item.type !== "zunchi") return false;
const rainy = worldRef.weather === "light_rain";
const rainBoost = rainy ? 1.28 : 1;
const decayBoost = rainy ? 1.35 : 1;
const groundId = worldRef?.groundType || "soil";
const stageMul = Math.max(0.1, Number(global.TarinaiGround?.zunchiStageMultiplier?.(groundId) || 1) || 1);
const groundDecayMul = Math.max(0.1, Number(global.TarinaiGround?.zunchiDecayMultiplier?.(groundId) || 1) || 1);
const decayBoost = (rainy ? 1.35 : 1) * groundDecayMul;
let waterBoost = 0;
const nearby = worldRef.nearbyItems ? worldRef.nearbyItems(item.x, item.y, 84) : (worldRef.items || []);
for (const it of nearby) {
if (it.type !== "water") continue;
waterBoost += clamp(1 - distXY(item.x, item.y, it.x, it.y) / 80, 0, 1);
}
item.stageTimer += dt * 0.70 * (rainBoost + waterBoost * 0.65);
const decayDt = (item.spawnGrace || 0) > 0 ? 0 : dt;
item.stageTimer += dt * 0.70 * stageMul * (rainBoost + waterBoost * 0.65);
const decayDt = ((item.spawnGrace || 0) > 0 && groundDecayMul <= 1.01) ? 0 : dt;
if (item.stage === "fresh") {
item.freshness = clamp(1 - item.stageTimer / 110, 0, 1);
item.amount -= decayDt * 0.018 * decayBoost;