Module: Lich::DragonRealms::DRCH

Defined in:
documented/dragonrealms/commons/common-healing.rb,
documented/dragonrealms/commons/common-healing-data.rb

Defined Under Namespace

Classes: HealthResult, Wound

Constant Summary collapse

BLEED_RATE_TO_SEVERITY =

Maps bleed rates from health command to severity number. A partially tended wound is considered more severe than its non-tended counterpart because once the bandages come off then the wound is much worse so they should be triaged first. https://elanthipedia.play.net/Damage#Bleeding_Levels

Skill to tend based on https://elanthipedia.play.net/First_Aid_skill#Skill_to_Tend A 'nil' value means that can't be tended because already is tended or isn't bleeding. Maps bleed rates from health command to severity number.

A partially tended wound is considered more severe than its non-tended counterpart because once the bandages come off then the wound is much worse so they should be triaged first.

See Also:

  • WOUND_SEVERITY
  • LODGED_SEVERITY
{
  'tended'                   => { severity: 1, bleeding: false, skill_to_tend: nil, skill_to_tend_internal: nil }.freeze,
  '(tended)'                 => { severity: 1, bleeding: false, skill_to_tend: nil, skill_to_tend_internal: nil }.freeze,
  'clotted'                  => { severity: 2, bleeding: false, skill_to_tend: nil, skill_to_tend_internal: nil }.freeze,
  'clotted(tended)'          => { severity: 3, bleeding: false, skill_to_tend: nil, skill_to_tend_internal: nil }.freeze,
  'slight'                   => { severity: 3, bleeding: true, skill_to_tend: 30, skill_to_tend_internal: 600 }.freeze,
  'slight(tended)'           => { severity: 4, bleeding: true, skill_to_tend: nil, skill_to_tend_internal: nil }.freeze,
  'light'                    => { severity: 4, bleeding: true, skill_to_tend: 40, skill_to_tend_internal: 600 }.freeze,
  'light(tended)'            => { severity: 5, bleeding: true, skill_to_tend: nil, skill_to_tend_internal: nil }.freeze,
  'moderate'                 => { severity: 5, bleeding: true, skill_to_tend: 50, skill_to_tend_internal: 600 }.freeze,
  'moderate(tended)'         => { severity: 6, bleeding: true, skill_to_tend: nil, skill_to_tend_internal: nil }.freeze,
  'bad'                      => { severity: 6, bleeding: true, skill_to_tend: 60, skill_to_tend_internal: 620 }.freeze,
  'bad(tended)'              => { severity: 7, bleeding: true, skill_to_tend: nil, skill_to_tend_internal: nil }.freeze,
  'very bad'                 => { severity: 7, bleeding: true, skill_to_tend: 75, skill_to_tend_internal: 620 }.freeze,
  'very bad(tended)'         => { severity: 8, bleeding: true, skill_to_tend: nil, skill_to_tend_internal: nil }.freeze,
  'heavy'                    => { severity: 8, bleeding: true, skill_to_tend: 90, skill_to_tend_internal: 640 }.freeze,
  'heavy(tended)'            => { severity: 9, bleeding: true, skill_to_tend: nil, skill_to_tend_internal: nil }.freeze,
  'very heavy'               => { severity: 9, bleeding: true, skill_to_tend: 105, skill_to_tend_internal: 640 }.freeze,
  'very heavy(tended)'       => { severity: 10, bleeding: true, skill_to_tend: nil, skill_to_tend_internal: nil }.freeze,
  'severe'                   => { severity: 10, bleeding: true, skill_to_tend: 120, skill_to_tend_internal: 660 }.freeze,
  'severe(tended)'           => { severity: 11, bleeding: true, skill_to_tend: nil, skill_to_tend_internal: nil }.freeze,
  'very severe'              => { severity: 11, bleeding: true, skill_to_tend: 140, skill_to_tend_internal: 660 }.freeze,
  'very severe(tended)'      => { severity: 12, bleeding: true, skill_to_tend: nil, skill_to_tend_internal: nil }.freeze,
  'extremely severe'         => { severity: 12, bleeding: true, skill_to_tend: 160, skill_to_tend_internal: 700 }.freeze,
  'extremely severe(tended)' => { severity: 13, bleeding: true, skill_to_tend: nil, skill_to_tend_internal: nil }.freeze,
  'profuse'                  => { severity: 13, bleeding: true, skill_to_tend: 180, skill_to_tend_internal: 800 }.freeze,
  'profuse(tended)'          => { severity: 14, bleeding: true, skill_to_tend: nil, skill_to_tend_internal: nil }.freeze,
  'very profuse'             => { severity: 14, bleeding: true, skill_to_tend: 205, skill_to_tend_internal: 800 }.freeze,
  'very profuse(tended)'     => { severity: 15, bleeding: true, skill_to_tend: nil, skill_to_tend_internal: nil }.freeze,
  'massive'                  => { severity: 15, bleeding: true, skill_to_tend: 230, skill_to_tend_internal: 850 }.freeze,
  'massive(tended)'          => { severity: 16, bleeding: true, skill_to_tend: nil, skill_to_tend_internal: nil }.freeze,
  'gushing'                  => { severity: 16, bleeding: true, skill_to_tend: 255, skill_to_tend_internal: 850 }.freeze,
  'gushing(tended)'          => { severity: 17, bleeding: true, skill_to_tend: nil, skill_to_tend_internal: nil }.freeze,
  'massive stream'           => { severity: 17, bleeding: true, skill_to_tend: 285, skill_to_tend_internal: 1000 }.freeze,
  'massive stream(tended)'   => { severity: 18, bleeding: true, skill_to_tend: nil, skill_to_tend_internal: nil }.freeze,
  'gushing fountain'         => { severity: 18, bleeding: true, skill_to_tend: 285, skill_to_tend_internal: 1200 }.freeze,
  'gushing fountain(tended)' => { severity: 19, bleeding: true, skill_to_tend: nil, skill_to_tend_internal: nil }.freeze,
  'uncontrollable'           => { severity: 19, bleeding: true, skill_to_tend: 400, skill_to_tend_internal: 1400 }.freeze,
  'uncontrollable(tended)'   => { severity: 20, bleeding: true, skill_to_tend: nil, skill_to_tend_internal: nil }.freeze,
  'unbelievable'             => { severity: 20, bleeding: true, skill_to_tend: 500, skill_to_tend_internal: 1600 }.freeze,
  'unbelievable(tended)'     => { severity: 21, bleeding: true, skill_to_tend: nil, skill_to_tend_internal: nil }.freeze,
  'beyond measure'           => { severity: 21, bleeding: true, skill_to_tend: 600, skill_to_tend_internal: 1750 }.freeze,
  'beyond measure(tended)'   => { severity: 22, bleeding: true, skill_to_tend: nil, skill_to_tend_internal: nil }.freeze,
  'death awaits'             => { severity: 22, bleeding: true, skill_to_tend: 700, skill_to_tend_internal: 1750 }.freeze,
}.freeze
LODGED_SEVERITY =

