Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make Spell data from client database available in core #323

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

ToxicKevinFerm
Copy link
Contributor

@ToxicKevinFerm ToxicKevinFerm commented May 5, 2024

(This is essentially a 1 to 1 translation of the same functionality in Simulationcraft)

I'm experimenting with making spell data from the client database files available for the sim to work with.
I achieve this by using the Simulationcraft client extractors (python) and modding them to extract to json instead. (this will be another repo I think)

What it contains:

  1. Spell Data
  2. Spell Effect Data
  3. Power Data
  4. Spell Scaling (real)

I've made this available in a dbc package inside Core currently, and here's why I'm unsure and would love feedback/pushes on this branch on this.

It works right now for getting data from effects manually, and whatever we can get from the spell itself, Right now we return School, MissileSpeed, SpellSchool, cast time, gcd, cooldown and resource cost, pre parsing effects.

The future idea would be to build a complete spell with the data, and allow the possibility of overriding when the client is not enough.

Right now I tried modifying Kill Shot according to this and we go from

	hunter.KillShot = hunter.RegisterSpell(core.SpellConfig{
		ActionID:     core.ActionID{SpellID: 53351},
		SpellSchool:  core.SpellSchoolPhysical,
		ProcMask:     core.ProcMaskRangedSpecial,
		Flags:        core.SpellFlagMeleeMetrics | core.SpellFlagIncludeTargetBonusDamage | core.SpellFlagAPL,
		MissileSpeed: 40,

		FocusCost: core.FocusCostOptions{
			Cost: 0,
		},
		Cast: core.CastConfig{
			DefaultCast: core.Cast{
				GCD: time.Second,
			},
			IgnoreHaste: true,
			CD: core.Cooldown{
				Timer:    hunter.NewTimer(),
				Duration: time.Second * 10,
			},
		},
		ExtraCastCondition: func(sim *core.Simulation, target *core.Unit) bool {
			return sim.IsExecutePhase20()
		},

		BonusCritRating:  0 + 5*core.CritRatingPerCritChance*float64(hunter.Talents.SniperTraining),
		DamageMultiplier: 1.5, //
		CritMultiplier:   hunter.CritMultiplier(true, true, false),
		ThreatMultiplier: 1,
		// https://web.archive.org/web/20120207222124/http://elitistjerks.com/f74/t110306-hunter_faq_cataclysm_edition_read_before_asking_questions/
		ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) {
			// (100% weapon dmg + 45% RAP + 543) * 150%
			normalizedWeaponDamage := hunter.AutoAttacks.Ranged().CalculateNormalizedWeaponDamage(sim, spell.RangedAttackPower(target))
			rapBonusDamage := spell.RangedAttackPower(target) * 0.45
			flatBonus := 543.0

			baseDamage := normalizedWeaponDamage + rapBonusDamage + flatBonus
			result := spell.CalcDamage(sim, target, baseDamage, spell.OutcomeRangedHitAndCrit)

			spell.WaitTravelTime(sim, func(sim *core.Simulation) {
				spell.DealDamage(sim, result)
			})
		},
	})

To

	spellData, _ := core.CurrentSpellGen().GetDBC().FetchSpell(53351)
	eff2, _ := spellData.EffectN(2)
	actionId := core.ActionID{SpellID: 53351}
	spellConfig := core.CurrentSpellGen().ParseSpellData(53351, &hunter.Unit, &actionId)
	spellConfig.ProcMask = core.ProcMaskRangedSpecial // Probably can get this for config as well
	spellConfig.Flags = core.SpellFlagMeleeMetrics | core.SpellFlagIncludeTargetBonusDamage | core.SpellFlagAPL
	spellConfig.ExtraCastCondition = func(sim *core.Simulation, target *core.Unit) bool {
		return sim.IsExecutePhase20()
	}
	spellConfig.BonusCritRating = 0 + 5*core.CritRatingPerCritChance*float64(hunter.Talents.SniperTraining)
	spellConfig.DamageMultiplier = eff2.Min(core.CurrentSpellGen().GetDBC(), 85, 85)
	spellConfig.CritMultiplier = hunter.CritMultiplier(true, true, false)
	spellConfig.ApplyEffects = func(sim *core.Simulation, target *core.Unit, spell *core.Spell) {
		weaponDamage := 0.0
		eff1, _ := spellData.EffectN(1)
		weaponDamage += hunter.AutoAttacks.Ranged().CalculateNormalizedWeaponDamage(sim, spell.RangedAttackPower(target))
		weaponDamage += eff1.Average(core.CurrentSpellGen().GetDBC(), 85, 85)

		// Todo: Figure out where exactly this part comes from, cant find an effect for it
		rapBonusDamage := spell.RangedAttackPower(target) * (0.45 * eff2.Min(core.CurrentSpellGen().GetDBC(), 85, 85))

		baseDamage := weaponDamage + rapBonusDamage
		result := spell.CalcDamage(sim, target, baseDamage, spell.OutcomeRangedHitAndCrit)

		spell.WaitTravelTime(sim, func(sim *core.Simulation) {
			spell.DealDamage(sim, result)
		})
	}

	hunter.KillShot = hunter.RegisterSpell(*spellConfig)

So compared to the old KS, I dont need to figure out what the average weapon damage is from effect1 or the Damage Multiplier from effect2, I also dont need to state gcd or cooldown, it also choses the correct spell school

@ToxicKevinFerm ToxicKevinFerm marked this pull request as draft May 5, 2024 13:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant