Class: Lich::Gemstone::CreatureInstance

Inherits:
Object
  • Object
show all
Defined in:
documented/gemstone/creature.rb

Overview

Represents an instance of a creature in the game.

This class manages the state and behavior of individual creatures.

Constant Summary collapse

BODY_PARTS =
%w[abdomen back chest head leftArm leftEye leftFoot leftHand leftLeg neck nerves rightArm rightEye rightFoot rightHand rightLeg]
UCS_TTL =

UCS data expires after 2 minutes

120
UCS_SMITE_TTL =

Smite effect expires after 15 seconds

15
STATUS_DURATIONS =

Status effect durations (in seconds) for auto-cleanup nil = no auto-cleanup (waits for removal message)

{
  'breeze'      => 6, # 6 seconds roundtime
  'bind'        => 10, # 10 seconds typical
  'web'         => 8, # 8 seconds typical
  'entangle'    => 10, # 10 seconds typical
  'hypnotism'   => 12, # 12 seconds typical
  'calm'        => 15, # 15 seconds typical
  'mass_calm'   => 15, # 15 seconds typical
  'sleep'       => 8, # 8 seconds typical (can wake early)
  # Statuses with reliable removal messages - no duration needed
  'stunned'     => nil, # Has removal messages
  'immobilized' => nil, # Has removal messages
  'prone'       => nil,         # Has removal messages
  'blind'       => nil,         # Has removal messages
  'sunburst'    => nil, # Has removal messages
  'webbed'      => nil, # Has removal messages
  'poisoned'    => nil # Has removal messages
}.freeze
@@instances =
{}
@@max_size =
1000
@@auto_register =
true

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(id, noun, name) ⇒ CreatureInstance

Returns a new instance of CreatureInstance.



223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
# File 'documented/gemstone/creature.rb', line 223

def initialize(id, noun, name)
  @id = id.to_i
  @noun = noun
  @name = name
  @status = []
  @injuries = Hash.new(0)
  @health = nil
  @damage_taken = 0
  @created_at = Time.now
  @fatal_crit = false
  @status_timestamps = {}
  @ucs_position = nil
  @ucs_tierup = nil
  @ucs_smote = nil
  @ucs_updated = nil
end

Instance Attribute Details

#created_atObject

Returns the value of attribute created_at.



193
194
195
# File 'documented/gemstone/creature.rb', line 193

def created_at
  @created_at
end

#damage_takenObject

Returns the value of attribute damage_taken.



193
194
195
# File 'documented/gemstone/creature.rb', line 193

def damage_taken
  @damage_taken
end

#fatal_critObject

Returns the value of attribute fatal_crit.



193
194
195
# File 'documented/gemstone/creature.rb', line 193

def fatal_crit
  @fatal_crit
end

#healthObject

Returns the value of attribute health.



193
194
195
# File 'documented/gemstone/creature.rb', line 193

def health
  @health
end

#idObject

Returns the value of attribute id.



193
194
195
# File 'documented/gemstone/creature.rb', line 193

def id
  @id
end

#injuriesObject

Returns the value of attribute injuries.



193
194
195
# File 'documented/gemstone/creature.rb', line 193

def injuries
  @injuries
end

#nameObject

Returns the value of attribute name.



193
194
195
# File 'documented/gemstone/creature.rb', line 193

def name
  @name
end

#nounObject

Returns the value of attribute noun.



193
194
195
# File 'documented/gemstone/creature.rb', line 193

def noun
  @noun
end

#statusObject

Returns the value of attribute status.



193
194
195
# File 'documented/gemstone/creature.rb', line 193

def status
  @status
end

#status_timestampsObject

Returns the value of attribute status_timestamps.



193
194
195
# File 'documented/gemstone/creature.rb', line 193

def status_timestamps
  @status_timestamps
end

#ucs_positionObject



377
378
379
380
# File 'documented/gemstone/creature.rb', line 377

def ucs_position
  return nil if ucs_expired?
  @ucs_position
end

#ucs_smoteObject

Returns the value of attribute ucs_smote.



193
194
195
# File 'documented/gemstone/creature.rb', line 193

def ucs_smote
  @ucs_smote
end

#ucs_tierupObject



382
383
384
385
# File 'documented/gemstone/creature.rb', line 382

def ucs_tierup
  return nil if ucs_expired?
  @ucs_tierup
end

#ucs_updatedObject

Returns the value of attribute ucs_updated.



