feat(rust): RunicNPC is required for every Place NPCs step (runicnpc stage 9, D310)
A Place NPCs step on a server without RunicNPC, or with one older than the
bridge needs, is refused before it is sent: "<server> needs RunicNPC to place
NPCs, Rust's own scientists included: <why>". Rust's own scientists were the
fallback until now (D243); they need RunicNPC too. Crates are unaffected.
- npcs.model: API_NEEDED rises from 4 to 6, the bridge's RunicNpcApiNeeded, so a
server the site calls ready is one the bridge will not refuse as runicnpc-old.
The profile push follows the same floor.
- eventWorld: profileMissing becomes npcMissing, asked for every NPC step.
- Admin → Rust → Servers: each server carries `runicNpc` ({ready, absence,
version, api}) and a server without one that will do reads "Incomplete" with
the reason. Swagger documents the field.
The event picker is unchanged in this commit (an open question on the PR).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
This commit is contained in:
@@ -116,7 +116,8 @@ const PERMANENT = new Set([
|
||||
// and a dome asked of a server without ZoneDomes or the domes helper.
|
||||
'bad-option',
|
||||
'dome-unavailable',
|
||||
// runicnpc stage 4 (D243): a profile the server does not have, or no RunicNPC.
|
||||
// runicnpc stage 4 (D243): a profile the server does not have, or no RunicNPC
|
||||
// (since stage 9, D310, for every NPC step, Rust's own scientists included).
|
||||
'unknown-profile',
|
||||
'runicnpc-missing',
|
||||
// runicnpc stage 5 (D272): no zone of the run holds the point; a RunicNPC
|
||||
@@ -538,8 +539,9 @@ function placeVerb({ id, kind, budget, max, label, description, source, example
|
||||
const found = await serverFor(where.serverId)
|
||||
if (!found.ok) return found
|
||||
|
||||
if (profile !== null) {
|
||||
const missing = await profileMissing(found.server, profile)
|
||||
// D310: every NPC needs RunicNPC on the server, Rust's own scientists included.
|
||||
if (kind === 'npc') {
|
||||
const missing = await npcMissing(found.server, profile)
|
||||
if (missing) return { ok: false, retry: false, error: missing }
|
||||
}
|
||||
|
||||
@@ -651,16 +653,19 @@ function npcOrders(params, server) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Why a profile cannot be placed on this server, from what the site knows, or
|
||||
* null (D243). A server without RunicNPC offers only Rust's own until stage 9;
|
||||
* a profile the site does not push there is not on it. What the server itself
|
||||
* holds is the plugin's to answer (`unknown-profile`).
|
||||
* Why NPCs cannot be placed on this server, from what the site knows, or null.
|
||||
* Since runicnpc stage 9 (D310) that is every Place NPCs step on a server
|
||||
* without RunicNPC, or with one older than the bridge needs, Rust's own
|
||||
* scientists included: the bridge refuses them the same way. `profile` is null
|
||||
* for one of Rust's own; a profile the site does not push there is not on it.
|
||||
* What the server itself holds is the plugin's to answer (`unknown-profile`).
|
||||
*/
|
||||
async function profileMissing(server, profile) {
|
||||
const [list, profiles] = await Promise.all([npcsDb.listNpcServers(), npcsDb.listProfiles()])
|
||||
async function npcMissing(server, profile) {
|
||||
const [list, profiles] = await Promise.all([npcsDb.listNpcServers(), profile === null ? [] : npcsDb.listProfiles()])
|
||||
const here = list.find((s) => s.id === server.id)
|
||||
const name = server.name || server.id
|
||||
if (!npcs.npcReady(here)) return `${name} cannot place the profile "${profile}": ${npcs.npcAbsence(here)}. Pick one of the server's own scientists.`
|
||||
if (!npcs.npcReady(here)) return `${name} needs RunicNPC to place NPCs, Rust's own scientists included: ${npcs.npcAbsence(here)}`
|
||||
if (profile === null) return null
|
||||
if (!profiles.some((p) => !p.replaced && p.name === profile && npcs.covers(p, server.id))) {
|
||||
return `the site has no NPC profile "${profile}" for ${name} (Admin → Rust NPC profiles)`
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user