mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2024-11-18 02:16:23 -05:00
9e61079e93
* add interface for stats, d2 is an implementation * fix incorrect comment, remove ennecessary int * simplified description functions, remove duplicates * moved default stringer functions * fixed incorrect stat combine method * change `Create` to `New` in method names * d2stats + diablo2stats refactored again - simplified `NewStat` provider function - added initializer for stat values that sets the stringer functions, value types, and combination types for values when created - removed redundant description functions - added stat value combination types `sum` and `static` `static` stat values which are not altered when stats are combined. this makes sense for stats like proc-on-hit or +skills to class example: Stat A: `10% reanimate as: skeleton mage` Stat B: `8% reanimate as: skeleton archer` Stat C: `6% reanimate as: skeleton archer` A and B can not be combined B and C can be combined to `14% reanimate as: skeleton archer`
121 lines
2.8 KiB
Go
121 lines
2.8 KiB
Go
package diablo2stats
|
|
|
|
import (
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2stats"
|
|
)
|
|
|
|
// static check that diablo2Stat implements Stat
|
|
var _ d2stats.StatList = &Diablo2StatList{}
|
|
|
|
// Diablo2StatList is a diablo 2 implementation of a stat list
|
|
type Diablo2StatList struct {
|
|
stats []d2stats.Stat
|
|
}
|
|
|
|
// Index returns a stat given with the given index
|
|
func (sl *Diablo2StatList) Index(idx int) d2stats.Stat {
|
|
if idx < 0 || idx > len(sl.stats) {
|
|
return nil
|
|
}
|
|
|
|
return sl.stats[idx]
|
|
}
|
|
|
|
// Stats returns a slice of stats
|
|
func (sl *Diablo2StatList) Stats() []d2stats.Stat {
|
|
return sl.stats
|
|
}
|
|
|
|
// SetStats sets the stats, given a slice of stats
|
|
func (sl *Diablo2StatList) SetStats(stats []d2stats.Stat) d2stats.StatList {
|
|
sl.stats = stats
|
|
return sl
|
|
}
|
|
|
|
// Pop removes the last stat from the stat list
|
|
func (sl *Diablo2StatList) Pop() d2stats.Stat {
|
|
num := len(sl.stats)
|
|
if num < 1 {
|
|
return nil
|
|
}
|
|
|
|
idx := num - 1
|
|
last := sl.stats[idx]
|
|
sl.stats = sl.stats[:idx]
|
|
|
|
return last
|
|
}
|
|
|
|
// Push adds a stat at the end of the stat list
|
|
func (sl *Diablo2StatList) Push(stat d2stats.Stat) d2stats.StatList {
|
|
sl.stats = append(sl.stats, stat)
|
|
|
|
return sl
|
|
}
|
|
|
|
// Clone returns a deep copy of the stat list
|
|
func (sl *Diablo2StatList) Clone() d2stats.StatList {
|
|
clone := &Diablo2StatList{}
|
|
clone.stats = make([]d2stats.Stat, len(sl.stats))
|
|
|
|
for idx := range sl.stats {
|
|
if stat := sl.Index(idx); stat != nil {
|
|
clone.stats[idx] = stat.Clone()
|
|
}
|
|
}
|
|
|
|
return clone
|
|
}
|
|
|
|
// ReduceStats combines like stats (does not alter this stat list, returns clone)
|
|
func (sl *Diablo2StatList) ReduceStats() d2stats.StatList {
|
|
clone := sl.Clone()
|
|
reduction := make([]d2stats.Stat, 0)
|
|
|
|
// for quick lookups
|
|
lookup := make(map[string]int)
|
|
|
|
for len(clone.Stats()) > 0 {
|
|
stat := clone.Pop()
|
|
|
|
// if we find it in the lookup, immediately try to combine
|
|
// if it doesn't combine, we append to the reduction
|
|
if idx, found := lookup[stat.Name()]; found {
|
|
if result, err := reduction[idx].Combine(stat); err == nil {
|
|
reduction[idx] = result
|
|
continue
|
|
}
|
|
}
|
|
|
|
// we didnt find it in the lookup, so we will try to combine with other stats
|
|
for idx := range reduction {
|
|
if _, err := reduction[idx].Combine(stat); err == nil {
|
|
continue
|
|
}
|
|
}
|
|
|
|
lookup[stat.Name()] = len(lookup)
|
|
|
|
reduction = append(reduction, stat)
|
|
}
|
|
|
|
return clone.SetStats(reduction)
|
|
}
|
|
|
|
// RemoveStatAtIndex removes the stat from the stat list, returns the stat
|
|
func (sl *Diablo2StatList) RemoveStatAtIndex(idx int) d2stats.Stat {
|
|
picked := sl.stats[idx]
|
|
sl.stats[idx] = sl.stats[len(sl.stats)-1]
|
|
sl.stats[len(sl.stats)-1] = nil
|
|
sl.stats = sl.stats[:len(sl.stats)-1]
|
|
|
|
return picked
|
|
}
|
|
|
|
// AppendStatList adds the stats from the other stat list to this stat list
|
|
func (sl *Diablo2StatList) AppendStatList(other d2stats.StatList) d2stats.StatList {
|
|
sl.stats = append(sl.stats, other.Stats()...)
|
|
|
|
return sl
|
|
}
|