193
194
195
# File 'documented/gemstone/creature.rb', line 193

def ucs_updated
  @ucs_updated
end

Class Method Details

.[](id) ⇒ Object



537
538
539
# File 'documented/gemstone/creature.rb', line 537

def [](id)
  @@instances[id.to_i]
end

.allObject



541
542
543
# File 'documented/gemstone/creature.rb', line 541

def all
  @@instances.values
end

.auto_register?Boolean

Returns:

  • (Boolean)


499
500
501
# File 'documented/gemstone/creature.rb', line 499

def auto_register?
  @@auto_register
end

.cleanup_old(max_age_seconds = 600) ⇒ Integer

Cleans up old creature instances based on their age.

Parameters:

  • max_age_seconds (Integer) (defaults to: 600)

    the maximum age in seconds for instances to keep

Returns:

  • (Integer)

    the number of instances removed



552
553
554
555
556
557
# File 'documented/gemstone/creature.rb', line 552

def cleanup_old(max_age_seconds = 600)
  cutoff = Time.now - max_age_seconds
  removed = @@instances.select { |_id, instance| instance.created_at < cutoff }.size
  @@instances.reject! { |_id, instance| instance.created_at < cutoff }
  removed
end

.clearObject



545
546
547
# File 'documented/gemstone/creature.rb', line 545

def clear
  @@instances.clear
end

.configure(max_size: 1000, auto_register: true) ⇒ Object



494
495
496
497
# File 'documented/gemstone/creature.rb', line 494

def configure(max_size: 1000, auto_register: true)
  @@max_size = max_size
  @@auto_register = auto_register
end

.full?Boolean

Returns:

  • (Boolean)


507
508
509
# File 'documented/gemstone/creature.rb', line 507

def full?
  size >= @@max_size
end

.register(name, id, noun = nil) ⇒ CreatureInstance?

Registers a new creature instance.

Parameters:

  • name (String)

    the name of the creature

  • id (Integer)

    the unique identifier for the creature

  • noun (String, nil) (defaults to: nil)

    optional noun representing the creature

Returns:

  • (CreatureInstance, nil)

    the registered creature instance or nil if registration failed



516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
# File 'documented/gemstone/creature.rb', line 516

def register(name, id, noun = nil)
  return nil unless auto_register?
  return @@instances[id.to_i] if @@instances[id.to_i] # Already exists

  # Auto-cleanup old instances if registry is full - get progressively more aggressive
  if full?
    # Try 120 minutes, then 15 minute intervals.
    [7200, 6300, 5400, 4500, 3600, 2700, 1800, 900].each do |age_threshold|
      removed = cleanup_old(age_threshold)
      respond "--- Auto-cleanup: removed #{removed} old creatures (threshold: #{age_threshold}s)" if removed > 0 && $creature_debug
      break unless full?
    end
    return nil if full? # Still full after all cleanup attempts
  end

  instance = new(id, noun, name)
  @@instances[id.to_i] = instance
  respond "--- Creature registered: #{name} (#{id})" if $creature_debug
  instance
end

.sizeObject



503
504
505
# File 'documented/gemstone/creature.rb', line 503

def size
  @@instances.size
end

Instance Method Details

#add_damage(amount) ⇒ void

This method returns an undefined value.

Adds damage to the creature instance.

Parameters:

  • amount (Integer)

    the amount of damage to add



418
419
420
# File 'documented/gemstone/creature.rb', line 418

def add_damage(amount)
  @damage_taken += amount.to_i
end

#add_injury(body_part, amount = 1) ⇒ void

This method returns an undefined value.

Adds an injury to a specific body part of the creature instance.

Parameters:

  • body_part (String)

    the body part to injure

  • amount (Integer) (defaults to: 1)

    the amount of injury to add

Raises:

  • (ArgumentError)

    if the body part is invalid



392
393
394
395
396
397
# File 'documented/gemstone/creature.rb', line 392

def add_injury(body_part, amount = 1)
  unless BODY_PARTS.include?(body_part.to_s)
    raise ArgumentError, "Invalid body part: #{body_part}"
  end
  @injuries[body_part.to_sym] += amount
end

#add_status(status, duration = nil) ⇒ void

This method returns an undefined value.

Adds a status effect to the creature instance.

Parameters:

  • status (String)

    the status to add

  • duration (Integer, nil) (defaults to: nil)

    optional duration for the status effect



254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
# File 'documented/gemstone/creature.rb', line 254

