203 lines
5.0 KiB
Go
203 lines
5.0 KiB
Go
package skills
|
|
|
|
import (
|
|
"sync"
|
|
)
|
|
|
|
// MasterSkillList manages the master list of all available skills
|
|
type MasterSkillList struct {
|
|
skills map[int32]*Skill // All skills by ID
|
|
populatePackets map[int16][]byte // Cached packets by version
|
|
mutex sync.RWMutex // Thread safety
|
|
}
|
|
|
|
// NewMasterSkillList creates a new master skill list
|
|
func NewMasterSkillList() *MasterSkillList {
|
|
return &MasterSkillList{
|
|
skills: make(map[int32]*Skill),
|
|
populatePackets: make(map[int16][]byte),
|
|
}
|
|
}
|
|
|
|
// AddSkill adds a skill to the master list
|
|
func (msl *MasterSkillList) AddSkill(skill *Skill) {
|
|
if skill == nil {
|
|
return
|
|
}
|
|
|
|
msl.mutex.Lock()
|
|
defer msl.mutex.Unlock()
|
|
|
|
msl.skills[skill.SkillID] = skill
|
|
|
|
// Clear cached packets when skills change
|
|
msl.populatePackets = make(map[int16][]byte)
|
|
}
|
|
|
|
// GetSkillCount returns the total number of skills
|
|
func (msl *MasterSkillList) GetSkillCount() int16 {
|
|
msl.mutex.RLock()
|
|
defer msl.mutex.RUnlock()
|
|
|
|
return int16(len(msl.skills))
|
|
}
|
|
|
|
// GetAllSkills returns a copy of all skills
|
|
func (msl *MasterSkillList) GetAllSkills() map[int32]*Skill {
|
|
msl.mutex.RLock()
|
|
defer msl.mutex.RUnlock()
|
|
|
|
// Return a copy to prevent external modification
|
|
skills := make(map[int32]*Skill)
|
|
for id, skill := range msl.skills {
|
|
skills[id] = skill
|
|
}
|
|
|
|
return skills
|
|
}
|
|
|
|
// GetSkill returns a skill by ID
|
|
func (msl *MasterSkillList) GetSkill(skillID int32) *Skill {
|
|
msl.mutex.RLock()
|
|
defer msl.mutex.RUnlock()
|
|
|
|
if skill, exists := msl.skills[skillID]; exists {
|
|
return skill
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// GetSkillByName returns a skill by name (case-insensitive)
|
|
func (msl *MasterSkillList) GetSkillByName(skillName string) *Skill {
|
|
msl.mutex.RLock()
|
|
defer msl.mutex.RUnlock()
|
|
|
|
// Convert to lowercase for comparison
|
|
lowerName := toLower(skillName)
|
|
|
|
for _, skill := range msl.skills {
|
|
if toLower(skill.Name.Data) == lowerName {
|
|
return skill
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// GetPopulateSkillsPacket builds a packet containing all skills for a client version
|
|
func (msl *MasterSkillList) GetPopulateSkillsPacket(version int16) ([]byte, error) {
|
|
msl.mutex.Lock()
|
|
defer msl.mutex.Unlock()
|
|
|
|
// Check if we have a cached packet for this version
|
|
if packet, exists := msl.populatePackets[version]; exists {
|
|
// Return a copy of the cached packet
|
|
result := make([]byte, len(packet))
|
|
copy(result, packet)
|
|
return result, nil
|
|
}
|
|
|
|
// Build the packet - this is a placeholder implementation
|
|
// In the full implementation, this would use the PacketStruct system
|
|
// to build a proper WS_SkillMap packet for the given version
|
|
|
|
packet := msl.buildSkillMapPacket(version)
|
|
|
|
// Cache the packet
|
|
msl.populatePackets[version] = packet
|
|
|
|
// Return a copy
|
|
result := make([]byte, len(packet))
|
|
copy(result, packet)
|
|
return result, nil
|
|
}
|
|
|
|
// buildSkillMapPacket builds a WS_SkillMap packet
|
|
func (msl *MasterSkillList) buildSkillMapPacket(version int16) []byte {
|
|
// This is a placeholder implementation
|
|
// In a real implementation, this would use the PacketStruct system:
|
|
// packet := configReader.getStruct("WS_SkillMap", version)
|
|
// packet.setArrayLengthByName("skill_count", len(msl.skills))
|
|
// for i, skill := range msl.skills {
|
|
// packet.setArrayDataByName("skill_id", skill.SkillID, i)
|
|
// packet.setArrayDataByName("short_name", &skill.ShortName, i)
|
|
// packet.setArrayDataByName("name", &skill.Name, i)
|
|
// packet.setArrayDataByName("description", &skill.Description, i)
|
|
// }
|
|
// return packet.serialize()
|
|
|
|
// For now, return an empty packet
|
|
return make([]byte, 0)
|
|
}
|
|
|
|
// RemoveSkill removes a skill from the master list
|
|
func (msl *MasterSkillList) RemoveSkill(skillID int32) {
|
|
msl.mutex.Lock()
|
|
defer msl.mutex.Unlock()
|
|
|
|
delete(msl.skills, skillID)
|
|
|
|
// Clear cached packets when skills change
|
|
msl.populatePackets = make(map[int16][]byte)
|
|
}
|
|
|
|
// ClearSkills removes all skills from the master list
|
|
func (msl *MasterSkillList) ClearSkills() {
|
|
msl.mutex.Lock()
|
|
defer msl.mutex.Unlock()
|
|
|
|
msl.skills = make(map[int32]*Skill)
|
|
msl.populatePackets = make(map[int16][]byte)
|
|
}
|
|
|
|
// GetSkillsByType returns all skills of a specific type
|
|
func (msl *MasterSkillList) GetSkillsByType(skillType int32) []*Skill {
|
|
msl.mutex.RLock()
|
|
defer msl.mutex.RUnlock()
|
|
|
|
var skills []*Skill
|
|
for _, skill := range msl.skills {
|
|
if skill.SkillType == skillType {
|
|
skills = append(skills, skill)
|
|
}
|
|
}
|
|
|
|
return skills
|
|
}
|
|
|
|
// HasSkill checks if a skill exists in the master list
|
|
func (msl *MasterSkillList) HasSkill(skillID int32) bool {
|
|
msl.mutex.RLock()
|
|
defer msl.mutex.RUnlock()
|
|
|
|
_, exists := msl.skills[skillID]
|
|
return exists
|
|
}
|
|
|
|
// GetSkillIDs returns all skill IDs
|
|
func (msl *MasterSkillList) GetSkillIDs() []int32 {
|
|
msl.mutex.RLock()
|
|
defer msl.mutex.RUnlock()
|
|
|
|
ids := make([]int32, 0, len(msl.skills))
|
|
for id := range msl.skills {
|
|
ids = append(ids, id)
|
|
}
|
|
|
|
return ids
|
|
}
|
|
|
|
// toLower converts a string to lowercase (simple implementation)
|
|
func toLower(s string) string {
|
|
result := make([]byte, len(s))
|
|
for i, c := range []byte(s) {
|
|
if c >= 'A' && c <= 'Z' {
|
|
result[i] = c + 32
|
|
} else {
|
|
result[i] = c
|
|
}
|
|
}
|
|
return string(result)
|
|
}
|