====== Script Law — Items ====== Item-shell scripting detail for new creators. This page assumes you can already create and attach an item SpecProc ([[immortal:scriptlaw:objects|Script objects]]) and that the object prototype exists ([[immortal:creationlaw:objects|Objects]]). If you only remember one teaching point: **many "item quests" are really mobile scripts** that inspect ''var.item''. Put behavior on the entity whose event actually fires. This page documents what you can do when the **item** proc runs, and the item-side primitives mobile scripts call. Hub: [[immortal:scriptlaw|Script Law]]. ===== Attach reminder (then come back here) ===== > @proc item new my_sword_proc Okay. > @proc item script my_sword_proc (paste Beanshell that branches on var.STATE; end with return false;) > @load item 3100 > @item proc my_sword_proc > @examine item > @save item > create item 3100 > Full attach pedagogy: [[immortal:scriptlaw:objects|Script objects]]. ===== What ''var'' looks like for items ===== Item procs receive an ''ItemEvent.Var''. Fields you will read or branch on: * ''STATE'', ''state'' — trigger kind and a free mutable script state integer * ''item'' — the SpecProc owner shell (''ItemScript'' / item shell) * ''mobile'', ''room'', ''victim'', ''victims'', ''items'' — context when the event provides them * ''command'', ''args'' — when interpreter / post-interpreter hooks fire * Scratch aliases such as ''m'', ''it'', ''rm'', ''s'', ''n'' where the Var exposes them Always branch on ''var.STATE'' (or named constants like ''var.STATE_POST_INTERPRETER''). Return ''false'' unless you mean to block the triggering command. Why branching matters: the same script text can be invoked for different STATEs. A stub that only chatters on ''STATE_SCRIPT'' will look "broken" if you were testing a give/drop path that never hits that STATE. ===== Item shell APIs (proven patterns) ===== Scripts call methods on shells rather than inventing verbs. From code and live world usage, item shells expose (illustrative — **not** an exhaustive javadoc dump): * Type tests: ''isWeapon'', ''isKey'', and related ''is…'' helpers present on ''ItemShell'' * ''purge()'' — remove this item instance * ''vid()'' — prototype / instance identity checks in quest scripts * ''createMobile'' / fill helpers — where the shell provides them * Other echo / container helpers that appear on the script subclass in real procs Every eval also binds ''util'': ''roll'', ''chance'', ''limit'', ''max'', ''min'', ''getPosInt'', ''tokenizerNoFill'', … **Rule for new creators:** before you invent a call, run ''@proc item examine '' or ''index proc_item'' and copy a pattern that already works. Only methods on ''ItemShell'' / script subclasses are legal. Fabricating ''var.item.doSomethingCool()'' will fail at eval time. ===== Pattern: type guard ===== Use when ambient item logic should only run for weapons (or keys, …): if (var.STATE == var.STATE_SCRIPT) { if (var.item.isWeapon()) { // weapon-only flavor — keep it cheap } } return false; If an ''is…'' method is missing at eval time, you invented it — examine a live proc or shell source; do not guess. ===== Pattern: identity + purge (usually from a **mobile** proc) ===== Quest turn-ins typically live on the mobile (see ''thanksgiving'' on [[immortal:scriptlaw:mobiles|Script mobiles]]). The item-side primitives those scripts rely on: * ''var.item.vid()'' — compare to the quest prototype VID you built in Creation * ''var.item.purge()'' — consume the turned-in instance * mobile ''createItem'' (or equivalent shell helper) — grant the reward Teaching checklist when something "eats the give" wrong: - [ ] You are testing the VID you think you are (''stat item'', Creation notes) - [ ] The **mobile** has the proc attached, not only the item - [ ] You return ''true'' only when you intend to consume/block the give - [ ] Between tests you ''purge'' leftover rewards and re-''create'' the quest item ===== Pattern: when to put logic on the item vs the mobile ===== * **Mobile proc** — reactions to ''give'', ''say'', ''sayto'', socials, combat involving the NPC * **Item proc** — behavior that must run because **this object** is pulsing / interpreting, independent of a particular NPC * If you attached only ''@item proc'' and expected a shopkeeper to thank you for a give, move the quest logic to ''@npc proc'' ===== Editing and re-test loop ===== > @proc item script my_sword_proc (revise Beanshell, finish writer) > purge sword > create item 3100 (exercise the trigger again) > If a zone loads the object, ''@save'' the script then ''zone reset'' so you are not staring at an old mental model of "stale instances." Script text lives on the SpecProc row; the prototype must still ''@item proc'' that name. ===== Safety ===== * Immortal / creator only * Eval errors: Beanshell ''EvalError'' caught; when the proc name matches a player, that player may receive the error text * Laggy scripts (> ''Eventable.MAX_LAG_TIME'') are logged * Shared static Interpreter on ''SpecProc'' — leave no leftover globals; runtime unsets ''var'' / ''util'' after each eval * ''@proc item delete'' only after prototypes stop naming the proc ===== Common mistakes ===== * Inventing shell methods * Expecting item procs to see every ''give'' (that is usually the mobile) * Forgetting ''return false;'' * Editing script text but testing an old instance without purge/reset * Attaching a proc name that ''index proc_item'' cannot find ===== Related ===== * [[immortal:scriptlaw:objects|Script objects]] — attach workflow * [[immortal:creationlaw:items|Creation items]] — types/flags/spawn * [[immortal:scriptlaw:mobiles|Script mobiles]] — give/quest patterns that read items * [[immortal:scriptlaw|Script Law]] — hub