WoWInterface

WoWInterface (https://www.wowinterface.com/forums/index.php)
-   Lua/XML Help (https://www.wowinterface.com/forums/forumdisplay.php?f=16)
-   -   Transforming an existing addon (https://www.wowinterface.com/forums/showthread.php?t=36780)

Dzib 11-16-10 07:28 AM

Transforming an existing addon
 
Hi

I'd like to make an addon which add the letters "rr" after each "r" detected in the chat (like someone who's rolling r's)
Being a total newbie in programming, I took an addon which adds an "o" after every consonant and tried to modify it.

Here's the original code:

Code:

function doRoevar(str)
       
        local endstr = "";
        local konsonanter = {"b","c","d","f","g","h","j","k","l","m","n","p","q","r","s","t","v","w","x","z"};
        local bokstvr = {};
       
        for i = 1,string.len(str) do

                bokstvr[i] = string.sub(str,i,i);
               
                for t = 1,19 do
                if (string.lower(bokstvr[i]) == konsonanter[t]) then
                        bokstvr[i] = bokstvr[i] .. "o" .. string.lower(bokstvr[i]);
                        end
                end

                endstr = endstr .. bokstvr[i];
               
        end
       
        return endstr;               
               
end

And here's the code I've modified

Code:

function doRoevar(str)
       
        local endstr = "";
        local konsonanter = {"r"};
        local bokstvr = {};
       
        for i = 1,string.len(str) do

        bokstvr[i] = string.sub(str,i,i);
               
                for t = 1,19 do
                if (string.lower(bokstvr[i]) == konsonanter[t]) then
                        bokstvr[i] = bokstvr[i] .. "r" .. string.lower(bokstvr[i]);
                        end
                end

                endstr = endstr .. bokstvr[i];
               
        end
       
        return endstr;               
               
end

I'm sur I could simplfy the function but I'm a bit afraid of blowing up eveything. Anyway, it works this way but the only thing I can't find out is how to activate the function only if I'm talking in the guild/say/yell chat???

Thanks

Nobgul 11-16-10 07:48 AM

That can't be all the code, in order for us to help you could you provide the full code.

Dzib 11-16-10 08:03 AM

Sorry, here's the full code:

Code:

function InitRoevar()

        DEFAULT_CHAT_FRAME:AddMessage("|c00FF0000Rovarspraket |cFF00FF01loaded.\nTalk like a |c00FF0000rovare!");
       
        roevar_toggle = false;
       
        SLASH_ROEVARTOGGLE1 = "/rovar";
        SLASH_ROEVARTOGGLE2 = "/rtoggle";
        SLASH_ROEVARTOGGLE3 = "/rovartoggle";
        SlashCmdList["ROEVARTOGGLE"] = roevarToggle;
       
end
       
local Rovar_OldSCM = SendChatMessage;

function SendChatMessage(msg, system, language, chatnumber)

        if (msg == "!roevar") then
                roevarToggle();
                msg = "";
        elseif (msg ~= "" and (string.find(msg, "%[") == nil)) then
                if ( string.find(msg, "^%/") == nil ) then
                        if (roevar_toggle == true) then
                                msg = doRoevar(msg);
                        end
                end
        end

        Rovar_OldSCM(msg, system, language, chatnumber);
end
       
function doRoevar(str)
       
        local endstr = "";
        local konsonanter = {"r"};
        local bokstvr = {};
       
        for i = 1,string.len(str) do

                bokstvr[i] = string.sub(str,i,i);
               
                for t = 1,19 do
                if (string.lower(bokstvr[i]) == konsonanter[t]) then
                        bokstvr[i] = bokstvr[i] .. "r" .. string.lower(bokstvr[i]);
                        end
                end

                endstr = endstr .. bokstvr[i];
               
        end
       
        return endstr;               
               
end

function roevarToggle(msg)
        if (msg == "" or msg == nil) then
                if (roevar_toggle == false) then
                        roevar_toggle = true;
                        DEFAULT_CHAT_FRAME:AddMessage("|c00FF0000Rovarspraket |c0000bbbbenabled.");
                else
                        roevar_toggle = false;
                        DEFAULT_CHAT_FRAME:AddMessage("|c00FF0000Rovarspraket |c00FF00bbdisabled.");
                end
        elseif (msg == "help") then
                DEFAULT_CHAT_FRAME:AddMessage("|cFF00FF01Toggle |c00FF0000Rovarspraket |cFF00FF01with /roevar, /rtoggle or /rovarspraket to talk like a pirate!\n|c00FF0000Rovarspraket |cFF00FF01is currently " .. (roevar_toggle and "|c0000bbbbenabled" or "|c00FF00bbdisabled") .. ".");
        end
       
end


Ailae 11-16-10 08:10 AM

Sorry to go off-topic, but I really laughed that someone made an addon for 'Rövarspråket'.

http://en.wikipedia.org/wiki/Rövarspråket

Guess we need one for Pig Latin now too. :)

Nobgul 11-16-10 11:22 AM

Quote:

Originally Posted by Ailae (Post 218024)
Sorry to go off-topic, but I really laughed that someone made an addon for 'Rövarspråket'.

http://en.wikipedia.org/wiki/Rövarspråket

Guess we need one for Pig Latin now too. :)

That is where he got this code from .

To the OP I vaguely remember someone else having a issue with a chat type program for role playing. I think they had to add a function for each of the other types of chat RAID PARTY.

I think you need to find the index of the trade channel first in order to do this. I will play with the code later.

Phanx 11-16-10 05:01 PM

If all you want to do is double the letter "r", then your code is way more complicated than it needs to be. Try this:

Code:

local old = SendChatMessage

local new = function(message, ...)
        if message:len() > 0 and not message:match("^/") then
                message = message:replace("r", "rr"):replace("rrrr", "rr"):replace("R" "RR"):replace("RRRR", "RR")
        end
        old(message, ...)
end

SendChatMessage = new

SLASH_ADDONNAME1 = "/doubler"

SlashCmdList.ADDONNAME = function()
        if SendChatMessage == new then
                SendChatMessage = old
                DEFAULT_CHAT_FRAME:AddMessage("AddonName disabled.")
        else
                SendChatMessage = new
                DEFAULT_CHAT_FRAME:AddMessage("AddonName enabled.")
        end
end

It'll work for both lowercase and capital letters, and won't double any "r" that's already doubled (eg. if you type "arrange" it won't end up as "arrrrange").

