Город Мастеров
IPB

Здравствуйте, гость ( Вход | Регистрация )

 Правила этого форума ПРАВИЛА РАЗДЕЛА
> Мануалы в помощь новичкам..., Читать обязательно...
MasterMage
сообщение Mar 22 2005, 18:10
Сообщение #1


Level 8
***

Класс: Маг
Характер: Lawful Good
Раса: Полуэльф



Вот, как и сказал Айв, создаю тему, посвященную моим статьям... Написал пока две: для квестов и скриптов. Обе в Worde, так как нету у мну такой умной проги, как у Айва... =) Одна про Квесты весит 1.6Мб в архиве, а другая про Скрипты всего 90-100 Кб, посему выставляю это, вторую, а первую потом как-нить, так как на ФТП не загружается так много(пробовал, хоть убейте, ни в какую!!!)

CODE
*************************  САМА СТАТЬЯ  **********************************


Данная статья является интеллектуальной собственностью. Любое использование ее материалов допускается только с разрешения ее автора.
Скрипты
Если вы решили создать свой модуль, вам обязательно понадобятся скрипты. Это особый программный язык, разработанный для набора инструментов Aurora Toolset. Без него никак не обойтись, если вы собрались построить хороший модуль. Именно они заставляют всех персонажей в игре выполнять их действия, врагов – нападать на вас, подателей сюжет – давать вам квесты. Без них модуль будет выглядеть безжизненным.
Чтобы освоить этот язык, нужно научиться понимать функции и алгоритм их написания. Обязательно вооружитесь статьей с полным описанием всех функции на русском языке. Или на крайний случай воспользуйтесь Lexicon’ом. Найти статьи вы сможете на форуме «Город мастеров» по адресу www.wrg.ru/forums.
Создайте персонажа с тегом “NPC_1”, точку с тегом “WP_1” и поставьте их на достаточном на ваше усмотрение расстоянии.
Теперь напишем скрипт, с помощью которого можно заставить персонажа совершить переход в определенную точку на карте. Этим примером пользуются многие в своих статьях, и я не буду исключением.
Neverwinter Script Source
void main()
{
object oNPC=GetObjectByTag("NPC_1");
object oWp=GetWaypointByTag("WP_1");
AssignCommand(oNPC,ActionMoveToObject(oWp));
}