def add_status(status, duration = nil)
  return if @status.include?(status)

  @status << status

  # Set expiration timestamp for timed statuses
  status_key = status.to_s.downcase
  duration ||= STATUS_DURATIONS[status_key]
  if duration
    @status_timestamps[status] = Time.now + duration
    respond "  +status: #{status} (expires in #{duration}s)" if $creature_debug
  else
    respond "  +status: #{status} (no auto-expiry)" if $creature_debug
  end
end

#cleanup_expired_statusesvoid

This method returns an undefined value.

Cleans up any expired status effects from the creature instance.



281
282
283
284
285
286
287
288
289
290
# File 'documented/gemstone/creature.rb', line 281

def cleanup_expired_statuses
  return unless @status_timestamps && !@status_timestamps.empty?

  now = Time.now
  @status_timestamps.select { |_status, expires_at| expires_at <= now }.keys.each do |expired_status|
    @status.delete(expired_status)
    @status_timestamps.delete(expired_status)
    respond "  ~status: #{expired_status} (auto-expired)" if $creature_debug
  end
end

#clear_smoteObject



364
365
366
367
368
# File 'documented/gemstone/creature.rb', line 364

def clear_smote
  @ucs_smote = nil
  @ucs_updated = Time.now
  respond "  UCS: smote cleared" if $creature_debug
end

#current_hpInteger?

Calculates the current hit points of the creature instance.

Returns:

  • (Integer, nil)

    the current hit points or nil if max_hp is not set



444
445
446
447
# File 'documented/gemstone/creature.rb', line 444

def current_hp
  return nil unless max_hp
  [max_hp - @damage_taken, 0].max
end

#dead?Boolean

Returns:

  • (Boolean)


462
463
464
# File 'documented/gemstone/creature.rb', line 462

def dead?
  current_hp == 0
end

#essential_dataHash

Retrieves essential data about the creature instance.

Returns:

  • (Hash)

    a hash containing essential attributes of the creature instance



472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
# File 'documented/gemstone/creature.rb', line 472

def essential_data
  {
    id: @id,
    noun: @noun,
    name: @name,
    status: @status,
    injuries: @injuries,
    health: @health,
    damage_taken: @damage_taken,
    max_hp: max_hp,
    current_hp: current_hp,
    hp_percent: hp_percent,
    has_template: has_template?,
    created_at: @created_at,
    ucs_position: ucs_position,
    ucs_tierup: ucs_tierup,
    ucs_smote: smote?
  }
end

#fatal_crit?Boolean

Returns:

  • (Boolean)


407
408
409
# File 'documented/gemstone/creature.rb', line 407

def fatal_crit?
  @fatal_crit
end

#has_status?(status) ⇒ Boolean

Checks if the creature instance has a specific status effect.

Parameters:

  • status (String)

    the status to check

Returns:

  • (Boolean)

    true if the status is present, false otherwise



295
296
297
298
# File 'documented/gemstone/creature.rb', line 295

def has_status?(status)
  cleanup_expired_statuses # Clean up expired statuses first
  @status.include?(status.to_s)
end

#has_template?Boolean

Returns:

  • (Boolean)


246
247
248
# File 'documented/gemstone/creature.rb', line 246

def has_template?
  !template.nil?
end

#hp_percentObject



449
450
451
452
# File 'documented/gemstone/creature.rb', line 449

def hp_percent
  return nil unless max_hp && max_hp > 0
  ((current_hp.to_f / max_hp) * 100).round(1)
end

#injured?(location, threshold = 1) ⇒ Boolean

Returns:

  • (Boolean)


399
400
401
# File 'documented/gemstone/creature.rb', line 399

def injured?(location, threshold = 1)
  @injuries[location.to_sym] >= threshold
end

#injured_locations(threshold = 1) ⇒ Object



411
412
413
# File 'documented/gemstone/creature.rb', line 411

def injured_locations(threshold = 1)
  @injuries.select { |_, value| value >= threshold }.keys
end

#low_hp?(threshold = 25) ⇒ Boolean

Checks if the creature instance is below a certain HP threshold.

Parameters:

  • threshold (Integer) (defaults to: 25)

    the HP percentage threshold to check against

Returns:

  • (Boolean)

    true if below the threshold, false otherwise



457
458
459
460
# File 'documented/gemstone/creature.rb', line 457

def low_hp?(threshold = 25)
  return false unless hp_percent
  hp_percent <= threshold
end

