qqq
This commit is contained in:
parent
acf93ec6df
commit
ee22e1a929
49 changed files with 1380 additions and 338 deletions
|
|
@ -1,27 +1,34 @@
|
|||
"use strict";
|
||||
|
||||
// Layer: tarinai/nest-sleep
|
||||
// Centralizes sleep furniture, nest occupancy/reservation, and sleep-target
|
||||
// selection policy so nest-box entrance logic and bed targeting do not drift.
|
||||
// Centralizes sleep furniture, nest/pipe occupancy/reservation, and sleep-target
|
||||
// selection policy so entrance logic and bed targeting do not drift.
|
||||
(function (global) {
|
||||
const distFn = typeof dist === "function" ? dist : ((a, b) => Math.hypot((a?.x || 0) - (b?.x || 0), (a?.y || 0) - (b?.y || 0)));
|
||||
const clampFn = typeof clamp === "function" ? clamp : ((v, a, b) => Math.max(a, Math.min(b, v)));
|
||||
|
||||
function isNestContainer(item) {
|
||||
return Boolean(item && (typeof global.isNestContainerType === "function" ? global.isNestContainerType(item.type) : (item.type === "nest_box" || item.type === "pipe")));
|
||||
}
|
||||
|
||||
function isSleepFurniture(item) {
|
||||
return Boolean(item && (item.roles?.sleepPlace || (typeof global.isSleepFurnitureType === "function" ? global.isSleepFurnitureType(item.type) : (item.type === "bed" || item.type === "nest_box" || item.type === "grass_bed"))));
|
||||
return Boolean(item && (item.roles?.sleepPlace || (typeof global.isSleepFurnitureType === "function" ? global.isSleepFurnitureType(item.type) : (item.type === "bed" || item.type === "nest_box" || item.type === "pipe" || item.type === "grass_bed"))));
|
||||
}
|
||||
|
||||
function sleepTargetBlocked(worldRef, tarinai, item) {
|
||||
if (!worldRef || !tarinai || !item) return false;
|
||||
// Pipe mouths are floor-level entry points. Treat them as reachable even if
|
||||
// their circular sprite overlaps the tarinai body.
|
||||
if (item.type === "pipe") return false;
|
||||
return Boolean(worldRef.targetBlockedByObstacle?.(tarinai, item, Math.max(18, (tarinai.radius || 20) * 0.65)));
|
||||
}
|
||||
|
||||
function nestBoxCapacity(worldRef, box = null) {
|
||||
return typeof worldRef?.nestBoxCapacity === "function" ? worldRef.nestBoxCapacity(box) : 5;
|
||||
return typeof worldRef?.nestBoxCapacity === "function" ? worldRef.nestBoxCapacity(box) : (box?.type === "pipe" ? 3 : 5);
|
||||
}
|
||||
|
||||
function nestBoxOccupants(worldRef, box, limit = 5) {
|
||||
if (!worldRef || !box || box.dead || box.type !== "nest_box") return [];
|
||||
if (!worldRef || !box || box.dead || !isNestContainer(box)) return [];
|
||||
const occupants = (worldRef.tarinai || []).filter(t => t && !t.dead && t.insideNestBoxId === box.id);
|
||||
return Number.isFinite(limit) ? occupants.slice(0, Math.max(0, limit)) : occupants;
|
||||
}
|
||||
|
|
@ -44,7 +51,7 @@
|
|||
}
|
||||
|
||||
function nestBoxReservationCount(worldRef, box) {
|
||||
if (!worldRef || !box || box.dead || box.type !== "nest_box") return 0;
|
||||
if (!worldRef || !box || box.dead || !isNestContainer(box)) return 0;
|
||||
const now = Number(worldRef.time || 0) || 0;
|
||||
let n = 0;
|
||||
for (const t of worldRef.tarinai || []) if (tarinaiIsReservingNest(t, box, now)) n += 1;
|
||||
|
|
@ -53,7 +60,7 @@
|
|||
|
||||
function bedOccupancy(worldRef, bed) {
|
||||
if (!worldRef || !isSleepFurniture(bed)) return 0;
|
||||
if (bed.type === "nest_box") {
|
||||
if (isNestContainer(bed)) {
|
||||
return nestBoxOccupants(worldRef, bed, Infinity).length + nestBoxReservationCount(worldRef, bed);
|
||||
}
|
||||
let n = 0;
|
||||
|
|
@ -69,7 +76,8 @@
|
|||
function bedComfort(worldRef, bed) {
|
||||
if (!isSleepFurniture(bed)) return 0.7;
|
||||
const occ = bedOccupancy(worldRef, bed);
|
||||
return clampFn((bed.comfort ?? 1) - Math.max(0, occ - 3) * 0.075 - (bed.wear || 0) * 0.18, 0.42, 1.18);
|
||||
const base = bed.type === "pipe" ? Math.min(Number(bed.comfort ?? 0.74) || 0.74, 0.82) : (bed.comfort ?? 1);
|
||||
return clampFn(base - Math.max(0, occ - 3) * 0.075 - (bed.wear || 0) * 0.18, bed.type === "pipe" ? 0.46 : 0.42, bed.type === "pipe" ? 0.88 : 1.18);
|
||||
}
|
||||
|
||||
function sleepPlaceAvailableFor(worldRef, tarinai, item) {
|
||||
|
|
@ -79,7 +87,7 @@
|
|||
if (tarinai.shouldAvoidTarget?.(item)) return false;
|
||||
if (worldRef?.sleepTargetTemperatureBlocked?.(tarinai, item)) return false;
|
||||
if (sleepTargetBlocked(worldRef, tarinai, item)) return false;
|
||||
const capacity = item.type === "nest_box" ? nestBoxCapacity(worldRef, item) : 1;
|
||||
const capacity = isNestContainer(item) ? nestBoxCapacity(worldRef, item) : 1;
|
||||
const occupancy = bedOccupancy(worldRef, item);
|
||||
return occupancy < capacity || tarinai.target === item || (tarinai.insideNestBoxId && tarinai.insideNestBoxId === item.id);
|
||||
}
|
||||
|
|
@ -135,6 +143,7 @@
|
|||
return findOwnedStructure(worldRef, tarinai, "grass_bed", maxDist)
|
||||
|| nearestSleepPlaceOfType(worldRef, tarinai, "nest_box", maxDist)
|
||||
|| nearestSleepPlaceOfType(worldRef, tarinai, "bed", maxDist)
|
||||
|| nearestSleepPlaceOfType(worldRef, tarinai, "pipe", maxDist)
|
||||
|| nearestSleepPlaceOfType(worldRef, tarinai, "grass_bed", maxDist)
|
||||
|| null;
|
||||
}
|
||||
|
|
@ -145,6 +154,7 @@
|
|||
}
|
||||
|
||||
global.TarinaiNestSleepSystem = Object.freeze({
|
||||
isNestContainer,
|
||||
isSleepFurniture,
|
||||
isTarinaiHiddenInNestBox,
|
||||
nestBoxOccupants,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue