Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 51 additions & 65 deletions src/Data/ModCache.lua

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions src/Data/SkillStatMap.lua
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,9 @@
["base_skill_cost_life_instead_of_mana"] = {
flag("CostLifeInsteadOfMana"),
},
["generic_ongoing_triggerer_is_invocation_skill"] = {

Check warning on line 181 in src/Data/SkillStatMap.lua

View workflow job for this annotation

GitHub Actions / spellcheck

Unknown word (triggerer)
flag("Condition:InvocationSkill"),
},
["base_skill_cost_life_instead_of_mana_%"] = {
mod("HybridManaAndLifeCost_Life", "BASE", nil),
},
Expand Down
6 changes: 5 additions & 1 deletion src/Modules/CalcDefence.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1530,7 +1530,11 @@ function calcs.defence(env, actor)
if modDB.conditions["AffectedByArcaneSurge"] or modDB:Flag(nil, "Condition:ArcaneSurge") then
modDB.conditions["AffectedByArcaneSurge"] = true
local effect = 1 + modDB:Sum("INC", nil, "ArcaneSurgeEffect", "BuffEffectOnSelf") / 100
modDB:NewMod("ManaRegen", "MORE", (modDB:Max(nil, "ArcaneSurgeManaRegen") or 20) * effect, "Arcane Surge")
if modDB:Flag(nil, "ArcaneSurgeLifeRegen") then
modDB:NewMod("LifeRegen", "MORE", (modDB:Max(nil, "ArcaneSurgeManaRegen") or 20) * effect, "Arcane Surge")
else
modDB:NewMod("ManaRegen", "MORE", (modDB:Max(nil, "ArcaneSurgeManaRegen") or 20) * effect, "Arcane Surge")
end
modDB:NewMod("Speed", "INC", (modDB:Max(nil, "ArcaneSurgeCastSpeed") or 15) * effect, "Arcane Surge", ModFlag.Cast)
local arcaneSurgeDamage = modDB:Max(nil, "ArcaneSurgeDamage") or 0
if arcaneSurgeDamage ~= 0 then modDB:NewMod("Damage", "MORE", arcaneSurgeDamage * effect, "Arcane Surge", ModFlag.Spell) end
Expand Down
29 changes: 20 additions & 9 deletions src/Modules/CalcOffence.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1152,7 +1152,7 @@ function calcs.offence(env, actor, activeSkill)
if skillModList:Flag(skillCfg, "CannotChain") or skillModList:Flag(skillCfg, "NoAdditionalChains")then
output.ChainMaxString = "Cannot chain"
else
output.ChainMax = skillModList:Sum("BASE", skillCfg, "ChainCountMax", not skillFlags.projectile and "BeamChainCountMax" or nil) * skillModList:More(skillCfg, "ChainCountMax", not skillFlags.projectile and "BeamChainCountMax" or nil)
output.ChainMax = (skillModList:Sum("BASE", skillCfg, "ChainCountMax", not skillFlags.projectile and "BeamChainCountMax" or nil) + skillModList:Sum("BASE", skillCfg, "ChainChance") / 100) * skillModList:More(skillCfg, "ChainCountMax", not skillFlags.projectile and "BeamChainCountMax" or nil)
output.TerrainChain = m_min(skillModList:Sum("BASE", skillCfg, "TerrainChainChance"), 100)
if skillModList:Flag(skillCfg, "AdditionalProjectilesAddChainsInstead") then
output.ChainMax = output.ChainMax + m_floor((skillModList:Sum("BASE", skillCfg, "ProjectileCount") - 1) * skillModList:More(skillCfg, "ProjectileCount"))
Expand Down Expand Up @@ -2659,6 +2659,7 @@ function calcs.offence(env, actor, activeSkill)
output.BoltCount = skillData.boltCount
output.EffectiveBoltCount = output.BoltCount
output.ChanceToNotConsumeAmmo = activeSkill.skillModList:Sum("BASE", activeSkill.skillCfg, "ChanceToNotConsumeAmmo")
output.ChanceToReloadInstantly = m_min(activeSkill.skillModList:Sum("BASE", activeSkill.skillCfg, "InstantReloadChance"), 100)
if output.ChanceToNotConsumeAmmo > 0 then
if output.ChanceToNotConsumeAmmo < 100 then
output.EffectiveBoltCount = output.BoltCount / (1 - (output.ChanceToNotConsumeAmmo / 100))
Expand All @@ -2669,11 +2670,12 @@ function calcs.offence(env, actor, activeSkill)
output.TotalFiringTime = 1 / output.FiringRate * ((output.ChanceToNotConsumeAmmo >= 100) and 0 or output.EffectiveBoltCount)
output.ReloadRate = 1 / skillData.reloadTime
output.ReloadTime = skillData.reloadTime
output.Speed = (output.ChanceToNotConsumeAmmo >= 100) and output.FiringRate or (1 / ((output.TotalFiringTime + output.ReloadTime) / (output.EffectiveBoltCount)))
output.EffectiveReloadTime = output.ReloadTime * (1 - output.ChanceToReloadInstantly / 100)
output.Speed = (output.ChanceToNotConsumeAmmo >= 100) and output.FiringRate or (1 / ((output.TotalFiringTime + output.EffectiveReloadTime) / (output.EffectiveBoltCount)))

