Class: Lich::Gemstone::Injured

Inherits:
CharacterStatus show all
Defined in:
documented/gemstone/injured.rb

Overview

Represents the character’s injury status in the Gemstone module.

Examples:

Creating an instance of Injured

injured_status = Lich::Gemstone::Injured

Constant Summary collapse

BODY_PART_GROUPS =

A constant that groups body parts for injury checks. Each key represents a group of body parts.

{
  eyes: %i[leftEye rightEye],
  arms: %i[leftArm rightArm],
  hands: %i[leftHand rightHand],
  legs: %i[leftLeg rightLeg],
  feet: %i[leftFoot rightFoot],
  head_and_nerves: %i[head nsys]
}.freeze

Class Method Summary collapse

Methods inherited from CharacterStatus

fix_injury_mode, method_missing

Class Method Details

.able_to_cast?Boolean

Checks if the character is able to cast spells based on their injury status.

Examples:

can_cast = able_to_cast?

Returns:

  • (Boolean)

    True if the character can cast spells.



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'documented/gemstone/injured.rb', line 114

def able_to_cast?
  fix_injury_mode("both")

  # Fetch cached or fresh injury data
  wounds, scars = get_injury_data

  # Rank 3 critical injuries prevent casting (Sigil cannot bypass)
  return false if injuries_at_rank?(3, wounds, scars, :head, :nsys, *BODY_PART_GROUPS[:eyes])

  # Check for rank 3 in arms/hands (worst of arm vs hand per side)
  left_arm = effective_injury_from_hashes(:leftArm, wounds, scars)
  left_hand = effective_injury_from_hashes(:leftHand, wounds, scars)
  right_arm = effective_injury_from_hashes(:rightArm, wounds, scars)
  right_hand = effective_injury_from_hashes(:rightHand, wounds, scars)

  left_side = [left_arm, left_hand].max
  right_side = [right_arm, right_hand].max

  return false if left_side == 3 || right_side == 3

  # Sigil of Determination bypasses rank 2 or lower injuries
  return true if bypasses_injuries?

  # Head or nerve injuries > rank 1 prevent casting
  return false if injuries_at_or_above_rank?(2, wounds, scars, *BODY_PART_GROUPS[:head_and_nerves])

  # Cumulative injuries >= 3 prevent casting
  eyes_total = BODY_PART_GROUPS[:eyes].sum { |part| effective_injury_from_hashes(part, wounds, scars) }
  return false if eyes_total >= 3

  arms_total = left_side + right_side
  return false if arms_total >= 3

  true
end

.able_to_search?Boolean

Checks if the character is able to search based on their injury status.

Examples:

can_search = able_to_search?

Returns:

  • (Boolean)

    True if the character can search.



176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'documented/gemstone/injured.rb', line 176

def able_to_search?
  fix_injury_mode("both")

  wounds, scars = get_injury_data

  # Rank 3 critical injuries prevent searching (Sigil cannot bypass)
  return false if injuries_at_rank?(3, wounds, scars, :head, :nsys, *BODY_PART_GROUPS[:eyes])

  # Sigil of Determination bypasses rank 2 or lower injuries
  return true if bypasses_injuries?

  # Rank 2+ head or nerve injury prevents searching
  return false if injuries_at_or_above_rank?(2, wounds, scars, *BODY_PART_GROUPS[:head_and_nerves])

  true
end

.able_to_sneak?Boolean

Checks if the character is able to sneak based on their injury status.

Examples:

can_sneak = able_to_sneak?

Returns:

  • (Boolean)

    True if the character can sneak.



154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'documented/gemstone/injured.rb', line 154

def able_to_sneak?
  fix_injury_mode("both")

  wounds, scars = get_injury_data

  # Rank 3 leg/foot injuries always prevent sneaking, but these are NOT critical
  # (Sigil cannot bypass, but they're not in the critical list for other actions)
  return false if injuries_at_rank?(3, wounds, scars, *BODY_PART_GROUPS[:legs], *BODY_PART_GROUPS[:feet])

  # Sigil of Determination bypasses rank 2 or lower injuries
  return true if bypasses_injuries?

  # Any leg or foot injury > rank 1 prevents sneaking
  return false if injuries_at_or_above_rank?(2, wounds, scars, *BODY_PART_GROUPS[:legs], *BODY_PART_GROUPS[:feet])

  true
end

.able_to_use_ranged?Boolean

Checks if the character is able to use ranged weapons based on their injury status.

Examples:

can_use_ranged = able_to_use_ranged?

Returns:

  • (Boolean)

    True if the character can use ranged weapons.



197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
# File 'documented/gemstone/injured.rb', line 197

