Skip to content

Conversation

@Paliak
Copy link
Contributor

@Paliak Paliak commented Jul 15, 2022

Fixes #2444 , #4107 , #4210 , #3558, #4959, #4679

Description of the problems being solved:

Separation of Skill cooldown and trigger cooldown in CalcPerform. Correct calculation of triggers for Kitava's Thirst and Craft trigger with improved source selection for the latter. Change Kitava's Thirst to use the in game trigger mod and add parsing for it. Improved handling of hard skill cooldown overrides. Improved handling of a gem being supported by more than one trigger. Adds isTriger property to skills that can trigger other skills. Adds triggeredBy property to skills triggered. Handling of helmet focus trigger (focus trigger now assumes the player recasts focus when the cooldown ends). Correctly account for the fact that some skills have no cooldown in calcMultiSpellRotationImpact. Attack rate calculation for counter attack skills. Fix handling of hard skill cooldown overrides (Discharge). Add support for more unique triggers. Refactoring of trigger code. Improved breakdowns for skills where average trigger rate is affected by accuracy and or crit chance.

The changes are extensive and there may be more edge cases that i was not able to find.

Rundown:

There are flags and properties scattered all over, but the main code starts in CalcActiveSkill.lua

-- Handle multiple triggers situation and if triggered by a trigger skill save a reference to the trigger.
local match = skillEffect.grantedEffect.addSkillTypes and activeSkill.skillTypes[SkillType.Triggerable] and (not skillFlags.disable)
if match and skillEffect.grantedEffect.isTrigger then
if activeSkill.triggeredBy then
skillFlags.disable = true
activeSkill.disableReason = "This skill is supported by more than one trigger"
else
activeSkill.triggeredBy = skillEffect
end
end

Currently, pob inherits the cooldown from supports when a skill has no cooldown it self. For example, if you link arc to Cast on Crit arc will inherit the cooldown of cast on crit. Later in the code this looks exactly like any other cooldown; Therefore, making it impossible to tell where that cooldown came from (skill itself ? support? cooldown override (discharge)?) This caused issues with cooldown manipulation such as in the case of discharge where the cooldown of the skill itself needs to be overwritten but because both the trigger cooldown and cooldown of the skill get effectively max() 'ed there's just no way to do it. This also cases issues when trying to simulate the impact of skill rotation. If multiple skills are linked to a trigger they will be fired off sequentially, but if a skill happens to be on cooldown when the trigger tries to fire it off nothing will happen. @Nostrademous created the calcMultiSpellRotationImpact to simulate this so more accurate dps numbers can be provided. The function itself works great, but it was being fed the wrong numbers. You can see the difference that makes in the comment @QuickStick123 has made. It was also missing support for newer trigger mechanics such as lightning conduit adding cast time to cooldown if triggered, and it didn't take cooldown overrides into account. The heart of the code starts where it used to. I didn't touch the mirage archer handling code much, if at all. Simply adapted it to work with the changes I made. Lower starts special handling for the focus trigger. Because it uses the focus mechanic and can trigger all linked skills at the same time getting it to work with the rest of the trigger handling code was difficult, so I decided to make a special if case for it. Going lower, there's the special handling for cast while channeling. Cast while channeling differs from other triggers as it casts the linked skills on a monotonic interval. This means that normal trigger rules don't apply, and thus it has its own section. Just below that is the main trigger handling code. This handles the majority of "normal" triggers. Currently, in pob each trigger has its own section, but because I wanted to add support for more triggers adding a section for every single one quickly turned into copy pasting dozens of lines of code and every small change i made had to be applied and adjusted to every single code block. I decided to create a single block but split it into segments, flexible enough to handle the majority of cases. Stating off, I define some local variables that allow handling specific cases and abstract away some parts to make handling cases such as minion triggers (holy relic) easier.