https://elanthipedia.play.net/Damage#Lodged_Items Maps lodged item descriptions to severity levels.

Examples:

LODGED_SEVERITY["loosely hanging"] # => 1
LODGED_SEVERITY["deeply"] # => 4

See Also:

  • BLEED_RATE_TO_SEVERITY
{
  'loosely hanging' => 1,
  'shallowly'       => 2,
  'firmly'          => 3,
  'deeply'          => 4,
  'savagely'        => 5
}.freeze
WOUND_SEVERITY =

https://elanthipedia.play.net/Damage#Wound_Severity_Levels Maps wound descriptions to severity levels.

Examples:

WOUND_SEVERITY["insignificant"] # => 1
WOUND_SEVERITY["devastating"] # => 11

See Also:

  • BLEED_RATE_TO_SEVERITY
{
  'insignificant'    => 1,
  'negligible'       => 2,
  'minor'            => 3,
  'more than minor'  => 4,
  'harmful'          => 5,
  'very harmful'     => 6,
  'damaging'         => 7,
  'very damaging'    => 8,
  'severe'           => 9,
  'very severe'      => 10,
  'devastating'      => 11,
  'very devastating' => 12,
  'useless'          => 13
}.freeze
PARASITES_REGEX =

https://elanthipedia.play.net/Damage#Parasites Regular expressions to match parasite descriptions.

Examples:

PARASITES_REGEX[0].match("small black blood mite") # => #<MatchData>

See Also:

  • WOUND_SEVERITY
[
  /(?:small|large) (?:black|red) blood mite/,
  /(?:black|red|albino) (sand|forest) leech/,
  /(?:green|red) blood worm/,
  /retch maggot/
].freeze
PERCEIVE_HEALTH_SEVERITY_REGEX =

Parses the severity number out of the wound line from 'perceive health self'. For example, the 'negligible' in "Fresh External: light scratches -- negligible" Parses the severity number out of the wound line from 'perceive health self'.

Examples:

"Fresh External:  light scratches -- negligible".match(PERCEIVE_HEALTH_SEVERITY_REGEX)

Returns:

  • (MatchData, nil)

    returns MatchData if matched, nil otherwise

/(?<freshness>Fresh|Scars) (?<location>External|Internal).+--\s+(?<severity>insignificant|negligible|minor|more than minor|harmful|very harmful|damaging|very damaging|severe|very severe|devastating|very devastating|useless)\b/
BODY_PART_REGEX =
/(?<part>(?:l\.|r\.|left|right)?\s?(?:\w+))/
WOUND_BODY_PART_REGEX =

Matches body parts in the health line for wounds and bleeders.

/(?:inside)?\s?#{BODY_PART_REGEX}/
LODGED_BODY_PART_REGEX =

Matches body parts in the health line for lodged items.

/lodged .* into your #{BODY_PART_REGEX}/
PARASITE_BODY_PART_REGEX =

Matches body parts in the health line for parasites.

/on your #{BODY_PART_REGEX}/
BLEEDER_LINE_REGEX =

Matches body parts in the health line for bleeders.

/^\b(inside\s+)?((l\.|r\.|left|right)\s+)?(head|eye|neck|chest|abdomen|back|arm|hand|leg|tail|skin)\b/
WOUND_SEVERITY_REGEX_MAP =

https://elanthipedia.play.net/Damage#Wounds Maps wound descriptions to severity levels using regular expressions.

Examples:

WOUND_SEVERITY_REGEX_MAP[/minor abrasions to the head/] # => { severity: 1, internal: false, scar: false }

