Module: Lich::DragonRealms::DRCI

Defined in:
documented/dragonrealms/commons/common-items.rb

Overview

DragonRealms Common Items module.

Low-level, stateless methods for interacting with items in the game world: getting, putting, wearing, removing, counting, searching, and querying hand contents. All methods in this module operate independently of game state beyond what the method itself queries or mutates.

Constant Summary collapse

TRASH_STORAGE =

How to add new trash receptacles https://github.com/elanthia-online/dr-scripts/wiki/Adding-new-trash-receptacles Default trash-receptacle nouns. Players extend this at runtime via the custom_trash_storage setting; see trash_storage and CustomSubstitutions.

%w[arms barrel basin basket bin birdbath bucket chamberpot gloop hole log puddle statue stump tangle tree turtle urn gelapod].freeze
DROP_TRASH_SUCCESS_PATTERNS =

Patterns that match successful item disposal via drop/put commands.

Used by #dispose_trash to recognize when an item has been successfully dropped or placed in a trash receptacle.

Examples:

Matches

"You drop the rock."
"You put the rock in the trash."
"As you open your hand to release the moonblade, it crumbles away."

See Also:

[
  /^You drop/,
  /^You put/,
  /^You spread .* on the ground/,
  /smashing it to bits/,
  # The next message is when item crumbles when leaves your hand, like a moonblade.
  /^As you open your hand to release the/,
  /^You toss .* at the domesticated gelapod/,
  /^You feed .* a bit warily to the domesticated gelapod/
].freeze
DROP_TRASH_FAILURE_PATTERNS =

Patterns that match failed item disposal attempts.

Used by #dispose_trash to recognize when an item cannot be disposed, usually due to game restrictions (cursed items, loitering rules, full containers).

Examples:

Matches

"What were you referring to?"
"No littering in the bank."
"You can't put that there."

See Also:

[
  /^What were you referring to/,
  /^I could not find/,
  /^But you aren't holding that/,
  /^Perhaps you should be holding that first/,
  /^You're kidding, right/,
  /^You can't do that/,
  /No littering/, # A guard steps over to you and says, "No littering in the bank."
  /^Where do you want to put that/,
  /^You really shouldn't be loitering/,
  /^You don't seem to be able to move/,
  # You may get the next message if you've been cursed and unable to let go of items.
  # Find a Cleric to uncurse you.
  /^Oddly, when you attempt to stash it away safely/,
  /^You need something in your right hand/,
  /^You can't put that there/,
  /^The domesticated gelapod glances warily at/, # deeds
  /^You should empty it out, first./ # container with items
].freeze
DROP_TRASH_RETRY_PATTERNS =

Messages that when trying to drop an item you're warned. To continue you must retry the command.

[
  # You may get the next message if the item would be damaged upon dropping.
  /^If you still wish to drop it/,
  /would damage it/,
  # You may get the next messages when an outdated item is updated upon use.
  # "Something appears different about the <item>, perhaps try doing that again."
  # Example: https://elanthipedia.play.net/Item:Leather_lotion
  /^Something appears different about/,
  /perhaps try doing that again/
].freeze
WORN_TRASHCAN_VERB_PATTERNS =

Patterns that match activation of worn trash-disposal containers.

Used by #dispose_trash when a worn_trashcan_verb (e.g., "tap", "drum") is executed to empty the container after item disposal.

Examples:

Matches

"You drum your fingers on the shroud."
"You pull a lever on the refuse bin."

See Also:

  • #dispose_trash
[
  /^You drum your fingers/,
  /^You pull a lever/,
  /^You poke your finger around/
].freeze
GET_ITEM_SUCCESS_PATTERNS =

Patterns that match successful item retrieval via GET command.

Used by #get_item_unsafe to verify that an item was successfully picked up and placed in the character's hands.

Examples:

Matches

"You get the sword."
"You pick up the shield."
"You are already holding the dagger."
"With a flick of your wrist, you stealthily unsheath the blade."

See Also:

