diff --git a/save.dat b/save.dat
new file mode 100644
index 00000000..6b2aaa76
--- /dev/null
+++ b/save.dat
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/toontown/estate/DistributedEstate.py b/toontown/estate/DistributedEstate.py
index db00c499..3f0ad9f7 100644
--- a/toontown/estate/DistributedEstate.py
+++ b/toontown/estate/DistributedEstate.py
@@ -74,6 +74,7 @@ class DistributedEstate(DistributedObject.DistributedObject):
         self.loadFlowerSellBox()
         self.oldClear = base.win.getClearColor()
         base.win.setClearColor(Vec4(0.09, 0.55, 0.21, 1.0))
+        self.startGame()
 
     def unload(self):
         self.ignoreAll()
@@ -100,6 +101,7 @@ class DistributedEstate(DistributedObject.DistributedObject):
             self.flowerSellBox.removeNode()
             del self.flowerSellBox
             self.flowerSellBox = None
+        GardenDropGame.GardenDropGame().endGame()
         return
 
     def announceGenerate(self):
@@ -107,7 +109,7 @@ class DistributedEstate(DistributedObject.DistributedObject):
         self.accept('gardenGame', self.startGame)
 
     def startGame(self):
-        self.game = GardenDropGame.GardenDropGame()
+        self.game = GardenDropGame.GardenDropGame().playGardenDrop()
 
     def loadAirplane(self):
         self.airplane = loader.loadModel('phase_4/models/props/airplane.bam')
diff --git a/toontown/estate/DistributedFurnitureManager.py b/toontown/estate/DistributedFurnitureManager.py
index 007b3849..1540bd49 100644
--- a/toontown/estate/DistributedFurnitureManager.py
+++ b/toontown/estate/DistributedFurnitureManager.py
@@ -34,8 +34,8 @@ class DistributedFurnitureManager(DistributedObject.DistributedObject):
         if self.ownerId == base.localAvatar.doId:
             self.cr.furnitureManager = self
             if self.cr.objectManager == None:
-                import HouseDesign
-                self.cr.objectManager = HouseDesign.ObjectManager()
+                import houseDesign
+                self.cr.objectManager = houseDesign.ObjectManager()
         return
 
     def setOwnerName(self, name):
diff --git a/toontown/estate/GameSprite.py b/toontown/estate/GameSprite.py
index 17c720da..c7a06425 100644
--- a/toontown/estate/GameSprite.py
+++ b/toontown/estate/GameSprite.py
@@ -1,14 +1,30 @@
+########################## TOONTOWN ADVENTURE ##########################
+# Filename: GameSprite.py
+# Created by: sillypeppymacspeed
+# Date: March 28th, 2014
+####
+# Description:
+#
+# This codes the sprites for the Garden Drop estate game.
+####
+### DEFINITELY NOT COPIED FROM TOONTOWN HOUSE
+ 
 import math
 
 class GameSprite:
+
     colorRed = (1, 0, 0, 1)
     colorBlue = (0, 0, 1, 1)
     colorGreen = (0, 1, 0, 1)
+    colorYellow = (1, 1, 0, 1)
+    colorPurple = (1, 0, 1, 1)
     colorGhostRed = (1, 0, 0, 0.5)
     colorGhostBlue = (0, 0, 1, 0.5)
     colorGhostGreen = (0, 1, 0, 0.5)
+    colorGhostYellow = (1, 1, 0, 0.5)
+    colorGhostPurple = (1, 0, 1, 0.5)
     colorWhite = (1, 1, 1, 1)
-    colorBlack = (0, 0, 0, 1.0)
+    colorBlack = (0.5, 0.5, 0.5, 1.0)
     colorShadow = (0, 0, 0, 0.5)
 
     def __init__(self, nodeObj, colorType = 0, foundation = 0):
@@ -29,12 +45,20 @@ class GameSprite:
                 self.setColor(GameSprite.colorGhostBlue)
             elif colorType == 2:
                 self.setColor(GameSprite.colorGhostGreen)
+            elif colorType == 3:
+                self.setColor(GameSprite.colorGhostYellow)
+            elif colorType == 4:
+                self.setColor(GameSprite.colorGhostPurple)
         elif colorType == 0:
             self.setColor(GameSprite.colorRed)
         elif colorType == 1:
             self.setColor(GameSprite.colorBlue)
         elif colorType == 2:
             self.setColor(GameSprite.colorGreen)
+        elif colorType == 3:
+            self.setColor(GameSprite.colorYellow)
+        elif colorType == 4:
+            self.setColor(GameSprite.colorPurple)
         self.markedForDeath = 0
 
     def delete(self):
diff --git a/toontown/estate/GardenDropGame.py b/toontown/estate/GardenDropGame.py
index c71e2bf3..c73a0e47 100644
--- a/toontown/estate/GardenDropGame.py
+++ b/toontown/estate/GardenDropGame.py
@@ -1,467 +1,436 @@
-from pandac.PandaModules import *
-from toontown.toonbase.ToonBaseGlobal import *
-from direct.gui.DirectGui import *
-from pandac.PandaModules import *
-from direct.gui.DirectScrolledList import *
-from direct.distributed.ClockDelta import *
-from toontown.toontowngui import TTDialog
-import math
-from direct.task.Task import Task
-from toontown.toonbase import ToontownGlobals
-from direct.distributed import DistributedObject
-from direct.directnotify import DirectNotifyGlobal
-from direct.fsm import ClassicFSM
-from direct.fsm import State
-from toontown.toon import Toon
-from direct.showbase import RandomNumGen
-from toontown.toonbase import TTLocalizer
-import random
-import random
-import cPickle
-from direct.showbase import PythonUtil
-import GameSprite
+import math, random, GameSprite, GardenGameGlobals
 from math import pi
-import GardenProgressMeter
-
-class GardenDropGame(DirectObject.DirectObject):
-
+from direct.gui.DirectGui import *
+from direct.distributed.ClockDelta import *
+from toontown.toonbase import TTLocalizer
+ 
+LevelNumber = 1
+ 
+class GardenDropGame:
+ 
     def __init__(self):
-        self.acceptErrorDialog = None
-        self.doneEvent = 'game Done'
+        self.inHelp = False
         self.sprites = []
-        self.load()
-        thing = self.model.find('**/item_board')
-        self.block = self.model1.find('**/minnieCircle')
-        self.colorRed = (1, 0, 0, 1)
-        self.colorBlue = (0, 0, 1, 1)
-        self.colorGreen = (0, 1, 0, 1)
-        self.colorGhostRed = (1, 0, 0, 0.5)
-        self.colorGhostBlue = (0, 0, 1, 0.5)
-        self.colorGhostGreen = (0, 1, 0, 0.5)
-        self.colorWhite = (1, 1, 1, 1)
-        self.colorBlack = (0, 0, 0, 1.0)
-        self.colorShadow = (0, 0, 0, 0.5)
-        self.lastTime = None
-        self.running = 0
+        self.lastTime = []
+        self.grid = []
+        print ('Grid Dimensions X%s Z%s' % (GardenGameGlobals.gX,
+         GardenGameGlobals.gZ))
+        base.gardenGame = self
+        self.matchList = []
         self.massCount = 0
         self.foundCount = 0