-- Average bolts reloaded past six second for purposes of calculating Fresh Clip support damage bonus
local boltsReloadedPastSixSeconds = skillModList:Override({ source = "Config"}, "Multiplier:BoltsReloadedPastSixSeconds") or (output.ChanceToNotConsumeAmmo > 100) and 0 or (output.BoltCount * 6 / (output.TotalFiringTime + output.ReloadTime)) -- assume 0 bolts reloaded when none are consumed
local boltsReloadedPastEightSeconds = skillModList:Override({ source = "Config"}, "Multiplier:BoltsReloadedPastEightSeconds") or (output.ChanceToNotConsumeAmmo > 100) and 0 or (output.BoltCount * 8 / (output.TotalFiringTime + output.ReloadTime)) -- assume 0 bolts reloaded when none are consumed
local boltsReloadedPastSixSeconds = skillModList:Override({ source = "Config"}, "Multiplier:BoltsReloadedPastSixSeconds") or (output.ChanceToNotConsumeAmmo > 100) and 0 or (output.BoltCount * 6 / (output.TotalFiringTime + output.EffectiveReloadTime)) -- assume 0 bolts reloaded when none are consumed
local boltsReloadedPastEightSeconds = skillModList:Override({ source = "Config"}, "Multiplier:BoltsReloadedPastEightSeconds") or (output.ChanceToNotConsumeAmmo > 100) and 0 or (output.BoltCount * 8 / (output.TotalFiringTime + output.EffectiveReloadTime)) -- assume 0 bolts reloaded when none are consumed
if boltsReloadedPastSixSeconds > 0 then
skillModList:ReplaceMod("Multiplier:BoltsReloadedPastSixSeconds", "BASE", boltsReloadedPastSixSeconds, activeSkill.activeEffect.grantedEffect.name)
end
Expand Down Expand Up @@ -2733,10 +2735,10 @@ function calcs.offence(env, actor, activeSkill)

breakdown.Speed = { }
t_insert(breakdown.Speed, s_format(" %.2fs ^8(total firing time)", output.TotalFiringTime))
t_insert(breakdown.Speed, s_format("+ %.2fs ^8(reload time)", output.ReloadTime))
t_insert(breakdown.Speed, s_format("= %.2fs ^8(total attack time)", output.TotalFiringTime + output.ReloadTime))
t_insert(breakdown.Speed, s_format("+ %.2fs ^8(eff. reload time)", output.EffectiveReloadTime))
t_insert(breakdown.Speed, s_format("= %.2fs ^8(total attack time)", output.TotalFiringTime + output.EffectiveReloadTime))
t_insert(breakdown.Speed, s_format("\n"))
t_insert(breakdown.Speed, s_format(" %.2fs ^8(total attack time)", output.TotalFiringTime + output.ReloadTime))
t_insert(breakdown.Speed, s_format(" %.2fs ^8(total attack time)", output.TotalFiringTime + output.EffectiveReloadTime))
t_insert(breakdown.Speed, s_format("/ %.2f ^8(eff. bolt count)", output.EffectiveBoltCount))
t_insert(breakdown.Speed, s_format("= %.2fs ^8(eff. attack time)", 1 / output.Speed))
t_insert(breakdown.Speed, s_format("\n"))
Expand Down Expand Up @@ -4101,11 +4103,13 @@ function calcs.offence(env, actor, activeSkill)
-- Combine stats related to reload and bolt functionality
combineStat("FiringRate", "AVERAGE")
combineStat("ReloadTime", "AVERAGE")
combineStat("EffectiveReloadTime", "AVERAGE")
combineStat("ReloadRate", "AVERAGE")
combineStat("BoltCount", "AVERAGE")
combineStat("EffectiveBoltCount", "AVERAGE")
combineStat("TotalFiringTime", "AVERAGE")
combineStat("ChanceToNotConsumeAmmo", "AVERAGE")
combineStat("ChanceToReloadInstantly", "AVERAGE")

