-- Кастомные наборы 6610998, 6610999, 6611000, 6611001. local function grant_items(MapID, InstanceID, TargetID, items) for _, row in ipairs(items) do role.AddRoleItem(MapID, InstanceID, TargetID, row[1], row[2], row[3], row[4], row[5]) end end --[[ Разделение по классу как в оф. сундуках и veshi.lua: левая линейка лёгкая броня (486): клинки 2/6/7, луки 3/8/9; тяжёлая (7704): сила 4/10/11, музыкант 5/12/13. ]] local ELITE_EXTRA_OPEN = { 1, 6, 8, 420 } local ELITE52 = { WEAPON = { 8018001, 8028001, 8038001, 8048001 }, LIGHT_ARMOR = { 8050901, 8060901, 8070901, 8080901, 8090901, 8101301, 8110901, 8110901, 8121901, 8130901 }, HEAVY_ARMOR = { 8051901, 8061901, 8071901, 8081901, 8091901, 8101302, 8111901, 8111901, 8122901, 8130902 }, } local ELITE67 = { WEAPON = { 8018002, 8028002, 8038002, 8048002 }, LIGHT_ARMOR = { 8050902, 8060902, 8070902, 8080902, 8090902, 8101303, 8110902, 8110902, 8121902, 8130903 }, HEAVY_ARMOR = { 8051902, 8061902, 8071902, 8081902, 8091902, 8101304, 8111902, 8111902, 8122902, 8130904 }, } local function elite_gear_weapon_family(class) if class == 2 or class == 6 or class == 7 then return 1 end if class == 3 or class == 8 or class == 9 then return 2 end if class == 5 or class == 12 or class == 13 then return 3 end if class == 4 or class == 10 or class == 11 then return 4 end return 1 end local function elite_gear_is_light_armor(class) return class == 2 or class == 6 or class == 7 or class == 3 or class == 8 or class == 9 end local ELITE_GEAR_WEAPONS_PER_BOX = 2 -- слоты сумки: два оружия + шлем, тело, ноги, перчаты, обувь, пояс, 2 кольца, медальон, перстень local ELITE_GEAR_SET_SLOT_COUNT = ELITE_GEAR_WEAPONS_PER_BOX + 10 local function grant_elite_equip_set(MapID, InstanceID, TargetID, def) local class = role.GetRoleClass(TargetID) local weaponId = def.WEAPON[elite_gear_weapon_family(class)] local armorList = elite_gear_is_light_armor(class) and def.LIGHT_ARMOR or def.HEAVY_ARMOR for _ = 1, ELITE_GEAR_WEAPONS_PER_BOX do role.AddRoleItem(MapID, InstanceID, TargetID, weaponId, ELITE_EXTRA_OPEN[1], ELITE_EXTRA_OPEN[2], ELITE_EXTRA_OPEN[3], ELITE_EXTRA_OPEN[4]) end for i = 1, #armorList do role.AddRoleItem(MapID, InstanceID, TargetID, armorList[i], ELITE_EXTRA_OPEN[1], ELITE_EXTRA_OPEN[2], ELITE_EXTRA_OPEN[3], ELITE_EXTRA_OPEN[4]) end end local ITEMS_6610998 = { { 3020071, 30, 6, 8, 420 }, -- Руна стража [+19] { 3020012, 30, 6, 8, 420 }, -- Руна удачи [+20] { 4530095, 10, 6, 8, 420 }, -- Сумка камней 4 ур { 4530102, 10, 6, 8, 420 }, -- Святые знаки 5 ур. [Ув. урона] { 4530105, 10, 6, 8, 420 }, -- Святые знаки 5 ур. [Ум. урона] { 3010034, 50, 6, 8, 420 }, -- Сильное зелье бодрости { 3070113, 1, 6, 8, 420 }, -- Руна битвы [30 дн] { 4300008, 1, 6, 8, 420 }, -- Премиум [7 дн] { 3070022, 20, 6, 8, 420 }, -- Эликсир эльфов { 3500207, 30, 6, 8, 420 }, -- Ядро души эльфа [100] { 4100611, 100, 6, 8, 420 }, -- Выпечка { 6610999, 5, 6, 8, 420 }, -- куклы } ---------------------------------------------------------------------- -- 6610999 «Куклы»: 10 случайных разных кукол, шансы по качеству (весами ниже). -- Границы совпадают с секциями item_name.xml: белый → розовый. ---------------------------------------------------------------------- local DOLL6610999_PICK_COUNT = 10 --[[ Относительные веса выпадения КАЧЕСТВА на один «слот» из 10 (чем выше — тем чаще). Пример: { 400, 200, 100, 50, 25 } — белые ~ в 16 раз чаще оранжевых при полном пуле. Если для всех непустых ярусов веса = 0, используется равный шанс между оставшимися ярусами. Вес 0: ярус не участвует в лотерее, пока есть другие ярусы с куклами; если остались только ярусы с весом 0 — берётся случайный ярус среди них. ]] local DOLL6610999_TIER_MAX = 7 local DOLL6610999_QUALITY_WEIGHT = { [1] = 200, -- белый 1360133–1360155, 1360356–1360432 [2] = 100, -- жёлтый 1360433–1360512 [3] = 50, -- зелёный 1360513–1360572 [4] = 30, -- синий 1360573–1360612 [5] = 20, -- оранж. 1360613–1360642 [6] = 6, -- фиол. 1360643–1360662 [7] = 1, -- розов. 1360663–1360677 } local function doll6610999_append_range(t, fromId, toId) for id = fromId, toId do t[#t + 1] = id end end local function doll6610999_build_template_by_quality() local q = { {}, {}, {}, {}, {}, {}, {} } doll6610999_append_range(q[1], 1360133, 1360155) doll6610999_append_range(q[1], 1360356, 1360432) doll6610999_append_range(q[2], 1360433, 1360512) doll6610999_append_range(q[3], 1360513, 1360572) doll6610999_append_range(q[4], 1360573, 1360612) doll6610999_append_range(q[5], 1360613, 1360642) doll6610999_append_range(q[6], 1360643, 1360662) doll6610999_append_range(q[7], 1360663, 1360677) return q end local DOLLS6610999_TEMPLATE = doll6610999_build_template_by_quality() local function doll6610999_total_in_template() local n = 0 for tier = 1, DOLL6610999_TIER_MAX do n = n + #DOLLS6610999_TEMPLATE[tier] end return n end local function doll6610999_clone_remaining() local rem = {} for tier = 1, DOLL6610999_TIER_MAX do local src = DOLLS6610999_TEMPLATE[tier] local dst = {} for i = 1, #src do dst[i] = src[i] end rem[tier] = dst end return rem end local function doll6610999_remove_random_from_tier(rem, tier) local t = rem[tier] local n = #t if n < 1 then return nil end local idx = math.random(1, n) local id = t[idx] t[idx] = t[n] t[n] = nil return id end local function doll6610999_pick_tier(rem, weights) local tw = 0 for tier = 1, DOLL6610999_TIER_MAX do local cnt = #(rem[tier]) if cnt > 0 then local w = weights[tier] if w == nil then w = 0 end if w < 0 then w = 0 end tw = tw + w end end if tw < 1 then local pool = {} for tier = 1, DOLL6610999_TIER_MAX do if #(rem[tier]) > 0 then pool[#pool + 1] = tier end end if #pool < 1 then return nil end return pool[math.random(1, #pool)] end local r = math.random(1, tw) local acc = 0 for tier = 1, DOLL6610999_TIER_MAX do if #(rem[tier]) > 0 then local w = weights[tier] if w == nil then w = 0 end if w < 0 then w = 0 end acc = acc + w if r <= acc then return tier end end end return nil end local function doll6610999_pick_weighted_unique_ids(count) count = math.min(count, doll6610999_total_in_template()) local rem = doll6610999_clone_remaining() local out = {} for i = 1, count do local tier = doll6610999_pick_tier(rem, DOLL6610999_QUALITY_WEIGHT) if tier == nil then break end local id = doll6610999_remove_random_from_tier(rem, tier) if id == nil then break end out[i] = id end return out end do function I6610998_CanUseGiftBag(MapID, InstanceID, TypeID, TargetID) local bRet, bIgnore = 0, false local need = #ITEMS_6610998 if need < 1 then bRet = 103 return bRet, bIgnore end if role.GetBagFreeSize(TargetID) < need then bRet = 40 end return bRet, bIgnore end function I6610998_GiftBag(MapID, InstanceID, TypeID, TargetID) grant_items(MapID, InstanceID, TargetID, ITEMS_6610998) return 1 end aux.RegisterItemEvent(6610998, 0, "I6610998_CanUseGiftBag") aux.RegisterItemEvent(6610998, 1, "I6610998_GiftBag") end do function I6610999_CanUseGiftBag(MapID, InstanceID, TypeID, TargetID) local bRet, bIgnore = 0, false local need = DOLL6610999_PICK_COUNT if doll6610999_total_in_template() < need then bRet = 103 return bRet, bIgnore end if role.GetBagFreeSize(TargetID) < need then bRet = 40 end return bRet, bIgnore end function I6610999_GiftBag(MapID, InstanceID, TypeID, TargetID) local ids = doll6610999_pick_weighted_unique_ids(DOLL6610999_PICK_COUNT) for _, typeId in ipairs(ids) do role.AddRoleItem(MapID, InstanceID, TargetID, typeId, 1, 6, 8, 420) end return 1 end aux.RegisterItemEvent(6610999, 0, "I6610999_CanUseGiftBag") aux.RegisterItemEvent(6610999, 1, "I6610999_GiftBag") end do function I6611000_CanUseGiftBag(MapID, InstanceID, TypeID, TargetID) local bRet, bIgnore = 0, false local class = role.GetRoleClass(TargetID) if class == 1 then bRet = 46 return bRet, bIgnore end if role.GetBagFreeSize(TargetID) < ELITE_GEAR_SET_SLOT_COUNT then bRet = 40 end return bRet, bIgnore end function I6611000_GiftBag(MapID, InstanceID, TypeID, TargetID) grant_elite_equip_set(MapID, InstanceID, TargetID, ELITE52) return 1 end aux.RegisterItemEvent(6611000, 0, "I6611000_CanUseGiftBag") aux.RegisterItemEvent(6611000, 1, "I6611000_GiftBag") end do function I6611001_CanUseGiftBag(MapID, InstanceID, TypeID, TargetID) local bRet, bIgnore = 0, false local class = role.GetRoleClass(TargetID) if class == 1 then bRet = 46 return bRet, bIgnore end if role.GetBagFreeSize(TargetID) < ELITE_GEAR_SET_SLOT_COUNT then bRet = 40 end return bRet, bIgnore end function I6611001_GiftBag(MapID, InstanceID, TypeID, TargetID) grant_elite_equip_set(MapID, InstanceID, TargetID, ELITE67) return 1 end aux.RegisterItemEvent(6611001, 0, "I6611001_CanUseGiftBag") aux.RegisterItemEvent(6611001, 1, "I6611001_GiftBag") end