def able_to_use_ranged?
  fix_injury_mode("both")

  wounds, scars = get_injury_data

  # Rank 3 critical injuries prevent ranged weapon use (Sigil cannot bypass)
  return false if injuries_at_rank?(3, wounds, scars, :head, :nsys, *BODY_PART_GROUPS[:eyes], *BODY_PART_GROUPS[:arms], *BODY_PART_GROUPS[:hands])

  # Sigil of Determination bypasses rank 2 or lower injuries
  return true if bypasses_injuries?

  # Any single arm or hand injury >= rank 2 prevents ranged weapon use
  return false if injuries_at_or_above_rank?(2, wounds, scars, *BODY_PART_GROUPS[:arms], *BODY_PART_GROUPS[:hands], :nsys)

  true
end

.bypasses_injuries?Boolean

Determines if the character can bypass injuries based on active effects.

Examples:

can_bypass = bypasses_injuries?

Returns:

  • (Boolean)

    True if the character can bypass injuries.



106
107
108
# File 'documented/gemstone/injured.rb', line 106

def bypasses_injuries?
  Effects::Buffs.active?("Sigil of Determination")
end

.effective_injury_from_hashes(body_part, wounds_hash, scars_hash) ⇒ Integer

Calculates the effective injury from wounds and scars for a given body part.

Examples:

effective_injury = effective_injury_from_hashes(:leftArm, wounds_hash, scars_hash)

Parameters:

  • body_part (Symbol)

    The body part to check (e.g., :leftArm).

  • wounds_hash (Hash)

    A hash containing wounds data.

  • scars_hash (Hash)

    A hash containing scars data.

Returns:

  • (Integer)

    The effective injury value.



66
67
68
69
70
71
72
# File 'documented/gemstone/injured.rb', line 66

def effective_injury_from_hashes(body_part, wounds_hash, scars_hash)
  scar = scars_hash[body_part.to_s] || 0
  wound = wounds_hash[body_part.to_s] || 0
  effective_scar = (scar == 1) ? 0 : scar

  [wound, effective_scar].max
end

.get_injury_dataArray

Note:

This method uses a mutex for thread safety.

Retrieves injury data, utilizing caching for efficiency.

Examples:

wounds, scars = get_injury_data

Returns:

  • (Array)

    An array containing wounds and scars data.



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'documented/gemstone/injured.rb', line 31

def get_injury_data
  current_key = XMLData.injuries

  # Fast path: return cached data if key hasn't changed
  if @injury_cache_key == current_key && @wounds_cache && @scars_cache
    return [@wounds_cache, @scars_cache]
  end

  # Slow path: fetch new data with mutex protection
  @cache_mutex.synchronize do
    # Double-check after acquiring lock (another thread may have updated)
    if @injury_cache_key == current_key && @wounds_cache && @scars_cache
      return [@wounds_cache, @scars_cache]
    end

    # Fetch fresh data
    wounds = Wounds.all_wounds
    scars = Scars.all_scars

    # Update cache
    @wounds_cache = wounds
    @scars_cache = scars
    @injury_cache_key = current_key

    [wounds, scars]
  end
end

.injuries_at_or_above_rank?(rank, wounds_hash, scars_hash, *parts) ⇒ Boolean

Checks if there are injuries at or above a specific rank for given body parts.

Examples:

has_injuries = injuries_at_or_above_rank?(2, wounds_hash, scars_hash, :leftArm, :rightArm)

Parameters:

  • rank (Integer)

    The rank of injury to check.

  • wounds_hash (Hash)

    A hash containing wounds data.

  • scars_hash (Hash)

    A hash containing scars data.

  • parts (Array<Symbol>)

    The body parts to check.

Returns:

  • (Boolean)

    True if any part has an injury at or above the specified rank.



96
97
98
99
100
# File 'documented/gemstone/injured.rb', line 96

def injuries_at_or_above_rank?(rank, wounds_hash, scars_hash, *parts)
  parts.flatten.any? do |part|
    effective_injury_from_hashes(part, wounds_hash, scars_hash) >= rank
  end
end

.injuries_at_rank?(rank, wounds_hash, scars_hash, *parts) ⇒ Boolean

Checks if there are injuries at a specific rank for given body parts.

Examples:

has_injuries = injuries_at_rank?(2, wounds_hash, scars_hash, :leftArm, :rightArm)

Parameters:

  • rank (Integer)

    The rank of injury to check.

  • wounds_hash (Hash)

    A hash containing wounds data.

  • scars_hash (Hash)

    A hash containing scars data.

  • parts (Array<Symbol>)

    The body parts to check.

Returns:

  • (Boolean)

    True if any part has an injury at the specified rank.



82
83
84
85
86
# File 'documented/gemstone/injured.rb', line 82

def injuries_at_rank?(rank, wounds_hash, scars_hash, *parts)
  parts.flatten.any? do |part|
    effective_injury_from_hashes(part, wounds_hash, scars_hash) == rank
  end
end