-        self.maxX = 0.47
-        self.minX = -0.47
-        self.maxZ = 0.65
-        self.minZ = -0.1
-        self.newBallX = 0.0
-        self.newBallZ = 0.6
-        self.rangeX = self.maxX - self.minX
-        self.rangeZ = self.maxZ - self.minZ
-        size = 0.085
-        sizeZ = size * 0.8
-        gX = int(self.rangeX / size)
-        gZ = int(self.rangeZ / sizeZ)
-        self.maxX = self.minX + gX * size
-        self.maxZ = self.minZ + gZ * sizeZ
-        self.controlOffsetX = 0.0
-        self.controlOffsetZ = 0.0
-        self.queExtent = 3
-        print 'Grid Dimensions X%s Z%s' % (gX, gZ)
+ 
+        return None
+ 
+    def reinitialize(self):
+        self.inHelp = False
+        self.sprites = []
+        self.lastTime = []
         self.grid = []
-        self.gridDimX = gX
-        self.gridDimZ = gZ
-        self.gridBrick = False
-        base.gardenGame = self
-        for countX in xrange(self.gridDimX):
-            newRow = []
-            for countZ in xrange(self.gridDimZ):
-                offset = 0
-                if countZ % 2 == 0:
-                    offset = size / 2
-                newRow.append([None, countX * size + self.minX + offset, countZ * sizeZ + self.minZ])
-
-            self.grid.append(newRow)
-
-        self.controlSprite = None
-        self.cogSprite = self.addUnSprite(self.block, posX=0.25, posZ=0.5)
-        self.cogSprite.setColor(self.colorShadow)
-        for ball in xrange(0, 3):
-            place = random.random() * self.rangeX
-            newSprite = self.addSprite(self.block, size=0.5, posX=self.minX + place, posZ=0.0, found=1)
-            self.stickInGrid(newSprite, 1)
-
-        self.queBall = self.addSprite(self.block, posX=0.25, posZ=0.5, found=0)
-        self.queBall.setColor(self.colorWhite)
-        self.queBall.isQue = 1
         self.matchList = []
-        self.newBallTime = 1.0
-        self.newBallCountUp = 0.0
-        self.cogX = 0
-        self.cogZ = 0
-        self.__run()
-        return
-
+        self.massCount = 0
+        self.foundCount = 0
+ 
+        return None
+ 
+    def load(self):
+        model = loader.loadModel('phase_5.5/models/gui/package_delivery_panel.bam')
+        model1 = loader.loadModel('phase_3.5/models/gui/matching_game_gui.bam')
+ 
+        self.model = model
+        self.model1 = model1
+ 
+        background = model.find('**/bg')
+        itemBoard = model.find('**/item_board')
+ 
+        self.frame = DirectFrame(scale=1.1000000000000001, relief=DGG.FLAT, frameSize=(-0.5,
+         0.5,
+         -0.45000000000000001,
+         -0.050000000000000003), frameColor=(0.73699999999999999, 0.57299999999999995, 0.34499999999999997, 1.0))
+ 
+        self.background = DirectFrame(self.frame, image=background, image_scale=0.050000000000000003, relief=None, pos=(0, 1, 0))
+        self.itemBoard = DirectFrame(parent=self.frame, image=itemBoard, image_scale=0.050000000000000003, image_color=(0.92200000000000004, 0.92200000000000004, 0.753, 1), relief=None, pos=(0, 1, 0))
+        gui2 = loader.loadModel('phase_3/models/gui/quit_button.bam')
+ 
+        self.font = loader.loadFont("phase_3/models/fonts/MickeyFont.bam")
+        self.gardenDropText = OnscreenText(parent=self.frame, text=TTLocalizer.GardenDropTitle,scale=(0.17,0.17,0.17), font=self.font, pos=(0,0.685,0), fg=(1,1,1,1))
+ 
+        self.quitButton = DirectButton(parent=self.frame, relief=None, image=(gui2.find('**/QuitBtn_UP'),
+         gui2.find('**/QuitBtn_DN'),
+         gui2.find('**/QuitBtn_RLVR')), pos=(0.5,
+         1.0,
+         -0.41999999999999998), scale=0.90000000000000002, text=TTLocalizer.GardenDropExitGame, text_font=self.font, text0_fg=(1, 1, 1, 1), text1_fg=(1, 1, 1, 1), text2_fg=(1, 1, 1, 1), text_scale=0.044999999999999998, text_pos=(0,
+         -0.01), command=self._GardenDropGame__handleExit)
+ 
+        if LevelNumber == 1:
+            self.helpButton = DirectButton(parent=self.frame, relief=None, image=(gui2.find('**/QuitBtn_UP'),
+             gui2.find('**/QuitBtn_DN'),
+             gui2.find('**/QuitBtn_RLVR')), pos=(-0.5,
+             1.0,
+             -0.41999999999999998), scale=0.90000000000000002, text=TTLocalizer.PicnicTableTutorial, text_font=self.font, text0_fg=(1, 1, 1, 1), text1_fg=(1, 1, 1, 1), text2_fg=(1, 1, 1, 1), text_scale=0.044999999999999998, text_pos=(0,
+             -0.01), command=self._GardenDropGame__openHelp)
+ 
+    def help(self):
+        self.inHelp = True
+ 
+        frameGui = loader.loadModel('phase_3/models/gui/dialog_box_gui.bam')
+        self.helpFrame = DirectFrame(scale=1.1, relief=None, image=frameGui, image_scale=(1.75, 1, 0.75), image_color=(1,1,1,1), frameSize=(-0.5,
+         0.5,
+         -0.45,
+         -0.05))
+ 
+        self.font = loader.loadFont("phase_3/models/fonts/MickeyFont.bam")
+        self.helpText = DirectLabel(scale=1.1, relief=None, text_pos=(0, 0.2), text_wordwrap=16, text=TTLocalizer.GardenDropHelpTitle, text_font=self.font, pos=(0.0, 0.0, 0.0), text_scale=0.1, text0_fg=(1, 1, 1, 1), parent=self.helpFrame)
+ 
+        self.font2 = loader.loadFont("phase_3/models/fonts/Comedy.bam")
+        self.helpText2 = DirectLabel(scale=1.1, relief=None, text_pos=(-0.6, 0.1), text_wordwrap=15, text=TTLocalizer.GardenDropInstructions, text_font=self.font2, pos=(0.0, 0.0, 0.0), text_scale=0.085, text0_fg=(0, 0, 0, 1), parent=self.helpFrame, text_align=TextNode.ALeft)
+ 
+        gui2 = loader.loadModel('phase_3/models/gui/quit_button.bam')
+        self.backButton = DirectButton(parent=self.helpFrame, relief=None, image=(gui2.find('**/QuitBtn_UP'), gui2.find('**/QuitBtn_DN'), gui2.find('**/QuitBtn_RLVR')), pos=(0.5, 1.0, -0.32), scale=0.9, text=TTLocalizer.GardenDropBackToGame, text_font=self.font, text0_fg=(1, 1, 1, 1), text1_fg=(1, 1, 1, 1), text2_fg=(1, 1, 1, 1), text_scale=0.045, text_pos=(0, -0.01), command=self.unloadHelp)
+ 
+        return True
+ 
+    def addSprite(self, image, size = 0.5, posX = 0, posZ = 0, found = 0):
+        nodeObj = DirectLabel(parent=self.frame, relief=None, image=image, pos=(posX, 0.0, posZ), scale=size, image_color=(1.0, 1.0, 1.0, 1))
+        if LevelNumber == 1 or LevelNumber == 2:
+            colorChoice = random.choice(range(0, 3))
+        if LevelNumber == 3 or LevelNumber == 4:
+            colorChoice = random.choice(range(0, 4))
+        if LevelNumber == 5:
+            colorChoice = random.choice(range(0, 5))
+ 
+        newSprite = GameSprite.GameSprite(nodeObj, colorChoice, found)
+        self.sprites.append(newSprite)
+ 
+        if found:
+            self.foundCount += 1
+ 
+        return newSprite
+ 
+    def addUnSprite(self, image, size = 0.5, posX = 0, posZ = 0):
+        nodeObj = DirectLabel(parent=self.frame, relief=None, image=image, pos=(posX, 0.0, posZ), scale=size, image_color=(1.0, 1.0, 1.0, 1))
+ 
+        newSprite = GameSprite.GameSprite(nodeObj)
+        newSprite = GameSprite.GameSprite(nodeObj)
+ 
+        return newSprite
+ 
+    def testPointDistanceSquare(self, x1, z1, x2, z2):
+        distX = x1 - x2
+        distZ = z1 - z2
+        distC = distX * distX + distZ * distZ
+ 
+        if distC == 0:
+            distC = 1e-10
+ 
+        return distC
+ 
+    def testDistance(self, nodeA, nodeB):
+        distX = nodeA.getX() - nodeB.getX()
+        distZ = nodeA.getZ() - nodeB.getZ()
+        distC = distX * distX + distZ * distZ
+        dist = math.sqrt(distC)
+ 
+        return dist
+ 
+    def testGridfull(self, cell):
+        if not cell:
+            return 0
+ 
+        elif cell[0] != None:
+            return 1
+ 
+        else:
+            return 0
+ 
+        returnTrue
+ 
+    def getValidGrid(self, x, z):
+        if x < 0 or x >= GardenGameGlobals.gridDimX:
+            return None
+ 
+        elif z < 0 or z >= GardenGameGlobals.gridDimZ:
+            return None
+ 
+        else:
+            return self.grid[x][z]
+ 
+        return None
+ 
+    def getColorType(self, x, z):
+        if x < 0 or x >= GardenGameGlobals.gridDimX:
+            return -1
+ 
+        elif z < 0 or z >= GardenGameGlobals.gridDimZ:
+            return -1
+ 
+        elif self.grid[x][z][0] == None:
+            return -1
+ 
+        else:
+            return self.grid[x][z][0].colorType
+ 
+        return True
+ 
+    def getSprite(self, spriteIndex):
+        if spriteIndex >= len(self.sprites) or self.sprites[spriteIndex].markedForDeath:
+            return None
+ 
+        else:
+            return self.sprites[spriteIndex]
+ 
+        return None
+ 
     def findGrid(self, x, z, force = 0):
         currentClosest = None
         currentDist = 10000000
