Гайд по написанию скриптов для гомункулусов
-
У меня на TACT_SNIPE крашится причем подозреваю, что из-за моего бага уже. А танкует нормально, правда пробовал на одном мобе только и АИ не чистый а сильно перелопаченный.
-
ну у меня падало сразу, так что если не падает значит не падает. Правда есть шанс что ты его починил во время перелопачивания) Давно твой исходный аззи был скачан?
-
ну у меня падало сразу, так что если не падает значит не падает. Правда есть шанс что ты его починил во время перелопачивания) Давно твой исходный аззи был скачан?
-
тоесть есть вариант перенести все настройки тактики для мобов с одного аи в другой? а как? обьясните по пунктам на пальцах)
-
тоесть есть вариант перенести все настройки тактики для мобов с одного аи в другой? а как? обьясните по пунктам на пальцах)
-
вручную, просто прописывая в новом аи настройки аналогичные настройкам в старом. У аззи и мирки разный формат конфига. Можно, конечно, написать конвертер, но думаю стоит это делать только если у вас количество записей сотнями исчисляются
-
вручную, просто прописывая в новом аи настройки аналогичные настройкам в старом. У аззи и мирки разный формат конфига. Можно, конечно, написать конвертер, но думаю стоит это делать только если у вас количество записей сотнями исчисляются
-
В блокноте есть мегакрутой конвертер для этих целей, вызывается сочетанием Ctrl+H
-
В блокноте есть мегакрутой конвертер для этих целей, вызывается сочетанием Ctrl+H
-
конвертер в моем понимании подал на вход одно, нажал кнопку, получил на выходе другое, а все остальное - так, полуавтоматика в лучшем случае
-
конвертер в моем понимании подал на вход одно, нажал кнопку, получил на выходе другое, а все остальное - так, полуавтоматика в лучшем случае
-
Для разнообразия решила покачать джобы в московии, а там от скуки решила добавить танкование в мираи.
Идея была следующая: в AI.lua в функции
[code:a03m5yaj]--------------------------------------------------
function OnATTACK_ST()
--------------------------------------------------[/code:a03m5yaj]
вместо
[code:a03m5yaj]DoCombat()[/code:a03m5yaj]
вставляем:
[code:a03m5yaj] if ((EnemyTarget ~= MyID) or (HTact.Behav ~= BEHA_tank)) then
DoCombat()
end[/code:a03m5yaj]И вносим соответствующее поведение в GetEnemyNoKS или как её. У меня не в неё, а в функции, которые она использует.
Естественно, в const.lua следует добавить
[code:a03m5yaj]BEHA_tank = 15 -- Tank mob[/code:a03m5yaj]Возникло два вопроса.
- Почему-то иногда, когда хозяин начинает бить моба, лифка всё же присоединяется. Довольно часто (на леших реже, на лесавках чаще), но не всегда. Не очень понимаю. Дело не в участке "помогать хозяину" - во-первых, там есть проверка на "другого врага", во-вторых, чтобы не сомневаться, я отключала этот участок... и больше, вроде как, DoCombat() не вызывается ниоткуда вообще.
- Может мне кто-нибудь кинуть оригинальный код GetEnemyNoKS, чтобы я могла сгенерировать соответствующую правку для не-модифицированной мирки? Если кому-нибудь нужно, конечно ^^''
upd: (1) поняла - похоже, дело в том, что даже неагрессивные мобы могут переключать цель время от времени. Меня лесавка сейчас куснула, на лифку заагренная. Сейчас посмотрю, как это будет действовать, если не руками бить, а кастами.
upd2: Вроде бы, пока моб не переагривается, всё нормально. Подпись, печать ><
-
Для разнообразия решила покачать джобы в московии, а там от скуки решила добавить танкование в мираи.
Идея была следующая: в AI.lua в функции
[code:a03m5yaj]--------------------------------------------------
function OnATTACK_ST()
--------------------------------------------------[/code:a03m5yaj]
вместо
[code:a03m5yaj]DoCombat()[/code:a03m5yaj]
вставляем:
[code:a03m5yaj] if ((EnemyTarget ~= MyID) or (HTact.Behav ~= BEHA_tank)) then
DoCombat()
end[/code:a03m5yaj]И вносим соответствующее поведение в GetEnemyNoKS или как её. У меня не в неё, а в функции, которые она использует.
Естественно, в const.lua следует добавить
[code:a03m5yaj]BEHA_tank = 15 -- Tank mob[/code:a03m5yaj]Возникло два вопроса.
- Почему-то иногда, когда хозяин начинает бить моба, лифка всё же присоединяется. Довольно часто (на леших реже, на лесавках чаще), но не всегда. Не очень понимаю. Дело не в участке "помогать хозяину" - во-первых, там есть проверка на "другого врага", во-вторых, чтобы не сомневаться, я отключала этот участок... и больше, вроде как, DoCombat() не вызывается ниоткуда вообще.
- Может мне кто-нибудь кинуть оригинальный код GetEnemyNoKS, чтобы я могла сгенерировать соответствующую правку для не-модифицированной мирки? Если кому-нибудь нужно, конечно ^^''
upd: (1) поняла - похоже, дело в том, что даже неагрессивные мобы могут переключать цель время от времени. Меня лесавка сейчас куснула, на лифку заагренная. Сейчас посмотрю, как это будет действовать, если не руками бить, а кастами.
upd2: Вроде бы, пока моб не переагривается, всё нормально. Подпись, печать ><
-
Как вариант - раз в сколько-то времени поддерживать агро на хомяке, пиная моба.
-
Как вариант - раз в сколько-то времени поддерживать агро на хомяке, пиная моба.
-
Loneliness, эта функция?
! [code:1v9tylrq]--------------------------------------------------
! function GetMyEnemy_AnyNoKS(myid)
! --------------------------------------------------
! -- Log(string.format("---- AGGRESSIVE SCAN STARTED for ID (%d)", myid))
! local result = 0
! local actors = GetActors ()
! local players = {}
! local player_idx = 1
! local enemy_1st = {} -- primary targets
! local index_1st = 1
! local enemy_std = {} -- normal targets
! local index_std = 1
! local enemy_lss = {} -- last targets
! local index_lss = 1
! local mob_type, mob_target, mobBehav, ListedType
! local EnemyMaxHP
! local HomunMaxHP = GetV(V_MAXHP, MyID)
!
! for i,v in ipairs(actors) do -- fill the (not "friend") player list
! if (v ~= OwnerID and v ~= MyID) then
! if (0 == IsMonster(v)) then
! if isNotFriend(v) then
! players[player_idx] = v
! player_idx = player_idx + 1
! end
! end
! end
! end
!
! for i,v in ipairs(actors) do
! if (v ~= OwnerID) and (v ~= MyID) then -- owner and homunculus aren't valid target, of course
! if (IsMonster(v) == 1) and (BlockedPathToEnemyID ~= v) then -- if target is a (reachable) monster
!
! local isOKToAttack = false
! mob_type = GetV(V_HOMUNTYPE, v) -- get tact data
! mobBehav = GetTact(V_TACTBEHAV, mob_type)
! if( (mobBehav == BEHA_attack_1st)
! or (mobBehav == BEHA_attack)
! or (mobBehav == BEHA_attack_last)
! or (mobBehav == BEHA_attack_weak)
! ) then -- OK, this a type of monster to attack
! if isMobMotionOK(v, players) then
! mob_target = GetV(V_TARGET, v) -- check for the monster's target
! if (mob_target == 0) then -- if the monster is not in battle
! isOKToAttack = true -- he/she can be attacked, unless...
! for i2,v2 in ipairs(players) do
! if (v == GetV(V_TARGET, v2)) then
! isOKToAttack = false -- ...another player is already aiming at him/her (anti-KS)
! break
! end
! end
! else -- else, if the monster is already in battle
! if (mob_target == MyID)
! or (mob_target == OwnerID)
! or (not isNotFriend(mob_target))
! or IsMonster2(mob_target) then
! isOKToAttack = true -- but with me/my owner/a friend, it's OK (anti-KS)
! end
! end
! end
! end
!
! if isOKToAttack then
! if (mobBehav == BEHA_attack_1st) then
! enemy_1st[index_1st] = v
! index_1st = index_1st + 1
! -- Log(string.format(" added to (1st) as enemyID %d", v))
! elseif (mobBehav == BEHA_attack) then
! enemy_std[index_std] = v
! index_std = index_std + 1
! -- Log(string.format(" added to (std) as enemyID %d", v))
! else -- BEHA_attack_last, BEHA_attack_weak
! enemy_lss[index_lss] = v
! index_lss = index_lss + 1
! -- Log(string.format(" added to (lss) as enemyID %d", v))
! end
! end
!
! end
! end
! end
!
! -- Searches for nearest target ---------------
! result = GetClosest(enemy_1st)
! if (result == 0) then
! -- Log("No primary target in range")
! result = GetClosest(enemy_std)
! end
! if (result == 0) then
! -- Log("No standard target in range")
! result = GetClosest(enemy_lss)
! end
! if (result == 0) then
! -- Log("No target in range")
! else
! Log(string.format("<aggressive scan> Target found (ID %d):", result))
! HTact = GetFullTact(GetV(V_HOMUNTYPE, result))
! end
!
! BlockedPathToEnemyID = 0
! -- Log("---- END OF AGGRESSIVE SCAN")
! return result
! end
! [/code:1v9tylrq] -
Loneliness, эта функция?
! [code:1v9tylrq]--------------------------------------------------
! function GetMyEnemy_AnyNoKS(myid)
! --------------------------------------------------
! -- Log(string.format("---- AGGRESSIVE SCAN STARTED for ID (%d)", myid))
! local result = 0
! local actors = GetActors ()
! local players = {}
! local player_idx = 1
! local enemy_1st = {} -- primary targets
! local index_1st = 1
! local enemy_std = {} -- normal targets
! local index_std = 1
! local enemy_lss = {} -- last targets
! local index_lss = 1
! local mob_type, mob_target, mobBehav, ListedType
! local EnemyMaxHP
! local HomunMaxHP = GetV(V_MAXHP, MyID)
!
! for i,v in ipairs(actors) do -- fill the (not "friend") player list
! if (v ~= OwnerID and v ~= MyID) then
! if (0 == IsMonster(v)) then
! if isNotFriend(v) then
! players[player_idx] = v
! player_idx = player_idx + 1
! end
! end
! end
! end
!
! for i,v in ipairs(actors) do
! if (v ~= OwnerID) and (v ~= MyID) then -- owner and homunculus aren't valid target, of course
! if (IsMonster(v) == 1) and (BlockedPathToEnemyID ~= v) then -- if target is a (reachable) monster
!
! local isOKToAttack = false
! mob_type = GetV(V_HOMUNTYPE, v) -- get tact data
! mobBehav = GetTact(V_TACTBEHAV, mob_type)
! if( (mobBehav == BEHA_attack_1st)
! or (mobBehav == BEHA_attack)
! or (mobBehav == BEHA_attack_last)
! or (mobBehav == BEHA_attack_weak)
! ) then -- OK, this a type of monster to attack
! if isMobMotionOK(v, players) then
! mob_target = GetV(V_TARGET, v) -- check for the monster's target
! if (mob_target == 0) then -- if the monster is not in battle
! isOKToAttack = true -- he/she can be attacked, unless...
! for i2,v2 in ipairs(players) do
! if (v == GetV(V_TARGET, v2)) then
! isOKToAttack = false -- ...another player is already aiming at him/her (anti-KS)
! break
! end
! end
! else -- else, if the monster is already in battle
! if (mob_target == MyID)
! or (mob_target == OwnerID)
! or (not isNotFriend(mob_target))
! or IsMonster2(mob_target) then
! isOKToAttack = true -- but with me/my owner/a friend, it's OK (anti-KS)
! end
! end
! end
! end
!
! if isOKToAttack then
! if (mobBehav == BEHA_attack_1st) then
! enemy_1st[index_1st] = v
! index_1st = index_1st + 1
! -- Log(string.format(" added to (1st) as enemyID %d", v))
! elseif (mobBehav == BEHA_attack) then
! enemy_std[index_std] = v
! index_std = index_std + 1
! -- Log(string.format(" added to (std) as enemyID %d", v))
! else -- BEHA_attack_last, BEHA_attack_weak
! enemy_lss[index_lss] = v
! index_lss = index_lss + 1
! -- Log(string.format(" added to (lss) as enemyID %d", v))
! end
! end
!
! end
! end
! end
!
! -- Searches for nearest target ---------------
! result = GetClosest(enemy_1st)
! if (result == 0) then
! -- Log("No primary target in range")
! result = GetClosest(enemy_std)
! end
! if (result == 0) then
! -- Log("No standard target in range")
! result = GetClosest(enemy_lss)
! end
! if (result == 0) then
! -- Log("No target in range")
! else
! Log(string.format("<aggressive scan> Target found (ID %d):", result))
! HTact = GetFullTact(GetV(V_HOMUNTYPE, result))
! end
!
! BlockedPathToEnemyID = 0
! -- Log("---- END OF AGGRESSIVE SCAN")
! return result
! end
! [/code:1v9tylrq] -
Да, эта, спасибо ^^ У меня она просто переписана для возможности выставления численных приоритетов и для ограничения минимальных хп/сп по мобам.
Как-то так должно быть. Не проверяла, но правка достаточно очевидна. Тут мобы для танкования считаются наиболее приоритетными наравне с attack_1st.
! [code:vrf7va6g]--------------------------------------------------
! function GetMyEnemy_AnyNoKS(myid)
! --------------------------------------------------
! -- Log(string.format("---- AGGRESSIVE SCAN STARTED for ID (%d)", myid))
! local result = 0
! local actors = GetActors ()
! local players = {}
! local player_idx = 1
! local enemy_1st = {} -- primary targets
! local index_1st = 1
! local enemy_std = {} -- normal targets
! local index_std = 1
! local enemy_lss = {} -- last targets
! local index_lss = 1
! local mob_type, mob_target, mobBehav, ListedType
! local EnemyMaxHP
! local HomunMaxHP = GetV(V_MAXHP, MyID)
!
! for i,v in ipairs(actors) do -- fill the (not "friend") player list
! if (v ~= OwnerID and v ~= MyID) then
! if (0 == IsMonster(v)) then
! if isNotFriend(v) then
! players[player_idx] = v
! player_idx = player_idx + 1
! end
! end
! end
! end
!
! for i,v in ipairs(actors) do
! if (v ~= OwnerID) and (v ~= MyID) then -- owner and homunculus aren't valid target, of course
! if (IsMonster(v) == 1) and (BlockedPathToEnemyID ~= v) then -- if target is a (reachable) monster
!
! local isOKToAttack = false
! mob_type = GetV(V_HOMUNTYPE, v) -- get tact data
! mobBehav = GetTact(V_TACTBEHAV, mob_type)
! if( (mobBehav == BEHA_attack_1st)
! or (mobBehav == BEHA_attack)
! or (mobBehav == BEHA_attack_last)
! or (mobBehav == BEHA_attack_weak)
! or (mobBehav == BEHA_tank)
! ) then -- OK, this a type of monster to attack
! if isMobMotionOK(v, players) then
! mob_target = GetV(V_TARGET, v) -- check for the monster's target
! if (mob_target == 0) then -- if the monster is not in battle
! isOKToAttack = true -- he/she can be attacked, unless...
! for i2,v2 in ipairs(players) do
! if (v == GetV(V_TARGET, v2)) then
! isOKToAttack = false -- ...another player is already aiming at him/her (anti-KS)
! break
! end
! end
! else -- else, if the monster is already in battle
! if (mob_target == MyID)
! or (mob_target == OwnerID)
! or (not isNotFriend(mob_target))
! or IsMonster2(mob_target) then
! isOKToAttack = true -- but with me/my owner/a friend, it's OK (anti-KS)
! end
! end
! end
! end
!
! if isOKToAttack then
! if ((mobBehav == BEHA_attack_1st) or (mobBehav == BEHA_tank)) then
! enemy_1st[index_1st] = v
! index_1st = index_1st + 1
! -- Log(string.format(" added to (1st) as enemyID %d", v))
! elseif (mobBehav == BEHA_attack) then
! enemy_std[index_std] = v
! index_std = index_std + 1
! -- Log(string.format(" added to (std) as enemyID %d", v))
! else -- BEHA_attack_last, BEHA_attack_weak
! enemy_lss[index_lss] = v
! index_lss = index_lss + 1
! -- Log(string.format(" added to (lss) as enemyID %d", v))
! end
! end
!
! end
! end
! end
!
! -- Searches for nearest target ---------------
! result = GetClosest(enemy_1st)
! if (result == 0) then
! -- Log("No primary target in range")
! result = GetClosest(enemy_std)
! end
! if (result == 0) then
! -- Log("No standard target in range")
! result = GetClosest(enemy_lss)
! end
! if (result == 0) then
! -- Log("No target in range")
! else
! Log(string.format("<aggressive scan> Target found (ID %d):", result))
! HTact = GetFullTact(GetV(V_HOMUNTYPE, result))
! end
!
! BlockedPathToEnemyID = 0
! -- Log("---- END OF AGGRESSIVE SCAN")
! return result
! end[/code:vrf7va6g]upd: Aiko Star, несложно, но смысла не вижу. Мне это нужно в основном, чтобы лифка добавляла 25% и не била моба дальше. Лешие и так не переагриваются, а лесавки очень быстро умирают (и у меня таки 194 фли). Ну, и на касты с расстояния лесавки тоже не идут (а если пойдут, то хом сразу начнёт их кусать), поэтому хрупкие интовые химы, по идее, тоже в безопасности.
Но если что, выглядеть это будет примерно так:
[code:vrf7va6g] if ( (EnemyTarget ~= MyID) or (HTact.Behav ~= BEHA_tank) or ((GetTick() - AgrPrevention_Last) > AgrPrevention_Delay ) then
DoCombat()
AgrPrevention_Last = GetTick()
end[/code:vrf7va6g]И где-нибудь в конфиг.луа объявить, соответственно,
AgrPrevention_Last = 0
AgrPrevention_Delay = 5000
(последнее - задержка между попинываниями в миллисекундах) -
Да, эта, спасибо ^^ У меня она просто переписана для возможности выставления численных приоритетов и для ограничения минимальных хп/сп по мобам.
Как-то так должно быть. Не проверяла, но правка достаточно очевидна. Тут мобы для танкования считаются наиболее приоритетными наравне с attack_1st.
! [code:vrf7va6g]--------------------------------------------------
! function GetMyEnemy_AnyNoKS(myid)
! --------------------------------------------------
! -- Log(string.format("---- AGGRESSIVE SCAN STARTED for ID (%d)", myid))
! local result = 0
! local actors = GetActors ()
! local players = {}
! local player_idx = 1
! local enemy_1st = {} -- primary targets
! local index_1st = 1
! local enemy_std = {} -- normal targets
! local index_std = 1
! local enemy_lss = {} -- last targets
! local index_lss = 1
! local mob_type, mob_target, mobBehav, ListedType
! local EnemyMaxHP
! local HomunMaxHP = GetV(V_MAXHP, MyID)
!
! for i,v in ipairs(actors) do -- fill the (not "friend") player list
! if (v ~= OwnerID and v ~= MyID) then
! if (0 == IsMonster(v)) then
! if isNotFriend(v) then
! players[player_idx] = v
! player_idx = player_idx + 1
! end
! end
! end
! end
!
! for i,v in ipairs(actors) do
! if (v ~= OwnerID) and (v ~= MyID) then -- owner and homunculus aren't valid target, of course
! if (IsMonster(v) == 1) and (BlockedPathToEnemyID ~= v) then -- if target is a (reachable) monster
!
! local isOKToAttack = false
! mob_type = GetV(V_HOMUNTYPE, v) -- get tact data
! mobBehav = GetTact(V_TACTBEHAV, mob_type)
! if( (mobBehav == BEHA_attack_1st)
! or (mobBehav == BEHA_attack)
! or (mobBehav == BEHA_attack_last)
! or (mobBehav == BEHA_attack_weak)
! or (mobBehav == BEHA_tank)
! ) then -- OK, this a type of monster to attack
! if isMobMotionOK(v, players) then
! mob_target = GetV(V_TARGET, v) -- check for the monster's target
! if (mob_target == 0) then -- if the monster is not in battle
! isOKToAttack = true -- he/she can be attacked, unless...
! for i2,v2 in ipairs(players) do
! if (v == GetV(V_TARGET, v2)) then
! isOKToAttack = false -- ...another player is already aiming at him/her (anti-KS)
! break
! end
! end
! else -- else, if the monster is already in battle
! if (mob_target == MyID)
! or (mob_target == OwnerID)
! or (not isNotFriend(mob_target))
! or IsMonster2(mob_target) then
! isOKToAttack = true -- but with me/my owner/a friend, it's OK (anti-KS)
! end
! end
! end
! end
!
! if isOKToAttack then
! if ((mobBehav == BEHA_attack_1st) or (mobBehav == BEHA_tank)) then
! enemy_1st[index_1st] = v
! index_1st = index_1st + 1
! -- Log(string.format(" added to (1st) as enemyID %d", v))
! elseif (mobBehav == BEHA_attack) then
! enemy_std[index_std] = v
! index_std = index_std + 1
! -- Log(string.format(" added to (std) as enemyID %d", v))
! else -- BEHA_attack_last, BEHA_attack_weak
! enemy_lss[index_lss] = v
! index_lss = index_lss + 1
! -- Log(string.format(" added to (lss) as enemyID %d", v))
! end
! end
!
! end
! end
! end
!
! -- Searches for nearest target ---------------
! result = GetClosest(enemy_1st)
! if (result == 0) then
! -- Log("No primary target in range")
! result = GetClosest(enemy_std)
! end
! if (result == 0) then
! -- Log("No standard target in range")
! result = GetClosest(enemy_lss)
! end
! if (result == 0) then
! -- Log("No target in range")
! else
! Log(string.format("<aggressive scan> Target found (ID %d):", result))
! HTact = GetFullTact(GetV(V_HOMUNTYPE, result))
! end
!
! BlockedPathToEnemyID = 0
! -- Log("---- END OF AGGRESSIVE SCAN")
! return result
! end[/code:vrf7va6g]upd: Aiko Star, несложно, но смысла не вижу. Мне это нужно в основном, чтобы лифка добавляла 25% и не била моба дальше. Лешие и так не переагриваются, а лесавки очень быстро умирают (и у меня таки 194 фли). Ну, и на касты с расстояния лесавки тоже не идут (а если пойдут, то хом сразу начнёт их кусать), поэтому хрупкие интовые химы, по идее, тоже в безопасности.
Но если что, выглядеть это будет примерно так:
[code:vrf7va6g] if ( (EnemyTarget ~= MyID) or (HTact.Behav ~= BEHA_tank) or ((GetTick() - AgrPrevention_Last) > AgrPrevention_Delay ) then
DoCombat()
AgrPrevention_Last = GetTick()
end[/code:vrf7va6g]И где-нибудь в конфиг.луа объявить, соответственно,
AgrPrevention_Last = 0
AgrPrevention_Delay = 5000
(последнее - задержка между попинываниями в миллисекундах) -
Обратный вопорос, как в Azzy сделать, чтобы мерк ждал смерти моба, но сам не бил его при этом?
1lvl арч в мск всё-равно дохнет от мантисов даже если прикрывать его забеганием химика и приоритетом атаки гома, а вот копейщик - держит и хп реген у него поприличнее ,да вот только подходит к лесавкам вплотную и они на него переагриваются.
Подозреваю что через сочетание TACT_REACT + KITE_ALWAYS, но KITE вообще не пашет почему-то.