|
Архив - только для чтения |
Модератор форума: andycrowz |
Форум Корзина форума Корзина Уроки по созданию .LUA скриптов для WoW №1 Часть 1 (Обучающий учебник .LUA языка.) |
Уроки по созданию .LUA скриптов для WoW №1 Часть 1 |
Долго думал с чего начать и наткнулся на этот учебник и решил его опубликовать тут как начальный урок по созданию lua скриптов.
Обучающий учебник .LUA языка. Это руководство можно найти на wow-v и на ac-web. На английском языке. (Автор идеи учебника не я. Я наткнулся на него на одном англ форуме и решил сделать подобный учебник здесь). Обратите внимание, что этот учебник, устарел и не будет работать с LuaBridge, хотя синтаксис задан правильно, но функции не будут работать. От автора: Привет всем и добро пожаловать на мой конечный учебник Lua. Этот учебник направлен на тех людей, которые хотели бы узнать Lua, но не могут найти способ сделать это легко и надежно. Этот учебник будет также охватывать некоторые расширенные возможности языка программирования. Введение в Lua. Вероятно вы пришли узнать о Lua, и таким образом у вас уже есть ясное понимание того, на что способен язык Lua. Если вы сможете скриптовать в Lua, вы, вероятно, будет в состоянии применить высокопоставленные должности в частных серверах— это очень мощный, легкий язык. Lua можно сделать почти как C++ и его гораздо, гораздо легче понять и писать. Плюсы и минусы обучения Lua. Плюсы: Легкий. Мощный. Простой. Поддержка всех ArcEmu серверов по умолчанию. Его власть, безгранична. Минусы Ограничивает вас только в ArcEmu серверов (если Mangos и Trinitycore решили бы поддержать Lua, не дай Бог этому.) Основы. Эта тема является самым низким уровнем lua,что вы можете получить внутри этой темы. Этот раздел состоит из: Code Low-level functions Arguments Gossip NPCs If statements Else & Elseif Commenting Variables В этом учебнике предполагается что вы ищете ArcEmu обучения, и поэтому мы будет фокусироваться на пути ArcEmu сценариев. В этом учебнике я научу вас, как сделать сплетни NPC. Прежде чем начать, я считаю, что вы должны иметь эти вещи, прежде чем начать изучать Lua: Сборка ArcEmu с поддержкой LuaHypArc. ArcEmu Default Lua Command List. Notepad++ Installer Если вы не имеете что то из этого списка, не волнуйтесь! Это не обязательно что бы научиться Lua, но я уверен, что будет проще делать скрипты с этим. Вы можете найти Notepad++. и список команд ArcEmu, нажав ссылки ниже. Notepad++. ArcEmu команды. Все это бесплатно. Для более удобного управления скриптами можно использовать коментарии. Комментарии являются строки кода, которые не читают Lua язык. Он просто игнорирует их. Существует два типа комментариев; Однострочный комментарий и блок комментарий. Однострочный комментарий Однострочный комментарий; он блокирует остальные линии (где вы использовали идентификатор комментария). После так называемого комментария идентификатора является полностью игнорируемым обработчиком Lua и впоследствии ArcEmu-миром. Однострочный комментарий обозначается двумя дефисами, размещены в непосредственной близости друг от друга. Пример можно увидеть ниже. Code Stuff() --Ваш коментарий! Это хороший метод для обеспечения того, что ваши мысли помещены на виртуальной бумаге. Но что делать, если этот комментарий занимает более одной строки? Конечно было бы запутанно, если сделать это так; Code -- This -- Needs -- To -- Be -- Neater -- ...! Блок комментарий. Блок комментарий: является комментарий, который занимает несколько строк, пока вы не добавите закрывающий символ. Что написано между открывающим и закрывающим идентификатором полностью игнорируются. Это отлично подходит для вступительных пунктов в верхней части сценария или вообще указанием каких либо мыслей. Блок комментарий выглядит так: Code --[[ Это ,блок комментарий , он может занимать несколько строк! ]] Открытие блок комментария Code --[[ Закрытие блок комментария Code ]] Пожалуйста, обратите внимание, что это не имеет никакого эффекта на скрипт. Добавлено (01.10.2012, 01:59) --------------------------------------------- Функции.(function) Функции являются обязательным (в ArcEmu), чтобы сделать этот сценарий рабочим. Функция начинается с function и закрывается end значением. После слова «function» есть пространство и там вы можете поместить ваше название функции, далее идут -(). Скобки, известны как аргументы. Они в основном решают, какой бит данных передается на мир WOW от ArcEmu-мира. Вот пример функции; Code function FunctionName(Unit, Event) -- Это функция! end Обратите внимание, что ключевое слово «function» пишется с маленькой буквы. Использование большой буквы «F» (или любой другой буквы) приведет к тому что система, не признает ее за функцию. То же самое для имен функций, аргументов и т.д. Ну как упоминалось ранее, они являются аргументами. Почти в каждой функции, которые вы используете как Lua Scripter вы будете использовать значения внутри этих скобок. Существуют различные аргументы для различных событий. Вот наиболее распространенные: Code GeneralCreatureEvent(Unit, Event[, pMisc]) GossipOnTalkEvent(Unit, Event, player) GossipOnSelectEvent(Unit, Event, player, id, intid, code, pMisc) Квадратные скобки указывают факультативный выбор. (Unit, Event)может быть использован вместо (Unit, Event, pMisc) например. Создание вашей первой функции. В соответствии с традицией, ваша первая функция/сценарий будет «Привет Мир!». Code function HelloWorld() print("Привет Мир!") print("Это мой первый сценарий LUA!") end HelloWorld() Вас интересует что я сделал? Ну, во-первых, я создал функцию HelloWorld без аргументов. Обратите внимание, что я еще добавил пару круглых скобках. Это является обязательным для каждой функции которую вы создаете. В первой строке, функция HelloWorld () ничего не делает, кроме как рассказать Lua, что мы начинаем новую функцию, которую мы обозначили под названием "HelloWorld", и что он не имеет аргументов. Далее идет print скобки кавычки. Внутри этих кавычек вы пишете тот текст который вы хотите видеть. Если вы сохраните этот код в HelloWorld.lua и поместите его в вашу папку / scripts , а затем открыть ArcEmu-World, она будет печатать в консоль: Code Привет Мир!") Это мой первый сценарий LUA! Скучно да? Это не полезно, так что мы будем двигаться немного дальше... Ваш первый gossip скрипт. В WoW, когда вы говорите с NPC, он дает вам разные варианты. Такие, как: "Да, я готов», и так далее. Это называется gossip. И это то, что мы собираемся создать сейчас. Прежде всего, необходимо создать NPC ... После создания NPC установите ему флаг 1. Это можно сделать через базу данных либо через команду в игре ( .npc flag 1 ). Теперь создайте новый файл lua и напишите в нем Code --[[ Мой первый сценарий! -- Variables local NPC_ID = YourEntryID -- On Triggers -- RegisterUnitEvents ]] Замените YourEntryID на ид вашего NPC. Variables. Переменная данных, которое хранит определенную часть данных. В отличие от C + +, нет типами переменных в Lua. Кроме того, нет необходимости беспокоиться о неподписанных / Подпись переменных. Переменная создается путем ввода строки в сценарий. Эта строка может быть почти везде, однако, оно не может быть ключевым словом или именем функций. Кроме того, переменные могут быть только буквенно-цифровые и подчеркивания или дефис в них. Вы можете использовать эти символы: Code a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 1 2 3 4 5 6 7 8 9 0 _ Обратите внимание, что переменные чувствительны к регистру. MY_VAR не то же самое, как my_var или My_VaR. Глобальная переменная может переходить от одного сценария к другому, так что это может вызвать проблемы. Лучше всего использовать локальные переменные, которые остаются внутри текущего сценария, для уменьшения помех. Хорошие имена переменных: Code My_Var = 1 myVar = 2 Неверное имя переменных: Code %MyVar = 1 My.Var = 2 My&Var = 3 Это всегда хорошая идея, чтобы назвать ваши переменные функции. Code local Var983 Это не так просто, чтобы знать, что он делает, как это: Code local Npc_Id Во всяком случае, вернемся к Gossip NPC! Code --[[ Мой первый сценарий! -- Variables local NPC_ID = YourEntryID -- On Triggers -- RegisterUnitEvents ]] Прежде всего, давайте создадим новую функцию под названием "exampleGossipOnTalk (Unit, Event, player). Эти аргументы являются стандартными для OnTalk события сплетни. Мероприятие OnTalk сплетни первого меню в диалоге который вы видите, когда вы говорите с NPC. Code --[[ Мой первый сценарий! ]] -- Variables local NPC_ID = YourEntryID -- On Triggers function exampleGossipOnTalk(Unit, Event, player) end -- RegisterUnitEvents Обратите внимание, что я добавил end ниже функции. Мы должны закончить каждую функцию, которая будет создана, или Lua будет бросать ошибку. Теперь, когда мы создали функцию, давайте добавим RegisterUnitEvent. Обычно, если вы создаете босса, вы будете использовать RegisterUnitEvent(), но так как мы делаем Gossip NPC, мы используем RegisterUnitGossipEvent. Отметим, что это учитывается. Добавляйте это под соответствующий раздел; Code RegisterUnitGossipEvent(NPC_ID, 1, exampleGossipOnTalk) RegisterUnitGossipEvent () имеет четыре аргумента: ID, Event ID и имя функции. Вы можете использовать переменные для ID Event ID и событий, поэтому я добавил NPC_ID переменной вместо ID. Code RegisterUnitGossipEvent(ID, EVENT_ID, FUNCTION_NAME) Сейчас этот сценарий будет регистрироваться как пустая функция, когда вы говорите с NPC. Это что-то, но это бесполезно. Итак, давайте начнем его конкретизацию. Code function exampleGossipOnTalk(Unit, Event, player) end Как мы видели выше, заявления идут между функцией и концом (function и end), например, так. Code function exampleGossipOnTalk(Unit, Event, player) -- Заявления суда end Добавлено (01.10.2012, 02:01) --------------------------------------------- Чтобы начать создание gossip меню, Lua должен знать, что мы создаем меню, мы создаем оболочку, используя: GossipCreateMenu() заявление. Code :GossipCreateMenu(TEXT_ID, player, INTID) Обратите внимание, что :GossipCreateMenu() имеет двоеточие перед ним; это означает, что требуется Unit. По умолчанию, Группа 'Unit'. Это не нужно менять, если мы имеем дело с несколькими НПС в один сценарий; Мы вернемся к этому позже. Давайте добавим наше заявление в функцию. Code function exampleGossipOnTalk(Unit, Event, player) Unit:GossipCreateMenu(100, player, 0) end Вы видите, что я использовал '100 'для текста ID. Это значение по умолчанию: "Привет, <name>. Чем я могу вам помочь?». Он может быть изменен, глядя в соответствующей таблице в вашей базе данных. Я установил Intid '0 ', потому что это то, что все первые меню устанавливаются на; 0. Это делает логический смысл. Так что теперь мы создали меню, которое отображает "Привет, <name>. Чем я могу вам помочь? '. Это все еще довольно непрактичный сценарий и не поможет никому. Чтобы сделать этого NPC полезным, давайте добавим несколько вариантов, :GossipMenuAddItem () Code :GossipMenuAddItem(ICON_ID, MENU_CONTENT, INTID[, CODE]) Это утверждение может сбить вас с толку; INTID? CODE? ICON_ID? Что это такое? Ну, ICON_IDs как вы видите рядом с текстом, когда вы открываете меню. Есть несколько различных значков, идентификаторов перечисленных ниже; Code 0 = Chat bubble 1 = Bag 2 = Wings 3 = Book 4 = Cog/Gear 5 = Cog/Gear 6 = Bag with coin 7 = Chat bubble with "..." Когда вы пишете в MENU_CONTENT, вы можете покрасить его. Вы можете использовать его, положив |ср######, где #S ваш шестнадцатеричный цвет (Web Color Chart - Hexadecimal - by VisiBone Дополнительная информация) и добавление |г в конце. Code :GossipMenuAddItem(0, "|cfFFFFFF White! |r", 1, 0) INTID? Ну, когда вы используете функцию OnSelect, INTID используется, чтобы определить, какое меню было открыто. Таким образом, вы должны использовать уникальные IntIDs для каждого выбора меню или сценария иначе они не будут работать. Кроме того, IntID используется в числовой форме. CODE является дополнительным ... вариантом .. , которые могут быть пропущены. Они используется только, когда вы хотите, загрузить CodeBox. Это не будет объяснено в этом учебнике, и вам придется поэкспериментировать, чтобы получить его рабочим. Само собой разумеется, оставить его на 0. Я добавлю несколько вариантов Gossip Menu.. Code function exampleGossipOnTalk(Unit, Event, player) Unit:GossipCreateMenu(100, player, 0) Unit:GossipMenuAddItem(0, "Телепорт меня в столицу.", 1, 0) Unit:GossipMenuAddItem(0, "Удалить болезнь после воскрешения.", 2, 0) Unit:GossipMenuAddItem(0, "Выход.", 3, 0) end Это добавляет три варианта нашего меню, Телепорт меня в столицу, Удалить болезнь после воскрешения, и вариант, чтобы закрыть меню. Тем не менее, это не будет работать. Мы создали меню, но, мы не сможем послать его к игроку. Для этого мы добавим: GossipSendMenu() команду. Code Unit:GossipSendMenu(player) Что делает нашу функцию такой: Code function exampleGossipOnTalk(Unit, Event, player) Unit:GossipCreateMenu(100, player, 0) Unit:GossipMenuAddItem(0, "Телепорт меня в столицу.", 1, 0) Unit:GossipMenuAddItem(0, "Удалить болезнь после воскрешения.", 2, 0) Unit:GossipMenuAddItem(0, "Выход.", 3, 0) Unit:GossipSendMenu(player) end Давайте добавим это к остальной части нашего кода: Code --[[ Мой первый сценарий! ]] -- Variables local NPC_ID = ид нпс -- On Triggers function exampleGossipOnTalk(Unit, Event, player) Unit:GossipCreateMenu(100, player, 0) Unit:GossipMenuAddItem(0, "Телепорт меня в столицу.", 1, 0) Unit:GossipMenuAddItem(0, "Удалить болезнь после воскрешения.", 2, 0) Unit:GossipMenuAddItem(0, "Выход.", 3, 0) Unit:GossipSendMenu(player) end -- RegisterUnitEvents RegisterUnitGossipEvent(NPC_ID, 1, "exampleGossipOnTalk") У нас получилось! Однако, это только показывает меню. Варианты не будут работать, вы будете иметь возможность видеть их, но если вы нажмете на них, ничего не произойдет. Вы должны прописать ему, что делать. И мы делаем это с нашей второй функцией; OnSelect Code exampleGossipOnSelect(Unit, Event, player, id, intid, code, pMisc) Это ничего не значит для вас на данный момент, не так ли? Давайте создадим еще одну функцию. Code --[[ Мой первый сценарий! ]] -- Variables local NPC_ID = ид нпс -- On Triggers function exampleGossipOnTalk(Unit, Event, player) Unit:GossipCreateMenu(100, player, 0) Unit:GossipMenuAddItem(0, "Телепорт меня в столицу.", 1, 0) Unit:GossipMenuAddItem(0, "Удалить болезнь после воскрешения.", 2, 0) Unit:GossipMenuAddItem(0, "Выход.", 3, 0) Unit:GossipSendMenu(player) End function exampleGossipOnSelect(Unit, Event, player, id, intid, code, pMisc) end -- RegisterUnitEvents RegisterUnitGossipEvent(NPC_ID, 1, "exampleGossipOnTalk") И добавить RegisterUnitGossipEvent под OnTalk Code --[[ Мой первый сценарий! ]] -- Variables local NPC_ID = ид нпс -- On Triggers function exampleGossipOnTalk(Unit, Event, player) Unit:GossipCreateMenu(100, player, 0) Unit:GossipMenuAddItem(0, "Телепорт меня в столицу.", 1, 0) Unit:GossipMenuAddItem(0, "Удалить болезнь после воскрешения.", 2, 0) Unit:GossipMenuAddItem(0, "Выход.", 3, 0) Unit:GossipSendMenu(player) End function exampleGossipOnSelect(Unit, Event, player, id, intid, code, pMisc) end -- RegisterUnitEvents RegisterUnitGossipEvent(NPC_ID, 1, "exampleGossipOnTalk") RegisterUnitGossipEvent(NPC_ID, 2, exampleGossipOnSelect) Итак, давайте добавим первый вариант (из 3) наших новых функций. Code function exampleGossipOnSelect(Unit, Event, player, id, intid, code, pMisc) if (intid == 1) then player:Teleport(MapID, x, y, z) player:GossipComplete() end end Что мы видим. Code if (intid == 1) then Он используется, чтобы проверить, если определенные условия. Помните, когда мы добавили варианты, и мы должны были определить уникальный номер? Это было intid. Таким образом, если intid, я выбрал 1 ("Телепорт меня в столицу!”), То мы запустим эту часть сценария. Code player:Teleport(MapID, x, y, z) Эти значения говорят о том что они телепортируют игрока по введенным координатам. Для примера я возьму Shattrat. Его координаты. Code MapID: 1 X: -9101.980469 Y: 1612.902832 Z: 21 Так что это будет выглядеть так: Code player:Teleport(1, -9101.980469, 1612.902832, 21) -- Это не точные координаты шаттрат. Теперь мы знаем, что это делает, и мы будем двигаться дальше; Player:GossipComplete(). Это довольно просто и не требует весь абзац, чтобы объяснить это. Он просто закрывает меню. Code end Подождите, у нас есть два end? Да, мы сделали все правильно. «if» заявление необходимо положить конец, так как Lua не может определить, когда он закончился. Давайте посмотрим что у нас получилось. Code function exampleGossipOnSelect(Unit, Event, player, id, intid, code, pMisc) if (intid == 1) then player:Teleport(1, -9101.980469, 1612.902832, 21) player:GossipComplete() end end Таким образом, мы понимаем, что это все делает? Хорошо. Давайте перейдем на следующий intid; Удалить болезнь после воскрешения. Code function exampleGossipOnSelect(Unit, Event, player, id, intid, code, pMisc) if (intid == 1) then player:Teleport(1, -9101.980469, 1612.902832, 21) player:GossipComplete() end if (intid == 2) then end end Как вы можете видеть, мы создали другую, петлю. На этот раз, она работает, только если intid равен 2. Таким образом, в этой функции мы хотим удалить ауру болезнь после воскрешения. Теперь идем на wowhead.com и находим там ид ауры 15007. Смотрим что у нас получается. Code function exampleGossipOnSelect(Unit, Event, player, id, intid, code, pMisc) if (intid == 1) then player:Teleport(1, -9101.980469, 1612.902832, 21) player:GossipComplete() end if (intid == 2) then if (player:HasAura(15007) == true) then player:SendBroadcastMessage("Болезнь после воскрешения была удалена. Будьте осторожны в следующий раз!") player:RemoveAura(15007) player:GossipComplete() else player:SendBroadcastMessage("У вас нет болезни после воскрешения!") player:GossipComplete() end end end Что мы тут видим. Я добавил Code HasAura() и Code RemoveAura(). HasAura() проверяет есть ли на вас эта аура. RemoveAura() снимает эту ауру. Так же я добавил player:SendBroadcastMessage объяснять что это делает я не буду. Так как это понятно наглядно. Конечно, вы все равно должны добавить end для "if" и "function". Итак, теперь у нас есть два intids, давайте посмотрим на нашу функцию сейчас, и добавить последнюю. Code function exampleGossipOnSelect(Unit, Event, player, id, intid, code, pMisc) if (intid == 1) then player:Teleport(1, -9101.980469, 1612.902832, 21) player:GossipComplete() end if (intid == 2) then if (player:HasAura(15007) == true) then player:SendBroadcastMessage("Болезнь после воскрешения была удалена. Будьте осторожны в следующий раз!") player:RemoveAura(15007) player:GossipComplete() else player:SendBroadcastMessage("У вас нет болезни после воскрешения!") player:GossipComplete() end end if (intid == 3) then player:GossipComplete() end end Мы просто добавили в intid 3: GossipComplete(), потому что опция стоит, чтобы закрыть окно. Теперь посмотрим что у нас получилось. Code --[[ Мой первый сценарий! ]] -- Variables local NPC_ID = ид нпс -- On Triggers function exampleGossipOnTalk(Unit, Event, player) Unit:GossipCreateMenu(100, player, 0) Unit:GossipMenuAddItem(0, "Телепорт меня в столицу.", 1, 0) Unit:GossipMenuAddItem(0, "Удалить болезнь после воскрешения.", 2, 0) Unit:GossipMenuAddItem(0, "Выход.", 3, 0) Unit:GossipSendMenu(player) end function exampleGossipOnSelect(Unit, Event, player, id, intid, code, pMisc) if (intid == 1) then player:Teleport(1, -9101.980469, 1612.902832, 21) player:GossipComplete() end if (intid == 2) then if (player:HasAura(15007) == true) then player:SendBroadcastMessage("Болезнь после воскрешения была удалена. Будьте осторожны в следующий раз!") player:RemoveAura(15007) player:GossipComplete() else player:SendBroadcastMessage("У вас нет болезни после воскрешения!") player:GossipComplete() end end if (intid == 3) then player:GossipComplete() end end RegisterUnitGossipEvent(NPC_ID, 1, "exampleGossipOnTalk") RegisterUnitGossipEvent(NPC_ID, 2, exampleGossipOnSelect) Молодцы! Вы создали свой первый сценарий функционирования. Или, по крайней мере, с помощью этого учебника. Сохраните его как TeleporterNPC.lua и поместить его в папку scripts. Поставьте нпс и перезагрузите сервер, и наслаждайтесь вашим первым сценарием! If и elseif. Таким образом, вы знаете, как использовать If и elseif но, используя следующее довольно сложно читать ну и как то однообразно; Code if (var == true) then Weee() end if (var == false) then Awww() end if (var == nil) then WTFITSHOULDNTBENIL() end Вместо этого, вы можете заменить 2й и 3й if на elseIf, в зависимости от ситуации. elseIf в основном удаляет последующие if и заканчивается так, что они легко читаются. Вот наглядным пример. Code if (var == true) then Wee() elseif (var == false) then Awww() elseif (var == nil) then WTFITSHOULDNTBENIL() end Как вы можете видеть, это гораздо легче читать, чем предыдущие. Ну что же. Вот и конец этого учебника. Вторая часть будет более позже. Так же если вы будете использовать lua скрипты с русскими символами не забываем ставить кодировку UTF-8 Всем удачного изучения этого языка. Если у вас есть какие то либо вопросы то не стесняйтесь задавайте их. There is nothing better than .LUA |
| |||
| |||