-        for countX in xrange(self.gridDimX):
-            for countZ in xrange(self.gridDimZ):
+ 
+        for countX in range(GardenGameGlobals.gridDimX):
+            for countZ in range(GardenGameGlobals.gridDimZ):
                 testDist = self.testPointDistanceSquare(x, z, self.grid[countX][countZ][1], self.grid[countX][countZ][2])
                 if self.grid[countX][countZ][0] == None and testDist < currentDist and (force or self.hasNeighbor(countX, countZ)):
                     currentClosest = self.grid[countX][countZ]
                     self.closestX = countX
                     self.closestZ = countZ
                     currentDist = testDist
-
+ 
         return currentClosest
-
-    def hasNeighbor(self, cellX, cellZ):
-        gotNeighbor = 0
-        if cellZ % 2 == 0:
-            if self.testGridfull(self.getValidGrid(cellX - 1, cellZ)):
-                gotNeighbor = 1
-            elif self.testGridfull(self.getValidGrid(cellX + 1, cellZ)):
-                gotNeighbor = 1
-            elif self.testGridfull(self.getValidGrid(cellX, cellZ + 1)):
-                gotNeighbor = 1
-            elif self.testGridfull(self.getValidGrid(cellX + 1, cellZ + 1)):
-                gotNeighbor = 1
-            elif self.testGridfull(self.getValidGrid(cellX, cellZ - 1)):
-                gotNeighbor = 1
-            elif self.testGridfull(self.getValidGrid(cellX + 1, cellZ - 1)):
-                gotNeighbor = 1
-        elif self.testGridfull(self.getValidGrid(cellX - 1, cellZ)):
-            gotNeighbor = 1
-        elif self.testGridfull(self.getValidGrid(cellX + 1, cellZ)):
-            gotNeighbor = 1
-        elif self.testGridfull(self.getValidGrid(cellX, cellZ + 1)):
-            gotNeighbor = 1
-        elif self.testGridfull(self.getValidGrid(cellX - 1, cellZ + 1)):
-            gotNeighbor = 1
-        elif self.testGridfull(self.getValidGrid(cellX, cellZ - 1)):
-            gotNeighbor = 1
-        elif self.testGridfull(self.getValidGrid(cellX - 1, cellZ - 1)):
-            gotNeighbor = 1
-        return gotNeighbor
-
-    def clearMatchList(self):
-        for entry in self.matchList:
-            gridEntry = self.grid[entry[0]][entry[1]]
-            sprite = gridEntry[0]
-            gridEntry[0] = None
-            sprite.markedForDeath = 1
-
-        return
-
-    def createMatchList(self, x, z):
-        self.matchList = []
-        self.fillMatchList(x, z)
-
-    def fillMatchList(self, cellX, cellZ):
-        if (cellX, cellZ) in self.matchList:
-            return
-        self.matchList.append((cellX, cellZ))
-        colorType = self.grid[cellX][cellZ][0].colorType
-        if cellZ % 2 == 0:
-            if self.getColorType(cellX - 1, cellZ) == colorType:
-                self.fillMatchList(cellX - 1, cellZ)
-            if self.getColorType(cellX + 1, cellZ) == colorType:
-                self.fillMatchList(cellX + 1, cellZ)
-            if self.getColorType(cellX, cellZ + 1) == colorType:
-                self.fillMatchList(cellX, cellZ + 1)
-            if self.getColorType(cellX + 1, cellZ + 1) == colorType:
-                self.fillMatchList(cellX + 1, cellZ + 1)
-            if self.getColorType(cellX, cellZ - 1) == colorType:
-                self.fillMatchList(cellX, cellZ - 1)
-            if self.getColorType(cellX + 1, cellZ - 1) == colorType:
-                self.fillMatchList(cellX + 1, cellZ - 1)
-        else:
-            if self.getColorType(cellX - 1, cellZ) == colorType:
-                self.fillMatchList(cellX - 1, cellZ)
-            if self.getColorType(cellX + 1, cellZ) == colorType:
-                self.fillMatchList(cellX + 1, cellZ)
-            if self.getColorType(cellX, cellZ + 1) == colorType:
-                self.fillMatchList(cellX, cellZ + 1)
-            if self.getColorType(cellX - 1, cellZ + 1) == colorType:
-                self.fillMatchList(cellX - 1, cellZ + 1)
-            if self.getColorType(cellX, cellZ - 1) == colorType:
-                self.fillMatchList(cellX, cellZ - 1)
-            if self.getColorType(cellX - 1, cellZ - 1) == colorType:
-                self.fillMatchList(cellX - 1, cellZ - 1)
-
-    def testGridfull(self, cell):
-        if not cell:
-            return 0
-        elif cell[0] != None:
-            return 1
-        else:
-            return 0
-        return
-
-    def getValidGrid(self, x, z):
-        if x < 0 or x >= self.gridDimX:
-            return None
-        elif z < 0 or z >= self.gridDimZ:
-            return None
-        else:
-            return self.grid[x][z]
-        return None
-
-    def getColorType(self, x, z):
-        if x < 0 or x >= self.gridDimX:
-            return -1
-        elif z < 0 or z >= self.gridDimZ:
-            return -1
-        elif self.grid[x][z][0] == None:
-            return -1
-        else:
-            return self.grid[x][z][0].colorType
-        return
-
+ 
     def findGridCog(self):
