Module: Lich::Common::CreatureBase::ClassMethods

Defined in:
documented/common/creature/creature_base.rb

Overview

Class-level behaviour: the id-keyed instance registry, the current-room roster and the target/room queries shared by both games' Creature facades.

State lives in per-class instance variables (@instances, @current_room_ids, ...), so each extending class keeps an independent registry - GemStone and DragonRealms never share a roster even though they share this code.

Instance Method Summary collapse

Instance Method Details

#[](id) ⇒ Object?

Looks up a registered instance by id.

Parameters:

  • id (Integer, String)

    server creature id.

Returns:

  • (Object, nil)


252
253
254
# File 'documented/common/creature/creature_base.rb', line 252

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

#allArray<Object>

Returns every registered instance.

Returns:

  • (Array<Object>)

    every registered instance.



257
258
259
# File 'documented/common/creature/creature_base.rb', line 257

def all
  instances.values
end

#auto_register?Boolean

Returns whether auto-registration is enabled (default true).

Returns:

  • (Boolean)

    whether auto-registration is enabled (default true).



296
297
298
299
# File 'documented/common/creature/creature_base.rb', line 296

def auto_register?
  @auto_register = true if @auto_register.nil?
  @auto_register
end

#cleanup_old(max_age_seconds = 600) ⇒ Integer

Removes instances older than the given age.

Parameters:

  • max_age_seconds (Integer) (defaults to: 600)

    age cutoff in seconds.

Returns:

  • (Integer)

    number of instances removed.



273
274
275
276
277
278
# File 'documented/common/creature/creature_base.rb', line 273

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

#clearvoid

This method returns an undefined value.

Clears all instances and the room roster (session reset).



264
265
266
267
# File 'documented/common/creature/creature_base.rb', line 264

def clear
  instances.clear
  clear_room
end

#clear_roomvoid

This method returns an undefined value.

Empties the current-room roster (the persistent registry is untouched).

Called from the XML parser's nav and room-object refresh hooks; the roster is then rebuilt from fresh room XML.



230
231
232
233
234
# File 'documented/common/creature/creature_base.rb', line 230

def clear_room
  count = room_roster.size
  @current_room_ids = []
  respond "--- room: roster cleared (#{count} creature#{'s' unless count == 1})" if $creature_debug && count > 0
end

#configure(max_size: 1000, auto_register: true) ⇒ void

This method returns an undefined value.

Configures registry limits.

Every call resets omitted options to their defaults - max_size to 1000 and auto_register to true - so calling this with no arguments restores all defaults. Facade callers (e.g. Creature.configure(**options)) should pass every option they mean to keep.

Parameters:

  • max_size (Integer) (defaults to: 1000)

    maximum number of retained instances.

  • auto_register (Boolean) (defaults to: true)

    whether #register creates instances.



290
291
292
293
# File 'documented/common/creature/creature_base.rb', line 290

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

#current_room_idsArray<Integer>

Returns the creature ids currently present in the room.

Hands back a copy, not the live roster. The internal roster is mutated in place by #mark_in_room / #clear_room, so a caller that mutated the returned array - the GemStone facade relied on this defensive copy before the extraction - would otherwise corrupt shared targeting state.

Returns:

  • (Array<Integer>)


244
245
246
# File 'documented/common/creature/creature_base.rb', line 244

def current_room_ids
  room_roster.dup
end

#debug_on(level = :changes) ⇒ Boolean, Symbol

Toggles live echo of status, flag, and registration changes.

Parameters:

  • level (Boolean, Symbol) (defaults to: :changes)

    false disables debug output; true or :changes reports changes only; :all reports every <crtrStatus> flag; :active reports only active <crtrStatus> flags.

Returns:

  • (Boolean, Symbol)

    the configured debug value.



353
354
355
# File 'documented/common/creature/creature_base.rb', line 353

def debug_on(level = :changes)
  $creature_debug = level
end

#full?Boolean

Returns whether the registry is at capacity.

