refactor(rust): one placing verb per kind — rust.crate.place and rust.npc.place (D97)
Core learns which caps an action accepts by pricing its declared examples once, and drops a dimension priced at zero. A single rust.prefab.place whose cost moved between rust.prefabs and rust.npcs by its prefab param could only ever show the crates cap, so D89's separate dial for fights was unreachable. Two verbs, each pricing exactly one dimension, with the prefab source split to match (rust.options.crates / rust.options.npcs). The switchboard can now allow crates and leave NPCs off. The plugin's world.place is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
This commit is contained in:
@@ -129,7 +129,7 @@ test('a dry run checks everything it can and sends nothing', async (t) => {
|
||||
const zone = await action('rust.zone.open').perform({
|
||||
runId: 7, idempotencyKey: 'k1', verify: true, params: { monument: 'main/airfield_1', radius: 40, minutes: 60 },
|
||||
})
|
||||
const place = await action('rust.prefab.place').perform({
|
||||
const place = await action('rust.crate.place').perform({
|
||||
runId: 7, idempotencyKey: 'k2', verify: true, params: { monument: 'main/airfield_1', prefab: 'crate.elite', count: 3 },
|
||||
})
|
||||
assert.deepStrictEqual([zone, place], [{ ok: true }, { ok: true }])
|
||||
@@ -138,15 +138,18 @@ test('a dry run checks everything it can and sends nothing', async (t) => {
|
||||
|
||||
test('every authoring mistake is refused for good, before anything is sent', async (t) => {
|
||||
const calls = stub(t)
|
||||
const place = action('rust.prefab.place')
|
||||
const crates = action('rust.crate.place')
|
||||
const npcs = action('rust.npc.place')
|
||||
const zone = action('rust.zone.open')
|
||||
const run = (a, params) => a.perform({ runId: 7, idempotencyKey: 'k', params })
|
||||
|
||||
for (const result of [
|
||||
await run(place, { monument: 'main/a', prefab: 'minicopter', count: 1 }),
|
||||
await run(place, { monument: 'main/a', prefab: 'crate.elite', count: 26 }),
|
||||
await run(place, { monument: 'main/a', prefab: 'npc.scientist', count: 21 }),
|
||||
await run(place, { monument: 'main/a', prefab: 'crate.elite', count: 1, spread: 51 }),
|
||||
await run(crates, { monument: 'main/a', prefab: 'minicopter', count: 1 }),
|
||||
await run(crates, { monument: 'main/a', prefab: 'npc.scientist', count: 1 }), // D97: the other verb's
|
||||
await run(npcs, { monument: 'main/a', prefab: 'crate.elite', count: 1 }),
|
||||
await run(crates, { monument: 'main/a', prefab: 'crate.elite', count: 26 }),
|
||||
await run(npcs, { monument: 'main/a', prefab: 'npc.scientist', count: 21 }),
|
||||
await run(crates, { monument: 'main/a', prefab: 'crate.elite', count: 1, spread: 51 }),
|
||||
await run(zone, { monument: 'main/a', radius: 4, minutes: 10 }),
|
||||
await run(zone, { monument: 'main/a', radius: 40 }), // D96: minutes are required
|
||||
await run(zone, { monument: 'main/a', radius: 40, minutes: 7 * 24 * 60 + 1 }),
|
||||
@@ -182,7 +185,7 @@ test('one resource per thing placed, and a repeated key is said to be one', asyn
|
||||
data: { kind: 'world.ok', repeat: true, placed: [{ id: '101', kind: 'npc', prefab: 'npc.scientist' }] },
|
||||
}),
|
||||
})
|
||||
const result = await action('rust.prefab.place').perform({
|
||||
const result = await action('rust.npc.place').perform({
|
||||
runId: 7, idempotencyKey: 'k', params: { x: -604, z: -342, server: 'main', prefab: 'npc.scientist', count: 1 },
|
||||
})
|
||||
assert.strictEqual(result.ok, true)
|
||||
@@ -194,7 +197,7 @@ test('the switch being off is a refusal with the switch named, for good (D94)',
|
||||
stub(t, {
|
||||
place: async () => ({ ok: true, data: { kind: 'world.error', reason: 'events-disabled', message: 'set EventsEnabled' } }),
|
||||
})
|
||||
const result = await action('rust.prefab.place').perform({
|
||||
const result = await action('rust.crate.place').perform({
|
||||
runId: 7, idempotencyKey: 'k', params: { monument: 'main/a', prefab: 'crate.elite', count: 1 },
|
||||
})
|
||||
assert.deepStrictEqual(result, { ok: false, retry: false, error: 'set EventsEnabled' })
|
||||
@@ -202,7 +205,7 @@ test('the switch being off is a refusal with the switch named, for good (D94)',
|
||||
|
||||
test('a game that is down or slow is left to core to retry', async (t) => {
|
||||
stub(t, { place: async () => ({ ok: false, status: 'http-503' }) })
|
||||
const result = await action('rust.prefab.place').perform({
|
||||
const result = await action('rust.crate.place').perform({
|
||||
runId: 7, idempotencyKey: 'k', params: { monument: 'main/a', prefab: 'crate.elite', count: 1 },
|
||||
})
|
||||
assert.strictEqual(result.ok, false)
|
||||
@@ -296,10 +299,13 @@ test('the monument source lists each server\'s map as whole values, numbered whe
|
||||
assert.deepStrictEqual(narrowed.map((r) => r.value), ['main/powerplant_1'])
|
||||
})
|
||||
|
||||
test('the prefab source answers with every server off', async (t) => {
|
||||
test('the crate and NPC sources split the allowlist, and answer with every server off (D97)', async (t) => {
|
||||
const calls = stub(t)
|
||||
const rows = await source('rust.options.prefabs').resolve()
|
||||
assert.strictEqual(rows.length, world.PLACEABLE.length)
|
||||
const crates = await source('rust.options.crates').resolve()
|
||||
const npcs = await source('rust.options.npcs').resolve()
|
||||
assert.strictEqual(crates.length + npcs.length, world.PLACEABLE.length)
|
||||
assert.ok(crates.every((r) => !r.value.startsWith('npc.')))
|
||||
assert.ok(npcs.every((r) => r.value.startsWith('npc.')))
|
||||
assert.deepStrictEqual(calls.monuments, [])
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user