See Also:

  • WOUND_SEVERITY
{
  # insignificant
  /minor abrasions to the #{WOUND_BODY_PART_REGEX}/                                                                    => { severity: 1, internal: false, scar: false }.freeze,
  /a few nearly invisible scars along the #{WOUND_BODY_PART_REGEX}/                                                    => { severity: 1, internal: false, scar: true }.freeze,
  # negligible
  /some tiny scars (?:across|along) the #{WOUND_BODY_PART_REGEX}/                                                      => { severity: 2, internal: false, scar: true }.freeze,
  /(?:light|tiny) scratches to the #{WOUND_BODY_PART_REGEX}/                                                           => { severity: 2, internal: false, scar: false }.freeze,
  # minor / more than minor
  /a bruised (?<part>head)/                                                                                            => { severity: 3, internal: true, scar: false }.freeze,
  /(?<skin>a small skin rash)/                                                                                         => { severity: 3, internal: false, scar: false }.freeze,
  /(?<skin>loss of skin tone)/                                                                                         => { severity: 3, internal: false, scar: true }.freeze,
  /(?<skin>some minor twitching)/                                                                                      => { severity: 3, internal: true, scar: false }.freeze,
  /(?<skin>slight difficulty moving your fingers and toes)/                                                            => { severity: 3, internal: true, scar: true }.freeze,
  /cuts and bruises about the #{WOUND_BODY_PART_REGEX}/                                                                => { severity: 3, internal: false, scar: false }.freeze,
  /minor scar\w+ (?:about|along|across) the #{WOUND_BODY_PART_REGEX}/                                                  => { severity: 3, internal: false, scar: true }.freeze,
  /minor swelling and bruising (?:around|in) the #{WOUND_BODY_PART_REGEX}/                                             => { severity: 3, internal: true, scar: false }.freeze,
  /occasional twitch\w* (?:on|in) the #{WOUND_BODY_PART_REGEX}/                                                        => { severity: 3, internal: true, scar: true }.freeze,
  /a black and blue #{WOUND_BODY_PART_REGEX}/                                                                          => { severity: 3, internal: false, scar: false }.freeze,
  # harmful / very harmful
  /a deeply bruised (?<part>head)/                                                                                     => { severity: 4, internal: true, scar: false }.freeze,
  /(?<skin>a large skin rash)/                                                                                         => { severity: 4, internal: false, scar: false }.freeze,
  /(?<skin>minor skin discoloration)/                                                                                  => { severity: 4, internal: false, scar: true }.freeze,
  /(?<skin>some severe twitching)/                                                                                     => { severity: 4, internal: true, scar: false }.freeze,
  /(?<skin>slight numbness in your arms and legs)/                                                                     => { severity: 4, internal: true, scar: true }.freeze,
  /deep cuts (?:about|across) the #{WOUND_BODY_PART_REGEX}/                                                            => { severity: 4, internal: false, scar: false }.freeze,
  /severe scarring (?:across|along|about) the #{WOUND_BODY_PART_REGEX}/                                                => { severity: 4, internal: false, scar: true }.freeze,
  /a severely swollen and\s?(?:deeply)? bruised #{WOUND_BODY_PART_REGEX}/                                              => { severity: 4, internal: true, scar: false }.freeze,
  /(?:occasional|constant) twitch\w* (?:on|in) the #{WOUND_BODY_PART_REGEX}/                                           => { severity: 4, internal: true, scar: true }.freeze,
  /a bruised and swollen (?<part>(?:right|left) (?:eye))/                                                              => { severity: 4, internal: false, scar: false }.freeze,
  # damaging / very damaging
  /some deep slashes and cuts about the (?<part>head)/                                                                 => { severity: 5, internal: false, scar: false }.freeze,
  /severe scarring and ugly gashes about the #{WOUND_BODY_PART_REGEX}/                                                 => { severity: 5, internal: false, scar: true }.freeze,
  /major swelling and bruising around the (?<part>head)/                                                               => { severity: 5, internal: true, scar: false }.freeze,
  /an occasional twitch on the fore(?<part>head)/                                                                      => { severity: 5, internal: true, scar: true }.freeze,
  /a bruised,* swollen and bleeding #{WOUND_BODY_PART_REGEX}/                                                          => { severity: 5, internal: false, scar: false }.freeze,
  /deeply scarred gashes across the #{WOUND_BODY_PART_REGEX}/                                                          => { severity: 5, internal: false, scar: true }.freeze,
  /a severely swollen, bruised and crossed #{WOUND_BODY_PART_REGEX}/                                                   => { severity: 5, internal: true, scar: false }.freeze,
  /a constant twitching in the #{WOUND_BODY_PART_REGEX}/                                                               => { severity: 5, internal: true, scar: true }.freeze,
  /deep slashes across the #{WOUND_BODY_PART_REGEX}/                                                                   => { severity: 5, internal: false, scar: false }.freeze,
  /a severely swollen and deeply bruised #{WOUND_BODY_PART_REGEX}/                                                     => { severity: 5, internal: true, scar: false }.freeze,
  /severely swollen and bruised #{WOUND_BODY_PART_REGEX}/                                                              => { severity: 5, internal: true, scar: false }.freeze,
  /a constant twitching in the (?<part>chest) area and difficulty breathing/                                           => { severity: 5, internal: true, scar: true }.freeze,
  /(?<abdomen>a somewhat emaciated look)/                                                                              => { severity: 5, internal: true, scar: true }.freeze,
  /a constant twitching in the #{WOUND_BODY_PART_REGEX} and difficulty moving in general/                              => { severity: 5, internal: true, scar: true }.freeze,
  /(?<skin>a body rash)/                                                                                               => { severity: 5, internal: false, scar: false }.freeze,
  /severe (?<part>skin) discoloration/                                                                                 => { severity: 5, internal: false, scar: true }.freeze,
  /(?<skin>difficulty controlling actions)/                                                                            => { severity: 5, internal: true, scar: false }.freeze,
  /(?<skin>numbness in your fingers and toes)/                                                                         => { severity: 5, internal: true, scar: true }.freeze,
  # severe / very severe
  /(?<head>a cracked skull with deep slashes)/                                                                         => { severity: 6, internal: false, scar: false }.freeze,
  /missing chunks out of the (?<part>head)/                                                                            => { severity: 6, internal: false, scar: true }.freeze,
  /a bruised, swollen and slashed #{WOUND_BODY_PART_REGEX}/                                                            => { severity: 6, internal: false, scar: false }.freeze,
  /a punctured and shriveled #{WOUND_BODY_PART_REGEX}/                                                                 => { severity: 6, internal: false, scar: true }.freeze,
  /a severely swollen,* bruised and cloudy #{WOUND_BODY_PART_REGEX}/                                                   => { severity: 6, internal: true, scar: false }.freeze,
  /a clouded #{WOUND_BODY_PART_REGEX}/                                                                                 => { severity: 6, internal: true, scar: true }.freeze,
  /gaping holes in the #{WOUND_BODY_PART_REGEX}/                                                                       => { severity: 6, internal: false, scar: false }.freeze,
  /a broken #{WOUND_BODY_PART_REGEX} with gaping holes/                                                                => { severity: 6, internal: false, scar: false }.freeze,
  /severe scarring and ugly gashes about the #{WOUND_BODY_PART_REGEX}/                                                 => { severity: 6, internal: false, scar: true }.freeze,
  /severe scarring and chunks of flesh missing from the #{WOUND_BODY_PART_REGEX}/                                      => { severity: 6, internal: false, scar: true }.freeze,
  /a severely swollen and deeply bruised #{WOUND_BODY_PART_REGEX} with odd protrusions under the skin/                 => { severity: 6, internal: true, scar: false }.freeze,
  /a severely swollen and deeply bruised (?<part>chest) area with odd protrusions under the skin/                      => { severity: 6, internal: true, scar: false }.freeze,
  /a partially paralyzed #{WOUND_BODY_PART_REGEX}/                                                                     => { severity: 6, internal: true, scar: true }.freeze,
  /a painful #{WOUND_BODY_PART_REGEX} and difficulty moving without pain/                                              => { severity: 6, internal: true, scar: true }.freeze,
  /a painful (?<part>chest) area and difficulty getting a breath without pain/                                         => { severity: 6, internal: true, scar: true }.freeze,
  /a severely bloated and discolored #{WOUND_BODY_PART_REGEX} with strange round lumps under the skin/                 => { severity: 6, internal: true, scar: false }.freeze,
  /(?<abdomen>a definite greenish pallor and emaciated look)/                                                          => { severity: 6, internal: true, scar: true }.freeze,
  /(?<skin>a painful,* inflamed body rash)/                                                                            => { severity: 6, internal: false, scar: false }.freeze,
  /(?<skin>a painful,* enflamed body rash)/                                                                            => { severity: 6, internal: false, scar: false }.freeze,
  /some shriveled and oddly folded (?<part>skin)/                                                                      => { severity: 6, internal: false, scar: true }.freeze,
  /(?<skin>partial paralysis of the entire body)/                                                                      => { severity: 6, internal: true, scar: false }.freeze,
  /(?<skin>numbness in your arms and legs)/                                                                            => { severity: 6, internal: true, scar: true }.freeze,
  # devastating / very devastating
  /(?<head>a crushed skull with horrendous wounds)/                                                                    => { severity: 7, internal: false, scar: false }.freeze,
  /a mangled and malformed (?<part>head)/                                                                              => { severity: 7, internal: false, scar: true }.freeze,
  /a ghastly bloated (?<part>head) with bleeding from the ears/                                                        => { severity: 7, internal: true, scar: false }.freeze,
  /a confused look with sporadic twitching of the fore(?<part>head)/                                                   => { severity: 7, internal: true, scar: true }.freeze,
  /a bruised,* swollen and shattered #{WOUND_BODY_PART_REGEX}/                                                         => { severity: 7, internal: false, scar: false }.freeze,
  /a painfully mangled and malformed #{WOUND_BODY_PART_REGEX} in a shattered eye socket/                               => { severity: 7, internal: false, scar: true }.freeze,
  /a severely swollen,* bruised and blind #{WOUND_BODY_PART_REGEX}/                                                    => { severity: 7, internal: true, scar: false }.freeze,
  /severely scarred,* mangled and malformed #{WOUND_BODY_PART_REGEX}/                                                  => { severity: 7, internal: false, scar: true }.freeze,
  /a completely clouded #{WOUND_BODY_PART_REGEX}/                                                                      => { severity: 7, internal: true, scar: true }.freeze,
  /a shattered #{WOUND_BODY_PART_REGEX} with gaping wounds/                                                            => { severity: 7, internal: false, scar: false }.freeze,
  /shattered (?<part>chest) area with gaping wounds/                                                                   => { severity: 7, internal: false, scar: false }.freeze,
  /a severely swollen and deeply bruised #{WOUND_BODY_PART_REGEX} with bones protruding out from the skin/             => { severity: 7, internal: true, scar: false }.freeze,
  /a severely swollen and deeply bruised #{WOUND_BODY_PART_REGEX} with ribs or vertebrae protruding out from the skin/ => { severity: 7, internal: true, scar: false }.freeze,
  /a severely paralyzed #{WOUND_BODY_PART_REGEX}/                                                                      => { severity: 7, internal: true, scar: true }.freeze,
  /a severely painful #{WOUND_BODY_PART_REGEX} with significant problems moving/                                       => { severity: 7, internal: true, scar: true }.freeze,
  /a severely painful (?<part>chest) area with significant problems breathing/                                         => { severity: 7, internal: true, scar: true }.freeze,
  /#{WOUND_BODY_PART_REGEX} deeply gouged with gaping wounds/                                                          => { severity: 7, internal: false, scar: false }.freeze,
  /a severely bloated and discolored #{WOUND_BODY_PART_REGEX} with strange round lumps under the skin/                 => { severity: 7, internal: true, scar: false }.freeze,
  /(?<abdomen>a severely yellow pallor and a look of starvation)/                                                      => { severity: 7, internal: true, scar: true }.freeze,
  /boils and sores around the (?<part>skin)/                                                                           => { severity: 7, internal: false, scar: false }.freeze,
  /severely stiff and shriveled (?<part>skin) that seems to be peeling off the body/                                   => { severity: 7, internal: false, scar: true }.freeze,
  /(?<skin>severe paralysis of the entire body)/                                                                       => { severity: 7, internal: true, scar: false }.freeze,
  /(?<skin>general numbness all over)/                                                                                 => { severity: 7, internal: true, scar: true }.freeze,
  # useless
  /pulpy stump for a (?<part>head)/                                                                                    => { severity: 8, internal: false, scar: false }.freeze,
  /a stump for a (?<part>head)/                                                                                        => { severity: 8, internal: false, scar: true }.freeze,
  /an ugly stump for a #{WOUND_BODY_PART_REGEX}/                                                                       => { severity: 8, internal: false, scar: false }.freeze,
  /a grotesquely bloated (?<part>head) with bleeding from the eyes and ears/                                           => { severity: 8, internal: true, scar: false }.freeze,
  /(?<head>a blank stare)/                                                                                             => { severity: 8, internal: true, scar: true }.freeze,
  /a pulpy cavity for a #{WOUND_BODY_PART_REGEX}/                                                                      => { severity: 8, internal: false, scar: false }.freeze,
  /an empty #{WOUND_BODY_PART_REGEX} socket overgrown with bits of odd shaped flesh/                                   => { severity: 8, internal: false, scar: true }.freeze,
  /a severely swollen,* bruised and blind #{WOUND_BODY_PART_REGEX}/                                                    => { severity: 8, internal: true, scar: false }.freeze,
  /a blind #{WOUND_BODY_PART_REGEX}/                                                                                   => { severity: 8, internal: true, scar: true }.freeze,
  /a completely useless #{WOUND_BODY_PART_REGEX} with nearly all flesh and bone torn away/                             => { severity: 8, internal: false, scar: false }.freeze,
  /a completely destroyed #{WOUND_BODY_PART_REGEX} with nearly all flesh and bone torn away revealing a gaping hole/   => { severity: 8, internal: false, scar: false }.freeze,
  /an ugly flesh stump for a #{WOUND_BODY_PART_REGEX}/                                                                 => { severity: 8, internal: false, scar: true }.freeze,
  /an ugly flesh stump for a #{WOUND_BODY_PART_REGEX} with little left to support the head/                            => { severity: 8, internal: false, scar: true }.freeze,
  /a severely swollen and shattered #{WOUND_BODY_PART_REGEX} which appears completely useless/                         => { severity: 8, internal: true, scar: false }.freeze,
  /a severely swollen and shattered #{WOUND_BODY_PART_REGEX} which appears useless to hold up the head/                => { severity: 8, internal: true, scar: false }.freeze,
  /a completely paralyzed #{WOUND_BODY_PART_REGEX}/                                                                    => { severity: 8, internal: true, scar: true }.freeze,
  /a mostly non-existent #{WOUND_BODY_PART_REGEX} filled with ugly chunks of scarred flesh/                            => { severity: 8, internal: false, scar: true }.freeze,
  /a severely swollen (?<part>chest) area with a shattered rib cage/                                                   => { severity: 8, internal: true, scar: false }.freeze,
  /an extremely painful #{WOUND_BODY_PART_REGEX} while gasping for breath in short shallow bursts/                     => { severity: 8, internal: true, scar: true }.freeze,
  /a severely bloated and discolored #{WOUND_BODY_PART_REGEX} which appears oddly rearranged/                          => { severity: 8, internal: true, scar: false }.freeze,
  /(?<abdomen>a death pallor and extreme loss of weight)/                                                              => { severity: 8, internal: true, scar: true }.freeze,
  /a severely swollen #{WOUND_BODY_PART_REGEX} with a shattered spinal cord/                                           => { severity: 8, internal: true, scar: false }.freeze,
  /an extremely painful and bizarrely twisted #{WOUND_BODY_PART_REGEX} making it nearly impossible to move/            => { severity: 8, internal: true, scar: true }.freeze,
  /open and bleeding sores all over the (?<part>skin)/                                                                 => { severity: 8, internal: false, scar: false }.freeze,
  /severe (?<part>skin) loss exposing bone and internal organs/                                                        => { severity: 8, internal: false, scar: true }.freeze,
  /(?<skin>complete paralysis of the entire body)/                                                                     => { severity: 8, internal: true, scar: false }.freeze,
  /(?<skin>general numbness all over and have difficulty thinking)/                                                    => { severity: 8, internal: true, scar: true }.freeze,
}.freeze
WOUND_COMMA_SEPARATOR =
/(?<=swollen|bruised|scarred|painful),(?=\s(?:swollen|bruised|mangled|inflamed))/
TEND_SUCCESS_PATTERNS =