local uniqueTriggerName = getUniqueItemTriggerName(env.player.mainSkill)
local triggerName = uniqueTriggerName
local skip = false
local spellCount = {}
local trigRate = 0
local source = nil
local triggerChance = env.player.mainSkill.activeEffect and env.player.mainSkill.activeEffect.srcInstance and env.player.mainSkill.activeEffect.srcInstance.triggerChance
local globalTrigger = false
local actor = env.player
local output = output
local breakdown = breakdown
local minion = false
local triggerSkillCond = nil
local triggeredSkillCond = nil
local assumingEveryHitKills = nil
each skill has different requirements for a triggering skill and can trigger different skills, so it sets different triggerSkillCond and triggerSkillCond functions that are later used to find and select valid skills. Some triggers also need special handling, such as arcanist brand or global triggers, such as cast on stun or cwdt. If the current skill is not a trigger skill the skip flag is set then CalcPerform goes on to do other processing but if a trigger skill is found then first the affected skills need to be found.
--find trigger skill and triggered skills
if triggeredSkillCond or triggerSkillCond then
for _, skill in ipairs(env.player.activeSkillList) do
local triggered = skill.skillData.triggeredByUnique or skill.skillData.triggered or skill.skillTypes[SkillType.InbuiltTrigger] or skill.skillTypes[SkillType.Triggered]
if triggerSkillCond and triggerSkillCond(env, skill) and not triggered then
source, trigRate = findTriggerSkill(env, skill, source, trigRate)
end
if triggeredSkillCond and triggeredSkillCond(env,skill) and spellCount ~= nil then
local addsCastTime = nil
if skill.skillModList:Flag(skill.skillCfg, "SpellCastTimeAddedToCooldownIfTriggered") then
baseCastTime = skill.skillData.castTimeOverride or skill.activeEffect.grantedEffect.castTime or 1
local inc = skill.skillModList:Sum("INC", skill.skillCfg, "Speed")
local more = skill.skillModList:More(skill.skillCfg, "Speed")
addsCastTime = baseCastTime / round((1 + inc/100) * more, 2)
end
t_insert(spellCount, { uuid = cacheSkillUUID(skill), cd = skill.skillData.cooldown, cdOverride = skill.skillModList:Override(skill.skillCfg, "CooldownRecovery"), addsCastTime = addsCastTime})
end
end
end
This loop uses the functions defined by each trigger to find an appropriate triggering source and to find all other skills that are triggered, so they can be fed into the skill rotation simulation function. Going lower, some validation takes place and the main trigger processing code starts.
if source and (source.skillTypes[SkillType.Melee] or source.skillTypes[SkillType.Damage] or source.skillTypes[SkillType.Attack]) then
sourceAPS, dualWield = calcDualWieldImpact(env, trigRate, source.skillData.doubleHitsWhenDualWielding)
end
--Account for source unleash
if GlobalCache.cachedData["CACHE"][uuid] and source.skillModList:Flag(nil, "HasSeals") and source.skillTypes[SkillType.CanRapidFire] then
sourceAPS = sourceAPS * (GlobalCache.cachedData["CACHE"][uuid].ActiveSkill.skillData.dpsMultiplier or 1)
env.player.mainSkill.skillFlags.HasSeals = true
source.skillData.hasUnleash = GlobalCache.cachedData["CACHE"][uuid].ActiveSkill.skillData.dpsMultiplier
end
First source attack/cast speed modifiers are applied and later the main function that calculates trigger speed is called calcActualTriggerRate. This function, along with getTriggerRateCap and calcMultiSpellRotationImpact calculates the raw trigger rate. It takes into account cooldown recovery and other factors that influence trigger speed. A good chunk of those functions is dedicated to generating a decent looking breakdown for the user as there are so many edge cases.

TODO:

  • Implement proper handling for cwdt loops.

Steps taken to verify a working solution:

Live vs pr side by side pictures:

discharge
localidentity
morethanonetrigger
poeninja1
poeninja2

@Paliak
Copy link
Contributor Author

Paliak commented Jul 15, 2022

Found issue. When there's no triggering skill the triggered skill is assumed to be cast by the trigger not self cast. Fixing.

