This commit is contained in:
33333-33333 2026-06-30 22:30:37 +09:00
commit 7455d630fc
82 changed files with 2179 additions and 900 deletions

View file

@ -203,7 +203,7 @@
return now < (this._nestBoxEntrySmoothUntil || -Infinity) || ((this.nestFade || 0) > 0.01 && (this.nestFade || 0) < 0.985);
},
abortNestBoxEntry(box = null, reason = "巣箱がいっぱいで入れない") {
abortNestBoxEntry(box = null, reason = "\u5DE3\u7BB1\u304C\u3044\u3063\u3071\u3044\u3067\u5165\u308C\u306A\u3044") {
const now = this.world?.time || 0;
if (this.insideNestBoxId && (!box || this.insideNestBoxId === box.id)) this.leaveNestBox?.(box);
if (!this.insideNestBoxId) this.nestFade = 0;
@ -248,13 +248,28 @@
return this.target === box || this.insideNestBoxId === box.id;
},
enterNestBox(box, dt = 0.016) {
enterNestBox(box, dt = 0.016, options = {}) {
if (!box || box.dead || box.type !== "nest_box" || this.dead) return false;
const capacity = this.world?.nestBoxCapacity ? this.world.nestBoxCapacity(box) : 5;
const occupants = this.world?.nestBoxOccupants ? this.world.nestBoxOccupants(box, Infinity) : [];
let occupants = this.world?.nestBoxOccupants ? this.world.nestBoxOccupants(box, Infinity) : [];
const alreadyInside = this.insideNestBoxId === box.id;
const now = this.world?.time || 0;
if (!alreadyInside && occupants.length >= capacity) return this.abortNestBoxEntry?.(box, "巣箱がいっぱいで入れない") || false;
if (!alreadyInside && occupants.length >= capacity) {
if (options?.forceDisplace) {
const victim = occupants.find(t => t && t !== this && !t.dead && !t.isTarinaiChampion)
|| occupants.find(t => t && t !== this && !t.dead);
if (victim) {
victim.leaveNestBox?.(box);
victim.awakeLockTimer = Math.max(victim.awakeLockTimer || 0, 0.8);
victim.fearTimer = Math.max(victim.fearTimer || 0, 0.22);
victim.thought = "\u5DE3\u7BB1\u304B\u3089\u62BC\u3057\u51FA\u3055\u308C\u305F";
victim.pinchThoughtTimer = Math.max(victim.pinchThoughtTimer || 0, 0.65);
victim.goIdle?.("\u5DE3\u7BB1\u304B\u3089\u62BC\u3057\u51FA\u3055\u308C\u305F");
occupants = this.world?.nestBoxOccupants ? this.world.nestBoxOccupants(box, Infinity) : occupants.filter(t => t !== victim);
}
}
if (occupants.length >= capacity) return this.abortNestBoxEntry?.(box, "\u5DE3\u7BB1\u304C\u3044\u3063\u3071\u3044\u3067\u5165\u308C\u306A\u3044") || false;
}
if (!alreadyInside) {
this._nestBoxSeekStartedAt = NaN;
this._nestBoxSeekTargetId = "";
@ -392,7 +407,7 @@
}
this.sleeping = false;
this.sleepSession = null;
if (this.state === "sleep" || this.state === "seek_bed") this.goIdle?.("巣箱から出た");
if (this.state === "sleep" || this.state === "seek_bed") this.goIdle?.("\u5DE3\u7BB1\u304B\u3089\u51FA\u305F");
this.nestBoxStayUntil = -Infinity;
this.nestBoxSlotIndex = -1;
this._nestBoxEntrySmoothUntil = -Infinity;
@ -450,7 +465,7 @@
this._nestBoxSeekTargetId = targetBox.id;
}
if (!this.insideNestBoxId && global.TarinaiNestSleepSystem.sleepPlaceAvailableFor && !global.TarinaiNestSleepSystem.sleepPlaceAvailableFor(this.world, this, targetBox)) {
return this.abortNestBoxEntry?.(targetBox, "巣箱がいっぱいで入れない") || null;
return this.abortNestBoxEntry?.(targetBox, "\u5DE3\u7BB1\u304C\u3044\u3063\u3071\u3044\u3067\u5165\u308C\u306A\u3044") || null;
}
const entry = this.world?.nestBoxEntryPoint ? this.world.nestBoxEntryPoint(targetBox) : { x: targetBox.x, y: targetBox.y };
@ -484,6 +499,92 @@
if (this.explosionDisease) this.recoverExplosionDisease("\u6c34\u3067\u7206\u767a\u75c5\u304c\u6cbb\u3063\u305f");
},
igniteFire(source = null, force = false) {
if (this.dead) return false;
const already = Boolean(this.burning || (this.burnTimer || 0) > 0.02);
if (already && !force) return false;
const text = globalThis.TarinaiItemDynamicToolSystem?.fireBurningText || "\u71c3\u3048\u3066\u9003\u3052\u307e\u3069\u3063\u3066\u3044\u308b\u3002";
this.burning = true;
this.burnTimer = Math.max(Number(this.burnTimer || 0) || 0, 5.2 + deterministicRange(this.world, "tarinai-burn-duration", 0, 2.8, this, source || null));
this.firePanicTimer = 0;
this.lastPanicCause = "burning";
this.lastPanicDetail = text;
this.thought = text;
this.sleeping = false;
this.awakeLockTimer = Math.max(this.awakeLockTimer || 0, 0.8);
this.fearTimer = Math.max(this.fearTimer || 0, 2.2);
this.surpriseTimer = Math.max(this.surpriseTimer || 0, 0.65);
this.eatTimer = 0;
this.target = null;
this.burnWanderAngle = Number.isFinite(this.burnWanderAngle) ? this.burnWanderAngle : deterministicAngle(this.world, "tarinai-burn-angle", this, source || null);
if (typeof this.enterPanic === "function") this.enterPanic({ threat: source, target: null, reason: text, fear: 2.2, wake: true, cause: "burning", surpriseTimer: 0.65, awakeLockTimer: 0.8 });
else this.setActionState?.("panic", { target: null, reason: text, wake: true });
this.world?.effects?.push(new Effect("ring", this.x, this.y, { size: Math.max(26, this.radius * 1.35), life: 0.26, color: "rgba(255,110,36,0.58)" }));
this.world?.emit?.("fire:ignite", { tarinai: this, source });
this.recordChangeCause?.("\u708e\u4e0a", "\u708e");
return true;
},
extinguishFire(reason = "") {
if (!this.burning && !(this.burnTimer > 0)) return false;
this.burning = false;
this.burnTimer = 0;
this.firePanicTimer = Math.max(this.firePanicTimer || 0, 0.25);
this.hurtTimer = Math.max(this.hurtTimer || 0, 0.35);
if (reason) this.thought = reason;
this.world?.effects?.push(new Effect("ring", this.x, this.y, { size: Math.max(22, this.radius * 1.2), life: 0.22, color: "rgba(108,192,236,0.60)" }));
this.world?.emit?.("fire:extinguish", { tarinai: this, reason });
return true;
},
updateBurning(dt) {
this.firePanicTimer = Math.max(0, Number(this.firePanicTimer || 0) - dt);
if (!this.burning && !(this.burnTimer > 0)) return;
const text = globalThis.TarinaiItemDynamicToolSystem?.fireBurningText || "\u71c3\u3048\u3066\u9003\u3052\u307e\u3069\u3063\u3066\u3044\u308b\u3002";
this.burning = true;
this.burnTimer = Math.max(0, Number(this.burnTimer || 0) - dt);
this.lastPanicCause = "burning";
this.lastPanicDetail = text;
this.thought = text;
this.fearTimer = Math.max(this.fearTimer || 0, 0.8);
this.sleeping = false;
this.eatTimer = 0;
if (typeof applyNeedShock === "function") applyNeedShock(this, { health: dt * 6.2, safety: dt * 3.0 });
if (typeof this.damage === "function") this.damage(dt * 3.8, "\u708e");
else this.energy = clamp((this.energy || 0) - dt * 0.12, 0, typeof tarinaiMaxEnergy === "function" ? tarinaiMaxEnergy(this) : (Number(this.maxEnergy) || 100));
this.hurtTimer = Math.max(this.hurtTimer || 0, 0.22);
const water = globalThis.TarinaiItemDynamicToolSystem?.contactWaterDrop?.(this.world, this.x, this.y, Math.max(this.radius || 18, 16));
if (water) {
globalThis.TarinaiItemDynamicToolSystem?.consumeWaterForFire?.(this.world, water, Math.max(10, (this.radius || 18) * 0.55));
this.extinguishFire("\u6c34\u3067\u6d88\u706b\u3055\u308c\u305f");
return;
}
const mul = globalThis.TarinaiItemDynamicToolSystem?.fireTempMultiplier?.(this.world, this.x, this.y, this) || 1;
if (deterministicChance(this.world, "tarinai-fire-extinguish", dt * 0.016 * mul, this)) {
this.extinguishFire("\u81ea\u7136\u306b\u706b\u304c\u6d88\u3048\u305f");
return;
}
for (const viewer of [...(this.world?.nearbyTarinai?.(this.x, this.y, 190, true) || [])]) {
if (!viewer || viewer === this || viewer.dead) continue;
globalThis.TarinaiItemDynamicToolSystem?.panicTarinaiFromFire?.(viewer, this, this.world);
}
const contactRadius = Math.max(20, (this.radius || 18) * 1.1);
for (const other of [...(this.world?.nearbyTarinai?.(this.x, this.y, contactRadius + 28, true) || [])]) {
if (!other || other === this || other.dead) continue;
if (distXY(this.x, this.y, other.x, other.y) <= contactRadius + Math.max(other.radius || 18, 12) * 0.72) other.igniteFire?.(this, false);
}
for (const ant of [...(this.world?.nearbyAnts?.(this.x, this.y, contactRadius + 18, true) || [])]) {
if (!ant || ant.dead) continue;
if (distXY(this.x, this.y, ant.x, ant.y) <= contactRadius + Math.max(ant.r || 4, 4)) globalThis.TarinaiItemDynamicToolSystem?.igniteAntByFire?.(ant, this, this.world);
}
for (const it of [...(this.world?.nearbyItems?.(this.x, this.y, contactRadius + 32, true) || [])]) {
if (!it || it.dead || it.type !== "grass") continue;
if (distXY(this.x, this.y, it.x, it.y) <= contactRadius + Math.max(it.r || 16, 12)) globalThis.TarinaiItemDynamicToolSystem?.igniteGrassByFire?.(it, this, this.world, dt);
}
if (this.burnTimer <= 0.01) this.extinguishFire("\u81ea\u7136\u306b\u706b\u304c\u6d88\u3048\u305f");
},
updateSpecialDiseases(dt) {
this.sleepDiseaseCooldown = Math.max(0, (this.sleepDiseaseCooldown || 0) - dt);
this.fightDiseaseCooldown = Math.max(0, (this.fightDiseaseCooldown || 0) - dt);