2026-06-26 12:46:32 +09:00
|
|
|
"use strict";
|
|
|
|
|
|
|
|
|
|
// Non-eating contact effects for water, sleep furniture, toys, stains, and traces.
|
|
|
|
|
|
|
|
|
|
(function (global) {
|
|
|
|
|
function updateCandidate(tarinai, ctx, it, dt = 0) {
|
|
|
|
|
if (!tarinai || tarinai.dead || !ctx || !it || it.dead) return false;
|
|
|
|
|
const { foodActionActive = false } = ctx;
|
|
|
|
|
|
2026-06-30 22:30:37 +09:00
|
|
|
const ceremonialContact = it.type === "slave_chain" || it.type === "golden_crown";
|
2026-07-01 14:41:05 +09:00
|
|
|
const contact = global.TarinaiItemInteractionContext.contactForCandidate(tarinai, ctx, it, {
|
|
|
|
|
role: ceremonialContact ? "medicine" : "food",
|
|
|
|
|
activeTargetBonus: it?.type === "duplicator" ? 0 : (ceremonialContact ? 10 : 4),
|
|
|
|
|
});
|
|
|
|
|
if (!contact) return false;
|
|
|
|
|
const d = contact.distance;
|
2026-06-30 13:40:36 +09:00
|
|
|
|
2026-06-30 22:30:37 +09:00
|
|
|
if (ceremonialContact) {
|
|
|
|
|
const itemLabel = typeof toolLabel === "function" ? toolLabel(it.type) : (it.type === "slave_chain" ? "\u5974\u96B7\u306E\u9396" : "\u9EC4\u91D1\u306E\u51A0");
|
2026-06-30 13:40:36 +09:00
|
|
|
if (it.type === "slave_chain") {
|
|
|
|
|
tarinai.isTarinaiChampion = false;
|
|
|
|
|
tarinai.tarinaiChampionSince = 0;
|
|
|
|
|
tarinai.becomeZunchiSlave?.({ locked: true, forcedItem: true });
|
2026-06-30 22:30:37 +09:00
|
|
|
tarinai.bubble("\u9396", 2.4, "rgba(74,64,56,0.82)");
|
|
|
|
|
tarinai.world?.log?.(`${tarinai.name}\u306F${itemLabel}\u306B\u89E6\u308C\u3066\u305A\u3093\u3061\u3069\u308C\u3044\u306B\u306A\u3063\u305F\u3002`, "event", { participants: [tarinai], sound: false });
|
2026-06-30 13:40:36 +09:00
|
|
|
} else {
|
|
|
|
|
tarinai.becomeTarinaiChampion?.({ force: true, forcePersonality: true, forcedItem: true });
|
2026-06-30 22:30:37 +09:00
|
|
|
tarinai.bubble("\u738B", 2.4, "rgba(166,112,22,0.84)");
|
|
|
|
|
tarinai.world?.log?.(`${tarinai.name}\u306F${itemLabel}\u306B\u89E6\u308C\u3066\u305F\u308A\u306A\u3044\u738B\u306B\u306A\u3063\u305F\u3002`, "event", { participants: [tarinai], sound: false });
|
2026-06-30 13:40:36 +09:00
|
|
|
}
|
2026-06-30 22:30:37 +09:00
|
|
|
global.TarinaiStructureLifecycle?.deleteItem?.(tarinai.world, it, { reason: `consumed-${it.type}`, userReason: `${itemLabel}\u304C\u4F7F\u308F\u308C\u305F`, wake: false, panicOwner: false });
|
2026-06-30 13:40:36 +09:00
|
|
|
tarinai.world?.recordFamily?.(tarinai);
|
|
|
|
|
tarinai.world?.markFamilyTreeDirty?.(`consume-${it.type}`);
|
|
|
|
|
if (global.uiCache) global.uiCache.selectedSnapshot = "";
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-27 21:50:05 +09:00
|
|
|
if (it.type === "water") {
|
|
|
|
|
tarinai.thought = "\u6c34\u3092\u6d74\u3073\u3066\u843d\u3061\u7740\u3044\u3066\u3044\u308b";
|
2026-06-26 12:46:32 +09:00
|
|
|
tarinai.target = it;
|
|
|
|
|
tarinai.applyWaterEffect(dt, it.type);
|
|
|
|
|
if ((tarinai.world?.time || 0) > (tarinai.nextDrinkSound || -999)) {
|
|
|
|
|
audio.play?.("sfx_drink", { category: "ops", minGap: 0.20 });
|
|
|
|
|
tarinai.nextDrinkSound = (tarinai.world?.time || 0) + 0.72;
|
|
|
|
|
}
|
|
|
|
|
if (it.type === "water") it.amount -= dt * 2.4;
|
|
|
|
|
if (tarinai.type === "teary" || tarinai.type === "cry") tarinai.affection += dt * 0.18;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (it.type === "stone") {
|
|
|
|
|
if (tarinai.state === "idle" && tarinai.stress > 48) tarinai.thought = "\u77f3\u306e\u8fd1\u304f\u3067\u843d\u3061\u7740\u3044\u3066\u3044\u308b";
|
|
|
|
|
applyNeedRelief(tarinai, { safety: -dt * 4, fulfill: -dt * 2 });
|
|
|
|
|
tarinai.energy += dt * 0.18;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (tarinai.isSleepFurniture(it)) {
|
|
|
|
|
if (tarinai.energy < 74 + 6 * tarinai.personalityProfile().sleep) {
|
|
|
|
|
const isEasyBed = it.type === "grass_bed";
|
|
|
|
|
const occ = tarinai.world.bedOccupancy(it);
|
|
|
|
|
const comfort = tarinai.world.bedComfort(it);
|
|
|
|
|
it.use?.(tarinai, tarinai.world, isEasyBed ? { purpose: "sleep" } : undefined);
|
|
|
|
|
tarinai.startSleeping?.(it, it.type === "nest_box" ? "\u5de3\u7bb1\u306e\u4e2d\u3067\u4f11\u3093\u3067\u3044\u308b" : (isEasyBed ? "\u304b\u3093\u305f\u3093\u30d9\u30c3\u30c9\u3067\u5bdd\u3066\u3044\u308b" : "\u30d9\u30c3\u30c9\u3067\u4f11\u3093\u3067\u3044\u308b"));
|
|
|
|
|
if (tarinai.world.time > tarinai.nextSleepBubbleAt) {
|
|
|
|
|
tarinai.nextSleepBubbleAt = tarinai.world.time + 4.5;
|
|
|
|
|
tarinai.world.spawnBubble(tarinai.x, tarinai.y - tarinai.radius * 1.18, "Zzz...", "rgba(65,70,92,0.72)");
|
|
|
|
|
}
|
|
|
|
|
tarinai.energy += dt * (1.9 + comfort * 1.4);
|
|
|
|
|
if (occ > 5) applyNeedShock(tarinai, { safety: dt * 3 });
|
|
|
|
|
it.wear = clamp((it.wear || 0) + dt * 0.0008, 0, 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (it.type === "ball") {
|
|
|
|
|
const touch = clamp(1 - d / (tarinai.radius + it.r + 12), 0, 1);
|
|
|
|
|
if (tarinai.state === "play_ball" || tarinai.target === it || tarinai.shouldApplyPersonalityBehavior("openness", 1)) {
|
|
|
|
|
tarinai.goodMode = "smile";
|
|
|
|
|
applyNeedRelief(tarinai, { fulfill: -dt * (4 + touch * 8), social: -dt * (1 + touch * 3) });
|
|
|
|
|
tarinai.loneliness = clamp(tarinai.loneliness - dt * (0.4 + touch), 0, 110);
|
|
|
|
|
if (tarinai.state === "play_ball") tarinai.foodReactTimer = Math.max(tarinai.foodReactTimer, 0.10);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (it.type === "splat") {
|
|
|
|
|
const touch = clamp(1 - d / (tarinai.radius + it.r + 16), 0, 1);
|
|
|
|
|
if (touch > 0) {
|
|
|
|
|
applyNeedShock(tarinai, { safety: touch * dt * 5, health: touch * dt * 3 });
|
|
|
|
|
if (touch > 0.06) tarinai.adjustPersonality("neuroticism", -dt * touch * 0.0042, "after repeated contact with corpses");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (it.type === "trace") {
|
|
|
|
|
tarinai.loneliness -= dt * 0.25;
|
|
|
|
|
applyNeedShock(tarinai, { social: -dt * 1, safety: dt * 0.8 });
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
global.TarinaiContactItemSystem = Object.freeze({
|
|
|
|
|
updateCandidate,
|
|
|
|
|
});
|
|
|
|
|
})(typeof window !== "undefined" ? window : globalThis);
|