Tend action response patterns

[
  /You work carefully at tending/,
  /You work carefully at binding/,
  /That area has already been tended to/,
  /That area is not bleeding/
].freeze
TEND_FAILURE_PATTERNS =
[
  /You fumble/,
  /too injured for you to do that/,
  /TEND allows for the tending of wounds/,
  /^You must have a hand free/
].freeze
TEND_DISLODGE_PATTERNS =
[
  /^You \w+ remove (a|the|some) (.*) from/,
  /^As you reach for the clay fragment/
].freeze

Class Method Summary collapse

Class Method Details

.bind_wound(body_part, person = 'my') ⇒ Boolean

Binds a wound on the specified body part of a person.

Parameters:

  • body_part (String)

    the body part to bind

  • person (String) (defaults to: 'my')

    the person to bind the wound on (default is 'my')

Returns:

  • (Boolean)

    true if successful, false otherwise



383
384
385
386
387
388
389
390
391
392
393
394
395
396
# File 'documented/dragonrealms/commons/common-healing.rb', line 383

def bind_wound(body_part, person = 'my')
  result = DRC.bput("tend #{person} #{body_part}", *TEND_SUCCESS_PATTERNS, *TEND_FAILURE_PATTERNS, *TEND_DISLODGE_PATTERNS)
  waitrt?
  case result
  when *TEND_DISLODGE_PATTERNS
    dislodge_match = result.match(/^You \w+ remove (?:a|the|some) (?<item>.+) from/)
    DRCI.dispose_trash(dislodge_match[:item], get_settings.worn_trashcan, get_settings.worn_trashcan_verb) if dislodge_match
    bind_wound(body_part, person)
  when *TEND_FAILURE_PATTERNS
    false
  else
    true
  end
