Class: Lich::Gemstone::CreatureInstance
- Inherits:
-
Object
- Object
- Lich::Gemstone::CreatureInstance
- Defined in:
- documented/gemstone/creature.rb
Overview
Individual creature instance (runtime tracking with ID)
Represents a specific creature in the game world, tracked by unique ID. Manages runtime state including damage, injuries, status effects, and UCS data.
Instances are automatically registered and cleaned up based on age. Max registry size prevents memory exhaustion during extended play.
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
-
#created_at ⇒ Object
Returns the value of attribute created_at.
-
#damage_taken ⇒ Object
Returns the value of attribute damage_taken.
-
#fatal_crit ⇒ Object
Returns the value of attribute fatal_crit.
-
#health ⇒ Object
Returns the value of attribute health.
-
#id ⇒ Object
Returns the value of attribute id.
-
#injuries ⇒ Object
Returns the value of attribute injuries.
-
#name ⇒ Object
Returns the value of attribute name.
-
#noun ⇒ Object
Returns the value of attribute noun.
-
#status ⇒ Object
Returns the value of attribute status.
-
#status_timestamps ⇒ Object
Returns the value of attribute status_timestamps.
-
#ucs_position ⇒ Object
Get UCS position tier (1-3, or nil if expired).
-
#ucs_smote ⇒ Object
Returns the value of attribute ucs_smote.
-
#ucs_tierup ⇒ Object
Get UCS tierup vulnerability (or nil if expired).
-
#ucs_updated ⇒ Object
Returns the value of attribute ucs_updated.
Class Method Summary collapse
-
.[](id) ⇒ Object
Lookup creature by ID.
-
.all ⇒ Object
Get all registered instances.
-
.auto_register? ⇒ Boolean
Check if auto-registration is enabled.
-
.cleanup_old(max_age_seconds = 600) ⇒ Object
Remove old instances (cleanup).
-
.clear ⇒ Object
Clear all instances (session reset).
-
.configure(max_size: 1000, auto_register: true) ⇒ Object
Configure registry.
-
.full? ⇒ Boolean
Check if registry is full.
-
.register(name, id, noun = nil) ⇒ CreatureInstance?
Register a new creature instance in the global registry.
-
.size ⇒ Object
Get current registry size.
Instance Method Summary collapse
-
#add_damage(amount) ⇒ void
Add damage to creature’s health pool.
-
#add_injury(body_part, amount = 1) ⇒ Object
Add injury/wound to a body part.
-
#add_status(status, duration = nil) ⇒ void
Add a status effect to the creature.
-
#cleanup_expired_statuses ⇒ void
Clean up expired status effects.
-
#clear_smote ⇒ Object
Clear smote status.
-
#current_hp ⇒ Integer?
Calculate current hit points.
-
#dead? ⇒ Boolean
Check if creature is dead (0 HP).
-
#essential_data ⇒ Object
Essential data for this instance.
-
#fatal_crit? ⇒ Boolean
Check if creature died from fatal crit.
-
#has_status?(status) ⇒ Boolean
Check if creature has a specific status.
-
#has_template? ⇒ Boolean
Check if creature has template data.
-
#hp_percent ⇒ Object
Calculate HP percentage (0-100).
-
#initialize(id, noun, name) ⇒ CreatureInstance
constructor
Initialize a new creature instance.
-
#injured?(location, threshold = 1) ⇒ Boolean
Check if injured at location.
-
#injured_locations(threshold = 1) ⇒ Object
Get all injured locations.
-
#low_hp?(threshold = 25) ⇒ Boolean
Check if creature is below HP threshold.
-
#mark_fatal_crit! ⇒ Object
Mark creature as killed by fatal critical hit.
-
#max_hp ⇒ Object
Get maximum HP from template, with fallback.
-
#position_to_tier(pos) ⇒ Integer?
Convert UCS position string/number to tier (1-3).
-
#remove_status(status) ⇒ Object
Remove status from creature.
-
#reset_damage ⇒ Object
Reset damage (creature healed or respawned).
-
#set_ucs_position(position) ⇒ Object
Set UCS position tier.
-
#set_ucs_tierup(attack_type) ⇒ Object
Set UCS tierup vulnerability.
-
#smite! ⇒ Object
Mark creature as smote (crimson mist applied).
-
#smote? ⇒ Boolean
Check if creature is currently smote.
-
#statuses ⇒ Object
Get all current statuses.
-
#template ⇒ CreatureTemplate?
Get the static template for this creature.
-
#ucs_expired? ⇒ Boolean
Check if UCS data has expired.
Constructor Details
#initialize(id, noun, name) ⇒ CreatureInstance
Initialize a new creature instance
260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 |
# File 'documented/gemstone/creature.rb', line 260 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_at ⇒ Object
Returns the value of attribute created_at.
226 227 228 |
# File 'documented/gemstone/creature.rb', line 226 def created_at @created_at end |
#damage_taken ⇒ Object
Returns the value of attribute damage_taken.
226 227 228 |
# File 'documented/gemstone/creature.rb', line 226 def damage_taken @damage_taken end |
#fatal_crit ⇒ Object
Returns the value of attribute fatal_crit.
226 227 228 |
# File 'documented/gemstone/creature.rb', line 226 def fatal_crit @fatal_crit end |
#health ⇒ Object
Returns the value of attribute health.
226 227 228 |
# File 'documented/gemstone/creature.rb', line 226 def health @health end |
#id ⇒ Object
Returns the value of attribute id.
226 227 228 |
# File 'documented/gemstone/creature.rb', line 226 def id @id end |
#injuries ⇒ Object
Returns the value of attribute injuries.
226 227 228 |
# File 'documented/gemstone/creature.rb', line 226 def injuries @injuries end |
#name ⇒ Object
Returns the value of attribute name.
226 227 228 |
# File 'documented/gemstone/creature.rb', line 226 def name @name end |
#noun ⇒ Object
Returns the value of attribute noun.
226 227 228 |
# File 'documented/gemstone/creature.rb', line 226 def noun @noun end |
#status ⇒ Object
Returns the value of attribute status.
226 227 228 |
# File 'documented/gemstone/creature.rb', line 226 def status @status end |
#status_timestamps ⇒ Object
Returns the value of attribute status_timestamps.
226 227 228 |
# File 'documented/gemstone/creature.rb', line 226 def @status_timestamps end |
#ucs_position ⇒ Object
Get UCS position tier (1-3, or nil if expired)
423 424 425 |
# File 'documented/gemstone/creature.rb', line 423 def ucs_position @ucs_position end |
#ucs_smote ⇒ Object
Returns the value of attribute ucs_smote.
226 227 228 |
# File 'documented/gemstone/creature.rb', line 226 def ucs_smote @ucs_smote end |
#ucs_tierup ⇒ Object
Get UCS tierup vulnerability (or nil if expired)
429 430 431 |
# File 'documented/gemstone/creature.rb', line 429 def ucs_tierup @ucs_tierup end |
#ucs_updated ⇒ Object
Returns the value of attribute ucs_updated.
226 227 228 |
# File 'documented/gemstone/creature.rb', line 226 def ucs_updated @ucs_updated end |
Class Method Details
.[](id) ⇒ Object
Lookup creature by ID
606 607 608 |
# File 'documented/gemstone/creature.rb', line 606 def [](id) @@instances[id.to_i] end |
.all ⇒ Object
Get all registered instances
611 612 613 |
# File 'documented/gemstone/creature.rb', line 611 def all @@instances.values end |
.auto_register? ⇒ Boolean
Check if auto-registration is enabled
560 561 562 |
# File 'documented/gemstone/creature.rb', line 560 def auto_register? @@auto_register end |
.cleanup_old(max_age_seconds = 600) ⇒ Object
Remove old instances (cleanup)
621 622 623 624 625 626 627 628 629 630 631 632 633 |
# File 'documented/gemstone/creature.rb', line 621 def cleanup_old(max_age_seconds = 600) cutoff = Time.now - max_age_seconds removed = 0 @@instances.reject! do |_id, instance| if instance.created_at < cutoff removed += 1 true else false end end removed end |
.clear ⇒ Object
Clear all instances (session reset)
616 617 618 |
# File 'documented/gemstone/creature.rb', line 616 def clear @@instances.clear end |
.configure(max_size: 1000, auto_register: true) ⇒ Object
Configure registry
554 555 556 557 |
# File 'documented/gemstone/creature.rb', line 554 def configure(max_size: 1000, auto_register: true) @@max_size = max_size @@auto_register = auto_register end |
.full? ⇒ Boolean
Check if registry is full
570 571 572 |
# File 'documented/gemstone/creature.rb', line 570 def full? size >= @@max_size end |
.register(name, id, noun = nil) ⇒ CreatureInstance?
Returns nil if registry is full after cleanup attempts
Register a new creature instance in the global registry
Auto-cleanup triggers if registry is full, progressively removing older creatures (15min, 10min, 5min, 2min thresholds).
584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 |
# File 'documented/gemstone/creature.rb', line 584 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 15 minutes, then 10, then 5, then 2, then give up [900, 600, 300, 120].each do |age_threshold| removed = cleanup_old(age_threshold) puts "--- 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 puts "--- Creature registered: #{name} (#{id})" if $creature_debug instance end |
.size ⇒ Object
Get current registry size
565 566 567 |
# File 'documented/gemstone/creature.rb', line 565 def size @@instances.size end |
Instance Method Details
#add_damage(amount) ⇒ void
This method returns an undefined value.
Add damage to creature’s health pool
475 476 477 |
# File 'documented/gemstone/creature.rb', line 475 def add_damage(amount) @damage_taken += amount.to_i end |
#add_injury(body_part, amount = 1) ⇒ Object
Add injury/wound to a body part
441 442 443 444 445 446 |
# File 'documented/gemstone/creature.rb', line 441 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.
Add a status effect to the creature
Status effects like :stunned, :prone, :webbed are tracked with optional auto-expiration based on STATUS_DURATIONS.
301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 |
# File 'documented/gemstone/creature.rb', line 301 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 puts " +status: #{status} (expires in #{duration}s)" if $creature_debug else puts " +status: #{status} (no auto-expiry)" if $creature_debug end end |
#cleanup_expired_statuses ⇒ void
This is called frequently - performance sensitive
This method returns an undefined value.
Clean up expired status effects
Called automatically by has_status? and statuses methods. Removes any status whose expiration timestamp has passed.
331 332 333 334 335 336 337 338 339 340 |
# File 'documented/gemstone/creature.rb', line 331 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) puts " ~status: #{expired_status} (auto-expired)" if $creature_debug end end |
#clear_smote ⇒ Object
Clear smote status
410 411 412 413 414 |
# File 'documented/gemstone/creature.rb', line 410 def clear_smote @ucs_smote = nil @ucs_updated = Time.now puts " UCS: smote cleared" if $creature_debug end |
#current_hp ⇒ Integer?
Calculate current hit points
503 504 505 506 |
# File 'documented/gemstone/creature.rb', line 503 def current_hp return nil unless max_hp [max_hp - @damage_taken, 0].max end |
#dead? ⇒ Boolean
Check if creature is dead (0 HP)
521 522 523 |
# File 'documented/gemstone/creature.rb', line 521 def dead? current_hp == 0 end |
#essential_data ⇒ Object
Essential data for this instance
531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 |
# File 'documented/gemstone/creature.rb', line 531 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
Check if creature died from fatal crit
459 460 461 |
# File 'documented/gemstone/creature.rb', line 459 def fatal_crit? @fatal_crit end |
#has_status?(status) ⇒ Boolean
Check if creature has a specific status
343 344 345 346 |
# File 'documented/gemstone/creature.rb', line 343 def has_status?(status) cleanup_expired_statuses # Clean up expired statuses first @status.include?(status.to_s) end |
#has_template? ⇒ Boolean
Check if creature has template data
286 287 288 |
# File 'documented/gemstone/creature.rb', line 286 def has_template? !template.nil? end |
#hp_percent ⇒ Object
Calculate HP percentage (0-100)
509 510 511 512 |
# File 'documented/gemstone/creature.rb', line 509 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
Check if injured at location
449 450 451 |
# File 'documented/gemstone/creature.rb', line 449 def injured?(location, threshold = 1) @injuries[location.to_sym] >= threshold end |
#injured_locations(threshold = 1) ⇒ Object
Get all injured locations
464 465 466 |
# File 'documented/gemstone/creature.rb', line 464 def injured_locations(threshold = 1) @injuries.select { |_, value| value >= threshold }.keys end |
#low_hp?(threshold = 25) ⇒ Boolean
Check if creature is below HP threshold
515 516 517 518 |
# File 'documented/gemstone/creature.rb', line 515 def low_hp?(threshold = 25) return false unless hp_percent hp_percent <= threshold end |
#mark_fatal_crit! ⇒ Object
Mark creature as killed by fatal critical hit
454 455 456 |
# File 'documented/gemstone/creature.rb', line 454 def mark_fatal_crit! @fatal_crit = true end |
#max_hp ⇒ Object
Get maximum HP from template, with fallback
480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 |
# File 'documented/gemstone/creature.rb', line 480 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?
Convert UCS position string/number to tier (1-3)
360 361 362 363 364 365 366 367 |
# File 'documented/gemstone/creature.rb', line 360 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) ⇒ Object
Remove status from creature
318 319 320 321 322 |
# File 'documented/gemstone/creature.rb', line 318 def remove_status(status) @status.delete(status) @status_timestamps.delete(status) puts " -status: #{status}" if $creature_debug end |
#reset_damage ⇒ Object
Reset damage (creature healed or respawned)
526 527 528 |
# File 'documented/gemstone/creature.rb', line 526 def reset_damage @damage_taken = 0 end |
#set_ucs_position(position) ⇒ Object
Set UCS position tier
370 371 372 373 374 375 376 377 378 379 380 |
# File 'documented/gemstone/creature.rb', line 370 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 puts " UCS: position=#{new_tier}" if $creature_debug end |
#set_ucs_tierup(attack_type) ⇒ Object
Set UCS tierup vulnerability
383 384 385 386 387 |
# File 'documented/gemstone/creature.rb', line 383 def set_ucs_tierup(attack_type) @ucs_tierup = attack_type @ucs_updated = Time.now puts " UCS: tierup=#{attack_type}" if $creature_debug end |
#smite! ⇒ Object
Mark creature as smote (crimson mist applied)
390 391 392 393 394 |
# File 'documented/gemstone/creature.rb', line 390 def smite! @ucs_smote = Time.now @ucs_updated = Time.now puts " UCS: smote!" if $creature_debug end |
#smote? ⇒ Boolean
Check if creature is currently smote
397 398 399 400 401 402 403 404 405 406 407 |
# File 'documented/gemstone/creature.rb', line 397 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 |
#statuses ⇒ Object
Get all current statuses
349 350 351 352 |
# File 'documented/gemstone/creature.rb', line 349 def statuses cleanup_expired_statuses # Clean up expired statuses first @status.dup end |
#template ⇒ CreatureTemplate?
Result is memoized for performance
Get the static template for this creature
281 282 283 |
# File 'documented/gemstone/creature.rb', line 281 def template @template ||= CreatureTemplate[@name] end |
#ucs_expired? ⇒ Boolean
Check if UCS data has expired
417 418 419 420 |
# File 'documented/gemstone/creature.rb', line 417 def ucs_expired? return true unless @ucs_updated (Time.now - @ucs_updated) > UCS_TTL end |