This commit is contained in:
33333-33333 2026-06-20 21:41:15 +09:00
commit 10fbeb2327
18 changed files with 794 additions and 16 deletions

View file

@ -952,7 +952,7 @@ class Tarinai {
const low = this.lowHealthSprite();
if (low === "stretch") return low;
if (this.defeatedTimer > 0.04) return this.variantSprite("flee");
if (this.state === "intimidate" || this.intimidateTimer > 0.04) return this.variantSprite("intimidate");
if (this.state === "intimidate" || this.state === "ant_intimidate" || this.intimidateTimer > 0.04) return this.variantSprite("intimidate");
if (this.state === "panic" || this.state === "cursor_enemy" || this.fearTimer > 0.08 || this.intimidatedTimer > 0.08) return this.variantSprite("fear");
if (this.state === "fight" || this.fightTimer > 0.04) return "angry";
if (this.stress > 62 || (this.stress > 50 && this.mood < 46)) return this.variantSprite("stress");
@ -1377,6 +1377,40 @@ class Tarinai {
return;
}
const nearbyAnts = (this.world.ants || []).filter(a => a && !a.dead && distXY(this.x, this.y, a.x, a.y) <= (a.kind === "queen" ? 112 : 82));
let nearestAnt = null;
let nearestAntDist = Infinity;
for (const ant of nearbyAnts) {
const ad = distXY(this.x, this.y, ant.x, ant.y);
if (ad < nearestAntDist) {
nearestAnt = ant;
nearestAntDist = ad;
}
}
if (nearestAnt) {
const aggressiveToAnts = this.shouldApplyPersonalityBehavior("aggression", 1);
if (aggressiveToAnts && this.energy > 12 && this.fightTimer <= 0.04 && this.defeatedTimer <= 0.04) {
if (nearestAntDist < Math.max(36, this.radius + (nearestAnt.r || 4) + 8) && Math.random() < dt * 0.28) {
// Intimidation has no effect on ants. This is only a visible reaction.
this.state = "ant_intimidate";
this.target = nearestAnt;
this.bubble("!", 0.9, "rgba(145,68,52,0.78)");
this.thought = "\u30a2\u30ea\u3092\u5a01\u5687\u3057\u3066\u3044\u308b";
return;
}
this.state = "ant_attack";
this.target = nearestAnt;
this.goodMode = "angry";
this.thought = "\u30a2\u30ea\u3092\u653b\u6483\u3057\u3066\u3044\u308b";
return;
}
this.state = "panic";
this.target = this.panicDestination(nearestAnt);
this.fearTimer = Math.max(this.fearTimer, 0.34);
this.thought = "\u30a2\u30ea\u304b\u3089\u9003\u3052\u3066\u3044\u308b";
return;
}
const dayP = this.world.dayProgress();
const personalSleep = this.sleepStart < this.sleepEnd
? dayP >= this.sleepStart && dayP < this.sleepEnd
@ -1581,7 +1615,7 @@ class Tarinai {
}
if (this.hunger > 62) {
const itemTypes = this.isZunchiSlave ? ["zunchi"] : ["sweet", "love_mochi", "fight_mochi", "sleep_drug", "grass"];
const itemTypes = this.isZunchiSlave ? ["zunchi"] : ["sweet", "love_mochi", "fight_mochi", "sleep_drug", "grass", "ant_corpse"];
const item = this.world.nearest(this, itemTypes, 420);
if (item) {
this.state = "seek_food";
@ -1744,6 +1778,29 @@ class Tarinai {
break;
}
if (canBite && it.type === "ant_corpse") {
const bite = Math.min(it.amount, rand(3.2, 5.4));
if (bite > 0) {
this.state = "eat";
this.target = it;
this.vx *= Math.pow(0.18, dt * 60);
this.vy *= Math.pow(0.18, dt * 60);
it.amount -= bite;
this.hunger -= bite * 0.62;
this.recoverHealth(bite * 0.12);
this.stress = clamp(this.stress + bite * 0.05 * this.personalityProfile().fear, 0, 130);
this.eatTimer = Math.max(this.eatTimer, 0.26);
this.eatCooldown = rand(0.75, 1.25);
this.bubble("\u3082\u3050", 2.2, "rgba(72,60,48,0.78)");
const mouth = this.mouthPosition(it);
this.world.spawnEatEffect(mouth.x, mouth.y, "#4a3f36");
this.lastMealColor = "#4a3f36";
this.makePoop(bite * 0.08);
if (this.world.time > this.nextEatSound) { audio.eat(); this.nextEatSound = this.world.time + 0.62; }
break;
}
}
if (it.type === "zunchi") {
const touch = clamp(1 - d / (this.radius + it.r + 12), 0, 1);
if (!this.isZunchiSlave) {
@ -2019,7 +2076,7 @@ class Tarinai {
return;
}
if (this.intimidateTimer > 0.04 || this.state === "intimidate") {
if (this.intimidateTimer > 0.04 || this.state === "intimidate" || this.state === "ant_intimidate") {
this.vx *= Math.pow(0.22, dt * 60);
this.vy *= Math.pow(0.22, dt * 60);
return;
@ -2083,6 +2140,19 @@ class Tarinai {
strength = headbutt > -0.15 ? 2.65 : 0.65;
sign = headbutt > -0.15 ? 1 : -1;
}
} else if (this.state === "ant_attack") {
strength = d < this.radius + ((this.target && this.target.r) || 4) + 6 ? 0.18 : 1.32;
sign = 1;
if (d < this.radius + ((this.target && this.target.r) || 4) + 10) {
const aggression = Math.max(0, this.currentPersonality?.aggression || 0);
if ((this.world.time || 0) >= (this.nextAntAttackAt || 0)) {
this.nextAntAttackAt = (this.world.time || 0) + 0.34;
if (Number.isFinite(this.target.hp)) this.target.hp = Math.max(0, this.target.hp - (4.6 + aggression * 3.4));
this.fearTimer = Math.max(this.fearTimer, 0.12);
this.thought = "\u30a2\u30ea\u3092\u653b\u6483\u3057\u3066\u3044\u308b";
if (Math.random() < 0.55) this.bubble("!", 0.8, "rgba(145,68,52,0.76)");
}
}
}
ax += (dx / d) * baseSpeed * sign * strength;
ay += (dy / d) * baseSpeed * sign * strength;