end

.calculate_score(wounds_by_severity) ⇒ Integer

Calculates a score based on the severity of wounds.

Parameters:

  • wounds_by_severity (Hash)

    a hash of wounds categorized by severity

Returns:

  • (Integer)

    the calculated score



428
429
430
# File 'documented/dragonrealms/commons/common-healing.rb', line 428

def calculate_score(wounds_by_severity)
  wounds_by_severity.map { |severity, wound_list| (severity**2) * wound_list.count }.reduce(:+) || 0
end

.check_healthHealthResult

Checks the health status and returns a HealthResult object.

Returns:



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'documented/dragonrealms/commons/common-healing.rb', line 25

def check_health
  health_lines = Lich::Util.issue_command(
    'health',
    /^Your body feels\b/,
    /<prompt/,
    usexml: true,
    quiet: true,
    include_end: false
  )
  if health_lines.nil?
    Lich::Messaging.msg("bold", "DRCH: Failed to capture HEALTH output (timeout).")
    return HealthResult.new
  end

  parse_health_lines(strip_xml(health_lines))
end

.has_tendable_bleeders?Boolean

Checks if there are any tendable bleeders.

Returns:

  • (Boolean)

    true if there are tendable bleeders, false otherwise



18
19
20
# File 'documented/dragonrealms/commons/common-healing.rb', line 18

