-- Арена - основные переменные и функции системы арены -- Глобальные переменные системы арены -- Таблица активных арен по InstanceID Arena = {} -- Данные матчей: {Room, OpenTime, Battle, RedNum, BlueNum, Player[]} -- Счетчик номеров карт для циклического выбора ArenaMapNum = 0 -- Текущий номер карты (0-2 для выбора из 3 карт) -- Таблица данных игроков ArenaPlayer = {} -- Данные игроков: {Now, Info[]}, где Info содержит статистику матча -- Таблица таймеров существ ArenaCreature_Timer = {} -- Таймеры по ID существ: {TypeID} для управления временем --[[ Типы таймеров существ арены (ArenaCreature_Timer[creatureID].TypeID): 1 - 1-минутный таймер инициализации арены 2 - 10-минутный таймер начала боя (предупреждение за 1 мин) 3 - 30-минутный таймер основной битвы (с 15-минутным предупреждением) 4 - 15-минутный таймер окончания битвы (предупреждение за 15 мин) 5 - 10-минутный таймер перерыва (сброс настроек) 6 - 30-минутный таймер финальной битвы (завершение матча) 7 - 30-минутный таймер ожидания результатов (защита от выхода) 9 - 15-минутный таймер специальных событий (45-минутное предупреждение) ]] ArenaMap = {} ArenaMap[1] = {ArenaMapID = 2092183860, Door1 = 175, Door2 = 174, RedPoint = {x=210, y=207, z=71}, BluePoint = {x=42, y=207, z=182}, ExitPoint = {x=551, y=459, z=485}, BoxPoint = {x=128, y=11330, z=118}} ArenaMap[2] = {ArenaMapID = 2092184116, Door1 = 491, Door2 = 490, RedPoint = {x=39, y=14, z=169}, BluePoint = {x=217, y=14, z=114}, ExitPoint = {x=822, y=470, z=609}, BoxPoint = {x=129, y=530, z=151}} ArenaMap[0] = {ArenaMapID = 2092184372, Door1 = 174, Door2 = 175, RedPoint = {x=123, y=16, z=46}, BluePoint = {x=260, y=16, z=338}, ExitPoint = {x=286, y=470, z=749}, BoxPoint = {x=191, y=1280, z=179}} -- Инициализация матча арены -- Создает новый инстанс арены, распределяет игроков и настраивает таймеры function Arena_ArenaOnStart(MapID, InstanceID, RoomID, RoleID1, RoleID2, RoleID3, RoleID4, RoleID5, RoleID6) -- Проверяем входные параметры if MapID == nil or InstanceID == nil or RoomID == nil then return end -- Проверяем корректность ID игроков if RoleID1 == nil or RoleID2 == nil or RoleID3 == nil or RoleID4 == nil or RoleID5 == nil or RoleID6 == nil then return end -- Получаем ID карты и инстанса для арены local arenaMapID, arenaInstanceID = GetArenaMapID() if arenaMapID == nil or arenaInstanceID == nil then return end -- Используем полученные значения вместо входных параметров MapID = arenaMapID InstanceID = arenaInstanceID -- Рандомизация игроков для равномерного распределения команд RoleID1, RoleID2, RoleID3, RoleID4, RoleID5, RoleID6 = PlayerRandom_Arena(RoleID1, RoleID2, RoleID3, RoleID4, RoleID5, RoleID6) -- Инициализация данных арены и распределение игроков по командам DefineValue_Arena(InstanceID, RoomID, RoleID1, RoleID2, RoleID3, RoleID4, RoleID5, RoleID6) -- Массив ID игроков для обработки local Role = {} Role[1] = RoleID1 Role[2] = RoleID2 Role[3] = RoleID3 Role[4] = RoleID4 Role[5] = RoleID5 Role[6] = RoleID6 -- Телепортация игроков в арену и настройка их позиций for i = 1, 6 do local playerMap, playerInstance = role.GetRoleMapID(Role[i]) if playerMap ~= nil and playerInstance ~= nil then -- Определяем активную активность арены local activityID = act.GetActIsStart(31) and 31 or 32 -- Отправляем сообщение о переключении в арену msg.SendRoleSwitchMsg(1, playerMap, playerInstance, Role[i], 1, activityID) -- Добавляем бафф защиты от выхода unit.AddBuff(playerMap, playerInstance, Role[i], 6936001, Role[i]) -- Устанавливаем штраф за выход role.SetRoleScriptData(Role[i], 1, RoleDataType["Point_Arena"], Lose_Point_Arena(InstanceID, Role[i])) end end -- Создание сундука арены (случайный выбор типа: 10% шанс на премиум) local mapConfig = ArenaMap[InstanceID % 3] if mapConfig ~= nil then local chestType = (math.random(10) == 5) and 5512005 or 5512004 -- 5512005 - премиум, 5512004 - обычный map.MapCreateCreature(MapID, InstanceID, chestType, mapConfig.BoxPoint.x, mapConfig.BoxPoint.y, mapConfig.BoxPoint.z) end -- Создание таймерных существ для управления временем арены local creature1 = map.MapCreateCreature(MapID, InstanceID, 1094003, 6, 1, 9) -- 60 мин завершение local creature2 = map.MapCreateCreature(MapID, InstanceID, 1094002, 6, 1, 9) -- 30 мин битва local creature3 = map.MapCreateCreature(MapID, InstanceID, 1094004, 6, 1, 9) -- 10 мин начало local creature4 = map.MapCreateCreature(MapID, InstanceID, 1094001, 6, 1, 9) -- 15 мин события -- Регистрация таймеров if creature1 ~= nil then ArenaCreature_Timer[creature1] = {TypeID = 1} end -- Инициализация if creature2 ~= nil then ArenaCreature_Timer[creature2] = {TypeID = 3} end -- Основная битва if creature3 ~= nil then ArenaCreature_Timer[creature3] = {TypeID = 2} end -- Начало боя if creature4 ~= nil then ArenaCreature_Timer[creature4] = {TypeID = 9} end -- Специальные события end -- Обработка клика игрока по объекту арены (попытка возврата в матч) -- Проверяет возможность возврата игрока в активный матч арены function Arena_OnClick(MapID, InstanceID, RoleID, TOMsgID, ToMapID, x, y, z) -- Проверяем входные параметры if MapID == nil or InstanceID == nil or RoleID == nil then return end -- Проверяем, есть ли данные об игроке в системе арены if ArenaPlayer[RoleID] == nil then return end -- Получение текущего InstanceID арены игрока, если он в процессе боя local InstanceID_Now = GetNowArenaInstanceID(RoleID) if InstanceID_Now ~= 0 then -- Получаем текущее время для проверки возможности возврата local Hour = tonumber(os.date("%H")) local Min = tonumber(os.date("%M")) local Second = tonumber(os.date("%S")) -- Получаем время открытия арены local arenaData = Arena[InstanceID_Now] if arenaData == nil then return end local Hour_open = math.floor(arenaData.OpenTime / 10000) local Min_open = math.floor((arenaData.OpenTime % 10000) / 100) local Second_open = arenaData.OpenTime % 100 -- Функция проверки: прошло ли менее 1 минуты с момента выхода local function ShorterThan1Min() -- Обработка перехода через час if Hour - Hour_open == 1 then if Min - Min_open == -59 then -- 59 минут разницы (переход через час) if Second <= Second_open then return true end end elseif Hour == Hour_open then -- Тот же час if Min - Min_open == 1 then -- Прошла 1 минута if Second <= Second_open then return true end elseif Min == Min_open then -- Та же минута if Second >= Second_open then return true end end end return false end -- Проверяем возможность возврата в арену if ShorterThan1Min() and unit.IsDead(MapID, InstanceID, RoleID) ~= true then -- Игрок может вернуться в матч local playerInfo = ArenaPlayer[RoleID] if playerInfo ~= nil and playerInfo.Info[InstanceID_Now] ~= nil then local playerSide = playerInfo.Info[InstanceID_Now].Side local mapConfig = ArenaMap[InstanceID_Now % 3] if mapConfig ~= nil then -- Отменяем состояние торговли, если игрок в нем if role.IsRoleInStatus(RoleID, 1024) then role.CancelRoleStallState(MapID, InstanceID, RoleID) end -- Телепортируем в соответствующую точку спавна if playerSide == "red" then role.RoleGotoNewMap(MapID, InstanceID, RoleID, mapConfig.ArenaMapID, mapConfig.RedPoint.x, mapConfig.RedPoint.y, mapConfig.RedPoint.z) elseif playerSide == "blue" then role.RoleGotoNewMap(MapID, InstanceID, RoleID, mapConfig.ArenaMapID, mapConfig.BluePoint.x, mapConfig.BluePoint.y, mapConfig.BluePoint.z) end -- Сбрасываем штрафные очки role.SetRoleScriptData(RoleID, 1, RoleDataType["Point_Arena"], 0) end end elseif unit.IsDead(MapID, InstanceID, RoleID) == true then -- Игрок мертв - применяем штраф за смерть local Pt = Lose_Point_Arena(InstanceID_Now, RoleID) -- Очищаем данные игрока в арене if ArenaPlayer[RoleID] ~= nil then ArenaPlayer[RoleID].Now = 0 end -- Применяем штраф рейтинга role.ModRoleAttValue(MapID, InstanceID, RoleID, 79, -Pt) role.SetRoleScriptData(RoleID, 1, RoleDataType["Point_Arena"], 0) -- Отправляем сообщение о штрафе за смерть local MsgID = msg.BeginMsgEvent() msg.AddMsgEvent(MsgID, 71, 206251) -- "Вы погибли в бою и не смогли вернуться вовремя. Потеряно X очков рейтинга." msg.AddMsgEvent(MsgID, 9, Pt) msg.DispatchRoleMsgEvent(RoleID, MsgID) else -- Игрок не может вернуться (прошло слишком много времени) local Pt = Lose_Point_Arena(InstanceID_Now, RoleID) -- Отправляем сообщение о невозможности возврата local MsgID = msg.BeginMsgEvent() msg.AddMsgEvent(MsgID, 71, 206252) -- "Прошло слишком много времени с момента выхода из арены, поэтому вы не можете вернуться в бой. Потеряно X очков рейтинга." msg.AddMsgEvent(MsgID, 9, Pt) msg.DispatchRoleMsgEvent(RoleID, MsgID) -- Очищаем данные игрока в арене if ArenaPlayer[RoleID] ~= nil then ArenaPlayer[RoleID].Now = 0 end -- Применяем штраф рейтинга role.ModRoleAttValue(MapID, InstanceID, RoleID, 79, -Pt) role.SetRoleScriptData(RoleID, 1, RoleDataType["Point_Arena"], 0) end -- Игрок не участвует в матче арены (выполняется в любом случае) role.DeletRoleFromArenaTable(RoleID) -- Расчет штрафа за попытку входа без активного матча local rongyu = role.GetRoleAttValue(MapID, InstanceID, RoleID, 79) local function CountPoint_OnClick(Point) if Point <= 100 then return 0 elseif Point <= 250 then return 1 elseif Point <= 500 then return 2 elseif Point <= 750 then return 4 elseif Point > 750 then return math.floor((Point - 750) / 150) + 6 else return 0 end end local Pt = CountPoint_OnClick(rongyu) -- Отправляем сообщение о штрафе local MsgID = msg.BeginMsgEvent() msg.AddMsgEvent(MsgID, 71, 206252) -- "Вы не можете вернуться в арену, так как вышли слишком давно. Потеряно X очков рейтинга." msg.AddMsgEvent(MsgID, 9, Pt) msg.DispatchRoleMsgEvent(RoleID, MsgID) -- Применяем штраф role.ModRoleAttValue(MapID, InstanceID, RoleID, 79, -Pt) role.SetRoleScriptData(RoleID, 1, RoleDataType["Point_Arena"], 0) end end -- Функция входа игрока в арену -- Вызывается при входе игрока на карту арены function Arena_OnPlayerEnter(MapID, InstanceID, RoleID) -- Проверяем входные параметры if MapID == nil or InstanceID == nil or RoleID == nil then return end -- Добавляем защитный бафф для предотвращения выхода из арены unit.AddBuff(MapID, InstanceID, RoleID, 6936101, RoleID) -- Показываем информацию о противниках ShowEnemyInformation(MapID, InstanceID, RoleID, 1) -- Добавляем игрока в команду LetPlayerJoinTeam(MapID, InstanceID, RoleID) -- Показываем время до окончания матча ShowArenaTime(MapID, InstanceID, RoleID) -- Сбрасываем штрафные очки при входе role.SetRoleScriptData(RoleID, 1, RoleDataType["Point_Arena"], 0) -- Подсчет ежедневных участий в арене для статистики сервера local curTime = tonumber(os.date("%j")) -- День года -- Инициализируем глобальную таблицу, если она не существует if arena_Roles == nil then arena_Roles = {} end if arena_Roles[RoleID] == nil then -- Первый вход игрока сегодня UpdateSeverData(56, 1) arena_Roles[RoleID] = curTime elseif arena_Roles[RoleID] ~= curTime then -- Новый день - очищаем старую статистику и обновляем arena_Roles = {} arena_Roles[RoleID] = curTime UpdateSeverData(56, 1) end end -- Функция обработки убийства игрока в арене -- Вызывается при убийстве одного игрока другим в матче арены function Arena_KillPeople(MapID, InstanceID, RoleID, KillerID) -- Проверяем входные параметры if MapID == nil or InstanceID == nil or RoleID == nil or KillerID == nil then return end -- Проверяем существование данных арены и игроков if ArenaPlayer[RoleID] == nil or ArenaPlayer[RoleID].Info[InstanceID] == nil or Arena[InstanceID] == nil then return end -- Проверяем, что убийца - игрок (не монстр) if unit.IsPlayer(KillerID) then if ArenaPlayer[KillerID] ~= nil and ArenaPlayer[KillerID].Info[InstanceID] ~= nil then -- Отправляем сообщение убитому игроку local MsgID = msg.BeginMsgEvent() msg.AddMsgEvent(MsgID, 101, 206253) -- "Игрок XXX убил вас!" msg.AddMsgEvent(MsgID, 2, KillerID) msg.DispatchRoleMsgEvent(RoleID, MsgID) -- Увеличиваем счетчик убийств для убийцы (максимум 3) local killerInfo = ArenaPlayer[KillerID].Info[InstanceID] killerInfo.Kill = killerInfo.Kill + 1 if killerInfo.Kill > 3 then killerInfo.Kill = 3 end -- Показываем иконку убийцы role.ShowKillerPictureInArena(KillerID, killerInfo.Kill) -- Отправляем уведомления всем игрокам об убийстве for i = 1, 6 do local notifyPlayerID = Arena[InstanceID].Player[i] if notifyPlayerID ~= nil and notifyPlayerID ~= RoleID and role.IsRoleOnLine(MapID, InstanceID, notifyPlayerID) == 1 and ArenaPlayer[notifyPlayerID] ~= nil and ArenaPlayer[notifyPlayerID].Info[InstanceID] ~= nil then local killerSide = killerInfo.Side local notifySide = ArenaPlayer[notifyPlayerID].Info[InstanceID].Side local MsgID = msg.BeginMsgEvent() if killerSide == "red" then if notifySide == "red" then -- Красный убил красного (убийство союзника) msg.AddMsgEvent(MsgID, 101, 206254) -- "XXX убил XXX" msg.AddMsgEvent(MsgID, 2, KillerID) msg.AddMsgEvent(MsgID, 2, RoleID) else -- Красный убил синего msg.AddMsgEvent(MsgID, 101, 206255) -- "Наша команда убила XXX противника" msg.AddMsgEvent(MsgID, 2, RoleID) msg.AddMsgEvent(MsgID, 2, KillerID) end else if notifySide == "red" then -- Синий убил красного msg.AddMsgEvent(MsgID, 101, 206255) -- "Наша команда убила XXX противника" msg.AddMsgEvent(MsgID, 2, RoleID) msg.AddMsgEvent(MsgID, 2, KillerID) else -- Синий убил синего (убийство союзника) msg.AddMsgEvent(MsgID, 101, 206254) -- "XXX убил XXX" msg.AddMsgEvent(MsgID, 2, KillerID) msg.AddMsgEvent(MsgID, 2, RoleID) end end msg.DispatchRoleMsgEvent(notifyPlayerID, MsgID) end end end end -- Обновляем информацию о противниках для убитого игрока ShowEnemyInformation(MapID, InstanceID, RoleID, 2) -- Проверяем данные убитого игрока и обновляем счетчики команд if ArenaPlayer[RoleID] ~= nil and ArenaPlayer[RoleID].Info[InstanceID] ~= nil then local playerSide = ArenaPlayer[RoleID].Info[InstanceID].Side local arenaData = Arena[InstanceID] if playerSide == "red" then -- Уменьшаем счетчик красной команды arenaData.RedNum = arenaData.RedNum - 1 -- Проверяем, не уничтожена ли красная команда if arenaData.RedNum <= 0 then if arenaData.Battle ~= 2 then -- Завершаем бой победой синей команды arenaData.Battle = 2 -- 0: ожидание, 1: бой, 2: завершен ShowArenaFinalFrame(MapID, InstanceID) -- Создаем таймер для финальной обработки local creature1 = map.MapCreateCreature(MapID, InstanceID, 1094003, 6, 1, 9) if creature1 ~= nil then ArenaCreature_Timer[creature1] = {TypeID = 6} -- 30-минутный таймер завершения end end end elseif playerSide == "blue" then -- Уменьшаем счетчик синей команды arenaData.BlueNum = arenaData.BlueNum - 1 -- Проверяем, не уничтожена ли синяя команда if arenaData.BlueNum <= 0 then if arenaData.Battle ~= 2 then -- Завершаем бой победой красной команды arenaData.Battle = 2 -- 0: ожидание, 1: бой, 2: завершен ShowArenaFinalFrame(MapID, InstanceID) -- Создаем таймер для финальной обработки local creature1 = map.MapCreateCreature(MapID, InstanceID, 1094003, 6, 1, 9) if creature1 ~= nil then ArenaCreature_Timer[creature1] = {TypeID = 6} -- 30-минутный таймер завершения end end end end end end -- Функция выхода игрока из арены -- Вызывается при выходе игрока с карты арены function Arena_LeaveMap(MapID, InstanceID, RoleID) -- Проверяем входные параметры if MapID == nil or InstanceID == nil or RoleID == nil then return end -- Удаляем игрока из команды, если он в ней состоит local TeamID_Old = role.IsRoleHaveTeam(MapID, InstanceID, RoleID) if TeamID_Old ~= nil and TeamID_Old ~= 4294967295 then role.LetRoleLeaveTeam(TeamID_Old, RoleID) end -- Удаляем из таблицы арены role.DeletRoleFromArenaTable(RoleID) -- Снимаем состояния арены unit.UnsetState(MapID, InstanceID, RoleID, 10) -- PvP защита unit.UnsetState(MapID, InstanceID, RoleID, 11) -- PvP усиление -- Проверяем данные игрока и арены if ArenaPlayer[RoleID] ~= nil and ArenaPlayer[RoleID].Info[InstanceID] ~= nil and Arena[InstanceID] ~= nil then -- Проверяем, не завершилась ли битва if Arena[InstanceID].Battle ~= 2 then -- Увеличиваем счетчик общих участий local TotleTimes_Arena = role.GetRoleScriptData(RoleID, 1, RoleDataType["TotleTimes_Arena"]) role.SetRoleScriptData(RoleID, 1, RoleDataType["TotleTimes_Arena"], TotleTimes_Arena + 1) -- Применяем штраф за выход role.ModRoleAttValue(MapID, InstanceID, RoleID, 79, -Lose_Point_Arena(InstanceID, RoleID)) -- Очищаем данные игрока ArenaPlayer[RoleID].Now = 0 role.SetRoleScriptData(RoleID, 1, RoleDataType["Point_Arena"], 0) -- Уведомляем всех игроков в матче о выходе for i = 1, 6 do local notifyPlayerID = Arena[InstanceID].Player[i] if notifyPlayerID ~= nil and notifyPlayerID ~= RoleID then local playerMap, playerInstance = role.GetRoleMapID(notifyPlayerID) if playerMap ~= nil and playerInstance ~= nil and playerMap == MapID and playerInstance == InstanceID and role.IsRoleOnLine(MapID, InstanceID, notifyPlayerID) == 1 then -- Отправляем уведомление о выходе local MsgID = msg.BeginMsgEvent() msg.AddMsgEvent(MsgID, 26, 206256) -- "XXX вышел из арены" msg.AddMsgEvent(MsgID, 2, RoleID) msg.DispatchRoleMsgEvent(notifyPlayerID, MsgID) -- Дублируем сообщение для совместимости local MsgID2 = msg.BeginMsgEvent() msg.AddMsgEvent(MsgID2, 13, 0) msg.AddMsgEvent(MsgID2, 1, 206256) -- "XXX вышел из арены" msg.AddMsgEvent(MsgID2, 2, RoleID) msg.DispatchRoleMsgEvent(notifyPlayerID, MsgID2) end end end -- Обновляем информацию о противниках для ушедшего игрока ShowEnemyInformation(MapID, InstanceID, RoleID, 3) -- Пересчитываем количество живых игроков в команде ушедшего игрока local playerSide = ArenaPlayer[RoleID].Info[InstanceID].Side local arenaData = Arena[InstanceID] if playerSide == "red" then -- Пересчитываем красную команду arenaData.RedNum = 0 for i = 1, 3 do -- Красная команда: игроки 1-3 local teamPlayerID = arenaData.Player[i] if teamPlayerID ~= nil and teamPlayerID ~= RoleID then local playerMap, playerInstance = role.GetRoleMapID(teamPlayerID) if playerMap ~= nil and playerInstance ~= nil and playerMap == MapID and playerInstance == InstanceID and role.IsRoleOnLine(MapID, InstanceID, teamPlayerID) == 1 and unit.IsDead(MapID, InstanceID, teamPlayerID) ~= true then arenaData.RedNum = arenaData.RedNum + 1 end end end -- Проверяем, не уничтожена ли красная команда if arenaData.RedNum <= 0 then if arenaData.Battle == 1 then -- Завершаем бой победой синей команды arenaData.Battle = 2 -- 0: ожидание, 1: бой, 2: завершен ShowArenaFinalFrame(MapID, InstanceID) -- Создаем таймер для финальной обработки local creature1 = map.MapCreateCreature(MapID, InstanceID, 1094003, 6, 1, 9) if creature1 ~= nil then ArenaCreature_Timer[creature1] = {TypeID = 6} -- 30-минутный таймер завершения end end end elseif playerSide == "blue" then -- Пересчитываем синюю команду arenaData.BlueNum = 0 for i = 4, 6 do -- Синяя команда: игроки 4-6 local teamPlayerID = arenaData.Player[i] if teamPlayerID ~= nil and teamPlayerID ~= RoleID then local playerMap, playerInstance = role.GetRoleMapID(teamPlayerID) if playerMap ~= nil and playerInstance ~= nil and playerMap == MapID and playerInstance == InstanceID and role.IsRoleOnLine(MapID, InstanceID, teamPlayerID) == 1 and unit.IsDead(MapID, InstanceID, teamPlayerID) ~= true then arenaData.BlueNum = arenaData.BlueNum + 1 end end end -- Проверяем, не уничтожена ли синяя команда if arenaData.BlueNum <= 0 then if arenaData.Battle == 1 then -- Завершаем бой победой красной команды arenaData.Battle = 2 -- 0: ожидание, 1: бой, 2: завершен ShowArenaFinalFrame(MapID, InstanceID) -- Создаем таймер для финальной обработки local creature1 = map.MapCreateCreature(MapID, InstanceID, 1094003, 6, 1, 9) if creature1 ~= nil then ArenaCreature_Timer[creature1] = {TypeID = 6} -- 30-минутный таймер завершения end end end end end end end -- Воскрешение игрока в арене -- Вызывается при воскрешении игрока в арене function Arena_RoloRevive(MapID, InstanceID, RoleID, Type, ReviveHP, ReviveMP, x, y, z, RebornMapID) -- Проверяем входные параметры if MapID == nil or InstanceID == nil or RoleID == nil then return ReviveHP, ReviveMP, x, y, z, RebornMapID end -- Устанавливаем HP и MP для воскрешения ReviveHP = role.GetRoleAttValue(MapID, InstanceID, RoleID, 8) -- Максимальное HP ReviveMP = role.GetRoleAttValue(MapID, InstanceID, RoleID, 10) -- Максимальное MP -- Удаляем игрока из таблицы арены (он вышел из боя) role.DeletRoleFromArenaTable(RoleID) -- Выбираем случайную точку выхода local mapIndex = math.random(0, 2) local exitConfig = ArenaMap[mapIndex] if exitConfig ~= nil then return ReviveHP, ReviveMP, exitConfig.ExitPoint.x, exitConfig.ExitPoint.y * 51, exitConfig.ExitPoint.z, 3424073512 else return ReviveHP, ReviveMP, x, y, z, RebornMapID end end -- Обработка входа в комнату ожидания арены -- Проверяет возможность входа игрока в систему матчей арены function JoinArenaRoom(MapID, InstanceID, Type, RoomID, RoleID) -- Проверяем входные параметры if MapID == nil or RoleID == nil then return false end -- Проверяем штрафные очки игрока local penaltyPoints = role.GetRoleScriptData(RoleID, 1, RoleDataType["Point_Arena"]) -- Очищаем активные данные игрока в арене if ArenaPlayer[RoleID] ~= nil then local currentInstanceID = GetNowArenaInstanceID(RoleID) if currentInstanceID ~= 0 then ArenaPlayer[RoleID].Now = 0 end end -- Применяем штраф за предыдущие нарушения if penaltyPoints > 0 then role.ModRoleAttValue(MapID, InstanceID, RoleID, 79, -penaltyPoints) role.SetRoleScriptData(RoleID, 1, RoleDataType["Point_Arena"], 0) end -- Проверяем активность арены if act.GetActIsStart(31) ~= true and act.GetActIsStart(32) ~= true then -- Арена не активна local MsgID = msg.BeginMsgEvent() msg.AddMsgEvent(MsgID, 26, 206257) -- "Система арены временно недоступна, попробуйте зайти позже." msg.DispatchRoleMsgEvent(RoleID, MsgID) return false elseif MapID == 3424073512 then -- Специальная карта арены - разрешаем вход return 1 else -- Другие случаи - запрещаем вход return false end end -- Определение отношений между игроками в арене (друг/враг) -- Возвращает: IsFriend, IsEnemy, CanAttackFriend, CanAttackEnemy function Arena_FriendEnemy(MapID, InstanceID, SrcID, TargetID) -- Проверяем входные параметры if MapID == nil or InstanceID == nil or SrcID == nil or TargetID == nil then return false, false, false, false end -- Проверяем существование данных арены if Arena[InstanceID] == nil then return false, false, false, false end -- Проверяем, что оба участника - игроки if not unit.IsPlayer(SrcID) or not unit.IsPlayer(TargetID) then return false, false, false, false end local srcTeam = -1 -- 1 = красная команда, 0 = синяя команда local targetTeam = -1 -- Определяем команду атакующего for i = 1, 6 do if Arena[InstanceID].Player[i] == SrcID then srcTeam = (i <= 3) and 1 or 0 -- Игроки 1-3: красная, 4-6: синяя break end end -- Определяем команду цели for i = 1, 6 do if Arena[InstanceID].Player[i] == TargetID then targetTeam = (i <= 3) and 1 or 0 -- Игроки 1-3: красная, 4-6: синяя break end end -- Определяем отношения if srcTeam ~= -1 and targetTeam ~= -1 then if srcTeam ~= targetTeam then -- Разные команды - враги return false, true, false, true -- Не друг, враг, нельзя атаковать друзей, можно атаковать врагов elseif srcTeam == targetTeam then -- Одна команда - друзья return true, false, false, true -- Друг, не враг, нельзя атаковать друзей, можно атаковать врагов end end -- Игроки не в арене или другие случаи return false, false, false, false end -- Регистрация событий системы арены -- Все карты арены имеют одинаковые события -- Вход игрока на карту арены (событие 2) aux.RegisterMapEvent("a01", 2, "Arena_OnPlayerEnter") -- Карта арены 1 aux.RegisterMapEvent("a02", 2, "Arena_OnPlayerEnter") -- Карта арены 2 aux.RegisterMapEvent("a03", 2, "Arena_OnPlayerEnter") -- Карта арены 3 -- Клик по объекту в активности (событие 8) aux.RegisterActEvent(31, 8, "Arena_OnClick") -- Активность арены 31 aux.RegisterActEvent(32, 8, "Arena_OnClick") -- Активность арены 32 -- Запуск матча арены (мировое событие 1) aux.RegisterWorldEvent(1, "Arena_ArenaOnStart") -- Убийство игрока в арене (событие 5) aux.RegisterMapEvent("a01", 5, "Arena_KillPeople") -- Карта арены 1 aux.RegisterMapEvent("a02", 5, "Arena_KillPeople") -- Карта арены 2 aux.RegisterMapEvent("a03", 5, "Arena_KillPeople") -- Карта арены 3 -- Выход игрока с карты арены (событие 3) aux.RegisterMapEvent("a01", 3, "Arena_LeaveMap") -- Карта арены 1 aux.RegisterMapEvent("a02", 3, "Arena_LeaveMap") -- Карта арены 2 aux.RegisterMapEvent("a03", 3, "Arena_LeaveMap") -- Карта арены 3 -- Воскрешение игрока в арене (событие 11) aux.RegisterMapEvent("a01", 11, "Arena_RoloRevive") -- Карта арены 1 aux.RegisterMapEvent("a02", 11, "Arena_RoloRevive") -- Карта арены 2 aux.RegisterMapEvent("a03", 11, "Arena_RoloRevive") -- Карта арены 3 -- Вход в комнату ожидания арены (ролевые события 36 и 37) aux.RegisterRoleEvent(36, "JoinArenaRoom") -- Событие входа 1 aux.RegisterRoleEvent(37, "JoinArenaRoom") -- Событие входа 2 -- Определение отношений друг/враг (событие 16) aux.RegisterMapEvent("a01", 16, "Arena_FriendEnemy") -- Карта арены 1 aux.RegisterMapEvent("a02", 16, "Arena_FriendEnemy") -- Карта арены 2 aux.RegisterMapEvent("a03", 16, "Arena_FriendEnemy") -- Карта арены 3