207 lines
12 KiB
JavaScript
207 lines
12 KiB
JavaScript
"use strict";
|
|
|
|
const TEXT_CATALOG = {
|
|
toolTips: toolTipsFromDefinitions(),
|
|
ecologyCards: [
|
|
{
|
|
title: "たりないとは",
|
|
image: "assets/sprites/tarinai_01_smile.webp",
|
|
text: "庭やケージで生活する観察対象。空腹、睡眠、健康、安全、関係、充足の6欲求とストレスで行動が変わります。個体ごとに性格、体格、家族、経験が残ります。",
|
|
},
|
|
{
|
|
title: "欲求とストレス",
|
|
image: "assets/ui/ecology_hp_stress.webp",
|
|
text: "空腹や眠気が強いと食べ物や寝床を探します。ストレスは恐怖、混雑、汚れ、けんか、地面の種類などで増減し、高いほど逃走、威嚇、体調不良が起きやすくなります。",
|
|
},
|
|
{
|
|
title: "食事と水分",
|
|
image: "assets/sprites/tarinai_05_drool.webp",
|
|
text: "草、ずんち、餅、ジュースなどを状況に応じて食べます。病気や極度の空腹では優先順位が変わり、近くの食べ物を探します。水や雨滴は一部の病気や環境の回復にも関わります。",
|
|
},
|
|
{
|
|
title: "睡眠と寝場所",
|
|
image: "assets/sprites/tarinai_20_sleep2.webp",
|
|
text: "眠くなると巣箱やかんたんベッドを探します。かんたんベッドは草を使って作られ、起床時に消えます。長く寝床を用意できない場合は、何もない場所で眠ることもあります。",
|
|
},
|
|
{
|
|
title: "草、地面、天気",
|
|
image: "assets/ui/tool_grass.webp",
|
|
text: "草は成長し、食料やかんたんベッドの材料になります。地面は砂、土、コンクリート、ふわふわ毛布、足つぼ、氷を切り替えられ、草の発生やストレス増加に影響します。雨や時間帯も状態に関わります。",
|
|
},
|
|
{
|
|
title: "性格と行動傾向",
|
|
image: "assets/sprites/tarinai_21_normal_happy.webp",
|
|
text: "攻撃性、開放性、社交性、神経質性などがあり、経験で少しずつ変化します。性格は食事、接近、逃走、けんか、繁殖相手の探し方などの差として表れます。",
|
|
},
|
|
{
|
|
title: "関係、家族、繁殖",
|
|
image: "assets/sprites/tarinai_27_birth_ritual.webp",
|
|
text: "親子、共同親、友好、敵対、恐怖が記録されます。条件がそろうとへこへこを行い、子が生まれます。子は親の性格傾向を受け継ぎ、世代情報は家系図に残ります。",
|
|
},
|
|
{
|
|
title: "病気と回復",
|
|
image: "assets/sprites/tarinai_24_stress_dizzy.webp",
|
|
text: "ずんち病、ねむり病、爆発病、きずつき病などがあります。病気ごとに求めるものや行動が変わり、水、薬、食べ物、休息、環境の改善が回復に関係します。",
|
|
},
|
|
{
|
|
title: "危険と事故",
|
|
image: "assets/sprites/tarinai_26_intimidate.webp",
|
|
text: "けんか、爆竹、げんこつ、ピン、ボール、アリ、落下物などで体力が減ります。体力が0になると死亡し、死因はログと統計に残ります。危険な道具は観察の流れを大きく変えます。",
|
|
},
|
|
{
|
|
title: "道具と構造物",
|
|
image: "assets/ui/tool_duplicator.webp",
|
|
text: "食べ物、薬、巣箱、柵、看板、複製機などを配置できます。複製機には対応する食べ物、薬、草などをセットできます。削除ツールでは不要な構造物や一部アイテムを取り除けます。",
|
|
},
|
|
{
|
|
title: "コロニーの見方",
|
|
image: "assets/sprites/tarinai_11_weak.webp",
|
|
text: "コロニー欄では個体数、死亡数、全体状態、地面、欲求平均、物を確認できます。たりないデータでは選択中の個体の健康、性格、関係、行動理由、記録を追えます。",
|
|
},
|
|
],};
|
|
|
|
|
|
TEXT_CATALOG.stateLabels = Object.freeze({
|
|
idle: "ぼーっとしている",
|
|
seek_food: "\u98df\u3079\u7269\u3078\u5411\u304b\u3046",
|
|
seek_bed: "\u5bdd\u5e8a\u3078\u5411\u304b\u3046",
|
|
play_ball: "\u30dc\u30fc\u30eb\u904a\u3073",
|
|
seek_water: "\u6c34\u3092\u63a2\u3059",
|
|
seek_material: "\u6750\u6599\u3092\u63a2\u3059",
|
|
seek_enemy: "\u76f8\u624b\u3078\u5411\u304b\u3046",
|
|
wander: "\u79fb\u52d5\u4e2d",
|
|
build: "\u4f5c\u6210\u4e2d",
|
|
zunchi_sick: "\u305a\u3093\u3061\u75c5",
|
|
fight_sick: "\u304d\u305a\u3064\u304d\u75c5",
|
|
system: "\u305a\u3093\u3061\u75c5",
|
|
seek_friend: "\u4ef2\u9593\u3092\u63a2\u3059",
|
|
follow_parent: "\u89aa\u306b\u3064\u3044\u3066\u3044\u304f",
|
|
cursor_friend: "\u30ab\u30fc\u30bd\u30eb\u306b\u3064\u3044\u3066\u3044\u304f",
|
|
cursor_enemy: "\u30ab\u30fc\u30bd\u30eb\u3092\u907f\u3051\u308b",
|
|
fight: "\u55a7\u5629\u4e2d",
|
|
sleep: "\u7761\u7720\u4e2d",
|
|
eat: "\u98df\u4e8b\u4e2d",
|
|
panic: "\u30d1\u30cb\u30c3\u30af",
|
|
intimidate: "\u5a01\u5687\u4e2d",
|
|
birth_ritual: "\u8a95\u751f\u524d",
|
|
sunbath: "\u65e5\u5149\u6d74\u4e2d",
|
|
ant_attack: "\u30a2\u30ea\u653b\u6483\u4e2d",
|
|
ant_intimidate: "\u30a2\u30ea\u5a01\u5687\u4e2d",
|
|
frozen: "\u51b7\u51cd\u4e2d",
|
|
});
|
|
|
|
|
|
TEXT_CATALOG.behaviorLabels = Object.freeze({
|
|
seek_material: "材料を探している",
|
|
build_structure: "作成している",
|
|
build: "作成している",
|
|
seek_enemy: "気になる相手へ向かっている",
|
|
wander_lightly: "少し移動している",
|
|
eat_food: "食事をしている",
|
|
drink_water: "水を飲んでいる",
|
|
sleep_in_bed: "寝床で休んでいる",
|
|
sleep_anywhere: "休んでいる",
|
|
intimidate_enemy: "威嚇している",
|
|
panic_escape: "逃げている",
|
|
});
|
|
|
|
TEXT_CATALOG.behaviorLabel = function behaviorLabelFromCatalog(value = "") {
|
|
const key = String(value || "");
|
|
return TEXT_CATALOG.behaviorLabels?.[key] || TEXT_CATALOG.stateLabels?.[key] || key;
|
|
};
|
|
|
|
TEXT_CATALOG.cleanBehaviorText = function cleanBehaviorText(text = "", fallbackKey = "") {
|
|
const raw = String(text || "").trim();
|
|
const key = String(fallbackKey || raw || "").trim();
|
|
const mapped = TEXT_CATALOG.behaviorLabel(key);
|
|
if (!raw) return mapped || "";
|
|
if (/^[a-z][a-z0-9_:-]*$/i.test(raw)) return TEXT_CATALOG.behaviorLabel(raw);
|
|
return raw;
|
|
};
|
|
|
|
TEXT_CATALOG.targetLabelOverrides = Object.freeze({
|
|
system: "\u305a\u3093\u3061\u75c5",
|
|
zunchi_sick: "\u305a\u3093\u3061\u75c5",
|
|
fight_sick: "\u304d\u305a\u3064\u304d\u75c5",
|
|
});
|
|
TEXT_CATALOG.targetLabels = TEXT_CATALOG.targetLabelOverrides;
|
|
|
|
TEXT_CATALOG.idleGroundText = function idleGroundText(t = null) {
|
|
const ground = String(t?.world?.groundType || (typeof world !== "undefined" ? world?.groundType : "") || "soil");
|
|
if (ground === "foot_massage") return "足つぼに耐えている。";
|
|
if (ground === "blanket") return "毛布にうっとりしている。";
|
|
if (ground === "ice") return "氷の上でじっとしている。";
|
|
return "ぼーっとしている。";
|
|
};
|
|
|
|
TEXT_CATALOG.stateLabel = function stateLabelFromCatalog(s, t = null) {
|
|
if (String(s || "") === "idle") return TEXT_CATALOG.idleGroundText(t);
|
|
return TEXT_CATALOG.stateLabels?.[s] || s || "";
|
|
};
|
|
|
|
TEXT_CATALOG.targetLabel = function targetLabelFromCatalog(target) {
|
|
if (!target) return "\u306a\u3057";
|
|
if (target.name) return target.name;
|
|
if (target.kind === "queen") return "\u5973\u738b\u30a2\u30ea";
|
|
if (target.kind === "worker") return "\u50cd\u304d\u30a2\u30ea";
|
|
if (target.type) {
|
|
const type = String(target.type || "");
|
|
if (TEXT_CATALOG.targetLabelOverrides?.[type]) return TEXT_CATALOG.targetLabelOverrides[type];
|
|
const label = typeof toolLabel === "function" ? toolLabel(type) : "";
|
|
return label || type;
|
|
}
|
|
if (Number.isFinite(target.x) && Number.isFinite(target.y)) return "\u4f4d\u7f6e";
|
|
return "\u4e0d\u660e";
|
|
};
|
|
|
|
TEXT_CATALOG.reasonLabel = function reasonLabelFromCatalog(t) {
|
|
if (!t) return "\u306a\u3057";
|
|
if ((t.pinchThoughtTimer || 0) > 0) return "\u3064\u307e\u307e\u308c\u3066\u3044\u308b";
|
|
const behaviorState = typeof currentTarinaiBehavior === "function" ? currentTarinaiBehavior(t) : t?.behavior;
|
|
const behaviorLabel = typeof globalThis.behaviorText === "function"
|
|
? globalThis.behaviorText(t)
|
|
: String(typeof getTarinaiBehaviorText === "function" ? getTarinaiBehaviorText(t) : (behaviorState?.text || behaviorState?.reason || "")).trim();
|
|
const cleanedBehaviorLabel = TEXT_CATALOG.cleanBehaviorText(behaviorLabel, behaviorState?.actionId || t.state || "");
|
|
if (cleanedBehaviorLabel) return cleanedBehaviorLabel;
|
|
const target = TEXT_CATALOG.targetLabel(t.target);
|
|
if (t.state === "eat") return target !== "\u306a\u3057" ? `${target}\u3092\u98df\u3079\u3066\u3044\u308b` : "\u98df\u3079\u3066\u3044\u308b";
|
|
if (t.state === "sleep") return t.target?.type === "nest_box" ? "\u5de3\u7bb1\u306e\u4e2d\u3067\u4f53\u529b\u3092\u56de\u5fa9\u3057\u3066\u3044\u308b" : "\u4f53\u529b\u3092\u56de\u5fa9\u3057\u3066\u3044\u308b";
|
|
if (t.state === "panic") return t.target ? `${target}\u304b\u3089\u9003\u3052\u3066\u3044\u308b` : "\u6016\u304c\u3063\u3066\u3044\u308b";
|
|
if (t.state === "intimidate") return target !== "\u306a\u3057" ? `${target}\u3092\u5a01\u5687\u3057\u3066\u3044\u308b` : "\u76f8\u624b\u3092\u5a01\u5687\u3057\u3066\u3044\u308b";
|
|
if (t.state === "ant_intimidate") return "\u30a2\u30ea\u3092\u5a01\u5687\u3057\u3066\u3044\u308b";
|
|
if (t.state === "ant_attack") return "\u30a2\u30ea\u3092\u653b\u6483\u3057\u3066\u3044\u308b";
|
|
if (t.state === "birth_ritual") return t.target?.name ? `${t.target.name}とへこへこしている` : "へこへこしている";
|
|
if (t.state === "sunbath") return "\u6674\u308c\u305f\u65e5\u306a\u305f\u3067\u30b9\u30c8\u30ec\u30b9\u3092\u4e0b\u3052\u3066\u3044\u308b";
|
|
if (t.state === "frozen") return "\u30d5\u30a3\u30fc\u30eb\u30c9\u5916\u3067\u51b7\u51cd\u4fdd\u5b58\u3055\u308c\u3066\u3044\u308b";
|
|
if (t.state === "seek_food") return target !== "\u306a\u3057" ? `${target}\u3092\u63a2\u3057\u3066\u3044\u308b` : "\u304a\u8179\u304c\u3059\u3044\u3066\u3044\u308b";
|
|
if (t.state === "seek_water") return t.explosionDisease ? "\u7206\u767a\u75c5\u3067\u6c34\u3092\u63a2\u3057\u3066\u3044\u308b" : "\u305a\u3093\u3061\u75c5\u3067\u6c34\u3092\u63a2\u3057\u3066\u3044\u308b";
|
|
if (t.state === "seek_bed") return target !== "\u306a\u3057" ? `${target}\u3078\u5411\u304b\u3063\u3066\u3044\u308b` : "\u7720\u308b\u5834\u6240\u3092\u63a2\u3057\u3066\u3044\u308b";
|
|
if (t.state === "play_ball") return "\u30dc\u30fc\u30eb\u304c\u6c17\u306b\u306a\u3063\u3066\u3044\u308b";
|
|
if (t.state === "seek_friend" && (typeof getTarinaiBehaviorId === "function" ? getTarinaiBehaviorId(t) : t.behavior?.id) === "approach_mate") return t.target?.name ? `${t.target.name}\u306b\u7e41\u6b96\u306e\u305f\u3081\u8fd1\u3065\u3044\u3066\u3044\u308b` : "\u7e41\u6b96\u3067\u304d\u308b\u76f8\u624b\u3092\u63a2\u3057\u3066\u3044\u308b";
|
|
if (t.state === "seek_friend") return "\u4ef2\u9593\u3092\u63a2\u3057\u3066\u3044\u308b";
|
|
if (t.state === "follow_parent") return "\u89aa\u306b\u3064\u3044\u3066\u3044\u304f";
|
|
if (t.state === "cursor_friend") return "\u30ab\u30fc\u30bd\u30eb\u306b\u3064\u3044\u3066\u3044\u304f";
|
|
if (t.state === "cursor_enemy") return "\u30ab\u30fc\u30bd\u30eb\u3092\u907f\u3051\u3066\u3044\u308b";
|
|
if (t.state === "fight") return target !== "\u306a\u3057" ? `${target}\u3068\u55a7\u5629\u3057\u3066\u3044\u308b` : "\u55a7\u5629\u3057\u3066\u3044\u308b";
|
|
if (t.state === "fight_sick") return "\u304d\u305a\u3064\u304d\u75c5\u3067\u5f53\u3066\u3082\u306a\u304f\u5f77\u5fa8\u3063\u3066\u3044\u308b";
|
|
if (t.state === "zunchi_sick" || t.state === "system") return "\u305a\u3093\u3061\u75c5\u3067\u8abf\u5b50\u304c\u60aa\u3044";
|
|
if ((t.hurtTimer || 0) > 0.08) return "\u75db\u307f\u3067\u6df7\u4e71\u3057\u3066\u3044\u308b";
|
|
if ((t.fearTimer || 0) > 0.08) return "\u6016\u304c\u3063\u3066\u3044\u308b";
|
|
if ((t.grassEatTimer || 0) > 0.04) return "\u8349\u3092\u98df\u3079\u3066\u3044\u308b";
|
|
const thought = String(t.thought || "").trim();
|
|
const cleanedThought = TEXT_CATALOG.cleanBehaviorText(thought, t.state || "");
|
|
if (["待機", "待っている", "待っている。", "ぼーっとしている", "ぼーっとしている。", "周囲を見ている"].includes(cleanedThought)) return TEXT_CATALOG.idleGroundText(t);
|
|
if (thought) return thought;
|
|
if (t.state === "idle" || !t.state) return TEXT_CATALOG.idleGroundText(t);
|
|
return "周囲を見ている";
|
|
};
|
|
|
|
function stateLabel(s) { return TEXT_CATALOG.stateLabel(s); }
|
|
function targetLabel(target) { return TEXT_CATALOG.targetLabel(target); }
|
|
function reasonLabel(t) { return TEXT_CATALOG.reasonLabel(t); }
|
|
|
|
window.stateLabel = stateLabel;
|
|
window.targetLabel = targetLabel;
|
|
window.reasonLabel = reasonLabel;
|
|
|
|
window.TEXT_CATALOG = TEXT_CATALOG;
|