initial commit
This commit is contained in:
@@ -0,0 +1,197 @@
|
||||
--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]
|
||||
local ____exports = {}
|
||||
--- Каталог арсенала: реестр всех экип-предметов и список играбельных героев.
|
||||
--
|
||||
-- Раскладывается в две NetTable:
|
||||
-- - "arsenal_catalog" / "items" → ArsenalItemDef[]
|
||||
-- - "arsenal_catalog" / "heroes" → string[] (npc_dota_hero_*)
|
||||
local DEFAULT_ITEM_ICON = "s2r://panorama/images/items/recipe_psd.vtex"
|
||||
local ARSENAL_ICON = {
|
||||
weapon = {ironBlade = "file://{images}/custom_game/arsenal/ironblade.png", stormEdge = "file://{images}/custom_game/arsenal/stormedge.png", sunfangSaber = "file://{images}/custom_game/arsenal/sunfangsaber.png"},
|
||||
armor = {chainMail = "file://{images}/custom_game/arsenal/chainmail.png", dragonPlate = "file://{images}/custom_game/arsenal/dragonplate.png", vanguardShell = "file://{images}/custom_game/arsenal/vanguardshell.png"},
|
||||
helmet = {leatherCap = "file://{images}/custom_game/arsenal/leathercap.png", arcaneCirclet = "file://{images}/custom_game/arsenal/arcanecirclet.png", warcrownMask = "file://{images}/custom_game/arsenal/warcrownmask.png"},
|
||||
boots = {swiftBoots = "file://{images}/custom_game/arsenal/swiftboots.png", phaseTreads = "file://{images}/custom_game/arsenal/phasetreads.png", hermesGreaves = "file://{images}/custom_game/arsenal/hermesgreaves.png"},
|
||||
necklace = {amberPendant = "file://{images}/custom_game/arsenal/amberpendant.png", soulLocket = "file://{images}/custom_game/arsenal/soullocket.png", prismChoker = "file://{images}/custom_game/arsenal/prismchoker.png"},
|
||||
ring = {copperBand = "file://{images}/custom_game/arsenal/copperband.png", voidSignet = "file://{images}/custom_game/arsenal/voidsignet.png", titanLoop = "file://{images}/custom_game/arsenal/titancircle.png"}
|
||||
}
|
||||
--- Перечень слотов в порядке отображения в UI.
|
||||
____exports.ARSENAL_SLOTS = {
|
||||
"weapon",
|
||||
"armor",
|
||||
"helmet",
|
||||
"boots",
|
||||
"necklace",
|
||||
"ring"
|
||||
}
|
||||
--- Полный список экип-предметов. Эффекты — отдельные модификаторы в
|
||||
-- `src/vscripts/arsenal/items/<slot>/...` (имена согласованы с полем `modifier`).
|
||||
--
|
||||
-- Это базовый набор-каркас (по 2 предмета на слот). Расширять отдельной задачей.
|
||||
____exports.ARSENAL_ITEMS = {
|
||||
{
|
||||
itemName = "item_arsenal_weapon_iron_blade",
|
||||
slot = "weapon",
|
||||
quality = "epic",
|
||||
modifier = "modifier_arsenal_weapon_iron_blade",
|
||||
icon = ARSENAL_ICON.weapon.ironBlade
|
||||
},
|
||||
{
|
||||
itemName = "item_arsenal_weapon_storm_edge",
|
||||
slot = "weapon",
|
||||
quality = "epic",
|
||||
modifier = "modifier_arsenal_weapon_storm_edge",
|
||||
icon = ARSENAL_ICON.weapon.stormEdge
|
||||
},
|
||||
{
|
||||
itemName = "item_arsenal_weapon_sunfang_saber",
|
||||
slot = "weapon",
|
||||
quality = "epic",
|
||||
modifier = "modifier_arsenal_weapon_storm_edge",
|
||||
icon = ARSENAL_ICON.weapon.sunfangSaber
|
||||
},
|
||||
{
|
||||
itemName = "item_arsenal_armor_chain_mail",
|
||||
slot = "armor",
|
||||
quality = "epic",
|
||||
modifier = "modifier_arsenal_armor_chain_mail",
|
||||
icon = ARSENAL_ICON.armor.chainMail
|
||||
},
|
||||
{
|
||||
itemName = "item_arsenal_armor_dragon_plate",
|
||||
slot = "armor",
|
||||
quality = "epic",
|
||||
modifier = "modifier_arsenal_armor_dragon_plate",
|
||||
icon = ARSENAL_ICON.armor.dragonPlate
|
||||
},
|
||||
{
|
||||
itemName = "item_arsenal_armor_vanguard_shell",
|
||||
slot = "armor",
|
||||
quality = "epic",
|
||||
modifier = "modifier_arsenal_armor_dragon_plate",
|
||||
icon = ARSENAL_ICON.armor.vanguardShell
|
||||
},
|
||||
{
|
||||
itemName = "item_arsenal_helmet_leather_cap",
|
||||
slot = "helmet",
|
||||
quality = "rare",
|
||||
modifier = "modifier_arsenal_helmet_leather_cap",
|
||||
icon = ARSENAL_ICON.helmet.leatherCap
|
||||
},
|
||||
{
|
||||
itemName = "item_arsenal_helmet_arcane_circlet",
|
||||
slot = "helmet",
|
||||
quality = "rare",
|
||||
modifier = "modifier_arsenal_helmet_arcane_circlet",
|
||||
icon = ARSENAL_ICON.helmet.arcaneCirclet
|
||||
},
|
||||
{
|
||||
itemName = "item_arsenal_helmet_warcrown_mask",
|
||||
slot = "helmet",
|
||||
quality = "rare",
|
||||
modifier = "modifier_arsenal_helmet_arcane_circlet",
|
||||
icon = ARSENAL_ICON.helmet.warcrownMask
|
||||
},
|
||||
{
|
||||
itemName = "item_arsenal_boots_swift_boots",
|
||||
slot = "boots",
|
||||
quality = "legendary",
|
||||
modifier = "modifier_arsenal_boots_swift_boots",
|
||||
icon = ARSENAL_ICON.boots.swiftBoots
|
||||
},
|
||||
{
|
||||
itemName = "item_arsenal_boots_phase_treads",
|
||||
slot = "boots",
|
||||
quality = "legendary",
|
||||
modifier = "modifier_arsenal_boots_phase_treads",
|
||||
icon = ARSENAL_ICON.boots.phaseTreads
|
||||
},
|
||||
{
|
||||
itemName = "item_arsenal_boots_hermes_greaves",
|
||||
slot = "boots",
|
||||
quality = "legendary",
|
||||
modifier = "modifier_arsenal_boots_phase_treads",
|
||||
icon = ARSENAL_ICON.boots.hermesGreaves
|
||||
},
|
||||
{
|
||||
itemName = "item_arsenal_necklace_amber_pendant",
|
||||
slot = "necklace",
|
||||
quality = "legendary",
|
||||
modifier = "modifier_arsenal_necklace_amber_pendant",
|
||||
icon = ARSENAL_ICON.necklace.amberPendant
|
||||
},
|
||||
{
|
||||
itemName = "item_arsenal_necklace_soul_locket",
|
||||
slot = "necklace",
|
||||
quality = "legendary",
|
||||
modifier = "modifier_arsenal_necklace_soul_locket",
|
||||
icon = ARSENAL_ICON.necklace.soulLocket
|
||||
},
|
||||
{
|
||||
itemName = "item_arsenal_necklace_prism_choker",
|
||||
slot = "necklace",
|
||||
quality = "legendary",
|
||||
modifier = "modifier_arsenal_necklace_soul_locket",
|
||||
icon = ARSENAL_ICON.necklace.prismChoker
|
||||
},
|
||||
{
|
||||
itemName = "item_arsenal_ring_copper_band",
|
||||
slot = "ring",
|
||||
quality = "mythic",
|
||||
modifier = "modifier_arsenal_ring_copper_band",
|
||||
icon = ARSENAL_ICON.ring.copperBand
|
||||
},
|
||||
{
|
||||
itemName = "item_arsenal_ring_void_signet",
|
||||
slot = "ring",
|
||||
quality = "mythic",
|
||||
modifier = "modifier_arsenal_ring_void_signet",
|
||||
icon = ARSENAL_ICON.ring.voidSignet
|
||||
},
|
||||
{
|
||||
itemName = "item_arsenal_ring_titan_loop",
|
||||
slot = "ring",
|
||||
quality = "mythic",
|
||||
modifier = "modifier_arsenal_ring_void_signet",
|
||||
icon = ARSENAL_ICON.ring.titanLoop
|
||||
}
|
||||
}
|
||||
--- Карта itemName → ArsenalItemDef (для быстрого поиска по имени).
|
||||
____exports.ARSENAL_ITEMS_MAP = (function()
|
||||
local map = {}
|
||||
for ____, item in ipairs(____exports.ARSENAL_ITEMS) do
|
||||
map[item.itemName] = item
|
||||
end
|
||||
return map
|
||||
end)(nil)
|
||||
--- Парс `scripts/npc/herolist.txt` → имена героев со значением `>0` или `-1` (включённые).
|
||||
-- Тот же фильтр, что в `GameMode.getEnabledHeroesFromHeroList`.
|
||||
function ____exports.getEnabledHeroes(self)
|
||||
local rawKv = LoadKeyValues("scripts/npc/herolist.txt")
|
||||
local ____temp_2 = rawKv and rawKv.CustomHeroList
|
||||
if ____temp_2 == nil then
|
||||
____temp_2 = rawKv
|
||||
end
|
||||
local heroList = ____temp_2
|
||||
if not heroList then
|
||||
return {}
|
||||
end
|
||||
local result = {}
|
||||
for heroName in pairs(heroList) do
|
||||
local value = tonumber(tostring(heroList[heroName])) or 0
|
||||
if value > 0 or value == -1 then
|
||||
result[#result + 1] = tostring(heroName)
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
--- Опубликовать каталог и список героев в NetTable. Вызывать один раз при старте сервера.
|
||||
function ____exports.publishArsenalCatalog(self)
|
||||
CustomNetTables:SetTableValue("arsenal_catalog", "items", ____exports.ARSENAL_ITEMS)
|
||||
CustomNetTables:SetTableValue(
|
||||
"arsenal_catalog",
|
||||
"heroes",
|
||||
{list = ____exports.getEnabledHeroes(nil)}
|
||||
)
|
||||
CustomNetTables:SetTableValue("arsenal_catalog", "slots", {list = ____exports.ARSENAL_SLOTS})
|
||||
end
|
||||
return ____exports
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,41 @@
|
||||
--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]
|
||||
local ____exports = {}
|
||||
local EMPTY_TOTALS = {
|
||||
battle_level = 0,
|
||||
bonus_damage = 0,
|
||||
attack_speed = 0,
|
||||
bonus_armor = 0,
|
||||
max_health = 0,
|
||||
max_mana = 0,
|
||||
health_regen = 0,
|
||||
mana_regen = 0,
|
||||
move_speed = 0,
|
||||
magic_resist = 0,
|
||||
spell_amp = 0,
|
||||
all_stats = 0,
|
||||
all_stats_pct = 0,
|
||||
bonus_strength = 0,
|
||||
bonus_agility = 0,
|
||||
bonus_intellect = 0,
|
||||
strength_pct = 0,
|
||||
agility_pct = 0,
|
||||
intellect_pct = 0,
|
||||
luck = 0,
|
||||
outgoing_damage_pct = 0,
|
||||
incoming_damage_reduction_pct = 0,
|
||||
attack_speed_pct = 0,
|
||||
move_speed_pct = 0,
|
||||
base_damage_pct = 0,
|
||||
crit_mult = 0
|
||||
}
|
||||
local provider
|
||||
function ____exports.setArsenalTotalsProvider(self, nextProvider)
|
||||
provider = nextProvider
|
||||
end
|
||||
function ____exports.getArsenalTotals(self, hero)
|
||||
if not provider then
|
||||
return EMPTY_TOTALS
|
||||
end
|
||||
return provider(nil, hero)
|
||||
end
|
||||
return ____exports
|
||||
@@ -0,0 +1,727 @@
|
||||
local ____lualib = require("lualib_bundle")
|
||||
local __TS__NumberIsFinite = ____lualib.__TS__NumberIsFinite
|
||||
local ____exports = {}
|
||||
local ARSENAL_RARITY_ORDER = {
|
||||
"common",
|
||||
"rare",
|
||||
"epic",
|
||||
"legendary",
|
||||
"mythic"
|
||||
}
|
||||
local ASCENDED_STAT_QUALITY = "ascended"
|
||||
local ARSENAL_RARITY_MULTIPLIER = {
|
||||
common = 1,
|
||||
rare = 1.2,
|
||||
epic = 1.45,
|
||||
legendary = 1.75,
|
||||
mythic = 2.1,
|
||||
ascended = 2.55
|
||||
}
|
||||
local BASE_STAT_COUNT = 2
|
||||
local ADDITIONAL_STAT_COUNT = 4
|
||||
local HIDDEN_FINAL_STAT_INDEX = 6
|
||||
local HIDDEN_FINAL_UNLOCK_LEVEL = 1
|
||||
local MAX_UPGRADE_LEVEL = 5
|
||||
local PER_LEVEL_GROWTH = 0.12
|
||||
local MYTHIC_BEST_LINE_CHANCE_PCT = 24
|
||||
local MYTHIC_WEAK_LINE_CHANCE_PCT = 10
|
||||
--- С вероятностью N% новая строка копирует ключ уже существующего (ниже — реже дубли одного и того же стата на предмете).
|
||||
local ARSENAL_REPEAT_EXISTING_STAT_CHANCE_PCT = 26
|
||||
local MAX_RARITY_INDEX = #ARSENAL_RARITY_ORDER - 1
|
||||
local MAX_RARITY_CAP_APPROACH_PER_STEP = 0.22
|
||||
local ADDITIONAL_SLOTS_BY_ITEM_QUALITY = {
|
||||
common = 0,
|
||||
rare = 1,
|
||||
epic = 2,
|
||||
legendary = 3,
|
||||
mythic = 4
|
||||
}
|
||||
--- Диапазоны с учётом 6 слотов экипировки и роста от редкости/уровня (см. Panorama `getTemplateForStatKey`).
|
||||
--
|
||||
-- `upgradeGrowthMin` / `upgradeGrowthMax` — диапазон для **`k`** в формуле итога:
|
||||
-- `значение ∝ effectiveBase × rarityMult × (1 + k × lineBonus)`.
|
||||
-- Это **не** «+N к тултипу» и **не** проценты вида «15 = 15%»; типичные **`k`** — **доли 0.08…0.14**
|
||||
-- (при `lineBonus = 5` множитель прокачки около **1.4…1.7**).
|
||||
local ARSENAL_STAT_POOL = {
|
||||
{
|
||||
key = "bonus_damage",
|
||||
min = 12,
|
||||
max = 64,
|
||||
upgradeGrowthMin = 0.1,
|
||||
upgradeGrowthMax = 0.14
|
||||
},
|
||||
{
|
||||
key = "attack_speed",
|
||||
min = 5,
|
||||
max = 22,
|
||||
upgradeGrowthMin = 0.09,
|
||||
upgradeGrowthMax = 0.13
|
||||
},
|
||||
{
|
||||
key = "bonus_armor",
|
||||
min = 2,
|
||||
max = 8,
|
||||
upgradeGrowthMin = 0.1,
|
||||
upgradeGrowthMax = 0.14
|
||||
},
|
||||
{
|
||||
key = "max_health",
|
||||
min = 70,
|
||||
max = 240,
|
||||
upgradeGrowthMin = 0.09,
|
||||
upgradeGrowthMax = 0.12
|
||||
},
|
||||
{
|
||||
key = "max_mana",
|
||||
min = 50,
|
||||
max = 180,
|
||||
upgradeGrowthMin = 0.09,
|
||||
upgradeGrowthMax = 0.12
|
||||
},
|
||||
{
|
||||
key = "health_regen",
|
||||
min = 0.4,
|
||||
max = 3.2,
|
||||
decimals = 1,
|
||||
upgradeGrowthMin = 0.09,
|
||||
upgradeGrowthMax = 0.12
|
||||
},
|
||||
{
|
||||
key = "mana_regen",
|
||||
min = 0.2,
|
||||
max = 1.8,
|
||||
decimals = 2,
|
||||
upgradeGrowthMin = 0.09,
|
||||
upgradeGrowthMax = 0.12
|
||||
},
|
||||
{
|
||||
key = "move_speed",
|
||||
min = 6,
|
||||
max = 12,
|
||||
upgradeGrowthMin = 0.08,
|
||||
upgradeGrowthMax = 0.12
|
||||
},
|
||||
{
|
||||
key = "magic_resist",
|
||||
min = 0.2,
|
||||
max = 1.2,
|
||||
decimals = 1,
|
||||
upgradeGrowthMin = 0.04,
|
||||
upgradeGrowthMax = 0.1
|
||||
},
|
||||
{
|
||||
key = "spell_amp",
|
||||
min = 1,
|
||||
max = 5,
|
||||
decimals = 1,
|
||||
upgradeGrowthMin = 0.08,
|
||||
upgradeGrowthMax = 0.13
|
||||
},
|
||||
{
|
||||
key = "all_stats",
|
||||
min = 2,
|
||||
max = 5,
|
||||
upgradeGrowthMin = 0.045,
|
||||
upgradeGrowthMax = 0.07
|
||||
},
|
||||
{
|
||||
key = "bonus_strength",
|
||||
min = 4,
|
||||
max = 16,
|
||||
upgradeGrowthMin = 0.09,
|
||||
upgradeGrowthMax = 0.13
|
||||
},
|
||||
{
|
||||
key = "bonus_agility",
|
||||
min = 4,
|
||||
max = 16,
|
||||
upgradeGrowthMin = 0.09,
|
||||
upgradeGrowthMax = 0.13
|
||||
},
|
||||
{
|
||||
key = "bonus_intellect",
|
||||
min = 4,
|
||||
max = 16,
|
||||
upgradeGrowthMin = 0.09,
|
||||
upgradeGrowthMax = 0.13
|
||||
},
|
||||
{
|
||||
key = "all_stats_pct",
|
||||
min = 0.2,
|
||||
max = 1.1,
|
||||
decimals = 1,
|
||||
upgradeGrowthMin = 0.04,
|
||||
upgradeGrowthMax = 0.065
|
||||
},
|
||||
{
|
||||
key = "strength_pct",
|
||||
min = 0.8,
|
||||
max = 10,
|
||||
decimals = 1,
|
||||
upgradeGrowthMin = 0.05,
|
||||
upgradeGrowthMax = 0.08
|
||||
},
|
||||
{
|
||||
key = "agility_pct",
|
||||
min = 0.8,
|
||||
max = 10,
|
||||
decimals = 1,
|
||||
upgradeGrowthMin = 0.05,
|
||||
upgradeGrowthMax = 0.08
|
||||
},
|
||||
{
|
||||
key = "intellect_pct",
|
||||
min = 0.8,
|
||||
max = 10,
|
||||
decimals = 1,
|
||||
upgradeGrowthMin = 0.05,
|
||||
upgradeGrowthMax = 0.08
|
||||
},
|
||||
{
|
||||
key = "luck",
|
||||
min = 0.5,
|
||||
max = 2.5,
|
||||
decimals = 1,
|
||||
upgradeGrowthMin = 0.08,
|
||||
upgradeGrowthMax = 0.14
|
||||
},
|
||||
{
|
||||
key = "outgoing_damage_pct",
|
||||
min = 0.8,
|
||||
max = 3.5,
|
||||
decimals = 1,
|
||||
upgradeGrowthMin = 0.06,
|
||||
upgradeGrowthMax = 0.1
|
||||
},
|
||||
{
|
||||
key = "incoming_damage_reduction_pct",
|
||||
min = 0.5,
|
||||
max = 2,
|
||||
decimals = 1,
|
||||
upgradeGrowthMin = 0.06,
|
||||
upgradeGrowthMax = 0.1
|
||||
},
|
||||
{
|
||||
key = "attack_speed_pct",
|
||||
min = 1.5,
|
||||
max = 6,
|
||||
decimals = 1,
|
||||
upgradeGrowthMin = 0.07,
|
||||
upgradeGrowthMax = 0.11
|
||||
},
|
||||
{
|
||||
key = "move_speed_pct",
|
||||
min = 1,
|
||||
max = 4,
|
||||
decimals = 1,
|
||||
upgradeGrowthMin = 0.07,
|
||||
upgradeGrowthMax = 0.11
|
||||
},
|
||||
{
|
||||
key = "base_damage_pct",
|
||||
min = 0.8,
|
||||
max = 3.5,
|
||||
decimals = 1,
|
||||
upgradeGrowthMin = 0.07,
|
||||
upgradeGrowthMax = 0.11
|
||||
},
|
||||
{
|
||||
key = "crit_mult",
|
||||
min = 1,
|
||||
max = 8,
|
||||
decimals = 1,
|
||||
upgradeGrowthMin = 0.07,
|
||||
upgradeGrowthMax = 0.11
|
||||
},
|
||||
{key = "battle_level", min = 1, max = 1, decimals = 0}
|
||||
}
|
||||
local function roundTo(self, value, decimals)
|
||||
if decimals == nil then
|
||||
decimals = 0
|
||||
end
|
||||
if decimals <= 0 then
|
||||
return math.floor(value + 0.5)
|
||||
end
|
||||
local mul = math.pow(10, decimals)
|
||||
return math.floor(value * mul + 0.5) / mul
|
||||
end
|
||||
local function randomTemplateIndex(self)
|
||||
return RandomInt(1, #ARSENAL_STAT_POOL) - 1
|
||||
end
|
||||
local function inferSlotFromItemName(self, itemName)
|
||||
local n = string.lower(itemName)
|
||||
if (string.find(n, "_weapon_", nil, true) or 0) - 1 >= 0 then
|
||||
return "weapon"
|
||||
end
|
||||
if (string.find(n, "_armor_", nil, true) or 0) - 1 >= 0 then
|
||||
return "armor"
|
||||
end
|
||||
if (string.find(n, "_helmet_", nil, true) or 0) - 1 >= 0 then
|
||||
return "helmet"
|
||||
end
|
||||
if (string.find(n, "_boots_", nil, true) or 0) - 1 >= 0 then
|
||||
return "boots"
|
||||
end
|
||||
if (string.find(n, "_necklace_", nil, true) or 0) - 1 >= 0 then
|
||||
return "necklace"
|
||||
end
|
||||
return "ring"
|
||||
end
|
||||
local function getSlotWeightForStat(self, slot, key)
|
||||
if slot == "ring" then
|
||||
if key == "max_mana" or key == "magic_resist" or key == "spell_amp" then
|
||||
return 2.5
|
||||
end
|
||||
if key == "mana_regen" then
|
||||
return 2.2
|
||||
end
|
||||
if key == "max_health" then
|
||||
return 1.4
|
||||
end
|
||||
if key == "all_stats_pct" then
|
||||
return 1.55
|
||||
end
|
||||
if key == "all_stats" then
|
||||
return 1.15
|
||||
end
|
||||
if key == "intellect_pct" or key == "strength_pct" or key == "agility_pct" or key == "bonus_intellect" or key == "bonus_strength" or key == "bonus_agility" then
|
||||
return 1.3
|
||||
end
|
||||
elseif slot == "weapon" then
|
||||
if key == "bonus_damage" or key == "attack_speed" or key == "base_damage_pct" then
|
||||
return 2.6
|
||||
end
|
||||
if key == "attack_speed_pct" or key == "outgoing_damage_pct" or key == "crit_mult" then
|
||||
return 1.8
|
||||
end
|
||||
if key == "strength_pct" or key == "agility_pct" or key == "bonus_strength" or key == "bonus_agility" then
|
||||
return 1.5
|
||||
end
|
||||
if key == "all_stats_pct" then
|
||||
return 1.25
|
||||
end
|
||||
elseif slot == "armor" then
|
||||
if key == "health_regen" or key == "max_health" then
|
||||
return 1.85
|
||||
end
|
||||
if key == "mana_regen" or key == "bonus_armor" then
|
||||
return 1.55
|
||||
end
|
||||
if key == "all_stats_pct" then
|
||||
return 1.55
|
||||
end
|
||||
if key == "all_stats" then
|
||||
return 1.2
|
||||
end
|
||||
if key == "strength_pct" or key == "bonus_strength" then
|
||||
return 1.6
|
||||
end
|
||||
elseif slot == "helmet" then
|
||||
if key == "health_regen" then
|
||||
return 1.65
|
||||
end
|
||||
if key == "all_stats_pct" then
|
||||
return 1.72
|
||||
end
|
||||
if key == "all_stats" then
|
||||
return 1.25
|
||||
end
|
||||
if key == "intellect_pct" or key == "bonus_intellect" then
|
||||
return 1.8
|
||||
end
|
||||
elseif slot == "boots" then
|
||||
if key == "all_stats_pct" then
|
||||
return 1.38
|
||||
end
|
||||
if key == "agility_pct" or key == "bonus_agility" then
|
||||
return 1.6
|
||||
end
|
||||
elseif slot == "necklace" then
|
||||
if key == "mana_regen" or key == "spell_amp" then
|
||||
return 1.75
|
||||
end
|
||||
if key == "all_stats_pct" then
|
||||
return 1.62
|
||||
end
|
||||
if key == "all_stats" then
|
||||
return 1.2
|
||||
end
|
||||
if key == "intellect_pct" or key == "bonus_intellect" then
|
||||
return 1.5
|
||||
end
|
||||
end
|
||||
return 1
|
||||
end
|
||||
local function randomTemplateIndexForSlot(self, slot)
|
||||
local totalWeight = 0
|
||||
for ____, t in ipairs(ARSENAL_STAT_POOL) do
|
||||
totalWeight = totalWeight + getSlotWeightForStat(nil, slot, t.key)
|
||||
end
|
||||
if totalWeight <= 0 then
|
||||
return randomTemplateIndex(nil)
|
||||
end
|
||||
local roll = RandomFloat(0, totalWeight)
|
||||
local passed = 0
|
||||
do
|
||||
local i = 0
|
||||
while i < #ARSENAL_STAT_POOL do
|
||||
passed = passed + getSlotWeightForStat(nil, slot, ARSENAL_STAT_POOL[i + 1].key)
|
||||
if roll <= passed then
|
||||
return i
|
||||
end
|
||||
i = i + 1
|
||||
end
|
||||
end
|
||||
return #ARSENAL_STAT_POOL - 1
|
||||
end
|
||||
local function findTemplateIndexByKey(self, key)
|
||||
do
|
||||
local i = 0
|
||||
while i < #ARSENAL_STAT_POOL do
|
||||
if ARSENAL_STAT_POOL[i + 1].key == key then
|
||||
return i
|
||||
end
|
||||
i = i + 1
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
--- Реже, чем раньше: часть строк может взять тот же стат, что уже выпал (случайная из набранных).
|
||||
-- Иначе — обычный взвешенный ролл по слоту.
|
||||
local function randomTemplateIndexForSlotWithStackBias(self, slot, existingLines)
|
||||
if #existingLines == 0 or RandomInt(1, 100) > ARSENAL_REPEAT_EXISTING_STAT_CHANCE_PCT then
|
||||
return randomTemplateIndexForSlot(nil, slot)
|
||||
end
|
||||
local linePick = RandomInt(1, #existingLines) - 1
|
||||
local key = existingLines[linePick + 1].key
|
||||
local idx = findTemplateIndexByKey(nil, key)
|
||||
if idx == nil then
|
||||
return randomTemplateIndexForSlot(nil, slot)
|
||||
end
|
||||
return idx
|
||||
end
|
||||
local function rollStatBase(self, template, slotIndex, contractDropStatBias)
|
||||
if contractDropStatBias == nil then
|
||||
contractDropStatBias = 0
|
||||
end
|
||||
local roll01 = RandomFloat(0, 1)
|
||||
local exponent = slotIndex < BASE_STAT_COUNT and 1.35 or 1.75
|
||||
if contractDropStatBias > 0 then
|
||||
exponent = exponent * (1 - 0.45 * contractDropStatBias)
|
||||
end
|
||||
local biased = math.pow(roll01, exponent)
|
||||
local raw = template.min + (template.max - template.min) * biased
|
||||
return roundTo(nil, raw, template.decimals or 0)
|
||||
end
|
||||
local function rollStatBaseInBand(self, template, fromRatio, toRatio)
|
||||
local clampedFrom = math.max(
|
||||
0,
|
||||
math.min(1, fromRatio)
|
||||
)
|
||||
local clampedTo = math.max(
|
||||
clampedFrom,
|
||||
math.min(1, toRatio)
|
||||
)
|
||||
local ratio = RandomFloat(clampedFrom, clampedTo)
|
||||
local raw = template.min + (template.max - template.min) * ratio
|
||||
return roundTo(nil, raw, template.decimals or 0)
|
||||
end
|
||||
--- Случайный множитель роста строки по шаблону; без min/max в шаблоне — undefined (берётся PER_LEVEL_GROWTH).
|
||||
local function rollUpgradeGrowthForTemplate(self, template)
|
||||
local minG = template.upgradeGrowthMin
|
||||
local maxG = template.upgradeGrowthMax
|
||||
if minG == nil or maxG == nil then
|
||||
return nil
|
||||
end
|
||||
if not __TS__NumberIsFinite(minG) or not __TS__NumberIsFinite(maxG) then
|
||||
return nil
|
||||
end
|
||||
local lo = math.min(minG, maxG)
|
||||
local hi = math.max(minG, maxG)
|
||||
return roundTo(
|
||||
nil,
|
||||
RandomFloat(lo, hi),
|
||||
4
|
||||
)
|
||||
end
|
||||
local function clampRarityIndex(self, index)
|
||||
if index < 0 then
|
||||
return 0
|
||||
end
|
||||
if index >= #ARSENAL_RARITY_ORDER then
|
||||
return #ARSENAL_RARITY_ORDER - 1
|
||||
end
|
||||
return index
|
||||
end
|
||||
local function getRarityIndex(self, quality)
|
||||
do
|
||||
local i = 0
|
||||
while i < #ARSENAL_RARITY_ORDER do
|
||||
if ARSENAL_RARITY_ORDER[i + 1] == quality then
|
||||
return i
|
||||
end
|
||||
i = i + 1
|
||||
end
|
||||
end
|
||||
return 0
|
||||
end
|
||||
local function elevateRarityBySteps(self, baseQuality, steps)
|
||||
if steps <= 0 then
|
||||
return baseQuality
|
||||
end
|
||||
local nextIndex = clampRarityIndex(
|
||||
nil,
|
||||
getRarityIndex(nil, baseQuality) + steps
|
||||
)
|
||||
return ARSENAL_RARITY_ORDER[nextIndex + 1]
|
||||
end
|
||||
local function capStatQualityByItemQuality(self, statQuality, itemQuality)
|
||||
local statIndex = getRarityIndex(nil, statQuality)
|
||||
local itemIndex = getRarityIndex(nil, itemQuality)
|
||||
return ARSENAL_RARITY_ORDER[math.min(statIndex, itemIndex) + 1]
|
||||
end
|
||||
local function getTemplateByKey(self, key)
|
||||
for ____, t in ipairs(ARSENAL_STAT_POOL) do
|
||||
if t.key == key then
|
||||
return t
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
local function getStatQualityByBaseValue(self, stat)
|
||||
local tpl = getTemplateByKey(nil, stat.key)
|
||||
if not tpl then
|
||||
return "common"
|
||||
end
|
||||
local span = tpl.max - tpl.min
|
||||
if span <= 0 then
|
||||
return "common"
|
||||
end
|
||||
local ratio = (stat.base - tpl.min) / span
|
||||
local clamped = math.max(
|
||||
0,
|
||||
math.min(1, ratio)
|
||||
)
|
||||
local rawTier = math.floor(clamped * #ARSENAL_RARITY_ORDER)
|
||||
return ARSENAL_RARITY_ORDER[clampRarityIndex(nil, rawTier) + 1]
|
||||
end
|
||||
local function getEffectiveStatQuality(self, item, statIndex, baseQuality)
|
||||
if item.quality == "mythic" and statIndex == HIDDEN_FINAL_STAT_INDEX and math.floor(item.upgradeLevel) >= MAX_UPGRADE_LEVEL then
|
||||
return ASCENDED_STAT_QUALITY
|
||||
end
|
||||
return capStatQualityByItemQuality(nil, baseQuality, item.quality)
|
||||
end
|
||||
local function getBaseAfterCapApproach(self, stat, extraMaxRaritySteps)
|
||||
if extraMaxRaritySteps <= 0 then
|
||||
return stat.base
|
||||
end
|
||||
local tpl = getTemplateByKey(nil, stat.key)
|
||||
if not tpl or tpl.max <= stat.base then
|
||||
return stat.base
|
||||
end
|
||||
local approachFactor = 1 - math.pow(1 - MAX_RARITY_CAP_APPROACH_PER_STEP, extraMaxRaritySteps)
|
||||
local shifted = stat.base + (tpl.max - stat.base) * approachFactor
|
||||
return roundTo(nil, shifted, tpl.decimals or 0)
|
||||
end
|
||||
local function getActiveAdditionalCount(self, itemQuality)
|
||||
return ADDITIONAL_SLOTS_BY_ITEM_QUALITY[itemQuality] or 0
|
||||
end
|
||||
local function getAdditionalUpgradeTargetIndex(self, item, levelStep, activeAdditional)
|
||||
if levelStep <= 0 then
|
||||
return nil
|
||||
end
|
||||
if levelStep == HIDDEN_FINAL_UNLOCK_LEVEL then
|
||||
return HIDDEN_FINAL_STAT_INDEX
|
||||
end
|
||||
local poolSize = math.min(ADDITIONAL_STAT_COUNT, activeAdditional) + 1
|
||||
if poolSize <= 0 then
|
||||
return nil
|
||||
end
|
||||
local seed = levelStep * 97 + poolSize * 31
|
||||
do
|
||||
local offset = 0
|
||||
while offset < poolSize do
|
||||
local idx = offset == poolSize - 1 and HIDDEN_FINAL_STAT_INDEX or BASE_STAT_COUNT + offset
|
||||
local line = item.stats[idx + 1]
|
||||
local baseInt = math.floor((line and line.base or 0) * 100 + 0.5)
|
||||
seed = seed + ((idx + 1) * 17 + baseInt)
|
||||
offset = offset + 1
|
||||
end
|
||||
end
|
||||
local offset = math.floor(math.abs(seed)) % poolSize
|
||||
return offset == poolSize - 1 and HIDDEN_FINAL_STAT_INDEX or BASE_STAT_COUNT + offset
|
||||
end
|
||||
function ____exports.contractRewardMultToDropStatBias01(self, rewardMultiplier)
|
||||
local minM = 3
|
||||
local maxM = 10
|
||||
local span = maxM - minM
|
||||
if span <= 0 then
|
||||
return 0
|
||||
end
|
||||
return math.max(
|
||||
0,
|
||||
math.min(1, (rewardMultiplier - minM) / span)
|
||||
)
|
||||
end
|
||||
function ____exports.createInitialItemState(self, itemName, quality, context)
|
||||
local bias = math.max(
|
||||
0,
|
||||
math.min(1, context and context.contractDropStatBias or 0)
|
||||
)
|
||||
local mythicBandLift = bias * 0.035
|
||||
local slot = inferSlotFromItemName(nil, itemName)
|
||||
local stats = {}
|
||||
local totalStatLines = BASE_STAT_COUNT + ADDITIONAL_STAT_COUNT + 1
|
||||
local mythicBestLines = 0
|
||||
if quality == "mythic" then
|
||||
mythicBestLines = 1
|
||||
if RandomInt(1, 100) <= MYTHIC_BEST_LINE_CHANCE_PCT then
|
||||
mythicBestLines = 2
|
||||
end
|
||||
end
|
||||
do
|
||||
local i = 0
|
||||
while i < BASE_STAT_COUNT + ADDITIONAL_STAT_COUNT + 1 do
|
||||
local templateIndex = randomTemplateIndexForSlotWithStackBias(nil, slot, stats)
|
||||
local template = ARSENAL_STAT_POOL[templateIndex + 1]
|
||||
local rolledBase
|
||||
if quality == "mythic" then
|
||||
local guaranteedBestCut = totalStatLines - mythicBestLines
|
||||
if i >= guaranteedBestCut then
|
||||
rolledBase = rollStatBaseInBand(
|
||||
nil,
|
||||
template,
|
||||
0.8,
|
||||
math.min(1, 0.97 + mythicBandLift)
|
||||
)
|
||||
elseif RandomInt(1, 100) <= MYTHIC_WEAK_LINE_CHANCE_PCT then
|
||||
rolledBase = rollStatBaseInBand(
|
||||
nil,
|
||||
template,
|
||||
0.05,
|
||||
math.min(1, 0.59 + mythicBandLift * 0.5)
|
||||
)
|
||||
else
|
||||
rolledBase = rollStatBaseInBand(
|
||||
nil,
|
||||
template,
|
||||
0.6,
|
||||
math.min(1, 0.79 + mythicBandLift)
|
||||
)
|
||||
end
|
||||
else
|
||||
rolledBase = rollStatBase(nil, template, i, bias)
|
||||
end
|
||||
local rolledGrowth = rollUpgradeGrowthForTemplate(nil, template)
|
||||
local row = {key = template.key, base = rolledBase}
|
||||
if rolledGrowth ~= nil then
|
||||
row.upgradeGrowth = rolledGrowth
|
||||
end
|
||||
stats[#stats + 1] = row
|
||||
i = i + 1
|
||||
end
|
||||
end
|
||||
return {itemName = itemName, quality = quality, upgradeLevel = 0, stats = stats}
|
||||
end
|
||||
function ____exports.createArsenalItemInstance(self, instanceId, serial, itemName, quality, rollContext)
|
||||
local core = ____exports.createInitialItemState(nil, itemName, quality, rollContext)
|
||||
return {
|
||||
instanceId = instanceId,
|
||||
serial = serial,
|
||||
itemName = core.itemName,
|
||||
quality = core.quality,
|
||||
upgradeLevel = core.upgradeLevel,
|
||||
stats = core.stats
|
||||
}
|
||||
end
|
||||
function ____exports.getEffectiveItemStats(self, item)
|
||||
local result = {}
|
||||
local level = math.max(
|
||||
0,
|
||||
math.min(
|
||||
MAX_UPGRADE_LEVEL,
|
||||
math.floor(item.upgradeLevel)
|
||||
)
|
||||
)
|
||||
local activeAdditional = getActiveAdditionalCount(nil, item.quality)
|
||||
local lineLevelBonus = {}
|
||||
do
|
||||
local i = 0
|
||||
while i < #item.stats do
|
||||
lineLevelBonus[i + 1] = 0
|
||||
i = i + 1
|
||||
end
|
||||
end
|
||||
do
|
||||
local i = 0
|
||||
while i < BASE_STAT_COUNT and i < #item.stats do
|
||||
lineLevelBonus[i + 1] = level
|
||||
i = i + 1
|
||||
end
|
||||
end
|
||||
do
|
||||
local step = 1
|
||||
while step <= level do
|
||||
local target = getAdditionalUpgradeTargetIndex(nil, item, step, activeAdditional)
|
||||
if target ~= nil and target < #item.stats then
|
||||
lineLevelBonus[target + 1] = (lineLevelBonus[target + 1] or 0) + 1
|
||||
end
|
||||
step = step + 1
|
||||
end
|
||||
end
|
||||
do
|
||||
local i = 0
|
||||
while i < #item.stats do
|
||||
do
|
||||
if i >= BASE_STAT_COUNT and i < BASE_STAT_COUNT + ADDITIONAL_STAT_COUNT then
|
||||
local localIndex = i - BASE_STAT_COUNT
|
||||
if localIndex >= activeAdditional then
|
||||
goto __continue106
|
||||
end
|
||||
end
|
||||
if i == HIDDEN_FINAL_STAT_INDEX and level < HIDDEN_FINAL_UNLOCK_LEVEL then
|
||||
goto __continue106
|
||||
end
|
||||
local rolledQuality = getStatQualityByBaseValue(nil, item.stats[i + 1])
|
||||
local rarityBonusSteps = lineLevelBonus[i + 1] or 0
|
||||
local upgradedQuality = elevateRarityBySteps(nil, rolledQuality, rarityBonusSteps)
|
||||
local maxRarityStepsSpent = math.max(
|
||||
0,
|
||||
rarityBonusSteps - (MAX_RARITY_INDEX - getRarityIndex(nil, rolledQuality))
|
||||
)
|
||||
local statQuality = getEffectiveStatQuality(nil, item, i, upgradedQuality)
|
||||
local effectiveBase = getBaseAfterCapApproach(nil, item.stats[i + 1], maxRarityStepsSpent)
|
||||
local qualityMult = ARSENAL_RARITY_MULTIPLIER[statQuality]
|
||||
local lineBonus = lineLevelBonus[i + 1] or 0
|
||||
local statKey = item.stats[i + 1].key
|
||||
if statKey == "battle_level" then
|
||||
result[#result + 1] = {
|
||||
key = statKey,
|
||||
value = math.max(
|
||||
0,
|
||||
math.floor(item.stats[i + 1].base) + lineBonus
|
||||
)
|
||||
}
|
||||
goto __continue106
|
||||
end
|
||||
local tpl = getTemplateByKey(nil, statKey)
|
||||
local outDecimals = tpl and tpl.decimals or 0
|
||||
local perLevelGrowth = item.stats[i + 1].upgradeGrowth or PER_LEVEL_GROWTH
|
||||
local growthMult = 1 + perLevelGrowth * lineBonus
|
||||
result[#result + 1] = {
|
||||
key = statKey,
|
||||
value = roundTo(nil, effectiveBase * qualityMult * growthMult, outDecimals)
|
||||
}
|
||||
end
|
||||
::__continue106::
|
||||
i = i + 1
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
function ____exports.getItemVisibleStatsCount(self, item)
|
||||
local activeAdditional = getActiveAdditionalCount(nil, item.quality)
|
||||
local hasHidden = math.floor(item.upgradeLevel) >= HIDDEN_FINAL_UNLOCK_LEVEL and 1 or 0
|
||||
return BASE_STAT_COUNT + activeAdditional + hasHidden
|
||||
end
|
||||
return ____exports
|
||||
@@ -0,0 +1,75 @@
|
||||
local ____lualib = require("lualib_bundle")
|
||||
local __TS__Class = ____lualib.__TS__Class
|
||||
local __TS__ClassExtends = ____lualib.__TS__ClassExtends
|
||||
local __TS__Decorate = ____lualib.__TS__Decorate
|
||||
local ____exports = {}
|
||||
local ____dota_ts_adapter = require("lib.dota_ts_adapter")
|
||||
local BaseModifier = ____dota_ts_adapter.BaseModifier
|
||||
local registerModifier = ____dota_ts_adapter.registerModifier
|
||||
____exports.modifier_arsenal_armor_chain_mail = __TS__Class()
|
||||
local modifier_arsenal_armor_chain_mail = ____exports.modifier_arsenal_armor_chain_mail
|
||||
modifier_arsenal_armor_chain_mail.name = "modifier_arsenal_armor_chain_mail"
|
||||
modifier_arsenal_armor_chain_mail.____file_path = "scripts/vscripts/arsenal/items/armor.lua"
|
||||
__TS__ClassExtends(modifier_arsenal_armor_chain_mail, BaseModifier)
|
||||
function modifier_arsenal_armor_chain_mail.prototype.IsHidden(self)
|
||||
return false
|
||||
end
|
||||
function modifier_arsenal_armor_chain_mail.prototype.IsPurgable(self)
|
||||
return false
|
||||
end
|
||||
function modifier_arsenal_armor_chain_mail.prototype.RemoveOnDeath(self)
|
||||
return false
|
||||
end
|
||||
function modifier_arsenal_armor_chain_mail.prototype.GetTexture(self)
|
||||
return "item_chainmail"
|
||||
end
|
||||
function modifier_arsenal_armor_chain_mail.prototype.DeclareFunctions(self)
|
||||
return {MODIFIER_PROPERTY_PHYSICAL_ARMOR_BONUS}
|
||||
end
|
||||
function modifier_arsenal_armor_chain_mail.prototype.GetModifierPhysicalArmorBonus(self)
|
||||
return 5
|
||||
end
|
||||
modifier_arsenal_armor_chain_mail = __TS__Decorate(
|
||||
modifier_arsenal_armor_chain_mail,
|
||||
modifier_arsenal_armor_chain_mail,
|
||||
{registerModifier(nil)},
|
||||
{kind = "class", name = "modifier_arsenal_armor_chain_mail"}
|
||||
)
|
||||
____exports.modifier_arsenal_armor_chain_mail = modifier_arsenal_armor_chain_mail
|
||||
____exports.modifier_arsenal_armor_dragon_plate = __TS__Class()
|
||||
local modifier_arsenal_armor_dragon_plate = ____exports.modifier_arsenal_armor_dragon_plate
|
||||
modifier_arsenal_armor_dragon_plate.name = "modifier_arsenal_armor_dragon_plate"
|
||||
modifier_arsenal_armor_dragon_plate.____file_path = "scripts/vscripts/arsenal/items/armor.lua"
|
||||
__TS__ClassExtends(modifier_arsenal_armor_dragon_plate, BaseModifier)
|
||||
function modifier_arsenal_armor_dragon_plate.prototype.IsHidden(self)
|
||||
return false
|
||||
end
|
||||
function modifier_arsenal_armor_dragon_plate.prototype.IsPurgable(self)
|
||||
return false
|
||||
end
|
||||
function modifier_arsenal_armor_dragon_plate.prototype.RemoveOnDeath(self)
|
||||
return false
|
||||
end
|
||||
function modifier_arsenal_armor_dragon_plate.prototype.GetTexture(self)
|
||||
return "item_platemail"
|
||||
end
|
||||
function modifier_arsenal_armor_dragon_plate.prototype.DeclareFunctions(self)
|
||||
return {MODIFIER_PROPERTY_PHYSICAL_ARMOR_BONUS, MODIFIER_PROPERTY_HEALTH_BONUS, MODIFIER_PROPERTY_MAGICAL_RESISTANCE_BONUS}
|
||||
end
|
||||
function modifier_arsenal_armor_dragon_plate.prototype.GetModifierPhysicalArmorBonus(self)
|
||||
return 12
|
||||
end
|
||||
function modifier_arsenal_armor_dragon_plate.prototype.GetModifierHealthBonus(self)
|
||||
return 350
|
||||
end
|
||||
function modifier_arsenal_armor_dragon_plate.prototype.GetModifierMagicalResistanceBonus(self)
|
||||
return 10
|
||||
end
|
||||
modifier_arsenal_armor_dragon_plate = __TS__Decorate(
|
||||
modifier_arsenal_armor_dragon_plate,
|
||||
modifier_arsenal_armor_dragon_plate,
|
||||
{registerModifier(nil)},
|
||||
{kind = "class", name = "modifier_arsenal_armor_dragon_plate"}
|
||||
)
|
||||
____exports.modifier_arsenal_armor_dragon_plate = modifier_arsenal_armor_dragon_plate
|
||||
return ____exports
|
||||
@@ -0,0 +1,62 @@
|
||||
local ____lualib = require("lualib_bundle")
|
||||
local __TS__Class = ____lualib.__TS__Class
|
||||
local __TS__ClassExtends = ____lualib.__TS__ClassExtends
|
||||
local __TS__Decorate = ____lualib.__TS__Decorate
|
||||
local ____exports = {}
|
||||
local ____dota_ts_adapter = require("lib.dota_ts_adapter")
|
||||
local BaseModifier = ____dota_ts_adapter.BaseModifier
|
||||
local registerModifier = ____dota_ts_adapter.registerModifier
|
||||
____exports.modifier_arsenal_battle_level = __TS__Class()
|
||||
local modifier_arsenal_battle_level = ____exports.modifier_arsenal_battle_level
|
||||
modifier_arsenal_battle_level.name = "modifier_arsenal_battle_level"
|
||||
modifier_arsenal_battle_level.____file_path = "scripts/vscripts/arsenal/items/battle_level.lua"
|
||||
__TS__ClassExtends(modifier_arsenal_battle_level, BaseModifier)
|
||||
function modifier_arsenal_battle_level.prototype.IsHidden(self)
|
||||
return true
|
||||
end
|
||||
function modifier_arsenal_battle_level.prototype.RemoveOnDeath(self)
|
||||
return false
|
||||
end
|
||||
function modifier_arsenal_battle_level.prototype.OnCreated(self)
|
||||
if not IsServer() then
|
||||
return
|
||||
end
|
||||
self:applyBattleLevel()
|
||||
end
|
||||
function modifier_arsenal_battle_level.prototype.OnRefresh(self)
|
||||
if not IsServer() then
|
||||
return
|
||||
end
|
||||
self:applyBattleLevel()
|
||||
end
|
||||
function modifier_arsenal_battle_level.prototype.applyBattleLevel(self)
|
||||
local hero = self:GetParent()
|
||||
if not hero or not IsValidEntity(hero) or not hero:IsRealHero() then
|
||||
return
|
||||
end
|
||||
local bonus = math.max(
|
||||
0,
|
||||
math.floor(self:GetStackCount() or 0)
|
||||
)
|
||||
if bonus <= 0 then
|
||||
return
|
||||
end
|
||||
local targetLevel = 1 + bonus
|
||||
local cur = hero:GetLevel()
|
||||
if cur >= targetLevel then
|
||||
return
|
||||
end
|
||||
local prevAbilityPoints = hero:GetAbilityPoints()
|
||||
while hero:GetLevel() < targetLevel do
|
||||
hero:HeroLevelUp(false)
|
||||
hero:SetAbilityPoints(prevAbilityPoints)
|
||||
end
|
||||
end
|
||||
modifier_arsenal_battle_level = __TS__Decorate(
|
||||
modifier_arsenal_battle_level,
|
||||
modifier_arsenal_battle_level,
|
||||
{registerModifier(nil)},
|
||||
{kind = "class", name = "modifier_arsenal_battle_level"}
|
||||
)
|
||||
____exports.modifier_arsenal_battle_level = modifier_arsenal_battle_level
|
||||
return ____exports
|
||||
@@ -0,0 +1,72 @@
|
||||
local ____lualib = require("lualib_bundle")
|
||||
local __TS__Class = ____lualib.__TS__Class
|
||||
local __TS__ClassExtends = ____lualib.__TS__ClassExtends
|
||||
local __TS__Decorate = ____lualib.__TS__Decorate
|
||||
local ____exports = {}
|
||||
local ____dota_ts_adapter = require("lib.dota_ts_adapter")
|
||||
local BaseModifier = ____dota_ts_adapter.BaseModifier
|
||||
local registerModifier = ____dota_ts_adapter.registerModifier
|
||||
____exports.modifier_arsenal_boots_swift_boots = __TS__Class()
|
||||
local modifier_arsenal_boots_swift_boots = ____exports.modifier_arsenal_boots_swift_boots
|
||||
modifier_arsenal_boots_swift_boots.name = "modifier_arsenal_boots_swift_boots"
|
||||
modifier_arsenal_boots_swift_boots.____file_path = "scripts/vscripts/arsenal/items/boots.lua"
|
||||
__TS__ClassExtends(modifier_arsenal_boots_swift_boots, BaseModifier)
|
||||
function modifier_arsenal_boots_swift_boots.prototype.IsHidden(self)
|
||||
return false
|
||||
end
|
||||
function modifier_arsenal_boots_swift_boots.prototype.IsPurgable(self)
|
||||
return false
|
||||
end
|
||||
function modifier_arsenal_boots_swift_boots.prototype.RemoveOnDeath(self)
|
||||
return false
|
||||
end
|
||||
function modifier_arsenal_boots_swift_boots.prototype.GetTexture(self)
|
||||
return "item_boots"
|
||||
end
|
||||
function modifier_arsenal_boots_swift_boots.prototype.DeclareFunctions(self)
|
||||
return {MODIFIER_PROPERTY_MOVESPEED_BONUS_CONSTANT}
|
||||
end
|
||||
function modifier_arsenal_boots_swift_boots.prototype.GetModifierMoveSpeedBonus_Constant(self)
|
||||
return 35
|
||||
end
|
||||
modifier_arsenal_boots_swift_boots = __TS__Decorate(
|
||||
modifier_arsenal_boots_swift_boots,
|
||||
modifier_arsenal_boots_swift_boots,
|
||||
{registerModifier(nil)},
|
||||
{kind = "class", name = "modifier_arsenal_boots_swift_boots"}
|
||||
)
|
||||
____exports.modifier_arsenal_boots_swift_boots = modifier_arsenal_boots_swift_boots
|
||||
____exports.modifier_arsenal_boots_phase_treads = __TS__Class()
|
||||
local modifier_arsenal_boots_phase_treads = ____exports.modifier_arsenal_boots_phase_treads
|
||||
modifier_arsenal_boots_phase_treads.name = "modifier_arsenal_boots_phase_treads"
|
||||
modifier_arsenal_boots_phase_treads.____file_path = "scripts/vscripts/arsenal/items/boots.lua"
|
||||
__TS__ClassExtends(modifier_arsenal_boots_phase_treads, BaseModifier)
|
||||
function modifier_arsenal_boots_phase_treads.prototype.IsHidden(self)
|
||||
return false
|
||||
end
|
||||
function modifier_arsenal_boots_phase_treads.prototype.IsPurgable(self)
|
||||
return false
|
||||
end
|
||||
function modifier_arsenal_boots_phase_treads.prototype.RemoveOnDeath(self)
|
||||
return false
|
||||
end
|
||||
function modifier_arsenal_boots_phase_treads.prototype.GetTexture(self)
|
||||
return "item_phase_boots"
|
||||
end
|
||||
function modifier_arsenal_boots_phase_treads.prototype.DeclareFunctions(self)
|
||||
return {MODIFIER_PROPERTY_MOVESPEED_BONUS_CONSTANT, MODIFIER_PROPERTY_PREATTACK_BONUS_DAMAGE}
|
||||
end
|
||||
function modifier_arsenal_boots_phase_treads.prototype.GetModifierMoveSpeedBonus_Constant(self)
|
||||
return 50
|
||||
end
|
||||
function modifier_arsenal_boots_phase_treads.prototype.GetModifierPreAttack_BonusDamage(self)
|
||||
return 15
|
||||
end
|
||||
modifier_arsenal_boots_phase_treads = __TS__Decorate(
|
||||
modifier_arsenal_boots_phase_treads,
|
||||
modifier_arsenal_boots_phase_treads,
|
||||
{registerModifier(nil)},
|
||||
{kind = "class", name = "modifier_arsenal_boots_phase_treads"}
|
||||
)
|
||||
____exports.modifier_arsenal_boots_phase_treads = modifier_arsenal_boots_phase_treads
|
||||
return ____exports
|
||||
@@ -0,0 +1,429 @@
|
||||
local ____lualib = require("lualib_bundle")
|
||||
local __TS__ObjectValues = ____lualib.__TS__ObjectValues
|
||||
local __TS__ObjectAssign = ____lualib.__TS__ObjectAssign
|
||||
local __TS__Class = ____lualib.__TS__Class
|
||||
local __TS__ClassExtends = ____lualib.__TS__ClassExtends
|
||||
local __TS__Decorate = ____lualib.__TS__Decorate
|
||||
local ____exports = {}
|
||||
local ____dota_ts_adapter = require("lib.dota_ts_adapter")
|
||||
local BaseModifier = ____dota_ts_adapter.BaseModifier
|
||||
local registerModifier = ____dota_ts_adapter.registerModifier
|
||||
local ____ArsenalStatRuntime = require("arsenal.ArsenalStatRuntime")
|
||||
local getArsenalTotals = ____ArsenalStatRuntime.getArsenalTotals
|
||||
local ____modifier_stats_multiplier = require("modifiers.modifier_stats_multiplier")
|
||||
local ARSENAL_STATS_MULTIPLIER_SOURCE_ID = ____modifier_stats_multiplier.ARSENAL_STATS_MULTIPLIER_SOURCE_ID
|
||||
local invalidateStatsMultiplierSumCache = ____modifier_stats_multiplier.invalidateStatsMultiplierSumCache
|
||||
local removeStatsMultiplierSource = ____modifier_stats_multiplier.removeStatsMultiplierSource
|
||||
local setStatsMultiplierSource = ____modifier_stats_multiplier.setStatsMultiplierSource
|
||||
local ____incoming_damage_reduction_combine = require("utils.incoming_damage_reduction_combine")
|
||||
local removeIncomingDamageReductionSource = ____incoming_damage_reduction_combine.removeIncomingDamageReductionSource
|
||||
local setIncomingDamageReductionSource = ____incoming_damage_reduction_combine.setIncomingDamageReductionSource
|
||||
local ____luck = require("utils.luck")
|
||||
local addLuck = ____luck.addLuck
|
||||
local reduceLuck = ____luck.reduceLuck
|
||||
local ____crit_mult = require("utils.crit_mult")
|
||||
local addCritMult = ____crit_mult.addCritMult
|
||||
local reduceCritMult = ____crit_mult.reduceCritMult
|
||||
local ZERO_TOTALS = {
|
||||
battle_level = 0,
|
||||
bonus_damage = 0,
|
||||
attack_speed = 0,
|
||||
bonus_armor = 0,
|
||||
max_health = 0,
|
||||
max_mana = 0,
|
||||
health_regen = 0,
|
||||
mana_regen = 0,
|
||||
move_speed = 0,
|
||||
magic_resist = 0,
|
||||
spell_amp = 0,
|
||||
all_stats = 0,
|
||||
all_stats_pct = 0,
|
||||
bonus_strength = 0,
|
||||
bonus_agility = 0,
|
||||
bonus_intellect = 0,
|
||||
strength_pct = 0,
|
||||
agility_pct = 0,
|
||||
intellect_pct = 0,
|
||||
luck = 0,
|
||||
outgoing_damage_pct = 0,
|
||||
incoming_damage_reduction_pct = 0,
|
||||
attack_speed_pct = 0,
|
||||
move_speed_pct = 0,
|
||||
base_damage_pct = 0,
|
||||
crit_mult = 0
|
||||
}
|
||||
--- % атрибутов — через stats multiplier (база × %). Боевые % — прямо в DeclareFunctions ниже.
|
||||
local ARSENAL_ATTRIBUTE_PCT_KINDS = {"all_stats_pct", "strength_pct", "agility_pct", "intellect_pct"}
|
||||
local ALL_ARSENAL_MULTIPLIER_SOURCE_IDS = __TS__ObjectValues(ARSENAL_STATS_MULTIPLIER_SOURCE_ID)
|
||||
local ARSENAL_INCOMING_REDUCTION_SOURCE_ID = "arsenal_dynamic_stats_incoming"
|
||||
--- Раньше вешались на stats_multiplier — снимаем, чтобы не дублировать с прямым DeclareFunctions.
|
||||
local ARSENAL_LEGACY_COMBAT_PCT_KINDS = {
|
||||
"outgoing_damage_pct",
|
||||
"incoming_damage_reduction_pct",
|
||||
"attack_speed_pct",
|
||||
"move_speed_pct",
|
||||
"base_damage_pct"
|
||||
}
|
||||
local function coerceTotals(self, next)
|
||||
if not next then
|
||||
return __TS__ObjectAssign({}, ZERO_TOTALS)
|
||||
end
|
||||
return {
|
||||
battle_level = next.battle_level or 0,
|
||||
bonus_damage = next.bonus_damage or 0,
|
||||
attack_speed = next.attack_speed or 0,
|
||||
bonus_armor = next.bonus_armor or 0,
|
||||
max_health = next.max_health or 0,
|
||||
max_mana = next.max_mana or 0,
|
||||
health_regen = next.health_regen or 0,
|
||||
mana_regen = next.mana_regen or 0,
|
||||
move_speed = next.move_speed or 0,
|
||||
magic_resist = next.magic_resist or 0,
|
||||
spell_amp = next.spell_amp or 0,
|
||||
all_stats = next.all_stats or 0,
|
||||
all_stats_pct = next.all_stats_pct or 0,
|
||||
bonus_strength = next.bonus_strength or 0,
|
||||
bonus_agility = next.bonus_agility or 0,
|
||||
bonus_intellect = next.bonus_intellect or 0,
|
||||
strength_pct = next.strength_pct or 0,
|
||||
agility_pct = next.agility_pct or 0,
|
||||
intellect_pct = next.intellect_pct or 0,
|
||||
luck = next.luck or 0,
|
||||
outgoing_damage_pct = next.outgoing_damage_pct or 0,
|
||||
incoming_damage_reduction_pct = next.incoming_damage_reduction_pct or 0,
|
||||
attack_speed_pct = next.attack_speed_pct or 0,
|
||||
move_speed_pct = next.move_speed_pct or 0,
|
||||
base_damage_pct = next.base_damage_pct or 0,
|
||||
crit_mult = next.crit_mult or 0
|
||||
}
|
||||
end
|
||||
____exports.modifier_arsenal_dynamic_stats = __TS__Class()
|
||||
local modifier_arsenal_dynamic_stats = ____exports.modifier_arsenal_dynamic_stats
|
||||
modifier_arsenal_dynamic_stats.name = "modifier_arsenal_dynamic_stats"
|
||||
modifier_arsenal_dynamic_stats.____file_path = "scripts/vscripts/arsenal/items/dynamic_stats.lua"
|
||||
__TS__ClassExtends(modifier_arsenal_dynamic_stats, BaseModifier)
|
||||
function modifier_arsenal_dynamic_stats.prototype.____constructor(self, ...)
|
||||
BaseModifier.prototype.____constructor(self, ...)
|
||||
self.totals = __TS__ObjectAssign({}, ZERO_TOTALS)
|
||||
self.appliedLuckFromArsenal = 0
|
||||
self.appliedCritMultFromArsenal = 0
|
||||
end
|
||||
function modifier_arsenal_dynamic_stats.prototype.OnCreated(self)
|
||||
if not IsServer() then
|
||||
return
|
||||
end
|
||||
self:SetHasCustomTransmitterData(true)
|
||||
self:refreshTotalsFromServer()
|
||||
self:applyBattleLevelFromTotals()
|
||||
self:syncLuckFromTotals()
|
||||
self:syncCritMultFromTotals()
|
||||
self:wireArsenalAttributePctSources()
|
||||
self:wireArsenalIncomingReductionSource()
|
||||
end
|
||||
function modifier_arsenal_dynamic_stats.prototype.OnRefresh(self)
|
||||
if not IsServer() then
|
||||
return
|
||||
end
|
||||
self:refreshTotalsFromServer()
|
||||
self:applyBattleLevelFromTotals()
|
||||
self:syncLuckFromTotals()
|
||||
self:syncCritMultFromTotals()
|
||||
self:wireArsenalAttributePctSources()
|
||||
self:wireArsenalIncomingReductionSource()
|
||||
end
|
||||
function modifier_arsenal_dynamic_stats.prototype.OnDestroy(self)
|
||||
if not IsServer() then
|
||||
return
|
||||
end
|
||||
self:clearLuckFromTotals()
|
||||
self:clearCritMultFromTotals()
|
||||
self:unwireAllArsenalMultiplierSources()
|
||||
self:unwireArsenalIncomingReductionSource()
|
||||
end
|
||||
function modifier_arsenal_dynamic_stats.prototype.wireArsenalIncomingReductionSource(self)
|
||||
local hero = self:GetParent()
|
||||
if not hero or not IsValidEntity(hero) or not hero:IsRealHero() then
|
||||
return
|
||||
end
|
||||
setIncomingDamageReductionSource(
|
||||
nil,
|
||||
hero,
|
||||
ARSENAL_INCOMING_REDUCTION_SOURCE_ID,
|
||||
function()
|
||||
if not hero or not IsValidEntity(hero) then
|
||||
return 0
|
||||
end
|
||||
local totals = coerceTotals(
|
||||
nil,
|
||||
getArsenalTotals(nil, hero)
|
||||
)
|
||||
return math.max(0, totals.incoming_damage_reduction_pct or 0)
|
||||
end
|
||||
)
|
||||
end
|
||||
function modifier_arsenal_dynamic_stats.prototype.unwireArsenalIncomingReductionSource(self)
|
||||
local hero = self:GetParent()
|
||||
if not hero or not IsValidEntity(hero) then
|
||||
return
|
||||
end
|
||||
removeIncomingDamageReductionSource(nil, hero, ARSENAL_INCOMING_REDUCTION_SOURCE_ID)
|
||||
end
|
||||
function modifier_arsenal_dynamic_stats.prototype.unwireLegacyArsenalCombatPctSources(self, hero)
|
||||
for ____, k in ipairs(ARSENAL_LEGACY_COMBAT_PCT_KINDS) do
|
||||
removeStatsMultiplierSource(nil, hero, ARSENAL_STATS_MULTIPLIER_SOURCE_ID[k])
|
||||
end
|
||||
end
|
||||
function modifier_arsenal_dynamic_stats.prototype.wireArsenalAttributePctSources(self)
|
||||
local hero = self:GetParent()
|
||||
if not hero or not IsValidEntity(hero) or not hero:IsRealHero() then
|
||||
return
|
||||
end
|
||||
self:unwireLegacyArsenalCombatPctSources(hero)
|
||||
for ____, k in ipairs(ARSENAL_ATTRIBUTE_PCT_KINDS) do
|
||||
local sourceId = ARSENAL_STATS_MULTIPLIER_SOURCE_ID[k]
|
||||
setStatsMultiplierSource(
|
||||
nil,
|
||||
hero,
|
||||
sourceId,
|
||||
function()
|
||||
if not hero or not IsValidEntity(hero) then
|
||||
return 0
|
||||
end
|
||||
local t = coerceTotals(
|
||||
nil,
|
||||
getArsenalTotals(nil, hero)
|
||||
)
|
||||
if k == "strength_pct" then
|
||||
return t.strength_pct
|
||||
end
|
||||
if k == "agility_pct" then
|
||||
return t.agility_pct
|
||||
end
|
||||
if k == "intellect_pct" then
|
||||
return t.intellect_pct
|
||||
end
|
||||
if k == "all_stats_pct" then
|
||||
return t.all_stats_pct
|
||||
end
|
||||
return 0
|
||||
end,
|
||||
k
|
||||
)
|
||||
end
|
||||
end
|
||||
function modifier_arsenal_dynamic_stats.prototype.unwireAllArsenalMultiplierSources(self)
|
||||
local hero = self:GetParent()
|
||||
if not hero or not IsValidEntity(hero) then
|
||||
return
|
||||
end
|
||||
for ____, sourceId in ipairs(ALL_ARSENAL_MULTIPLIER_SOURCE_IDS) do
|
||||
removeStatsMultiplierSource(nil, hero, sourceId)
|
||||
end
|
||||
end
|
||||
function modifier_arsenal_dynamic_stats.prototype.AddCustomTransmitterData(self)
|
||||
return self.totals
|
||||
end
|
||||
function modifier_arsenal_dynamic_stats.prototype.HandleCustomTransmitterData(self, data)
|
||||
self.totals = coerceTotals(nil, data)
|
||||
end
|
||||
function modifier_arsenal_dynamic_stats.prototype.refreshTotalsFromServer(self)
|
||||
local parent = self:GetParent()
|
||||
local hero = parent
|
||||
local next = getArsenalTotals(nil, hero)
|
||||
self.totals = coerceTotals(nil, next)
|
||||
self:SendBuffRefreshToClients()
|
||||
if hero and IsValidEntity(hero) and hero:IsRealHero() then
|
||||
invalidateStatsMultiplierSumCache(nil, hero)
|
||||
end
|
||||
end
|
||||
function modifier_arsenal_dynamic_stats.prototype.syncLuckFromTotals(self)
|
||||
local hero = self:GetParent()
|
||||
if not hero or not IsValidEntity(hero) or not hero:IsRealHero() then
|
||||
return
|
||||
end
|
||||
local targetLuck = self:getTotals().luck or 0
|
||||
local delta = targetLuck - self.appliedLuckFromArsenal
|
||||
if math.abs(delta) <= 0.0001 then
|
||||
return
|
||||
end
|
||||
if delta > 0 then
|
||||
addLuck(nil, hero, delta)
|
||||
else
|
||||
reduceLuck(nil, hero, -delta)
|
||||
end
|
||||
self.appliedLuckFromArsenal = targetLuck
|
||||
end
|
||||
function modifier_arsenal_dynamic_stats.prototype.clearLuckFromTotals(self)
|
||||
local hero = self:GetParent()
|
||||
if not hero or not IsValidEntity(hero) or not hero:IsRealHero() then
|
||||
return
|
||||
end
|
||||
if math.abs(self.appliedLuckFromArsenal) <= 0.0001 then
|
||||
return
|
||||
end
|
||||
if self.appliedLuckFromArsenal > 0 then
|
||||
reduceLuck(nil, hero, self.appliedLuckFromArsenal)
|
||||
else
|
||||
addLuck(nil, hero, -self.appliedLuckFromArsenal)
|
||||
end
|
||||
self.appliedLuckFromArsenal = 0
|
||||
end
|
||||
function modifier_arsenal_dynamic_stats.prototype.syncCritMultFromTotals(self)
|
||||
local hero = self:GetParent()
|
||||
if not hero or not IsValidEntity(hero) or not hero:IsRealHero() then
|
||||
return
|
||||
end
|
||||
local targetCrit = self:getTotals().crit_mult or 0
|
||||
local delta = targetCrit - self.appliedCritMultFromArsenal
|
||||
if math.abs(delta) <= 0.0001 then
|
||||
return
|
||||
end
|
||||
if delta > 0 then
|
||||
addCritMult(nil, hero, delta)
|
||||
else
|
||||
reduceCritMult(nil, hero, -delta)
|
||||
end
|
||||
self.appliedCritMultFromArsenal = targetCrit
|
||||
end
|
||||
function modifier_arsenal_dynamic_stats.prototype.clearCritMultFromTotals(self)
|
||||
local hero = self:GetParent()
|
||||
if not hero or not IsValidEntity(hero) or not hero:IsRealHero() then
|
||||
return
|
||||
end
|
||||
if math.abs(self.appliedCritMultFromArsenal) <= 0.0001 then
|
||||
return
|
||||
end
|
||||
if self.appliedCritMultFromArsenal > 0 then
|
||||
reduceCritMult(nil, hero, self.appliedCritMultFromArsenal)
|
||||
else
|
||||
addCritMult(nil, hero, -self.appliedCritMultFromArsenal)
|
||||
end
|
||||
self.appliedCritMultFromArsenal = 0
|
||||
end
|
||||
function modifier_arsenal_dynamic_stats.prototype.applyBattleLevelFromTotals(self)
|
||||
local hero = self:GetParent()
|
||||
if not hero or not IsValidEntity(hero) or not hero:IsRealHero() then
|
||||
return
|
||||
end
|
||||
local bonus = math.max(
|
||||
0,
|
||||
math.floor(self:getTotals().battle_level or 0)
|
||||
)
|
||||
if bonus <= 0 then
|
||||
return
|
||||
end
|
||||
local targetLevel = 1 + bonus
|
||||
if hero:GetLevel() >= targetLevel then
|
||||
return
|
||||
end
|
||||
local prevAbilityPoints = hero:GetAbilityPoints()
|
||||
while hero:GetLevel() < targetLevel do
|
||||
hero:HeroLevelUp(false)
|
||||
hero:SetAbilityPoints(prevAbilityPoints)
|
||||
end
|
||||
end
|
||||
function modifier_arsenal_dynamic_stats.prototype.IsHidden(self)
|
||||
return true
|
||||
end
|
||||
function modifier_arsenal_dynamic_stats.prototype.IsPurgable(self)
|
||||
return false
|
||||
end
|
||||
function modifier_arsenal_dynamic_stats.prototype.RemoveOnDeath(self)
|
||||
return false
|
||||
end
|
||||
function modifier_arsenal_dynamic_stats.prototype.GetTexture(self)
|
||||
return "item_mantle"
|
||||
end
|
||||
function modifier_arsenal_dynamic_stats.prototype.DeclareFunctions(self)
|
||||
return {
|
||||
MODIFIER_PROPERTY_PREATTACK_BONUS_DAMAGE,
|
||||
MODIFIER_PROPERTY_ATTACKSPEED_BONUS_CONSTANT,
|
||||
MODIFIER_PROPERTY_PHYSICAL_ARMOR_BONUS,
|
||||
MODIFIER_PROPERTY_HEALTH_BONUS,
|
||||
MODIFIER_PROPERTY_MANA_BONUS,
|
||||
MODIFIER_PROPERTY_HEALTH_REGEN_CONSTANT,
|
||||
MODIFIER_PROPERTY_MANA_REGEN_CONSTANT,
|
||||
MODIFIER_PROPERTY_MOVESPEED_BONUS_CONSTANT,
|
||||
MODIFIER_PROPERTY_MAGICAL_RESISTANCE_BONUS,
|
||||
MODIFIER_PROPERTY_SPELL_AMPLIFY_PERCENTAGE,
|
||||
MODIFIER_PROPERTY_STATS_STRENGTH_BONUS,
|
||||
MODIFIER_PROPERTY_STATS_AGILITY_BONUS,
|
||||
MODIFIER_PROPERTY_STATS_INTELLECT_BONUS,
|
||||
MODIFIER_PROPERTY_DAMAGEOUTGOING_PERCENTAGE,
|
||||
MODIFIER_PROPERTY_ATTACKSPEED_PERCENTAGE,
|
||||
MODIFIER_PROPERTY_MOVESPEED_BONUS_PERCENTAGE,
|
||||
MODIFIER_PROPERTY_BASEDAMAGEOUTGOING_PERCENTAGE
|
||||
}
|
||||
end
|
||||
function modifier_arsenal_dynamic_stats.prototype.getTotals(self)
|
||||
if IsServer() then
|
||||
local parent = self:GetParent()
|
||||
return coerceTotals(
|
||||
nil,
|
||||
getArsenalTotals(nil, parent)
|
||||
)
|
||||
end
|
||||
return self.totals
|
||||
end
|
||||
function modifier_arsenal_dynamic_stats.prototype.GetModifierPreAttack_BonusDamage(self)
|
||||
return self:getTotals().bonus_damage
|
||||
end
|
||||
function modifier_arsenal_dynamic_stats.prototype.GetModifierAttackSpeedBonus_Constant(self)
|
||||
return self:getTotals().attack_speed
|
||||
end
|
||||
function modifier_arsenal_dynamic_stats.prototype.GetModifierPhysicalArmorBonus(self)
|
||||
return self:getTotals().bonus_armor
|
||||
end
|
||||
function modifier_arsenal_dynamic_stats.prototype.GetModifierHealthBonus(self)
|
||||
return self:getTotals().max_health
|
||||
end
|
||||
function modifier_arsenal_dynamic_stats.prototype.GetModifierManaBonus(self)
|
||||
return self:getTotals().max_mana
|
||||
end
|
||||
function modifier_arsenal_dynamic_stats.prototype.GetModifierConstantHealthRegen(self)
|
||||
return self:getTotals().health_regen
|
||||
end
|
||||
function modifier_arsenal_dynamic_stats.prototype.GetModifierConstantManaRegen(self)
|
||||
return self:getTotals().mana_regen
|
||||
end
|
||||
function modifier_arsenal_dynamic_stats.prototype.GetModifierMoveSpeedBonus_Constant(self)
|
||||
return self:getTotals().move_speed
|
||||
end
|
||||
function modifier_arsenal_dynamic_stats.prototype.GetModifierMagicalResistanceBonus(self)
|
||||
return self:getTotals().magic_resist
|
||||
end
|
||||
function modifier_arsenal_dynamic_stats.prototype.GetModifierSpellAmplify_Percentage(self)
|
||||
return self:getTotals().spell_amp
|
||||
end
|
||||
function modifier_arsenal_dynamic_stats.prototype.GetModifierBonusStats_Strength(self)
|
||||
local t = self:getTotals()
|
||||
return t.all_stats + t.bonus_strength
|
||||
end
|
||||
function modifier_arsenal_dynamic_stats.prototype.GetModifierBonusStats_Agility(self)
|
||||
local t = self:getTotals()
|
||||
return t.all_stats + t.bonus_agility
|
||||
end
|
||||
function modifier_arsenal_dynamic_stats.prototype.GetModifierBonusStats_Intellect(self)
|
||||
local t = self:getTotals()
|
||||
return t.all_stats + t.bonus_intellect
|
||||
end
|
||||
function modifier_arsenal_dynamic_stats.prototype.GetModifierDamageOutgoing_Percentage(self)
|
||||
return self:getTotals().outgoing_damage_pct
|
||||
end
|
||||
function modifier_arsenal_dynamic_stats.prototype.GetModifierAttackSpeedPercentage(self)
|
||||
return self:getTotals().attack_speed_pct
|
||||
end
|
||||
function modifier_arsenal_dynamic_stats.prototype.GetModifierMoveSpeedBonus_Percentage(self)
|
||||
return self:getTotals().move_speed_pct
|
||||
end
|
||||
function modifier_arsenal_dynamic_stats.prototype.GetModifierBaseDamageOutgoing_Percentage(self)
|
||||
return self:getTotals().base_damage_pct
|
||||
end
|
||||
modifier_arsenal_dynamic_stats = __TS__Decorate(
|
||||
modifier_arsenal_dynamic_stats,
|
||||
modifier_arsenal_dynamic_stats,
|
||||
{registerModifier(nil)},
|
||||
{kind = "class", name = "modifier_arsenal_dynamic_stats"}
|
||||
)
|
||||
____exports.modifier_arsenal_dynamic_stats = modifier_arsenal_dynamic_stats
|
||||
return ____exports
|
||||
@@ -0,0 +1,72 @@
|
||||
local ____lualib = require("lualib_bundle")
|
||||
local __TS__Class = ____lualib.__TS__Class
|
||||
local __TS__ClassExtends = ____lualib.__TS__ClassExtends
|
||||
local __TS__Decorate = ____lualib.__TS__Decorate
|
||||
local ____exports = {}
|
||||
local ____dota_ts_adapter = require("lib.dota_ts_adapter")
|
||||
local BaseModifier = ____dota_ts_adapter.BaseModifier
|
||||
local registerModifier = ____dota_ts_adapter.registerModifier
|
||||
____exports.modifier_arsenal_helmet_leather_cap = __TS__Class()
|
||||
local modifier_arsenal_helmet_leather_cap = ____exports.modifier_arsenal_helmet_leather_cap
|
||||
modifier_arsenal_helmet_leather_cap.name = "modifier_arsenal_helmet_leather_cap"
|
||||
modifier_arsenal_helmet_leather_cap.____file_path = "scripts/vscripts/arsenal/items/helmet.lua"
|
||||
__TS__ClassExtends(modifier_arsenal_helmet_leather_cap, BaseModifier)
|
||||
function modifier_arsenal_helmet_leather_cap.prototype.IsHidden(self)
|
||||
return false
|
||||
end
|
||||
function modifier_arsenal_helmet_leather_cap.prototype.IsPurgable(self)
|
||||
return false
|
||||
end
|
||||
function modifier_arsenal_helmet_leather_cap.prototype.RemoveOnDeath(self)
|
||||
return false
|
||||
end
|
||||
function modifier_arsenal_helmet_leather_cap.prototype.GetTexture(self)
|
||||
return "item_helm_of_iron_will"
|
||||
end
|
||||
function modifier_arsenal_helmet_leather_cap.prototype.DeclareFunctions(self)
|
||||
return {MODIFIER_PROPERTY_HEALTH_REGEN_CONSTANT}
|
||||
end
|
||||
function modifier_arsenal_helmet_leather_cap.prototype.GetModifierConstantHealthRegen(self)
|
||||
return 3
|
||||
end
|
||||
modifier_arsenal_helmet_leather_cap = __TS__Decorate(
|
||||
modifier_arsenal_helmet_leather_cap,
|
||||
modifier_arsenal_helmet_leather_cap,
|
||||
{registerModifier(nil)},
|
||||
{kind = "class", name = "modifier_arsenal_helmet_leather_cap"}
|
||||
)
|
||||
____exports.modifier_arsenal_helmet_leather_cap = modifier_arsenal_helmet_leather_cap
|
||||
____exports.modifier_arsenal_helmet_arcane_circlet = __TS__Class()
|
||||
local modifier_arsenal_helmet_arcane_circlet = ____exports.modifier_arsenal_helmet_arcane_circlet
|
||||
modifier_arsenal_helmet_arcane_circlet.name = "modifier_arsenal_helmet_arcane_circlet"
|
||||
modifier_arsenal_helmet_arcane_circlet.____file_path = "scripts/vscripts/arsenal/items/helmet.lua"
|
||||
__TS__ClassExtends(modifier_arsenal_helmet_arcane_circlet, BaseModifier)
|
||||
function modifier_arsenal_helmet_arcane_circlet.prototype.IsHidden(self)
|
||||
return false
|
||||
end
|
||||
function modifier_arsenal_helmet_arcane_circlet.prototype.IsPurgable(self)
|
||||
return false
|
||||
end
|
||||
function modifier_arsenal_helmet_arcane_circlet.prototype.RemoveOnDeath(self)
|
||||
return false
|
||||
end
|
||||
function modifier_arsenal_helmet_arcane_circlet.prototype.GetTexture(self)
|
||||
return "item_helm_of_the_dominator"
|
||||
end
|
||||
function modifier_arsenal_helmet_arcane_circlet.prototype.DeclareFunctions(self)
|
||||
return {MODIFIER_PROPERTY_MANA_BONUS, MODIFIER_PROPERTY_MANA_REGEN_CONSTANT}
|
||||
end
|
||||
function modifier_arsenal_helmet_arcane_circlet.prototype.GetModifierManaBonus(self)
|
||||
return 250
|
||||
end
|
||||
function modifier_arsenal_helmet_arcane_circlet.prototype.GetModifierConstantManaRegen(self)
|
||||
return 3
|
||||
end
|
||||
modifier_arsenal_helmet_arcane_circlet = __TS__Decorate(
|
||||
modifier_arsenal_helmet_arcane_circlet,
|
||||
modifier_arsenal_helmet_arcane_circlet,
|
||||
{registerModifier(nil)},
|
||||
{kind = "class", name = "modifier_arsenal_helmet_arcane_circlet"}
|
||||
)
|
||||
____exports.modifier_arsenal_helmet_arcane_circlet = modifier_arsenal_helmet_arcane_circlet
|
||||
return ____exports
|
||||
@@ -0,0 +1,75 @@
|
||||
local ____lualib = require("lualib_bundle")
|
||||
local __TS__Class = ____lualib.__TS__Class
|
||||
local __TS__ClassExtends = ____lualib.__TS__ClassExtends
|
||||
local __TS__Decorate = ____lualib.__TS__Decorate
|
||||
local ____exports = {}
|
||||
local ____dota_ts_adapter = require("lib.dota_ts_adapter")
|
||||
local BaseModifier = ____dota_ts_adapter.BaseModifier
|
||||
local registerModifier = ____dota_ts_adapter.registerModifier
|
||||
____exports.modifier_arsenal_necklace_amber_pendant = __TS__Class()
|
||||
local modifier_arsenal_necklace_amber_pendant = ____exports.modifier_arsenal_necklace_amber_pendant
|
||||
modifier_arsenal_necklace_amber_pendant.name = "modifier_arsenal_necklace_amber_pendant"
|
||||
modifier_arsenal_necklace_amber_pendant.____file_path = "scripts/vscripts/arsenal/items/necklace.lua"
|
||||
__TS__ClassExtends(modifier_arsenal_necklace_amber_pendant, BaseModifier)
|
||||
function modifier_arsenal_necklace_amber_pendant.prototype.IsHidden(self)
|
||||
return false
|
||||
end
|
||||
function modifier_arsenal_necklace_amber_pendant.prototype.IsPurgable(self)
|
||||
return false
|
||||
end
|
||||
function modifier_arsenal_necklace_amber_pendant.prototype.RemoveOnDeath(self)
|
||||
return false
|
||||
end
|
||||
function modifier_arsenal_necklace_amber_pendant.prototype.GetTexture(self)
|
||||
return "item_pendant"
|
||||
end
|
||||
function modifier_arsenal_necklace_amber_pendant.prototype.DeclareFunctions(self)
|
||||
return {MODIFIER_PROPERTY_MAGICAL_RESISTANCE_BONUS}
|
||||
end
|
||||
function modifier_arsenal_necklace_amber_pendant.prototype.GetModifierMagicalResistanceBonus(self)
|
||||
return 8
|
||||
end
|
||||
modifier_arsenal_necklace_amber_pendant = __TS__Decorate(
|
||||
modifier_arsenal_necklace_amber_pendant,
|
||||
modifier_arsenal_necklace_amber_pendant,
|
||||
{registerModifier(nil)},
|
||||
{kind = "class", name = "modifier_arsenal_necklace_amber_pendant"}
|
||||
)
|
||||
____exports.modifier_arsenal_necklace_amber_pendant = modifier_arsenal_necklace_amber_pendant
|
||||
____exports.modifier_arsenal_necklace_soul_locket = __TS__Class()
|
||||
local modifier_arsenal_necklace_soul_locket = ____exports.modifier_arsenal_necklace_soul_locket
|
||||
modifier_arsenal_necklace_soul_locket.name = "modifier_arsenal_necklace_soul_locket"
|
||||
modifier_arsenal_necklace_soul_locket.____file_path = "scripts/vscripts/arsenal/items/necklace.lua"
|
||||
__TS__ClassExtends(modifier_arsenal_necklace_soul_locket, BaseModifier)
|
||||
function modifier_arsenal_necklace_soul_locket.prototype.IsHidden(self)
|
||||
return false
|
||||
end
|
||||
function modifier_arsenal_necklace_soul_locket.prototype.IsPurgable(self)
|
||||
return false
|
||||
end
|
||||
function modifier_arsenal_necklace_soul_locket.prototype.RemoveOnDeath(self)
|
||||
return false
|
||||
end
|
||||
function modifier_arsenal_necklace_soul_locket.prototype.GetTexture(self)
|
||||
return "item_pipe"
|
||||
end
|
||||
function modifier_arsenal_necklace_soul_locket.prototype.DeclareFunctions(self)
|
||||
return {MODIFIER_PROPERTY_MAGICAL_RESISTANCE_BONUS, MODIFIER_PROPERTY_SPELL_AMPLIFY_PERCENTAGE, MODIFIER_PROPERTY_HEALTH_BONUS}
|
||||
end
|
||||
function modifier_arsenal_necklace_soul_locket.prototype.GetModifierMagicalResistanceBonus(self)
|
||||
return 18
|
||||
end
|
||||
function modifier_arsenal_necklace_soul_locket.prototype.GetModifierSpellAmplify_Percentage(self)
|
||||
return 12
|
||||
end
|
||||
function modifier_arsenal_necklace_soul_locket.prototype.GetModifierHealthBonus(self)
|
||||
return 200
|
||||
end
|
||||
modifier_arsenal_necklace_soul_locket = __TS__Decorate(
|
||||
modifier_arsenal_necklace_soul_locket,
|
||||
modifier_arsenal_necklace_soul_locket,
|
||||
{registerModifier(nil)},
|
||||
{kind = "class", name = "modifier_arsenal_necklace_soul_locket"}
|
||||
)
|
||||
____exports.modifier_arsenal_necklace_soul_locket = modifier_arsenal_necklace_soul_locket
|
||||
return ____exports
|
||||
@@ -0,0 +1,81 @@
|
||||
local ____lualib = require("lualib_bundle")
|
||||
local __TS__Class = ____lualib.__TS__Class
|
||||
local __TS__ClassExtends = ____lualib.__TS__ClassExtends
|
||||
local __TS__Decorate = ____lualib.__TS__Decorate
|
||||
local ____exports = {}
|
||||
local ____dota_ts_adapter = require("lib.dota_ts_adapter")
|
||||
local BaseModifier = ____dota_ts_adapter.BaseModifier
|
||||
local registerModifier = ____dota_ts_adapter.registerModifier
|
||||
____exports.modifier_arsenal_ring_copper_band = __TS__Class()
|
||||
local modifier_arsenal_ring_copper_band = ____exports.modifier_arsenal_ring_copper_band
|
||||
modifier_arsenal_ring_copper_band.name = "modifier_arsenal_ring_copper_band"
|
||||
modifier_arsenal_ring_copper_band.____file_path = "scripts/vscripts/arsenal/items/ring.lua"
|
||||
__TS__ClassExtends(modifier_arsenal_ring_copper_band, BaseModifier)
|
||||
function modifier_arsenal_ring_copper_band.prototype.IsHidden(self)
|
||||
return false
|
||||
end
|
||||
function modifier_arsenal_ring_copper_band.prototype.IsPurgable(self)
|
||||
return false
|
||||
end
|
||||
function modifier_arsenal_ring_copper_band.prototype.RemoveOnDeath(self)
|
||||
return false
|
||||
end
|
||||
function modifier_arsenal_ring_copper_band.prototype.GetTexture(self)
|
||||
return "item_ring_of_basilius"
|
||||
end
|
||||
function modifier_arsenal_ring_copper_band.prototype.DeclareFunctions(self)
|
||||
return {MODIFIER_PROPERTY_MANA_REGEN_CONSTANT, MODIFIER_PROPERTY_MANA_BONUS}
|
||||
end
|
||||
function modifier_arsenal_ring_copper_band.prototype.GetModifierConstantManaRegen(self)
|
||||
return 1
|
||||
end
|
||||
function modifier_arsenal_ring_copper_band.prototype.GetModifierManaBonus(self)
|
||||
return 100
|
||||
end
|
||||
modifier_arsenal_ring_copper_band = __TS__Decorate(
|
||||
modifier_arsenal_ring_copper_band,
|
||||
modifier_arsenal_ring_copper_band,
|
||||
{registerModifier(nil)},
|
||||
{kind = "class", name = "modifier_arsenal_ring_copper_band"}
|
||||
)
|
||||
____exports.modifier_arsenal_ring_copper_band = modifier_arsenal_ring_copper_band
|
||||
____exports.modifier_arsenal_ring_void_signet = __TS__Class()
|
||||
local modifier_arsenal_ring_void_signet = ____exports.modifier_arsenal_ring_void_signet
|
||||
modifier_arsenal_ring_void_signet.name = "modifier_arsenal_ring_void_signet"
|
||||
modifier_arsenal_ring_void_signet.____file_path = "scripts/vscripts/arsenal/items/ring.lua"
|
||||
__TS__ClassExtends(modifier_arsenal_ring_void_signet, BaseModifier)
|
||||
function modifier_arsenal_ring_void_signet.prototype.IsHidden(self)
|
||||
return false
|
||||
end
|
||||
function modifier_arsenal_ring_void_signet.prototype.IsPurgable(self)
|
||||
return false
|
||||
end
|
||||
function modifier_arsenal_ring_void_signet.prototype.RemoveOnDeath(self)
|
||||
return false
|
||||
end
|
||||
function modifier_arsenal_ring_void_signet.prototype.GetTexture(self)
|
||||
return "item_void_stone"
|
||||
end
|
||||
function modifier_arsenal_ring_void_signet.prototype.DeclareFunctions(self)
|
||||
return {MODIFIER_PROPERTY_STATS_INTELLECT_BONUS, MODIFIER_PROPERTY_STATS_STRENGTH_BONUS, MODIFIER_PROPERTY_STATS_AGILITY_BONUS, MODIFIER_PROPERTY_SPELL_AMPLIFY_PERCENTAGE}
|
||||
end
|
||||
function modifier_arsenal_ring_void_signet.prototype.GetModifierBonusStats_Intellect(self)
|
||||
return 18
|
||||
end
|
||||
function modifier_arsenal_ring_void_signet.prototype.GetModifierBonusStats_Strength(self)
|
||||
return 18
|
||||
end
|
||||
function modifier_arsenal_ring_void_signet.prototype.GetModifierBonusStats_Agility(self)
|
||||
return 18
|
||||
end
|
||||
function modifier_arsenal_ring_void_signet.prototype.GetModifierSpellAmplify_Percentage(self)
|
||||
return 8
|
||||
end
|
||||
modifier_arsenal_ring_void_signet = __TS__Decorate(
|
||||
modifier_arsenal_ring_void_signet,
|
||||
modifier_arsenal_ring_void_signet,
|
||||
{registerModifier(nil)},
|
||||
{kind = "class", name = "modifier_arsenal_ring_void_signet"}
|
||||
)
|
||||
____exports.modifier_arsenal_ring_void_signet = modifier_arsenal_ring_void_signet
|
||||
return ____exports
|
||||
@@ -0,0 +1,72 @@
|
||||
local ____lualib = require("lualib_bundle")
|
||||
local __TS__Class = ____lualib.__TS__Class
|
||||
local __TS__ClassExtends = ____lualib.__TS__ClassExtends
|
||||
local __TS__Decorate = ____lualib.__TS__Decorate
|
||||
local ____exports = {}
|
||||
local ____dota_ts_adapter = require("lib.dota_ts_adapter")
|
||||
local BaseModifier = ____dota_ts_adapter.BaseModifier
|
||||
local registerModifier = ____dota_ts_adapter.registerModifier
|
||||
____exports.modifier_arsenal_weapon_iron_blade = __TS__Class()
|
||||
local modifier_arsenal_weapon_iron_blade = ____exports.modifier_arsenal_weapon_iron_blade
|
||||
modifier_arsenal_weapon_iron_blade.name = "modifier_arsenal_weapon_iron_blade"
|
||||
modifier_arsenal_weapon_iron_blade.____file_path = "scripts/vscripts/arsenal/items/weapon.lua"
|
||||
__TS__ClassExtends(modifier_arsenal_weapon_iron_blade, BaseModifier)
|
||||
function modifier_arsenal_weapon_iron_blade.prototype.IsHidden(self)
|
||||
return false
|
||||
end
|
||||
function modifier_arsenal_weapon_iron_blade.prototype.IsPurgable(self)
|
||||
return false
|
||||
end
|
||||
function modifier_arsenal_weapon_iron_blade.prototype.RemoveOnDeath(self)
|
||||
return false
|
||||
end
|
||||
function modifier_arsenal_weapon_iron_blade.prototype.GetTexture(self)
|
||||
return "item_blade_of_alacrity"
|
||||
end
|
||||
function modifier_arsenal_weapon_iron_blade.prototype.DeclareFunctions(self)
|
||||
return {MODIFIER_PROPERTY_PREATTACK_BONUS_DAMAGE}
|
||||
end
|
||||
function modifier_arsenal_weapon_iron_blade.prototype.GetModifierPreAttack_BonusDamage(self)
|
||||
return 8
|
||||
end
|
||||
modifier_arsenal_weapon_iron_blade = __TS__Decorate(
|
||||
modifier_arsenal_weapon_iron_blade,
|
||||
modifier_arsenal_weapon_iron_blade,
|
||||
{registerModifier(nil)},
|
||||
{kind = "class", name = "modifier_arsenal_weapon_iron_blade"}
|
||||
)
|
||||
____exports.modifier_arsenal_weapon_iron_blade = modifier_arsenal_weapon_iron_blade
|
||||
____exports.modifier_arsenal_weapon_storm_edge = __TS__Class()
|
||||
local modifier_arsenal_weapon_storm_edge = ____exports.modifier_arsenal_weapon_storm_edge
|
||||
modifier_arsenal_weapon_storm_edge.name = "modifier_arsenal_weapon_storm_edge"
|
||||
modifier_arsenal_weapon_storm_edge.____file_path = "scripts/vscripts/arsenal/items/weapon.lua"
|
||||
__TS__ClassExtends(modifier_arsenal_weapon_storm_edge, BaseModifier)
|
||||
function modifier_arsenal_weapon_storm_edge.prototype.IsHidden(self)
|
||||
return false
|
||||
end
|
||||
function modifier_arsenal_weapon_storm_edge.prototype.IsPurgable(self)
|
||||
return false
|
||||
end
|
||||
function modifier_arsenal_weapon_storm_edge.prototype.RemoveOnDeath(self)
|
||||
return false
|
||||
end
|
||||
function modifier_arsenal_weapon_storm_edge.prototype.GetTexture(self)
|
||||
return "item_maelstrom"
|
||||
end
|
||||
function modifier_arsenal_weapon_storm_edge.prototype.DeclareFunctions(self)
|
||||
return {MODIFIER_PROPERTY_PREATTACK_BONUS_DAMAGE, MODIFIER_PROPERTY_ATTACKSPEED_BONUS_CONSTANT}
|
||||
end
|
||||
function modifier_arsenal_weapon_storm_edge.prototype.GetModifierPreAttack_BonusDamage(self)
|
||||
return 18
|
||||
end
|
||||
function modifier_arsenal_weapon_storm_edge.prototype.GetModifierAttackSpeedBonus_Constant(self)
|
||||
return 30
|
||||
end
|
||||
modifier_arsenal_weapon_storm_edge = __TS__Decorate(
|
||||
modifier_arsenal_weapon_storm_edge,
|
||||
modifier_arsenal_weapon_storm_edge,
|
||||
{registerModifier(nil)},
|
||||
{kind = "class", name = "modifier_arsenal_weapon_storm_edge"}
|
||||
)
|
||||
____exports.modifier_arsenal_weapon_storm_edge = modifier_arsenal_weapon_storm_edge
|
||||
return ____exports
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user