ДЕСЯТЬ УРОКОВ СКРИПТИНГА В ИНЖЕКТЕ
Урок 1. Самая важная команда, синтаксис и "Hello, shard!"
Итак, вы стали счастливым обладателем инжекта, вам удалось его настроить (или для вас это сделал кто-то другой
), вы прочитали справочник по инжекту (составленный мной), более-менее разобрались в его менюшках и настройках… Но самое главное - скрипты - для вас все еще тайна за семью печатями? Ну что ж, этот небольшой учебник поможет вам освоить азы программирования на инжекте. Я не буду пытаться охватить все команды инжекта, но я покажу вам как пользоваться основными командами, а дальше… дальше вы уже сами.
А начнем мы с самой важной команды скриптов. Команды, без которой не обходится, фактически, ни один скрипт. Команды, которую вы можете использовать только в скриптах - большинство команд инжекта имеют как форму для скриптов, так и "консольную" форму, то есть вы их можете писать прямо в клиенте и запускать. Многие мелкие скрипты, кстати, именно так и устроены. При бинде их на клавишу просто перечисляются команды инжекта и вуаля - скрипт готов. Но я отвлекся. Так вот, эту команду в консоли вы написать не можете. Как некоторые из вас уже наверно догадались, это команда Wait() - пауза.
Wait() - ждать заданное количество миллисекунд.
Внутри скобок этой команды надо указать ей параметр - сколько миллисекунд ждать. 1 секунда - это 1000 миллисекунд. Поэтому Wait(1000) - это ждать 1 секунду. В конце этого урока я приведу пример как
не надо писать скрипты. А именно - скрипт который совершенно надежно подвешивает компьютер, на котором он запущен. И ошибка того скрипта в том, что в нем нету команды wait в нужном месте. Причем с самым маленьким параметром времени. Хотя бы wait(50) - и скрипт уже не подвесит вашу систему.
Паузы очень важны в ваших скриптах. Во-первых, нужно дожидаться, пока игра совершит какое-либо действие. Во-вторых, надо дожидаться появления какого-либо сообщения. В-третьих, надо дожидаться появления какого-либо чара или животного - в основном все скрипты состоят из пауз. Причем в начале, пока вы неопытны, вы будете использовать в основном фиксированные паузы, типа wait(4000) - ждать 4 секунды (именно столько вам надо ждать на Цитадели, чтобы сработал скил Хайдинг), в дальнейшем вы быстрее всего перейдете на использование динамических пауз - то есть пауз, длина которых заранее не определена, это просто паузы пока не совершится какое-либо событие. Но в основе этих динамических пауз все равно вы найдете команду wait.
Вот теперь пора познакомиться с синтаксисом скриптов инжекта.
Для начала, несколько слов о терминологии. Скрипт - это программа. Написанная на специальном языке. Основой для этого языка стал язык программирования Basic, причем в самой простой своей форме. Еще вам будут постоянно встречаться такие понятия, как функции и процедуры. По определению, функция получает какие-то параметры, обрабатывает их и возвращает какое-то значение. Процедура от функции отличается тем, что ничего не возвращает. На самом деле, разницы между процедурами и функциями никакой нету. Это те же самые скрипты. Или программы, как хотите. Зачастую функция, которая, по идее, что-то возвращает, будет вами использоваться как процедура - ну не нужен нам этот результат. А из процедуры можно вернуть результат "непрямым" способом. Да и параметры не обязательны. Головной скрипт (главный) - это тоже, фактически, процедура. Поэтому, если путаетесь - плюньте. Даже опытные программисты постоянно в этих терминах путаются и называют одно другим. Неважно. Главное - знать что все это отдельные программы.
Любой скрипт (программа) на языке скриптов инжекта всегда начинается с команды sub и заканчивается командой endsub. Скрипты пишутся в текстовые файлы, в одном файле может быть очень много скриптов (я даже затрудняюсь сказать сколько, у меня есть скрипта на 3000 строк кода, там этих функций и процедур под сотню, и ничего, все нормально живет в одном файле). Итак, любой скрипт должен выглядеть так:
Code:
sub MyScript()
……….
endsub
Тут есть одна тонкость, запомните ее на будущее - если вы напишете команду sub вначале скрипта с заглавной буквы, то есть Sub - этот скрипт не будет отражаться в списке скриптов, доступных к запуску в инжекте, но при этом будет спокойно запускаться из других скриптов. Поэтому многие скриптеры "прячут" свои функции и процедуры именно таким образом, чтобы они "не мешали" в списке скриптов к запуску.
После команды sub через пробел пишется имя этого скрипта. После имени указываются круглые скобки, в которые могут быть помещены 1 или несколько имен переменных для параметров скрипта. Если это функция или процедура.
(снова читаем тремя абзацами выше).
Но к параметрам мы еще вернемся. А пока давайте напишем самый первый скрипт, используя те знания, что уже получили:
Code:
sub MyWait()
wait(3000)
endsub
Этот скрипт делает всего одну вещь - он ждет 3 секунды. То есть ничего не делает. Но работает.
Понятное дело, совершенно бесполезный скрипт. Пауза всегда нужна для чего-то, сама по себе она не нужна. Но ничего, счас изучим еще одну команду и сделаем первый рабочий скрипт. Эта команда – UO.Print(). Вывести сообщение.
UO.Print() – вывести информационное сообщение в игреВнутри скобок этой команды надо указать сообщение в кавычках и вы получите в игре это сообщение. Его видите только вы и на сервер оно не направляется. Например UO.Print( 'Privet' ) – выведет сообщение 'Privet'. Кавычки вы можете использовать как одинарные (апостроф), так и двойные - главное чтобы они были одинаковые в начале и в конце выражения. Давайте вставим такую команду в наш скрипт.
Code:
sub MyMessage()
UO.Print( "Hello, shard!" )
wait(3000)
endsub
Если вы сохраните и запустите этот скрипт он вам выдаст сообщение Hello, Shard!, потом подождет 3 сек (зачем-то) и закончит работу. Пауза здесь, как понятно, опять же не у дел. Но не будем ее трогать, а просто добавим еще одну команду UO.Print.
Code:
sub MyMessage()
UO.Print( "Hello, shard!" )
wait(3000)
UO.Print( "I go!" )
endsub
Вот теперь все встало на свои места. Скрипт говорит: "привет, шард", ждет три секунды и добавляет: "я иду"...
Все было бы хорошо, но вот только ваше приветствие кроме вас никто и не увидит... Лучше бы было, если бы эти фразы произносил ваш чар, тогда все кто рядом будут их "слышать". Нет проблем:
UO.Say() - произнести фразу чаром в игреТак что если мы заменим в нашей программе UO.Print на UO.Say - получится то, что надо.
Code:
sub MyMessage()
UO.Say( "Hello, shard!" )
wait(3000)
UO.Say( "I go!" )
endsub
На самом деле язык скриптов инжекта содержит множество разных команд, которые позволяют выводить, говорить чаром, говорить минуя чара в игре и т. д. Потом, может быть, мы к этой теме еще вернемся, а пока этих двух команд нам вполне хватит.
Продолжим рассматривать синтаксис скриптов. Теперь поговорим о переменных. Переменная - это какое-то имя, заданное вами, которому в скрипте вы можете присваивать различные значения. Перед использованием переменную нужно создать. В более сложных языках программирования переменные обычно надо задавать указывая их тип: числовые, строковые и т. д. В инжекте вам это не требуется. Главное - ее создать. Создать ее можно перед самим использованием, но хорошей привычкой будет создавать все нужные вам переменные (пока не станете опытным скриптописателем) в начале скрипта. Для этого используется оператор VAR:
VAR myvar1, myvar2, myvar3 ...Имена myvar1 и т.д. - это просто пример имен. Имя может быть любым, главное чтобы оно состояло из английских букв и цифр и не имело пробелов. Дефисы тоже допустимы. Цифру в начало имени не ставим.
Значение переменной присваивается знаком равно (=). Это можно сделать отдельной строкой, а можно сделать в операторе VAR:
VAR i = 1, mymessage1 = 'Hello, Shard!', mymessage2 = "I go!"Вот тут переменная i числовая, мы ей присвоили единицу, остальные две переменные строковые - им мы присвоили свои сообщения. Естественно, в скрипте мы можем присвоить переменной новое значение в любой момент. Для этого ее создавать снова не надо, достаточно в отдельной строке скрипта написать:
i = 2И все. Давайте перепишем наш скрипт на приветствие через переменные:
Code:
sub MyMessage()
VAR mymessage1 = 'Hello, Shard!', mymessage2 = "I go!"
UO.Say( mymessage1 )
wait(3000)
UO.Say( mymessage2 )
endsub
Теперь мы передаем командам UO.Say не конкретный текст, а имена переменных, этот текст содержащих. По фигу. Одно и тоже.
Вот теперь стоит вернуться к функциям и процедурам. Давайте посмотрим как нам их писать (возращаемые значения пока рассматривать не будем, так что речь идет о процедурах).
Code:
sub MyMessage()
VAR mymessage1 = 'Hello, Shard!', mymessage2 = "I go!"
MySay( mymessage1 )
MySay( mymessage2 )
endsub
sub MySay( myparam )
UO.Say( myparam )
wait(1000)
endsub
У нас теперь два скрипта. Первый - основной, в нем мы создаем две переменных с приветствиями, и дважды вызываем процедуру MySay, передавая ей в качестве параметра имя переменной с сообщением. Потом у нас идет эта процедура, в имени которой в качестве параметра написано myparam - это мы определили новую переменную, в которую будет попадать параметр, переданный в эту процедуру. То есть текстовую строку. А дальше - процедура выводит ее на экран и ждет 1 сек.
Кстати, созданные вами переменные действуют только в пределах того скрипта (функции, процедуры), в которой вы их создали. В другом скрипте вы можете снова использовать эти же имена - это все равно будут другие переменные.
Вот с этим (все что выше) вам надо очень внимательно разорбраться. В дальнейшем я подобные вещи подробно расписывать не буду. Так что если хоть что-то осталось непонятно - перечитайте еще раз, попробуйте сами.
Теперь несколько слов о тех переменных, которые уже существуют в инжекте. Вы не можете использовать их имена, но вы можете использовать значения этих переменных просто указав в скрипте их имя. Перечислю основные:
UO.Life - текущее здоровье вашего чара
UO.Mana - текущее количество маны вашего чара
UO.Stamina - текущее количество стамины вашего чара
UO.STR - уровень силы вашего чара
UO.INT - уровень интеллекта вашего чара
UO.DEX - уровень ловкости вашего чара
UO.Weight - вес вашего чара
UO.Armor - текущий армор-класс вашего чара
UO.Gold - суммарное количество денег (бэкпак и банк) вашего чара
UO.BM - количество рега bloodmoss в паке у вашего чара
UO.BP - количество рега black pearl в паке у вашего чара
UO.GA - количество рега garlic в паке у вашего чара
UO.GS - количество рега ginseng в паке у вашего чара
UO.MR - количество рега mandrake root в паке у вашего чара
UO.NS - количество рега nightshade в паке у вашего чара
UO.SA - количество рега sulfurous ash в паке у вашего чара
UO.SS - количество рега spider's silk в паке у вашего чара
UO.VA - количество паган рега volcanic ash в паке у вашего чара
UO.EN - количество паган рега eyes of newt в паке у вашего чара
UO.WH - - количество паган рега wyrm's heart в паке у вашего чара
UO.FD - количество паган рега blackmoor в паке у вашего чара
UO.BR - количество паган рега fertile dirt в паке у вашего чара
UO.H - количество поушенов heal в паке у вашего чара
UO.C - количество поушенов cure в паке у вашего чара
UO.M - количество поушенов mana в паке у вашего чара
UO.L - количество поушенов refresh в паке у вашего чара
UO.B - количество бинтов в паке у вашего чара
UO.AR - количество стрел в паке у вашего чара
UO.BT - количество болтов в паке у вашего чараВы не можете изменять эти переменные, они автоматически изменяются в игре, но вы можете использовать их в своих скриптах. Не буду приводить примера, тут и так все ясно. Позже в примерах мы будем эти переменные активно использовать.
Теперь посмотрим как устроен скрипт. В скрипте каждая команда должна идти на отдельной строке, объединять несколько команд в одну строку нельзя. Если вам нужно просто выполнить несколько команд по очереди - это самый простейший вид скриптов, то вы пишете каждую команду в отдельную строку (именно так мы и делали в скрипте на приветствие) и все. Но такое требуется редко. Обычно в скриптах нужно проверять выполнение каких-нибудь условий, в зависимости от этого выполнять разные действия, повторять какой-то набор действий либо фиксированное количество раз, либо пока не выполнится определенное условие. Для этого нам потребуются условные операторы и циклы.
Простейший условный оператор - If. Выглядит он так:
Code:
If условие Then
.........
Endif
Если условие выполняется тогда делать то-то и то-то. Расширенный вариант этого условного оператора:
Code:
If условие Then
...........
Else
...........
Endif
Если условие выполняется тогда делать то-то и то-то, иначе (если условие не выполняется) - делать другое что-то. Условный оператор If является простейшим способом проверки выполнения условия. И одним из основных. Давайте переделаем наш пример на приветствие с использованием проверки условия. При этом введем еще переменную i которой в начале присвоим 1.
Code:
sub MyMessage()
VAR i = 1
VAR mymessage1 = 'Hello, Shard!', mymessage2 = "I go!"
If i == 1 Then
UO.Say( mymessage1 )
Else
UO.Say( mymessage2 )
Endif
endsub
Внимательно посмотрите на пример. Во-первых, у нас появилось две строки с VAR. Их вообще может быть сколько угодно. Во-вторых, условие в If. Тут мы используем знак == - сравнение двух значений. Не путайте его с присваиванием (=). Если написать If i = 1 Then - вы получите ошибку. Что теперь делает наш скрипт? На самом деле он выводит только первое приветствие, второе не будет выводиться никогда. Разберитесь сами почему. Попробуйте в строке VAR i = 1 единицу заменить на 2. Посмотрите на результат. А я иду дальше.
Следующим оператором, важным для скриптинга в инжекте является while.
Code:
While условие
...
Wend
Повторять действия до тех пор, пока выполняется условие. Проверка условия производится
перед выполнением действий! То есть если условие не выполняется - никаких действий не будет. Скрипт сразу перейдет на следующую команду, расположенную сразу за словом wend. Вот теперь мы можем переделать наш скрипт на новый лад.
Code:
sub MyMessage()
VAR i = 1
VAR mymessage1 = 'Hello, Shard!', mymessage2 = "I go!"
While i < 3
If i == 1 Then
UO.Say( mymessage1 )
Else
UO.Say( mymessage2 )
Endif
i = i + 1
Wend
endsub
Вот тут рассмотрим работу скрипта подробнее. Вначале у нас переменная i равна 1. Приходим к while. Проверяется i, меньше ли оно 3. 1 меньше чем 3, значит все что между while и wend будет выполняться. Здесь проверяется - равно ли i единице - равно. Поэтому сработает команда UO.Say( mymessage1 ). В результате чар скажет первое приветственное сообщение. Выход из if - следующий оператор i = i + 1. В нем переменная i будет увеличена на 1. Это стандартный способ увеличения счетчиков (такие переменные в скритптах обычно называют счетчиками) на какую-то величину. То есть к переменной i прибавляется 1 и результат сложения записывается в переменную i. В результате в переменная i будет равна 2. Дальше следует wend - значит переходим снова к строке While i < 3. Это условие опять выполняется (2 меньше 3). Теперь проверяется условие If. 2 не равно 1, поэтому условие не выполняется и будет выполнено действие после Else. То есть UO.Say( mymessage2 ) - получим на экране второе приветственное сообщение. Теперь опять счетчик увеличивается на 1 - i будет равно 3. Опять переходим на проверку условия в While - вот теперь оно не выполняется (3 не меньше 3) - соответсвенно сразу переходим на оператор после wend - а там у нас конец скрипта.
Разбирайтесь с этим примером столько раз, сколько потребуется чтобы все понять. Очень мало будет вам встречаться скриптов в которых нету операторов if, while и оператора repeat - аналогичного оператору while с некоторыми изменениями.
Code:
repeat
....................
until условие
Выполнять действия пока условие НЕ выполняется. Проверка условия производится
после действий! Этот оператор отличается от while - только этими двумя вещами, названными мной, но при этом это отличие принципиальное! Давайте рассмотрим маленький пример.
Code:
while i < 3
wait( 1000)
wend
Code:
repeat
wait(1000)
until i > 2
Вот два цикла. Условие в обоих одно и то же по действию - в первом случае цикл выполняется пока i меньше 3, во втором случае пока не выполняется i > 2. То есть пока i < 3. Проще всего это понять подставив вместо i разные числа. Если например i равняется 2: 2 меньше 3 - это верно, while выполняется. 2 не больше 2 - то есть условие в until не выполняется - значит действия в repeat выполняются. Понятно? Вот теперь насчет "после". Предположим, что i равно 3. Что у нас происходит? В цикле while проверка производится перед действиями - так как 3 не меньше 3, то никаких действий не производится, скрипт сразу переходит к командам после wend. В случае же repeat - проверка производится после действий, поэтому одна пауза в 1 секунду все равно будет выполнена! После этого проверка 3 > 2 выдаст истину и цикл repeat будет прерван. Итак, цикл repeat важен тем, что указанные в нем действия будут выполняться по крайней мере 1 раз!
Вот мы и подбираемся к концу первого урока. Это далеко не все операторы языка скриптов инжекта, но пока нам хватит и их. Другие операторы мы рассмотрим позже. А счас, как и обещал в начале, привожу пример (у вас достаточно знаний чтобы этот скрипт понять) скрипта, как не надо писать скрипты
Code:
sub MyScript()
While UO.Life > 0
If UO.Life < 70 Then
UO.Bandageself()
wait(2000)
Endif
Wend
endsub
Этот скрипт - это попытка написать автополхилл чара. Цикл while "крутится" пока здоровья больше 0, то есть пока чар не умрет. Если здоровья становится меньше 70 - чар лечится с бинтов (именно это и делает команда UO.Bandageself() ). В чем же ошибка этого скрипта? Эта ошибка называется "пустой цикл". Давайте проверим, что происходит во время работы этого скрипта. А именно, если здоровья у чара больше 70 (или равно). В этом случае действия внутри if...endif не выполняются, и цикл while...wend становится пустым, то есть в нем не производится никаких действий. Скриптовый модуль инжекта устроен так, что в этом случае вы получите 100%-загрузку процессора вашего компьютера (зависнет) и, быстрее всего, креш игры или системы. Как избежать такого конца? Очень просто. Предусмотреть чтобы в скрипте
всегда какие-нибудь действия производились. В данном случае вполне достаточно добавить Else:
Code:
sub MyScript()
While UO.Life > 0
If UO.Life < 70 Then
UO.Bandageself()
wait(2000)
Else
wait(50)
Endif
Wend
endsub
Вот смотрите: мы добавили в скрипт паузу в 50 миллисекунд, то есть 0,005 секунды, а скрипт сразу заработал.
Ну и напоследок. Обратите внимание на то, как я привожу скрипты. А именно на отступы. Старайтесь сразу приучить себя использовать подобный стиль написания. Это облегчит понимание скриптов и вам, и тем другим, кто их будет смотреть. А чем легче читается скрипт, тем проще найти в нем ошибки.