Module: Lich::Stash

Defined in:
documented/stash.rb

Overview

Provides methods for managing containers and items in the Lich game.

Examples:

Using the Stash module

Lich::Stash.find_container("my_container")

Class Method Summary collapse

Class Method Details

.add_to_bag(bag, item) ⇒ Boolean

Adds an item to a specified bag/container.

Examples:

Adding an item to a bag

result = Lich::Stash.add_to_bag("my_bag", item)

Parameters:

  • bag (String, GameObj)

    The name of the bag or a GameObj instance.

  • item (GameObj)

    The item to add to the bag.

Returns:

  • (Boolean)

    True if the item was successfully added, false otherwise.



67
68
69
70
71
72
73
74
75
76
77
78
# File 'documented/stash.rb', line 67

def self.add_to_bag(bag, item)
  bag = container(bag)
  try_or_fail(command: "_drag ##{item.id} ##{bag.id}") do
    20.times {
      return true if ![GameObj.right_hand, GameObj.left_hand].map(&:id).compact.include?(item.id) && @weapon_displayer.include?(bag.id)
      return true if (![GameObj.right_hand, GameObj.left_hand].map(&:id).compact.include?(item.id) and bag.contents.to_a.map(&:id).include?(item.id))
      return true if item.name =~ /^ethereal \w+$/ && ![GameObj.right_hand, GameObj.left_hand].map(&:id).compact.include?(item.id)
      sleep 0.1
    }
    return false
  end
end

.container(param) ⇒ GameObj

Retrieves a container and ensures it is displayed.

Examples:

Checking a container

container = Lich::Stash.container("my_container")

Parameters:

  • param (String, GameObj)

    The name of the container or a GameObj instance.

Returns:

  • (GameObj)

    The checked container.



36
37
38
39
40
41
42
43
44
45
# File 'documented/stash.rb', line 36

def self.container(param)
  @weapon_displayer ||= []
  container_to_check = find_container(param)
  unless @weapon_displayer.include?(container_to_check.id)
    result = Lich::Util.issue_command("look in ##{container_to_check.id}", /In the .*$|That is closed\.|^You glance at/, silent: true, quiet: true) if container_to_check.contents.nil?
    fput "open ##{container_to_check.id}" if result.include?('That is closed.')
    @weapon_displayer.push(container_to_check.id) if GameObj.containers.find { |item| item[0] == container_to_check.id }.nil?
  end
  return container_to_check
end

.equip_hands(left: false, right: false, both: false) ⇒ void

This method returns an undefined value.

Equips items from the stash back into the hands.

Examples:

Equipping hands

Lich::Stash.equip_hands(both: true)

Parameters:

  • left (Boolean) (defaults to: false)

    Whether to equip the left hand (default: false).

  • right (Boolean) (defaults to: false)

    Whether to equip the right hand (default: false).

  • both (Boolean) (defaults to: false)

    Whether to equip both hands (default: false).



278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
# File 'documented/stash.rb', line 278

def self.equip_hands(left: false, right: false, both: false)
  if both
    for action in $fill_hands_actions.pop
      action.call
    end
  elsif left
    for action in $fill_left_hand_actions.pop
      action.call
    end
  elsif right
    for action in $fill_right_hand_actions.pop
      action.call
    end
  else
    if $fill_right_hand_actions.length > 0
      for action in $fill_right_hand_actions.pop
        action.call
      end
    elsif $fill_left_hand_actions.length > 0
      for action in $fill_left_hand_actions.pop
        action.call
      end
    end
  end
end

.find_container(param, loud_fail: true) ⇒ GameObj

Finds a container by name.

Examples:

Finding a container

container = Lich::Stash.find_container("my_container")

Parameters:

  • param (String, GameObj)

    The name of the container or a GameObj instance.

  • loud_fail (Boolean) (defaults to: true)

    Whether to raise an error if the container is not found (default: true).

Returns:

  • (GameObj)

    The found container.

