[Lua] Not Everything is Perfect menu

User Tag List

Results 1 to 2 of 2
  1. #1
    darkwiz787's Avatar Member
    Reputation
    35
    Join Date
    Mar 2009
    Posts
    250
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    [Lua] Not Everything is Perfect

    Welcome to the new scripting standards announcement
    Hey. Today I'm going to teach you how to script bosses properly. "But I thought I was already scripting uber l33t bosses!?" I hear you say? Well, that's true, but most of us know what the current Lua scripting style didn't cut it in many situations. Things like Violet Hold were impossible, with variables being passed around locally. Also, with everything on the global level, performance was impacted and it just didn't look good. I'll further explain this now.

    The problem
    1. Conflicting variables. When you have more than one copy of a monster using the same script, variables usually collide.
    Example

    Code:
    local player --please never do this from now on.
    
    function NPC_OnSpawn(pUnit, event)
       player = pUnit:GetRandomPlayer(0)
       pUnit:RegisterEvent("NPC_cast_attack", 10000, 1)
    end
    
    function NPC_cast_attack(pUnit, event)
       pUnit:CastSpellOnTarget(1234, player)
    end
    
    RegisterUnitEvent(1337, 1, "NPC_OnSpawn")
    Let's consider that script. So npc #1337 spawns, and chooses a player, and stores it in the script-wide variable player. BUT, what if another npc of #1337 was spawned after the first one? Well, since that npc also uses the same script, player would be changed to whatever the second #1337 picked, and so the first #1337 would have the wrong player. Noes.

    2. Everything has to be stored on the global table. What do I mean by this? Well, when you create a variable, ANY variable, Lua stores it in a table. Yep. A Table. And this table is named "_G". So, when you are in fact creating a variable, you are just assigning another key in the _G table.

    Code:
    my_var = 5
    _G["my_var"] = 5
    Both of those do the same thing, just the top one is the one we use all the time.
    Now, in our current Lua practices, EVERYTHING gets thrown onto the _G table. Including variables and functions. So, you can imagine that this _G table gets very cluttered by users' functions and variables, which affects Lua engine performance.

    3. Not only does it affect performance, but it's bad programming practice, and we don't want that.


    The solution
    Well, to solve this, we need to get everything off the _G table. And to do that, we create our own new tables to hold our functions and variables. This is where Functions in Tables comes in.
    Code:
    ILLIDAN = {} --when using this feature make sure you don't "local" these.
    function ILLIDAN.OnCombat(pUnit, event, pAttacker) --we create a new function within the ILLIDAN table
       pUnit:SendChatMessage(12, 0, "Rawr!")
    end
    
    RegisterUnitEvent(24417, 1, "ILLIDAN.OnCombat")
    So we've taken this entire script off of the _G table, much more efficient, modular and win. We can also store script-based variables in our own tables, using unique keys to keep everything private and avoid those collisions I described earlier.
    Code:
    ILLIDAN = {}
    function ILLIDAN.OnCombat(pUnit, event, pAttacker)
       pUnit:SendChatMessage(12, 0, "Rawr!")
       local sUnit = tostring(pUnit) --locals within functions are fine, i'm using it here for convenience
       ILLIDAN[sUnit] = {} --have to initialise your tables!
       ILLIDAN[sUnit].initialAttacker = pAttacker
    end
    
    RegisterUnitEvent(24417, 1, "ILLIDAN.OnCombat")
    Yep, that's how you avoid the variables colliding. Let me tell you what actually happens here.
    1. <in jargon> We assign the "ILLIDAN" table with a key sUnit, and within that, we assign the "initialAttacker" variable to pAttacker.
    2. So, we use sUnit as a key because that is unique. sUnit is the string form of pUnit, and we no there are no two same pUnits. We turn it into a string because, in simple terms, we don't like using a weird object like pUnit as a key.
    3. Then we use our dot notation to create our set of variables, which looks better, is cleaner, and isn't buggy.

    If you use variables in this way it's good practice to clear out the table when you're done with it, for example when you despawn the creature or he dies.
    Code:
    function ILLIDAN.OnDeath(pUnit, event, killer)
       pUnit:SendChatMessage(12, 0, "I am slain by "..killer:GetName())
       local sUnit = tostring(pUnit)
       ILLIDAN[sUnit] = nil
    end
    (Forums: [The More You Know?] Creature Events - Additional Arguments | WoW-V.com if you don't know why killer is there)

    Instances

    You can script instances in a very similar new way, but it should be done differently. Because creatures often need to share variables in instances, instead of using pUnit as a key for privacy, we use the Instance ID. An instance ID is a unique number automatically generated when a new instance is created. They use it on retail to track what instance groups you're saved to. You can get an instance id by doing pUnit:GetInstanceID().
    Example, if our illidan wanted to have a shared variable in an instance:

    Code:
    BLACK_TEMPLE = {}
    BLACK_TEMPLE.ILLIDAN_FUNCS = {} --we'll split up the funcs from the variables for instances
    BLACK_TEMPLE.MOTHER_FUNCS = {}
    function BLACK_TEMPLE.ILLIDAN_FUNCS.OnCombat(pUnit, event, pAttacker)
       local id = pUnit:GetInstanceID()
       pUnit:SendChatMessage(12, 0, "Rawr!")
       if (BLACK_TEMPLE[id].motherIsDead == true) then
          pUnit:SendChatMessage(12, 0, "You killed my mother! This is revenge!")
       end
    end
    
    function BLACK_TEMPLE.MOTHER_FUNCS.OnDied(pUnit, event, pKiller)
       local id = pUnit:GetInstanceID()
       BLACK_TEMPLE[id] = {} --initialise our table
       BLACK_TEMPLE[id].motherIsDead = true
       --try to keep variables on just one table, better not to go crazy with subtables.
    end
    
    RegisterUnitEvent(24417, 1, "BLACK_TEMPLE.ILLIDAN_FUNCS.OnCombat")
    RegisterUnitEvent(24654, 4, "BLACK_TEMPLE.MOTHER_FUNCS.OnDied")
    The end
    While I have striven to make this guide as clear, concise and understandable as possible, there may be something that just isn't. If that happens, please post
    Seriously, post here or MSN me if you're lost, I'm happy to help.
    And I don't want to see any of the old kind of scripts anymore. These are new times!
    People who release a script in this fashion will get incredible congrats from me. Especially the first few brave fellows.



    CREDITS TO HYPERSNIPER FOR MAKING THIS TUTORIAL!
    Last edited by stoneharry; 02-06-2010 at 03:49 AM.

    [Lua] Not Everything is Perfect
  2. #2
    darkwiz787's Avatar Member
    Reputation
    35
    Join Date
    Mar 2009
    Posts
    250
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Shit, was in the wrong section... can this be moved to guides? sorry

Similar Threads

  1. TeleporterNPC.lua not working!
    By _DEFiANT in forum WoW EMU Questions & Requests
    Replies: 12
    Last Post: 08-26-2008, 01:24 AM
  2. LUA Not Working.
    By pplzperson in forum WoW EMU Questions & Requests
    Replies: 7
    Last Post: 08-13-2008, 08:12 AM
  3. [Help] Lua not working
    By Lich King in forum World of Warcraft Emulator Servers
    Replies: 15
    Last Post: 03-15-2008, 04:41 PM
  4. [Share] Learn Lua ( Not for lazy people )
    By Tom_2001 in forum World of Warcraft Emulator Servers
    Replies: 5
    Last Post: 02-21-2008, 03:28 PM
  5. LUA guide for ppl who want to learn lua not just copy
    By runiker in forum WoW EMU Guides & Tutorials
    Replies: 2
    Last Post: 02-20-2008, 01:54 AM
All times are GMT -5. The time now is 09:20 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