--[[ v.mezhisnky Системные стражи для низкоуровневых магмарских/людских локаций. Находится в локации и вступает в каждый бой, который в ней проводится. Если бой происходит между игроками, смотрит кто начал бой Если игрок противоположной фракции - проверяет его уровень Если уровень выше 14, призывает на противоположную сторону стража-босса Босс-страж Если, в начале боя, в моей команде есть игрок с уровнем ниже, чем уровень игрока-противника, вешаю на того игрока щит Если передо мной стоит противник-игрок и на нем нет антивампа, вешаю на него антивамп Раз в 60 секунд сбрасывает супер ]] --------------------------------------------------- common ------------------------------------------------------------- function cmn_get_pers_list_both(...) --[[ params: alive, except, isbot, n getPersList analog that process both teams at once ]] function cmn_merge_tables(tbl1, tbl2) if (type(tbl1) == 'table') and (type(tbl2) == 'table') then local newTable = {} for _, item in pairs(tbl1) do newTable[#newTable + 1] = item end for _, item in pairs(tbl2) do newTable[#newTable + 1] = item end return newTable else return {} end end local team1 = aux.getPersList(1, ...) -- aux.getPersList(teamNum, alive, except, isbot, n) local team2 = aux.getPersList(2, ...) -- aux.getPersList(teamNum, alive, except, isbot, n) local allTeams = cmn_merge_tables(team1, team2) return allTeams end --------------------------------------------------- common ------------------------------------------------------------- -------------------------------------------------Chance Time----------------------------------------------------- function Cmn_EffUse_Chance_Time_init(Effect) -- Инициализация, выполняется однажды при создании боя local botId = PERS_ID(my.persPtr) if sbot_state == nil then sbot_state = {} end if sbot_state[botId] == nil then sbot_state[botId] = {} end -- Инициализация признака первого хода if (sbot_state[botId].CurUsage == nil) then sbot_state[botId].CurUsage = {} end if (sbot_state[botId].CurUsage[Effect] == nil) then sbot_state[botId].CurUsage[Effect] = 1 end -- Здесь хранится номер следующего применения эффекта if (sbot_state[botId].NextUseTime == nil) then sbot_state[botId].NextUseTime = {} end if (sbot_state[botId].NextUseTime[Effect] == nil) then sbot_state[botId].NextUseTime[Effect] = os.time() end end function Cmn_EffUse_Chance_Time_use(Effect, MaxUse, CooldownTime, UseChance, PersPointer, ExceptArtId, ExceptArtIdPersPointer) --[[ -- Применение эффекта, который должен использоваться каждый ход с некоторым шансом, если прошел его кулдаун -- Параметры: - Effect - ID эффекта - (необязательный параметр) MaxUse - Максимальное число использований. По-умолчанию - 30000 - (необязательный параметр) CooldownTime - Кулдаун эффекта (в секундах). По-умолчанию - 0 - (необязательный параметр) UseChance - Шанс использования в данный ход. По-умолчанию - 100% - (необязательный параметр) PersPointer - указатель на то, на кого применять заклинание (себя или противника). По-умолчанию - на себя - (необязательный параметр) ExceptArtId - массив id-шников эффектов. Если хоть один из этих эффектов висит на ExceptArtIdPersPointer, то эффекты не применяются. По-умолчанию - пустой, не проверяем - (необязательный параметр) ExceptArtIdPersPointer - указатель на перса на котором проверять эти эффекты. По-умолчанию - на себя -- Логика: -- Текущий ход от применения эффекта храним в переменной state.CooldownTurn. -- Если истек кулдаун и применения не закончились, то применяем эффект в шансом UseChance -- ВНИМАНИЕ! Требует после себя удара с завершением хода!!! ]] local ReturnValue = false if (Effect ~= nil) then if (my.status == FS_PS_ACTIVE) then if (MaxUse == nil) then MaxUse = 30000 end --Задаем максимальное число использований по-умолчанию 30000 if (CooldownTime == nil) then CooldownTime = 0 end --Задаем нулевой кулдаун по-умолчанию if (UseChance == nil) then UseChance = 1 end --Задаем 100%-ю вероятность по-умолчанию if (PersPointer == nil) then PersPointer = my.persPtr end --Задаем себя в качестве указателя цели эффекта по-умолчанию if (ExceptArtId == nil) then ExceptArtId = nil end --Задаем пустой массив на проверку if (ExceptArtIdPersPointer == nil) then ExceptArtIdPersPointer = my.persPtr end --По-умолчанию проверяем эффекты на себя if (type(ExceptArtId) == "number") then --Если ExceptArtId задана числом - преобразуем его в таблицу local TMP_var = ExceptArtId ExceptArtId = nil ExceptArtId = {} ExceptArtId[1] = TMP_var end local botId = PERS_ID(my.persPtr) local state = sbot_state[botId] local dice = math.random() local CurTime = os.time() local IsArtId = false -- Пробегаем по массиву эффектов-исключений и если хоть один из них висит на ExceptArtIdPersPointer, то ставим флаг IsArtId - не "стрелять" if (ExceptArtId ~= nil) then for _, ArtId in pairs(ExceptArtId) do if (#aux.activeEffects(ExceptArtIdPersPointer, { artId = ArtId }) > 0) then IsArtId = true end end end if (state.CurUsage[Effect] <= MaxUse) and (CurTime >= state.NextUseTime[Effect]) and (dice <= UseChance) and (IsArtId == false) then local EffectUsed EffectUsed = aux.useEffect(Effect, PersPointer) state.CurUsage[Effect] = state.CurUsage[Effect] + 1 state.NextUseTime[Effect] = CurTime + CooldownTime if (EffectUsed ~= false) and (EffectUsed ~= -100) then ReturnValue = true end end end -- if FS_PS_ACTIVE end -- if all initials exist return ReturnValue end function Cmn_EffUse_Chance_Time(Effect, MaxUse, CooldownTime, UseChance, PersPointer, ExceptArtId, ExceptArtIdPersPointer) local ReturnValue = false if (Effect ~= nil) then -- Инициализируем Cmn_EffUse_Chance_Time_init(Effect) -- Применяем эффект, если надо ReturnValue = Cmn_EffUse_Chance_Time_use(Effect, MaxUse, CooldownTime, UseChance, PersPointer, ExceptArtId, ExceptArtIdPersPointer) end return ReturnValue end -----------------------------------------------End Chance Time---------------------------------------------------- -------------------------------------------------HPC Turns----------------------------------------------------- function Cmn_EffUse_HPC_Turns_init(Effect) -- Инициализация, выполняется однажды при создании боя local botId = PERS_ID(my.persPtr) if sbot_state == nil then sbot_state = {} end if sbot_state[botId] == nil then sbot_state[botId] = {} end -- Инициализация признака первого хода if (sbot_state[botId].CurUsage == nil) then sbot_state[botId].CurUsage = {} end if (sbot_state[botId].CurUsage[Effect] == nil) then sbot_state[botId].CurUsage[Effect] = 1 end -- Здесь хранится номер следующего применения эффекта (его параметры хранятся в таблице с этим номером) if (sbot_state[botId].CurTurn == nil) then sbot_state[botId].CurTurn = 1 end --Если вдруг по какой-то причине CurTurn не определен if (sbot_state[botId].NextUseTurn == nil) then sbot_state[botId].NextUseTurn = {} end if (sbot_state[botId].NextUseTurn[Effect] == nil) then sbot_state[botId].NextUseTurn[Effect] = sbot_state[botId].CurTurn end -- Инициализируем следующее использование в 1-й (первый) ход end function Cmn_EffUse_HPC_Turns_use(Effect, hpCMap, CooldownTurns, UseChance, PersPointer, ExceptArtId, ExceptArtIdPersPointer) --[[ Применение эффекта, который должен использоваться при достижении определенных порогов (например самохил), если прошел его кулдаун (в ходах). -- Параметры: - Effect - ID эффекта - hpCMap - таблица с порогами срабатывания эффекта, отсортированными по убыванию. В процентах (доле) от максимального здоровья бота - (необязательный параметр) CooldownTurns - кулдаун в ходах, не считая текущий. По-умолчанию - 0 - (необязательный параметр) UseChance - шанс использования в данный ход. По-умолчанию - 100% - (необязательный параметр) PersPointer - указатель на то, на кого применять эффект (себя или противника). По-умолчанию - на себя - (необязательный параметр) ExceptArtId - массив id-шников эффектов. Если хоть один из этих эффектов висит на ExceptArtIdPersPointer, то эффекты не применяются. По-умолчанию - пустой, не проверяем - (необязательный параметр) ExceptArtIdPersPointer - указатель на перса на котором проверять эти эффекты. По-умолчанию - на себя -- Логика: -- Эффект срабатывается при достижении порогов из hpCMap, срабатывания шанса UseChance и истечения кулдауна CooldownTurns -- ВНИМАНИЕ! Требует после себя удара с завершением хода!!! ]] local ReturnValue = false if (Effect ~= nil) and (hpCMap ~= nil) then if (my.status == FS_PS_ACTIVE) then if (CooldownTurns == nil) then CooldownTurns = 0 end --Задаем нулевой кулдаун по-умолчанию if (PersPointer == nil) then PersPointer = my.persPtr end --Задаем себя в качестве указателя цели эффекта по-умолчанию if (UseChance == nil) then UseChance = 1 end --Задаем 100%-ю вероятность по-умолчанию if (ExceptArtId == nil) then ExceptArtId = nil end --Задаем пустой массив на проверку if (ExceptArtIdPersPointer == nil) then ExceptArtIdPersPointer = my.persPtr end --По-умолчанию проверяем эффекты на противнике if (type(ExceptArtId) == "number") then --Если ExceptArtId задана числом - преобразуем его в таблицу local TMP_var = ExceptArtId ExceptArtId = nil ExceptArtId = {} ExceptArtId[1] = TMP_var end local botId = PERS_ID(my.persPtr) local state = sbot_state[botId] local bot = PERS(my.persPtr) local hpC = bot.hp / bot.hpMax local dice = math.random() local IsArtId = false local CurTurn = state.CurTurn -- Пробегаем по массиву эффектов-исключений и если хоть один из них висит на ExceptArtIdPersPointer, то ставим флаг IsArtId - не "стрелять" if (ExceptArtId ~= nil) then for _, ArtId in pairs(ExceptArtId) do if (#aux.activeEffects(ExceptArtIdPersPointer, { artId = ArtId }) > 0) then IsArtId = true end end end -- Есть массив порогов срабатывания эффекта. Пороги отсортированы по убыванию. -- По-умолчанию мы работаем с первым порогом. Если текужее здоровье меньше текущего порога и срабатывает шанс, то применяем эффект. -- Также проверяем прошел ли кулдаун с момента прошлого применения и не превысили ли мы число применений (вышли за пределы массива). -- После чего переходим к следующему элементу массива порога if (state.CurUsage[Effect] <= #hpCMap) and (hpC <= hpCMap[state.CurUsage[Effect]]) and (CurTurn >= state.NextUseTurn[Effect]) and (dice <= UseChance) and (IsArtId == false) then local EffectUsed EffectUsed = aux.useEffect(Effect, PersPointer) state.CurUsage[Effect] = state.CurUsage[Effect] + 1 state.NextUseTurn[Effect] = CurTurn + CooldownTurns if (EffectUsed == 0) then ReturnValue = true end end end -- if FS_PS_ACTIVE end -- if all initials exist return ReturnValue end function Cmn_EffUse_HPC_Turns(Effect, hpCMap, CooldownTurns, UseChance, PersPointer, ExceptArtId, ExceptArtIdPersPointer) local ReturnValue = false if (Effect ~= nil) and (hpCMap ~= nil) then -- Инициализируем Cmn_EffUse_HPC_Turns_init(Effect) -- Применяем эффект, если надо ReturnValue = Cmn_EffUse_HPC_Turns_use(Effect, hpCMap, CooldownTurns, UseChance, PersPointer, ExceptArtId, ExceptArtIdPersPointer) end return ReturnValue end ------------------------------------------------End HPC Turns---------------------------------------------------- -------------------------------------------------Chance Turns----------------------------------------------------- function Cmn_EffUse_Chance_Turns_init(Effect) -- Инициализация, выполняется однажды при создании боя local botId = PERS_ID(my.persPtr) if sbot_state == nil then sbot_state = {} end if sbot_state[botId] == nil then sbot_state[botId] = {} end -- Инициализация признака первого хода if (sbot_state[botId].CurUsage == nil) then sbot_state[botId].CurUsage = {} end if (sbot_state[botId].CurUsage[Effect] == nil) then sbot_state[botId].CurUsage[Effect] = 1 end -- Здесь хранится номер следующего применения эффекта if (sbot_state[botId].CurTurn == nil) then sbot_state[botId].CurTurn = 1 end --Если вдруг по какой-то причине CurTurn не определен if (sbot_state[botId].NextUseTurn == nil) then sbot_state[botId].NextUseTurn = {} end if (sbot_state[botId].NextUseTurn[Effect] == nil) then sbot_state[botId].NextUseTurn[Effect] = sbot_state[botId].CurTurn end -- Инициализируем следующее использование в 1-й (первый) ход end function Cmn_EffUse_Chance_Turns_use(Effect, MaxUse, CooldownTurns, UseChance, PersPointer, ExceptArtId, ExceptArtIdPersPointer) --[[ -- Применение эффекта, который должен использоваться каждый ход с некоторым шансом, если прошел его кулдаун -- Параметры: - Effect - ID эффекта - (необязательный параметр) MaxUse - Максимальное число использований. По-умолчанию 30000 - (необязательный параметр) CooldownTurns - Кулдаун эффекта (в ходах). По-умолчанию - 0 - (необязательный параметр) UseChance - Шанс использования в данный ход. По-умолчанию - 100% - (необязательный параметр) PersPointer - указатель на то, на кого применять заклинание (себя или противника). По-умолчанию - на себя - (необязательный параметр) ExceptArtId - массив id-шников эффектов. Если хоть один из этих эффектов висит на ExceptArtIdPersPointer, то эффекты не применяются. По-умолчанию - пустой, не проверяем - (необязательный параметр) ExceptArtIdPersPointer - указатель на перса на котором проверять эти эффекты. По-умолчанию - на себя -- Логика: -- Ход следующего применения эффекта храним в переменной state.NextUseTurn. -- Если истек кулдаун и применения не закончились, то применяем эффект в шансом UseChance -- ВНИМАНИЕ! Требует после себя удара с завершением хода!!! ]] local ReturnValue = false if (Effect ~= nil) then if (my.status == FS_PS_ACTIVE) then if (MaxUse == nil) then MaxUse = 30000 end --Задаем максимальное число использований по-умолчанию 30000 if (CooldownTurns == nil) then CooldownTurns = 0 end --Задаем нулевой кулдаун по-умолчанию if (UseChance == nil) then UseChance = 1 end --Задаем 100%-ю вероятность по-умолчанию if (PersPointer == nil) then PersPointer = my.persPtr end --Задаем себя в качестве указателя цели эффекта по-умолчанию if (ExceptArtId == nil) then ExceptArtId = nil end --Задаем пустой массив на проверку if (ExceptArtIdPersPointer == nil) then ExceptArtIdPersPointer = my.persPtr end --По-умолчанию проверяем эффекты на себя if (type(ExceptArtId) == "number") then --Если ExceptArtId задана числом - преобразуем его в таблицу local TMP_var = ExceptArtId ExceptArtId = {} ExceptArtId[1] = TMP_var end local botId = PERS_ID(my.persPtr) local state = sbot_state[botId] local dice = math.random() local IsArtId = false local CurTurn = state.CurTurn -- Пробегаем по массиву эффектов-исключений и если хоть один из них висит на ExceptArtIdPersPointer, то ставим флаг IsArtId - не "стрелять" if (ExceptArtId ~= nil) then for _, ArtId in pairs(ExceptArtId) do if (#aux.activeEffects(ExceptArtIdPersPointer, { artId = ArtId }) > 0) then IsArtId = true end end end if (state.CurUsage[Effect] <= MaxUse) and (CurTurn >= state.NextUseTurn[Effect]) and (dice <= UseChance) and (IsArtId == false) then local EffectUsed EffectUsed = aux.useEffect(Effect, PersPointer) state.CurUsage[Effect] = state.CurUsage[Effect] + 1 state.NextUseTurn[Effect] = CurTurn + CooldownTurns if (EffectUsed ~= false) and (EffectUsed ~= -100) then ReturnValue = true end end end -- if FS_PS_ACTIVE end -- if all initials exist return ReturnValue end function Cmn_EffUse_Chance_Turns(Effect, MaxUse, CooldownTurns, UseChance, PersPointer, ExceptArtId, ExceptArtIdPersPointer) local ReturnValue = false if (Effect ~= nil) then -- Инициализируем Cmn_EffUse_Chance_Turns_init(Effect) -- Применяем эффект, если надо ReturnValue = Cmn_EffUse_Chance_Turns_use(Effect, MaxUse, CooldownTurns, UseChance, PersPointer, ExceptArtId, ExceptArtIdPersPointer) end return ReturnValue end -----------------------------------------------End Chance Turns---------------------------------------------------- -------------------------------------------------Turns Counter----------------------------------------------------- function Cmn_EffUse_Turns_init() local botId = PERS_ID(my.persPtr) if sbot_state == nil then sbot_state = {} end if sbot_state[botId] == nil then sbot_state[botId] = {} end -- Инициализация признака первого хода if (sbot_state[botId].CurTurn == nil) then sbot_state[botId].CurTurn = 0 end end function Cmn_EffUse_Turns_AddTurn() local ReturnValue = false if (my.status == FS_PS_ACTIVE) then local botId = PERS_ID(my.persPtr) local state = sbot_state[botId] state.CurTurn = state.CurTurn + 1 ReturnValue = true end return ReturnValue end function Cmn_EffUse_Turns_Counter() --[[ Функция необходимая дла подсчета колическтва ходов Нужна для функкций ..._Turns (является для них как бы аналогом os.time()) Вызывать надо перед всеми абилками, но после if (my.status == FS_PS_ACTIVE) ВАЖНО!!! Вызывать один раз ]] local ReturnValue = false Cmn_EffUse_Turns_init() ReturnValue = Cmn_EffUse_Turns_AddTurn() end ---------------------------------------------End Turns Counter----------------------------------------------------- --------------------------------------------------- guards_main -------------------------------------------------------- function guards_3_0_human_init(wait) local botId = PERS_ID(my.persPtr) if sbot_state == nil then sbot_state = {} end if sbot_state[botId] == nil then sbot_state[botId] = {} end -- Инициализация признака первого хода if (sbot_state[botId].nextCheckCustom == nil) then sbot_state[botId].nextCheckCustom = os.time() end -- Переменная для синхронных проверок if (sbot_state[botId].PveFight == nil) then sbot_state[botId].PveFight = 0 end if (sbot_state[botId].initLevelT1 == nil) then sbot_state[botId].PveFight = 0 end if (sbot_state[botId].initLevelT2 == nil) then sbot_state[botId].PveFight = 0 end -- if (sbot_state[botId].nextCheck1sec == nil) then -- sbot_state[botId].nextCheck1sec = os.time() -- end -- Переменная для ежесекундных проверок end function guards_3_0_human_run_once() local botId = PERS_ID(my.persPtr) local state = sbot_state[PERS_ID(my.persPtr)] if (state.FirstRun == nil) then local Team1 = (aux.getPersList(1,true,nil,false)) local Team2 = (aux.getPersList(2,true,nil,true)) if Team1 and Team1[1] and Team2 and Team2[1] then sbot_state[botId].PveFight = 1 end local Team2Players = (aux.getPersList(2,true,nil,false)) if Team1 and Team1[1] then for _,persPtr in pairs(Team1) do local player1 = PERS(persPtr) sbot_state[botId].initLevelT1 = player1.level end end if Team2Players and Team2Players[1] then for _,persPtr in pairs(Team2Players) do local player2 = PERS(persPtr) sbot_state[botId].initLevelT2 = player2.level end end -- Put here what you want to run once state.FirstRun = true end end function guards_3_0_human_cycle_fastest(summonGuardId, summonedMarkId, race, level, checkTO,shieldId,antivampId,weakId) local botId = PERS_ID(my.persPtr) local state = sbot_state[botId] local ostime = os.time() -- Gamelogic Start if (state.nextCheckCustom <= ostime) then --and (state.FirstRun == true) the --if (#aux.activeEffects(my.persPtr, {artId = summonedMarkId}) == 0 ) then local Team1 = (aux.getPersList(1, true, nil, false)) local Team2 = (aux.getPersList(2, true, nil, false)) if Team1 and Team1[1] and Team2 and Team2[1] then for _, persPtr in pairs(Team1) do local player1 = PERS(persPtr) if (player1.kind == race) then if (player1.level >= level) and (player1.level > sbot_state[botId].initLevelT2) then for _, persPtr in pairs(Team2) do local player2 = PERS(persPtr) if (#aux.activeEffects(my.persPtr, {artId = summonedMarkId}) == 0 ) then if (player1.level > sbot_state[botId].initLevelT2) then aux.useEffect(summonGuardId,persPtr) aux.useEffect(summonedMarkId,my.persPtr) end end for _,persPtr in pairs(Team1) do local player1 = PERS(persPtr) if (player1.level > sbot_state[botId].initLevelT2) then if (#aux.activeEffects(persPtr, {artId = antivampId}) == 0) then aux.useEffect(antivampId, persPtr) end if (#aux.activeEffects(persPtr,{artId = weakId}) == 0) then aux.useEffect(weakId,persPtr) end end end end end end end for _,persPtr in pairs (Team2) do local player2 = PERS(persPtr) if (player2.kind == race) then if (player2.level >= level) then local Team2Full = (aux.getPersList(2,true,nil,nil)) if Team2Full[2] then if (sbot_state[botId].PveFight == 1) then for _,persPtr in pairs(Team1) do local player1 = PERS(persPtr) if (#aux.activeEffects(my.persPtr, {artId = summonedMarkId}) == 0) then if (player2.level > sbot_state[botId].initLevelT1) then aux.useEffect(summonGuardId,persPtr) aux.useEffect(summonedMarkId,my.persPtr) end end for _,persPtr in pairs(Team2) do local player2 = PERS(persPtr) if (player2.level > sbot_state[botId].initLevelT1) then if (#aux.activeEffects(persPtr, {artId = antivampId}) == 0) then aux.useEffect(antivampId, persPtr) end if (#aux.activeEffects(persPtr, {artId = weakId}) == 0) then aux.useEffect(weakId, persPtr) end end end end end end end end end end -- end state.nextCheckCustom = ostime + checkTO end -- Gamelogic Stop end ------------------------------------------------------- guards_main ---------------------------------------------------- --------------------------------------------------- human guard -------------------------------------------------------- function guards_3_0_human() local wait = 2 guards_3_0_human_init(wait) guards_3_0_human_run_once() local summonGuardId = 34047 local summonedMarkId = 34049 local race = 2 local level = 14 local checkTO = 1 local shieldId = 34097 local antivampId = 34094 local weakId = 34096 guards_3_0_human_cycle_fastest(summonGuardId, summonedMarkId, race, level, checkTO,shieldId,antivampId,weakId) end --------------------------------------------------- human guard -------------------------------------------------------- --------------------------------------------------- magmar guard ------------------------------------------------------- function guards_3_0_magmar() local wait = 2 guards_3_0_human_init(wait) guards_3_0_human_run_once() local summonGuardId = 34048 local summonedMarkId = 34049 local race = 1 local level = 14 local checkTO = 1 local shieldId = 34097 local antivampId = 34094 local weakId = 34096 guards_3_0_human_cycle_fastest(summonGuardId, summonedMarkId, race, level, checkTO,shieldId,antivampId,weakId) end --------------------------------------------------- magmar guard -------------------------------------------------------