-        self.cogX = 0
-        self.cogZ = 0
+        GardenGameGlobals.cogX = 0
+        GardenGameGlobals.cogZ = 0
         self.massCount = 0
+ 
         for row in self.grid:
             for cell in row:
                 if cell[0] != None:
-                    self.cogX += cell[1]
-                    self.cogZ += cell[2]
+                    GardenGameGlobals.cogX += cell[1]
+                    GardenGameGlobals.cogZ += cell[2]
                     self.massCount += 1
-
+ 
         if self.massCount > 0:
-            self.cogX = self.cogX / self.massCount
-            self.cogZ = self.cogZ / self.massCount
+            self.cogX = (GardenGameGlobals.cogX / self.massCount)
+            self.cogZ = (GardenGameGlobals.cogZ / self.massCount)
             self.cogSprite.setX(self.cogX)
             self.cogSprite.setZ(self.cogZ)
         else:
             self.doOnClearGrid()
-        return
-
-    def doOnClearGrid(self):
-        secondSprite = self.addSprite(self.block, posX=self.newBallX, posZ=0.0, found=1)
-        secondSprite.addForce(0, 1.55 * pi)
-        self.stickInGrid(secondSprite, 1)
-
-    def findGrid2(self, x, z):
-        rangeX = self.maxX - self.minX
-        rangeZ = self.maxZ - self.minZ
-        framedX = x - self.minX
-        framedZ = z - self.minZ
-        tileDimX = rangeX / self.gridDimX
-        tileDimZ = rangeZ / self.gridDimZ
-        tileX = int(framedX / tileDimX)
-        tileZ = int(framedZ / tileDimZ)
-        print 'find Grid tileX%s tileZ%s' % (tileX, tileZ)
-        return (tileX, tileZ)
-
-    def findPos(self, x, z):
-        rangeX = self.maxX - self.minX
-        rangeZ = self.maxZ - self.minZ
-        tileDimX = rangeX / self.gridDimX
-        tileDimZ = rangeZ / self.gridDimZ
-        posX = tileDimX * x + self.minX
-        posZ = tileDimZ * z + self.minZ
-        print 'find Pos X%s Z%s' % (posX, posZ)
-        return (posX, posZ)
-
-    def placeIntoGrid(self, sprite, x, z):
-        if self.grid[x][z][0] == None:
-            self.grid[x][z][0] = sprite
-            sprite.setActive(0)
-            newX, newZ = self.findPos(x, z)
-            sprite.setX(newX)
-            sprite.setZ(newZ)
-            print 'Setting Final Pos X%s Z%s' % (newX, newZ)
-        else:
-            self.placeIntoGrid(sprite, x + 1, z - 1)
-        return
-
+ 
+        return True
+ 
     def stickInGrid(self, sprite, force = 0):
         if sprite.isActive and not sprite.isQue:
             gridCell = self.findGrid(sprite.getX(), sprite.getZ(), force)
+ 
             if gridCell:
                 gridCell[0] = sprite
                 sprite.setActive(0)
                 sprite.setX(gridCell[1])
                 sprite.setZ(gridCell[2])
                 self.createMatchList(self.closestX, self.closestZ)
+ 
                 if len(self.matchList) >= 3:
                     self.clearMatchList()
                 self.findGridCog()
