Members Class
The Members class is the core data structure for individual raid members within a Loot Profile in the Spectrum Federation addon. Each Loot Profile contains a dictionary of Member instances that represent the current state of each member's loot profile.
Purpose and Role: Member instances serve as a computed, queryable representation of member data that is generated from the profile's Loot Logs. The logs are the single source of truth, recording all point awards and gear assignments. Member instances are rebuilt from these logs using the UpdateFromLootLog() method, and then used to drive UI displays showing point balances, armor slot states, and other member information. This log-driven architecture enables easy syncing between multiple users editing the same profile - logs can be synchronized across users while each user rebuilds their local member instances from the shared log data. This ensures data consistency while providing efficient access for UI rendering.
The class uses Lua's metatable-based OOP pattern to provide instance methods for point management, equipment tracking, and role administration.
Overview
Each member within a loot profile is represented by a Member instance that tracks:
- Identity: Character name and realm
- Role: Admin or member permissions
- Point Balance: Available loot points (can be positive or negative)
- Armor Slots: 16 equipment slots, each can be used once per member
Data Flow
Member instances follow a log-driven architecture:
- Profile Loot Logs are the primary data source - All point awards and gear assignments are recorded in logs
- Member instances are generated from logs - The
UpdateFromLootLog()method rebuilds member state from log history - Member objects drive the UI - The UI displays point balances and armor slot states from member instances
This ensures the logs remain the single source of truth, while member instances provide an efficient, queryable representation for UI rendering.
Point System
The Members class implements a one-point-per-slot system:
- Each member has a point balance that can increase or decrease
- Each of the 16 armor slots can only be "used" once per member
- When a slot is marked as
true, the member has spent their ONE point for that specific armor piece - When a slot is
false, the member has not yet used their point for that armor piece - Point debt is allowed: Members can go into negative point balances for edge cases (e.g., accidental gear awards)
Class Structure
Constants
Member Roles
Roles can be accessed via:
SF.MemberRoles.ADMIN- Admin permissionsSF.MemberRoles.MEMBER- Standard member permissions
Armor Slots
SF.ArmorSlots = {
HEAD = "Head",
SHOULDER = "Shoulder",
NECK = "Neck",
BACK = "Back",
CHEST = "Chest",
BRACERS = "Bracers",
WEAPON = "Weapon",
OFFHAND = "OffHand",
HANDS = "Hands",
BELT = "Belt",
PANTS = "Pants",
BOOTS = "Boots",
RING1 = "Ring1",
RING2 = "Ring2",
TRINKET1 = "Trinket1",
TRINKET2 = "Trinket2"
}
Access via:
SF.ArmorSlots.HEAD- "Head"SF.ArmorSlots.WEAPON- "Weapon"- etc.
Properties
Each Member instance has the following properties:
| Property | Type | Description |
|---|---|---|
identifier |
string | Full character identifier (e.g., "Shadowbane-Garona") |
role |
string | Member role ("admin" or "member") |
class |
string|nil | WoW class name (e.g., "WARRIOR") or nil if not set |
pointBalance |
number | Current loot points (can be negative) |
armor |
table | Dictionary of 16 armor slots (boolean values) |
Creating Members
Constructor
The Members class uses dot notation for the constructor (factory function pattern):
Parameters:
identifier(string, required) - Full character identifier in "Name-Realm" formatrole(string, optional) - Member role, defaults to"member"class(string, optional) - WoW class name (e.g., "WARRIOR", "PALADIN"), must matchSF.WOW_CLASSESkeys
Example:
-- Create a standard member
local member = SF.Member.new("Shadowbane-Garona")
-- Create an admin
local admin = SF.Member.new("Guildmaster-Garona", SF.MemberRoles.ADMIN)
-- Create a member with class information
local warrior = SF.Member.new("Tanky-Garona", SF.MemberRoles.MEMBER, "WARRIOR")
-- Create an admin with class
local paladinAdmin = SF.Member.new("Healz-Garona", SF.MemberRoles.ADMIN, "PALADIN")
Initial State
New members are created with:
- Point balance:
0 - All armor slots:
false(unused) - Role:
"member"(unless specified) - Class:
nil(unless specified and valid)
Class Validation: If a class parameter is provided but doesn't match a key in SF.WOW_CLASSES, the member's class will be set to nil and a warning will be logged (if debug enabled).
Instance Methods
All instance methods use colon notation (:) which automatically passes self:
Identity Methods
GetFullIdentifier()
Returns the member's full character identifier in "Name-Realm" format.
Use case: Unique keys for member dictionaries, displaying character names.
GetClass()
Returns the member's WoW class name or nil if not set.
Use case: Determine member's class for UI display, validation, or filtering.
getClass()
Lowercase alias for GetClass() for convenience.
Use case: Same as GetClass(). Use whichever naming convention fits your code style.
GetClassColor()
Returns the RGB color table for the member's class, or nil if class is not set.
local color = member:GetClassColor()
if color then
-- color.r, color.g, color.b are values from 0-1
print(color.r, color.g, color.b)
end
Returns: {r = 0.78, g = 0.61, b = 0.43} (example for Warrior) or nil
Use case: Color-coding member names in UI, setting frame background colors.
GetClassColorCode()
Returns the hex color code string for the member's class in WoW color format.
local colorCode = member:GetClassColorCode()
-- Returns: "|cffC79C6E" (Warrior) or "|cffffffff" (white, if class not set)
-- Use in UI text
local coloredName = colorCode .. member:GetFullIdentifier() .. "|r"
print(coloredName) -- Displays name in class color
Returns: string - Hex color code in WoW format (e.g., "|cffC79C6E") or white ("|cffffffff") if class not set
Use case: Creating color-coded text strings for UI display, chat messages, or tooltips. Automatically handles cases where class is not set by returning white color.
GetClassTexture()
Returns the texture file path for the member's class icon, or nil if class is not set.
local texturePath = member:GetClassTexture()
-- Returns: "Interface\\Icons\\ClassIcon_Warrior" or nil
if texturePath then
iconFrame:SetTexture(texturePath)
end
Use case: Displaying class icons next to member names in UI.
Note: See WoW Classes Documentation for complete information about class colors and textures.
GetPointBalance()
Returns the member's current point balance.
Use case: Displaying point balance in UI, checking if member has points before operations.
GetArmorStatuses()
Returns the entire armor dictionary with all 16 slots and their boolean values.
local armorDict = member:GetArmorStatuses()
-- Returns: { Head = false, Shoulder = true, ... }
-- Example: Check specific slot
if armorDict[SF.ArmorSlots.HEAD] then
-- Head slot is used
end
Use case: Displaying armor slot status in UI, exporting member data, checking multiple slots.
IsAdmin()
Checks if the member has admin role.
Use case: Permission checks, UI access control, displaying admin badges.
Role Management
SetRole(newRole)
Updates the member's role with validation and admin permission checks.
Parameters:
newRole(string) - New role (SF.MemberRoles.ADMINorSF.MemberRoles.MEMBER)
Returns: boolean - true if successful, false otherwise
Features:
- Validates role against
MEMBER_ROLESconstants - Logs the change
- Enforces admin permissions
Point Management
IncrementPoints()
Increases the member's point balance by 1.
Use cases:
- Awarding points for raid participation
- Returning points when removing armor slot usage
- Manual point adjustments
DecrementPoints()
Decreases the member's point balance by 1.
Features:
- Allows negative balances (point debt)
- Logs the change
- No floor restriction
Use cases:
- Spending points on gear
- Manual point deductions
Equipment Management
ToggleEquipment(slot)
Toggles an armor slot's usage state. This is the primary method for UI interactions.
Parameters:
slot(string) - Armor slot name (useSF.ArmorSlotsconstants)
Returns: boolean - true if successful, false if invalid slot
Behavior:
When slot is false (not used) → Toggle to true (used):
- Calls
DecrementPoints() - Marks slot as
true - Logs the change
When slot is true (used) → Toggle to false (not used):
- Calls
IncrementPoints() - Marks slot as
false - Logs the change
Example UI integration:
-- Button click handler for a specific armor slot button
local slotName = SF.ArmorSlots.HEAD -- Use ARMOR_SLOTS constant
local member = GetCurrentMember()
local success = member:ToggleEquipment(slotName)
if success then
-- Update button visual state
UpdateButtonAppearance(slotName, member.armor[slotName])
end
UpdateFromLootLog()
Rebuilds the member's point balance and armor states from loot logs. Used to synchronize member state with historical log data.
Process:
- Filters loot logs for this specific member
- Updates each armor slot based on most recent log entry
- Calculates point balance from point log entries
Use cases:
- Initial profile loading
- Recalculating after log imports
- Fixing desynced member states
Usage Examples
Creating and Managing a Member
-- Create a new member
local member = SF.Member.new("Shadowbane-Garona")
-- Award initial points
member:IncrementPoints()
member:IncrementPoints()
member:IncrementPoints()
-- Point balance: 3
-- Member receives head piece
member:ToggleEquipment(SF.ArmorSlots.HEAD)
-- Point balance: 2, Head slot: true
-- Member receives shoulder piece
member:ToggleEquipment(SF.ArmorSlots.SHOULDER)
-- Point balance: 1, Shoulder slot: true
-- Accidentally award chest piece when they have no points
-- First, decrement point to get to 0
member:DecrementPoints()
-- Point balance: 0
member:ToggleEquipment(SF.ArmorSlots.CHEST)
-- Point balance: -1 (point debt), Chest slot: true
-- Remove incorrect chest award
member:ToggleEquipment(SF.ArmorSlots.CHEST)
-- Point balance: 0, Chest slot: false
File Location
Source: SpectrumFederation/modules/LootHelper/Members.lua
TOC Load Order: Loaded early in the LootHelper module chain, before profile management.