Fixed by: #5b6ebd9e143a8b7540dd2fb95aa454ca24d81ba7

@QuickStick123 QuickStick123 added the enhancement New feature, calculation, or mod label Jul 16, 2022
@Paliak
Copy link
Contributor Author

Paliak commented Jul 16, 2022

Cast on melee kill and cast on stun not working correctly. Should behave closer to CWDT. Cast on Damage Taken currently doesn't take skill rotation into account. Fixing.

Should be Fixed.

Basic support for global triggers added.

@Paliak Paliak marked this pull request as draft July 16, 2022 19:51
@Paliak Paliak marked this pull request as ready for review July 19, 2022 21:09
@QuickStick123
Copy link
Contributor

QuickStick123 commented Aug 11, 2022

This skill isn't really implemented.
image
image
This skill is supposed to trigger Tawhoa's Chosen which summon's a Mirage Chieftain that attacks once with the given slam that triggered it with no echo/repeat.
image
#4732 Will fix this crash by dropping support.

@Paliak
Copy link
Contributor Author

Paliak commented Jun 1, 2023

I've moved trigger related code to a new file CalcTriggers.lua.

Some things are likely still broken but i've tested everything that makes sense to implement from https://www.poewiki.net/wiki/Trigger and everything should behave correctly.

@Paliak Paliak marked this pull request as ready for review June 1, 2023 08:01
@LocalIdentity LocalIdentity changed the base branch from dev to beta June 2, 2023 04:44
@LocalIdentity LocalIdentity merged commit 20d2a3b into PathOfBuildingCommunity:beta Jun 2, 2023
Paliak added a commit to Paliak/PathOfBuilding that referenced this pull request Jun 2, 2023
LocalIdentity added a commit that referenced this pull request Aug 21, 2023
* FEAT: impl more sources of self hit dmg

This code has been moved from #4599 after abandoning cwdt loop support.

* FIX: spelling

* FIX: remove file implemented in #4599

* Add support for non-Boneshatter Trauma

* Add new gems from 3.22 and other stuff

* Fix Crucible Export

* Fix Ruthless support to work with all ailments

* Update for actual support gem

* Support inc stun duration per trauma

