Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions proto/common.proto
Original file line number Diff line number Diff line change
Expand Up @@ -927,8 +927,10 @@ enum EnchantType {

// Contains only the Enchant info needed by the sim.
message SimEnchant {
int32 effect_id = 1;
repeated double stats = 2;
int32 effect_id = 1;
repeated double stats = 2;
string name = 3; // Only needed for unit tests.
ItemType type = 4; // Only needed for unit tests.
}

// Contains only the Gem info needed by the sim.
Expand Down
2 changes: 1 addition & 1 deletion sim/common/wotlk/enchant_effects.go
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ func init() {
})

// Enchant: 3843, Spell: 61471 - Diamond-cut Refractor Scope
core.AddWeaponEffect(3843, func(agent core.Agent, _ proto.ItemSlot) {
core.NewEnchantEffect(3843, func(agent core.Agent) {
w := agent.GetCharacter().AutoAttacks.Ranged()
w.BaseDamageMin += 15
w.BaseDamageMax += 15
Expand Down
14 changes: 14 additions & 0 deletions sim/core/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -209,12 +209,16 @@ func RandomSuffixFromProto(pData *proto.ItemRandomSuffix) RandomSuffix {
type Enchant struct {
EffectID int32 // Used by UI to apply effect to tooltip
Stats stats.Stats
Name string // Only needed for unit tests
Type proto.ItemType // Only needed for unit tests
}

func EnchantFromProto(pData *proto.SimEnchant) Enchant {
return Enchant{
EffectID: pData.EffectId,
Stats: stats.FromProtoArray(pData.Stats),
Name: pData.Name,
Type: pData.Type,
}
}

Expand Down Expand Up @@ -345,6 +349,16 @@ func (equipment *Equipment) EquipItem(item Item) {
}
}

func (equipment *Equipment) EquipEnchant(enchant Enchant) {
// Some shield enchants parse as ItemTypeUnknown, so default those to
// the OH slot to ensure they still get tested.
if enchant.Type == proto.ItemType_ItemTypeUnknown {
equipment.OffHand().Enchant = enchant
} else {
equipment[ItemTypeToSlot(enchant.Type)].Enchant = enchant
}
}

func (equipment *Equipment) containsEnchantInSlot(effectID int32, slot proto.ItemSlot) bool {
return (equipment[slot].Enchant.EffectID == effectID) || (equipment[slot].TempEnchant == effectID)
}
Expand Down
2 changes: 2 additions & 0 deletions sim/core/database_load.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ func init() {
simDB.Enchants[i] = &proto.SimEnchant{
EffectId: enchant.EffectId,
Stats: enchant.Stats,
Name: enchant.Name,
Type: enchant.Type,
}
}

Expand Down
32 changes: 4 additions & 28 deletions sim/core/item_effects.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"strconv"
"time"

"github.com/wowsims/cata/sim/core/proto"
"github.com/wowsims/cata/sim/core/stats"
)

Expand All @@ -16,15 +15,12 @@ import (
// but there are occasionally class-specific item effects.
type ApplyEffect func(Agent)

// Function for applying permanent effects to an agent's weapon
type ApplyWeaponEffect func(Agent, proto.ItemSlot)

var itemEffects = map[int32]ApplyEffect{}
var weaponEffects = map[int32]ApplyWeaponEffect{}
var enchantEffects = map[int32]ApplyEffect{}

// IDs of item effects which should be used for tests.
var itemEffectsForTest []int32
var enchantEffectsForTest []int32

// This value can be set before adding item effects, to control whether they are included in tests.
var AddEffectsToTest = true
Expand All @@ -37,11 +33,6 @@ func HasItemEffectForTest(id int32) bool {
return slices.Contains(itemEffectsForTest, id)
}

func HasWeaponEffect(id int32) bool {
_, ok := weaponEffects[id]
return ok
}

func HasEnchantEffect(id int32) bool {
_, ok := enchantEffects[id]
return ok
Expand Down Expand Up @@ -80,22 +71,13 @@ func NewEnchantEffect(id int32, enchantEffect ApplyEffect) {
}

enchantEffects[id] = enchantEffect
}

func AddWeaponEffect(id int32, weaponEffect ApplyWeaponEffect) {
if WITH_DB {
if _, ok := EnchantsByEffectID[id]; !ok {
panic(fmt.Sprintf("No enchant with ID: %d", id))
}
}
if HasWeaponEffect(id) {
panic(fmt.Sprintf("Cannot add multiple effects for one item: %d, %#v", id, weaponEffect))
if AddEffectsToTest {
enchantEffectsForTest = append(enchantEffectsForTest, id)
}
weaponEffects[id] = weaponEffect
}

func (equipment *Equipment) applyItemEffects(agent Agent, registeredItemEffects map[int32]bool, registeredItemEnchantEffects map[int32]bool, includeGemEffects bool) {
for slot, eq := range equipment {
for _, eq := range equipment {
if applyItemEffect, ok := itemEffects[eq.ID]; ok && !registeredItemEffects[eq.ID] {
applyItemEffect(agent)
registeredItemEffects[eq.ID] = true
Expand All @@ -113,12 +95,6 @@ func (equipment *Equipment) applyItemEffects(agent Agent, registeredItemEffects
applyEnchantEffect(agent)
registeredItemEnchantEffects[eq.Enchant.EffectID] = true
}

if applyWeaponEffect, ok := weaponEffects[eq.Enchant.EffectID]; ok && !registeredItemEnchantEffects[eq.Enchant.EffectID] {
applyWeaponEffect(agent, proto.ItemSlot(slot))
registeredItemEnchantEffects[eq.Enchant.EffectID] = true
}

}
}

Expand Down
33 changes: 31 additions & 2 deletions sim/core/test_generators.go
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,9 @@ type ItemFilter struct {

// Item IDs to ignore.
IDBlacklist []int32

// Effect IDs to ignore.
EnchantBlacklist []int32
}

// Returns whether the given item matches the conditions of this filter.
Expand Down Expand Up @@ -314,6 +317,22 @@ func (filter *ItemFilter) FindAllMetaGems() []Gem {
return filteredGems
}

func (filter *ItemFilter) FindAllEnchants() []Enchant {
filteredEnchantIDs := FilterSlice(enchantEffectsForTest, func(id int32) bool {
return !slices.Contains(filter.EnchantBlacklist, id)
})

return MapSlice(filteredEnchantIDs, func(id int32) Enchant {
enchant, ok := EnchantsByEffectID[id]

if !ok {
panic(fmt.Sprintf("No DB data for enchant with id: %d", id))
}

return enchant
})
}

type ItemsTestGenerator struct {
// Fields describing the base API request.
Player *proto.Player
Expand All @@ -333,6 +352,7 @@ type ItemsTestGenerator struct {
sets []*ItemSet

metagems []Gem
enchants []Enchant

metaSocketIdx int
}
Expand All @@ -349,10 +369,15 @@ func (generator *ItemsTestGenerator) init() {
}
for _, itemSpec := range generator.Player.Equipment.Items {
generator.ItemFilter.IDBlacklist = append(generator.ItemFilter.IDBlacklist, itemSpec.Id)

if itemSpec.Enchant != 0 {
generator.ItemFilter.EnchantBlacklist = append(generator.ItemFilter.EnchantBlacklist, itemSpec.Enchant)
}
}

generator.items = generator.ItemFilter.FindAllItems()
generator.sets = generator.ItemFilter.FindAllSets()
generator.enchants = generator.ItemFilter.FindAllEnchants()

baseEquipment := ProtoToEquipment(generator.Player.Equipment)
generator.metaSocketIdx = -1
Expand All @@ -370,7 +395,7 @@ func (generator *ItemsTestGenerator) init() {

func (generator *ItemsTestGenerator) NumTests() int {
generator.init()
return len(generator.items) + len(generator.sets) + len(generator.metagems)
return len(generator.items) + len(generator.sets) + len(generator.metagems) + len(generator.enchants)
}

func (generator *ItemsTestGenerator) GetTest(testIdx int) (string, *proto.ComputeStatsRequest, *proto.StatWeightsRequest, *proto.RaidSimRequest) {
Expand All @@ -389,14 +414,18 @@ func (generator *ItemsTestGenerator) GetTest(testIdx int) (string, *proto.Comput
equipment.EquipItem(setItem)
}
label = strings.ReplaceAll(testSet.Name, " ", "")
} else {
} else if testIdx < len(generator.items)+len(generator.sets)+len(generator.metagems) {
testMetaGem := generator.metagems[testIdx-len(generator.items)-len(generator.sets)]
headItem := &equipment[proto.ItemSlot_ItemSlotHead]
for len(headItem.Gems) <= generator.metaSocketIdx {
headItem.Gems = append(headItem.Gems, Gem{})
}
headItem.Gems[generator.metaSocketIdx] = testMetaGem
label = strings.ReplaceAll(testMetaGem.Name, " ", "")
} else {
testEnchant := generator.enchants[testIdx-len(generator.items)-len(generator.sets)-len(generator.metagems)]
equipment.EquipEnchant(testEnchant)
label = fmt.Sprintf("%s-%d", strings.ReplaceAll(testEnchant.Name, " ", ""), testEnchant.EffectID)
}
playerCopy.Equipment = equipment.ToEquipmentSpecProto()

Expand Down
Loading
Loading