This commit is contained in:
33333-33333 2026-07-11 21:13:39 +09:00
commit d14550dad6
78 changed files with 2827 additions and 563 deletions

View file

@ -113,25 +113,25 @@
if (this.temperatureAuto === false) this.currentTemperature = this.manualTemperature;
return this.manualTemperature;
},
weatherFeltTemperatureOffsetAt(x, y, actor = null) {
if (!actor) return 0;
const weather = String(this.weather || "sunny");
if (weather === "sunny") return 3.5;
if (weather === "light_rain") return -3.5;
return 0;
},
temperatureAt(x, y, actor = null) {
let temp = Number.isFinite(Number(this.currentTemperature)) ? Number(this.currentTemperature) : this.updateTemperature?.(0) ?? (CONFIG.standardTemperature ?? 15);
if (this.temperatureAuto === false) temp = this.temperatureNumber(this.manualTemperature);
if ((this.groundType || "soil") === "ice") temp -= 5;
const range = Math.max(24, CONFIG.temperatureItemRange ?? 190);
for (const it of this.nearbyItems(x, y, range + 8)) {
const fanRange = 320;
for (const it of this.nearbyItems(x, y, Math.max(range + 8, fanRange + 40))) {
if (!it || it.dead || (it.type !== "dry_ice" && it.type !== "stove" && it.type !== "fan")) continue;
if (it.type === "fan") {
const angle = itemAngleFor(it);
const dx = x - it.x;
const dy = y - it.y;
const along = dx * Math.cos(angle) + dy * Math.sin(angle);
const fanRange = range * 1.35;
if (along <= 8 || along > fanRange) continue;
const lateral = Math.abs(-dx * Math.sin(angle) + dy * Math.cos(angle));
const halfWidth = 28 + along * 0.72;
if (lateral > halfWidth) continue;
const edge = Math.pow(clamp(1 - along / fanRange, 0, 1), 0.62) * Math.pow(clamp(1 - lateral / Math.max(1, halfWidth), 0, 1), 0.30);
temp -= 5 * edge;
const wind = global.TarinaiItemDynamicBallSystem?.fanWindAt?.(it, x, y, { range: fanRange }) || null;
if (!wind) continue;
temp -= 5 * wind.falloff;
continue;
}
const d = distXY(x, y, it.x, it.y);
@ -151,7 +151,10 @@
temp += clamp(toward, -nestWarmthLimit, nestWarmthLimit);
break;
}
if (actor && (actor.state === "sunbath" || (actor.sunbathTimer || 0) > 0.04)) temp += 3;
const parasolSystem = global.TarinaiParasolSystem || global.TarinaiRainShelterSystem;
const weatherBlocked = Boolean(actor && parasolSystem?.blocksWeatherAt?.(this, x, y));
temp += weatherBlocked ? 0 : (this.weatherFeltTemperatureOffsetAt?.(x, y, actor) || 0);
if (actor && !weatherBlocked && (actor.state === "sunbath" || (actor.sunbathTimer || 0) > 0.04)) temp += 3;
return this.temperatureNumber(temp);
},
pipeInteriorTemperatureFor(pipe, actor = null) {
@ -204,6 +207,8 @@
if (direction === "cold") types.push("stove");
else if (direction === "hot") types.push("dry_ice", "fan");
else types.push("stove", "dry_ice", "fan");
const weather = String(this.weather || "sunny");
if ((direction === "hot" && weather === "sunny") || (direction === "cold" && weather === "light_rain")) types.push("rain_shelter");
const seen = new Set();
const out = [];
for (const type of types) {
@ -242,6 +247,19 @@
const itemRange = Math.max(24, CONFIG.temperatureItemRange ?? 190);
for (const it of this.temperatureComfortCandidateItems?.(currentStatus.direction) || this.items || []) {
if (!it || it.dead) continue;
if (it.type === "rain_shelter") {
const parasolSystem = global.TarinaiParasolSystem || global.TarinaiRainShelterSystem;
const footprint = parasolSystem?.parasolFootprint?.(it) || {
centerX: it.x,
centerY: it.y + (Number(it.r || 50) || 50) * 0.84,
radiusX: (Number(it.r || 50) || 50) * 1.58,
radiusY: (Number(it.r || 50) || 50) * 0.68,
};
for (const [nx, ny] of [[0.82, 0], [-0.82, 0], [0.72, 0.36], [-0.72, 0.36], [0.72, -0.36], [-0.72, -0.36]]) {
pushCandidate(footprint.centerX + footprint.radiusX * nx, footprint.centerY + footprint.radiusY * ny, -72);
}
continue;
}
if (it.type === "nest_box" || it.type === "pipe") {
const shelterTemp = it.type === "pipe" && this.pipeInteriorTemperatureFor
? this.pipeInteriorTemperatureFor(it, actor)
@ -273,7 +291,7 @@
let bestScore = Infinity;
for (const c of candidates) {
if (this.pointBlockedByObstacle?.(c.x, c.y, Math.max(14, radius * 0.72), { exclude: actor })) continue;
const temp = Number.isFinite(Number(c.tempOverride)) ? Number(c.tempOverride) : this.temperatureAt(c.x, c.y, actor);
const temp = c.tempOverride != null && Number.isFinite(Number(c.tempOverride)) ? Number(c.tempOverride) : this.temperatureAt(c.x, c.y, actor);
const status = this.temperatureStatusFor(temp, actor);
if (currentStatus.direction === "cold" && temp <= current + 0.6 && !status.comfortable) continue;
if (currentStatus.direction === "hot" && temp >= current - 0.6 && !status.comfortable) continue;
@ -282,7 +300,7 @@
const score = status.discomfort * 110 + Math.abs(temp - targetTemp) * 2.8 + d * 0.22 + blockedPenalty + (c.extra || 0);
if (score < bestScore) {
bestScore = score;
const shelterLabel = c.targetItem?.type === "pipe" ? "土管" : (c.targetItem?.type === "nest_box" ? "巣箱" : "快適な温度帯");
const shelterLabel = c.targetItem?.type === "pipe" ? "\u571f\u7ba1" : (c.targetItem?.type === "nest_box" ? "\u5de3\u7bb1" : "\u5feb\u9069\u306a\u6e29\u5ea6\u5e2f");
best = { x: c.x, y: c.y, dead: false, detour: !c.targetItem, temperatureTarget: true, temperature: temp, label: shelterLabel };
if (c.targetItem) best.shelterItem = c.targetItem;
}