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

@ -8,7 +8,7 @@ function selectRoleTarget(role, range) {
};
}
function startMoveToTarget(state, fallbackLabel = "行動している") {
function startMoveToTarget(state, fallbackLabel = "\u884c\u52d5\u3057\u3066\u3044\u308b") {
return function start(tarinai, world, ctx = {}) {
const target = ctx.target ?? this.selectTarget?.(tarinai, world, ctx) ?? null;
return moveToOrUse(tarinai, target, state, this.label || fallbackLabel);
@ -59,8 +59,8 @@ function createSleepInBedActionSpec() {
id: "sleep_in_bed",
need: "sleep",
state: "seek_bed",
label: "寝る場所を探している",
phrase: "寝る場所へ戻った",
label: "\u5bdd\u308b\u5834\u6240\u3092\u63a2\u3057\u3066\u3044\u308b",
phrase: "\u5bdd\u308b\u5834\u6240\u3078\u623b\u3063\u305f",
weight: 42,
timerBacked: true,
selectTarget(t, world) { return findNearestSleepPlace(world, t, 760); },
@ -71,7 +71,7 @@ function createSleepInBedActionSpec() {
if (dist(t, bed) > (t.radius || 20) + 18) return moveToOrUse(t, bed, "seek_bed", this.label);
const isEasyBed = bed.type === "grass_bed";
bed.use?.(t, world, isEasyBed ? { purpose: "sleep" } : undefined);
t.startSleeping?.(bed, bed.type === "nest_box" ? "巣箱の中で寝ている" : (isEasyBed ? "かんたんベッドで寝ている" : "ベッドで寝ている"));
t.startSleeping?.(bed, bed.type === "nest_box" ? "\u5de3\u7bb1\u306e\u4e2d\u3067\u5bdd\u3066\u3044\u308b" : (isEasyBed ? "\u304b\u3093\u305f\u3093\u30d9\u30c3\u30c9\u3067\u5bdd\u3066\u3044\u308b" : "\u30d9\u30c3\u30c9\u3067\u5bdd\u3066\u3044\u308b"));
return true;
},
tick(t) {
@ -87,8 +87,8 @@ function createSleepBuildGrassBedActionSpec() {
need: "sleep",
subNeed: "bed",
state: "build",
label: "寝る場所がないのでかんたんベッドを作っている",
phrase: "かんたんベッドを作った",
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,
timerBacked: true,
selectTarget: selectRoleTarget("grassMaterial", 520),
@ -112,8 +112,8 @@ function createSleepAnywhereActionSpec() {
id: "sleep_anywhere",
need: "sleep",
state: "sleep",
label: "なにもない所で寝ている",
phrase: "そのまま寝た",
label: "\u306a\u306b\u3082\u306a\u3044\u6240\u3067\u5bdd\u3066\u3044\u308b",
phrase: "\u305d\u306e\u307e\u307e\u5bdd\u305f",
weight: 8,
timerBacked: true,
canStart(t, world) {
@ -146,8 +146,8 @@ function createRestActionSpec() {
id: "rest_to_recover",
need: "health",
state: "idle",
label: "元気になるまで休んでいる",
phrase: "休んだ",
label: "\u5143\u6c17\u306b\u306a\u308b\u307e\u3067\u4f11\u3093\u3067\u3044\u308b",
phrase: "\u4f11\u3093\u3060",
weight: 24,
canStart() { return true; },
start(t) {
@ -168,8 +168,8 @@ function createSunbathActionSpec() {
need: "health",
subNeed: "sunbath",
state: "sunbath",
label: "日光浴している",
phrase: "日光浴している",
label: "\u65e5\u5149\u6d74\u3057\u3066\u3044\u308b",
phrase: "\u65e5\u5149\u6d74\u3057\u3066\u3044\u308b",
weight: 32,
timerBacked: true,
canStart(t, world, ctx = {}) {
@ -190,7 +190,7 @@ function createSunbathActionSpec() {
fail(t) {
if (t && t.state === "sunbath") {
t.sunbathTimer = 0;
t.goIdle?.("日光浴をやめた");
t.goIdle?.("\u65e5\u5149\u6d74\u3092\u3084\u3081\u305f");
}
return false;
},
@ -211,8 +211,8 @@ function createWanderActionSpec() {
id: "wander_lightly",
need: "fulfill",
state: "wander",
label: "少し歩いている",
phrase: "少し歩いた",
label: "\u5c11\u3057\u6b69\u3044\u3066\u3044\u308b",
phrase: "\u5c11\u3057\u6b69\u3044\u305f",
weight: 14,
canStart() { return true; },
selectTarget: targetFor,
@ -247,8 +247,8 @@ function createPanicEscapeActionSpec() {
need: "safety",
subNeed: "panic",
state: "panic",
label: "怖くて逃げている",
phrase: "逃げた",
label: "\u6016\u304f\u3066\u9003\u3052\u3066\u3044\u308b",
phrase: "\u9003\u3052\u305f",
weight: 62,
timerBacked: true,
selectTarget(t, world) {
@ -279,8 +279,8 @@ function createFleeActionSpec() {
need: "safety",
subNeed: "avoid",
state: "flee",
label: "危ないものから離れている",
phrase: "離れた",
label: "\u5371\u306a\u3044\u3082\u306e\u304b\u3089\u96e2\u308c\u3066\u3044\u308b",
phrase: "\u96e2\u308c\u305f",
weight: 40,
selectTarget(t, world) { return findNearbyDanger(world, t, 220); },
canStart: basicCanStartWithTarget,
@ -299,12 +299,12 @@ function createApproachFriendActionSpec() {
need: "social",
subNeed: "bond",
state: "seek_friend",
label: "仲間に近づいている",
phrase: "仲間に近づいた",
label: "\u4ef2\u9593\u306b\u8fd1\u3065\u3044\u3066\u3044\u308b",
phrase: "\u4ef2\u9593\u306b\u8fd1\u3065\u3044\u305f",
weight: 46,
selectTarget(t, world) { return t.bestFriendLive?.(FRIEND_AFFINITY_THRESHOLD, 520) || world.nearestOther?.(t, 420) || null; },
canStart: basicCanStartWithTarget,
start: startMoveToTarget("seek_friend", "仲間に近づいている"),
start: startMoveToTarget("seek_friend", "\u4ef2\u9593\u306b\u8fd1\u3065\u3044\u3066\u3044\u308b"),
tick(t, world, dt) { return updateSocialContactBehavior(t, world, dt, "bond"); },
};
}
@ -315,12 +315,12 @@ function createApproachFamilyActionSpec() {
need: "social",
subNeed: "family",
state: "follow_parent",
label: "家族に近づいている",
phrase: "家族に近づいた",
label: "\u5bb6\u65cf\u306b\u8fd1\u3065\u3044\u3066\u3044\u308b",
phrase: "\u5bb6\u65cf\u306b\u8fd1\u3065\u3044\u305f",
weight: 28,
selectTarget(t) { return t.parentToFollow?.() || null; },
canStart: basicCanStartWithTarget,
start: startMoveToTarget("follow_parent", "家族に近づいている"),
start: startMoveToTarget("follow_parent", "\u5bb6\u65cf\u306b\u8fd1\u3065\u3044\u3066\u3044\u308b"),
tick(t, world, dt) { return updateSocialContactBehavior(t, world, dt, "family"); },
};
}
@ -331,8 +331,8 @@ function createApproachMateActionSpec() {
need: "social",
subNeed: "mate",
state: "seek_friend",
label: "繁殖できる相手に近づいている",
phrase: "繁殖できる相手に近づいている",
label: "\u7e41\u6b96\u3067\u304d\u308b\u76f8\u624b\u306b\u8fd1\u3065\u3044\u3066\u3044\u308b",
phrase: "\u7e41\u6b96\u3067\u304d\u308b\u76f8\u624b\u306b\u8fd1\u3065\u3044\u3066\u3044\u308b",
weight: 48,
selectTarget(t, world) { return selectMateTarget(t, world, 520); },
canStart(t, world, ctx = {}) { return (t.reproductionTimer || 0) <= 12 && !!(ctx.target ?? this.selectTarget(t, world, ctx)); },
@ -352,8 +352,8 @@ function createFightRivalActionSpec() {
need: "social",
subNeed: "conflict",
state: "seek_enemy",
label: "気に入らない相手に向かっている",
phrase: "喧嘩を始めた",
label: "\u6c17\u306b\u5165\u3089\u306a\u3044\u76f8\u624b\u306b\u5411\u304b\u3063\u3066\u3044\u308b",
phrase: "\u55a7\u5629\u3092\u59cb\u3081\u305f",
weight: 18,
timerBacked: true,
selectTarget(t, world) { return selectFightRivalTarget(t, world); },
@ -390,8 +390,8 @@ function createIntimidateEnemyActionSpec() {
need: "social",
subNeed: "conflict",
state: "intimidate",
label: "気になる相手を威嚇している",
phrase: "威嚇した",
label: "\u6c17\u306b\u306a\u308b\u76f8\u624b\u3092\u5a01\u5687\u3057\u3066\u3044\u308b",
phrase: "\u5a01\u5687\u3057\u305f",
weight: 8,
timerBacked: true,
selectTarget(t) { return t.recentFightRival?.(80, 180) || null; },
@ -421,8 +421,8 @@ function createBirthRitualActionSpec() {
id: "birth_ritual",
need: "social",
subNeed: "mate",
label: "へこへこしている",
phrase: "へこへこしている",
label: "\u3078\u3053\u3078\u3053\u3057\u3066\u3044\u308b",
phrase: "\u3078\u3053\u3078\u3053\u3057\u3066\u3044\u308b",
weight: 0,
state: "birth_ritual",
timerBacked: true,
@ -437,8 +437,8 @@ const TARINAI_ACTION_DEFINITIONS = [
id: "eat_food",
subNeed: "meal",
state: "seek_food",
label: "食べ物を探している",
phrase: "食べ物を食べている",
label: "\u98df\u3079\u7269\u3092\u63a2\u3057\u3066\u3044\u308b",
phrase: "\u98df\u3079\u7269\u3092\u98df\u3079\u3066\u3044\u308b",
weight: 62,
role: "food",
range: 760,
@ -447,8 +447,8 @@ const TARINAI_ACTION_DEFINITIONS = [
id: "drink_water",
subNeed: "water",
state: "seek_water",
label: "水を探している",
phrase: "水を飲んだ",
label: "\u6c34\u3092\u63a2\u3057\u3066\u3044\u308b",
phrase: "\u6c34\u3092\u98f2\u3093\u3060",
weight: 24,
role: "drink",
range: 560,
@ -460,8 +460,8 @@ const TARINAI_ACTION_DEFINITIONS = [
id: "use_medicine",
subNeed: "medicine",
state: "seek_food",
label: "元気になるものを探している",
phrase: "元気になった",
label: "\u5143\u6c17\u306b\u306a\u308b\u3082\u306e\u3092\u63a2\u3057\u3066\u3044\u308b",
phrase: "\u5143\u6c17\u306b\u306a\u3063\u305f",
weight: 34,
role: "medicine",
range: 620,
@ -474,12 +474,12 @@ const TARINAI_ACTION_DEFINITIONS = [
id: "hide_at_owned_structure",
need: "safety",
state: "seek_bed",
label: "自分の場所に隠れている",
phrase: "自分の場所へ戻った",
label: "\u81ea\u5206\u306e\u5834\u6240\u306b\u96a0\u308c\u3066\u3044\u308b",
phrase: "\u81ea\u5206\u306e\u5834\u6240\u3078\u623b\u3063\u305f",
weight: 30,
selectTarget: selectOwnedStructure("grass_bed", 620),
canStart(t, world, ctx = {}) { return !!(ctx.target ?? this.selectTarget(t, world, ctx)); },
start: startMoveToTarget("seek_bed", "自分の場所に隠れている"),
start: startMoveToTarget("seek_bed", "\u81ea\u5206\u306e\u5834\u6240\u306b\u96a0\u308c\u3066\u3044\u308b"),
},
createApproachFriendActionSpec(),
createApproachFamilyActionSpec(),
@ -490,19 +490,19 @@ const TARINAI_ACTION_DEFINITIONS = [
id: "play",
need: "fulfill",
state: "play_ball",
label: "遊んでいる",
phrase: "遊んだ",
label: "\u904a\u3093\u3067\u3044\u308b",
phrase: "\u904a\u3093\u3060",
weight: 24,
selectTarget(t, world) { return world.nearest?.(t, ["ball"], 520) || null; },
canStart(t, world, ctx = {}) { return !!(ctx.target ?? this.selectTarget(t, world, ctx)); },
start: startMoveToTarget("play_ball", "遊んでいる"),
start: startMoveToTarget("play_ball", "\u904a\u3093\u3067\u3044\u308b"),
},
{
id: "build_grass_bed",
need: "fulfill",
state: "build",
label: "かんたんベッドを作っている",
phrase: "かんたんベッドを作った",
label: "\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: 34,
selectTarget: selectRoleTarget("grassMaterial", 520),
canStart(t, world, ctx = {}) { return canBuildOwnedStructureByAge(t) && !findOwnedStructure(world, t, "grass_bed") && !!(ctx.target ?? this.selectTarget(t, world, ctx)) && !["sleep", "fight", "panic", "intimidate"].includes(t.state); },
@ -512,8 +512,8 @@ const TARINAI_ACTION_DEFINITIONS = [
id: "build_plushie",
need: "fulfill",
state: "build",
label: "ぬいぐるみを作っている",
phrase: "ぬいぐるみを作った",
label: "\u306c\u3044\u3050\u308b\u307f\u3092\u4f5c\u3063\u3066\u3044\u308b",
phrase: "\u306c\u3044\u3050\u308b\u307f\u3092\u4f5c\u3063\u305f",
weight: 28,
selectTarget: selectRoleTarget("grassMaterial", 520),
canStart(t, world, ctx = {}) { return canBuildOwnedStructureByAge(t) && !findOwnedStructure(world, t, "plushie") && !!(ctx.target ?? this.selectTarget(t, world, ctx)) && !["sleep", "fight", "panic", "intimidate"].includes(t.state); },
@ -523,19 +523,19 @@ const TARINAI_ACTION_DEFINITIONS = [
id: "return_owned_structure",
need: "fulfill",
state: "seek_bed",
label: "自分の場所へ戻っている",
phrase: "自分の場所へ戻った",
label: "\u81ea\u5206\u306e\u5834\u6240\u3078\u623b\u3063\u3066\u3044\u308b",
phrase: "\u81ea\u5206\u306e\u5834\u6240\u3078\u623b\u3063\u305f",
weight: 22,
selectTarget: selectOwnedStructure("grass_bed", 620),
canStart(t, world, ctx = {}) { return !!(ctx.target ?? this.selectTarget(t, world, ctx)); },
start: startMoveToTarget("seek_bed", "自分の場所へ戻っている"),
start: startMoveToTarget("seek_bed", "\u81ea\u5206\u306e\u5834\u6240\u3078\u623b\u3063\u3066\u3044\u308b"),
},
{
id: "use_plushie",
need: "fulfill",
state: "idle",
label: "ぬいぐるみを抱えている",
phrase: "ぬいぐるみを抱えた",
label: "\u306c\u3044\u3050\u308b\u307f\u3092\u62b1\u3048\u3066\u3044\u308b",
phrase: "\u306c\u3044\u3050\u308b\u307f\u3092\u62b1\u3048\u305f",
weight: 18,
selectTarget: selectOwnedStructure("plushie", Infinity),
canStart(t, world, ctx = {}) { return !!(ctx.target ?? this.selectTarget(t, world, ctx)); },