Module: Lich::DragonRealms::DRCS

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

Overview

DragonRealms Common Scripts: shared utilities for summoning and manipulating magical weapons (moonblades/staves for Moon Mages, elemental weapons for Warrior Mages).

Constant Summary collapse

LACK_CHARGE =

Shared response for elemental charge depletion

'You lack the elemental charge'.freeze
SUMMON_WEAPON_RESPONSES =

Expected game responses from the SUMMON WEAPON command.

See Also:

  • #summon_weapon
[
  LACK_CHARGE,
  'you draw out'
].freeze
BREAK_WEAPON_RESPONSES =

Expected game responses from the BREAK command on a summoned weapon.

See Also:

  • #break_summoned_weapon
[
  'Focusing your will',
  'disrupting its matrix',
  "You can't break",
  'Break what'
].freeze
MOON_SKILL_TO_SHAPE =

Moon Mage skill-to-shape mapping for moonblades/staves

{
  'Staves'          => 'blunt',
  'Twohanded Edged' => 'huge',
  'Large Edged'     => 'heavy',
  'Small Edged'     => 'normal'
}.freeze
MOON_SHAPE_RESPONSES =

Expected game responses from shaping a Moon Mage moonblade/staff.

See Also:

  • #shape_summoned_weapon
[
  'you adjust the magic that defines its shape',
  'already has',
  'You fumble around'
].freeze
WM_SHAPE_FAILURES =

Expected game responses from attempting to shape a Warrior Mage summoned weapon, including failures (depleted charge, unknown weapon type).

See Also:

  • #shape_summoned_weapon
[
  LACK_CHARGE,
  'You reach out',
  'You fumble around',
  "You don't know how to manipulate your weapon in that way"
].freeze
TURN_WEAPON_RESPONSES =

Expected game responses from the TURN command on a summoned weapon.

See Also:

  • #turn_summoned_weapon
[LACK_CHARGE, 'You reach out'].freeze
PUSH_WEAPON_RESPONSES =

Expected game responses from the PUSH command on a summoned weapon.

See Also:

  • #push_summoned_weapon
[LACK_CHARGE, 'Closing your eyes', "That's as"].freeze
PULL_WEAPON_RESPONSES =

Expected game responses from the PULL command on a summoned weapon.

See Also:

  • #pull_summoned_weapon
[LACK_CHARGE, 'Closing your eyes', "That's as"].freeze
SUMMON_ADMITTANCE_RESPONSES =

Expected game responses from the SUMMON ADMITTANCE command, which restores elemental charge for Warrior Mage summoned weapons.

See Also:

  • #summon_admittance
[
  'You align yourself to it',
  'further increasing your proximity',
  'Going any further while in this plane would be fatal',
  'Summon allows Warrior Mages to draw',
  'You are a bit too distracted'
].freeze
WM_ELEMENT_ADJECTIVES =

Default element adjectives for Warrior Mage summoned weapons

%w[stone fiery icy electric].freeze

Class Method Summary collapse

Class Method Details

.base_summoned_weapon(summoned_weapon, settings = nil) ⇒ String

Strips the summoned weapon's custom element adjective so the game recognizes the base weapon for shaping (custom Books-of-Binding adjectives aren't accepted by SHAPE).

Picks the LONGEST matching adjective, not the first: with a substring pair like ['flame', 'flamewreathed'] a first-match would strip 'flame' from "flamewreathed sword" and leave a bogus "wreathed sword".

Parameters:

  • summoned_weapon (String)

    the held weapon's

  • settings (OpenStruct, nil) (defaults to: nil)

    user settings (for the legacy key)

Returns:

  • (String)

    the weapon with its custom adjective removed (if any)

See Also:

  • #custom_summoned_weapon_adjectives


267
268
269
270
# File 'documented/dragonrealms/commons/common-summoning.rb', line 267

def base_summoned_weapon(summoned_weapon, settings = nil)
  present = custom_summoned_weapon_adjectives(settings).select { |adjective| summoned_weapon.include?(adjective) }.max_by(&:length)
  present ? summoned_weapon.sub(present, '') : summoned_weapon
end

.break_summoned_weapon(item) ⇒ void

This method returns an undefined value.

Breaks a summoned weapon using the BREAK command.

If item is nil, returns immediately without sending a command.

Examples:

Break a moonblade

break_summoned_weapon("moonblade")