def has_tendable_bleeders?
  check_health.has_tendable_bleeders?
end

.parse_bleeders(health_lines) ⇒ Hash

Parses the health lines to extract information about bleeders.

Parameters:

  • health_lines (Array<String>)

    the lines containing health information

Returns:

  • (Hash)

    a hash of bleeders categorized by severity



261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
# File 'documented/dragonrealms/commons/common-healing.rb', line 261

def parse_bleeders(health_lines)
  bleeders = Hash.new { |h, k| h[k] = [] }
  return bleeders unless health_lines.grep(/^Bleeding|^\s*\bArea\s+Rate\b/).any?

  health_lines
    .drop_while { |line| !(BLEEDER_LINE_REGEX =~ line) }
    .take_while { |line| BLEEDER_LINE_REGEX =~ line }
    .each do |line|
      match = line.match(WOUND_BODY_PART_REGEX)
      next unless match

      body_part = match.names.find { |name| match[name.to_sym] }
      body_part = match[:part] if body_part == 'part'
      body_part = body_part.gsub('l.', 'left').gsub('r.', 'right')

      rate_match = line.match(/(?:head|eye|neck|chest|abdomen|back|arm|hand|leg|tail|skin)\s+(?<rate>.+)/)
      next unless rate_match

      bleed_rate = rate_match[:rate].strip
      bleed_info = BLEED_RATE_TO_SEVERITY[bleed_rate]
      next unless bleed_info

      bleeders[bleed_info[:severity]] << Wound.new(
        body_part: body_part,
        severity: bleed_info[:severity],
        bleeding_rate: bleed_rate,
        is_internal: line.start_with?('inside')
      )
    end

  bleeders
end

.parse_health_lines(health_lines) ⇒ HealthResult

Parses the health lines to extract health information.

Parameters:

  • health_lines (Array<String>)

    the lines containing health information

Returns:



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
82
83
84
85
86
# File 'documented/dragonrealms/commons/common-healing.rb', line 46

