Files
PathOfBuilding/Export/skills.lua
Openarl 2806cbac3d 1.4.118 Initial commit
- Added/updated skill gems and bases
- Fixed curse stats with wrong sign
- Fixed wrong sources on quality mods
2018-12-09 16:29:54 +13:00

527 lines
16 KiB
Lua

-- Skill types:
-- 1 Attack
-- 2 Spell
-- 3 Fires projectiles
-- 4 Dual wield skill (Only on Dual Strike)
-- 5 Buff
-- 6 Only uses main hand
-- 7 Combines both weapons? (Only on Cleave)
-- 8 Minion skill
-- 9 Spell with hit damage
-- 10 Area
-- 11 Duration
-- 12 Shield skill
-- 13 Projectile damage
-- 14 Mana cost is reservation
-- 15 Mana cost is percentage
-- 16 Skill can be trap?
-- 17 Spell can be totem?
-- 18 Skill can be mine?
-- 19 Causes status effects (Only on Arctic Armour, allows Elemental Proliferation)
-- 20 Creates minions
-- 21 Attack can be totem?
-- 22 Chaining
-- 23 Melee
-- 24 Single target melee
-- 25 Spell can multicast
-- 26 ?? (On auras, searing bond, tempest shield, blade vortex and others)
-- 27 Attack can multistrike
-- 28 Burning
-- 29 Totem
-- 30 ?? (On Molten Shell + Glove Thunder, applied by Blasphemy)
-- 31 Curse
-- 32 Fire skill
-- 33 Cold skill
-- 34 Lightning skill
-- 35 Triggerable spell
-- 36 Trap
-- 37 Movement
-- 38 Damage over Time
-- 39 Mine
-- 40 Triggered spell
-- 41 Vaal
-- 42 Aura
-- 43 Lightning spell
-- 44 ?? (Not on any skills or supports)
-- 45 Triggered attack
-- 46 Projectile attack
-- 47 Minion spell
-- 48 Chaos skill
-- 49 ?? (Not on any skills, excluded by Faster/Slower Projectiles)
-- 50 ?? (Only on Contagion, allows Iron Will)
-- 51 ?? (Only on Burning Arrow/Vigilant Strike, allows Inc AoE + Conc Effect)
-- 52 Projectile? (Not on any skills, allows all projectile supports)
-- 53 ?? (Only on Burning Arrow/VBA, allows Inc/Red Duration + Rapid Decay)
-- 54 Projectile attack? (Not on any skills, allows projectile attack supports)
-- 55 ?? Same as 47
-- 56 Channelled
-- 57 ?? (Only on Contagion, allows Controlled Destruction)
-- 58 Cold spell
-- 59 Granted triggered skill (Prevents trigger supports, trap, mine, totem)
-- 60 Golem
-- 61 Herald
-- 62 Aura Debuff
-- 63 ?? (Excludes Ruthless from Cyclone)
-- 64 ?? (Allows Iron Will)
-- 65 Spell can cascade
-- 66 Skill can Volley
-- 67 Skill can Mirage Archer
-- 68 ?? (Excludes Volley on Vaal Fireball/Spark)
-- 69 ?? (Excludes Volley on Spectral Shield Throw)
local function mapAST(ast)
if ast >= 36 then
return ast + 4
elseif ast >= 6 then
return ast + 3
else
return ast
end
end
local function addMod(mods, modDef, value)
local mod = {
mult = 1,
val = value,
levels = { value },
def = modDef,
}
table.insert(mods, mod)
return mod
end
local weaponClassMap = {
[6] = "Claw",
[7] = "Dagger",
[8] = "Wand",
[9] = "One Handed Sword",
[10] = "Thrusting One Handed Sword",
[11] = "One Handed Axe",
[12] = "One Handed Mace",
[13] = "Bow",
[14] = "Staff",
[15] = "Two Handed Sword",
[16] = "Two Handed Axe",
[17] = "Two Handed Mace",
[32] = "Sceptre",
[36] = "None",
}
local gems = { }
local directiveTable = { }
-- I'll leave all this here as a monument to how badly I got screwed by BIT being absent in the prepatch
--local gemMap = dofile("Gems.lua")
local wildAssGuessAtNewGemInfo = {
["SupportPhysicalProjectileAttackDamage"] = {
"Metadata/Items/Gems/SupportGemPhysicalProjectileAttackDamage", "Vicious Projectiles"
},
["Smite"] = {
"Metadata/Items/Gems/Smite", "Smite"
},
["ConsecratedPath"] = {
"Metadata/Items/Gems/ConsecratedPath", "Consecrated Path",
},
["SummonRelic"] = {
"Metadata/Items/Gems/SummonRelic", "Summon Holy Relic",
},
["HeraldOfPurity"] = {
"Metadata/Items/Gems/HeraldOfPurity", "Herald of Purity",
},
["ScourgeArrow"] = {
"Metadata/Items/Gems/ScourgeArrow", "Scourge Arrow",
},
["RainOfSpores"] = {
"Metadata/Items/Gems/RainOfSpores", --[["Chocolate Rain"]]"Toxic Rain",
},
["HeraldOfAgony"] = {
"Metadata/Items/Gems/HeraldOfAgony", "Herald of Agony",
},
["VaalAncestralWarchief"] = {
"Metadata/Items/Gems/VaalAncestralWarchief", "Vaal Ancestral Warchief",
},
["SupportChaosAttacks"] = {
"Metadata/Items/Gems/SupportGemChaosAttacks", "Withering Touch",
},
}
function dammitChris(grantedId)
if wildAssGuessAtNewGemInfo[grantedId] then
return unpack(wildAssGuessAtNewGemInfo[grantedId])
end
for id, data in pairs(gemMap) do
if data.grantedEffectId == grantedId then
return id, data.name
end
end
error("GrantedId '"..grantedId.."' no gem")
end
local wellShitIGotThoseWrong = {
-- Serves me right for not paying attention (not that I've gotten them all right anyway)
-- Let's just sweep these under the carpet so we don't break everyone's shiny new builds
["Metadata/Items/Gems/SkillGemSmite"] = "Metadata/Items/Gems/Smite",
["Metadata/Items/Gems/SkillGemConsecratedPath"] = "Metadata/Items/Gems/ConsecratedPath",
["Metadata/Items/Gems/SkillGemVaalAncestralWarchief"] = "Metadata/Items/Gems/VaalAncestralWarchief",
["Metadata/Items/Gems/SkillGemHeraldOfAgony"] = "Metadata/Items/Gems/HeraldOfAgony",
["Metadata/Items/Gems/SkillGemHeraldOfPurity"] = "Metadata/Items/Gems/HeraldOfPurity",
["Metadata/Items/Gems/SkillGemScourgeArrow"] = "Metadata/Items/Gems/ScourgeArrow",
["Metadata/Items/Gems/SkillGemToxicRain"] = "Metadata/Items/Gems/RainOfSpores",
["Metadata/Items/Gems/SkillGemSummonRelic"] = "Metadata/Items/Gems/SummonRelic",
}
-- #noGem
-- Disables the gem component of the next skill
directiveTable.noGem = function(state, args, out)
state.noGem = true
end
-- #skill <GrantedEffectId> [<Display name>]
-- Initialises the skill data and emits the skill header
directiveTable.skill = function(state, args, out)
local grantedId, displayName = args:match("(%w+) (.+)")
if not grantedId then
grantedId = args
displayName = args
end
out:write('skills["', grantedId, '"] = {\n')
local grantedKey = GrantedEffects.Id(grantedId)[1]
local granted = GrantedEffects[grantedKey]
if not granted then
print('Unknown GE: "'..grantedId..'"')
end
local skillGemKey = SkillGems.GrantedEffectsKey(grantedKey)[1]
local skill = { }
state.skill = skill
if skillGemKey and not state.noGem then
gems[skillGemKey] = true
if granted.IsSupport then
local skillGem = SkillGems[skillGemKey]
local baseItemType = BaseItemTypes[skillGem.BaseItemTypesKey]
out:write('\tname = "', baseItemType.Name:gsub(" Support",""), '",\n')
--local gemId, gemName = dammitChris(grantedId)
--out:write('\tname = "', gemName, '",\n')
if #skillGem.Description > 0 then
out:write('\tdescription = "', skillGem.Description, '",\n')
end
else
out:write('\tname = "', ActiveSkills[granted.ActiveSkillsKey].DisplayedName, '",\n')
end
else
if displayName == args and not granted.IsSupport then
displayName = ActiveSkills[granted.ActiveSkillsKey].DisplayedName
end
out:write('\tname = "', displayName, '",\n')
out:write('\thidden = true,\n')
end
state.noGem = false
skill.baseFlags = { }
local modMap = { }
skill.mods = { }
skill.levels = { }
local statMap = { }
skill.stats = { }
skill.statInterpolation = { }
out:write('\tcolor = ', granted.Unknown0, ',\n')
if granted.IncrementalEffectiveness ~= 0 then
out:write('\tbaseEffectiveness = ', granted.BaseEffectiveness, ',\n')
out:write('\tincrementalEffectiveness = ', granted.IncrementalEffectiveness, ',\n')
end
if granted.IsSupport then
skill.isSupport = true
out:write('\tsupport = true,\n')
out:write('\trequireSkillTypes = { ')
for _, type in ipairs(granted.AllowedActiveSkillTypes) do
out:write(mapAST(type), ', ')
end
out:write('},\n')
out:write('\taddSkillTypes = { ')
for _, type in ipairs(granted.AddedActiveSkillTypes) do
out:write(mapAST(type), ', ')
end
out:write('},\n')
out:write('\texcludeSkillTypes = { ')
for _, type in ipairs(granted.ExcludedActiveSkillTypes) do
out:write(mapAST(type), ', ')
end
out:write('},\n')
if granted.SupportsGemsOnly then
out:write('\tsupportGemsOnly = true,\n')
end
else
local activeSkill = ActiveSkills[granted.ActiveSkillsKey]
if #activeSkill.Description > 0 then
out:write('\tdescription = "', activeSkill.Description, '",\n')
end
out:write('\tskillTypes = { ')
for _, type in ipairs(activeSkill.ActiveSkillTypes) do
out:write('[', mapAST(type), '] = true, ')
end
out:write('},\n')
if activeSkill.MinionActiveSkillTypes[1] then
out:write('\tminionSkillTypes = { ')
for _, type in ipairs(activeSkill.MinionActiveSkillTypes) do
out:write('[', mapAST(type), '] = true, ')
end
out:write('},\n')
end
local weaponTypes = { }
for _, classKey in ipairs(activeSkill.WeaponRestriction_ItemClassesKeys) do
if weaponClassMap[classKey] then
weaponTypes[weaponClassMap[classKey]] = true
end
end
if next(weaponTypes) then
out:write('\tweaponTypes = {\n')
for type in pairs(weaponTypes) do
out:write('\t\t["', type, '"] = true,\n')
end
out:write('\t},\n')
end
if activeSkill.SkillTotemId ~= 17 then
out:write('\tskillTotemId = ', activeSkill.SkillTotemId, ',\n')
end
addMod(skill.mods, 'skill("castTime", {val})', granted.CastTime / 1000)
end
for _, key in ipairs(GrantedEffectsPerLevel.GrantedEffectsKey(grantedKey)) do
local level = { }
local levelRow = GrantedEffectsPerLevel[key]
level.level = levelRow.Level
table.insert(skill.levels, level)
local function addLevelMod(modDef, value, forcePerLevel)
local mod = skill.mods[modMap[modDef]]
if mod then
if value ~= mod.val then
mod.perLevel = true
end
else
modMap[modDef] = #skill.mods + 1
addMod(skill.mods, modDef)
mod = skill.mods[modMap[modDef]]
mod.val = value
end
if forcePerLevel then
mod.perLevel = true
end
mod.levels[levelRow.Level] = value
end
if not granted.IsSupport then
addLevelMod('skill("levelRequirement", {val})', levelRow.LevelRequirement, true)
else
addLevelMod("nil", levelRow.LevelRequirement, true)
end
if levelRow.ManaCost and levelRow.ManaCost ~= 0 then
addLevelMod('skill("manaCost", {val})', levelRow.ManaCost)
end
if levelRow.ManaMultiplier ~= 100 then
addLevelMod('mod("ManaCost", "MORE", {val})', levelRow.ManaMultiplier - 100)
end
if levelRow.DamageEffectiveness ~= 0 then
addLevelMod('skill("damageEffectiveness", {val})', levelRow.DamageEffectiveness / 100 + 1)
end
if levelRow.CriticalStrikeChance ~= 0 then
addLevelMod('skill("CritChance", {val})', levelRow.CriticalStrikeChance / 100)
end
if levelRow.DamageMultiplier and levelRow.DamageMultiplier ~= 0 then
addLevelMod('skill("baseMultiplier", {val})', levelRow.DamageMultiplier / 10000 + 1)
end
if levelRow.ManaReservationOverride ~= 0 then
addLevelMod('skill("manaCostOverride", {val})', levelRow.ManaReservationOverride)
end
if levelRow.Cooldown and levelRow.Cooldown ~= 0 then
addLevelMod('skill("cooldown", {val})', levelRow.Cooldown / 1000)
end
for i, statKey in ipairs(levelRow.StatsKeys) do
local statId = Stats[statKey].Id
if not statMap[statId] then
statMap[statId] = #skill.stats + 1
table.insert(skill.stats, { id = statId })
end
skill.statInterpolation[i] = levelRow.StatInterpolationTypesKeys[i]
if skill.statInterpolation[i] == 3 and levelRow.EffectivenessCostConstantsKeys[i] ~= 2 then
table.insert(skill.stats[statMap[statId]], levelRow["Stat"..i.."Float"] / EffectivenessCostConstants[levelRow.EffectivenessCostConstantsKeys[i]].Multiplier)
else
table.insert(skill.stats[statMap[statId]], levelRow["Stat"..i.."Value"])
end
end
for i, statKey in ipairs(levelRow.StatsKeys2) do
local statId = Stats[statKey].Id
if not statMap[statId] then
statMap[statId] = #skill.stats + 1
table.insert(skill.stats, { id = statId })
end
end
if not skill.qualityStats then
skill.qualityStats = { }
for i, statKey in ipairs(levelRow.Quality_StatsKeys) do
table.insert(skill.qualityStats, { Stats[statKey].Id, levelRow.Quality_Values[i] / 1000 })
end
end
end
end
-- #flags <flag>[ <flag>[...]]
-- Sets the base flags for this active skill
directiveTable.flags = function(state, args, out)
local skill = state.skill
for flag in args:gmatch("%a+") do
table.insert(skill.baseFlags, flag)
end
end
-- #baseMod <mod definition>
-- Adds a base modifier to the skill
directiveTable.baseMod = function(state, args, out)
local skill = state.skill
addMod(skill.mods, args)
end
-- #levelMod <mod definition>==<val>[ <val>[...]]
-- Adds a per-level modifier to the skill
directiveTable.levelMod = function(state, args, out)
local skill = state.skill
local def, vals = args:match("(.*)==(.*)")
local mod = addMod(skill.mods, def)
mod.perLevel = true
local i = 1
for _, level in ipairs(skill.levels) do
local s, e, val = vals:find("([%+%-]?[%d%.]+)", i)
mod.levels[level.level] = tonumber(val)
i = e + 1
end
end
-- #setLevelVals <index>==<val>[ <val>[...]]
-- Overrides the values of the given level modifier
directiveTable.setLevelVals = function(state, args, out)
local skill = state.skill
local index, vals = args:match("(.*)==(.*)")
index = tonumber(index)
for _, mod in ipairs(skill.mods) do
if mod.perLevel then
index = index - 1
if index == 0 then
local i = 1
for _, level in ipairs(skill.levels) do
local s, e, val = vals:find("([%+%-]?[%d%.]+)", i)
mod.levels[level.level] = tonumber(val)
i = e + 1
end
break
end
end
end
end
-- #mods
-- Emits the skill modifiers
directiveTable.mods = function(state, args, out)
local skill = state.skill
if not skill.isSupport then
out:write('\tbaseFlags = {\n')
for _, flag in ipairs(skill.baseFlags) do
out:write('\t\t', flag, ' = true,\n')
end
out:write('\t},\n')
end
out:write('\tqualityStats = {\n')
for _, stat in ipairs(skill.qualityStats) do
out:write('\t\t{ "', stat[1], '", ', stat[2], ' },\n')
end
out:write('\t},\n')
out:write('\tstats = {\n')
for _, stat in ipairs(skill.stats) do
out:write('\t\t"', stat.id, '",\n')
end
out:write('\t},\n')
out:write('\tstatInterpolation = { ')
for _, type in ipairs(skill.statInterpolation) do
out:write(type, ', ')
end
out:write('},\n')
out:write('\tstatLevels = {\n')
for index, level in ipairs(skill.levels) do
out:write('\t\t[', level.level, '] = { ')
for _, stat in ipairs(skill.stats) do
out:write(tostring(stat[index]), ', ')
end
out:write('},\n')
end
out:write('\t},\n')
out:write('\tbaseMods = {\n')
for _, mod in ipairs(skill.mods) do
if not mod.perLevel then
out:write('\t\t', mod.def:gsub("{val}",(mod.val or 0)*mod.mult), ',\n')
end
end
out:write('\t},\n')
out:write('\tlevelMods = {\n')
local lcol = 1
for _, mod in ipairs(skill.mods) do
if mod.perLevel then
out:write('\t\t[', lcol, '] = ', mod.def:gsub("{val}","nil"), ',\n')
mod.col = lcol
lcol = lcol + 1
end
end
out:write('\t},\n')
out:write('\tlevels = {\n')
for _, level in ipairs(skill.levels) do
out:write('\t\t[', level.level, '] = { ')
for _, mod in ipairs(skill.mods) do
if mod.perLevel then
if mod.levels[level.level] then
out:write(tostring(mod.levels[level.level] * mod.mult), ', ')
else
out:write('nil, ')
end
end
end
out:write('},\n')
end
out:write('\t},\n')
out:write('}')
state.skill = nil
end
for _, name in pairs({"act_str","act_dex","act_int","other","glove","minion","spectre","sup_str","sup_dex","sup_int"}) do
processTemplateFile("Skills/"..name, directiveTable)
end
local out = io.open("../Data/3_0/Gems.lua", "w")
out:write('-- This file is automatically generated, do not edit!\n')
out:write('-- Gem data (c) Grinding Gear Games\n\nreturn {\n')
for skillGemKey = 0, SkillGems.maxRow do
if gems[skillGemKey] then
local skillGem = SkillGems[skillGemKey]
local baseItemType = BaseItemTypes[skillGem.BaseItemTypesKey]
out:write('\t["', wellShitIGotThoseWrong[baseItemType.Id] or baseItemType.Id, '"] = {\n')
out:write('\t\tname = "', baseItemType.Name:gsub(" Support",""), '",\n')
--local gemId, gemName = dammitChris(GrantedEffects[skillGem.GrantedEffectsKey].Id)
--out:write('\t["', gemId, '"] = {\n')
--out:write('\t\tname = "', gemName, '",\n')
out:write('\t\tgrantedEffectId = "', GrantedEffects[skillGem.GrantedEffectsKey].Id, '",\n')
if skillGem.GrantedEffectsKey2 then
out:write('\t\tsecondaryGrantedEffectId = "', GrantedEffects[skillGem.GrantedEffectsKey2].Id, '",\n')
end
local tagNames = { }
out:write('\t\ttags = {\n')
for i, tagKey in ipairs(skillGem.GemTagsKeys) do
out:write('\t\t\t', GemTags[tagKey].Id, ' = true,\n')
if #GemTags[tagKey].Tag > 0 then
table.insert(tagNames, GemTags[tagKey].Tag)
end
end
out:write('\t\t},\n')
out:write('\t\ttagString = "', table.concat(tagNames, ", "), '",\n')
out:write('\t\treqStr = ', skillGem.Str, ',\n')
out:write('\t\treqDex = ', skillGem.Dex, ',\n')
out:write('\t\treqInt = ', skillGem.Int, ',\n')
out:write('\t},\n')
end
end
out:write('}')
os.execute("xcopy Skills\\*.lua ..\\Data\\3_0\\Skills\\ /Y /Q")
print("Skill data exported.")