diff --git a/models/creatures.go b/models/creatures.go index 3d865cc..d671b29 100644 --- a/models/creatures.go +++ b/models/creatures.go @@ -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() diff --git a/models/items.go b/models/items.go index 1f08a6e..eda80c4 100644 --- a/models/items.go +++ b/models/items.go @@ -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) diff --git a/models/maps.go b/models/maps.go index f4ed6c5..05700fe 100644 --- a/models/maps.go +++ b/models/maps.go @@ -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 +} diff --git a/models/spells.go b/models/spells.go index bbb044d..f1d1ac1 100644 --- a/models/spells.go +++ b/models/spells.go @@ -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 }