Class: Lich::Gemstone::Bounty::Parser
- Inherits:
-
Object
- Object
- Lich::Gemstone::Bounty::Parser
- Defined in:
- documented/gemstone/bounty/parser.rb
Overview
Parses bounty descriptions to extract task information. This class uses regular expressions to match various task types.
Constant Summary collapse
- HMM_REGEX =
Regular expression to match the ‘Hmm’ phrase in task descriptions.
/(?:Hmm, I've got a task here from .*?(?<town>[A-Z].*?)\..*?)?/- LOCATION_REGEX =
Regular expression to match location descriptions in tasks.
/(?:on|in|near) (?:the\s+)?(?<area>[^.]+?)(?:\s+(?:near|between|under) (?<town>[^.]+))?/- GUARD_REGEX =
Regular expression to match various guard descriptions.
Regexp.union( /one of the guardsmen just inside the (?<town>Ta'Illistim) City Gate/, /one of the guardsmen just inside the Sapphire Gate/, /one of the guardsmen just inside the gate/, /one of the (?<town>.*) (?:gate|tunnel) guards/, /one of the (?<town>Icemule Trace) gate guards or the halfing Belle at the Pinefar Trading Post/, /Quin Telaren of (?<town>Wehnimer's Landing)/, /the dwarven militia sergeant near the (?<town>Kharam-Dzu) town gates/, /the sentry just outside town/, /the sentry just outside (?<town>Kraken's Fall)/, /the purser of (?<town>River's Rest)/, /the tavernkeeper at Rawknuckle's Common House/, /the captain of the (?<town>Contempt)/ )
- CONCOCTION_REGEX =
Regular expression to match descriptions of concoctions required for tasks.
/is working on a concoction that requires (?:an?|some|several) (?<herb>[^.]+?) found [oi]n (?:the\s+)?(?<area>[^.]+?)(?:\s+(?:near|under|between) [^.]+)?\. These samples must be in pristine condition\. You have been tasked to retrieve (?<number>\d+) (?:more\s+)?samples?\./- TASK_MAYBE_REGEX =
/^(?:The taskmaster told you: ")/- TASK_MATCHERS =
A hash mapping task types to their corresponding regular expressions.
{ :none => /^You are not currently assigned a task/, :bandit_assignment => /#{HMM_REGEX}It appears they have a bandit problem they'd like you to solve/, :creature_assignment => Regexp.union( /#{HMM_REGEX}It appears they have a creature problem they'd like you to solve/, /#{TASK_MAYBE_REGEX}I've got an urgent mission for you. We have a creature problem we'd like you to solve. Go report to the (?<town>[A-Z].*?) to find out/, /#{TASK_MAYBE_REGEX}I've a favor to ask of you. We have a creature problem we'd like you to solve: you know, by killing. Go report to the (?<town>[A-Z].*?)/ ), :gem_assignment => Regexp.union( /#{HMM_REGEX}The local gem dealer, (?<npc_name>[^,]+), has an order to fill and wants our help/, /All right. I've a mission for you. Our guest, the trader (?<npc_name>[^,]+)/, ), :heirloom_assignment => Regexp.union( /#{HMM_REGEX}It appears they need your help in tracking down some kind of lost heirloom/, /#{TASK_MAYBE_REGEX}?It's time for you to earn your keep around here. I'd like you track down a lost heirloom./ ), :herb_assignment => Regexp.union( /#{HMM_REGEX}The local [^,]+?, (?<npc_name>[^,]+), has asked for our aid. Head over there and see what you can do. Be sure to ASK about BOUNTIES./, /#{TASK_MAYBE_REGEX}I've got a mission for you. Our [^,]+?, (?<npc_name>[^,]+), has asked for our aid. Head over there and see what you can do./ ), :rescue_assignment => /#{HMM_REGEX}It appears that a local resident urgently needs our help in some matter/, :skin_assignment => Regexp.union( /#{HMM_REGEX}The local furrier (?<npc_name>.+) has an order to fill and wants our help/, /#{TASK_MAYBE_REGEX}?You look like you need work. The flesh merchant (?<npc_name>.+), down in the hold, has an order to fill and wants our help./ ), :taskmaster => /^You have succeeded in your task and can return to the Adventurer's Guild/, :heirloom_found => /^You have located (?:an?|some) (?<item>.+) and should bring (it back|your find) to #{GUARD_REGEX}\.$/, :guard => /^You succeeded in your task and should report back to #{GUARD_REGEX}\.$/, :dangerous_spawned => /^You have been tasked to hunt down and kill a particularly dangerous (?<creature>[^.]+) that has established a territory #{LOCATION_REGEX}\. You have provoked (?:his|her|its) attention and now you must(?: return to where you left (?:him|her|it) and)? kill (?:him|her|it)!$/, :rescue_spawned => /^You have made contact with the child you are to rescue and you must get (?:him|her) back alive to #{GUARD_REGEX}\.$/, :bandit => /^You have been tasked to(?: help (?<assist>\w+))? suppress (?<creature>bandit) activity #{LOCATION_REGEX}\. You need to kill (?<number>\d+) (?:more\s+)?of them to complete your task\.$/, :dangerous => /^You have been tasked to hunt down and kill a (?:particularly )?dangerous (?<creature>[^.]+) that has established a territory #{LOCATION_REGEX}\. You can get its attention by killing other creatures of the same type in its territory\.$/, :escort => /#{TASK_MAYBE_REGEX}?I've got a special mission for you\. A certain client has hired us to provide a protective escort on (?:his|her) upcoming journey\. Go to (?<start>[^.]+) and WAIT for (?:him|her) to meet you there\. You must guarantee (?:his|her) safety to (?<destination>[^.]+) as soon as you can, being ready for any dangers that the two of you may face\. Good luck!"?$/, :gem => Regexp.union( /^The gem dealer in (?<town>[^,]+), (?<npc_name>[^,]+), has received orders from multiple customers requesting (?:an?|some) (?<gem>[^.]+)\. You have been tasked to retrieve (?<number>\d+) (?:more\s+)?of them\. You can SELL them to the gem dealer as you find them\.$/, /^The gem dealer in has received orders from multiple customers requesting (?:an?|some) (?<gem>[^.]+)\. You have been tasked to retrieve (?<number>\d+) (?:more\s+)?of them\. You can SELL them to the gem dealer as you find them\.$/ ), :heirloom => /^You have been tasked to recover (?:an?|some) (?<item>[^.]+) that an unfortunate citizen lost after being attacked by an? (?<creature>[^.]+?) #{LOCATION_REGEX}\. The heirloom can be identified by the initials \w+ engraved upon it\. [^.]*?(?<action>LOOT|SEARCH)[^.]+\.$/, :herb => Regexp.union( /^The .+? in (?<town>[^,]+?), (?<npc_name>[^,]+), #{CONCOCTION_REGEX}$/, /^The .+, (?<npc_name>[^,]+), aboard the (?<town>\w+?) in .*? #{CONCOCTION_REGEX}$/ ), :rescue => /^You have been tasked to rescue the young (?:runaway|kidnapped) (?:son|daughter) of a local citizen\. A local divinist has had visions of the child fleeing from an? (?<creature>[^.]+?) #{LOCATION_REGEX}\. Find the area where the child was last seen and clear out the creatures that have been tormenting (?:him|her) in order to bring (?:him|her) out of hiding\.$/, :skin => /^You have been tasked to retrieve (?<number>\d+) (?<skin>[^.]+?)s? of at least (?<quality>[^.]+) quality for (?<npc_name>.+) in (?<town>[^.]+?)\. You can SKIN them off the corpse of an? (?<creature>[^.]+) or purchase them from another adventurer\. You can SELL the skins to the furrier as you collect them\."$/, :cull => Regexp.union( /^You have been tasked to(?: help (?<assist>\w+))? suppress (?<creature>[^.]+) activity #{LOCATION_REGEX}\. You need to kill (?<number>\d+) (?:more\s+)?of them to complete your task\.$/, /^You have been tasked to help (?<assist>\w+) rescue a missing child by suppressing (?<creature>[^.]+) activity #{LOCATION_REGEX} during the rescue attempt\. You need to kill (?<number>\d+) (?:more\s+)?of them to complete your task\.$/, /^You have been tasked to help (?<assist>\w+) retrieve an heirloom by suppressing (?<creature>[^.]+) activity #{LOCATION_REGEX} during the retrieval effort\. You need to kill (?<number>\d+) (?:more\s+)?of them to complete your task\.$/, /^You have been tasked to help (?<assist>\w+) kill a dangerous creature by suppressing (?<creature>[^.]+) activity #{LOCATION_REGEX} during the hunt\. You need to kill (?<number>\d+) (?:more\s+)?of them to complete your task\.$/, ), :failed => Regexp.union( /^You have failed in your task/, /^The child you were tasked to rescue is gone and your task is failed. Report this failure to the Adventurer's Guild./, ), }
Instance Attribute Summary collapse
-
#description ⇒ Object
readonly
Returns the value of attribute description.
Class Method Summary collapse
-
.parse(desc = checkbounty) ⇒ Hash?
Parses a bounty description from a string.
Instance Method Summary collapse
-
#determine_town(captured_town) ⇒ String
Determines the town based on captured town name and description context.
-
#initialize(description) ⇒ Parser
constructor
Initializes a new Parser instance with a description.
-
#normalized_creature_name(raw_creature_name) ⇒ String
Normalizes the creature name based on specific patterns.
-
#parse ⇒ Hash?
Parses the description to identify the task type and details.
-
#task_details_from(captures) ⇒ Hash
Extracts task details from named captures.
Constructor Details
#initialize(description) ⇒ Parser
Initializes a new Parser instance with a description.
96 97 98 |
# File 'documented/gemstone/bounty/parser.rb', line 96 def initialize(description) @description = description end |
Instance Attribute Details
#description ⇒ Object (readonly)
Returns the value of attribute description.
100 101 102 |
# File 'documented/gemstone/bounty/parser.rb', line 100 def description @description end |
Class Method Details
.parse(desc = checkbounty) ⇒ Hash?
Parses a bounty description from a string.
192 193 194 195 196 197 198 |
# File 'documented/gemstone/bounty/parser.rb', line 192 def self.parse(desc = checkbounty) if desc&.empty? return else self.new(desc).parse end end |
Instance Method Details
#determine_town(captured_town) ⇒ String
Determines the town based on captured town name and description context.
173 174 175 176 177 178 179 180 181 182 183 184 185 |
# File 'documented/gemstone/bounty/parser.rb', line 173 def determine_town(captured_town) if description =~ /the sentry just outside town\.$/ "Kraken's Fall" elsif description =~ /the tavernkeeper at Rawknuckle's Common House\.$/ "Cold River" elsif description =~ /\b(?:Captain|Reiya|Ataum|Galeb)\b/ || description =~ /gem dealer in has received/ # the latter is a temporary workaround because of an actual typo in the messaging # that should be removed if it is ever actually fixed 'Contempt' else captured_town end end |
#normalized_creature_name(raw_creature_name) ⇒ String
Normalizes the creature name based on specific patterns.
157 158 159 160 161 162 163 164 165 166 |
# File 'documented/gemstone/bounty/parser.rb', line 157 def normalized_creature_name(raw_creature_name) case raw_creature_name when /^\w+ being$/ 'being' when /^\w+ magna vereri$/ 'magna vereri' else raw_creature_name end end |
#parse ⇒ Hash?
Parses the description to identify the task type and details.
106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'documented/gemstone/bounty/parser.rb', line 106 def parse TASK_MATCHERS.each do |(task_type, regex)| if (md = regex.match(description)) return ( { type: task_type, }.merge( task_details_from(md.named_captures) ).compact ) end end end |
#task_details_from(captures) ⇒ Hash
Extracts task details from named captures.
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
# File 'documented/gemstone/bounty/parser.rb', line 125 def task_details_from(captures) { requirements: {} }.tap do |task_details| if (town = determine_town(captures["town"])) task_details[:town] = town task_details[:requirements][:town] = town end captures.each do |(key, value)| task_details[:requirements][key.to_sym] = case key when "town" town when "number" value.to_i when "action" value.downcase when "creature" normalized_creature_name(value) else value end end end end |