From 136f784925ccc6ea84b3f3c77ed2e3b5a458b91a Mon Sep 17 00:00:00 2001 From: Ben Echols Date: Sun, 4 Apr 2021 19:13:43 -0600 Subject: [PATCH] started gems and made CDs int --- itemparser/main.go | 7 +- main.go | 6 +- tbc/auras.go | 147 ++++++++++++++++++++++++------ tbc/buffs.go | 162 +++++++++++++++++++++++++++++++++ tbc/items.go | 66 ++++++++++---- tbc/sim.go | 218 +++++++++------------------------------------ tbc/sim1.go | 87 ------------------ tbc/sim2.go | 24 +++-- tbc/spells.go | 28 +++--- tbc/stats.go | 4 +- ui/lib.wasm | Bin 2865407 -> 2859312 bytes ui/main_wasm.go | 10 +-- web.go | 56 +----------- 13 files changed, 414 insertions(+), 401 deletions(-) delete mode 100644 tbc/sim1.go diff --git a/itemparser/main.go b/itemparser/main.go index 21735b8..fa7a7b5 100644 --- a/itemparser/main.go +++ b/itemparser/main.go @@ -41,7 +41,7 @@ func main() { // Another header row... continue } - if v[0] != "" && v[1] == "" && v[2] == "" { + if v[0] != "" && v[2] == "" { // Change slot switch v[0] { case "Helm", "Head": @@ -87,6 +87,10 @@ func main() { haste, _ := strconv.ParseFloat(v[8], 64) // spp, _ := strconv.ParseFloat(v[], 64) + numRed. _ := strconv.Atoi(v[12]) + numRed. _ := strconv.Atoi(v[13]) + numRed. _ := strconv.Atoi(v[14]) + numRed. _ := strconv.Atoi(v[15]) i := tbc.Item{ Name: v[1], SourceZone: v[2], @@ -100,6 +104,7 @@ func main() { tbc.StatHaste: haste, tbc.StatMP5: mp5, }, + GemSlots: , } fmt.Fprintf(os.Stdout, "%#v,\n", i) diff --git a/main.go b/main.go index 71f5256..334d088 100644 --- a/main.go +++ b/main.go @@ -86,7 +86,7 @@ func main() { ) gearStats := gear.Stats() - fmt.Printf("Gear Stats:\n%s", gearStats.Print()) + fmt.Printf("Gear Stats:\n%s", gearStats.Print(true)) opt := tbc.Options{ NumBloodlust: 1, @@ -155,14 +155,14 @@ func runTBCSim(equip tbc.Equipment, opt tbc.Options, seconds int, numSims int, c spellOrders = [][]string{customRotation} } - fmt.Printf("\nFinal Stats: %s\n", stats.Print()) + fmt.Printf("\nFinal Stats: %s\n", stats.Print(true)) statchan := make(chan string, 3) for spi, spells := range spellOrders { go func(spo []string) { simDmgs := []float64{} simOOMs := []int{} histogram := map[int]int{} - casts := map[string]int{} + casts := map[int32]int{} manaSpent := 0.0 manaLeft := 0.0 oomdps := 0.0 diff --git a/tbc/auras.go b/tbc/auras.go index 16b1438..d74990e 100644 --- a/tbc/auras.go +++ b/tbc/auras.go @@ -2,11 +2,10 @@ package tbc import ( "math" - "strings" ) type Aura struct { - ID string + ID int32 Expires int // ticks aura will apply OnCast AuraEffect @@ -19,12 +18,46 @@ type Aura struct { // AuraEffects will mutate a cast or simulation state. type AuraEffect func(sim *Simulation, c *Cast) +// List of all magic effects and spells and items and stuff that can go on CD or have an aura. +const ( + MagicIDUnknown int32 = iota + // Auras + MagicIDLOTalent + MagicIDJoW + MagicIDEleFocus + MagicIDEleMastery + MagicIDStormcaller + MagicIDSilverCrescent + MagicIDQuagsEye + MagicIDFungalFrenzy + MagicIDBloodlust + MagicIDSkycall + MagicIDEnergized + MagicIDNAC + MagicIDChaoticSkyfire + MagicIDInsightfulEarthstorm + MagicIDMysticSkyfire + MagicIDMysticFocus + MagicIDEmberSkyfire + + //Spells + MagicIDLB12 + MagicIDCL6 + + //Items + MagicIDISCTrink + MagicIDNACTrink + MagicIDPotion + MagicIDRune + MagicIDAllTrinket +) + func AuraJudgementOfWisdom() Aura { return Aura{ - ID: "jow", + ID: MagicIDJoW, Expires: math.MaxInt32, OnSpellHit: func(sim *Simulation, c *Cast) { - debug(" -Judgement Of Wisdom +74 mana- ") + sim.debug(" -Judgement Of Wisdom +74 mana- \n") sim.CurrentMana += 74 }, } @@ -32,19 +65,23 @@ func AuraJudgementOfWisdom() Aura { func AuraLightningOverload(lvl int) Aura { return Aura{ - ID: "lotalent", + ID: MagicIDLOTalent, Expires: math.MaxInt32, OnSpellHit: func(sim *Simulation, c *Cast) { - if !strings.HasPrefix(c.Spell.ID, "LB") && !strings.HasPrefix(c.Spell.ID, "CL") { + if c.Spell.ID == MagicIDLB12 || c.Spell.ID == MagicIDCL6 { return } + if c.isLO { + return // can't proc LO on LO + } if sim.rando.Float64() < 0.04*float64(lvl) { - debug("\tLightning Overload...") + sim.debug("Lightning Overload Proc\n") dmg := c.DidDmg if c.DidCrit { dmg /= 2 } clone := &Cast{ + isLO: true, Spell: c.Spell, Hit: c.Hit, Crit: c.Crit, @@ -65,7 +102,7 @@ func AuraLightningOverload(lvl int) Aura { func AuraElementalFocus(tick int) Aura { count := 2 return Aura{ - ID: "elefocus", + ID: MagicIDEleFocus, Expires: tick + (15 * TicksPerSecond), OnCast: func(sim *Simulation, c *Cast) { c.ManaCost *= .6 // reduced by 40% @@ -76,7 +113,7 @@ func AuraElementalFocus(tick int) Aura { } count-- if count == 0 { - sim.cleanAuraName("elefocus") + sim.cleanAuraName(MagicIDEleFocus) } }, } @@ -84,35 +121,35 @@ func AuraElementalFocus(tick int) Aura { func AuraEleMastery() Aura { return Aura{ - ID: "elemastery", + ID: MagicIDEleMastery, Expires: math.MaxInt32, OnCast: func(sim *Simulation, c *Cast) { - debug(" -ele mastery active- ") + sim.debug(" -ele mastery active- \n") c.Crit = 1.01 // 101% chance of crit c.ManaCost = 0 - sim.CDs["elemastery"] = 180 * TicksPerSecond + sim.CDs[MagicIDEleMastery] = 180 * TicksPerSecond }, OnCastComplete: func(sim *Simulation, c *Cast) { - sim.cleanAuraName("elemastery") + sim.cleanAuraName(MagicIDEleMastery) }, } } func AuraStormcaller(tick int) Aura { return Aura{ - ID: "stormcaller", + ID: MagicIDStormcaller, Expires: tick + (8 * TicksPerSecond), OnCast: func(sim *Simulation, c *Cast) { - debug(" -stormcaller- ") + sim.debug(" -stormcaller- \n") c.Spellpower += 50 }, } } func ActivateSilverCrescent(sim *Simulation) Aura { - debug(" -silver crescent active- ") + sim.debug(" -silver crescent active- \n") return Aura{ - ID: "silvercrescent", + ID: MagicIDSilverCrescent, Expires: sim.currentTick + 20*TicksPerSecond, OnCast: func(sim *Simulation, c *Cast) { c.Spellpower += 155 @@ -124,20 +161,20 @@ func ActivateQuagsEye(sim *Simulation) Aura { lastActivation := math.MinInt32 const hasteBonus = 320.0 return Aura{ - ID: "quageye", + ID: MagicIDQuagsEye, Expires: math.MaxInt32, OnCastComplete: func(sim *Simulation, c *Cast) { if lastActivation+(45*TicksPerSecond) < sim.currentTick && sim.rando.Float64() < 0.1 { - debug(" -quags eye- ") + sim.debug(" -quags eye- \n") sim.Buffs[StatHaste] += hasteBonus - sim.addAura(AuraHasteRemoval(sim.currentTick, 6.0, hasteBonus, "fungalfrenzy")) + sim.addAura(AuraHasteRemoval(sim.currentTick, 6.0, hasteBonus, MagicIDFungalFrenzy)) lastActivation = sim.currentTick } }, } } -func AuraHasteRemoval(tick int, seconds int, amount float64, id string) Aura { +func AuraHasteRemoval(tick int, seconds int, amount float64, id int32) Aura { return Aura{ ID: id, Expires: tick + (seconds * TicksPerSecond), @@ -148,31 +185,31 @@ func AuraHasteRemoval(tick int, seconds int, amount float64, id string) Aura { } func ActivateBloodlust(sim *Simulation) Aura { - debug(" -BL Activated- ") + sim.debug(" -BL Activated- \n") sim.Buffs[StatHaste] += 472.8 - sim.CDs["bloodlust"] = 40 * TicksPerSecond // assumes that multiple BLs are different shaman. - return AuraHasteRemoval(sim.currentTick, 40, 472.8, "bloodlust") + sim.CDs[MagicIDBloodlust] = 40 * TicksPerSecond // assumes that multiple BLs are different shaman. + return AuraHasteRemoval(sim.currentTick, 40, 472.8, MagicIDBloodlust) } func ActivateSkycall(sim *Simulation) Aura { const hasteBonus = 101 return Aura{ - ID: "skycall", + ID: MagicIDSkycall, Expires: math.MaxInt32, OnCastComplete: func(sim *Simulation, c *Cast) { if sim.rando.Float64() < 0.1 { // TODO: what is actual proc rate? - debug(" -skycall energized- ") + sim.debug(" -skycall energized- \n") sim.Buffs[StatHaste] += hasteBonus - sim.addAura(AuraHasteRemoval(sim.currentTick, 10, hasteBonus, "energized")) + sim.addAura(AuraHasteRemoval(sim.currentTick, 10, hasteBonus, MagicIDEnergized)) } }, } } func ActivateNAC(sim *Simulation) Aura { - debug(" -NAC active- ") + sim.debug(" -NAC active- \n") return Aura{ - ID: "nac", + ID: MagicIDNAC, Expires: sim.currentTick + 300*TicksPerSecond, OnCast: func(sim *Simulation, c *Cast) { c.Spellpower += 250 @@ -180,3 +217,55 @@ func ActivateNAC(sim *Simulation) Aura { }, } } + +func ActivateCSD(sim *Simulation) Aura { + return Aura{ + ID: MagicIDChaoticSkyfire, + Expires: math.MaxInt32, + OnCastComplete: func(sim *Simulation, c *Cast) { + if c.DidCrit { + c.DidDmg *= 1.09 // 150% crit * 1.03 = 154.5% crit dmg. Double crit dmg talent *= 2 -> 309-100 = x2.09. Crit calc earlier added the x2. We just add the 0.09 + } + }, + } +} + +func ActivateIED(sim *Simulation) Aura { + lastActivation := math.MinInt32 + return Aura{ + ID: MagicIDInsightfulEarthstorm, + Expires: math.MaxInt32, + OnCastComplete: func(sim *Simulation, c *Cast) { + if lastActivation+(15*TicksPerSecond) < sim.currentTick && sim.rando.Float64() < 0.04 { + lastActivation = sim.currentTick + sim.debug(" -Insightful Earthstorm Mana Restore- \n") + sim.CurrentMana += 300 + } + }, + } +} + +func ActivateMSD(sim *Simulation) Aura { + lastActivation := math.MinInt32 + const hasteBonus = 320.0 + return Aura{ + ID: MagicIDMysticSkyfire, + Expires: math.MaxInt32, + OnCastComplete: func(sim *Simulation, c *Cast) { + if lastActivation+(45*TicksPerSecond) < sim.currentTick && sim.rando.Float64() < 0.1 { + sim.debug(" -mystic skyfire- \n") + sim.Buffs[StatHaste] += hasteBonus + sim.addAura(AuraHasteRemoval(sim.currentTick, 4.0, hasteBonus, MagicIDMysticFocus)) + lastActivation = sim.currentTick + } + }, + } +} + +func ActivateESD(sim *Simulation) Aura { + sim.Buffs[StatInt] += (sim.Stats[StatInt] + sim.Buffs[StatInt]) * 0.02 + return Aura{ + ID: MagicIDEmberSkyfire, + Expires: math.MaxInt32, + } +} diff --git a/tbc/buffs.go b/tbc/buffs.go index a210dad..ddb76ac 100644 --- a/tbc/buffs.go +++ b/tbc/buffs.go @@ -1 +1,163 @@ package tbc + +import "fmt" + +type Options struct { + SpellOrder []string + RSeed int64 + ExitOnOOM bool + + NumBloodlust int + NumDrums int + + Buffs Buffs + Consumes Consumes + Talents Talents + Totems Totems + + Debug bool // enables debug printing. + // TODO: could change this to be a func/stream consumer could provide, + // make it easier to integrate into different output systems. +} + +func (o Options) StatTotal(e Equipment) Stats { + gearStats := e.Stats() + stats := o.BaseStats() + for i := range stats { + stats[i] += gearStats[i] + } + + stats = o.Talents.AddStats(o.Buffs.AddStats(o.Consumes.AddStats(o.Totems.AddStats(stats)))) + + if o.Buffs.BlessingOfKings { + stats[StatInt] *= 1.1 // blessing of kings + } + + // Final calculations + stats[StatSpellCrit] += (stats[StatInt] / 80) / 100 + stats[StatMana] += stats[StatInt] * 15 + fmt.Printf("\fFinal MP5: %f", (stats[StatMP5] + (stats[StatInt] * 0.06))) + + return stats +} + +func (o Options) BaseStats() Stats { + stats := Stats{ + StatInt: 104, // Base + StatMana: 2958, // level 70 shaman + StatLen: 0, + } + return stats +} + +type Totems struct { + TotemOfWrath int + WrathOfAir bool + ManaStream bool +} + +func (tt Totems) AddStats(s Stats) Stats { + s[StatSpellCrit] += 66.24 * float64(tt.TotemOfWrath) + s[StatSpellHit] += 37.8 * float64(tt.TotemOfWrath) + if tt.WrathOfAir { + s[StatSpellDmg] += 104 + } + if tt.ManaStream { + s[StatMP5] += 50 + } + return s +} + +type Talents struct { + LightninOverload int + ElementalPrecision int + NaturesGuidance int + TidalMastery int + ElementalMastery bool + UnrelentingStorm int + CallOfThunder int + Convection int + Concussion int +} + +func (t Talents) AddStats(s Stats) Stats { + s[StatSpellHit] += 25.2 * float64(t.ElementalPrecision) + s[StatSpellHit] += 12.6 * float64(t.NaturesGuidance) + s[StatSpellCrit] += 22.08 * float64(t.TidalMastery) + s[StatSpellCrit] += 22.08 * float64(t.CallOfThunder) + + return s +} + +type Buffs struct { + // Raid buffs + ArcaneInt bool + GiftOftheWild bool + BlessingOfKings bool + ImprovedBlessingOfWisdom bool + + // Party Buffs + Moonkin bool + SpriestDPS int // adds Mp5 ~ 25% (dps*5%*5sec = 25%) + + // Self Buffs + WaterShield bool + WaterShieldPPM int // how many procs per minute does watershield get? Every 3 requires a recast. + + // Target Debuff + JudgementOfWisdom bool +} + +func (b Buffs) AddStats(s Stats) Stats { + if b.ArcaneInt { + s[StatInt] += 40 + } + if b.GiftOftheWild { + s[StatInt] += 18 // assumes improved gotw, rounded down to nearest int... not sure if that is accurate. + } + if b.ImprovedBlessingOfWisdom { + s[StatMP5] += 42 + } + if b.Moonkin { + s[StatSpellCrit] += 110.4 + } + if b.WaterShield { + s[StatMP5] += 50 + } + s[StatMP5] += float64(b.SpriestDPS) * 0.25 + + return s +} + +type Consumes struct { + // Buffs + BrilliantWizardOil bool + MajorMageblood bool + FlaskOfBlindingLight bool + FlaskOfMightyRestoration bool + BlackendBasilisk bool + + // Used in rotations + SuperManaPotion bool + DarkRune bool +} + +func (c Consumes) AddStats(s Stats) Stats { + if c.BrilliantWizardOil { + s[StatSpellCrit] += 14 + s[StatSpellDmg] += 36 + } + if c.MajorMageblood { + s[StatMP5] += 16.0 + } + if c.FlaskOfBlindingLight { + s[StatSpellDmg] += 80 + } + if c.FlaskOfMightyRestoration { + s[StatMP5] += 25 + } + if c.BlackendBasilisk { + s[StatSpellDmg] += 23 + } + return s +} diff --git a/tbc/items.go b/tbc/items.go index 4117257..8f880b3 100644 --- a/tbc/items.go +++ b/tbc/items.go @@ -298,9 +298,9 @@ var items = struct { {Slot: EquipTrinket, Name: "Quagmirran's Eye", SourceZone: "The Slave Pens", SourceDrop: "Quagmirran", Stats: Stats{StatSpellDmg: 37}, Activate: ActivateQuagsEye, ActivateCD: -1}, // -1 will trigger an activation only once {Slot: EquipTrinket, Name: "Icon of the Silver Crescent", SourceZone: "Shattrath", SourceDrop: "G'eras - 41 Badges", Stats: Stats{StatSpellDmg: 44}, - Activate: ActivateSilverCrescent, ActivateCD: 120 * TicksPerSecond, CoolID: "icsctrink"}, + Activate: ActivateSilverCrescent, ActivateCD: 120 * TicksPerSecond, CoolID: MagicIDISCTrink}, {Slot: EquipTrinket, Name: "Natural Alignment Crystal", SourceZone: "BWL", SourceDrop: "", Stats: Stats{}, - Activate: ActivateNAC, ActivateCD: 300 * TicksPerSecond, CoolID: "nactrink"}, + Activate: ActivateNAC, ActivateCD: 300 * TicksPerSecond, CoolID: MagicIDNACTrink}, {Slot: EquipTrinket, Name: "Neltharion's Tear", SourceZone: "BWL", SourceDrop: "Nefarian", Stats: Stats{StatSpellDmg: 44, StatSpellHit: 16}}, }, Totem: []Item{ @@ -309,6 +309,27 @@ var items = struct { }, } +var Gems = []Gem{ + // {Name: "Destructive Skyfire Diamond", Color: GemColorMeta, Stats: Stats{}}, + // {Name: "Enigmatic Skyfire Diamond", Color: GemColorMeta, Stats: Stats{}}, + {Name: "Chaotic Skyfire Diamond", Color: GemColorMeta, Stats: Stats{StatSpellCrit: 12}, Activate: ActivateCSD}, + // {Name: "Swift Skyfire Diamond", Color: GemColorMeta, Stats: Stats{}}, + // {Name: "Potent Unstable Diamond", Color: GemColorMeta, Stats: Stats{}}, + // {Name: "Swift Windfire Diamond", Color: GemColorMeta, Stats: Stats{}}, + // {Name: "Powerful Earthstorm Diamond", Color: GemColorMeta, Stats: Stats{}}, + {Name: "Bracing Earthstorm Diamond", Color: GemColorMeta, Stats: Stats{StatSpellDmg: 14}}, + {Name: "Imbued Unstable Diamond", Color: GemColorMeta, Stats: Stats{StatSpellDmg: 14}}, + {Name: "Ember Skyfire Diamond", Color: GemColorMeta, Stats: Stats{StatSpellDmg: 14}, Activate: ActivateESD}, + {Name: "Swift Starfire Diamond", Color: GemColorMeta, Stats: Stats{StatSpellDmg: 12}}, + {Name: "Mystical Skyfire Diamond", Color: GemColorMeta, Stats: Stats{}, Activate: ActivateMSD}, + // {Name: "Thundering Skyfire Diamond", Color: GemColorMeta, Stats: Stats{}}, + // {Name: "Relentless Earthstorm Diamond", Color: GemColorMeta, Stats: Stats{}}, + // {Name: "Tenacious Earthstorm Diamond", Color: GemColorMeta, Stats: Stats{}}, + // {Name: "Eternal Earthstorm Diamond", Color: GemColorMeta, Stats: Stats{}}, + // {Name: "Brutal Earthstorm Diamond", Color: GemColorMeta, Stats: Stats{}}, + {Name: "Insightful Earthstorm Diamond", Color: GemColorMeta, Stats: Stats{StatInt: 12}, Activate: ActivateIED}, +} + var ItemLookup = map[string]*Item{} func IL(name string) *Item { @@ -410,20 +431,45 @@ func init() { // Figurine - Living Ruby Serpent Jewelcarfting BoP 33 23 type Item struct { - Slot int + Slot byte Name string SourceZone string SourceDrop string Stats Stats // Stats applied to wearer + GemSlots []GemColor + Gems []Gem + SocketBonus Stats + // For simplicity all items that produce an aura are 'activatable'. // Since we activate all items on CD, this works fine for stuff like Quags Eye. // TODO: is this the best design for this? Activate ItemActivation // Activatable Ability, produces an aura ActivateCD int // cooldown on activation, -1 means perm effect. - CoolID string // ID used for cooldown + CoolID int32 // ID used for cooldown +} + +type Gem struct { + Name string + Stats Stats // flat stats gem adds + Activate ItemActivation // Meta gems activate an aura on player when socketed. + Color GemColor + // Requirements // Validate the gem can be used... later } +type GemColor byte + +const ( + GemColorUnknown GemColor = iota + GemColorMeta + GemColorRed + GemColorBlue + GemColorYellow + GemColorGreen + GemColorOrange + GemColorPurple +) + type ItemActivation func(*Simulation) Aura type Equipment []Item @@ -456,7 +502,7 @@ func NewEquipmentSet(names ...string) Equipment { } const ( - EquipUnknown int = iota + EquipUnknown byte = iota EquipHead EquipNeck EquipShoulder @@ -634,16 +680,6 @@ var moreItems = []Item{ {Slot: 11, Name: "Cobalt Band of Tyrigosa", SourceZone: "H MT - Nexus-Prince Shaffar", SourceDrop: "", Stats: Stats{17, 19, 0, 0, 35, 0, 0}}, {Slot: 11, Name: "Seal of the Exorcist", SourceZone: "50 Spirit Shards ", SourceDrop: "", Stats: Stats{0, 24, 0, 12, 28, 0, 0}}, {Slot: 11, Name: "Lola's Eve", SourceZone: "BoE World Drop", SourceDrop: "", Stats: Stats{14, 15, 0, 0, 29, 0, 0}}, - {Slot: 11, Name: "Yor's Collapsing Band", SourceZone: "H MT - Yor (Summoned Boss)", SourceDrop: "", Stats: Stats{20, 0, 0, 0, 23, 0, 0}}, - // {Slot: 11, Name: "Darkmoon Card: Crusade", SourceZone: "Blessings Deck", SourceDrop: "", Stats: Stats{0, 0, 0, 0, 0, 0, 0}}, - // {Slot: 11, Name: "Scryer's Bloodgem", SourceZone: "The Scryers - Revered", SourceDrop: "", Stats: Stats{0, 0, 0, 32, 0, 0, 0}}, - // {Slot: 11, Name: "Quagmirran's Eye", SourceZone: "H SP - Quagmirran", SourceDrop: "", Stats: Stats{0, 0, 0, 0, 37, 0, 0}}, - // {Slot: 11, Name: "Arcanist's Stone", SourceZone: "H OHF - Epoch Hunter", SourceDrop: "", Stats: Stats{0, 0, 0, 25, 0, 0, 0}}, - // {Slot: 11, Name: "Icon of the Silver Crescent", SourceZone: "41 Badge of Justice - G'eras", SourceDrop: "", Stats: Stats{0, 0, 0, 0, 43, 0, 0}}, - // {Slot: 11, Name: "Shiffar's Nexus-Horn", SourceZone: "Arc - Harbinger Skyriss", SourceDrop: "", Stats: Stats{0, 0, 30, 0, 0, 0, 0}}, - // {Slot: 11, Name: "Xi'ri's Gift", SourceZone: "The Sha'tar - Revered", SourceDrop: "", Stats: Stats{0, 0, 32, 0, 0, 0, 0}}, - // {Slot: 11, Name: "Vengeance of the Illidari", SourceZone: "Cruel's Intentions/Overlord - HFP Quest", SourceDrop: "", Stats: Stats{0, 0, 26, 0, 0, 0, 0}}, - // {Slot: 11, Name: "Figurine - Living Ruby Serpent", SourceZone: "Jewelcarfting BoP", SourceDrop: "", Stats: Stats{23, 33, 0, 0, 0, 0, 0}}, {Slot: 19, Name: "Totem of the Void", SourceZone: "Mech - Cache of the Legion", SourceDrop: "", Stats: Stats{StatSpellDmg: 55}}, // TODO: Make an aura that effects only LB/CL {Slot: 19, Name: "Totem of the Pulsing Earth", SourceZone: "15 Badge of Justice - G'eras", SourceDrop: "", Stats: Stats{0, 0, 0, 0, 0, 0, 0}}, {Slot: 19, Name: "Totem of Impact", SourceZone: "15 Mark of Thrallmar/ Honor Hold", SourceDrop: "", Stats: Stats{0, 0, 0, 0, 0, 0, 0}}, diff --git a/tbc/sim.go b/tbc/sim.go index 44c1d86..44481d8 100644 --- a/tbc/sim.go +++ b/tbc/sim.go @@ -4,14 +4,13 @@ import ( "fmt" "math" "math/rand" - "strings" ) var IsDebug = false -func debug(s string, vals ...interface{}) { - if IsDebug { - fmt.Printf(s, vals...) +func debugFunc(sim *Simulation) func(string, ...interface{}) { + return func(s string, vals ...interface{}) { + fmt.Printf("[%0.1f] "+s, append([]interface{}{(float64(sim.currentTick) / float64(TicksPerSecond))}, vals...)...) } } @@ -24,14 +23,14 @@ type Simulation struct { activeEquip Equipment // cache of gear that can activate. Options Options - SpellRotation []string + SpellRotation []int32 RotationIdx int // ticks until cast is complete CastingSpell *Cast // timeToRegen := 0 - CDs map[string]int + CDs map[int32]int Auras []Aura // this is array instaed of map to speed up browser perf. // Clears and regenerates on each Run call. @@ -40,6 +39,8 @@ type Simulation struct { rando *rand.Rand rseed int64 currentTick int + + debug func(string, ...interface{}) } type SimMetrics struct { @@ -51,162 +52,6 @@ type SimMetrics struct { Rotation []string } -type Options struct { - SpellOrder []string - RSeed int64 - ExitOnOOM bool - - NumBloodlust int - NumDrums int - - Buffs Buffs - Consumes Consumes - Talents Talents - Totems Totems -} - -func (o Options) StatTotal(e Equipment) Stats { - gearStats := e.Stats() - stats := o.BaseStats() - for i := range stats { - stats[i] += gearStats[i] - } - - stats = o.Talents.AddStats(o.Buffs.AddStats(o.Consumes.AddStats(o.Totems.AddStats(stats)))) - - if o.Buffs.BlessingOfKings { - stats[StatInt] *= 1.1 // blessing of kings - } - - // Final calculations - stats[StatSpellCrit] += (stats[StatInt] / 80) / 100 - stats[StatMana] += stats[StatInt] * 15 - fmt.Printf("\fFinal MP5: %f", (stats[StatMP5] + (stats[StatInt] * 0.06))) - - return stats -} - -func (o Options) BaseStats() Stats { - stats := Stats{ - StatInt: 104, // Base - StatMana: 2958, // level 70 shaman - StatLen: 0, - } - return stats -} - -type Totems struct { - TotemOfWrath int - WrathOfAir bool - ManaStream bool -} - -func (tt Totems) AddStats(s Stats) Stats { - s[StatSpellCrit] += 66.24 * float64(tt.TotemOfWrath) - s[StatSpellHit] += 37.8 * float64(tt.TotemOfWrath) - if tt.WrathOfAir { - s[StatSpellDmg] += 104 - } - if tt.ManaStream { - s[StatMP5] += 50 - } - return s -} - -type Talents struct { - LightninOverload int - ElementalPrecision int - NaturesGuidance int - TidalMastery int - ElementalMastery bool - UnrelentingStorm int - CallOfThunder int - Convection int - Concussion int -} - -func (t Talents) AddStats(s Stats) Stats { - s[StatSpellHit] += 25.2 * float64(t.ElementalPrecision) - s[StatSpellHit] += 12.6 * float64(t.NaturesGuidance) - s[StatSpellCrit] += 22.08 * float64(t.TidalMastery) - s[StatSpellCrit] += 22.08 * float64(t.CallOfThunder) - - return s -} - -type Buffs struct { - // Raid buffs - ArcaneInt bool - GiftOftheWild bool - BlessingOfKings bool - ImprovedBlessingOfWisdom bool - - // Party Buffs - Moonkin bool - SpriestDPS int // adds Mp5 ~ 25% (dps*5%*5sec = 25%) - - // Self Buffs - WaterShield bool - WaterShieldPPM int // how many procs per minute does watershield get? Every 3 requires a recast. - - // Target Debuff - JudgementOfWisdom bool -} - -func (b Buffs) AddStats(s Stats) Stats { - if b.ArcaneInt { - s[StatInt] += 40 - } - if b.GiftOftheWild { - s[StatInt] += 18 // assumes improved gotw, rounded down to nearest int... not sure if that is accurate. - } - if b.ImprovedBlessingOfWisdom { - s[StatMP5] += 42 - } - if b.Moonkin { - s[StatSpellCrit] += 110.4 - } - if b.WaterShield { - s[StatMP5] += 50 - } - s[StatMP5] += float64(b.SpriestDPS) * 0.25 - - return s -} - -type Consumes struct { - // Buffs - BrilliantWizardOil bool - MajorMageblood bool - FlaskOfBlindingLight bool - FlaskOfMightyRestoration bool - BlackendBasilisk bool - - // Used in rotations - SuperManaPotion bool - DarkRune bool -} - -func (c Consumes) AddStats(s Stats) Stats { - if c.BrilliantWizardOil { - s[StatSpellCrit] += 14 - s[StatSpellDmg] += 36 - } - if c.MajorMageblood { - s[StatMP5] += 16.0 - } - if c.FlaskOfBlindingLight { - s[StatSpellDmg] += 80 - } - if c.FlaskOfMightyRestoration { - s[StatMP5] += 25 - } - if c.BlackendBasilisk { - s[StatSpellDmg] += 23 - } - return s -} - // New sim contructs a simulator with the given stats / equipment / options. // Technically we can calculate stats from equip/options but want the ability to override those stats // mostly for stat weight purposes. @@ -220,17 +65,31 @@ func NewSim(stats Stats, equip Equipment, options Options) *Simulation { rotIdx = -1 options.SpellOrder = options.SpellOrder[1:] } + rot := make([]int32, len(options.SpellOrder)) + + for i, v := range options.SpellOrder { + for _, sp := range spells { + if sp.Name == v { + rot[i] = sp.ID + break + } + } + } sim := &Simulation{ RotationIdx: rotIdx, Stats: stats, - SpellRotation: options.SpellOrder, + SpellRotation: rot, Options: options, - CDs: map[string]int{}, + CDs: map[int32]int{}, Buffs: Stats{StatLen: 0}, Auras: []Aura{}, Equip: equip, rseed: options.RSeed, rando: rand.New(rand.NewSource(options.RSeed)), + debug: func(a string, v ...interface{}) {}, + } + if IsDebug { + sim.debug = debugFunc(sim) } return sim } @@ -243,7 +102,7 @@ func (sim *Simulation) reset() { sim.CurrentMana = sim.Stats[StatMana] sim.CastingSpell = nil sim.Buffs = Stats{StatLen: 0} - sim.CDs = map[string]int{} + sim.CDs = map[int32]int{} sim.Auras = []Aura{} sim.metrics = SimMetrics{} @@ -264,9 +123,9 @@ func (sim *Simulation) reset() { } } - debug("\nRotation: %v\n", sim.SpellRotation) - debug("Effective MP5: %0.1f\n", sim.Stats[StatMP5]+sim.Buffs[StatMP5]) - debug("----------------------\n") + sim.debug("\nSIM RESET\nRotation: %v\n", sim.SpellRotation) + sim.debug("Effective MP5: %0.1f\n", sim.Stats[StatMP5]+sim.Buffs[StatMP5]) + sim.debug("----------------------\n") } func (sim *Simulation) Run(seconds int) SimMetrics { @@ -274,9 +133,9 @@ func (sim *Simulation) Run(seconds int) SimMetrics { return sim.Run2(seconds) } -func (sim *Simulation) cleanAuraName(name string) { +func (sim *Simulation) cleanAuraName(id int32) { for i := range sim.Auras { - if sim.Auras[i].ID == name { + if sim.Auras[i].ID == id { sim.cleanAura(i) break } @@ -292,7 +151,7 @@ func (sim *Simulation) cleanAura(i int) { sim.Auras[i].OnSpellHit = nil sim.Auras[i].OnExpire = nil - debug(" -removed: %s- ", sim.Auras[i].ID) + sim.debug(" -removed: %s- \n", sim.Auras[i].ID) sim.Auras = sim.Auras[:i+copy(sim.Auras[i:], sim.Auras[i+1:])] } @@ -350,7 +209,7 @@ func (sim *Simulation) ChooseSpell() int { } return cast.TicksUntilCast } else { - debug("Current Mana %0.0f, Cast Cost: %0.0f\n", sim.CurrentMana, cast.ManaCost) + sim.debug("Current Mana %0.0f, Cast Cost: %0.0f\n", sim.CurrentMana, cast.ManaCost) if sim.metrics.OOMAt == 0 { sim.metrics.OOMAt = sim.currentTick / TicksPerSecond sim.metrics.DamageAtOOM = sim.metrics.TotalDamage @@ -367,21 +226,24 @@ func (sim *Simulation) Cast(cast *Cast) { aur.OnCastComplete(sim, cast) } } + sim.debug("Completed Cast (%s)\n", cast.Spell.ID) + dbgCast := cast.Spell.Name if sim.rando.Float64() < cast.Hit { dmg := (float64(sim.rando.Intn(int(cast.Spell.MaxDmg-cast.Spell.MinDmg))) + cast.Spell.MinDmg) + (sim.Stats[StatSpellDmg] * cast.Spell.Coeff) if cast.DidDmg != 0 { // use the pre-set dmg dmg = cast.DidDmg } cast.DidHit = true - dbgCast := "hit" if sim.rando.Float64() < cast.Crit { cast.DidCrit = true dmg *= 2 sim.addAura(AuraElementalFocus(sim.currentTick)) - dbgCast = "crit" + dbgCast += " crit" + } else { + dbgCast += " hit" } - if sim.Options.Talents.Concussion > 0 && (strings.HasPrefix(cast.Spell.ID, "LB") || strings.HasPrefix(cast.Spell.ID, "CL")) { + if sim.Options.Talents.Concussion > 0 && cast.Spell.ID == MagicIDLB12 || cast.Spell.ID == MagicIDCL6 { // Talent Concussion dmg *= 1 + (0.01 * float64(sim.Options.Talents.Concussion)) } @@ -391,7 +253,7 @@ func (sim *Simulation) Cast(cast *Cast) { // For now hardcode the 25% chance resist at 2.5% (this assumes bosses have 0 nature resist) if sim.rando.Float64() < 0.025 { // chance of 25% resist dmg *= .75 - debug("(partial resist)") + dbgCast += " (partial resist)" } cast.DidDmg = dmg // Apply any effects specific to this cast. @@ -404,13 +266,13 @@ func (sim *Simulation) Cast(cast *Cast) { aur.OnSpellHit(sim, cast) } } - debug("%s: %0.0f\n", dbgCast, cast.DidDmg) sim.metrics.TotalDamage += cast.DidDmg sim.metrics.Casts = append(sim.metrics.Casts, cast) } else { - debug("miss.\n") + dbgCast += " miss" } + sim.debug("%s: %0.0f\n", dbgCast, cast.DidDmg) sim.CurrentMana -= cast.ManaCost sim.CastingSpell = nil if cast.Spell.Cooldown > 0 { diff --git a/tbc/sim1.go b/tbc/sim1.go deleted file mode 100644 index 7942a20..0000000 --- a/tbc/sim1.go +++ /dev/null @@ -1,87 +0,0 @@ -package tbc - -// Old fully ticking style simulator. -func (sim *Simulation) Run1(seconds int) SimMetrics { - sim.reset() - - ticks := seconds * TicksPerSecond - for i := 0; i < ticks; i++ { - sim.currentTick = i - sim.Tick1(i) - } - debug("(%0.0f/%0.0f mana)\n", sim.CurrentMana, sim.Stats[StatMana]) - return sim.metrics -} - -func (sim *Simulation) Tick1(tickID int) { - if sim.CurrentMana < 0 { - panic("you should never have negative mana.") - } - - secondID := tickID / TicksPerSecond - // MP5 regen - sim.CurrentMana += ((sim.Stats[StatMP5] + sim.Buffs[StatMP5]) / 5.0) / float64(TicksPerSecond) - - if sim.CurrentMana > sim.Stats[StatMana] { - sim.CurrentMana = sim.Stats[StatMana] - } - - if sim.CastingSpell != nil { - sim.CastingSpell.TicksUntilCast-- // advance state of current cast. - if sim.CastingSpell.TicksUntilCast == 0 { - sim.Cast(sim.CastingSpell) - } - } - - if sim.CastingSpell == nil { - // Pop potion before next cast. - if sim.Stats[StatMana]-sim.CurrentMana+sim.Stats[StatMP5] >= 1500 && sim.CDs["darkrune"] < 1 { - // Restores 900 to 1500 mana. (2 Min Cooldown) - sim.CurrentMana += float64(900 + sim.rando.Intn(1500-900)) - sim.CDs["darkrune"] = 120 * TicksPerSecond - debug("[%d] Used Mana Potion\n", secondID) - } - if sim.Stats[StatMana]-sim.CurrentMana+sim.Stats[StatMP5] >= 3000 && sim.CDs["potion"] < 1 { - // Restores 1800 to 3000 mana. (2 Min Cooldown) - sim.CurrentMana += float64(1800 + sim.rando.Intn(3000-1800)) - sim.CDs["potion"] = 120 * TicksPerSecond - debug("[%d] Used Mana Potion\n", secondID) - } - // Pop any on-use trinkets - - for _, item := range sim.Equip { - if item.Activate == nil || item.ActivateCD == -1 { // ignore non-activatable, and always active items. - continue - } - if sim.CDs[item.CoolID] > 0 { - continue - } - sim.addAura(item.Activate(sim)) - sim.CDs[item.CoolID] = item.ActivateCD * TicksPerSecond - } - - // Choose next spell - sim.ChooseSpell() - if sim.CastingSpell != nil { - debug("[%d] Casting %s (%0.1f) ...", secondID, sim.CastingSpell.Spell.ID, float64(sim.CastingSpell.TicksUntilCast)/float64(TicksPerSecond)) - } - } - - // CDS - for k := range sim.CDs { - sim.CDs[k]-- - if sim.CDs[k] <= 0 { - delete(sim.CDs, k) - } - } - - todel := []int{} - for i := range sim.Auras { - if sim.Auras[i].Expires <= tickID { - todel = append(todel, i) - } - } - for i := len(todel) - 1; i >= 0; i-- { - sim.cleanAura(todel[i]) - } -} diff --git a/tbc/sim2.go b/tbc/sim2.go index f0610b9..b9b949f 100644 --- a/tbc/sim2.go +++ b/tbc/sim2.go @@ -30,8 +30,6 @@ func (sim *Simulation) Run2(seconds int) SimMetrics { // Activates trinkets before spellcasting of off CD. // It will pop mana potions if needed. func (sim *Simulation) Spellcasting(tickID int) int { - secondID := tickID / TicksPerSecond - // technically we dont really need this check with the new advancer. if sim.CastingSpell != nil && sim.CastingSpell.TicksUntilCast == 0 { sim.Cast(sim.CastingSpell) @@ -39,28 +37,28 @@ func (sim *Simulation) Spellcasting(tickID int) int { if sim.CastingSpell == nil { // Activate any specials - if sim.Options.NumBloodlust > 0 && sim.CDs["bl"] < 1 { + if sim.Options.NumBloodlust > 0 && sim.CDs[MagicIDBloodlust] < 1 { sim.addAura(ActivateBloodlust(sim)) sim.Options.NumBloodlust-- // TODO: will this break anything? } - if sim.Options.Talents.ElementalMastery && sim.CDs["elemastery"] < 1 { + if sim.Options.Talents.ElementalMastery && sim.CDs[MagicIDEleMastery] < 1 { // Apply auras sim.addAura(AuraEleMastery()) } // Pop potion before next cast if we have less than the mana provided by the potion minues 1mp5 tick. - if sim.Stats[StatMana]-sim.CurrentMana+sim.Stats[StatMP5] >= 1500 && sim.CDs["darkrune"] < 1 { + if sim.Stats[StatMana]-sim.CurrentMana+sim.Stats[StatMP5] >= 1500 && sim.CDs[MagicIDRune] < 1 { // Restores 900 to 1500 mana. (2 Min Cooldown) sim.CurrentMana += float64(900 + sim.rando.Intn(1500-900)) - sim.CDs["darkrune"] = 120 * TicksPerSecond - debug("[%d] Used Mana Potion\n", secondID) + sim.CDs[MagicIDRune] = 120 * TicksPerSecond + sim.debug("Used Mana Potion\n") } - if sim.Stats[StatMana]-sim.CurrentMana+sim.Stats[StatMP5] >= 3000 && sim.CDs["potion"] < 1 { + if sim.Stats[StatMana]-sim.CurrentMana+sim.Stats[StatMP5] >= 3000 && sim.CDs[MagicIDPotion] < 1 { // Restores 1800 to 3000 mana. (2 Min Cooldown) sim.CurrentMana += float64(1800 + sim.rando.Intn(3000-1800)) - sim.CDs["potion"] = 120 * TicksPerSecond - debug("[%d] Used Mana Potion\n", secondID) + sim.CDs[MagicIDPotion] = 120 * TicksPerSecond + sim.debug("Used Mana Potion\n") } // Pop any on-use trinkets @@ -71,20 +69,20 @@ func (sim *Simulation) Spellcasting(tickID int) int { if sim.CDs[item.CoolID] > 0 { continue } - if item.Slot == EquipTrinket && sim.CDs["trinket"] > 0 { + if item.Slot == EquipTrinket && sim.CDs[MagicIDAllTrinket] > 0 { continue } sim.addAura(item.Activate(sim)) sim.CDs[item.CoolID] = item.ActivateCD * TicksPerSecond if item.Slot == EquipTrinket { - sim.CDs["trinket"] = 30 * TicksPerSecond + sim.CDs[MagicIDAllTrinket] = 30 * TicksPerSecond } } // Choose next spell ticks := sim.ChooseSpell() if sim.CastingSpell != nil { - debug("[%d] Casting %s (%0.1f) ...", secondID, sim.CastingSpell.Spell.ID, float64(sim.CastingSpell.TicksUntilCast)/float64(TicksPerSecond)) + sim.debug("Start Casting %s Cast Time: %0.1fs\n", sim.CastingSpell.Spell.ID, float64(sim.CastingSpell.TicksUntilCast)/float64(TicksPerSecond)) } return ticks } diff --git a/tbc/spells.go b/tbc/spells.go index f9e4ec9..166a05a 100644 --- a/tbc/spells.go +++ b/tbc/spells.go @@ -3,6 +3,7 @@ package tbc type Cast struct { Spell *Spell // Caster ... // Needed for onstruck effects? + isLO bool // stupid hack // Pre-hit Mutatable State TicksUntilCast int @@ -28,8 +29,8 @@ func NewCast(sim *Simulation, sp *Spell, spellDmg, spHit, spCrit float64) *Cast } castTime := sp.CastTime - isLB := sp.ID[0] == 'L' && sp.ID[1] == 'B' - isCL := sp.ID[0] == 'C' && sp.ID[1] == 'L' + isLB := sp.ID == MagicIDLB12 + isCL := sp.ID == MagicIDCL6 if isLB || isCL { // Talent to reduce cast time. @@ -56,7 +57,8 @@ func NewCast(sim *Simulation, sp *Spell, spellDmg, spHit, spCrit float64) *Cast } type Spell struct { - ID string + ID int32 + Name string CastTime float64 Cooldown int Mana float64 @@ -69,7 +71,7 @@ type Spell struct { DotDur float64 } -type DamageType int +type DamageType byte const ( DamageTypeUnknown DamageType = iota @@ -86,17 +88,17 @@ const ( // spells // TODO: DRP == (spellrankavailbetobetrained+11)/70 var spells = []Spell{ - {ID: "LB4", Coeff: 0.795, CastTime: 2.0, MinDmg: 88, MaxDmg: 100, Mana: 50, DamageType: DamageTypeNature}, - {ID: "LB10", Coeff: 0.795, CastTime: 2.5, MinDmg: 428, MaxDmg: 477, Mana: 265, DamageType: DamageTypeNature}, - {ID: "LB12", Coeff: 0.795, CastTime: 2.5, MinDmg: 563, MaxDmg: 643, Mana: 300, DamageType: DamageTypeNature}, - {ID: "CL4", Coeff: 0.643, CastTime: 2, Cooldown: 6, MinDmg: 505, MaxDmg: 564, Mana: 605, DamageType: DamageTypeNature}, - {ID: "CL6", Coeff: 0.643, CastTime: 2, Cooldown: 6, MinDmg: 734, MaxDmg: 838, Mana: 760, DamageType: DamageTypeNature}, - {ID: "ES8", Coeff: 0.3858, CastTime: 1.5, Cooldown: 6, MinDmg: 658, MaxDmg: 692, Mana: 535, DamageType: DamageTypeNature}, - {ID: "FrS5", Coeff: 0.3858, CastTime: 1.5, Cooldown: 6, MinDmg: 640, MaxDmg: 676, Mana: 525, DamageType: DamageTypeFrost}, - {ID: "FlS7", Coeff: 0.15, CastTime: 1.5, Cooldown: 6, MinDmg: 377, MaxDmg: 420, Mana: 500, DotDmg: 100, DotDur: 6, DamageType: DamageTypeFire}, + // {ID: MagicIDLB4, Name: "LB4", Coeff: 0.795, CastTime: 2.0, MinDmg: 88, MaxDmg: 100, Mana: 50, DamageType: DamageTypeNature}, + // {ID: MagicIDLB10, Name: "LB10", Coeff: 0.795, CastTime: 2.5, MinDmg: 428, MaxDmg: 477, Mana: 265, DamageType: DamageTypeNature}, + {ID: MagicIDLB12, Name: "LB12", Coeff: 0.795, CastTime: 2.5, MinDmg: 563, MaxDmg: 643, Mana: 300, DamageType: DamageTypeNature}, + // {ID: MagicIDCL4, Name: "CL4", Coeff: 0.643, CastTime: 2, Cooldown: 6, MinDmg: 505, MaxDmg: 564, Mana: 605, DamageType: DamageTypeNature}, + {ID: MagicIDCL6, Name: "CL6", Coeff: 0.643, CastTime: 2, Cooldown: 6, MinDmg: 734, MaxDmg: 838, Mana: 760, DamageType: DamageTypeNature}, + // {ID: MagicIDES8, Name: "ES8", Coeff: 0.3858, CastTime: 1.5, Cooldown: 6, MinDmg: 658, MaxDmg: 692, Mana: 535, DamageType: DamageTypeNature}, + // {ID: MagicIDFrS5, Name: "FrS5", Coeff: 0.3858, CastTime: 1.5, Cooldown: 6, MinDmg: 640, MaxDmg: 676, Mana: 525, DamageType: DamageTypeFrost}, + // {ID: MagicIDFlS7, Name: "FlS7", Coeff: 0.15, CastTime: 1.5, Cooldown: 6, MinDmg: 377, MaxDmg: 420, Mana: 500, DotDmg: 100, DotDur: 6, DamageType: DamageTypeFire}, } -var spellmap = map[string]*Spell{} +var spellmap = map[int32]*Spell{} func init() { for _, sp := range spells { diff --git a/tbc/stats.go b/tbc/stats.go index 9046d16..80d15e7 100644 --- a/tbc/stats.go +++ b/tbc/stats.go @@ -4,11 +4,11 @@ import ( "strconv" ) -var TicksPerSecond = 30 +const TicksPerSecond = 30 type Stats []float64 -type Stat int +type Stat byte const ( StatInt Stat = iota diff --git a/ui/lib.wasm b/ui/lib.wasm index 42146ca9cc225872c07e184dbb3819f53de2919e..c7da80f930299880979ecbce90aad690243ea08c 100755 GIT binary patch literal 2859312 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