vanilla-wow-addons – Rev 1

Subversion Repositories:
Rev:
-- Gems, a silly gems-based minigame to kill time.
-- Use /gems to bring up the game.

local Gems_GameIsOver = false;

local Gems_Paused = false;
local Gems_TimerOn = false;
local Gems_TimerFunction;
local Gems_Tick;
local Gems_TimerEnd = 0;
local Gems_PulseTime = 0.5;
local Gems_Score = 0;

local Gems_GemTypes = 10;

local Gems_FallingX = -1;
local Gems_FallingY = 0;

local Gems_GemTextures = {
        "",
        "Interface\\Icons\\INV_Misc_Gem_Topaz_01",
        "Interface\\Icons\\INV_Misc_Gem_Diamond_01",
        "Interface\\Icons\\INV_Misc_Gem_Opal_01",
        "Interface\\Icons\\INV_Misc_Gem_Ruby_01",
        "Interface\\Icons\\INV_Misc_Gem_Amethyst_01",
        "Interface\\Icons\\INV_Misc_Gem_Bloodstone_01",
        "Interface\\Icons\\INV_Misc_Gem_Crystal_01",
        "Interface\\Icons\\INV_Misc_Gem_Emerald_01",
        "Interface\\Icons\\INV_Misc_Gem_Sapphire_01",
        "Interface\\Icons\\INV_Misc_Gem_Stone_01",
        "Interface\\Icons\\INV_Misc_Gem_Variety_01",
        "Interface\\Icons\\INV_Misc_Gem_01",
        "Interface\\Icons\\INV_Misc_Gear_01",
        "Interface\\Icons\\INV_Misc_Rune_01",
        "Interface\\Icons\\INV_Ore_Arcanite_01",
        "Interface\\Icons\\INV_Ore_Copper_01",
        "Interface\\Icons\\INV_Ore_Iron_01",
        "Interface\\Icons\\INV_Ore_Mithril_01",
        "Interface\\Icons\\INV_Ore_Thorium_01",
        "Interface\\Icons\\INV_Ore_Tin_01",
        "Interface\\Icons\\INV_Ore_TrueSilver_01"
}

-- some strings for the key bindings
BINDING_HEADER_GEMS = "Val's Gems";
BINDING_NAME_GEMS_LEFT = "Move Left";
BINDING_NAME_GEMS_RIGHT = "Move Right";
BINDING_NAME_GEMS_DOWN = "Move Down";
        

function Gems_OnLoad()
        -- Register the slash command
        SLASH_GEMS1 = "/gems";
        SlashCmdList["GEMS"] = function(msg)
                Gems_SlashCommand(msg);
        end

        -- hide the frame when escape is pressed
        tinsert(UISpecialFrames,"Gems_Frame");

        Gems_Write("Val's Gems loaded. Type |cffff0000/gems|r to play or |cffff0000/gems help|r for instructions.");
        Gems_NewGame();
end

function Gems_SlashCommand(msg)
        if(msg == nil or msg == "") then
                Gems_Toggle();
        elseif(msg == "help") then
                Gems_Help();
        end
end

function Gems_Help()
        Gems_Write("Help for Val's Gems");
        Gems_Write("=================");
        Gems_Write("The premise of this game is easy - connect 4 of the same gem horizontally, vertically, or diagonally.");
        Gems_Write("Use the < and > buttons to move the falling gems left or right, and the v button to drop the gem to the bottom.");
end

function Gems_Toggle()
        if(getglobal("Gems_Frame"):IsShown()) then
                getglobal("Gems_Frame"):Hide();
        else
                getglobal("Gems_Frame"):Show();
        end
end

function Gems_NewGame()
        
        Gems_GameIsOver = false;
        
        Gems_TimerEnd = 0;
        Gems_Paused = false;

        Gems_FallingX = -1;
        Gems_FallingY = 0;
        Gems_Score = 0;
        Gems_UpdateScore(Gems_Score);
        
        getglobal("Gems_PauseButton"):UnlockHighlight();
        
        for i = 1,64 do
                getglobal("Gems_Cell" .. i).gem = 0;
                Gems_DrawCell(i);
        end

        Gems_ScheduleTimer(Gems_PulseTime, Gems_Pulse);
