basic item filter wip
This commit is contained in:
45
pkg/itemfilter/chain.go
Normal file
45
pkg/itemfilter/chain.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package itemfilter
|
||||
|
||||
import "github.com/hectorgimenez/d2go/pkg/nip"
|
||||
|
||||
type evaluationChain struct {
|
||||
links []link
|
||||
}
|
||||
|
||||
type link struct {
|
||||
Result bool
|
||||
Operand nip.Operand
|
||||
}
|
||||
|
||||
func (ch *evaluationChain) Add(result bool, operand nip.Operand) {
|
||||
ch.links = append(ch.links, link{
|
||||
Result: result,
|
||||
Operand: operand,
|
||||
})
|
||||
}
|
||||
|
||||
func (ch *evaluationChain) Evaluate() bool {
|
||||
if len(ch.links) == 1 {
|
||||
return ch.links[0].Result
|
||||
}
|
||||
|
||||
result := ch.links[0].Result
|
||||
operand := ch.links[0].Operand
|
||||
for i, eval := range ch.links {
|
||||
if i == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
if i < len(ch.links) {
|
||||
switch operand {
|
||||
case nip.OperandAnd:
|
||||
result = result && eval.Result
|
||||
case nip.OperandOr:
|
||||
result = result || eval.Result
|
||||
}
|
||||
}
|
||||
operand = eval.Operand
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
64
pkg/itemfilter/chain_test.go
Normal file
64
pkg/itemfilter/chain_test.go
Normal file
@@ -0,0 +1,64 @@
|
||||
package itemfilter
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/hectorgimenez/d2go/pkg/nip"
|
||||
)
|
||||
|
||||
func Test_evaluationChain_Evaluate(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
links []link
|
||||
want bool
|
||||
}{
|
||||
{
|
||||
name: "Given one single link with true value should return true",
|
||||
links: []link{
|
||||
{true, nip.OperandNone},
|
||||
},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "Given one single link with false value should return false",
|
||||
links: []link{
|
||||
{false, nip.OperandNone},
|
||||
},
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "Given different links using OR and one valid value should be true",
|
||||
links: []link{
|
||||
{false, nip.OperandOr},
|
||||
{true, nip.OperandNone},
|
||||
},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "Given different links using OR and no valid value should be false",
|
||||
links: []link{
|
||||
{false, nip.OperandOr},
|
||||
{false, nip.OperandNone},
|
||||
},
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "Given different links using AND and one valid value should be false",
|
||||
links: []link{
|
||||
{true, nip.OperandAnd},
|
||||
{false, nip.OperandNone},
|
||||
},
|
||||
want: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
ch := &evaluationChain{
|
||||
links: tt.links,
|
||||
}
|
||||
if got := ch.Evaluate(); got != tt.want {
|
||||
t.Errorf("Evaluate() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
90
pkg/itemfilter/itemfilter.go
Normal file
90
pkg/itemfilter/itemfilter.go
Normal file
@@ -0,0 +1,90 @@
|
||||
package itemfilter
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/hectorgimenez/d2go/pkg/data"
|
||||
"github.com/hectorgimenez/d2go/pkg/nip"
|
||||
)
|
||||
|
||||
func Evaluate(i data.Item, rules []nip.Rule) bool {
|
||||
for _, r := range rules {
|
||||
if !checkProperties(i, r.Properties) {
|
||||
// Properties not matching, skipping
|
||||
continue
|
||||
}
|
||||
|
||||
// We can not check stats, item is not identified, but properties matching
|
||||
if !i.Identified {
|
||||
return true
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func checkProperties(i data.Item, properties []nip.Group) bool {
|
||||
groupChain := evaluationChain{}
|
||||
for _, propGroup := range properties {
|
||||
propChain := evaluationChain{}
|
||||
for _, prop := range propGroup.Comparable {
|
||||
propChain.Add(checkProperty(i, prop), prop.Operand)
|
||||
}
|
||||
groupChain.Add(propChain.Evaluate(), propGroup.Operand)
|
||||
}
|
||||
|
||||
return groupChain.Evaluate()
|
||||
}
|
||||
|
||||
func checkProperty(i data.Item, prop nip.Comparable) bool {
|
||||
switch prop.Keyword {
|
||||
case nip.PropertyType:
|
||||
return strings.EqualFold(i.Type(), prop.ValueString)
|
||||
case nip.PropertyName:
|
||||
return strings.EqualFold(string(i.Name), prop.ValueString)
|
||||
case nip.PropertyClass:
|
||||
// TODO: Implement
|
||||
case nip.PropertyQuality:
|
||||
quality, found := qualities[prop.ValueString]
|
||||
if !found {
|
||||
return false
|
||||
}
|
||||
|
||||
return compare(int(i.Quality), int(quality), prop.Comparison)
|
||||
case nip.PropertyFlag:
|
||||
if prop.Comparison == nip.OperandEqual && !i.Ethereal {
|
||||
return false
|
||||
}
|
||||
if prop.Comparison == nip.OperandNotEqualTo && i.Ethereal {
|
||||
return false
|
||||
}
|
||||
case nip.PropertyLevel:
|
||||
// TODO: Implement
|
||||
case nip.PropertyPrefix:
|
||||
// TODO: Implement
|
||||
case nip.PropertySuffix:
|
||||
// TODO: Implement
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func compare(val1, val2 int, operand nip.Operand) bool {
|
||||
switch operand {
|
||||
case nip.OperandEqual:
|
||||
return val1 == val2
|
||||
case nip.OperandGreaterThan:
|
||||
return val1 > val2
|
||||
case nip.OperandGreaterOrEqualTo:
|
||||
return val1 >= val2
|
||||
case nip.OperandLessThan:
|
||||
return val1 < val2
|
||||
case nip.OperandLessThanOrEqualTo:
|
||||
return val1 <= val2
|
||||
case nip.OperandNotEqualTo:
|
||||
return val1 != val2
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
17
pkg/itemfilter/mapping.go
Normal file
17
pkg/itemfilter/mapping.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package itemfilter
|
||||
|
||||
import (
|
||||
"github.com/hectorgimenez/d2go/pkg/data/item"
|
||||
"github.com/hectorgimenez/d2go/pkg/nip"
|
||||
)
|
||||
|
||||
var qualities = map[string]item.Quality{
|
||||
nip.QualityLowQuality: item.QualityLowQuality,
|
||||
nip.QualityNormal: item.QualityNormal,
|
||||
nip.QualitySuperior: item.QualitySuperior,
|
||||
nip.QualityMagic: item.QualityMagic,
|
||||
nip.QualitySet: item.QualitySet,
|
||||
nip.QualityRare: item.QualityRare,
|
||||
nip.QualityUnique: item.QualityUnique,
|
||||
nip.QualityCrafted: item.QualityCrafted,
|
||||
}
|
||||
Reference in New Issue
Block a user