package skills // AddSkillBonus adds a skill bonus from a spell func (psl *PlayerSkillList) AddSkillBonus(spellID int32, skillID int32, value float32) { if value == 0 { return } psl.bonusMutex.Lock() defer psl.bonusMutex.Unlock() // Get or create skill bonus entry for this spell skillBonus, exists := psl.skillBonusList[spellID] if !exists { skillBonus = &SkillBonus{ SpellID: spellID, Skills: make(map[int32]*SkillBonusValue), } psl.skillBonusList[spellID] = skillBonus } // Add or update the skill bonus value if skillBonus.Skills[skillID] == nil { skillBonus.Skills[skillID] = &SkillBonusValue{ SkillID: skillID, Value: value, } } } // GetSkillBonus returns skill bonus for a spell func (psl *PlayerSkillList) GetSkillBonus(spellID int32) *SkillBonus { psl.bonusMutex.RLock() defer psl.bonusMutex.RUnlock() if bonus, exists := psl.skillBonusList[spellID]; exists { return bonus } return nil } // RemoveSkillBonus removes all skill bonuses from a spell func (psl *PlayerSkillList) RemoveSkillBonus(spellID int32) { psl.bonusMutex.Lock() defer psl.bonusMutex.Unlock() if skillBonus, exists := psl.skillBonusList[spellID]; exists { // Clean up skill bonus values for _, bonusValue := range skillBonus.Skills { _ = bonusValue // In C++, this would be safe_delete(bonusValue) } delete(psl.skillBonusList, spellID) } } // CalculateSkillValue calculates a skill's value including bonuses func (psl *PlayerSkillList) CalculateSkillValue(skillID int32, currentVal int16) int16 { if currentVal <= 5 { return currentVal } psl.bonusMutex.RLock() defer psl.bonusMutex.RUnlock() newVal := currentVal // Apply all skill bonuses for _, skillBonus := range psl.skillBonusList { if bonusValue, exists := skillBonus.Skills[skillID]; exists { newVal += int16(bonusValue.Value) } } return newVal } // CalculateSkillMaxValue calculates a skill's max value including bonuses func (psl *PlayerSkillList) CalculateSkillMaxValue(skillID int32, maxVal int16) int16 { psl.bonusMutex.RLock() defer psl.bonusMutex.RUnlock() newVal := maxVal // Apply all skill bonuses to max value for _, skillBonus := range psl.skillBonusList { if bonusValue, exists := skillBonus.Skills[skillID]; exists { newVal += int16(bonusValue.Value) } } return newVal } // GetAllSkillBonuses returns all skill bonuses (for debugging/admin) func (psl *PlayerSkillList) GetAllSkillBonuses() map[int32]*SkillBonus { psl.bonusMutex.RLock() defer psl.bonusMutex.RUnlock() // Return a copy to prevent external modification bonuses := make(map[int32]*SkillBonus) for spellID, bonus := range psl.skillBonusList { // Deep copy the skill bonus newBonus := &SkillBonus{ SpellID: bonus.SpellID, Skills: make(map[int32]*SkillBonusValue), } for skillID, bonusValue := range bonus.Skills { newBonus.Skills[skillID] = &SkillBonusValue{ SkillID: bonusValue.SkillID, Value: bonusValue.Value, } } bonuses[spellID] = newBonus } return bonuses } // RemoveAllSkillBonuses removes all skill bonuses (for cleanup) func (psl *PlayerSkillList) RemoveAllSkillBonuses() { psl.bonusMutex.Lock() defer psl.bonusMutex.Unlock() // Clean up all skill bonuses for spellID := range psl.skillBonusList { if skillBonus, exists := psl.skillBonusList[spellID]; exists { for _, bonusValue := range skillBonus.Skills { _ = bonusValue // In C++, this would be safe_delete(bonusValue) } } } psl.skillBonusList = make(map[int32]*SkillBonus) } // GetSkillBonusTotal returns the total bonus for a specific skill func (psl *PlayerSkillList) GetSkillBonusTotal(skillID int32) float32 { psl.bonusMutex.RLock() defer psl.bonusMutex.RUnlock() var total float32 for _, skillBonus := range psl.skillBonusList { if bonusValue, exists := skillBonus.Skills[skillID]; exists { total += bonusValue.Value } } return total } // HasSkillBonuses returns whether the player has any skill bonuses func (psl *PlayerSkillList) HasSkillBonuses() bool { psl.bonusMutex.RLock() defer psl.bonusMutex.RUnlock() return len(psl.skillBonusList) > 0 } // GetSpellsWithSkillBonuses returns all spell IDs that provide skill bonuses func (psl *PlayerSkillList) GetSpellsWithSkillBonuses() []int32 { psl.bonusMutex.RLock() defer psl.bonusMutex.RUnlock() spellIDs := make([]int32, 0, len(psl.skillBonusList)) for spellID := range psl.skillBonusList { spellIDs = append(spellIDs, spellID) } return spellIDs }