def parse_health_lines(health_lines)
  parasites_regex = Regexp.union(PARASITES_REGEX)
  wounds_line = nil
  parasites_line = nil
  lodged_line = nil
  diseased = false
  poisoned = false

  health_lines.each do |line|
    case line
    when /^Your body feels\b/, /^Your spirit feels\b/, /^You are .*fatigued/, /^You feel fully rested/
      next
    when /^You have (?!no significant injuries)(?!.* lodged .* in(?:to)? your)(?!.* infection)(?!.* poison(?:ed)?)(?!.* #{parasites_regex})/
      wounds_line = line
    when /^You have .* lodged .* in(?:to)? your/
      lodged_line = line
    when /^You have a .* on your/, parasites_regex
      parasites_line = line
    when /^You have a dormant infection/, /^Your wounds are infected/, /^Your body is covered in open oozing sores/
      diseased = true
    when /^You have .* poison(?:ed)?/, /^You feel somewhat tired and seem to be having trouble breathing/
      poisoned = true
    end
  end

  bleeders = parse_bleeders(health_lines)
  wounds = parse_wounds(wounds_line)
  parasites = parse_parasites(parasites_line)
  lodged_items = parse_lodged_items(lodged_line)
  score = calculate_score(wounds)

  HealthResult.new(
    wounds: wounds,
    bleeders: bleeders,
    parasites: parasites,
    lodged: lodged_items,
    poisoned: poisoned,
    diseased: diseased,
    score: score
  )
end

.parse_lodged_items(lodged_line) ⇒ Hash

Parses a line containing lodged items information.

Parameters:

  • lodged_line (String)

    the line containing lodged items information

Returns:

  • (Hash)

    a hash of lodged items categorized by severity



351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
# File 'documented/dragonrealms/commons/common-healing.rb', line 351

def parse_lodged_items(lodged_line)
  lodged_items = Hash.new { |h, k| h[k] = [] }
  return lodged_items unless lodged_line

  lodged_line = lodged_line.gsub(/^You have\s+/, '').gsub(/\.$/, '')
  lodged_line.split(',').map(&:strip).each do |wound|
    match = wound.match(LODGED_BODY_PART_REGEX)
    next unless match

    body_part = match.names.find { |name| match[name.to_sym] }
    body_part = match[:part] if body_part == 'part'

    severity_match = wound.match(/\blodged\s+(?<depth>.+)\s+in(?:to)? your\b/)
    next unless severity_match

    severity = LODGED_SEVERITY[severity_match[:depth]]

    lodged_items[severity] << Wound.new(
      body_part: body_part,
      severity: severity,
      is_lodged_item: true
    )
  end

  lodged_items
end

.parse_parasites(parasites_line) ⇒ Hash

Parses a line containing parasites information.

Parameters:

  • parasites_line (String)

    the line containing parasites information

Returns:

  • (Hash)

    a hash of parasites categorized by severity



328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
# File 'documented/dragonrealms/commons/common-healing.rb', line 328

def parse_parasites(parasites_line)
  parasites = Hash.new { |h, k| h[k] = [] }
  return parasites unless parasites_line

  parasites_line = parasites_line.gsub(/^You have\s+/, '').gsub(/\.$/, '')
  parasites_line.split(',').map(&:strip).each do |parasite|
    match = parasite.match(PARASITE_BODY_PART_REGEX)
    next unless match

    parasites[1] << Wound.new(
      body_part: match[:part],
      severity: 1,
      is_parasite: true
    )
  end

  parasites
end

.parse_perceived_health_lines(lines) ⇒ HealthResult

Parses the lines perceived from another character's health.

Parameters:

  • lines (Array<String>)

    the lines containing perceived health information

Returns:



184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
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
246
247
248
249
250
251
252
253
254
255
# File 'documented/dragonrealms/commons/common-healing.rb', line 184

def parse_perceived_health_lines(lines)
  parasites_regex = Regexp.union(PARASITES_REGEX)
  poisons_regex = Regexp.union([
                                 /^[\w]+ (?:has|have) a .* poison/,
                                 /having trouble breathing/,
                                 /Cyanide poison/
                               ])
  diseases_regex = Regexp.union([
                                  /^[\w]+ wounds are (?:badly )?infected/,
                                  /^[\w]+ (?:has|have) a dormant infection/,
                                  /^[\w]+ (?:body|skin) is covered (?:in|with) open oozing sores/
                                ])
  dead_regex = /^(?:He|She) is dead/
  vitality_regex = /has (\d+)% vitality remaining/

  perceived_wounds = Hash.new { |h, k| h[k] = [] }
  perceived_parasites = Hash.new { |h, k| h[k] = [] }
  perceived_poison = false
  perceived_disease = false
  perceived_vitality = 100
  wound_body_part = nil
  dead = false

  lines.each do |line|
    case line
    when dead_regex
      dead = true
    when vitality_regex
      perceived_vitality = Regexp.last_match(1).to_i
    when diseases_regex
      perceived_disease = true
    when poisons_regex
      perceived_poison = true
    when parasites_regex
      match = line.match(/.* on (?:his|her|your) (?<body_part>[\w\s]*)/)
      body_part = match[:body_part] if match
      perceived_parasites[1] << Wound.new(body_part: body_part, severity: 1)
    when /^Wounds to the /
      match = line.match(/^Wounds to the (?<body_part>.+):/)
      wound_body_part = match[:body_part] if match
      perceived_wounds[wound_body_part] = []
    when /^(?:Fresh|Scars) (?:External|Internal)/
      match = line.match(PERCEIVE_HEALTH_SEVERITY_REGEX)
      next unless match
      next unless wound_body_part

      severity = WOUND_SEVERITY[match[:severity]]
      perceived_wounds[wound_body_part] << Wound.new(
        body_part: wound_body_part,
        severity: severity,
        is_internal: match[:location] == 'Internal',
        is_scar: match[:freshness] == 'Scars'
      )
    end
  end

  # Bucket wounds by severity.
  wounds = Hash.new { |h, k| h[k] = [] }
  perceived_wounds.values.flatten.each do |wound|
    wounds[wound.severity] << wound
  end

  HealthResult.new(
    wounds: wounds,
    parasites: perceived_parasites,
    poisoned: perceived_poison,
    diseased: perceived_disease,
    dead: dead,
    vitality: perceived_vitality,
    score: calculate_score(wounds)
  )
end

.parse_wounds(wounds_line) ⇒ Hash

Parses a line containing wounds information.

Parameters:

  • wounds_line (String)

    the line containing wounds information

Returns:

  • (Hash)

    a hash of wounds categorized by severity



298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
# File 'documented/dragonrealms/commons/common-healing.rb', line 298

def parse_wounds(wounds_line)
  wounds = Hash.new { |h, k| h[k] = [] }
  return wounds unless wounds_line

  wounds_line = wounds_line.gsub(WOUND_COMMA_SEPARATOR, '')
  wounds_line = wounds_line.gsub(/^You have\s+/, '').gsub(/\.$/, '')
  wounds_line.split(',').map(&:strip).each do |wound|
    WOUND_SEVERITY_REGEX_MAP.each do |regex, template|
      match = wound.match(regex)
      next unless match

      body_part = match.names.find { |name| match[name.to_sym] }
      body_part = match[:part] if body_part == 'part'

      wounds[template[:severity]] << Wound.new(
        body_part: body_part,
        severity: template[:severity],
        is_internal: template[:internal],
        is_scar: template[:scar]
      )
    end
  end

  wounds
end

.perceive_healthHealthResult?

Allows an empath to perceive their own health status.

Returns:

  • (HealthResult, nil)

    the perceived health result or nil if not an empath



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
130
131
132
133
134
# File 'documented/dragonrealms/commons/common-healing.rb', line 91

def perceive_health
  unless DRStats.empath?
    Lich::Messaging.msg("bold", "DRCH: Only empaths can perceive health.")
    return nil
  end

  lines = Lich::Util.issue_command(
    'perceive health self',
    /injuries include\.\.\.|feel only an aching emptiness/,
    /<prompt/,
    usexml: true,
    quiet: true,
    include_end: false,
    timeout: 15
  )
  if lines.nil?
    Lich::Messaging.msg("bold", "DRCH: Failed to capture PERCEIVE HEALTH output (timeout).")
    return nil
  end

  lines = strip_xml(lines)

  if lines.any? { |line| line =~ /feel only an aching emptiness/ }
    waitrt?
    return check_health
  end

  perceived = parse_perceived_health_lines(lines)
  health_data = check_health

  waitrt?

  HealthResult.new(
    wounds: perceived.wounds,
    bleeders: health_data.bleeders,
    parasites: health_data.parasites,
    lodged: health_data.lodged,
    poisoned: health_data.poisoned,
    diseased: health_data.diseased,
    vitality: perceived.vitality,
    dead: perceived.dead,
    score: perceived.score
  )
end

.perceive_health_other(target) ⇒ HealthResult?

Allows an empath to perceive the health status of another target.

Parameters:

  • target (String)

    the name of the target to perceive

Returns:

  • (HealthResult, nil)

    the perceived health result or nil if not an empath



140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'documented/dragonrealms/commons/common-healing.rb', line 140

def perceive_health_other(target)
  unless DRStats.empath?
    Lich::Messaging.msg("bold", "DRCH: Only empaths can perceive health of others.")
    return nil
  end

  touch_lines = Lich::Util.issue_command(
    "touch #{target}",
    /You sense a successful empathic link|Touch what|feels cold|avoids your touch|You quickly recoil/,
    /<prompt/,
    usexml: true,
    quiet: true,
    include_end: false,
    timeout: 10
  )
  if touch_lines.nil?
    Lich::Messaging.msg("bold", "DRCH: Failed to capture TOUCH output for #{target} (timeout).")
    return nil
  end

  touch_lines = strip_xml(touch_lines)

  if touch_lines.any? { |line| line =~ /Touch what|feels cold|avoids your touch|You quickly recoil/ }
    Lich::Messaging.msg("bold", "DRCH: Unable to perceive health of #{target}.")
    return nil
  end

  # Extract actual character name from the empathic link message.
  # The target passed to the method may be abbreviated or differently cased.
  touch_lines.each do |line|
    match = line.match(/between you and (?<name>\w+)\./)
    if match
      target = match[:name]
      break
    end
  end

  parse_perceived_health_lines(touch_lines)
end

.skilled_to_tend_wound?(bleed_rate, internal = false) ⇒ Boolean

Checks if the character has the skill to tend to a wound based on its bleed rate.

Parameters:

  • bleed_rate (String)

    the rate of bleeding

  • internal (Boolean) (defaults to: false)

    whether the wound is internal (default is false)

Returns:

  • (Boolean)

    true if skilled enough, false otherwise



413
414
415
416
417
418
419
420
421
422
# File 'documented/dragonrealms/commons/common-healing.rb', line 413

def skilled_to_tend_wound?(bleed_rate, internal = false)
  bleed_info = BLEED_RATE_TO_SEVERITY[bleed_rate]
  return false unless bleed_info

  skill_target = internal ? :skill_to_tend_internal : :skill_to_tend
  min_skill = bleed_info[skill_target]
  return false if min_skill.nil?

  DRSkill.getrank('First Aid') >= min_skill
end

.strip_xml(lines) ⇒ Array<String>

Strips XML tags from the given lines.

Parameters:

  • lines (Array<String>)

    the lines containing XML to be stripped

Returns:

  • (Array<String>)

    the lines without XML tags



11
12
13
# File 'documented/dragonrealms/commons/common-healing.rb', line 11

def strip_xml(lines)
  DRC.strip_xml(lines)
end

.unwrap_wound(body_part, person = 'my') ⇒ void

This method returns an undefined value.

Unwraps a wound on the specified body part of a person.

Parameters:

  • body_part (String)

    the body part to unwrap

  • person (String) (defaults to: 'my')

    the person to unwrap the wound on (default is 'my')



403
404
405
406
# File 'documented/dragonrealms/commons/common-healing.rb', line 403

def unwrap_wound(body_part, person = 'my')
  DRC.bput("unwrap #{person} #{body_part}", 'You unwrap .* bandages', 'That area is not tended', 'You may undo the affects of TENDing')
  waitrt?
end