not baaad

This commit is contained in:
33333-33333 2026-06-25 22:30:35 +09:00
commit fbdac9ebf1
44 changed files with 2152 additions and 454 deletions

View file

@ -40,6 +40,8 @@
this.liveIdFree = [];
this.liveIdSerial = 0;
this.liveTarinai = new Map();
this.worldSeed = global.TarinaiSeedFactory?.createWorldSeed?.() || `w${Date.now().toString(36)}`;
this.birthSerial = 0;
this.lastBirthAt = -999;
this.maxGeneration = 1;
this.family = {};
@ -62,10 +64,8 @@
this.nextWeatherChange = rand(CONFIG.weatherChangeMin, CONFIG.weatherChangeMax);
seedPopulation = seedPopulation ?? field.population ?? CONFIG.initialPopulation;
const grassCount = field.grass ?? 18;
const types = spawnableSprites().map(s => s.id);
for (let i = 0; i < seedPopulation; i++) {
this.addTarinai({
type: types[i % types.length],
x: rand(80, this.w - 80),
y: rand(80, this.h - 80),
generation: 1,
@ -410,6 +410,7 @@
},
addTarinai(opts = {}) {
opts = global.TarinaiSeedFactory?.prepareAddOptions?.(this, opts) || opts;
const t = new Tarinai(this, opts);
this.assignTarinaiLiveId(t);
this.tarinai.push(t);
@ -501,7 +502,7 @@
b.birthRitualRole = 1;
a.birthRitualLeader = true;
b.birthRitualLeader = false;
const ritualReason = "\u7e41\u6b96\u306e\u524d\u3076\u308c\u3092\u3057\u3066\u3044\u308b";
const ritualReason = "へこへこしている";
const applyRitualAction = (actor, partner) => {
if (!actor) return false;
if (typeof actor.setActionState === "function") {
@ -526,10 +527,10 @@
const bBehavior = typeof currentTarinaiBehavior === "function" ? currentTarinaiBehavior(b) : b.behavior;
const aLoveCause = (aBehavior?.source === "love_mochi" || (a.loveMochiTimer || 0) > 0.04) ? "\u3078\u3053\u9905\u306e\u52b9\u679c" : `${b.name || "\u76f8\u624b"}\u304c\u6c17\u306b\u306a\u308b`;
const bLoveCause = (bBehavior?.source === "love_mochi" || (b.loveMochiTimer || 0) > 0.04) ? "\u3078\u3053\u9905\u306e\u52b9\u679c" : `${a.name || "\u76f8\u624b"}\u304c\u6c17\u306b\u306a\u308b`;
const aText = typeof buildReasonText === "function" ? buildReasonText("social", aBehavior?.tiedNeeds || ["social"], { id: "birth_ritual", need: "social", subNeed: "mate", label: `${b.name || "\u76f8\u624b"}\u3068\u7e41\u6b96\u306e\u524d\u3076\u308c\u3092\u3057\u3066\u3044\u308b` }, a, this, { causeText: aLoveCause }) : `${b.name || "\u76f8\u624b"}\u3068\u7e41\u6b96\u306e\u524d\u3076\u308c\u3092\u3057\u3066\u3044\u308b`;
const bText = typeof buildReasonText === "function" ? buildReasonText("social", bBehavior?.tiedNeeds || ["social"], { id: "birth_ritual", need: "social", subNeed: "mate", label: `${a.name || "\u76f8\u624b"}\u3068\u7e41\u6b96\u306e\u524d\u3076\u308c\u3092\u3057\u3066\u3044\u308b` }, b, this, { causeText: bLoveCause }) : `${a.name || "\u76f8\u624b"}\u3068\u7e41\u6b96\u306e\u524d\u3076\u308c\u3092\u3057\u3066\u3044\u308b`;
setBehaviorText(a, { need: "social", subNeed: "mate", actionId: "birth_ritual", actionLabel: `${b.name || "\u76f8\u624b"}\u3068\u7e41\u6b96\u306e\u524d\u3076\u308c\u3092\u3057\u3066\u3044\u308b`, reasonText: aText, causeText: aLoveCause, target: b });
setBehaviorText(b, { need: "social", subNeed: "mate", actionId: "birth_ritual", actionLabel: `${a.name || "\u76f8\u624b"}\u3068\u7e41\u6b96\u306e\u524d\u3076\u308c\u3092\u3057\u3066\u3044\u308b`, reasonText: bText, causeText: bLoveCause, target: a });
const aText = typeof buildReasonText === "function" ? buildReasonText("social", aBehavior?.tiedNeeds || ["social"], { id: "birth_ritual", need: "social", subNeed: "mate", label: `${b.name || "\u76f8\u624b"}\u3068へこへこしている` }, a, this, { causeText: aLoveCause }) : `${b.name || "\u76f8\u624b"}\u3068へこへこしている`;
const bText = typeof buildReasonText === "function" ? buildReasonText("social", bBehavior?.tiedNeeds || ["social"], { id: "birth_ritual", need: "social", subNeed: "mate", label: `${a.name || "\u76f8\u624b"}\u3068へこへこしている` }, b, this, { causeText: bLoveCause }) : `${a.name || "\u76f8\u624b"}\u3068へこへこしている`;
setBehaviorText(a, { need: "social", subNeed: "mate", actionId: "birth_ritual", actionLabel: `${b.name || "\u76f8\u624b"}\u3068へこへこしている`, reasonText: aText, causeText: aLoveCause, target: b });
setBehaviorText(b, { need: "social", subNeed: "mate", actionId: "birth_ritual", actionLabel: `${a.name || "\u76f8\u624b"}\u3068へこへこしている`, reasonText: bText, causeText: bLoveCause, target: a });
}
a.reproductionTimer = CONFIG.reproductionCooldown + rand(2, 10);
b.reproductionTimer = CONFIG.reproductionCooldown + rand(2, 10);
@ -616,32 +617,18 @@
spawnChild(a, b, index = 0, total = 1) {
const zunchiSlaveChild = !!(a.isZunchiSlave && b.isZunchiSlave);
const inherited = Math.random() < 0.56 ? a.type : b.type;
const mutation = zunchiSlaveChild ? "zunchi_slave" : (Math.random() < 0.18 ? baseSpriteId() : inherited);
const childSeed = crypto.randomUUID ? crypto.randomUUID() : `${Date.now()}-${Math.random()}-${index}`;
const childGenetics = inheritedGenetics(a, b, childSeed);
const childAdultScale = adultScaleFromGenetics(childSeed, childGenetics);
const childBirthPersonality = zunchiSlaveChild ? zunchiSlavePersonalityValue() : personalityFromParents(a, b);
const child = this.addTarinai({
familyKey: childSeed,
type: mutation,
birthPersonality: childBirthPersonality,
currentPersonality: childBirthPersonality,
genetics: childGenetics,
adultScale: childAdultScale,
name: zunchiSlaveChild ? "\u305a\u3093\u3061\u3069\u308c\u3044" : makeName(),
seedParents: [a, b],
isZunchiSlave: zunchiSlaveChild,
age: 0,
x: (a.x + b.x) / 2 + rand(-14, 14) + (index - (total - 1) / 2) * 18,
y: (a.y + b.y) / 2 + rand(-14, 14) + (total > 1 ? rand(-10, 10) : 0),
scale: scaleForGrowth(childAdultScale, 0),
hunger: rand(20, 40),
loneliness: rand(30, 56),
energy: rand(55, 95),
stress: rand(0, 14),
need: "",
generation: Math.max(a.generation, b.generation) + 1,
lifeSpan: rand(1500, 2200) * (childGenetics.lifeSpanMul || 1),
parents: [this.tarinaiFamilyKey(a), this.tarinaiFamilyKey(b)],
parentNames: [a.name, b.name],
birthTime: this.time,
@ -708,6 +695,9 @@
if (alreadyFighting) return true;
if ((a.fightTimer || 0) > 0.04 || (b.fightTimer || 0) > 0.04) return false;
if (this.fightPairCooldownRemaining?.(a, b) > 0.04) return false;
const maxForcedFightDistance = Math.max(142, (a.radius || 20) + (b.radius || 20) + 96);
if (dist(a, b) > maxForcedFightDistance) return false;
if ((a.fightCooldown || 0) > 0.04 || (b.fightCooldown || 0) > 0.04) return false;
for (const t of [a, b]) {
t.birthRitualTimer = 0;
t.birthRitualMax = 0;
@ -715,7 +705,6 @@
t.birthRitualLeader = false;
t.birthRitualRole = 0;
t.postBirthPeaceTimer = 0;
t.fightCooldown = 0;
t.intimidateTimer = 0;
t.intimidateTargetId = null;
t.intimidatedTimer = 0;
@ -850,7 +839,9 @@
const allowForcedStart = Boolean(opts?.forced);
if (!allowForcedStart && ((a.fightTimer || 0) > 0.04 || (b.fightTimer || 0) > 0.04 || (a.intimidateTimer || 0) > 0.04 || (b.intimidateTimer || 0) > 0.04)) return false;
if (!allowForcedStart && this.fightPairCooldownRemaining?.(a, b) > 0.04) return false;
this.markFightPairCooldown?.(a, b, 3.4);
const maxStartFightDistance = Math.max(150, (a.radius || 20) + (b.radius || 20) + 104);
if (dist(a, b) > maxStartFightDistance) return false;
this.markFightPairCooldown?.(a, b, CONFIG.fightCooldown + 6);
const initiator = opts?.initiator === b ? b : a;
const receiver = initiator === a ? b : a;
const causeFor = (self, other) => {