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 ".

  • :known (Boolean)

    Whether or not the object is a known one. Defaults to true.

  • :unknown_name (String)

    The name to be shown, if the object is unkown.

  • :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
237
238
239
240
241
242
243
244
245
# 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
  # > General properties.
  @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
  # > Armor properties.
  @ac              = options.key?(:ac) ? options[:ac] : nil
  @max_dex_bonus   = options.key?(:max_dex_bonus) ? options[:max_dex_bonus].to_i : 1_000
  # > Weapon properties.
  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 properties.
  @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
  # > Unkown properties.
  @known           = options.key?(:known) ? (options[:known] == true) : true
  @unknown_name    = options.key?(:unknown_name) ? options[:unknown_name].strip : "Unknown #{@type}"
  @unknown_desc    = options.key?(:unknown_desc) ? options[:unknown_desc].strip : "Unknown #{@type}."
  # > Misc properties.
  @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 ".



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

def attunement
  @attunement
end

#dmg_typeObject (readonly)

Item's type of damage.



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

def dmg_type
  @dmg_type
end

#knownObject (readonly)

Whether the item is identified (known) or not.



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

def known
  @known
end

#rarityObject (readonly)

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



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

def rarity
  @rarity
end

#sourceObject

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



29
30
31
# File 'lib/adventure/item.rb', line 29

def source
  @source
end

#typeObject (readonly)

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



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

def type
  @type
end

#valueObject

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



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

def value
  @value
end

#weightObject

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



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

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.



343
344
345
346
347
348
349
# File 'lib/adventure/item.rb', line 343

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.



335
336
337
# File 'lib/adventure/item.rb', line 335

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



301
302
303
304
305
306
307
308
309
310
311
312
# File 'lib/adventure/item.rb', line 301

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.



280
281
282
283
284
285
286
287
288
289
290
291
292
# File 'lib/adventure/item.rb', line 280

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

#descriptionString

Return a String with the item's description, or its placeholder if unknown.

Returns:

  • (String)

    A String with the item's description, or its placeholder if unknown.



271
272
273
# File 'lib/adventure/item.rb', line 271

def description
  @known ? @description : @unknown_desc
end

#identifyObject

Set the Adventure::Item as known.



359
360
361
# File 'lib/adventure/item.rb', line 359

def identify
  @known = true
end

#magic?Boolean

Whether this item is magical or not.

Returns:

  • (Boolean)

    true if the item is magical, false otherwise.



328
329
330
# File 'lib/adventure/item.rb', line 328

def magic?
  @magic
end

#nameString

Return a String with the item's name, or its placeholder if unknown.

Returns:

  • (String)

    A String with the item's name, or its placeholder if unknown.



250
251
252
# File 'lib/adventure/item.rb', line 250

def name
  @known ? @name : @unknown_name
end

#parse_damage_notation(notation) ⇒ Object (private)

Parse damage notation to actual damage data.

Parameters:

  • notation (String)

    A notation in the format XdY+Z.



368
369
370
371
372
373
374
375
376
# File 'lib/adventure/item.rb', line 368

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.



354
355
356
# File 'lib/adventure/item.rb', line 354

def price
  @value
end

#to_fFloat

Return a Float with the item's weight.

Returns:

  • (Float)

    A String with the item's weight.



264
265
266
# File 'lib/adventure/item.rb', line 264

def to_f
  @weight
end

#to_sString

An alias for name.

Returns:

  • (String)

    A String with the item's name, or its placeholder if unknown.



257
258
259
# File 'lib/adventure/item.rb', line 257

def to_s
  name
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.



317
318
319
320
321
322
323
# File 'lib/adventure/item.rb', line 317

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