Ketho 11-16-10 06:31 PM

Can't
Code:

message = message:replace("r", "rr"):replace("rrrr", "rr"):replace("R" "RR"):replace("RRRR", "RR")
be shortened to this for case-insensitive pattern matching?
Code:

message = message:replace("[Rr]", "rr"):replace("[Rr][Rr][Rr][Rr]", "rr")

Phanx 11-16-10 07:02 PM

Only if you don't care about the resulting case. Your pattern would change "CARE" to "CArrE" which isn't really a desirable result. I guess you could do:

Code:

message = message:gsub("([Rr])", "%1%1"):gsub("([Rr])([Rr])([Rr])([Rr])", "%1%2")
...but gsub is significantly more expensive than a simple replace.

Dzib 11-17-10 01:00 AM

Quote:

Originally Posted by Phanx (Post 218115)
If all you want to do is double the letter "r", then your code is way more complicated than it needs to be. Try this:

Code:

local old = SendChatMessage

local new = function(message, ...)
        if message:len() > 0 and not message:match("^/") then
                message = message:replace("r", "rr"):replace("rrrr", "rr"):replace("R" "RR"):replace("RRRR", "RR")
        end
        old(message, ...)
end

SendChatMessage = new

SLASH_ADDONNAME1 = "/doubler"

SlashCmdList.ADDONNAME = function()
        if SendChatMessage == new then
                SendChatMessage = old
                DEFAULT_CHAT_FRAME:AddMessage("AddonName disabled.")
        else
                SendChatMessage = new
                DEFAULT_CHAT_FRAME:AddMessage("AddonName enabled.")
        end
end

It'll work for both lowercase and capital letters, and won't double any "r" that's already doubled (eg. if you type "arrange" it won't end up as "arrrrange").

You mean this replace the whole code I posted above? Much more simple, I agree :)
Thanks for the responses.... what about applying the modification only if I'm talking in the guild/say/yell channel? Is it possible?

Xubera 11-17-10 01:13 AM

Code:

local old = SendChatMessage

local new = function(message, ...)
        local channel = ...
        if channel == "GUILD" or channel == "SAY" or channel == "YELL" then
            if message:len() > 0 and not message:match("^/") then
                    message = message:replace("r", "rr"):replace("rrrr", "rr"):replace("R" "RR"):replace("RRRR", "RR")
            end
        end
        old(message, ...)
end

SendChatMessage = new

SLASH_ADDONNAME1 = "/doubler"

SlashCmdList.ADDONNAME = function()
        if SendChatMessage == new then
                SendChatMessage = old
                DEFAULT_CHAT_FRAME:AddMessage("AddonName disabled.")
        else
                SendChatMessage = new
                DEFAULT_CHAT_FRAME:AddMessage("AddonName enabled.")
        end
end


Dzib 11-17-10 01:17 AM

Thanks, I think I tried something like that but it didn't worked... I'll try your solution as soon as the servers will be online :)

So, here's the full code modified with another addon name, but it doesn't work, seems it doesn't load cos when I type /rrr nothing happens (and of course the text I type in /say isn't modified)

Code:

