h
This commit is contained in:
parent
e00bfd8879
commit
f941200504
70 changed files with 1856 additions and 429 deletions
|
|
@ -89,7 +89,7 @@ function createSleepBuildGrassBedActionSpec() {
|
|||
state: "build",
|
||||
label: "\u5bdd\u308b\u5834\u6240\u304c\u306a\u3044\u306e\u3067\u304b\u3093\u305f\u3093\u30d9\u30c3\u30c9\u3092\u4f5c\u3063\u3066\u3044\u308b",
|
||||
phrase: "\u304b\u3093\u305f\u3093\u30d9\u30c3\u30c9\u3092\u4f5c\u3063\u305f",
|
||||
weight: 18,
|
||||
weight: 26,
|
||||
timerBacked: true,
|
||||
selectTarget(t, world) { return (typeof findNearbyBuildMaterial === "function" ? findNearbyBuildMaterial(world, t, "grass_bed", 520) : null) || findNearbyMaterial(world, t, "grassMaterial", 520); },
|
||||
canStart(t, world, ctx = {}) {
|
||||
|
|
@ -201,6 +201,56 @@ function createSunbathActionSpec() {
|
|||
};
|
||||
}
|
||||
|
||||
function createTemperatureComfortActionSpec() {
|
||||
return {
|
||||
id: "seek_comfort_temperature",
|
||||
need: "health",
|
||||
subNeed: "temperature",
|
||||
state: "seek_temperature",
|
||||
label: "快適な温度帯へ移動している",
|
||||
phrase: "快適な温度帯を探している",
|
||||
text(t, world) {
|
||||
const felt = world?.temperatureAt?.(t?.x, t?.y) ?? t?.feltTemperature ?? t?.tempComfort ?? (CONFIG.standardTemperature ?? 15);
|
||||
const status = world?.temperatureStatusFor?.(felt) || t?.temperatureStatus || null;
|
||||
return status?.direction === "cold" ? "寒いので温まろうとしている。" : "暑いので涼もうとしている。";
|
||||
},
|
||||
weight: 42,
|
||||
selectTarget(t, world, ctx = {}) {
|
||||
return world?.findComfortTemperatureSpot?.(t, { force: !!ctx.force, requireComfort: true }) || null;
|
||||
},
|
||||
canStart(t, world, ctx = {}) {
|
||||
const felt = world?.temperatureAt?.(t.x, t.y);
|
||||
const status = world?.temperatureStatusFor?.(Number.isFinite(Number(felt)) ? felt : (t?.feltTemperature ?? CONFIG.standardTemperature ?? 15));
|
||||
if (!status || status.comfortable || (status.discomfort || 0) < 2.5) return false;
|
||||
return !!(ctx.target ?? this.selectTarget(t, world, ctx));
|
||||
},
|
||||
start(t, world, ctx = {}) {
|
||||
const status = world?.temperatureStatusFor?.(world?.temperatureAt?.(t.x, t.y) ?? t?.feltTemperature ?? (CONFIG.standardTemperature ?? 15));
|
||||
const label = status?.direction === "cold" ? "あたたかい場所へ移動している" : (status?.direction === "hot" ? "涼しい場所へ移動している" : this.label);
|
||||
const target = ctx.target ?? this.selectTarget(t, world, ctx);
|
||||
return moveToOrUse(t, target, "seek_temperature", label);
|
||||
},
|
||||
tick(t, world, dt, needs, ctx = {}) {
|
||||
const felt = world?.temperatureAt?.(t.x, t.y) ?? t?.feltTemperature ?? (CONFIG.standardTemperature ?? 15);
|
||||
const status = world?.temperatureStatusFor?.(felt);
|
||||
if (status?.comfortable || (status?.discomfort || 0) <= 1.5) {
|
||||
if (typeof applyNeedSatisfaction === "function") applyNeedSatisfaction(t, { health: 10, safety: 8 }, "temperature");
|
||||
t.goIdle?.("快適な温度になった");
|
||||
return "finished";
|
||||
}
|
||||
const target = t.target && !t.target.dead ? t.target : (ctx.target ?? this.selectTarget(t, world, { force: true, requireComfort: true }));
|
||||
if (!target) return false;
|
||||
t.target = target;
|
||||
if (distXY(t.x, t.y, target.x, target.y) < Math.max(24, (t.radius || 20) * 0.9)) {
|
||||
const next = this.selectTarget(t, world, { force: true, requireComfort: true });
|
||||
if (!next || distXY(t.x, t.y, next.x, next.y) < Math.max(28, (t.radius || 20))) return "finished";
|
||||
t.target = next;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function createWanderActionSpec() {
|
||||
function targetFor(t, world) {
|
||||
const radius = rand(80, 180);
|
||||
|
|
@ -350,12 +400,12 @@ function createFightRivalActionSpec() {
|
|||
const parts = t?.socialReasonParts || {};
|
||||
const conflict = Number(parts.conflict || 0) || 0;
|
||||
const socialPull = Math.max(Number(parts.bond || 0) || 0, Number(parts.mate || 0) || 0, Number(parts.family || 0) || 0);
|
||||
if (!candidate?.target || conflict < 30 || conflict < socialPull * 0.82) return false;
|
||||
if (!candidate?.target || conflict < 22 || conflict < socialPull * 0.68) return false;
|
||||
}
|
||||
return !!(ctx.target ?? candidate?.target ?? this.selectTarget(t, world, ctx));
|
||||
},
|
||||
start(t, world, ctx = {}) {
|
||||
const candidate = conflictTargetFor(t, world, (t?.fightMochiTimer || 0) > 0.04 || isCurrentBehaviorForced(t) ? 18 : 34);
|
||||
const candidate = conflictTargetFor(t, world, (t?.fightMochiTimer || 0) > 0.04 || isCurrentBehaviorForced(t) ? 18 : 26);
|
||||
const rival = ctx.target ?? this.selectTarget(t, world, ctx);
|
||||
if (!isLiveTarinaiEntity(rival)) return false;
|
||||
t.conflictTargetId = rival.id;
|
||||
|
|
@ -381,9 +431,9 @@ function createIntimidateEnemyActionSpec() {
|
|||
timerBacked: true,
|
||||
selectTarget(t) { return t.recentFightRival?.(80, 180) || null; },
|
||||
canStart(t, world, ctx = {}) {
|
||||
// 威嚇は通常の欲求行動としては選ばず、喧嘩判定時の30%分岐で実行する。
|
||||
if (!isCurrentBehaviorForced(t)) return false;
|
||||
if ((t.intimidateTimer || 0) > 0.04 || (t.postConflictPeaceTimer || 0) > 0.04) return false;
|
||||
const parts = t?.socialReasonParts || {};
|
||||
if ((t.fightMochiTimer || 0) <= 0.04 && Number(parts.conflict || 0) < 24) return false;
|
||||
return basicCanStartWithTarget.call(this, t, world, ctx);
|
||||
},
|
||||
start(t, world, ctx = {}) {
|
||||
|
|
@ -453,6 +503,7 @@ const TARINAI_ACTION_DEFINITIONS = [
|
|||
}),
|
||||
createRestActionSpec(),
|
||||
createSunbathActionSpec(),
|
||||
createTemperatureComfortActionSpec(),
|
||||
createPanicEscapeActionSpec(),
|
||||
{
|
||||
id: "hide_at_owned_structure",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue