Skip to content
Open
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
9 changes: 9 additions & 0 deletions src/Data/BuffStatMap.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
-- Path of Building
--
-- Stat to internal modifier mapping table for buffs
-- Stat data (c) Grinding Gear Games
--
local mod, flag, skill = ...

return {
}
70 changes: 70 additions & 0 deletions src/Data/Buffs/general.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
-- This file is automatically generated, do not edit!
-- Path of Building
--
-- Buff data (c) Grinding Gear Games
--
local buffs, mod, flag = ...

buffs["archon_elemental"] = {
name = "Elemental Archon",
check="Condition:CanHaveElementalArchon",
condition="ElementalArchon",
statMap={
["elemental_damage_with_spell_skills_+%_final_from_archon_buff"]={
mod("ElementalDamage", "MORE", nil, ModFlag.Spell),
},
["archon_spells_ignite_chance_+%_final"]={
mod("EnemyIgniteChance", "MORE", nil, ModFlag.Spell),
},
["archon_spells_hit_damage_freeze_multiplier_+%_final"]={
mod("EnemyFreezeBuildup", "MORE", nil, ModFlag.Spell),
},
["archon_spells_shock_chance_+%_final"]={
mod("EnemyShockChance", "MORE", nil, ModFlag.Spell),
}
},
incEffectMods={
"ArchonEffect"
},
durationIncMods={
"ArchonDuration"
},
ignoreIncEffectMods={
},
stats={
"elemental_damage_with_spell_skills_+%_final_from_archon_buff",
"base_movement_velocity_+%",
"base_resist_all_elements_%",
"archon_spells_ignite_chance_+%_final",
"archon_spells_hit_damage_freeze_multiplier_+%_final",
"archon_spells_shock_chance_+%_final",
"base_critical_strike_multiplier_+",
"critical_strike_chance_+%",
},
flags={
"have_archon_elemental",
"deal_no_non_elemental_spell_damage",
"base_is_floating",
},
grants={
"elemental_damage_with_spell_skills_+%_final_from_archon_buff",
"base_movement_velocity_+%",
"base_resist_all_elements_%",
"archon_spells_ignite_chance_+%_final",
"archon_spells_hit_damage_freeze_multiplier_+%_final",
"archon_spells_shock_chance_+%_final",
"base_critical_strike_multiplier_+",
"critical_strike_chance_+%",
},
values={
{"buff_impl_stat",25},
{"archon_grants_movement_speed_+%",0},
{"archon_grants_all_elemental_resistance_+%",0},
{"buff_impl_stat",100},
{"buff_impl_stat",100},
{"buff_impl_stat",100},
{"archon_grants_base_critical_strike_multiplier_+",0},
{"archon_grants_critical_strike_chance_+%",0},
},
duration = 10,
}
5 changes: 5 additions & 0 deletions src/Data/Skills/sup_int.lua
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,11 @@ skills["SupportArbitersIgnitionPlayer"] = {
label = "Arbiter's Ignition",
incrementalEffectiveness = 0.054999999701977,
statDescriptionScope = "gem_stat_descriptions",
statMap = {
["gain_archon_elemental_when_you_ignite_enemy_chance_%"] = {
flag("Condition:CanHaveElementalArchon", { type = "GlobalEffect", effectType = "Buff" }),
},
},
baseFlags = {
},
constantStats = {
Expand Down
32 changes: 32 additions & 0 deletions src/Export/Buffs/general.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
-- Path of Building
--
-- Buff data (c) Grinding Gear Games
--
local buffs, mod, flag = ...

#buff archon_elemental
#condition ElementalArchon
statMap={
["elemental_damage_with_spell_skills_+%_final_from_archon_buff"]={
mod("ElementalDamage", "MORE", nil, ModFlag.Spell),
},
["archon_spells_ignite_chance_+%_final"]={
mod("EnemyIgniteChance", "MORE", nil, ModFlag.Spell),
},
["archon_spells_hit_damage_freeze_multiplier_+%_final"]={
mod("EnemyFreezeBuildup", "MORE", nil, ModFlag.Spell),
},
["archon_spells_shock_chance_+%_final"]={
mod("EnemyShockChance", "MORE", nil, ModFlag.Spell),
}
},
incEffectMods={
"ArchonEffect"
},
durationIncMods={
"ArchonDuration"
},
ignoreIncEffectMods={
},
#stats
#buffEnd
89 changes: 89 additions & 0 deletions src/Export/Scripts/buff.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
if not loadStatFile then
dofile("statdesc.lua")
end
loadStatFile("stat_descriptions.csd")

local directiveTable = { }

-- #Buff <BuffDefinitionId>
directiveTable.buff = function(state, args, out)
state.currentBuffId = args
local bufDefinitionID = dat("buffdefinitions"):GetRow("Id", state.currentBuffId)
if not bufDefinitionID then
error("BuffDefinitionId '" .. state.currentBuffId .. "' not found in database")
end
state.currentBuffDefinitionId = bufDefinitionID
out:write('buffs["', state.currentBuffId, '"] = {\n')

-- print name
if bufDefinitionID.Name then
out:write('\tname = "', bufDefinitionID.Name:gsub('"', '\\"'), '",\n')
end
end

directiveTable.buffEnd = function(state, args, out)
state.currentBuffId = nil
state.currentBuffDefinitionId = nil
out:write('}')
end

-- #condition <condition>
-- build "Condition:<condition>" and "Condition:CanHave<condition>"
directiveTable.condition = function(state, args, out)
out:write('\tcheck="Condition:CanHave' .. args .. '",\n')
out:write('\tcondition="' .. args .. '",\n')
end

-- #stats
directiveTable.stats = function(state, args, out)
if not state.currentBuffDefinitionId.Stats then
error("BuffDefinitionId '" .. state.currentBuffId .. "' has no associated stats")
end

print("Writing stats for buff " .. state.currentBuffId)
local stats = state.currentBuffDefinitionId.Stats
local flags = state.currentBuffDefinitionId.GrantedFlags
local grantStats = state.currentBuffDefinitionId.GrantedStats

out:write('\tstats={\n')
for k, stat in ipairs(stats) do
print(" Writing stat " .. stat.Id)
out:write('\t\t"' .. stat.Id .. '",\n')
end
out:write('\t},\n')

out:write('\tflags={\n')
for k, stat in ipairs(flags) do
print(" Writing flag " .. stat.Id)
out:write('\t\t"' .. stat.Id .. '",\n')
end
out:write('\t},\n')

out:write('\tgrants={\n')
for k, stat in ipairs(grantStats) do
print(" Writing granted stat " .. stat.Id)
out:write('\t\t"' .. stat.Id .. '",\n')
end
out:write('\t},\n')

-- now search for bufftemplates that reference this buffdefinition
print("Searching for buff templates for buff " .. state.currentBuffId)
local buffTemplates = dat("bufftemplates"):GetRow("BuffDefinition", state.currentBuffDefinitionId)
if buffTemplates then
out:write('\tvalues={\n')
for k, stat in ipairs(buffTemplates.Stats) do
print(" Writing template stat " .. stat.Id)
out:write('\t\t{"' .. stat.Id .. '",' .. buffTemplates.StatValues[k] .. '}')
out:write(',\n')
end
out:write('\t},\n')
-- enable duration
out:write('\tduration = ', buffTemplates.Duration, ',\n')
end
end

for _, name in pairs({"general"}) do
processTemplateFile(name, "Buffs/", "../Data/Buffs/", directiveTable)
end

print("Buff data exported.")
5 changes: 5 additions & 0 deletions src/Export/Skills/sup_int.txt
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,11 @@ statMap = {

#skill SupportArbitersIgnitionPlayer
#set SupportArbitersIgnitionPlayer
statMap = {
["gain_archon_elemental_when_you_ignite_enemy_chance_%"] = {
flag("Condition:CanHaveElementalArchon", { type = "GlobalEffect", effectType = "Buff" }),
},
},
#mods
#skillEnd

Expand Down
93 changes: 93 additions & 0 deletions src/Modules/CalcPerform.lua
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,38 @@ local m_modf = math.modf
local s_format = string.format
local m_huge = math.huge

-- Merge level modifier with given mod list
local mergeLevelCache = { }
local function mergeLevelMod(modList, mod, value, scale)
if not value then
modList:AddMod(mod)
return
end
if not mergeLevelCache[mod] then
mergeLevelCache[mod] = { }
end
if mergeLevelCache[mod][value] then
modList:AddMod(mergeLevelCache[mod][value])
elseif value then
local newMod = copyTable(mod, true)
if type(newMod.value) == "table" then
newMod.value = copyTable(newMod.value, true)
if newMod.value.mod then
newMod.value.mod = copyTable(newMod.value.mod, true)
newMod.value.mod.value = value
else
newMod.value.value = value
end
else
newMod.value = value
end
mergeLevelCache[mod][value] = newMod
modList:ScaleAddMod(newMod, scale)
else
modList:ScaleAddMod(mod, scale)
end
end

--- getCachedOutputValue
--- retrieves a value specified by key from a cached version of skill
--- specified by @uuid or if not found in cache computes teh cache.
Expand Down Expand Up @@ -696,6 +728,67 @@ local function doActorMisc(env, actor)
local max = modDB:Override(nil, "SoulEaterMax") or modDB:Sum("BASE", nil, "SoulEaterMax")
modDB:NewMod("Multiplier:SoulEater", "BASE", 1, "Base", { type = "Multiplier", var = "SoulEaterStack", limit = max })
end

-- Build the list of buff base on conditions "Condition:CanHave<Buff>"
for buffId, buffInfo in pairs(env.data.buffs) do
if modDB:Flag(nil, buffInfo.check) then
-- add buff stats
local modBuffList = new("ModList")

-- calculate inc Effect modifier
local buffEffectMod = 1
local incSum = 0
for _, incEffect in ipairs(buffInfo.incEffectMods or {}) do
incSum = incSum + modDB:Sum("INC", nil, incEffect)
end
buffEffectMod = buffEffectMod * (1 + incSum / 100)

-- calculate duration modifier
local durationIncSum = 0
for _, durationInc in ipairs(buffInfo.durationIncMods or {}) do
durationIncSum = durationIncSum + modDB:Sum("INC", nil, durationInc)
end

-- add mods base for duration
modBuffList:NewMod(buffInfo.condition .. "Duration", "BASE", buffInfo.duration, "Base Duration")

env.player.output[buffInfo.condition .. "Duration"] = m_floor(buffInfo.duration * (1 + durationIncSum / 100))
env.player.output[buffInfo.condition .. "IncEffect"] = buffEffectMod * 100

for k, stat in ipairs(buffInfo.stats) do
local statValue = buffInfo.values and buffInfo.values[k] and buffInfo.values[k][2] or 0
local map = buffInfo.statMap[stat]
if map then
-- Some mods need different scalars for different stats, but the same value. Putting them in a group allows this
for _, mod in ipairs(map) do
-- Found a mod, since all mods have names
local modOrGroup = copyTable(mod)

-- we should add the conditional flag for each mod coming from a buff
table.insert(modOrGroup, { type = "Condition", var = buffInfo.condition })

-- add multiplier for buff effect
local modIncBuffEffect = 1
if modOrGroup.name~= nil or buffInfo.ignoreIncEffectMods[modOrGroup.name] ~= true then
modIncBuffEffect = buffEffectMod
end

if modOrGroup.name then
modOrGroup.source = string.format("Buff:%s", buffId)
mergeLevelMod(modBuffList, modOrGroup, map.value or statValue * (map.mult or 1) / (map.div or 1) + (map.base or 0), modIncBuffEffect)
else
for _, mod in ipairs(modOrGroup) do
mod.source = string.format("Buff:%s", buffId)
mergeLevelMod(modBuffList, mod, modOrGroup.value or statValue * (modOrGroup.mult or 1) / (modOrGroup.div or 1) + (modOrGroup.base or 0), modIncBuffEffect)
end
end
end
end
end

modDB:AddList(modBuffList)
end
end
end

-- Process enemy modifiers
Expand Down
7 changes: 7 additions & 0 deletions src/Modules/CalcSections.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1431,6 +1431,13 @@ return {
{ breakdown = "OffHand.KnockbackDistance" },
{ modName = "EnemyKnockbackDistance", cfg = "weapon2" },
}, },
{ label = "Archon Effect", haveOutput = "ElementalArchonIncEffect", { format = "{0:output:ElementalArchonIncEffect}%",
{ modName = "ArchonEffect"},
}, },
{ label = "Archon Duration", haveOutput = "ElementalArchonDuration", { format = "{2:output:ElementalArchonDuration}s",
{ modName = "ElementalArchonDuration"},
{ modName = "ArchonDuration"},
}, },
{ label = "Presence Mod", haveOutput = "PresenceMod", { format = "{2:output:PresenceMod}", { breakdown = "PresenceMod" }, { modName = "PresenceRadius", cfg = "skill" }} , },
{ label = "Presence Radius", haveOutput = "PresenceRadius", { format = "{1:output:PresenceRadiusMetres}m", { breakdown = "PresenceRadius" }, { modName = "PresenceArea", cfg = "skill"} }, },
{ label = "Surrounded Mod", haveOutput = "SurroundedMod", { format = "{2:output:SurroundedMod}", { breakdown = "SurroundedMod" }, { modName = "SurroundedRadius", cfg = "skill" }} , },
Expand Down
5 changes: 5 additions & 0 deletions src/Modules/Calcs.lua
Original file line number Diff line number Diff line change
Expand Up @@ -704,6 +704,11 @@ function calcs.buildOutput(build, mode)
if env.modDB:Flag(nil, "Elusive") then
t_insert(combatList, "Elusive")
end
for buffId, buffInfo in pairs(env.data.buffs) do
if env.modDB:Flag(nil, buffInfo.check) then
t_insert(combatList, buffInfo.name)
end
end
table.sort(buffList)
env.player.breakdown.SkillBuffs = { modList = { } }
for _, name in ipairs(buffList) do
Expand Down
4 changes: 4 additions & 0 deletions src/Modules/ConfigOptions.lua
Original file line number Diff line number Diff line change
Expand Up @@ -849,6 +849,10 @@ Huge sets the radius to 11.
{ var = "buffArcaneSurge", type = "check", label = "Do you have Arcane Surge?", tooltip = "In addition to allowing any 'while you have Arcane Surge' modifiers to apply,\nthis will enable the Arcane Surge buff itself. (Grants 15% increased Cast Speed and 20% more Mana Regeneration rate)", apply = function(val, modList, enemyModList)
modList:NewMod("Condition:ArcaneSurge", "FLAG", true, "Config", { type = "Condition", var = "Combat" })
end },
{ var = "buffElementalArchon", type = "check", label = "Do you have Elemental Archon?", ifFlag = "Condition:CanHaveElementalArchon", tooltip = "", apply = function(val, modList, enemyModList)
modList:NewMod("Condition:ElementalArchon", "FLAG", true, "Config", { type = "Condition", var = "Combat" })
modList:NewMod("Condition:ArchonBuff", "FLAG", true, "Config", { type = "Condition", var = "Combat" })
end },
{ var = "buffQuicksandHourglass", type = "check", label = "Do you have Quicksand Hourglass?", ifFlag = "Condition:CanGainQuicksandHourglass", tooltip = "this will enable the Quicksand Hourglass buff itself.", apply = function(val, modList, enemyModList)
modList:NewMod("Condition:QuicksandHourglass", "FLAG", true, "Config", { type = "Condition", var = "Combat" })
end },
Expand Down
Loading
Loading