end

function Gems_Pulse()
        
        if(Gems_FallingX == -1) then
                Gems_SpawnGem();
        else
                local gemcell = Gems_FallingX * 8 + Gems_FallingY;
                
                if(gemcell > 56) then
                        Gems_CheckMatch(Gems_FallingX, Gems_FallingY);
                        Gems_FallingX = -1;

                elseif(getglobal("Gems_Cell" .. gemcell+8).gem > 0) then
                        Gems_CheckMatch(Gems_FallingX, Gems_FallingY);
                        Gems_FallingX = -1

                else
                        --Gems_Write("gemcell is " .. gemcell);
                        local gemval = getglobal("Gems_Cell" .. gemcell).gem;
                        getglobal("Gems_Cell" .. gemcell).gem = 0;
                        getglobal("Gems_Cell" .. gemcell+8).gem = gemval;
                        Gems_DrawCell(gemcell);
                        Gems_DrawCell(gemcell+8);
                        Gems_FallingX = Gems_FallingX + 1;
                end
        end
        
        Gems_ScheduleTimer(Gems_PulseTime, Gems_Pulse);
end

function Gems_DrawCell(cellnum)
        local i = getglobal("Gems_Cell" .. cellnum).gem + 1;
        --getglobal("Gems_Cell" .. cellnum):SetBackdropColor(Gems_GemColors[i]["r"], Gems_GemColors[i]["g"], Gems_GemColors[i]["b"]);
        if(i == 1) then
                getglobal("Gems_Cell" .. cellnum):Hide();
        else
                getglobal("Gems_Cell" .. cellnum):Show();
                getglobal("Gems_Cell" .. cellnum):SetNormalTexture(Gems_GemTextures[i]);
        end
end

function Gems_SpawnGem()
        local column = 4;
        local gemval = math.random(1,Gems_GemTypes);
        
        Gems_FallingX = 0;
        Gems_FallingY = column;
        
        --Gems_Write("spawning in " .. column);
        
        getglobal("Gems_Cell" .. Gems_FallingY).gem = gemval;
        Gems_DrawCell(Gems_FallingY);
end

function Gems_MoveLeft()
        local gemcell = Gems_FallingX * 8 + Gems_FallingY;
        if(Gems_FallingY > 1) then
                if(Gems_FallingX == -1 or Gems_FallingX > 6 or getglobal("Gems_Cell" .. gemcell-1).gem > 0) then return end;
                Gems_FallingY = Gems_FallingY - 1;      
                local gemval = getglobal("Gems_Cell" .. gemcell).gem;
                getglobal("Gems_Cell" .. gemcell).gem = 0;
                getglobal("Gems_Cell" .. gemcell-1).gem = gemval;
                Gems_DrawCell(gemcell);
                Gems_DrawCell(gemcell-1);
        end
end

function Gems_MoveRight()
        local gemcell = Gems_FallingX * 8 + Gems_FallingY;
        if(Gems_FallingY < 8) then
                if(Gems_FallingX == -1 or Gems_FallingX > 6 or getglobal("Gems_Cell" .. gemcell+1).gem > 0) then return end;
                Gems_FallingY = Gems_FallingY + 1;
                local gemval = getglobal("Gems_Cell" .. gemcell).gem;
                getglobal("Gems_Cell" .. gemcell).gem = 0;
                getglobal("Gems_Cell" .. gemcell+1).gem = gemval;
                Gems_DrawCell(gemcell);
                Gems_DrawCell(gemcell+1);
        end
end

function Gems_MoveDown()
        if(Gems_FallingX == -1) then
                return;
        end
        local gemcell = Gems_FallingX * 8 + Gems_FallingY;
        local gemval = getglobal("Gems_Cell" .. gemcell).gem;

        while(gemcell <= 56 and getglobal("Gems_Cell" .. gemcell+8).gem == 0) do
                getglobal("Gems_Cell" .. gemcell).gem = 0;
                getglobal("Gems_Cell" .. gemcell+8).gem = gemval;
                Gems_DrawCell(gemcell);
                Gems_DrawCell(gemcell+8);
                gemcell = gemcell + 8;
                Gems_FallingX = Gems_FallingX + 1;
        end