#mark_fatal_crit!Object



403
404
405
# File 'documented/gemstone/creature.rb', line 403

def mark_fatal_crit!
  @fatal_crit = true
end

#max_hpObject



422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
# File 'documented/gemstone/creature.rb', line 422

def max_hp
  # Try template first
  hp = template&.max_hp
  return hp if hp && hp > 0

  # Fall back to combat tracker setting if available
  begin
    if defined?(Lich::Gemstone::Combat::Tracker) &&
       Lich::Gemstone::Combat::Tracker.respond_to?(:fallback_hp)
      fallback = Lich::Gemstone::Combat::Tracker.fallback_hp
      return fallback if fallback && fallback > 0
    end
  rescue
    # Ignore errors accessing tracker
  end

  # Last resort: hardcoded fallback
  400
end

#position_to_tier(pos) ⇒ Integer?

Converts a position string to a tier number.

Parameters:

  • pos (String, Integer)

    the position to convert

Returns:

  • (Integer, nil)

    the corresponding tier number or nil if invalid



309
310
311
312
313
314
315
316
# File 'documented/gemstone/creature.rb', line 309

def position_to_tier(pos)
  case pos
  when "decent", 1, "1" then 1
  when "good", 2, "2" then 2
  when "excellent", 3, "3" then 3
  else nil
  end
end

#remove_status(status) ⇒ void

This method returns an undefined value.

Removes a status effect from the creature instance.

Parameters:

  • status (String)

    the status to remove



273
274
275
276
277
# File 'documented/gemstone/creature.rb', line 273

def remove_status(status)
  @status.delete(status)
  @status_timestamps.delete(status)
  respond "  -status: #{status}" if $creature_debug
end

#reset_damageObject



466
467
468
# File 'documented/gemstone/creature.rb', line 466

def reset_damage
  @damage_taken = 0
end

#set_ucs_position(position) ⇒ void

This method returns an undefined value.

Sets the UCS position for the creature instance.

Parameters:

  • position (String, Integer)

    the new position to set



321
322
323
324
325
326
327
328
329
330
331
# File 'documented/gemstone/creature.rb', line 321

def set_ucs_position(position)
  new_tier = position_to_tier(position)
  return unless new_tier

  # Clear tierup if tier changed
  @ucs_tierup = nil if new_tier != @ucs_position

  @ucs_position = new_tier
  @ucs_updated = Time.now
  respond "  UCS: position=#{new_tier}" if $creature_debug
end

#set_ucs_tierup(attack_type) ⇒ void

This method returns an undefined value.

Sets the UCS tier-up type for the creature instance.

Parameters:

  • attack_type (String)

    the type of attack that caused the tier-up



336
337
338
339
340
# File 'documented/gemstone/creature.rb', line 336

def set_ucs_tierup(attack_type)
  @ucs_tierup = attack_type
  @ucs_updated = Time.now
  respond "  UCS: tierup=#{attack_type}" if $creature_debug
end

#smite!void

This method returns an undefined value.

Marks the creature instance as smote.



344
345
346
347
348
# File 'documented/gemstone/creature.rb', line 344

def smite!
  @ucs_smote = Time.now
  @ucs_updated = Time.now
  respond "  UCS: smote!" if $creature_debug
end

#smote?Boolean

Checks if the creature instance is currently smote.

Returns:

  • (Boolean)

    true if smote, false otherwise



352
353
354
355
356
357
358
359
360
361
362
# File 'documented/gemstone/creature.rb', line 352

def smote?
  return false unless @ucs_smote

  # Check if smite effect has expired
  if Time.now - @ucs_smote > UCS_SMITE_TTL
    @ucs_smote = nil
    return false
  end

  true
end

#statusesObject



300
301
302
303
# File 'documented/gemstone/creature.rb', line 300

def statuses
  cleanup_expired_statuses # Clean up expired statuses first
  @status.dup
end

#templateCreatureTemplate?

Retrieves the template associated with this creature instance.

Returns:



242
243
244
# File 'documented/gemstone/creature.rb', line 242

def template
  @template ||= CreatureTemplate[@name]
end

#ucs_expired?Boolean

Checks if the UCS data for the creature instance has expired.

Returns:

  • (Boolean)

    true if expired, false otherwise



372
373
374
375
# File 'documented/gemstone/creature.rb', line 372

def ucs_expired?
  return true unless @ucs_updated
  (Time.now - @ucs_updated) > UCS_TTL
end