Часто у начинающих скриптеров появляется такая проблема - запутанный и/или неоптимизированный код. Такая проблема была и у меня, и у многих других, ведь хорошими скриптерами не рождаются, а становятся.
Казалось бы, какая разница - лишь бы работало. Действительно, бывают ситуации, когда нужно защитить код, тогда можно запутывать код как вам угодно. Хороший пример - http://cheat-master.ru/forum/116-20818-1
Однако, зачастую, код редактируем мы сами. И чем проще и оптимизированней код, тем проще вам же будет его совершенствовать.
Используя много переменных, очень просто забыть какая за что отвечает. Тогда нам могут помочь константы. Они позволяют дать название чему угодно, в том числе и переменным. Согласитесь, удобнее писать X, Y и Z вместо, например, 1@, 2@ и 3@.
Однако с ними стоит быть аккуратным. Недавно, оптимизируя свой скрипт, я решил использовать константы. Одну из констант я назвал ANGLE, то есть угол. Я использовал эту константу в опкоде, который рисует текстуру. После этого эта текстура начала странным образом менять цвет в зависимости от поворота. Я долго не мог понять, в чем же дело. Но потом я все же решил проблему.
Стоит упомянуть о так называемых комментариях опкода. Они есть в каждом опкоде и игнорируются компилятором, и нужны для того, чтобы вы могли найти опкод, а также понять, что он делает. Например, в опкоде "0AB0: key_pressed 2" "key_pressed" - комментарий. Можно вообще не писать комментарии - "0AB0: 2". Именно поэтому я и допустил ошибку - в опкоде слово angle было комментарием. А после него я писал ANGLE - переменную, которую сделал константой. Получалось, что я указывал угол, да еще и компилятор воспринимал комментарий как константу. Угол стал еще и одним из цветов текстуры. Как только я понял, в чем дело, я очень быстро исправил свою ошибку - поменял название константы на ANG, и скрипт заработал как надо.
Зачем же это делать? Можно обойтись и без этого. Это действительно так, но если каждый раз тратить пару секунд на это, можно сэкономить гораздо больше времени. Почему? Например, попробуйте написать "1@ += 2@". Конечно, у вас ничего не выйдет, так как компилятор использует разные опкоды для сложения целых и дробных чисел. И он не знает, какие числа у вас в переменных в данном случае - целые или дробные.
Если же мы объявим переменные - напишем, что такая-то переменная хранит целые числа, а такая-то дробные, мы сможем использовать такие конструкции как "1@ += 2@".
Теперь, когда мы знаем, что это действительно полезно, возникает главный вопрос: как? Тут все просто:
Код
var 0@:int // переменная 0 хранит целые числа, например, 5 (можно писать и integer, но int короче) 1@:float // переменная 1 хранит дробные числа, например, 5.0 end
Вот и все, теперь стало гораздо проще работать с переменными.
Упомяну только об одном - нельзя складывать целые и дробные числа, в переменных они или нет. Чтобы добавить к дробному числу целое, например к 5.0 добавить 1, нужно дописать .0 - 1.0. С вычитанием, умножением, делением - делаем так же.
Сначала скрипт узнает позицию и угол игрока, после чего конвертирует в координаты карты и отображает текстуру на экране в этих координатах. Затем скрипт узнает координаты метки, конвертирует, и, опять же, выводит на экран. В обоих случаях используются переменные 1, 2 и 3 (а также 0, где хранится номер загруженной текстуры).
То есть, как только переменная не нужна, её можно использовать повторно. Можно даже менять её тип и хранить разные типы чисел - целые или дробные в разных частях скрипта. Однако, если вы объявляете переменные, при смене типа одной из них, её стоит переобъявить.
Что такое госаб (gosub)? Это вложение, то есть часть когда, куда можно перейти и вернуться обратно туда, откуда был осуществлен переход.
Часто в скриптах много раз используется один и тот же опкод, или даже несколько подряд. Например скрипт телепортирующий игрока. Возьмем, к примеру, скрипт "Бот для автобуса". Открыв его, можно увидеть, что скрипт много раз повторяет одно и то же действие, только координаты всегда разные. Можно существенно уменьшить размер скрипта, если использовать госаб.
Как же это сделать? Очень просто - добавляем в конец скрипта обычную метку, например ":TP", после которой написать один раз нужный опкод, в нашем случае -
После этого в каждом месте, где раньше было телепортирование, пишем:
Код
1@ = 1234.56 // X 2@ = 1234.56 // Y 3@ = 1234.56 // Z 0@ = 1000 // wait
Также в госаб можно добавить проверку на заданность 0@, и если не задано - устанавливать значение 1000, а перед return нужно будет сбрасывать значение переменной - устанавливать на 0. В таком случае задержку нужно будет задавать лишь в тех случаях, где автобус должен стоять на остановке.
Помимо этого у госаба есть скрытая возможность - его можно использовать как условие. Например:
Код
if gosub @test jf @start jump @start
:test 0AB0: key_pressed 2 return
Это может быть полезным, если нужно проверить несколько несовместимых условий.
Если скрипт большой, легко в нем запутаться. Но кто запрещает вам помечать нужные места?
Например, здесь происходит активация, используется такая-то клавиша, а здесь мы выводим на экран какую-то фразу, а вот тут телепортируем игрока.
Чтобы добавитьк комментарий, нужно написать "//", и все, что находится правде этих символов, будет игнорироваться компилятором. Пишите там все что считаете нужным. Также, можно комментировать область, заключив комментарий в фигурные скобки - "{комментарий}". В этом случае комментарий может быть даже посреди опкода, или занимать несколько строк.
Также, комментирование может быть полезно, если вы хотите исключить одну или несколько строк из скрипта, не удаляя их. Выберите одну, либо выделите несколько строк и нажмите CTRL + Q. Для разкомментирования используйте те же клавиши.
Это может быть полезно, если игра зависает, или вылетает при активации скрипта, и, таким образом исключая по очереди строки, можно найти проблемое место.
Переменным можно присваивать метку:
Код
1@ = @Label
После чего можно использовать динамический переход:
Код
jump 1@
Например:
Код
:Start 1@ = @Label jump 1@
:Label ...
Это можно использовать для изменения скрипта по ходу игры.
Часто вижу в скриптах wait. wait 1000, wait 100... Это все, конечно, хорошо, и в половине случаев этого хватает. Но в другой половине нужно, чтобы и задержка была, и, при этом скрипт еще и что-то делал. Например, чтобы можно было выключать скрипт в любой момент, а не "когда вы у сдачи мешка", при этом еще и зажимая кнопку.
В этот момент пора напомнить о двух последних переменных, которые являются таймерами. Многие читали справку, и помнят, что есть 32 обычных переменных (от 0@ до 31@) и два таймера - 32@ и 33@, значение которых постоянно увеличивается. Если быть точным, каждую миллисекунду на единицу, то есть каждую секунду на 1000.
Несмотря на то, что многие это знают, до сих пор ни в одном скрипте не видел их использования. До недавних пор, и я обходился без них, но недавно осознал, что с ними все будет гораздо удобнее.
Приступим. Обе переменные увеличиваются одинаково, так что разницы между ними нет, используем любую. А использовать их очень просто: достаточно написать, например, 32@ = 0, после чего в цикле проверять значение этой переменной. Например, нужно подождать секунду, тогда:
Код
32@ = 0 repeat wait 0 until 32@ >= 1000
Для незнакомых с циклом repeat ... until поясню, что цикл повторяется до тех пор, пока условие в until не станет верным. Другими словами, "повторять ... до тех пор пока не ..." А >=, то есть больше или равно я использую для тех случаев, когда скрипт может пропустить нужное значения из-за лага, да и попросту, из-за того, что wait 100 не то же самое, что и wait 0 100 раз. Проверьте сами, это даже не одна, а несколько секунд.
Как я уже говорил, это может быть полезно для той же проверки на нажатие клавиши, чтобы выключить скрипт. Для этого нужно добавить в цикл эту самую проверку:
Код
32@ = 0 repeat wait 0 if 0AB0: key_pressed 2 then jump @1 // тут прыжок на начало скрипта, метку ставьте свою, если начата кнопка ПКМ (измените на нужную) end until 32@ >= 1000
Вместо проверки можно написать что угодно, например, я в своем моде на coord master выводил в этом цикле 3D-текст на экран, так как его нужно выводить на экран в цикле, причем с задержкой 0. Но мы-то знаем, что 0 в качестве задержки гораздо больше, чем просто ноль.
Бывает, нужно записать в переменную больше 15 символов. Но переменная вида 0@v не может хранить больше. Как же быть? А почему бы не хранить текст в обычной переменой, без ограничений? Мне удавалось записать до 100 символов в одну переменную. Сначала пишем
Код
0AC8: 0@ = allocate_memory_size 260
потом записываем текст в переменную 0@, а когда она уже не нужна
Код
0AC9: free_allocated_memory 0@
Выше я писал о константах. Теперь вы можете увидеть их практическое применение. Зачем каждый раз лезть в справку для того чтобы посмотреть одну кнопку? Не проще ли использовать, например, VK_ENTER или VK_F? У нас есть такая возможность - нужно, всего лишь, вставить данный текст в файл и подключить к скрипту:
Это следует сохранить в файл и поместить неподалеку от места где лежат ваши исходники клео. Я положил в cleo/includes/vk_keys.txt Когда все готово, нужно подключить к скрипту, в котором будем использовать данные константы:
Код
{$I includes/vk_keys.txt}
Теперь можно писать, например, 0AB0: key_pressed VK_1
Представьте. Вы делаете что-то грандиозное. Прямо огромное. И тут вам не хватает переменных. Что же делать? Бросать все? Зачем? Ведь можно спокойно выделить область в памяти под свои нужды и хранить данные там. Сначала нам нужно выделить область в памяти.
Код
0AC8: 0@ = allocate_memory_size 100
Вместо 100 пишем необходимый размер. Сколько угодно. Но слишком большие числа писать не следует - вам, все равно, не понадобится, а память будет занята. Далее я бы рекомендовал очистить память. Проще говоря - забить нулями.
Код
0A8C: write_memory 0@ size 100 value 0 virtual_protect 0
Если этого не сделать, в нашем массиве будет мусор. Я думаю, это - информация хранившаяся здесь до выделения памяти. Проще говоря, она уже тут не нужна ни игре, ни нам. Теперь - две функции. Одна пишет в наш массив, другая - читает.
В комментариях написано, за что отвечают переменные, а также есть небольшой пример использования. Если вам нужно хранить что-то существеннее, чем 1 или 0 в вашем массиве, умножайте номер элемента на 4 (для того, чтобы элементы не затирали друг друга, получится, что 0 - 3 байты это первый эдемент, 4 - 7 - второй, и т.д.), а размер, соответственно, указывайте 4.
Теперь разберемся с таймерами. Скорее всего, вы уже знаете, что их всего 2. Это - 33 и 34 переменные (32@ и 33@ - нумерация с нуля). Теперь подумаем - как же сделать больше? Да очень просто. За определенный промежуток времени таймер увеличивается на определенное число. И если мы каждый такой промежуток времени будем добавлять столько же к любой переменной, получится еще один таймер! Причем их количество вообще получается неограниченным, если использовать в паре с массивом в памяти.
Код
while true 33@ = 0 wait 0 005A: 0@ += 33@ 0AD1: show_formatted_text_highpriority "%d %d" time 0 0@ 32@ end
Вот простенький пример скрипта. он делает из переменной 0@ еще один таймер и выводит его значение на экран. Если значение правого таймера слишком большое - не удивляйтесь, это часто происходит с игровыми таймерами. С нашим, кстати, этого не произойдет, зато он будет увеличиваться абсолютно синхронно с обычными. Также можно добавить "включатель" для таймера, и если он выключен, просто присваивать ему 0. А если отнимать от нашего таймера значение игрового таймера, получится не увеличивающийся, а уменьшающийся таймер.
Добавь в gosub, что еще можно использовать его как проверку, например для нескольких проверок не совместимых друг с другом. помогаю по пхп хтмл в лс писать <br\> верстаю сайты в лс тоже помог ставь +++ в репку
NRG-500, ну, смотри, например, у тебя скрипт узнает твои координаты и пишет в файл, после чего узнает координаты метки и тоже пишет в файл. Так как после записи твоих координат в файл, переменные больше не нужны (задача выполнена) - можно использовать те же переменные для метки.
NRG-500, используй прямо так, переменных в клео аж 34 штуки
Добавлено (13.12.2012, 15:31) --------------------------------------------- Monrecarlo, вместо создания машины напиши поиск машины с определенной моделью (вместо модели будет переменная), а потом, если найдена - телепорт ее к себе