feat: API 3, placements from a website (stage 4, D249)

RunicNpc_AddPlacement creates a placement and names it as /rnpc place
does (D241, D246). A position without y is a map point: it is put on the
ground there (terrain and rock, never a building or a tree, D245), then
checked against the navmesh like an in-game placement. It answers the id,
the grounded position, whether the spot is player-built, and the cost
warning, or the in-game refusal sentence.

RunicNpc_RenamePlacement and RunicNpc_RespawnPlacement do what rnpc
rename and rnpc respawn do. OnRunicNpcPlacementChanged(id, change,
previous) is raised on every set, remove and rename, from the API or in
game, so the bridge can tell the site at once.

rnpc place and here now share CreatePlacement with the API, so both give
the same refusals. The test harness gains an api3 group; all 157 checks
pass on the Oxide and Carbon rigs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
This commit is contained in:
2026-09-30 04:01:30 -05:00
parent 9c366ab5b5
commit fe20ca41af
4 changed files with 264 additions and 44 deletions

View File

@@ -23,8 +23,10 @@
# lets a bundle check the pair BEFORE an operator installs it.
#
# 1 was stage 0's: `RunicNpc_ApiVersion()` and nothing else.
# Current: 2 — stage 2's whole API, PLAN.md §4, documented in docs/runicnpc/API.md.
api = 2
# 2 was stage 2's whole API, PLAN.md §4.
# Current: 3 — stage 4 (D249): RunicNpc_AddPlacement, _RenamePlacement, _RespawnPlacement and the
# OnRunicNpcPlacementChanged hook, documented in docs/runicnpc/API.md.
api = 3
# ── Framework floors ─────────────────────────────────────────────────────────
#