end

function Gems_Collapse()
        local didcollapse = false;
        for y = 1,8 do
                for x = 7,1,-1 do
                        --Gems_Write("checking " .. x .. "," .. y .. " (" .. (x*8 + y) .. " - " .. getglobal("Gems_Cell" .. (x*8 + y)).gem);
                        if(getglobal("Gems_Cell" .. (x*8 + y)).gem == 0) then
                        --      Gems_Write("collapsing");
                                getglobal("Gems_Cell" .. (x*8 + y)).gem = getglobal("Gems_Cell" .. ((x-1)*8 + y)).gem;
                                getglobal("Gems_Cell" .. ((x-1)*8 + y)).gem = 0;
                                Gems_DrawCell(x*8 + y);
                                Gems_DrawCell((x-1)*8 + y);
                                didcollapse = true;
                --      else
                --              Gems_Write("breaking");
                --              break;
                        end
                end
        end
        
        if(didcollapse) then
                for y = 1,8 do
                        for x = 7,1,-1 do
                                if(getglobal("Gems_Cell" .. (x*8 + y)).gem > 0) then
                                        Gems_CheckMatch(x,y);
                                end
                        end
                end
        end
end

function Gems_CheckMatch(x, y)
        local gemcell = x * 8 + y;
        local gemval = getglobal("Gems_Cell" .. gemcell).gem;
        
        if(gemval == 0) then return     end

        local htotal = Gems_ScanLeft(x, y, gemval) + Gems_ScanRight(x, y, gemval) - 1;
        local dtotal1 = Gems_ScanUpLeft(x, y, gemval) + Gems_ScanDownRight(x, y, gemval) - 1;
        local dtotal2 = Gems_ScanDownLeft(x, y, gemval) + Gems_ScanUpRight(x, y, gemval) - 1;
        local vtotal = Gems_ScanUp(x, y, gemval) + Gems_ScanDown(x, y, gemval) -1;
        
        local scoreval = 0;

        if(htotal >= 4) then
                if(y > 1) then
                        Gems_DelLeft(x, y-1, gemval);
                end
                
                if(y < 8) then
                        Gems_DelRight(x, y+1, gemval);
                end
                scoreval = scoreval + (htotal - 3) * 5;
        end
        
        if(vtotal >= 4) then
                if(x > 0) then
                        Gems_DelUp(x-1, y, gemval);
                end
                
                if(x < 7) then
                        Gems_DelDown(x+1, y, gemval);
                end
                scoreval = scoreval + (vtotal - 3) * 5;
        end
        
        if(dtotal2 >= 4) then
                if(x < 7 and y > 1) then
                        Gems_DelDownLeft(x+1, y-1, gemval);
                end
                
                if(x > 0 and y < 8) then
                        Gems_DelUpRight(x-1, y+1, gemval);
                end
                scoreval = scoreval + (dtotal2 - 3) * 5;
        end
        
        if(dtotal1 >= 4) then
                if(x > 0 and y > 1) then
                        Gems_DelUpLeft(x-1, y-1, gemval);
                end
                
                if(x < 7 and y < 8) then
                        Gems_DelDownRight(x+1, y+1, gemval);
                end
                scoreval = scoreval + (dtotal1 - 3) * 5;
        end
        
        if(htotal >= 4 or vtotal >=4 or dtotal1 >= 4 or dtotal2 >= 4) then
                getglobal("Gems_Cell" .. gemcell).gem = 0;
                Gems_DrawCell(gemcell);
                Gems_Collapse();
                Gems_UpdateScore(Gems_Score + scoreval);
        end
end

function Gems_ScanLeft(x, y, gemval)
        local total = 0;
        local gemcell = x * 8 + y;
        if(getglobal("Gems_Cell" .. gemcell).gem == gemval) then
                total = 1;
                
                if(y > 1) then
                        total = total + Gems_ScanLeft(x, y-1, gemval);
                end
        end
        return total;
end

function Gems_ScanRight(x, y, gemval)
        local total = 0;
        local gemcell = x * 8 + y;
        if(getglobal("Gems_Cell" .. gemcell).gem == gemval) then
                total = 1;

                if(y < 8) then
                        total = total + Gems_ScanRight(x, y+1, gemval);
                end
        end
                
        return total;
