fix(feed): print weapons by name, not "ak47u entity"
The bridge names a kill's weapon by the held entity's short prefab name (ak47u.entity), and the feed printed it with the dots turned to spaces: "with ak47u entity". Every event read now gives the frame a weaponName (server/model/titles/weaponNames.js): the game's own English name for the 53 ranged weapons (guns, bows, crossbows, launchers, flamethrowers), read off the Oxide rig's item list on Rust 26139947, and for anything else the prefab name as words with its .entity/.weapon ending dropped. The site prints weaponName and falls back to the same stripping for an older server. The prefab name stays in the frame: the title lists count by it. Added at read, so stored rows are renamed too. No protocol change; the events route's Swagger description names the new field. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
This commit is contained in:
@@ -21,7 +21,7 @@
|
||||
// here is presentation, and the honest presentation of a kind we have no words
|
||||
// for is its own name.
|
||||
|
||||
import { attacker, duration, prefab } from './format.js'
|
||||
import { attacker, duration, weapon } from './format.js'
|
||||
|
||||
/**
|
||||
* Kinds this feed asks for.
|
||||
@@ -205,7 +205,7 @@ export function describe(row) {
|
||||
*/
|
||||
function death(frame, name) {
|
||||
const where = [
|
||||
frame.weapon ? `with ${prefab(frame.weapon)}` : null,
|
||||
frame.weapon ? `with ${weapon(frame)}` : null,
|
||||
frame.distance ? `${Math.round(frame.distance)}m` : null,
|
||||
frame.grid || null,
|
||||
frame.sleeping ? 'while sleeping' : null,
|
||||
|
||||
@@ -130,6 +130,18 @@ export function prefab(name) {
|
||||
return String(name).replace(/[_.]+/g, ' ').trim()
|
||||
}
|
||||
|
||||
/**
|
||||
* The weapon in a kill. The server sends `weaponName` — the game's own name for
|
||||
* a gun, or the prefab name as words (`server/model/titles/weaponNames.js`) —
|
||||
* and that is what prints. A server too old to send it gets the same fallback
|
||||
* here: the `.entity` / `.weapon` ending dropped, so never "ak47u entity".
|
||||
*/
|
||||
export function weapon(frame) {
|
||||
if (!frame || !frame.weapon) return ''
|
||||
if (frame.weaponName) return String(frame.weaponName)
|
||||
return prefab(String(frame.weapon).trim().replace(/[._](entity|weapon|deployed)$/, ''))
|
||||
}
|
||||
|
||||
/**
|
||||
* The NPC families whose prefab reads badly as words, by the prefix the game's
|
||||
* short names share. First match wins, so a longer prefix sits above a shorter
|
||||
|
||||
@@ -338,3 +338,18 @@ test('a purchase and an admin lock name the player only when the server sent the
|
||||
assert.equal(describe(raid('raid.locked', { difficulty: 'Wobbly' })).verb, 'A Wobbly raid base was locked to a player')
|
||||
assert.equal(describe(raid('raid.ended', { difficulty: 'Wobbly' })).verb, 'A Wobbly raid base despawned')
|
||||
})
|
||||
|
||||
test('a kill line says the weapon by name', () => {
|
||||
const named = describe(row('player.death', {
|
||||
name: 'Bob', attackerType: 'player', attackerName: 'Alice',
|
||||
weapon: 'ak47u.entity', weaponName: 'Assault Rifle', distance: 22,
|
||||
}))
|
||||
assert.match(named.detail, /with Assault Rifle/)
|
||||
assert.doesNotMatch(named.detail, /entity/)
|
||||
|
||||
const older = describe(row('player.death', {
|
||||
name: 'Bob', attackerType: 'player', attackerName: 'Alice', weapon: 'bolt_rifle.entity',
|
||||
}))
|
||||
assert.match(older.detail, /with bolt rifle/)
|
||||
assert.doesNotMatch(older.detail, /entity/)
|
||||
})
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
import test from 'node:test'
|
||||
import assert from 'node:assert/strict'
|
||||
|
||||
import { ago, attacker, clock, coins, contrastInk, count, day, duration, nextWipe, prefab, shortId } from '../src/lib/format.js'
|
||||
import { ago, attacker, clock, coins, contrastInk, count, day, duration, nextWipe, prefab, shortId, weapon } from '../src/lib/format.js'
|
||||
|
||||
const NOW = Date.parse('2026-09-16T12:00:00Z')
|
||||
|
||||
@@ -147,3 +147,15 @@ test('an NPC attacker reads as a name: a family, or the prefab without its varia
|
||||
test('a weapon keeps the light touch — attacker() is for what did the killing', () => {
|
||||
assert.equal(prefab('rifle.ak'), 'rifle ak')
|
||||
})
|
||||
|
||||
test('a kill prints the weapon the server named, and never an entity ending', () => {
|
||||
// weaponName is the server's (model/titles/weaponNames.js): the game's own name for a gun.
|
||||
assert.equal(weapon({ weapon: 'ak47u.entity', weaponName: 'Assault Rifle' }), 'Assault Rifle')
|
||||
// A server too old to send it: the ending dropped, the rest as words.
|
||||
assert.equal(weapon({ weapon: 'ak47u.entity' }), 'ak47u')
|
||||
assert.equal(weapon({ weapon: 'bolt_rifle.entity' }), 'bolt rifle')
|
||||
assert.equal(weapon({ weapon: 'machete.weapon' }), 'machete')
|
||||
assert.equal(weapon({ weapon: 'rifle.ak' }), 'rifle ak')
|
||||
assert.equal(weapon({}), '')
|
||||
assert.equal(weapon(null), '')
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user