Class: Lich::Gemstone::CreatureTemplate
- Inherits:
-
Object
- Object
- Lich::Gemstone::CreatureTemplate
- Defined in:
- documented/gemstone/creature.rb
Overview
Static creature template data (ID-less reference information)
Constant Summary collapse
- BOON_ADJECTIVES =
Adjectives that appear as a prefix to some creature names in bestiary lookups. When looking up a template, boon adjectives are stripped to normalize lookups (e.g. "dashing orc" -> "orc").
Includes weather effects (blurry, ethereal), conditions (diseased, sickly), dispositions (aggressive, raging), and visual states (glowing, shimmering).
%w[ adroit afflicted apt barbed belligerent blurry canny combative dazzling deft diseased drab dreary ethereal flashy flexile flickering flinty frenzied ghastly ghostly gleaming glittering glorious glowing grotesque hardy illustrious indistinct keen lanky luminous lustrous muculent nebulous oozing pestilent radiant raging ready resolute robust rune-covered shadowy shifting shimmering shining sickly green sinuous slimy sparkling spindly spiny stalwart steadfast stout tattoed tenebrous tough twinkling unflinching unyielding wavering wispy ]
- BOON_REGEX =
Clean creature name by removing boon adjectives Optimized to use single compiled regex instead of 50+ sequential matches
/^(#{BOON_ADJECTIVES.join('|')})\s+/i.freeze
- @@templates =
{}
- @@loaded =
false
Instance Attribute Summary collapse
-
#abilities ⇒ Object
readonly
Returns the value of attribute abilities.
-
#alchemy ⇒ Object
readonly
Returns the value of attribute alchemy.
-
#areas ⇒ Object
readonly
Returns the value of attribute areas.
-
#attack_attributes ⇒ Object
readonly
Returns the value of attribute attack_attributes.
-
#bcs ⇒ Object
readonly
Returns the value of attribute bcs.
-
#defense_attributes ⇒ Object
readonly
Returns the value of attribute defense_attributes.
-
#family ⇒ Object
readonly
Returns the value of attribute family.
-
#height ⇒ Object
readonly
Returns the value of attribute height.
-
#level ⇒ Object
readonly
Returns the value of attribute level.
-
#max_hp ⇒ Object
readonly
Returns the value of attribute max_hp.
-
#messaging ⇒ Object
readonly
Returns the value of attribute messaging.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
-
#otherclass ⇒ Object
readonly
Returns the value of attribute otherclass.
-
#picture ⇒ Object
readonly
Returns the value of attribute picture.
-
#size ⇒ Object
readonly
Returns the value of attribute size.
-
#special_other ⇒ Object
readonly
Returns the value of attribute special_other.
-
#speed ⇒ Object
readonly
Returns the value of attribute speed.
-
#treasure ⇒ Object
readonly
Returns the value of attribute treasure.
-
#type ⇒ Object
readonly
Returns the value of attribute type.
-
#undead ⇒ Object
readonly
Returns the value of attribute undead.
-
#url ⇒ Object
readonly
Returns the value of attribute url.
Class Method Summary collapse
-
.[](name) ⇒ Object
Lookup template by name.
-
.all ⇒ Object
Get all loaded templates.
-
.fix_template_name(template_name) ⇒ String
Normalizes a creature name for template lookup by removing boon adjectives and converting to lowercase.
-
.load_all(dir = File.join(File.dirname(__FILE__), 'creatures')) ⇒ Object
Load all templates from files dir defaults to the real templates directory; overridable so tests can load an isolated fixture directory instead.
Instance Method Summary collapse
-
#has_blood? ⇒ Boolean?
Returns whether the bestiary template says the creature has blood.
-
#has_bones? ⇒ Boolean?
Returns whether the bestiary template says the creature has bones.
-
#initialize(data) ⇒ CreatureTemplate
constructor
A new instance of CreatureTemplate.
-
#muggable? ⇒ Boolean?
Returns whether the bestiary template says the creature can be mugged.
Constructor Details
#initialize(data) ⇒ CreatureTemplate
Returns a new instance of CreatureTemplate.
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'documented/gemstone/creature.rb', line 45 def initialize(data) @name = data[:name] @url = data[:url] @picture = data[:picture] @level = data[:level]&.to_i @family = data[:family] @type = data[:type] @undead = data[:undead] # Tri-state (true/false/nil) - nil means uncatalogued/unknown, not false. @has_blood = data[:has_blood] @has_bones = data[:has_bones] @muggable = data[:muggable] @otherclass = data[:otherclass] || [] @areas = data[:areas] || [] @bcs = data[:bcs] @max_hp = data[:max_hp]&.to_i || data[:hitpoints]&.to_i @speed = data[:speed] @height = data[:height].to_i @size = data[:size] atk = data[:attack_attributes] || {} @attack_attributes = OpenStruct.new( physical_attacks: atk[:physical_attacks] || [], bolt_spells: atk[:bolt_spells] || [], warding_spells: normalize_spells(atk[:warding_spells]), offensive_spells: normalize_spells(atk[:offensive_spells]), maneuvers: atk[:maneuvers] || [], special_abilities: (atk[:special_abilities] || []).map { |s| SpecialAbility.new(s) } ) @defense_attributes = DefenseAttributes.new(data[:defense_attributes] || {}) @treasure = Treasure.new(data[:treasure] || {}) @messaging = Messaging.new(data[:messaging] || {}) @special_other = data[:special_other] @abilities = data[:abilities] || [] @alchemy = data[:alchemy] || [] end |
Instance Attribute Details
#abilities ⇒ Object (readonly)
Returns the value of attribute abilities.
22 23 24 |
# File 'documented/gemstone/creature.rb', line 22 def abilities @abilities end |
#alchemy ⇒ Object (readonly)
Returns the value of attribute alchemy.
22 23 24 |
# File 'documented/gemstone/creature.rb', line 22 def alchemy @alchemy end |
#areas ⇒ Object (readonly)
Returns the value of attribute areas.
22 23 24 |
# File 'documented/gemstone/creature.rb', line 22 def areas @areas end |
#attack_attributes ⇒ Object (readonly)
Returns the value of attribute attack_attributes.
22 23 24 |
# File 'documented/gemstone/creature.rb', line 22 def attack_attributes @attack_attributes end |
#bcs ⇒ Object (readonly)
Returns the value of attribute bcs.
22 23 24 |
# File 'documented/gemstone/creature.rb', line 22 def bcs @bcs end |
#defense_attributes ⇒ Object (readonly)
Returns the value of attribute defense_attributes.
22 23 24 |
# File 'documented/gemstone/creature.rb', line 22 def defense_attributes @defense_attributes end |
#family ⇒ Object (readonly)
Returns the value of attribute family.
22 23 24 |
# File 'documented/gemstone/creature.rb', line 22 def family @family end |
#height ⇒ Object (readonly)
Returns the value of attribute height.
22 23 24 |
# File 'documented/gemstone/creature.rb', line 22 def height @height end |
#level ⇒ Object (readonly)
Returns the value of attribute level.
22 23 24 |
# File 'documented/gemstone/creature.rb', line 22 def level @level end |
#max_hp ⇒ Object (readonly)
Returns the value of attribute max_hp.
22 23 24 |
# File 'documented/gemstone/creature.rb', line 22 def max_hp @max_hp end |
#messaging ⇒ Object (readonly)
Returns the value of attribute messaging.
22 23 24 |
# File 'documented/gemstone/creature.rb', line 22 def messaging @messaging end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
22 23 24 |
# File 'documented/gemstone/creature.rb', line 22 def name @name end |
#otherclass ⇒ Object (readonly)
Returns the value of attribute otherclass.
22 23 24 |
# File 'documented/gemstone/creature.rb', line 22 def otherclass @otherclass end |
#picture ⇒ Object (readonly)
Returns the value of attribute picture.
22 23 24 |
# File 'documented/gemstone/creature.rb', line 22 def picture @picture end |
#size ⇒ Object (readonly)
Returns the value of attribute size.
22 23 24 |
# File 'documented/gemstone/creature.rb', line 22 def size @size end |
#special_other ⇒ Object (readonly)
Returns the value of attribute special_other.
22 23 24 |
# File 'documented/gemstone/creature.rb', line 22 def special_other @special_other end |
#speed ⇒ Object (readonly)
Returns the value of attribute speed.
22 23 24 |
# File 'documented/gemstone/creature.rb', line 22 def speed @speed end |
#treasure ⇒ Object (readonly)
Returns the value of attribute treasure.
22 23 24 |
# File 'documented/gemstone/creature.rb', line 22 def treasure @treasure end |
#type ⇒ Object (readonly)
Returns the value of attribute type.
22 23 24 |
# File 'documented/gemstone/creature.rb', line 22 def type @type end |
#undead ⇒ Object (readonly)
Returns the value of attribute undead.
22 23 24 |
# File 'documented/gemstone/creature.rb', line 22 def undead @undead end |
#url ⇒ Object (readonly)
Returns the value of attribute url.
22 23 24 |
# File 'documented/gemstone/creature.rb', line 22 def url @url end |
Class Method Details
.[](name) ⇒ Object
Lookup template by name
168 169 170 171 172 173 174 175 176 177 178 179 |
# File 'documented/gemstone/creature.rb', line 168 def self.[](name) load_all unless @@loaded return nil unless name # Try exact match first template = @@templates[name.downcase] return template if template # Try with boon adjectives removed normalized_name = fix_template_name(name) @@templates[normalized_name] end |
.all ⇒ Object
Get all loaded templates
182 183 184 185 |
# File 'documented/gemstone/creature.rb', line 182 def self.all load_all unless @@loaded @@templates.values.uniq end |
.fix_template_name(template_name) ⇒ String
Normalizes a creature name for template lookup by removing boon adjectives and converting to lowercase.
The lookup key is always lowercase; boon adjectives ("dashing", "ethereal", "raging", etc.) are stripped as a prefix to match how multiple in-game instances of the same creature type may differ visually but share one template.
147 148 149 150 151 |
# File 'documented/gemstone/creature.rb', line 147 def self.fix_template_name(template_name) name = template_name.dup.downcase name.sub!(BOON_REGEX, '') name.strip end |
.load_all(dir = File.join(File.dirname(__FILE__), 'creatures')) ⇒ Object
Load all templates from files dir defaults to the real templates directory; overridable so tests can load an isolated fixture directory instead.
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'documented/gemstone/creature.rb', line 86 def self.load_all(dir = File.join(File.dirname(__FILE__), 'creatures')) return if @@loaded return unless File.directory?(dir) template_count = 0 Dir[File.join(dir, '*.rb')].each do |path| next if File.basename(path) == '_creature_template.rb' # Filename-derived name, used only as a fallback for files that # don't set their own :name - the file's own value takes priority # so a name with characters the filename can't represent (a # hyphen, an apostrophe) still round-trips correctly. Both the # display name and the lookup key come from the same source now; # previously both were overwritten from the filename regardless of # what the file itself said, silently breaking lookup for any # creature whose real name a slugified filename can't represent # exactly (e.g. "shield-maiden" -> "shield_maiden" -> "shield maiden"). fallback_name = File.basename(path, '.rb').tr('_', ' ') begin # Safer loading with validation file_content = File.read(path) data = load_template_data(file_content, path) next unless data.is_a?(Hash) data[:name] = fallback_name if data[:name].to_s.strip.empty? normalized_name = fix_template_name(data[:name]) if @@templates.key?(normalized_name) && $creature_debug respond "--- warning: '#{fallback_name}' collides with an already-loaded template on lookup key '#{normalized_name}' - one will silently overwrite the other" end template = new(data) @@templates[normalized_name] = template template_count += 1 rescue StandardError, ScriptError => e # ScriptError (SyntaxError's parent) isn't a StandardError, so a # single template file with malformed Ruby would otherwise abort # load_all entirely instead of just being skipped. respond "--- error loading template #{fallback_name}: #{e.}" if $creature_debug end end @@loaded = true respond "--- loaded #{template_count} creature templates" if $creature_debug end |
Instance Method Details
#has_blood? ⇒ Boolean?
Returns whether the bestiary template says the creature has blood.
190 191 192 |
# File 'documented/gemstone/creature.rb', line 190 def has_blood? @has_blood end |
#has_bones? ⇒ Boolean?
Returns whether the bestiary template says the creature has bones.
197 198 199 |
# File 'documented/gemstone/creature.rb', line 197 def has_bones? @has_bones end |
#muggable? ⇒ Boolean?
Returns whether the bestiary template says the creature can be mugged.
204 205 206 |
# File 'documented/gemstone/creature.rb', line 204 def muggable? @muggable end |