end

function Gems_ScanUp(x, y, gemval)
        local total = 0;
        local gemcell = x * 8 + y;
        if(getglobal("Gems_Cell" .. gemcell).gem == gemval) then
                total = 1;
        
                if(x > 0) then
                        total = total + Gems_ScanUp(x-1, y, gemval);
                end
        end
        return total;
end

function Gems_ScanDown(x, y, gemval)
        local total = 0;
        local gemcell = x * 8 + y;
        if(getglobal("Gems_Cell" .. gemcell).gem == gemval) then
                total = 1;
        
                if(x < 7) then
                        total = total + Gems_ScanDown(x+1, y, gemval);
                end
        end
        return total;
end

function Gems_ScanUpLeft(x, y, gemval)
        local total = 0;
        local gemcell = x * 8 + y;
        if(getglobal("Gems_Cell" .. gemcell).gem == gemval) then
                total = 1;
        
                if(x > 0 and y > 1) then
                        total = total + Gems_ScanUpLeft(x-1, y-1, gemval);
                end
        end
        return total;
end

function Gems_ScanUpRight(x, y, gemval)
        local total = 0;
        local gemcell = x * 8 + y;
        if(getglobal("Gems_Cell" .. gemcell).gem == gemval) then
                total = 1;
        
                if(x > 0 and y < 8) then
                        total = total + Gems_ScanUpRight(x-1, y+1, gemval);
                end
        end
        return total;
end

function Gems_ScanDownLeft(x, y, gemval)
        local total = 0;
        local gemcell = x * 8 + y;
        if(getglobal("Gems_Cell" .. gemcell).gem == gemval) then
                total = 1;
        
                if(x < 7 and y > 1) then
                        total = total + Gems_ScanDownLeft(x+1, y-1, gemval);
                end
        end
        return total;
end

function Gems_ScanDownRight(x, y, gemval)
        local total = 0;
        local gemcell = x * 8 + y;
        if(getglobal("Gems_Cell" .. gemcell).gem == gemval) then
                total = 1;
        
                if(x < 7 and y < 8) then
                        total = total + Gems_ScanDownRight(x+1, y+1, gemval);
                end
        end
        return total;
end

function Gems_DelLeft(x, y, gemval)
        local gemcell = x * 8 + y;
        if(getglobal("Gems_Cell" .. gemcell).gem == gemval) then
                getglobal("Gems_Cell" .. gemcell).gem = 0;
                Gems_DrawCell(gemcell);
                
                if(y > 1) then
                        Gems_DelLeft(x, y-1, gemval);
                end
        end
end

function Gems_DelRight(x, y, gemval)
        local gemcell = x * 8 + y;
        if(getglobal("Gems_Cell" .. gemcell).gem == gemval) then
                getglobal("Gems_Cell" .. gemcell).gem = 0;
                Gems_DrawCell(gemcell);

                if(y < 8) then
                        Gems_DelRight(x, y+1, gemval);
                end
        end
end

function Gems_DelUp(x, y, gemval)
        local gemcell = x * 8 + y;
        if(getglobal("Gems_Cell" .. gemcell).gem == gemval) then
                getglobal("Gems_Cell" .. gemcell).gem = 0;
                Gems_DrawCell(gemcell);
        
                if(x > 0) then
                        Gems_DelUp(x-1, y, gemval);
                end
        end
end

function Gems_DelDown(x, y, gemval)
        local gemcell = x * 8 + y;
        if(getglobal("Gems_Cell" .. gemcell).gem == gemval) then
                getglobal("Gems_Cell" .. gemcell).gem = 0;
                Gems_DrawCell(gemcell);
        
                if(x < 7) then
                        Gems_DelDown(x+1, y, gemval);
                end
        end
end

function Gems_DelUpLeft(x, y, gemval)
        local gemcell = x * 8 + y;
        if(getglobal("Gems_Cell" .. gemcell).gem == gemval) then
                getglobal("Gems_Cell" .. gemcell).gem = 0;
                Gems_DrawCell(gemcell);
        
                if(x > 0 and y > 1) then
                        Gems_DelUpLeft(x-1, y-1, gemval);
                end
        end

