[Lua] 'Instanced' variables menu

User Tag List

Results 1 to 8 of 8
  1. #1
    chaggs's Avatar Corporal
    Reputation
    5
    Join Date
    Mar 2010
    Posts
    27
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    [Lua] 'Instanced' variables

    Hello, I'm working on recreating the pre-Wotlk zombie invasion event for testing if nothing else, however I'm running into an issue. I'm not well versed in the Wow/Arcemu lua API, and I can't seem to think of a way to make variables that are only stored with single units, rather than server wide. Here's my script so far:

    Code:
    --[[
    
    Type: World Event
    Name: Scourge Invasion
    Description: Recreation of scourge invasion pre-Wrath of the Lich King Event.
    Written by Sokyru ~ 2014
    
    ]]--
    
    
    local PlagueRat = 10441;
    
    local NPC_A;
    local Player;
    
    local DefaultFaction;
    
    local IsInfected = false;
    local IsZombie = false;
    
    local AllianceStanding;
    local HordeStanding;
    
    local PlagueTime = 0;
    
    function PlagueRat_OnDeath(pUnit, event, pPlayer)
    	Player = pPlayer;
    	AllianceStanding = Player:GetStanding(72);
    	DefaultFaction = Player:GetFaction();
    	Player:AddAura(43958, 60000);
    	IsInfected = true;
    	RegisterTimedEvent("Plague_Timer", 1000, 60);
    	print(Player:GetName() .. " was infected!");
    	print(Player:GetName() .. " - Default Faction: " .. DefaultFaction);
    end
    
    function Plague_Timer(Event, pPlayer)
    	if IsInfected == true then
    		if PlagueTime >= 59 then
    			if Player:IsPlayer() ==  true then
    				Player:CastSpell(43869);
    				Player:LearnSpell(57596);
    				Player:LearnSpell(51230);
    				Player:LearnSpell(56560);
    				Player:LearnSpell(43949);
    				Player:LearnSpell(56528);
    				Player:FlagFFA(true);
    				Player:SetStanding(72, -50000);
    				IsInfected = false;
    				IsZombie = true;
    				PlagueTime = 0;
    				print(Player:GetName() .. " turned into a zombie!");
    			else
    				Player:CastSpell(43869);
    				Player:LearnSpell(57596);
    				Player:LearnSpell(51230);
    				Player:LearnSpell(56560);
    				Player:LearnSpell(43949);
    				Player:LearnSpell(56528);
    				Player:SetFaction(168);
    				IsInfected = false;
    				IsZombie = true;
    				PlagueTime = 0;
    				print(Player:GetName() .. " turned into a zombie!");
    			end
    		else
    			PlagueTime = PlagueTime + 1;
    			print("Added 1 to PlagueTime. Current PlagueTime: " .. PlagueTime);
    		end
    	end
    end
    
    function Player_OnDeath(event, pPlayer)
    	if IsZombie == true then
    		if Player:IsPlayer() then
    			Player:RemoveAura(43869);
    			Player:UnlearnSpell(57596);
    			Player:UnlearnSpell(51230);
    			Player:UnlearnSpell(56560);
    			Player:UnlearnSpell(43949);
    			Player:UnlearnSpell(56528);
    			Player:FlagFFA(false);
    			Player:SetStanding(72, AllianceStanding);
    			IsZombie = false;
    		else
    			Player:RemoveAura(43869);
    			Player:UnlearnSpell(57596);
    			Player:UnlearnSpell(51230);
    			Player:UnlearnSpell(56560);
    			Player:UnlearnSpell(43949);
    			Player:UnlearnSpell(56528);
    			Player:SetFaction(DefaultFaction);
    			IsZombie = false;
    		end
    	end
    end
    
    RegisterUnitEvent(PlagueRat, 4, "PlagueRat_OnDeath");
    RegisterServerHook(6, "Player_OnDeath");
    I know there are many logic issues, however the one I'm trying to tackle first is the variable issue. How would I go about making variables such as 'IsZombie,' 'IsInfected,' and 'PlagueTime' stored for only the attacking unit, instead of server wide (which causes only one unit to be able to be infected at a time)?

    Thanks.

    [Lua] 'Instanced' variables
  2. #2
    stoneharry's Avatar Moderator Harry

    Authenticator enabled
    Reputation
    1613
    Join Date
    Sep 2007
    Posts
    4,554
    Thanks G/R
    151/146
    Trade Feedback
    0 (0%)
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    You have to implement object orientated programming.

    If you add this script to your server it will implement this:

    https://github.com/stoneharry/Misc-W...a%20Values.lua
    Code:
    --Made by Laurea (the Insane)
    
    local DataValue = {
    	_player = {},
    	_creature = {},
    	_gameobject = {},
    	_map = {},
    	_instance = {},
    };
    PLAYER = LCF.PlayerMethods;
    UNIT = LCF.CreatureMethods;
    GOBJ = LCF.GOMethods;
    assert(PLAYER);
    assert(UNIT);
    assert(GOBJ);
    
    function err(val, exp, func, arg, lvl)
    	if (exp == type(val)) then
    		return true;
    	end
    	local tmp = {"Bad argument #", arg, " to ", func, " (", exp, " expected, got ", type(val), ")."};
    	error(table.concat(tmp), lvl or 3);
    end
    -----------------------------------------------------------------------------------------------------
    local function Set(tbl, field, value, obj, extra)
    	if (type(field) ~= "string" and type(field) ~= "number") then
    		local pos = 1;
    		local func = "SetValue";
    		if (extra == 1) then
    			pos = 2;
    			func = "SetMapValue";
    		elseif (extra == 2) then
    			pos = 2;
    			func = "SetInstanceValue";
    		end
    		err(field, "string or number", func, pos, 4);
    		return nil;
    	end
    	if (tbl[obj] == nil) then
    		tbl[obj] = {};
    	end
    	tbl[obj][field] = value;
    	return 1;
    end
    --Set PLAYER
    function PLAYER:SetValue(field, value)
    	return Set(DataValue._player, field, value, tostring(self));
    end
    function PLAYER:SetMapValue(field, value)
    	return Set(DataValue._map, field, value, self:GetMapId(), 1);
    end
    function PLAYER:SetInstanceValue(field, value)
    	return Set(DataValue._instance, field, value, self:GetInstanceID(), 2);
    end
    --Set UNIT
    function UNIT:SetValue(field, value)
    	return Set(DataValue._creature, field, value, tostring(self));
    end
    function UNIT:SetMapValue(field, value)
    	return Set(DataValue._map, field, value, self:GetMapId(), 1);
    end
    function UNIT:SetInstanceValue(field, value)
    	return Set(DataValue._instance, field, value, self:GetInstanceID(), 2);
    end
    --Set GOBJ
    function GOBJ:SetValue(field, value)
    	return Set(DataValue._gameobject, field, value, tostring(self));
    end
    function GOBJ:SetMapValue(field, value)
    	return Set(DataValue._map, field, value, self:GetMapId(), 1);
    end
    function GOBJ:SetInstanceValue(field, value)
    	return Set(DataValue._instance, field, value, self:GetInstanceID(), 2);
    end
    --Set Global
    function SetMapValue(map, field, value)
    	if (type(map) ~= "number") then err(map, "number", "SetMapValue", 1, 3); end
    	return Set(DataValue._map, field, value, map, 1);
    end
    function SetInstanceValue(instance, field, value)
    	if (type(instance) ~= "number") then err(instance, "number", "SetInstanceValue", 1, 3); end
    	return Set(DataValue._instance, field, value, instance, 2);
    end
    -----------------------------------------------------------------------------------------------------
    local function Get(tbl, field, obj, extra)
    	if (type(field) ~= "string" and type(field) ~= "number") then
    		local pos = 1;
    		local func = "GetValue";
    		if (extra == 1) then
    			pos = 2;
    			func = "GetMapValue";
    		elseif (extra == 2) then
    			pos = 2;
    			func = "GetInstanceValue";
    		end
    		err(field, "string or number", func, pos, 4);
    		return nil;
    	end
    	if (tbl[obj] == nil) then
    		return nil;
    	end
    	return tbl[obj][field];
    end
    --Get PLAYER
    function PLAYER:GetValue(field)
    	return Get(DataValue._player, field, tostring(self));
    end
    function PLAYER:GetMapValue(field)
    	return Get(DataValue._map, field, self:GetMapId(), 1);
    end
    function PLAYER:GetInstanceValue(field)
    	return Get(DataValue._instance, field, self:GetInstanceID(), 2);
    end
    --Get UNIT
    function UNIT:GetValue(field)
    	return Get(DataValue._creature, field, tostring(self));
    end
    function UNIT:GetMapValue(field)
    	return Get(DataValue._map, field, self:GetMapId(), 1);
    end
    function UNIT:GetInstanceValue(field)
    	return Get(DataValue._instance, field, self:GetInstanceID(), 2);
    end
    --Get GOBJ
    function GOBJ:GetValue(field)
    	return Get(DataValue._gameobject, field, tostring(self));
    end
    function GOBJ:GetMapValue(field)
    	return Get(DataValue._map, field, self:GetMapId(), 1);
    end
    function GOBJ:GetInstanceValue(field)
    	return Get(DataValue._instance, field, self:GetInstanceID(), 2);
    end
    --Get Global
    function GetMapValue(map, field)
    	if (type(map) ~= "number") then err(map, "number", "GetMapValue", 1, 3); end
    	return Get(DataValue._map, field, map, 1);
    end
    function GetInstanceValue(instance, field)
    	if (type(instance) ~= "number") then err(instance, "number", "GetInstanceValue", 1, 3); end
    	return Get(DataValue._instance, field, instance, 2);
    end
    -----------------------------------------------------------------------------------------------------
    local function Mod(tbl, field, value, obj, extra)
    	if (value == nil) then return nil; end
    	local t = type(value);
    	if (type(field) ~= "string" and type(field) ~= "number") then
    		local pos = 1;
    		local func = "ModValue";
    		if (extra == 1) then
    			pos = 2;
    			func = "ModMapValue";
    		elseif (extra == 2) then
    			pos = 2;
    			func = "ModInstanceValue";
    		end
    		err(field, "string or number", func, pos, 4);
    		return nil;
    	elseif (t ~= "string" and t ~= "number" and t ~= "table") then
    		local pos = 2;
    		local func = "ModValue";
    		if (extra == 1) then
    			pos = 3;
    			func = "ModMapValue";
    		elseif (extra == 2) then
    			pos = 3;
    			func = "ModInstanceValue";
    		elseif (extra == 3) then
    			func = "ModMemberValue";
    		end
    		err(field, "string, number or table", func, pos, 4);
    		return nil;
    	end
    	if (tbl[obj] == nil) then
    		tbl[obj] = {};
    	end
    	if (t ~= type(tbl[obj][field])) then
    		tbl[obj][field] = value;
    	else
    		local val = tbl[obj][field];
    		if (t == "number") then
    			tbl[obj][field] = val + value;
    		elseif (t == "string") then
    			tbl[obj][field] = val..value;
    		elseif (t == "table") then
    			for k, v in pairs (value) do
    				tbl[obj][field][k] = v;
    			end
    		end
    	end
    	return tbl[obj][field];
    end
    --Mod PLAYER
    function PLAYER:ModValue(field, value)
    	return Mod(DataValue._player, field, value, tostring(self));
    end
    function PLAYER:ModMapValue(field, value)
    	return Mod(DataValue._map, field, value, self:GetMapId(), 1);
    end
    function PLAYER:ModInstanceValue(field, value)
    	return Mod(DataValue._instance, field, value, self:GetInstanceID(), 2);
    end
    --Mod UNIT
    function UNIT:ModValue(field, value)
    	return Mod(DataValue._creature, field, value, tostring(self));
    end
    function UNIT:ModMapValue(field, value)
    	return Mod(DataValue._map, field, value, self:GetMapId(), 1);
    end
    function UNIT:ModInstanceValue(field, value)
    	return Mod(DataValue._instance, field, value, self:GetInstanceID(), 2);
    end
    --Mod GOBJ
    function GOBJ:ModValue(field, value)
    	return Mod(DataValue._gameobject, field, value, tostring(self));
    end
    function GOBJ:ModMapValue(field, value)
    	return Mod(DataValue._map, field, value, self:GetMapId(), 1);
    end
    function GOBJ:ModInstanceValue(field, value)
    	return Mod(DataValue._instance, field, value, self:GetInstanceID(), 2);
    end
    --Mod Global
    function ModMapValue(map, field, value)
    	if (type(map) ~= "number") then err(map, "number", "ModMapValue", 1, 3); end
    	return Mod(DataValue._map, field, value, map, 1);
    end
    function ModInstanceValue(instance, field, value)
    	if (type(instance) ~= "number") then err(instance, "number", "ModInstanceValue", 1, 3); end
    	return Mod(DataValue._instance, field, value, instance, 2);
    end
    -----------------------------------------------------------------------------------------------------
    function SetDataValue()
    	error("SetDataValue has been removed.", 3);
    end
    function GetDataValue()
    	error("GetDataValue has been removed.", 3);
    end
    function ModDataValue()
    	error("ModDataValue has been removed.", 3);
    end
    Then you can call:

    Code:
      local variable = 0
      pUnit:SetValue("variable_name", variable)
    ...
      local value = pUnit:GetValue("variable_name")
    I use it extensively in instance scripts, like see here: https://github.com/stoneharry/Misc-W...Silvermoon.lua

    You may need the LCF scripts which are located in the same folder of the repository I link to.

  3. #3
    chaggs's Avatar Corporal
    Reputation
    5
    Join Date
    Mar 2010
    Posts
    27
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by stoneharry View Post
    You have to implement object orientated programming.

    If you add this script to your server it will implement this:

    https://github.com/stoneharry/Misc-W...a%20Values.lua
    Code:
    --Made by Laurea (the Insane)
    
    local DataValue = {
    	_player = {},
    	_creature = {},
    	_gameobject = {},
    	_map = {},
    	_instance = {},
    };
    PLAYER = LCF.PlayerMethods;
    UNIT = LCF.CreatureMethods;
    GOBJ = LCF.GOMethods;
    assert(PLAYER);
    assert(UNIT);
    assert(GOBJ);
    
    function err(val, exp, func, arg, lvl)
    	if (exp == type(val)) then
    		return true;
    	end
    	local tmp = {"Bad argument #", arg, " to ", func, " (", exp, " expected, got ", type(val), ")."};
    	error(table.concat(tmp), lvl or 3);
    end
    -----------------------------------------------------------------------------------------------------
    local function Set(tbl, field, value, obj, extra)
    	if (type(field) ~= "string" and type(field) ~= "number") then
    		local pos = 1;
    		local func = "SetValue";
    		if (extra == 1) then
    			pos = 2;
    			func = "SetMapValue";
    		elseif (extra == 2) then
    			pos = 2;
    			func = "SetInstanceValue";
    		end
    		err(field, "string or number", func, pos, 4);
    		return nil;
    	end
    	if (tbl[obj] == nil) then
    		tbl[obj] = {};
    	end
    	tbl[obj][field] = value;
    	return 1;
    end
    --Set PLAYER
    function PLAYER:SetValue(field, value)
    	return Set(DataValue._player, field, value, tostring(self));
    end
    function PLAYER:SetMapValue(field, value)
    	return Set(DataValue._map, field, value, self:GetMapId(), 1);
    end
    function PLAYER:SetInstanceValue(field, value)
    	return Set(DataValue._instance, field, value, self:GetInstanceID(), 2);
    end
    --Set UNIT
    function UNIT:SetValue(field, value)
    	return Set(DataValue._creature, field, value, tostring(self));
    end
    function UNIT:SetMapValue(field, value)
    	return Set(DataValue._map, field, value, self:GetMapId(), 1);
    end
    function UNIT:SetInstanceValue(field, value)
    	return Set(DataValue._instance, field, value, self:GetInstanceID(), 2);
    end
    --Set GOBJ
    function GOBJ:SetValue(field, value)
    	return Set(DataValue._gameobject, field, value, tostring(self));
    end
    function GOBJ:SetMapValue(field, value)
    	return Set(DataValue._map, field, value, self:GetMapId(), 1);
    end
    function GOBJ:SetInstanceValue(field, value)
    	return Set(DataValue._instance, field, value, self:GetInstanceID(), 2);
    end
    --Set Global
    function SetMapValue(map, field, value)
    	if (type(map) ~= "number") then err(map, "number", "SetMapValue", 1, 3); end
    	return Set(DataValue._map, field, value, map, 1);
    end
    function SetInstanceValue(instance, field, value)
    	if (type(instance) ~= "number") then err(instance, "number", "SetInstanceValue", 1, 3); end
    	return Set(DataValue._instance, field, value, instance, 2);
    end
    -----------------------------------------------------------------------------------------------------
    local function Get(tbl, field, obj, extra)
    	if (type(field) ~= "string" and type(field) ~= "number") then
    		local pos = 1;
    		local func = "GetValue";
    		if (extra == 1) then
    			pos = 2;
    			func = "GetMapValue";
    		elseif (extra == 2) then
    			pos = 2;
    			func = "GetInstanceValue";
    		end
    		err(field, "string or number", func, pos, 4);
    		return nil;
    	end
    	if (tbl[obj] == nil) then
    		return nil;
    	end
    	return tbl[obj][field];
    end
    --Get PLAYER
    function PLAYER:GetValue(field)
    	return Get(DataValue._player, field, tostring(self));
    end
    function PLAYER:GetMapValue(field)
    	return Get(DataValue._map, field, self:GetMapId(), 1);
    end
    function PLAYER:GetInstanceValue(field)
    	return Get(DataValue._instance, field, self:GetInstanceID(), 2);
    end
    --Get UNIT
    function UNIT:GetValue(field)
    	return Get(DataValue._creature, field, tostring(self));
    end
    function UNIT:GetMapValue(field)
    	return Get(DataValue._map, field, self:GetMapId(), 1);
    end
    function UNIT:GetInstanceValue(field)
    	return Get(DataValue._instance, field, self:GetInstanceID(), 2);
    end
    --Get GOBJ
    function GOBJ:GetValue(field)
    	return Get(DataValue._gameobject, field, tostring(self));
    end
    function GOBJ:GetMapValue(field)
    	return Get(DataValue._map, field, self:GetMapId(), 1);
    end
    function GOBJ:GetInstanceValue(field)
    	return Get(DataValue._instance, field, self:GetInstanceID(), 2);
    end
    --Get Global
    function GetMapValue(map, field)
    	if (type(map) ~= "number") then err(map, "number", "GetMapValue", 1, 3); end
    	return Get(DataValue._map, field, map, 1);
    end
    function GetInstanceValue(instance, field)
    	if (type(instance) ~= "number") then err(instance, "number", "GetInstanceValue", 1, 3); end
    	return Get(DataValue._instance, field, instance, 2);
    end
    -----------------------------------------------------------------------------------------------------
    local function Mod(tbl, field, value, obj, extra)
    	if (value == nil) then return nil; end
    	local t = type(value);
    	if (type(field) ~= "string" and type(field) ~= "number") then
    		local pos = 1;
    		local func = "ModValue";
    		if (extra == 1) then
    			pos = 2;
    			func = "ModMapValue";
    		elseif (extra == 2) then
    			pos = 2;
    			func = "ModInstanceValue";
    		end
    		err(field, "string or number", func, pos, 4);
    		return nil;
    	elseif (t ~= "string" and t ~= "number" and t ~= "table") then
    		local pos = 2;
    		local func = "ModValue";
    		if (extra == 1) then
    			pos = 3;
    			func = "ModMapValue";
    		elseif (extra == 2) then
    			pos = 3;
    			func = "ModInstanceValue";
    		elseif (extra == 3) then
    			func = "ModMemberValue";
    		end
    		err(field, "string, number or table", func, pos, 4);
    		return nil;
    	end
    	if (tbl[obj] == nil) then
    		tbl[obj] = {};
    	end
    	if (t ~= type(tbl[obj][field])) then
    		tbl[obj][field] = value;
    	else
    		local val = tbl[obj][field];
    		if (t == "number") then
    			tbl[obj][field] = val + value;
    		elseif (t == "string") then
    			tbl[obj][field] = val..value;
    		elseif (t == "table") then
    			for k, v in pairs (value) do
    				tbl[obj][field][k] = v;
    			end
    		end
    	end
    	return tbl[obj][field];
    end
    --Mod PLAYER
    function PLAYER:ModValue(field, value)
    	return Mod(DataValue._player, field, value, tostring(self));
    end
    function PLAYER:ModMapValue(field, value)
    	return Mod(DataValue._map, field, value, self:GetMapId(), 1);
    end
    function PLAYER:ModInstanceValue(field, value)
    	return Mod(DataValue._instance, field, value, self:GetInstanceID(), 2);
    end
    --Mod UNIT
    function UNIT:ModValue(field, value)
    	return Mod(DataValue._creature, field, value, tostring(self));
    end
    function UNIT:ModMapValue(field, value)
    	return Mod(DataValue._map, field, value, self:GetMapId(), 1);
    end
    function UNIT:ModInstanceValue(field, value)
    	return Mod(DataValue._instance, field, value, self:GetInstanceID(), 2);
    end
    --Mod GOBJ
    function GOBJ:ModValue(field, value)
    	return Mod(DataValue._gameobject, field, value, tostring(self));
    end
    function GOBJ:ModMapValue(field, value)
    	return Mod(DataValue._map, field, value, self:GetMapId(), 1);
    end
    function GOBJ:ModInstanceValue(field, value)
    	return Mod(DataValue._instance, field, value, self:GetInstanceID(), 2);
    end
    --Mod Global
    function ModMapValue(map, field, value)
    	if (type(map) ~= "number") then err(map, "number", "ModMapValue", 1, 3); end
    	return Mod(DataValue._map, field, value, map, 1);
    end
    function ModInstanceValue(instance, field, value)
    	if (type(instance) ~= "number") then err(instance, "number", "ModInstanceValue", 1, 3); end
    	return Mod(DataValue._instance, field, value, instance, 2);
    end
    -----------------------------------------------------------------------------------------------------
    function SetDataValue()
    	error("SetDataValue has been removed.", 3);
    end
    function GetDataValue()
    	error("GetDataValue has been removed.", 3);
    end
    function ModDataValue()
    	error("ModDataValue has been removed.", 3);
    end
    Then you can call:

    Code:
      local variable = 0
      pUnit:SetValue("variable_name", variable)
    ...
      local value = pUnit:GetValue("variable_name")
    I use it extensively in instance scripts, like see here: https://github.com/stoneharry/Misc-W...Silvermoon.lua

    You may need the LCF scripts which are located in the same folder of the repository I link to.
    Thanks as always stoneharry! This is just basically copying the variable into a new one unique to pUnit, correct?

    Edit: One more question, is there a way to do this with things such as RegisterTimedEvent as well?
    Last edited by chaggs; 09-05-2014 at 03:39 PM.

  4. #4
    stoneharry's Avatar Moderator Harry

    Authenticator enabled
    Reputation
    1613
    Join Date
    Sep 2007
    Posts
    4,554
    Thanks G/R
    151/146
    Trade Feedback
    0 (0%)
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by chaggs View Post
    Thanks as always stoneharry! This is just basically copying the variable into a new one unique to pUnit, correct?

    Edit: One more question, is there a way to do this with things such as RegisterTimedEvent as well?
    It uses a metatable to map a pointer to a value.

    Once you link a creature to a value, it will forever have that value (unless you set it to null), so you can call pUnit:GetValue(variable) at any point even if you set it at a different function point or whatever.

  5. #5
    trademastah's Avatar Member
    Reputation
    1
    Join Date
    Jun 2014
    Posts
    3
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by stoneharry View Post
    It uses a metatable to map a pointer to a value.

    Once you link a creature to a value, it will forever have that value (unless you set it to null), so you can call pUnit:GetValue(variable) at any point even if you set it at a different function point or whatever.
    Hey, sorry to bump this old thread, but I got inspired from your tower defense and I'm trying to recreate it in Eluna. Unfortunately I'm having lots of struggles since there are many differences from your script.. When I try to implement Misc-WoW-Stuff/Data Values.lua at master * stoneharry/Misc-WoW-Stuff * GitHub I get the following error
    "lua_scripts/Globals/Data Values.lua:21: '}' expected near 'argument'" any advice ..

  6. #6
    stoneharry's Avatar Moderator Harry

    Authenticator enabled
    Reputation
    1613
    Join Date
    Sep 2007
    Posts
    4,554
    Thanks G/R
    151/146
    Trade Feedback
    0 (0%)
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by trademastah View Post
    Hey, sorry to bump this old thread, but I got inspired from your tower defense and I'm trying to recreate it in Eluna. Unfortunately I'm having lots of struggles since there are many differences from your script.. When I try to implement Misc-WoW-Stuff/Data Values.lua at master * stoneharry/Misc-WoW-Stuff * GitHub I get the following error
    "lua_scripts/Globals/Data Values.lua:21: '}' expected near 'argument'" any advice ..
    Yeah, that script will not work with Eluna. Luckily there's an alternative system that works in the same way that came with the repository last time I checked. If you don't have it, I have it in one of mine:

    ZombiesProject/ObjectVariables.ext at master * stoneharry/ZombiesProject * GitHub
    Code:
    --
    -- Copyright (C) 2010 - 2014 Eluna Lua Engine <http://emudevs.com/>
    -- This program is free software licensed under GPL version 3
    -- Please see the included DOCS/LICENSE.md for more information
    --
    
    local variableStores = {
        Map = {},
        Player = {},
        Creature = {},
        GameObject = {},
    }
    
    local function DestroyData(event, obj)
        if (event == 18) then
            local mapid = obj:GetMapId()
            local instid = obj:GetInstanceId()
            if (variableStores.Map[mapid]) then
                variableStores.Map[mapid][instid] = nil
            end
        else
            variableStores[obj:GetObjectType()][obj:GetGUIDLow()] = nil
        end
    end
    
    local function GetData(self, field)
        local Type = self:GetObjectType()
        local varStore = variableStores[Type]
        local id
        if (Type == "Map") then
            local mapid = self:GetMapId()
            varStore = varStore[mapid]
            if (not varStore) then
                return nil
            end
            id = self:GetInstanceId()
        else
            id = self:GetGUIDLow()
        end
        
        if (not varStore[id]) then
            return nil
        end
        
        if (field == nil) then
            return varStore[id]
        else
            return varStore[id][field]
        end
    end
    
    local function SetData(self, field, val)
        assert(field ~= nil, "field was nil", 2)
        
        local Type = self:GetObjectType()
        local varStore = variableStores[Type]
        local id
        if (Type == "Map") then
            local mapid = self:GetMapId()
        
            if (not varStore[mapid]) then
                varStore[mapid] = {}
            end
            varStore = varStore[mapid]
            
            id = self:GetInstanceId()
        else
            id = self:GetGUIDLow()
        end
        
        if (not varStore[id]) then
            varStore[id] = {}
        end
        
        varStore[id][field] = val
    end
    
    for k,v in pairs(variableStores) do
        _G[k].GetData = GetData
        _G[k].SetData = SetData
    end
    
    RegisterPlayerEvent(4, DestroyData)
    RegisterServerEvent(31, DestroyData)
    RegisterServerEvent(32, DestroyData)
    RegisterServerEvent(18, DestroyData)
    The 'ext' file extension rather than 'lua' makes it load before the 'lua' files are loaded. This means the functions and other variables are registered and available when the lua scripts are loaded.

    Here's an example of me using that API in another script:

    ZombiesProject/ScalingHealthSystem.ext at master * stoneharry/ZombiesProject * GitHub
    Code:
    local playerDistance = 80
    local minPlayerScaling = 5
    local healthMap = {}
    
    function Creature:GetScaledDamage(damage)
    	local p = self:GetPlayersInRange(playerDistance)
    	if not p or #p < 5 then
    		return damage * 3.5
    	end
    	return damage * (1 + (#p / 2))
    end
    
    --[[
    function Creature:GetMaxScaledHealth()
    	local hp = maxHealthMap[self:GetGUIDLow()]
    	local p = self:GetPlayersInRange(playerDistance)
    	if not p or #p < 5 then
    		return hp * 5
    	end
    	return hp * (1 + (#p / 2))
    end
    ]]
    
    function Creature:UpdateScaledHealth()
    	local scaling = self:GetData("currentScaling") or 1.0
    	--self:SendUnitSay("Updating ----")
    	--self:SendUnitSay("Scaling: " .. scaling)
    	local maxHealth = self:GetMaxHealth() / scaling;
    	local currentHealth = self:GetHealth() / scaling;
    	local players = #(self:GetPlayersInRange(playerDistance, 0, 0) or {}); -- both friendly and hostile players, both dead and alive players
    	--self:SendUnitSay("Player count: " .. tostring(players))
    	scaling = math.max(minPlayerScaling, 1.0 + players / 2.0);
    	--self:SendUnitSay("Scaling: " .. scaling)
    	self:SetMaxHealth(maxHealth * scaling);
    	self:SetHealth(currentHealth * scaling);
    	--self:SendUnitSay("New scaling: " .. scaling)
    	self:SetData("currentScaling", scaling);
    end
    
    function Creature:RegisterScalingHealth()
    	if self then
    		local guid = self:GetGUID()
    		local exists = false
    		for i=#healthMap,1,-1 do
    			if healthMap[i] == guid then
    				--self:SendUnitSay("Not increasing health already in map")
    				exists = true
    				break
    			end
    		end
    		if not exists then
    			--self:SendUnitSay("Scaling my health")
    			table.insert(healthMap, guid)
    		end
    	end
    end
    
    local function ScaleCreatureHealths(_, _, _)
    	for i=#healthMap,1,-1 do
    		local pUnit = GetCreatureByGUID(healthMap[i])
    		if pUnit then
    			if pUnit:IsAlive() then
    				pUnit:UpdateScaledHealth()
    			else
    				table.remove(healthMap, i)
    			end
    		end
    	end
    end
    
    CreateLuaEvent(ScaleCreatureHealths, 5000, 0)
    
    ----- DEBUG
    
    local function ScalingHealthRegister(event, pUnit)
    	pUnit:RegisterScalingHealth()
    end
    
    RegisterCreatureEvent(2809, 5, ScalingHealthRegister)

  7. #7
    trademastah's Avatar Member
    Reputation
    1
    Join Date
    Jun 2014
    Posts
    3
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by stoneharry View Post
    Yeah, that script will not work with Eluna. Luckily there's an alternative system that works in the same way that came with the repository last time I checked. If you don't have it, I have it in one of mine:

    ZombiesProject/ObjectVariables.ext at master * stoneharry/ZombiesProject * GitHub
    Code:
    --
    -- Copyright (C) 2010 - 2014 Eluna Lua Engine <http://emudevs.com/>
    -- This program is free software licensed under GPL version 3
    -- Please see the included DOCS/LICENSE.md for more information
    --
    
    local variableStores = {
        Map = {},
        Player = {},
        Creature = {},
        GameObject = {},
    }
    
    local function DestroyData(event, obj)
        if (event == 18) then
            local mapid = obj:GetMapId()
            local instid = obj:GetInstanceId()
            if (variableStores.Map[mapid]) then
                variableStores.Map[mapid][instid] = nil
            end
        else
            variableStores[obj:GetObjectType()][obj:GetGUIDLow()] = nil
        end
    end
    
    local function GetData(self, field)
        local Type = self:GetObjectType()
        local varStore = variableStores[Type]
        local id
        if (Type == "Map") then
            local mapid = self:GetMapId()
            varStore = varStore[mapid]
            if (not varStore) then
                return nil
            end
            id = self:GetInstanceId()
        else
            id = self:GetGUIDLow()
        end
        
        if (not varStore[id]) then
            return nil
        end
        
        if (field == nil) then
            return varStore[id]
        else
            return varStore[id][field]
        end
    end
    
    local function SetData(self, field, val)
        assert(field ~= nil, "field was nil", 2)
        
        local Type = self:GetObjectType()
        local varStore = variableStores[Type]
        local id
        if (Type == "Map") then
            local mapid = self:GetMapId()
        
            if (not varStore[mapid]) then
                varStore[mapid] = {}
            end
            varStore = varStore[mapid]
            
            id = self:GetInstanceId()
        else
            id = self:GetGUIDLow()
        end
        
        if (not varStore[id]) then
            varStore[id] = {}
        end
        
        varStore[id][field] = val
    end
    
    for k,v in pairs(variableStores) do
        _G[k].GetData = GetData
        _G[k].SetData = SetData
    end
    
    RegisterPlayerEvent(4, DestroyData)
    RegisterServerEvent(31, DestroyData)
    RegisterServerEvent(32, DestroyData)
    RegisterServerEvent(18, DestroyData)
    The 'ext' file extension rather than 'lua' makes it load before the 'lua' files are loaded. This means the functions and other variables are registered and available when the lua scripts are loaded.

    Here's an example of me using that API in another script:

    ZombiesProject/ScalingHealthSystem.ext at master * stoneharry/ZombiesProject * GitHub
    Code:
    local playerDistance = 80
    local minPlayerScaling = 5
    local healthMap = {}
    
    function Creature:GetScaledDamage(damage)
    	local p = self:GetPlayersInRange(playerDistance)
    	if not p or #p < 5 then
    		return damage * 3.5
    	end
    	return damage * (1 + (#p / 2))
    end
    
    --[[
    function Creature:GetMaxScaledHealth()
    	local hp = maxHealthMap[self:GetGUIDLow()]
    	local p = self:GetPlayersInRange(playerDistance)
    	if not p or #p < 5 then
    		return hp * 5
    	end
    	return hp * (1 + (#p / 2))
    end
    ]]
    
    function Creature:UpdateScaledHealth()
    	local scaling = self:GetData("currentScaling") or 1.0
    	--self:SendUnitSay("Updating ----")
    	--self:SendUnitSay("Scaling: " .. scaling)
    	local maxHealth = self:GetMaxHealth() / scaling;
    	local currentHealth = self:GetHealth() / scaling;
    	local players = #(self:GetPlayersInRange(playerDistance, 0, 0) or {}); -- both friendly and hostile players, both dead and alive players
    	--self:SendUnitSay("Player count: " .. tostring(players))
    	scaling = math.max(minPlayerScaling, 1.0 + players / 2.0);
    	--self:SendUnitSay("Scaling: " .. scaling)
    	self:SetMaxHealth(maxHealth * scaling);
    	self:SetHealth(currentHealth * scaling);
    	--self:SendUnitSay("New scaling: " .. scaling)
    	self:SetData("currentScaling", scaling);
    end
    
    function Creature:RegisterScalingHealth()
    	if self then
    		local guid = self:GetGUID()
    		local exists = false
    		for i=#healthMap,1,-1 do
    			if healthMap[i] == guid then
    				--self:SendUnitSay("Not increasing health already in map")
    				exists = true
    				break
    			end
    		end
    		if not exists then
    			--self:SendUnitSay("Scaling my health")
    			table.insert(healthMap, guid)
    		end
    	end
    end
    
    local function ScaleCreatureHealths(_, _, _)
    	for i=#healthMap,1,-1 do
    		local pUnit = GetCreatureByGUID(healthMap[i])
    		if pUnit then
    			if pUnit:IsAlive() then
    				pUnit:UpdateScaledHealth()
    			else
    				table.remove(healthMap, i)
    			end
    		end
    	end
    end
    
    CreateLuaEvent(ScaleCreatureHealths, 5000, 0)
    
    ----- DEBUG
    
    local function ScalingHealthRegister(event, pUnit)
    	pUnit:RegisterScalingHealth()
    end
    
    RegisterCreatureEvent(2809, 5, ScalingHealthRegister)
    Thanks man, I'll see what I can do
    By the way, what does SetDbcSPellVar do ?
    Last edited by trademastah; 07-15-2017 at 11:28 AM.

  8. #8
    stoneharry's Avatar Moderator Harry

    Authenticator enabled
    Reputation
    1613
    Join Date
    Sep 2007
    Posts
    4,554
    Thanks G/R
    151/146
    Trade Feedback
    0 (0%)
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by trademastah View Post
    Thanks man, I'll see what I can do
    By the way, what does SetDbcSPellVar do ?
    I believe I was using it to make the spell aura appear negative (you can't right click to dismiss it). It's just overwriting the data being loaded from the DBC's, so you could change it in there for a proper fix.

Similar Threads

  1. [Release] Custom LUA Instance
    By Spartansp in forum World of Warcraft Emulator Servers
    Replies: 49
    Last Post: 05-12-2023, 02:55 AM
  2. Replies: 0
    Last Post: 01-02-2015, 01:13 AM
  3. [RELEASE/CUSTOM INSTANCE] DEATHWING (Video+advanced LUA scipts+spawns)
    By Meltoor in forum World of Warcraft Emulator Servers
    Replies: 23
    Last Post: 02-09-2008, 06:46 AM
  4. [Release] Goldensun City+instance+lua+quests+items
    By Spartansp in forum World of Warcraft Emulator Servers
    Replies: 61
    Last Post: 02-08-2008, 08:40 PM
  5. [NEWS] preview of custom lua instance
    By Spartansp in forum World of Warcraft Emulator Servers
    Replies: 16
    Last Post: 01-21-2008, 08:17 PM
All times are GMT -5. The time now is 04:58 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