--A file to show what functions are used for minigames print("rubick's circle included!") --[[ 7 0 1 \ | / \ | / \|/ 6---------2 /|\ / | \ / | \ ]]-- 5 4 3 Game = Game or {} --Required functions --Called once when the plyer starts casting Game.Cast = function(spelltab,difficulty) --Initalization stuff --[[The cirlces for this spelltab, each cirlce has dots, represtented as a number, 0 is empty]]-- spelltab.Circles = {} --The win conditions stored in the same way as Circles spelltab.Goal = {} --The currently selected circle number, 0 is the inner most spelltab.SelectedCircle = 0 --The Points that need to be filled, represtented as circle, then a number 0-7 on which direction needs to be filled spelltab.Requirements = {} --How many circles there are on the lowest difficulty spelltab.numcircle = 3 --The Next input, the color(as a number) and a number 0-7 of the direction spelltab.NextInputColor = 0 spelltab.NextInputDirection = 0 --When things are moveing spelltab.Animateingringnum = -1 spelltab.Animateingdirection = 0 spelltab.Animateingstart = 0 spelltab.ANIMATE_MOVEING_DURATION = 0.5 --If the column is falling, can be more than one spelltab.AnimateFalling = false spelltab.AnimateFallingColumnNum = {} spelltab.AnimateFallingStartLvl = {} spelltab.AnimateFallingStartTime = 0 spelltab.ANIMATE_FALLING_DURATION = 0.5 spelltab.AnimateRemoveing = false --All the points that need to be animated to be removed --Organized the same way as spelltab.Circles spelltab.AnimateRemoveingPoints = {} spelltab.AnimateRemoveingStartTime = 0 spelltab.ANIMATE_REMOVE_DURATION = 0.5 spelltab.MaxColor = 3 spelltab.GoalNum = 2 --Create a dummy panel so that the mouse is trapped, untrap it when it right clicks spelltab.Score = nil local scoreboard = vgui.Create("MBFrame") if(!scoreboard) then return end scoreboard:SetPos(0,0) scoreboard:SetSize(0,0) scoreboard:MakePopup() spelltab.scoreboard = scoreboard spelltab.numcircle = 3 if(difficulty == 3) then spelltab.numcircle = spelltab.numcircle+2 end for i=0, spelltab.numcircle-1 do spelltab.AnimateRemoveingPoints[i] = {} spelltab.Circles[i] = {} spelltab.Goal[i] = {} for j = 0, 7 do spelltab.AnimateRemoveingPoints[i][j] = false --spelltab.Circles[i][j] = math.Round(math.random(0,3)) spelltab.Circles[i][j] = 0 spelltab.Goal[i][j] = 0 end end for i=0, 7 do spelltab.AnimateFallingColumnNum[i] = false spelltab.AnimateFallingStartLvl[i] = -1 end spelltab.NextInputDirection = math.Round(math.random(0,7)) spelltab.NextInputColor = math.Round(math.random(1,spelltab.MaxColor)) --Generate 5 random spots and colors that need to be filled local i = 0 while(i < spelltab.GoalNum) do local randLvl = math.Round(math.random(0,spelltab.numcircle-2)) local randang = math.Round(math.random(0,7)) local randcolor = math.Round(math.random(1,spelltab.MaxColor)) if(spelltab.Goal[randLvl][randang] != 0) then continue else spelltab.Goal[randLvl][randang] = randcolor i = i+1 end end end --Called continuously while the player is casting Game.Draw = function(self) if not input.IsKeyTrapping() then input.StartKeyTrapping() end draw.DrawText( "Fill in the empty circles with the appropriate colors. Click the circle to select them, and use Q nd E to rotate the circles.", "TargetID", ScrW() * 0.5, ScrH() * 0.25, Color( 255, 255, 255, 255 ), TEXT_ALIGN_CENTER ) --Draw the rings for i = 0, self.numcircle-1 do if(self.SelectedCircle == i) then surface.DrawCircle(ScrW()/2,ScrH()/2,(i+1)*100,Color(255,255,255)) surface.DrawCircle(ScrW()/2,ScrH()/2,((i+1)*100)+5,Color(255,255,255)) surface.DrawCircle(ScrW()/2,ScrH()/2,((i+1)*100)-5,Color(255,255,255)) else surface.DrawCircle(ScrW()/2,ScrH()/2,(i+1)*100,Color(255,255,255)) end --Draw the circles on the rings local angadd = ((self.Animateingstart-CurTime())/self.ANIMATE_MOVEING_DURATION)*45*self.Animateingdirection local subdist = (((self.AnimateFallingStartTime-CurTime())/self.ANIMATE_FALLING_DURATION)*100) local altraid = 20 - (((self.AnimateRemoveingStartTime-CurTime())/self.ANIMATE_REMOVE_DURATION)*20) for j = 0, 7 do if(self.Circles[i][j] != 0) then local angle = (-j*45)+90 if(i == self.SelectedCircle)then angle = angle+angadd end local mul = (i+1)*100 if(self.AnimateFallingColumnNum[j] and i > self.AnimateFallingStartLvl[j]) then mul = mul + subdist end local x = (math.cos(math.rad(angle))*mul) + (ScrW()/2) local y = (math.sin(math.rad(angle))*mul) + (ScrH()/2) local radius = 20 if(self.AnimateRemoveingPoints[i][j]) then radius = 40 - altraid end surface.DrawCircle(x,y,radius,self.ColorFor(self.Circles[i][j])) end if(self.Goal[i][j] != 0) then local angle = (-j*45)+90 local mul = (i+1)*100 local x = (math.cos(math.rad(angle))*mul) + (ScrW()/2) local y = (math.sin(math.rad(angle))*mul) + (ScrH()/2) local color = self.ColorFor(self.Goal[i][j]) surface.SetDrawColor(color) if(self.Goal[i][j] == self.Circles[i][j]) then surface.DrawRect(x-20,y-20,40,40) else surface.DrawOutlinedRect(x-20,y-20,40,40) end end end end --Draw the next-to-add circle local mul = ((self.numcircle+1)*100)-50 local nextang = (-self.NextInputDirection*45)+90 local x = (math.cos(math.rad(nextang))*mul) + (ScrW()/2) local y = (math.sin(math.rad(nextang))*mul) + (ScrH()/2) local nextcol = self.ColorFor(self.NextInputColor) surface.DrawCircle(x,y,20,nextcol) --Deal with moveing stuff if(self.Animateingringnum != -1 and CurTime() > self.Animateingstart+self.ANIMATE_MOVEING_DURATION) then if(self.Animateingdirection == 1) then local tmp = self.Circles[self.SelectedCircle][7] for i = 0, 6 do self.Circles[self.SelectedCircle][7-i]=self.Circles[self.SelectedCircle][6-i] end self.Circles[self.SelectedCircle][0] = tmp self.Animateingringnum = -1 self.Animateingdirection = 0 --Add the new dot in, or fail if we can't if(self.Circles[self.numcircle-1][self.NextInputDirection] != 0) then print("self fail :(") self.Score = 0 self.scoreboard:Remove() else self.Circles[self.numcircle-1][self.NextInputDirection] = self.NextInputColor self.NextInputDirection = math.Round(math.random(0,7)) self.NextInputColor = math.Round(math.random(1,self.MaxColor)) end self.ProcessMoved(self) elseif(self.Animateingdirection == -1) then local tmp = self.Circles[self.SelectedCircle][0] for i = 0, 6 do self.Circles[self.SelectedCircle][i]=self.Circles[self.SelectedCircle][i+1] end self.Circles[self.SelectedCircle][7] = tmp self.Animateingringnum = -1 self.Animateingdirection = 0 --Add the new dot in, or fail if we can't if(self.Circles[self.numcircle-1][self.NextInputDirection] != 0) then print("self fail :(") self.Score = 0 self.scoreboard:Remove() else self.Circles[self.numcircle-1][self.NextInputDirection] = self.NextInputColor self.NextInputDirection = math.Round(math.random(0,7)) self.NextInputColor = math.Round(math.random(1,self.MaxColor)) end self.ProcessMoved(self) end elseif(self.AnimateFalling and CurTime() > self.AnimateFallingStartTime + self.ANIMATE_FALLING_DURATION) then for k,v in pairs(self.AnimateFallingColumnNum) do if(v) then for i = self.AnimateFallingStartLvl[k], self.numcircle-2 do self.Circles[i][k] = self.Circles[i+1][k] end self.Circles[self.numcircle-1][k] = 0 end end for i = 0, 7 do self.AnimateFalling = false self.AnimateFallingColumnNum[i] = false self.AnimateFallingStartLvl[i] = -1 end self.ProcessMoved(self) --[[ elseif(self.AnimateRemoveing and CurTime() > self.AnimateRemoveingStartTime + self.ANIMATE_REMOVE_DURATION) then for i = 0, self.numcircle-1 do for k = 0, 7 do if(self.AnimateRemoveingPoints[i][k]) then self.Circles[k][n] = 0 self.AnimateRemoveingPoints[k][n] = false end end end self.AnimateRemoveing = false self.ProcessMoved() ]]-- elseif(input.IsKeyDown(KEY_Q)) then --If anything is animateing, don't allow the player input if(self.Animateingringnum != -1 or self.AnimateFalling) then return end --Rotate stuff counter-clockwise self.Animateingringnum = self.SelectedCircle self.Animateingdirection = 1 self.Animateingstart = CurTime() elseif(input.IsKeyDown(KEY_E)) then --Don't move if animations are happeneing if(self.Animateingringnum != -1 or self.AnimateFalling) then return end --Rotate stuff clockwise self.Animateingringnum = self.SelectedCircle self.Animateingdirection = -1 self.Animateingstart = CurTime() --Detect mouse input elseif(input.IsMouseDown(MOUSE_LEFT)) then local offset = math.Distance(gui.MouseX(),gui.MouseY(),ScrW()/2,ScrH()/2) print("Offset:" .. offset) for i = 0, self.numcircle-1 do if(offset > (100*(i+1))-50 and offset < (100*(1+i))+50) then self.SelectedCircle = i end end end if(input.IsMouseDown(MOUSE_RIGHT)) then self.Score = 0 self.scoreboard:Remove() end end Game.CheckCompleted = function(self) local numcompleted = 0 for i=0,self.numcircle-1 do for j=0, 7 do if(self.Goal[i][j] != 0 and self.Circles[i][j] == self.Goal[i][j]) then numcompleted = numcompleted + 1 end end end if(numcompleted == self.GoalNum) then self.Score = 100 self.scoreboard:Remove() end end --What to do when anything moved Game.ProcessMoved = function(self) PrintTable(self) if(self.Circles == nil) then print("OH NO, CIRCLES WAS NIL!") return end --First, check to see if anything is 3 in a column for i = 0, 7 do for j = 0, self.numcircle-3 do if(self.Circles[j] == nil) then print("J table:") PrintTable(j) --print("OH NO, CIRCLE " .. j .. " WAS NIL!") return end local tomatch = self.Circles[j][i] if(tomatch == 0) then continue end local ismatching = true for k = 0, 2 do if(self.Circles[j+k][i] != tomatch) then ismatching = false break end end if(ismatching) then --PrintTable(self.Circles) --print("Found a matching column ring " .. j .. " column " .. i .. " " .. tomatch) for k = 0, 2 do self.Circles[j+k][i] = 0 --self.AnimateRemoveingPoints[j+k][i] = true --self.AnimateRemoveingStartTime = CurTime() end end end end --Next, check to see if anything is 3 in a row for i = 0, self.numcircle-1 do for j = 0, 7 do local tomatch = self.Circles[i][j] if(tomatch == 0) then continue end local ismatching = true for k = 0,2 do if(self.Circles[i][(j+k)%8] != tomatch) then ismatching = false break end end if(ismatching) then --PrintTable(self.Circles) --print("Found a matching row ring " .. i .. " column " .. j .. " " .. tomatch) for k = 0,2 do self.Circles[i][(j+k)%8] = 0 --self.AnimateRemoveingPoints[i][(j+k)%8] = true --self.AnimateRemoveingStartTime = CurTime() end end end end --Next, check to see if we need to drop anything for i = 0, 7 do for j = 0, self.numcircle-1 do if(self.Circles[j][i] == 0) then for k=j, self.numcircle-1 do if(self.Circles[k][i] != 0) then --self.Circles[j][i] = self.Circles[k][i] --self.Circles[k][i] = 0 self.AnimateFallingStartLvl[i] = j self.AnimateFallingColumnNum[i] = true self.AnimateFallingStartTime = CurTime() self.AnimateFalling = true --return break end end end end end self.CheckCompleted(self) end Game.ColorFor = function(num) if(num == 0) then return nil end if(num == 1) then return Color(255,0,0) end if(num == 2) then return Color(0,255,0) end if(num == 3) then return Color(0,0,255) end if(num == 4) then return Color(255,0,255) end if(num == 5) then return Color(0,255,255) end if(num == 6) then return Color(255,255,0) end end