void main() – это сам скрипт. Они бываю разные по своему назначению, но этот является универсальным, по умолчанию.
{} – все, что находится внутри фигурных скобок – ваш скрипт. Если он правильно написан, он будет выполняться сверху вниз, не иначе!
Самые первые строчки скрипта – это раздача ролей актерам. Вы задаете скрипту всех, кто будет участвовать в действиях, по тегам.
object oNPC = GetObjectByTag(“NPC_1”);
Разберем эту строку! Object – это тип задаваемого объекта. Он всегда пишется с маленькой буквы и выделяется синим цветом, если вы правильно его написали. Таких типов существует несколько: effect – это эффект, который будет накладываться на какой-то объект, живой или нет; object – размещаемый объект (персонаж, сундук, точка, дверь, – все, что имеет тег и материально); string – это какая-то фраза, либо тег объекта (адрес, задаваемый вами в свойствах); int – какое-то целое число или же константа, используемая в скрипте. Есть еще несколько типов, но они не так важны как эти (location – локация, местность; vector – вектор, float – дробное число (с плавающей точкой)). Они используются редко и в специальных скриптах, сложность которых вам пока не под силу… 
oNPC – o-строчная – это опять же тип задаваемого объекта, но уже в сокращенном виде (s-string, o-object, e-effect, l-location и т.д.). Советую вам использовать их, чтобы не забыть, к какому типу относится ваша переменная. Но по желанию можно менять название. 
NPC – это ваша переменная, которая будет использована в данном скрипте. Ёе вы можете задать сами, но лучше делать это не от балды, а придерживаясь принципа объект-переменная. Так если ваш объект – персонаж, то NPC, если игрок – PC, если точка – Wp и т.д., чтобы в дальнейшем вы не запутались. А то назовете переменную персонажа oSunduk, а потом будете гадать, где же в скрипте ваш персонаж, позабыв, что назвали его в честь ящика. 
= – знак арифметического равенства. Ничего сверхъестественного. Левая часть равна правой и наоборот…
GetObjectByTag(“NPC_1”); – это уже сложнее. Перед вами одна из многочисленный, но не бесконечных (что уже радует…) функций, которые расположены в длинном столбике справа окна редактора скрипта. Каждая из них выполняет свою функцию, с которыми вы можете ознакомиться в Lexicon’е или же в статьях. В данном случае представлена функция (кстати, они пишутся слитно и каждое слово с заглавной буквы!), которая вылавливает из палитры объект с определенным тегом, который у нас указан в скобках и кавычках. Кавычки всегда используются, когда вы задаете тег объекта или же фразу. Тег вы назначаете сами, как хотите. Можете писать там имя персонажа латинскими, а можете брать из балды, как я сейчас и сделал. Только следите, чтобы тег, указанный в скрипте, совпадал с тегом самого перса, иначе скрипт не сработает (компилятор различает заглавные и строчные буквы!).
После каждой функции обязательно(!) ставьте (;), иначе строка не скомпилируется. Дело в том, что компилятор воспринимает этот знак, как конец функции, и начинает считывание следующей.
Идем далее…
object oWp = GetWaypointByTag(“WP_1”);
GetWaypointByTag(“WP_1”) – это точка, заданная специальной функцией по тегу, который мы присвоили точке маршрута.
Теперь напишем действие:
AssignCommand ( oNPC, ActionMoveToObject(oWp));
Разберем по косточкам… начнем, скажем, с конца…
ActionMoveToObject(oWp) – это само действие «идти» к точке, переменная которой указана в скобках.
AssignCommand(oNPC, – эта функция обременит действием oNPC’а.
И само собой (;)…
Теперь проверим: у нас есть функция, задающая точку и персонажа, который туда пойдет; у нас имеется само действие «идти»; после каждой ф-и стоит (;). Можно компилировать. Если вы все правильно сделали, то внизу экрана появится сообщение об удачной компиляции.
Перед следующим примером стоит дать вам еще немного теории. Разберем логические операторы, часто употребляемые в скриптах: и, или, не.
! – «не», например, (GetObjectByTag(“…”) – задать объект. (!GetObjectByTag(“…”)) – не задать объект.
|| – «или». Ставится для условия: или то, или это. Пример:
GetObjectByTag(“1”)|| GetObjectByTag(“2”), так если или объект с тегом «1» или с тегом «2».
&& – «и». Опять же: GetObjectByTag(“1”)&&GetObjectByTag(“2”), так если возьмем объекты с тегами «1» и «2», но одновременно оба.
Операторы очень важны, поэтому никогда не путайте их и не забывайте. Чтобы легче запомнить, приглядитесь к оператору &&, это же американский значок «и», ну а ||, это или | или |…
В скриптописании имеются переменные, те что вы задаете непосредственно в скрипте, и константы, которые как и функции, висят постоянно в самом редакторе. Большую часть я использую очень редко, а чаще всего те, которые определяют какой-то визуальный эффект, анимацию или управление камерой. Но есть среди них несколько очень важных констант, которые я вам сейчас перечислю.
OBJECT_SELF – это постоянная, которая при правильном вводе окрасится в синий цвет. Зачем она нужна?
Допустим, вы хотите написать не скрипт-одиночку, который подойдет только объекту с определенным тегом, а универсальный скрипт, в котором не нужно будет каждый раз менять тег, если вы хотите задать другой объект с другим тегом.
Помните строку AssignCommand(oNPC, ActionMoveToObject(oWp));? Тут команда задается объекту с тегом. Такой скрипт можно поставить куда угодно (триггер, слоты модуль, локации, персонажа и т.д.). Но этот скрипт будет действовать только на персонажа с тегом “NPC_1”. Если вы захотите написать точно такой же скрипт для другого персонажа, то просто исправите тег и сохраните под другим именем, но если у вас 10 персов нуждаются в таком скрипте? А если 100? А? Тут-то мы и прибегнем к маленькой хитрости.
AssignCommand(OBJECT_SELF, ActionMoveToObject(oWp));
Какие у нас изменения? oNPC заменили на константу OBJECT_SELF, которая означает «объект_сам». Теперь можно удалить строчку object oNPC=GetObjectByTag(“NPC_1”); за ненадобностью. После такого изменения скрипт можно использовать для любого персонажа, но(!) теперь вы сможете поместить его только в слоты самого персонажа или в слот «Совершены действия» диалога, но опять же принадлежащего данному персонажу. Это нужно для того, чтобы «объект_сам» был под постоянным наблюдением скрипта. Это не такой уж и страшный убыток по сравнению с приобретенными качествами скрипта.
OBJECT_INVALID. Что же это за фрукт? Разберемся! «Объект_недействителен», вот как можно представить эту константу. Она нужна для обозначения ценности определенного предмета. Я использую ее всего в 2-3 ф-ях с условием if, поэтому расскажу попозже о ее назначении, иначе вам будет просто не понять.
Кстати! Константы пишутся только заглавными буквами! Вы можете написать их сами по памяти, или же вызвать в правом столбике и нажать два раза на нужную. Она появится в основном окне там, где был курсор.
TRUE и FALSE. «Правда» и «Ложь» соответственно. Это нужно для определения ценности того или иного действия, истинно оно или нет. Также они означают два положения выключателя «1» и «0» соответственно. 1 – включено, 0 – выключено. Они встречаются почти во всех функциях. К примеру, в ф-и ActionMoveToObject(oWp), из нашего первого скрипта-примера, тоже есть эти константы, но мы не писали их, так как значение по умолчанию нам вполне подходит. Но по схеме функция должна быть такой: ActionMoveToObject(oWp, TRUE) – если мы хотим, чтобы непись бежала (Истинно), или же ActionMoveToObject(oWp,FALSE) – чтобы непись шла (ложно). В разных ф-ях TRUE и FALSE применяются по разному. Чтобы узнать подробно, смотрите помощь в нижней части экрана редактора скрипта, подсветив ф-ю:

Теперь следует оговорить три особо важные на мой взгляд ф-и. Лично я пользуюсь ими чаще всего, особенно когда пишу свои излюбленные CutScene.
AssignCommand(), ActionDoCommand(), DelayCommand()
Кто они? Что они? Зачем нужны? Все по порядку. 
AssignCommand() – это ф-я, которая непосредственно к объекту применяет ту ф-ю, которая прописана в ее скобках. В нашем случае AssignCommand(oNPC,ActionMoveToObject(oWp)); к объекту oNPC будет применена ф-я движения. Иначе скрипт просто не узнает, кто должен выполнить действие. Задать переменную-то мы задали, а вот как ее использовать без этой ф-и? Никак!
ActionDoCommand() – это ф-я последовательности действий. Если есть несколько ф-й, заключенных в скобки данной, то они выполнятся в строгой последовательности сверху вниз. Очередное действие начнется только после того, как закончится предыдущее. Очень важная ф-я если делать несложные CutScene.
DelayCommand() – самая важная, по крайней мере для меня, ф-я. Она распределяет все действия по времени друг за другом. Вы создаете своего рода расписание, по которому все поезда отправятся точно в указный срок.
DelayCommand(0.5, AssignCommand(oNPC,ActionMoveToObject(oWp1)));
DelayCommand(5.5, AssignCommand(oNPC,ActionMoveToObject(oWp2)));
Что же значат эти строки? Они значат, что на 0.5 секунде от начала выполнения скрипта непись направится в точку Wp1, а на 5.5 секунде непись изменит свой курс и пойдет в точке Wp2 не зависимо от того, завершил ли он предыдущий маршрут. Сложность этой ф-и состоит в том, что вам придется точно подгонять время совершения очередного действия, чтобы все они не сбились в кучу. Сначала нужно расставить всех участников CutScene, к примеру, а потом начинать писать ролик. Даже если ваш глаз превосходно наметан, все равно не обойтись без нескольких загрузок игры, чтобы проверить время выполнения каждого действия. Это очень нудно и сложно, но когда вы сделаете ролик, у вас не хватит слов описать, как здорово выглядят слаженные и настроенные действия.
Создайте непись с тегом «NPC_2» и точку с тегом «WP_2». Улучшим скрипт и сделаем его сложнее. Пусть непись совершит переход в точку, скажет фразу и проиграет анимацию.
Neverwinter Script Source
void main()
{
    object oNPC=GetObjectByTag("NPC_2");
    object oWp=GetWaypointByTag("WP_2");
    string sString="Привет!!!";
    ActionDoCommand(AssignCommand(oNPC,ActionMoveToObject(oWp,FALSE)));
    ActionDoCommand(AssignCommand(oNPC,SpeakString(sString)));
    ActionDoCommand(AssignCommand(oNPC,ActionPlayAnimation
    (ANIMATION_FIREFORGET_SALUTE,1.0,2.0)));
}


Действия произойдут по очереди, благодаря ф-и ActionDoCommand(). В строке ActionDoCommand(AssignCommand(oNPC,ActionMoveToObject(oWp,FALSE))); мы поставили FALSE, чтобы непись шла, а не бежала. Анимация будет длиться со скоростью 1,0 в течении 2,0 секунд.
Проверьте работоспособность скрипта, и приступим к изучению более сложных.
Разберем скрипты с условием IF. Здесь все скрипты будут проверяться условием «если», прежде чем выполнить или же нет какие-то действия. Зачем это нужно? А вдруг вы захотите, чтобы скрипт запустился именно таким-то человеком с таким-то тегом. Как сделать? Поставить условие. Разберем алгоритм.
Neverwinter Script Source
If (…)
{

}
return;
//Если (условие выполнения)
{
то выполнится то, что в скобках
}
//иначе возврат в начало скрипта.
//Разберем простой скрипт с условием.
void main()
{
    object oPC=GetEnteringObject();
    string sString="ГЫ!!!";
    if (GetIsPC(oPC))
    {
    AssignCommand(oPC,SpeakString(sString));
    }
    return;
}


Дело обстоит так: GetEnteringObject() – это ф-я без наличия чего-либо в скобках, так как просто-напросто хватает «за шиворот» наступившего на триггер или же вошедшего в комнату (ставится на соответствующие слоты). Если oPC (вошедший или наступивший) является игроком, управляемым вами непосредственно (GetIsPC(oPC)), то выполнится условие в скобках. Если же наступившим или вошедшим является непись, зверь или что-то еще, то скрипт не сработает и вернется в начало, т.е. будет снова боеспособным.
Теперь рассмотрим другой скрипт, но по смыслу абсолютно идентичный предыдущему.
Neverwinter Script Source
void main()
{
    object oPC=GetEnteringObject();
    string sString="ГЫ!!!";
    if (!GetIsPC(oPC))
    return;
    {
    AssignCommand(oPC,SpeakString(sString));
    }
}


Что изменилось? Положение слова “return”. И перед GetIsPC(oPC) появился «!», так если логический оператор «не». Зачем мы так сделали? Поменялся ли смысл написанного? Отвечаю: нет, не поменялся.
Читается скрипт так: если вошедший/наступивший НЕ игрок, то возврат, если же игрок, то он произнесет фразу. Понятно почему? В первом скрипте было определенное утверждение, а во втором мы поставили отрицание, следовательно поменялось положение возврата. Я лично предпочитаю писать второй вариант, но это лишь вопрос вкуса и привычки. На самом деле, повторяю, они абсолютно идентичны.
Рассмотрим еще одно условие, но с двумя телами.
Neverwinter Script Source
If (…)
{

}
else
{

}
void main()
{
    object oPC=GetEnteringObject();
    string sString1="Перед вами женщина!!!";
    string sString2="Перед вами мужчина!!!";
    if (GetGender(oPC)==GENDER_MALE)
    {
    AssignCommand(oPC,SpeakString(sString2));
    }
    else
    {
    AssignCommand(oPC,SpeakString(sString2));
    }
}


Если пол oPC – мужской, то он скажет фразу sString2, иначе sString1. Почему так? Проверка пойдет сверху. Ф-я GetGender(oPC) возьмет пол игрока и сравнит его с постоянной (мужчина и женщина, GENDER_MALE и GENDER_FEMALE, соответственно). Если пол совпадет с мужской постоянной, то пойдет выполнение действия, но если пол не совпадет с указанным, то проверка перепрыгнет через тело №1 и пойдет по телу №2, там где покоится женская фраза. В данном случае все просто, так как пола всего два. Третьего не дано от рождения… Но что если условия три, десять? К примеру проверка стоит на расу. И для каждой прописаны действия. Что тогда? Тогда идет небольшая корректировка. Тогда алгоритм будет выглядеть так:
Neverwinter Script Source
if(…)
{

}
else if //(новое условие)
{

}
return;


Если выполнится условие один, то пойдет выполнение тела №1, если задание соответствует условию 2, то пойдет выполнение тела 2. Если же действительность не совпадет ни с одним условием, произойдет возврат. Таких условий можно писать бесконечное множество, пока не надоест. 
Осталось поговорить про циклы. Что это такое, я толком так и не понял. Вроде какая-то нужная вещь, но я очень редко пользуюсь ими. Помнится, один раз написал цикл и поставил на триггер. Так как на нем стояло условие, которое начинало выполняться при загрузке модуля, у меня игра зависала еще при выборе персонажа. Так что циклы могут оказаться весьма полезными, если вы хотите подвесить ваш модуль. 
Цикл состоит из условие, проверка на которое будет происходить при запуске скрипта, и тела, внутри которого вы пишете то, что будет выполнятся. В зависимости от ваших нужд цикл может выполнятся вечно, несколько раз или же не выполниться ни разу.
Neverwinter Script Source
while (…)
{

}
// Рассмотрим простой пример по удалению эффектов с игрока скриптом с циклом.
void main()
{
    object oPC=GetEnteringObject();
    effect eEf=GetFirstEffect(oPC);
    while (GetIsEffectValid(eEf))
    {
    RemoveEffect(oPC,eEf);
    eEf=GetNextEffect(oPC);
    }
}


Цикл будет действовать так: сначала условие цикла проверит, существует ли такой эффект на персонаже. Если существует, эффект удалится, а цикл возьмется сравнивать следующий эффект (GetNextEffect(oPC)). Если же цикл больше не обнаружит наложенных эффектов, он прервется. Этот скрипт можно поставить на триггер или на вход в локацию, потому как oPC задан GetEnteringObject, но если вы зададите его по другому, то и скрипт можно будет поставить в другое место. Можете испробовать, но прежде чем наступать на триггер, наложите на себя парочку эффектов.  Кстати, если вы поставите слово break в конце тела цикла, то он выполнится только один раз. Это нужно… для чего-то, но я не пользовался такой фишкой. 
Neverwinter Script Source
void main()
{
    object oPC=GetEnteringObject();
    effect eEf=GetFirstEffect(oPC);
    while (GetIsEffectValid(eEf))
    {
    RemoveEffect(oPC,eEf);
    break;
    }
}


Существуют еще такие фишки, как Base и Switch, но у меня руки так и не дошли до их изучения, но ходят слухи среди посетителей Города Мастеров, что они сходны с циклами и условиями if.
Давайте теперь для самоконтроля разберем такой скрипт:

Neverwinter Script Source
//::///////////////////////////////////////////////
//:: Created By: MasterMage ©
//:: Created On:
//::///////////////////////////////////////////////
void main()
{
    //-----------objects---------------------------
    object oPC=GetEnteringObject();
    object oArea =GetObjectByTag("area011");
    //-----------effects---------------------------
    effect oEf=EffectVisualEffect(VFX_IMP_UNSUMMON,FALSE);
    //-----------vector----------------------------
    vector oVec=Vector(101.0f,52.0f,0.0f);
    //-----------location--------------------------
    location lLoc=Location(oArea,oVec, DIRECTION_NORTH);
    //-----------script----------------------------
    if (GetLocalInt(oPC,"ZedInt")==TRUE)
    {
    ActionDoCommand(SetCutsceneMode(oPC));
    ActionDoCommand(AssignCommand(oPC,SetCameraFacing(280.0, 8.5, 65.0, CAMERA_TRANSITION_TYPE_SLOW)));
    ActionWait(3.5);
    ActionDoCommand(ApplyEffectToObject( DURATION_TYPE_PERMANENT,oEf, oPC));
    ActionWait(3.0);
    ActionDoCommand(SetCutsceneMode(oPC,FALSE));
    ActionDoCommand(AssignCommand(oPC,ActionJumpToLocation(lLoc)));
    }
    return;
}


Что же делает этот скрипт? Его я написал специально для моего модуля. Работает он отлично и выглядит вполне эффектно. Когда вы наступаете на поверхность портала, включается экран Cutscene, после чего следует красивый визуальный эффект, который якобы перебрасывает вас в место назначения, а потом вы оказываетесь совершенно в другом месте.
Как же это делается? Отвечаю.
object oPC=GetEnteringObject(); – этой строкой задается переменная наступившего на триггер (портал).
object oArea =GetObjectByTag("area011"); – этой строкой задается локация, в которую надо перенестись.
effect oEf=EffectVisualEffect(VFX_IMP_UNSUMMON,FALSE); – визуальный эффект, который придаст картине более мистический оттенок.
vector oVec=Vector(101.0f,52.0f,0.0f); – этой строкой я задал точку, в которой появится персонаж.
location lLoc=Location(oArea,oVec, DIRECTION_NORTH); – эта строка объединяет в себе две ф-и выше и обозначает место телепортации, сторону света, куда будет смотреть персонаж.
if (GetLocalInt(oPC,"ZedInt")==TRUE) – если переменная, которую я поставил в диалоге равна TRUE, то скрипт сработает. Так если мне сказали в диалоге, что порталом можно пользоваться, и теперь скрипт будет работать постоянно.
Теперь, что касается тела скрипта. Сначала включится режим Cutscene. Затем (все происходит по очереди, благодаря ф-и ActionDoCommand) камера настраивается на персонажа, показывая его с выгодных позиций. Третья строка – ждем 3,5 секунды. Применяем эффект на персонажа. Опять ждем, но уже 3,0 секунды. Быстро отключаем режим Cutscene и переносим перса с назначенное место. 
Этот скрипт я написал сам, при помощи советов жителей Города Мастеров (не буду перечислять имена, так как они и сами знают, кто мне помогал, но если я кого-то забуду, будет не очень-то честно). Тогда я еще учился. Теперь же, когда я многое знаю по скриптописанию, то могу переписать этот скрипт вот так. Уловите разницу:
Neverwinter Script Source
void main()
{
    //-----------objects---------------------------
    object oPC=GetEnteringObject();
    object oWp=GetWaypointByTag("Wp1");
    //-----------effects---------------------------
    effect oEf=EffectVisualEffect(VFX_IMP_UNSUMMON,FALSE);
    //-----------script----------------------------
    if (GetLocalInt(oPC,"ZedInt")==TRUE)
    {
    ActionDoCommand(SetCutsceneMode(oPC));
    ActionDoCommand(AssignCommand(oPC,SetCameraFacing(280.0, 8.5, 65.0, CAMERA_TRANSITION_TYPE_SLOW)));
    ActionWait(3.5);
    ActionDoCommand(ApplyEffectToObject( DURATION_TYPE_PERMANENT,oEf, oPC));
    ActionWait(3.0);
    ActionDoCommand(SetCutsceneMode(oPC,FALSE));
    ActionDoCommand(AssignCommand(oPC,ActionJumpToLocation(GetLocation(oWp))));
    }
    return;
}


Вместо того, чтобы щепетильно высчитывать место векторами и локациями, я просто поставил туда точку с тегом “Wp1”. Теперь две строки не нужны. А если заменить ActionDoComman DelayCommand, то угадайте сколько строчек можно будет убрать? Вот вам задание, запишите этот скрипт через временную ф-ю. Ниже и предлагаю свой вариант. Можете подглядеть в него сразу, а можете проверить свои силы без моей помощи. Это на ваше усмотрение.
Neverwinter Script Source
void main()
{
    //-----------objects---------------------------
    object oPC=GetEnteringObject();
    object oWp=GetWaypointByTag("Wp1");
    //-----------effects---------------------------
    effect oEf=EffectVisualEffect(VFX_IMP_UNSUMMON);
    //-----------script----------------------------
    if (GetLocalInt(oPC,"ZedInt")==TRUE)
    {
    DelayCommand(0.1,SetCutsceneMode(oPC));
    DelayCommand(0.2,AssignCommand(oPC,SetCameraFacing(280.0, 8.5, 65.0, CAMERA_TRANSITION_TYPE_SLOW)));
    DelayCommand(3.7,ApplyEffectToObject( DURATION_TYPE_PERMANENT,oEf, oPC));
    DelayCommand(6.7,SetCutsceneMode(oPC,FALSE));
    DelayCommand(6.8,AssignCommand(oPC,ActionJumpToLocation(GetLocation(oWp))));
    }
    return;
}

Надеюсь, мне удалось заронить в ваши умы искорки понимания. Если же нет, то советую вам почитать другое статьи, пообщаться со знающими людьми и, наконец, много раз пытаться самому. Когда я осваивал этот язык, я иногда часами мучился с одним маленьким скриптом, но какова была моя радость, когда мне самому удавалось понять, в чем ошибка. Конечно, поначалу ваши скрипты могут выглядеть не так уж и красиво, но это не важно. Гибкость придет со временем, а пока главное, чтобы скрипты работали. Желаю дальнейших успехов. Читайте другие мои статьи из этой серии. 


Автор статьи: MasterMage©
Особая благодарность выражается: Aiwan’у, который закидывал меня советами и подсказками, ни разу не ответив грубо на мое постоянное нытье, что я ничего не понимаю; DBColl’у, который часто поправлял меня, наставляя «на путь истинный»; Lex’у, знания которого в области скриптописания не раз выручали меня; Lemegeton’у, который ни разу не пропустил мимо ушей мои вопросы; 2GoDoom’у, который появлялся редко, когда висели мои вопросы, но отвечал метко; Friedrich’у, за мудрые советы… Если я кого-то забыл, не серчайте.
P.S. – вы тоже можете попросить у них помощи, если посещаете Город Мастеров.


Айван: читайте и обсуждайте.


Сообщение отредактировал Aiwan - Mar 22 2005, 20:15
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
 
Открыть новую тему
Ответов
Friedrich
сообщение Mar 26 2005, 02:31
Сообщение #2


Level 5
**

Класс: Рейнджер
Характер: Neutral Good
Раса: Человек



QUOTE (MasterMage @ Mar 25 2005, 22:21)
подателей сюжет

Может быть, подателей (чего?) сюжета.
QUOTE (MasterMage @ Mar 25 2005, 22:21)
Обязательно вооружитесь статьей с полным описанием всех функции на русском языке. Или на крайний случай воспользуйтесь Lexicon’ом.
Я бы сказал наоборот, "Обязательно вооружитесь лексиконом, или, на крайний случай воспользуйтесь статьей с описанием всех функций на русском". :lol:
QUOTE (MasterMage @ Mar 25 2005, 22:21)
void main() – это сама функция. Они бываю разные по своему назначению, но этот является универсальным, по умолчанию.
Молодой человек, что у вас какой язык родной? Уж куда я не грамотный, но в родах падежах, обычно не путаюсь.

main() { ... }

определяет функцию, названную main. Каждая программа должна
содержать функцию с именем main, и работа программы начинается с
выполнения этой функции.
Бьярн Страустрап, Введение в язык Си++

Заменить слово "программа", на слово "скрипт" (или "сценарий") и будет то, что надо... :P

QUOTE (MasterMage @ Mar 25 2005, 22:21)
После каждой функции обязательно(!) ставьте;, иначе строка не скомпилируется. Дело в том, что компилятор воспринимает этот знак, как конец функции, и начинает считывание следующей.

';' нужно ставить не после каждой функции, а после каждого выражения.
if (!GetIsObjectValid(oPC)) return;
После функции GetIsObjectValid ты ведь не ставишь ';'.

Продолжать не буду.
Добавлено в 02:34
Надо еще сказать, что вместо main скрипт может содержать функцию StartingConditional.

Сообщение отредактировал Friedrich - Mar 26 2005, 02:36
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения

Сообщений в этой теме
- MasterMage   Мануалы в помощь новичкам...   Mar 22 2005, 18:10
- - Lex   QUOTE (MasterMage @ Mar 22 2005, 18:10)void ...   Mar 22 2005, 22:11
- - Friedrich   QUOTE = – знак арифметического равенства. Ничего с...   Mar 23 2005, 00:52
- - Vhall   QUOTE (Friedrich @ Mar 23 2005, 00:52)(возмо...   Mar 23 2005, 09:50
- - Lex   ИТОГ: в таком виде статью НИ В КОЕМ СЛУЧАЕ НЕЛЬЗЯ ...   Mar 23 2005, 10:22
- - slavaz   QUOTE (Lex @ Mar 22 2005, 23:11)QUOTE (Maste...   Mar 23 2005, 12:48
- - MasterMage   Все учел, имеено для этого тема и создана, чтобы в...   Mar 23 2005, 15:39
- - Lex   QUOTE (MasterMage @ Mar 22 2005, 18:10)//Есл...   Mar 23 2005, 23:15
- - baskan   Жду след. статей. Ты до меня достучался   Mar 25 2005, 22:07
- - MasterMage   baskan будут LEX Вот... Отредактировал, посмотр...   Mar 25 2005, 22:21
- - Friedrich   QUOTE (MasterMage @ Mar 25 2005, 22:21)подат...   Mar 26 2005, 02:31
- - Lex   QUOTE (Friedrich @ Mar 26 2005, 02:31)Продол...   Mar 26 2005, 03:02
- - Friedrich   QUOTE (Lex @ Mar 26 2005, 03:02)а чего так? ...   Mar 26 2005, 05:21
- - MasterMage   QUOTE (Friedrich @ Mar 26 2005, 02:31)Молодо...   Mar 26 2005, 10:45
- - Friedrich   void main() – это сама функция. Они бываю (я бываю...   Mar 26 2005, 12:20
- - Lex   поднял тему... может продолжим?   Sep 13 2005, 16:14
- - _kaa_   Ага, удали все кроме самой статьи p.s. с выходом...   Sep 13 2005, 16:22
- - Lex   ты ее внимательно почитай.... мы ее тут правили.. ...   Sep 13 2005, 16:38
- - _kaa_   Для мануала сойдет перевод "первые 10 шагов...   Sep 13 2005, 16:46
- - 2_advanced   XShock (раурин тим) мутил хрень с заменой НВНовски...   Sep 13 2005, 17:27
- - dumbo   QUOTE (2_advanced @ Sep 13 2005, 18:27)XShoc...   Sep 14 2005, 08:35
- - 2_advanced   ответ напоминает этот НВНХ тоже бред? а всякие S...   Sep 17 2005, 14:10
- - dumbo   QUOTE (2_advanced @ Sep 17 2005, 15:10)ответ...   Sep 19 2005, 08:55
- - Alina   Вы меня извините, я собственно по тексту статьи хо...   Sep 21 2005, 00:18
- - Aiwan   QUOTE (Alina @ Sep 21 2005, 03:18)Я только н...   Sep 23 2005, 07:03


Ответить в эту темуОткрыть новую тему
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0

 



Текстовая версия Сейчас: 26th April 2025 - 22:32