Raises:

  • (RuntimeError)

    If the container is not found and loud_fail is true.



19
20
21
22
23
24
25
26
27
28
29
# File 'documented/stash.rb', line 19

def self.find_container(param, loud_fail: true)
  param = param.name if param.is_a?(GameObj) # (Lich::Gemstone::GameObj)
  found_container = GameObj.inv.find do |container|
    container.name =~ %r[#{param.strip}]i || container.name =~ %r[#{param.sub(' ', ' .*')}]i
  end
  if found_container.nil? && loud_fail
    fail "could not find Container[name: #{param}]"
  else
    return found_container
  end
end

.missing_primary_sheath?Boolean

Checks if the primary sheath is missing from the inventory.

Examples:

Checking for missing primary sheath

result = Lich::Stash.missing_primary_sheath?

Returns:

  • (Boolean)

    True if the primary sheath is missing, false otherwise.



127
128
129
# File 'documented/stash.rb', line 127

def self.missing_primary_sheath? # check entry against actual inventory to catch inventory updatees
  @sheath.has_key?(:sheath) && !GameObj.inv.any? { |item| item.id == @sheath[:sheath].id }
end

.missing_secondary_sheath?Boolean

Checks if the secondary sheath is missing from the inventory.

Examples:

Checking for missing secondary sheath

result = Lich::Stash.missing_secondary_sheath?

Returns:

  • (Boolean)

    True if the secondary sheath is missing, false otherwise.



135
136
137
# File 'documented/stash.rb', line 135

def self.missing_secondary_sheath? # check entry against actual inventory to catch inventory updates
  @sheath.has_key?(:secondary_sheath) && !GameObj.inv.any? { |item| item.id == @sheath[:secondary_sheath].id }
end

.sheath_bagsvoid

This method returns an undefined value.

Finds and stores sheath settings from the ready list.

Examples:

Finding sheath bags

Lich::Stash.sheath_bags


100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'documented/stash.rb', line 100

def self.sheath_bags
  # find ready list settings for sheaths only; regex courtesy Eloot
  @sheath = {}
  @checked_sheaths = false
  sheath_list_match = /(?:sheath|secondary sheath):\s+<d\scmd="store\s(\w+)\sclear">[^<]+<a\sexist="(\d+)"\snoun="[^"]+">([^<]+)<\/a>(?:\s[^<]+)?<\/d>/

  ready_lines = Lich::Util.issue_command("ready list", /Your current settings are/, /To change your default item for a category that is already set/, silent: true, quiet: true)
  ready_lines.each { |line|
    if line =~ sheath_list_match
      sheath_obj = Regexp.last_match(3).to_s.downcase
      sheath_type = Regexp.last_match(1).to_s.downcase.gsub('2', 'secondary_')
      found_container = Stash.find_container(sheath_obj, loud_fail: false)
      unless found_container.nil?
        @sheath.store(sheath_type.to_sym, found_container)
      else
        respond("Lich::Stash.sheath_bags Error: Could not find sheath(#{sheath_obj}) in inventory. Not using, possibly hidden, tucked, or missing.")
        Lich.log("Lich::Stash.sheath_bags Error: Could not find sheath(#{sheath_obj}) in inventory. Not using, possibly hidden, tucked, or missing.")
      end
    end
  }
  @checked_sheaths = true
end

.stash_hands(right: false, left: false, both: false) ⇒ void

This method returns an undefined value.

Stashes items from the hands into specified containers.

Examples:

Stashing hands

Lich::Stash.stash_hands(right: true, left: true)

Parameters:

  • right (Boolean) (defaults to: false)

    Whether to stash the right hand (default: false).

  • left (Boolean) (defaults to: false)

    Whether to stash the left hand (default: false).

  • both (Boolean) (defaults to: false)

    Whether to stash both hands (default: false).



146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
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
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
# File 'documented/stash.rb', line 146