-- Add stats related to "Chance to not consume a bolt" to breakdown
if breakdown then
Expand All @@ -4116,6 +4120,13 @@ function calcs.offence(env, actor, activeSkill)
t_insert(breakdown.EffectiveBoltCount, s_format("\n"))
t_insert(breakdown.EffectiveBoltCount, s_format("= %.2f ^8(effective bolt count)", output.EffectiveBoltCount or (1/0))) -- 1/0 is used as a stand-in for "infinite"
end
if output.ChanceToReloadInstantly then
breakdown.EffectiveReloadTime = { }
t_insert(breakdown.EffectiveReloadTime, s_format("%.2f ^8(reload time)", output.ReloadTime))
t_insert(breakdown.EffectiveReloadTime, s_format("* (1 - %.2f) ^8(chance to reload instantly)", m_min(output.ChanceToReloadInstantly / 100, 1)))
t_insert(breakdown.EffectiveReloadTime, s_format("\n"))
t_insert(breakdown.EffectiveReloadTime, s_format("= %.2f ^8(effective reload time)", output.EffectiveReloadTime))
end

end
-- Game data specifies "base skill show average damage instead of dps" for many crossbow skills, where that doesn't make sense for PoB (e.g. Explosive Shot)
Expand Down Expand Up @@ -5388,8 +5399,8 @@ function calcs.offence(env, actor, activeSkill)
elseif skillModList:Flag(nil, "HasSeals") and skillModList:Flag(nil, "UseMaxUnleash") then
useSpeed = env.player.mainSkill.skillData.hitTimeOverride / repeats
timeType = "full unleash"
elseif output.ReloadTime then -- Crossbows: Account for mana cost only happening on reload (once all bolts are fired)
useSpeed = (not output.EffectiveBoltCount) and 0 or (1 / (output.TotalFiringTime + output.ReloadTime))
elseif output.EffectiveReloadTime then -- Crossbows: Account for mana cost only happening on reload (once all bolts are fired)
useSpeed = (not output.EffectiveBoltCount) and 0 or (1 / (output.TotalFiringTime + output.EffectiveReloadTime))
timeType = "effective reload"
else
useSpeed = (output.Cooldown and output.Cooldown > 0 and (output.Speed > 0 and output.Speed or 1 / output.Cooldown) or output.Speed) / repeats
Expand Down
15 changes: 13 additions & 2 deletions src/Modules/CalcPerform.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1011,8 +1011,8 @@ function calcs.perform(env, skipEHP)
output.WarcryPower = modDB:Override(nil, "WarcryPower") or modDB:Sum("BASE", nil, "WarcryPower") or 0
modDB.multipliers["WarcryPower"] = output.WarcryPower

