-- Функция запуска активности арены -- Отправляет широковещательное сообщение о начале арены function ArenaAct_OnStart(actID) -- Проверяем входные параметры if actID == nil then return end local MsgID = msg.BeginMsgEvent() msg.AddMsgEvent(MsgID, 102, 100131) -- "Мастер арены: Приветствуем всех в зале арены! Каждый желающий может войти в специальную комнату для поиска соперника, иначе придется ждать начала битвы!" msg.DispatchBroadcast(MsgID, -1, -1, -1) end -- Функция обработки таймера активности арены -- Каждые 10 минут отправляет напоминание о скором начале матча function ArenaAct_OnTimerMin(actID) -- Проверяем входные параметры if actID == nil then return end local Min = tonumber(os.date("%M")) -- Отправляем напоминание за 5 минут до начала часа if Min == 5 or Min == 15 then local MsgID = msg.BeginMsgEvent() msg.AddMsgEvent(MsgID, 102, 100132) -- "Осталось недолго до начала арены! Успейте встать в очередь для поиска соперника в специальную комнату арены для начала PvP!" msg.DispatchBroadcast(MsgID, -1, -1, -1) end end -- Функция завершения активности арены -- Очищает данные активности и закрывает комнату ожидания function ArenaAct_OnEnd(actID) -- Проверяем входные параметры if actID == nil then return end -- Очищаем данные всех слотов активности (6 игроков) for i = 0, 5 do act.SetActScriptData(actID, 1, i) end -- Закрываем комнату ожидания арены role.CloseArenaWaitingRoom() end -- Регистрация событий активности арены -- actID 31 и 32 - два типа активности арены -- 2 - событие запуска, 3 - событие завершения, 4 - событие таймера aux.RegisterActEvent(31, 3, "ArenaAct_OnEnd") -- Завершение активности 31 aux.RegisterActEvent(32, 3, "ArenaAct_OnEnd") -- Завершение активности 32 aux.RegisterActEvent(31, 2, "ArenaAct_OnStart") -- Запуск активности 31 aux.RegisterActEvent(31, 4, "ArenaAct_OnTimerMin") -- Таймер активности 31 aux.RegisterActEvent(32, 2, "ArenaAct_OnStart") -- Запуск активности 32 aux.RegisterActEvent(32, 4, "ArenaAct_OnTimerMin") -- Таймер активности 32 -- Диалог с NPC арены (Мастер арены) -- Обрабатывает все варианты взаимодействия с NPC арены function x5512001_OnTalk(MapID, InstanceID, TargetID, TargetTypeID, RoleID, TalkIndex) -- Проверяем входные параметры if MapID == nil or InstanceID == nil or TargetID == nil or TargetTypeID == nil or RoleID == nil or TalkIndex == nil then return end -- Определяем активную активность арены local actID = nil local rolelevel = role.GetRoleLevel(MapID, InstanceID, RoleID) -- Главное меню диалога с NPC if TalkIndex == -1 then local MsgID = msg.BeginMsgEvent() msg.AddMsgEvent(MsgID, 20, 206263) -- "Мастер арены: Приветствую тебя, отважный воин! Что ты желаешь? Говори же!" msg.AddMsgEvent(MsgID, 24, TargetID) -- ID NPC -- Опция 1: Войти в очередь на арену msg.AddMsgEvent(MsgID, 21, 4) -- Кнопка диалога msg.AddMsgEvent(MsgID, 1, 206264) -- "Войти в специальную комнату для поиска соперника" -- Опция 2: Информация о правилах msg.AddMsgEvent(MsgID, 21, 5) -- Кнопка диалога msg.AddMsgEvent(MsgID, 1, 206265) -- "Узнать правила участия в арене" -- Опция 3: Информация о наградах msg.AddMsgEvent(MsgID, 21, 6) -- Кнопка диалога msg.AddMsgEvent(MsgID, 1, 206266) -- "Узнать о наградах арены" -- Опция 4: Купить очки арены msg.AddMsgEvent(MsgID, 21, 9) -- Кнопка диалога msg.AddMsgEvent(MsgID, 1, 206289) -- "Купить очки арены" -- Опция 5: Покинуть очередь msg.AddMsgEvent(MsgID, 21, 10) -- Кнопка диалога msg.AddMsgEvent(MsgID, 1, 206290) -- "Покинуть очередь арены" msg.DispatchRoleMsgEvent(RoleID, MsgID) -- Обработка входа в очередь на арену elseif TalkIndex == 4 then -- Проверяем, активна ли хотя бы одна активность арены if act.GetActIsStart(31) ~= true and act.GetActIsStart(32) ~= true then local MsgID = msg.BeginMsgEvent() msg.AddMsgEvent(MsgID, 20, 206280) -- "Мастер арены: Сейчас нет активной сессии арены. Попробуй зайти позже, когда начнется время арены!" msg.AddMsgEvent(MsgID, 24, TargetID) -- ID NPC msg.AddMsgEvent(MsgID, 21, -1) -- Кнопка "Закрыть" msg.AddMsgEvent(MsgID, 1, 100001) -- "Закрыть" msg.DispatchRoleMsgEvent(RoleID, MsgID) -- Проверяем уровень игрока (минимум 40) elseif rolelevel < 40 then local MsgID = msg.BeginMsgEvent() msg.AddMsgEvent(MsgID, 20, 206267) -- "Мастер арены: Твой уровень ниже 40 уровня, поэтому ты не можешь участвовать в боях арены. Приходи позже, когда станешь сильнее!" msg.AddMsgEvent(MsgID, 24, TargetID) -- ID NPC msg.AddMsgEvent(MsgID, 21, -1) -- Кнопка "Закрыть" msg.AddMsgEvent(MsgID, 1, 100001) -- "Закрыть" msg.DispatchRoleMsgEvent(RoleID, MsgID) -- Проверяем, есть ли у игрока запрет на участие в PvP elseif role.IsRoleHaveBuff(MapID, InstanceID, RoleID, 69360) then local MsgID = msg.BeginMsgEvent() msg.AddMsgEvent(MsgID, 20, 206281) -- "Мастер арены: У тебя есть бафф, запрещающий PvP активность, поэтому ты не можешь войти в специальную комнату." msg.AddMsgEvent(MsgID, 24, TargetID) -- ID NPC msg.AddMsgEvent(MsgID, 21, -1) -- Кнопка "Закрыть" msg.AddMsgEvent(MsgID, 1, 100001) -- "Закрыть" msg.DispatchRoleMsgEvent(RoleID, MsgID) -- Все проверки пройдены - добавляем в очередь else role.JoinArena(MapID, InstanceID, RoleID) end -- Информация о правилах арены elseif TalkIndex == 5 then local MsgID = msg.BeginMsgEvent() msg.AddMsgEvent(MsgID, 20, 206268) -- "Мастер арены: Твой уровень должен быть 40 уровня, чтобы участвовать в боях арены. Каждый участник получает награду, которая зависит от его результата. У тебя есть возможность участвовать 6 раз. Каждый бой длится от 1 до 10 минут. Победитель получает очки рейтинга, проигравший теряет их. Очки зависят от уровня противника и твоего рейтинга. Чем сильнее противник, тем больше очков. Победивший получает золото и опыт. Каждый день ты можешь участвовать 10 раз. После этого тебе нужно подождать следующий день." msg.AddMsgEvent(MsgID, 24, TargetID) -- ID NPC msg.AddMsgEvent(MsgID, 21, -1) -- Кнопка "Закрыть" msg.AddMsgEvent(MsgID, 1, 100001) -- "Закрыть" msg.DispatchRoleMsgEvent(RoleID, MsgID) -- Меню покупки очков арены elseif TalkIndex == 6 then local MsgID = msg.BeginMsgEvent() msg.AddMsgEvent(MsgID, 20, 206269) -- "Мастер арены: Что ты желаешь купить?" msg.AddMsgEvent(MsgID, 24, TargetID) -- ID NPC -- Опция 1: Купить ежедневные попытки msg.AddMsgEvent(MsgID, 21, 7) -- Кнопка диалога msg.AddMsgEvent(MsgID, 1, 206270) -- "Купить ежедневные попытки участия в арене" -- Опция 2: Купить очки арены msg.AddMsgEvent(MsgID, 21, 8) -- Кнопка диалога msg.AddMsgEvent(MsgID, 1, 206271) -- "Обменять 40 уровней опыта на 1 очко арены" msg.AddMsgEvent(MsgID, 21, -1) -- Кнопка "Закрыть" msg.AddMsgEvent(MsgID, 1, 100001) -- "Закрыть" msg.DispatchRoleMsgEvent(RoleID, MsgID) -- Покупка ежедневных попыток elseif TalkIndex == 7 then local TimesToday = role.GetRoleScriptData(RoleID, 1, RoleDataType["TimesToday_Arena"]) -- Проверяем, не куплены ли уже дополнительные попытки сегодня if TimesToday > 1000 then local MsgID = msg.BeginMsgEvent() msg.AddMsgEvent(MsgID, 20, 206272) -- "Мастер арены: Ты уже купил дополнительные попытки участия в арене." msg.AddMsgEvent(MsgID, 24, TargetID) -- ID NPC msg.AddMsgEvent(MsgID, 21, 6) -- Кнопка "Закрыть" msg.AddMsgEvent(MsgID, 1, 100001) -- "Закрыть" msg.DispatchRoleMsgEvent(RoleID, MsgID) -- Проверяем, что у игрока меньше 6 базовых попыток elseif TimesToday < 6 then local MsgID = msg.BeginMsgEvent() msg.AddMsgEvent(MsgID, 20, 206273) -- "Мастер арены: У тебя осталось X попыток участия в арене. Чтобы купить дополнительные попытки, нужно иметь 10 попыток." msg.AddMsgEvent(MsgID, 24, TargetID) -- ID NPC msg.AddMsgEvent(MsgID, 9, TimesToday) -- Количество оставшихся попыток msg.AddMsgEvent(MsgID, 21, 6) -- Кнопка "Закрыть" msg.AddMsgEvent(MsgID, 1, 100001) -- "Закрыть" msg.DispatchRoleMsgEvent(RoleID, MsgID) -- Покупка дополнительных попыток else -- Расчет стоимости покупки (80% от опыта уровня игрока) local roleexp = math.floor(activity_expe[rolelevel] * 0.8) -- Применяем покупку role.AddRoleExp(MapID, InstanceID, RoleID, roleexp) -- Снимаем опыт role.ModRoleAttValue(MapID, InstanceID, RoleID, 80, 250) -- Снимаем 250 очков арены role.SetRoleScriptData(RoleID, 1, RoleDataType["TimesToday_Arena"], TimesToday + 1000) -- Отмечаем покупку local MsgID = msg.BeginMsgEvent() msg.AddMsgEvent(MsgID, 20, 206274) -- "Мастер арены: Ты купил дополнительные попытки участия в арене: XXX опыта и XX очков арены. Теперь ты можешь участвовать в боях дополнительно." msg.AddMsgEvent(MsgID, 24, TargetID) -- ID NPC msg.AddMsgEvent(MsgID, 9, roleexp) -- Стоимость в опыте msg.AddMsgEvent(MsgID, 9, 250) -- Стоимость в очках арены msg.AddMsgEvent(MsgID, 21, 6) -- Кнопка "Закрыть" msg.AddMsgEvent(MsgID, 1, 100001) -- "Закрыть" msg.DispatchRoleMsgEvent(RoleID, MsgID) -- Обновление данных сервера - счетчик использований арены UpdateSeverData(57, 1) -- Обновление данных персонажа - счетчик использований арены UpdateRoleData(RoleID, 13, 1) end -- Обмен очков арены на золото elseif TalkIndex == 8 then -- Проверяем, достаточно ли очков арены (минимум 25) if role.GetRoleAttValue(MapID, InstanceID, RoleID, 80) < 25 then local MsgID = msg.BeginMsgEvent() msg.AddMsgEvent(MsgID, 20, 206275) -- "Мастер арены: Недостаточно очков арены, чтобы обменять их на золото." msg.AddMsgEvent(MsgID, 24, TargetID) -- ID NPC msg.AddMsgEvent(MsgID, 21, 6) -- Кнопка "Закрыть" msg.AddMsgEvent(MsgID, 1, 100001) -- "Закрыть" msg.DispatchRoleMsgEvent(RoleID, MsgID) else -- Проверяем, есть ли место в инвентаре if role.GetBagFreeSize(RoleID) >= 1 then -- Совершаем обмен: 25 очков арены на 1 золото role.ModRoleAttValue(MapID, InstanceID, RoleID, 80, -25) role.AddRoleItem(MapID, InstanceID, RoleID, 4600001, 1, -1, 8, 420) -- Возвращаем в меню покупки local MsgID = msg.BeginMsgEvent() msg.AddMsgEvent(MsgID, 20, 206269) -- "Мастер арены: Что ты желаешь купить?" msg.AddMsgEvent(MsgID, 24, TargetID) -- ID NPC msg.AddMsgEvent(MsgID, 21, 7) -- Кнопка "Купить ежедневные попытки" msg.AddMsgEvent(MsgID, 1, 206270) -- "Купить ежедневные попытки участия в арене" msg.AddMsgEvent(MsgID, 21, 8) -- Кнопка "Обменять очки" msg.AddMsgEvent(MsgID, 1, 206271) -- "Обменять 40 уровней опыта на 1 очко арены" msg.AddMsgEvent(MsgID, 21, -1) -- Кнопка "Закрыть" msg.AddMsgEvent(MsgID, 1, 100001) -- "Закрыть" msg.DispatchRoleMsgEvent(RoleID, MsgID) else -- Нет места в инвентаре local MsgID = msg.BeginMsgEvent() msg.AddMsgEvent(MsgID, 20, 206276) -- "Мастер арены: Освободи место в инвентаре, чтобы получить золото." msg.AddMsgEvent(MsgID, 24, TargetID) -- ID NPC msg.AddMsgEvent(MsgID, 21, 6) -- Кнопка "Закрыть" msg.AddMsgEvent(MsgID, 1, 100001) -- "Закрыть" msg.DispatchRoleMsgEvent(RoleID, MsgID) end end -- Выход из очереди арены elseif TalkIndex == 10 then -- Определяем активную активность арены if act.GetActIsStart(31) == true then actID = 31 elseif act.GetActIsStart(32) == true then actID = 32 end -- Получаем список игроков в очереди local Role = {} Role[1] = act.GetActScriptData(actID, 1, 0) Role[2] = act.GetActScriptData(actID, 1, 1) Role[3] = act.GetActScriptData(actID, 1, 2) Role[4] = act.GetActScriptData(actID, 1, 3) Role[5] = act.GetActScriptData(actID, 1, 4) Role[6] = act.GetActScriptData(actID, 1, 5) -- Очищаем данные активности for i = 0, 5 do act.SetActScriptData(actID, 1, i) end -- Удаляем игрока из таблицы арены role.DeletRoleFromArenaTable(RoleID) -- Просмотр статистики арены elseif TalkIndex == 9 then -- Определяем активную активность арены if act.GetActIsStart(31) == true then actID = 31 elseif act.GetActIsStart(32) == true then actID = 32 end -- Показываем статистику игроков local MsgID = msg.BeginMsgEvent() msg.AddMsgEvent(MsgID, 20, 206288) -- "Текущие участники арены:" msg.AddMsgEvent(MsgID, 24, TargetID) -- ID NPC -- Показываем каждого игрока в очереди msg.AddMsgEvent(MsgID, 9, 1) -- Позиция 1 msg.AddMsgEvent(MsgID, 2, act.GetActScriptData(actID, 1, 0)) -- ID игрока 1 msg.AddMsgEvent(MsgID, 9, 2) -- Позиция 2 msg.AddMsgEvent(MsgID, 2, act.GetActScriptData(actID, 1, 1)) -- ID игрока 2 msg.AddMsgEvent(MsgID, 9, 3) -- Позиция 3 msg.AddMsgEvent(MsgID, 2, act.GetActScriptData(actID, 1, 2)) -- ID игрока 3 msg.AddMsgEvent(MsgID, 9, 4) -- Позиция 4 msg.AddMsgEvent(MsgID, 2, act.GetActScriptData(actID, 1, 3)) -- ID игрока 4 msg.AddMsgEvent(MsgID, 9, 5) -- Позиция 5 msg.AddMsgEvent(MsgID, 2, act.GetActScriptData(actID, 1, 4)) -- ID игрока 5 msg.AddMsgEvent(MsgID, 9, 6) -- Позиция 6 msg.AddMsgEvent(MsgID, 2, act.GetActScriptData(actID, 1, 5)) -- ID игрока 6 msg.AddMsgEvent(MsgID, 21, -1) -- Кнопка "Закрыть" msg.AddMsgEvent(MsgID, 1, 100001) -- "Закрыть" msg.DispatchRoleMsgEvent(RoleID, MsgID) end end -- Регистрация событий NPC арены (Мастер арены) -- Событие 7 - взаимодействие с NPC (диалог) aux.RegisterCreatureEvent(5512001, 7, "x5512001_OnTalk") -- Диалог с сундуком арены -- TargetTypeID: 5512004 - обычный сундук, 5512005 - премиум сундук function ArenaBox_OnTalk(MapID, InstanceID, TargetID, TargetTypeID, RoleID, TalkIndex) -- Проверяем входные параметры if MapID == nil or InstanceID == nil or TargetID == nil or TargetTypeID == nil or RoleID == nil or TalkIndex == nil then return end -- Основное взаимодействие с сундуком if TalkIndex == -1 then -- Проверяем существование данных арены и игрока if Arena[InstanceID] ~= nil and Arena[InstanceID].Battle ~= nil then -- Проверяем условия для открытия сундука if (Arena[InstanceID].Battle == 0 or Arena[InstanceID].Battle == 1) or (ArenaPlayer[RoleID] == nil or ArenaPlayer[RoleID].Info[InstanceID] == nil or ArenaPlayer[RoleID].Info[InstanceID].Win == 0) then -- Сундук недоступен (бой еще идет или игрок не победил) local MsgID = msg.BeginMsgEvent() msg.AddMsgEvent(MsgID, 20, 206277) -- "Сундук пока недоступен, подожди окончания битвы чтобы получить награду." msg.AddMsgEvent(MsgID, 21, 6) -- Кнопка "Закрыть" msg.AddMsgEvent(MsgID, 1, 100001) -- "Закрыть" msg.DispatchRoleMsgEvent(RoleID, MsgID) elseif Arena[InstanceID].Battle == 2 and ArenaPlayer[RoleID] ~= nil and ArenaPlayer[RoleID].Info[InstanceID] ~= nil and ArenaPlayer[RoleID].Info[InstanceID].Win == 1 then -- Сундук доступен для победителя local MsgID = msg.BeginMsgEvent() msg.AddMsgEvent(MsgID, 20, 206278) -- "Поздравляем с победой, забери свою награду!" msg.AddMsgEvent(MsgID, 24, TargetID) -- ID сундука msg.AddMsgEvent(MsgID, 21, 4) -- Кнопка "Открыть" msg.AddMsgEvent(MsgID, 1, 100001) -- "Открыть" msg.DispatchRoleMsgEvent(RoleID, MsgID) end end -- Открытие сундука победителем elseif TalkIndex == 4 and ArenaPlayer[RoleID] ~= nil and ArenaPlayer[RoleID].Info[InstanceID] ~= nil and ArenaPlayer[RoleID].Info[InstanceID].Win == 1 then -- Проверяем, что бой завершен и игрок победил if Arena[InstanceID] ~= nil and Arena[InstanceID].Battle == 2 then -- Раздаем награды всем союзникам победившей команды for i = 1, 6 do local Map_ID, Instance_ID = role.GetRoleMapID(Arena[InstanceID].Player[i]) -- Проверяем, что игрок онлайн и в той же арене if Map_ID ~= nil and Instance_ID ~= nil and Map_ID == MapID and Instance_ID == InstanceID and ArenaPlayer[Arena[InstanceID].Player[i]] ~= nil and ArenaPlayer[Arena[InstanceID].Player[i]].Info[InstanceID] ~= nil then -- Проверяем, что игрок в той же команде if ArenaPlayer[RoleID].Info[InstanceID].Side == ArenaPlayer[Arena[InstanceID].Player[i]].Info[InstanceID].Side then -- Вызываем функцию получения награды ArenaBox_GetItem(MapID, InstanceID, TargetTypeID, Arena[InstanceID].Player[i]) end end end end -- Удаляем сундук после раздачи наград map.MapDeleteCreature(MapID, InstanceID, TargetID) end end -- Регистрация событий сундуков арены -- Событие 7 - взаимодействие с объектом (диалог) aux.RegisterCreatureEvent(5512004, 7, "ArenaBox_OnTalk") -- Обычный сундук арены aux.RegisterCreatureEvent(5512005, 7, "ArenaBox_OnTalk") -- Премиум сундук арены