eq2go/internal/world/title_manager.go
2025-08-07 11:21:56 -05:00

230 lines
6.8 KiB
Go

package world
import (
"fmt"
"sync"
"eq2emu/internal/database"
"eq2emu/internal/titles"
)
// 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]any {
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]any{
"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")
}