fixed many of the issues with spells and items

This commit is contained in:
2024-07-13 21:22:27 -04:00
parent 6cb950cd2f
commit 87d6649081
4 changed files with 170 additions and 59 deletions

View File

@@ -60,7 +60,6 @@ func (db Database) GetBossLoot(bossId int) ([]Item, error) {
entry in
(SELECT item from acore_world.creature_loot_template where entry = ? and GroupId != 0 and Reference = 0)
and Quality > 2
and StatsCount > 0
`
udb := db.client.Unsafe()

View File

@@ -378,6 +378,10 @@ func (item *Item) GetSpells() ([]Spell, error) {
continue
}
if spellId == -1 {
continue
}
spell, err := DB.GetSpell(int(spellId))
if err != nil {
log.Printf("failed to get the spell: %v error: %v", spellId, err)
@@ -417,6 +421,7 @@ func (item *Item) GetNonStatSpells() ([]Spell, error) {
continue
}
spell.ItemSpellSlot = i
nonStatSpells = append(nonStatSpells, spell)
}
return nonStatSpells, nil
@@ -435,6 +440,9 @@ func (item *Item) ScaleItem(itemLevel int, itemQuality int) (bool, error) {
return false, errors.New("field quality is not set")
}
log.Printf("Scaling item %v %v to item level %v and quality %v", item.Name, item.Entry, itemLevel, itemQuality)
fromItemLevel := *item.ItemLevel
*item.ItemLevel = itemLevel
*item.Quality = itemQuality
@@ -446,12 +454,19 @@ func (item *Item) ScaleItem(itemLevel int, itemQuality int) (bool, error) {
}
for i := 0; i < len(spells); i++ {
log.Printf("Spell %v (%v) Effect %v AuraEffect %v Spell Desc: %v basePoints %v", spells[i].Name, spells[i].ID, spells[i].Effect1, spells[i].EffectAura1, spells[i].Description, spells[i].EffectBasePoints1)
convStats, err := spells[i].ConvertToStats()
if err != nil {
log.Printf("Failed to convert spell to stats: %v for spell %v", err, spells[i].Name)
continue
}
if len(convStats) != 0 {
item.UpdateField(fmt.Sprintf("SpellId%v", i+1), 0)
}
allSpellStats = append(allSpellStats, convStats...)
}
@@ -460,6 +475,7 @@ func (item *Item) ScaleItem(itemLevel int, itemQuality int) (bool, error) {
origValue := stat.Value
stat.Value = scaleStat(itemLevel, *item.InventoryType, itemQuality, stat.Percent, StatModifiers[statId])
log.Printf(">>>>>> Scaled : StatId: %v Type: %s Orig: %v - New Value: %v Percent: %v", statId, stat.Type, origValue, stat.Value, stat.Percent)
}
@@ -505,10 +521,26 @@ func (item *Item) ScaleItem(itemLevel int, itemQuality int) (bool, error) {
log.Printf("failed to get non stat spells: %v", err)
}
log.Printf("\n\n\n -------------------- COUNT OF other spells %v \n\n", len(otherSpells))
item.Spells = []Spell{}
// Spells that can not be scaled into stats must get new spells scaled and created
for _, spell := range otherSpells {
log.Printf(" --------SPELL --- Spell %v (%v) Effect %v AuraEffect %v Spell Desc: %v basePoints %v", spell.Name, spell.ID, spell.Effect1, spell.EffectAura1, spell.Description, spell.EffectBasePoints1)
spell.ScaleSpell(itemLevel, itemQuality)
log.Printf(" --^^^^^^--------SPELL --- Spell %v (%v) Effect %v AuraEffect %v Spell Desc: %v basePoints %v", spell.Name, spell.ID, spell.Effect1, spell.EffectAura1, spell.Description, spell.EffectBasePoints1)
newId, err := spell.ScaleSpell(fromItemLevel, itemLevel, itemQuality)
if err != nil {
log.Printf("Failed to scale spell: %v, Spell %v", err, spell.ID)
continue
}
if newId == 0 {
log.Printf("Failed to scale spell: %v, Spell %v", err, spell.ID)
continue
}
item.UpdateField(fmt.Sprintf("SpellId%v", spell.ItemSpellSlot), newId)
item.Spells = append(item.Spells, spell)
log.Printf(" --SCALED---SPELL --- Spell %v (%v) Effect %v AuraEffect %v Spell Desc: %v basePoints %v", spell.Name, spell.ID, spell.Effect1, spell.EffectAura1, spell.Description, spell.EffectBasePoints1)
}
@@ -547,9 +579,7 @@ func (item *Item) UpdateField(fieldName string, value int) {
case reflect.Ptr:
newValue := reflect.ValueOf(&value)
field.Set(newValue)
// log.Printf("Successfully set %s to %d", fieldName, value)
default:
// log.Printf("field %s is not a pointer", fieldName)
}
}
@@ -578,32 +608,32 @@ func (item *Item) emptyStats() {
// Cleans up spells from the item that have been converted to stats and leaves only the ones that are not
func (item *Item) cleanSpells() {
spells, err := item.GetSpells()
if err != nil {
log.Printf("Failed to get spells for item: %v", err)
return
}
for i := 1; i < 3; i++ {
currentId, err := item.GetField(fmt.Sprintf("SpellId%v", i))
if len(spells) == 0 {
return
}
for i := 1; i < 4; i++ {
for _, spell := range spells {
currentId, err := item.GetField(fmt.Sprintf("SpellId%v", i))
if err != nil {
log.Printf("ERROR: Failed to get spell id %v err: %v", i, err)
continue
}
if currentId == 0 {
continue
}
if currentId == spell.ID {
item.UpdateField(fmt.Sprintf("SpellId%v", i), 0)
log.Printf("Removed spell %v from spellSlot: %v", spell.Name, fmt.Sprintf("SpellId%v", i))
}
log.Printf("Checking spell id %v - value %v", i, currentId)
if err != nil {
log.Printf("ERROR: Failed to get spell id %v err: %v", i, err)
continue
}
// if there no spellId set then check the next one if it is set move it and clear it
if currentId == 0 {
nextSpellId, err := item.GetField(fmt.Sprintf("SpellId%v", i+1))
if err != nil {
log.Printf("ERROR: Failed to get spell id %v err: %v", i+1, err)
}
if nextSpellId != 0 {
item.UpdateField(fmt.Sprintf("SpellId%v", i), nextSpellId)
item.UpdateField(fmt.Sprintf("SpellId%v", i+1), 0)
log.Printf("Moved spell %v to %v to replace removed spell", nextSpellId, i)
continue
}
continue
}
}
}
@@ -621,6 +651,27 @@ func (item *Item) addStats(stats map[int]*ItemStat) {
statTypeField := fmt.Sprintf("StatType%d", i)
statValueField := fmt.Sprintf("StatValue%d", i)
// MP5 adjustment
if statId == 43 {
stat.Value = int(math.Round(float64(stat.Value) * 0.5))
}
if statId == 12 {
stat.Value = int(math.Round(float64(stat.Value) * 0.5))
}
if statId == 12 {
stat.Value = int(math.Round(float64(stat.Value) * 0.75))
}
if statId == 13 {
stat.Value = int(math.Round(float64(stat.Value) * 0.65))
}
if statId == 31 {
stat.Value = int(math.Round(float64(stat.Value) * 0.55))
}
// Update the item with new stats from scaling
item.UpdateField(statTypeField, statId)
item.UpdateField(statValueField, stat.Value)

View File

@@ -1,6 +1,10 @@
package models
import "fmt"
import (
"fmt"
"github.com/araxiaonline/endgame-item-generator/utils"
)
type Dungeon struct {
Id int `db:"Id"`
@@ -10,7 +14,7 @@ type Dungeon struct {
}
// dungeon instance id : avg level
var dungeons = map[int]int{
var dungeonLevels = map[int]int{
// Classic WoW dungeons
389: 18, // Ragefire Chasm
@@ -23,44 +27,47 @@ var dungeons = map[int]int{
47: 40, // Razorfen Kraul
189: 45, // Scarlet Monastery (Graveyard)
289: 60, // Scholomance
109: 60, // Sunken Temple
129: 33, // Razorfen Downs
70: 40, // Uldaman
329: 60, // Stratholme
229: 60, // Blackrock Spire (Lower)
230: 60, // Blackrock Spire (Upper)
429: 60, // Dire Maul
209: 54, // Zul'Farrak
209: 50, // Zul'Farrak
349: 55, // Maraudon
269: 57, // Temple of Atal'Hakkar
// The Burning Crusade dungeons
540: 62, // Hellfire Citadel: Hellfire Ramparts
542: 63, // Hellfire Citadel: The Blood Furnace
547: 64, // Coilfang Reservoir: The Slave Pens
540: 70, // Shattered Halls
542: 65, // Hellfire The Blood Furnace
543: 62, // Hellfire Ramparts
545: 64, // Coilfang Steamvaults
546: 65, // Coilfang Reservoir: The Underbog
547: 64, // Coilfang Reservoir: The Underbog
557: 66, // Auchindoun: Mana-Tombs
558: 67, // Auchindoun: Auchenai Crypts
560: 68, // Caverns of Time: Old Hillsbrad Foothills
556: 69, // Auchindoun: Sethekk Halls
545: 70, // Coilfang Reservoir: The Steamvault
556: 70, // Auchindoun: Sethekk Halls
555: 70, // Auchindoun: Shadow Labyrinth
543: 70, // Hellfire Citadel: The Shattered Halls
560: 68, // Caverns of Time: Old Hillsbrad Foothills
553: 70, // Tempest Keep: The Botanica
554: 70, // Tempest Keep: The Mechanar
552: 70, // Tempest Keep: The Arcatraz
585: 70, // Magisters' Terrace
// Wrath of the Lich King dungeons
70: 72, // Utgarde Keep
129: 74, // Azjol-Nerub
574: 72, // Utgarde keep
575: 76, // Utgarde Pinnacle
619: 75, // Ahn'kahet: The Old Kingdom
576: 73, // The Nexus
595: 80, // The Culling of Stratholme
600: 76, // Drak'Tharon Keep
601: 75, // Azjol-Nerub
608: 77, // The Violet Hold
604: 78, // Gundrak
599: 79, // Halls of Stone
599: 78, // Halls of Stone
602: 80, // Halls of Lightning
578: 79, // The Oculus
575: 80, // Utgarde Pinnacle
595: 80, // The Culling of Stratholme
578: 78, // The Oculus
650: 80, // Trial of the Champion
632: 80, // The Forge of Souls
658: 80, // Pit of Saron
@@ -73,7 +80,7 @@ func (db Database) GetDungeons(expansionId int) ([]Dungeon, error) {
sql := `
SELECT ID as Id, MapName_Lang_enUS as Name, ExpansionID as ExpansionId
FROM map_dbc
WHERE InstanceType = 1 AND Name NOT LIKE '%unused%';
WHERE InstanceType = 1 AND MapName_Lang_enUS NOT LIKE '%unused%'
`
var err error
if expansionId != -1 {
@@ -87,5 +94,56 @@ func (db Database) GetDungeons(expansionId int) ([]Dungeon, error) {
return nil, fmt.Errorf("failed to get dungeons %v", err)
}
for i := range dungeons {
if level, ok := dungeonLevels[dungeons[i].Id]; ok {
dungeons[i].Level = level
}
}
return dungeons, nil
}
func (db Database) GetAddlDungeonDrops(instanceId int) ([]Item, error) {
var items []Item
sql := fmt.Sprintf(`
SELECT `+utils.GetItemFields("it")+`
from
acore_world.map_dbc m
join acore_world.creature c on m.ID = c.map
join acore_world.creature_template ct on c.id1 = ct.entry
left join acore_world.creature_loot_template clt on ct.lootid = clt.Entry
left join reference_loot_template rlt on clt.Reference = rlt.Entry
left join item_template it on rlt.Item = it.entry
WHERE m.ID = %v and Quality >= 3 and it.bonding = 2 and class IN(2,4)
UNION
SELECT `+utils.GetItemFields("it")+`
from
acore_world.map_dbc m
join acore_world.creature c on m.ID = c.map
join acore_world.creature_template ct on c.id1 = ct.entry
left join acore_world.creature_loot_template clt on clt.Entry = ct.Entry
left join item_template it on clt.Item = it.entry
WHERE m.ID = %v and Quality >= 3 and it.bonding = 2 and it.class IN(2,4)
UNION
SELECT `+utils.GetItemFields("it")+`
from
acore_world.map_dbc m
join acore_world.gameobject go on m.ID = go.map
left join acore_world.gameobject_template got on go.id = got.entry
left join acore_world.gameobject_loot_template glt on glt.Entry = got.Data1
left join reference_loot_template rlt on glt.Reference = rlt.Entry
left join item_template it on rlt.Item = it.entry
where m.ID = %v and Quality >=3 and it.bonding IN(1,2) and it.class IN(2,4);
`, instanceId, instanceId, instanceId)
// log.Printf("sql: %s", sql)
err := db.client.Select(&items, sql)
if err != nil {
return nil, fmt.Errorf("failed to get additional dungeon items: %v ", err)
}
return items, nil
}

View File

@@ -119,6 +119,8 @@ type Spell struct {
EffectBonusMultiplier1 int `db:"EffectBonusMultiplier_1"`
EffectBonusMultiplier2 int `db:"EffectBonusMultiplier_2"`
EffectBonusMultiplier3 int `db:"EffectBonusMultiplier_3"`
ItemSpellSlot int
Scaled bool
}
func (db Database) GetSpell(id int) (Spell, error) {
@@ -395,12 +397,12 @@ func parseStatDesc(desc string) int {
// stats on the item level and quality. This is a big assumption as the stats are not penalized
// from having the extra damage. This could really create some unique sought after weapons that exploit this.
// modified ratio ((s1 / existing iLevel) * newIlevel) * (0.20 Rare or 0.30 Epic or 0.4 for Legendary).
func (s *Spell) ScaleSpell(itemLevel int, itemQuality int) (int, error) {
func (s *Spell) ScaleSpell(fromItemLevel int, itemLevel int, itemQuality int) (int, error) {
s.Scaled = false
qualModifier := map[int]float64{
3: 0.20,
4: 0.30,
5: 0.40,
3: 1.20,
4: 1.30,
5: 1.40,
}
idBump := 30000000
@@ -417,47 +419,48 @@ func (s *Spell) ScaleSpell(itemLevel int, itemQuality int) (int, error) {
didScale := false
// Causes direct damage
if s.Effect1 != 0 && funk.Contains(dd, s.Effect1) {
s.EffectBasePoints1 = int(float64(s.EffectBasePoints1) / float64(s.SpellLevel) * float64(itemLevel) * qualModifier[itemQuality])
s.EffectBasePoints1 = int(float64(s.EffectBasePoints1) / float64(fromItemLevel) * float64(itemLevel) * qualModifier[itemQuality] * 2.5)
didScale = true
}
if s.Effect2 != 0 && funk.Contains(dd, s.Effect1) {
s.EffectBasePoints2 = int(float64(s.EffectBasePoints2) / float64(s.SpellLevel) * float64(itemLevel) * qualModifier[itemQuality])
s.EffectBasePoints2 = int(float64(s.EffectBasePoints2) / float64(fromItemLevel) * float64(itemLevel) * qualModifier[itemQuality] * 2.5)
didScale = true
}
// Restores a Power / Mana
if s.Effect1 != 0 && s.Effect1 == 30 {
// skip anyhing else that is not mana as they are flat values
if strings.Contains(s.Description, "Mana") {
s.EffectBasePoints1 = int(float64(s.EffectBasePoints1) / float64(s.SpellLevel) * float64(itemLevel) * qualModifier[itemQuality] * 0.75)
if strings.Contains(s.Description, "Mana") || strings.Contains(s.Description, "mana") {
s.EffectBasePoints1 = int(float64(s.EffectBasePoints1) / float64(fromItemLevel) * float64(itemLevel) * qualModifier[itemQuality])
didScale = true
}
}
// Scales a stat buff
if s.Effect1 != 0 && s.Effect1 == 35 {
s.EffectBasePoints1 = int(float64(s.EffectBasePoints1) / float64(s.SpellLevel) * float64(itemLevel) * qualModifier[itemQuality])
s.EffectBasePoints1 = int(float64(s.EffectBasePoints1) / float64(fromItemLevel) * float64(itemLevel) * qualModifier[itemQuality])
didScale = true
}
if s.Effect1 != 0 && s.Effect2 == 35 {
s.EffectBasePoints2 = int(float64(s.EffectBasePoints2) / float64(s.SpellLevel) * float64(itemLevel) * qualModifier[itemQuality])
s.EffectBasePoints2 = int(float64(s.EffectBasePoints2) / float64(fromItemLevel) * float64(itemLevel) * qualModifier[itemQuality])
didScale = true
}
// Handle special aura effects
if s.EffectAura1 != 0 && s.EffectAura1 == 3 && s.Effect1 == 6 {
s.EffectBasePoints1 = int(float64(s.EffectBasePoints1) / float64(s.SpellLevel) * float64(itemLevel) * qualModifier[itemQuality])
s.EffectBasePoints1 = int(float64(s.EffectBasePoints1) / float64(fromItemLevel) * float64(itemLevel) * qualModifier[itemQuality] * 2)
didScale = true
}
// Damage Shield Increase Scale due to HP curve
if s.EffectAura1 != 0 && s.EffectAura1 == 15 && s.Effect1 == 6 {
s.EffectBasePoints1 = int(float64(s.EffectBasePoints1) / float64(s.SpellLevel) * float64(itemLevel) * qualModifier[itemQuality] * 1.50)
s.EffectBasePoints1 = int(float64(s.EffectBasePoints1) / float64(fromItemLevel) * float64(itemLevel) * qualModifier[itemQuality] * 1.50)
didScale = true
}
if !didScale {
return 0, fmt.Errorf("did not qualify to be scaled in ScaleSpell %v (%v)", s.Name, s.ID)
}
s.Scaled = true
return idBump + s.ID, nil
}