diff --git a/addons/yt_world/data/yt_world_race.xml b/addons/yt_world/data/yt_world_race.xml
index 2945f24..30cac8c 100644
--- a/addons/yt_world/data/yt_world_race.xml
+++ b/addons/yt_world/data/yt_world_race.xml
@@ -20,6 +20,7 @@
均衡型。各项能力标准,无特殊被动,适合新手。
10
1
+ sentient
demon
@@ -40,6 +41,7 @@
均衡型。无特殊被动,与人类齐平的基础战力。
20
1
+ sentient
dwarf
@@ -200,5 +202,112 @@
均衡型。眼中发光的岩石巨像,无特殊被动,基础战力与人类一致。
100
1
+ sentient
+
+
+
+ cow
+ 牛
+ 🐄
+ assets/characters/cow/cow_walk_1x6.png
+ assets/characters/cow/cow_idle_attack_1x6.png
+ assets/characters/cow/cow_work_comm_1x6.png
+ 30
+ 80
+ 2
+ 2
+ 50
+ 30
+ 0
+ 0
+ 0.0
+ 家畜。体型大、移动慢,产肉产奶。
+ 110
+ 1
+ animal
+
+
+ sheep
+ 羊
+ 🐑
+ assets/characters/sheep/sheep_walk_1x6.png
+ assets/characters/sheep/sheep_idle_attack_1x6.png
+ assets/characters/sheep/sheep_work_comm_1x6.png
+ 20
+ 60
+ 1
+ 1
+ 70
+ 20
+ 0
+ 0
+ 0.0
+ 家畜。温顺群居,产毛产肉。
+ 115
+ 1
+ animal
+
+
+ chicken
+ 鸡
+ 🐔
+ assets/characters/chicken/chicken_walk_1x6.png
+ assets/characters/chicken/chicken_idle_attack_1x6.png
+ assets/characters/chicken/chicken_work_comm_1x6.png
+ 10
+ 40
+ 1
+ 1
+ 100
+ 15
+ 0
+ 0
+ 0.0
+ 家禽。体型小、移动快,产蛋。
+ 120
+ 1
+ animal
+
+
+ pig
+ 猪
+ 🐷
+ assets/characters/pig/pig_walk_1x6.png
+ assets/characters/pig/pig_idle_attack_1x6.png
+ assets/characters/pig/pig_work_comm_1x6.png
+ 25
+ 60
+ 2
+ 2
+ 65
+ 25
+ 0
+ 0
+ 0.0
+ 家畜。杂食健壮,产肉。
+ 125
+ 1
+ animal
+
+
+ horse
+ 马
+ 🐴
+ assets/characters/horse/horse_walk_1x6.png
+ assets/characters/horse/horse_idle_attack_1x6.png
+ assets/characters/horse/horse_work_comm_1x6.png
+ 35
+ 90
+ 3
+ 3
+ 140
+ 40
+ 0
+ 0
+ 0.0
+ 家畜。速度最快的动物,可骑乘。
+ 130
+ 1
+ animal
diff --git a/addons/yt_world/models/yt_world_game.py b/addons/yt_world/models/yt_world_game.py
index cdc9996..ce2e121 100644
--- a/addons/yt_world/models/yt_world_game.py
+++ b/addons/yt_world/models/yt_world_game.py
@@ -361,6 +361,11 @@ class YtWorldRace(models.Model):
trait = fields.Text(string='特性文案')
sequence = fields.Integer(string='排序', default=10)
active = fields.Boolean(string='启用', default=True)
+ category = fields.Selection(
+ [('sentient', '智慧生物'), ('animal', '非智慧生物')],
+ string='类别', default='sentient',
+ help='智慧生物会主动捡宝箱;非智慧生物(牲畜/家禽)不会。'
+ )
_sql_constraints = [
('uniq_code', 'unique(code)', '种族编码必须唯一'),
@@ -394,5 +399,6 @@ class YtWorldRace(models.Model):
'shield_ratio': self.shield_ratio,
'trait': self.trait or '',
'active': self.active,
+ 'category': self.category or 'sentient',
}
diff --git a/assets/characters.js b/assets/characters.js
index 0ad7b06..1a776d5 100644
--- a/assets/characters.js
+++ b/assets/characters.js
@@ -17,6 +17,7 @@ async function loadRaces() {
map[rc.code] = {
name: rc.name,
icon: rc.icon || '👤',
+ category: rc.category || 'sentient',
speed: rc.speed,
attack: rc.attack,
defense: rc.defense,
@@ -100,7 +101,9 @@ function allSheetsLoaded() {
}
function preloadAllSheets() {
Object.keys(RACE_CONFIG).forEach(race => {
- ['walk','idle_attack','work_comm'].forEach(k => loadCharSheet(race, k));
+ const cfg = RACE_CONFIG[race];
+ ['walk','idle_attack'].forEach(k => loadCharSheet(race, k));
+ if (cfg.category !== 'animal') loadCharSheet(race, 'work_comm'); // 动物无工作/交流动作
});
}
@@ -382,6 +385,9 @@ function clearChars() {
function triggerCharAction(charId, action) {
const ch = getChar(charId);
if (!ch || !CHAR_STATES[action]) return false;
+ const raceCfg = RACE_CONFIG[ch.race];
+ // 非智慧生物(动物)无工作/交流动作,禁止触发
+ if (raceCfg && raceCfg.category === 'animal' && (action === 'work' || action === 'communicate')) return false;
ch.state = action;
ch.frame = 0;
ch.frameT = 0;
@@ -531,6 +537,12 @@ function updateChars(dt) {
// 原有漫游 / 行走逻辑
// 自由移动开关:ch.freeMove !== false 才允许自主漫游(默认开,可被面板按钮关闭)
if (ch.freeMove !== false && !ch.selected && ch.state === 'idle') {
+ // 非智慧生物(动物)不捡宝箱,直接走漫游逻辑
+ const raceCfg = RACE_CONFIG[ch.race];
+ const isAnimal = raceCfg && raceCfg.category === 'animal';
+ let goToChest = false;
+
+ if (!isAnimal) {
// 宝箱吸引:附近存在活跃宝箱时优先去开启(测试阶段吸引半径全屏)
const chests = window.microChests;
const c2s = window.microCellToScreen;
@@ -553,13 +565,19 @@ function updateChars(dt) {
ch._userMove = false;
ch.wanderT = 0;
ch.trail = [];
- } else {
+ goToChest = true;
+ }
+ } // end if (!isAnimal) — 动物跳过整段宝箱吸引
+
+ // 漫游逻辑:动物始终走这里;智慧生物在无宝箱时走这里
+ if (!goToChest) {
ch.wanderT = (ch.wanderT || 0) + dt;
const interval = ch.wanderInterval || (2 + Math.random() * 4);
if (ch.wanderT >= interval) {
ch.wanderT = 0;
ch.wanderInterval = 2 + Math.random() * 4;
- // 多意图漫游目标:闲逛 / 朝中心 / 远行(带岛内+建筑校验)
+
+ // 动物只做漫游走动(不捡宝箱、不吃草)
const target = generateWanderTarget(ch);
if (!target) {
ch.wanderInterval = 1 + Math.random() * 2; // 找不到就短等重试
@@ -699,6 +717,7 @@ function updateChars(dt) {
if (st.loop) {
ch.frame = (ch.frame + 1) % st.count;
} else if (ch.frame >= st.count - 1) {
+ // 非循环动画(attack/work/communicate)播完 → 回 idle
ch.state = 'idle';
ch.frame = 0;
} else {
@@ -945,7 +964,8 @@ function updateCharPanel() {
const shieldHtml = ch.shieldMax > 0
? `
🛡 护盾 ${ch.shield}/${ch.shieldMax}${ch.shield > 0 ? '' : '(未触发)'}
`
: '';
- const actions = ['idle', 'attack', 'work', 'communicate'];
+ const isAnimal = rc && rc.category === 'animal';
+ const actions = isAnimal ? ['idle', 'attack'] : ['idle', 'attack', 'work', 'communicate'];
const btns = actions.map(a => {
const active = ch.state === a ? 'background:#2a4a6a;border-color:#5a9acc;' : '';
return ``;
diff --git a/assets/characters/chicken/chicken_idle_attack_1x6.png b/assets/characters/chicken/chicken_idle_attack_1x6.png
new file mode 100644
index 0000000..6b5b2f8
Binary files /dev/null and b/assets/characters/chicken/chicken_idle_attack_1x6.png differ
diff --git a/assets/characters/chicken/chicken_thumb.png b/assets/characters/chicken/chicken_thumb.png
new file mode 100644
index 0000000..75c0a3e
Binary files /dev/null and b/assets/characters/chicken/chicken_thumb.png differ
diff --git a/assets/characters/chicken/chicken_walk_1x6.png b/assets/characters/chicken/chicken_walk_1x6.png
new file mode 100644
index 0000000..77805f1
Binary files /dev/null and b/assets/characters/chicken/chicken_walk_1x6.png differ
diff --git a/assets/characters/cow/cow_idle_attack_1x6.png b/assets/characters/cow/cow_idle_attack_1x6.png
new file mode 100644
index 0000000..1d4d3e2
Binary files /dev/null and b/assets/characters/cow/cow_idle_attack_1x6.png differ
diff --git a/assets/characters/cow/cow_thumb.png b/assets/characters/cow/cow_thumb.png
new file mode 100644
index 0000000..74b4001
Binary files /dev/null and b/assets/characters/cow/cow_thumb.png differ
diff --git a/assets/characters/cow/cow_walk_1x6.png b/assets/characters/cow/cow_walk_1x6.png
new file mode 100644
index 0000000..19e6b4a
Binary files /dev/null and b/assets/characters/cow/cow_walk_1x6.png differ
diff --git a/assets/characters/horse/horse_idle_attack_1x6.png b/assets/characters/horse/horse_idle_attack_1x6.png
new file mode 100644
index 0000000..6f7449d
Binary files /dev/null and b/assets/characters/horse/horse_idle_attack_1x6.png differ
diff --git a/assets/characters/horse/horse_thumb.png b/assets/characters/horse/horse_thumb.png
new file mode 100644
index 0000000..33b1e51
Binary files /dev/null and b/assets/characters/horse/horse_thumb.png differ
diff --git a/assets/characters/horse/horse_walk_1x6.png b/assets/characters/horse/horse_walk_1x6.png
new file mode 100644
index 0000000..2f1f0d5
Binary files /dev/null and b/assets/characters/horse/horse_walk_1x6.png differ
diff --git a/assets/characters/pig/Game_sprite_sheet_of_a_cute_ca_2026-09-15T04-08-39.png b/assets/characters/pig/Game_sprite_sheet_of_a_cute_ca_2026-09-15T04-08-39.png
new file mode 100644
index 0000000..408663a
Binary files /dev/null and b/assets/characters/pig/Game_sprite_sheet_of_a_cute_ca_2026-09-15T04-08-39.png differ
diff --git a/assets/characters/pig/Transform_this_exact_same_pig__2026-09-15T04-09-00.png b/assets/characters/pig/Transform_this_exact_same_pig__2026-09-15T04-09-00.png
new file mode 100644
index 0000000..f509994
Binary files /dev/null and b/assets/characters/pig/Transform_this_exact_same_pig__2026-09-15T04-09-00.png differ
diff --git a/assets/characters/pig/pig_idle_attack_1x6.png b/assets/characters/pig/pig_idle_attack_1x6.png
new file mode 100644
index 0000000..d721f75
Binary files /dev/null and b/assets/characters/pig/pig_idle_attack_1x6.png differ
diff --git a/assets/characters/pig/pig_thumb.png b/assets/characters/pig/pig_thumb.png
new file mode 100644
index 0000000..dc21e88
Binary files /dev/null and b/assets/characters/pig/pig_thumb.png differ
diff --git a/assets/characters/pig/pig_walk_1x6.png b/assets/characters/pig/pig_walk_1x6.png
new file mode 100644
index 0000000..751ac3c
Binary files /dev/null and b/assets/characters/pig/pig_walk_1x6.png differ
diff --git a/assets/characters/sheep/sheep_idle_attack_1x6.png b/assets/characters/sheep/sheep_idle_attack_1x6.png
new file mode 100644
index 0000000..a248dfd
Binary files /dev/null and b/assets/characters/sheep/sheep_idle_attack_1x6.png differ
diff --git a/assets/characters/sheep/sheep_thumb.png b/assets/characters/sheep/sheep_thumb.png
new file mode 100644
index 0000000..83c416a
Binary files /dev/null and b/assets/characters/sheep/sheep_thumb.png differ
diff --git a/assets/characters/sheep/sheep_walk_1x6.png b/assets/characters/sheep/sheep_walk_1x6.png
new file mode 100644
index 0000000..0c1d99c
Binary files /dev/null and b/assets/characters/sheep/sheep_walk_1x6.png differ
diff --git a/world.html b/world.html
index 9ecd866..2a98b87 100644
--- a/world.html
+++ b/world.html
@@ -2540,7 +2540,7 @@ const MICRO_BUILD_EXTRA = [
{ id: 'barracks', cat: 'build', icon: 'assets/buildings/spring/barracks/barracks_l.png?v=9', name: '兵营', desc: '训练士兵与储备武备的军事建筑,提升领地军事产出。', flat: false, w: 3, h: 3, statLevel: 1, statHp: 130, statYield: { military: 4 }, costGold: 130 },
{ id: 'guild', cat: 'build', icon: 'assets/buildings/spring/guild/guild_l.png?v=4', name: '公会', desc: '冒险者与住民集结之所,可发布委托与招募成员。', flat: false, w: 2, h: 2, statLevel: 1, statHp: 140, statYield: { prestige: 2, coin: 1 }, costGold: 100 },
{ id: 'village', cat: 'build', icon: 'assets/buildings/spring/village/village_l.png?v=5', name: '村庄', desc: '族群聚落的核心,提升人口上限与基础产出。', flat: false, w: 3, h: 3, statLevel: 1, statHp: 150, statYield: { population: 6, food: 1 }, costGold: 200 },
- // 生物分类:9 种族角色(点击进入"点地面放置"模式,不进入建筑模式)
+ // 生物分类:10 智慧种族 + 5 非智慧动物(点击进入"点地面放置"模式,不进入建筑模式)
{ id: 'race_human', cat: 'bio', icon: 'assets/characters/human/human_thumb.png', sprite: 'assets/characters/human/human_idle_attack_1x6.png', name: '人族', isChar: true, race: 'human' },
{ id: 'race_demon', cat: 'bio', icon: 'assets/characters/demon/demon_thumb.png', sprite: 'assets/characters/demon/demon_idle_attack_1x6.png', name: '妖族', isChar: true, race: 'demon' },
{ id: 'race_dwarf', cat: 'bio', icon: 'assets/characters/dwarf/dwarf_thumb.png', sprite: 'assets/characters/dwarf/dwarf_idle_attack_1x6.png', name: '矮人', isChar: true, race: 'dwarf' },
@@ -2551,6 +2551,11 @@ const MICRO_BUILD_EXTRA = [
{ id: 'race_angel', cat: 'bio', icon: 'assets/characters/angel/angel_thumb.png', sprite: 'assets/characters/angel/angel_idle_attack_1x6.png', name: '天使', isChar: true, race: 'angel' },
{ id: 'race_werewolf',cat: 'bio', icon: 'assets/characters/werewolf/werewolf_thumb.png', sprite: 'assets/characters/werewolf/werewolf_idle_attack_1x6.png', name: '狼人', isChar: true, race: 'werewolf' },
{ id: 'race_golem', cat: 'bio', icon: 'assets/characters/golem/golem_thumb.png', sprite: 'assets/characters/golem/golem_idle_attack_1x6.png', name: '石傀儡', isChar: true, race: 'golem' },
+ { id: 'race_cow', cat: 'bio', icon: 'assets/characters/cow/cow_thumb.png', sprite: 'assets/characters/cow/cow_idle_attack_1x6.png', name: '牛', isChar: true, race: 'cow' },
+ { id: 'race_sheep', cat: 'bio', icon: 'assets/characters/sheep/sheep_thumb.png', sprite: 'assets/characters/sheep/sheep_idle_attack_1x6.png', name: '羊', isChar: true, race: 'sheep' },
+ { id: 'race_chicken', cat: 'bio', icon: 'assets/characters/chicken/chicken_thumb.png', sprite: 'assets/characters/chicken/chicken_idle_attack_1x6.png', name: '鸡', isChar: true, race: 'chicken' },
+ { id: 'race_pig', cat: 'bio', icon: 'assets/characters/pig/pig_thumb.png', sprite: 'assets/characters/pig/pig_idle_attack_1x6.png', name: '猪', isChar: true, race: 'pig' },
+ { id: 'race_horse', cat: 'bio', icon: 'assets/characters/horse/horse_thumb.png', sprite: 'assets/characters/horse/horse_idle_attack_1x6.png', name: '马', isChar: true, race: 'horse' },
];
// 建筑交互配置(数据驱动,与后端 BUILD_EFFECTS 的 (code,action) 对应)。