more refactoring to something i like better

This commit is contained in:
2024-08-21 23:07:35 -04:00
parent c2281e0c19
commit cd3715b13f
11 changed files with 282 additions and 169 deletions

View File

@@ -0,0 +1,93 @@
package config
var InvTypeModifiers = map[int]float64{
1: 0.813, // Head
2: 1.0, // Neck
3: 0.75, // Shoulder
5: 1.0, // Chest
6: 0.562, // Waist
7: 0.875, // Legs
8: 0.688, // Feet
9: 0.437, // Wrists
10: 0.625, // Hands
11: 1.0, // Finger
13: 0.42, // One-Hand (not to confuse with Off-Hand = 22)
14: 0.56, // Shield (class = armor, not weapon even if in weapon slot)
15: 0.32, // Ranged (Bows) (see also Ranged right = 26)
16: 0.56, // Back
17: 1.0, // Two-Hand
18: 1.0, // Bag (assuming same as Chest for simplicity)
19: 1.0, // Tabard (assuming same as Chest for simplicity)
20: 1.0, // Robe (see also Chest = 5)
21: 1.0, // Main hand
22: 0.42, // Off Hand weapons (see also One-Hand = 13)
23: 0.56, // Held in Off-Hand (class = armor, not weapon even if in weapon slot)
24: 1.0, // Ammo (assuming same as Chest for simplicity)
25: 0.32, // Thrown
26: 0.32, // Ranged right (Wands, Guns) (see also Ranged = 15)
27: 1.0, // Quiver (assuming same as Chest for simplicity)
}
var QualityModifiers = map[int]float64{
0: 1.0, // Common
1: 1.1, // Uncommon
2: 1.2, // Rare
3: 1.3, // Epic
4: 1.5, // Legendary
5: 1.7, // Artifact
}
var MaterialModifiers = map[int]float64{
1: 1.2, // Cloth
2: 2.2, // Leather
3: 4.75, // Mail
4: 9.0, // Plate
6: 20.0, // Plate
}
var StatModifiers = map[int]float64{
0: 1.0, // ITEM_MOD_MANA
1: 1.0, // ITEM_MOD_HEALTH
3: 1.0, // ITEM_MOD_AGILITY
4: 1.0, // ITEM_MOD_STRENGTH
5: 1.0, // ITEM_MOD_INTELLECT
6: 1.0, // ITEM_MOD_SPIRIT
7: 1.0, // ITEM_MOD_STAMINA
12: 1.0, // ITEM_MOD_DEFENSE_SKILL_RATING
13: 1.0, // ITEM_MOD_DODGE_RATING
14: 1.0, // ITEM_MOD_PARRY_RATING
15: 1.0, // ITEM_MOD_BLOCK_RATING
16: 1.0, // ITEM_MOD_HIT_MELEE_RATING
17: 1.0, // ITEM_MOD_HIT_RANGED_RATING
18: 1.0, // ITEM_MOD_HIT_SPELL_RATING
19: 1.0, // ITEM_MOD_CRIT_MELEE_RATING
20: 1.0, // ITEM_MOD_CRIT_RANGED_RATING
21: 1.0, // ITEM_MOD_CRIT_SPELL_RATING
22: 1.0, // ITEM_MOD_HIT_TAKEN_MELEE_RATING
23: 1.0, // ITEM_MOD_HIT_TAKEN_RANGED_RATING
24: 1.0, // ITEM_MOD_HIT_TAKEN_SPELL_RATING
25: 1.0, // ITEM_MOD_CRIT_TAKEN_MELEE_RATING
26: 1.0, // ITEM_MOD_CRIT_TAKEN_RANGED_RATING
27: 1.0, // ITEM_MOD_CRIT_TAKEN_SPELL_RATING
28: 1.0, // ITEM_MOD_HASTE_MELEE_RATING
29: 1.0, // ITEM_MOD_HASTE_RANGED_RATING
30: 1.0, // ITEM_MOD_HASTE_SPELL_RATING
31: 1.0, // ITEM_MOD_HIT_RATING
32: 1.0, // ITEM_MOD_CRIT_RATING
33: 1.0, // ITEM_MOD_HIT_TAKEN_RATING
34: 1.0, // ITEM_MOD_CRIT_TAKEN_RATING
35: 1.0, // ITEM_MOD_RESILIENCE_RATING
36: 1.0, // ITEM_MOD_HASTE_RATING
37: 1.0, // ITEM_MOD_EXPERTISE_RATING
38: 0.5, // ITEM_MOD_ATTACK_POWER
39: 0.5, // ITEM_MOD_RANGED_ATTACK_POWER
40: 0.5, // ITEM_MOD_FERAL_ATTACK_POWER (not used as of 3.3)
41: 0.5, // ITEM_MOD_SPELL_HEALING_DONE
42: 0.5, // ITEM_MOD_SPELL_DAMAGE_DONE
43: 2.5, // ITEM_MOD_MANA_REGENERATION
44: 1.0, // ITEM_MOD_ARMOR_PENETRATION_RATING
45: 0.5, // ITEM_MOD_SPELL_POWER
46: 1.0, // ITEM_MOD_HEALTH_REGEN
47: 2.0, // ITEM_MOD_SPELL_PENETRATION
48: 0.65, // ITEM_MOD_BLOCK_VALUE
}

