"use strict"; (function (global) { const Tarinai = global.Tarinai; if (!Tarinai) throw new Error("Tarinai is not available for mixin: tarinai_disease_nest.js"); Object.defineProperties(Tarinai.prototype, Object.getOwnPropertyDescriptors({ infectZunchiDisease(source = null, force = false) { if (this.dead || this.zunchiDisease) return false; if (!force && (this.zunchiDiseaseCooldown || 0) > 0) return false; this.zunchiDisease = true; this.zunchiDiseaseSeverity = Math.max(this.zunchiDiseaseSeverity || 0, source ? 0.72 : 0.86); this.zunchiDiseaseCooldown = 12; this.fearTimer = Math.max(this.fearTimer || 0, 0.35); this.surpriseTimer = Math.max(this.surpriseTimer || 0, 0.45); this.thought = "\u305a\u3093\u3061\u75c5\u306b\u304b\u304b\u3063\u305f"; audio.disease?.(); this.world?.spawnBubble?.(this.x, this.y - this.radius * 1.20, "\u3046\u3045\u2026", "rgba(38,82,38,0.82)"); this.world?.emit?.("disease:infected", { tarinai: this, diseaseId: "disease_zunchi", source }); this.recordChangeCause?.("\u75c5\u6c17\u767a\u75c7", "\u305a\u3093\u3061\u75c5"); return true; }, recoverZunchiDisease(reason = "") { if (!this.zunchiDisease) return false; this.zunchiDisease = false; this.zunchiDiseaseSeverity = 0; this.zunchiDiseaseCooldown = 18; this.zunchiStain = clamp((this.zunchiStain || 0) - 35, 0, 100); this.stress = clamp(this.stress - 8, 0, 130); this.thought = reason || "\u305a\u3093\u3061\u75c5\u304c\u6cbb\u307e\u3063\u305f"; audio.heal?.(); this.world?.spawnBubble?.(this.x, this.y - this.radius * 1.18, "\u306f\u3046", "rgba(62,104,62,0.78)"); this.world?.emit?.("disease:cured", { tarinai: this, diseaseId: "disease_zunchi", reason }); this.recordChangeCause?.("\u75c5\u6c17\u56de\u5fa9", "\u305a\u3093\u3061\u75c5"); return true; }, emitZunchiDiseaseEffect(dt) { if (!this.zunchiDisease || !this.world?.effects) return; if (Math.random() < dt * (1.2 + (this.zunchiDiseaseSeverity || 0) * 1.4)) { this.world.effects.push(new Effect("zunchi_miasma", this.x + rand(-this.radius * 0.45, this.radius * 0.45), this.y - this.radius * rand(0.05, 0.72), { vx: rand(-5, 5), vy: rand(-10, -3), life: rand(1.4, 2.4), size: rand(8, 18) * (0.8 + (this.zunchiDiseaseSeverity || 0) * 0.45), color: "rgba(16,78,28,0.70)", })); } }, updateZunchiDisease(dt) { this.zunchiStain = clamp(this.zunchiStain || 0, 0, 100); this.zunchiDiseaseCooldown = Math.max(0, (this.zunchiDiseaseCooldown || 0) - dt); if (this.world?.weather === "light_rain") { this.zunchiStain = clamp(this.zunchiStain - dt * 2.4, 0, 100); if (this.zunchiDisease) this.zunchiDiseaseSeverity = Math.max(0, (this.zunchiDiseaseSeverity || 1) - dt * 0.006); } if (!this.zunchiDisease && this.zunchiStain > 82 && Math.random() < (this.diseaseChance ? this.diseaseChance(dt * clamp((this.zunchiStain - 82) / 18, 0, 1) * 0.045) : dt * clamp((this.zunchiStain - 82) / 18, 0, 1) * 0.045)) { this.infectZunchiDisease(null, true); this.world?.log?.(`${this.name}\u306f\u305a\u3093\u3061\u75c5\u3092\u767a\u75c7\u3057\u305f\u3002`, "accident", { participants: [this] }); } if (this.zunchiDisease) { this.zunchiDiseaseSeverity = clamp((this.zunchiDiseaseSeverity || 0.7) + dt * 0.004, 0, 1.25); this.stress = clamp(this.stress + dt * (0.28 + 0.18 * this.zunchiDiseaseSeverity), 0, 130); this.energy = clamp(this.energy - dt * 0.035 * this.zunchiDiseaseSeverity, 0, 100); if (this.energy > 82) this.zunchiDiseaseSeverity = Math.max(0, this.zunchiDiseaseSeverity - dt * (this.energy > 94 ? 0.020 : 0.010)); this.emitZunchiDiseaseEffect(dt); if (this.zunchiDiseaseSeverity <= 0.04) { if (this.recoverZunchiDisease("\u4f53\u529b\u304c\u623b\u308a\u3001\u305a\u3093\u3061\u75c5\u304c\u6cbb\u307e\u3063\u305f")) this.world?.log?.(`${this.name}\u306e\u305a\u3093\u3061\u75c5\u304c\u6cbb\u307e\u3063\u305f\u3002`, "accident", { participants: [this] }); } } }, hasWaterCurableDisease() { return Boolean(this.zunchiDisease || this.explosionDisease); }, hasZundaCurableDisease() { return Boolean(this.explosionDisease || this.fightDisease); }, infectSleepDisease(source = null) { if (this.dead || this.sleepDisease) return false; this.sleepDisease = true; this.sleepDiseaseCooldown = 8; this.sleepDiseaseAnchorX = this.x; this.sleepDiseaseAnchorY = this.y; this.startSleeping(null, "ねむり病で眠り続けている"); this.fightTimer = 0; this.intimidateTimer = 0; this.fightTargetIds = []; this.thought = "\u306d\u3080\u308a\u75c5\u3067\u7720\u308a\u7d9a\u3051\u3066\u3044\u308b"; audio.disease?.(); this.world?.spawnBubble?.(this.x, this.y - this.radius * 1.18, "Zzz...", "rgba(72,76,120,0.76)"); this.world?.log?.(`${this.name}\u306f\u306d\u3080\u308a\u75c5\u306b\u304b\u304b\u3063\u305f\u3002`, "accident", { participants: [this] }); this.world?.emit?.("disease:infected", { tarinai: this, diseaseId: "disease_sleep", source }); this.recordChangeCause?.("\u75c5\u6c17\u767a\u75c7", "\u306d\u3080\u308a\u75c5"); return true; }, recoverSleepDisease(reason = "") { if (!this.sleepDisease) return false; this.sleepDisease = false; this.sleepDiseaseCooldown = 14; this.sleepDiseaseAnchorX = null; this.sleepDiseaseAnchorY = null; this.goIdle(reason || "ねむり病が治った"); this.sleeping = false; this.awakeLockTimer = Math.max(this.awakeLockTimer || 0, 10); audio.heal?.(); this.surpriseTimer = Math.max(this.surpriseTimer || 0, 0.65); this.world?.spawnBubble?.(this.x, this.y - this.radius * 1.18, "!", "rgba(72,76,120,0.76)"); this.world?.log?.(`${this.name}\u306e\u306d\u3080\u308a\u75c5\u304c\u6cbb\u3063\u305f\u3002`, "accident", { participants: [this] }); this.world?.emit?.("disease:cured", { tarinai: this, diseaseId: "disease_sleep", reason }); this.recordChangeCause?.("\u75c5\u6c17\u56de\u5fa9", "\u306d\u3080\u308a\u75c5"); return true; }, infectExplosionDisease(source = null) { if (this.dead || this.explosionDisease) return false; this.explosionDisease = true; this.explosionDiseaseTimer = Math.max(this.explosionDiseaseTimer || 0, 60); this.fearTimer = Math.max(this.fearTimer || 0, 0.55); this.thought = "\u7206\u767a\u75c5\u3067\u843d\u3061\u7740\u304b\u306a\u3044"; audio.disease?.(); this.world?.spawnBubble?.(this.x, this.y - this.radius * 1.2, "!", "rgba(178,78,42,0.82)"); this.world?.log?.(`${this.name}\u306f\u7206\u767a\u75c5\u3092\u767a\u75c7\u3057\u305f\u3002`, "accident", { participants: [this] }); this.world?.emit?.("disease:infected", { tarinai: this, diseaseId: "disease_explosion", source }); this.recordChangeCause?.("\u75c5\u6c17\u767a\u75c7", "\u7206\u767a\u75c5"); return true; }, recoverExplosionDisease(reason = "") { if (!this.explosionDisease) return false; this.explosionDisease = false; this.explosionDiseaseTimer = 0; this.thought = reason || "\u7206\u767a\u75c5\u304c\u6cbb\u3063\u305f"; audio.heal?.(); this.stress = clamp(this.stress - 10, 0, 130); this.world?.spawnBubble?.(this.x, this.y - this.radius * 1.18, "\u306f\u3046", "rgba(82,126,88,0.76)"); this.world?.log?.(`${this.name}\u306e\u7206\u767a\u75c5\u304c\u6cbb\u3063\u305f\u3002`, "accident", { participants: [this] }); this.world?.emit?.("disease:cured", { tarinai: this, diseaseId: "disease_explosion", reason }); this.recordChangeCause?.("\u75c5\u6c17\u56de\u5fa9", "\u7206\u767a\u75c5"); return true; }, recordBleedExposure() { this.lastBleedAt = this.world?.time || 0; }, infectFightDisease(source = null) { if (this.dead || this.fightDisease) return false; this.fightDisease = true; this.fightDiseaseCooldown = 18; this.fearTimer = Math.max(this.fearTimer || 0, 0.35); this.thought = "\u304d\u305a\u3064\u304d\u75c5\u3067\u5f53\u3066\u3082\u306a\u304f\u5f77\u5fa8\u3063\u3066\u3044\u308b"; audio.disease?.(); this.world?.spawnBubble?.(this.x, this.y - this.radius * 1.20, "?", "rgba(150,78,44,0.80)"); this.world?.log?.(`${this.name}\u306f\u304d\u305a\u3064\u304d\u75c5\u3092\u767a\u75c7\u3057\u305f\u3002`, "fight", { participants: [this] }); this.world?.emit?.("disease:infected", { tarinai: this, diseaseId: "disease_fight", source }); this.recordChangeCause?.("\u75c5\u6c17\u767a\u75c7", "\u304d\u305a\u3064\u304d\u75c5"); return true; }, recoverFightDisease(reason = "") { if (!this.fightDisease) return false; this.fightDisease = false; this.fightDiseaseCooldown = 20; this.thought = reason || "\u304d\u305a\u3064\u304d\u75c5\u304c\u6cbb\u3063\u305f"; audio.heal?.(); this.stress = clamp(this.stress - 12, 0, 130); this.world?.spawnBubble?.(this.x, this.y - this.radius * 1.18, "\u306f\u3046", "rgba(82,126,88,0.76)"); this.world?.log?.(`${this.name}\u306e\u304d\u305a\u3064\u304d\u75c5\u304c\u6cbb\u3063\u305f\u3002`, "fight", { participants: [this] }); this.world?.emit?.("disease:cured", { tarinai: this, diseaseId: "disease_fight", reason }); this.recordChangeCause?.("\u75c5\u6c17\u56de\u5fa9", "\u304d\u305a\u3064\u304d\u75c5"); return true; }, freezeSleepDiseaseMotion(dt = 0) { if (!this.sleepDisease) return false; const beingDraggedByAnt = Boolean((this.antDraggedTimer || 0) > 0 && this.antDraggedBy); if (!Number.isFinite(this.sleepDiseaseAnchorX)) this.sleepDiseaseAnchorX = this.x; if (!Number.isFinite(this.sleepDiseaseAnchorY)) this.sleepDiseaseAnchorY = this.y; this.startSleeping(null, beingDraggedByAnt ? "眠ったままアリに運ばれている" : "ねむり病で眠り続けている"); this.vx = 0; this.vy = 0; if (beingDraggedByAnt) { this.sleepDiseaseAnchorX = this.x; this.sleepDiseaseAnchorY = this.y; } else { this.x = this.sleepDiseaseAnchorX; this.y = this.sleepDiseaseAnchorY; } this.wanderAngle = this.wanderAngle || 0; this.thought = beingDraggedByAnt ? "\u7720\u3063\u305f\u307e\u307e\u30a2\u30ea\u306b\u904b\u3070\u308c\u3066\u3044\u308b" : "\u306d\u3080\u308a\u75c5\u3067\u7720\u308a\u7d9a\u3051\u3066\u3044\u308b"; if (this.world && this.world.time > (this.nextSleepBubbleAt || 0)) { this.nextSleepBubbleAt = this.world.time + 5.0; this.world.spawnBubble?.(this.x, this.y - this.radius * 1.18, "Zzz...", "rgba(65,70,92,0.72)"); } return true; }, nestBoxById(id) { if (!id) return null; return this.world?.items?.find?.(it => it && !it.dead && it.id === id && it.type === "nest_box") || null; }, isInsideNestBox() { return Boolean(this.insideNestBoxId); }, wantsNestBox(box = null) { if (!box || box.dead || box.type !== "nest_box") return false; if (this.insideNestBoxId === box.id && (this.world?.time || 0) < (this.nestBoxStayUntil || -Infinity)) return true; if (!(this.state === "sleep" || this.state === "seek_bed")) return false; return this.target === box || this.insideNestBoxId === box.id; }, enterNestBox(box, dt = 0.016) { 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) : []; const alreadyInside = this.insideNestBoxId === box.id; if (!alreadyInside && occupants.length >= capacity) return false; if (!alreadyInside) { this.nestBoxEnteredAt = this.world?.time || 0; this.nestBoxStayUntil = Math.max(this.nestBoxStayUntil || -Infinity, (this.world?.time || 0) + 14); } this.insideNestBoxId = box.id; this.target = box; if (this.state === "seek_bed") this.startSleeping(box, "巣箱の中で眠っている"); if (this.state === "sleep") this.sleeping = true; const inner = this.world?.nestBoxInnerPoint ? this.world.nestBoxInnerPoint(box, this) : { x: box.x, y: box.y }; const pull = clamp(dt * (alreadyInside ? 10.0 : 13.5), 0, 1); this.x = lerp(this.x, inner.x, pull); this.y = lerp(this.y, inner.y, pull); if (this.nestFade >= 0.88 || distXY(this.x, this.y, inner.x, inner.y) < 3.5) { this.x = inner.x; this.y = inner.y; } this.nestFade = clamp((this.nestFade || 0) + dt * 5.8, 0, 1); this.vx = 0; this.vy = 0; this.impulseVx = 0; this.impulseVy = 0; return true; }, leaveNestBox(box = null) { const b = box || this.nestBoxById(this.insideNestBoxId); if (b && this.world?.nestBoxEntryPoint) { const entry = this.world.nestBoxExitPoint ? this.world.nestBoxExitPoint(b, this) : this.world.nestBoxEntryPoint(b); this.x = clamp(entry.x, CONFIG.worldPadding, this.world.w - CONFIG.worldPadding); this.y = clamp(entry.y, CONFIG.worldPadding, this.world.h - CONFIG.worldPadding); this.vx = rand(-8, 8); this.vy = rand(6, 18); } this.insideNestBoxId = null; this.nestFade = 0; this.nestBoxEnteredAt = -Infinity; this.nestBoxStayUntil = -Infinity; return true; }, updateNestBoxPresence(dt = 0) { const currentBox = this.nestBoxById(this.insideNestBoxId); const targetBox = this.target && !this.target.dead && this.target.type === "nest_box" ? this.target : null; const box = currentBox || targetBox; if (!box) { this.insideNestBoxId = null; this.nestFade = clamp((this.nestFade || 0) - dt * 3.0, 0, 1); return null; } if (currentBox && !this.wantsNestBox(currentBox)) { this.leaveNestBox(currentBox); return null; } if (currentBox) { if ((this.world?.time || 0) < (this.nestBoxStayUntil || -Infinity)) { this.startSleeping(box, "巣箱の中で眠っている"); this.sleeping = true; this.target = currentBox; } this.enterNestBox(currentBox, dt); return currentBox; } if (!this.wantsNestBox(targetBox)) { this.nestFade = clamp((this.nestFade || 0) - dt * 3.0, 0, 1); return null; } const entry = this.world?.nestBoxEntryPoint ? this.world.nestBoxEntryPoint(targetBox) : { x: targetBox.x, y: targetBox.y }; const base = this.world?.nestBoxBaseRect ? this.world.nestBoxBaseRect(targetBox) : null; const r = targetBox.r || 42; const entryD = distXY(this.x, this.y, entry.x, entry.y); const centerD = distXY(this.x, this.y, targetBox.x, targetBox.y); const inDoorColumn = base && this.x >= base.left + r * 0.18 && this.x <= base.right - r * 0.18 && this.y >= base.top + r * 0.06 && this.y <= base.bottom + r * 0.48; const captureRange = Math.max(118, r * 2.05, this.radius + 82); const nearEnough = entryD <= captureRange || centerD <= Math.max(104, r * 1.90) || inDoorColumn; if (nearEnough) { this.enterNestBox(targetBox, dt || 0.016); return targetBox; } this.nestFade = clamp((this.nestFade || 0) - dt * 3.0, 0, 1); return null; }, applyWaterEffect(dt, source = "water") { const power = Math.max(0, dt || 0); this.stress = clamp(this.stress - power * 2.4, 0, 130); this.energy = clamp(this.energy + power * 0.5, 0, 100); this.hunger = clamp(this.hunger - power * 0.2, 0, 115); this.zunchiStain = clamp((this.zunchiStain || 0) - power * 10.5, 0, 100); if (this.zunchiDisease) { this.zunchiDiseaseSeverity = Math.max(0, (this.zunchiDiseaseSeverity || 1) - power * (this.energy > 70 ? 0.050 : 0.028)); if (this.zunchiDiseaseSeverity <= 0.04 && this.recoverZunchiDisease("\u6c34\u3067\u305a\u3093\u3061\u75c5\u304c\u6cbb\u307e\u3063\u305f")) { this.world?.log?.(`${this.name}\u306f\u6c34\u3067\u305a\u3093\u3061\u75c5\u304c\u6cbb\u307e\u3063\u305f\u3002`, "accident", { participants: [this] }); } } if (this.explosionDisease) this.recoverExplosionDisease("\u6c34\u3067\u7206\u767a\u75c5\u304c\u6cbb\u3063\u305f"); }, updateSpecialDiseases(dt) { this.sleepDiseaseCooldown = Math.max(0, (this.sleepDiseaseCooldown || 0) - dt); this.fightDiseaseCooldown = Math.max(0, (this.fightDiseaseCooldown || 0) - dt); if (this.explosionDisease) { this.explosionDiseaseTimer = Math.max(0, (this.explosionDiseaseTimer || 0) - dt); this.addStress ? this.addStress(dt * 0.22, { threshold: 9, duration: 3.6 }) : (this.stress = clamp(this.stress + dt * 0.22, 0, 130)); if (Math.random() < dt * 2.1) { const a = rand(0, Math.PI * 2); this.world?.effects?.push(new Effect("explosion", this.x + Math.cos(a) * this.radius * rand(0.2, 0.9), this.y + Math.sin(a) * this.radius * rand(0.1, 0.8), { vx: Math.cos(a) * rand(10, 38), vy: Math.sin(a) * rand(10, 38) - rand(8, 22), size: rand(5, 12), life: rand(0.18, 0.42), color: "rgba(255,64,48,0.86)" })); } if (this.explosionDiseaseTimer <= 0.01) { this.world?.explodeDiseaseTarinai?.(this); return; } if (this.explosionDiseaseTimer < 8 && Math.random() < dt * 0.45) this.bubble("!", 1.0, "rgba(178,78,42,0.82)"); } const bleedAge = (this.world?.time || 0) - (this.lastBleedAt || -999); if (!this.fightDisease && this.fightDiseaseCooldown <= 0 && bleedAge >= (CONFIG.dayLength || 120) * 5 / 24 && bleedAge < (CONFIG.dayLength || 120) * 0.85) { if (Math.random() < (this.diseaseChance ? this.diseaseChance(dt * 0.000375) : dt * 0.000375)) this.infectFightDisease(); } if (this.zunchiDisease && Math.random() < dt * 0.00055 * (this.energy > 66 ? 1.8 : 1.0)) { if (this.recoverZunchiDisease("\u81ea\u7136\u306b\u305a\u3093\u3061\u75c5\u304c\u6cbb\u307e\u3063\u305f")) this.world?.log?.(`${this.name}\u306e\u305a\u3093\u3061\u75c5\u304c\u81ea\u7136\u306b\u6cbb\u3063\u305f\u3002`, "accident", { participants: [this] }); } if (this.fightDisease && Math.random() < dt * 0.00070 * (this.energy > 58 ? 1.4 : 1.0)) { this.recoverFightDisease("\u81ea\u7136\u306b\u304d\u305a\u3064\u304d\u75c5\u304c\u6cbb\u3063\u305f"); } if (this.fightDisease) { this.stress = clamp(this.stress + dt * 0.16, 0, 130); if (Math.random() < dt * 0.30) this.wanderAngle += rand(-2.8, 2.8); if (Math.random() < dt * 0.08) this.bubble("?", 2.6, "rgba(150,78,44,0.80)"); } } })); })(typeof window !== "undefined" ? window : globalThis);