This commit is contained in:
33333-33333 2026-06-28 13:40:41 +09:00
commit f500279abd
93 changed files with 1893 additions and 1198 deletions

View file

@ -50,6 +50,34 @@
const bodyContactRange = Math.max(74, selfRadius + otherRadius + 18);
if (d < 0.01 || d > bodyContactRange) continue;
closeCount += 1;
const champion = this.isTarinaiChampion ? this : (o.isTarinaiChampion ? o : null);
if (champion && this.isTarinaiChampion !== o.isTarinaiChampion) {
const avoider = champion === this ? o : this;
const nx = (avoider.x - champion.x) / d;
const ny = (avoider.y - champion.y) / d;
const avoidRange = Math.max(92, selfRadius + otherRadius + 34);
const urgency = clamp(1 - d / avoidRange, 0, 1);
const push = dt * (64 + urgency * 260);
avoider.vx += nx * push;
avoider.vy += ny * push;
if (d <= selfRadius + otherRadius + 14) {
avoider.vx += nx * dt * 190;
avoider.vy += ny * dt * 190;
champion.vx -= nx * dt * 8;
champion.vy -= ny * dt * 8;
avoider.surpriseTimer = Math.max(avoider.surpriseTimer || 0, 0.20);
avoider.fearTimer = Math.max(avoider.fearTimer || 0, 0.32 * avoider.personalityProfile().fear);
if (typeof applyNeedShock === "function") applyNeedShock(avoider, { safety: dt * 26, social: dt * 5 }, champion);
if (this.world.relationNotice?.(avoider.id, champion.id, "tarinai-champion-avoid", 18)) {
this.world.log(`${avoider.name}はたりない王者の${champion.name}にぶつかりそうになって避けた。`, "relation", { participants: [avoider, champion], eventType: "avoid_relationship", hiddenFromObservation: true, sound: false });
}
}
avoider.lastNeedShockBreaker = champion;
avoider.thought = `${champion.name || "相手"}はたりない王者だ`;
avoider.adjustRelation?.(champion, -dt * 0.025, dt * 0.18, "tarinai_champion_avoid");
if (this !== champion) continue;
}
const fightMochiContact = this.world.canFightPair?.(this, o) && (this.hasFightMochiEffect() || o.hasFightMochiEffect());
if (fightMochiContact && (this.world.fightPairCooldownRemaining?.(this, o) || 0) <= 0.04 && this.fightCooldown <= 0.04 && o.fightCooldown <= 0.04 && d <= Math.max(42, this.radius + o.radius + 16)) {
@ -266,7 +294,7 @@
const dx = spot.x - this.x;
const dy = spot.y - this.y;
const d = Math.hypot(dx, dy);
if (externalActive && d > 8.5 && !this.sleepDisease && marker?.wakeSleepingFromExternalMotion?.(this, "動かされて目が覚めた")) return;
if (externalActive && d > 8.5 && !this.sleepDisease && marker?.wakeSleepingFromExternalMotion?.(this, "\u52d5\u304b\u3055\u308c\u3066\u76ee\u304c\u899a\u3081\u305f")) return;
if (d > 2.2) {
const restore = externalActive ? (2.0 + bedComfort * 2.0) : (12 + bedComfort * 14);
const maxRestore = externalActive ? Math.min(d, 3.2) : d;
@ -298,7 +326,7 @@
marker?.markSleepExternalMotion?.(this, dt, "sleep-full-contact");
const cdx = (Number(this.x || 0) || 0) - beforeContactX;
const cdy = (Number(this.y || 0) || 0) - beforeContactY;
if (Math.hypot(cdx, cdy) > 1.8 && !this.sleepDisease && marker?.wakeSleepingFromExternalMotion?.(this, "ぶつかって目が覚めた")) return;
if (Math.hypot(cdx, cdy) > 1.8 && !this.sleepDisease && marker?.wakeSleepingFromExternalMotion?.(this, "\u3076\u3064\u304b\u3063\u3066\u76ee\u304c\u899a\u3081\u305f")) return;
if (Math.hypot(cdx, cdy) > 0.05) {
this.vx = clamp((Number(this.vx) || 0) + cdx / Math.max(0.016, dt) * 0.085, -170, 170);
this.vy = clamp((Number(this.vy) || 0) + cdy / Math.max(0.016, dt) * 0.085, -170, 170);
@ -318,7 +346,7 @@
if (this.birthRitualTimer > 0.04 || this.state === "birth_ritual") {
const pendingImpulse = Math.hypot(Number.isFinite(this.impulseVx) ? this.impulseVx : 0, Number.isFinite(this.impulseVy) ? this.impulseVy : 0);
const canceledByForce = this.world?.cancelBirthRitualOnForce?.(this, pendingImpulse, {
reason: "強い衝撃で繁殖が中断された",
reason: "\u5f37\u3044\u885d\u6483\u3067\u7e41\u6b96\u304c\u4e2d\u65ad\u3055\u308c\u305f",
target: this.target || null,
fear: 1.0,
cause: "stored_impulse",
@ -515,12 +543,16 @@
if (reason) this.die(reason);
},
die(reason) {
die(reason, opts = {}) {
if (this.dead) return;
const finalReason = this.normalizeDeathReason ? this.normalizeDeathReason(reason) : (reason || "\u4e8b\u6545");
const finalReason = this.normalizeDeathReason ? this.normalizeDeathReason(reason, opts) : (reason || "\u4e8b\u6545");
this.dead = true;
this.deathReason = finalReason;
this.world.deadCount += 1;
this.world.lastDeathAt = this.world.time || 0;
if (!Array.isArray(this.world.recentDeathTimes)) this.world.recentDeathTimes = [];
this.world.recentDeathTimes.push(this.world.lastDeathAt);
if (this.world.recentDeathTimes.length > 24) this.world.recentDeathTimes = this.world.recentDeathTimes.slice(-24);
for (const item of this.world.items || []) {
if (!item || item.dead || !item.isStructure || item.type !== "plushie" || item.ownerId !== this.id) continue;
item.dead = true;