Team Create (���������� ��������������) + ���������� ���� + ������ 16/17/20/40/44/05 #34

Merged
min merged 69 commits from restore/all-tasks into main 2026-06-08 01:13:01 +00:00
Showing only changes of commit e4fdd91b12 - Show all commits

View File

@ -161,6 +161,20 @@ export class NpcManager {
r15Animator, r15Animator,
}; };
this.npcs.set(id, npc); this.npcs.set(id, npc);
// Пометить меши NPC для попаданий оружия (бластер/меч): pickable + npcId
// в metadata. Без pickable raycast оружия проходит сквозь NPC и урон/
// floater'ы не срабатывают (задача 40).
try {
const root = npc.data && npc.data.rootMesh;
if (root) {
root.isPickable = true;
root.metadata = Object.assign({}, root.metadata, { npcId: id });
for (const m of root.getChildMeshes(false)) {
m.isPickable = true;
m.metadata = Object.assign({}, m.metadata, { npcId: id });
}
}
} catch (e) { /* ignore */ }
return id; return id;
} }
@ -308,16 +322,23 @@ export class NpcManager {
* содержат hit-меш (или предка). Вызывает damage() авто-floater. */ * содержат hit-меш (или предка). Вызывает damage() авто-floater. */
damageByMesh(mesh, amount) { damageByMesh(mesh, amount) {
if (!mesh) return false; if (!mesh) return false;
// 1) Быстрый путь: npcId в metadata меша (или предка).
let m = mesh;
for (let i = 0; i < 8 && m; i++) {
const nid = m.metadata && m.metadata.npcId;
if (nid != null && this.npcs.has(nid)) { this.damage(nid, amount); return true; }
m = m.parent;
}
// 2) Fallback: сравнение с rootMesh по иерархии.
for (const npc of this.npcs.values()) { for (const npc of this.npcs.values()) {
if (npc.dead) continue; if (npc.dead) continue;
const root = npc.data && npc.data.rootMesh; const root = npc.data && npc.data.rootMesh;
if (!root) continue; if (!root) continue;
let m = mesh, hit = false; let mm = mesh;
for (let i = 0; i < 8 && m; i++) { for (let i = 0; i < 8 && mm; i++) {
if (m === root) { hit = true; break; } if (mm === root) { this.damage(npc.id, amount); return true; }
m = m.parent; mm = mm.parent;
} }
if (hit) { this.damage(npc.id, amount); return true; }
} }
return false; return false;
} }