Module: Lich::DragonRealms::DRCM

Defined in:
documented/dragonrealms/commons/common-money.rb,
documented/dragonrealms/commons/common-money-data.rb

Constant Summary collapse

DENOMINATIONS =

Coin denominations ordered from highest to lowest value. Each entry is [copper_multiplier, name]. Coin denominations ordered from highest to lowest value. Each entry is [copper_multiplier, name].

[
  [10_000, 'platinum'],
  [1000, 'gold'],
  [100, 'silver'],
  [10, 'bronze'],
  [1, 'copper']
].freeze
DENOMINATION_VALUES =

Maps denomination names to their copper multiplier. Maps denomination names to their copper multiplier.

{
  'platinum' => 10_000,
  'gold'     => 1000,
  'silver'   => 100,
  'bronze'   => 10,
  'copper'   => 1
}.freeze
DENOMINATION_REGEX_MAP =

Regex abbreviations for coin denominations. Supports in-game abbreviations (e.g., "p" for platinum, "g" for gold). Regex abbreviations for coin denominations. Supports in-game abbreviations (e.g., "p" for platinum, "g" for gold).

{
  'platinum' => /\bp(l|la|lat|lati|latin|latinu|latinum)?\b/i,
  'gold'     => /\bg(o|ol|old)?\b/i,
  'silver'   => /\bs(i|il|ilv|ilve|ilver)?\b/i,
  'bronze'   => /\bb(r|ro|ron|ronz|ronze)?\b/i,
  'copper'   => /\bc(o|op|opp|oppe|opper)?\b/i
}.freeze
CURRENCY_REGEX_MAP =

Regex abbreviations for currency types. Supports in-game abbreviations (e.g., "k" for kronars, "l" for lirums). Regex abbreviations for currency types. Supports in-game abbreviations (e.g., "k" for kronars, "l" for lirums).

{
  'kronars' => /\bk(r|ro|ron|rona|ronar|ronars)?\b/i,
  'lirums'  => /\bl(i|ir|iru|irum|irums)?\b/i,
  'dokoras' => /\bd(o|ok|oko|okor|okora|okoras)?\b/i
}.freeze
CURRENCIES =

Canonical currency names for abbreviation resolution. Canonical currency names for abbreviation resolution.

%w[kronars lirums dokoras].freeze
EXCHANGE_RATES =

Exchange rates between DR currencies. Usage: EXCHANGE_RATES[to_currency] Exchange rates between DR currencies. Usage: EXCHANGE_RATES[to_currency]

{
  'dokoras' => {
    'dokoras' => 1,
    'kronars' => 1.385808991,
    'lirums'  => 1.108646953
  }.freeze,
  'kronars' => {
    'dokoras' => 0.7216,
    'kronars' => 1,
    'lirums'  => 0.8
  }.freeze,
  'lirums'  => {
    'dokoras' => 0.902,
    'kronars' => 1.25,
    'lirums'  => 1
  }.freeze
}.freeze
WEALTH_COPPER_REGEX =

Regex for parsing copper values from wealth output. Named captures: :coppers, :currency Regex for parsing copper values from wealth output. Named captures: :coppers, :currency

/\((?<coppers>\d+) copper (?<currency>kronars|lirums|dokoras)\)/i.freeze

Class Method Summary collapse

Class Method Details

.check_wealth(currency) ⇒ Integer

Checks the wealth of the user in a specified currency.

Parameters:

  • currency (String)

    the currency to check wealth in

Returns:

  • (Integer)

    the amount of wealth in the specified currency



89
90
91
# File 'documented/dragonrealms/commons/common-money.rb', line 89

