Skip to content

Conversation

@Timmynat0r
Copy link

@Timmynat0r Timmynat0r commented Mar 25, 2025

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 Timmynat0r marked this pull request as draft March 25, 2025 20:30
}
for _, kb := range preKeys {
utils.Sleep(100)
utils.Sleep(200)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

did you have issues with the lower sleep values?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, i sometimes missed cta buffs on characters with low fcr, atleast thats what i think what caused it, i saw the skil switch happen, but the rightclick did not "happen" or register, with higher sleep values i get all the casts done on any class


if len(preKeys) > 0 {
ctx.Logger.Debug("PRE CTA Buffing...")
if ctx.WeaponBonusCache.IsValid {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when is this not true?

Copy link
Author

@Timmynat0r Timmynat0r Mar 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

right now this is not true if we have dont have a cta, because that is relevant in the current code (this propably will change) and if we for what reason ever have not build a gearcache, so it will fall back to the old version of buffing

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kept ctx.WeaponBonusCache.IsValid in case of error while calculating GearCache, so we can always fall back on original buff logic

@Timmynat0r Timmynat0r changed the title Automaticly assign best Weapon slot for Pre and Post CTA buffs Automatically assign best Weapon slot for Pre and Post CTA buffs Mar 26, 2025
@CarlPoppa1
Copy link

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

@Timmynat0r
Copy link
Author

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 ?

@CarlPoppa1
Copy link

CarlPoppa1 commented Mar 28, 2025

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

@Timmynat0r
Copy link
Author

Timmynat0r commented Mar 28, 2025

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....

@CarlPoppa1
Copy link

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

@Timmynat0r
Copy link
Author

Timmynat0r commented Mar 28, 2025

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

@CarlPoppa1
Copy link

CarlPoppa1 commented Mar 28, 2025

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
}

@Timmynat0r
Copy link
Author

Timmynat0r commented Mar 28, 2025

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
Copy link
Author

Timmynat0r commented Mar 28, 2025

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 Timmynat0r marked this pull request as ready for review March 28, 2025 23:20
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.

3 participants