tarinai/js/tarinai_update_step_ai.js
2026-07-20 14:36:59 +09:00

52 lines
2.2 KiB
JavaScript

"use strict";
// Layer: entity-runtime/tarinai/update-step
// Owns low-frequency AI cadence, need resolution, item/social interaction scans,
// and facing refresh. Extracted from Tarinai.prototype.update.
(function (global) {
function update(t, dt, context = {}) {
if (!t || t.dead) return { done: true };
if (t.playerHeld || t._heldByPlayer) {
t.aiTimer = 0;
t.target = null;
t.targetKey = "";
t.updateFacing?.();
return { done: false, held: true };
}
t.behaviorLockTimer = Math.max(0, (t.behaviorLockTimer || 0) - dt);
t.aiTimer += dt;
const urgentFoodNeed = Number(t.needRaw?.food ?? t.needs?.food ?? 0) || 0;
const urgentAi = t.fightTimer > 0.04 || t.intimidateTimer > 0.04 || t.intimidatedTimer > 0.04 || t.birthRitualTimer > 0.04 || t.defeatedTimer > 0.04 || t.eatTimer > 0.02 || t.hurtTimer > 0.02 || t.hunger >= 96 || urgentFoodNeed >= 84;
const aiJitter = stableUnit(t.familyKey || t.id, "ai-interval") * 0.35;
context.urgentAi = urgentAi;
const aiInterval = urgentAi ? 0.35 : (1.0 + aiJitter);
if (t.aiTimer >= aiInterval && t.world.spendScheduledWork?.("ai", urgentAi) !== false) {
const elapsedAiDt = Math.max(0.016, Math.min(t.aiTimer, urgentAi ? 0.75 : 1.50));
const scanDt = Math.min(elapsedAiDt, 0.75);
t.aiTimer = 0;
// Needs intentionally advance by a fixed coarse step per AI update.
// Exact elapsed-time integration is unnecessary for this observation game
// and can over-amplify safety/fear transitions when updates are sparse.
const needStepDt = urgentAi ? 0.50 : 1.00;
t.resolveNeeds(needStepDt);
if (global.TarinaiMemorialBellSystem?.updateAi?.(t, scanDt)) {
t.updateFacing();
return { done: false, special: true };
}
const sleepingNow = t.state === "sleep";
if (!sleepingNow) {
t.reactToFreshZunchi(scanDt);
t.updateFacing();
TarinaiItemInteractionSystem.updateOne(t, scanDt);
t.interactWithOthers(scanDt);
} else {
t.updateFacing();
}
} else {
t.updateFacing();
}
return { done: false };
}
global.TarinaiAiUpdateStep = Object.freeze({ update });
})(typeof window !== "undefined" ? window : globalThis);