end

function Gems_DelUpRight(x, y, gemval)
        local gemcell = x * 8 + y;
        if(getglobal("Gems_Cell" .. gemcell).gem == gemval) then
                getglobal("Gems_Cell" .. gemcell).gem = 0;
                Gems_DrawCell(gemcell);
        
                if(x > 0 and y < 8) then
                        Gems_DelUpRight(x-1, y+1, gemval);
                end
        end
end

function Gems_DelDownLeft(x, y, gemval)
        local gemcell = x * 8 + y;
        if(getglobal("Gems_Cell" .. gemcell).gem == gemval) then
                getglobal("Gems_Cell" .. gemcell).gem = 0;
                Gems_DrawCell(gemcell);
        
                if(x < 7 and y > 1) then
                        Gems_DelDownLeft(x+1, y-1, gemval);
                end
        end
end

function Gems_DelDownRight(x, y, gemval)
        local gemcell = x * 8 + y;
        if(getglobal("Gems_Cell" .. gemcell).gem == gemval) then
                getglobal("Gems_Cell" .. gemcell).gem = 0;
                Gems_DrawCell(gemcell);
        
                if(x < 7 and y < 8) then
                        Gems_DelDownRight(x+1, y+1, gemval);
                end
        end
end

function Gems_UpdateScore(newscore)
        Gems_Score = newscore;
        --Gems_Write("Score is now " .. Gems_Score);
        getglobal("Gems_ScoreString"):SetText(Gems_Score);
end

function Gems_PauseToggle()
        if(Gems_Paused == false) then
                Gems_Paused = true;
                Gems_TimerOn = false;
                this:LockHighlight();
        else
                Gems_Paused = false;
                Gems_TimerOn = true;
                this:UnlockHighlight();
        end
end

function Gems_ScheduleTimer(time, func)
        Gems_TimerFunction = func;
        Gems_TimerEnd = GetTime() + time;
        Gems_TimerOn = true;
end

function Gems_OnUpdate()
        if (not Gems_TimerOn) then return end
        local Gems_Tick = GetTime();
        if (Gems_TimerEnd - Gems_Tick < 0) then
                Gems_TimerOn = false;
                Gems_TimerFunction();
        end
end

function Gems_Difficulty_Initialize()
        local info;
        info = {
                text = "Easy";
                func = Gems_Difficulty_OnClick;
        };
        UIDropDownMenu_AddButton(info);
        
        info = {
                text = "Medium";
                func = Gems_Difficulty_OnClick;
        };
        UIDropDownMenu_AddButton(info);
        
        info = {
                text = "Hard";
                func = Gems_Difficulty_OnClick;
        };
        UIDropDownMenu_AddButton(info);
        
        info = {
                text = "Crazy";
                func = Gems_Difficulty_OnClick;
        };
        UIDropDownMenu_AddButton(info);

end

function Gems_Difficulty_OnLoad()
        UIDropDownMenu_Initialize(Gems_Difficulty, Gems_Difficulty_Initialize);
        UIDropDownMenu_SetSelectedID(Gems_Difficulty, 1);
        UIDropDownMenu_SetWidth(60);
end

function Gems_Difficulty_OnClick()
        local oldID = UIDropDownMenu_GetSelectedID(Gems_Difficulty);
        UIDropDownMenu_SetSelectedID(Gems_Difficulty, this:GetID());
        if(oldID ~= this:GetID()) then
                Gems_ChangeDifficulty();
        end
end

function Gems_Write(msg)
        if (DEFAULT_CHAT_FRAME) then
                DEFAULT_CHAT_FRAME:AddMessage(msg);
        end
end

function Gems_ChangeDifficulty()
        local id = UIDropDownMenu_GetSelectedID(Gems_Difficulty);
        if(id == 1) then
                Gems_GemTypes = 10
        elseif(id == 2) then
                Gems_GemTypes = 13
        elseif(id == 3) then
                Gems_GemTypes = 15
        elseif(id == 4) then
                Gems_GemTypes = 20
        end
        
        Gems_NewGame();
end