duu
This commit is contained in:
parent
88f618cadf
commit
8f9f5b5100
108 changed files with 2139 additions and 1500 deletions
|
|
@ -35,6 +35,80 @@
|
|||
const groundForResetPreset = resetPresets.groundForResetPreset || (() => "soil");
|
||||
const resetPresetLabel = resetPresets.label || (() => "\u30C7\u30D5\u30A9\u30EB\u30C8");
|
||||
|
||||
function pointerLargeTarinaiTooltipCandidatesLocal(worldRef, now = worldRef?.time || 0) {
|
||||
const cache = worldRef._pointerTooltipLargeTarinaiCache;
|
||||
if (cache && worldRef._pointerTooltipLargeTarinaiSerial === worldRef.liveIdSerial && now < (worldRef._pointerTooltipLargeTarinaiUntil || 0)) return cache;
|
||||
const out = [];
|
||||
for (const t of worldRef.tarinai || []) {
|
||||
if (!t || t.dead) continue;
|
||||
if ((Number(t.radius) || 20) > 64) out.push(t);
|
||||
}
|
||||
worldRef._pointerTooltipLargeTarinaiCache = out;
|
||||
worldRef._pointerTooltipLargeTarinaiSerial = worldRef.liveIdSerial;
|
||||
worldRef._pointerTooltipLargeTarinaiUntil = now + 0.35;
|
||||
return out;
|
||||
}
|
||||
|
||||
function pointerTarinaiTooltipCandidatesLocal(worldRef, p) {
|
||||
const all = Array.isArray(worldRef.tarinai) ? worldRef.tarinai : [];
|
||||
if (!p?.inside || !all.length) return all;
|
||||
if (all.length < 72 || typeof worldRef.nearbyTarinai !== "function") return all;
|
||||
const local = worldRef.nearbyTarinai(p.x, p.y, 128, false) || [];
|
||||
const large = pointerLargeTarinaiTooltipCandidatesLocal(worldRef, worldRef.time || 0) || [];
|
||||
if (!large.length) return local;
|
||||
const stamp = (worldRef._pointerTooltipCandidateStamp = (worldRef._pointerTooltipCandidateStamp || 0) + 1);
|
||||
for (const t of local) if (t) t._pointerTooltipCandidateStamp = stamp;
|
||||
for (const t of large) {
|
||||
if (!t || t.dead || t._pointerTooltipCandidateStamp === stamp) continue;
|
||||
t._pointerTooltipCandidateStamp = stamp;
|
||||
local.push(t);
|
||||
}
|
||||
return local;
|
||||
}
|
||||
|
||||
function pointerTarinaiTooltipInfoLocal(worldRef) {
|
||||
const p = worldRef.pointer;
|
||||
if (!p?.inside || !Array.isArray(worldRef.tarinai)) return null;
|
||||
let best = null, bestD = Infinity;
|
||||
for (const t of pointerTarinaiTooltipCandidatesLocal(worldRef, p) || worldRef.tarinai) {
|
||||
if (!t || t.dead) continue;
|
||||
if (worldRef.isTarinaiHiddenInNestBox?.(t)) continue;
|
||||
const d = distXY(p.x, p.y, t.x, t.y);
|
||||
const limit = Math.max(46, (t.radius || 20) * 1.35);
|
||||
if (d <= limit && d < bestD) { best = t; bestD = d; }
|
||||
}
|
||||
if (!best) return null;
|
||||
const nameLine = String(best.name || "たりない");
|
||||
const behavior = (typeof behaviorText === "function" ? behaviorText(best) : "")
|
||||
|| window.TEXT_CATALOG?.stateLabel?.(best.state, best)
|
||||
|| best.thought
|
||||
|| "様子を見ている";
|
||||
const maxEnergy = typeof tarinaiMaxEnergy === "function" ? tarinaiMaxEnergy(best) : (Number(best.maxEnergy) || 100);
|
||||
const statusLine = `体力: ${Math.round(best.energy || 0)}/${Math.round(maxEnergy)} 空腹: ${Math.round(best.hunger || 0)} ストレス: ${Math.round(best.stress || 0)}`;
|
||||
const tempLine = worldRef.temperatureTooltipLineFor(best, "体感気温") || "体感気温: --℃";
|
||||
return { target: best, lines: [nameLine, String(behavior), statusLine, tempLine], kind: "tarinai" };
|
||||
}
|
||||
|
||||
function pointerOwnedBedInfoLocal(worldRef) {
|
||||
const p = worldRef.pointer;
|
||||
if (!p?.inside) return null;
|
||||
let best = null, bestD = Infinity;
|
||||
for (const it of worldRef.nearbyItems(p.x, p.y, 140)) {
|
||||
if (!it || it.dead || it.type !== "grass_bed") continue;
|
||||
const d = distXY(p.x, p.y, it.x, it.y);
|
||||
if (d < bestD && d <= Math.max(60, (it.r || 24) * 2.0)) { best = it; bestD = d; }
|
||||
}
|
||||
if (!best) return null;
|
||||
const owner = worldRef.liveTarinaiById?.(best.ownerId) || null;
|
||||
return { bed: best, owner };
|
||||
}
|
||||
|
||||
function ownedBedTooltipLinesLocal(worldRef, bed) {
|
||||
if (!bed || bed.dead || bed.type !== "grass_bed") return [];
|
||||
const owner = worldRef.liveTarinaiById?.(bed.ownerId) || null;
|
||||
return ["かんたんベッド", `持ち主: ${owner?.name || "不明"}`, worldRef.temperatureTooltipLineFor?.(bed, "周辺気温")].filter(Boolean);
|
||||
}
|
||||
|
||||
Object.defineProperties(World.prototype, Object.getOwnPropertyDescriptors({
|
||||
reset(seedPopulation = null, fieldType = this.fieldType || "garden", presetId = "default") {
|
||||
const field = FIELD_TYPES?.[fieldType] || FIELD_TYPES.garden;
|
||||
|
|
@ -433,12 +507,25 @@
|
|||
}
|
||||
}
|
||||
const t = new Tarinai(this, opts);
|
||||
const isSeededSpawn = !Number.isFinite(Number(opts.age))
|
||||
&& opts.birthTime == null
|
||||
&& !opts.dead
|
||||
&& !(Array.isArray(opts.parents) && opts.parents.length)
|
||||
&& !(Array.isArray(opts.seedParents) && opts.seedParents.length)
|
||||
&& (Number(opts.generation ?? 1) <= 1);
|
||||
if (isSeededSpawn) {
|
||||
const span = Math.max(1, Number(t.lifeSpan || 1) || 1);
|
||||
const ratio = typeof deterministicRange === "function"
|
||||
? deterministicRange(this, "initial-life-spent-ratio", 0, 0.30, t.familyKey || t.birthSeed || t.id || this.birthSerial || Math.random())
|
||||
: Math.random() * 0.30;
|
||||
t.age = Math.max(Number(t.age || 0) || 0, span * ratio);
|
||||
t.birthTime = (this.time || 0) - t.age;
|
||||
}
|
||||
this.assignTarinaiLiveId(t);
|
||||
this.tarinai.push(t);
|
||||
this.drawListDirty = true;
|
||||
if (t.hasPaired || (t.parents || []).length || (t.children || []).length) this.recordFamily(t);
|
||||
this.maxGeneration = Math.max(this.maxGeneration, t.generation);
|
||||
this.emit?.("tarinai:born", { tarinai: t, source: opts.parents?.length ? "family" : "spawn" });
|
||||
return t;
|
||||
},
|
||||
|
||||
|
|
@ -451,7 +538,7 @@
|
|||
if (!p?.inside) return null;
|
||||
let best = null, bestD = Infinity;
|
||||
for (const it of this.nearbyItems(p.x, p.y, 140)) {
|
||||
if (!it || it.dead || !(typeof globalThis.isNestContainerType === "function" ? globalThis.isNestContainerType(it.type) : (it.type === "nest_box" || it.type === "pipe"))) continue;
|
||||
if (!it || it.dead || !globalThis.TarinaiToolRuntime?.isNestContainerItem?.(it)) continue;
|
||||
const d = distXY(p.x, p.y, it.x, it.y);
|
||||
if (d < bestD && d <= Math.max(80, it.r * 2.1)) { best = it; bestD = d; }
|
||||
}
|
||||
|
|
@ -462,7 +549,7 @@
|
|||
},
|
||||
|
||||
nestBoxTooltipLines(box) {
|
||||
if (!box || box.dead || !(typeof globalThis.isNestContainerType === "function" ? globalThis.isNestContainerType(box.type) : (box.type === "nest_box" || box.type === "pipe"))) return [];
|
||||
if (!box || box.dead || !globalThis.TarinaiToolRuntime?.isNestContainerItem?.(box)) return [];
|
||||
const isPipe = box.type === "pipe";
|
||||
let occupants = [];
|
||||
if (isPipe) {
|
||||
|
|
@ -500,65 +587,25 @@
|
|||
|
||||
temperatureTooltipLineFor(target, label = "体感気温") {
|
||||
if (!target || !this.temperatureAt) return "";
|
||||
const temp = target.type === "pipe" && this.pipeInteriorTemperatureFor
|
||||
? this.pipeInteriorTemperatureFor(target)
|
||||
: this.temperatureAt(target.x, target.y);
|
||||
const isActor = Array.isArray(this.tarinai) && this.tarinai.includes(target);
|
||||
const temp = isActor
|
||||
? (this.feltTemperatureFor?.(target) ?? this.temperatureAt(target.x, target.y, target))
|
||||
: (target.type === "pipe" && this.pipeInteriorTemperatureFor
|
||||
? this.pipeInteriorTemperatureFor(target)
|
||||
: this.temperatureAt(target.x, target.y));
|
||||
if (!Number.isFinite(Number(temp))) return "";
|
||||
const status = this.temperatureStatusFor?.(temp) || null;
|
||||
const status = this.temperatureStatusFor?.(temp, isActor ? target : null) || null;
|
||||
const suffix = status?.label ? `(${status.label})` : "";
|
||||
return `${label}: ${Number(temp).toFixed(1)}℃${suffix}`;
|
||||
},
|
||||
|
||||
pointerTarinaiTooltipInfo() {
|
||||
const p = this.pointer;
|
||||
if (!p?.inside || !Array.isArray(this.tarinai)) return null;
|
||||
let best = null, bestD = Infinity;
|
||||
for (const t of this.tarinai) {
|
||||
if (!t || t.dead) continue;
|
||||
if (this.isTarinaiHiddenInNestBox?.(t)) continue;
|
||||
const d = distXY(p.x, p.y, t.x, t.y);
|
||||
const limit = Math.max(46, (t.radius || 20) * 1.35);
|
||||
if (d <= limit && d < bestD) { best = t; bestD = d; }
|
||||
}
|
||||
if (!best) return null;
|
||||
const nameLine = String(best.name || "たりない");
|
||||
const behavior = (typeof behaviorText === "function" ? behaviorText(best) : "")
|
||||
|| window.TEXT_CATALOG?.stateLabel?.(best.state, best)
|
||||
|| best.thought
|
||||
|| "様子を見ている";
|
||||
const maxEnergy = typeof tarinaiMaxEnergy === "function" ? tarinaiMaxEnergy(best) : (Number(best.maxEnergy) || 100);
|
||||
const statusLine = `体力: ${Math.round(best.energy || 0)}/${Math.round(maxEnergy)} 空腹: ${Math.round(best.hunger || 0)} ストレス: ${Math.round(best.stress || 0)}`;
|
||||
const tempLine = this.temperatureTooltipLineFor(best, "体感気温") || "体感気温: --℃";
|
||||
return { target: best, lines: [nameLine, String(behavior), statusLine, tempLine], kind: "tarinai" };
|
||||
},
|
||||
|
||||
pointerOwnedBedInfo() {
|
||||
const p = this.pointer;
|
||||
if (!p?.inside) return null;
|
||||
let best = null, bestD = Infinity;
|
||||
for (const it of this.nearbyItems(p.x, p.y, 140)) {
|
||||
if (!it || it.dead || it.type !== "grass_bed") continue;
|
||||
const d = distXY(p.x, p.y, it.x, it.y);
|
||||
if (d < bestD && d <= Math.max(60, (it.r || 24) * 2.0)) { best = it; bestD = d; }
|
||||
}
|
||||
if (!best) return null;
|
||||
const owner = this.liveTarinaiById?.(best.ownerId) || null;
|
||||
return { bed: best, owner };
|
||||
},
|
||||
|
||||
ownedBedTooltipLines(bed) {
|
||||
if (!bed || bed.dead || bed.type !== "grass_bed") return [];
|
||||
const owner = this.liveTarinaiById?.(bed.ownerId) || null;
|
||||
return ["\u304b\u3093\u305f\u3093\u30d9\u30c3\u30c9", `\u6301\u3061\u4e3b: ${owner?.name || "\u4e0d\u660e"}`, this.temperatureTooltipLineFor?.(bed, "\u5468\u8FBA\u6C17\u6E29")].filter(Boolean);
|
||||
},
|
||||
|
||||
pointerItemTooltipInfo() {
|
||||
const tarinaiInfo = this.pointerTarinaiTooltipInfo?.();
|
||||
const tarinaiInfo = pointerTarinaiTooltipInfoLocal(this);
|
||||
if (tarinaiInfo?.target) return tarinaiInfo;
|
||||
const nest = this.pointerNestBoxInfo?.();
|
||||
if (nest?.box) return { target: nest.box, lines: this.nestBoxTooltipLines(nest.box), kind: nest.box?.type === "pipe" ? "pipe" : "nest_box" };
|
||||
const bedInfo = this.pointerOwnedBedInfo?.();
|
||||
if (bedInfo?.bed) return { target: bedInfo.bed, lines: this.ownedBedTooltipLines(bedInfo.bed), kind: "grass_bed" };
|
||||
const bedInfo = pointerOwnedBedInfoLocal(this);
|
||||
if (bedInfo?.bed) return { target: bedInfo.bed, lines: ownedBedTooltipLinesLocal(this, bedInfo.bed), kind: "grass_bed" };
|
||||
return null;
|
||||
},
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue