This commit is contained in:
33333-33333 2026-06-27 19:22:38 +09:00
commit 129c07183a
51 changed files with 5711 additions and 1122 deletions

View file

@ -1,4 +1,34 @@
"use strict";
(function ensureDeterministicHelpers(global) {
if (typeof global.deterministicChance === "function" && typeof global.deterministicRange === "function") return;
const clamp01 = v => Math.max(0, Math.min(1, Number(v) || 0));
const keyPart = value => {
if (value == null) return "null";
if (typeof value === "number") return Number.isFinite(value) ? value.toFixed(3) : "nan";
if (typeof value === "string" || typeof value === "boolean") return String(value);
if (typeof value === "object") {
const id = value.familyKey || value.id || value.seed || value.liveToken || value.name;
if (id) return `${value.type || value.constructor?.name || "entity"}:${id}`;
const x = Number.isFinite(value.x) ? value.x.toFixed(1) : "x";
const y = Number.isFinite(value.y) ? value.y.toFixed(1) : "y";
return `${value.type || value.constructor?.name || "entity"}@${x},${y}`;
}
return String(value);
};
const hashUnit = (seed, salt = "") => {
const str = `${seed}:${salt}`;
let h = 2166136261;
for (let i = 0; i < str.length; i++) { h ^= str.charCodeAt(i); h = Math.imul(h, 16777619); }
return ((h >>> 0) % 100000) / 100000;
};
global.deterministicFrame = global.deterministicFrame || ((worldRef = null, hz = 60) => Math.floor((Number(worldRef?.time || 0) || 0) * Math.max(1, Number(hz) || 60) + 1e-6));
global.deterministicUnit = global.deterministicUnit || ((worldRef = null, salt = "", ...parts) => hashUnit(String(worldRef?.worldSeed || "tarinai-world"), [salt, global.deterministicFrame(worldRef, 60), Number(worldRef?._deterministicEpoch || 0) || 0, ...parts.map(keyPart)].join("|")));
global.deterministicRange = global.deterministicRange || ((worldRef = null, salt = "", min = 0, max = 1, ...parts) => (Number(min) || 0) + global.deterministicUnit(worldRef, salt, ...parts) * ((Number(max) || 0) - (Number(min) || 0)));
global.deterministicSigned = global.deterministicSigned || ((worldRef = null, salt = "", ...parts) => global.deterministicUnit(worldRef, salt, ...parts) < 0.5 ? -1 : 1);
global.deterministicChance = global.deterministicChance || ((worldRef = null, salt = "", chance = 0, ...parts) => { const p = clamp01(chance); return p >= 1 || (p > 0 && global.deterministicUnit(worldRef, salt, ...parts) < p); });
global.deterministicAngle = global.deterministicAngle || ((worldRef = null, salt = "", ...parts) => global.deterministicRange(worldRef, salt, 0, Math.PI * 2, ...parts));
})(typeof window !== "undefined" ? window : globalThis);
// Layer: entity-runtime/items/dynamic-system
// Owns pushpin/oshibyo item motion, attachment, lodged damage, and detach
@ -85,7 +115,7 @@
} else {
t.hurtTimer = Math.max(t.hurtTimer || 0, 1.2);
t.fearTimer = Math.max(t.fearTimer || 0, 1.3);
t.setActionState?.("panic", { target: t.panicDestination ? t.panicDestination(item) : { x: t.x + rand(-80, 80), y: t.y + rand(-80, 80) }, reason: "\u753b\u92f2\u304c\u523a\u3055\u3063\u3066\u30d1\u30cb\u30c3\u30af\u306b\u306a\u3063\u3066\u3044\u308b", wake: true });
t.setActionState?.("panic", { target: t.panicDestination ? t.panicDestination(item) : { x: t.x + deterministicRange(worldRef, "pin-panic-target-x", -80, 80, item, t), y: t.y + deterministicRange(worldRef, "pin-panic-target-y", -80, 80, item, t) }, reason: "\u753b\u92f2\u304c\u523a\u3055\u3063\u3066\u30d1\u30cb\u30c3\u30af\u306b\u306a\u3063\u3066\u3044\u308b", wake: true });
if (t.addStress) t.addStress(behavior?.stressOnAttach ?? 18, { threshold: 8 });
}
if (t.damage && (behavior?.damageOnAttach ?? 6) > 0) t.damage(behavior?.damageOnAttach ?? 6, "\u753b\u92f2");
@ -127,12 +157,12 @@
if (t.damage && (behavior?.damagePerTick ?? 1.4) > 0) t.damage(behavior?.damagePerTick ?? 1.4, "\u753b\u92f2");
t.hurtTimer = Math.max(t.hurtTimer || 0, 0.50);
if (t.addStress) t.addStress(behavior?.stressPerTick ?? 2.6, { threshold: 8, duration: 3.4 });
if (Math.random() < 0.22) t.bubble?.("!!", 0.6, "rgba(168,72,72,0.82)");
if (deterministicChance(worldRef, "pin-pain-bubble", 0.22, item, t)) t.bubble?.("!!", 0.6, "rgba(168,72,72,0.82)");
}
t.sleeping = false;
if (t.enterPanic) t.enterPanic({ threat: item, reason: "\u753b\u92f2\u304c\u523a\u3055\u3063\u3066\u30d1\u30cb\u30c3\u30af\u306b\u306a\u3063\u3066\u3044\u308b", fear: 0.65, surpriseTimer: 0.22, awakeLockTimer: 2.4, cause: "pushpin_lodged" });
else {
t.setActionState?.("panic", { target: t.panicDestination ? t.panicDestination(item) : { x: t.x + rand(-80, 80), y: t.y + rand(-80, 80) }, reason: "\u753b\u92f2\u304c\u523a\u3055\u3063\u3066\u30d1\u30cb\u30c3\u30af\u306b\u306a\u3063\u3066\u3044\u308b", wake: true });
t.setActionState?.("panic", { target: t.panicDestination ? t.panicDestination(item) : { x: t.x + deterministicRange(worldRef, "pin-panic-target-x", -80, 80, item, t), y: t.y + deterministicRange(worldRef, "pin-panic-target-y", -80, 80, item, t) }, reason: "\u753b\u92f2\u304c\u523a\u3055\u3063\u3066\u30d1\u30cb\u30c3\u30af\u306b\u306a\u3063\u3066\u3044\u308b", wake: true });
t.fearTimer = Math.max(t.fearTimer || 0, 0.65);
t.surpriseTimer = Math.max(t.surpriseTimer || 0, 0.22);
t.awakeLockTimer = Math.max(t.awakeLockTimer || 0, 2.4);
@ -140,7 +170,7 @@
item.pinFallCheckTimer = (item.pinFallCheckTimer || 0) + dt;
while (item.pinFallCheckTimer >= 1.0) {
item.pinFallCheckTimer -= 1.0;
if (Math.random() < 0.10) {
if (deterministicChance(worldRef, "pin-fall-out", 0.10, item, t)) {
detach(item, worldRef, "fall");
return;
}
@ -174,13 +204,13 @@
item.vy = 0;
item.spinVelocity = 0;
} else {
item.vx = rand(-24, 24);
item.vy = rand(-10, 18);
item.spinVelocity = rand(-1.6, 1.6);
item.spin += rand(-0.25, 0.25);
item.vx = deterministicRange(worldRef, "pin-detach-vx", -24, 24, item, t, reason);
item.vy = deterministicRange(worldRef, "pin-detach-vy", -10, 18, item, t, reason);
item.spinVelocity = deterministicRange(worldRef, "pin-detach-spin-velocity", -1.6, 1.6, item, t, reason);
item.spin += deterministicRange(worldRef, "pin-detach-spin", -0.25, 0.25, item, t, reason);
if (t) {
item.x = clamp(t.x + rand(-(t.radius || 16) * 0.75, (t.radius || 16) * 0.75), CONFIG.worldPadding || 30, (worldRef?.w || item.x) - (CONFIG.worldPadding || 30));
item.y = clamp(t.y + rand((t.radius || 16) * 0.12, (t.radius || 16) * 0.72), CONFIG.worldPadding || 30, (worldRef?.h || item.y) - (CONFIG.worldPadding || 30));
item.x = clamp(t.x + deterministicRange(worldRef, "pin-detach-x", -(t.radius || 16) * 0.75, (t.radius || 16) * 0.75, item, t, reason), CONFIG.worldPadding || 30, (worldRef?.w || item.x) - (CONFIG.worldPadding || 30));
item.y = clamp(t.y + deterministicRange(worldRef, "pin-detach-y", (t.radius || 16) * 0.12, (t.radius || 16) * 0.72, item, t, reason), CONFIG.worldPadding || 30, (worldRef?.h || item.y) - (CONFIG.worldPadding || 30));
}
worldRef?.effects?.push(new Effect("ring", item.x, item.y, { size: Math.max(14, (item.r || 16) * 0.92), life: 0.16, color: "rgba(214,112,112,0.40)" }));
if (reason === "fall" && t) worldRef?.log?.(`${t.name}\u306e\u753b\u92f2\u304c\u629c\u3051\u843d\u3061\u305f\u3002`, "observe", { participants: [t] });