koolo icon indicating copy to clipboard operation
koolo copied to clipboard

Automatically assign best Weapon slot for Pre and Post CTA buffs

Open Timmynat0r opened this issue 9 months ago • 9 comments

Automatically assign best Weapon slot for Buffs

V1:

  • Created function to calculate current +allSkills and +classSkills from ID 127 and ID 83
  • Adjusted buff logic to use this calculation for assigning the "best" weapon slot

V2:

  • incorporated swap_weapons logic mentioned by User: @jasorello
  • we now accurately look at the layer of ID 83 and cross check for our current class, to not get +skills from other classes

V3: (not working as intended right now)

  • added function to also incorporate +specificSkills (ID 97)
    • buildGearCache, getspecificSkillBonuses, calculateSlotBonus, should now account for +allSkills ID 127 +classSkills ID 83 and +specificSkills ID 97
  • added grouping of buffs to "bestSlots" for less weaponswapping
  • still mostly kept original buff logic, to still have a fallback routine

V4:

  • fixed +noClassSkills (former +specificSkills)
  • added +singleSkills
  • fixed optimalSlot generation
  • fixed optimalSlot assignment
  • reduced weaponSwapping to almost the minimum
  • excluded berzerk_barb from buffCTA(), since he is now also able to use CTA to boost BattleCommand/BattleOrders
  • removed step.SwapToMainWeapon from BuffCTA(), since we will automaticly use step.SwapToMainWeapo at the end of buff()

V5:

  • added skillsToTab for crossreferencing stats.AddSkillTab
  • added stats.AddSkillTab to calculation

Right now PR is working as intended

Timmynat0r avatar Mar 25 '25 20:03 Timmynat0r

Does this help for the tabskill issue? tabskillLayer := int(ctx.Data.PlayerUnit.Class)*8 + (<1,2,3> - 1)

Where 1,2,3 is the skill.Desc().Page

CarlPoppa1 avatar Mar 27 '25 15:03 CarlPoppa1

ctx.Data.PlayerUnit.Stats.FindStat(stat.AddSkillTab, tabskills)

This already gives me a predetermined list:

188: {
	0:  "+# to Bow and Crossbow Skills (Amazon only)",     // bowandcrossbowskilltab
	1:  "+# to Passive and Magic Skills (Amazon only)",    // passiveandmagicskilltab
	2:  "+# to Javelin and Spears Skills (Amazon only)",   // javelinandspearskilltab
	8:  "+# to Fire Skills (Sorceress only)",              // fireskilltab
	9:  "+# to Lightning Skills (Sorceress only)",         // lightningskilltab
	10: "+# to Cold Skills (Sorceress only)",              // coldskilltab
	16: "+# to Curses Skills (Necromancer only)",          // cursesskilltab
	17: "+# to Poison and Bone Skills (Necromancer only)", // poisonandboneskilltab
	18: "+# to Summoning Skills (Necromancer only)",       // necromancersummoningskilltab
	24: "+# to Paladin Combat Skills (Paladin only)",      // palicombatskilltab
	25: "+# to Offensive Aura Skills (Paladin only)",      // offensiveaurasskilltab
	26: "+# to Defensive Aura Skills (Paladin only)",      // defensiveaurasskilltab
	32: "+# to Barbarian Combat Skills (Barbarian only)",  // barbcombatskilltab
	33: "+# to Mastery Skills (Barbarian only)",           // masteryesskilltab
	34: "+# to War Cry Skills (Barbarian only)",           // warcriesskilltab
	40: "+# to Druid Summoning Skills (Druid only)",       // druidsummoningskilltab
	41: "+# to Shapeshifting Skills (Druid only)",         // shapeshiftingskilltab
	42: "+# to Elemental Skills (Druid only)",             // elementalskilltab
	48: "+# to Traps Skills (Assassin only)",              // trapsskilltab
	49: "+# to Shadow Discipline Skills (Assassin only)",  // shadowdisciplinesskilltab
	50: "+# to Martial Arts Skills (Assassin only)",       // martialartsskilltab

My problem right now is that those "layers" are not connected to skills.go (atleast not that i know of) So at this stage, yes i can read those +skills, their value, and what they should influence.

So for example: I have a weapon in slot1, that gives +2 to Cold Skills ctx.Data.PlayerUnit.Stats.FindStat(stat.AddSkillTab, tabskills) would give me ID 188 val=2 tabskills=10

and my BuffSkills() has FrozenArmor [skill.id] 40 and no other informations

Now i need a "connection" from [skill.id] 40 to tabskills=10

Whats the easiest way to do that ? The only thing i have in my head right now is to generate a static map for this. Or am i missing something ?

Timmynat0r avatar Mar 27 '25 16:03 Timmynat0r

Why not do something like this?

	buff := skill.FrozenArmor
	tabskillLayer := (int((buff)-6)/30)*8 + (buff.Desc().Page - 1)
	ctx.Logger.Debug(fmt.Sprintf("tabskillLayer: %d", tabskillLayer))

6 is the number of non-class skills at the start of skills.go. 30 is the number of skills for each class

CarlPoppa1 avatar Mar 28 '25 09:03 CarlPoppa1

that would still only leave me with the class skills, because they are not ordered by tabs and plus classskills is directly read from "stat.AddClassSkills"


MagicArrow //bowandarrow
FireArrow //bowandarrow
InnerSight //passiveandmagic
CriticalStrike //passiveandmagic
Jab //javelinandspear
ColdArrow //bowandarrow
MultipleShot //bowandarrow
Dodge //passiveandmagic
PowerStrike //javelinandspear
	
etc....

Timmynat0r avatar Mar 28 '25 13:03 Timmynat0r

Sorry I don't understand what you mean. My example takes 40 and returns 10, isn't that what is needed?

CarlPoppa1 avatar Mar 28 '25 13:03 CarlPoppa1

you have 5 different kinds of "stats" as +skills that you can have

+skills to All Skills (example: anihinilus +1allskills) +skills to Class Skills (example: tal amu +2sorc skills) +skills to singleskills (example: snowclash +2 To Chilling Armor etc.) +skills to nonClassSkills (example: CTA +6 to BattleOrders) +skills to Skill Tree Tabs (example: Bo Sticks +3 warcries)

and the last example is not mapped in skills.go in d2go right now it would need something like this:

"WakeOfInferno":     48,
"WarCry":            34,
"Warmth":            8,

this would be ctx.Data.PlayerUnit.Stats.FindStat(stat.AddSkillTab, tab) ID188 value:3 tab: 34

maybe i just overcomplicate stuff, but if i want to really calculate the best slot for every possibility, i would need this

If i had this, a BO Barb script, would automaticly use +3warcries sticks in the second slot, and cast his bo/bc

Timmynat0r avatar Mar 28 '25 13:03 Timmynat0r

Nah it sounds good, but I don't see why my suggestion wouldn't work, this is untested but it seems exactly what's needed, sorry if I'm being stupid:

func getSpecificSkillBonuses(ctx *context.Status, skillIDs []skill.ID) map[skill.ID]int {
	bonuses := make(map[skill.ID]int)

	for _, skillID := range skillIDs {
		tabskillLayer := (int((skillID)-6)/30)*8 + (skillID.Desc().Page - 1)
		if s, found := ctx.Data.PlayerUnit.Stats.FindStat(stat.SingleSkill, int(skillID)); found {
			bonuses[skillID] = s.Value
		} else if s, found := ctx.Data.PlayerUnit.Stats.FindStat(stat.NonClassSkill, int(skillID)); found {
			bonuses[skillID] = s.Value
		} else if s, found := ctx.Data.PlayerUnit.Stats.FindStat(stat.AddSkillTab, tabskillLayer); found {
			bonuses[skillID] = s.Value

		}

	}
	return bonuses
}

CarlPoppa1 avatar Mar 28 '25 15:03 CarlPoppa1

btw: i send a DM on discord @CarlPoppa1 if you want to communicate about this directly

but this:

} else if s, found := ctx.Data.PlayerUnit.Stats.FindStat(stat.AddSkillTab, tabskillLayer); found {
			bonuses[skillID] = s.Value

does not give out [skillID], this will give value and skilltab (value would be +X to skilltab)

188: {
	0:  "+# to Bow and Crossbow Skills (Amazon only)",     // bowandcrossbowskilltab
	1:  "+# to Passive and Magic Skills (Amazon only)",    // passiveandmagicskilltab
	2:  "+# to Javelin and Spears Skills (Amazon only)",   // javelinandspearskilltab
	8:  "+# to Fire Skills (Sorceress only)",              // fireskilltab
	9:  "+# to Lightning Skills (Sorceress only)",         // lightningskilltab
	10: "+# to Cold Skills (Sorceress only)",              // coldskilltab
	16: "+# to Curses Skills (Necromancer only)",          // cursesskilltab
	17: "+# to Poison and Bone Skills (Necromancer only)", // poisonandboneskilltab
	18: "+# to Summoning Skills (Necromancer only)",       // necromancersummoningskilltab
	24: "+# to Paladin Combat Skills (Paladin only)",      // palicombatskilltab
	25: "+# to Offensive Aura Skills (Paladin only)",      // offensiveaurasskilltab
	26: "+# to Defensive Aura Skills (Paladin only)",      // defensiveaurasskilltab
	32: "+# to Barbarian Combat Skills (Barbarian only)",  // barbcombatskilltab
	33: "+# to Mastery Skills (Barbarian only)",           // masteryesskilltab
	34: "+# to War Cry Skills (Barbarian only)",           // warcriesskilltab
	40: "+# to Druid Summoning Skills (Druid only)",       // druidsummoningskilltab
	41: "+# to Shapeshifting Skills (Druid only)",         // shapeshiftingskilltab
	42: "+# to Elemental Skills (Druid only)",             // elementalskilltab
	48: "+# to Traps Skills (Assassin only)",              // trapsskilltab
	49: "+# to Shadow Discipline Skills (Assassin only)",  // shadowdisciplinesskilltab
	50: "+# to Martial Arts Skills (Assassin only)",       // martialartsskilltab

Timmynat0r avatar Mar 28 '25 16:03 Timmynat0r

Why not do something like this?

	buff := skill.FrozenArmor
	tabskillLayer := (int((buff)-6)/30)*8 + (buff.Desc().Page - 1)
	ctx.Logger.Debug(fmt.Sprintf("tabskillLayer: %d", tabskillLayer))

6 is the number of non-class skills at the start of skills.go. 30 is the number of skills for each class

It took some time and another pair of eyes to get what you ment here. I was not aware of "skilldesc.go" I even almost succesfully used this here, BUT for this to work, right now, we need the list i now added at the end, because Druid Skills and Assassin Skills are missing in "github.com/hectorgimenez/d2go/pkg/data/skill/skilldesc.go"

And since the skillIDs for Assasin and Druid skills, are much higher (propably due to LOD Expansion) , even with the Information for the Page, your calculation propably wouldnt have worked.

buff := skill.Tornado [245]
tabskillLayer := (int((buff)-6)/30)*8 + (buff.Desc().Page -1) -->page propably 3, but not defined in skilldesc.go
tabskillLayer =58

But the tabskill Layer is 42 for elemental (druid)

Timmynat0r avatar Mar 28 '25 23:03 Timmynat0r