-
-    def stickInGrid2(self, sprite):
-        if sprite.isActive and not sprite.isQue:
-            tileX, tileZ = self.findGrid(sprite.getX(), sprite.getZ())
-            self.placeIntoGrid(sprite, tileX, tileZ)
-            sprite.isActive = 0
-
-    def load(self):
-        model = loader.loadModel('phase_5.5/models/gui/package_delivery_panel')
-        model1 = loader.loadModel('phase_3.5/models/gui/matching_game_gui')
-        self.model = model
-        self.model1 = model1
-        background = model.find('**/bg')
-        itemBoard = model.find('**/item_board')
-        self.frame = DirectFrame(scale=1.1, relief=DGG.FLAT, frameSize=(-0.5,
-         0.5,
-         -0.45,
-         -0.05), frameColor=(0.737, 0.573, 0.345, 1.0))
-        self.background = DirectFrame(self.frame, image=background, image_scale=0.05, relief=None, pos=(0, 1, 0))
-        self.itemBoard = DirectFrame(parent=self.frame, image=itemBoard, image_scale=0.05, image_color=(0.922, 0.922, 0.753, 1), relief=None, pos=(0, 1, 0))
-        gui2 = loader.loadModel('phase_3/models/gui/quit_button')
-        self.quitButton = DirectButton(parent=self.frame, relief=None, image=(gui2.find('**/QuitBtn_UP'), gui2.find('**/QuitBtn_DN'), gui2.find('**/QuitBtn_RLVR')), pos=(0.5, 1.0, -0.42), scale=0.9, text='Exit Mini Game', text_font=ToontownGlobals.getSignFont(), text0_fg=(1, 1, 1, 1), text1_fg=(1, 1, 1, 1), text2_fg=(1, 1, 1, 1), text_scale=0.045, text_pos=(0, -0.01), command=self.__handleExit)
-        return
-
-    def unload(self):
-        self.frame.destroy()
-        del self.frame
-        if self.acceptErrorDialog:
-            self.acceptErrorDialog.cleanup()
-            self.acceptErrorDialog = None
-        taskMgr.remove('gameTask')
-        self.ignoreAll()
-        return
-
-    def show(self):
-        self.frame.show()
-
-    def hide(self):
-        self.frame.hide()
-
-    def __handleExit(self):
-        self.__acceptExit()
-
-    def __acceptExit(self, buttonValue = None):
-        if hasattr(self, 'frame'):
-            self.hide()
-            self.unload()
-            messenger.send(self.doneEvent)
-
-    def addSprite(self, image, size = 0.5, posX = 0, posZ = 0, found = 0):
-        nodeObj = DirectLabel(parent=self.frame, relief=None, image=image, pos=(posX, 0.0, posZ), scale=size, image_color=(1.0, 1.0, 1.0, 1))
-        colorChoice = random.choice(range(0, 3))
-        newSprite = GameSprite.GameSprite(nodeObj, colorChoice, found)
-        self.sprites.append(newSprite)
-        if found:
-            self.foundCount += 1
-        return newSprite
-
-    def addUnSprite(self, image, size = 0.5, posX = 0, posZ = 0):
-        nodeObj = DirectLabel(parent=self.frame, relief=None, image=image, pos=(posX, 0.0, posZ), scale=size, image_color=(1.0, 1.0, 1.0, 1))
-        newSprite = GameSprite.GameSprite(nodeObj)
-        newSprite = GameSprite.GameSprite(nodeObj)
-        return newSprite
-
-    def __run(self, cont = 1):
-        if self.lastTime == None:
-            self.lastTime = globalClock.getRealTime()
-        timeDelta = globalClock.getRealTime() - self.lastTime
-        self.lastTime = globalClock.getRealTime()
-        self.newBallCountUp += timeDelta
-        if base.mouseWatcherNode.hasMouse():
-            x = base.mouseWatcherNode.getMouseX()
-            y = base.mouseWatcherNode.getMouseY()
-            self.queBall.setX(x)
-            self.queBall.setZ(y)
-        for sprite in self.sprites:
-            sprite.run(timeDelta)
-            if sprite.getX() > self.maxX:
-                sprite.setX(self.maxX)
-                sprite.velX = -sprite.velX
-            if sprite.getX() < self.minX:
-                sprite.setX(self.minX)
-                sprite.velX = -sprite.velX
-            if sprite.getZ() > self.maxZ:
-                sprite.setZ(self.maxZ)
-                sprite.velZ = -sprite.velZ
-            if sprite.getZ() < self.minZ:
-                self.stickInGrid(sprite, 1)
-            if sprite.isActive:
-                sprite.addForce(timeDelta * 0.9, pi * 1.5)
-
-        self.queBall.velX = (self.queBall.getX() - self.queBall.prevX) / timeDelta
-        self.queBall.velZ = (self.queBall.getZ() - self.queBall.prevZ) / timeDelta
-        self.__colTest()
-        for sprite in self.sprites:
-            if sprite.markedForDeath:
-                if sprite.foundation:
-                    self.foundCount -= 1
-                self.sprites.remove(sprite)
-                sprite.delete()
-
-        if self.controlSprite == None:
-            self.addControlSprite(self.newBallX, self.newBallZ)
-            self.newBallCountUp = 0.0
-        if self.newBallCountUp >= self.newBallTime:
-            self.addControlSprite(self.newBallX, self.newBallZ)
-            self.newBallCountUp = 0.0
-        if not self.controlSprite.isActive:
-            self.controlSprite = None
-        if self.foundCount <= 0:
-            self.__handleWin()
-        if cont and not self.running:
-            taskMgr.add(self.__run, 'gameTask')
-            self.running = 1
-        return Task.cont
-
-    def __handleWin(self):
-        GardenProgressMeter.GardenProgressMeter()
-        self.__handleExit()
-
-    def addControlSprite(self, x = 0.0, z = 0.0):
-        newSprite = self.addSprite(self.block, posX=x, posZ=z)
-        self.controlSprite = newSprite
-
+ 
+    def fillMatchList(self, cellX, cellZ):
+        if (cellX, cellZ) in self.matchList:
+            return True
+ 
+        self.matchList.append((cellX, cellZ))
+        colorType = self.grid[cellX][cellZ][0].colorType
+ 
+        if cellZ % 2 == 0:
+            if self.getColorType(cellX - 1, cellZ) == colorType:
+                self.fillMatchList(cellX - 1, cellZ)
+ 
+            if self.getColorType(cellX + 1, cellZ) == colorType:
+                self.fillMatchList(cellX + 1, cellZ)
+ 
+            if self.getColorType(cellX, cellZ + 1) == colorType:
+                self.fillMatchList(cellX, cellZ + 1)
+ 
+            if self.getColorType(cellX + 1, cellZ + 1) == colorType:
+                self.fillMatchList(cellX + 1, cellZ + 1)
+ 
+            if self.getColorType(cellX, cellZ - 1) == colorType:
+                self.fillMatchList(cellX, cellZ - 1)
+ 
+            if self.getColorType(cellX + 1, cellZ - 1) == colorType:
+                self.fillMatchList(cellX + 1, cellZ - 1)
+ 
+        else:
+            if self.getColorType(cellX - 1, cellZ) == colorType:
+                self.fillMatchList(cellX - 1, cellZ)
+ 
+            if self.getColorType(cellX + 1, cellZ) == colorType:
+                self.fillMatchList(cellX + 1, cellZ)
+ 
+            if self.getColorType(cellX, cellZ + 1) == colorType:
+                self.fillMatchList(cellX, cellZ + 1)
+ 
+            if self.getColorType(cellX - 1, cellZ + 1) == colorType:
+                self.fillMatchList(cellX - 1, cellZ + 1)
+ 
+            if self.getColorType(cellX, cellZ - 1) == colorType:
+                self.fillMatchList(cellX, cellZ - 1)
+ 
+            if self.getColorType(cellX - 1, cellZ - 1) == colorType:
+                self.fillMatchList(cellX - 1, cellZ - 1)
+ 
+    def createMatchList(self, x, z):
+        self.matchList = []
+        self.fillMatchList(x, z)
+ 
+    def clearMatchList(self):
+        for entry in self.matchList:
+            gridEntry = self.grid[entry[0]][entry[1]]
+            sprite = gridEntry[0]
+            gridEntry[0] = None
+            sprite.markedForDeath = 1
+ 
+        return True
+ 
+    def hasNeighbor(self, cellX, cellZ):
+        gotNeighbor = 0
+ 
+        if cellZ % 2 == 0:
+            if self.testGridfull(self.getValidGrid(cellX - 1, cellZ)):
+                gotNeighbor = 1
+ 
+            elif self.testGridfull(self.getValidGrid(cellX + 1, cellZ)):
+                gotNeighbor = 1
+ 
+            elif self.testGridfull(self.getValidGrid(cellX, cellZ + 1)):
+                gotNeighbor = 1
+ 
+            elif self.testGridfull(self.getValidGrid(cellX + 1, cellZ + 1)):
+                gotNeighbor = 1
+ 
+            elif self.testGridfull(self.getValidGrid(cellX, cellZ - 1)):
+                gotNeighbor = 1
+ 
+            elif self.testGridfull(self.getValidGrid(cellX + 1, cellZ - 1)):
+                gotNeighbor = 1
+ 
+        elif self.testGridfull(self.getValidGrid(cellX - 1, cellZ)):
+            gotNeighbor = 1
+ 
+        elif self.testGridfull(self.getValidGrid(cellX + 1, cellZ)):
+            gotNeighbor = 1
+ 
+        elif self.testGridfull(self.getValidGrid(cellX, cellZ + 1)):
+            gotNeighbor = 1
+ 
+        elif self.testGridfull(self.getValidGrid(cellX - 1, cellZ + 1)):
+            gotNeighbor = 1
+ 
+        elif self.testGridfull(self.getValidGrid(cellX, cellZ - 1)):
+            gotNeighbor = 1
+ 
+        elif self.testGridfull(self.getValidGrid(cellX - 1, cellZ - 1)):
+            gotNeighbor = 1
+ 
+        return gotNeighbor
+ 
     def __colTest(self):
         if not hasattr(self, 'tick'):
             self.tick = 0
+ 
         self.tick += 1
+ 
         if self.tick > 5:
             self.tick = 0
         sizeSprites = len(self.sprites)
-        for movingSpriteIndex in xrange(len(self.sprites)):
-            for testSpriteIndex in xrange(movingSpriteIndex, len(self.sprites)):
+ 
+        for movingSpriteIndex in range(len(self.sprites)):
+            for testSpriteIndex in range(movingSpriteIndex, len(self.sprites)):
                 movingSprite = self.getSprite(movingSpriteIndex)
                 testSprite = self.getSprite(testSpriteIndex)
