Class: Adventure::Item

Inherits:
Object
  • Object
show all
Defined in:
lib/adventure/item.rb

Overview

Represents an ingame item.

Defined Under Namespace

Modules: DamageType, Property, Rarity, Type

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, description, type, **options) ⇒ Item

Create a new instance of Item.

Parameters:

  • name (String)

    Item's name.

  • description (String)

    Item's full description, in GFM.

  • type (Type, String)

    Item's type from the Type list, or a String.

  • options (Hash)

    A list of optional parameters.

Options Hash (**options):

  • :rarity (Rarity, String)

    Item's rarity. Either one of Adventure::Item::Rarity or a String, or nil when unset.

  • :value (Float)

    Item's value in gold pieces (gp). Fractional values represent the gp equivalent of sps and cps.

  • :weight (Float)

    Item's weight in kilograms.

  • :source (String)

    Item's source and page.

  • :ac (Integer)

    Item's AC bonus.

  • :max_dex_bonus (Boolean)

    If this item is an armor, the maximum Dexterity bonus applicable to the AC.

  • :dmg_notation (String)

    The damage notation in the format XdY+Z.

  • :dmg_die_count (Integer)

    The X in the notation XdY+Z, for damage.

  • :dmg_die_type (Integer)

    The Y in the notation XdY+Z, for damage.

  • :dmg_mod (Integer)

    The Z in the notation XdY+Z, for damage.

  • :dmg_type (DamageType)

    Item's type of damage.

  • :magic (Boolean)

    Whether or not the item is of magical nature.

  • :attunement (Boolean, String)

    Whether the item requires attunement or not. If a string, it will be prepended by "Requires attunement ".

  • :properties (Array<Property>)

    An array of properties.



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 'lib/adventure/item.rb', line 207

def initialize(name, description, type, **options)
  # Mandatory parameters
  @name        = name.strip
  @description = description.strip
  @type        = type
  # Optional parameters
  @rarity        = options.key?(:rarity) ? options[:rarity] : nil
  @value         = options.key?(:value) ? options[:value].to_f : 0.0
  @weight        = options.key?(:weight) ? options[:weight].to_f : 0.0
  @source        = options.key?(:source) ? options[:source] : nil
  @ac            = options.key?(:ac) ? options[:ac] : nil
  @max_dex_bonus = options.key?(:max_dex_bonus) ? options[:max_dex_bonus].to_i : 1_000
  if options.key?(:dmg_notation) && !options[:dmg_notation].strip.empty?
    @dmg_die_count, @dmg_die_type, @dmg_mod = parse_damage_notation(options[:dmg_notation].strip)
  else
    @dmg_die_count = options.key?(:dmg_die_count) ? options[:dmg_die_count].to_i : 0
    @dmg_die_type  = options.key?(:dmg_die_type) ? options[:dmg_die_type].to_i : 0
    @dmg_mod       = options.key?(:dmg_mod) ? options[:dmg_mod].to_i : 0
  end
  @dmg_type      = options.key?(:dmg_type) ? options[:dmg_type] : nil
  @magic         = options.key?(:magic) || false
  @rarity        = Rarity::UNKNOWN if @magic && @rarity.nil?
  if options.key?(:attunement)
    @attunement  = 'Requires attunement'
    @attunement += " #{options[:attunement].strip}" if options[:attunement].is_a?(String)
  else
    @attunement  = ''
  end
  @properties = options.key?(:properties) ? options[:properties] : nil
end

Instance Attribute Details

#attunementObject (readonly)

Whether the item requires attunement or not. If a string, it will be prepended by "Requires attunement ".



21
22
23
# File 'lib/adventure/item.rb', line 21

def attunement
  @attunement
end

#descriptionObject (readonly)

Full description of the item, in GFM.



9
10
11
# File 'lib/adventure/item.rb', line 9

def description
  @description
end

#dmg_typeObject (readonly)

Item's type of damage.



14
15
16
# File 'lib/adventure/item.rb', line 14

def dmg_type
  @dmg_type
end

#nameObject (readonly)

Item's name.



7
8
9
# File 'lib/adventure/item.rb', line 7

def name
  @name
end

#rarityObject (readonly)

Item's rarity, if applicable. Either one of Rarity, a String, or nil when unset.



18
19
20
# File 'lib/adventure/item.rb', line 18

