-- ======================================== -- ИВЕНТ БИТВА НЕБЕСНЫХ ИЗБРАННИКОВ - ФУНКЦИИ -- ======================================== -- TianXuanZhe_Function.lua -- Вспомогательные функции для системы TianXuan -- Управление объектами игроков, сторон, битв и областей -- -- Функциональность: -- - Создание объектов игроков, сторон, битв и областей -- - Управление логикой активности -- - Распределение игроков по сторонам -- - Выбор небесных избранников -- - Начисление очков и опыта -- -- Автор: Система -- Версия: 2.0 -- ======================================== -- ======================================== -- КОНСТАНТЫ ФУНКЦИЙ -- ======================================== -- Константы для функций TianXuan local TIANXUAN_FUNCTION_CONSTANTS = { -- Максимальное количество игроков для создания битв MAX_PLAYERS_FOR_MULTIPLE_BATTLES = 159, PLAYERS_PER_BATTLE = 80, MIN_PLAYERS_PER_SIDE = 5, -- Баффы для областей AREA_BUFF_1 = 6109301, -- Бафф для существа 5610077 AREA_BUFF_2 = 6109101, -- Бафф для существа 5610078 AREA_BUFF_3 = 6109201, -- Бафф для существа 5610079 -- Существа в областях CREATURE_TYPE_1 = 5610077, CREATURE_TYPE_2 = 5610078, CREATURE_TYPE_3 = 5610079, -- Баффы системы CHOSEN_BUFF = 6109501, -- Бафф небесного избранника IMMORTAL_BUFF = 6109401, -- Бафф неуязвимости ATTRIBUTE_BUFF_BASE = 6107001, -- Базовый ID атрибутного баффа -- Цвета игроков COLOR_RED = 10, -- Красный цвет COLOR_BLUE = 11, -- Синий цвет -- Статусы STATUS_DEAD = 1, -- Игрок мертв STATUS_ALIVE = 0, -- Игрок жив STATUS_IN_GAME = "InSide", -- Игрок в игре STATUS_OUT_GAME = "OutSide" -- Игрок вышел из игры } -- ======================================== -- СОЗДАНИЕ ОБЪЕКТОВ -- ======================================== -- Создание объекта игрока для активности TianXuan -- Проверяет уровень и создает объект с необходимыми методами function CreatTianXuanRoleObj(RoleID) -- Проверяем входные параметры if RoleID == nil then return end -- Проверяем, не существует ли уже объект игрока if TianXuan_Role[RoleID] ~= nil then return end -- Получаем данные игрока local Target_MapID, Target_InstanceID = role.GetRoleMapID(RoleID) if Target_MapID == nil or Target_InstanceID == nil then return end local rolelevel = role.GetRoleLevel(Target_MapID, Target_InstanceID, RoleID) if rolelevel == nil then return end -- Проверка минимального уровня (50) if rolelevel >= 50 then -- Увеличиваем счетчик игроков if TianXuan_Roletotal == nil then TianXuan_Roletotal = 0 end TianXuan_Roletotal = TianXuan_Roletotal + 1 -- Создание объекта игрока с базовыми параметрами TianXuan_Role[RoleID] = { RoleID = RoleID, Time = 0, Side = "None", InstanceID = 0, State = TIANXUAN_FUNCTION_CONSTANTS.STATUS_OUT_GAME, Kill = 0 } -- Получение данных гильдии и семьи с проверками local Guild = guild.GetRoleGuildID(RoleID) local FamilyID = role.GetRoleFamilyID(Target_MapID, Target_InstanceID, RoleID) -- Проверяем и устанавливаем ID гильдии и семьи TianXuan_Role[RoleID].Guild = (Guild ~= nil and Guild ~= 4294967295) and Guild or 0 TianXuan_Role[RoleID].FamilyID = (FamilyID ~= nil and FamilyID ~= 4294967295) and FamilyID or 0 -- Привязка методов к объекту игрока TianXuan_Role[RoleID].ShowTianXuanTime = ShowTianXuanTime TianXuan_Role[RoleID].GetAttBuff_TianXuan = GetAttBuff_TianXuan TianXuan_Role[RoleID].WuDi_TianXuan = WuDi_TianXuan TianXuan_Role[RoleID].SetColor_TianXuan = SetColor_TianXuan TianXuan_Role[RoleID].SendInfo_TianXuan = SendInfo_TianXuan TianXuan_Role[RoleID].PlayerLeaveTianXuan = PlayerLeaveTianXuan TianXuan_Role[RoleID].PlayerEnterTianXuan = PlayerEnterTianXuan TianXuan_Role[RoleID].GetKillExp_TianXuan = GetKillExp_TianXuan end end -- Создание объекта стороны для активности TianXuan -- Создает объект стороны с начальным состоянием function CreatTianXuanSideObj() -- Проверяем существование массива сторон if TianXuan_Side == nil then TianXuan_Side = {} end local k = #TianXuan_Side + 1 TianXuan_Side[k] = { Player = {}, -- Список игроков в стороне InSidePlayer = {}, -- Список игроков внутри области Num = 0, -- Количество игроков Point = 0, -- Очки стороны Side = k % 2 == 1 and "Red" or "Blue", -- Определение стороны (красная/синяя) PlayerJoinTianXuanSide = PlayerJoinTianXuanSide -- Метод добавления игрока } return TianXuan_Side[k] end -- Добавление игрока в сторону TianXuan -- Добавляет игрока в список стороны и устанавливает его принадлежность function PlayerJoinTianXuanSide(Obj, PlayerID) -- Проверяем входные параметры if Obj == nil or PlayerID == nil then return end -- Проверяем существование массивов if Obj.Player == nil then Obj.Player = {} end -- Проверяем, не состоит ли игрок уже в стороне if TianXuan_Role[PlayerID] ~= nil then table.insert(Obj.Player, PlayerID) TianXuan_Role[PlayerID].Side = Obj.Side end end -- Создание объекта области для активности TianXuan -- Создает 9 областей с существами, дающими баффы function CreatTianXuanAreaObj(InstanceID) -- Проверяем входные параметры if InstanceID == nil then return nil end -- Проверяем существование массива областей if TianXuan_Area == nil then TianXuan_Area = {} end local k = #TianXuan_Area + 1 TianXuan_Area[k] = {area = {}, InstanceID = InstanceID} -- Таблица соответствия ID существ и баффов local buff = { [TIANXUAN_FUNCTION_CONSTANTS.CREATURE_TYPE_1] = TIANXUAN_FUNCTION_CONSTANTS.AREA_BUFF_1, [TIANXUAN_FUNCTION_CONSTANTS.CREATURE_TYPE_2] = TIANXUAN_FUNCTION_CONSTANTS.AREA_BUFF_2, [TIANXUAN_FUNCTION_CONSTANTS.CREATURE_TYPE_3] = TIANXUAN_FUNCTION_CONSTANTS.AREA_BUFF_3 } -- Создание существ в 9 областях for i = 1, 9 do -- Проверяем существование необходимых данных if S59_MapID ~= nil and S59_ItemPoint ~= nil and S59_Area ~= nil and S59_ItemPoint[S59_Area[i]] ~= nil then local id = 5610076 + math.random(3) -- Случайный ID существа local cre = map.MapCreateCreature(S59_MapID, InstanceID, id, S59_ItemPoint[S59_Area[i]].x, S59_ItemPoint[S59_Area[i]].y, S59_ItemPoint[S59_Area[i]].z) TianXuan_Area[k].area[S59_Area[i]] = { CreID = cre, -- ID созданного существа TypeID = id, -- Тип существа BuffID = buff[id] -- ID баффа } end end -- Привязка методов к объекту области TianXuan_Area[k].ReSetTianXuanArea = ReSetTianXuanArea TianXuan_Area[k].IntoTianXuanArea = IntoTianXuanArea return TianXuan_Area[k] end -- Создание объекта битвы для активности TianXuan -- Создает инстанс карты и настраивает стороны function CreatTianXuanBattleObj(RedPlayer, BluePlayer) -- Проверяем входные параметры if RedPlayer == nil or BluePlayer == nil then return end -- Проверяем существование массива битв if TianXuan_Battle == nil then TianXuan_Battle = {} end -- Проверяем существование карты if S59_MapID == nil then return end local k = #TianXuan_Battle + 1 map.CreateInstance(S59_MapID, k) -- Создание инстанса карты -- Создание объекта битвы TianXuan_Battle[k] = { RedPlayer = RedPlayer, -- Красная сторона BluePlayer = BluePlayer, -- Синяя сторона InstanceID = k -- ID инстанса } -- Установка ID инстанса для всех игроков красной стороны if RedPlayer.Player ~= nil then for k1, v in pairs(RedPlayer.Player) do if TianXuan_Role[v] ~= nil then TianXuan_Role[v].InstanceID = k end end end -- Установка ID инстанса для всех игроков синей стороны if BluePlayer.Player ~= nil then for k1, v in pairs(BluePlayer.Player) do if TianXuan_Role[v] ~= nil then TianXuan_Role[v].InstanceID = k end end end -- Создание области для битвы TianXuan_Battle[k].Area = CreatTianXuanAreaObj(k) -- Привязка методов к объекту битвы TianXuan_Battle[k].GetTianXuanAreaObjFromBattle = GetTianXuanAreaObjFromBattle TianXuan_Battle[k].SendAllInfo_TianXuan = SendAllInfo_TianXuan TianXuan_Battle[k].ChooseTianXuanZhiRen = ChooseTianXuanZhiRen TianXuan_Battle[k].SetPlayerPoint_TianXuan = SetPlayerPoint_TianXuan TianXuan_Battle[k].SetPlayerFinalPoint_TianXuan = SetPlayerFinalPoint_TianXuan TianXuan_Battle[k].ResetInSidePlayer_TianXuan = ResetInSidePlayer_TianXuan end -- Сброс области TianXuan (воссоздание существ) -- Восстанавливает существ в областях, где их нет function ReSetTianXuanArea(AreaObj) -- Проверяем входные параметры if AreaObj == nil or AreaObj.area == nil then return end -- Таблица соответствия ID существ и баффов local buff = { [TIANXUAN_FUNCTION_CONSTANTS.CREATURE_TYPE_1] = TIANXUAN_FUNCTION_CONSTANTS.AREA_BUFF_1, [TIANXUAN_FUNCTION_CONSTANTS.CREATURE_TYPE_2] = TIANXUAN_FUNCTION_CONSTANTS.AREA_BUFF_2, [TIANXUAN_FUNCTION_CONSTANTS.CREATURE_TYPE_3] = TIANXUAN_FUNCTION_CONSTANTS.AREA_BUFF_3 } -- Проверка и воссоздание существ в каждой области for i = 1, 9 do -- Проверяем существование данных области if AreaObj.area[S59_Area[i]] ~= nil and AreaObj.area[S59_Area[i]].CreID == 0 then -- Проверяем существование необходимых данных if S59_MapID ~= nil and S59_ItemPoint ~= nil and S59_ItemPoint[S59_Area[i]] ~= nil then local id = 5610076 + math.random(3) -- Случайный ID существа local cre = map.MapCreateCreature(S59_MapID, AreaObj.InstanceID, id, S59_ItemPoint[S59_Area[i]].x, S59_ItemPoint[S59_Area[i]].y, S59_ItemPoint[S59_Area[i]].z) -- Обновляем данные области AreaObj.area[S59_Area[i]].CreID = cre AreaObj.area[S59_Area[i]].TypeID = id AreaObj.area[S59_Area[i]].BuffID = buff[id] end end end end -- Вход в область TianXuan (получение баффа) -- Игрок получает бафф и существо исчезает function IntoTianXuanArea(AreaObj, AreaID, RoleID) -- Проверяем входные параметры if AreaObj == nil or AreaObj.area == nil or AreaObj.area[AreaID] == nil or RoleID == nil then return end -- Проверяем, есть ли существо в области if AreaObj.area[AreaID].CreID ~= 0 then -- Проверяем существование карты if S59_MapID ~= nil then -- Добавление баффа игроку unit.AddBuff(S59_MapID, AreaObj.InstanceID, RoleID, AreaObj.area[AreaID].BuffID, RoleID) -- Удаление существа map.MapDeleteCreature(S59_MapID, AreaObj.InstanceID, AreaObj.area[AreaID].CreID) -- Сброс данных области AreaObj.area[AreaID].CreID = 0 AreaObj.area[AreaID].TypeID = 0 AreaObj.area[AreaID].BuffID = 0 end end end -- Получение объекта игрока TianXuan -- Возвращает объект игрока или nil, если игрок не найден function GetTianXuanRoleObj(RoleID) -- Проверяем входные параметры if RoleID == nil then return nil end -- Проверяем существование массива игроков if TianXuan_Role == nil then return nil end return TianXuan_Role[RoleID] end -- Выбор сторон для активности TianXuan -- Распределяет игроков по сторонам с учетом гильдий и семей function TianXuan_ChooseSide() -- Проверяем количество игроков if TianXuan_Roletotal == nil or TianXuan_Roletotal <= 0 then return end -- Проверяем существование массива ролей if TianXuan_Role == nil then return end if TianXuan_Roletotal > TIANXUAN_FUNCTION_CONSTANTS.MAX_PLAYERS_FOR_MULTIPLE_BATTLES then -- Для большого количества игроков - создание нескольких битв local k = math.floor(TianXuan_Roletotal / 80) -- Количество битв local av_player = math.floor(TianXuan_Roletotal / k) -- Среднее количество игроков на битву local num = {} -- Распределение игроков по битвам for i = 1, k do num[i] = i ~= k and av_player or TianXuan_Roletotal - av_player * (k - 1) end local Player = {} local Playertotal = 0 -- Функция определения индекса битвы для игрока local function GetIndex(Playertotal) local total = 0 for i = 1, k do total = total + num[i] if total >= Playertotal then return i end end end -- Распределение игроков по битвам for k1, v in pairs(TianXuan_Role) do Playertotal = Playertotal + 1 local index = GetIndex(Playertotal) if Player[index] == nil then Player[index] = {} end table.insert(Player[index], k1) end -- Создание битв для каждой группы игроков for i = 1, k do local RedSideObj = CreatTianXuanSideObj() local BlueSideObj = CreatTianXuanSideObj() local red = 0 local times = 0 -- Распределение игроков по сторонам с учетом гильдий и семей while red < num[i] / 2 and #Player[i] > 0 do RedSideObj:PlayerJoinTianXuanSide(Player[i][1]) local Player1Obj = GetTianXuanRoleObj(Player[i][1]) red = red + 1 -- Добавление игроков из той же гильдии/семьи for k1 = #Player[i], 1, -1 do local v = Player[i][k1] local PlayerObj = GetTianXuanRoleObj(v) if PlayerObj ~= nil and Player1Obj ~= nil and v ~= Player[i][1] and ((PlayerObj.Guild ~= 0 and PlayerObj.Guild == Player1Obj.Guild) or (PlayerObj.FamilyID ~= 0 and PlayerObj.FamilyID == Player1Obj.FamilyID)) then RedSideObj:PlayerJoinTianXuanSide(v) red = red + 1 table.remove(Player[i], k1) if red >= num[i] / 2 then break end end end table.remove(Player[i], 1) times = times + 1 if times > 160 then break end end -- Оставшиеся игроки идут в синюю сторону for k1, v in pairs(Player[i]) do BlueSideObj:PlayerJoinTianXuanSide(v) end CreatTianXuanBattleObj(RedSideObj, BlueSideObj) end else -- Для небольшого количества игроков - одна битва local Player = {} for k, v in pairs(TianXuan_Role) do table.insert(Player, k) end local RedSideObj = CreatTianXuanSideObj() local BlueSideObj = CreatTianXuanSideObj() local red = 0 local times = 0 -- Распределение игроков по сторонам while red < TianXuan_Roletotal / 2 and #Player > 0 do RedSideObj:PlayerJoinTianXuanSide(Player[1]) local Player1Obj = GetTianXuanRoleObj(Player[1]) red = red + 1 -- Добавление игроков из той же гильдии/семьи for k1 = #Player, 1, -1 do local v = Player[k1] local PlayerObj = GetTianXuanRoleObj(v) if PlayerObj ~= nil and Player1Obj ~= nil and v ~= Player[1] and ((PlayerObj.Guild ~= 0 and PlayerObj.Guild == Player1Obj.Guild) or (PlayerObj.FamilyID ~= 0 and PlayerObj.FamilyID == Player1Obj.FamilyID)) then RedSideObj:PlayerJoinTianXuanSide(v) red = red + 1 table.remove(Player, k1) if red >= TianXuan_Roletotal / 2 then break end end end table.remove(Player, 1) times = times + 1 if times > 160 then break end end -- Оставшиеся игроки идут в синюю сторону for k1, v in pairs(Player) do BlueSideObj:PlayerJoinTianXuanSide(v) end CreatTianXuanBattleObj(RedSideObj, BlueSideObj) end end -- Показ оставшегося времени активности function ShowTianXuanTime(RoleObj) local leftSec = 3600 -- 1 час в секундах local Min = tonumber(os.date("%M")) local Second = tonumber(os.date("%S")) leftSec = leftSec - Min * 60 - Second -- Отправка сообщения с оставшимся временем local MsgID = msg.BeginMsgEvent() msg.AddMsgEvent(MsgID, 16, 28) msg.AddMsgEvent(MsgID, 16, leftSec) msg.DispatchRoleMsgEvent(RoleObj.RoleID, MsgID) end -- Получение атрибутного баффа для активности TianXuan function GetAttBuff_TianXuan(RoleObj) local rolelevel = role.GetRoleLevel(S59_MapID, RoleObj.InstanceID, RoleObj.RoleID) if rolelevel > 100 then rolelevel = 100 end -- Добавление баффа в зависимости от уровня if rolelevel >= 50 then local index = math.floor((rolelevel - 50) / 5) + 1 unit.AddBuff(S59_MapID, RoleObj.InstanceID, RoleObj.RoleID, index * 100 + 6107001, RoleObj.RoleID) end end -- Получение опыта за убийство в активности TianXuan function GetKillExp_TianXuan(RoleObj) local rolelevel = role.GetRoleLevel(S59_MapID, RoleObj.InstanceID, RoleObj.RoleID) if rolelevel < 50 then rolelevel = 50 elseif rolelevel > 100 then rolelevel = 100 end RoleObj.Kill = RoleObj.Kill + 1 local exp1 = math.floor(TianXuan_Exp[rolelevel] / 10) -- Ограничение опыта после 30 убийств if RoleObj.Kill > 30 then exp1 = 0 else role.AddRoleExp(S59_MapID, RoleObj.InstanceID, RoleObj.RoleID, exp1) end -- Отправка сообщения о полученном опыте local MsgID = msg.BeginMsgEvent() msg.AddMsgEvent(MsgID, 13, 0) msg.AddMsgEvent(MsgID, 1, 206731) msg.AddMsgEvent(MsgID, 9, RoleObj.Kill) msg.AddMsgEvent(MsgID, 9, exp1) msg.DispatchRoleMsgEvent(RoleObj.RoleID, MsgID) end -- Активация неуязвимости в TianXuan function WuDi_TianXuan(RoleObj) unit.AddBuff(S59_MapID, RoleObj.InstanceID, RoleObj.RoleID, 6109401, RoleObj.RoleID) end -- Установка цвета игрока в TianXuan function SetColor_TianXuan(RoleObj) if RoleObj.Side == "Red" then unit.SetState(S59_MapID, RoleObj.InstanceID, RoleObj.RoleID, 10) -- Красный цвет else unit.SetState(S59_MapID, RoleObj.InstanceID, RoleObj.RoleID, 11) -- Синий цвет end end -- Отправка информации о счете в TianXuan function SendInfo_TianXuan(RoleObj) local redpoint = TianXuan_Battle[RoleObj.InstanceID].RedPlayer.Point local rednum = TianXuan_Battle[RoleObj.InstanceID].RedPlayer.Num local bluepoint = TianXuan_Battle[RoleObj.InstanceID].BluePlayer.Point local bluenum = TianXuan_Battle[RoleObj.InstanceID].BluePlayer.Num local char = redpoint .. "," .. rednum .. "," .. bluepoint .. "," .. bluenum role.DotaSendMsg(S59_MapID, RoleObj.InstanceID, RoleObj.RoleID, 1, char) end -- Вход игрока в TianXuan function PlayerEnterTianXuan(RoleObj) RoleObj.State = "InSide" local tbl = {} -- Обновление счетчиков игроков в зависимости от стороны if RoleObj.Side == "Red" then TianXuan_Battle[RoleObj.InstanceID].RedPlayer.Num = TianXuan_Battle[RoleObj.InstanceID].RedPlayer.Num + 1 tbl = TianXuan_Battle[RoleObj.InstanceID].RedPlayer.InSidePlayer elseif RoleObj.Side == "Blue" then TianXuan_Battle[RoleObj.InstanceID].BluePlayer.Num = TianXuan_Battle[RoleObj.InstanceID].BluePlayer.Num + 1 tbl = TianXuan_Battle[RoleObj.InstanceID].BluePlayer.InSidePlayer end table.insert(tbl, RoleObj.RoleID) end -- Выход игрока из TianXuan function PlayerLeaveTianXuan(RoleObj) RoleObj.State = "OutSide" local tbl = {} -- Обновление счетчиков игроков в зависимости от стороны if RoleObj.Side == "Red" then TianXuan_Battle[RoleObj.InstanceID].RedPlayer.Num = TianXuan_Battle[RoleObj.InstanceID].RedPlayer.Num - 1 tbl = TianXuan_Battle[RoleObj.InstanceID].RedPlayer.InSidePlayer elseif RoleObj.Side == "Blue" then TianXuan_Battle[RoleObj.InstanceID].BluePlayer.Num = TianXuan_Battle[RoleObj.InstanceID].BluePlayer.Num - 1 tbl = TianXuan_Battle[RoleObj.InstanceID].BluePlayer.InSidePlayer end -- Удаление игрока из списка for k, v in pairs(tbl) do if v == RoleObj.RoleID then table.remove(tbl, k) end end end -- Отправка всей информации о счете в TianXuan function SendAllInfo_TianXuan(BattleObj) -- Отправка информации игрокам красной стороны for k, v in pairs(BattleObj.RedPlayer.Player) do local RoleObj = GetTianXuanRoleObj(v) local Target_MapID, Target_InstanceID = role.GetRoleMapID(RoleObj.RoleID) if Target_MapID ~= nil and Target_InstanceID ~= nil and Target_MapID == S59_MapID and RoleObj.InstanceID == Target_InstanceID then RoleObj:SendInfo_TianXuan() end end -- Отправка информации игрокам синей стороны for k, v in pairs(BattleObj.BluePlayer.Player) do local RoleObj = GetTianXuanRoleObj(v) local Target_MapID, Target_InstanceID = role.GetRoleMapID(RoleObj.RoleID) if Target_MapID ~= nil and Target_InstanceID ~= nil and Target_MapID == S59_MapID and RoleObj.InstanceID == Target_InstanceID then RoleObj:SendInfo_TianXuan() end end end -- Выбор ZhiRen (небесных избранников) в TianXuan function ChooseTianXuanZhiRen(BattleObj) local bluenum = 5 if BattleObj.BluePlayer.Num < bluenum then bluenum = BattleObj.BluePlayer.Num end -- Выбор избранников синей стороны for i = 1, bluenum do if BattleObj.BluePlayer.InSidePlayer[i] ~= nil then unit.AddBuff(S59_MapID, BattleObj.InstanceID, BattleObj.BluePlayer.InSidePlayer[i], 6109501, BattleObj.BluePlayer.InSidePlayer[i]) end end -- Дополнительные избранники если синяя сторона меньше красной if BattleObj.BluePlayer.Num < BattleObj.RedPlayer.Num then local k = math.floor((BattleObj.RedPlayer.Num - BattleObj.BluePlayer.Num) / 5) if k > 0 then local m = k + 5 if m > #BattleObj.BluePlayer.InSidePlayer then local tbl = {} for k, v in pairs(BattleObj.BluePlayer.InSidePlayer) do tbl[k] = v end for i = 1, m do local index = math.random(#tbl) unit.AddBuff(S59_MapID, BattleObj.InstanceID, tbl[index], 6109501, tbl[index]) table.remove(tbl, index) end else for k, v in pairs(BattleObj.BluePlayer.InSidePlayer) do unit.AddBuff(S59_MapID, BattleObj.InstanceID, v, 6109501, v) end end end end local rednum = 5 if BattleObj.RedPlayer.Num < rednum then rednum = BattleObj.RedPlayer.Num end -- Выбор избранников красной стороны for i = 1, rednum do if BattleObj.RedPlayer.InSidePlayer[i] ~= nil then unit.AddBuff(S59_MapID, BattleObj.InstanceID, BattleObj.RedPlayer.InSidePlayer[i], 6109501, BattleObj.RedPlayer.InSidePlayer[i]) end end -- Дополнительные избранники если красная сторона меньше синей if BattleObj.RedPlayer.Num < BattleObj.BluePlayer.Num then local k = math.floor((BattleObj.BluePlayer.Num - BattleObj.RedPlayer.Num) / 5) if k > 0 then local m = k + 5 if m > #BattleObj.RedPlayer.InSidePlayer then local tbl = {} for k, v in pairs(BattleObj.RedPlayer.InSidePlayer) do tbl[k] = v end for i = 1, m do local index = math.random(#tbl) unit.AddBuff(S59_MapID, BattleObj.InstanceID, tbl[index], 6109501, tbl[index]) table.remove(tbl, index) end else for k, v in pairs(BattleObj.RedPlayer.InSidePlayer) do unit.AddBuff(S59_MapID, BattleObj.InstanceID, v, 6109501, v) end end end end end -- Получение объекта области из битвы TianXuan function GetTianXuanAreaObjFromBattle(BattleObj) return BattleObj.Area end -- Установка очков игроков в TianXuan function SetPlayerPoint_TianXuan(BattleObj) local RedSideObj = BattleObj.RedPlayer local BlueSideObj = BattleObj.BluePlayer -- Начисление очков игрокам красной стороны for k, v in pairs(RedSideObj.Player) do local RoleObj = TianXuan_Role[v] if RoleObj.State == "InSide" then local Target_MapID, Target_InstanceID = role.GetRoleMapID(RoleObj.RoleID) if Target_MapID ~= nil then if not unit.IsDead(Target_MapID, Target_InstanceID, RoleObj.RoleID) then role.SetRoleScriptData(RoleObj.RoleID, 1, RoleDataType["Tianxuanzhe_Point"], role.GetRoleScriptData(RoleObj.RoleID, 1, RoleDataType["Tianxuanzhe_Point"]) + 1) end end end end -- Начисление очков игрокам синей стороны for k, v in pairs(BlueSideObj.Player) do local RoleObj = TianXuan_Role[v] if RoleObj.State == "InSide" then local Target_MapID, Target_InstanceID = role.GetRoleMapID(RoleObj.RoleID) if Target_MapID ~= nil then if not unit.IsDead(Target_MapID, Target_InstanceID, RoleObj.RoleID) then role.SetRoleScriptData(RoleObj.RoleID, 1, RoleDataType["Tianxuanzhe_Point"], role.GetRoleScriptData(RoleObj.RoleID, 1, RoleDataType["Tianxuanzhe_Point"]) + 1) end end end end end -- Установка финальных очков игроков в TianXuan function SetPlayerFinalPoint_TianXuan(BattleObj) local RedSideObj = BattleObj.RedPlayer local BlueSideObj = BattleObj.BluePlayer -- Удвоение очков для победившей красной стороны if RedSideObj.Point > BlueSideObj.Point then for k, v in pairs(RedSideObj.Player) do local RoleObj = TianXuan_Role[v] if RoleObj.State == "InSide" then local Target_MapID, Target_InstanceID = role.GetRoleMapID(RoleObj.RoleID) if Target_MapID ~= nil then if not unit.IsDead(Target_MapID, Target_InstanceID, RoleObj.RoleID) then role.SetRoleScriptData(RoleObj.RoleID, 1, RoleDataType["Tianxuanzhe_Point"], role.GetRoleScriptData(RoleObj.RoleID, 1, RoleDataType["Tianxuanzhe_Point"]) * 2) end end end end elseif RedSideObj.Point < BlueSideObj.Point then -- Удвоение очков для победившей синей стороны for k, v in pairs(BlueSideObj.Player) do local RoleObj = TianXuan_Role[v] if RoleObj.State == "InSide" then local Target_MapID, Target_InstanceID = role.GetRoleMapID(RoleObj.RoleID) if Target_MapID ~= nil then if not unit.IsDead(Target_MapID, Target_InstanceID, RoleObj.RoleID) then role.SetRoleScriptData(RoleObj.RoleID, 1, RoleDataType["Tianxuanzhe_Point"], role.GetRoleScriptData(RoleObj.RoleID, 1, RoleDataType["Tianxuanzhe_Point"]) * 2) end end end end end -- При ничьей (RedSideObj.Point == BlueSideObj.Point) никто не получает удвоение end -- Сброс игроков внутри области в TianXuan function ResetInSidePlayer_TianXuan(BattleObj) -- Функция перемешивания массива local function reset(tbl) local tbl_new = {} if #tbl > 0 then for i = 1, #tbl do local index = math.random(#tbl) table.insert(tbl_new, tbl[index]) table.remove(tbl, index) end end return tbl_new end -- Перемешивание списков игроков обеих сторон BattleObj.BluePlayer.InSidePlayer = reset(BattleObj.BluePlayer.InSidePlayer) BattleObj.RedPlayer.InSidePlayer = reset(BattleObj.RedPlayer.InSidePlayer) end -- ======================================== -- ИНФОРМАЦИЯ О СИСТЕМЕ ФУНКЦИЙ TIANXUAN -- ======================================== -- -- TianXuanZhe_Function.lua - Вспомогательные функции -- ======================================== -- -- ОСНОВНЫЕ КОМПОНЕНТЫ: -- -- 1. СОЗДАНИЕ ОБЪЕКТОВ: -- - CreatTianXuanRoleObj: Создание объекта игрока -- - CreatTianXuanSideObj: Создание объекта стороны -- - CreatTianXuanAreaObj: Создание объекта области -- - CreatTianXuanBattleObj: Создание объекта битвы -- -- 2. УПРАВЛЕНИЕ ОБЛАСТЯМИ: -- - ReSetTianXuanArea: Сброс областей (восстановление существ) -- - IntoTianXuanArea: Вход в область (получение баффа) -- -- 3. УПРАВЛЕНИЕ ИГРОКАМИ: -- - PlayerJoinTianXuanSide: Добавление игрока в сторону -- - GetTianXuanRoleObj: Получение объекта игрока -- - TianXuan_ChooseSide: Распределение игроков по сторонам -- -- КОНСТАНТЫ ФУНКЦИЙ: -- -- - MAX_PLAYERS_FOR_MULTIPLE_BATTLES: Максимум игроков для нескольких битв (159) -- - PLAYERS_PER_BATTLE: Игроков на битву (80) -- - MIN_PLAYERS_PER_SIDE: Минимум игроков в стороне (5) -- -- БАФФЫ СИСТЕМЫ: -- -- - CHOSEN_BUFF: Бафф небесного избранника (6109501) -- - IMMORTAL_BUFF: Бафф неуязвимости (6109401) -- - ATTRIBUTE_BUFF_BASE: Базовый атрибутный бафф (6107001) -- -- СУЩЕСТВА В ОБЛАСТЯХ: -- -- - CREATURE_TYPE_1: Существо тип 1 (5610077) -> Бафф 6109301 -- - CREATURE_TYPE_2: Существо тип 2 (5610078) -> Бафф 6109101 -- - CREATURE_TYPE_3: Существо тип 3 (5610079) -> Бафф 6109201 -- -- ЦВЕТА ИГРОКОВ: -- -- - COLOR_RED: Красный цвет (10) -- - COLOR_BLUE: Синий цвет (11) -- -- СТАТУСЫ: -- -- - STATUS_DEAD: Игрок мертв (1) -- - STATUS_ALIVE: Игрок жив (0) -- - STATUS_IN_GAME: Игрок в игре ("InSide") -- - STATUS_OUT_GAME: Игрок вышел из игры ("OutSide") -- -- АЛГОРИТМ РАСПРЕДЕЛЕНИЯ ИГРОКОВ: -- -- 1. Если игроков > 159: Создаются несколько битв -- 2. Игроки распределяются по битвам равномерно -- 3. В каждой битве игроки делятся на красную и синюю стороны -- 4. Приоритет отдается игрокам из одной гильдии/семьи -- -- НЕБЕСНЫЕ ИЗБРАННИКИ: -- -- - Выбираются каждые 2 минуты из активных игроков -- - Минимум 5 избранников с каждой стороны -- - Дополнительные избранники, если одна сторона меньше другой -- - Дают 10 очков за убийство вместо 1 -- -- СИСТЕМА ОПЫТА: -- -- - Опыт за убийство: TianXuan_Exp[уровень] / 10 -- - Ограничение: максимум 30 убийств дают опыт -- - Уровни опыта от 50 до 100 -- -- ПРОВЕРКИ БЕЗОПАСНОСТИ: -- -- - Все функции проверяют входные параметры на nil -- - Проверяется существование массивов и объектов -- - Проверяется существование необходимых данных карты -- - Безопасное создание существ и объектов -- -- ЗАМЕЧАНИЯ: -- -- - Функции работают как с TianXuan, так и с KuaFu PK режимами -- - Все магические числа заменены на константы -- - Добавлены подробные комментарии и проверки безопасности -- - Система поддерживает динамическое создание битв