OPX//77
opx_infinitygunsmith

gunsmith

Last updated on

Armouries made of a crafting bench, a stash chest and a job gate, all declared in one config file.

Each config entry becomes an armoury: a workbench where players craft ammunition, weapons or tools, and a chest (a shared stash) beside it, both as rows on the target eye. An armoury can be public or limited to jobs, a minimum grade and on-duty status; each recipe can ask for a higher grade. The bench is run by crafting, the chest by inventory. Gives a job or a district its own armoury without code.

Sideboth
Requirescrafting, character (hard)
Optionalinventory (the chest), target (the bench and chest rows)
Contractnone
Configconfig/gunsmith.lua (shared)
Datanone of its own. Orders in opx77_crafting_orders; chests are stash rows in opx77_inventories.

The shipped armoury positions in config/gunsmith.lua are placeholders and have not been surveyed. A bench more than REACH metres from where players stand can never be used, and nothing reports it. Set real positions before going live.

How an armoury works

  • At start one crafting bench is registered per armoury, keyed gunsmith:<armouryKey>, owner = 'gunsmith'. Recipes use the crafting recipe fields plus GRADE.
  • The bench gate reads the character's job from the character contract. A gated armoury refuses when the job record is older than JOB_MAX_AGE_MS. An armoury with no JOBS is open to everyone, and GRADE is then ignored.
  • A recipe's GRADE is a minimum on top of the armoury's own JOBS grades.
  • The chest opens through the inventory OpenStash contract with the chest's position, so inventory checks reach with its own REACH.DISTANCE. Same job gate as the bench (without recipe grades). Opening it is audited (gunsmith.chest).
  • Without inventory, benches work and no chest opens. Without crafting, no armoury has a bench.

Configuration

config/gunsmith.lua sets OPX.Config.MODULES.gunsmith. Shared script (the client draws the target spheres).

KeyDefaultEffect
enabledtruefalse switches the module off.
MEMBERSHIP'primary''primary': only the job being worked counts. 'any': every job the character holds counts for the grade, but never for ON_DUTY.
JOB_MAX_AGE_MS60000Oldest job record a gated armoury accepts.
REACH2.5Bench reach in metres, checked by crafting on the server.
PROMPT_RADIUS2.5Radius of the bench and chest target spheres.
ARMOURIESarasaka_armoury, ncpd_watson_armoury, kabuki_workshopThe armouries, keyed by slug. See below.

An armoury entry

FieldEffect
LABELBench menu title. Defaults to the key.
JOBS{ job = minimumGrade }. Absent or empty = public.
ON_DUTYtrue = the job must be the one worked, on duty.
BENCH{ X, Y, Z, BUCKET? }. Without a valid position the armoury has no bench.
CHEST{ NAME, LABEL?, SLOTS? (50), MAX_WEIGHT? (100000), X, Y, Z, BUCKET? (0) }. NAME is the stash key: letters, digits, _, -, ., up to 48. Never rename it: a new name is an empty chest.
QUEUEOrders per character on this bench (crafting caps it at its MAX_QUEUE).
RECIPESList of crafting recipes, each with an optional GRADE (0–255).

Refusal codes

Chest refusals use gunsmith.<code>. Bench gate refusals use crafting.<code>; this module adds those four keys to the locales.

CodeWhereMeaning
job_requiredchest, benchThe character does not hold a listed job.
grade_too_lowchest, benchGrade below the armoury's or the recipe's minimum.
off_dutychest, benchON_DUTY is set and the character is off duty.
job_stalechest, benchThe job record is older than JOB_MAX_AGE_MS.
no_characterchest, benchNo character loaded (gated armouries only).
no_such_chestchestUnknown armoury, or it has no chest. A refusal names back the chest key only when it names a known chest.
deadchestThe player is down (Not while you are down.).
not_for_youchestGate refused with no code.
unavailablechestNo inventory contract, or an inventory code with no gunsmith.* text (for example a failed load). The real code goes to the log.
too_far, not_ready, not_loaded, bad_argumentchestPassed through from inventory OpenStash.

The chest accepts one open request per 750 ms per player.

On this page