local minionTypeCount = 0
local minionType = { }
local minionTypeCount, ammoTypeCount, grenadeTypeCount = 0, 0, 0
local minionType, ammoType, grenadeType = { }, { }, { }
for _, activeSkill in ipairs(env.player.activeSkillList) do
local skillFlags
if env.mode == "CALCS" then
Expand Down Expand Up @@ -1087,6 +1087,16 @@ function calcs.perform(env, skipEHP)
minionType[activeSkill.activeEffect.grantedEffect.id] = true
end
env.modDB.multipliers["PersistentMinionTypes"] = minionTypeCount
if activeSkill.skillTypes[SkillType.CrossbowAmmoSkill] and not ammoType[activeSkill.activeEffect.grantedEffect.id] then
ammoTypeCount = ammoTypeCount + 1
ammoType[activeSkill.activeEffect.grantedEffect.id] = true
end
env.modDB.multipliers["AmmoTypes"] = ammoTypeCount
if activeSkill.skillTypes[SkillType.Grenade] and not grenadeType[activeSkill.activeEffect.grantedEffect.id] then
grenadeTypeCount = grenadeTypeCount + 1
grenadeType[activeSkill.activeEffect.grantedEffect.id] = true
end
env.modDB.multipliers["GrenadeTypes"] = grenadeTypeCount
if activeSkill.activeEffect.grantedEffect and activeSkill.skillTypes[SkillType.CreatesCompanion] then
modDB:NewMod("Condition:HaveCompanion", "FLAG", true, activeSkill.activeEffect.grantedEffect.name)
end
Expand Down Expand Up @@ -2937,6 +2947,7 @@ function calcs.perform(env, skipEHP)
end
min = min * (modDB:Sum("INC", nil, element.."ExposureEffect") / 100 + 1)
enemyDB:NewMod("Condition:Has"..element.."Exposure", "FLAG", true, "")
enemyDB:NewMod("Condition:HasExposure", "FLAG", true, "")
enemyDB:NewMod(element.."Resist", "BASE", m_min(min, modDB:Override(nil, "ExposureMin")), source)
modDB:NewMod("Condition:AppliedExposureRecently", "FLAG", true, "")
end
Expand Down
3 changes: 2 additions & 1 deletion src/Modules/CalcSections.lua
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,7 @@ return {
{ label = "Inc. Reload Speed", haveOutput = "ReloadTime", notFlag = "triggered", { format = "{0:mod:1}%", { modName = "ReloadSpeed", modType = "INC", cfg = "skill"}, }, },
{ label = "More Reload Speed", haveOutput = "ReloadTime", notFlag = "triggered", { format = "{0:mod:1}%", { modName = "ReloadSpeed", modType = "MORE", cfg = "skill"}, }, },
{ label = "Reload Time", haveOutput = "ReloadTime", notFlag = "triggered", { format = "{2:output:ReloadTime}s", { breakdown = "ReloadTime" }, }, },
{ label = "Eff. Reload Time", haveOutput = "ChanceToReloadInstantly", { format = "{2:output:EffectiveReloadTime}", { breakdown = "EffectiveReloadTime" }, }, },
{ label = "Attacks per second", flag = "bothWeaponAttack", notFlag = "triggered", { format = "{2:output:Speed}", { breakdown = "Speed" }, }, },
{ label = "Attack time", flag = "attack", notFlag = "triggered", { format = "{2:output:Time}s", { breakdown = "MainHand.Time" }, }, },
{ label = "Inc. Cast Speed", flag = "spell", notFlag = "triggered", { format = "{0:mod:1}%", { modName = "Speed", modType = "INC", cfg = "skill", }, }, },
Expand Down Expand Up @@ -679,7 +680,7 @@ return {
{ label = "2 Add. Proj. Chance", haveOutput = "TwoAdditionalProjectiles", { format = "{output:TwoAdditionalProjectiles}%", { modName = { "TwoAdditionalProjectilesChance", "NoAdditionalProjectiles" }, cfg = "skill" }, }, },
{ label = "Pierce Count", haveOutput = "PierceCount", { format = "{output:PierceCountString}", { modName = { "CannotPierce", "PierceCount", "PierceChance", "PierceAllTargets" }, cfg = "skill" }, }, },
{ label = "Fork Count", haveOutput = "ForkCountMax", { format = "{output:ForkCountString}", { modName = { "CannotFork", "ForkCountMax" }, cfg = "skill" }, }, },
{ label = "Max Chain Count", haveOutput = "ChainMax", { format = "{output:ChainMaxString}", { modName = { "CannotChain", "ChainCountMax", "NoAdditionalChains" }, cfg = "skill" }, }, },
{ label = "Max Chain Count", haveOutput = "ChainMax", { format = "{output:ChainMaxString}", { modName = { "CannotChain", "ChainCountMax", "ChainChance", "NoAdditionalChains" }, cfg = "skill" }, }, },
{ label = "Terrain Chain", haveOutput = "TerrainChain", { format = "{output:TerrainChain}%", { modName = { "TerrainChainChance", "NoAdditionalChains" }, cfg = "skill" }, }, },
{ label = "Split Count", haveOutput = "SplitCountString", { format = "{output:SplitCountString}",
{ label = "Player modifiers", modName = { "CannotSplit", "SplitCount", "AdditionalProjectilesAddSplitsInstead", "AdditionalChainsAddSplitsInstead" }, cfg = "skill" },
Expand Down
Loading
Loading