Class: Lich::Common::GameObj
- Inherits:
-
Object
- Object
- Lich::Common::GameObj
- Defined in:
- documented/common/gameobj.rb
Overview
Represents a game object in the world.
Direct Known Subclasses
Constant Summary collapse
- @@loot =
Class-level registries
[]
- @@npcs =
[]
- @@npc_status =
{}
- @@pcs =
[]
- @@pc_status =
{}
- @@inv =
[]
- @@reserve =
nil- @@contents =
{}
- @@right_hand =
nil- @@left_hand =
nil- @@room_desc =
[]
- @@fam_loot =
[]
- @@fam_npcs =
[]
- @@fam_pcs =
[]
- @@fam_room_desc =
[]
- @@type_data =
{}
- @@type_cache =
{}
- @@sellable_data =
{}
- @@index =
Shared identity index — single persistent O(1) lookup pool with TTL.
Maps composite key String "id|noun|name" to a two-element array [GameObj, last_seen_at] where
last_seen_atis a Float timestamp (fromProcess.clock_gettime(Process::CLOCK_MONOTONIC)) recording when the entry was last accessed byfind_or_create.All registries share this one index because a GameObj with the same id, noun, and name is the same logical game entity regardless of which registry it belongs to.
The index is intentionally not flushed when a registry is cleared. Room transitions call multiple
clear_*methods in quick succession; flushing on every clear would cause every re-encountered object to be needlessly reallocated. Instead, stale index entries self-heal: whenfind_or_createfinds an entry for an object that was cleared from its registry, it simply re-adds that same instance to the target registry and refreshes itslast_seen_attimestamp.Garbage collection is handled by
prune_index!, which removes entries whoselast_seen_atis older than a given TTL (default 15 minutes). Call it at natural session breakpoints (e.g. after a room transition or from a script's idle loop). It is safe to call frequently — entries that were just accessed will never be pruned regardless of how often it runs.Use
index_statsto inspect the current state of the index at any time.For very long automated sessions an alternative
LruIndexdrop-in is also available — seeLich::Common::LruIndexbelow. {}
Instance Attribute Summary collapse
-
#after_name ⇒ Object
Returns the value of attribute after_name.
-
#before_name ⇒ Object
Returns the value of attribute before_name.
-
#id ⇒ Object
readonly
Returns the value of attribute id.
-
#name ⇒ Object
Returns the value of attribute name.
-
#noun ⇒ Object
Returns the value of attribute noun.
Class Method Summary collapse
- .[](val) ⇒ Object
- .clear_all_containers ⇒ Object
- .clear_container(container_id) ⇒ Object
- .clear_fam_loot ⇒ Object
- .clear_fam_npcs ⇒ Object
- .clear_fam_pcs ⇒ Object
- .clear_fam_room_desc ⇒ Object
- .clear_inv ⇒ Object
- .clear_loot ⇒ Object
- .clear_npcs ⇒ Object
- .clear_pcs ⇒ Object
- .clear_reserve ⇒ Object
- .clear_room_desc ⇒ Object
- .containers ⇒ Object
- .dead ⇒ Object
- .delete_container(container_id) ⇒ Object
- .fam_loot ⇒ Object
- .fam_npcs ⇒ Object
- .fam_pcs ⇒ Object
- .fam_room_desc ⇒ Object
- .hidden_targets ⇒ Object
-
.index_or_create(id, noun, name, before = nil, after = nil) ⇒ GameObj
Looks up an existing
GameObjin the shared identity index by composite key (+id+,noun,name), or creates and indexes a new one. -
.index_stats(verbose: false) ⇒ Hash
Provides statistics about the current state of the index.
- .inv ⇒ Object
- .left_hand ⇒ Object
- .load_data(filename = nil) ⇒ Object
- .loot ⇒ Object
- .merge_data(existing, new_value) ⇒ Object
- .new_fam_loot(id, noun, name) ⇒ Object
- .new_fam_npc(id, noun, name) ⇒ Object
- .new_fam_pc(id, noun, name) ⇒ Object
- .new_fam_room_desc(id, noun, name) ⇒ Object
- .new_inv(id, noun, name, container = nil, before = nil, after = nil) ⇒ Object
- .new_left_hand(id, noun, name) ⇒ Object
- .new_loot(id, noun, name) ⇒ Object
-
.new_npc(id, noun, name, status = nil) ⇒ GameObj
Creates a new NPC game object and registers it.
-
.new_pc(id, noun, name, status = nil) ⇒ GameObj
Creates a new player character game object and registers it.
- .new_reserve(id, noun, name) ⇒ Object
- .new_right_hand(id, noun, name) ⇒ Object
- .new_room_desc(id, noun, name) ⇒ Object
- .npcs ⇒ Object
- .pcs ⇒ Object
-
.prune_index!(ttl: 900, verbose: false) ⇒ Hash
Removes entries from the shared identity index whose
last_seen_attimestamp is older thanttlseconds ago and whose object is not currently present in any active registry, then GC-hints Ruby. -
.reload(filename = nil) ⇒ Boolean
Reloads the game object data from the specified file.
- .reserve ⇒ Object
- .right_hand ⇒ Object
- .room_desc ⇒ Object
- .sellable_data ⇒ Object
- .target ⇒ Object
- .targets ⇒ Object
- .type_cache ⇒ Object
- .type_data ⇒ Object
Instance Method Summary collapse
- #contents ⇒ Object
- #empty? ⇒ Boolean
- #full_name ⇒ Object
- #GameObj ⇒ Object
-
#initialize(id, noun, name, before = nil, after = nil) ⇒ GameObj
constructor
Initializes a new game object.
-
#sellable ⇒ String?
Retrieves the sellable types of the game object.
- #status ⇒ Object
- #status=(val) ⇒ Object
- #to_s ⇒ Object
-
#type ⇒ String?
Retrieves the type of the game object based on its name.
- #type?(type_to_check) ⇒ Boolean
Constructor Details
#initialize(id, noun, name, before = nil, after = nil) ⇒ GameObj
Initializes a new game object.
86 87 88 89 90 91 92 |
# File 'documented/common/gameobj.rb', line 86 def initialize(id, noun, name, before = nil, after = nil) @id = id.is_a?(Integer) ? id.to_s : id @noun = normalize_noun(noun, name) @name = name @before_name = before @after_name = after end |
Instance Attribute Details
#after_name ⇒ Object
Returns the value of attribute after_name.
77 78 79 |
# File 'documented/common/gameobj.rb', line 77 def after_name @after_name end |
#before_name ⇒ Object
Returns the value of attribute before_name.
75 76 77 |
# File 'documented/common/gameobj.rb', line 75 def before_name @before_name end |
#id ⇒ Object (readonly)
Returns the value of attribute id.
69 70 71 |
# File 'documented/common/gameobj.rb', line 69 def id @id end |
#name ⇒ Object
Returns the value of attribute name.
73 74 75 |
# File 'documented/common/gameobj.rb', line 73 def name @name end |
#noun ⇒ Object
Returns the value of attribute noun.
71 72 73 |
# File 'documented/common/gameobj.rb', line 71 def noun @noun end |
Class Method Details
.[](val) ⇒ Object
313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 |
# File 'documented/common/gameobj.rb', line 313 def self.[](val) unless val.is_a?(String) || val.is_a?(Regexp) respond "--- Lich: error: GameObj[] passed with #{val.class} #{val} via caller: #{caller[0]}" respond "--- Lich: error: GameObj[] supports String or Regexp only" Lich.log "--- Lich: error: GameObj[] passed with #{val.class} #{val} via caller: #{caller[0]}\n\t" Lich.log "--- Lich: error: GameObj[] supports String or Regexp only\n\t" if val.is_a?(Integer) respond "--- Lich: error: GameObj[] converted Integer #{val} to String to continue" val = val.to_s else return nil end end if val.is_a?(Regexp) return search_registries { |o| o.name =~ val } end if val =~ /^\-?[0-9]+$/ # Numeric ID lookup (room_desc excluded from primary, appended last for completeness) search_registries { |o| o.id == val } elsif val.split(' ').length == 1 # Single-word noun lookup search_registries { |o| o.noun == val } else # Name lookup — exact first, then suffix, then fuzzy suffix escaped = Regexp.escape(val.strip) fuzzy = Regexp.escape(val).sub(' ', ' .*') search_registries { |o| o.name == val } || search_registries { |o| o.name =~ /\b#{escaped}$/i } || search_registries { |o| o.name =~ /\b#{fuzzy}$/i } end end |
.clear_all_containers ⇒ Object
302 |
# File 'documented/common/gameobj.rb', line 302 def self.clear_all_containers = @@contents.clear |
.clear_container(container_id) ⇒ Object
304 305 306 |
# File 'documented/common/gameobj.rb', line 304 def self.clear_container(container_id) @@contents[container_id] = [] end |
.clear_fam_loot ⇒ Object
296 |
# File 'documented/common/gameobj.rb', line 296 def self.clear_fam_loot = @@fam_loot.clear |
.clear_fam_npcs ⇒ Object
298 |
# File 'documented/common/gameobj.rb', line 298 def self.clear_fam_npcs = @@fam_npcs.clear |
.clear_fam_pcs ⇒ Object
300 |
# File 'documented/common/gameobj.rb', line 300 def self.clear_fam_pcs = @@fam_pcs.clear |
.clear_fam_room_desc ⇒ Object
294 |
# File 'documented/common/gameobj.rb', line 294 def self.clear_fam_room_desc = @@fam_room_desc.clear |
.clear_inv ⇒ Object
288 |
# File 'documented/common/gameobj.rb', line 288 def self.clear_inv = @@inv.clear |
.clear_loot ⇒ Object
282 |
# File 'documented/common/gameobj.rb', line 282 def self.clear_loot = @@loot.clear |
.clear_npcs ⇒ Object
284 |
# File 'documented/common/gameobj.rb', line 284 def self.clear_npcs = (@@npcs.clear; @@npc_status.clear) |
.clear_pcs ⇒ Object
286 |
# File 'documented/common/gameobj.rb', line 286 def self.clear_pcs = (@@pcs.clear; @@pc_status.clear) |
.clear_reserve ⇒ Object
290 |
# File 'documented/common/gameobj.rb', line 290 def self.clear_reserve = (@@reserve = []) |
.clear_room_desc ⇒ Object
292 |
# File 'documented/common/gameobj.rb', line 292 def self.clear_room_desc = @@room_desc.clear |
.containers ⇒ Object
279 |
# File 'documented/common/gameobj.rb', line 279 def self.containers = @@contents.dup |
.dead ⇒ Object
369 370 371 372 |
# File 'documented/common/gameobj.rb', line 369 def self.dead dead_list = @@npcs.select { |obj| obj.status == 'dead' } dead_list.empty? ? nil : dead_list end |
.delete_container(container_id) ⇒ Object
308 309 310 |
# File 'documented/common/gameobj.rb', line 308 def self.delete_container(container_id) @@contents.delete(container_id) end |
.fam_loot ⇒ Object
273 |
# File 'documented/common/gameobj.rb', line 273 def self.fam_loot = registry_or_nil(@@fam_loot) |
.fam_npcs ⇒ Object
275 |
# File 'documented/common/gameobj.rb', line 275 def self.fam_npcs = registry_or_nil(@@fam_npcs) |
.fam_pcs ⇒ Object
277 |
# File 'documented/common/gameobj.rb', line 277 def self.fam_pcs = registry_or_nil(@@fam_pcs) |
.fam_room_desc ⇒ Object
271 |
# File 'documented/common/gameobj.rb', line 271 def self.fam_room_desc = registry_or_nil(@@fam_room_desc) |
.hidden_targets ⇒ Object
361 362 363 |
# File 'documented/common/gameobj.rb', line 361 def self.hidden_targets XMLData.current_target_ids.reject { |id| @@npcs.any? { |n| n.id == id } } end |
.index_or_create(id, noun, name, before = nil, after = nil) ⇒ GameObj
Looks up an existing GameObj in the shared identity index by composite
key (+id+, noun, name), or creates and indexes a new one.
Unlike find_or_create, this method does not push the object into any
Looks up an existing game object in the shared identity index by composite key (id, noun, name), or creates and indexes a new one.
236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 |
# File 'documented/common/gameobj.rb', line 236 def self.index_or_create(id, noun, name, before = nil, after = nil) str_id = id.is_a?(Integer) ? id.to_s : id key = "#{str_id}|#{noun}|#{name}" now = Process.clock_gettime(Process::CLOCK_MONOTONIC) if (entry = @@index[key]) existing, _ts = entry @@index[key] = [existing, now] existing.before_name = before if existing.before_name.nil? && !before.nil? existing.after_name = after if existing.after_name.nil? && !after.nil? return existing end obj = GameObj.new(id, noun, name, before, after) @@index[key] = [obj, now] obj end |
.index_stats(verbose: false) ⇒ Hash
Provides statistics about the current state of the index.
476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 |
# File 'documented/common/gameobj.rb', line 476 def self.index_stats(verbose: false) require 'objspace' return empty_index_stats if @@index.empty? now = Process.clock_gettime(Process::CLOCK_MONOTONIC) live_ids = live_registry_ids buckets = { 'under5m' => 0, '5-15m' => 0, '15-30m' => 0, '30-60m' => 0, 'over60m' => 0 } stale = 0 oldest_age = 0.0 @@index.each_value do |obj, last_seen| age = now - last_seen oldest_age = age if age > oldest_age stale += 1 unless live_ids.include?(obj.id) buckets[case age when 0...300 then 'under5m' when 300...900 then '5-15m' when 900...1800 then '15-30m' when 1800...3600 then '30-60m' else 'over60m' end] += 1 end obj_mem = gameobj_memory_bytes heap_mem = ruby_heap_bytes result = { total_entries: @@index.size, live_in_registries: @@index.size - stale, stale_entries: stale, oldest_entry_seconds: oldest_age.round(1), age_buckets: buckets, gameobj_bytes: obj_mem, heap_bytes: heap_mem } if verbose oldest_fmt = if oldest_age < 60 "#{oldest_age.round(1)}s" elsif oldest_age < 3600 "#{(oldest_age / 60).round(1)}m" else "#{(oldest_age / 3600).round(2)}h" end w = 28 puts "=" * 52 puts " GameObj.index_stats" puts "=" * 52 puts format(" %-#{w}s %d", "Total index entries:", @@index.size) puts format(" %-#{w}s %d", "Live in registries:", result[:live_in_registries]) puts format(" %-#{w}s %d", "Stale (index-only):", stale) puts format(" %-#{w}s %s", "Oldest entry:", oldest_fmt) puts "-" * 52 puts " Age distribution:" buckets.each do |label, count| = "#" * [count, 30].min puts format(" %-10s %4d %s", label, count, ) end puts "-" * 52 puts format(" %-#{w}s %s", "GameObj object memory:", format_bytes(obj_mem)) puts format(" %-#{w}s %s", "Ruby heap size:", format_bytes(heap_mem)) puts "=" * 52 end result end |
.inv ⇒ Object
265 |
# File 'documented/common/gameobj.rb', line 265 def self.inv = registry_or_nil(@@inv) |
.left_hand ⇒ Object
257 |
# File 'documented/common/gameobj.rb', line 257 def self.left_hand = @@left_hand&.dup |
.load_data(filename = nil) ⇒ Object
558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 |
# File 'documented/common/gameobj.rb', line 558 def self.load_data(filename = nil) primary = filename || File.join(DATA_DIR, 'gameobj-data.xml') unless File.exist?(primary) @@type_data = @@sellable_data = nil echo "error: GameObj.load_data: file does not exist: #{primary}" return false end begin @@type_data = {} @@sellable_data = {} @@type_cache = {} parse_data_file(primary) rescue => e @@type_data = @@sellable_data = nil echo "error: GameObj.load_data: #{e}" respond e.backtrace[0..1] return false end custom = File.join(DATA_DIR, 'gameobj-custom', 'gameobj-data.xml') if File.exist?(custom) begin parse_data_file(custom, merge: true) rescue => e echo "error: Custom GameObj.load_data: #{e}" respond e.backtrace[0..1] return false end end true end |
.loot ⇒ Object
261 |
# File 'documented/common/gameobj.rb', line 261 def self.loot = registry_or_nil(@@loot) |
.merge_data(existing, new_value) ⇒ Object
554 555 556 |
# File 'documented/common/gameobj.rb', line 554 def self.merge_data(existing, new_value) existing.is_a?(Regexp) ? Regexp.union(existing, new_value) : new_value end |
.new_fam_loot(id, noun, name) ⇒ Object
205 206 207 |
# File 'documented/common/gameobj.rb', line 205 def self.new_fam_loot(id, noun, name) find_or_create(@@fam_loot, id, noun, name) end |
.new_fam_npc(id, noun, name) ⇒ Object
209 210 211 |
# File 'documented/common/gameobj.rb', line 209 def self.new_fam_npc(id, noun, name) find_or_create(@@fam_npcs, id, noun, name) end |
.new_fam_pc(id, noun, name) ⇒ Object
213 214 215 |
# File 'documented/common/gameobj.rb', line 213 def self.new_fam_pc(id, noun, name) find_or_create(@@fam_pcs, id, noun, name) end |
.new_fam_room_desc(id, noun, name) ⇒ Object
201 202 203 |
# File 'documented/common/gameobj.rb', line 201 def self.new_fam_room_desc(id, noun, name) find_or_create(@@fam_room_desc, id, noun, name) end |
.new_inv(id, noun, name, container = nil, before = nil, after = nil) ⇒ Object
183 184 185 186 187 188 189 190 |
# File 'documented/common/gameobj.rb', line 183 def self.new_inv(id, noun, name, container = nil, before = nil, after = nil) if container @@contents[container] ||= [] find_or_create(@@contents[container], id, noun, name, before, after) else find_or_create(@@inv, id, noun, name, before, after) end end |
.new_left_hand(id, noun, name) ⇒ Object
221 222 223 |
# File 'documented/common/gameobj.rb', line 221 def self.new_left_hand(id, noun, name) @@left_hand = index_or_create(id, noun, name) end |
.new_loot(id, noun, name) ⇒ Object
167 168 169 |
# File 'documented/common/gameobj.rb', line 167 def self.new_loot(id, noun, name) find_or_create(@@loot, id, noun, name) end |
.new_npc(id, noun, name, status = nil) ⇒ GameObj
Creates a new NPC game object and registers it.
161 162 163 164 165 |
# File 'documented/common/gameobj.rb', line 161 def self.new_npc(id, noun, name, status = nil) obj = find_or_create(@@npcs, id, noun, name) @@npc_status[obj.id] = status obj end |
.new_pc(id, noun, name, status = nil) ⇒ GameObj
Creates a new player character game object and registers it.
177 178 179 180 181 |
# File 'documented/common/gameobj.rb', line 177 def self.new_pc(id, noun, name, status = nil) obj = find_or_create(@@pcs, id, noun, name) @@pc_status[obj.id] = status obj end |
.new_reserve(id, noun, name) ⇒ Object
192 193 194 195 |
# File 'documented/common/gameobj.rb', line 192 def self.new_reserve(id, noun, name) @@reserve ||= [] find_or_create(@@reserve, id, noun, name) end |
.new_right_hand(id, noun, name) ⇒ Object
217 218 219 |
# File 'documented/common/gameobj.rb', line 217 def self.new_right_hand(id, noun, name) @@right_hand = index_or_create(id, noun, name) end |
.new_room_desc(id, noun, name) ⇒ Object
197 198 199 |
# File 'documented/common/gameobj.rb', line 197 def self.new_room_desc(id, noun, name) find_or_create(@@room_desc, id, noun, name) end |
.npcs ⇒ Object
259 |
# File 'documented/common/gameobj.rb', line 259 def self.npcs = registry_or_nil(@@npcs) |
.pcs ⇒ Object
263 |
# File 'documented/common/gameobj.rb', line 263 def self.pcs = registry_or_nil(@@pcs) |
.prune_index!(ttl: 900, verbose: false) ⇒ Hash
Removes entries from the shared identity index whose last_seen_at
timestamp is older than ttl seconds ago and whose object is not
currently present in any active registry, then GC-hints Ruby.
The live-registry check is the critical guard: an object that is still
held in @@npcs, @@loot, @@inv, or any other registry must never be
pruned regardless of how long ago it was last re-registered. Pruning a
live entry would cause the next find_or_create call for that object to
allocate a brand-new instance, silently breaking the identity guarantee.
An entry is only eligible for pruning when both conditions are true:
1. +last_seen_at+ is older than +ttl+ seconds ago
2. The object's ID is not present in any active registry
Safe to call at any time and as frequently as desired. Entries that are live in registries are always skipped. Entries accessed within the TTL window are always skipped. Removes entries from the shared identity index whose last_seen_at timestamp is older than ttl seconds ago and whose object is not currently present in any active registry.
399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 |
# File 'documented/common/gameobj.rb', line 399 def self.prune_index!(ttl: 900, verbose: false) require 'objspace' t_start = Process.clock_gettime(Process::CLOCK_MONOTONIC) cutoff = t_start - ttl # Build the live-ID set once before the sweep so we do not repeatedly # iterate all registries inside the delete_if block. live_ids = live_registry_ids obj_before = gameobj_memory_bytes heap_before = ruby_heap_bytes pruned = 0 skipped_live = 0 @@index.delete_if do |_key, (obj, last_seen)| if live_ids.include?(obj.id) # Object is currently held in a registry — never prune regardless of age. skipped_live += 1 false elsif last_seen < cutoff pruned += 1 true else false end end GC.start(full_mark: false, immediate_sweep: false) if pruned.positive? obj_after = gameobj_memory_bytes heap_after = ruby_heap_bytes elapsed = (Process.clock_gettime(Process::CLOCK_MONOTONIC) - t_start) * 1000 result = { pruned: pruned, skipped_live: skipped_live, remaining: @@index.size, gameobj_bytes_before: obj_before, gameobj_bytes_after: obj_after, gameobj_bytes_freed: obj_before - obj_after, heap_bytes_before: heap_before, heap_bytes_after: heap_after, heap_bytes_freed: heap_before - heap_after, elapsed_ms: elapsed.round(3) } if verbose w = 28 puts "=" * 52 puts " GameObj.prune_index! - TTL: #{ttl}s" puts "=" * 52 puts format(" %-#{w}s %s -> %s (%s)", "GameObj object memory:", format_bytes(obj_before), format_bytes(obj_after), format_delta(result[:gameobj_bytes_freed])) puts format(" %-#{w}s %s -> %s (%s)", "Ruby heap size:", format_bytes(heap_before), format_bytes(heap_after), format_delta(result[:heap_bytes_freed])) puts format(" %-#{w}s %d removed, %d skipped (live), %d remaining", "Index entries:", pruned, skipped_live, @@index.size) puts format(" %-#{w}s %.3f ms", "Elapsed:", elapsed) puts "=" * 52 end result end |
.reload(filename = nil) ⇒ Boolean
Reloads the game object data from the specified file.
550 551 552 |
# File 'documented/common/gameobj.rb', line 550 def self.reload(filename = nil) load_data(filename) end |
.reserve ⇒ Object
267 |
# File 'documented/common/gameobj.rb', line 267 def self.reserve = @@reserve&.dup |
.right_hand ⇒ Object
255 |
# File 'documented/common/gameobj.rb', line 255 def self.right_hand = @@right_hand&.dup |
.room_desc ⇒ Object
269 |
# File 'documented/common/gameobj.rb', line 269 def self.room_desc = registry_or_nil(@@room_desc) |
.sellable_data ⇒ Object
597 |
# File 'documented/common/gameobj.rb', line 597 def self.sellable_data = @@sellable_data |
.target ⇒ Object
365 366 367 |
# File 'documented/common/gameobj.rb', line 365 def self.target (@@npcs + @@pcs).find { |n| n.id == XMLData.current_target_id } end |
.targets ⇒ Object
349 350 351 352 353 354 355 356 357 358 359 |
# File 'documented/common/gameobj.rb', line 349 def self.targets XMLData.current_target_ids.filter_map do |id| npc = @@npcs.find { |n| n.id == id } next unless npc next if npc.status.to_s =~ /dead|gone/i next if npc.name =~ /^animated\b/i && npc.name !~ /^animated slush/i next if npc.noun =~ /^(?:arm|appendage|claw|limb|pincer|tentacle)s?$|^(?:palpus|palpi)$/i && npc.name !~ /(?:amaranthine|ghostly|grizzled|ancient) kraken tentacle/i npc end end |
.type_cache ⇒ Object
595 |
# File 'documented/common/gameobj.rb', line 595 def self.type_cache = @@type_cache |
.type_data ⇒ Object
593 |
# File 'documented/common/gameobj.rb', line 593 def self.type_data = @@type_data |
Instance Method Details
#contents ⇒ Object
106 107 108 |
# File 'documented/common/gameobj.rb', line 106 def contents @@contents[@id]&.dup end |
#empty? ⇒ Boolean
102 103 104 |
# File 'documented/common/gameobj.rb', line 102 def empty? false end |
#full_name ⇒ Object
110 111 112 113 |
# File 'documented/common/gameobj.rb', line 110 def full_name parts = [@before_name, @name, @after_name] parts.compact.reject(&:empty?).join(' ') end |
#GameObj ⇒ Object
98 99 100 |
# File 'documented/common/gameobj.rb', line 98 def GameObj @noun end |
#sellable ⇒ String?
Retrieves the sellable types of the game object.
132 133 134 135 136 |
# File 'documented/common/gameobj.rb', line 132 def sellable GameObj.load_data if @@sellable_data.empty? matches = matching_data_keys(@@sellable_data) matches.empty? ? nil : matches.join(',') end |
#status ⇒ Object
139 140 141 142 143 144 |
# File 'documented/common/gameobj.rb', line 139 def status return @@npc_status[@id] if @@npc_status.key?(@id) return @@pc_status[@id] if @@pc_status.key?(@id) present_in_any_registry? ? nil : 'gone' end |
#status=(val) ⇒ Object
146 147 148 149 150 151 152 |
# File 'documented/common/gameobj.rb', line 146 def status=(val) if @@npcs.any? { |npc| npc.id == @id } @@npc_status[@id] = val elsif @@pcs.any? { |pc| pc.id == @id } @@pc_status[@id] = val end end |
#to_s ⇒ Object
94 95 96 |
# File 'documented/common/gameobj.rb', line 94 def to_s @noun end |
#type ⇒ String?
Retrieves the type of the game object based on its name.
118 119 120 121 122 123 124 |
# File 'documented/common/gameobj.rb', line 118 def type GameObj.load_data if @@type_data.empty? return @@type_cache[@name] if @@type_cache.key?(@name) matches = matching_data_keys(@@type_data) @@type_cache[@name] = matches.empty? ? nil : matches.join(',') end |
#type?(type_to_check) ⇒ Boolean
126 127 128 |
# File 'documented/common/gameobj.rb', line 126 def type?(type_to_check) type.to_s.split(',').include?(type_to_check) end |