local ____lualib = require("lualib_bundle") local __TS__NumberIsFinite = ____lualib.__TS__NumberIsFinite local ____exports = {} require("lib.dota_ts_adapter") --- Удача только из NetTable (без бонуса арсенала) — для setLuck/addLuck. local function getLuckBaseFromTable(self, hero) if not hero or not IsValidEntity(hero) then return 0 end local playerId = hero:GetPlayerOwnerID() if playerId == nil or playerId == nil or playerId < 0 then return 0 end local key = "luck_" .. tostring(playerId) local data = CustomNetTables:GetTableValue("custom_stats", key) local ____data_0 if data then ____data_0 = data.value else ____data_0 = 0 end return ____data_0 end function ____exports.setLuck(self, hero, luck) if not IsServer() then return end local playerId = hero:GetPlayerOwnerID() if playerId == nil or playerId == nil or playerId < 0 then return end local key = "luck_" .. tostring(playerId) CustomNetTables:SetTableValue("custom_stats", key, {value = luck}) end function ____exports.addLuck(self, hero, delta) if not IsServer() then return end local current = getLuckBaseFromTable(nil, hero) ____exports.setLuck(nil, hero, current + delta) end function ____exports.reduceLuck(self, hero, delta) if not IsServer() then return end ____exports.addLuck( nil, hero, -math.abs(delta) ) end function ____exports.getLuck(self, hero) if not hero or not IsValidEntity(hero) then return 0 end local playerId = hero:GetPlayerOwnerID() if playerId == nil or playerId == nil or playerId < 0 then return 0 end return getLuckBaseFromTable(nil, hero) end --- По умолчанию удача не может поднять шанс выше этого множителя от базы (15% → макс. 30%). local DEFAULT_MAX_CHANCE_VS_BASE = 2 --- Рассчитывает шанс с учетом удачи героя и базового значения -- -- @param hero - герой для которого рассчитывается шанс -- @param baseValue - базовое значение шанса (0-1) -- @param luckMultiplier - аддитивный бонус за 1 удачу (в долях, по умолчанию 0.01 = +1 п.п.) -- @param maxChanceVsBaseMult - потолок: итог не выше baseValue * этого числа (по умолчанию 2). Для baseValue <= 0 потолок не применяется. -- @returns итоговый шанс (0-1) function ____exports.calculateLuckChance(self, hero, baseValue, luckMultiplier, maxChanceVsBaseMult) if luckMultiplier == nil then luckMultiplier = 0.01 end if maxChanceVsBaseMult == nil then maxChanceVsBaseMult = DEFAULT_MAX_CHANCE_VS_BASE end local luck = ____exports.getLuck(nil, hero) local finalChance = baseValue + luck * luckMultiplier if baseValue > 0 and __TS__NumberIsFinite(maxChanceVsBaseMult) and maxChanceVsBaseMult > 0 and maxChanceVsBaseMult < 1000000000 then local ceiling = baseValue * maxChanceVsBaseMult finalChance = math.min(finalChance, ceiling) end return math.max( 0, math.min(1, finalChance) ) end --- Проверяет, сработал ли шанс с учетом удачи -- -- @param hero - герой для которого проверяется шанс -- @param baseValue - базовое значение шанса (0-1) -- @param luckMultiplier - аддитивный бонус за 1 удачу (по умолчанию 0.01) -- @param maxChanceVsBaseMult - см. calculateLuckChance (по умолчанию ×2 от базы) -- @returns true если шанс сработал function ____exports.rollLuckChance(self, hero, baseValue, luckMultiplier, maxChanceVsBaseMult) if luckMultiplier == nil then luckMultiplier = 0.01 end if maxChanceVsBaseMult == nil then maxChanceVsBaseMult = DEFAULT_MAX_CHANCE_VS_BASE end local chance = ____exports.calculateLuckChance( nil, hero, baseValue, luckMultiplier, maxChanceVsBaseMult ) return math.random() < chance end local g = _G g.setLuck = ____exports.setLuck g.addLuck = ____exports.addLuck g.reduceLuck = ____exports.reduceLuck g.getLuck = ____exports.getLuck g.calculateLuckChance = ____exports.calculateLuckChance g.rollLuckChance = ____exports.rollLuckChance return ____exports