Class: Lich::DragonRealms::EquipmentManager
- Inherits:
-
Object
- Object
- Lich::DragonRealms::EquipmentManager
- Defined in:
- documented/dragonrealms/commons/equipmanager.rb
Overview
Manages the equipment for the player character.
This class handles the retrieval, wearing, and stowing of items. It also manages gear sets and combat items.
Constant Summary collapse
- STOW_RECOVERY_PATTERNS =
Recovery patterns handled by stow_helper's retry logic. These are automatically appended to every stow_helper call so callers only need to pass success/failure patterns.
[ /unload/, /close the fan/, /You are a little too busy/, /You don't seem to be able to move/, /is too small to hold that/, /Your wounds hinder your ability to do that/, /Sheath your .* where/ ].freeze
- STOW_HELPER_MAX_RETRIES =
Maximum retry attempts for stow_helper before giving up.
10- UNTIE_EXHAUSTED_PATTERNS =
Non-recoverable untie failure patterns that should return false immediately in #get_item_helper. Contains every entry from DRCI::UNTIE_ITEM_FAILURE_PATTERNS EXCEPT the "too busy" patterns which are recoverable (retreat / stop playing) and live in the
:failuresarray instead.For
:wornand +:stowed+/+:transform+, exhausted is set directly to the full DRCI failure constant because their:failuresentries don't overlap.:tiedis the exception -- "too busy" appears in both DRCI failures and the recoverable:failuresarray, so this curated subset excludes them to prevent the exhausted branch from swallowing recovery.If a new pattern is added to DRCI::UNTIE_ITEM_FAILURE_PATTERNS, it must be categorized here or in
:failures-- the coverage spec enforces that no DRCI failure falls through to the timeout branch. [ /^You don't seem to be able to move/, /^You fumble with the ties/, /^Untie what/, /^What were you referring/ ].freeze
Instance Method Summary collapse
-
#desc_to_items(descs) ⇒ Array<Lich::DragonRealms::Item>
Converts a list of descriptions to corresponding items.
-
#empty_hands ⇒ void
Empties the hands by returning held gear or stowing items.
-
#get_combat_items ⇒ Array<String>
Retrieves the list of combat items currently worn.
-
#get_item?(item) ⇒ Boolean
Retrieves an item from the inventory or its transformed state.
- #get_item_helper(item, type) ⇒ Object
-
#initialize(settings = nil) ⇒ void
constructor
Initializes a new EquipmentManager instance.
-
#item_by_desc(description) ⇒ Lich::DragonRealms::Item?
Finds an item by its description.
- #item_noun_in_hands?(noun) ⇒ Boolean
-
#items(settings = nil) ⇒ Array<Lich::DragonRealms::Item>
Retrieves the list of items managed by the EquipmentManager.
- #listed_item?(desc) ⇒ Boolean (also: #is_listed_item?)
-
#matching_combat_items(list) ⇒ Array<Lich::DragonRealms::Item>
(also: #worn_items)
Filters the combat items based on a provided list.
-
#notify_missing(lost_items) ⇒ void
Notifies the user of any missing items.
-
#remove_gear_by {|item| ... } ⇒ Array<Lich::DragonRealms::Item>
Removes gear based on a given condition defined in the block.
-
#remove_item(item, retries: 2) ⇒ Boolean
Removes a specified item from the player's inventory.
-
#remove_unmatched_items(combat_items, target_items) ⇒ Array<Lich::DragonRealms::Item>
Removes items from combat that do not match the target items.
-
#return_held_gear(gear_set = 'standard') ⇒ void
Returns any gear currently held in the hands to the specified gear set.
- #stow_by_type(item) ⇒ Object
-
#stow_helper(action, weapon_name, *accept_strings, failure_patterns: [], retries: STOW_HELPER_MAX_RETRIES) ⇒ Boolean
Helper method to stow an item with retries and recovery patterns.
- #stow_weapon(description = nil, transform_depth: 3) ⇒ Object
- #swap_to_skill?(noun, skill) ⇒ Boolean
- #turn_to_weapon?(old_noun, new_noun) ⇒ Boolean
- #unload_weapon(name) ⇒ Object
-
#verb_data(item) ⇒ Object
Builds a hash of verb configurations for retrieving an item by type.
-
#wear_equipment_set?(set_name) ⇒ Boolean
Wears an entire equipment set by name.
-
#wear_item?(item) ⇒ Boolean
Wears a specified item if it is available.
-
#wear_items(items_list) ⇒ void
Wears the specified items from the list.
-
#wear_missing_items(target_items, combat_items) ⇒ Array<Lich::DragonRealms::Item>
Wears items that are missing from the combat items list.
-
#wield_weapon?(description, skill = nil) ⇒ Boolean
(also: #wield_weapon)
Wields a weapon in the main hand.
-
#wield_weapon_offhand?(description, skill = nil) ⇒ Boolean
(also: #wield_weapon_offhand)
Wields a weapon in the offhand if possible.
Constructor Details
#initialize(settings = nil) ⇒ void
Initializes a new EquipmentManager instance.
31 32 33 |
# File 'documented/dragonrealms/commons/equipmanager.rb', line 31 def initialize(settings = nil) items(settings) end |
Instance Method Details
#desc_to_items(descs) ⇒ Array<Lich::DragonRealms::Item>
Converts a list of descriptions to corresponding items.
97 98 99 |
# File 'documented/dragonrealms/commons/equipmanager.rb', line 97 def desc_to_items(descs) descs.map { |description| item_by_desc(description) }.compact end |
#empty_hands ⇒ void
This method returns an undefined value.
Empties the hands by returning held gear or stowing items.
384 385 386 |
# File 'documented/dragonrealms/commons/equipmanager.rb', line 384 def empty_hands return_held_gear || DRCI.stow_hands end |
#get_combat_items ⇒ Array<String>
Retrieves the list of combat items currently worn.
159 160 161 162 163 164 |
# File 'documented/dragonrealms/commons/equipmanager.rb', line 159 def get_combat_items snapshot = Lich::Util.issue_command("inv combat", /All of your worn combat|You aren't wearing anything like that/, /Use INVENTORY HELP for more options/, usexml: false, include_end: false) return [] unless snapshot snapshot.map(&:strip) - ["All of your worn combat equipment:", "You aren't wearing anything like that."] end |
#get_item?(item) ⇒ Boolean
Retrieves an item from the inventory or its transformed state.
323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 |
# File 'documented/dragonrealms/commons/equipmanager.rb', line 323 def get_item?(item) return true if DRCI.in_hands?(item) if item.wield case DRC.bput("wield my #{item.short_name}", *DRCI::WIELD_ITEM_SUCCESS_PATTERNS, *DRCI::WIELD_ITEM_FAILURE_PATTERNS) when *DRCI::WIELD_ITEM_SUCCESS_PATTERNS return true else Lich::Messaging.msg("bold", "EquipmentManager: Unable to wield #{item.short_name}") return false end elsif item.transforms_to transform_item = item_by_desc(item.transforms_to) unless transform_item Lich::Messaging.msg("bold", "EquipmentManager: Could not find transformed item matching '#{item.transforms_to}' in gear list") return false end unless transform_item.worn ? get_item_helper(transform_item, :worn) : get_item_helper(transform_item, :stowed) Lich::Messaging.msg("bold", "EquipmentManager: Unable to retrieve #{transform_item.short_name} for transform") return false end get_item_helper(transform_item, :transform) elsif (item.tie_to && get_item_helper(item, :tied)) || (item.worn && get_item_helper(item, :worn)) || (item.container && DRCI.get_item(item.short_name, item.container)) || get_item_helper(item, :stowed) true else Lich::Messaging.msg("bold", "EquipmentManager: Could not find #{item.short_name} anywhere") false end end |
#get_item_helper(item, type) ⇒ Object
498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 |
# File 'documented/dragonrealms/commons/equipmanager.rb', line 498 def get_item_helper(item, type) return false unless item data = verb_data(item)[type] snapshot = [DRC.left_hand, DRC.right_hand] waitrt? response = DRC.bput("#{data[:verb]} my #{item.short_name}", *data[:matches]) waitrt? # Handle empty/nil response (bput timeout) as failure if response.nil? || response.empty? Lich::Messaging.msg("bold", "EquipmentManager: No response from game for '#{data[:verb]} my #{item.short_name}' - command may have been lost") return false end # For non-transform types, verify success via the XML game-object # feed rather than trusting bput's text match. This prevents false # positives where an unrelated game message (e.g., "You get the # feeling...") matches /^You get/ in GET_ITEM_SUCCESS_PATTERNS, # causing bput to return "You get" which then triggers the failure # recovery proc and stows the item that was just retrieved. # See elanthia-online/lich-5#1286 for the same approach in # DRCI.get_item_unsafe. # Transform is excluded because the item changes identity (e.g., # orb -> armor) so noun verification against the original item # would fail. if type != :transform noun = DRC.get_noun(item.short_name) 10.times do break if item_noun_in_hands?(noun) pause 0.05 end return true if item_noun_in_hands?(noun) end case response when 'You are already holding' return true when *data[:exhausted] return false when *data[:failures] data[:failure_recovery].call(item.name, item, response) # Check if hands changed from pre-command snapshot, consistent with # the success (else) branch. Using in_hands?(item) here would fail # for :transform where the item changes identity (e.g., orb -> armor). return snapshot != [DRC.left_hand, DRC.right_hand] else # Wait for hands to change with a timeout to prevent infinite loop timeout = Time.now + 5 pause 0.05 while snapshot == [DRC.left_hand, DRC.right_hand] && Time.now < timeout if snapshot == [DRC.left_hand, DRC.right_hand] Lich::Messaging.msg("bold", "EquipmentManager: Hands did not change after '#{data[:verb]} my #{item.short_name}' - item may not have been retrieved") return false end return true end end |
#item_by_desc(description) ⇒ Lich::DragonRealms::Item?
Finds an item by its description.
104 105 106 |
# File 'documented/dragonrealms/commons/equipmanager.rb', line 104 def item_by_desc(description) items.find { |item| item.short_regex =~ description } end |
#item_noun_in_hands?(noun) ⇒ Boolean
556 557 558 |
# File 'documented/dragonrealms/commons/equipmanager.rb', line 556 def item_noun_in_hands?(noun) [DRC.left_hand_noun, DRC.right_hand_noun].compact.include?(noun) end |
#items(settings = nil) ⇒ Array<Lich::DragonRealms::Item>
Retrieves the list of items managed by the EquipmentManager. If the items have not been initialized, it will load them from settings.
39 40 41 42 43 44 45 46 47 |
# File 'documented/dragonrealms/commons/equipmanager.rb', line 39 def items(settings = nil) return @items if @items settings ||= get_settings @gear_sets = {} settings.gear_sets.each { |set_name, gear_list| @gear_sets[set_name] = gear_list.flatten.uniq } @sort_head = settings.sort_auto_head @items = settings.gear.map { |item| DRC::Item.new(name: item[:name], leather: item[:is_leather], hinders_locks: item[:hinders_lockpicking], worn: item[:is_worn], swappable: item[:swappable], tie_to: item[:tie_to], adjective: item[:adjective], bound: item[:bound], wield: item[:wield], transforms_to: item[:transforms_to], transform_verb: item[:transform_verb], transform_text: item[:transform_text], lodges: item[:lodges], ranged: item[:ranged], needs_unloading: item[:needs_unloading], skip_repair: item[:skip_repair], container: item[:container]) } end |
#listed_item?(desc) ⇒ Boolean Also known as: is_listed_item?
353 354 355 |
# File 'documented/dragonrealms/commons/equipmanager.rb', line 353 def listed_item?(desc) items.find { |item| item.short_regex =~ desc } end |
#matching_combat_items(list) ⇒ Array<Lich::DragonRealms::Item> Also known as: worn_items
Filters the combat items based on a provided list.
169 170 171 172 173 |
# File 'documented/dragonrealms/commons/equipmanager.rb', line 169 def matching_combat_items(list) filter_gear = desc_to_items(list) gear = desc_to_items(get_combat_items) gear.select { |x| filter_gear.include?(x) } end |
#notify_missing(lost_items) ⇒ void
This method returns an undefined value.
Notifies the user of any missing items.
111 112 113 114 115 116 117 118 119 |
# File 'documented/dragonrealms/commons/equipmanager.rb', line 111 def notify_missing(lost_items) return unless lost_items && !lost_items.empty? DRC.beep Lich::Messaging.msg("bold", "EquipmentManager: MISSING EQUIPMENT - Please verify these items are in a closed container and not lost:") Lich::Messaging.msg("bold", "EquipmentManager: #{lost_items.map(&:short_name).join(', ')}") pause DRC.beep end |
#remove_gear_by {|item| ... } ⇒ Array<Lich::DragonRealms::Item>
Removes gear based on a given condition defined in the block.
52 53 54 55 56 57 |
# File 'documented/dragonrealms/commons/equipmanager.rb', line 52 def remove_gear_by(&_block) combat_items = get_combat_items gear = desc_to_items(combat_items).select { |item| yield(item) } gear.each { |item| remove_item(item) } gear end |
#remove_item(item, retries: 2) ⇒ Boolean
Removes a specified item from the player's inventory.
181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 |
# File 'documented/dragonrealms/commons/equipmanager.rb', line 181 def remove_item(item, retries: 2) if retries <= 0 Lich::Messaging.msg("bold", "EquipmentManager: remove_item exceeded max retries for #{item.short_name}") return false end result = DRC.bput("remove my #{item.short_name}", *DRCI::REMOVE_ITEM_SUCCESS_PATTERNS, *DRCI::REMOVE_ITEM_FAILURE_PATTERNS, "then constricts tighter around your") waitrt? case result when /then constricts tighter around your/ # Items that auto-repair, like exoskeletal armor, # may have a timer on them that prevents you removing them. Lich::Messaging.msg("bold", "EquipmentManager: The #{item.short_name} is not ready to be removed yet. Try again later.") return false when *DRCI::REMOVE_ITEM_FAILURE_PATTERNS # We may need to empty our hands to remove the item. # For example, exoskeletal armor requires two hands. temp_left_item = DRC.left_hand temp_right_item = DRC.right_hand # Lower the items because that preserves loaded bows. # Stowing them in a container would require unloading. did_lower = [temp_left_item, temp_right_item].compact.all? { |item_in_hand| DRCI.lower_item?(item_in_hand) } if did_lower remove_item(item, retries: retries - 1) else Lich::Messaging.msg("bold", "EquipmentManager: Unable to empty your hands to remove #{item.short_name}") end # Pick up the items in reverse order you lowered them # so that they end up in the correct hands again. DRCI.get_item_if_not_held?(temp_right_item) if temp_right_item DRCI.get_item_if_not_held?(temp_left_item) if temp_left_item # In case they end up in different hands, swap. if DRC.left_hand != temp_left_item || DRC.right_hand != temp_right_item swap_result = DRC.bput('swap', *DRCI::SWAP_HANDS_SUCCESS_PATTERNS, *DRCI::SWAP_HANDS_FAILURE_PATTERNS) unless DRCI::SWAP_HANDS_SUCCESS_PATTERNS.any? { |p| p.match?(swap_result) } Lich::Messaging.msg("bold", "EquipmentManager: Unable to restore hand order after removing #{item.short_name}") end end when *DRCI::REMOVE_ITEM_SUCCESS_PATTERNS # If removing item transforms it (e.g. exoskeletal armor => orb) then continue with the transformed item. if item.transforms_to && DRCI.in_hands?(item.transforms_to) transform_desc = item.transforms_to item = item_by_desc(transform_desc) unless item Lich::Messaging.msg("bold", "EquipmentManager: Could not find transformed item matching '#{transform_desc}' in gear list") return false end end if item.tie_to || item.wield || item.container stow_by_type(item) elsif /more room|too long to fit/ =~ DRC.bput("stow my #{item.short_name}", *DRCI::PUT_AWAY_ITEM_SUCCESS_PATTERNS, 'There isn\'t any more room', 'straps have all been used', 'is too long to fit') wear_item?(item) end end waitrt? end |
#remove_unmatched_items(combat_items, target_items) ⇒ Array<Lich::DragonRealms::Item>
Removes items from combat that do not match the target items.
144 145 146 147 148 149 150 151 152 153 154 155 |
# File 'documented/dragonrealms/commons/equipmanager.rb', line 144 def remove_unmatched_items(combat_items, target_items) if UserVars.equipmanager_debug Lich::Messaging.msg("plain", "EquipmentManager: removing unmatched items between these two sets") Lich::Messaging.msg("plain", "EquipmentManager: combat: #{combat_items.join(',')}") Lich::Messaging.msg("plain", "EquipmentManager: target: #{target_items.map(&:short_name).join(',')}") end combat_items .reject { |description| target_items.find { |item| item.short_regex =~ description } } .map { |description| items.find { |item| item.short_regex =~ description } } .compact .each { |item| remove_item(item) } end |
#return_held_gear(gear_set = 'standard') ⇒ void
This method returns an undefined value.
Returns any gear currently held in the hands to the specified gear set.
362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 |
# File 'documented/dragonrealms/commons/equipmanager.rb', line 362 def return_held_gear(gear_set = 'standard') return unless DRC.right_hand || DRC.left_hand todo = [DRC.left_hand, DRC.right_hand].compact gear_set_items = desc_to_items(@gear_sets[gear_set] || []) todo.all? do |held_item| if (info = gear_set_items.find { |item| item.short_regex =~ held_item }) unload_weapon(info.short_name) if info.needs_unloading stow_helper("wear my #{info.short_name}", info.short_name, *DRCI::WEAR_ITEM_SUCCESS_PATTERNS, failure_patterns: DRCI::WEAR_ITEM_FAILURE_PATTERNS) elsif (info = items.find { |item| item.short_regex =~ held_item }) unload_weapon(info.short_name) if info.needs_unloading stow_by_type(info) else false end end end |
#stow_by_type(item) ⇒ Object
729 730 731 732 733 734 735 736 737 738 739 |
# File 'documented/dragonrealms/commons/equipmanager.rb', line 729 def stow_by_type(item) if item.tie_to stow_helper("tie my #{item.short_name} to my #{item.tie_to}", item.short_name, *DRCI::TIE_ITEM_SUCCESS_PATTERNS, failure_patterns: DRCI::TIE_ITEM_FAILURE_PATTERNS) elsif item.wield stow_helper("sheath my #{item.short_name}", item.short_name, *DRCI::SHEATH_ITEM_SUCCESS_PATTERNS, failure_patterns: DRCI::SHEATH_ITEM_FAILURE_PATTERNS) elsif item.container stow_helper("put my #{item.short_name} in my #{item.container}", item.short_name, *DRCI::PUT_AWAY_ITEM_SUCCESS_PATTERNS, failure_patterns: DRCI::PUT_AWAY_ITEM_FAILURE_PATTERNS) else stow_helper("stow my #{item.short_name}", item.short_name, *DRCI::PUT_AWAY_ITEM_SUCCESS_PATTERNS, failure_patterns: DRCI::PUT_AWAY_ITEM_FAILURE_PATTERNS) end end |
#stow_helper(action, weapon_name, *accept_strings, failure_patterns: [], retries: STOW_HELPER_MAX_RETRIES) ⇒ Boolean
Helper method to stow an item with retries and recovery patterns.
748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 |
# File 'documented/dragonrealms/commons/equipmanager.rb', line 748 def stow_helper(action, weapon_name, *accept_strings, failure_patterns: [], retries: STOW_HELPER_MAX_RETRIES) if retries <= 0 Lich::Messaging.msg("bold", "EquipmentManager: stow_helper exceeded max retries for '#{action}'") return false end result = DRC.bput(action, *accept_strings, *failure_patterns, *STOW_RECOVERY_PATTERNS) if result.nil? || result.empty? Lich::Messaging.msg("bold", "EquipmentManager: stow_helper got no response for '#{action}'") return false end case result when /unload/ unload_weapon(weapon_name) return stow_helper(action, weapon_name, *accept_strings, failure_patterns: failure_patterns, retries: retries - 1) when /close the fan/ fput("close my #{weapon_name}") return stow_helper(action, weapon_name, *accept_strings, failure_patterns: failure_patterns, retries: retries - 1) when /You are a little too busy/ DRC.retreat return stow_helper(action, weapon_name, *accept_strings, failure_patterns: failure_patterns, retries: retries - 1) when /You don't seem to be able to move/ pause 1 return stow_helper(action, weapon_name, *accept_strings, failure_patterns: failure_patterns, retries: retries - 1) when /is too small to hold that/ fput("swap my #{weapon_name}") return stow_helper(action, weapon_name, *accept_strings, failure_patterns: failure_patterns, retries: retries - 1) when /Your wounds hinder your ability to do that/, /Sheath your .* where/ return stow_helper("stow my #{weapon_name}", weapon_name, *DRCI::PUT_AWAY_ITEM_SUCCESS_PATTERNS, failure_patterns: DRCI::PUT_AWAY_ITEM_FAILURE_PATTERNS, retries: retries - 1) when *STOW_RECOVERY_PATTERNS # Catch-all for any recovery pattern not explicitly handled above Lich::Messaging.msg("bold", "EquipmentManager: stow_helper unhandled recovery for '#{action}': #{result}") return false end # Check if the result matched an explicit failure pattern if failure_patterns.any? { |p| p.match?(result) } Lich::Messaging.msg("bold", "EquipmentManager: stow_helper failed for '#{action}': #{result}") return false end true end |
#stow_weapon(description = nil, transform_depth: 3) ⇒ Object
699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 |
# File 'documented/dragonrealms/commons/equipmanager.rb', line 699 def stow_weapon(description = nil, transform_depth: 3) unless description return unless DRC.right_hand || DRC.left_hand stow_weapon(DRC.right_hand) if DRC.right_hand stow_weapon(DRC.left_hand) if DRC.left_hand return end weapon = item_by_desc(description) return unless weapon # Is this a weapon that needs to be unloaded before it is put away? # This is an optimization attempt so that the script # isn't trying to unload every weapon that gets put away. # Would be silly to try "unload my scimitar" wouldn't it? :grins: unload_weapon(weapon.short_name) if weapon.needs_unloading if weapon.worn stow_helper("wear my #{weapon.short_name}", weapon.short_name, *DRCI::WEAR_ITEM_SUCCESS_PATTERNS, failure_patterns: DRCI::WEAR_ITEM_FAILURE_PATTERNS) elsif weapon.transforms_to if transform_depth <= 0 Lich::Messaging.msg("bold", "EquipmentManager: stow_weapon exceeded max transform depth for #{weapon.short_name}") return end stow_helper("#{weapon.transform_verb} my #{weapon.short_name}", weapon.short_name, weapon.transform_text) stow_weapon(weapon.transforms_to, transform_depth: transform_depth - 1) else stow_by_type(weapon) end end |
#swap_to_skill?(noun, skill) ⇒ Boolean
573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 |
# File 'documented/dragonrealms/commons/equipmanager.rb', line 573 def swap_to_skill?(noun, skill) if noun =~ /\bfan\b/i command = skill =~ /edged/i ? 'open' : 'close' DRC.bput("#{command} my fan", 'you snap', 'already') return true end proper_skill = case skill when /^he$|heavy edge|large edge|one-handed/i 'heavy edged' when /^2he$|^the$|twohanded edge|two-handed edge/i 'two-handed edged' when /^hb$|heavy blunt|large blunt/i 'heavy blunt' when /^2hb$|^thb$|twohanded blunt|two-handed blunt/i 'two-handed blunt' when /^se$|small edged|light edge|medium edge/i '(light edged|medium edged)' when /^sb$|small blunt|light blunt|medium blunt/i '(light blunt|medium blunt)' when /^lt$|light thrown/i 'light thrown' when /^ht$|heavy thrown/i 'heavy thrown' when /stave/i '(short|quarter) staff' when /polearms/i '(halberd|pike)' when /^ow$|offhand weapon/i return true # just use weapon in your left hand else Lich::Messaging.msg("bold", "EquipmentManager: Unsupported weapon swap: #{noun} to #{skill}. Please report this to https://github.com/elanthia-online/lich-5/issues") return false end # All possible weapon skills to swap into. weapon_skills = [ 'light edged', 'medium edged', 'heavy edged', 'two-handed edged', 'light blunt', 'medium blunt', 'heavy blunt', 'two-handed blunt', 'light thrown', 'heavy thrown', 'short staff', 'quarter staff', 'halberd', 'pike' ] failure_matches = [ /You have nothing to swap/, /Your (left|right) hand is too injured/, /Will alone cannot conquer the paralysis that has wracked your body/, /^You move a .* to your (left|right) hand/ ] # The spaces in the regex are deliberate skill_match = / #{proper_skill} /i swapped_count = 0 loop do pause 0.25 # Avoid infinite loop where weapon can't swap to desired skill. return false if swapped_count > weapon_skills.length swapped_count += 1 # Try to swap weapon to desired skill. case DRC.bput("swap my #{noun}", skill_match, /\b#{noun}\b.*(#{weapon_skills.join('|')})/, "You must have two free hands", *failure_matches) when /You must have two free hands/ DRCI.stow_hand('left') if DRC.left_hand && DRC.left_hand !~ /#{noun}/i DRCI.stow_hand('right') if DRC.right_hand && DRC.right_hand !~ /#{noun}/i hands_free = [DRC.left_hand, DRC.right_hand].compact.all? { |h| h =~ /#{noun}/i } unless hands_free Lich::Messaging.msg("bold", "EquipmentManager: Unable to free hands for weapon swap") return false end when *failure_matches return false when skill_match return true end end end |
#turn_to_weapon?(old_noun, new_noun) ⇒ Boolean
560 561 562 563 564 565 566 567 568 569 570 571 |
# File 'documented/dragonrealms/commons/equipmanager.rb', line 560 def turn_to_weapon?(old_noun, new_noun) return true if old_noun == new_noun result = DRC.bput("turn my #{old_noun} to #{new_noun}", /^Turn what?/i, /^Which weapon did you want to pull out/i, /^Your .*\b#{old_noun}.* shifts .*/i) waitrt? # turning may incur roundtime case result when /^Your .*\b#{old_noun}.* shifts .* before resolving itself into .*\b#{new_noun}/i true else false end end |
#unload_weapon(name) ⇒ Object
657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 |
# File 'documented/dragonrealms/commons/equipmanager.rb', line 657 def unload_weapon(name) result = DRC.bput("unload my #{name}", *DRCI::UNLOAD_WEAPON_SUCCESS_PATTERNS, *DRCI::UNLOAD_WEAPON_FAILURE_PATTERNS) ammo_match = result&.match(/^(?:Your .*?\b(?<ammo>[\w]+)\b fall.* from your .* to your feet\.)$/) if ammo_match # Ammo fell to ground because hands are full. # Lower weapon, stow ammo, then pick it back up. ammo = ammo_match[:ammo] unless DRCI.lower_item?(name) Lich::Messaging.msg("bold", "EquipmentManager: Unable to lower #{name} to pick up ammo") return end DRCI.put_away_item?(ammo) unless DRCI.get_item?(name) Lich::Messaging.msg("bold", "EquipmentManager: Unable to pick #{name} back up after unloading") end elsif result&.match?(/As you release the string/) # Ammo tumbled to the ground (e.g., "As you release the string, the arrow tumbles to the ground.") # Same recovery as ammo falling to feet: lower weapon, stow ammo, pick weapon back up. ammo_ground_match = result.match(/the (?<ammo>\w+) tumbles/) if ammo_ground_match ammo = ammo_ground_match[:ammo] unless DRCI.lower_item?(name) Lich::Messaging.msg("bold", "EquipmentManager: Unable to lower #{name} to pick up ammo") return end DRCI.put_away_item?(ammo) unless DRCI.get_item?(name) Lich::Messaging.msg("bold", "EquipmentManager: Unable to pick #{name} back up after unloading") end end elsif result&.match?(/^(?:You unload|You .* unloading)/) # Ammo is in hand, stow whichever hand isn't holding the weapon. unless DRCI.in_left_hand?(name) Lich::Messaging.msg("bold", "EquipmentManager: Unable to stow ammo from left hand") unless DRCI.stow_hand('left') end unless DRCI.in_right_hand?(name) Lich::Messaging.msg("bold", "EquipmentManager: Unable to stow ammo from right hand") unless DRCI.stow_hand('right') end end waitrt? end |
#verb_data(item) ⇒ Object
Builds a hash of verb configurations for retrieving an item by type.
Each type (+:worn+, :tied, :stowed, :transform) maps to a hash
with the game verb, match patterns, failure patterns, and recovery procs.
Match patterns reference DRCI constants so that new game messages added
415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 |
# File 'documented/dragonrealms/commons/equipmanager.rb', line 415 def verb_data(item) { worn: { verb: 'remove', matches: [ /^You .*#{item.short_regex}/, /^You (get|sling|pull|work|loosen|slide|remove|yank|unbuckle).*#{item.name}/, *DRCI::REMOVE_ITEM_SUCCESS_PATTERNS, *DRCI::REMOVE_ITEM_FAILURE_PATTERNS ], failures: [/^You (get|sling|pull|work|slide|remove|yank|unbuckle) $/], failure_recovery: proc { |noun| DRC.bput("wear my #{noun}", '^You ') }, exhausted: DRCI::REMOVE_ITEM_FAILURE_PATTERNS }, tied: { verb: 'untie', matches: [ /^You .*#{item.short_regex}/, /^You remove.*#{item.name}/, /^.*you untie your .*#{item.short_regex} from it./, *DRCI::UNTIE_ITEM_SUCCESS_PATTERNS, *DRCI::UNTIE_ITEM_FAILURE_PATTERNS ], # NOTE: /^You remove$/ (with end anchor) prevents matching successful # untie responses like "You remove a sword from your belt" -- only # matches the bare "You remove" edge case. failures: [/^You remove$/, /^You are a little too busy/, /^You are a bit too busy/], # NOTE: response is accepted as a single String (not *splat) so that # case/when uses Regexp#=== for proper pattern matching. The original # *matches splat wrapped the response in an Array, making Regexp-based # when clauses silently fall through to else. failure_recovery: proc { |_noun, item_to_recover, response| case response when /You are a little too busy/ DRC.retreat get_item?(item_to_recover) when /You are a bit too busy/ DRC. get_item?(item_to_recover) else stow_weapon end }, exhausted: UNTIE_EXHAUSTED_PATTERNS }, stowed: { verb: 'get', matches: [ /^You .*#{item.short_regex}/, /^You .*#{item.name}/, *DRCI::GET_ITEM_SUCCESS_PATTERNS, *DRCI::GET_ITEM_FAILURE_PATTERNS, /^The.* slides easily out/, /But that is already/ ], failures: [/^You get$/, /But that is already/], failure_recovery: proc { |noun| DRC.bput("stow my #{noun}", 'You put', 'But that is already in') }, exhausted: DRCI::GET_ITEM_FAILURE_PATTERNS }, transform: { verb: item.transform_verb, matches: [ item.transform_text, /You'll need a free hand to do that!/, /You don't seem to be holding/, *DRCI::GET_ITEM_FAILURE_PATTERNS ], failures: [/You'll need a free hand to do that!/, /You don't seem to be holding/], failure_recovery: proc do |noun| DRCI.stow_hand('left') if DRC.left_hand && DRC.left_hand !~ /#{noun}/i DRCI.stow_hand('right') if DRC.right_hand && DRC.right_hand !~ /#{noun}/i if (DRC.left_hand && DRC.left_hand !~ /#{noun}/i) || (DRC.right_hand && DRC.right_hand !~ /#{noun}/i) Lich::Messaging.msg("bold", "EquipmentManager: Unable to free hands for transform") next end item.worn ? DRC.bput("remove my #{noun}", '^You') : DRC.bput("get my #{noun}", '^You') DRC.bput("#{item.transform_verb} my #{item.short_name}", *verb_data(item)[:transform][:matches]) end, exhausted: DRCI::GET_ITEM_FAILURE_PATTERNS } } end |
#wear_equipment_set?(set_name) ⇒ Boolean
Wears an entire equipment set by name.
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'documented/dragonrealms/commons/equipmanager.rb', line 71 def wear_equipment_set?(set_name) return false unless set_name unless @gear_sets[set_name] Lich::Messaging.msg("bold", "EquipmentManager: Could not find gear set '#{set_name}'") return false end gear_set_items = desc_to_items(@gear_sets[set_name]) Lich::Messaging.msg("plain", "EquipmentManager: expected worn items: #{gear_set_items.map(&:short_name).join(',')}") if UserVars.equipmanager_debug combat_items = get_combat_items remove_unmatched_items(combat_items, gear_set_items) lost_items = wear_missing_items(gear_set_items, combat_items) notify_missing(lost_items) DRC.bput('sort auto head', /^Your inventory is now arranged/) if @sort_head lost_items.empty? end |
#wear_item?(item) ⇒ Boolean
Wears a specified item if it is available.
241 242 243 244 245 246 247 248 249 250 |
# File 'documented/dragonrealms/commons/equipmanager.rb', line 241 def wear_item?(item) if item.nil? Lich::Messaging.msg("bold", "EquipmentManager: Failed to match an item, try turning on debugging with #{$clean_lich_char}e UserVars.equipmanager_debug = true") return false end if get_item?(item) return DRCI.wear_item?(item.short_name) end return false end |
#wear_items(items_list) ⇒ void
This method returns an undefined value.
Wears the specified items from the list.
62 63 64 65 66 |
# File 'documented/dragonrealms/commons/equipmanager.rb', line 62 def wear_items(items_list) items_list.each { |item| wear_item?(item) } DRC.bput('sort auto head', /^Your inventory is now arranged/) if @sort_head end |
#wear_missing_items(target_items, combat_items) ⇒ Array<Lich::DragonRealms::Item>
Wears items that are missing from the combat items list.
125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
# File 'documented/dragonrealms/commons/equipmanager.rb', line 125 def wear_missing_items(target_items, combat_items) if UserVars.equipmanager_debug Lich::Messaging.msg("plain", "EquipmentManager: wearing missing items between these two sets") Lich::Messaging.msg("plain", "EquipmentManager: combat: #{combat_items.join(',')}") Lich::Messaging.msg("plain", "EquipmentManager: target: #{target_items.map(&:short_name).join(',')}") end missing_items = target_items .reject { |item| combat_items.find { |c_item| item.short_regex =~ c_item } } .reject { |item| [DRC.right_hand, DRC.left_hand].grep(item.short_regex).any? ? (stow_weapon(item.short_name) || true) : false } Lich::Messaging.msg("plain", "EquipmentManager: wear missing items #{missing_items}") if !missing_items.empty? && UserVars.equipmanager_debug missing_items.reject { |item| wear_item?(item) } end |
#wield_weapon?(description, skill = nil) ⇒ Boolean Also known as: wield_weapon
Wields a weapon in the main hand.
286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 |
# File 'documented/dragonrealms/commons/equipmanager.rb', line 286 def wield_weapon?(description, skill = nil) return unless description && !description.empty? offhand = skill == 'Offhand Weapon' weapon = item_by_desc(description) unless weapon Lich::Messaging.msg("bold", "EquipmentManager: Failed to match a weapon for #{description}:#{skill}") return false end if [DRC.left_hand, DRC.right_hand].grep(weapon.short_regex).any? stow_weapon end if get_item?(weapon) swap_to_skill?(weapon.name, skill) if skill && weapon.swappable if offhand && DRC.right_hand case DRC.bput('swap', *DRCI::SWAP_HANDS_SUCCESS_PATTERNS, *DRCI::SWAP_HANDS_FAILURE_PATTERNS) when *DRCI::SWAP_HANDS_SUCCESS_PATTERNS return true else return false end end return true end return false end |
#wield_weapon_offhand?(description, skill = nil) ⇒ Boolean Also known as: wield_weapon_offhand
Wields a weapon in the offhand if possible.
256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 |
# File 'documented/dragonrealms/commons/equipmanager.rb', line 256 def wield_weapon_offhand?(description, skill = nil) return unless description && !description.empty? weapon = item_by_desc(description) unless weapon Lich::Messaging.msg("bold", "EquipmentManager: Failed to match a weapon for #{description}:#{skill}") return false end if get_item?(weapon) swap_to_skill?(weapon.name, skill) if skill && weapon.swappable if DRCI.in_right_hand?(weapon) case DRC.bput('swap', *DRCI::SWAP_HANDS_SUCCESS_PATTERNS, *DRCI::SWAP_HANDS_FAILURE_PATTERNS) when *DRCI::SWAP_HANDS_SUCCESS_PATTERNS return true else return false end end end return false end |