+ 
                 if testSprite and movingSprite:
                     if movingSpriteIndex != testSpriteIndex and (movingSprite.isActive or testSprite.isActive):
                         if movingSprite.isQue or testSprite.isQue:
-                            if self.testDistance(movingSprite.nodeObj, testSprite.nodeObj) < self.queExtent * (movingSprite.size + testSprite.size):
+                            if self.testDistance(movingSprite.nodeObj, testSprite.nodeObj) < GardenGameGlobals.queExtent * (movingSprite.size + testSprite.size):
                                 self.push(movingSprite, testSprite)
+ 
                         elif self.testDistance(movingSprite.nodeObj, testSprite.nodeObj) < movingSprite.size + testSprite.size:
-                            if not (movingSprite.isActive and testSprite.isActive):
-                                self.__collide(movingSprite, testSprite)
+                            if movingSprite.isActive:
+                                testSprite.isActive or self.__collide(movingSprite, testSprite)
+ 
+                        if self.testDistance(self.cogSprite.nodeObj, testSprite.nodeObj) < (self.cogSprite.size + testSprite.size):
+                            if movingSprite.isActive:
+                                self.stickInGrid(testSprite, 1)
+ 
                         if self.tick == 5:
                             pass
-
-    def getSprite(self, spriteIndex):
-        if spriteIndex >= len(self.sprites) or self.sprites[spriteIndex].markedForDeath:
-            return None
+ 
+    def __collide(self, move, test):
+        queHit = 0
+ 
+        if move.isQue:
+            que = move
+            hit = test
+            queHit = 1
+ 
+        elif test.isQue:
+            que = test
+            hit = move
+            queHit = 1
+ 
         else:
-            return self.sprites[spriteIndex]
-        return None
-
-    def testDistance(self, nodeA, nodeB):
-        distX = nodeA.getX() - nodeB.getX()
-        distZ = nodeA.getZ() - nodeB.getZ()
-        distC = distX * distX + distZ * distZ
-        dist = math.sqrt(distC)
-        return dist
-
-    def testPointDistance(self, x1, z1, x2, z2):
-        distX = x1 - x2
-        distZ = z1 - z2
-        distC = distX * distX + distZ * distZ
-        dist = math.sqrt(distC)
-        if dist == 0:
-            dist = 1e-10
-        return dist
-
-    def testPointDistanceSquare(self, x1, z1, x2, z2):
-        distX = x1 - x2
-        distZ = z1 - z2
-        distC = distX * distX + distZ * distZ
-        if distC == 0:
-            distC = 1e-10
-        return distC
-
+            test.velX = 0
+            test.velZ = 0
+            move.velX = 0
+            move.velZ = 0
+            test.collide()
+            move.collide()
+            self.stickInGrid(move,1)
+            self.stickInGrid(test,1)
+ 
+        if queHit:
+            forceM = 0.1
+            distX = que.getX() - hit.getX()
+            distZ = que.getZ() - hit.getZ()
+            self.stickInGrid(move,1)
+            self.stickInGrid(test,1)
+ 
+    def push(self, move, test):
+        queHit = 0
+ 
+        if move.isQue:
+            que = move
+            hit = test
+            queHit = 1
+ 
+        elif test.isQue:
+            que = test
+            hit = move
+            queHit = 1
+ 
+        if queHit:
+            forceM = 0.1
+            dist = self.testDistance(move.nodeObj, test.nodeObj)
+ 
+            if abs(dist) < GardenGameGlobals.queExtent * que.size and abs(dist) > 0:
+                scaleSize = GardenGameGlobals.queExtent * que.size * 0.5
+                distFromPara = abs(abs(dist) - scaleSize)
+                force = (scaleSize - distFromPara) / scaleSize * (dist / abs(dist))
+                angle = self.angleTwoSprites(que, hit)
+ 
+                if angle < 0:
+                    angle = angle + 2 * pi
+ 
+                if angle > pi * 2.0:
+                    angle = angle - 2 * pi
+ 
+                newAngle = pi * 1.0
+ 
+                if angle > pi * 1.5 or angle < pi * 0.5:
+                    newAngle = pi * 0.0
+ 
+                hit.addForce(forceM * force, newAngle)
+ 
     def angleTwoSprites(self, sprite1, sprite2):
         x1 = sprite1.getX()
         z1 = sprite1.getZ()
@@ -470,61 +439,252 @@ class GardenDropGame(DirectObject.DirectObject):
         x = x2 - x1
         z = z2 - z1
         angle = math.atan2(-x, z)
+ 
         return angle + pi * 0.5