def self.stash_hands(right: false, left: false, both: false)
  $fill_hands_actions ||= Array.new
  $fill_left_hand_actions ||= Array.new
  $fill_right_hand_actions ||= Array.new

  actions = Array.new
  right_hand = GameObj.right_hand
  left_hand = GameObj.left_hand

  # extending to use sheath / 2sheath wherever possible
  if !@checked_sheaths || missing_primary_sheath? || missing_secondary_sheath?
    Stash.sheath_bags # @checked_sheaths is set true when this method executes
  end
  if @sheath.has_key?(:sheath)
    unless @sheath.has_key?(:secondary_sheath)
      sheath = second_sheath = @sheath.fetch(:sheath)
    else
      sheath = @sheath.fetch(:sheath) if @sheath.has_key?(:sheath)
      second_sheath = @sheath.fetch(:secondary_sheath) if @sheath.has_key?(:secondary_sheath)
    end
  elsif @sheath.has_key?(:secondary_sheath)
    sheath = second_sheath = @sheath.fetch(:secondary_sheath)
  else
    sheath = second_sheath = nil
  end
  # weaponsack for both hands
  if UserVars.weapon.is_a?(String) and UserVars.weaponsack.is_a?(String) and not UserVars.weapon.empty? and not UserVars.weaponsack.empty? and (right_hand.name =~ /#{Regexp.escape(UserVars.weapon.strip)}/i or right_hand.name =~ /#{Regexp.escape(UserVars.weapon).sub(' ', ' .*')}/i)
    weaponsack = nil unless (weaponsack = find_container(UserVars.weaponsack, loud_fail: false)).is_a?(GameObj) # (Lich::Gemstone::GameObj)
  end
  # lootsack for both hands
  if !UserVars.lootsack.is_a?(String) || UserVars.lootsack.empty?
    lootsack = nil
  else
    lootsack = nil unless (lootsack = find_container(UserVars.lootsack, loud_fail: false)).is_a?(GameObj) # (Lich::Gemstone::GameObj)
  end
  # finding another container if needed
  other_containers_var = nil
  other_containers = proc {
    results = Lich::Util.issue_command('inventory containers', /^(?:You are carrying nothing at this time|You are wearing)/, silent: true, quiet: true)
    other_containers_ids = results.to_s.scan(/exist=\\"(.*?)\\"/).flatten - [lootsack.id]
    other_containers_var = GameObj.inv.find_all { |obj| other_containers_ids.include?(obj.id) }
    other_containers_var
  }

  if (left || both) && left_hand.id
    waitrt?
    if (left_hand.noun =~ /shield|buckler|targe|heater|parma|aegis|scutum|greatshield|mantlet|pavis|arbalest|bow|crossbow|yumi|arbalest/)\
      and Lich::Stash::wear_to_inv(left_hand)
      actions.unshift proc {
        fput "remove ##{left_hand.id}"
        20.times { break if GameObj.left_hand.id == left_hand.id or GameObj.right_hand.id == left_hand.id; sleep 0.1 }

        if GameObj.right_hand.id == left_hand.id
          dothistimeout 'swap', 3, /^You don't have anything to swap!|^You swap/
        end
      }
    else
      actions.unshift proc {
        if left_hand.name =~ /^ethereal \w+$/
          fput "rub #{left_hand.noun} tattoo"
          20.times { break if (GameObj.left_hand.name == left_hand.name) or (GameObj.right_hand.name == left_hand.name); sleep 0.1 }
        else
          fput "get ##{left_hand.id}"
          20.times { break if (GameObj.left_hand.id == left_hand.id) or (GameObj.right_hand.id == left_hand.id); sleep 0.1 }
        end

        if GameObj.right_hand.id == left_hand.id or (GameObj.right_hand.name == left_hand.name && left_hand.name =~ /^ethereal \w+$/)
          dothistimeout 'swap', 3, /^You don't have anything to swap!|^You swap/
        end
      }
      if !second_sheath.nil? && GameObj.left_hand.type =~ /weapon/
        result = Lich::Stash.add_to_bag(second_sheath, GameObj.left_hand)
      elsif weaponsack && GameObj.left_hand.type =~ /weapon/
        result = Lich::Stash::add_to_bag(weaponsack, GameObj.left_hand)
      elsif lootsack
        result = Lich::Stash::add_to_bag(lootsack, GameObj.left_hand)
      else
        result = nil
      end
      if result.nil? or !result
        for container in other_containers.call
          result = Lich::Stash::add_to_bag(container, GameObj.left_hand)
          break if result
        end
      end
    end
  end
  if (right || both) && right_hand.id
    waitrt?
    actions.unshift proc {
      if right_hand.name =~ /^ethereal \w+$/
        fput "rub #{right_hand.noun} tattoo"
        20.times { break if GameObj.left_hand.name == right_hand.name or GameObj.right_hand.name == right_hand.name; sleep 0.1 }
      else
        fput "get ##{right_hand.id}"
        20.times { break if GameObj.left_hand.id == right_hand.id or GameObj.right_hand.id == right_hand.id; sleep 0.1 }
      end

      if GameObj.left_hand.id == right_hand.id or (GameObj.left_hand.name == right_hand.name && right_hand.name =~ /^ethereal \w+$/)
        dothistimeout 'swap', 3, /^You don't have anything to swap!|^You swap/
      end
    }

    if !sheath.nil? && GameObj.right_hand.type =~ /weapon/
      result = Lich::Stash.add_to_bag(sheath, GameObj.right_hand)
    elsif weaponsack && GameObj.right_hand.type =~ /weapon/
      result = Lich::Stash::add_to_bag(weaponsack, GameObj.right_hand)
    elsif lootsack
      result = Lich::Stash::add_to_bag(lootsack, GameObj.right_hand)
    else
      result = nil
    end
    sleep 0.1
    if result.nil? or !result
      for container in other_containers.call
        result = Lich::Stash::add_to_bag(container, GameObj.right_hand)
        break if result
      end
    end
  end
  $fill_hands_actions.push(actions) if both
  $fill_left_hand_actions.push(actions) if left
  $fill_right_hand_actions.push(actions) if right
end

.try_or_fail(seconds: 2, command: nil) ⇒ void

This method returns an undefined value.

Attempts to execute a command and waits for a condition to be met.

Examples:

Trying a command

Lich::Stash.try_or_fail(command: "some_command") { some_condition_met }

Parameters:

  • seconds (Integer) (defaults to: 2)

    The number of seconds to wait before failing (default: 2).

  • command (String) (defaults to: nil)

    The command to execute.

Raises:

  • (RuntimeError)

    If the command does not succeed within the time limit.



54
55
56
57
58
59
# File 'documented/stash.rb', line 54

def self.try_or_fail(seconds: 2, command: nil)
  fput(command)
  expiry = Time.now + seconds
  wait_until do yield or Time.now > expiry end
  fail "Error[command: #{command}, seconds: #{seconds}]" if Time.now > expiry
end

.wear_to_inv(item) ⇒ Boolean

Wears an item and attempts to add it to the inventory.

Examples:

Wearing an item

result = Lich::Stash.wear_to_inv(item)

Parameters:

  • item (GameObj)

    The item to wear.

Returns:

  • (Boolean)

    True if the item was successfully worn, false otherwise.



85
86
87
88
89
90
91
92
93
94
# File 'documented/stash.rb', line 85

def self.wear_to_inv(item)
  try_or_fail(command: "wear ##{item.id}") do
    20.times {
      return true if (![GameObj.right_hand, GameObj.left_hand].map(&:id).compact.include?(item.id) and GameObj.inv.to_a.map(&:id).include?(item.id))
      return true if item.name =~ /^ethereal \w+$/ && ![GameObj.right_hand, GameObj.left_hand].map(&:id).compact.include?(item.id)
      sleep 0.1
    }
    return false
  end
end