人物,建筑素材 #2
|
Before Width: | Height: | Size: 122 KiB After Width: | Height: | Size: 86 KiB |
|
Before Width: | Height: | Size: 121 KiB After Width: | Height: | Size: 87 KiB |
|
Before Width: | Height: | Size: 126 KiB After Width: | Height: | Size: 79 KiB |
|
Before Width: | Height: | Size: 126 KiB After Width: | Height: | Size: 79 KiB |
|
Before Width: | Height: | Size: 136 KiB After Width: | Height: | Size: 82 KiB |
|
Before Width: | Height: | Size: 136 KiB After Width: | Height: | Size: 81 KiB |
|
Before Width: | Height: | Size: 116 KiB After Width: | Height: | Size: 118 KiB |
|
Before Width: | Height: | Size: 116 KiB After Width: | Height: | Size: 117 KiB |
|
Before Width: | Height: | Size: 143 KiB After Width: | Height: | Size: 106 KiB |
|
Before Width: | Height: | Size: 143 KiB After Width: | Height: | Size: 106 KiB |
|
Before Width: | Height: | Size: 128 KiB After Width: | Height: | Size: 67 KiB |
|
Before Width: | Height: | Size: 128 KiB After Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 132 KiB After Width: | Height: | Size: 81 KiB |
|
Before Width: | Height: | Size: 131 KiB After Width: | Height: | Size: 81 KiB |
|
Before Width: | Height: | Size: 132 KiB After Width: | Height: | Size: 102 KiB |
|
Before Width: | Height: | Size: 132 KiB After Width: | Height: | Size: 101 KiB |
|
Before Width: | Height: | Size: 114 KiB After Width: | Height: | Size: 83 KiB |
|
Before Width: | Height: | Size: 114 KiB After Width: | Height: | Size: 83 KiB |
|
Before Width: | Height: | Size: 107 KiB After Width: | Height: | Size: 86 KiB |
|
Before Width: | Height: | Size: 107 KiB After Width: | Height: | Size: 87 KiB |
|
Before Width: | Height: | Size: 126 KiB After Width: | Height: | Size: 79 KiB |
|
Before Width: | Height: | Size: 126 KiB After Width: | Height: | Size: 79 KiB |
|
Before Width: | Height: | Size: 136 KiB After Width: | Height: | Size: 82 KiB |
|
Before Width: | Height: | Size: 136 KiB After Width: | Height: | Size: 81 KiB |
|
Before Width: | Height: | Size: 116 KiB After Width: | Height: | Size: 118 KiB |
|
Before Width: | Height: | Size: 116 KiB After Width: | Height: | Size: 117 KiB |
|
Before Width: | Height: | Size: 143 KiB After Width: | Height: | Size: 106 KiB |
|
Before Width: | Height: | Size: 143 KiB After Width: | Height: | Size: 106 KiB |
|
Before Width: | Height: | Size: 124 KiB After Width: | Height: | Size: 84 KiB |
|
Before Width: | Height: | Size: 124 KiB After Width: | Height: | Size: 84 KiB |
|
Before Width: | Height: | Size: 108 KiB After Width: | Height: | Size: 79 KiB |
|
Before Width: | Height: | Size: 109 KiB After Width: | Height: | Size: 79 KiB |
|
Before Width: | Height: | Size: 128 KiB After Width: | Height: | Size: 67 KiB |
|
Before Width: | Height: | Size: 128 KiB After Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 132 KiB After Width: | Height: | Size: 81 KiB |
|
Before Width: | Height: | Size: 131 KiB After Width: | Height: | Size: 81 KiB |
|
Before Width: | Height: | Size: 110 KiB After Width: | Height: | Size: 92 KiB |
|
Before Width: | Height: | Size: 110 KiB After Width: | Height: | Size: 91 KiB |
|
Before Width: | Height: | Size: 132 KiB After Width: | Height: | Size: 102 KiB |
|
Before Width: | Height: | Size: 132 KiB After Width: | Height: | Size: 101 KiB |
|
Before Width: | Height: | Size: 108 KiB After Width: | Height: | Size: 82 KiB |
|
Before Width: | Height: | Size: 108 KiB After Width: | Height: | Size: 82 KiB |
@@ -7,14 +7,19 @@ const RACE_CONFIG = {
|
||||
demon: { name: '妖族', speed: 90, attack: 5, hpMax: 50, regen: false, trait: '均衡型。无特殊被动,与人类齐平的基础战力。', walk: 'assets/characters/demon/demon_walk_1x6.png', idle_attack: 'assets/characters/demon/demon_idle_attack_1x6.png', work_comm: 'assets/characters/demon/demon_work_comm_1x6.png' },
|
||||
dwarf: { name: '矮人', speed: 72, attack: 5, hpMax: 50, regen: false, enrage: true, shieldRatio: 0.10, trait: '铁壁·狂暴:移速较慢(0.8倍);每损失10%生命攻击+5%;生命≤30%时获得10%最大生命护盾。', walk: 'assets/characters/dwarf/dwarf_walk_1x6.png', idle_attack: 'assets/characters/dwarf/dwarf_idle_attack_1x6.png', work_comm: 'assets/characters/dwarf/dwarf_work_comm_1x6.png' },
|
||||
elf: { name: '精灵', speed: 135, attack: 5, hpMax: 50, regen: false, trait: '疾风:移速飞快(1.5倍),机动性最强的种族。', walk: 'assets/characters/elf/elf_walk_1x6.png', idle_attack: 'assets/characters/elf/elf_idle_attack_1x6.png', work_comm: 'assets/characters/elf/elf_work_comm_1x6.png' },
|
||||
dragon: { name: '龙族', speed: 90, attack: 8, hpMax: 50, regen: false, trait: '龙威:攻击力高(8),爆发型输出种族。', walk: 'assets/characters/dragon/dragon_walk_1x6.png', idle_attack: 'assets/characters/dragon/dragon_idle_attack_1x6.png', work_comm: 'assets/characters/dragon/dragon_work_comm_1x6.png' },
|
||||
dragon: { name: '龙族', speed: 90, attack: 8, attackRange: 90, hpMax: 50, regen: false, trait: '龙威:攻击力高(8),攻击范围大(1.5倍),爆发型输出种族。', walk: 'assets/characters/dragon/dragon_walk_1x6.png', idle_attack: 'assets/characters/dragon/dragon_idle_attack_1x6.png', work_comm: 'assets/characters/dragon/dragon_work_comm_1x6.png' },
|
||||
undead: { name: '不死族', speed: 90, attack: 4, hpMax: 100, regen: true, trait: '不死:生命极高(100);脱战10秒后每秒恢复5%最大生命。', walk: 'assets/characters/undead/undead_walk_1x6.png', idle_attack: 'assets/characters/undead/undead_idle_attack_1x6.png', work_comm: 'assets/characters/undead/undead_work_comm_1x6.png' },
|
||||
orc: { name: '兽人', speed: 90, attack: 5, hpMax: 50, regen: false, trait: '均衡型。绿皮獠牙的战士,无特殊被动,基础战力与人类一致。', walk: 'assets/characters/orc/orc_walk_1x6.png', idle_attack: 'assets/characters/orc/orc_idle_attack_1x6.png', work_comm: 'assets/characters/orc/orc_work_comm_1x6.png' },
|
||||
angel: { name: '天使', speed: 90, attack: 5, hpMax: 50, regen: false, trait: '均衡型。头顶光环的天界战士,无特殊被动,基础战力与人类一致。', walk: 'assets/characters/angel/angel_walk_1x6.png', idle_attack: 'assets/characters/angel/angel_idle_attack_1x6.png', work_comm: 'assets/characters/angel/angel_work_comm_1x6.png' },
|
||||
werewolf:{ name: '狼人', speed: 90, attack: 5, hpMax: 50, regen: false, trait: '均衡型。竖耳狼首的猎手,无特殊被动,基础战力与人类一致。', walk: 'assets/characters/werewolf/werewolf_walk_1x6.png', idle_attack: 'assets/characters/werewolf/werewolf_idle_attack_1x6.png', work_comm: 'assets/characters/werewolf/werewolf_work_comm_1x6.png' },
|
||||
golem: { name: '石傀儡', speed: 90, attack: 5, hpMax: 50, regen: false, trait: '均衡型。眼中发光的岩石巨像,无特殊被动,基础战力与人类一致。', walk: 'assets/characters/golem/golem_walk_1x6.png', idle_attack: 'assets/characters/golem/golem_idle_attack_1x6.png', work_comm: 'assets/characters/golem/golem_work_comm_1x6.png' },
|
||||
};
|
||||
|
||||
function raceStats(race) {
|
||||
const rc = RACE_CONFIG[race] || RACE_CONFIG.human;
|
||||
return {
|
||||
speed: rc.speed, attack: rc.attack, hpMax: rc.hpMax, regen: !!rc.regen,
|
||||
speed: rc.speed, attack: rc.attack, attackRange: rc.attackRange || CHAR_ATTACK_RANGE,
|
||||
hpMax: rc.hpMax, regen: !!rc.regen,
|
||||
enrage: !!rc.enrage, shieldRatio: rc.shieldRatio || 0,
|
||||
};
|
||||
}
|
||||
@@ -219,6 +224,7 @@ async function loadMicroChars() {
|
||||
hp: (typeof c.hp === 'number' && c.hp > 0) ? c.hp : stats.hpMax,
|
||||
hpMax: stats.hpMax,
|
||||
attack: stats.attack,
|
||||
attackRange: stats.attackRange,
|
||||
regen: stats.regen,
|
||||
enrage: stats.enrage,
|
||||
shieldMax: stats.shieldRatio ? Math.max(1, Math.round(stats.hpMax * stats.shieldRatio)) : 0,
|
||||
@@ -231,6 +237,7 @@ async function loadMicroChars() {
|
||||
wanderT: Math.random() * 3,
|
||||
wanderInterval: 2 + Math.random() * 4,
|
||||
_userMove: false,
|
||||
freeMove: true, // 自由移动开关(默认开;面板按钮可切换)
|
||||
...(local ? { frame: local.frame, frameT: local.frameT } : {}),
|
||||
};
|
||||
});
|
||||
@@ -254,6 +261,7 @@ function createChar(race, x, y) {
|
||||
hp: stats.hpMax, // 生命值(满血)
|
||||
hpMax: stats.hpMax, // 最大生命(种族差异)
|
||||
attack: stats.attack, // 攻击力(种族差异)
|
||||
attackRange: stats.attackRange, // 攻击范围(龙族 1.5 倍 = 90px)
|
||||
regen: stats.regen, // 是否有脱战恢复
|
||||
enrage: stats.enrage, // 是否狂暴(矮人:掉血加攻)
|
||||
shieldMax: stats.shieldRatio ? Math.max(1, Math.round(stats.hpMax * stats.shieldRatio)) : 0, // 护盾上限(矮人 10% 最大生命)
|
||||
@@ -267,6 +275,7 @@ function createChar(race, x, y) {
|
||||
wanderT: Math.random() * 3, // 首次漫游前随机等待
|
||||
wanderInterval: 2 + Math.random() * 4, // 2~6 秒
|
||||
_userMove: false, // 是否用户指令移动
|
||||
freeMove: charPlaceFreeMove, // 自由移动开关(默认按右侧面板"自由移动"按钮)
|
||||
};
|
||||
microChars.push(ch);
|
||||
selectChar(id);
|
||||
@@ -321,12 +330,13 @@ function triggerCharAction(charId, action) {
|
||||
function applyAttackDamage(attacker) {
|
||||
const now = Date.now();
|
||||
const damage = currentAttackOf(attacker); // 攻击力(含矮人狂暴加成)
|
||||
const range = attacker.attackRange || CHAR_ATTACK_RANGE; // 攻击范围(龙族 1.5 倍 = 90px)
|
||||
const fmt = (v) => (v % 1 === 0 ? String(v) : String(parseFloat(v.toFixed(2)))); // 显示去尾零
|
||||
const vis = visibleMicroChars();
|
||||
for (const other of vis) {
|
||||
if (other.id === attacker.id) continue;
|
||||
const d = Math.hypot(other.x - attacker.x, other.y - attacker.y);
|
||||
if (d <= CHAR_ATTACK_RANGE) {
|
||||
if (d <= range) {
|
||||
let dmg = damage;
|
||||
// 护盾优先吸收(矮人铁壁)
|
||||
if ((other.shield || 0) > 0 && dmg > 0) {
|
||||
@@ -442,7 +452,8 @@ function updateChars(dt) {
|
||||
ch.targetY = ch.y;
|
||||
} else {
|
||||
// 原有漫游 / 行走逻辑
|
||||
if (!ch.selected && ch.state === 'idle') {
|
||||
// 自由移动开关:ch.freeMove !== false 才允许自主漫游(默认开,可被面板按钮关闭)
|
||||
if (ch.freeMove !== false && !ch.selected && ch.state === 'idle') {
|
||||
ch.wanderT = (ch.wanderT || 0) + dt;
|
||||
const interval = ch.wanderInterval || (2 + Math.random() * 4);
|
||||
if (ch.wanderT >= interval) {
|
||||
@@ -854,6 +865,9 @@ function updateCharPanel() {
|
||||
<div style="margin-top:5px;color:#8a9aaa;font-size:11px;">⚔ 攻击 <b style="color:#e8eef7;">${fmt(curAtk)}</b>${atkBonus}</div>
|
||||
<div style="margin-top:8px;padding:6px 8px;background:#16213a;border-radius:5px;color:#9fb2cc;font-size:11px;line-height:1.5;">📖 ${rc.trait || '暂无介绍'}</div>
|
||||
<div style="margin-top:8px;display:flex;gap:8px;flex-wrap:wrap;">${btns}</div>
|
||||
<div style="margin-top:8px;">
|
||||
<button id="charFreeMoveBtn" style="background:${ch.freeMove !== false ? '#1d4a2a' : '#3a3a4a'};color:${ch.freeMove !== false ? '#7ef0a0' : '#aab'};border:1px solid ${ch.freeMove !== false ? '#3a8a5e' : '#5a5a7a'};padding:5px 10px;border-radius:5px;cursor:pointer;font-size:12px;width:100%;">${ch.freeMove !== false ? '⏸ 停止自由移动' : '▶ 自由移动'}</button>
|
||||
</div>
|
||||
<div style="margin-top:8px;color:#8a9aaa;font-size:11px;">💡 点击地图移动 · WASD 方向键控制</div>
|
||||
<div style="margin-top:6px;">
|
||||
<button id="charDelBtn" style="background:#4a1e1e;color:#faa;border:1px solid #8a3a3a;padding:4px 10px;border-radius:5px;cursor:pointer;font-size:11px;">删除</button>
|
||||
@@ -862,29 +876,68 @@ function updateCharPanel() {
|
||||
panel.querySelectorAll('.charActBtn').forEach(btn => {
|
||||
btn.addEventListener('click', () => { triggerCharAction(ch.id, btn.dataset.act); updateCharPanel(); });
|
||||
});
|
||||
panel.querySelector('#charFreeMoveBtn').addEventListener('click', () => {
|
||||
if (ch.freeMove !== false) {
|
||||
// 停止自由移动:立即打断漫游行走 + 重置计时(freeMove=false 后漫游分支不再进入)
|
||||
ch.freeMove = false;
|
||||
ch.wanderT = 0;
|
||||
if (!ch._userMove && ch.state === 'walk') {
|
||||
ch.state = 'idle';
|
||||
ch.frame = 0;
|
||||
ch.frameT = 0;
|
||||
}
|
||||
} else {
|
||||
// 开启自由移动:重置计时,取消选中后即可漫游
|
||||
ch.freeMove = true;
|
||||
ch.wanderT = 0;
|
||||
ch.wanderInterval = 2 + Math.random() * 4;
|
||||
}
|
||||
updateCharPanel();
|
||||
});
|
||||
panel.querySelector('#charDelBtn').addEventListener('click', () => deleteChar(ch.id));
|
||||
}
|
||||
|
||||
// ---- 放置面板 ----
|
||||
// ---- 放置面板(右侧建筑面板"角色"分类下) ----
|
||||
// 新放置角色默认是否自由移动(面板上的自由移动按钮切换此值)
|
||||
let charPlaceFreeMove = true;
|
||||
function updateCharPlacePanel() {
|
||||
const panel = document.getElementById('charPlacePanel');
|
||||
if (!panel) return;
|
||||
const races = Object.keys(RACE_CONFIG);
|
||||
const fmBtnStyle = charPlaceFreeMove
|
||||
? 'background:#1d4a2a;color:#7ef0a0;border:1px solid #3a8a5e;'
|
||||
: 'background:#3a3a4a;color:#aab;border:1px solid #5a5a7a;';
|
||||
panel.innerHTML = `
|
||||
<div style="font-size:12px;color:#8a9aaa;margin-bottom:6px;">放置角色</div>
|
||||
<div style="display:flex;gap:6px;flex-wrap:wrap;">
|
||||
${races.map(r => `<button class="charRaceBtn" data-race="${r}" style="${charPlaceRace===r?'background:#2a4a6a;border-color:#5a9acc;':''}background:#1d2b4a;color:#cde;border:1px solid #3a5a8e;padding:5px 10px;border-radius:5px;cursor:pointer;font-size:12px;">${RACE_CONFIG[r].name}</button>`).join('')}
|
||||
${races.map(r => {
|
||||
const active = charPlaceRace === r && charPlaceMode;
|
||||
const style = active
|
||||
? 'background:#2a4a6a;color:#cde;border:1px solid #5a9acc;'
|
||||
: 'background:#1d2b4a;color:#cde;border:1px solid #3a5a8e;';
|
||||
return `<button class="charRaceBtn" data-race="${r}" style="${style}padding:5px 10px;border-radius:5px;cursor:pointer;font-size:12px;">${RACE_CONFIG[r].name}</button>`;
|
||||
}).join('')}
|
||||
</div>
|
||||
<div style="margin-top:6px;display:flex;gap:6px;">
|
||||
<button id="charPlaceToggle" style="background:${charPlaceMode?'#2a4a6a':'#1d2b4a'};color:#cde;border:1px solid #3a5a8e;padding:4px 10px;border-radius:5px;cursor:pointer;font-size:11px;">${charPlaceMode?'取消放置':'开始放置'}</button>
|
||||
<button id="charClearAll" style="background:#4a1e1e;color:#faa;border:1px solid #8a3a3a;padding:4px 10px;border-radius:5px;cursor:pointer;font-size:11px;">清空全部</button>
|
||||
<div style="margin-top:8px;display:flex;gap:6px;flex-wrap:wrap;">
|
||||
<button id="charFreeMoveToggle" style="${fmBtnStyle}padding:4px 10px;border-radius:5px;cursor:pointer;font-size:11px;">${charPlaceFreeMove ? '⏸ 停止自由移动' : '▶ 自由移动'}</button>
|
||||
<button id="charClearAll" style="background:#4a1e1e;color:#faa;border:1px solid #8a3a3a;padding:4px 10px;border-radius:5px;cursor:pointer;font-size:11px;">取消全部</button>
|
||||
</div>
|
||||
`;
|
||||
panel.querySelectorAll('.charRaceBtn').forEach(btn => {
|
||||
btn.addEventListener('click', () => { charPlaceRace = btn.dataset.race; charPlaceMode = true; updateCharPlacePanel(); });
|
||||
btn.addEventListener('click', () => {
|
||||
charPlaceRace = btn.dataset.race;
|
||||
charPlaceMode = true; // 点击种族直接进入放置模式(简化:无需再点"开始放置")
|
||||
updateCharPlacePanel();
|
||||
});
|
||||
});
|
||||
panel.querySelector('#charFreeMoveToggle').addEventListener('click', () => {
|
||||
charPlaceFreeMove = !charPlaceFreeMove;
|
||||
updateCharPlacePanel();
|
||||
});
|
||||
panel.querySelector('#charClearAll').addEventListener('click', () => {
|
||||
clearChars();
|
||||
updateCharPlacePanel();
|
||||
});
|
||||
panel.querySelector('#charPlaceToggle').addEventListener('click', () => { charPlaceMode = !charPlaceMode; updateCharPlacePanel(); });
|
||||
panel.querySelector('#charClearAll').addEventListener('click', () => { clearChars(); updateCharPlacePanel(); });
|
||||
}
|
||||
|
||||
// 导出到 window
|
||||
|
||||
|
Before Width: | Height: | Size: 1014 B After Width: | Height: | Size: 5.8 KiB |
|
Before Width: | Height: | Size: 958 B After Width: | Height: | Size: 4.9 KiB |
|
Before Width: | Height: | Size: 932 B After Width: | Height: | Size: 5.3 KiB |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 5.9 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 5.1 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 5.4 KiB |
|
Before Width: | Height: | Size: 861 B After Width: | Height: | Size: 5.7 KiB |
|
Before Width: | Height: | Size: 853 B After Width: | Height: | Size: 4.8 KiB |
|
Before Width: | Height: | Size: 828 B After Width: | Height: | Size: 5.1 KiB |
|
Before Width: | Height: | Size: 1006 B After Width: | Height: | Size: 6.0 KiB |
|
Before Width: | Height: | Size: 960 B After Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 929 B After Width: | Height: | Size: 5.4 KiB |
|
Before Width: | Height: | Size: 868 B After Width: | Height: | Size: 6.0 KiB |
|
Before Width: | Height: | Size: 882 B After Width: | Height: | Size: 4.8 KiB |
|
Before Width: | Height: | Size: 853 B After Width: | Height: | Size: 5.6 KiB |
|
Before Width: | Height: | Size: 941 B After Width: | Height: | Size: 5.3 KiB |
|
Before Width: | Height: | Size: 949 B After Width: | Height: | Size: 4.6 KiB |
|
Before Width: | Height: | Size: 917 B After Width: | Height: | Size: 4.8 KiB |
@@ -1749,10 +1749,10 @@ const MICRO_BUILD_ITEMS = [
|
||||
// 建筑 / 设施 目录(兜底:未登录或 Odoo 未提供时直接用此;登录后由 /yt_world/api/micro/catalog 覆盖)。
|
||||
// flat=true 表示平面俯视,岛上压成菱形贴地;否则为 3/4 立绘,竖直站立。
|
||||
const MICRO_BUILD_EXTRA = [
|
||||
{ id: 'cottage', cat: 'build', icon: 'assets/buildings/spring/cottage/cottage_l.png', name: '农舍', desc: '村民起居的基本居所,提供人口上限与夜间休息。', flat: false, w: 2, h: 2, statLevel: 1, statHp: 120, statYield: { population: 4 } },
|
||||
{ id: 'windmill', cat: 'build', icon: 'assets/buildings/spring/windmill/windmill_l.png', name: '风车', desc: '利用风力磨粉与提水,提升粮食加工效率。', flat: false, w: 2, h: 2, statLevel: 1, statHp: 110, statYield: { flour: 2 } },
|
||||
{ id: 'blacksmith', cat: 'build', icon: 'assets/buildings/spring/blacksmith/blacksmith_l.png',name: '铁匠铺', desc: '锻造工具与武器,产出金属制品。', flat: false, w: 2, h: 2, statLevel: 1, statHp: 130, statYield: { metal: 2 } },
|
||||
{ id: 'grocery', cat: 'build', icon: 'assets/buildings/spring/grocery/grocery_l.png', name: '杂货铺', desc: '交易日用物资的小型商铺,促进经济流通。', flat: false, w: 2, h: 2, statLevel: 1, statHp: 90, statYield: { coin: 2 } },
|
||||
{ id: 'cottage', cat: 'build', icon: 'assets/buildings/spring/cottage/cottage_l.png?v=2', name: '农舍', desc: '村民起居的基本居所,提供人口上限与夜间休息。', flat: false, w: 2, h: 2, statLevel: 1, statHp: 120, statYield: { population: 4 } },
|
||||
{ id: 'windmill', cat: 'build', icon: 'assets/buildings/spring/windmill/windmill_l.png?v=2', name: '风车', desc: '利用风力磨粉与提水,提升粮食加工效率。', flat: false, w: 2, h: 2, statLevel: 1, statHp: 110, statYield: { flour: 2 } },
|
||||
{ id: 'blacksmith', cat: 'build', icon: 'assets/buildings/spring/blacksmith/blacksmith_l.png?v=2',name: '铁匠铺', desc: '锻造工具与武器,产出金属制品。', flat: false, w: 2, h: 2, statLevel: 1, statHp: 130, statYield: { metal: 2 } },
|
||||
{ id: 'grocery', cat: 'build', icon: 'assets/buildings/spring/grocery/grocery_l.png?v=2', name: '杂货铺', desc: '交易日用物资的小型商铺,促进经济流通。', flat: false, w: 2, h: 2, statLevel: 1, statHp: 90, statYield: { coin: 2 } },
|
||||
{ id: 'temple', cat: 'build', icon: 'assets/buildings/spring/temple/temple_l.png', name: '神庙', desc: '供奉信仰的场所,提升居民精神状态与领地声望。', flat: false, w: 2, h: 2, statLevel: 1, statHp: 160, statYield: { prestige: 3 } },
|
||||
{ id: 'clinic', cat: 'build', icon: 'assets/buildings/spring/clinic/clinic_l.png', name: '医务室', desc: '诊治伤病,恢复居民生命值。', flat: false, w: 2, h: 2, statLevel: 1, statHp: 100, statYield: { heal: 2 } },
|
||||
{ id: 'restaurant', cat: 'build', icon: 'assets/buildings/spring/restaurant/restaurant_l.png',name: '酒馆', desc: '烹制料理,为居民提供饱食与心情加成。', flat: false, w: 2, h: 2, statLevel: 1, statHp: 95, statYield: { satiety: 3 } },
|
||||
@@ -1764,7 +1764,18 @@ const MICRO_BUILD_EXTRA = [
|
||||
{ id: 'library', cat: 'build', icon: 'assets/buildings/spring/library/library_l.png', name: '图书馆', desc: '收藏典籍与卷轴,提升领地科研与知识产出。', flat: false, w: 2, h: 2, statLevel: 1, statHp: 110, statYield: { research: 4 } },
|
||||
{ id: 'barracks', cat: 'build', icon: 'assets/buildings/spring/barracks/barracks_l.png', name: '兵营', desc: '训练士兵与储备武备的军事建筑,提升领地军事产出。', flat: false, w: 2, h: 2, statLevel: 1, statHp: 130, statYield: { military: 4 } },
|
||||
{ id: 'guild', cat: 'build', icon: 'assets/buildings/spring/guild/guild_l.png', name: '公会', desc: '冒险者与住民集结之所,可发布委托与招募成员。', flat: false, w: 2, h: 2, statLevel: 1, statHp: 140, statYield: { prestige: 2, coin: 1 } },
|
||||
{ id: 'village', cat: 'build', icon: 'assets/buildings/spring/village/village_l.png', name: '村庄', desc: '族群聚落的核心,提升人口上限与基础产出。', flat: false, w: 2, h: 2, statLevel: 1, statHp: 150, statYield: { population: 6, food: 1 } }
|
||||
{ id: 'village', cat: 'build', icon: 'assets/buildings/spring/village/village_l.png', name: '村庄', desc: '族群聚落的核心,提升人口上限与基础产出。', flat: false, w: 2, h: 2, statLevel: 1, statHp: 150, statYield: { population: 6, food: 1 } },
|
||||
// 生物分类:9 种族角色(点击进入"点地面放置"模式,不进入建筑模式)
|
||||
{ id: 'race_human', cat: 'bio', icon: 'assets/characters/human/human_thumb.png', name: '人族', isChar: true, race: 'human' },
|
||||
{ id: 'race_demon', cat: 'bio', icon: 'assets/characters/demon/demon_thumb.png', name: '妖族', isChar: true, race: 'demon' },
|
||||
{ id: 'race_dwarf', cat: 'bio', icon: 'assets/characters/dwarf/dwarf_thumb.png', name: '矮人', isChar: true, race: 'dwarf' },
|
||||
{ id: 'race_elf', cat: 'bio', icon: 'assets/characters/elf/elf_thumb.png', name: '精灵', isChar: true, race: 'elf' },
|
||||
{ id: 'race_dragon', cat: 'bio', icon: 'assets/characters/dragon/dragon_thumb.png', name: '龙族', isChar: true, race: 'dragon' },
|
||||
{ id: 'race_undead', cat: 'bio', icon: 'assets/characters/undead/undead_thumb.png', name: '不死族', isChar: true, race: 'undead' },
|
||||
{ id: 'race_orc', cat: 'bio', icon: 'assets/characters/orc/orc_thumb.png', name: '兽人', isChar: true, race: 'orc' },
|
||||
{ id: 'race_angel', cat: 'bio', icon: 'assets/characters/angel/angel_thumb.png', name: '天使', isChar: true, race: 'angel' },
|
||||
{ id: 'race_werewolf',cat: 'bio', icon: 'assets/characters/werewolf/werewolf_thumb.png', name: '狼人', isChar: true, race: 'werewolf' },
|
||||
{ id: 'race_golem', cat: 'bio', icon: 'assets/characters/golem/golem_thumb.png', name: '石傀儡', isChar: true, race: 'golem' },
|
||||
];
|
||||
|
||||
// 建筑交互配置(数据驱动,与后端 BUILD_EFFECTS 的 (code,action) 对应)。
|
||||
@@ -5750,6 +5761,25 @@ function microRenderBuildPanel() {
|
||||
gridEl.querySelectorAll('.mv-cell').forEach(el => {
|
||||
el.addEventListener('click', () => {
|
||||
const id = el.dataset.build;
|
||||
const item = microAllBuildItems().find(x => x.id === id);
|
||||
// 角色素材(生物栏):进入"点地面放置"模式,不进建筑模式
|
||||
if (item && item.isChar) {
|
||||
// characters.js 顶层 let charPlaceRace/charPlaceMode 在同全局词法环境可直接读写
|
||||
charPlaceRace = item.race;
|
||||
charPlaceMode = true;
|
||||
// 退出建造模式(如果有)+ 清掉建筑选中态
|
||||
microBuildSel = null;
|
||||
microEditRef = null;
|
||||
microGhost = null;
|
||||
microGhostFrozen = false;
|
||||
if (microBuildMode) microSetBuildMode(false);
|
||||
clearBuildSelUI();
|
||||
microRenderBuildPanel();
|
||||
if (typeof updateCharPlacePanel === 'function') updateCharPlacePanel();
|
||||
const raceName = (window.RACE_CONFIG && window.RACE_CONFIG[item.race]) ? window.RACE_CONFIG[item.race].name : item.name;
|
||||
microToast('👤 点地面放置' + raceName);
|
||||
return;
|
||||
}
|
||||
microBuildSel = (microBuildSel === id) ? null : id;
|
||||
microEditRef = null; // 选新素材退出编辑
|
||||
microGhostFrozen = false; // 进入跟随模式,移动鼠标,点一下才冻结
|
||||
|
||||