feat(rust): bosses and passive NPCs on the profile form, and public boss triggers (runicnpc stage 6)
The profile form's boss box (D273-D277): the bar's distance, where its lines are said, the spawn and death lines, and phases at health percentages, each with optional damage, aim, speed, ranges, a kit swap, adds of another profile and a line. The passive role (D278, D279, D288): press E answers with a chat line or a window, it moves as its profile says (now including `stand`), and it starts unhurtable. The site checks both as RunicNPC does, in its words; a phase's kit is checked on each server like the profile's own, and its adds must name a site profile that is not a boss. Public triggers rust.boss.spawned, rust.boss.phase and rust.boss.killed (D277) from the bridge's new frames. In the feed, a boss appearing is public; its death names the killer, so it sits behind the presence setting; its phases are staff's, as the game tells them only to players near it (D286). engagement-triggers.json regenerated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
This commit is contained in:
@@ -145,6 +145,11 @@ test('the classification covers exactly the event kinds the protocol defines, th
|
||||
'npc.placement.changed',
|
||||
'plugin.loaded',
|
||||
'plugin.unloaded',
|
||||
// Protocol 13, RunicNPC (runicnpc stage 6): a boss's spawn and death are said to
|
||||
// the whole server and are public; its phases are told only to players near it.
|
||||
'npc.boss.spawned',
|
||||
'npc.boss.phase',
|
||||
'npc.boss.died',
|
||||
]
|
||||
|
||||
assert.deepEqual([...catalogue.ALL_KINDS].sort(), [...PROTOCOL_4].sort())
|
||||
@@ -154,9 +159,12 @@ test('the classification covers exactly the event kinds the protocol defines, th
|
||||
}
|
||||
|
||||
assert.equal(catalogue.isPublic('config.outcome'), false, 'a server’s log tail must not be public')
|
||||
for (const kind of ['plugin.loaded', 'plugin.unloaded', 'lease.expired', 'world.expired']) {
|
||||
for (const kind of ['plugin.loaded', 'plugin.unloaded', 'lease.expired', 'world.expired', 'npc.boss.phase']) {
|
||||
assert.equal(catalogue.isPublic(kind), false, `${kind} is staff-only`)
|
||||
}
|
||||
for (const kind of ['npc.boss.spawned', 'npc.boss.died']) {
|
||||
assert.equal(catalogue.isPublic(kind), true, `${kind} is said to the whole server, so it is public (D286)`)
|
||||
}
|
||||
})
|
||||
|
||||
test('every kind that names a player who was on is behind the presence setting', () => {
|
||||
@@ -169,6 +177,7 @@ test('every kind that names a player who was on is behind the presence setting',
|
||||
'player.death',
|
||||
'player.chat',
|
||||
'player.tally',
|
||||
'npc.boss.died',
|
||||
]) {
|
||||
assert.ok(catalogue.isPresence(kind), `${kind} must be gated as presence`)
|
||||
assert.ok(!catalogue.kindsFor({}).includes(kind), `${kind} must not reach a default public view`)
|
||||
@@ -179,5 +188,5 @@ test('every kind that names a player who was on is behind the presence setting',
|
||||
for (const kind of catalogue.PRESENCE_KINDS) assert.ok(catalogue.PUBLIC_KINDS.includes(kind))
|
||||
|
||||
// And what is left names nobody.
|
||||
assert.deepEqual(catalogue.kindsFor({}).sort(), ['server.initialized', 'server.shutdown', 'server.wipe'])
|
||||
assert.deepEqual(catalogue.kindsFor({}).sort(), ['npc.boss.spawned', 'server.initialized', 'server.shutdown', 'server.wipe'])
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user