* add devour, volatility and locus mine support (#6412)

* add devour, volatility and locus mine support

* Add full support for gems

Add mine tag to Locus Mine
Add support for Anomalous Devour
Fix Mine PvP damage multiplier
Fix flags for damage against full/low life enemies

---------

Co-authored-by: LocalIdentity <localidentity2@gmail.com>

* Spellblade support (#6343)

* Initial spellblade support

* Update label for spellblade damage breakdown

* Update with actual stats and qualities

* Update .txt too

* Floor all final flat values

---------

Co-authored-by: LocalIdentity <localidentity2@gmail.com>

* Fix export

* Add spacing and fix typos

Alter the breakdowns to no longer show the damage taken multi/taken % line if the value has not changed
Added spacing to the lines so you can more clearly read the breakdown when you have multiple taken as elements
Fix some spacing and spelling mistakes

---------

Co-authored-by: Paliak <91493239+Paliak@users.noreply.github.com>
Co-authored-by: Lilylicious <lily.hammerskog@gmail.com>
Co-authored-by: LocalIdentity <localidentity2@gmail.com>
Co-authored-by: Regisle <49933620+Regisle@users.noreply.github.com>
Co-authored-by: Lily <Lilylicious@users.noreply.github.com>
LocalIdentity added a commit that referenced this pull request Aug 24, 2023
…ork code. (#6447)

* Fix version number mishap

* move timeless jewel stuff (#5747)

* move timeless jewel stuff

* add back all the local versions of functions for future use

* Help section improvements (#6156)

* increase size of box and text

* implement hotkey to directly open help at a given section

* add ability to "fast scroll" to next section

* add section heights to changelog

* update txt

* fix merge issue

* fix line overlap and add note about scrollbars

* Add lot of stuff for ancestor league (#6288)

* FEAT: impl explode and extra support mods

* FEAT: impl new aura recovery mod

* FEAT: impl between you and linked target mods

* FEAT: impl Sentinel of Radiance mod

Currently implemented as less damage taken as that's what the
spreadsheet said.

I think this may be possible to implement like frost shield or other
"taken before you" mods given more info on stats of the sentinel.

* FEAT: impl reserved mana as armor mod

* FIX: use arbitrary taken before you instead of generic less dmg taken

* FIX: cache result of dmg type max hit str concat

* FEAT: code for generally supporting have no mods

* FEAT: impl resistance conversion mods

* FEAT: impl extra jewel func code for new chief mod

* FEAT: impl mod on all other slots condition

* FEAT: add new uniques

* Wording fixes, new unique

* Remove debugging lines

* Adding fire mastery explosion mod

* FIX: use ailment immunity flags from #6297

* Late breaking Chieftain change

* Update mod ranges

* Fix Amulet and belt

---------

Co-authored-by: Wires77 <Wires77@users.noreply.github.com>
Co-authored-by: LocalIdentity <31035929+LocalIdentity@users.noreply.github.com>

* FEAT: add immunity flags to breakdown (#6389)

* FIX: fix totem duration mods not applying (#6388)

* Fix DPS on Vaal Flicker when using 2x 1h weapons (#6380)

The block was inside the 2 pass loop so was running twice
Also fixes the issue when you used a custom `more DPS` mod

Co-authored-by: LocalIdentity <localidentity2@gmail.com>

* Apply RepeatCount according to their SkillTypes (#6376)

* Apply RepeatCount according to their SkillTypes

* Fix Vaal Flicker Strike

---------

Co-authored-by: LocalIdentity <localidentity2@gmail.com>

* Fix Immunities breakdown

* Fix Maata'a Teaching typo

* Fix allocation issue on convert while maintaining node id/name filtering (#6364)

* Fix lower channel time stat using red text (#6381)

* Fix lower channel time stat using red text

* Fix Channel time showing on calcs page for more skills than necessary

---------

Co-authored-by: LocalIdentity <localidentity2@gmail.com>

* Fix "Enemies maimed by you take inc damage over time` not in breakdown (#6400)

The mod was not displaying in the breakdown as it was using the dot flag instead of `DamageTakenOverTime`

Co-authored-by: LocalIdentity <localidentity2@gmail.com>

* Fix Pierce and Chain count config not appearing sometimes (#6401)

* Fix Pierced count config not appearing sometimes

* Fix Chain config not appearing

---------

Co-authored-by: LocalIdentity <localidentity2@gmail.com>

* Regen ModCache

* Fix Snipe damage going negative (#6399)

* FIX: snipe damage going negative

* Set SnipeStacks min value earlier

---------

Co-authored-by: LocalIdentity <31035929+LocalIdentity@users.noreply.github.com>

* Null-check node.finalModList when hovering trees (#6408)

Looks like node.finalModList is not initalized when hovering trees, this
simply null checks it.

Closes #6405

Signed-off-by: Tomas Slusny <slusnucky@gmail.com>

* Update 3.22 tree (#6411)

* update tree

* Fix rewording on Chieftain Node

---------

Co-authored-by: LocalIdentity <localidentity2@gmail.com>

* Fix Snipe showing DPS values when triggering support skills (#6415)

Added damage was still contributing to the damage of the skill so it was showing DPS numbers even if the skill was actually dealing no damage
Also removes the debug tooltip I forgot to remove from testing

Co-authored-by: LocalIdentity <localidentity2@gmail.com>

* 3.22 Additions (#6418)

* FEAT: impl more sources of self hit dmg

This code has been moved from #4599 after abandoning cwdt loop support.

* FIX: spelling

* FIX: remove file implemented in #4599

* Add support for non-Boneshatter Trauma

* Add new gems from 3.22 and other stuff

* Fix Crucible Export

* Fix Ruthless support to work with all ailments

* Update for actual support gem

* Support inc stun duration per trauma

* add devour, volatility and locus mine support (#6412)

* add devour, volatility and locus mine support

* Add full support for gems

Add mine tag to Locus Mine
Add support for Anomalous Devour
Fix Mine PvP damage multiplier
Fix flags for damage against full/low life enemies

---------

Co-authored-by: LocalIdentity <localidentity2@gmail.com>

* Spellblade support (#6343)

* Initial spellblade support

* Update label for spellblade damage breakdown

* Update with actual stats and qualities

* Update .txt too

* Floor all final flat values

---------

Co-authored-by: LocalIdentity <localidentity2@gmail.com>

* Fix export

* Add spacing and fix typos

Alter the breakdowns to no longer show the damage taken multi/taken % line if the value has not changed
Added spacing to the lines so you can more clearly read the breakdown when you have multiple taken as elements
Fix some spacing and spelling mistakes

---------

Co-authored-by: Paliak <91493239+Paliak@users.noreply.github.com>
Co-authored-by: Lilylicious <lily.hammerskog@gmail.com>
Co-authored-by: LocalIdentity <localidentity2@gmail.com>
Co-authored-by: Regisle <49933620+Regisle@users.noreply.github.com>
Co-authored-by: Lily <Lilylicious@users.noreply.github.com>

* Regen ModCache

* FIX: allow setting inspiration charges to 0 (#6421)

* Add support for Guardian's Blessing no reservation for auras (#6425)

Signed-off-by: Tomas Slusny <slusnucky@gmail.com>

* FEAT: impl sadism less ailment duration mod (#6431)

* FIX: incorrect increased usage mod range (#6434)

* Implement Corrupting Cry support (#6436)

* FEAT: impl Corrupting Cry support

* FIX: crash caused by incorrect capitalization

* FIX: add statMap and baseFlags to txt template

* FIX: spelling

* Revert "FEAT: impl Corrupting Cry support"

* FIX: reimplement using generic physDot

* FIX: copy paste issue

* FIX: cap corrupting blood staged.

Note that this config option also is affected by the one off bug in
config tab code.

* FIX: off by one in the config

* FIX: don't override skillData.durationSecondary

Overriding skillData.durationSecondary of exterted attacks may mess with
secondary effect of skills such as Dominating Blow

* FIX: CorruptingCry cfg stages not affecting exerts

* FIX: crash when hovering over more mult

* change dot type to corrupting blood to prevent dot from stacking

* Remove Attack dot addition + move config

* Fix removal of line

* Empty

---------

Co-authored-by: Paliak <91493239+Paliak@users.noreply.github.com>
Co-authored-by: LocalIdentity <localidentity2@gmail.com>

* Add support for new Ancestor uniques (#6426)

* Add mod text only

Signed-off-by: Wires77 <Wires77@users.noreply.github.com>

* Fix Level requirements and add Replica Dragonfang's Flight

* Support Ahuana's Bite

* Support Bound Fate

* Support Kahuturoa's Certainty

* Support Rakiata's Dance

* Fix global gem level/quality name change

---------

Signed-off-by: Wires77 <Wires77@users.noreply.github.com>
Co-authored-by: LocalIdentity <localidentity2@gmail.com>

* Removing allocated mastery from hover list (#6374)

* Removing allocated mastery from hover list

* Updating wording on mastery

---------

Co-authored-by: LocalIdentity <localidentity2@gmail.com>

* Add Ruthless tree (#6367)

* Add support for Ruthless trees

* Fix export URL for Ruthless trees

* Removed data.json

* Fix PR comments

* Fix edge cases around converting and importing

* Updating support for 3rd party ruthless tree links

* Update tree and add Tattoos

* Add support for new Ruthless tree mods

* Fix comment

---------

Co-authored-by: LocalIdentity <localidentity2@gmail.com>

* Support ruthless for poeskilltree

* Optimize itemLib.applyRange, improve startup time (#6407)

* Add applyRange tests

* Optimize itemLib.applyRange, improve startup time

* Fix tree import crash

* Tattoo implementation (#6396)

* Initial tattoo implementation

* Tattoo spec update

* Tattoo export

* Update spec

* Fix spec

* New dat files

* More fixes

* Add artwork, restrict Makanga tattoos

Signed-off-by: Wires77 <Wires77@users.noreply.github.com>

* Fix bug with saving/loading, cleanup code

* Fixed import bug and matched format for save files

* Fixing logic issues preventing proper tattoos from appearing

* Fixed bug with linked node count and supported new tattoo jewel

* Temp fix for effectSprites

* Can't tattoo changed nodes

* Fix tattoo interaction with Timeless jewels

* Update tree, fix more bugs

* Add dropdown search

* Add help text to tattoo dropdown

* Fix stat description error

* Dynamically set popup width

* Made popup width fully dynamic

* Truncate mod lines in tattoo popup

* text wrap in popup

* Dynamic word wrapping, ignoring GGG wrapping

* Revert tree merge

---------

Signed-off-by: Wires77 <Wires77@users.noreply.github.com>
Co-authored-by: LocalIdentity <localidentity2@gmail.com>
Co-authored-by: Peechey <92683202+Peechey@users.noreply.github.com>

* Fix secondary effect skills being added as supports (#6393)

* FIX:secondary effect skills being added as support

* FIX: cleanup duplicate code

* Fix Bleed/Ignite Stack potential issues (#6386)

The config was not affecting the number of bleeds/ignites affecting the enemy and was instead only affecting the average roll %
Ignite and Bleed roll % was not calculated to be at least 50% roll as a minimum
Ignite was also not taking into account Hit Chance when calculating the average roll
Breakdowns were improved to show the potential when max stacks is more than 1

Co-authored-by: LocalIdentity <localidentity2@gmail.com>

* Regen ModCache

* Version dropdown QoL (#6365)

* Version dropdown QoL

* ruthless update

* Add support for Fresh Meat Support (#6443)

* Add support for Fresh Meat Support

* Adding general support for increased minion critical strike chance

* Move Config

---------

Co-authored-by: LocalIdentity <31035929+LocalIdentity@users.noreply.github.com>

* Implement Sacrifice, Frigid Bond, Guardian's Blessing, Controlled Blaze

* Add initial support for Guardian Minions (#6445)

Adds support for the new Guardian minions to show in the sidebar. The level is manually set to 85 right now as we don't support the `minion_actor_level_is_user_level_up_to_maximum` stat yet

Co-authored-by: LocalIdentity <localidentity2@gmail.com>

* Release 2.32.0 (#6440)

* Prepare release 2.32.0

* Fix changelogs

* Spelling

---------

Co-authored-by: LocalIdentity <LocalIdentity@users.noreply.github.com>
Co-authored-by: LocalIdentity <localidentity2@gmail.com>

---------

Signed-off-by: Tomas Slusny <slusnucky@gmail.com>
Signed-off-by: Wires77 <Wires77@users.noreply.github.com>
Co-authored-by: Wires77 <Wires77@users.noreply.github.com>
Co-authored-by: Regisle <49933620+Regisle@users.noreply.github.com>
Co-authored-by: LocalIdentity <31035929+LocalIdentity@users.noreply.github.com>
Co-authored-by: LocalIdentity <localidentity2@gmail.com>
Co-authored-by: Peechey <92683202+Peechey@users.noreply.github.com>
Co-authored-by: Tomas Slusny <slusnucky@gmail.com>
Co-authored-by: Lilylicious <lily.hammerskog@gmail.com>
Co-authored-by: Lily <Lilylicious@users.noreply.github.com>
Co-authored-by: Lancej <1243476+Lancej@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: LocalIdentity <LocalIdentity@users.noreply.github.com>
@Paliak Paliak deleted the triggerfix branch January 23, 2024 19:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working crash Causes PoB to crash and is High Priority enhancement New feature, calculation, or mod

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Kitava's thirst trigger rate

8 participants