284 lines
7.9 KiB
Go
284 lines
7.9 KiB
Go
package skills
|
|
|
|
import (
|
|
"fmt"
|
|
"sync"
|
|
)
|
|
|
|
// Manager provides high-level management of the skills system
|
|
type Manager struct {
|
|
masterSkillList *MasterSkillList
|
|
mutex sync.RWMutex
|
|
|
|
// Statistics
|
|
totalSkillUps int64
|
|
skillUpsByType map[int32]int64 // Skill type -> count
|
|
skillUpsBySkill map[int32]int64 // Skill ID -> count
|
|
playersWithSkills int64
|
|
}
|
|
|
|
// NewManager creates a new skills manager
|
|
func NewManager() *Manager {
|
|
return &Manager{
|
|
masterSkillList: NewMasterSkillList(),
|
|
skillUpsByType: make(map[int32]int64),
|
|
skillUpsBySkill: make(map[int32]int64),
|
|
}
|
|
}
|
|
|
|
// Initialize loads skills data (placeholder for database loading)
|
|
func (m *Manager) Initialize() error {
|
|
// TODO: Load skills from database when database system is integrated
|
|
// This would typically load all skills from a skills table
|
|
return nil
|
|
}
|
|
|
|
// GetMasterSkillList returns the master skill list
|
|
func (m *Manager) GetMasterSkillList() *MasterSkillList {
|
|
return m.masterSkillList
|
|
}
|
|
|
|
// AddSkillToMaster adds a skill to the master list
|
|
func (m *Manager) AddSkillToMaster(skill *Skill) {
|
|
m.masterSkillList.AddSkill(skill)
|
|
}
|
|
|
|
// GetSkill returns a skill from the master list by ID
|
|
func (m *Manager) GetSkill(skillID int32) *Skill {
|
|
return m.masterSkillList.GetSkill(skillID)
|
|
}
|
|
|
|
// GetSkillByName returns a skill from the master list by name
|
|
func (m *Manager) GetSkillByName(skillName string) *Skill {
|
|
return m.masterSkillList.GetSkillByName(skillName)
|
|
}
|
|
|
|
// CreatePlayerSkillList creates a new player skill list
|
|
func (m *Manager) CreatePlayerSkillList() *PlayerSkillList {
|
|
m.mutex.Lock()
|
|
m.playersWithSkills++
|
|
m.mutex.Unlock()
|
|
|
|
return NewPlayerSkillList()
|
|
}
|
|
|
|
// RecordSkillUp records a skill increase for statistics
|
|
func (m *Manager) RecordSkillUp(skillID int32, skillType int32) {
|
|
m.mutex.Lock()
|
|
defer m.mutex.Unlock()
|
|
|
|
m.totalSkillUps++
|
|
m.skillUpsByType[skillType]++
|
|
m.skillUpsBySkill[skillID]++
|
|
}
|
|
|
|
// GetStatistics returns skill system statistics
|
|
func (m *Manager) GetStatistics() map[string]any {
|
|
m.mutex.RLock()
|
|
defer m.mutex.RUnlock()
|
|
|
|
stats := make(map[string]any)
|
|
stats["total_skill_ups"] = m.totalSkillUps
|
|
stats["players_with_skills"] = m.playersWithSkills
|
|
stats["total_skills_in_master"] = m.masterSkillList.GetSkillCount()
|
|
|
|
// Copy skill type statistics
|
|
typeStats := make(map[int32]int64)
|
|
for skillType, count := range m.skillUpsByType {
|
|
typeStats[skillType] = count
|
|
}
|
|
stats["skill_ups_by_type"] = typeStats
|
|
|
|
// Copy individual skill statistics
|
|
skillStats := make(map[int32]int64)
|
|
for skillID, count := range m.skillUpsBySkill {
|
|
skillStats[skillID] = count
|
|
}
|
|
stats["skill_ups_by_skill"] = skillStats
|
|
|
|
return stats
|
|
}
|
|
|
|
// ResetStatistics resets all statistics
|
|
func (m *Manager) ResetStatistics() {
|
|
m.mutex.Lock()
|
|
defer m.mutex.Unlock()
|
|
|
|
m.totalSkillUps = 0
|
|
m.playersWithSkills = 0
|
|
m.skillUpsByType = make(map[int32]int64)
|
|
m.skillUpsBySkill = make(map[int32]int64)
|
|
}
|
|
|
|
// GetSkillsByType returns all skills of a specific type
|
|
func (m *Manager) GetSkillsByType(skillType int32) []*Skill {
|
|
return m.masterSkillList.GetSkillsByType(skillType)
|
|
}
|
|
|
|
// GetSkillTypeCount returns the number of skills of a specific type
|
|
func (m *Manager) GetSkillTypeCount(skillType int32) int {
|
|
skills := m.GetSkillsByType(skillType)
|
|
return len(skills)
|
|
}
|
|
|
|
// GetSkillUpCount returns the total number of skill ups for a skill
|
|
func (m *Manager) GetSkillUpCount(skillID int32) int64 {
|
|
m.mutex.RLock()
|
|
defer m.mutex.RUnlock()
|
|
|
|
return m.skillUpsBySkill[skillID]
|
|
}
|
|
|
|
// GetSkillTypeUpCount returns the total number of skill ups for a skill type
|
|
func (m *Manager) GetSkillTypeUpCount(skillType int32) int64 {
|
|
m.mutex.RLock()
|
|
defer m.mutex.RUnlock()
|
|
|
|
return m.skillUpsByType[skillType]
|
|
}
|
|
|
|
// ValidateSkillData validates that all skills in the master list are properly configured
|
|
func (m *Manager) ValidateSkillData() []string {
|
|
skills := m.masterSkillList.GetAllSkills()
|
|
issues := make([]string, 0)
|
|
|
|
if len(skills) == 0 {
|
|
issues = append(issues, "No skills configured in master list")
|
|
return issues
|
|
}
|
|
|
|
for skillID, skill := range skills {
|
|
if skill == nil {
|
|
issues = append(issues, fmt.Sprintf("Skill ID %d is nil", skillID))
|
|
continue
|
|
}
|
|
|
|
if skill.SkillID != skillID {
|
|
issues = append(issues, fmt.Sprintf("Skill %d has mismatched ID: %d", skillID, skill.SkillID))
|
|
}
|
|
|
|
if skill.Name.Data == "" {
|
|
issues = append(issues, fmt.Sprintf("Skill %d has empty name", skillID))
|
|
}
|
|
|
|
if skill.SkillType == 0 {
|
|
issues = append(issues, fmt.Sprintf("Skill %d (%s) has no skill type", skillID, skill.Name.Data))
|
|
}
|
|
|
|
if skill.MaxVal < 0 {
|
|
issues = append(issues, fmt.Sprintf("Skill %d (%s) has negative max value: %d", skillID, skill.Name.Data, skill.MaxVal))
|
|
}
|
|
|
|
if skill.CurrentVal < 0 {
|
|
issues = append(issues, fmt.Sprintf("Skill %d (%s) has negative current value: %d", skillID, skill.Name.Data, skill.CurrentVal))
|
|
}
|
|
|
|
if skill.CurrentVal > skill.MaxVal {
|
|
issues = append(issues, fmt.Sprintf("Skill %d (%s) has current value (%d) greater than max value (%d)",
|
|
skillID, skill.Name.Data, skill.CurrentVal, skill.MaxVal))
|
|
}
|
|
}
|
|
|
|
return issues
|
|
}
|
|
|
|
// ProcessCommand handles skill-related commands
|
|
func (m *Manager) ProcessCommand(command string, args []string) (string, error) {
|
|
switch command {
|
|
case "stats":
|
|
return m.handleStatsCommand(args)
|
|
case "validate":
|
|
return m.handleValidateCommand(args)
|
|
case "list":
|
|
return m.handleListCommand(args)
|
|
case "info":
|
|
return m.handleInfoCommand(args)
|
|
default:
|
|
return "", fmt.Errorf("unknown skills command: %s", command)
|
|
}
|
|
}
|
|
|
|
// handleStatsCommand shows skill system statistics
|
|
func (m *Manager) handleStatsCommand(args []string) (string, error) {
|
|
stats := m.GetStatistics()
|
|
|
|
result := "Skills System Statistics:\n"
|
|
result += fmt.Sprintf("Total Skills in Master List: %d\n", stats["total_skills_in_master"])
|
|
result += fmt.Sprintf("Players with Skills: %d\n", stats["players_with_skills"])
|
|
result += fmt.Sprintf("Total Skill Ups: %d\n", stats["total_skill_ups"])
|
|
|
|
return result, nil
|
|
}
|
|
|
|
// handleValidateCommand validates skill data
|
|
func (m *Manager) handleValidateCommand(args []string) (string, error) {
|
|
issues := m.ValidateSkillData()
|
|
|
|
if len(issues) == 0 {
|
|
return "All skill data is valid.", nil
|
|
}
|
|
|
|
result := fmt.Sprintf("Found %d issues with skill data:\n", len(issues))
|
|
for i, issue := range issues {
|
|
result += fmt.Sprintf("%d. %s\n", i+1, issue)
|
|
}
|
|
|
|
return result, nil
|
|
}
|
|
|
|
// handleListCommand lists skills
|
|
func (m *Manager) handleListCommand(args []string) (string, error) {
|
|
skills := m.masterSkillList.GetAllSkills()
|
|
|
|
if len(skills) == 0 {
|
|
return "No skills configured.", nil
|
|
}
|
|
|
|
result := fmt.Sprintf("Skills (%d):\n", len(skills))
|
|
count := 0
|
|
for _, skill := range skills {
|
|
if count >= 20 { // Limit output
|
|
result += "... (and more)\n"
|
|
break
|
|
}
|
|
result += fmt.Sprintf(" %d: %s (Type: %d)\n", skill.SkillID, skill.Name.Data, skill.SkillType)
|
|
count++
|
|
}
|
|
|
|
return result, nil
|
|
}
|
|
|
|
// handleInfoCommand shows information about a specific skill
|
|
func (m *Manager) handleInfoCommand(args []string) (string, error) {
|
|
if len(args) == 0 {
|
|
return "", fmt.Errorf("skill name or ID required")
|
|
}
|
|
|
|
skillName := args[0]
|
|
skill := m.GetSkillByName(skillName)
|
|
|
|
if skill == nil {
|
|
return fmt.Sprintf("Skill '%s' not found.", skillName), nil
|
|
}
|
|
|
|
result := fmt.Sprintf("Skill Information:\n")
|
|
result += fmt.Sprintf("ID: %d\n", skill.SkillID)
|
|
result += fmt.Sprintf("Name: %s\n", skill.Name.Data)
|
|
result += fmt.Sprintf("Short Name: %s\n", skill.ShortName.Data)
|
|
result += fmt.Sprintf("Type: %d\n", skill.SkillType)
|
|
result += fmt.Sprintf("Description: %s\n", skill.Description.Data)
|
|
result += fmt.Sprintf("Max Value: %d\n", skill.MaxVal)
|
|
result += fmt.Sprintf("Current Value: %d\n", skill.CurrentVal)
|
|
result += fmt.Sprintf("Active: %t\n", skill.ActiveSkill)
|
|
|
|
upCount := m.GetSkillUpCount(skill.SkillID)
|
|
result += fmt.Sprintf("Total Skill Ups Recorded: %d\n", upCount)
|
|
|
|
return result, nil
|
|
}
|
|
|
|
// Shutdown gracefully shuts down the manager
|
|
func (m *Manager) Shutdown() {
|
|
// Nothing to clean up currently, but placeholder for future cleanup
|
|
}
|