eq2go/internal/skills/integration.go

253 lines
7.0 KiB
Go

package skills
import "fmt"
// SkillAware interface for entities that have skills
type SkillAware interface {
GetSkillList() *PlayerSkillList
GetSkillByName(name string) *Skill
GetSkill(skillID int32) *Skill
HasSkill(skillID int32) bool
IncreaseSkill(skillName string, amount int32) error
}
// PacketSender interface for sending skill packets to clients
type PacketSender interface {
QueuePacket(packet []byte)
GetVersion() int32
}
// Database interface for skill persistence
type Database interface {
LoadPlayerSkills(characterID int32) ([]*Skill, error)
SavePlayerSkill(characterID int32, skill *Skill) error
LoadMasterSkills() ([]*Skill, error)
SaveMasterSkill(skill *Skill) error
}
// Logger interface for skill system logging
type Logger interface {
LogInfo(message string, args ...interface{})
LogError(message string, args ...interface{})
LogDebug(message string, args ...interface{})
}
// EntitySkillAdapter provides skill functionality for entities
type EntitySkillAdapter struct {
skillList *PlayerSkillList
entityID int32
logger Logger
}
// NewEntitySkillAdapter creates a new entity skill adapter
func NewEntitySkillAdapter(entityID int32, logger Logger) *EntitySkillAdapter {
return &EntitySkillAdapter{
skillList: NewPlayerSkillList(),
entityID: entityID,
logger: logger,
}
}
// GetSkillList returns the player's skill list
func (esa *EntitySkillAdapter) GetSkillList() *PlayerSkillList {
return esa.skillList
}
// GetSkillByName returns a skill by name
func (esa *EntitySkillAdapter) GetSkillByName(name string) *Skill {
return esa.skillList.GetSkillByName(name)
}
// GetSkill returns a skill by ID
func (esa *EntitySkillAdapter) GetSkill(skillID int32) *Skill {
return esa.skillList.GetSkill(skillID)
}
// HasSkill checks if the entity has a skill
func (esa *EntitySkillAdapter) HasSkill(skillID int32) bool {
return esa.skillList.HasSkill(skillID)
}
// IncreaseSkill increases a skill by name
func (esa *EntitySkillAdapter) IncreaseSkill(skillName string, amount int32) error {
skill := esa.skillList.GetSkillByName(skillName)
if skill == nil {
if esa.logger != nil {
esa.logger.LogError("Entity %d: Skill '%s' not found for increase", esa.entityID, skillName)
}
return fmt.Errorf("skill '%s' not found", skillName)
}
esa.skillList.IncreaseSkill(skill, int16(amount))
if esa.logger != nil {
esa.logger.LogDebug("Entity %d: Increased skill '%s' by %d (now %d/%d)",
esa.entityID, skillName, amount, skill.CurrentVal, skill.MaxVal)
}
return nil
}
// AddSkill adds a new skill to the entity
func (esa *EntitySkillAdapter) AddSkill(skill *Skill) {
if skill == nil {
return
}
esa.skillList.AddSkill(skill)
if esa.logger != nil {
esa.logger.LogDebug("Entity %d: Added skill '%s' (ID: %d)", esa.entityID, skill.Name.Data, skill.SkillID)
}
}
// RemoveSkill removes a skill from the entity
func (esa *EntitySkillAdapter) RemoveSkill(skill *Skill) {
if skill == nil {
return
}
esa.skillList.RemoveSkill(skill)
if esa.logger != nil {
esa.logger.LogDebug("Entity %d: Removed skill '%s' (ID: %d)", esa.entityID, skill.Name.Data, skill.SkillID)
}
}
// GetSkillValue returns a skill's current value including bonuses
func (esa *EntitySkillAdapter) GetSkillValue(skillID int32) int16 {
skill := esa.skillList.GetSkill(skillID)
if skill == nil {
return 0
}
return esa.skillList.CalculateSkillValue(skillID, skill.CurrentVal)
}
// GetSkillMaxValue returns a skill's max value including bonuses
func (esa *EntitySkillAdapter) GetSkillMaxValue(skillID int32) int16 {
skill := esa.skillList.GetSkill(skillID)
if skill == nil {
return 0
}
return esa.skillList.CalculateSkillMaxValue(skillID, skill.MaxVal)
}
// ApplySkillBonus applies a skill bonus from a spell
func (esa *EntitySkillAdapter) ApplySkillBonus(spellID int32, skillID int32, value float32) {
esa.skillList.AddSkillBonus(spellID, skillID, value)
if esa.logger != nil {
esa.logger.LogDebug("Entity %d: Applied skill bonus from spell %d to skill %d: %f",
esa.entityID, spellID, skillID, value)
}
}
// RemoveSkillBonus removes skill bonuses from a spell
func (esa *EntitySkillAdapter) RemoveSkillBonus(spellID int32) {
esa.skillList.RemoveSkillBonus(spellID)
if esa.logger != nil {
esa.logger.LogDebug("Entity %d: Removed skill bonuses from spell %d", esa.entityID, spellID)
}
}
// CheckSkillIncrease attempts to increase a skill
func (esa *EntitySkillAdapter) CheckSkillIncrease(skillID int32) bool {
skill := esa.skillList.GetSkill(skillID)
if skill == nil {
return false
}
increased := esa.skillList.CheckSkillIncrease(skill)
if increased && esa.logger != nil {
esa.logger.LogInfo("Entity %d: Skill '%s' increased to %d/%d",
esa.entityID, skill.Name.Data, skill.CurrentVal, skill.MaxVal)
}
return increased
}
// GetSaveNeededSkills returns skills that need database saving
func (esa *EntitySkillAdapter) GetSaveNeededSkills() []*Skill {
return esa.skillList.GetSaveNeededSkills()
}
// GetSkillUpdates returns skills that need client updates
func (esa *EntitySkillAdapter) GetSkillUpdates() []*Skill {
return esa.skillList.GetSkillUpdates()
}
// HasSkillUpdates returns whether there are pending skill updates
func (esa *EntitySkillAdapter) HasSkillUpdates() bool {
return esa.skillList.HasSkillUpdates()
}
// SendSkillPacket sends skill updates to a client
func (esa *EntitySkillAdapter) SendSkillPacket(sender PacketSender) error {
if sender == nil {
return fmt.Errorf("packet sender is nil")
}
packet, err := esa.skillList.GetSkillPacket(int16(sender.GetVersion()))
if err != nil {
return fmt.Errorf("failed to build skill packet: %w", err)
}
sender.QueuePacket(packet)
if esa.logger != nil {
esa.logger.LogDebug("Entity %d: Sent skill packet to client (version %d)",
esa.entityID, sender.GetVersion())
}
return nil
}
// LoadSkillsFromDatabase loads skills from database (placeholder)
func (esa *EntitySkillAdapter) LoadSkillsFromDatabase(db Database, characterID int32) error {
if db == nil {
return fmt.Errorf("database is nil")
}
skills, err := db.LoadPlayerSkills(characterID)
if err != nil {
return fmt.Errorf("failed to load player skills: %w", err)
}
for _, skill := range skills {
esa.skillList.AddSkill(skill)
}
if esa.logger != nil {
esa.logger.LogInfo("Entity %d: Loaded %d skills from database", esa.entityID, len(skills))
}
return nil
}
// SaveSkillsToDatabase saves skills to database (placeholder)
func (esa *EntitySkillAdapter) SaveSkillsToDatabase(db Database, characterID int32) error {
if db == nil {
return fmt.Errorf("database is nil")
}
saveSkills := esa.GetSaveNeededSkills()
for _, skill := range saveSkills {
if err := db.SavePlayerSkill(characterID, skill); err != nil {
if esa.logger != nil {
esa.logger.LogError("Entity %d: Failed to save skill %s: %v", esa.entityID, skill.Name.Data, err)
}
return fmt.Errorf("failed to save skill %s: %w", skill.Name.Data, err)
}
}
if len(saveSkills) > 0 && esa.logger != nil {
esa.logger.LogInfo("Entity %d: Saved %d skills to database", esa.entityID, len(saveSkills))
}
return nil
}