function InitRrr()

        DEFAULT_CHAT_FRAME:AddMessage("|c00FF0000Rrr |cFF00FF01loaded.\nTalk like a |c00FF0000rovare!");
       
        rrr_toggle = true;
       
        SLASH_RRRTOGGLE = "/rrr";
        SlashCmdList["RRRTOGGLE"] = rrrToggle;
       
end
       
local old = SendChatMessage

local new = function(message, ...)
        local channel = ...
        if channel == "GUILD" or channel == "SAY" or channel == "YELL" then
            if message:len() > 0 and not message:match("^/") then
                    message = message:replace("r", "rr"):replace("rrrr", "rr"):replace("R" "RR"):replace("RRRR", "RR")
            end
        end
        old(message, ...)
end

SendChatMessage = new

SLASH_RRR = "/doubler"

SlashCmdList.RRR = function()
        if SendChatMessage == new then
                SendChatMessage = old
                DEFAULT_CHAT_FRAME:AddMessage("Rrr disabled.")
        else
                SendChatMessage = new
                DEFAULT_CHAT_FRAME:AddMessage("Rrr enabled.")
        end
end


Xubera 11-17-10 09:42 AM

well the main concept behind this is that "new" is actually now SendChatMessage() so "new" takes 4 parameteres.

Message, chatType, language, and channel

i made an error in judgement when i named my variable channel, i switched the two around in my head when iwrote that last night. either way its important to know that "channel" in the above code accepts the 2nd parameter "chatType"


when the snippet was originally written, we were never gonna use the last 3 parameters, so the vararg (...) was used, we could also write it like this

Code:

local new = function(message, chatType, ...)
        if chatType == "GUILD" or chatType == "SAY" or chatType == "YELL" then
            if message:len() > 0 and not message:match("^/") then
                    message = message:replace("r", "rr"):replace("rrrr", "rr"):replace("R" "RR"):replace("RRRR", "RR")
            end
        end
        old(message, chatType, ...)
end


Seerah 11-17-10 01:45 PM

Well, you defined /doubler as your slash command, not /rrr. ;)

Phanx 11-17-10 02:59 PM

Also, you don't need this:
Code:

function InitRrr()

        DEFAULT_CHAT_FRAME:AddMessage("|c00FF0000Rrr |cFF00FF01loaded.\nTalk like a |c00FF0000rovare!");
       
        rrr_toggle = true;
       
        SLASH_RRRTOGGLE = "/rrr";
        SlashCmdList["RRRTOGGLE"] = rrrToggle;
       
end

It's never called from anywhere, for one, and even if you did call it, the "/rrr" command still wouldn't do anything because no function "rrrToggle" is defined. Plus, nobody likes addons that spam "hey, this addon you just installed and enabled is loaded!" at login. :p

Dzib 11-17-10 04:26 PM

Quote:

Originally Posted by Seerah (Post 218293)
Well, you defined /doubler as your slash command, not /rrr. ;)

Damned, I didn't noticed... couldn't work this way :)

Dzib 11-17-10 04:28 PM

Quote:

Originally Posted by Phanx (Post 218306)
Also, you don't need this:
Code:

function InitRrr()

        DEFAULT_CHAT_FRAME:AddMessage("|c00FF0000Rrr |cFF00FF01loaded.\nTalk like a |c00FF0000rovare!");
       
        rrr_toggle = true;
       
        SLASH_RRRTOGGLE = "/rrr";
        SlashCmdList["RRRTOGGLE"] = rrrToggle;
       
end

It's never called from anywhere, for one, and even if you did call it, the "/rrr" command still wouldn't do anything because no function "rrrToggle" is defined. Plus, nobody likes addons that spam "hey, this addon you just installed and enabled is loaded!" at login. :p

Ok, but I called function Initrrr in rrr.xml:

Code:

<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">

        <Frame name="Rrr" parent="UIParent" hidden="true">
                <Scripts>
                        <OnLoad>
                                InitRrr();
                        </OnLoad>
                </Scripts>
        </Frame>
       
</Ui>


Seerah 11-17-10 10:09 PM

But you don't have a function called rrrToggle - aren't you getting a nil error there?

Phanx 11-18-10 01:27 AM

You don't get an error by setting something to nil; only if you then try to do something with the nil something.

But, nothing in your InitRrr function has any purpose, so you should just get rid of it (and get rid of the similarly useless XML file).

Dzib 11-18-10 02:48 AM

But I need an xml file, no? so what should be in it?

Xubera 11-18-10 10:15 AM

actually, you dont need an XML fille, you dont even need a frame. You dont listen for any events and you dont need any sort of timer. The only thing you need is a .toc and that .lua that phanx posted and it works.


All times are GMT -6. The time now is 10:13 AM.

vBulletin © 2024, Jelsoft Enterprises Ltd
© 2004 - 2022 MMOUI