fix(studio): оружие попадает по NPC (pickable+npcId) → авто-floater урона работает
Меши NPC ставились isPickable=false → raycast бластера/меча проходил сквозь них, урон и авто-floater не срабатывали. Теперь меши NPC pickable + npcId в metadata; damageByMesh находит NPC по metadata (быстро) или по rootMesh. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
854074bfa2
commit
e4fdd91b12
@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user