Parameters:

  • item (String, nil)

    the weapon item noun (e.g. "moonblade", "sword"), or nil to skip



175
176
177
178
179
# File 'documented/dragonrealms/commons/common-summoning.rb', line 175

def break_summoned_weapon(item)
  return if item.nil?

  DRC.bput("break my #{item}", *BREAK_WEAPON_RESPONSES)
end

.custom_summoned_weapon_adjectives(settings = nil) ⇒ Array<String>

Player-defined summoned-weapon adjectives (e.g. from Books of Binding tomes), merged and validated. Combines the plural custom_summoned_weapons_adjectives list with the legacy singular summoned_weapons_adjective setting (kept for backward compatibility). The built-in WM_ELEMENT_ADJECTIVES are NOT included here -- callers add those where needed.

Parameters:

  • settings (OpenStruct, nil) (defaults to: nil)

    user settings (for the legacy key)

Returns:

  • (Array<String>)

    validated custom adjectives

See Also:



247
248
249
250
251
252
253
# File 'documented/dragonrealms/commons/common-summoning.rb', line 247

def custom_summoned_weapon_adjectives(settings = nil)
  # dup: never mutate CustomSubstitutions' memoized array when adding legacy.
  adjectives = CustomSubstitutions.resolve(:custom_summoned_weapons_adjectives, [], type: :names).dup
  legacy = settings&.summoned_weapons_adjective
  adjectives << legacy if legacy.is_a?(String) && !legacy.empty? && !adjectives.include?(legacy)
  adjectives
end

.get_ingot(ingot, swap) ⇒ Boolean

Retrieves an ingot from storage.

If ingot is nil, returns true without attempting retrieval. Otherwise, gets the item matching "#ingot ingot" from storage using Lich::DragonRealms::DRCI.get_item?. If successful and swap is true, executes the SWAP command to exchange hands.

Examples:

Get a ruby ingot without swapping

get_ingot("ruby", false) #=> true

Parameters:

  • ingot (String, nil)

    ingot type name (e.g. "ruby", "emerald"), or nil to skip

  • swap (Boolean)

    whether to swap the ingot to the other hand after retrieval

Returns:

  • (Boolean)

    true if the ingot was retrieved (or skipped), false if retrieval failed



137
138
139
140
141
142
143
144
145
146
# File 'documented/dragonrealms/commons/common-summoning.rb', line 137

def get_ingot(ingot, swap)
  return true unless ingot

  unless DRCI.get_item?("#{ingot} ingot")
    Lich::Messaging.msg("bold", "DRCS: Could not get #{ingot} ingot")
    return false
  end
  DRC.bput('swap', 'You move') if swap
  true
end

.identify_summoned_weapon(settings = nil) ⇒ Object

Returns what kind of summoned weapon you're holding. Will be the like 'red-hot moonblade' or 'electric sword'. Recognizes WM_ELEMENT_ADJECTIVES plus any player-defined adjectives (custom_summoned_weapon_adjectives).



276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
# File 'documented/dragonrealms/commons/common-summoning.rb', line 276

