Skip to content

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
Polynomix pushed a commit to Polynomix/wowsims that referenced this pull request Jun 25, 2025
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