feat(rust): NPC profiles and placements pages, the profile leaderboard (runicnpc stage 4)
Admin: Rust NPC profiles (the form RunicNPC reads, per server, shared or fleet, each server's push state and refusals, replaced profiles with Restore) and Rust NPC placements (the live map: click to place, pins for every placement; edit, rename, respawn, remove). The live map takes a pick handler and pins, unchanged for the public page. Public: the leaderboard ranks by a profile's kills (D250), and opening a row shows that player's kills by profile (D252); the killfeed names a RunicNPC NPC by its own name. Player: your own kills by profile. Titles: a rule on a profile's kills picks the profile. npcs.test.js covers the profile checks, adoption, the push, the picker and verb, the triggers, kill crediting, titles and placements (481 server tests). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
This commit is contained in:
@@ -47,7 +47,8 @@ async function ownNpcKills(req, res) {
|
||||
for (const serverId of new Set(rows.map((r) => r.serverId))) {
|
||||
for (const p of await npcs.boardProfiles(serverId)) labels.set(`${serverId} ${p.name}`, p.label)
|
||||
}
|
||||
res.json({ kills: rows.map((r) => ({ ...r, label: labels.get(`${r.serverId} ${r.profile}`) || r.profile })) })
|
||||
const names = new Map((await servers.listPublic()).map((srv) => [srv.id, srv.name || srv.id]))
|
||||
res.json({ kills: rows.map((r) => ({ ...r, server: names.get(r.serverId) || r.serverId, label: labels.get(`${r.serverId} ${r.profile}`) || r.profile })) })
|
||||
} catch (err) {
|
||||
log.error('failed to read a player’s NPC kills', { error: err.message })
|
||||
res.status(500).json({ message: 'Failed to read your NPC kills' })
|
||||
|
||||
Reference in New Issue
Block a user