-
-    def angleTwoPoints(self, x1, z1, x2, z2):
-        x = x2 - x1
-        z = z2 - z1
-        angle = math.atan2(-x, z)
-        return angle + pi * 0.5
-
-    def __collide(self, move, test):
-        queHit = 0
-        if move.isQue:
-            que = move
-            hit = test
-            queHit = 1
-        elif test.isQue:
-            que = test
-            hit = move
-            queHit = 1
+ 
+    def doOnClearGrid(self):
+        secondSprite = self.addSprite(self.block, posX=GardenGameGlobals.newBallX, posZ=0.0, found=1)
+        secondSprite.addForce(0, 1.55 * pi)
+        self.stickInGrid(secondSprite, 1)
+ 
+    def __run(self, Task):
+        if self.lastTime == None:
+             self.lastTime = globalClock.getRealTime()
+ 
+        timeDelta = 0.0265
+        self.lastTime = globalClock.getRealTime()
+        GardenGameGlobals.newBallCountUp += timeDelta
+ 
+        if base.mouseWatcherNode.hasMouse():
+            x = base.mouseWatcherNode.getMouseX()
+            y = base.mouseWatcherNode.getMouseY()
+            self.queBall.setX(x)
+            self.queBall.setZ(y)
+ 
+        for sprite in self.sprites:
+            sprite.run(timeDelta)
+            if sprite.getX() > GardenGameGlobals.maxX:
+                sprite.setX(GardenGameGlobals.maxX)
+                sprite.velX = -sprite.velX
+ 
+            if sprite.getX() < GardenGameGlobals.minX:
+                sprite.setX(GardenGameGlobals.minX)
+                sprite.velX = -sprite.velX
+ 
+            if sprite.getZ() > GardenGameGlobals.maxZ:
+                sprite.setZ(GardenGameGlobals.maxZ)
+                sprite.velZ = -sprite.velZ
+ 
+            if sprite.getZ() < GardenGameGlobals.minZ:
+                self.stickInGrid(sprite, 1)
+ 
+            if sprite.isActive:
+                sprite.addForce(timeDelta * 0.9, pi * 1.5)
+ 
+        self.queBall.velX = (self.queBall.getX() - self.queBall.prevX) / timeDelta
+        self.queBall.velZ = (self.queBall.getZ() - self.queBall.prevZ) / timeDelta
+        self.__colTest()
+ 
+        for sprite in self.sprites:
+            if sprite.markedForDeath:
+                if sprite.foundation:
+                    self.foundCount -= 1
+ 
+                self.sprites.remove(sprite)
+                sprite.delete()
+ 
+        if GardenGameGlobals.controlSprite == None:
+            self.addControlSprite(GardenGameGlobals.newBallX, GardenGameGlobals.newBallZ)
+            GardenGameGlobals.newBallCountUp = 0.0
+ 
+        if GardenGameGlobals.newBallCountUp >= GardenGameGlobals.newBallTime:
+            self.addControlSprite(GardenGameGlobals.newBallX, GardenGameGlobals.newBallZ)
+            GardenGameGlobals.newBallCountUp = 0.0
+ 
+        if not GardenGameGlobals.controlSprite.isActive:
+            GardenGameGlobals.controlSprite = None
+ 
+        if self.foundCount <= 0:
+            self.__handleWin()
+ 
+        return Task.cont
+ 
+    def loadStartingSprites(self, levelNum):
+        self.queBall = self.addSprite(self.block, posX=0.25, posZ=0.5, found=0)
+        self.queBall.setColor(GardenGameGlobals.colorWhite)
+        self.queBall.isQue = 1
+ 
+        GardenGameGlobals.controlSprite = None
+        self.cogSprite = self.addUnSprite(self.block, posX=0.25, posZ=0.5)
+        self.cogSprite.setColor(GardenGameGlobals.colorBlack)
+ 
+        for ball in range(0, levelNum):
+            place = random.random() * GardenGameGlobals.rangeX
+            self.newSprite = self.addSprite(self.block, size=0.5, posX=GardenGameGlobals.minX + place, posZ=0.0, found=1)
+            self.stickInGrid(self.newSprite, 1)
+ 
+    def __handlePlay(self):
+        if hasattr(base, 'localAvatar'):
+            base.cr.playGame.getPlace().fsm.forceTransition('stopped')
+ 
+        self.reinitialize()
+        self.load()
+ 
+        self.itemboard = self.model.find('**/item_board')
+        self.block = self.model1.find('**/minnieCircle')
+ 
+        size = 0.085
+        sizeZ = size * 0.8
+ 
+        for countX in range(GardenGameGlobals.gridDimX):
+            newRow = []
+            for countZ in range(GardenGameGlobals.gridDimZ):
+                offset = 0
+                if countZ % 2 == 0:
+                    offset = size / 2
+                newRow.append([None, countX * size + GardenGameGlobals.minX + offset, countZ * sizeZ + GardenGameGlobals.minZ])
+ 
+            self.grid.append(newRow)
+ 
+        if LevelNumber == 1:
+            self.loadStartingSprites(3)
+        elif LevelNumber == 2:
+            self.loadStartingSprites(5)
+        elif LevelNumber == 3:
+            self.loadStartingSprites(7)
+        elif LevelNumber == 4:
+            self.loadStartingSprites(10)
+        elif LevelNumber == 5:
+            self.loadStartingSprites(15)
+        base.taskMgr.add(self._GardenDropGame__run,"MouseCheck")
+ 
+        if hasattr(self, 'victoryFrame'):
+            self.victoryFrame.removeNode()
+            del self.victoryFrame
+ 
+    def addControlSprite(self, x = 0.0, z = 0.0):
+        newSprite = self.addSprite(self.block, posX=x, posZ=z)
+        GardenGameGlobals.controlSprite = newSprite
+ 
+    def playGardenDrop(self):
+        self.GDButtonImage = loader.loadModel("phase_3/models/gui/quit_button.bam")
+        self.font = loader.loadFont("phase_3/models/fonts/MickeyFont.bam")
+        self.yellowButton = (self.GDButtonImage.find('**/QuitBtn_UP'), self.GDButtonImage.find('**/QuitBtn_DN'), self.GDButtonImage.find('**/QuitBtn_RLVR'))
+ 
+        self.GardenGameButton = DirectButton(frameSize=(0), text=TTLocalizer.GardenDropButtonTitle, image=self.yellowButton, text_pos=(0,0.01), relief=None, text_fg=(1, 1, 1, 1), \
+        geom=None, pad=(0.01, 0.01), suppressKeys=0, command=self.deleteGDButton, pos=(-.62,0,-.89), text_font=self.font, text_scale=(0.083,0.040,0.049), borderWidth=(0.13, 0.01), scale=(0.8,1,1.8))
+ 
+        base.localAvatar.gardenGameButton = self.GardenGameButton
+ 
+    def __openHelp(self):
+        self.unload()
+        self.help()
+        base.taskMgr.remove('MouseCheck')
+ 
+    def unload(self):
+        self.frame.destroy()
+        del self.frame
+ 
+        if (GardenGameGlobals.acceptErrorDialog and GardenGameGlobals.acceptErrorDialog.cleanup()):
+            GardenGameGlobals.acceptErrorDialog = 1
+ 
+    def unloadHelp(self):
+        self.helpFrame.removeNode()
+        self._GardenDropGame__handlePlay()
+ 
+    def deleteGDButton(self):
+        self.GardenGameButton.removeNode()
+        self.__handlePlay()
+ 
+    def __handleExit(self):
+        self._GardenDropGame__acceptExit()
+ 
+    def __acceptExit(self, buttonValue = None):
+        global LevelNumber
+        if hasattr(base, 'localAvatar'):
+            base.cr.playGame.getPlace().fsm.forceTransition('walk')
+ 
+        self.playGardenDrop()
+        if (hasattr(self, 'frame') and self.frame.hide()):
+            self.unload()
+            messenger.send(GardenGameGlobals.doneEvent)
+ 
+        LevelNumber = 1
+        base.taskMgr.remove('MouseCheck')
+ 
+    def __handleWin(self):
+        global LevelNumber
+        self.unload()
+        self.loadWin()
+        LevelNumber += 1
+        base.taskMgr.remove('MouseCheck')
+ 
+    def loadWin(self):
+        model = loader.loadModel('phase_5.5/models/gui/package_delivery_panel.bam')
+        model1 = loader.loadModel('phase_3.5/models/gui/matching_game_gui.bam')
+ 
+        self.model = model
+        self.model1 = model1
+ 
+        background = model.find('**/bg')
+        itemBoard = model.find('**/item_board')
+ 
+        frameGui = loader.loadModel('phase_3/models/gui/dialog_box_gui.bam')
+        self.victoryFrame = DirectFrame(scale=1.1, relief=None, image=frameGui, image_scale=(1.75, 1, 0.75), image_color=(1,1,1,1), frameSize=(-0.5,
+         0.5,
+         -0.45,
+         -0.05))
+ 
+        frameGui2 = loader.loadModel('phase_3.5/models/gui/jar_gui.bam')
+        self.jar = DirectFrame(parent=self.victoryFrame, scale=(0.65,1.4,1.3), relief=None, image=frameGui2, image_scale=(1.75, 1, 0.75), image_color=(1,1,1,1), pos=(-0.5,-0.15,-0.075), frameSize=(-0.5,
+         0.45,
+         -0.45,
+         -0.05))
+ 
+        gui2 = loader.loadModel('phase_3/models/gui/quit_button.bam')
+        self.font = loader.loadFont("phase_3/models/fonts/MickeyFont.bam")
+ 
+        if LevelNumber == 5:
+            congratsMessage = TTLocalizer.GardenDropWinGame
         else:
-            test.velX = 0
-            test.velZ = 0
-            move.velX = 0
-            move.velZ = 0
-            test.collide()
-            move.collide()
-            self.stickInGrid(move)
-            self.stickInGrid(test)
-        if queHit:
-            forceM = 0.1
-            distX = que.getX() - hit.getX()
-            distZ = que.getZ() - hit.getZ()
-
-    def push(self, move, test):
-        queHit = 0
-        if move.isQue:
-            que = move
-            hit = test
-            queHit = 1
-        elif test.isQue:
-            que = test
-            hit = move
-            queHit = 1
-        if queHit:
-            forceM = 0.1
-            dist = self.testDistance(move.nodeObj, test.nodeObj)
-            if abs(dist) < self.queExtent * que.size and abs(dist) > 0:
-                scaleSize = self.queExtent * que.size * 0.5
-                distFromPara = abs(abs(dist) - scaleSize)
-                force = (scaleSize - distFromPara) / scaleSize * (dist / abs(dist))
-                angle = self.angleTwoSprites(que, hit)
-                if angle < 0:
-                    angle = angle + 2 * pi
-                if angle > pi * 2.0:
-                    angle = angle - 2 * pi
-                newAngle = pi * 1.0
-                if angle > pi * 1.5 or angle < pi * 0.5:
-                    newAngle = pi * 0.0
-                hit.addForce(forceM * force, newAngle)
+            congratsMessage = TTLocalizer.GardenDropProgressLevels
+            self.nextButton = DirectButton(parent=self.victoryFrame, relief=None, image=(gui2.find('**/QuitBtn_UP'), gui2.find('**/QuitBtn_DN'), gui2.find('**/QuitBtn_RLVR')), pos=(0, 1.0, -0.32), scale=0.9, text=TTLocalizer.lNext, text_font=self.font, text0_fg=(1, 1, 1, 1), text1_fg=(1, 1, 1, 1), text2_fg=(1, 1, 1, 1), text_scale=0.045, text_pos=(0, -0.01), command=self._GardenDropGame__handlePlay)
+ 
+        self.congratsText = DirectLabel(scale=1.1, relief=None, text_pos=(0, 0.2), text_wordwrap=16, text=TTLocalizer.GardenDropCongradulations, text_font=self.font, pos=(0.0, 0.0, 0.0), text_scale=0.1, text0_fg=(1, 1, 1, 1), parent=self.victoryFrame)
+ 
+        self.font2 = loader.loadFont("phase_3/models/fonts/Comedy.bam")
+        self.congratsText2 = DirectLabel(scale=1.1, relief=None, text_pos=(0.2, 0.025), text_wordwrap=10, text=congratsMessage, text_font=self.font2, pos=(0.0, 0.0, 0.0), text_scale=0.085, text0_fg=(0, 0, 0, 1), parent=self.victoryFrame)
+ 
+        self.quitButton = DirectButton(parent=self.victoryFrame, relief=None, image=(gui2.find('**/QuitBtn_UP'), gui2.find('**/QuitBtn_DN'), gui2.find('**/QuitBtn_RLVR')), pos=(0.5, 1.0, -0.32), scale=0.9, text=TTLocalizer.GardenDropExit, text_font=self.font, text0_fg=(1, 1, 1, 1), text1_fg=(1, 1, 1, 1), text2_fg=(1, 1, 1, 1), text_scale=0.045, text_pos=(0, -0.01), command=self.__handleExitWin)
+ 
+        return True
+ 
+    def unloadWin(self):
+        self.victoryFrame.removeNode()
+        del self.victoryFrame
+ 
+        if GardenGameGlobals.acceptErrorDialog:
+            GardenGameGlobals.acceptErrorDialog.cleanup()
+            GardenGameGlobals.acceptErrorDialog = None
+ 
+        self.playGardenDrop()
+        base.taskMgr.remove('gameTask')
+ 
+        return True
+ 
+    def __handleExitWin(self):
+        global LevelNumber
+        self._GardenDropGame__acceptExitWin()
+        LevelNumber = 1
+ 
+    def __acceptExitWin(self, buttonValue = None):
+        if hasattr(base, 'localAvatar'):
+            base.cr.playGame.getPlace().fsm.forceTransition('walk')
+ 
+        if hasattr(self, 'victoryFrame'):
+            self.unloadWin()
+            messenger.send(GardenGameGlobals.doneEvent)
+ 
+    def endGame(self):
+        if hasattr(base, 'localAvatar'):
+            base.localAvatar.gardenGameButton.removeNode()
\ No newline at end of file
diff --git a/toontown/estate/GardenGameGlobals.py b/toontown/estate/GardenGameGlobals.py
new file mode 100644
index 00000000..e746bc98
--- /dev/null
+++ b/toontown/estate/GardenGameGlobals.py
@@ -0,0 +1,36 @@
+acceptErrorDialog = 0
+doneEvent = 'game Done'
+colorRed = (1, 0, 0, 1)
+colorBlue = (0, 0, 1, 1)
+colorGreen = (0, 1, 0, 1)
+colorGhostRed = (1, 0, 0, 0.5)
+colorGhostGreen = (0, 1, 0, 0.5)
+colorWhite = (1, 1, 1, 1)
+colorBlack = (0.5, 0.5, 0.5, 1.0)
+colorShadow = (0, 0, 0, 0.5)
+running = 0
+maxX = 0.46999999999999997
+minX = -0.46999999999999997
+maxZ = 0.75000000000000002
+minZ = -0.00000000000000001
+newBallX = 0.0
+newBallZ = 0.69999999999999998
+rangeX = (maxX - minX)
+rangeZ = (maxZ - minZ)
+size = 0.085000000000000006
+sizeZ = (size * 0.80000000000000004)
+gX = int((rangeX / size))
+gZ = int((rangeZ / sizeZ))
+maxX = (minX + (gX * size))
+maxZ = (minZ + (gZ * sizeZ))
+controlOffsetX = 0.0
+controlOffsetZ = 0.0
+queExtent = 3
+gridDimX = gX
+gridDimZ = gZ
+gridBrick = False
+newBallTime = 1.0
+newBallCountUp = 0.0
+cogX = 0
+cogZ = 0
+controlSprite = None
\ No newline at end of file
diff --git a/toontown/toonbase/TTLocalizerEnglish.py b/toontown/toonbase/TTLocalizerEnglish.py
index d1ec2373..3288964d 100644
--- a/toontown/toonbase/TTLocalizerEnglish.py
+++ b/toontown/toonbase/TTLocalizerEnglish.py
@@ -9609,6 +9609,16 @@ CheckersObserver = 'You are Observing'
 RegularCheckers = 'Checkers.'
 RegularCheckersGameOf = ' has just won a game of '
 RegularCheckersYouWon = 'You just won a game of Checkers!'
+GardenDropTitle = 'Garden Drop'
+GardenDropExitGame = 'Exit Mini Game'
+GardenDropHelpTitle = 'Instructions:'
+GardenDropInstructions = "Match the ghost balls with the normal balls! But beware of the cog ball, it will try to block you off!"
+GardenDropBackToGame = "Back to Game"
+GardenDropButtonTitle = 'Garden\nDrop'
+GardenDropCongradulations = 'Super Congratulations!!'
+GardenDropProgressLevels = "Click 'Next' to go to the next level!"
+GardenDropWinGame = 'You have won the Garden Drop Game!'
+GardenDropExit = 'Exit'
 MailNotifyNewItems = "You've got mail!"
 MailNewMailButton = 'Mail'
 MailSimpleMail = 'Note'