Returns:

  • (Boolean)

    whether the registry is at capacity.



312
313
314
# File 'documented/common/creature/creature_base.rb', line 312

def full?
  size >= max_size
end

#in_room(*filters) ⇒ Array<Object>

Returns all tracked creatures currently in the room.

Unlike #targets this requires neither hostility nor target validity, so it also serves dead creatures, looting and wound inspection. Filters are ANDed and may name a status, a classification flag, or a not_ negation such as :not_prone; unknown filters match nothing.

Parameters:

  • filters (Array<String, Symbol>)

    optional ANDed status/classification filters.

Returns:

  • (Array<Object>)


342
343
344
345
# File 'documented/common/creature/creature_base.rb', line 342

def in_room(*filters)
  candidates = room_roster.filter_map { |id| self[id] }
  apply_filters(candidates, filters)
end

#mark_in_room(id) ⇒ Boolean

Marks an id present in the current-room roster.

Parameters:

  • id (Integer, String)

    server creature id.

Returns:

  • (Boolean)

    true when the id was newly added.



216
217
218
219
220
221
222
# File 'documented/common/creature/creature_base.rb', line 216

def mark_in_room(id)
  id = id.to_i
  return false if room_roster.include?(id)

  room_roster << id
  true
end

#max_sizeInteger

Returns configured maximum registry size (default 1000).

Returns:

  • (Integer)

    configured maximum registry size (default 1000).



302
303
304
# File 'documented/common/creature/creature_base.rb', line 302

def max_size
  @max_size ||= 1000
end

#register(name, id, noun = nil) ⇒ Object?

Registers or looks up a creature instance, marking it present in the current room.

Room-marking happens on every call, new instance or not, because the feed event that triggers registration (a bolded room-object name, or a <crtrStatus> tag) is exactly the signal that the creature is present.

Parameters:

  • name (String, nil)

    display name; may be nil when the feed supplies an id before a name (DragonRealms <crtrStatus>).

  • id (Integer, String)

    server creature id.

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

    noun from room XML, when available.

Returns:

  • (Object, nil)

    the registered instance, or nil when auto-registration is disabled or the registry is full.



180
181
182
183
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
# File 'documented/common/creature/creature_base.rb', line 180

def register(name, id, noun = nil)
  # Record room presence first: the feed event that triggers this call
  # (a bolded room-object name or a <crtrStatus> tag) is itself proof the
  # creature is in the room, and that stays true even when
  # auto-registration is disabled and no instance will be created. Mark
  # before the guard so a known creature's room presence is still tracked
  # while auto-registration is off.
  entered_room = mark_in_room(id)
  return nil unless auto_register?

  existing = instances[id.to_i]
  if existing
    respond "--- #{name} (#{id}): in room" if entered_room && $creature_debug
    return existing
  end

  if full?
    # Progressively more aggressive: 120 minutes, then 15-minute steps.
    [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 every cleanup attempt.
  end

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

#sizeInteger

Returns current number of retained instances.

Returns:

  • (Integer)

    current number of retained instances.



307
308
309
# File 'documented/common/creature/creature_base.rb', line 307

def size
  instances.size
end

#targets(*filters) ⇒ Array<Object>

Returns attackable hostile creatures currently in the room.

Room membership comes from the creature roster (fed by XML room-object and <crtrStatus> events), not from any client last-selected-target control, which can go stale after movement or death. valid_target? (supplied by the game class) removes decoys/dead appendages and crtr_flag?(:hostile) supplies structured hostility.

Parameters:

  • filters (Array<String, Symbol>)

    optional ANDed status/classification filters.

Returns:

  • (Array<Object>)


326
327
328
329
330
331
# File 'documented/common/creature/creature_base.rb', line 326

def targets(*filters)
  candidates = room_roster
               .filter_map { |id| self[id] }
               .select { |c| c.valid_target? && c.crtr_flag?(:hostile) }
  apply_filters(candidates, filters)
end