def identify_summoned_weapon(settings = nil)
  if DRStats.moon_mage?
    return DRC.right_hand if DRCMM.is_moon_weapon?(DRC.right_hand)
    return DRC.left_hand  if DRCMM.is_moon_weapon?(DRC.left_hand)
  elsif DRStats.warrior_mage?
    adjectives = (WM_ELEMENT_ADJECTIVES + custom_summoned_weapon_adjectives(settings)).map { |adjective| Regexp.escape(adjective) }.join('|')
    weapon_regex = /^You tap (?:a|an|some)(?:[\w\s\-]+)(?:(?:#{adjectives}) [\w\s\-]+) that you are holding\.$/
    # For a two-worded weapon like 'short sword' the only way to know
    # which element it was summoned with is by tapping it. That's the only
    # way we can infer if it's a summoned sword or a regular one.
    # However, the <adj> <noun> of the item we return must be what's in
    # their hands, not what the regex matches in the tap.
    return DRC.right_hand if weapon_regex.match?(DRCI.tap(DRC.right_hand).to_s)
    return DRC.left_hand if weapon_regex.match?(DRCI.tap(DRC.left_hand).to_s)
  else
    Lich::Messaging.msg("bold", "DRCS: Unable to identify summoned weapons as a #{DRStats.guild}")
  end
end

.pull_summoned_weaponvoid

Note:

Pauses 1 second and calls #waitrt? at the end

This method returns an undefined value.

Pulls a summoned weapon backward in hand using the PULL command.

If elemental charge is depleted, automatically calls #summon_admittance to restore it and retries the pull.



336
337
338
339
340
341
342
343
344
# File 'documented/dragonrealms/commons/common-summoning.rb', line 336

def pull_summoned_weapon
  result = DRC.bput("pull my #{DRC.right_hand_noun}", *PULL_WEAPON_RESPONSES)
  if result == LACK_CHARGE
    summon_admittance
    DRC.bput("pull my #{DRC.right_hand_noun}", *PULL_WEAPON_RESPONSES)
  end
  pause 1
  waitrt?
end

.push_summoned_weaponvoid

Note:

Pauses 1 second and calls #waitrt? at the end

This method returns an undefined value.

Pushes a summoned weapon forward in hand using the PUSH command.

If elemental charge is depleted, automatically calls #summon_admittance to restore it and retries the push.



319
320
321
322
323
324
325
326
327
# File 'documented/dragonrealms/commons/common-summoning.rb', line 319

def push_summoned_weapon
  result = DRC.bput("push my #{DRC.right_hand_noun}", *PUSH_WEAPON_RESPONSES)
  if result == LACK_CHARGE
    summon_admittance
    DRC.bput("push my #{DRC.right_hand_noun}", *PUSH_WEAPON_RESPONSES)
  end
  pause 1
  waitrt?
end

.shape_summoned_weapon(skill, ingot = nil, settings = nil) ⇒ void

Note:

Pauses 1 second and calls #waitrt? at the end

This method returns an undefined value.

Reshapes a summoned weapon to a different form.

For Moon Mages: maps the skill name to a shape using MOON_SKILL_TO_SHAPE, then casts SHAPE on the held moonblade/staff (identified via #identify_summoned_weapon).

For Warrior Mages: retrieves the ingot, casts SHAPE MY TO , and stows the ingot. If the weapon has a custom element adjective from a Books of Binding tome, the command may be rejected; in that case, #base_summoned_weapon strips the adjective and retries. If elemental charge is depleted, automatically calls #summon_admittance to restore it.

Parameters:

  • skill (String)

    the skill name to shape to (e.g. "melee", "ranged") or Moon Mage shape key (e.g. "Staves", "Small Edged")

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

    ingot type name for Warrior Mages, or nil to skip

  • settings (OpenStruct, nil) (defaults to: nil)

    user settings for looking up custom adjectives

See Also:

  • #identify_summoned_weapon
  • #base_summoned_weapon
  • #custom_summoned_weapon_adjectives


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
# File 'documented/dragonrealms/commons/common-summoning.rb', line 201

def shape_summoned_weapon(skill, ingot = nil, settings = nil)
  summoned_weapon = identify_summoned_weapon(settings)
  if DRStats.moon_mage?
    shape = MOON_SKILL_TO_SHAPE[skill]
    if DRCMM.hold_moon_weapon?
      DRC.bput("shape #{summoned_weapon} to #{shape}", *MOON_SHAPE_RESPONSES)
    end
  elsif DRStats.warrior_mage?
    return unless get_ingot(ingot, false)

    result = DRC.bput("shape my #{summoned_weapon} to #{skill}", *(WM_SHAPE_FAILURES + ['What type of weapon were you trying']))
    case result
    when LACK_CHARGE
      summon_admittance
      DRC.bput("shape my #{summoned_weapon} to #{skill}", *WM_SHAPE_FAILURES)
    when 'What type of weapon were you trying'
      # Custom adjectives from https://elanthipedia.play.net/Books_of_Binding tomes
      # aren't recognized for shaping summoned elemental weapons, and the error message
      # itself is misleading. Breaking, turning, pulling, pushing work fine with custom adj.
      unless summoned_weapon.nil?
        base_weapon = base_summoned_weapon(summoned_weapon, settings)
        retry_result = DRC.bput("shape my #{base_weapon} to #{skill}", *WM_SHAPE_FAILURES)
        if retry_result == LACK_CHARGE
          summon_admittance
          DRC.bput("shape my #{base_weapon} to #{skill}", *WM_SHAPE_FAILURES)
        end
      end
    end
    stow_ingot(ingot)
  else
    Lich::Messaging.msg("bold", "DRCS: Unable to shape weapons as a #{DRStats.guild}")
  end
  pause 1
  waitrt?
end

.stow_ingot(ingot) ⇒ Boolean

Stows an ingot into storage.

If ingot is nil, returns true without attempting stowage. Otherwise, stows the item matching "#ingot ingot" using Lich::DragonRealms::DRCI.put_away_item?.

Examples:

Stow a sapphire ingot

stow_ingot("sapphire") #=> true

Parameters:

  • ingot (String, nil)

    ingot type name (e.g. "ruby", "emerald"), or nil to skip

Returns:

  • (Boolean)

    true if the ingot was stowed (or skipped), false if stowage failed



157
158
159
160
161
162
163
164
165
# File 'documented/dragonrealms/commons/common-summoning.rb', line 157

def stow_ingot(ingot)
  return true unless ingot

  unless DRCI.put_away_item?("#{ingot} ingot")
    Lich::Messaging.msg("bold", "DRCS: Could not stow #{ingot} ingot")
    return false
  end
  true
end

.summon_admittancevoid

Note:

Pauses 1 second and calls #waitrt? and Lich::DragonRealms::DRC.fix_standing at the end

This method returns an undefined value.

Restores elemental charge for summoned weapons via SUMMON ADMITTANCE command.

Loops until SUMMON ADMITTANCE succeeds. If the response is "You are a bit too distracted", calls Lich::DragonRealms::DRC.retreat and retries.



353
354
355
356
357
358
359
360
361
362
363
364
365
# File 'documented/dragonrealms/commons/common-summoning.rb', line 353

def summon_admittance
  loop do
    result = DRC.bput('summon admittance', *SUMMON_ADMITTANCE_RESPONSES)
    if result == 'You are a bit too distracted'
      DRC.retreat
      next
    end
    break
  end
  pause 1
  waitrt?
  DRC.fix_standing
end

.summon_weapon(_moon = nil, element = nil, ingot = nil, skill = nil) ⇒ void

Note:

Pauses 1 second and calls #waitrt? and Lich::DragonRealms::DRC.fix_standing at the end

This method returns an undefined value.

Summons an elemental weapon (Warrior Mage) or moonblade/staff (Moon Mage).

For Warrior Mages: retrieves the specified ingot, casts SUMMON WEAPON with the given element and skill, and stows the ingot. If elemental charge is depleted, automatically calls #summon_admittance to restore it and retries the summon. For Moon Mages: calls MM#hold_moon_weapon?.

Examples:

Summon a fiery sword for melee skill using a ruby ingot

summon_weapon(element: "fiery", ingot: "ruby", skill: "melee")

Parameters:

  • _moon (Object, nil) (defaults to: nil)

    unused (legacy parameter)

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

    element adjective (e.g. "fiery", "icy") for Warrior Mages

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

    ingot type name for Warrior Mages (e.g. "ruby", "sapphire")

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

    weapon skill target for Warrior Mages (e.g. "melee", "ranged")



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'documented/dragonrealms/commons/common-summoning.rb', line 106

def summon_weapon(_moon = nil, element = nil, ingot = nil, skill = nil)
  if DRStats.moon_mage?
    DRCMM.hold_moon_weapon?
  elsif DRStats.warrior_mage?
    return unless get_ingot(ingot, true)

    result = DRC.bput("summon weapon #{element} #{skill}", *SUMMON_WEAPON_RESPONSES)
    if result == LACK_CHARGE
      summon_admittance
      DRC.bput("summon weapon #{element} #{skill}", *SUMMON_WEAPON_RESPONSES)
    end
    stow_ingot(ingot)
  else
    Lich::Messaging.msg("bold", "DRCS: Unable to summon weapons as a #{DRStats.guild}")
  end
  pause 1
  waitrt?
  DRC.fix_standing
end

.turn_summoned_weaponvoid

Note:

Pauses 1 second and calls #waitrt? at the end

This method returns an undefined value.

Rotates a summoned weapon in hand using the TURN command.

If elemental charge is depleted, automatically calls #summon_admittance to restore it and retries the turn.



302
303
304
305
306
307
308
309
310
# File 'documented/dragonrealms/commons/common-summoning.rb', line 302

def turn_summoned_weapon
  result = DRC.bput("turn my #{DRC.right_hand_noun}", *TURN_WEAPON_RESPONSES)
  if result == LACK_CHARGE
    summon_admittance
    DRC.bput("turn my #{DRC.right_hand_noun}", *TURN_WEAPON_RESPONSES)
  end
  pause 1
  waitrt?
end