def rarity
  @rarity
end

#sourceObject

The source of the item, a String, with source name and page when applicable, or nil when unset.



31
32
33
# File 'lib/adventure/item.rb', line 31

def source
  @source
end

#typeObject (readonly)

Item's type, either one of Type or a String.



12
13
14
# File 'lib/adventure/item.rb', line 12

def type
  @type
end

#valueObject

The value of the item, a Float representing such value in gold pieces, or nil when unset.



24
25
26
# File 'lib/adventure/item.rb', line 24

def value
  @value
end

#weightObject

The weight of the item, a Float in kilograms, or nil when unset.



27
28
29
# File 'lib/adventure/item.rb', line 27

def weight
  @weight
end

Instance Method Details

#ac(dex_bonus = 0) ⇒ Integer?

The wearer's AC with this item, if it is an armor, nil otherwise.

Parameters:

  • dex_bonus (Integer, nil) (defaults to: 0)

    The wearer's Dexterity bonus.

Returns:

  • (Integer, nil)

    The AC, given the wearer's Dex bonus.



306
307
308
309
310
311
312
# File 'lib/adventure/item.rb', line 306

def ac(dex_bonus = 0)
  return nil unless armor?

  ac = @ac
  ac += [dex_bonus, @max_dex_bonus].min
  ac
end

#armor?Boolean

Whether this item is an armor or not.

Returns:

  • (Boolean)

    true if some AC modifier is set, false otherwise.



298
299
300
# File 'lib/adventure/item.rb', line 298

def armor?
  !@ac.nil?
end

#damage(advantage: false) ⇒ Integer?

Return the damage dealt by the item this iteration.

Each run of this method will return a different number, since each call represents one roll for damage --- which varies, obviously.

Returns:

  • (Integer, nil)

    This iteration's damage dealt by the item, or nil if not a valid weapon



264
265
266
267
268
269
270
271
272
273
274
275
# File 'lib/adventure/item.rb', line 264

def damage(advantage: false)
  if @dmg_die_count.zero? || @dmg_die_type.zero?
    nil
  else
    count = advantage ? @dmg_die_count * 2 : @dmg_die_count
    damage = @dmg_mod
    count.times do
      damage += rand(@dmg_die_type) + 1
    end
    damage
  end
end

#damage_notationString?

Return the default RPG notation for damage calculation.

This does not return actual damage!

Returns:

  • (String, nil)

    The item's damage in standart RPG notation, or nil if not a valid weapon.



243
244
245
246
247
248
249
250
251
252
253
254
255
# File 'lib/adventure/item.rb', line 243

def damage_notation
  if @dmg_die_count.nil? || @dmg_die_type.nil?
    nil
  else
    mod = ''
    if @dmg_mod.negative?
      mod = @dmg_mod.to_s
    elsif @dmg_mod.positive?
      mod = "+#{@dmg_mod}"
    end
    "#{@dmg_die_count}d#{@dmg_die_type}#{mod}"
  end
end

#magic?Boolean

Whether this item is magical or not.

Returns:

  • (Boolean)

    true if the item is magical, false otherwise.



291
292
293
# File 'lib/adventure/item.rb', line 291

def magic?
  @magic
end

#parse_damage_notation(notation) ⇒ Object (private)

Parse damage notation to actual damage data.

Parameters:

  • notation (String)

    A notation in the format XdY+Z.



326
327
328
329
330
331
332
333
334
# File 'lib/adventure/item.rb', line 326

def parse_damage_notation(notation)
  if /\d+d\d+([+-]\d+)?/.match?(notation)
    dmg = notation.scan(/(\d+)d(\d+)([+-]\d+)?/)[0]
    dmg.map!(&:to_i)
    dmg
  else
    [nil, nil, 0]
  end
end

#priceFloat

Alias for value.

Returns:

  • (Float)

    The value of the item.



317
318
319
# File 'lib/adventure/item.rb', line 317

def price
  @value
end

#weapon?Boolean

Whether this item is a weapon or not.

Returns:

  • (Boolean)

    true if the item is a weapon and have damage parameters, false otherwise.



280
281
282
283
284
285
286
# File 'lib/adventure/item.rb', line 280

def weapon?
  if @type.downcase.include?('weapon') && !damage_notation.nil?
    true
  else
    false
  end
end