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

@ -82,6 +82,81 @@ class AntActor {
this.carryLogAt = opts.carryLogAt || -999;
this.foundingAttempts = opts.foundingAttempts || 0;
this.dead = Boolean(opts.dead);
this.burning = Boolean(opts.burning);
this.burnTimer = Number.isFinite(opts.burnTimer) ? opts.burnTimer : 0;
this.burnTurnTimer = 0;
}
igniteFire(source = null) {
if (this.dead) return false;
this.burning = true;
this.burnTimer = Math.max(this.burnTimer || 0, 4.2 + rand(0, 2.4));
this.state = "panic";
this.targetId = "";
this.targetToken = 0;
this.targetRef = null;
this.burnWanderAngle = rand(0, Math.PI * 2);
this.hpBarTimer = Math.max(this.hpBarTimer || 0, 1.0);
this.world?.effects?.push(new Effect("ring", this.x, this.y, { size: Math.max(10, this.r * 2.8), life: 0.18, color: "rgba(255,110,36,0.56)" }));
this.world?.emit?.("fire:ignite-ant", { ant: this, source });
return true;
}
extinguishFire(reason = "") {
if (!this.burning && !(this.burnTimer > 0)) return false;
this.burning = false;
this.burnTimer = 0;
this.world?.effects?.push(new Effect("ring", this.x, this.y, { size: Math.max(9, this.r * 2.2), life: 0.16, color: "rgba(108,192,236,0.58)" }));
return true;
}
updateBurning(dt) {
if (!this.burning && !(this.burnTimer > 0)) return false;
this.burning = true;
this.burnTimer = Math.max(0, Number(this.burnTimer || 0) - dt);
this.hp = Math.max(0, Number(this.hp || 0) - dt * (this.kind === "queen" ? 11 : 7.5));
this.hpBarTimer = Math.max(this.hpBarTimer || 0, 0.55);
const water = globalThis.TarinaiItemDynamicToolSystem?.contactWaterDrop?.(this.world, this.x, this.y, Math.max(this.r || 5, 7));
if (water) {
globalThis.TarinaiItemDynamicToolSystem?.consumeWaterForFire?.(this.world, water, 5);
this.extinguishFire("water");
return true;
}
const mul = globalThis.TarinaiItemDynamicToolSystem?.fireTempMultiplier?.(this.world, this.x, this.y, this) || 1;
if (deterministicChance(this.world, "ant-fire-extinguish", dt * 0.020 * mul, this)) {
this.extinguishFire("natural");
return true;
}
this.burnTurnTimer = Math.max(0, Number(this.burnTurnTimer || 0) - dt);
if (this.burnTurnTimer <= 0) {
this.burnWanderAngle = deterministicAngle(this.world, "ant-burn-angle", this, Math.floor((this.world?.time || 0) * 6));
this.burnTurnTimer = deterministicRange(this.world, "ant-burn-turn", 0.08, 0.28, this);
} else {
this.burnWanderAngle += deterministicRange(this.world, "ant-burn-jitter", -9.0, 9.0, this) * dt;
}
const speed = this.kind === "queen" ? ANT_QUEEN_SPEED * 3.0 : ANT_WORKER_RETURN_SPEED * 3.3;
this.vx = Math.cos(this.burnWanderAngle || 0) * speed;
this.vy = Math.sin(this.burnWanderAngle || 0) * speed;
this.x = clamp(this.x + this.vx * dt, CONFIG.worldPadding, this.world.w - CONFIG.worldPadding);
this.y = clamp(this.y + this.vy * dt, CONFIG.worldPadding, this.world.h - CONFIG.worldPadding);
for (const viewer of [...(this.world?.nearbyTarinai?.(this.x, this.y, 170, true) || [])]) {
if (!viewer || viewer.dead) continue;
globalThis.TarinaiItemDynamicToolSystem?.panicTarinaiFromFire?.(viewer, this, this.world);
}
const contactRadius = Math.max(10, (this.r || 5) * 2.1);
for (const t of [...(this.world?.nearbyTarinai?.(this.x, this.y, contactRadius + 26, true) || [])]) {
if (!t || t.dead) continue;
if (distXY(this.x, this.y, t.x, t.y) <= contactRadius + Math.max(t.radius || 18, 12) * 0.7) t.igniteFire?.(this, false);
}
for (const it of [...(this.world?.nearbyItems?.(this.x, this.y, contactRadius + 28, 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 (deterministicChance(this.world, "ant-fire-effect", dt * 2.0, this)) {
this.world?.effects?.push(new Effect("fight", this.x, this.y - this.r, { vx: rand(-6, 6), vy: rand(-22, -8), size: Math.max(5, this.r * 1.8), life: 0.28, color: "rgba(255,118,35,0.72)" }));
}
if (this.burnTimer <= 0.01) this.extinguishFire("timeout");
return true;
}
homeNest() {
@ -180,7 +255,10 @@ class AntActor {
if (this.dead) return;
const hpBefore = this.hp;
this.age += dt;
if (this.kind === "queen") this.updateQueen(dt);
if (this.burning || (this.burnTimer || 0) > 0.02) {
this.updateBurning(dt);
if (this.hp <= 0) this.dieAsCorpse(this.homeNest?.() || null);
} else if (this.kind === "queen") this.updateQueen(dt);
else this.updateWorker(dt);
if (Number.isFinite(hpBefore) && this.hp < hpBefore - 0.01) this.hpBarTimer = Math.max(this.hpBarTimer || 0, 1.25);
this.hpBarTimer = Math.max(0, (this.hpBarTimer || 0) - dt);
@ -444,6 +522,18 @@ class AntActor {
ctx.arc(this.r * 1.15, -this.r * 0.05, this.r * 0.46, 0, Math.PI * 2);
ctx.fill();
}
if (this.burning || (this.burnTimer || 0) > 0.02) {
ctx.fillStyle = "rgba(255,112,34,0.82)";
ctx.strokeStyle = "rgba(255,226,92,0.70)";
ctx.lineWidth = Math.max(0.8, this.r * 0.16);
for (let i = 0; i < 3; i++) {
const a = this.seed + this.age * 8 + i * 2.1;
ctx.beginPath();
ctx.ellipse(Math.cos(a) * this.r * 0.34, -this.r * (0.8 + i * 0.32), this.r * (0.45 - i * 0.05), this.r * (0.75 - i * 0.08), a * 0.25, 0, Math.PI * 2);
ctx.fill();
ctx.stroke();
}
}
ctx.restore();
this.drawHealthBar(ctx);
}