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:
@@ -34,6 +34,15 @@ export function toLatLng(g, x, z) {
|
||||
return [(Number(z) + half) * s + m, (Number(x) + half) * s + m]
|
||||
}
|
||||
|
||||
/** The inverse of `toLatLng`: a point on the picture as world `{ x, z }` in metres (a click on the map). */
|
||||
export function fromLatLng(g, lat, lng) {
|
||||
const s = scaleOf(g)
|
||||
if (!(s > 0)) return null
|
||||
const half = g.worldSize / 2
|
||||
const m = g.oceanMargin || 0
|
||||
return { x: (Number(lng) - m) / s - half, z: (Number(lat) - m) / s - half }
|
||||
}
|
||||
|
||||
/** The picture's bounds in the same space. */
|
||||
export function boundsOf(g) {
|
||||
return [[0, 0], [g.height, g.width]]
|
||||
|
||||
Reference in New Issue
Block a user