package world import ( "fmt" "sync" "eq2emu/internal/titles" "eq2emu/internal/database" ) // TitleManager manages titles for the world server type TitleManager struct { titleManager *titles.TitleManager integrationMgr *titles.IntegrationManager database *database.Database mutex sync.RWMutex } // NewTitleManager creates a new title manager for the world server func NewTitleManager(db *database.Database) *TitleManager { titleMgr := titles.NewTitleManager() integrationMgr := titles.NewIntegrationManager(titleMgr) return &TitleManager{ titleManager: titleMgr, integrationMgr: integrationMgr, database: db, } } // LoadTitles loads all titles from database func (tm *TitleManager) LoadTitles() error { fmt.Println("Loading master title list...") pool := tm.database.GetPool() if pool == nil { return fmt.Errorf("database pool is nil") } // TODO: Implement title loading from database when database functions are available // For now, create some default titles for testing err := tm.createDefaultTitles() if err != nil { return fmt.Errorf("failed to create default titles: %w", err) } fmt.Printf("Loaded %d titles\n", tm.titleManager.GetMasterList().GetTitleCount()) return nil } // createDefaultTitles creates some default titles for testing func (tm *TitleManager) createDefaultTitles() error { masterList := tm.titleManager.GetMasterList() // Achievement-based titles achievementTitles := map[string]*titles.Title{ "First Blood": { ID: 1, Name: "Killer", Category: titles.CategoryCombat, Rarity: titles.TitleRarityCommon, Position: titles.TitlePositionPrefix, Description: "Granted for first NPC kill", }, "Veteran Hunter": { ID: 2, Name: "Veteran", Category: titles.CategoryCombat, Rarity: titles.TitleRarityUncommon, Position: titles.TitlePositionPrefix, Description: "Granted for killing high-level NPCs", }, "Boss Slayer": { ID: 10, Name: "Boss Slayer", Category: titles.CategoryCombat, Rarity: titles.TitleRarityRare, Position: titles.TitlePositionSuffix, Description: "Granted for killing boss NPCs", }, "Quest Master": { ID: 20, Name: "the Questor", Category: titles.CategoryQuest, Rarity: titles.TitleRarityCommon, Position: titles.TitlePositionSuffix, Description: "Granted for completing quests", }, "Hero's Journey": { ID: 21, Name: "Hero", Category: titles.CategoryQuest, Rarity: titles.TitleRarityLegendary, Position: titles.TitlePositionPrefix, Description: "Granted for completing main story quest", }, "Growing Strong": { ID: 30, Name: "the Promising", Category: "Progression", Rarity: titles.TitleRarityCommon, Position: titles.TitlePositionSuffix, Description: "Granted for reaching level 10", }, "Seasoned Adventurer": { ID: 31, Name: "the Seasoned", Category: "Progression", Rarity: titles.TitleRarityUncommon, Position: titles.TitlePositionSuffix, Description: "Granted for reaching level 20", }, "Veteran": { ID: 32, Name: "Veteran", Category: "Progression", Rarity: titles.TitleRarityRare, Position: titles.TitlePositionPrefix, Description: "Granted for reaching level 50", }, "Master Adventurer": { ID: 33, Name: "Master", Category: "Progression", Rarity: titles.TitleRarityEpic, Position: titles.TitlePositionPrefix, Description: "Granted for reaching level 90", }, "Level Up!": { ID: 34, Name: "the Accomplished", Category: "Progression", Rarity: titles.TitleRarityCommon, Position: titles.TitlePositionSuffix, Description: "Granted for leveling up", }, } // Add titles to master list for name, title := range achievementTitles { err := masterList.AddTitle(title) if err != nil { fmt.Printf("Warning: Failed to add title '%s': %v\n", name, err) } } return nil } // GrantTitle grants a title to a player func (tm *TitleManager) GrantTitle(playerID, titleID int32, sourceAchievementID, sourceQuestID uint32) error { return tm.titleManager.GrantTitle(playerID, titleID, sourceAchievementID, sourceQuestID) } // GetPlayerTitles gets a player's title collection func (tm *TitleManager) GetPlayerTitles(playerID int32) *titles.PlayerTitlesList { return tm.titleManager.GetPlayerTitles(playerID) } // GetPlayerFormattedName returns a player's name with active titles func (tm *TitleManager) GetPlayerFormattedName(playerID int32, playerName string) string { return tm.titleManager.GetPlayerFormattedName(playerID, playerName) } // GetIntegrationManager returns the integration manager func (tm *TitleManager) GetIntegrationManager() *titles.IntegrationManager { return tm.integrationMgr } // SetupAchievementIntegration sets up achievement-to-title integration func (tm *TitleManager) SetupAchievementIntegration() { // Setup callback to handle achievement completions tm.integrationMgr.AddTitleEarnedCallback(func(playerID, titleID int32, source string) { fmt.Printf("Player %d earned title %d from %s\n", playerID, titleID, source) // TODO: Send title granted packet to client // TODO: Send title list update to client // TODO: Broadcast title earned message if appropriate }) fmt.Println("Achievement-to-title integration setup complete") } // ProcessAchievementCompletion processes an achievement completion and grants associated titles func (tm *TitleManager) ProcessAchievementCompletion(playerID int32, achievementID uint32) error { // Use the title manager's built-in method err := tm.titleManager.ProcessAchievementCompletion(playerID, achievementID) if err != nil { return fmt.Errorf("failed to process achievement completion: %w", err) } // Notify integration system tm.integrationMgr.NotifyTitleEarned(playerID, 0, "achievement") // Title ID is handled internally fmt.Printf("Processed achievement completion %d for player %d\n", achievementID, playerID) return nil } // GetStatistics returns title system statistics func (tm *TitleManager) GetStatistics() map[string]interface{} { tm.mutex.RLock() defer tm.mutex.RUnlock() // Get statistics from the underlying title manager titleManagerStats := tm.titleManager.GetStatistics() // Combine with our own statistics stats := map[string]interface{}{ "total_titles": tm.titleManager.GetMasterList().GetTitleCount(), } // Add statistics from the title manager for key, value := range titleManagerStats { stats[key] = value } return stats } // Shutdown gracefully shuts down the title manager func (tm *TitleManager) Shutdown() { fmt.Println("Shutting down title manager...") // TODO: Save player title data to database // TODO: Cleanup any background processes fmt.Println("Title manager shutdown complete") }