Ultimate Lua Tutorial menu

User Tag List

Results 1 to 10 of 10
  1. #1
    Trle94's Avatar Contributor
    Reputation
    167
    Join Date
    May 2009
    Posts
    329
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Ultimate Lua Tutorial

    Welcome to the...
    ...Ultimate Lua Tutorial


    Index
    ======
    Intro 1 - Lua Rules
    Intro 2 - Lua Hooks
    Intro 3 - Lua Functions
    ======
    1.1 - Getting the Tools and References
    1.2 - Creating NPC Gossip
    1.3 - Understanding NPC Gossip
    1.4 - Creating a Teleporter
    ======
    2.1 - Creating Custom Commands
    2.2 - Understanding Custom Commands
    2.3 - Creating PvP System
    2.4 - Creating Global Chat System
    2.5 - Understanding the Chat/PvP System
    ======
    3.1 - Creating Bosses
    3.2 - Creating Advanced Bosses
    3.3 - Bosses and Phasing
    ======
    4.1 - Putting Variables in Text
    4.2 - Using GM Ranks for Different Outcomes
    4.3 - Misc
    ======

    Intro 1 - Lua Rules
    Lua is an easy to learn scripting language for the ArcEmu emulator. At some time before WotLK, Lua didn't have more than half of the commands it does now. This is all thanks to LuaHypArc, which is now standard in all ArcEmu cores. But like every thing in this world, there are rules. You may understand these as we go on, I may explain the rules as we go on.

    Remember: Every 'if' requires an 'end'
    Remember: Every 'function' requires an 'end'
    Remember: Every 'for' requires an 'end'
    Remember: Lua is case sensitive and code sensitive. (ex: pPlayer: cannot be pplayer: )
    Remember: You must use statements that ArcEmu has implemented. (ex: pPlayer:GetName(). Not: pPlayer's:Name())
    Remember: You can comment things with '--'. Comments WILL NOT be noticed by the Lua Engine. Comments can include your thoughts, ToDo's, and more. (ex: -- Kibblebit's Script)
    Remember: Block comments can comment more than one line (ex: --[[ Kibbles and Bits is a branded dogfood
    and is not supported by Kibblebit of ************ ]]--)

    ======
    Intro 2 - Lua Hooks

    In most (or every) script you make, you must register your function with server hooks. Server hooks determine how the script is used. (ex: Server hook '16' is for chatting scripts)
    Here is a Server Hook list I found using 'Google' <- a useful search engine.
    Code:
    http://www.arcemu.info/wiki/index.php?title=List_of_All_Events
    Here is an example of a hook in use: RegisterServerHook(HookID, "FunctionName")
    Hooks vary when registered. Bosses, Gossip NPC's, items, gameobjects all require different kind of hooks and Registter's...
    ======

    Intro 3 - Lua Functions

    Lua has A LOT of functions. Hell, you can even create your own (given advanced knowledge). Functions are what run your Lua script. Gossip, Chat, Boss, and Misc scripts all require some kind of functions. Functions determine your syntax too!
    Functions are something like:
    Code:
    function ChatSystem (event, player, message, type, language)
    That function is from my Global Chat System I made. Functions are very needed when getting a player or units information.

    ======
    1.1 Getting The Tools And References

    -- OPTIONAL --

    Notepad++ - VERY useful tool that highlights Lua syntax

    Lua Commands - Helpful list of Lua Commands that can be put into your script!

    -- OPTIONAL --

    ======

    1.2 - Creating NPC Gossip

    Lets start out with the basic script:
    Code:
    local NPCID = 90000
    
    function FirstGossipNPC(Unit, event, player)
    Unit:GossipCreateMenu(1000, player, 0)
    Unit:GossipMenuAddItem(1, "Hello", 1, 0)
    Unit:GossipSendMenu(player)
    end
    
    function GossipOnSelect(Unit, Event, player, id, intid, code)
    
    end
    
    RegisterUnitGossipEvent(NPCID,1,"FirstGossipNPC")
    RegisterUnitGossipEvent(NPCID,2,"GossipOnSelect")
    That is your basic outline of a Gossip script. When you go ingame, talk to a NPC with an entry ID of 90000, you will get an option menu that says 'Hello'. So far, when you click that option, it does NOTHING. Lets change that!

    Look at this revised Gossip Script:
    Code:
    local NPCID = 90000
    
    function FirstGossipNPC(Unit, event, player)
    Unit:GossipCreateMenu(1000, player, 0)
    Unit:GossipMenuAddItem(1, "Hello, give gold.", 1, 0)
    Unit:GossipSendMenu(player)
    end
    
    function GossipOnSelect(Unit, Event, player, id, intid, code)
    if (intid == 1) then
    player:DealGoldMerit(1000000)
    Unit:GossipCreateMenu(1000, player, 0)
    Unit:GossipMenuAddItem(1, "Thanks", 2, 0)
    Unit:GossipSendMenu(player)
    end
    
    if (intid == 2) then
    player:GossipComplete() -- Closes gossip menu
    end
    end
    
    RegisterUnitGossipEvent(NPCID,1,"FirstGossipNPC")
    RegisterUnitGossipEvent(NPCID,2,"GossipOnSelect")
    The revised script should give you an option saying 'Hello, give me gold.' when you talk to the NPC. When you click that option, you will receive 100 gold. Then, when you click 'Thanks', you will exit the gossip menu.
    Remember: When dealing with gold in Lua, convert it to copper. 1000000 copper = 100 gold.

    ======

    1.3 - Understanding NPC Gossip

    In the last chapter, you studied a simple Lua Gossip script that would give you an option to get 100 gold. I will now explain that entire script. Lets break it down; line by line.

    Code:
    local NPCID = 90000
    Locals are user defined variables. When using big scripts, these Locals help a lot! Usage:
    [code]
    local VARIABLENAME = KibbleChat
    /code]
    Locals must be all lower case. The 'VARIABLENAME' can be anything you want. You define your variable after the '=' sign.
    Code:
    function FirstGossipNPC(Unit, event, player)
    'function' is what you need, make sure to add a space after it. 'FirstGossipNPC' can be anything you want, just make sure you remember it for later use. '(Unit, event, player)' are the arguments in the function that you will/will not address.
    Code:
    Unit:GossipCreateMenu(1000, player, 0)
    Unit:GossipMenuAddItem(1, "Hello, give gold.", 1, 0)
    Unit:GossipSendMenu(player)
    end
    REMEMBER: The 'Unit:' prefix is what the Lua script is targeting. In this case, the Unit (or NPC, Player) is opening a Gossip Menu.

    'GossipCreateMenu(1000, player, 0)' basically opens up the Gossip Menu. 1000 is NPC Text. I think 1000 = "Hello, PlayerName, how can I help you?"

    'GossipMenuAddItem(1, "Hello, give gold.", 1, 0)' is the Lua command to give a Gossip option to the player. "Hello, give gold." is the option text. DO NOT DELETE THE QUOTES. The '1' before the option text is the icon id. I believe icons range from 1-10. The second '1' is your intid. Intids are like option ids. When you click 'Hello, give gold.", you will go to intid 1. In most Gossip scripts, the '0' will ALWAYS be '0'.

    Code:
    Unit:GossipSendMenu(player)
    Just make sure the player sees the Menu.

    Code:
    end
    Every function and every if requires an 'end'. So far, we only have a function, so only put 1 'end'.

    Code:
    function GossipOnSelect(Unit, Event, player, id, intid, code)
    if (intid == 1) then
    player:DealGoldMerit(1000000)
    Unit:GossipCreateMenu(1000, player, 0)
    Unit:GossipMenuAddItem(1, "Thanks", 2, 0)
    Unit:GossipSendMenu(player)
    end
    We needed a new function with new arguments so we can identify the intids.

    'if (intid == 1) then' says that -> If you clicked on "Hello, give gold.", then give the player 1000000 copper and send him/her a menu giving the 'Thanks' option.
    Which also explains the other menu haha.

    In this part of the script, add TWO 'end's. Why? Because we have an 'if' and a 'function'. I hope you understand.

    ======

    1.4 - Creating a Teleporter

    In this chapter, we will make you a simple, 1 optioned teleporter.

    Basically, this is a gossip script, only when you choose an option, you will teleport. Cool huh?

    Code:
    function Teleport_main_menu(pUnit, player)
    
        pUnit:GossipCreateMenu(3544, player, 0)
          pUnit:GossipMenuAddItem(0, "Stormwind", 1, 0)
    
          pUnit:GossipSendMenu(player)
         end
    
    function Teleport_on_gossip_talk(pUnit, event, player)
    if(intid == 1) then
          player:Teleport(0, -4981.250000, -881.541992, 501.660004) --Stormwind
    end
    end
    RegisterUnitGossipEvent(991198, 1, "Teleport_on_gossip_talk") 
    RegisterUnitGossipEvent(991198, 2, "Teleport_on_gossip_select")
    I'm pretty sure that will work, I can't test it right now. Anyway, 'player:Teleport(mapid, x, y, z)' is Lua command to teleport. You can get the mapid, x, y, z by going ingame and typing .gps.
    ======

    2.1 - Creating a Custom Command

    So far in this tutorial, we've learned about Gossip Lua and Basic Lua Rules and Functions. Along with some Server Hooks.

    In this chapter, we will focus on using those server hooks to your advantage. As well as using them to create custom player commands!

    For an example in this chapter, we will be creating a Global Chat System, Custom Player Commands, and a PvP System. Oh boy!

    First though, I'd like to start off with the easy stuff.... Custom Player Commands. Custom Player Commands allow the player to get perks when they type a certain phrase in the in-game chatbox. Exactly like GM Commands!

    Lets start off with one of the most basic Custom Commands in the world. We will make my 'Sex Me Up' script. You shall love it
    Here's the base script:
    Code:
    function Chat (event, player, message, type, language)
    	if (message == "#sex") then
    		player:SetModel(62969)
    		player:SendBroadcastMessage("You have been sexed up!")
    return 0
    end
    	end
    RegisterServerHook(16, "Chat")
    Take note of the function arguments. Our Server Hook is '16'. Server Hook 16 means that when the player types something, the script will perform.
    Also note that "Chat" is the same exact lettering as the function. THAT IS WHY YOU MUST ALWAYS REMEMBER YOUR FUNCTION NAME. YOU NEED THE SAME EXACT NAME TO REGISTER IT.
    The Lua script in the [code] box is our custom command script. When a player (or GM) goes in-game and types '#sex' (without ''), they will turn into a Panda and get a message saying "You have been sexed up!". Hehe.
    ======

    2.2 - Understanding Your Custom Command

    Code:
    function Chat (event, player, message, type, language)
    	if (message == "#sex") then
    		player:SetModel(62969)
    		player:SendBroadcastMessage("You have been sexed up!")
    return 0
    end
    	end
    RegisterServerHook(16, "Chat")
    That is the script we created in our last section. It turns you into Panda when you type #sex ingame.
    We will now break down the script so that we understand each Lua argument and command.

    I'm not even going to explain the 'function Chat' part. I've mentioned it so many times now.

    'if (message == "#sex") then' is the phrase the player needs to type ingame to use the command. You can change the "#sex" to whatever you wnat, just DO NOT DELETE QUOTES.

    'player:SetModel(62969)' turns the PLAYER: into a PANDA. Notice where '(62969)' is? Type your display ID inside the ( )! '62969' is a display ID for Kung Foo Panda. :>

    player:SendBroadcastMessage("You have been sexed up!") sends the player a broadcast message saying 'You have been sexed up!'. You may also use ":SendAreaTriggerMessage". Which will send the player a area trigger instead of a broadcast. The only difference is that area triggers disappear faster.

    'return 0' usually comes after the custom command portion. 'return 0' disables the players message to go through so you don't spam "#sex" everywhere.

    Since we have ONE function and ONE if, we will need to add ONE PLUS ONE. And we'll get TWO. Therefore, we will add TWO ENDS AT THE END OF THE SCRIPT.

    I explained the Server Hook part in the last section.
    ======

    2.3 - Creating a PvP System

    I hope you are enjoying this huge tutorial, because we will be creating a few more scripts that will give you the information you need to succeed in the emulation world!
    In this section, we will be creating a PvP Announcer! This will include: PvP Announcer. Sounds good huh? Yeah it is!

    Now, I should mention that this script is pretty easy if you pay attention. This script is simple, useful, and informational, so listen up!
    Here is our PvP Announcer. I have seperated the scripts for more simplicity. While you review the script, ask your self: "Hmm, what does that Lua argument/command do?". When you ask yourself that, you have a higher chance to understand!
    For this script, I'd like to give credits to Syke for his String Manipulation tutorial, for the script I'm using as an example.
    Code:
    function PvP_OnHonorableKill(event, pPlayer, pKilled)
    	for k,v in pairs(GetPlayersInWorld()) do
    	    v:SendBroadcastMessage("[PvP Announcer]:" .. pPlayer:GetName() .. "[" .. pPlayer:GetLevel() .. "] has killed " .. pKilled:GetName() .. "[" .. pKilled:GetLevel() .. "]")
    	end
    end
    
    RegisterServerHook(23, "PvP_OnHonorableKill")
    When you kill another player ingame, a broadcast message will appear saying: "[PvP Announcer]: Kibblebit[80] has killed Syke[80]" Pretty simple huh? Yeah!
    Now, we will create a Global Chat System, like my Kibblechat!
    ======

    2.4 - Creating a Global Chat System

    A Global Chat System allows the player to send a message to the world. A lot like the Channels in WoW. This script can be complicated if you do not pay attention.
    The |cFF00FFFF (and other simular codes) are Hex Color Codes. In text, put those before the desired group of words and your text will be colored in game!!! Just Google some codes!
    Here is a clip of my KibbleChat script. When you type: #c I love Kibblebit ingame, you will send a message to everyone that will appear like: [Chat System] [Horde] [Kibblebit]: I love Kibblebit!
    Keep in mind, the "local ChatMsg = "#c"" part of the script is the command used to initiate the chat message for Global use. DO NOT DELETE THE QUOTES AROUND THE COMMAND.

    Code:
    local ChatMsg = "#c"
    
    function GlobalChat (event, player, message, type, language)
    	if (message:find(ChatMsg.." ") == 1) then
    		local text = message:gsub(ChatMsg.." ", "") 
    				for k, v in pairs(GetPlayersInWorld()) do
    			if (player:GetTeam() == 0) then -- Alliance - Shows up as Cyan color text
    				v:SendBroadcastMessage("|cFF00FFFF[Chat System] |cFFFFA500[Alliance] |cFF00FFFF["..player:GetName().."]: |cffffcc00"..text.."")
    			end
    			if (player:GetTeam() == 1) then -- Horde - Shows up as redish text!
    				v:SendBroadcastMessage("|cFF00FFFF[Chat System] |cffff0000[Horde] |cFFFF6060["..player:GetName().."]: |cFFFF6060"..text.."")
    			
    				end
    					end
    						end
                                                         return 0
    							end
    RegisterServerHook(16, "GlobalChat")
    And there is the script. I made it so that Horde will get their own tags and colors and vice versa.
    Take note that there are 3 ifs, 1 function, and 1 for. When you see 'for' in your scripts, that requires a 'end' too. That means, we need a total of 5 'end's. The 'return 0' ensures that the message the player types does not end up in /say instead of the global chat.
    ======

    2.5 - Understanding PvP/Global Chat System

    In the last two sections, we gathered information about making PvP related scripts and Global Chat scripts. You can spice these up a bit. For the Global Chat system, you may add arguements for "IsGm" or " player:GetRank('az') " to add different tags for GMs and Admins!
    I would also like to tell you that if you have a 'if' followed by another 'if', just use 'elseif' for the second 'if' instead. You will get the hang of it, just take a look at my KibbleChat script to learn more about that!
    Anyway, I am going to break down the PvP Announcer to make it more understandable for your learning needs
    Code:
    function PvP_OnHonorableKill(event, pPlayer, pKilled)
    	for k,v in pairs(GetPlayersInWorld()) do
    	    v:SendBroadcastMessage("[PvP Announcer]:" .. pPlayer:GetName() .. "[" .. pPlayer:GetLevel() .. "] has killed " .. pKilled:GetName() .. "[" .. pKilled:GetLevel() .. "]")
    	end
    end
    
    RegisterServerHook(23, "PvP_OnHonorableKill")
    I am not even going to mention the 'function' part, I've explained it MANY times.'
    'for k,v in pairs(GetPlayersInWorld()) do' - Sends the PvP announce to all players online. 'v' is the prefix for your Lua commands. For example: v:SendBroadcastMessage
    You can also do something like: for k,v in pairs(GetPlayersInZone(zoneid)) do. (Please note: I'm not sure thats the real 'Get Players in Zone' command) That will send the message to all players in the zone, instead of the world. More like a General Channel.
    The v:SendBroadcastmessage part is pretty self explanatory. But, if you look where the text portion is, you'll notice that there are some Lua "Get" commands in there. Refer to the Unit Command list I gave in first chapter for more Get commands, but I will tell you that when you want to get a players info, you must type something like this: "..player:GetName()..". When ingame, that will show the player's name... YOU NEED TO ADD A QUOTE BEFORE AND AFTER THE LUA 'GET' COMMAND, AS WELL AS TWO PERIODS BEFORE AND AFTER THE LUA 'GET' COMMAND. THE PERIODS MUST BE INSIDE THE QUOTES THOUGH.
    /caps off
    We have 1 function, and 1 for. Therefor, we need 2 ends.
    The Server Hook for this script is 23. Why? because Server Hook 23 = OnHonorableKill (when a player kills another player)
    Not much to a PvP announcer!

    Now lets break down the chat system.
    Code:
    local ChatMsg = "#c"
    
    function GlobalChat (event, player, message, type, language)
    	if (message:find(ChatMsg.." ") == 1) then
    		local text = message:gsub(ChatMsg.." ", "") 
    				for k, v in pairs(GetPlayersInWorld()) do
    			if (player:GetTeam() == 0) then -- Alliance - Shows up as Cyan color text
    				v:SendBroadcastMessage("|cFF00FFFF[Chat System] |cFFFFA500[Alliance] |cFF00FFFF["..player:GetName().."]: |cffffcc00"..text.."")
    			end
    			if (player:GetTeam() == 1) then -- Horde - Shows up as redish text!
    				v:SendBroadcastMessage("|cFF00FFFF[Chat System] |cffff0000[Horde] |cFFFF6060["..player:GetName().."]: |cFFFF6060"..text.."")
    			
    				end
    					end
    						end
                                                         return 0
    							end
    RegisterServerHook(16, "GlobalChat")
    local ChatMsg = "#c" -- Defined Variable for the if(message:find(ChatMsg.." ") == 1) then line. DO NOT REMOVE THE QUOTES
    I'm not going to explain the function part. Explained in previous scripts.
    if (message:find(ChatMsg.." ") == 1) then -- Basically, it means: if the player says #c, followed by a space, then text, it will use that as our global Chat message!
    local text = message:gsub(ChatMsg.." ", "") -- Shortens up the Lua command for the scripter for more simplicity. The command just checks for a space after #c
    for k, v in pairs(GetPlayersInWorld()) do -- Same thing that I explained in PvP Announcer
    if (player:GetTeam() == 0) -- If the player is on the Alliance (Team ID = 0) then he is Alliance
    v:SendBroadcastMessage("Text and Variables Here") -- Sends broadcast message to the world (all players online) 'v' = GetPlayersInWorld()
    end -- Just seperates the Alliance team from Horde team (although Horde can see Alliance messages when they use Global Chat
    if (player:GetTeam() == 1) then -- If the player is a horde (Team ID = 1) then he is a Horde
    v:SendBroadcastMessage("Text and Variables Here") -- Sends broadcast message to the world only since you're a horde, you get a [Horde] tag. Same for alliance.
    We have 1 function, 3 if, and 1 for. 1 + 3 + 1 = 5. We need 5 end.
    Don't forget to add the 'return 0' before the last end!!! (The last end closes the entire script function.)

    Great! We've finished Chapter 2! In this tutorial you've: Made a PvP Announcer, Created a Global Chat System, and learned everything about them!
    But wait! We've got more to do! Read on!
    ======

    3.1 - Creating Bosses

    In this chapter, we will be working with bosses. Bosses are NPC's that you get to kill. It's not fun if the NPC does nothing but punch you though, that is why people script them in Lua and C++. (Although C++ isn't required!). Boss scripts can include boss messages, spells, and even phasing and waypoints!
    In this section, we will be just adding some messages to the boss when he begins combat, dies, and kills another player. These require different Server Hooks and functions as well. Trust me, you may be using a lot of functions and registers.
    Here is a simple boss I made, I'll even explain the commands in comments.
    Code:
    local npcid = 90000 -- Boss entry id
    
    function Boss_BeginCombat(pUnit, event)
    pUnit:SendChatMessage(14, 0, "I am going to destroy you.") -- 14 is the language. 14 = Universal (everyone can understand it, no matter race!) 0 is say ( the boss will say that message, not yell or whisper, etc...)
    end -- 1 function = 1 end
    
    function Boss_LeaveCombat(pUnit, event)
    pUnit:SendChatMessage(14, 7, "Did you get scared?") -- 7 = yelling the message. Boss will say this when he leaves combat.
    end
    
    function Boss_KillsPlayer(pUnit, event)
    pUnit:SendChatMessage(14, 0, "Muahaha I killed you!") -- Boss says this message when he kills a player.
    end
    
    function Boss_Death(pUnit, event)
    pUnit:SendChatMessage(14, 0, "Oh no! You killed me!") -- Boss says this message when he dies!
    end
    
    RegisterUnitEvent(npcid, 1, "Boss_BeginCombat") -- Note that when dealing with bosses, you register like: RegisterUnitEvent(npc entry id, Unit Hook (just like server hooks), "function name") (Unit Hook 1 = On Combat
    RegisterUnitEvent(npcid, 2, "Boss_LeaveCombat") -- Unit Hook 2 = OnLeaveCombat
    RegisterUnitEvent(npcid, 3, "Boss_KillsPlayer") -- Unit hook 3 = OnKillTarget(player)
    RegisterUnitEvent(npcid, 4, "Boss_Death") -- Unit Hook 4 = OnDeath
    There is nothing to it! Now lets say you want to add spells, cool! Then lets add spells!
    ======

    3.2 - Creating Advanced Bosses

    In the last section, we created a fairly simple boss that does nothing but say stuff when something happens, right? So now we want to make him more deadly!!! Lets add spells!
    I failed to mention earlier in the tutorial that you need to have a pre-existing NPC in your database to make this script work.
    Anyway, I'm going to show you what a complete Boss Fight with spells looks like. Credits to: EpiclyNoobish for this boss script. I did not feel like making my own.
    Code:
    local npcid = 90000 -- Boss Entry ID
    
    function ArchmageArugal_ArcaneExplosion(Unit, event, miscunit, misc)
    	Unit:FullCastSpellOnTarget(42921,Unit:GetClosestPlayer()) -- The spell id 42921 will be casted on the closest player to the boss on combat
    	Unit:SendChatMessage(14, 0, "Prepare to Vanish!")
    end
    
    function ArchmageArugal_Fear(Unit, event, miscunit, misc)
    	Unit:FullCastSpellOnTarget(6213,Unit:GetClosestPlayer()) -- The spell id 6213 will be casted on the clostest player (unless its aoe) when the boss kills a player
    	Unit:SendChatMessage(14, 0, "Run in fear!")
    end
    
    function ArchmageArugal_ShadowBolt(Unit, event, miscunit, misc)
    if Unit:GetHealthPct() <= 50 then -- When boss hits 50% health, he will do something specified below.
    	Unit:RemoveEvents() -- Make sure he doesn't spam his other spells. 
    	Unit:FullCastSpellOnTarget(47809,Unit:GetClosestPlayer()) -- The spell id 47809 will be casted on the closest player to the boss when his health reaches 50%
    	Unit:SendChatMessage(14, 0, "The Darkness Begins!")
    end
    end -- We need two end, because of the if.
    
    function ArchmageArugal_Death(Unit, event)
    	Unit:RemoveEvents()
    end
    
    RegisterUnitEvent(npcid,1,"ArchmageArugal_ArcaneExplosion")
    RegisterUnitEvent(npcid,1,"ArchmageArugal_ShadowBolt")
    RegisterUnitEvent(npcid,3,"ArchmageArugal_Fear")
    RegisterUnitEvent(npcid,4,"ArchmageArugal_Death")
    Keep in mind that you have to register a spell in the correct sequence. Ex: Registering the spell function in OnCombat would start a phase, or just simply a spell.
    Please note that I had to fix this script up alot because EpiclyNoobish really is Noobish. This script may not work because I have not tested it. It is a very useful reference anyway.
    Nice, in this section, we learned how to add spells to a boss. I even gave you a little information on how to make an event happen when a boss hits a certain point in his health. To learn more about phasing (just like retail style) move on to the next section!
    ======

    3.3 - Bosses and Phasing

    What is phasing?
    Phasing is just like the life of a human. At a certain point in life, they do different things!
    Since this is a boss, we are going to make him do certain things when he gets to a certain point on his health bar!

    For this section, I am going to cover everything in comments.
    The following script was created by blueteak. I'm using his script because it includes nice use of Phases, NPC Spawns, and Health Pcts!
    When go to fight hogger, Hogger will spawn a minion. Blueteak even went through the trouble of scripting the minion!
    I warn you, this script is almost 9000 characters long, so this might take up another post.
    Code:
    function Hogger_OnCombat (pUnit, Event) -- Hogger enters combat
    		pUnit:SendChatMessage(14,0, "Mmmm... more bones to gnaw on!") -- Hogger sends message when he begins fighting
    		pUnit:FullCastSpell(61672) -- Hogger casts a spell with this id
    		pUnit:RegisterEvent("Hogger_PhaseOne", 1000, 0) -- Hogger begins phase one. The '1000' part should always be '1000' when registering a new phase.
    end -- 1 function = 1 end
    
    function Hogger_OnLeave (pUnit, event) -- Hogger leaves combat
    			pUnit:SendChatMessage(14, 0, "The masters blade work wonders!") -- Sends chat message
    			pUnit:RemoveEvents() -- Hogger removes events (spells, auras, etc...)
    end
    
    function Hogger_KilledTarget (pUnit, event) -- Hogger killed something
    			pUnit:SendChatMessage(14, 0, "Come Now filthy woman!") -- Summons his minion
    		local x = pUnit:GetX(); -- The minion will spawn where hogger is at the time of this summon.
    		local y = pUnit:GetY(); -- The minion will spawn where hogger is at the time of this summon.
    		local z = pUnit:GetZ(); -- The minion will spawn where hogger is at the time of this summon.
    		local o = pUnit:GetO(); -- The minion will spawn where hogger is at the time of this summon.
    	pUnit:SpawnCreature (51008, x, y+5, z, o, 14 ,30000); -- Hogger spawns his minion
    end
    
    function Hogger_OnDie (pUnit, event) -- Hogger dies
    			pUnit:SendChatMessage(14, 0, "Not..possible......hogger...is...ETERNAL!") -- Hogger sends chat when he dies
    			pUnit:FullCastSpell(57381) -- Hogger casts this when he dies
    			pUnit:RemoveEvents() -- Hogger doesn't do anything after he dies
    end -- 1 function = 1 end
    
    RegisterUnitEvent (51007, 1, "Hogger_OnCombat") -- Blueteak uses his own scripting method of registering his basic hooks first.
    RegisterUnitEvent (51007, 2, "Hogger_OnLeave")
    RegisterUnitEvent (51007, 3, "Hogger_KilledTarget")
    RegisterUnitEvent (51007, 4, "Hogger_OnDie")
    
    function Hogger_PhaseOne (pUnit, Event) -- Hogger is in phase 1. Phase 1 starts as soon as he enters combat.
    	if pUnit:GetHealthPct() <= 100 then -- If hogger's health is at 100% then...
    		pUnit:RemoveEvents() -- removes events in case of problems
    			pUnit:RegisterEvent("Hogger_swarm", 20000, 0) -- Registering spell function for phase one. NOTE: 20000 = 20 SECOND INTERVALS.
    			pUnit:RegisterEvent("Hogger_Unbalance", 5000, 0) -- 5000 = 5 SECOND INTERVALS
    			pUnit:RegisterEvent("Hogger_ravage", 15000, 0) -- 15000 = 15 SECOND INTERVALS
    			-- Yes, where big numbers are, is the interval (in msecs i think) that the boss will do the functions
    	end -- closing the if
    	pUnit:RegisterEvent("Hogger_PhaseTwo", 1000, 0) -- Registering phase 2
    end -- closing PhaseOne
    
    function Hogger_PhaseTwo (pUnit, Event) -- Needs Two Tanks because of wither strike...
    	if pUnit:GetHealthPct() <=75 then -- When Hogger reaches 75% health, he will do...
    		pUnit:RemoveEvents() -- removes any previous usage of spells
    			pUnit:SendChatMessage(14, 0, "The master give me great power! You no take power!")  -- sends message
    			pUnit:SetScale(3.7) -- HOGGER INCREASES IN SIZE
    			pUnit:RegisterEvent("Hogger_Unrelenting", 5000, 0) -- Registering phase two spells
    			pUnit:RegisterEvent("Hogger_Howl", math.random(11000, 31000), 0) -- Hogger will howl anywhere from 11 seconds to 31 second intervals (nice job Blueteak)
    			pUnit:RegisterEvent("Hogger_Destroy", 21000, 0)
    			pUnit:RegisterEvent("Hogger_Wither2", 1500, 0) -- Stacks 50x, 2% reduced stats, lasts 10 seconds :)
    	end
    	pUnit:RegisterEvent("Hogger_PhaseThree", 1000, 0) -- Get ready for round 3
    end
    
    function Hogger_PhaseThree (pUnit, Event)
    	if pUnit:GetHealthPct() <=50 then -- When Hogger has 50% health, then.....
    		pUnit:RemoveEvents() -- removes any previous spells, auras, etc...
    			pUnit:SendChatMessage(14, 0, "Master say I have IQ of murloc! I not know what that means... only know that you die!")
    			pUnit:RegisterEvent("Hogger_Rampage", math.random(30000, 45000), 0) -- Spell is casted anywhere from 30 second to 45 second intervals
    			pUnit:RegisterEvent("Hogger_jab", 8000, 0)
    			pUnit:RegisterEvent("Hogger_Wither", math.random(90000, 1200000), 0) -- Casted anywhere from 1min 30 secs to 2mins
    	end
    	pUnit:RegisterEvent("Hogger_PhaseFour", 1000, 0) -- Uh oh... another phase. Take note of how he registers his phases
    end
    
    function Hogger_PhaseFour (pUnit, Event)
    	if pUnit:GetHealthPct() <=25 then -- When hogger has 25% health, he does...
    		pUnit:RemoveEvents()
    			pUnit:SendChatMessage(14, 0, "") -- Not sure why Blueteak has this to be honest. Useless.
    			pUnit:SetScale(4) -- Hogger increases in size
    			pUnit:RegisterEvent("Hogger_minienrage", 30000, 0) -- More spells for Phase 4
    			pUnit:RegisterEvent("Hogger_shred", 16000, 0)
    			pUnit:RegisterEvent("Hogger_rend", 30000, 0)
    			pUnit:RegisterEvent("Hogger_kick", 10000, 0)
    			pUnit:RegisterEvent("Hogger_uppercut", 5000, 0)
    	end
    	-- Notice how there are no more phases, so he doesn't register another phase
    end
    
    function Hogger_swarm (pUnit, Event)
    		local plr = pUnit:GetRandomPlayer(0) 
    		if(plr ~= nil) then -- If there are no random players, then...
    			pUnit:SendChatMessage(14, 0, "Master give me bugs to squish into gnomes' heads!")
    			pUnit:FullCastSpellOnTarget(58852, plr)
    		else
    	end
    end
    
    function Hogger_Destroy (pUnit, Event)
    		local plr = pUnit:GetMainTank() -- Casts spell on the tank
    		if(plr ~= nil) then
    			pUnit:SendChatMessage(14, 0, "NO!")
    			pUnit:FullCastSpellOnTarget(59151, plr)
    		else
    	end
    end
    
    function Hogger_ravage (pUnit, Event)
    		local plr = pUnit:GetMainTank()
    		if(plr ~= nil) then
    			pUnit:FullCastSpellOnTarget(29906, plr)
    		else
    	end
    end
    
    
    function Hogger_Wither2 (pUnit, Event)
    		local plr = pUnit:GetMainTank()
    		if(plr ~= nil) then
    			pUnit:FullCastSpellOnTarget(48585, plr)
    		else
    	end
    end
    
    
    function Hogger_uppercut (pUnit, Event)
    		local plr = pUnit:GetMainTank()
    		if(plr ~= nil) then
    		cut = math.random (1,3) -- More uses of randoms
    			if (cut == 1) then
    				pUnit:FullCastSpellOnTarget(32055, plr) -- Uppercut
    			end
    			if (cut == 2) then
    				pUnit:FullCastSpellOnTarget(32055, plr) -- Uppercut
    			end
    			if (cut == 3) then
    				pUnit:SendChatMessage(14, 0, "Hogger SMASH!")
    				pUnit:FullCastSpellOnTarget(50084, plr) -- HULKING UPPERCUT
    			end
    		else
    	end
    end
    
    
    function Hogger_kick (pUnit, Event)
    		local plr = pUnit:GetMainTank()
    		if(plr ~= nil) then
    			pUnit:FullCastSpellOnTarget(38625, plr)
    		else
    	end
    end
    
    
    function Hogger_Unbalance (pUnit, Event)
    		local plr = pUnit:GetRandomPlayer(0)
    		if(plr ~= nil) then
    			pUnit:FullCastSpellOnTarget(67237, plr)
    		else
    	end
    end
    
    function Hogger_Unrelenting (pUnit, Event)
    		local plr = pUnit:GetRandomPlayer(0)
    		if(plr ~= nil) then
    			pUnit:FullCastSpellOnTarget(51491, plr)
    		else
    	end
    end
    
    function Hogger_Howl (pUnit, Event)
    		local plr = pUnit:GetRandomPlayer(0)
    		if(plr ~= nil) then
    			pUnit:FullCastSpellOnTarget(10576, plr)
    		else
    	end
    end
    
    function Hogger_Rampage (pUnit, Event)
    		local plr = pUnit:GetRandomPlayer(7)
    		if(plr ~= nil) then
    			pUnit:FullCastSpellOnTarget(25744, plr)
    		else
    	end
    end
    
    function Hogger_jab (pUnit, Event)
    		local plr = pUnit:GetRandomPlayer(0)
    		if(plr ~= nil) then
    			pUnit:FullCastSpellOnTarget(31551, plr)
    		else
    	end
    end
    
    function Hogger_minienrage (pUnit, Event)
    			pUnit:SendChatMessage(14, 0, "No more play, now you die!")
    			pUnit:FullCastSpell(54475)
    end
    
    function Hogger_shred (pUnit, Event)
    		local plr = pUnit:GetRandomPlayer(0)
    		if(plr ~= nil) then
    			pUnit:FullCastSpellOnTarget(40770, plr)
    		else
    	end
    end
    
    function Hogger_rend (pUnit, Event)
    		local plr = pUnit:GetRandomPlayer(0)
    		if(plr ~= nil) then
    			pUnit:FullCastSpellOnTarget(42397, plr)
    		else
    	end
    end
    
    function Hogger_wither (pUnit, Event)
    		local plr = pUnit:GetMainTank()
    		if(plr ~= nil) then
    			pUnit:FullCastSpellOnTarget(5337, plr)
    		else
    	end
    end
    
    ----- Mankirks Wife! -----------
    -- Now this is the part where Blueteak scripts the minion Hogger spawns.
    function Wife_OnCombat (pUnit, Event)
    		pUnit:SendChatMessage(14, 0, "p..please... no more beatings...")
    		pUnit:RegisterEvent("Wife_PhaseOne", 1000, 0) -- Minion has to fight. Phase 1 woot
    end
    
    function Wife_OnLeave (pUnit, event)
    			pUnit:SendChatMessage(14, 0, "Mankrik! Save me!") -- When the minion leaves combat, this will happen
    			pUnit:RemoveEvents()
    			pUnit:Despawn(0, 0) -- Despawns the minion. (Delete this line if you want the minion to be looted)
    end
    
    function Wife_KilledTarget (pUnit, event) -- When the minion kills a unit...
    		pUnit:SendChatMessage(14, 0, "I will do what it takes to return to my husband!")
    end
    
    function Wife_OnDie (pUnit, event) -- When the minion dies...
    		pUnit:SendChatMessage(14, 0, "I must...return..to..the....Barrens.. MANKRIK!")
    end
    
    RegisterUnitEvent (51008, 1, "Wife_OnCombat") -- Registering basic hooks
    RegisterUnitEvent (51008, 2, "Wife_OnLeave")
    RegisterUnitEvent (51008, 3, "Wife_KilledTarget")
    RegisterUnitEvent (51008, 4, "Wife_OnDie")
    
    function Wife_PhaseOne (pUnit, Event) -- Woot
    	if pUnit:GetHealthPct() <= 100 then -- Explained already
    		pUnit:RemoveEvents()
    			pUnit:RegisterEvent("wife_drain", 5000, 0) -- Registering spells for phase 1, note that you have to use milliseconds when doing the intervals part.
    			pUnit:RegisterEvent("wife_screech", 11000, 0)
    			pUnit:RegisterEvent("wife_wail", 17000, 0)
    	end
    end
    
    function wife_drain (pUnit, Event)
    		local plr = pUnit:GetRandomPlayer(0)
    		if(plr ~= nil) then
    			pUnit:FullCastSpellOnTarget(44294, plr)
    		else
    	end
    end
    
    function wife_screech (pUnit, Event)
    		local plr = pUnit:GetRandomPlayer(0)
    		if(plr ~= nil) then
    			pUnit:SendChatMessage(14, 0, "I will escape from here to my husband! Nothing you can do will stop me!")
    			pUnit:FullCastSpellOnTarget(51897, plr)
    		else
    	end
    end
    
    function wife_wail (pUnit, Event)
    		local plr = pUnit:GetRandomPlayer(0)
    		if(plr ~= nil) then
    			pUnit:FullCastSpellOnTarget(41545, plr)
    		else
    	end
    end
    -- The minion only has 1 phase. Too bad, would have been cool :)
    Yes, this script is hard to understand at first, but I am pretty sure you will get the hang of it!
    ======

    4.1 - Putting Variables in Text

    Yes, when we created the PvP Announcer and Global Chat system, we saw things like: "..player:GetName().." in the middle of what was supposed to be text.
    In this section, I will explain them.

    You may have to refer to your Unit Commands list website on the Arcemu Wiki. (URL in 1.1)

    If you look closely to the Lua commands in that URL, you will notice they are categorized. Scroll down to the "Get Commands". These commands gather information from the player or NPC.
    For example:
    Code:
    local XX = 90000
    function Someone_OnEnterCombat(pUnit, Event)
        msg = string.format("My name is %s and i will kill you!", pUnit:GetName()) -- Gets the NPC's name.
        pUnit:SendChatMessage(11,0,msg)
    end
    RegisterUnitEvent(XX, 1, "Someone_OnEnterCombat")
    (Taken from the Arcemu Wiki)

    In the example, not only did I show you how to put information in text, I showed you string manipulation! Its fun, and prepares you for C++!
    But, if you're a nubcake, all you have to do is:
    Code:
    pUnit:SendBroadcastMessage("Hello there, "..player:GetName()..". What can I do you for?")
    In my opinion, it is easier to understand it the nubcake way.

    You can even put in User Defined Variables! For example:
    Code:
    local Name = player:GetName()
    pUnit:SendBroadcastMessage("Hello there, "..Name..", how's it going?")
    I think you get the hang of it, lets move on.
    ======

    4.2 - Using GM Ranks for Different Outcomes

    Kibblebit, what do you mean 'different outcomes'? Answer: If you have a certain GM rank, then you get one outcome; if you're a different rank, you get a different outcome from your first rank.
    It might be a little hard to understand, so here is an example:
    Code:
    if(player:GetGmRank() == 'a') then
    	v:SendBroadcastMessage("Yo Gamemaster, whatup G?")
    elseif(player:GetGmrank() == 'az') then
    	v:SendBroadcastMessage("Yo Admin, whatup A?")
    else -- Normal Player (or another rank)
    	v:SendBroadcastMessage("Shut yo mouth, you is not important.")
    Get it now? It isn't a hard concept at all! Take notice that I've made use of the 'elseif' because I have more than one rank to ask for.
    You may also use something like:
    Code:
    if(player:IsGm() == 1) then -- Player is GM (true)
    	v:SendBroadcastMessage("Hi Staff member!")
    else
    	v:SendBroadcastMessage("You are just a player.")
    That :IsGM() boolean asks if the player is a GM.

    Well, that is really all there is to this section...
    ======

    4.3 - Misc

    In this MegaTut, we've learned about Gossip NPCs, Items, and Gameobjects; Bosses, phases, and NPC spawns; and even custom commands and chat systems!
    With Lua, there are many open doors in the emulation world. There are even more with C++! The 'Misc' section has nothing to be filled with right now so I'm going to give you an outro!
    This tutorial has taken a few days to make. I had hand written it. I've researched everything, did many tests, and etc...
    All others work has been credited as we used it.

    I hope that you have enjoyed my tutorial and learned alot from it!

    Have any questions? Contact me. Reply to this post or PM me. Do not add my MSN.
    CREDITS TO Kibblebit


    Ultimate Lua Tutorial
  2. #2
    alj03's Avatar Contributor
    Reputation
    91
    Join Date
    Feb 2008
    Posts
    1,103
    Thanks G/R
    0/1
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Custom command of sex... lol cool.

    Anyway going to finish reading this.
    Death to all but Metal.

  3. #3
    Trle94's Avatar Contributor
    Reputation
    167
    Join Date
    May 2009
    Posts
    329
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Well i read whole and its pretty good


  4. #4
    Timmy420's Avatar Active Member
    Reputation
    16
    Join Date
    Jul 2006
    Posts
    181
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks man I really learned a lot. I understood it all pretty well.

  5. #5
    Trle94's Avatar Contributor
    Reputation
    167
    Join Date
    May 2009
    Posts
    329
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    No problem Tnx you for comment


  6. #6
    lyonar96's Avatar Sergeant
    Reputation
    5
    Join Date
    Aug 2010
    Posts
    36
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    This looks really good Perfect for a noob like me

  7. #7
    Frostic's Avatar Banned
    Reputation
    7
    Join Date
    May 2009
    Posts
    90
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    i say sticky this this is too good to lose

    thanks for the great tutorial

  8. #8
    Trle94's Avatar Contributor
    Reputation
    167
    Join Date
    May 2009
    Posts
    329
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    @lyonar96
    hehe okay as you say
    @Frostic
    No problem if you think that it should be stickied then report post and ask for sticky


  9. #9
    bellios's Avatar Private
    Reputation
    1
    Join Date
    Dec 2010
    Posts
    9
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    great tut, i just learned lua yesterday, and wrote a teleporter script with a few locations. this has helped me with everything you wrote, and gave me more understanding. although, i would have liked to seen how to add loot in a script. anyways, +Rep

  10. #10
    ExitWound's Avatar Member
    Reputation
    1
    Join Date
    Nov 2007
    Posts
    1
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I'm not sure how old this thread is but I have a problem with my script... When I get the npc to cast the finger of death, he casts it on himself instead of me. Here it is:

    Code:
    function Tyrael_OnEnterCombat(Unit)
    Unit:SendChatMessage(12, 0, "Nowhere for you to run...")
    Unit:RegisterEvent("Tyrael_FOD",10000, 0)
    end
    
    function Tyrael_FOD(Unit)
    Unit:FullCastSpellOnTarget(32111,Unit:GetRandomPlayer())
    Unit:SendChatMessage(12, 0, "Behold the power I possess...")
    end
    
    function Tyrael_OnLeaveCombat(Unit)
    Unit:RemoveEvents()
    end
    
    function Tyrael_OnKilledTarget(Unit)
    Unit:SendChatMessage(12, 0, "Who shall be next to fall?")
    Unit:RemoveEvents()
    end
    
    function Tyrael_OnDied(Unit)
    Unit:SendChatMessage(14, 0, "It's not... possible...")
    Unit:RemoveEvents()
    end
    
    RegisterUnitEvent(600001, 1, "Tyrael_OnEnterCombat")
    RegisterUnitEvent(600001, 2, "Tyrael_OnLeaveCombat")
    RegisterUnitEvent(600001, 3, "Tyrael_OnKilledTarget")
    RegisterUnitEvent(600001, 4, "Tyrael_OnDied")
    Can somebody help me?
    Last edited by ExitWound; 01-12-2011 at 07:43 AM.

Similar Threads

  1. [ULTIMATE] Lua Guide & Tutorial
    By Vision1000 in forum WoW EMU Guides & Tutorials
    Replies: 56
    Last Post: 08-17-2011, 10:58 AM
  2. Thekals Lua Tutorial
    By Thekal in forum WoW EMU Guides & Tutorials
    Replies: 36
    Last Post: 06-06-2009, 12:20 AM
  3. [Release] Theo's Ultimate LUA/SQL/EXE Package
    By Ground Zero in forum WoW EMU General Releases
    Replies: 12
    Last Post: 01-07-2009, 09:38 AM
  4. Basic Tutorial on Lua
    By [Shon3m] in forum World of Warcraft Emulator Servers
    Replies: 7
    Last Post: 12-09-2007, 10:26 AM
  5. Ultimate Fishing Bot Tutorial
    By zeks777 in forum World of Warcraft Bots and Programs
    Replies: 19
    Last Post: 05-13-2007, 03:52 PM
All times are GMT -5. The time now is 08:11 AM. Powered by vBulletin® Version 4.2.3
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved. User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2024 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search