[
  /you draw (?!\w+'s wounds)/i,
  /^You get/,
  /^You pick/,
  /^You pluck/,
  /^You slip/,
  /^You scoop/,
  /^You deftly remove/,
  /^You are already holding/,
  /^You fade in for a moment as you/,
  /^You carefully lift/,
  /^You carefully remove .* from the bundle/,
  /^With a flick of your wrist, you stealthily unsheath/
].freeze
GET_ITEM_FAILURE_PATTERNS =

Patterns that match failed item retrieval attempts.

Used by #get_item_unsafe to recognize when an item cannot be retrieved, usually due to game restrictions (hands full, injured limbs, item decay).

Examples:

Matches

"You need both hands free to do that."
"You can't reach that from here."
"The leather jacket rapidly decays away."

See Also:

[
  /^A magical force keeps you from grasping/,
  /^You'll need both hands free/,
  /^You need both hands free/,
  /^You need a free hand/,
  /^You can't pick that up with your hand that damaged/,
  /^Your (left|right) hand is too injured/,
  /^You just can't/,
  /^You stop as you realize the .* is not yours/,
  /^You can't reach that from here/, # on a mount like a flying carpet
  /^You don't seem to be able to move/,
  /^You should untie/,
  /^You can't do that/,
  /^Get what/,
  /^I could not/,
  /^What were you/,
  /already in your inventory/, # wearing it
  /needs to be tended to be removed/, # ammo lodged in you
  /push you over the item limit/, # you're at item capacity
  /rapidly decays away/, # item disappears when try to get it
  /cracks and rots away/, # item disappears when try to get it
  /^You should stop practicing your Athletics skill before you do that/
].freeze
WEAR_ITEM_SUCCESS_PATTERNS =

Patterns that match successful item wearing via WEAR command.

Matches diverse equipping verbs (put, strap, sling, slip, etc.) used by different item types and armor pieces.

Examples:

Matches

"You put on the cloak."
"You strap the shield to your arm."
"You are already wearing the ring."

See Also:

[
  /^You put/,
  /^You pull/,
  /^You sling/,
  /^You attach/,
  /^You strap/,
  /^You slide/,
  /^You spin/,
  /^You slip/,
  /^You place/,
  /^You hang/,
  /^You tug/,
  /^You struggle/,
  /^You squeeze/,
  /^You manage/,
  /^You gently place/,
  /^You toss one strap/,
  /^You carefully loop/,
  /^You work your way into/,
  /^You are already wearing/,
  /^Gritting your teeth, you grip/,
  /^You expertly sling the/,
  /put it on/, # weird clerical collar thing, trying to make it a bit generic
  /slide effortlessly onto your/,
  /^You carefully arrange/,
  /^A brisk chill rushes through you as you wear/, # some hiro bearskin gloves interlaced with strips of ice-veined leather
  /^You drape/,
  /You lean over and slip your feet into the boots./, # a pair of weathered barkcloth boots lined in flannel,
  /^You reach down and step into/, # pair of enaada boots clasped by asharsh'dai
  /Gritting your teeth/ # Gritting your teeth, you grip each of your heavy combat boots in turn by the straps, and drive your feet into them for a secure fit.
].freeze
WEAR_ITEM_FAILURE_PATTERNS =

Patterns that match failed item wearing attempts.

Used by #wear_item_unsafe? to recognize when an item cannot be equipped, usually due to game restrictions (incompatible items, unloaded weapons).

Examples:

Matches

"You can't wear that."
"Wear what?"

See Also:

[
  /^You can't wear/,
  /^You (need to|should) unload/,
  /close the fan/,
  /^You don't seem to be able to move/,
  /^Wear what/,
  /^I could not/,
  /^What were you/
].freeze
TIE_ITEM_SUCCESS_PATTERNS =

Patterns that match successful item tying via TIE command.

Used by #tie_item? to verify that an item (e.g., gem pouch, bundle) has been successfully tied or attached.

Examples:

Matches

"You tie the pouch to your belt."
"This item has already been tied off."

See Also:

[
  /^You .*tie/,
  /^You attach/,
  /has already been tied off/,
  /Tie it off when it's empty\?/
].freeze
TIE_ITEM_FAILURE_PATTERNS =

Patterns that match failed item tying attempts.

Used by #tie_item? to recognize when an item cannot be tied, usually due to lack of attachment points or item design.

Examples:

Matches

"There's no more free ties on this container."
"This item doesn't seem to fit."

See Also:

[
  /^There's no more free ties/,
  /^Tie what/,
  /^You are a little too busy/,
  /^You don't seem to be able to move/,
  /^You must be holding/,
  /^Your wounds hinder your ability to do that/,
  /close the fan/,
  /doesn't seem to fit/
].freeze
UNTIE_ITEM_SUCCESS_PATTERNS =

Patterns that match successful item untying via UNTIE command.

Used by #untie_item? to verify that an item has been successfully untied or detached from a container.

Examples:

Matches

"You remove the pouch from your belt."
"You untie the bundle."

See Also:

[
  /^You remove/,
  /You untie/i
].freeze
UNTIE_ITEM_FAILURE_PATTERNS =

Patterns that match failed item untying attempts.

Used by #untie_item? to recognize when an item cannot be untied, usually due to character restrictions (busy, fumbling, moving).

Examples:

Matches

"You fumble with the ties and fail to get it loose."
"Untie what?"

See Also:

[
  /^You don't seem to be able to move/,
  /^You fumble with the ties/,
  /^You are a little too busy/,
  /^You are a bit too busy/,
  /^Untie what/,
  /^What were you referring/
].freeze
REMOVE_ITEM_SUCCESS_PATTERNS =

Patterns that match successful item removal via REMOVE command.

Matches diverse removal verbs (pull, slide, detach, untie, etc.) used by different worn item types (armor, shields, boots, gloves, etc.).

Examples:

Matches

"You pull off the gloves."
"The boots slide off your feet."
"You remove the cloak."

See Also:

[
  /^Dropping your shoulder/,
  /^The .* slide/,
  /^Without any effort/,
  /^You .* slide/,
  /^You detach/,
  /^You loosen/,
  /^You pull/,
  /^You.*remove/,
  /^You slide/,
  /^You sling/,
  /^You slip/,
  /^You struggle/,
  /^You take/,
  /you tug/i,
  /^You untie/,
  /as you remove/,
  /slide themselves off of your/,
  /you manage to loosen/,
  /you unlace/,
  /^You slam the heels/,
  /^You work your way out/,
  /^Grunting with momentary exertion/, # Grunting with momentary exertion, you grip each of your heavy combat boots in turn by the heel, and pull them off.
  /^With masterful grace, you ready/,
  /^A brisk chill leaves you as you/ # cold-enchanted items (e.g., ice-veined leather gloves)
].freeze
REMOVE_ITEM_FAILURE_PATTERNS =

Patterns that match failed item removal attempts.

Used by #remove_item_unsafe? to recognize when an item cannot be removed, usually due to game restrictions (hand damage, not wearing item).

Examples:

Matches

"You aren't wearing that."
"You need a free hand to do that."

See Also:

[
  /^You'll need both hands free/,
  /^You need a free hand/,
  /^You aren't wearing/,
  /^You don't seem to be able to move/,
  /^Remove what/,
  /^I could not/,
  /^What were you/
].freeze
SHEATH_ITEM_SUCCESS_PATTERNS =

Success patterns for the SHEATH verb.

Matches game output when a weapon is successfully sheathed into a scabbard, sheath, or harness. Also splatted into PUT_AWAY_ITEM_SUCCESS_PATTERNS because STOW can trigger sheath responses when the default storage is a sheath.

Examples:

Matches

"Sheathing your sword, you put it away."
"You sheath your sword in your scabbard."
"With fluid and stealthy movements you slip the sabre into your harness."

See Also:

[
  /^Sheathing/,
  /^You sheath/,
  /^You secure your/,
  /^You slip/,
  /^You hang/,
  /^You (easily )?strap/,
  /^With a flick of your wrist,? you stealthily sheath/,
  /^With fluid and stealthy movements you slip/,
  /^The .* slides easily/
].freeze
SHEATH_ITEM_FAILURE_PATTERNS =

Failure patterns for the SHEATH verb.

Examples:

Matches

"Sheath your sword where?"
"There's no room for that."

See Also:

[
  /^Sheath your .* where/,
  /^There's no room/,
  /is too small to hold that/,
  /is too wide to fit/,
  /^Your (left|right) hand is too injured/
].freeze
PUT_AWAY_ITEM_SUCCESS_PATTERNS =

Success patterns for putting an item away via PUT or STOW.

Includes SHEATH_ITEM_SUCCESS_PATTERNS because STOW can trigger sheath responses when the default storage is a sheath/harness.

[
  /^You put your .* in/,
  /^You hold out/,
  /^You stuff/,
  /^You tuck/,
  /^You open your pouch and put/,
  /^You guide your/i, # puppy storage
  /^You nudge your/i, # monkey storage
  # The next message is when item crumbles when stowed, like a moonblade.
  /^As you open your hand to release the/,
  # You're a thief and you binned a stolen item.
  /nods toward you as your .* falls into the .* bin/,
  /^You add/,
  /^You rearrange/,
  /^You combine the stacks/,
  /^You secure/,
  # The following are success messages for putting an item in a container OFF your person.
  /^You drop/i,
  /^You set/i,
  /^You put/i,
  /^You carefully fit .* into your bundle/,
  /^You gently set/,
  # Sheath patterns included because STOW can trigger sheath responses.
  *SHEATH_ITEM_SUCCESS_PATTERNS,
  /^You toss .* into/ # You toss the alcohol into the bowl and mix it in thoroughly
].freeze
PUT_AWAY_ITEM_FAILURE_PATTERNS =

Patterns that match failed item storage via PUT or STOW commands.

Used by #put_away_item_unsafe? to recognize when an item cannot be stowed, usually due to container limitations (full, closed, incompatible items).

Examples:

Matches

"There isn't any more room in the backpack."
"That doesn't belong in there."

See Also:

[
  /^Stow what/,
  /^I can't find your container for stowing things in/,
  /^Please rephrase that command/,
  /^What were you referring to/,
  /^I could not find what you were referring to/,
  /^There isn't any more room in/,
  /^There's no room/,
  /^(The|That).* too heavy to go in there/,
  /^You (need to|should) unload/,
  /^You can't do that/,
  /^You just can't get/,
  /^You can't put items/,
  /^You can only take items out/,
  /^You don't seem to be able to move/,
  /^Perhaps you should be holding that first/,
  /^Containers can't be placed in/,
  /^The .* is not designed to carry anything/,
  /^You can't put that.*there/,
  /^Weirdly, you can't manage .* to fit/,
  /^\[Containers can't be placed in/,
  /even after stuffing it/,
  /is too .* to (fit|hold)/,
  /no matter how you arrange it/,
  /close the fan/,
  /to fit in the/,
  /doesn't seem to want to leave you/, # trying to put a pet in a home within a container
  # You may get the next message if you've been cursed and unable to let go of items.
  # Find a Cleric to uncurse you.
  /Oddly, when you attempt to stash it away safely/,
  /completely full/,
  /That doesn't belong in there!/,
  /exerts a steady force preventing/
].freeze
PUT_AWAY_ITEM_RETRY_PATTERNS =

Messages that when trying to put away an item you're warned. To continue you must retry the command.

[
  # You may get the next messages when an outdated item is updated upon use.
  # "Something appears different about the <item>, perhaps try doing that again."
  # Example: https://elanthipedia.play.net/Item:Leather_lotion
  /Something appears different about/,
  /perhaps try doing that again/
].freeze
STOW_ITEM_SUCCESS_PATTERNS =

Patterns that match successful item stowing via STOW command.

Combines GET_ITEM_SUCCESS_PATTERNS and PUT_AWAY_ITEM_SUCCESS_PATTERNS since STOW both picks up and stores an item in a single command.

[
  *GET_ITEM_SUCCESS_PATTERNS,
  *PUT_AWAY_ITEM_SUCCESS_PATTERNS
].freeze
STOW_ITEM_FAILURE_PATTERNS =

Patterns that match failed item stowing via STOW command.

Combines GET_ITEM_FAILURE_PATTERNS and PUT_AWAY_ITEM_FAILURE_PATTERNS to cover both retrieval and storage failures.

[
  *GET_ITEM_FAILURE_PATTERNS,
  *PUT_AWAY_ITEM_FAILURE_PATTERNS
].freeze
STOW_ITEM_RETRY_PATTERNS =

Patterns that trigger automatic retry of STOW command.

Contains PUT_AWAY_ITEM_RETRY_PATTERNS for messages like outdated items that require a second attempt to complete.

[
  *PUT_AWAY_ITEM_RETRY_PATTERNS
].freeze
WIELD_ITEM_SUCCESS_PATTERNS =

Success patterns for the WIELD verb.

Matches game output when a weapon is successfully drawn from a sheath, scabbard, or harness.

Examples:

Matches

"You draw your sword from your scabbard."
"You deftly remove a dagger from your thigh sheath."
"With a flick of your wrist, you stealthily unsheath your weapon."

See Also:

[
  /you draw (?!\w+'s wounds)/i,
  /^You deftly remove/,
  /^You slip/,
  /^With a flick of your wrist,? you stealthily unsheath/,
  /^With fluid and stealthy movements you draw/,
  /^The .* slides easily out/
].freeze
WIELD_ITEM_FAILURE_PATTERNS =

Failure patterns for the WIELD verb.

[
  /^Wield what/,
  /^Your (left|right) hand is too injured/
].freeze
SWAP_HANDS_SUCCESS_PATTERNS =

Success patterns for the SWAP verb (hand swap).

Matches game output when items are successfully swapped between left and right hands.

Examples:

Matches

"You move a steel sword to your left hand."

See Also:

[
  /^You move/
].freeze
SWAP_HANDS_FAILURE_PATTERNS =

Failure patterns for the SWAP verb (hand swap).

[
  /^Will alone cannot conquer the paralysis/
].freeze
UNLOAD_WEAPON_SUCCESS_PATTERNS =

Success patterns for the UNLOAD verb.

Matches game output when a ranged weapon is successfully unloaded. Includes both visible and hidden unloading messages, as well as the case where ammo falls to the ground (hands full).

The game may prepend an aim/firing timer tag to the unload line, e.g. " You unload the shortbow." The optional (?:<dialogData.*?<\/dialogData>)? prefix lets the patterns match whether or not the tag is present, without assuming its inner values.

Examples:

Matches

"You unload the crossbow."
"Your bolt falls from your crossbow to your feet."
"As you release the string, the arrow tumbles to the ground."
"You remain concealed by your surroundings, convinced that your unloading of the crossbow went unobserved."

See Also:

[
  /^(?:<dialogData.*?<\/dialogData>)?You unload/,
  /^Your .* fall.*to your feet\.$/,
  /As you release the string/,
  /^(?:<dialogData.*?<\/dialogData>)?You .* unloading/
].freeze
UNLOAD_WEAPON_FAILURE_PATTERNS =

Failure patterns for the UNLOAD verb.

[
  /But your .* isn't loaded/,
  /You can't unload such a weapon/,
  /You don't have a ranged weapon to unload/,
  /You must be holding the weapon to do that/
].freeze
RUMMAGE_SUCCESS_PATTERNS =

Patterns that match successful RUMMAGE command output.

Used by #rummage_container and #list_container_contents to extract container contents lists from the game response.

Examples:

Matches

"You rummage through the backpack and see a sword, a shield, and some rope."
"In the chest you see a pair of gloves."

See Also:

[
  /^You rummage through .* and see (.*)\./,
  /^In the .* you see (.*)\./,
  /there is nothing/i
].freeze
RUMMAGE_FAILURE_PATTERNS =

Patterns that match failed RUMMAGE command attempts.

Used by #rummage_container and #list_container_contents to recognize when a container cannot be accessed or rummaged.

Examples:

Matches

"I could not find what you were referring to."
"What were you referring to?"

See Also:

[
  /^You don't seem to be able to move/,
  /^I could not find/,
  /^I don't know what you are referring to/,
  /^What were you referring to/
].freeze
TAP_SUCCESS_PATTERNS =

Patterns that match successful TAP command output.

Used by #tap, #exists?, #wearing?, and #inside? to verify that an item exists and determine its location (worn, stowed, in a container, etc.).

Examples:

Matches

"You tap the pouch and it's inside your backpack."
"You tap the ring and it's wearing."

See Also:

[
  /^You tap\s(?!into).*/, # The `.*` is needed to capture entire phrase. Methods parse it to know if an item is worn, stowed, etc.
  /^You (thump|drum) your finger/, # You tapped an item with fancy verbiage, ohh la la!
  /^As you tap/, # As you tap a large ice-veined leather and flamewood surveyor's case
  /^The orb is delicate/, # You tapped a favor orb
  /^You .* on the shoulder/, # You tapped someone
  /^You suddenly forget what you were doing/ # "tap my tessera" messaging when hands are full
].freeze
TAP_FAILURE_PATTERNS =

Patterns that match failed TAP command attempts.

Used by #tap, #exists?, #wearing?, and #inside? to recognize when an item does not exist in inventory or a container.

Examples:

Matches

"I could not find what you were referring to."
"What were you referring to?"

See Also:

[
  /^You don't seem to be able to move/,
  /^I could not find/,
  /^I don't know what you are referring to/,
  /^What were you referring to/
].freeze
OPEN_CONTAINER_SUCCESS_PATTERNS =

Patterns that match successful container opening via OPEN command.

Used by #open_container? to verify that a container is now open and accessible.

Examples:

Matches

"You open the backpack."
"It's already open."

See Also:

[
  /^You open/,
  /^You slowly open/,
  /^The .* opens/,
  /^You unbutton/,
  /(It's|is) already open/,
  /^You spread your arms, carefully holding your bag well away from your body/
].freeze
OPEN_CONTAINER_FAILURE_PATTERNS =

Patterns that match failed container opening attempts.

Used by #open_container? to recognize when a container cannot be opened, usually due to game restrictions or commands being invalid.

Examples:

Matches

"What were you referring to?"
"Open what?"

See Also:

[
  /^Please rephrase that command/,
  /^What were you referring to/,
  /^I could not find what you were referring to/,
  /^You don't want to ruin your spell just for that do you/,
  /^It would be a shame to disturb the silence of this place for that/,
  /^This is probably not the time nor place for that/,
  /^You don't seem to be able to move/,
  /^There is no way to do that/,
  /^You can't do that/,
  /^Open what/
].freeze
CLOSE_CONTAINER_SUCCESS_PATTERNS =

Patterns that match successful container closing via CLOSE command.

Used by #close_container? to verify that a container is now closed.

Examples:

Matches

"You close the backpack."
"It is already closed."

See Also:

[
  /^You close/,
  /^You quickly close/,
  /^You pull/,
  /is already closed/
].freeze
CLOSE_CONTAINER_FAILURE_PATTERNS =

Patterns that match failed container closing attempts.

Used by #close_container? to recognize when a container cannot be closed.

Examples:

Matches

"What were you referring to?"

See Also:

[
  /^Please rephrase that command/,
  /^What were you referring to/,
  /^I could not find what you were referring to/,
  /^You don't want to ruin your spell just for that do you/,
  /^It would be a shame to disturb the silence of this place for that/,
  /^This is probably not the time nor place for that/,
  /^You don't seem to be able to move/,
  /^There is no way to do that/,
  /^You can't do that/
].freeze
CONTAINER_IS_CLOSED_PATTERNS =

Patterns that match messages indicating a closed container.

Used by #list_container_contents and #put_away_item_unsafe? to detect when a container must be opened before access is possible, triggering automatic retry with the container open.

Examples:

Matches

"But that's closed."
"While it's closed, you can't reach in."

See Also:

[
  /^But that's closed/,
  /^That is closed/,
  /^While it's closed/
].freeze
LOWER_SUCCESS_PATTERNS =

Patterns that match successful item lowering to the ground via LOWER command.

Used by #lower_item? to verify that a held item has been successfully placed on the ground at the character's feet.

Examples:

Matches

"You lower the sword to the ground."

See Also:

[
  /^You lower/,
  # The next message is when item crumbles when leaves your hand, like a moonblade.
  /^As you open your hand to release the/
].freeze
LOWER_FAILURE_PATTERNS =

Patterns that match failed item lowering attempts.

Used by #lower_item? to recognize when an item cannot be lowered.

Examples:

Matches

"You don't seem to be able to move."
"But you aren't holding anything."

See Also:

[
  /^You don't seem to be able to move/,
  /^But you aren't holding anything/,
  /^Please rephrase that command/,
  /^What were you referring to/,
  /^I could not find what you were referring to/
].freeze
LIFT_SUCCESS_PATTERNS =

Patterns that match successful item lifting from the ground via LIFT command.

Used by #lift? to verify that an item lying at the character's feet has been successfully picked up.

Examples:

Matches

"You pick up the sword."

See Also:

[
  /^You pick up/
].freeze
LIFT_FAILURE_PATTERNS =

Patterns that match failed item lifting attempts.

Used by #lift? to recognize when an item cannot be lifted from the ground.

Examples:

Matches

"You are not strong enough to pick that up."
"What did you want to try and lift?"

See Also:

[
  /^There are no items lying at your feet/,
  /^What did you want to try and lift/,
  /can't quite lift it/,
  /^You are not strong enough to pick that up/
].freeze
GIVE_ITEM_SUCCESS_PATTERNS =

Patterns that match successful item transfer via GIVE command.

Used by #give_item? to recognize when an item has been accepted by the target (player or NPC), including repair-service confirmations.

Examples:

Matches

"They accept your offer."
"You hand them your ticket and are handed back a repair ticket."

See Also:

[
  /has accepted your offer/,
  /your ticket and are handed back/,
  /Please don't lose this ticket!/,
  /^You hand .* gives you back a repair ticket/,
  /^You hand .* your ticket and are handed back/
].freeze
GIVE_ITEM_FAILURE_PATTERNS =

Patterns that match failed item transfer or rejected offers.

Used by #give_item? to recognize when an item transfer fails, including NPC refusals (non-repairable items) and player rejections.

Examples:

Matches

"They decline the offer."
"There isn't a scratch on that."

See Also:

[
  /I don't repair those here/,
  /There isn't a scratch on that/,
  /give me a few more moments/,
  /I will not repair something that isn't broken/,
  /I can't fix those/,
  /has declined the offer/,
  /^Your offer to .* has expired/,
  /^You may only have one outstanding offer at a time/,
  /^What is it you're trying to give/,
  /Lucky for you!  That isn't damaged!/
].freeze
FILL_POUCH_SUCCESS_PATTERNS =

Patterns that match successful gem pouch filling via FILL command.

Used by #fill_gem_pouch_with_container to recognize when gems have been successfully transferred into a pouch.

Examples:

Matches

"You fill your black pouch with gems."
"There aren't any gems in that container."

See Also:

[
  /^You open/,
  /^You fill your/,
  /^There aren't any gems/
].freeze
FILL_POUCH_NEEDS_TIE_PATTERNS =

Patterns indicating a gem pouch must be tied before further filling.

Used by #fill_gem_pouch_with_container to trigger tying when a partially-filled pouch needs to be secured before additional gems can be added.

Examples:

Matches

"You'd better tie it up before putting more in."

See Also:

[
  /^You'd better tie it up before putting/,
  /^You'll need to tie it up before/
].freeze
FILL_POUCH_FULL_PATTERN =

Pattern matching a full gem pouch that cannot accept more gems.

Used by #fill_gem_pouch_with_container to trigger pouch-swap operations when the current pouch reaches capacity.

Examples:

Matches

"Your black pouch is too full to fit that in."

See Also:

/is too full to fit/.freeze
FILL_POUCH_FAILURE_PATTERNS =

Patterns that match failed gem pouch filling attempts.

Used by #fill_gem_pouch_with_container to recognize command errors or invalid container references.

Examples:

Matches

"What were you referring to?"

See Also:

[
  /^Please rephrase that command/,
  /^What were you referring to/
].freeze
INV_BELT_START_PATTERN =

Pattern matching the start of INVENTORY BELT output.

Used by #check_belt_for_pouch? to identify the beginning of belt inventory listing for parsing.

See Also:

/^All of your items worn attached to the belt:/.freeze
INV_BELT_END_PATTERN =

Pattern matching the end of INVENTORY BELT output.

Used by #check_belt_for_pouch? to identify the end of belt inventory listing for parsing.

See Also:

/^\[Use INVENTORY HELP/.freeze
COUNT_PART_PATTERNS =

Patterns that match item part-count responses from COUNT command.

Used by #count_item_parts to extract numeric counts from game output when counting stackable items like crafting materials and ammunition.

Examples:

Matches

"There are 45 leather left."
"You count out 120 pieces of stone there."
"The wand has 8 uses remaining."

See Also:

  • #count_item_parts
[
  /and see there (?:is|are) (?<count>.+) left\./,
  /There (?:is|are) (?:only )?(?<count>.+) parts? left/,
  /There's (?:only )?(?<count>.+) parts? left/,
  /The (?:.+) has (?<count>.+) uses remaining./,
  /There are enough left to create (?<count>.+) more/,
  /You count out (?<count>.+) pieces? of material there/,
  /There (?:is|are) (?<count>.+) scrolls? left for use with crafting/
].freeze
BRAID_TOO_LONG_PATTERN =

Pattern matching when a braided item is too long to stow.

Used by #stow_hand to detect oversized braids that must be disposed as trash before the hand can be emptied.

Examples:

Matches

"The braided silver chain is too long to fit through any of the openings."

See Also:

  • #stow_hand
  • #dispose_trash
/The braided (?<braid_name>.+) is too long/.freeze
ACCEPT_SUCCESS_PATTERN =

Pattern matching successful item acceptance from another player.

Used by #accept_item? to extract the name of the player whose offer was accepted and verify the transaction completed.

Examples:

Matches

"You accept Falicor's offer and are now holding a steel sword."

See Also:

  • #accept_item?
/You accept (?<name>\w+)'s offer and are now holding/.freeze

Class Method Summary collapse

Class Method Details

.accept_item?String, false

Accepts a pending item offer from another player.

Returns:

  • (String, false)

    name of the person whose offer was accepted, or false if no offer pending or hands full

See Also:



2270
2271
2272
2273
2274
# File 'documented/dragonrealms/commons/common-items.rb', line 2270

def accept_item?
  result = DRC.bput("accept", ACCEPT_SUCCESS_PATTERN, "You have no offers", "Both of your hands are full", "would push you over your item limit")
  match = result&.match(ACCEPT_SUCCESS_PATTERN)
  match ? match[:name] : false
end

.check_belt_for_pouch?(gem_pouch_adjective, gem_pouch_noun) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Checks if a gem pouch is already attached to the belt.

Uses INV BELT to inspect belt contents and matches against the pouch adjective and noun.

Parameters:

  • gem_pouch_adjective (String)

    pouch adjective (e.g., "black")

  • gem_pouch_noun (String)

    pouch noun (e.g., "pouch")

Returns:

  • (Boolean)

    true if a matching pouch is found on the belt



2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
# File 'documented/dragonrealms/commons/common-items.rb', line 2289

def check_belt_for_pouch?(gem_pouch_adjective, gem_pouch_noun)
  belt_contents = Lich::Util.issue_command(
    "inv belt",
    INV_BELT_START_PATTERN,
    INV_BELT_END_PATTERN,
    timeout: 3,
    silent: true,
    quiet: true,
    usexml: false,
    include_end: false
  )

  return false if belt_contents.nil? || belt_contents.empty?

  pouch_pattern = /#{gem_pouch_adjective}.*gem.*#{gem_pouch_noun}/i
  belt_contents.any? { |line| line.match?(pouch_pattern) }
end

.close_container?(container) ⇒ Boolean

Closes a container.

Parameters:

  • container (String)

    container noun to close

Returns:

  • (Boolean)

    true if container was closed (or already closed)

See Also:



2190
2191
2192
2193
2194
2195
2196
# File 'documented/dragonrealms/commons/common-items.rb', line 2190

def close_container?(container)
  case DRC.bput("close #{container}", CLOSE_CONTAINER_SUCCESS_PATTERNS, CLOSE_CONTAINER_FAILURE_PATTERNS)
  when *CLOSE_CONTAINER_SUCCESS_PATTERNS
    return true
  end
  return false
end

.container_is_empty?(container) ⇒ Boolean?

Checks if a container is empty by looking inside it.

Parameters:

  • container (String)

    container noun to check

Returns:

  • (Boolean, nil)

    true if empty, false if not empty, nil if unable to determine (e.g., cannot open or look in container)



1944
1945
1946
# File 'documented/dragonrealms/commons/common-items.rb', line 1944

def container_is_empty?(container)
  look_in_container(container)&.empty?
end

.count_all_boxes(settings) ⇒ Integer

Counts all lockpick boxes across configured containers.

Checks the picking_box_source, picking_box_sources, blacklist, and too_hard containers from settings.

Parameters:

  • settings (OpenStruct)

    user settings from get_settings

Returns:

  • (Integer)

    total number of boxes across all containers



1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
# File 'documented/dragonrealms/commons/common-items.rb', line 1465

def count_all_boxes(settings)
  current_box_count = 0

  [
    settings.picking_box_source,
    settings.pick['picking_box_sources'],
    settings.pick['blacklist_container'],
    settings.pick['too_hard_container']
  ].flatten.uniq.reject { |container|
    container.to_s.empty?
  }.each { |container|
    current_box_count += get_box_list_in_container(container).size
  }

  current_box_count
end

.count_item_parts(item) ⇒ Integer

Counts the remaining parts/uses of a stackable item.

Iterates through ordinals (first, second, ...) to count across multiple stacks. Falls back to count_items if the item is not stackable.

Examples:

DRCI.count_item_parts("leather")  #=> 45

Parameters:

  • item (String)

    item noun to count

Returns:

  • (Integer)

    total number of parts across all stacks



1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
# File 'documented/dragonrealms/commons/common-items.rb', line 1355

def count_item_parts(item)
  count = 0
  # Item IDs (starting with #) are unique, so we count once without ordinals
  items_to_count = item&.start_with?('#') ? [item] : $ORDINALS.map { |ord| "#{ord} #{item}" }

  items_to_count.each do |item_with_ordinal|
    result = DRC.bput("count #{item_ref(item_with_ordinal)}",
                      'I could not find what you were referring to.',
                      'tell you much of anything.',
                      *COUNT_PART_PATTERNS)
    if result == 'I could not find what you were referring to.'
      break
    elsif result == 'tell you much of anything.'
      Lich::Messaging.msg("bold", "DRCI: count_item_parts called on non-stackable item: #{item}")
      count = count_items(item)
      break
    else
      # Try to match against our count patterns
      match = COUNT_PART_PATTERNS.lazy.filter_map { |pat| result.match(pat) }.first
      if match
        countval = match[:count].tr('-', ' ')
        if countval.match?(/\A\d+\z/)
          count += Integer(countval)
        else
          count += DRC.text2num(countval)
        end
      end
    end
    waitrt?
  end
  count
end

.count_items(item) ⇒ Integer

Counts matching items in the container inferred by tapping the item.

Taps the item to determine which container it is in, then delegates to count_items_in_container.

Parameters:

  • item (String)

    item noun to count

Returns:

  • (Integer)

    number of matching items in the inferred container

See Also:



1397
1398
1399
1400
1401
1402
1403
# File 'documented/dragonrealms/commons/common-items.rb', line 1397

def count_items(item)
  tap_result = tap(item)
  match = tap_result&.match(/inside your (?<container>.*)/)
  return 0 unless match

  count_items_in_container(item, match[:container])
end

.count_items_in_container(item, container) ⇒ Integer

Counts matching items in a specific container via RUMMAGE.

Parameters:

  • item (String)

    item noun to count

  • container (String)

    container noun to rummage

Returns:

  • (Integer)

    number of matching items found

See Also:



1412
1413
1414
1415
1416
1417
# File 'documented/dragonrealms/commons/common-items.rb', line 1412

def count_items_in_container(item, container)
  contents = DRC.bput("rummage /C #{item.split.last} in #{item_ref(container)}", /^You rummage .*/, /That would accomplish nothing/)
  # This regexp avoids counting the quoted item name in the message, as
  # well as avoiding finding the item as a substring of other items.
  contents.scan(/ #{item}\W/).size
end

.count_lockpick_container(container) ⇒ Integer

Counts how many more lockpicks a lockpick stacker can hold.

Uses APPRAISE QUICK to determine remaining capacity.

Parameters:

  • container (String)

    lockpick ring/stacker noun

Returns:

  • (Integer)

    number of additional lockpicks that can fit

See Also:



1427
1428
1429
1430
1431
# File 'documented/dragonrealms/commons/common-items.rb', line 1427

def count_lockpick_container(container)
  result = DRC.bput("appraise #{item_ref(container)} quick", /it appears to be full/, /it might hold an additional \d+/, /\d+ lockpicks would probably fit/)
  waitrt?
  result.scan(/\d+/).first.to_i
end

.count_necro_stacker(necro_stacker) ⇒ Integer

Counts items in a Necromancer material stacker via STUDY.

Parameters:

  • necro_stacker (String)

    stacker noun

Returns:

  • (Integer)

    number of items currently held



1453
1454
1455
1456
# File 'documented/dragonrealms/commons/common-items.rb', line 1453

def count_necro_stacker(necro_stacker)
  result = DRC.bput("study #{item_ref(necro_stacker)}", /currently holds \d+ items/)
  result.scan(/\d+/).first.to_i
end

.dispose_trash(item, worn_trashcan = nil, worn_trashcan_verb = nil, retries: 3) ⇒ Boolean?

Disposes of an item by putting it in a trash receptacle.

Tries multiple disposal strategies in order: worn trashcan, room meta-tagged trashcan, room objects matching known trash receptacles, and finally drops the item on the ground.

Examples:

Dispose using room trash bins

DRCI.dispose_trash("rock")

Dispose into a worn trashcan

DRCI.dispose_trash("rock", "shroud", "tap")

Parameters:

  • item (String)

    item noun to dispose of

  • worn_trashcan (String, nil) (defaults to: nil)

    worn container for trash (e.g., "shroud")

  • worn_trashcan_verb (String, nil) (defaults to: nil)

    verb to activate the worn trashcan after use

  • retries (Integer) (defaults to: 3)

    remaining retry attempts before giving up (default 3)

Returns:

  • (Boolean, nil)

    true if disposed, false if failed, nil if item is nil or not held



1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
# File 'documented/dragonrealms/commons/common-items.rb', line 1040

def dispose_trash(item, worn_trashcan = nil, worn_trashcan_verb = nil, retries: 3)
  return unless item

  if retries <= 0
    Lich::Messaging.msg("bold", "DRCI: dispose_trash exceeded max retries")
    return false
  end

  return unless DRCI.get_item_if_not_held?(item)

  if worn_trashcan
    result = execute_dispose_command("put #{item_ref(item)} in #{item_ref(worn_trashcan)}", item, retries, worn_trashcan, worn_trashcan_verb)
    if result == :success
      if worn_trashcan_verb
        DRC.bput("#{worn_trashcan_verb} #{item_ref(worn_trashcan)}", *WORN_TRASHCAN_VERB_PATTERNS)
        DRC.bput("#{worn_trashcan_verb} #{item_ref(worn_trashcan)}", *WORN_TRASHCAN_VERB_PATTERNS)
      end
      return true
    end
    return result unless result == :failure
  end

  # Check for meta:trashcan tag on the room to identify a specific trashcan to use.
  metatag_match = Room.current.tags.find { |t| t =~ /meta:trashcan:(?<trashcan>.*)/ }&.match(/meta:trashcan:(?<trashcan>.*)/)
  if metatag_match
    metatag_trashcan = metatag_match[:trashcan]

    # Gelapod needs special handling since you feed it, and it disappears in winter
    metatag_trash_command = nil
    if metatag_trashcan == 'gelapod'
      metatag_trash_command = "feed #{item_ref(item)} to gelapod" if DRRoom.room_objs.include?('gelapod')
    else
      metatag_trash_command = "put #{item_ref(item)} in #{metatag_trashcan}"
    end

    # gelapod is not here - probably winter move on to next attempt to get rid of
    unless metatag_trash_command.nil?
      result = execute_dispose_command(metatag_trash_command, item, retries)
      return true if result == :success
      return result unless result == :failure
    end
  end

  recognized_trash = trash_storage
  trashcans = DRRoom.room_objs
                    .reject { |obj| obj =~ /azure \w+ tree/ }
                    .map { |long_name| DRC.get_noun(long_name) }
                    .select { |obj| recognized_trash.include?(obj) }

  trashcans.each do |trashcan|
    if trashcan == 'gloop'
      trashcan = 'bucket' if DRRoom.room_objs.include?('bucket of viscous gloop')
      trashcan = 'cauldron' if DRRoom.room_objs.include?('small bubbling cauldron of viscous gloop')
    elsif trashcan == 'bucket'
      trashcan = 'sturdy bucket' if DRRoom.room_objs.include?('sturdy bucket')
    elsif trashcan == 'basket'
      trashcan = 'waste basket' if DRRoom.room_objs.include?('waste basket')
    elsif trashcan == 'bin'
      trashcan = 'waste bin' if DRRoom.room_objs.include?('waste bin')
      trashcan = 'small bin' if DRRoom.room_objs.include?('small bin concealed with some nearby brush')
    elsif trashcan == 'arms'
      trashcan = 'statue'
    elsif trashcan == 'birdbath'
      trashcan = 'alabaster birdbath'
    elsif trashcan == 'turtle'
      trashcan = 'stone turtle'
    elsif trashcan == 'tree'
      trashcan = 'hollow' if DRRoom.room_objs.include?('dead tree with a darkened hollow near its base')
    elsif trashcan == 'basin'
      trashcan = 'stone basin' if DRRoom.room_objs.include?('hollow stone basin')
    elsif trashcan == 'tangle'
      trashcan = 'dark gap' if DRRoom.room_objs.include?('tangle of thick roots forming a dark gap')
    elsif XMLData.room_title == '[[A Junk Yard]]'
      trashcan = 'bin'
    elsif trashcan == 'gelapod'
      trash_command = "feed #{item_ref(item)} to gelapod"
    end

    trash_command = "put #{item_ref(item)} in #{trashcan}" unless trashcan == 'gelapod'

    result = execute_dispose_command(trash_command, item, retries)
    return true if result == :success
    return true if result && result != :failure
  end

  # No trash bins or not able to put item in a bin, just drop it.
  result = execute_dispose_command("drop #{item_ref(item)}", item, retries)
  case result
  when :success
    true
  when :failure
    Lich::Messaging.msg("bold", "DRCI: Failed to dispose of '#{item}'.")
    false
  when false, nil
    Lich::Messaging.msg("bold", "DRCI: Unexpected response when dropping '#{item}'.")
    false
  else
    result
  end
end

.execute_dispose_command(command, item, retries, *retry_args) ⇒ Symbol, Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Executes a dispose command and handles common retry/recovery patterns.

Parameters:

  • command (String)

    game command to execute

  • item (String)

    item being disposed

  • retries (Integer)

    remaining retry attempts

  • retry_args (Array)

    extra args to pass to dispose_trash on retry

Returns:

  • (Symbol, Boolean)

    :success, :failure, or the boolean result of a retry



1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
# File 'documented/dragonrealms/commons/common-items.rb', line 1150

def execute_dispose_command(command, item, retries, *retry_args)
  case DRC.bput(command, DROP_TRASH_SUCCESS_PATTERNS, DROP_TRASH_FAILURE_PATTERNS, DROP_TRASH_RETRY_PATTERNS, /^Perhaps you should be holding that first/, /^But you aren't holding that/)
  when *DROP_TRASH_SUCCESS_PATTERNS
    :success
  when /^Perhaps you should be holding that first/, /^But you aren't holding that/
    DRCI.get_item?(item) && dispose_trash(item, *retry_args, retries: retries - 1)
  when *DROP_TRASH_FAILURE_PATTERNS
    :failure
  when *DROP_TRASH_RETRY_PATTERNS
    dispose_trash(item, *retry_args, retries: retries - 1)
  end
end

.exists?(item, container = nil) ⇒ Boolean

Checks if an item exists in inventory or a container by tapping it.

Examples:

DRCI.exists?("deed")
DRCI.exists?("sword", "backpack")

Parameters:

  • item (String)

    item noun to check

  • container (String, nil) (defaults to: nil)

    container to check in, or nil for general inventory

Returns:

  • (Boolean)

    true if the item exists



1204
1205
1206
1207
1208
1209
1210
1211
# File 'documented/dragonrealms/commons/common-items.rb', line 1204

def exists?(item, container = nil)
  case tap(item, container)
  when *TAP_SUCCESS_PATTERNS
    true
  else
    false
  end
end

.fill_gem_pouch_with_container(gem_pouch_adjective, gem_pouch_noun, source_container, full_pouch_container = nil, spare_gem_pouch_container = nil, should_tie_gem_pouches = false, retries: 10) ⇒ void

This method returns an undefined value.

Fills a gem pouch from a source container.

Handles full pouches by swapping them out for spares via swap_out_full_gempouch?. Handles untied pouches by tying them when requested.

Examples:

DRCI.fill_gem_pouch_with_container("black", "pouch", "lootbag",
  "backpack", "trunk", true)

Parameters:

  • gem_pouch_adjective (String)

    pouch adjective (e.g., "black")

  • gem_pouch_noun (String)

    pouch noun (e.g., "pouch")

  • source_container (String)

    container holding gems to transfer

  • full_pouch_container (String, nil) (defaults to: nil)

    container for full pouches

  • spare_gem_pouch_container (String, nil) (defaults to: nil)

    container holding spare pouches

  • should_tie_gem_pouches (Boolean) (defaults to: false)

    whether to tie pouches after filling

  • retries (Integer) (defaults to: 10)

    remaining retry attempts before giving up (default 10)



2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
# File 'documented/dragonrealms/commons/common-items.rb', line 2407

def fill_gem_pouch_with_container(gem_pouch_adjective, gem_pouch_noun, source_container, full_pouch_container = nil, spare_gem_pouch_container = nil, should_tie_gem_pouches = false, retries: 10)
  if retries <= 0
    Lich::Messaging.msg("bold", "DRCI: fill_gem_pouch_with_container exceeded max retries")
    return
  end

  Flags.add("pouch-full", FILL_POUCH_FULL_PATTERN)
  begin
    pouch = "#{gem_pouch_adjective} #{gem_pouch_noun}"
    result = DRC.bput(
      "fill #{item_ref(pouch)} with #{item_ref(source_container)}",
      *FILL_POUCH_SUCCESS_PATTERNS,
      FILL_POUCH_FULL_PATTERN,
      *FILL_POUCH_NEEDS_TIE_PATTERNS,
      *FILL_POUCH_FAILURE_PATTERNS
    )

    case result
    when *FILL_POUCH_FAILURE_PATTERNS
      Lich::Messaging.msg("bold", "DRCI: Fill failed - #{result}")
      return
    when *FILL_POUCH_NEEDS_TIE_PATTERNS
      # Pouch needs to be tied before more gems can be added
      if should_tie_gem_pouches
        # Tie the pouch and retry
        unless tie_gem_pouch?(gem_pouch_adjective, gem_pouch_noun)
          Lich::Messaging.msg("bold", "DRCI: Could not tie #{gem_pouch_adjective} #{gem_pouch_noun}.")
          return
        end
        return fill_gem_pouch_with_container(gem_pouch_adjective, gem_pouch_noun, source_container, full_pouch_container, spare_gem_pouch_container, should_tie_gem_pouches, retries: retries - 1)
      else
        # Treat as full - swap out the pouch
        unless swap_out_full_gempouch?(gem_pouch_adjective, gem_pouch_noun, full_pouch_container, spare_gem_pouch_container, should_tie_gem_pouches)
          Lich::Messaging.msg("bold", "DRCI: Could not swap gem pouches.")
          return
        end
        return fill_gem_pouch_with_container(gem_pouch_adjective, gem_pouch_noun, source_container, full_pouch_container, spare_gem_pouch_container, should_tie_gem_pouches, retries: retries - 1)
      end
    when FILL_POUCH_FULL_PATTERN
      # Pouch is full, swap it out
      unless swap_out_full_gempouch?(gem_pouch_adjective, gem_pouch_noun, full_pouch_container, spare_gem_pouch_container, should_tie_gem_pouches)
        Lich::Messaging.msg("bold", "DRCI: Could not swap gem pouches.")
        return
      end
      return fill_gem_pouch_with_container(gem_pouch_adjective, gem_pouch_noun, source_container, full_pouch_container, spare_gem_pouch_container, should_tie_gem_pouches, retries: retries - 1)
    end

    # Check flag for mid-fill full pouch (when pouch fills up during the fill operation)
    if Flags["pouch-full"]
      Flags.reset("pouch-full")
      unless swap_out_full_gempouch?(gem_pouch_adjective, gem_pouch_noun, full_pouch_container, spare_gem_pouch_container, should_tie_gem_pouches)
        Lich::Messaging.msg("bold", "DRCI: Could not swap gem pouches.")
        return
      end
      return fill_gem_pouch_with_container(gem_pouch_adjective, gem_pouch_noun, source_container, full_pouch_container, spare_gem_pouch_container, should_tie_gem_pouches, retries: retries - 1)
    end

    # Optionally tie the pouch after successful fill
    tie_gem_pouch?(gem_pouch_adjective, gem_pouch_noun) if should_tie_gem_pouches
  ensure
    Flags.delete("pouch-full")
  end
end

.get_box_list_in_container(container) ⇒ Array<String>

Lists boxes in a container via RUMMAGE /B.

Parameters:

  • container (String)

    container noun to rummage

Returns:

  • (Array<String>)

    list of box descriptions



1437
1438
1439
# File 'documented/dragonrealms/commons/common-items.rb', line 1437

def get_box_list_in_container(container)
  DRC.rummage('B', container)
end

.get_inventory_by_type(type = 'combat') ⇒ Array<String>

Returns a list of item descriptions from the INVENTORY <type|slot> verb output.

Examples:

DRCI.get_inventory_by_type('combat')
#=> ["steel plate helm", "dark leather jerkin with reinforced seams"]

Parameters:

  • type (String) (defaults to: 'combat')

    inventory type: armor, weapon, fluff, container, combat, or any slot from INVENTORY SLOTS LIST

Returns:

  • (Array<String>)

    item descriptions with articles stripped

See Also:



1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
# File 'documented/dragonrealms/commons/common-items.rb', line 1959

def get_inventory_by_type(type = 'combat')
  start_pattern = /^All of your |^You aren't wearing anything like that|^Both of your hands are empty/
  end_pattern = /^\[Use INVENTORY HELP/

  snapshot = Lich::Util.issue_command(
    "inventory #{type}",
    start_pattern,
    end_pattern,
    timeout: 5,
    usexml: false,
    include_end: false
  )

  if snapshot.nil? || snapshot.empty?
    Lich::Messaging.msg("bold", "DRCI: No inventory data for type '#{type}'. Valid options: ARMOR, WEAPON, FLUFF, CONTAINER, COMBAT, or any slot from INVENTORY SLOTS LIST.")
    return []
  end

  items_at_feet = snapshot.any? { |line| line.strip.start_with?('Lying at your feet') }

  snapshot
    .map(&:strip)
    .reject { |line| start_pattern.match?(line) || line.empty? }
    .take_while { |line| !items_at_feet || !line.start_with?('Lying at your feet') }
    .map { |item| item.gsub(/^(a|an|some)\s+/, '').gsub(/\s+\(closed\)/, '') }
end

.get_item(item, container = nil) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Gets an item, optionally from a specific container.

Accepts a single container or an array of containers to try in order. Delegates to get_item_safe with "my " prefix qualification.

Parameters:

  • item (String)

    item noun to get

  • container (String, Array<String>, nil) (defaults to: nil)

    container(s) to try, or nil for default

Returns:

  • (Boolean)

    true if item was retrieved successfully



1592
1593
1594
1595
1596
1597
1598
1599
1600
# File 'documented/dragonrealms/commons/common-items.rb', line 1592

def get_item(item, container = nil)
  if container.is_a?(Array)
    container.each do |c|
      return true if get_item_safe(item, c)
    end
    return false
  end
  get_item_safe(item, container)
end

.get_item?(item, container = nil) ⇒ Boolean

Gets an item, optionally from a specific container.

Predicate-named convenience wrapper for get_item.

Examples:

Get from default storage

DRCI.get_item?("sword")

Get from specific container

DRCI.get_item?("bandages", "backpack")

Parameters:

  • item (String)

    item noun to get

  • container (String, Array<String>, nil) (defaults to: nil)

    container noun, array of containers to try, or nil

Returns:

  • (Boolean)

    true if item was retrieved successfully

See Also:



1579
1580
1581
# File 'documented/dragonrealms/commons/common-items.rb', line 1579

def get_item?(item, container = nil)
  get_item(item, container)
end

.get_item_from_eddy_portal?(item, container) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Gets an item from an eddy portal after forcing a content refresh.

Workaround for a game change where you must LOOK in the portal before its contents are available for retrieval.

Parameters:

  • item (String)

    item name to get

  • container (String)

    portal container reference

Returns:

  • (Boolean)

    true if item was retrieved successfully

See Also:



1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
# File 'documented/dragonrealms/commons/common-items.rb', line 1683

def get_item_from_eddy_portal?(item, container)
  # Ensure the eddy is open then look in it to force the contents to be loaded.
  return false unless DRCI.open_container?('my eddy') && DRCI.look_in_container('portal in my eddy')

  from = container
  from = "from #{container}" if container && !(container =~ /^(in|on|under|behind|from) /i)
  case DRC.bput("get #{item} #{from}", GET_ITEM_SUCCESS_PATTERNS, GET_ITEM_FAILURE_PATTERNS)
  when *GET_ITEM_SUCCESS_PATTERNS
    return true
  else
    return false
  end
end

.get_item_if_not_held?(item, container = nil) ⇒ Boolean

Gets an item only if not already held in either hand.

Avoids getting a duplicate when you already have the item. Returns true if the item is already in hand or was successfully retrieved.

Examples:

DRCI.get_item_if_not_held?("almanac")
DRCI.get_item_if_not_held?("sword", "backpack")

Parameters:

  • item (String)

    item noun to get

  • container (String, nil) (defaults to: nil)

    container to get from, or nil for default

Returns:

  • (Boolean)

    true if item is now in hand

See Also:



1557
1558
1559
1560
1561
1562
# File 'documented/dragonrealms/commons/common-items.rb', line 1557

def get_item_if_not_held?(item, container = nil)
  return false unless item
  return true if in_hands?(item)

  return get_item(item, container)
end

.get_item_list(container, verb = 'rummage') ⇒ Array<String>?

Lists items in a container using RUMMAGE or LOOK.

RUMMAGE returns full tap descriptions (e.g., "grey ice skates with black laces"). LOOK returns short names (e.g., "grey ice skates"), which is easier to parse.

Examples:

DRCI.get_item_list("backpack", "look")

Parameters:

  • container (String)

    container noun to inspect

  • verb (String) (defaults to: 'rummage')

    "rummage" or "look"

Returns:

  • (Array<String>, nil)

    list of item descriptions, or nil on failure

See Also:



2000
2001
2002
2003
2004
2005
2006
2007
# File 'documented/dragonrealms/commons/common-items.rb', line 2000

def get_item_list(container, verb = 'rummage')
  case verb
  when /^(r|rummage)$/i
    rummage_container(container)
  when /^(l|look)$/i
    look_in_container(container)
  end
end

.get_item_safe(item, container = nil) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Gets an item with "my " prefix on item and container names.

Delegates to #get_item_safe? for implementation.

Parameters:

  • item (String)

    item noun to get

  • container (String, nil) (defaults to: nil)

    container noun, or nil for default

Returns:

  • (Boolean)

    true if item was retrieved successfully



1622
1623
1624
# File 'documented/dragonrealms/commons/common-items.rb', line 1622

def get_item_safe(item, container = nil)
  get_item_safe?(item, container)
end

.get_item_safe?(item, container = nil) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Gets an item with "my " prefix on item and container names.

Parameters:

  • item (String)

    item noun to get

  • container (String, nil) (defaults to: nil)

    container noun, or nil for default

Returns:

  • (Boolean)

    true if item was retrieved successfully



1608
1609
1610
1611
1612
# File 'documented/dragonrealms/commons/common-items.rb', line 1608

def get_item_safe?(item, container = nil)
  item = item_ref(item)
  container = item_ref(container) if container && !(container =~ /^(in|on|under|behind|from) /i)
  get_item_unsafe(item, container)
end

.get_item_unsafe(item, container = nil) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Gets an item without "my " prefix qualification.

Issues the GET command, then verifies success by checking whether the item's noun appears in either hand via the XML game-object feed (+in_hands?+) rather than relying on text-pattern matching of the game response. This avoids false positives from combat messages (e.g. "You get a startling sensation" matching /^You get/).

The success and failure patterns are still passed to bput so it returns promptly once the game has responded, but the return value of bput is not used to determine success.

A short polling loop (up to 1 second) accommodates XML feed lag between the text response and the GameObj update.

Examples:

Basic retrieval

get_item_unsafe("backpack")  #=> true (if backpack is now in hand)

With container

get_item_unsafe("sword", "chest")  #=> true

Parameters:

  • item (String)

    item name (unqualified)

  • container (String, nil) (defaults to: nil)

    container name (unqualified), or nil

Returns:

  • (Boolean)

    true if item was retrieved successfully

See Also:



1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
# File 'documented/dragonrealms/commons/common-items.rb', line 1654

def get_item_unsafe(item, container = nil)
  from = container
  from = "from #{container}" if container && !(container =~ /^(in|on|under|behind|from) /i)

  noun = DRC.get_noun(item)
  DRC.bput("get #{item} #{from}", GET_ITEM_FAILURE_PATTERNS, GET_ITEM_SUCCESS_PATTERNS)

  10.times do
    break if in_hands?(noun)
    sleep 0.1
  end

  return true if in_hands?(noun)
  return get_item_from_eddy_portal?(item, container) if container =~ /\bportal\b/i

  false
end

.get_scroll_list_in_container(container) ⇒ Array<String>

Lists scrolls in a container via RUMMAGE /SC.

Parameters:

  • container (String)

    container noun to rummage

Returns:

  • (Array<String>)

    list of scroll descriptions



1445
1446
1447
# File 'documented/dragonrealms/commons/common-items.rb', line 1445

def get_scroll_list_in_container(container)
  DRC.rummage('SC', container)
end

.give_item?(target, item = nil, retries: 5) ⇒ Boolean?

Gives a held item to a target (player or NPC).

Handles retry prompts, expired offers, and hand-swap scenarios. Uses a 35-second timeout to allow the target time to accept.

Examples:

Give to NPC for repair

DRCI.give_item?("Ragge", "sword")

Parameters:

  • target (String)

    player name or NPC noun to give to

  • item (String, nil) (defaults to: nil)

    item noun, or nil to give whatever is held

  • retries (Integer) (defaults to: 5)

    remaining retry attempts before giving up (default 5)

Returns:

  • (Boolean, nil)

    true if accepted, false if declined/failed, nil on edge cases

See Also:



2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
# File 'documented/dragonrealms/commons/common-items.rb', line 2216

def give_item?(target, item = nil, retries: 5)
  if retries <= 0
    Lich::Messaging.msg("bold", "DRCI: give_item? exceeded max retries")
    return false
  end

  command = item ? "give #{item_ref(item)} to #{target}" : "give #{target}"
  case DRC.bput(command, { 'timeout' => 35 }, /GIVE it again/, /give it to me again/, /^You don't need to specify the object/, /already has an outstanding offer/, GIVE_ITEM_SUCCESS_PATTERNS, GIVE_ITEM_FAILURE_PATTERNS)
  when *GIVE_ITEM_SUCCESS_PATTERNS
    true
  when *GIVE_ITEM_FAILURE_PATTERNS
    false
  when /give it to me again/
    give_item?(target, item, retries: retries - 1)
  when /already has an outstanding offer/
    pause 5
    give_item?(target, item, retries: retries - 1)
  when /GIVE it again/
    waitrt
    give_item?(target, item, retries: retries - 1)
  when /You don't need to specify the object/
    if in_right_hand?(item)
      give_item?(target, retries: retries - 1)
    elsif in_left_hand?(item)
      case DRC.bput('swap', *SWAP_HANDS_SUCCESS_PATTERNS, *SWAP_HANDS_FAILURE_PATTERNS)
      when *SWAP_HANDS_SUCCESS_PATTERNS
        give_item?(target, retries: retries - 1)
      else
        false
      end
    else
      Lich::Messaging.msg("bold", "DRCI: give_item? could not find '#{item}' in either hand")
      false
    end
  end
end

.have_item_by_look?(item, container) ⇒ Boolean

Checks if an item exists in a container by LOOKing at it.

Unlike exists? which uses TAP, this uses LOOK AT which can find items inside containers that TAP cannot reach.

Parameters:

  • item (String)

    item noun to look for

  • container (String)

    container noun to look in

Returns:

  • (Boolean)

    true if item is found in the container



1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
# File 'documented/dragonrealms/commons/common-items.rb', line 1300

def have_item_by_look?(item, container)
  return false unless item

  item = item.delete_prefix('my ')
  # For item IDs, don't add preposition with 'my' - just use 'in' for the container
  if container&.start_with?('#')
    preposition = 'in' if container && !(container =~ /^(in|on|under|behind|from) /i)
  else
    preposition = 'in my' if container && !(container =~ /^((in|on|under|behind|from) )?my /i)
  end

  case DRC.bput("look at #{item_ref(item)} #{preposition} #{container}", item, /^You see nothing unusual/, /^I could not find/, /^What were you referring to/)
  when /You see nothing unusual/, item
    true
  else
    false
  end
end

.in_hand?(item, which_hand = 'either') ⇒ Boolean

Checks if an item is in one or more hands.

Accepts a string noun or a Lich::DragonRealms::DRC::Item object. Strings are converted to Item objects for regex matching against hand contents.

Examples:

Check either hand

DRCI.in_hand?("sword")

Check specific hand

DRCI.in_hand?("shield", "left")

Parameters:

  • item (String, DRC::Item)

    item noun or Item object

  • which_hand (String) (defaults to: 'either')

    "left", "right", "either", or "both"

Returns:

  • (Boolean)

    true if item is in the specified hand(s)



1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
# File 'documented/dragonrealms/commons/common-items.rb', line 1273

def in_hand?(item, which_hand = 'either')
  return false unless item

  item = DRC::Item.from_text(item) if item.is_a?(String)
  case which_hand.downcase
  when 'left'
    !!(DRC.left_hand =~ item.short_regex)
  when 'right'
    !!(DRC.right_hand =~ item.short_regex)
  when 'either'
    in_left_hand?(item) || in_right_hand?(item)
  when 'both'
    in_left_hand?(item) && in_right_hand?(item)
  else
    Lich::Messaging.msg("bold", "DRCI: Unknown hand: #{which_hand}. Valid options are: left, right, either, both")
    false
  end
end

.in_hands?(item) ⇒ Boolean

Checks if the item is in either hand.

Parameters:

Returns:

  • (Boolean)

    true if item is in either hand

See Also:



1235
1236
1237
# File 'documented/dragonrealms/commons/common-items.rb', line 1235

def in_hands?(item)
  in_hand?(item, 'either')
end

.in_left_hand?(item) ⇒ Boolean

Checks if the item is in the left hand.

Parameters:

Returns:

  • (Boolean)

    true if item is in the left hand

See Also:



1245
1246
1247
# File 'documented/dragonrealms/commons/common-items.rb', line 1245

def in_left_hand?(item)
  in_hand?(item, 'left')
end

.in_right_hand?(item) ⇒ Boolean

Checks if the item is in the right hand.

Parameters:

Returns:

  • (Boolean)

    true if item is in the right hand

See Also:



1255
1256
1257
# File 'documented/dragonrealms/commons/common-items.rb', line 1255

def in_right_hand?(item)
  in_hand?(item, 'right')
end

.inside?(item, container = nil) ⇒ Boolean

Checks if an item is inside a container by tapping it.

Parameters:

  • item (String)

    item noun to check

  • container (String, nil) (defaults to: nil)

    container noun to check, or nil for any

Returns:

  • (Boolean)

    true if item is inside a container



1191
1192
1193
# File 'documented/dragonrealms/commons/common-items.rb', line 1191

def inside?(item, container = nil)
  !!(tap(item, container) =~ /inside/)
end

.item_ref(value) ⇒ String?

Prepends "my " to an item or container name for ownership qualification.

Skips the prefix when the value is nil, already starts with "my ", or uses item ID syntax (starts with "#").

Examples:

DRCI.item_ref("sword")       #=> "my sword"
DRCI.item_ref("my sword")    #=> "my sword"
DRCI.item_ref("#12345")       #=> "#12345"
DRCI.item_ref(nil)            #=> nil

Parameters:

  • value (String, nil)

    item or container noun

Returns:

  • (String, nil)

    qualified name, or nil if value was nil



58
59
60
61
62
# File 'documented/dragonrealms/commons/common-items.rb', line 58

def item_ref(value)
  return value if value.nil? || value =~ /^(my |#)/i

  "my #{value}"
end

.lift?(item = nil, stow = nil) ⇒ Boolean

Lifts an item from the ground, optionally stowing it afterward.

Examples:

Lift only

DRCI.lift?("sword")

Lift and stow to default

DRCI.lift?("sword", true)

Lift and put in specific container

DRCI.lift?("sword", "backpack")

Parameters:

  • item (String, nil) (defaults to: nil)

    item noun to lift (uses last word only)

  • stow (String, Boolean, nil) (defaults to: nil)

    if a String, puts item in that container; if true, stows to default container; if nil/false, just lifts

Returns:

  • (Boolean)

    true if lifted (and optionally stowed) successfully



1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
# File 'documented/dragonrealms/commons/common-items.rb', line 1917

def lift?(item = nil, stow = nil)
  return false unless item

  item = item.split.last # Necessary until adjectives are implemented for lift
  case DRC.bput("lift #{item}", LIFT_SUCCESS_PATTERNS, LIFT_FAILURE_PATTERNS)
  when *LIFT_SUCCESS_PATTERNS
    if stow.is_a?(String)
      put_away_item?(item, stow)
    elsif stow
      stow_item?(item)
    else
      true
    end
  else
    false
  end
end

.list_container_contents(verb, container, retries: 2) {|String| ... } ⇒ Array<String>?

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Shared implementation for listing container contents with retry and closed-container recovery. Callers provide a block to parse the game response into an item list.

Parameters:

  • verb (String)

    command verb ("rummage" or "look in")

  • container (String)

    container noun

  • retries (Integer) (defaults to: 2)

    remaining retry attempts

Yields:

  • (String)

    game response text for parsing

Yield Returns:

  • (Array<String>)

    parsed item list

Returns:

  • (Array<String>, nil)

    parsed items, empty array if empty, nil on failure



2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
# File 'documented/dragonrealms/commons/common-items.rb', line 2059

def list_container_contents(verb, container, retries: 2, &parse_block)
  container = item_ref(container)

  if retries <= 0
    Lich::Messaging.msg("bold", "DRCI: #{verb} exceeded max retries")
    return nil
  end

  contents = DRC.bput("#{verb} #{container}", CONTAINER_IS_CLOSED_PATTERNS, RUMMAGE_SUCCESS_PATTERNS, RUMMAGE_FAILURE_PATTERNS)
  case contents
  when *RUMMAGE_FAILURE_PATTERNS
    Lich::Messaging.msg("bold", "DRCI: Unable to #{verb} '#{container}'.")
    nil
  when *CONTAINER_IS_CLOSED_PATTERNS
    unless open_container?(container)
      Lich::Messaging.msg("bold", "DRCI: Unable to open '#{container}' for #{verb}.")
      return nil
    end

    list_container_contents(verb, container, retries: retries - 1, &parse_block)
  when /there is nothing/i
    []
  else
    parse_block.call(contents)
  end
end

.look_in_container(container, retries: 2) ⇒ Array<String>?

Lists items in a container via LOOK IN.

Returns short item names. Automatically opens closed containers before looking.

Parameters:

  • container (String)

    container noun to look in

  • retries (Integer) (defaults to: 2)

    remaining retry attempts before giving up (default 2)

Returns:

  • (Array<String>, nil)

    list of item descriptions, or nil if cannot access container



2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
# File 'documented/dragonrealms/commons/common-items.rb', line 2036

def look_in_container(container, retries: 2)
  list_container_contents("look in", container, retries: retries) do |contents|
    match = contents.match(/In the .* you see (?:some|an|a) (?<items>.*)\./)
    next [] unless match

    match[:items]
      .split(/(?:,|and) (?:some|an|a)/)
      .map(&:strip)
  end
end

.lower_item?(item) ⇒ Boolean

Lowers a held item to the ground (feet slot).

Determines which hand holds the item, then issues LOWER GROUND.

Examples:

DRCI.lower_item?("sword")

Parameters:

  • item (String)

    item noun to lower

Returns:

  • (Boolean)

    true if item was lowered successfully, false if not held or failed



1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
# File 'documented/dragonrealms/commons/common-items.rb', line 1889

def lower_item?(item)
  return false unless in_hands?(item)

  item_regex = /\b#{item}\b/
  hand = (DRC.left_hand =~ item_regex) ? 'left' : 'right'
  case DRC.bput("lower ground #{hand}", *LOWER_SUCCESS_PATTERNS, *LOWER_FAILURE_PATTERNS)
  when *LOWER_SUCCESS_PATTERNS
    true
  else
    false
  end
end

.open_container?(container) ⇒ Boolean

Opens a container.

Parameters:

  • container (String)

    container noun to open

Returns:

  • (Boolean)

    true if container was opened (or already open)

See Also:



2176
2177
2178
2179
2180
2181
2182
# File 'documented/dragonrealms/commons/common-items.rb', line 2176

def open_container?(container)
  case DRC.bput("open #{container}", OPEN_CONTAINER_SUCCESS_PATTERNS, OPEN_CONTAINER_FAILURE_PATTERNS)
  when *OPEN_CONTAINER_SUCCESS_PATTERNS
    return true
  end
  return false
end

.put_away_item?(item, container = nil) ⇒ Boolean

Puts away a held item, optionally into a specific container.

If no container is specified, uses the default stow location. Accepts an array of containers to try in order (useful when some may be full).

Examples:

Stow to default location

DRCI.put_away_item?("sword")

Put in specific container

DRCI.put_away_item?("sword", "backpack")

Try multiple containers

DRCI.put_away_item?("gem", ["pouch", "sack", "backpack"])

Parameters:

  • item (String)

    item noun to put away

  • container (String, Array<String>, nil) (defaults to: nil)

    container noun, array of containers, or nil

Returns:

  • (Boolean)

    true if item was put away successfully

See Also:



2110
2111
2112
2113
2114
2115
2116
2117
2118
# File 'documented/dragonrealms/commons/common-items.rb', line 2110

def put_away_item?(item, container = nil)
  if container.is_a?(Array)
    container.each do |c|
      return true if put_away_item_safe?(item, c)
    end
    return false
  end
  put_away_item_safe?(item, container)
end

.put_away_item_safe?(item, container = nil) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Puts away an item with "my " prefix on item and container names.

Parameters:

  • item (String)

    item noun to put away

  • container (String, nil) (defaults to: nil)

    container noun, or nil for default

Returns:

  • (Boolean)

    true if item was put away successfully



2126
2127
2128
# File 'documented/dragonrealms/commons/common-items.rb', line 2126

def put_away_item_safe?(item, container = nil)
  put_away_item_unsafe?(item_ref(item), item_ref(container))
end

.put_away_item_unsafe?(item, container = nil, preposition = "in", retries: 3) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Puts away an item without "my " prefix qualification.

Supports custom prepositions (e.g., "on", "under") and retries on closed containers or retry-pattern responses.

Parameters:

  • item (String)

    item name (unqualified)

  • container (String, nil) (defaults to: nil)

    container name (unqualified), or nil for default stow

  • preposition (String) (defaults to: "in")

    container preposition ("in", "on", "under", etc.)

  • retries (Integer) (defaults to: 3)

    remaining retry attempts before giving up (default 3)

Returns:

  • (Boolean)

    true if item was put away successfully



2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
# File 'documented/dragonrealms/commons/common-items.rb', line 2141

def put_away_item_unsafe?(item, container = nil, preposition = "in", retries: 3)
  if retries <= 0
    Lich::Messaging.msg("bold", "DRCI: put_away_item_unsafe? exceeded max retries")
    return false
  end

  command = "put #{item} #{preposition} #{container}" if container
  command = "stow #{item}" unless container
  result = DRC.bput(command, CONTAINER_IS_CLOSED_PATTERNS, PUT_AWAY_ITEM_SUCCESS_PATTERNS, PUT_AWAY_ITEM_FAILURE_PATTERNS, PUT_AWAY_ITEM_RETRY_PATTERNS)
  case result
  when *CONTAINER_IS_CLOSED_PATTERNS
    return false unless container && open_container?(container)

    return put_away_item_unsafe?(item, container, preposition, retries: retries - 1)
  when *PUT_AWAY_ITEM_RETRY_PATTERNS
    return put_away_item_unsafe?(item, container, preposition, retries: retries - 1)
  when *PUT_AWAY_ITEM_SUCCESS_PATTERNS
    return true
  when *PUT_AWAY_ITEM_FAILURE_PATTERNS
    return false
  else
    return false
  end
end

.remove_and_stow_pouch?(gem_pouch_adjective, gem_pouch_noun, full_pouch_container = nil) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Removes the current gem pouch and stows it in a container.

Parameters:

  • gem_pouch_adjective (String)

    pouch adjective (e.g., "black")

  • gem_pouch_noun (String)

    pouch noun (e.g., "pouch")

  • full_pouch_container (String, nil) (defaults to: nil)

    container for the full pouch, or nil for default

Returns:

  • (Boolean)

    true if removed and stowed successfully



2331
2332
2333
2334
2335
2336
2337
2338
# File 'documented/dragonrealms/commons/common-items.rb', line 2331

def remove_and_stow_pouch?(gem_pouch_adjective, gem_pouch_noun, full_pouch_container = nil)
  pouch = "#{gem_pouch_adjective} #{gem_pouch_noun}"
  unless remove_item?(pouch)
    Lich::Messaging.msg("bold", "DRCI: Unable to remove existing pouch.")
    return false
  end
  put_away_item?(pouch, full_pouch_container) || stow_item?(pouch)
end

.remove_item?(item) ⇒ Boolean

Removes a worn item into your hands.

Issues the REMOVE command with "my " prefix qualification.

Examples:

DRCI.remove_item?("cloak")

Parameters:

  • item (String)

    item noun to remove

Returns:

  • (Boolean)

    true if item was removed successfully

See Also:



1795
1796
1797
# File 'documented/dragonrealms/commons/common-items.rb', line 1795

def remove_item?(item)
  remove_item_safe?(item)
end

.remove_item_safe?(item) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Removes a worn item with "my " prefix qualification.

Parameters:

  • item (String)

    item noun to remove

Returns:

  • (Boolean)

    true if item was removed successfully



1804
1805
1806
# File 'documented/dragonrealms/commons/common-items.rb', line 1804

def remove_item_safe?(item)
  remove_item_unsafe?(item_ref(item))
end

.remove_item_unsafe?(item) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Removes a worn item without "my " prefix qualification.

Parameters:

  • item (String)

    item name (unqualified)

Returns:

  • (Boolean)

    true if item was removed successfully



1813
1814
1815
1816
1817
1818
1819
1820
# File 'documented/dragonrealms/commons/common-items.rb', line 1813

def remove_item_unsafe?(item)
  case DRC.bput("remove #{item}", REMOVE_ITEM_SUCCESS_PATTERNS, REMOVE_ITEM_FAILURE_PATTERNS)
  when *REMOVE_ITEM_SUCCESS_PATTERNS
    return true
  else
    return false
  end
end

.rummage_container(container, retries: 2) ⇒ Array<String>?

Lists items in a container via RUMMAGE.

Returns full tap descriptions. Automatically opens closed containers before rummaging.

Parameters:

  • container (String)

    container noun to rummage

  • retries (Integer) (defaults to: 2)

    remaining retry attempts before giving up (default 2)

Returns:

  • (Array<String>, nil)

    list of item descriptions, or nil if cannot access container



2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
# File 'documented/dragonrealms/commons/common-items.rb', line 2017

def rummage_container(container, retries: 2)
  list_container_contents("rummage", container, retries: retries) do |contents|
    match = contents.match(/You rummage through .* and see (?:a|an|some) (?<items>.*)\./)
    next [] unless match

    match[:items] # Get string of just the comma separated item list
      .sub(/ and (?=a|an|some)/, ", ") # replace " and " for the last item into " , "
      .split(/, (?:a|an|some) /) # Split at a, an, or some, but only when it follows a comma
  end
end

.search?(item) ⇒ Boolean

Searches inventory for an item using the INV SEARCH command.

Examples:

DRCI.search?("deed")  #=> true if found

Parameters:

  • item (String)

    item noun to search for

Returns:

  • (Boolean)

    true if item is found in inventory



1174
1175
1176
# File 'documented/dragonrealms/commons/common-items.rb', line 1174

def search?(item)
  !!(DRC.bput("inv search #{item}", /^You can't seem to find anything/, /(?:An?|Some) .+ is (?:in|being)/) =~ /(?:An?|Some) .+ is (?:in|being)/)
end

.stow_hand(hand, retries: 3) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Stows whatever is in the specified hand.

Handles braids that are too long by disposing them as trash.

Parameters:

  • hand (String)

    "right" or "left"

  • retries (Integer) (defaults to: 3)

    remaining retry attempts before giving up (default 3)

Returns:

  • (Boolean)

    true if the hand is now empty



1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
# File 'documented/dragonrealms/commons/common-items.rb', line 1519

def stow_hand(hand, retries: 3)
  if retries <= 0
    Lich::Messaging.msg("bold", "DRCI: stow_hand exceeded max retries")
    return false
  end

  result = DRC.bput("stow #{hand}", BRAID_TOO_LONG_PATTERN, CONTAINER_IS_CLOSED_PATTERNS, STOW_ITEM_SUCCESS_PATTERNS, STOW_ITEM_FAILURE_PATTERNS, STOW_ITEM_RETRY_PATTERNS)
  braid_match = result&.match(BRAID_TOO_LONG_PATTERN)
  if braid_match
    dispose_trash(DRC.get_noun(braid_match[:braid_name]))
  elsif STOW_ITEM_RETRY_PATTERNS.any? { |pat| pat.match?(result) }
    stow_hand(hand, retries: retries - 1)
  elsif STOW_ITEM_SUCCESS_PATTERNS.any? { |pat| pat.match?(result) }
    true
  else
    false
  end
end

.stow_handsBoolean

Stows whatever is held in both hands.

Skips empty hands. Returns true only if both hands are empty or successfully stowed.

Returns:

  • (Boolean)

    true if both hands are now empty

See Also:



1494
1495
1496
1497
# File 'documented/dragonrealms/commons/common-items.rb', line 1494

def stow_hands
  (!DRC.left_hand || stow_hand('left')) &&
    (!DRC.right_hand || stow_hand('right'))
end

.stow_item?(item) ⇒ Boolean

Stows an item into its default container (per STORE HELP settings).

Issues the STOW command with "my " prefix qualification. Retries automatically on retry-pattern responses.

Examples:

DRCI.stow_item?("sword")

Parameters:

  • item (String)

    item noun to stow

Returns:

  • (Boolean)

    true if item was stowed successfully

See Also:



1838
1839
1840
# File 'documented/dragonrealms/commons/common-items.rb', line 1838

def stow_item?(item)
  stow_item_safe?(item)
end

.stow_item_safe?(item) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Stows an item with "my " prefix qualification.

Parameters:

  • item (String)

    item noun to stow

Returns:

  • (Boolean)

    true if item was stowed successfully



1847
1848
1849
# File 'documented/dragonrealms/commons/common-items.rb', line 1847

def stow_item_safe?(item)
  stow_item_unsafe?(item_ref(item))
end

.stow_item_unsafe?(item, retries: 3) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Note:

Without "my " prefix, may attempt to stow an item on the ground rather than one in your inventory.

Stows an item without "my " prefix qualification.

Parameters:

  • item (String)

    item name (unqualified)

  • retries (Integer) (defaults to: 3)

    remaining retry attempts before giving up (default 3)

Returns:

  • (Boolean)

    true if item was stowed successfully



1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
# File 'documented/dragonrealms/commons/common-items.rb', line 1860

def stow_item_unsafe?(item, retries: 3)
  if retries <= 0
    Lich::Messaging.msg("bold", "DRCI: stow_item_unsafe? exceeded max retries")
    return false
  end

  case DRC.bput("stow #{item}", CONTAINER_IS_CLOSED_PATTERNS, STOW_ITEM_SUCCESS_PATTERNS, STOW_ITEM_FAILURE_PATTERNS, STOW_ITEM_RETRY_PATTERNS)
  when *STOW_ITEM_RETRY_PATTERNS
    return stow_item_unsafe?(item, retries: retries - 1)
  when *STOW_ITEM_SUCCESS_PATTERNS
    return true
  else
    return false
  end
end

.swap_out_full_gempouch?(gem_pouch_adjective, gem_pouch_noun, full_pouch_container = nil, spare_gem_pouch_container = nil, should_tie_gem_pouches = false) ⇒ Boolean

Swaps a full gem pouch for a spare one.

Removes and stows the current pouch, then checks the belt for an existing spare before getting one from the spare container.

Parameters:

  • gem_pouch_adjective (String)

    pouch adjective (e.g., "black")

  • gem_pouch_noun (String)

    pouch noun (e.g., "pouch")

  • full_pouch_container (String, nil) (defaults to: nil)

    container for the full pouch

  • spare_gem_pouch_container (String, nil) (defaults to: nil)

    container holding spare pouches

  • should_tie_gem_pouches (Boolean) (defaults to: false)

    whether to tie the new pouch

Returns:

  • (Boolean)

    true if swap completed successfully



2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
# File 'documented/dragonrealms/commons/common-items.rb', line 2351

def swap_out_full_gempouch?(gem_pouch_adjective, gem_pouch_noun, full_pouch_container = nil, spare_gem_pouch_container = nil, should_tie_gem_pouches = false)
  unless DRC.left_hand.nil? || DRC.right_hand.nil?
    Lich::Messaging.msg("bold", "DRCI: No free hand. Not swapping pouches now.")
    return false
  end

  unless remove_and_stow_pouch?(gem_pouch_adjective, gem_pouch_noun, full_pouch_container)
    Lich::Messaging.msg("bold", "DRCI: Remove and stow pouch routine failed.")
    return false
  end

  pouch = "#{gem_pouch_adjective} #{gem_pouch_noun}"

  # Check if there's already another pouch on the belt before getting from spare container
  if check_belt_for_pouch?(gem_pouch_adjective, gem_pouch_noun)
    Lich::Messaging.msg("plain", "DRCI: Found existing #{pouch} on belt, using that.")
    unless untie_item?(pouch)
      Lich::Messaging.msg("bold", "DRCI: Could not untie existing pouch on belt.")
      return false
    end
  elsif !get_item?(pouch, spare_gem_pouch_container)
    Lich::Messaging.msg("bold", "DRCI: No spare pouch found in #{spare_gem_pouch_container || 'default container'}.")
    return false
  end

  unless wear_item?(pouch)
    Lich::Messaging.msg("bold", "DRCI: Could not wear new pouch.")
    return false
  end

  if should_tie_gem_pouches && !tie_gem_pouch?(gem_pouch_adjective, gem_pouch_noun)
    Lich::Messaging.msg("bold", "DRCI: Could not tie new pouch.")
    # Not a fatal error - pouch is worn, just not tied
  end

  true
end

.tap(item, container = nil) ⇒ String?

Taps an item and returns the game response string.

The tap response indicates whether the item is worn, inside a container, etc. Used by wearing?, inside?, and exists?.

Parameters:

  • item (String)

    item noun to tap

  • container (String, nil) (defaults to: nil)

    container to qualify the tap, or nil for general inventory

Returns:

  • (String, nil)

    game response text, or nil if item is nil



1221
1222
1223
1224
1225
1226
1227
# File 'documented/dragonrealms/commons/common-items.rb', line 1221

def tap(item, container = nil)
  return nil unless item

  from = container
  from = "from #{item_ref(container)}" if container && !(container =~ /^(in|on|under|behind|from) /i)
  DRC.bput("tap #{item_ref(item)} #{from}", *TAP_SUCCESS_PATTERNS, *TAP_FAILURE_PATTERNS)
end

.tie_gem_pouch(gem_pouch_adjective, gem_pouch_noun) ⇒ Object

Deprecated.

Use tie_gem_pouch? instead for boolean return value.



2318
2319
2320
2321
2322
# File 'documented/dragonrealms/commons/common-items.rb', line 2318

def tie_gem_pouch(gem_pouch_adjective, gem_pouch_noun)
  unless tie_gem_pouch?(gem_pouch_adjective, gem_pouch_noun)
    Lich::Messaging.msg("bold", "DRCI: Failed to tie #{gem_pouch_adjective} #{gem_pouch_noun}.")
  end
end

.tie_gem_pouch?(gem_pouch_adjective, gem_pouch_noun) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Ties a gem pouch.

Parameters:

  • gem_pouch_adjective (String)

    pouch adjective (e.g., "black")

  • gem_pouch_noun (String)

    pouch noun (e.g., "pouch")

Returns:

  • (Boolean)

    true if tied successfully or already tied



2313
2314
2315
# File 'documented/dragonrealms/commons/common-items.rb', line 2313

def tie_gem_pouch?(gem_pouch_adjective, gem_pouch_noun)
  tie_item?("#{gem_pouch_adjective} #{gem_pouch_noun}")
end

.tie_item?(item, container = nil) ⇒ Boolean

Ties an item, optionally to a specific container.

Examples:

Tie to belt

DRCI.tie_item?("pouch", "belt")

Parameters:

  • item (String)

    item noun to tie

  • container (String, nil) (defaults to: nil)

    container to tie to, or nil for default

Returns:

  • (Boolean)

    true if item was tied successfully

See Also:



1711
1712
1713
1714
1715
1716
1717
1718
1719
# File 'documented/dragonrealms/commons/common-items.rb', line 1711

def tie_item?(item, container = nil)
  place = container ? "to #{item_ref(container)}" : nil
  case DRC.bput("tie #{item_ref(item)} #{place}", TIE_ITEM_SUCCESS_PATTERNS, TIE_ITEM_FAILURE_PATTERNS)
  when *TIE_ITEM_SUCCESS_PATTERNS
    true
  else
    false
  end
end

.trash_storageArray<String>

Recognized trash-receptacle nouns: the built-in TRASH_STORAGE defaults merged with the player's custom_trash_storage additions. Lets a player teach dispose_trash about a receptacle their town has that Lich does not yet know, without a Lich release.

Returns:

  • (Array<String>)

    recognized trash-receptacle nouns

See Also:



77
78
79
# File 'documented/dragonrealms/commons/common-items.rb', line 77

def trash_storage
  CustomSubstitutions.resolve(:custom_trash_storage, TRASH_STORAGE, type: :names)
end

.untie_item?(item, container = nil) ⇒ Boolean

Unties an item, optionally from a specific container.

Parameters:

  • item (String)

    item noun to untie

  • container (String, nil) (defaults to: nil)

    container to untie from, or nil for default

Returns:

  • (Boolean)

    true if item was untied successfully

See Also:



1728
1729
1730
1731
1732
1733
1734
1735
1736
# File 'documented/dragonrealms/commons/common-items.rb', line 1728

def untie_item?(item, container = nil)
  place = container ? "from #{item_ref(container)}" : nil
  case DRC.bput("untie #{item_ref(item)} #{place}", UNTIE_ITEM_SUCCESS_PATTERNS, UNTIE_ITEM_FAILURE_PATTERNS)
  when *UNTIE_ITEM_SUCCESS_PATTERNS
    true
  else
    false
  end
end

.wear_item?(item) ⇒ Boolean

Wears an item from your hands.

Issues the WEAR command with "my " prefix qualification.

Examples:

DRCI.wear_item?("cloak")

Parameters:

  • item (String)

    item noun to wear

Returns:

  • (Boolean)

    true if item was worn successfully

See Also:



1753
1754
1755
# File 'documented/dragonrealms/commons/common-items.rb', line 1753

def wear_item?(item)
  wear_item_safe?(item)
end

.wear_item_safe?(item) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Wears an item with "my " prefix qualification.

Parameters:

  • item (String)

    item noun to wear

Returns:

  • (Boolean)

    true if item was worn successfully



1762
1763
1764
# File 'documented/dragonrealms/commons/common-items.rb', line 1762

def wear_item_safe?(item)
  wear_item_unsafe?(item_ref(item))
end

.wear_item_unsafe?(item) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Wears an item without "my " prefix qualification.

Parameters:

  • item (String)

    item name (unqualified)

Returns:

  • (Boolean)

    true if item was worn successfully



1771
1772
1773
1774
1775
1776
1777
1778
# File 'documented/dragonrealms/commons/common-items.rb', line 1771

def wear_item_unsafe?(item)
  case DRC.bput("wear #{item}", WEAR_ITEM_SUCCESS_PATTERNS, WEAR_ITEM_FAILURE_PATTERNS)
  when *WEAR_ITEM_SUCCESS_PATTERNS
    return true
  else
    return false
  end
end

.wearing?(item) ⇒ Boolean

Checks if an item is currently worn by tapping it.

Parameters:

  • item (String)

    item noun to check

Returns:

  • (Boolean)

    true if item is currently worn



1182
1183
1184
# File 'documented/dragonrealms/commons/common-items.rb', line 1182

def wearing?(item)
  !!(tap(item) =~ /wearing/)
end