213 lines
5.7 KiB
Go
213 lines
5.7 KiB
Go
package groups
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"eq2emu/internal/common"
|
|
)
|
|
|
|
// MasterList manages all groups using generic MasterList pattern
|
|
type MasterList struct {
|
|
*common.MasterList[int32, *Group]
|
|
}
|
|
|
|
// NewMasterList creates a new master list for groups
|
|
func NewMasterList() *MasterList {
|
|
return &MasterList{
|
|
MasterList: common.NewMasterList[int32, *Group](),
|
|
}
|
|
}
|
|
|
|
// AddGroup adds a group to the master list
|
|
func (ml *MasterList) AddGroup(group *Group) bool {
|
|
return ml.MasterList.Add(group)
|
|
}
|
|
|
|
// GetGroup retrieves a group by ID
|
|
func (ml *MasterList) GetGroup(groupID int32) *Group {
|
|
return ml.MasterList.Get(groupID)
|
|
}
|
|
|
|
// RemoveGroup removes a group by ID
|
|
func (ml *MasterList) RemoveGroup(groupID int32) bool {
|
|
return ml.MasterList.Remove(groupID)
|
|
}
|
|
|
|
// GetAllGroups returns all groups
|
|
func (ml *MasterList) GetAllGroups() []*Group {
|
|
return ml.MasterList.GetAllSlice()
|
|
}
|
|
|
|
// GetGroupsByFilter returns groups matching the filter function
|
|
func (ml *MasterList) GetGroupsByFilter(filter func(*Group) bool) []*Group {
|
|
return ml.MasterList.Filter(filter)
|
|
}
|
|
|
|
// GetActiveGroups returns all non-disbanded groups
|
|
func (ml *MasterList) GetActiveGroups() []*Group {
|
|
return ml.GetGroupsByFilter(func(group *Group) bool {
|
|
return !group.IsDisbanded()
|
|
})
|
|
}
|
|
|
|
// GetGroupsByZone returns groups with members in the specified zone
|
|
func (ml *MasterList) GetGroupsByZone(zoneID int32) []*Group {
|
|
return ml.GetGroupsByFilter(func(group *Group) bool {
|
|
members := group.GetMembers()
|
|
for _, member := range members {
|
|
if member.ZoneID == zoneID {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
})
|
|
}
|
|
|
|
// GetGroupsBySize returns groups of the specified size
|
|
func (ml *MasterList) GetGroupsBySize(size int32) []*Group {
|
|
return ml.GetGroupsByFilter(func(group *Group) bool {
|
|
return group.GetSize() == size
|
|
})
|
|
}
|
|
|
|
// GetRaidGroups returns all groups that are part of raids
|
|
func (ml *MasterList) GetRaidGroups() []*Group {
|
|
return ml.GetGroupsByFilter(func(group *Group) bool {
|
|
return group.IsGroupRaid()
|
|
})
|
|
}
|
|
|
|
// GetSoloGroups returns all groups with only one member
|
|
func (ml *MasterList) GetSoloGroups() []*Group {
|
|
return ml.GetGroupsBySize(1)
|
|
}
|
|
|
|
// GetFullGroups returns all groups at maximum capacity
|
|
func (ml *MasterList) GetFullGroups() []*Group {
|
|
return ml.GetGroupsBySize(MAX_GROUP_SIZE)
|
|
}
|
|
|
|
// GetGroupsByLeader returns groups led by entities with the specified name
|
|
func (ml *MasterList) GetGroupsByLeader(leaderName string) []*Group {
|
|
return ml.GetGroupsByFilter(func(group *Group) bool {
|
|
return group.GetLeaderName() == leaderName
|
|
})
|
|
}
|
|
|
|
// GetGroupsByMember returns groups containing a member with the specified name
|
|
func (ml *MasterList) GetGroupsByMember(memberName string) []*Group {
|
|
return ml.GetGroupsByFilter(func(group *Group) bool {
|
|
members := group.GetMembers()
|
|
for _, member := range members {
|
|
if member.Name == memberName {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
})
|
|
}
|
|
|
|
// GetGroupStatistics returns statistics about the groups in the master list
|
|
func (ml *MasterList) GetGroupStatistics() *GroupMasterListStats {
|
|
allGroups := ml.GetAllGroups()
|
|
activeGroups := ml.GetActiveGroups()
|
|
raidGroups := ml.GetRaidGroups()
|
|
|
|
var totalMembers int32
|
|
var totalRaidMembers int32
|
|
|
|
for _, group := range activeGroups {
|
|
totalMembers += group.GetSize()
|
|
if group.IsGroupRaid() {
|
|
totalRaidMembers += group.GetSize()
|
|
}
|
|
}
|
|
|
|
var averageGroupSize float64
|
|
if len(activeGroups) > 0 {
|
|
averageGroupSize = float64(totalMembers) / float64(len(activeGroups))
|
|
}
|
|
|
|
return &GroupMasterListStats{
|
|
TotalGroups: int32(len(allGroups)),
|
|
ActiveGroups: int32(len(activeGroups)),
|
|
RaidGroups: int32(len(raidGroups)),
|
|
TotalMembers: totalMembers,
|
|
TotalRaidMembers: totalRaidMembers,
|
|
AverageGroupSize: averageGroupSize,
|
|
SoloGroups: int32(len(ml.GetSoloGroups())),
|
|
FullGroups: int32(len(ml.GetFullGroups())),
|
|
}
|
|
}
|
|
|
|
// GroupMasterListStats holds statistics about the groups master list
|
|
type GroupMasterListStats struct {
|
|
TotalGroups int32 `json:"total_groups"`
|
|
ActiveGroups int32 `json:"active_groups"`
|
|
RaidGroups int32 `json:"raid_groups"`
|
|
TotalMembers int32 `json:"total_members"`
|
|
TotalRaidMembers int32 `json:"total_raid_members"`
|
|
AverageGroupSize float64 `json:"average_group_size"`
|
|
SoloGroups int32 `json:"solo_groups"`
|
|
FullGroups int32 `json:"full_groups"`
|
|
}
|
|
|
|
// Cleanup removes disbanded groups from the master list
|
|
func (ml *MasterList) Cleanup() int32 {
|
|
disbandedGroups := ml.GetGroupsByFilter(func(group *Group) bool {
|
|
return group.IsDisbanded()
|
|
})
|
|
|
|
removed := int32(0)
|
|
for _, group := range disbandedGroups {
|
|
if ml.RemoveGroup(group.GetID()) {
|
|
removed++
|
|
}
|
|
}
|
|
|
|
return removed
|
|
}
|
|
|
|
// ValidateAll validates all groups in the master list
|
|
func (ml *MasterList) ValidateAll() []error {
|
|
var errors []error
|
|
|
|
allGroups := ml.GetAllGroups()
|
|
for _, group := range allGroups {
|
|
// Check for basic validity
|
|
if group.GetID() <= 0 {
|
|
errors = append(errors, fmt.Errorf("group %d has invalid ID", group.GetID()))
|
|
}
|
|
|
|
if group.GetSize() == 0 && !group.IsDisbanded() {
|
|
errors = append(errors, fmt.Errorf("group %d is empty but not disbanded", group.GetID()))
|
|
}
|
|
|
|
if group.GetSize() > MAX_GROUP_SIZE {
|
|
errors = append(errors, fmt.Errorf("group %d exceeds maximum size (%d > %d)",
|
|
group.GetID(), group.GetSize(), MAX_GROUP_SIZE))
|
|
}
|
|
|
|
// Check for leader
|
|
members := group.GetMembers()
|
|
hasLeader := false
|
|
leaderCount := 0
|
|
|
|
for _, member := range members {
|
|
if member.Leader {
|
|
hasLeader = true
|
|
leaderCount++
|
|
}
|
|
}
|
|
|
|
if !hasLeader && !group.IsDisbanded() {
|
|
errors = append(errors, fmt.Errorf("group %d has no leader", group.GetID()))
|
|
}
|
|
|
|
if leaderCount > 1 {
|
|
errors = append(errors, fmt.Errorf("group %d has multiple leaders (%d)", group.GetID(), leaderCount))
|
|
}
|
|
}
|
|
|
|
return errors
|
|
} |