package achievements import ( "fmt" "time" ) // PlayerList manages achievements for a specific player type PlayerList struct { achievements map[uint32]*Achievement } // PlayerUpdateList manages achievement updates/progress for a specific player type PlayerUpdateList struct { updates map[uint32]*Update } // NewPlayerList creates a new player achievement list func NewPlayerList() *PlayerList { return &PlayerList{ achievements: make(map[uint32]*Achievement), } } // NewPlayerUpdateList creates a new player achievement update list func NewPlayerUpdateList() *PlayerUpdateList { return &PlayerUpdateList{ updates: make(map[uint32]*Update), } } // AddAchievement adds an achievement to the player's list // Returns false if achievement with same ID already exists func (p *PlayerList) AddAchievement(achievement *Achievement) bool { if achievement == nil { return false } if _, exists := p.achievements[achievement.ID]; exists { return false } p.achievements[achievement.ID] = achievement return true } // GetAchievement retrieves an achievement by ID // Returns nil if not found func (p *PlayerList) GetAchievement(id uint32) *Achievement { return p.achievements[id] } // GetAllAchievements returns all player achievements func (p *PlayerList) GetAllAchievements() map[uint32]*Achievement { result := make(map[uint32]*Achievement, len(p.achievements)) for id, achievement := range p.achievements { result[id] = achievement } return result } // RemoveAchievement removes an achievement from the player's list // Returns true if achievement was found and removed func (p *PlayerList) RemoveAchievement(id uint32) bool { if _, exists := p.achievements[id]; !exists { return false } delete(p.achievements, id) return true } // HasAchievement checks if player has a specific achievement func (p *PlayerList) HasAchievement(id uint32) bool { _, exists := p.achievements[id] return exists } // Clear removes all achievements from the player's list func (p *PlayerList) Clear() { p.achievements = make(map[uint32]*Achievement) } // Size returns the number of achievements in the player's list func (p *PlayerList) Size() int { return len(p.achievements) } // GetAchievementsByCategory returns player achievements filtered by category func (p *PlayerList) GetAchievementsByCategory(category string) []*Achievement { var result []*Achievement for _, achievement := range p.achievements { if achievement.Category == category { result = append(result, achievement) } } return result } // AddUpdate adds an achievement update to the player's list // Returns false if update with same ID already exists func (p *PlayerUpdateList) AddUpdate(update *Update) bool { if update == nil { return false } if _, exists := p.updates[update.ID]; exists { return false } p.updates[update.ID] = update return true } // GetUpdate retrieves an achievement update by ID // Returns nil if not found func (p *PlayerUpdateList) GetUpdate(id uint32) *Update { return p.updates[id] } // GetAllUpdates returns all player achievement updates func (p *PlayerUpdateList) GetAllUpdates() map[uint32]*Update { result := make(map[uint32]*Update, len(p.updates)) for id, update := range p.updates { result[id] = update } return result } // UpdateProgress updates or creates achievement progress func (p *PlayerUpdateList) UpdateProgress(achievementID uint32, itemUpdate uint32) { update := p.updates[achievementID] if update == nil { update = NewUpdate() update.ID = achievementID p.updates[achievementID] = update } // Add or update the progress item found := false for i := range update.UpdateItems { if update.UpdateItems[i].AchievementID == achievementID { update.UpdateItems[i].ItemUpdate = itemUpdate found = true break } } if !found { update.AddUpdateItem(UpdateItem{ AchievementID: achievementID, ItemUpdate: itemUpdate, }) } } // CompleteAchievement marks an achievement as completed func (p *PlayerUpdateList) CompleteAchievement(achievementID uint32) { update := p.updates[achievementID] if update == nil { update = NewUpdate() update.ID = achievementID p.updates[achievementID] = update } update.CompletedDate = time.Now() } // IsCompleted checks if an achievement is completed func (p *PlayerUpdateList) IsCompleted(achievementID uint32) bool { update := p.updates[achievementID] return update != nil && !update.CompletedDate.IsZero() } // GetCompletedDate returns the completion date for an achievement // Returns zero time if not completed func (p *PlayerUpdateList) GetCompletedDate(achievementID uint32) time.Time { update := p.updates[achievementID] if update == nil { return time.Time{} } return update.CompletedDate } // GetProgress returns the current progress for an achievement // Returns 0 if no progress found func (p *PlayerUpdateList) GetProgress(achievementID uint32) uint32 { update := p.updates[achievementID] if update == nil || len(update.UpdateItems) == 0 { return 0 } // Return the first matching update item's progress for _, item := range update.UpdateItems { if item.AchievementID == achievementID { return item.ItemUpdate } } return 0 } // RemoveUpdate removes an achievement update from the player's list // Returns true if update was found and removed func (p *PlayerUpdateList) RemoveUpdate(id uint32) bool { if _, exists := p.updates[id]; !exists { return false } delete(p.updates, id) return true } // Clear removes all updates from the player's list func (p *PlayerUpdateList) Clear() { p.updates = make(map[uint32]*Update) } // Size returns the number of updates in the player's list func (p *PlayerUpdateList) Size() int { return len(p.updates) } // GetCompletedAchievements returns all completed achievement IDs func (p *PlayerUpdateList) GetCompletedAchievements() []uint32 { var completed []uint32 for id, update := range p.updates { if !update.CompletedDate.IsZero() { completed = append(completed, id) } } return completed } // GetInProgressAchievements returns all in-progress achievement IDs func (p *PlayerUpdateList) GetInProgressAchievements() []uint32 { var inProgress []uint32 for id, update := range p.updates { if update.CompletedDate.IsZero() && len(update.UpdateItems) > 0 { inProgress = append(inProgress, id) } } return inProgress } // PlayerManager combines achievement list and update list for a player type PlayerManager struct { Achievements *PlayerList Updates *PlayerUpdateList } // NewPlayerManager creates a new player manager func NewPlayerManager() *PlayerManager { return &PlayerManager{ Achievements: NewPlayerList(), Updates: NewPlayerUpdateList(), } } // CheckRequirements validates if player meets achievement requirements // This is a basic implementation - extend as needed for specific game logic func (pm *PlayerManager) CheckRequirements(achievement *Achievement) (bool, error) { if achievement == nil { return false, fmt.Errorf("achievement cannot be nil") } // Basic implementation - check if we have progress >= required quantity progress := pm.Updates.GetProgress(achievement.ID) return progress >= achievement.QtyRequired, nil } // GetCompletionStatus returns completion percentage for an achievement func (pm *PlayerManager) GetCompletionStatus(achievement *Achievement) float64 { if achievement == nil || achievement.QtyRequired == 0 { return 0.0 } progress := pm.Updates.GetProgress(achievement.ID) if progress >= achievement.QtyRequired { return 100.0 } return (float64(progress) / float64(achievement.QtyRequired)) * 100.0 }