We have detected that cookies are not enabled on your browser. Please enable cookies to ensure the proper experience.
Results 1 to 8 of 8
  1. #1

    First Plugin attempt, decided to take errors to wiser heads than my own.

    I want to eventually create a basic calculator that does operations like -*/+. Here's what I have so far. I'm trying to assign a chat command:

    import "Turbine"

    Turbine.Shell.WriteLine("Basic Calculator by Cerridan");
    BasicCalc = class( Turbine.ShellCommand );
    function BasicCalc:Execute( command, arguments )
    if((arguments == nil) or (string.len(arguments) == 0)) then
    Turbine.Shell.WriteLine("Inval id Arguments!");
    end

    --Assigning integers and symbols to separate arrays.
    local ints = {};
    local index = 1;
    local symbols = {};

    for word in arguments:gmatch( "%d+" ) do
    ints[index] = word;
    index = index + 1;
    end

    index = 1;

    for word in arguments:gmatch( "%[/*%-+]" ) do
    symbols[index] = word;
    index = index + 1;
    end
    end

    Calc = BasicCalc();
    Turbine.Shell.AddCommand( "calc", BasicCalc );
    When I run it though, I get:

    "...BasicCalculator\Main.lua:3 : attempt to call global 'class' (a nil value)"
    This may be the totally wrong way to assign a command but any help on it would be appreciated. I've got some Java experience, if anyone feels like explaining in terms of Java code.

    Thanks!
    Cerridan of Firefoot
    [charsig=http://lotrosigs.level3.turbine.com/0920d00000024d34d/01001/signature.png]undefined[/charsig]

  2. #2
    Join Date
    Mar 2007
    Posts
    1,780

    Re: First Plugin attempt, decided to take errors to wiser heads than my own.

    You mean like http://www.lotrointerface.com/downlo...alculator.html?



    The "class" definition is not imported with the default Turbine import (or any of the Turbine imports), and it is not a standard feature of lua. If you want to use classes (of course you do), you need to copy the "Class.lua" file from the Turbine Examples folder into your plugin (and you probably want "Type.lua" too) and import them in the right order (Class before Type iirc).
    [B]Elendilmir - [COLOR=#3333ff]Evenwyn[/COLOR][/B] Burglar[B] - [COLOR=#3333ff]Evendale[/COLOR][/B] Guardian
    [FONT=Verdana][COLOR=#ff0000][SIZE=2][B]Combat Analysis[/B] [/SIZE][/COLOR][SIZE=2]([B]v4.2.3b[/B]) - [/SIZE][/FONT]Download "[URL="http://www.lotrointerface.com/downloads/info502-CombatAnalysis.html"]here[/URL]"

  3. #3

    Re: First Plugin attempt, decided to take errors to wiser heads than my own.

    I think I fixed it. I put in
    BasicCalc = Turbine.ShellCommand();
    instead of the class() definition.

    I'm aiming to make a calculator that you can run via a text command that doesn't require UI, ie (works at the time of writing):
    /bc 20+3
    would print out
    20 + 3 = 23
    [charsig=http://lotrosigs.level3.turbine.com/0920d00000024d34d/01001/signature.png]undefined[/charsig]

  4. #4

    Re: First Plugin attempt, decided to take errors to wiser heads than my own.

    Replace:
    Code:
    Calc = BasicCalc();
    Turbine.Shell.AddCommand( "calc", BasicCalc );
    with:
    Code:
    Calc = BasicCalc();
    Turbine.Shell.AddCommand( "calc", Calc );
    You need to pass AddCommand an instance of a command and not the command class itself.


    This has the potential to get messy - it'll depend on how you approach it. Good luck.

    Massive edit: Although this is technically a parsing problem, you don't have to really use the full set of parsing tools to do it. I think.
    Last edited by moebius92; Mar 04 2012 at 02:02 AM.

  5. #5

    Re: First Plugin attempt, decided to take errors to wiser heads than my own.

    Code:
    import "Turbine"
    
    --[[
    Currently supported commands
    # represents positive numbers
    # may be substituted for "ans"
    
    #[/*-+^]#
    [/*-+^]#
    #[/*-+^]
    --]]
    
    --Version tracker
    versionNum = "1.0.1"
    --Warnings
    warn = true;
    warning = "!!This code does not support negative numbers!!";
    
    --Make this a command to be executed each time command called
    BasicCalc = Turbine.ShellCommand();
    
    --Create Previous Answer Variable
    prevValue = 1;
    
    --What to do every time user types in chat command
    function BasicCalc:Execute( command, arguments )
    
    	--If user types in base command then print help
    	if((arguments == nil) or (string.len(arguments) < 2)) then
    		Turbine.Shell.WriteLine(self:GetHelp());
    		return;
    	end
    	
    	--Answer assumption cases - if the first char of the string is an operator
    	--then append previous answer value to the front
    	if(arguments:sub(1,1):match("[%^/*%-+x]")) then
    		arguments = prevValue .. arguments;
    	end
    	--If the last char of the string is an operator then append to back
    	if(arguments:sub(arguments:len(), arguments:len()):match("[%^/*%-+x]")) then
    		arguments = arguments .. prevValue;
    	end
    	
    	--Split by operators
    	arr = self:Split(arguments, "[ +%-*/x%^]");
    	
    	--Kill invalid cases
    	if(arr[1] == nil or arr[2] == nil) then
    		Turbine.Shell.WriteLine("Arguments Invalid!");
    		return;
    	end
    	
    	--Get operator
    	find = string.find(arguments, "[/*%-+x%^]");
    	oper = string.sub(arguments, find, find);
    	
    	--If user entered "ans" for front, back, or both operators then replace with actual value.
    	if(arr[1] == "ans") then
    		arr[1] = prevValue;
    	end
    	if(arr[2] == "ans") then
    		arr[2] = prevValue;
    	end
    	
    	--If multiplication, replace with x to make it look nicer
    	if(oper == "*") then oper = "x"; end
    	
    	--Result Variable
    	out = 0;
    	
    	--Failure variable
    	fail = false;
    	
    	--Operator Cases
    	if(oper == "+") then	 out = arr[1] + arr[2];
    	elseif(oper == "-") then	out = arr[1] - arr[2];
    	elseif(oper == "x") then	out = arr[1] * arr[2];
    	elseif(oper == "/") then	out = arr[1] / arr[2];
    	elseif(oper == "^") then	out = math.pow(arr[1], arr[2]);
    	else 
    		fail = true;
    		Turbine.Shell.WriteLine("Unrecognized Operator!");
    	end
    	--Write a line out with the equation input and the resultant number.
    	if(fail == false)
    		Turbine.Shell.WriteLine(arr[1] .. " " .. oper .. " " .. arr[2] .. " = " .. out);
    		--Store answer in answer variable if not negative
    		if(out >= 0) prevValue = out; end
    	end	
    end
    
    --Get help strings.
    function BasicCalc:GetHelp()
    	return self:GetShortHelp() .. "\nCerridan's Calculator Plugin";
    end
    
    function BasicCalc:GetShortHelp()
    	return "/bc | /calc [#|ans] [/*-+] [#|ans]";
    end
    
    --Split method, not written by me.
    function BasicCalc:Split(str, delim, maxNb)
        -- Eliminate bad cases...
        if string.find(str, delim) == nil then
            return { str }
        end
        if maxNb == nil or maxNb < 1 then
            maxNb = 0    -- No limit
        end
        local result = {}
        local pat = "(.-)" .. delim .. "()"
        local nb = 0
        local lastPos
        for part, pos in string.gfind(str, pat) do
            nb = nb + 1
            result[nb] = part
            lastPos = pos
            if nb == maxNb then break end
        end
        -- Handle the last field
        if nb ~= maxNb then
            result[nb + 1] = string.sub(str, lastPos)
        end
        return result
    end
    
    --Text written on initialization
    Turbine.Shell.WriteLine("Basic Calculator " .. versionNum .. " by Cerridan");
    if(warn) then Turbine.Shell.WriteLine(warning); end
    Turbine.Shell.WriteLine("Usage: /bc | /calc [#|ans] [/*-+] [#|ans]");
    
    --Add commands so they can be called from the chatbox
    Turbine.Shell.AddCommand( "calc", BasicCalc );
    Turbine.Shell.AddCommand( "bc", BasicCalc );

    That's what I have so far, planning to add square roots, and negative number support...
    Last edited by Llandor; Mar 04 2012 at 11:25 AM.
    [charsig=http://lotrosigs.level3.turbine.com/0920d00000024d34d/01001/signature.png]undefined[/charsig]

  6. #6
    Join Date
    Mar 2007
    Posts
    1,174

    Re: First Plugin attempt, decided to take errors to wiser heads than my own.

    A couple of pointers.

    First, you can combine the AddCommand lines so that you assign all aliases for the same command in one line by separating the aliases with a semi-colon:
    Turbine.Shell.AddCommand( "calc;bc", BasicCalc );

    Second, and really more important, you should remove any alias commands that you add. The most common means is to use an Unload event handler. Failure to remove commands can have undesirable results including crashing the client in certain circumstances. The simplest Unload event handler would be:
    plugin.Unload = function()
    Turbine.Shell.RemoveCommand( BasicCalc );
    end

    Third, you can access the version info from the .plugin file instead of using a separate variable by using:
    Turbine.Shell.WriteLine( "Basic Calculator " .. plugin:GetVersion() .. " by Cerridan" );
    so that you only have to update the version number in the .plugin file (and the .plugincompendium file if you want to be supported by Plugin Compendium).

    Note that "plugin" is a special variable created by Turbine which is only valid during the initialization of your plugin - basically the time when your main plugin file is being parsed and executed - once the plugin is loaded, the "plugin" variable will no longer be accessible so don't reference it in event handlers, instead use Plugins["Calc"] (where "Calc" is the actual name of your plugin from the <name> tag of your .plugin file).

    As a rule, anything you create, you should destroy before unloading. That includes commands, eventhandlers, etc. That will help minimize the chances of your plugin causing undesirable results.
    Last edited by Garan; Mar 04 2012 at 01:56 PM.

  7. #7

    Re: First Plugin attempt, decided to take errors to wiser heads than my own.

    Thanks for all the help!

    The plugin thus far:
    Code:
    import "Turbine"
    
    --[[
    Currently supported commands
    # represents positive numbers
    # may be substituted for "ans"
    
    #[/*-+^]#
    [/*-+^]#
    #[/*-+^]
    
    # may not be substituted for ans in the below cases:
    sqrt#
    sin#
    cos#
    tan#
    --]]
    
    --Warnings
    warn = true;
    warning = "!!This code does not support negative numbers!!";
    
    --Make this a command to be executed each time command called
    BasicCalc = Turbine.ShellCommand();
    
    --Create Previous Answer Variable
    prevValue = 1;
    
    --What to do every time user types in chat command
    function BasicCalc:Execute( command, arguments )
    
    	--If user types in base command then print help
    	if((arguments == nil) or (string.len(arguments) < 2)) then
    		Turbine.Shell.WriteLine(self:GetHelp());
    		return;
    	end
    	
    	--Check for special functions
    	if(arguments:len() >=  5 and arguments:sub(1,4) == "sqrt")  then
    		self:PrintResult(arguments:sub(5, arguments:len()), nil, "sqrt", math.sqrt(arguments:sub(5, arguments:len())));
    		return;
    	elseif(arguments:len() >= 4 and arguments:sub(1, 3) == "sin") then
    		self:PrintResult(arguments:sub(4, arguments:len()), nil, "sin", math.sin(arguments:sub(4, arguments:len())));
    		return;
    	elseif(arguments:len() >= 4 and arguments:sub(1, 3) == "cos") then
    		self:PrintResult(arguments:sub(4, arguments:len()), nil, "cos", math.cos(arguments:sub(4, arguments:len())));
    		return;
    	elseif(arguments:len() >= 4 and arguments:sub(1, 3) == "tan") then
    		self:PrintResult(arguments:sub(4, arguments:len()), nil, "tan", math.tan(arguments:sub(4, arguments:len())));
    		return;
    	end
    	
    	
    	--Answer assumption cases - if the first char of the string is an operator
    	--then append previous answer value to the front
    	if(arguments:sub(1,1):match("[%^/*%-+x]")) then
    		arguments = prevValue .. arguments;
    	end
    	--If the last char of the string is an operator then append to back
    	if(arguments:sub(arguments:len(), arguments:len()):match("[%^/*%-+x]")) then
    		arguments = arguments .. prevValue;
    	end
    	
    	--Split by operators
    	arr = self:Split(arguments, "[ +%-*/x%^]");
    	
    	--Kill invalid cases
    	if(arr[1] == nil or arr[2] == nil) then
    		Turbine.Shell.WriteLine("Arguments Invalid!");
    		return;
    	end
    	
    	--Get operator
    	find = string.find(arguments, "[/*%-+x%^]");
    	oper = string.sub(arguments, find, find);
    	
    	--If user entered "ans" for front, back, or both operators then replace with actual value.
    	if(arr[1] == "ans") then
    		arr[1] = prevValue;
    	end
    	if(arr[2] == "ans") then
    		arr[2] = prevValue;
    	end
    	
    	--If multiplication, replace with x to make it look nicer
    	if(oper == "*") then oper = "x"; end
    	
    	--Result Variable
    	out = 0;
    	
    	--Failure variable
    	fail = false;
    	
    	--Operator Cases
    	if(oper == "+") then	 out = arr[1] + arr[2];
    	elseif(oper == "-") then	out = arr[1] - arr[2];
    	elseif(oper == "x") then	out = arr[1] * arr[2];
    	elseif(oper == "/") then	out = arr[1] / arr[2];
    	elseif(oper == "^") then	out = math.pow(arr[1], arr[2]);
    	else 
    		fail = true;
    		Turbine.Shell.WriteLine("Unrecognized Operator!");
    	end
    	--Write a line out with the equation input and the resultant number.
    	if(fail == false) then self:PrintResult(arr[1], arr[2], oper, out); end
    end
    
    function BasicCalc:PrintResult(one, two, oper, out)
    	if(oper == "sqrt" or oper == "sin" or oper == "cos" or oper == "tan") then
    		Turbine.Shell.WriteLine(oper .. "(" .. one .. ") = " .. out);
    	else
    		Turbine.Shell.WriteLine(arr[1] .. " " .. oper .. " " .. arr[2] .. " = " .. out);	
    	end	
    	--Store answer in answer variable if not negative
    	if(out >= 0) then prevValue = out; end
    end
    
    --Get help strings.
    function BasicCalc:GetHelp()
    	return self:GetShortHelp() .. "\nCerridan's Calculator Plugin";
    end
    
    function BasicCalc:GetShortHelp()
    	return "/bc | /calc [#|ans] [/*-+] [#|ans]";
    end
    
    --Split method, not written by me.
    function BasicCalc:Split(str, delim, maxNb)
        -- Eliminate bad cases...
        if string.find(str, delim) == nil then
            return { str }
        end
        if maxNb == nil or maxNb < 1 then
            maxNb = 0    -- No limit
        end
        local result = {}
        local pat = "(.-)" .. delim .. "()"
        local nb = 0
        local lastPos
        for part, pos in string.gfind(str, pat) do
            nb = nb + 1
            result[nb] = part
            lastPos = pos
            if nb == maxNb then break end
        end
        -- Handle the last field
        if nb ~= maxNb then
            result[nb + 1] = string.sub(str, lastPos)
        end
        return result
    end
    
    --Unload handler
    plugin.Unload = function()
    Turbine.Shell.RemoveCommand(BasicCalc);
    end
    
    --Text written on initialization
    Turbine.Shell.WriteLine("Basic Calculator " .. plugin:GetVersion() .. " by Cerridan");
    if(warn) then Turbine.Shell.WriteLine(warning); end
    Turbine.Shell.WriteLine("Usage: /bc | /calc [#|ans] [/*-+] [#|ans]");
    
    --Add commands so they can be called from the chatbox
    Turbine.Shell.AddCommand( "calc;bc", BasicCalc );
    Last edited by Llandor; Mar 04 2012 at 01:53 PM.
    [charsig=http://lotrosigs.level3.turbine.com/0920d00000024d34d/01001/signature.png]undefined[/charsig]

  8. #8

    Re: First Plugin attempt, decided to take errors to wiser heads than my own.

    Hmm... had an odd thought and did some poking around. You may want to check out the loadstring function. Apparently, it's Lua's version of eval().

 

 

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  

This form's session has expired. You need to reload the page.

Reload