91 lines
3.5 KiB
JavaScript
91 lines
3.5 KiB
JavaScript
"use strict";
|
|
|
|
(function (global) {
|
|
function markWorldAfterStructureChange(worldRef, reason = "structure-change") {
|
|
if (!worldRef) return;
|
|
worldRef.drawListDirty = true;
|
|
worldRef.markItemBucketsDirty?.(reason);
|
|
worldRef.markSpatialDirty?.(reason);
|
|
worldRef.markTerrainDirty?.(reason);
|
|
}
|
|
|
|
function markStructureGone(structure, reason = "structure-removed") {
|
|
if (!structure || structure.dead) return false;
|
|
structure.dead = true;
|
|
structure.hp = 0;
|
|
structure.amount = 0;
|
|
structure.removedReason = String(reason || "structure-removed");
|
|
return true;
|
|
}
|
|
|
|
function releaseStructureUsers(worldRef, structure, opts = {}) {
|
|
if (!worldRef || !structure) return 0;
|
|
const reason = opts.reason || "なくなった";
|
|
const wake = opts.wake !== false;
|
|
let released = 0;
|
|
for (const t of worldRef.tarinai || []) {
|
|
if (!t || t.dead) continue;
|
|
const targetMatch = t.target === structure;
|
|
const sleepTargetMatch = t.sleepSession?.targetId && t.sleepSession.targetId === structure.id;
|
|
const nestMatch = structure.type === "nest_box" && t.insideNestBoxId === structure.id;
|
|
if (!targetMatch && !sleepTargetMatch && !nestMatch) continue;
|
|
|
|
if (nestMatch) {
|
|
t.insideNestBoxId = null;
|
|
t.nestBoxSleepTimer = 0;
|
|
}
|
|
if (sleepTargetMatch && t.sleepSession) {
|
|
t.sleepSession.targetId = null;
|
|
t.sleepSession.consumesGrassBedOnWake = false;
|
|
}
|
|
if (targetMatch) t.target = null;
|
|
if (t.state === "sleep" || t.sleeping || t.state === "seek_bed" || nestMatch) {
|
|
t.setActionState?.("idle", { clearTarget: true, reason, wake, sleeping: false });
|
|
}
|
|
released += 1;
|
|
}
|
|
return released;
|
|
}
|
|
|
|
function deleteStructure(worldRef, structure, opts = {}) {
|
|
if (!structure || structure.dead) return false;
|
|
const reason = opts.reason || "structure-deleted";
|
|
releaseStructureUsers(worldRef, structure, { reason: opts.userReason || "置きものがなくなった", wake: opts.wake !== false });
|
|
const changed = markStructureGone(structure, reason);
|
|
if (!changed) return false;
|
|
markWorldAfterStructureChange(worldRef, reason);
|
|
worldRef?.emit?.("structure:deleted", { structure, type: structure.type, reason });
|
|
return true;
|
|
}
|
|
|
|
function consumeGrassBedOnWake(worldRef, bed, user = null, reason = "wake") {
|
|
if (!bed || bed.dead || bed.type !== "grass_bed") return false;
|
|
bed.singleUsePending = false;
|
|
bed.singleUseWakeReason = String(reason || "wake");
|
|
bed.singleUseConsumedById = user?.id || bed.singleUseConsumedById || null;
|
|
if (user?.target === bed) user.target = null;
|
|
const changed = markStructureGone(bed, "grass-bed-wake-used");
|
|
if (!changed) return false;
|
|
markWorldAfterStructureChange(worldRef, "grass-bed-wake-used");
|
|
worldRef?.emit?.("structure:usedUp", { structure: bed, user, reason: "wake" });
|
|
return true;
|
|
}
|
|
|
|
function deleteItem(worldRef, item, opts = {}) {
|
|
if (!item || item.dead) return false;
|
|
if (item.isStructure) return deleteStructure(worldRef, item, { reason: opts.reason || "delete-tool", userReason: opts.userReason, wake: opts.wake });
|
|
item.amount = 0;
|
|
item.hp = 0;
|
|
item.removedReason = String(opts.reason || "delete-tool");
|
|
markWorldAfterStructureChange(worldRef, opts.reason || "delete-tool");
|
|
return true;
|
|
}
|
|
|
|
global.TarinaiStructureLifecycle = Object.freeze({
|
|
markWorldAfterStructureChange,
|
|
releaseStructureUsers,
|
|
deleteStructure,
|
|
consumeGrassBedOnWake,
|
|
deleteItem,
|
|
});
|
|
})(window);
|