Module: Lich::Gemstone::Combat::Definitions::Statuses

Defined in:
documented/gemstone/combat/defs/statuses.rb

Overview

Combat status effect pattern definitions and parsing.

Defines patterns for recognizing status effects like stun, prone, blind, webbed, poisoned, etc., along with the messages that indicate those effects are applied (add_patterns) or removed (remove_patterns) on targets. Provides a .parse(line) method for efficient pattern matching against game output.

Defined Under Namespace

Classes: StatusDef

Constant Summary collapse

STATUS_EFFECTS =

Core status effects with both add and remove patterns

[
  StatusDef.new(:blind,
                [/You blinded (?<target>[^!]+)!/].freeze,
                [/(?<target>.+?) vision clears\./].freeze),

  StatusDef.new(:immobilized,
                [
                  /(?<target>.+?) form is entangled in an unseen force that restricts .+? movement\./,
                  /(?<target>.+?) shakes in utter terror!/
                ].freeze,
                [
                  /(?<target>.+?) movements no longer appear hampered as the lunar light encircling .+? fades away\./,
                  /The restricting force enveloping (?<target>.+?) fades away\./,
                ].freeze),

  StatusDef.new(:prone,
                [
                  /It is knocked to the ground!/,
                  /(?<target>.+?) is knocked to the ground!/,
                  /(?<target>.+?) falls to the ground!/
                ].freeze,
                [
                  /(?<target>.+?) stands back up\./,
                  /(?<target>.+?) gets back to .+? feet\./,
                  /(?<target>.+?) rises to .+? feet\./,
                  /(?<target>.+?) stands up\./
                ].freeze),

  StatusDef.new(:stunned,
                [/The (?<target>.+?) is stunned!/].freeze,
                [
                  /(?<target>.+?) shakes off the stun effect\./,
                  /(?<target>.+?) regains .+? composure\./,
                  /(?<target>.+?) is no longer stunned\./
                ].freeze),

  StatusDef.new(:sunburst,
                [/(?<target>.+?) reels and stumbles under the intense flare!/].freeze,
                [/(?<target>.+?) blinks a few times, regaining a sense of balance\./].freeze),

  StatusDef.new(:webbed,
                [/(?<target>.+?) becomes ensnared in thick strands of webbing!/].freeze,
                [
                  /(?<target>.+?) breaks free of the webs\./,
                  /(?<target>.+?) struggles free of the webs\./,
                  /(?<target>.+?) tears through the webbing\./,
                  /The webs dissolve from around (?<target>.+?)\./
                ].freeze),

  StatusDef.new(:sleeping,
                [
                  /(?<target>.+?) falls into a deep slumber\./,
                  /(?<target>.+?) falls asleep\./
                ].freeze,
                [
                  /(?<target>.+?) wakes up\./,
                  /(?<target>.+?) awakens\./,
                  /(?<target>.+?) opens .+? eyes\./
                ].freeze),

  StatusDef.new(:poisoned,
                [/(?<target>.+?) appears to be suffering from a poison\./].freeze,
                [
                  /(?<target>.+?) looks much better\./,
                  /(?<target>.+?) recovers from the poison\./
                ].freeze),

  StatusDef.new(:roundtime,
                [/(?<target>.+?) struggles momentarily with the gale\./].freeze,
                [].freeze),

  StatusDef.new(:sounds,
                [/(?<target>.+?) seems to be distracted by something\./].freeze,
                [].freeze),

  StatusDef.new(:calm,
                [/A calm washes over (?<target>.+?)\./].freeze,
                [
                  /The calmed look leaves (?<target>.+?)\./,
                  /(?<target>.+?) is enraged by your attack\!/
                ].freeze),

  StatusDef.new(:natures_decay,
                [
                  /An earthy, sweet aroma clings to (?<target>.+?) in a murky haze, accompanied by soot brown specks of leaf mold\./,
                  /An earthy, sweet aroma wafts from (?<target>.+?) in a murky haze\./,
                  /The earthy, sweet aroma clinging to (?<target>.+?) grows more pervasive\./
                ].freeze,
                [/The earthy, sweet aroma surrounding (?<target>.+?) dwindles as the murky haze disperses./].freeze),

  StatusDef.new(:tangleweed,
                [/You notice .+? scrape into (?<target>.+?) skin. .+? suddenly looks very weak!/].freeze,
                [/(?<target>.+?) appears to recover some strength\./].freeze)
].freeze
ADD_LOOKUP =

Create lookup tables for fast pattern matching

STATUS_EFFECTS.flat_map do |status_def|
  status_def.add_patterns.compact.map { |pattern| [pattern, status_def.name, :add] }
end.freeze
REMOVE_LOOKUP =

Lookup table mapping remove patterns to status names and action type.

Built from all remove_patterns across STATUS_EFFECTS. Each entry is a 3-tuple: [pattern, status_name, :remove]. Used by .parse(line) to detect when a status effect expires.

STATUS_EFFECTS.flat_map do |status_def|
  status_def.remove_patterns.compact.map { |pattern| [pattern, status_def.name, :remove] }
end.freeze
ALL_LOOKUP =

Combined lookup table of all add and remove patterns.

Union of ADD_LOOKUP and REMOVE_LOOKUP. Used to build the STATUS_DETECTOR regex and STATUS_GATE substring filter for efficient parsing. Each entry is a 3-tuple: [pattern, status_name, action] where action is :add or :remove.

(ADD_LOOKUP + REMOVE_LOOKUP).freeze
STATUS_DETECTOR =

Compiled regex for fast detection. NOTE: costs ~1ms per non-matching line (unanchored .+? alternatives); kept for compatibility but the literal gate below is what parse uses.

Regexp.union(ALL_LOOKUP.map(&:first)).freeze

Class Method Summary collapse

Class Method Details

.parse(line) ⇒ Object

Parse status effect from line



160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'documented/gemstone/combat/defs/statuses.rb', line 160

def self.parse(line)
  # Fast rejection: a line can only match a status pattern if it
  # contains that pattern's literal fragment.
  return nil if PatternGate.rejects?(STATUS_GATE, STATUS_ALWAYS_SCAN, line)

  ALL_LOOKUP.each do |pattern, name, action|
    if (match = pattern.match(line))
      result = {
        status: name,
        action: action # :add or :remove
      }
      result[:target] = match[:target] if match.names.include?('target') && match[:target]
      return result
    end
  end
  nil
end