Гайд по написанию скриптов для гомункулусов
-
Так, а че делать тем, кто ничего не понял? И врядли у него это получится? Я че буду без покемона? :shock:
-
Урок пятый: Текстовые файлы, автоскиллы, киллстил и прочие вкусности.
Прежде чем всю эту фигню продолжить, выскажусь.
Произучав два самых, на мой взгляд, популярных и мощных из вышедших скриптов для покемонов, я уж и не знаю, имеет ли смысл МНЕ чего-либо пытаться сделать на этом поприще.
МирАИ - универсальная "попсовая" машинка для ленивых со внешним графическим конфигом, обладающая довольно большой гибкостью.
РэмпейджАИ - это... это гениально. Полмегабайта (552 килобайта) чистого кода с комментариями - в последней релизной версии с дополнениями Накаямы. Умеет все, от проверки пвп- или гв-зон до отдачи ЛЮБЫХ команд "цифровым" передвижением покемона и эмулированием клиента РО для отладки собственного скрипта. Считает трафик, имеет специальные противолаговые функции работы скрипта, определяет варпы на карте (как - хз, мой мосск эту функцию не осилил), определяет время неуязвимости на гв 1.0 (нынче, уже, правда неактуально, но все же)... Честно - сняла бы шляпу, если бы она у меня была. Не знаю, сколько лет это писалось, но... в общем, вот.Немного отойдя от общих впечатлений, вернемся все-таки к обещанному.
Интересные и важные замечания/плюшки.
Заметки к скиллам покемонов, согласно readменя замечательного и всеми любимого MirAI (проверять эти утверждения надо ВСЕ, ибо последняя версия MirAI датируется концом 2006 года):
- Castling барашка не работает (вроде бы работало, когда мя с ним бегала недавно).
- Chaotic Blessings ванильки не работает через скрипты (только запуск вручную через панель).
- Accelerated Flight филира не работает вообще (возможно, актуально до сих пор, т.к. в RampageAI этот скилл тоже отнесен к неработающим).
Баг обработки скрипта:
Кроме скиллов, отталкивающих покемона назад (Charge Arrow и т.п.), наблюдается баг Гравити: даже с пустым AI скриптом покемончик подползает к стреляющим мобам, которые его ударили.
Надо проверять, опять же.Плюшки из RampageAI
Дополнения к константам:
-- возвращаемые значения для GetV(V_MOTION,id)
MOTION_STAND = 0 -- Стояние на месте
MOTION_MOVE = 1 -- Движение
MOTION_ATTACK = 2 -- Атака
MOTION_DEAD = 3 -- Смерть (трупиком лежит О.о)
MOTION_DAMAGE = 4 -- Получение повреждений
MOTION_BENDDOWN = 5 -- Э... наклоны х_х (при взятии лута, установки трапов, etc.)
MOTION_SIT = 6 -- Сидит
MOTION_SKILL = 7 -- Использует скилл (анимация окончания каста)
MOTION_CASTING = 8 -- Кастует скилл
MOTION_ATTACK2 = 9 -- Атака 2 (в оригинале в скобочках стоит "double dagger?", вероятно, Роберт сам так и не разобрался)
MOTION_TOSS = 12 -- Бросок чего-нибудь (spear boomerang / aid potion)
MOTION_COUNTER = 13 -- Counter-attack
MOTION_PERFORM = 17 -- Performance (скиллы бардов/данс?)
MOTION_JUMP_UP = 19 -- Тыквопрыг - взлетает
MOTION_JUMP_FALL= 20 -- Тыквопрыг - приземляется
MOTION_SOULLINK = 23 -- Soul linker использует линк
MOTION_TUMBLE = 25 -- Tumbling / тыквопрыг приземление (а разницы от того, что раньше было?)
MOTION_BIGTOSS = 28 -- "серьезный" бросок (slim поты / acid demonstration)Выдержки из комментариев к коду RampageAI.
- Покемоновский GetV(V_MOTION) никогда не возвращает MOTION_ATTACK, если применять на самого покемона. Вообще никогда.
Проверить бы... - Слух: ПВП-игроки показываются как противники, если они не в нашей пати.
Замечание: НЕПРАВДА!! ПВП-игроки всегда показываются как противники.
Знать бы еще, что нам это дает и что он подразумевает под противниками... функцию IsMonster()?
-- Check when the last received command was
function AMC_Check()
-- Check if we should be checking... XD
Без комментариев. Мя посмеялосьАнти-киллстил (на примере фукнции MirAI)
[code:8bhd8pjq]function isKS()
if 0 == IsMonster(MyEnemy) then return false; endlocal mob_target = GetV(V_TARGET, MyEnemy) if mob_target > 0 then if not IsMonster2(mob_target) then if (mob_target == MyID) or (mob_target == OwnerID) or (Friends[mob_target] ~= nil) then return false else Log("MyEnemy was already in battle, action aborted (anti-KS)") return true end end end local actors = GetActors() for i,v in ipairs(actors) do if (v ~= OwnerID) and (v ~= MyID) then if 0 == IsMonster(v) then if isNotFriend(v) then if GetV(V_TARGET, v) == MyEnemy then Log("Another player is aiming at MyEnemy, action aborted (anti-KS)") return true end end end end end return false
end[/code:8bhd8pjq]
Многа букф. Но будем разбирать, что поделать...
Перво-наперво, если наша цель - не моб (игрок, вестимо), то функция завершается. Как сказано в комментариях Rampage AI: "Нельзя скиллстилить игрока О.о"
Затем идет пачка проверок. Во-первых, берется цель нашей цели. Если эта цель есть, проверяем, выцеливают ли нас (хима, покемона или друга). Если выцеливают, то украсть мы ничего не можем, стало быть, можно бить (пока что). Если выцеливают не нас, то бить нельзя, о чем и пишем.
Вторая проверка - выцеливает ли кто-то еще нашу выбранную цель. Перебираем всех действующих лиц на экране. Если они не мы (хим или покемон), смотрим, моб ли это. Если не моб, проверяем дальше - друг это или нет. Если не друг и если он выцеливает нашу цель, то мы эту цель бить не будем.
Вот. RampageAI использует другой алгоритм, который в том числе высчитывает расстояние от моба до ближайшего игрока и не трогает мобов, стоящих близко к другим персонажам. Рассматривать его мы не будем, поскольку там используется огромнейшее количество собственных функций, которые я задолбаюсь объяснять. Кому интересно - сами посмотритеРабота с внешними файлами на примере френд-листа (утащено из Rampage AI).
Часть первая, запись файлов:[code:8bhd8pjq] local filename = ScriptLocation .. "Conf/Friends.lua"
local savefile = io.open(filename, "w")
savefile:write(StringBuffer.Get(out))
savefile:close()[/code:8bhd8pjq]Что же тут творится? Рассмотрим построчно. Сразу замечание - это конкретно кусок кода открытия-записи файла, часть используемых тут переменных определяется раньше, но я их объясню.
Первым делом в локальную переменную filename кладется путь к френдлисту (переменная ScriptLocation задается при первом запуске AI. В скрипте используется замороченная функция проверки существования файлов, но если очень условно, то оно выглядит так:
[code:8bhd8pjq]ScriptLocation = "./AI/USER_AI/"[/code:8bhd8pjq]
Следующая строчка открывает файл Friends.lua и заносит в переменную savefile внутренний код для работы с открытым файлом (file handler или хэндлер, простите мой французский). У функции io.open в качестве первого параметра указывается путь к открываемому файлу, в качестве второго - режим работы с файлом. В примере мы открываем файл для записи. Вообще же эти режимы могут быть следующими:
"r": режим чтения (по умолчанию);
"w": режим записи;
"a": режим добавления;
"r+": режим обновления, все предыдущие записи защищены;
"w+": режим обновления, все предыдущие записи стираются;
"a+": режим добавления-обновления (append update x_x), все предыдущие записи защищены, запись в файл разрешена только в конец файла.
У этой функции есть дополнительный параметр для открытия файлов в бинарном режиме, но нам это нафиг не надо. Кому интересно - читайте мануал lua
Следующая строчка - запись в файл savefile отформатированной определенным образом переменной out, которая в скрипте задается ранее. Записывать в файлы можно текстовые и числовые переменные, для остальных надо использовать tostring или string.format ДО записи в файл.
Последняя строчка закрывает файл savefile, сохраняя все изменения. В принципе, можно их и не закрывать, но это может плохо кончиться и вообще считается дурным тоном в программировании :РКасательно косяков - мне кажется, что оно Rampage AI неправильно пишет этот самый френд-лист (переменная out в указанном примере неправильно формируется), но это надо на практике проверять, а не на работе
Часть вторая, чтение файлов:
[code:8bhd8pjq] local filename = ScriptLocation .. "Conf/Friends.lua"
local func = loadfile(filename)
if func ~= nil then
func()
end[/code:8bhd8pjq]В принципе, все просто. Единственная заморочка с локальной функцией func. Первым делом мы эту функцию приравниваем к результату стандартной функции Lua loadfile(), которая читает указанный в качестве параметра файл и... и читает.
Проверяем, пустой ли у нас этот файл (func ~= nil), если не пустой, то читаем все-таки его. Поскольку файл отформатирован в соответствии с синтаксисом Lua и представляет собой просто толстую переменную friends вида[code:8bhd8pjq]Friends = {
[ID] = true
}[/code:8bhd8pjq]где ID - тот самый ID аккаунта нашего друга (то есть переменная Friends в данном случае - список, в котором на ID-ом месте лежит true, если это наш друх. Сложно, но работает х_х), то, прочитав файл, мы сразу получаем эту переменную в свое распоряжение и можем к ней обращаться.
Вопрос - почему не используем require?
Ответ - потому что require подключает файл один раз. А список друзей у нас может меняться в течение функционирования скрипта, поэтому надо иметь возможно его загружать по мере необходимости. Что тут и делается.Альтернативная функция IsMonster2() [MirAI]
[code:8bhd8pjq]function IsMonster2(ID)
local mob_type = GetV(V_HOMUNTYPE, ID)
if (mob_type >=0) and ((mob_type < 1000) or (mob_type > 4000)) then
return false
end
return true
end[/code:8bhd8pjq]Забавная функция
Использует GetV с аргументом V_HOMUNTYPE для определения мобов. По идее, работает, проверить бы. Но идея хороша, да
Утилиты для работы с .lua-файлами:
"MirAI рекомендует":ConTEXT - хороший редактор с подсветкой синтаксиса:
http://www.context.cx/
Плагин для подсветки:
http://context.cx/component/option,com_doc...,100/Itemid,48/ -
И куда его потом просто в папку с РО ложить? ОМГ :shock: :shock: фпанике
-
Сонечко, в папке с клиентом есть папка AI, в ней - USER_AI, вот в нее и кидаешь. В игре прописываешь один раз (вообще один, не при каждом заходе) /hoai и... любуешься.
-
фух, если так, то я могу выйти из шока и ждать введения маленьких зверенышей. Спасибки.
-
Я вот тут подумала. Я вот ниче не понимаю, накидаю себе в папку каких-нить скриптов, а меня хоп и в бан, мол низя.
Предлагаю, для таких как я, а я думаю, я не одна, создать какой-нить "социальный пакет" - скрипты, самые необходимые, и самое важное, согласованные с администрацией.- Как будет реализовано правило, типа не создай себе игрового преимущества. Вот я не могу себе ниче придумать понятно, а вот другие (это им плюс большой, могут), получиццо, что мой покемон и покемон товарища - это совершенно разные по полезности зверушки. Ну я допустим еще на форум захожу, могу себе тут чего-нить накачать, а есть товарищи и этого не делают, тогда их покемон, будет еще хуже моего. Че делать?
Что-то я не могу себе полностью уяснить, или если скрипты не вводить, то покемон тоже самоебудет делать, только ему надо это будет указывать, или как?
Что дают эти скрипты такого кординальноо, или можно без них обойтись вообще. И тут какбы и правила не нарушишь, и в тоже время зверь не совсем безполезный. Объясните для тугодумов. Спасибо. -
Сонечко, пока что администрация (в лице Zeno) ограничилась коментариями, что в скрипте не должно быть автокача и что за киллстил будет отвечать сам владелец.
В общем со всеми готовыми скриптами идёт описание. По нему и следует ориентироваться. В общем советую избегать скриптов, где не написанно, что есть защита от киллстилла, где написанно, что есть возможность атокача и где есть автоматизация использования поушен пинчера и болтов с мечей. (на счёт последних 2 пунктов официально запрета не было, но я б поостерёгся - а то будет ка с редумптио у пристов: вначале забанят, а потом объявят, что нельзя было использовать).
Скрипты не вводить нельзя - есть скрипт по умолчаению, но он далёк от идеала: в частности киллстиллит.
Тему со скриптами можно сделать хоть сейчас (я могу даже этим заняться), но вот как провести согласование с администрацией - я без понятия. -
Поясню еще кое-что. Без скриптов нельзя. Если удалить скрипты вообще, то вызванный покемончик будет просто стоять на месте, не реагируя вообще ни на что.
Далее, так и не уяснила для себя, что есть автокач. Автоматическое нападение покемона на мобов? Так это делает и дефолтный скрипт. И это не автокач (в связи с введением 6-минутного ограничения на стояние на месте).
С киллстилом все вроде понятно, за исключением пары забавных фактов. Я пользуюсь скриптом с двойной проверкой на киллстил (атакуют ли другие игроки моба и атакует ли он сам других игроков). И моя ванилька пару раз утаскивала из чужих паровозов хая :lol: -
Скрипт в студию,если можно >_<
Заранее спасибо. -
Aiko Star, ну автокач - это скорее не особенность скрипта, а особенность применения.
Но скажем скрипт с "эмуляцией зелки" (хомяк бьёт того, кого атакует химик) к автокачу не способен. -
LisandreL, ну это-то понятно. И если начинает ковырять тех, кто обижает хозяина. Только как, например, определить (со стороны сервера или других игроков), когда хим отправляет покемона в атаку, а когда тот бежит самостоятельно? Бред, имхо. Автокач убили как таковой этими шестью минутами. За это время многого не набьешь (зверек не настолько крут).
Имхо, гомункулус интересен, во-первых, тем, что позволяет полностью себя настраивать (да-да, моя программистская натура просто визжала от радости :!: ), во-вторых, тем, что позволяет лениво бродить по карте, не трогая толком мобов самостоятельно и иногда швыряясь потами в зверюшку (это уже природная лень :!: ). Ограничить какой-либо из этих пунктов - убить основные отличия гомункулусов от обычных петов (не учитывая зелку и алису - это особенность мотра, я не про них) в корне. Вот :!:А вообще все это оффтоп уже. Тут - гайд и его обсуждение. Обсуждение же прочего прошу перенести или в топик "Гайд по прохождению квеста на гомункулусов", или в "АI Гомунклов".
-
В том то и дело, что описание скрипта и сам скрипт разные весчи, вот пошутит кто то, я то в иероглифах не пойму чего там на самом деле, и пару-тройку десятков химов в бане...
-
Сонечко, всегда можно покемона отозвать к себе, если он творит что не так. Или просто свернуть. Так что придется некоторое время внимательно за ним следить
-
тогда вопрос как удалить скрипт, если мой покемон пойдет косить на право и налево :))), просто из той папки, что мне писали вначале, вынять его и поставить другой, или еще чего то делать нужно будет?
-
Именно - вынуть и поставить другой.
-
Имхо
Личный скрипт ето преимущество в игре над другими игроками. А ето уже попадает под правила:) Нужно создавать специальный скрипт от администрация и блочить замены етих скриптов на другие. Иначе ето не дело;) -
Ранд, преимущество? Да. Необоснованное преимущество? Нет.
Даже если тебе самому лениво возиться со скриптами в нете полно готовых. А если уж тебе лень их найти и скачать, то кто в этом виноват, кроме тебя?
А то вот, например, пол форума стонет, что их лагает, а меня не лагает, так что же меня забанить теперь за это преимущество надо? :shock:
К создание скрипта надо расценивать... ну как к выбору эквипа. Куда-то этот лучше пойдёт, куда-то тот.P.S. Кстати, вот тебе ссылочка - настоятельно рекомендую ознакомиться, а то ты похоже в школе уроки пропускал и о существовании 31-ой буквы нашего алфавита даже не догадываешься.
-
Немножко оффтопик
Те, у кого на тестовом были агрессивные гомункулы - получалось ли их надежно сделать неагрессивными?.. Потому что мне удобнее был бы как раз тихий-мирный гомункул вроде Лиф, только с боевыми способностями Филира :). И не килстиллит, и танковать я сама смогу, и точно на паразитов не нападет, когда я их после скиллрезета возьму :).
Если нет, то можно ли несложным образом (мне лень разбираться со скриптами :() задать всем гомункулам пассивные скрипты неигровыми методами? Стереть агрессивные, например :). -
Скрипт один. На всех гомункулусов. И по умолчанию (скрипт, который предоставляет Гравити) он довольно туп. Никаких проверок на киллстил нет, агрессивные покемончики атакуют всех подряд (и травку химов тоже). Так что пользуйте готовые скрипты, если лень разбираться
PS Так как с РО завязала, за новостями сервера больше не слежу. Напишите сюда, когда патч все-таки введут, я напишу последнюю часть гайда, после чего можно будет совсем спокойно исчезнуть отсюда
-
А нельзя ли достать стандартный скрипт и заменить в нем то, что прописано для агрессивного поведения, на то, что прописано для пассивного?
Должно получиться дешево и сердито :).
Пойду поищу, что там есть в AI :).