This commit is contained in:
33333-33333 2026-06-25 14:51:58 +09:00
commit 434f07cc4e
103 changed files with 8387 additions and 8152 deletions

View file

@ -7,11 +7,14 @@
Object.defineProperties(Tarinai.prototype, Object.getOwnPropertyDescriptors({
setActionState(state, opts = {}) {
if (this.dead) return false;
const wasSleeping = this.state === "sleep" || this.sleeping;
const nextState = state || "idle";
this.state = nextState;
if ("target" in opts) this.target = opts.target;
if (opts.reason != null) this.thought = String(opts.reason || "");
if (opts.clearTarget) this.target = null;
const wakingNow = Boolean(opts.wake) || (wasSleeping && nextState !== "sleep" && opts.sleeping === false);
if (wakingNow) this.consumePendingGrassBedOnWake?.(opts.reason || "wake");
if (opts.sleeping != null) this.sleeping = Boolean(opts.sleeping);
if (opts.wake) {
this.sleeping = false;
@ -20,6 +23,63 @@
this.insideNestBoxId = "";
}
if (nextState !== "sleep" && opts.sleeping === false) this.sleepSession = null;
const reason = String(opts.reason ?? this.thought ?? "");
if (nextState === "idle") {
if (typeof clearBehavior === "function") clearBehavior(this, reason || "待っている");
else if (typeof clearTarinaiBehavior === "function") clearTarinaiBehavior(this, { clearTarget: !!opts.clearTarget });
return true;
}
const stateActionIds = {
seek_food: "eat_food",
eat: "eat_food",
seek_water: "drink_water",
seek_bed: "sleep_in_bed",
sleep: "sleep_anywhere",
panic: "panic_escape",
flee: "flee",
fight: "fight_rival",
intimidate: "intimidate_enemy",
birth_ritual: "birth_ritual",
sunbath: "sunbath",
wander: "wander_lightly",
play_ball: "play",
seek_material: "seek_material",
seek_enemy: "fight_rival",
build: "build_structure",
};
const actionId = String(opts.actionId || opts.behaviorId || stateActionIds[nextState] || nextState);
const target = opts.clearTarget ? null : ("target" in opts ? opts.target : this.target);
const phase = opts.phase || (nextState === "sleep" || nextState === "eat" || nextState === "fight" || nextState === "intimidate" || nextState === "birth_ritual" || nextState === "sunbath" ? "acting" : "approaching");
if (typeof setBehaviorText === "function") {
setBehaviorText(this, {
need: opts.need || null,
subNeed: opts.subNeed || "",
actionId,
actionLabel: opts.actionLabel || reason || nextState,
reasonText: reason || opts.actionLabel || nextState,
target,
phase,
source: opts.source || "state",
forced: opts.forced || null,
forcedId: opts.forcedId || "",
sourceReasonText: opts.sourceReasonText || opts.forcedReasonText || "",
causeText: opts.causeText || "",
});
} else if (typeof patchTarinaiBehavior === "function") {
patchTarinaiBehavior(this, {
actionId,
phase,
target,
source: opts.source || "state",
reason,
label: opts.actionLabel || reason || nextState,
text: reason || opts.actionLabel || nextState,
need: opts.need || "fulfill",
subNeed: opts.subNeed || "",
});
}
return true;
},
@ -30,7 +90,7 @@
reason: text,
sleeping: false,
});
if (typeof setLiveActionText === "function") setLiveActionText(this, { need: "food", actionId: "eat_food", actionLabel: "\u98df\u3079\u3066\u3044\u308b", reasonText: text, target: item || null, phase: "perform", source: "behavior" });
if (typeof setBehaviorText === "function") setBehaviorText(this, { need: "food", actionId: "eat_food", actionLabel: "\u98df\u3079\u3066\u3044\u308b", reasonText: text, target: item || null, phase: "perform", source: "behavior" });
return ok;
},
@ -48,8 +108,7 @@
},
goIdle(reason = "") {
if (typeof clearActiveBehavior === "function") clearActiveBehavior(this, reason || this.thought || "\u5f85\u3063\u3066\u3044\u308b");
return this.setActionState("idle", { target: null, reason: reason || this.thought || "\u5f85\u3063\u3066\u3044\u308b", sleeping: false });
return this.setActionState("idle", { target: null, reason: reason || this.thought || "\u5f85\u3063\u3066\u3044\u308b", wake: this.state === "sleep" || this.sleeping, sleeping: false });
},
startSleeping(target = null, reason = "") {
@ -62,13 +121,38 @@
targetEnergy: inFurniture ? rand(84, 94) : rand(74, 86),
maxDuration: inFurniture ? rand(42, 68) : rand(28, 48),
targetId: target?.id || null,
consumesGrassBedOnWake: target?.type === "grass_bed",
};
}
if (target?.type === "grass_bed") {
this.sleepSession.targetId = target.id || this.sleepSession.targetId || null;
this.sleepSession.consumesGrassBedOnWake = true;
this.pendingGrassBedWakeId = target.id || this.pendingGrassBedWakeId || "";
target.singleUsePending = true;
target.singleUseConsumedById = this.id || target.singleUseConsumedById || "";
target.singleUseWakeReason = "sleep";
}
const text = reason || (target?.type === "nest_box" ? "\u5de3\u7bb1\u306e\u4e2d\u3067\u7720\u3063\u3066\u3044\u308b" : "\u7720\u3063\u3066\u3044\u308b");
if (typeof setLiveActionText === "function") setLiveActionText(this, { need: "sleep", actionId: target ? "sleep_in_bed" : "sleep_anywhere", actionLabel: "\u7720\u3063\u3066\u3044\u308b", reasonText: text, target, phase: "perform", source: "behavior" });
if (typeof setBehaviorText === "function") setBehaviorText(this, { need: "sleep", actionId: target ? "sleep_in_bed" : "sleep_anywhere", actionLabel: "\u7720\u3063\u3066\u3044\u308b", reasonText: text, target, phase: "perform", source: "behavior" });
return this.setActionState("sleep", { target, reason: text, sleeping: true });
},
consumePendingGrassBedOnWake(reason = "wake") {
const worldRef = this.world || null;
const sessionTargetId = this.sleepSession?.targetId || this.pendingGrassBedWakeId || null;
const bySession = sessionTargetId && worldRef?.itemById ? worldRef.itemById(sessionTargetId) : null;
const byItems = sessionTargetId ? (worldRef?.items || []).find(it => it && it.id === sessionTargetId) : null;
const candidates = [this.target, bySession, byItems];
let bed = candidates.find(it => it && !it.dead && it.type === "grass_bed" && (it.singleUsePending || it.singleUseConsumedById === this.id || (this.sleepSession?.consumesGrassBedOnWake && it.id === sessionTargetId)));
if (!bed && (this.sleepSession?.consumesGrassBedOnWake || sessionTargetId)) {
bed = (worldRef?.items || []).find(it => it && !it.dead && it.type === "grass_bed"
&& (it.id === sessionTargetId || (it.singleUsePending && (it.singleUseConsumedById === this.id || it.ownerId === this.id))));
}
if (!bed) return false;
this.pendingGrassBedWakeId = "";
return window.TarinaiStructureLifecycle?.consumeGrassBedOnWake?.(worldRef, bed, this, reason) || false;
},
seekTarget(state, target = null, reason = "") {
return this.setActionState(state, { target, reason, sleeping: false });
},
@ -79,7 +163,7 @@
},
currentBehaviorText() {
if (typeof activeBehaviorText === "function") return activeBehaviorText(this);
if (typeof behaviorText === "function") return behaviorText(this);
return String((typeof getTarinaiBehaviorText === "function" ? getTarinaiBehaviorText(this) : "") || this.thought || "").trim();
},
@ -111,9 +195,9 @@
wake: opts.wake !== false,
sleeping: false,
});
if (typeof setLiveActionText === "function") {
if (typeof setBehaviorText === "function") {
const causeText = this.lastPanicDetail || (String(panicReason).includes("\u3001") ? String(panicReason).split("\u3001")[0].replace(/\u3066$/, "\u305f") : "\u6016\u3044");
setLiveActionText(this, { need: "safety", actionId: "panic_escape", actionLabel: "\u30d1\u30cb\u30c3\u30af\u306b\u306a\u3063\u3066\u3044\u308b", reasonText: panicReason, causeText, target, phase: "perform", source: "behavior" });
setBehaviorText(this, { need: "safety", actionId: "panic_escape", actionLabel: "\u30d1\u30cb\u30c3\u30af\u306b\u306a\u3063\u3066\u3044\u308b", reasonText: panicReason, causeText, target, phase: "perform", source: "behavior" });
}
this.fearTimer = Math.max(this.fearTimer || 0, 2.4);
}
@ -127,6 +211,8 @@
if (opts.bubble) this.bubble?.(opts.bubble, opts.bubbleCooldown ?? 0.9, opts.bubbleColor || "rgba(84,66,86,0.80)");
this.lastPanicCause = opts.cause || opts.reason || this.thought || "panic";
this.lastPanicAt = this.world?.time || 0;
if (this.state === "panic" && !Number.isFinite(this.panicStartedAt)) this.panicStartedAt = this.lastPanicAt;
if (this.state === "panic") this.panicHardStopAt = Math.max(this.panicHardStopAt || 0, this.lastPanicAt + 7.5);
return true;
},
}));