Class: Lich::Gemstone::Group

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

Overview

Observes and manages group membership and state changes via game output.

This is the second definition of the Group class, providing the Observer module that automatically updates group state when game output matches group-related patterns. Watches for membership changes, leadership transfers, group status updates, and hand-holding actions that form groups.

Defined Under Namespace

Modules: Observer

Class Method Summary collapse

Class Method Details

._membersArray<GameObj>

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns the internal members array without checking or copying. Used internally by the Observer to avoid infinite loops.

Returns:

  • (Array<GameObj>)

    the internal members array



90
91
92
# File 'documented/gemstone/group.rb', line 90

def self._members
  @@members
end

.add(*members) ⇒ Array<Hash>

Adds one or more members to the group by sending GROUP commands. Handles both String names and GameObj instances. Can accept nested arrays of members.

Examples:

Add a single member

Group.add("PlayerName")

Add multiple members

Group.add("Player1", "Player2")

Parameters:

  • members (Array<String, GameObj, Array>)

    members to add

Returns:

  • (Array<Hash>)

    array of results, each containing :ok or :err key with member



211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
# File 'documented/gemstone/group.rb', line 211

def self.add(*members)
  members.map do |member|
    if member.is_a?(Array)
      Group.add(*member)
    else
      member = GameObj.pcs.find { |pc| pc.noun.eql?(member) } if member.is_a?(String)

      break if member.nil?

      result = dothistimeout("group ##{member.id}", 3, Regexp.union(
                                                         %r{You add #{member.noun} to your group},
                                                         %r{#{member.noun}'s group status is closed},
                                                         %r{But #{member.noun} is already a member of your group}
                                                       ))

      case result
      when %r{You add}, %r{already a member}
        Group.push(member)
        { ok: member }
      when %r{closed}
        Group.delete(member)
        { err: member }
      else
      end
    end
  end
end

.broken?Boolean

Checks if the group state is broken or inconsistent. Waits for any claim locks to release before checking. For leaders: checks if member list matches actual PCs in room. For members: checks if leader is still present.

Returns:

  • (Boolean)

    true if group state is inconsistent



267
268
269
270
271
272
273
274
275
276
# File 'documented/gemstone/group.rb', line 267

def self.broken?
  sleep(0.1) while Lich::Gemstone::Claim::Lock.locked?
  if Group.leader?
    return true if (GameObj.pcs.empty? || GameObj.pcs.nil?) && !@@members.empty?
    return false if (GameObj.pcs.empty? || GameObj.pcs.nil?) && @@members.empty?
    (GameObj.pcs.map(&:noun) & @@members.map(&:noun)).size < @@members.size
  else
    GameObj.pcs.find do |pc| pc.noun.eql?(Group.leader.noun) end.nil?
  end
end

.checkArray<GameObj>

Actively checks group status by sending the GROUP command to the game. Clears current group data and waits up to 3 seconds for response. Should be called at script initialization.

Returns:

  • (Array<GameObj>)

    copy of the members array after checking



157
158
159
160
161
162
163
# File 'documented/gemstone/group.rb', line 157

def self.check
  Group.clear()
  ttl = Time.now + 3
  Game._puts "<c>group\r\n"
  wait_until { Group.checked? or Time.now > ttl }
  @@members.dup
end

.checked=(flag) ⇒ Boolean

Sets the checked flag indicating group data has been verified.

Parameters:

  • flag (Boolean)

    true if group data is verified

Returns:

  • (Boolean)

    the flag value



117
118
119
# File 'documented/gemstone/group.rb', line 117

def self.checked=(flag)
  @@checked = flag
end

.checked?Boolean

Checks if group data has been verified with the game.

Returns:

  • (Boolean)

    true if group data has been checked



43
44
45
# File 'documented/gemstone/group.rb', line 43

def self.checked?
  @@checked
end

.clearArray

Clears all group members and resets the checked flag. Does not change leader status.

Returns:

  • (Array)

    Empty array



35
36
37
38
# File 'documented/gemstone/group.rb', line 35

def self.clear()
  @@members = []
  @@checked = false
end

.closed?Boolean

Checks if the group is closed to new members.

Returns:

  • (Boolean)

    true if group status is not open



148
149
150
# File 'documented/gemstone/group.rb', line 148

def self.closed?
  not open?
end

.delete(*members) ⇒ Array<GameObj>

Removes one or more members from the group by ID.

Parameters:

  • members (Array<GameObj>)

    one or more GameObj instances to remove

Returns:

  • (Array<GameObj>)

    the updated members array



62
63
64
65
# File 'documented/gemstone/group.rb', line 62

def self.delete(*members)
  gone = members.map(&:id)
  @@members.reject! do |m| gone.include?(m.id) end
end

.disksArray<Disk>

Returns Disk objects for all group members. If the player is leader with no members, returns only the player's disk. Always includes the current character's disk if available.

Returns:

  • (Array<Disk>)

    array of Disk objects for group members



99
100
101
102
103
104
# File 'documented/gemstone/group.rb', line 99

def self.disks
  return [Disk.find_by_name(Char.name)].compact if Group.leader? && members.empty?
  member_disks = members.map(&:noun).compact.map { |noun| Disk.find_by_name(noun) }.compact
  member_disks.push(Disk.find_by_name(Char.name)) if Disk.find_by_name(Char.name)
  return member_disks
end

.idsArray<String>

Returns array of all member IDs.

Returns:

  • (Array<String>)

    array of member IDs



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

def self.ids
  @@members.map(&:id)
end

.include?(*members) ⇒ Boolean

Checks if all specified members are in the group.

Parameters:

  • members (Array<GameObj>)

    members to check

Returns:

  • (Boolean)

    true if all members are in the group



257
258
259
# File 'documented/gemstone/group.rb', line 257

def self.include?(*members)
  members.all? { |m| ids.include?(m.id) }
end

.leaderSymbol, GameObj

Gets the current group leader.

Returns:

  • (Symbol, GameObj)

    :self if current player is leader, or GameObj of leader



190
191
192
# File 'documented/gemstone/group.rb', line 190

def self.leader
  @@leader
end

.leader=(char) ⇒ Symbol, GameObj

Sets the group leader.

Parameters:

  • char (Symbol, GameObj)

    :self if current player is leader, or GameObj of leader

Returns:

  • (Symbol, GameObj)

    the leader value



183
184
185
# File 'documented/gemstone/group.rb', line 183

def self.leader=(char)
  @@leader = char
end

.leader?Boolean

Checks if the current player is the group leader.

Returns:

  • (Boolean)

    true if current player is leader



197
198
199
# File 'documented/gemstone/group.rb', line 197

def self.leader?
  @@leader.eql?(:self)
end

.maybe_checkArray<GameObj>?

Checks group status only if not already checked.

Returns:

  • (Array<GameObj>, nil)

    members array if check was needed, nil otherwise



168
169
170
# File 'documented/gemstone/group.rb', line 168

def self.maybe_check
  Group.check unless checked?
end

.membersArray<GameObj>

Returns a copy of the current group members. Automatically checks group status if not already checked.

Returns:

  • (Array<GameObj>)

    copy of the members array



80
81
82
83
# File 'documented/gemstone/group.rb', line 80

def self.members
  maybe_check
  @@members.dup
end

.method_missing(method, *args, &block) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Delegates missing methods to the members array. Allows Group to act like an Array in many contexts.



282
283
284
# File 'documented/gemstone/group.rb', line 282

def self.method_missing(method, *args, &block)
  @@members.send(method, *args, &block)
end

.nonmembersArray<GameObj>

Returns all PCs in the room who are not in the group.

Returns:

  • (Array<GameObj>)

    array of PC GameObj instances not in group



175
176
177
# File 'documented/gemstone/group.rb', line 175

def self.nonmembers
  GameObj.pcs.to_a.reject { |pc| ids.include?(pc.id) }
end

.nounsArray<String>

Returns array of all member nouns (names).

Returns:

  • (Array<String>)

    array of member nouns



249
250
251
# File 'documented/gemstone/group.rb', line 249

def self.nouns
  @@members.map(&:noun)
end

.open?Boolean

Checks if the group is open to new members. Automatically verifies group status if not already checked.

Returns:

  • (Boolean)

    true if group status is open



140
141
142
143
# File 'documented/gemstone/group.rb', line 140

def self.open?
  maybe_check
  @@status.eql?(:open)
end

.push(*members) ⇒ Array<GameObj>

Adds one or more members to the group if they're not already included. Does not duplicate members.

Parameters:

  • members (Array<GameObj>)

    one or more GameObj instances to add

Returns:

  • (Array<GameObj>)

    the updated members array



52
53
54
55
56
# File 'documented/gemstone/group.rb', line 52

def self.push(*members)
  members.each do |member|
    @@members.push(member) unless include?(member)
  end
end

.refresh(*members) ⇒ Array<GameObj>

Replaces the entire members list with new members. Used when receiving a complete group listing from the game.

Parameters:

  • members (Array<GameObj>)

    the complete list of group members

Returns:

  • (Array<GameObj>)

    the new members array



72
73
74
# File 'documented/gemstone/group.rb', line 72

def self.refresh(*members)
  @@members = members.dup
end

.statusSymbol

Gets the current group status.

Returns:

  • (Symbol)

    :open or :closed



132
133
134
# File 'documented/gemstone/group.rb', line 132

def self.status()
  @@status
end

.status=(state) ⇒ Symbol

Sets the group status (open or closed).

Parameters:

  • state (Symbol)

    :open or :closed

Returns:

  • (Symbol)

    the status value



125
126
127
# File 'documented/gemstone/group.rb', line 125

def self.status=(state)
  @@status = state
end

.to_sString

String representation of the group members.

Returns:

  • (String)

    string representation of members array



109
110
111
# File 'documented/gemstone/group.rb', line 109

def self.to_s
  @@members.to_s
end