def check_wealth(currency)
  DRC.bput("wealth #{currency}", /\(\d+ copper #{currency}\)/i, /No #{currency}/i).scan(/\d+/).first.to_i
end

.convert_currency(amount, from, to, fee) ⇒ Integer

Converts an amount from one currency to another, applying a fee if necessary.

Parameters:

  • amount (Numeric)

    the amount to convert

  • from (String)

    the currency to convert from

  • to (String)

    the currency to convert to

  • fee (Float)

    the conversion fee as a decimal

Returns:

  • (Integer)

    the converted amount after applying the fee



61
62
63
64
65
66
67
# File 'documented/dragonrealms/commons/common-money.rb', line 61

def convert_currency(amount, from, to, fee)
  if fee < 0
    ((amount / EXCHANGE_RATES[from][to]).ceil / (1 + fee)).ceil
  else
    ((amount * EXCHANGE_RATES[from][to]).ceil * (1 - fee)).floor
  end
end

.convert_to_copper(amount, denomination) ⇒ Integer

Converts a given amount in a specific denomination to copper.

Parameters:

  • amount (Numeric)

    the amount to convert

  • denomination (String)

    the denomination to convert from

Returns:

  • (Integer)

    the equivalent amount in copper



35
36
37
38
39
40
41
42
43
44
# File 'documented/dragonrealms/commons/common-money.rb', line 35

def convert_to_copper(amount, denomination)
  denomination = denomination.to_s.strip
  unless denomination.empty?
    DENOMINATION_VALUES.each do |name, multiplier|
      return (amount.to_f * multiplier).to_i if name.start_with?(denomination.downcase)
    end
  end
  Lich::Messaging.msg('bold', "DRCM: Unknown denomination, assuming coppers: #{denomination}")
  amount.to_i
end

.debt(hometown) ⇒ Integer

Retrieves the debt of the user in their hometown currency.

Parameters:

  • hometown (String)

    the name of the hometown

Returns:

  • (Integer)

    the amount of debt in the hometown's currency



210
211
212
213
# File 'documented/dragonrealms/commons/common-money.rb', line 210

def debt(hometown)
  currency = hometown_currency(hometown)
  DRC.bput('wealth', /\(\d+ copper #{currency}\)/i, /Wealth:/i).scan(/\d+/).first.to_i
end

.deposit_coins(keep_copper, settings, hometown = nil) ⇒ void

This method returns an undefined value.

Deposits coins into the bank, keeping a specified amount of copper on hand.

Parameters:

  • keep_copper (Integer)

    the amount of copper to keep on hand

  • settings (OpenStruct)

    the settings object containing user preferences

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

    optional hometown name



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

def deposit_coins(keep_copper, settings, hometown = nil)
  return if settings.skip_bank

  hometown = settings.hometown if hometown.nil?

  DRCT.walk_to(get_data('town')[hometown]['deposit']['id'])
  DRC.release_invisibility
  DRC.bput('wealth', 'Wealth:')
  case DRC.bput('deposit all', 'you drop all your', 'You hand the clerk some coins', "You don't have any",
                'There is no teller here', 'reached the maximum balance I can permit',
                'You find your jar with little effort', 'Searching methodically through the shelves')
  when 'There is no teller here'
    Lich::Messaging.msg('bold', "DRCM: No teller found at this location. Cannot deposit coins.")
    return
  end
  minimize_coins(keep_copper).each { |amount| withdraw_exact_amount?(amount, settings) } if settings.hometown == hometown
  balance_result = DRC.bput('check balance',
                            /current balance is .*? (?:Kronars?|Dokoras?|Lirums?)\."$/,
                            /If you would like to open one, you need only deposit a few (?:Kronars?|Dokoras?|Lirums?)\."$/,
                            /As expected, there are .*? (?:Kronars?|Dokoras?|Lirums?)\.$/,
                            'Perhaps you should find a new deposit jar for your financial needs.  Be sure to mark it with your name')
  case balance_result
  when /current balance is (?<bal>.*?) (?<cur>Kronars?|Dokoras?|Lirums?)\."$/,
       /As expected, there are (?<bal>.*?) (?<cur>Kronars?|Dokoras?|Lirums?)\.$/
    match = balance_result.match(/(?:current balance is|As expected, there are) (?<bal>.*?) (?<cur>Kronars?|Dokoras?|Lirums?)/)
    currency = match[:cur]
    balance = 0
    match[:bal].gsub(/and /, '').split(', ').each do |amount_as_string|
      amount, denomination = amount_as_string.split
      balance += convert_to_copper(amount, denomination)
    end
  when /If you would like to open one, you need only deposit a few (?<cur>Kronars?|Dokoras?|Lirums?)\."$/
    match = balance_result.match(/deposit a few (?<cur>Kronars?|Dokoras?|Lirums?)/)
    balance = 0
    currency = match[:cur]
  when /Perhaps you should find a new deposit jar/
    balance = 0
    currency = 'Dokoras'
  end
  [balance, currency]
end

.ensure_copper_on_hand(copper, settings, hometown = nil) ⇒ Boolean

Ensures that the user has a specified amount of copper on hand.

Parameters:

  • copper (Integer)

    the amount of copper required

  • settings (OpenStruct)

    the settings object containing user preferences

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

    optional hometown name

Returns:

  • (Boolean)

    true if the user has enough copper, false otherwise



134
135
136
137
138
139
140
141
142
143
# File 'documented/dragonrealms/commons/common-money.rb', line 134

def ensure_copper_on_hand(copper, settings, hometown = nil)
  hometown = settings.hometown if hometown.nil?

  on_hand = wealth(hometown)
  return true if on_hand >= copper

  withdrawals = minimize_coins(copper - on_hand)

  withdrawals.all? { |amount| withdraw_exact_amount?(amount, settings, hometown) }
end

.get_canonical_currency(currency) ⇒ String?

Retrieves the canonical currency name for a given currency string.

Parameters:

  • currency (String)

    the currency string to look up

Returns:

  • (String, nil)

    the canonical currency name or nil if not found



50
51
52
# File 'documented/dragonrealms/commons/common-money.rb', line 50

def get_canonical_currency(currency)
  CURRENCIES.find { |c| c.start_with?(currency) }
end

.get_money_from_bank(amount_as_string, settings, hometown = nil) ⇒ Boolean

Retrieves a specified amount of money from the bank.

Parameters:

  • amount_as_string (String)

    the amount to withdraw as a string

  • settings (OpenStruct)

    the settings object containing user preferences

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

    optional hometown name

Returns:

  • (Boolean)

    true if the withdrawal was successful, false otherwise



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

def get_money_from_bank(amount_as_string, settings, hometown = nil)
  hometown = settings.hometown if hometown.nil?

  DRCT.walk_to(get_data('town')[hometown]['deposit']['id'])
  DRC.release_invisibility
  loop do
    case DRC.bput("withdraw #{amount_as_string}", 'The clerk counts', 'The clerk tells',
                  'The clerk glares at you.', 'You count out', 'find a new deposit jar', 'If you value your hands',
                  'Hey!  Slow down!', "You must be at a bank teller's window to withdraw money",
                  "You don't have that much money", 'have an account',
                  /The clerk says, "I'm afraid you can't withdraw that much at once/,
                  /^How much do you wish to withdraw/i)
    when 'The clerk counts', 'You count out'
      break true
    when 'The clerk glares at you.', 'Hey!  Slow down!', "I don't know what you think you're doing"
      pause 15
    when 'The clerk tells', 'If you value your hands', 'find a new deposit jar',
      "You must be at a bank teller's window to withdraw money", "You don't have that much money",
      'have an account', /The clerk says, "I'm afraid you can't withdraw that much at once/,
      /^How much do you wish to withdraw/i
      break false
    else
      break false
    end
  end
end

.get_total_wealthHash

Retrieves the total wealth of the user across all currencies.

Returns:

  • (Hash)

    a hash containing the total wealth in different currencies



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

def get_total_wealth
  wealth_lines = Lich::Util.issue_command(
    'wealth',
    /^Wealth:/,
    /<prompt/,
    usexml: true,
    quiet: true,
    include_end: false,
    timeout: 5
  )

  result = { 'kronars' => 0, 'lirums' => 0, 'dokoras' => 0 }
  return result if wealth_lines.nil?

  strip_xml(wealth_lines).each do |line|
    match = line.match(WEALTH_COPPER_REGEX)
    next unless match

    result[match[:currency].downcase] = match[:coppers].to_i
  end

  result
end

.hometown_currency(hometown_name) ⇒ String

Retrieves the currency used in a given hometown.

Parameters:

  • hometown_name (String)

    the name of the hometown

Returns:

  • (String)

    the currency used in the hometown



73
74
75
# File 'documented/dragonrealms/commons/common-money.rb', line 73

def hometown_currency(hometown_name)
  get_data('town')[hometown_name]['currency']
end

.minimize_coins(copper) ⇒ Array<String>

Minimizes the number of coins needed for a given amount of copper.

Parameters:

  • copper (Integer)

    the amount of copper to minimize

Returns:

  • (Array<String>)

    an array of strings representing the minimized coins



19
20
21
22
23
24
25
26
27
28
# File 'documented/dragonrealms/commons/common-money.rb', line 19

def minimize_coins(copper)
  DENOMINATIONS.inject([copper, []]) do |result, denomination|
    remaining = result.first
    display = result.last
    if remaining / denomination.first > 0
      display << "#{remaining / denomination.first} #{denomination.last}"
    end
    [remaining % denomination.first, display]
  end.last
end

.strip_xml(lines) ⇒ Array<String>

Strips XML tags from the given lines.

Parameters:

  • lines (Array<String>)

    the lines containing XML to be stripped

Returns:

  • (Array<String>)

    the lines without XML tags



11
12
13
# File 'documented/dragonrealms/commons/common-money.rb', line 11

def strip_xml(lines)
  DRC.strip_xml(lines)
end

.town_currency(town) ⇒ String

Retrieves the currency used in a specified town.

Parameters:

  • town (String)

    the name of the town

Returns:

  • (String)

    the currency used in the town



81
82
83
# File 'documented/dragonrealms/commons/common-money.rb', line 81

def town_currency(town)
  hometown_currency(town)
end

.wealth(hometown) ⇒ Integer

Retrieves the wealth of a user in their hometown currency.

Parameters:

  • hometown (String)

    the name of the hometown

Returns:

  • (Integer)

    the amount of wealth in the hometown's currency



97
98
99
# File 'documented/dragonrealms/commons/common-money.rb', line 97

def wealth(hometown)
  check_wealth(hometown_currency(hometown))
end

.withdraw_exact_amount?(amount_as_string, settings, hometown = nil) ⇒ Boolean

Withdraws an exact amount of currency from the bank.

Parameters:

  • amount_as_string (String)

    the amount to withdraw as a string

  • settings (OpenStruct)

    the settings object containing user preferences

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

    optional hometown name

Returns:

  • (Boolean)

    true if the withdrawal was successful, false otherwise



151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'documented/dragonrealms/commons/common-money.rb', line 151

def withdraw_exact_amount?(amount_as_string, settings, hometown = nil)
  hometown = settings.hometown if hometown.nil?

  if settings.bankbot_enabled
    DRCT.walk_to(settings.bankbot_room_id)
    DRC.release_invisibility
    if DRRoom.pcs.include?(settings.bankbot_name)
      amount_convert, type = amount_as_string.split
      amount = convert_to_copper(amount_convert, type)
      currency = hometown_currency(settings.hometown)
      case DRC.bput("whisper #{settings.bankbot_name} withdraw #{amount} #{currency}", 'offers you', 'Whisper what to who?')
      when 'offers you'
        DRC.bput('accept tip', 'Your current balance is')
      end
    else
      get_money_from_bank(amount_as_string, settings, hometown)
    end
  else
    get_money_from_bank(amount_as_string, settings, hometown)
  end
end