not bad
This commit is contained in:
parent
2741b93dea
commit
434f07cc4e
103 changed files with 8387 additions and 8152 deletions
|
|
@ -19,6 +19,11 @@
|
|||
this.items = [];
|
||||
this.ants = [];
|
||||
this.effects = [];
|
||||
this.itemCounts = {};
|
||||
this.effectCounts = {};
|
||||
this.itemTypeBuckets = new Map();
|
||||
this.itemIdMap = new Map();
|
||||
this.itemBucketsDirty = false;
|
||||
this.logs = [];
|
||||
this.events = window.TarinaiEvents || null;
|
||||
this.eventCounters = {};
|
||||
|
|
@ -27,6 +32,8 @@
|
|||
this.drawSortTimer = 0;
|
||||
this.drawListDirty = true;
|
||||
this.antUpdatePhase = 0;
|
||||
this.grassGrowthTimer = 0;
|
||||
this.nextGrassLimitCheckAt = 0;
|
||||
this.selected = null;
|
||||
this.deadCount = 0;
|
||||
this.liveIdNext = 1;
|
||||
|
|
@ -51,6 +58,7 @@
|
|||
this.clampCamera();
|
||||
this.lastPhase = this.phaseName();
|
||||
this.weather = "sunny";
|
||||
this.groundType = window.TarinaiGround?.exists?.(this.groundType || "soil") ? (this.groundType || "soil") : "soil";
|
||||
this.nextWeatherChange = rand(CONFIG.weatherChangeMin, CONFIG.weatherChangeMax);
|
||||
seedPopulation = seedPopulation ?? field.population ?? CONFIG.initialPopulation;
|
||||
const grassCount = field.grass ?? 18;
|
||||
|
|
@ -65,11 +73,14 @@
|
|||
}
|
||||
for (let i = 0; i < grassCount; i++) {
|
||||
const grass = new Item("grass", rand(70, this.w - 70), rand(70, this.h - 70));
|
||||
globalThis.TarinaiGrass?.setStage?.(grass, Math.floor(rand(0, 2.999)), { force: true });
|
||||
if (this.addItem) this.addItem(grass, "reset-grass");
|
||||
else this.items.push(grass);
|
||||
}
|
||||
this.addItem?.(new Item("stone", this.w * 0.68, this.h * 0.32), "reset-stone") || this.items.push(new Item("stone", this.w * 0.68, this.h * 0.32));
|
||||
this.updateItemCounts();
|
||||
this.enforceGrassLimit?.("reset-grass-limit");
|
||||
this.updateItemCounts();
|
||||
this.updateEffectCounts();
|
||||
this.markTerrainDirty?.("reset");
|
||||
this.rebuildSpatial(true);
|
||||
|
|
@ -78,7 +89,7 @@
|
|||
},
|
||||
|
||||
tarinaiFamilyKey(t) {
|
||||
return t?.familyKey || t?.archiveKey || t?.id || "";
|
||||
return t?.familyKey || t?.id || "";
|
||||
},
|
||||
|
||||
assignTarinaiLiveId(t) {
|
||||
|
|
@ -377,7 +388,6 @@
|
|||
this.markFamilyTreeDirty("death");
|
||||
}
|
||||
}
|
||||
this.notifyDeathToRelations?.(t, finalReason);
|
||||
this.familyPrunePending = true;
|
||||
},
|
||||
|
||||
|
|
@ -410,8 +420,66 @@
|
|||
return t;
|
||||
},
|
||||
|
||||
nestBoxOccupants(box, limit = 5) {
|
||||
if (!box || box.dead || box.type !== "nest_box") return [];
|
||||
const occupants = (this.tarinai || []).filter(t => t && !t.dead && t.insideNestBoxId === box.id);
|
||||
return Number.isFinite(limit) ? occupants.slice(0, Math.max(0, limit)) : occupants;
|
||||
},
|
||||
|
||||
pointerNestBoxInfo() {
|
||||
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 !== "nest_box") 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; }
|
||||
}
|
||||
if (!best) return null;
|
||||
const occupants = this.nestBoxOccupants(best, Infinity);
|
||||
const capacity = this.nestBoxCapacity(best);
|
||||
return { box: best, occupants, capacity };
|
||||
},
|
||||
|
||||
nestBoxTooltipLines(box) {
|
||||
if (!box || box.dead || box.type !== "nest_box") return [];
|
||||
const occupants = this.nestBoxOccupants(box, Infinity);
|
||||
const names = occupants.map(t => t?.name).filter(Boolean).slice(0, 5);
|
||||
const more = occupants.length > names.length ? `、ほか${occupants.length - names.length}匹` : "";
|
||||
return ["巣箱", names.length ? `入ってる子: ${names.join("、")}${more}` : "入ってる子: なし"];
|
||||
},
|
||||
|
||||
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 ["かんたんベッド", `持ち主: ${owner?.name || "不明"}`];
|
||||
},
|
||||
|
||||
pointerItemTooltipInfo() {
|
||||
const nest = this.pointerNestBoxInfo?.();
|
||||
if (nest?.box) return { target: nest.box, lines: this.nestBoxTooltipLines(nest.box), kind: "nest_box" };
|
||||
const bedInfo = this.pointerOwnedBedInfo?.();
|
||||
if (bedInfo?.bed) return { target: bedInfo.bed, lines: this.ownedBedTooltipLines(bedInfo.bed), kind: "grass_bed" };
|
||||
return null;
|
||||
},
|
||||
|
||||
startBirthRitual(a, b) {
|
||||
if (!a || !b || a.dead || b.dead) return false;
|
||||
if (!this.tarinai?.includes?.(a) || !this.tarinai?.includes?.(b)) return false;
|
||||
if (!!a.isZunchiSlave !== !!b.isZunchiSlave) return false;
|
||||
if (this.areParentChild(a, b)) return false;
|
||||
if (a.sleepDisease || b.sleepDisease || a.fightDisease || b.fightDisease) return false;
|
||||
|
|
@ -433,17 +501,35 @@
|
|||
b.birthRitualRole = 1;
|
||||
a.birthRitualLeader = true;
|
||||
b.birthRitualLeader = false;
|
||||
a.setActionState("birth_ritual", { target: b, reason: "\u7e41\u6b96\u306e\u524d\u3076\u308c\u3092\u3057\u3066\u3044\u308b" });
|
||||
b.setActionState("birth_ritual", { target: a, reason: "\u7e41\u6b96\u306e\u524d\u3076\u308c\u3092\u3057\u3066\u3044\u308b" });
|
||||
if (typeof setLiveActionText === "function") {
|
||||
const ritualReason = "\u7e41\u6b96\u306e\u524d\u3076\u308c\u3092\u3057\u3066\u3044\u308b";
|
||||
const applyRitualAction = (actor, partner) => {
|
||||
if (!actor) return false;
|
||||
if (typeof actor.setActionState === "function") {
|
||||
actor.setActionState("birth_ritual", { target: partner || null, reason: ritualReason, need: "social", subNeed: "mate", actionId: "birth_ritual", phase: "acting" });
|
||||
return true;
|
||||
}
|
||||
actor.state = "birth_ritual";
|
||||
actor.target = partner || null;
|
||||
actor.thought = ritualReason;
|
||||
actor.sleeping = false;
|
||||
if (typeof setBehaviorText === "function") {
|
||||
setBehaviorText(actor, { need: "social", subNeed: "mate", actionId: "birth_ritual", actionLabel: ritualReason, reasonText: ritualReason, target: partner || null, phase: "acting", source: "state" });
|
||||
} else if (typeof patchTarinaiBehavior === "function") {
|
||||
patchTarinaiBehavior(actor, { actionId: "birth_ritual", phase: "acting", target: partner || null, source: "state", need: "social", subNeed: "mate", reason: ritualReason, label: ritualReason, text: ritualReason });
|
||||
}
|
||||
return true;
|
||||
};
|
||||
applyRitualAction(a, b);
|
||||
applyRitualAction(b, a);
|
||||
if (typeof setBehaviorText === "function") {
|
||||
const aBehavior = typeof currentTarinaiBehavior === "function" ? currentTarinaiBehavior(a) : a.behavior;
|
||||
const bBehavior = typeof currentTarinaiBehavior === "function" ? currentTarinaiBehavior(b) : b.behavior;
|
||||
const aLoveCause = (aBehavior?.source === "love_mochi" || (a.loveMochiTimer || 0) > 0.04) ? "\u3078\u3053\u9905\u306e\u52b9\u679c" : `${b.name || "\u76f8\u624b"}\u304c\u6c17\u306b\u306a\u308b`;
|
||||
const bLoveCause = (bBehavior?.source === "love_mochi" || (b.loveMochiTimer || 0) > 0.04) ? "\u3078\u3053\u9905\u306e\u52b9\u679c" : `${a.name || "\u76f8\u624b"}\u304c\u6c17\u306b\u306a\u308b`;
|
||||
const aText = typeof buildReasonText === "function" ? buildReasonText("social", aBehavior?.tiedNeeds || ["social"], { id: "birth_ritual", need: "social", subNeed: "mate", label: `${b.name || "\u76f8\u624b"}\u3068\u7e41\u6b96\u306e\u524d\u3076\u308c\u3092\u3057\u3066\u3044\u308b` }, a, this, { causeText: aLoveCause }) : `${b.name || "\u76f8\u624b"}\u3068\u7e41\u6b96\u306e\u524d\u3076\u308c\u3092\u3057\u3066\u3044\u308b`;
|
||||
const bText = typeof buildReasonText === "function" ? buildReasonText("social", bBehavior?.tiedNeeds || ["social"], { id: "birth_ritual", need: "social", subNeed: "mate", label: `${a.name || "\u76f8\u624b"}\u3068\u7e41\u6b96\u306e\u524d\u3076\u308c\u3092\u3057\u3066\u3044\u308b` }, b, this, { causeText: bLoveCause }) : `${a.name || "\u76f8\u624b"}\u3068\u7e41\u6b96\u306e\u524d\u3076\u308c\u3092\u3057\u3066\u3044\u308b`;
|
||||
setLiveActionText(a, { need: "social", subNeed: "mate", actionId: "birth_ritual", actionLabel: `${b.name || "\u76f8\u624b"}\u3068\u7e41\u6b96\u306e\u524d\u3076\u308c\u3092\u3057\u3066\u3044\u308b`, reasonText: aText, causeText: aLoveCause, target: b });
|
||||
setLiveActionText(b, { need: "social", subNeed: "mate", actionId: "birth_ritual", actionLabel: `${a.name || "\u76f8\u624b"}\u3068\u7e41\u6b96\u306e\u524d\u3076\u308c\u3092\u3057\u3066\u3044\u308b`, reasonText: bText, causeText: bLoveCause, target: a });
|
||||
setBehaviorText(a, { need: "social", subNeed: "mate", actionId: "birth_ritual", actionLabel: `${b.name || "\u76f8\u624b"}\u3068\u7e41\u6b96\u306e\u524d\u3076\u308c\u3092\u3057\u3066\u3044\u308b`, reasonText: aText, causeText: aLoveCause, target: b });
|
||||
setBehaviorText(b, { need: "social", subNeed: "mate", actionId: "birth_ritual", actionLabel: `${a.name || "\u76f8\u624b"}\u3068\u7e41\u6b96\u306e\u524d\u3076\u308c\u3092\u3057\u3066\u3044\u308b`, reasonText: bText, causeText: bLoveCause, target: a });
|
||||
}
|
||||
a.reproductionTimer = CONFIG.reproductionCooldown + rand(2, 10);
|
||||
b.reproductionTimer = CONFIG.reproductionCooldown + rand(2, 10);
|
||||
|
|
@ -584,7 +670,6 @@
|
|||
if (this.family[aKey] && !this.family[aKey].children.includes(childKey)) this.family[aKey].children.push(childKey);
|
||||
if (this.family[bKey] && !this.family[bKey].children.includes(childKey)) this.family[bKey].children.push(childKey);
|
||||
this.familyCleanVersion = null;
|
||||
audio.birth();
|
||||
this.lastBirthAt = this.time;
|
||||
if (total <= 1) this.log(`${child.name}\u304c${a.name}\u3068${b.name}\u306e\u5b50\u3068\u3057\u3066\u751f\u307e\u308c\u305f\u3002`, "birth", { participants: [child, a, b] });
|
||||
return child;
|
||||
|
|
@ -715,7 +800,7 @@
|
|||
actor.intimidateTimer = Math.max(actor.intimidateTimer, rand(1.05, 1.65));
|
||||
actor.intimidateTargetId = target.id;
|
||||
actor.setActionState("intimidate", { target, reason: "\u76f8\u624b\u3092\u5a01\u5687\u3057\u3066\u3044\u308b" });
|
||||
if (typeof setLiveActionText === "function") setLiveActionText(actor, { need: "social", subNeed: "conflict", actionId: "intimidate_enemy", actionLabel: "\u5a01\u5687\u3057\u3066\u3044\u308b", reasonText: `${target.name || "\u76f8\u624b"}\u3092\u5a01\u5687\u3057\u3066\u3044\u308b`, target, phase: "perform", source: "behavior" });
|
||||
if (typeof setBehaviorText === "function") setBehaviorText(actor, { need: "social", subNeed: "conflict", actionId: "intimidate_enemy", actionLabel: "\u5a01\u5687\u3057\u3066\u3044\u308b", reasonText: `${target.name || "\u76f8\u624b"}\u3092\u5a01\u5687\u3057\u3066\u3044\u308b`, target, phase: "perform", source: "behavior" });
|
||||
this.effects.push(new Effect("ring", actor.x, actor.y - actor.radius * 0.65, {
|
||||
life: 0.42,
|
||||
size: actor.radius * 0.55,
|
||||
|
|
@ -782,9 +867,9 @@
|
|||
b.counterAttackFromId = b === receiver ? initiator.id : null;
|
||||
a.setActionState("fight", { target: b, reason: reasonA });
|
||||
b.setActionState("fight", { target: a, reason: reasonB });
|
||||
if (typeof setLiveActionText === "function") {
|
||||
setLiveActionText(a, { need: "social", subNeed: "conflict", actionId: "fight_rival", actionLabel: a === receiver ? "\u53cd\u6483\u3057\u3066\u3044\u308b" : "\u55a7\u5629\u3057\u3066\u3044\u308b", reasonText: reasonA, causeText: causeFor(a, b), target: b, phase: "perform", source: "behavior" });
|
||||
setLiveActionText(b, { need: "social", subNeed: "conflict", actionId: "fight_rival", actionLabel: b === receiver ? "\u53cd\u6483\u3057\u3066\u3044\u308b" : "\u55a7\u5629\u3057\u3066\u3044\u308b", reasonText: reasonB, causeText: causeFor(b, a), target: a, phase: "perform", source: "behavior" });
|
||||
if (typeof setBehaviorText === "function") {
|
||||
setBehaviorText(a, { need: "social", subNeed: "conflict", actionId: "fight_rival", actionLabel: a === receiver ? "\u53cd\u6483\u3057\u3066\u3044\u308b" : "\u55a7\u5629\u3057\u3066\u3044\u308b", reasonText: reasonA, causeText: causeFor(a, b), target: b, phase: "perform", source: "behavior" });
|
||||
setBehaviorText(b, { need: "social", subNeed: "conflict", actionId: "fight_rival", actionLabel: b === receiver ? "\u53cd\u6483\u3057\u3066\u3044\u308b" : "\u55a7\u5629\u3057\u3066\u3044\u308b", reasonText: reasonB, causeText: causeFor(b, a), target: a, phase: "perform", source: "behavior" });
|
||||
}
|
||||
a.fightTimer = Math.max(a.fightTimer, rand(3.2, 4.8));
|
||||
b.fightTimer = Math.max(b.fightTimer, rand(3.2, 4.8));
|
||||
|
|
@ -820,7 +905,7 @@
|
|||
}));
|
||||
audio.fight();
|
||||
if (this.time - Math.max(a.lastLog, b.lastLog) > 6) {
|
||||
this.log(`${a.name}\u3068${b.name}\u304c\u5c0f\u3055\u306a\u55a7\u5629\u3092\u3057\u305f\u3002`, "fight", { participants: [a, b] });
|
||||
this.log(`${a.name}\u3068${b.name}\u304c\u5c0f\u3055\u306a\u55a7\u5629\u3092\u3057\u305f\u3002`, "fight", { participants: [a, b], sound: false });
|
||||
a.lastLog = b.lastLog = this.time;
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue