Module: Lich::Stash

Defined in:
lib/stash.rb

Class Method Summary collapse

Class Method Details

.add_to_bag(bag, item) ⇒ Boolean

Adds an item to a specified bag.

Examples:

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

Parameters:

  • bag (String)

    The name of the bag to add the item to.

  • item (GameObj)

    The item to be added to the bag.

Returns:

  • (Boolean)

    True if the item was successfully added, false otherwise.



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

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:

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

Parameters:

  • param (String)

    The name of the container.

Returns:

  • (GameObj)

    The found container.



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

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 in the hands based on the specified parameters.

Examples:

Lich::Stash.equip_hands(left: true)

Parameters:

  • left (Boolean) (defaults to: false)

    Whether to equip items in the left hand.

  • right (Boolean) (defaults to: false)

    Whether to equip items in the right hand.

  • both (Boolean) (defaults to: false)

    Whether to equip items in both hands.



285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
# File 'lib/stash.rb', line 285

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 its name.

Examples:

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 is true.

Returns:

  • (GameObj, nil)

    The found container or nil if not found.

Raises:

  • (RuntimeError)

    If the container is not found and loud_fail is true.



17
18
19
20
21
22
23
24
25
26
27
# File 'lib/stash.rb', line 17

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:

is_missing = Lich::Stash.missing_primary_sheath?

Returns:

  • (Boolean)

    True if the primary sheath is missing, false otherwise.



131
132
133
# File 'lib/stash.rb', line 131

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:

is_missing = Lich::Stash.missing_secondary_sheath?

Returns:

  • (Boolean)

    True if the secondary sheath is missing, false otherwise.



140
141
142
# File 'lib/stash.rb', line 140

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.

Checks and retrieves the settings for sheaths.

Examples:

Lich::Stash.sheath_bags


103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/stash.rb', line 103

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 in the hands based on the specified parameters.

Examples:

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

Parameters:

  • right (Boolean) (defaults to: false)

    Whether to stash items in the right hand.

  • left (Boolean) (defaults to: false)

    Whether to stash items in the left hand.

  • both (Boolean) (defaults to: false)

    Whether to stash items in both hands.



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
270
271
272
273
274
275
# File 'lib/stash.rb', line 152

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.class == String and UserVars.weaponsack.class == 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.class != 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) ⇒ Boolean

Executes a command and waits for a specified duration.

Examples:

Lich::Stash.try_or_fail(command: "some_command")

Parameters:

  • seconds (Integer) (defaults to: 2)

    The number of seconds to wait before failing. Default is 2.

  • command (String) (defaults to: nil)

    The command to execute.

Returns:

  • (Boolean)

    True if the command was successful within the time limit.

Raises:

  • (RuntimeError)

    If the command does not succeed within the specified time.



54
55
56
57
58
59
# File 'lib/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 to the inventory.

Examples:

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.



87
88
89
90
91
92
93
94
95
96
# File 'lib/stash.rb', line 87

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