View File

@@ -5,6 +5,7 @@ import (
"fmt"
"github.com/araxiaonline/endgame-item-generator/import/utils"
"github.com/araxiaonline/endgame-item-generator/internal/pkg/db"
_ "github.com/go-sql-driver/mysql"
_ "github.com/jmoiron/sqlx"
)
@@ -16,34 +17,17 @@ type Boss struct {
ExperienceModifier int `db:"ExperienceModifier"`
}
func (db Database) GetBosses(mapId int) ([]Boss, error) {
type MySql struct {
*db.MySql
}
if mapId == 0 {
return nil, errors.New("mapId cannot be 0")
}
bosses := []Boss{}
var sql string
// 540 is pre-classic dungeons so XP Multiplier is best way to determine bosses / rare mobs
if mapId < 540 {
sql = `
SELECT ct.entry, ct.name, ct.ScriptName, ct.ExperienceModifier from acore_world.creature c
JOIN acore_world.creature_template ct ON(c.id1 = ct.entry) WHERE map = ? and ExperienceModifier >= 2;
`
} else {
sql = `
SELECT ct.entry, ct.name, ct.ScriptName, ct.ExperienceModifier from acore_world.creature c
JOIN acore_world.creature_template ct ON(c.id1 = ct.entry) WHERE map = ? and ct.ScriptName Like 'boss_%'
`
}
err := db.client.Select(&bosses, sql, mapId)
// NewMySql initializes the MySql struct with the MySQL connection instance
func NewMySql() (*MySql, error) {
client, err := db.ConnectMySql(nil)
if err != nil {
return nil, err
}
return bosses, nil
return &MySql{MySql: client}, nil
}
func (db Database) GetBossLoot(bossId int) ([]Item, error) {

View File

@@ -0,0 +1,103 @@
package creatures
import (
"errors"
"fmt"
"github.com/araxiaonline/endgame-item-generator/internal/items"
"github.com/araxiaonline/endgame-item-generator/internal/pkg/db"
)
type MySql struct {
*db.MySql
}
func (db *MySql) GetBosses(mapId int) ([]Boss, error) {
if mapId == 0 {
return nil, errors.New("mapId cannot be 0")
}
bosses := []Boss{}
var sql string
// 540 is pre-classic dungeons so XP Multiplier is best way to determine bosses / rare mobs
if mapId < 540 {
sql = `
SELECT ct.entry, ct.name, ct.ScriptName, ct.ExperienceModifier from acore_world.creature c
JOIN acore_world.creature_template ct ON(c.id1 = ct.entry) WHERE map = ? and ExperienceModifier >= 2;
`
} else {
sql = `
SELECT ct.entry, ct.name, ct.ScriptName, ct.ExperienceModifier from acore_world.creature c
JOIN acore_world.creature_template ct ON(c.id1 = ct.entry) WHERE map = ? and ct.ScriptName Like 'boss_%'
`
}
err := db.Select(&bosses, sql, mapId)
if err != nil {
return nil, err
}
return bosses, nil
}
func (db *MySql) GetBossLoot(bossId int) ([]items.Item, error) {
if bossId == 0 {
return nil, errors.New("bossId cannot be 0")
}
// This will first find items that are not in the reference boss loot table
items := []items.Item{}
fields := items.GetItemFields("")
sql := `
SELECT ` + fields + `
from acore_world.item_template
where
entry in
(SELECT item from acore_world.creature_loot_template where entry = ? and GroupId != 0 and Reference = 0)
and Quality > 2
`
udb := db.client.Unsafe()
err := udb.Select(&items, sql, bossId)
if err != nil {
return nil, err
}
// Get all the boss reference items now
var references []int
sql = `
SELECT reference
FROM acore_world.creature_loot_template
WHERE entry = ? AND Reference != 0
`
err = db.client.Select(&references, sql, bossId)
if err != nil {
return nil, fmt.Errorf("failed to get references: %v sql %s", err, sql)
}
if len(references) == 0 {
return items, nil
}
refItems := []items.Item{}
// For each reference we now need to get the items and add them to the items slice
for _, ref := range references {
sql = `
SELECT ` + items.GetItemFields("it") + `
FROM acore_world.reference_loot_template rlt
JOIN acore_world.item_template it ON rlt.Item = it.entry
WHERE rlt.Entry = ? and it.Quality > 2 and it.StatsCount > 0
`
err = db.client.Select(&refItems, sql, ref)
if err != nil {
return nil, fmt.Errorf("failed to get ref items: %v sql %s", err, sql)
}
items = append(items, refItems...)
}
return items, nil
}

View File

@@ -3,9 +3,14 @@ package maps
import (
"fmt"
"github.com/araxiaonline/endgame-item-generator/utils"
"github.com/araxiaonline/endgame-item-generator/internal/items"
"github.com/araxiaonline/endgame-item-generator/internal/pkg/db"
)
type MySql struct {
*db.MySql
}
type Dungeon struct {
Id int `db:"Id"`
Name string `db:"Name"`
@@ -74,7 +79,7 @@ var dungeonLevels = map[int]int{
668: 80, // Halls of Reflection
}
func (db Database) GetDungeons(expansionId int) ([]Dungeon, error) {
func (db *MySql) GetDungeons(expansionId int) ([]Dungeon, error) {
dungeons := []Dungeon{}
sql := `
@@ -85,9 +90,9 @@ func (db Database) GetDungeons(expansionId int) ([]Dungeon, error) {
var err error
if expansionId != -1 {
sql = sql + "AND ExpansionID = ?"
err = db.client.Select(&dungeons, sql, expansionId)
err = db.Select(&dungeons, sql, expansionId)
} else {
err = db.client.Select(&dungeons, sql)
err = db.Select(&dungeons, sql)
}
if err != nil {
@@ -103,11 +108,13 @@ func (db Database) GetDungeons(expansionId int) ([]Dungeon, error) {
return dungeons, nil
}
func (db Database) GetAddlDungeonDrops(instanceId int) ([]Item, error) {
// Gets a list of other rare+ items that drop in a specific instance.
func (db *MySql) GetAddlDungeonDrops(instanceId int) ([]items.Item, error) {
var items []Item
fields := items.GetItemFields("it")
var items []items.Item
sql := fmt.Sprintf(`
SELECT `+utils.GetItemFields("it")+`
SELECT `+fields+`
from
acore_world.map_dbc m
join acore_world.creature c on m.ID = c.map
@@ -118,7 +125,7 @@ from
WHERE m.ID = %v and Quality >= 3 and it.bonding = 2 and class IN(2,4)
UNION
SELECT `+utils.GetItemFields("it")+`
SELECT `+fields+`
from
acore_world.map_dbc m
join acore_world.creature c on m.ID = c.map
@@ -127,7 +134,7 @@ from
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")+`
SELECT `+fields+`
from
acore_world.map_dbc m
join acore_world.gameobject go on m.ID = go.map
@@ -140,7 +147,7 @@ where m.ID = %v and Quality >=3 and it.bonding IN(1,2) and it.class IN(2,4);
// log.Printf("sql: %s", sql)
err := db.client.Select(&items, sql)
err := db.Select(&items, sql)
if err != nil {
return nil, fmt.Errorf("failed to get additional dungeon items: %v ", err)
}

View File

@@ -7,8 +7,8 @@ import (
"github.com/jmoiron/sqlx"
)
type MySql struct {
client *sqlx.DB
type MySqlDb struct {
*sqlx.DB
}
type MySqlConfig struct {
@@ -18,7 +18,9 @@ type MySqlConfig struct {
Database string
}
func ConnectMySql(config *MySqlConfig) (*MySql, error) {
var MySql MySqlDb
func ConnectMySql(config *MySqlConfig) (*MySqlDb, error) {
if config == nil {
config = &MySqlConfig{
@@ -35,9 +37,10 @@ func ConnectMySql(config *MySqlConfig) (*MySql, error) {
return nil, err
}
return &MySql{client: client}, nil
Conn = &MySql{client}
return Conn, nil
}
func (db *MySql) Close() {
db.client.Close()
db.Close()
}

View File

@@ -2,8 +2,32 @@ package spells
import (
"fmt"
"strconv"
"github.com/araxiaonline/endgame-item-generator/internal/pkg/db"
)
type MySql struct {
*db.MySql
}
func (db *MySql) GetSpell(id int) (Spell, error) {
if id == 0 {
return Spell{}, fmt.Errorf("id cannot be 0")
}
spell := Spell{}
sql := "SELECT " + GetSpellFields() + " FROM `spell_dbc` WHERE ID = ? -- " + strconv.Itoa(id)
err := db.Get(&spell, sql, id)
if err != nil {
return Spell{}, fmt.Errorf("failed to get spell: %v", err)
}
return spell, nil
}
func GetSpellFields() string {
return `
ID,

View File

@@ -8,6 +8,8 @@ import (
"math/rand/v2"
"reflect"
"slices"
"github.com/araxiaonline/endgame-item-generator/internal/spells"
)
/**
@@ -67,7 +69,7 @@ type Item struct {
SpellTrigger3 *int `db:"spelltrigger_3"`
StatsMap map[int]*ItemStat
ConvStatCount int
Spells []Spell
Spells []spells.Spell
}
// Use for storing item stats for all stats that will be scaled.
@@ -78,98 +80,6 @@ type ItemStat struct {
AdjValue float64
}
var InvTypeModifiers = map[int]float64{
1: 0.813, // Head
2: 1.0, // Neck
3: 0.75, // Shoulder
5: 1.0, // Chest
6: 0.562, // Waist
7: 0.875, // Legs
8: 0.688, // Feet
9: 0.437, // Wrists
10: 0.625, // Hands
11: 1.0, // Finger
13: 0.42, // One-Hand (not to confuse with Off-Hand = 22)
14: 0.56, // Shield (class = armor, not weapon even if in weapon slot)
15: 0.32, // Ranged (Bows) (see also Ranged right = 26)
16: 0.56, // Back
17: 1.0, // Two-Hand
18: 1.0, // Bag (assuming same as Chest for simplicity)
19: 1.0, // Tabard (assuming same as Chest for simplicity)
20: 1.0, // Robe (see also Chest = 5)
21: 1.0, // Main hand
22: 0.42, // Off Hand weapons (see also One-Hand = 13)
23: 0.56, // Held in Off-Hand (class = armor, not weapon even if in weapon slot)
24: 1.0, // Ammo (assuming same as Chest for simplicity)
25: 0.32, // Thrown
26: 0.32, // Ranged right (Wands, Guns) (see also Ranged = 15)
27: 1.0, // Quiver (assuming same as Chest for simplicity)
}
var QualityModifiers = map[int]float64{
0: 1.0, // Common
1: 1.1, // Uncommon
2: 1.2, // Rare
3: 1.3, // Epic
4: 1.5, // Legendary
5: 1.7, // Artifact
}
var MaterialModifiers = map[int]float64{
1: 1.2, // Cloth
2: 2.2, // Leather
3: 4.75, // Mail
4: 9.0, // Plate
6: 20.0, // Plate
}
var StatModifiers = map[int]float64{
0: 1.0, // ITEM_MOD_MANA
1: 1.0, // ITEM_MOD_HEALTH
3: 1.0, // ITEM_MOD_AGILITY
4: 1.0, // ITEM_MOD_STRENGTH
5: 1.0, // ITEM_MOD_INTELLECT
6: 1.0, // ITEM_MOD_SPIRIT
7: 1.0, // ITEM_MOD_STAMINA
12: 1.0, // ITEM_MOD_DEFENSE_SKILL_RATING
13: 1.0, // ITEM_MOD_DODGE_RATING
14: 1.0, // ITEM_MOD_PARRY_RATING
15: 1.0, // ITEM_MOD_BLOCK_RATING
16: 1.0, // ITEM_MOD_HIT_MELEE_RATING
17: 1.0, // ITEM_MOD_HIT_RANGED_RATING
18: 1.0, // ITEM_MOD_HIT_SPELL_RATING
19: 1.0, // ITEM_MOD_CRIT_MELEE_RATING
20: 1.0, // ITEM_MOD_CRIT_RANGED_RATING
21: 1.0, // ITEM_MOD_CRIT_SPELL_RATING
22: 1.0, // ITEM_MOD_HIT_TAKEN_MELEE_RATING
23: 1.0, // ITEM_MOD_HIT_TAKEN_RANGED_RATING
24: 1.0, // ITEM_MOD_HIT_TAKEN_SPELL_RATING
25: 1.0, // ITEM_MOD_CRIT_TAKEN_MELEE_RATING
26: 1.0, // ITEM_MOD_CRIT_TAKEN_RANGED_RATING
27: 1.0, // ITEM_MOD_CRIT_TAKEN_SPELL_RATING
28: 1.0, // ITEM_MOD_HASTE_MELEE_RATING
29: 1.0, // ITEM_MOD_HASTE_RANGED_RATING
30: 1.0, // ITEM_MOD_HASTE_SPELL_RATING
31: 1.0, // ITEM_MOD_HIT_RATING
32: 1.0, // ITEM_MOD_CRIT_RATING
33: 1.0, // ITEM_MOD_HIT_TAKEN_RATING
34: 1.0, // ITEM_MOD_CRIT_TAKEN_RATING
35: 1.0, // ITEM_MOD_RESILIENCE_RATING
36: 1.0, // ITEM_MOD_HASTE_RATING
37: 1.0, // ITEM_MOD_EXPERTISE_RATING
38: 0.5, // ITEM_MOD_ATTACK_POWER
39: 0.5, // ITEM_MOD_RANGED_ATTACK_POWER
40: 0.5, // ITEM_MOD_FERAL_ATTACK_POWER (not used as of 3.3)
41: 0.5, // ITEM_MOD_SPELL_HEALING_DONE
42: 0.5, // ITEM_MOD_SPELL_DAMAGE_DONE
43: 2.5, // ITEM_MOD_MANA_REGENERATION
44: 1.0, // ITEM_MOD_ARMOR_PENETRATION_RATING
45: 0.5, // ITEM_MOD_SPELL_POWER
46: 1.0, // ITEM_MOD_HEALTH_REGEN
47: 2.0, // ITEM_MOD_SPELL_PENETRATION
48: 0.65, // ITEM_MOD_BLOCK_VALUE
}
// Get the primary stat for an item (strength, agility, intellect, spirit, stamina)
func (item Item) GetPrimaryStat() (int, int, error) {
var primaryStat int64
@@ -348,21 +258,6 @@ func (item *Item) ScaleDPS(level int) (float64, error) {
return dps, nil
}
func (d Database) GetItem(entry int) (Item, error) {
if entry == 0 {
return Item{}, fmt.Errorf("entry cannot be 0")
}
item := Item{}
sql := "SELECT " + utils.GetItemFields("") + " FROM item_template WHERE entry = ?"
err := d.client.Get(&item, sql, entry)
if err != nil {
return Item{}, err
}
return item, nil
}
// Create a Map of stat percentages based on the current stat and how budgets are caluated
func (item Item) GetStatPercents(spellStats []ConvItemStat) map[int]*ItemStat {
@@ -570,7 +465,7 @@ func (item *Item) ScaleItem(itemLevel int, itemQuality int) (bool, error) {
log.Printf("\n\n\n -------------------- COUNT OF other spells %v \n\n", len(otherSpells))
item.Spells = []Spell{}
item.Spells = []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)

View File

@@ -2,8 +2,29 @@ package items
import (
"fmt"
"github.com/araxiaonline/endgame-item-generator/internal/pkg/db"
)
type MySql struct {
*db.MySql
}
func (db *MySql) GetItem(entry int) (Item, error) {
if entry == 0 {
return Item{}, fmt.Errorf("entry cannot be 0")
}
item := Item{}
sql := "SELECT " + GetItemFields("") + " FROM item_template WHERE entry = ?"
err := db.Get(&item, sql, entry)
if err != nil {
return Item{}, err
}
return item, nil
}
func GetItemFields(prefix string) string {
pre := ""
if prefix != "" {

View File

@@ -4,9 +4,9 @@ import (
"fmt"
"log"
"math"
"strconv"
"strings"
"github.com/araxiaonline/endgame-item-generator/internal/config"
"github.com/thoas/go-funk"
)
@@ -35,6 +35,7 @@ var SpellAuraEffects = [...]int{
189, // Modifies Critical Strike
}
// Mapping of spell aura effects to stat types they modify
var AuraEffectsStatMap = map[int]int{
8: 46,
13: 45,
@@ -122,23 +123,6 @@ type Spell struct {
Scaled bool
}
func (db Database) GetSpell(id int) (Spell, error) {
if id == 0 {
return Spell{}, fmt.Errorf("id cannot be 0")
}
spell := Spell{}
sql := "SELECT " + GetSpellFields() + " FROM `spell_dbc` WHERE ID = ? -- " + strconv.Itoa(id)
err := db.client.Get(&spell, sql, id)
if err != nil {
return Spell{}, fmt.Errorf("failed to get spell: %v", err)
}
return spell, nil
}
func calcMaxValue(base int, sides int) int {
if base < 0 {
return base - sides
@@ -288,7 +272,7 @@ func (s Spell) ConvertToStats() ([]ConvItemStat, error) {
// Wotlk changed everything to spell power so might as well do the same in
// scaling process.
seen = append(seen, statId)
statMod := float64(StatModifiers[statId])
statMod := float64(config.StatModifiers[statId])
stats = append(stats, ConvItemStat{
StatType: statId,
StatValue: e.CalculatedMax,
@@ -309,7 +293,7 @@ func (s Spell) ConvertToStats() ([]ConvItemStat, error) {
stats = append(stats, ConvItemStat{
StatType: statId,
StatValue: calced,
Budget: int(math.Abs(math.Ceil(float64(calced) * float64(StatModifiers[statId])))),
Budget: int(math.Abs(math.Ceil(float64(calced) * float64(config.StatModifiers[statId])))),
})
}

View File

@@ -1 +0,0 @@
package utils