Files
bd2/go/internal/server/player/equipment_craft_runtime.go
T

67 lines
2.1 KiB
Go

package player
import (
"errors"
"fmt"
"math"
)
// AddTalentExperience applies the same clamp as the client: talent experience
// may reach the cumulative threshold of the current level, but this request
// never promotes the talent level itself.
func (s *CharacterStore) AddTalentExperience(index, gain, maximum uint64) (Character, error) {
if s == nil || index == 0 || maximum == 0 {
return Character{}, errors.New("player: invalid talent experience update")
}
s.mu.Lock()
for position, current := range s.characters {
if current.InvenIndex != index {
continue
}
if current.TalentExp > maximum {
s.mu.Unlock()
return Character{}, fmt.Errorf("player: character %d talent experience exceeds current threshold", index)
}
if gain > maximum-current.TalentExp {
gain = maximum - current.TalentExp
}
if current.TalentExp > math.MaxUint64-gain {
s.mu.Unlock()
return Character{}, errors.New("player: talent experience overflow")
}
current.TalentExp += gain
next := append([]Character(nil), s.characters...)
next[position] = current
if err := s.persist(next); err != nil {
s.mu.Unlock()
return Character{}, fmt.Errorf("player: persist equipment making talent experience: %w", err)
}
s.characters = next
s.mu.Unlock()
return current, nil
}
collection := s.collection
s.mu.Unlock()
if collection == nil {
return Character{}, fmt.Errorf("player: unknown equipment making character %d", index)
}
current, found := collection.FindCharacter(index)
if !found {
return Character{}, fmt.Errorf("player: unknown equipment making character %d", index)
}
if current.TalentExp > maximum {
return Character{}, fmt.Errorf("player: character %d talent experience exceeds current threshold", index)
}
if gain > maximum-current.TalentExp {
gain = maximum - current.TalentExp
}
if current.TalentExp > math.MaxUint64-gain {
return Character{}, errors.New("player: talent experience overflow")
}
current.TalentExp += gain
if err := collection.UpdateCharacter(current.ID, current); err != nil {
return Character{}, fmt.Errorf("player: persist collection equipment making talent experience: %w", err)
}
return current, nil
}