local r=game:GetService("\087\111\114\107\115\112\097\099\101")local P=game:GetService("\080\108\097\121\101\114\115")local v=game:GetService("\082\101\112\108\105\099\097\116\101\100\083\116\111\114\097\103\101")local f=game:GetService("\084\119\101\101\110\083\101\114\118\105\099\101")local Q=require((v:WaitForChild("\080\114\111\106\101\099\116")):WaitForChild("\082\101\112\108\105\099\097\116\101\100\083\116\111\114\097\103\101"))local b=Q:GetResource("\071\101\110\101\114\097\116\105\111\110\046\067\101\108\108\046\066\097\115\101\071\114\097\115\115\067\101\108\108")local A=Q:GetResource("\071\101\110\101\114\097\116\105\111\110\046\072\111\117\115\101\115")local j=Q:GetResource("\071\101\110\101\114\097\116\105\111\110\046\072\111\117\115\101\115\046\080\111\108\101\073\116\101\109\115")local Y=Q:GetResource("\071\101\110\101\114\097\116\105\111\110\046\072\111\117\115\101\115\046\083\116\097\105\114\073\116\101\109\115")local u=Q:GetResource("\071\097\109\101\083\116\097\116\101\046\072\111\117\115\101\083\116\097\116\101")local R=Q:GetResource("\071\097\109\101\082\101\112\108\105\099\097\116\105\111\110\046\072\111\117\115\101\082\101\112\108\105\099\097\116\105\111\110\046\083\116\097\114\116\072\111\117\115\101")local N=b:Extend()N:SetClassName("\072\111\117\115\101\067\101\108\108")function N.__new(M,r,v,f,Q,b,N)M:InitializeSuper(r,v,f,Q,b,N)M.CurrentState="\065\067\084\073\086\069"local B=A.Colors.WallColors[M.RandomNumberGenerator:NextInteger(1,#A.Colors.WallColors)]local U=A.Colors.RoofColors[M.RandomNumberGenerator:NextInteger(1,#A.Colors.RoofColors)]local o=A.HouseAssemblies[M.RandomNumberGenerator:NextInteger(1,#A.HouseAssemblies)]local S={}for r,P in pairs(o.Components)do local v=P.Options[M.RandomNumberGenerator:NextInteger(1,#P.Options)]if v~=nil then S[P.Group]=o.HouseName..("\046"..(P.Group..("\046"..v)))end end local e=CFrame.new(r*100,0,v*100)if b=="\082\111\097\100"then e=e*CFrame.Angles(0,math.pi*.5,0)elseif N=="\082\111\097\100"then e=e*CFrame.Angles(0,math.pi*1.5,0)elseif f=="\082\111\097\100"then e=e*CFrame.Angles(0,math.pi,0)end local k=Instance.new("\077\111\100\101\108")k.Name="\072\111\117\115\101"k.Parent=M.CellModel M.HouseModel=k local D=M:AddModel(S.BaseLevels,e)M:AddModel(S.Fronts,e)local H if S.SecondLevels then H=M:AddModel(S.SecondLevels,(D:WaitForChild("\084\111\112\067\101\110\116\101\114")).CFrame)end M:AddModel(S.Roofs,H and(H:WaitForChild("\084\111\112\067\101\110\116\101\114")).CFrame or(D:WaitForChild("\084\111\112\067\101\110\116\101\114")).CFrame)if S.Additions then M:AddModel(S.Additions,e)end local s=k:WaitForChild("\082\111\111\102")for r,P in pairs((k:WaitForChild("\067\111\108\111\114\101\100\087\097\108\108\115")):GetChildren())do if P:IsA("\066\097\115\101\080\097\114\116")then P.BrickColor=B end end for r,P in pairs(s:GetChildren())do if P:IsA("\066\097\115\101\080\097\114\116")then P.BrickColor=U end end for r,P in pairs(s:GetChildren())do for r=1,(P.Size.X*P.Size.Z)/200,1 do local v=M.RandomNumberGenerator:NextNumber(8,12)if P.Size.X>v and P.Size.Z>v then local r=Instance.new("\080\097\114\116")r.Transparency=1 r.Size=Vector3.new(v,.2,v)r.CFrame=(P.CFrame*CFrame.new(M.RandomNumberGenerator:NextNumber(-(P.Size.X-v)/2,(P.Size.X-v)/2),P.Size.Y/2-.075,M.RandomNumberGenerator:NextNumber(-(P.Size.Z-v)/2,(P.Size.Z-v)/2)))*CFrame.Angles(0,M.RandomNumberGenerator:NextNumber(-math.pi,math.pi),0)r.Anchored=true r.CanCollide=false r.TopSurface="\083\109\111\111\116\104"r.BottomSurface="\083\109\111\111\116\104"r.Parent=k local f=Instance.new("\068\101\099\097\108")f.Texture="\114\098\120\097\115\115\101\116\105\100\058\047\047\049\051\052\054\054\048\053\057\048"f.Face="\084\111\112"f.Parent=r end end end for r=1,M.RandomNumberGenerator:NextInteger(1,3),1 do local P=e*CFrame.new(0,0,-50+M.RandomNumberGenerator:NextNumber(2,o.LawnDepth))if M.RandomNumberGenerator:NextNumber()>=.5 then P=P*CFrame.new(M.RandomNumberGenerator:NextNumber(-45,-6),0,0)else P=P*CFrame.new(M.RandomNumberGenerator:NextNumber(6,45),0,0)end P=P*CFrame.Angles(0,M.RandomNumberGenerator:NextNumber(math.rad(-10),math.rad(10)),0)local v=(j:GetChildren())[M.RandomNumberGenerator:NextInteger(1,#j:GetChildren())]:Clone()v.PrimaryPart=v:WaitForChild("\080\111\108\101")v:SetPrimaryPartCFrame((P*CFrame.new(0,v.PrimaryPart.Size.X/2,0))*CFrame.Angles(0,0,math.pi/2))v.Parent=k end for r,P in pairs({(k:WaitForChild("\083\116\097\105\114\115")):FindFirstChild("\076\101\102\116"),(k:WaitForChild("\083\116\097\105\114\115")):FindFirstChild("\082\105\103\104\116")})do if P then for r=1,M.RandomNumberGenerator:NextInteger(0,1),1 do local v=(Y:GetChildren())[M.RandomNumberGenerator:NextInteger(1,#Y:GetChildren())]:Clone()v.CFrame=(P.CFrame*CFrame.new(M.RandomNumberGenerator:NextNumber(-0.3,.3),P.Size.Y/2+v.Size.Y/2,M.RandomNumberGenerator:NextNumber(-0.3,.3)))*CFrame.Angles(0,M.RandomNumberGenerator:NextNumber(math.rad(-20),math.rad(20)),0)v.Parent=k end end end local i=(k:WaitForChild("\068\111\111\114")):WaitForChild("\077\097\105\110\068\111\111\114")M.MainDoorPart=i local T=Instance.new("\083\111\117\110\100")T.SoundId="\104\116\116\112\058\047\047\119\119\119\046\114\111\098\108\111\120\046\099\111\109\047\097\115\115\101\116\047\063\105\100\061\049\051\048\049\054\056\055\055\049"T.Parent=i M.DoorSound=T local x=Instance.new("\067\108\105\099\107\068\101\116\101\099\116\111\114")x.MaxActivationDistance=20 x.Parent=i M.DoorClickDetector=x x.MouseClick:Connect(function()if M.CurrentState=="\065\067\084\073\086\069"then R:FireServer(r,v)end end)i.Touched:Connect(function(f)if M.CurrentState=="\065\067\084\073\086\069"then local Q=P.LocalPlayer.Character if Q and f:IsDescendantOf(Q)then R:FireServer(r,v)end end end)M.Events={}local G=tostring(r)..("\095"..tostring(v))table.insert(M.Events,u.ChildAdded:Connect(function(r)if r.Name==G then table.insert(M.Events,r.Changed:Connect(function()M:FetchState()end))M:FetchState()end end))table.insert(M.Events,u.ChildRemoved:Connect(function(r)if r.Name==G then M:FetchState()end end))M:FetchState()end function N.AddModel(v,r,P)local f=(Q:GetResource("\071\101\110\101\114\097\116\105\111\110\046\072\111\117\115\101\115\046"..r)):Clone()f.PrimaryPart=f:WaitForChild("\067\101\110\116\101\114")f:SetPrimaryPartCFrame(P)for r,P in pairs(f:GetChildren())do if P.Name~="\067\101\110\116\101\114"and P.Name~="\084\111\112\067\101\110\116\101\114"then local r=v.HouseModel:FindFirstChild(P.Name)if r and P:IsA("\077\111\100\101\108")then for P,v in pairs(P:GetChildren())do v.Parent=r end else P.Parent=v.HouseModel end end end return f end function N.UpdateState(r)if r.StartingAnimationModel then r.StartingAnimationModel:Destroy()r.StartingAnimationModel=nil end if r.CurrentState=="\065\067\084\073\086\069"then for r,P in pairs((r.HouseModel:WaitForChild("\087\105\110\100\111\119\115")):GetChildren())do local v=P:WaitForChild("\067\117\114\116\097\105\110")local f=v:WaitForChild("\076\105\103\104\116")v.BrickColor=BrickColor.new("\080\097\115\116\101\108 \121\101\108\108\111\119")v.Material="\078\101\111\110"f.Enabled=true end r.DoorClickDetector.MaxActivationDistance=20 elseif r.CurrentState=="\073\078\065\067\084\073\086\069"then for r,P in pairs((r.HouseModel:WaitForChild("\087\105\110\100\111\119\115")):GetChildren())do local v=P:WaitForChild("\067\117\114\116\097\105\110")local f=v:WaitForChild("\076\105\103\104\116")v.BrickColor=BrickColor.new("\066\108\097\099\107")v.Material="\083\109\111\111\116\104\080\108\097\115\116\105\099"f.Enabled=false end r.DoorClickDetector.MaxActivationDistance=0 elseif r.CurrentState=="\083\084\065\082\084\073\078\071"then for r,P in pairs((r.HouseModel:WaitForChild("\087\105\110\100\111\119\115")):GetChildren())do local v=P:WaitForChild("\067\117\114\116\097\105\110")local f=v:WaitForChild("\076\105\103\104\116")v.BrickColor=BrickColor.new("\080\097\115\116\101\108 \121\101\108\108\111\119")v.Material="\078\101\111\110"f.Enabled=true end r.DoorClickDetector.MaxActivationDistance=0;(coroutine.wrap(function()local P=Instance.new("\077\111\100\101\108")P.Name="\083\116\097\114\116\105\110\103\065\110\105\109\097\116\105\111\110\077\111\100\101\108"P.Parent=r.CellModel r.StartingAnimationModel=P local v={}for f=0,1.5,.5 do local Q=Instance.new("\080\097\114\116")Q.Transparency=1 Q.CFrame=(CFrame.new(r.X*100,2,r.Y*100)*CFrame.Angles(0,math.pi*f,0))*CFrame.new(0,0,50)Q.Size=Vector3.new(100,4,.2)Q.Anchored=true Q.CanCollide=false Q.Parent=P local b=Instance.new("\083\112\101\099\105\097\108\077\101\115\104")b.MeshType=Enum.MeshType.Brick b.Scale=Vector3.new(1,1,0)b.Parent=Q local A=Instance.new("\068\101\099\097\108")A.Color3=Color3.new(0,.66666666666667,1.0)A.Transparency=1 A.Texture="\104\116\116\112\058\047\047\119\119\119\046\114\111\098\108\111\120\046\099\111\109\047\097\115\115\101\116\047\063\105\100\061\049\053\052\055\052\049\056\055\056"A.Face="\070\114\111\110\116"A.Parent=Q table.insert(v,A)local j=Instance.new("\068\101\099\097\108")j.Color3=Color3.new(0,.66666666666667,1.0)j.Transparency=1 j.Texture="\104\116\116\112\058\047\047\119\119\119\046\114\111\098\108\111\120\046\099\111\109\047\097\115\115\101\116\047\063\105\100\061\049\053\052\055\052\049\056\055\056"j.Face="\066\097\099\107"j.Parent=Q table.insert(v,j)end local Q=Instance.new("\080\097\114\116")Q.Transparency=1 Q.Size=Vector3.new(10,5,1)Q.CFrame=(r.MainDoorPart.CFrame*CFrame.Angles(0,0,math.pi/2))*CFrame.new(0,4,-3)Q.Anchored=true Q.CanCollide=false Q.Parent=P local b=Instance.new("\068\101\099\097\108")b.Texture="\104\116\116\112\058\047\047\119\119\119\046\114\111\098\108\111\120\046\099\111\109\047\097\115\115\101\116\047\063\105\100\061\049\051\048\049\055\048\057\049\053"b.Transparency=1 b.Parent=Q local A=Instance.new("\080\097\114\116")A.Transparency=1 A.Size=Vector3.new(10,5,1)A.CFrame=(r.MainDoorPart.CFrame*CFrame.Angles(0,0,math.pi/2))*CFrame.new(0,4,-3)A.Anchored=true A.CanCollide=false A.Parent=P local j=Instance.new("\068\101\099\097\108")j.Texture="\104\116\116\112\058\047\047\119\119\119\046\114\111\098\108\111\120\046\099\111\109\047\097\115\115\101\116\047\063\105\100\061\049\051\048\049\054\057\052\057\052"j.Transparency=1 j.Parent=A for r,P in pairs(v)do(f:Create(P,TweenInfo.new(3),{Transparency=0})):Play()end r.DoorSound:Play()b.Transparency=0;(f:Create(Q,TweenInfo.new(5.5,Enum.EasingStyle.Quad,Enum.EasingDirection.Out),{CFrame=(r.MainDoorPart.CFrame*CFrame.Angles(0,0,math.pi/2))*CFrame.new(math.random(-1,1),13,-4)})):Play()wait(.15)j.Transparency=0;(f:Create(A,TweenInfo.new(5.5,Enum.EasingStyle.Quad,Enum.EasingDirection.Out),{CFrame=(r.MainDoorPart.CFrame*CFrame.Angles(0,0,math.pi/2))*CFrame.new(math.random(-1,1),8,-4)})):Play()wait(2.85);(f:Create(b,TweenInfo.new(1.5),{Transparency=1})):Play()wait(.15);(f:Create(j,TweenInfo.new(1.5),{Transparency=1})):Play()end))()end end function N.FetchState(r)local P=u:FindFirstChild(tostring(r.X)..("\095"..tostring(r.Y)))local v=P and P.Value or"\065\067\084\073\086\069"if v~=r.CurrentState then r.CurrentState=v r:UpdateState()end end function N.Destroy(r)r.super:Destroy()r.HouseModel:Destroy()for r,P in pairs(r.Events)do P:Disconnect()end r.Events={}end return N
--[[
TheNexusAvenger

Generates a house cell.
--]]

local Workspace = game:GetService("Workspace")
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local TweenService = game:GetService("TweenService")

local ReplicatedStorageProject = require(ReplicatedStorage:WaitForChild("Project"):WaitForChild("ReplicatedStorage"))

local BaseGrassCell = ReplicatedStorageProject:GetResource("Generation.Cell.BaseGrassCell")
local HouseData = ReplicatedStorageProject:GetResource("Generation.Houses")
local PoleItems = ReplicatedStorageProject:GetResource("Generation.Houses.PoleItems")
local StairItems = ReplicatedStorageProject:GetResource("Generation.Houses.StairItems")
local HouseState = ReplicatedStorageProject:GetResource("GameState.HouseState")
local StartHouse = ReplicatedStorageProject:GetResource("GameReplication.HouseReplication.StartHouse")

local HouseCell = BaseGrassCell:Extend()
HouseCell:SetClassName("HouseCell")



--[[
Creates a cell.
--]]
function HouseCell:__new(X,Y,TopCellType,BottomCellType,LeftCellType,RightCellType)
    self:InitializeSuper(X,Y,TopCellType,BottomCellType,LeftCellType,RightCellType)
    self.CurrentState = "ACTIVE"

    --Get the house data.
    local WallColor = HouseData.Colors.WallColors[self.RandomNumberGenerator:NextInteger(1,#HouseData.Colors.WallColors)]
    local RoofColor = HouseData.Colors.RoofColors[self.RandomNumberGenerator:NextInteger(1,#HouseData.Colors.RoofColors)]
    local AssemblyData = HouseData.HouseAssemblies[self.RandomNumberGenerator:NextInteger(1,#HouseData.HouseAssemblies)]
    local Components = {}
    for _,Component in pairs(AssemblyData.Components) do
        local ChosenComponent = Component.Options[self.RandomNumberGenerator:NextInteger(1,#Component.Options)]
        if ChosenComponent ~= nil then
            Components[Component.Group] = AssemblyData.HouseName.."."..Component.Group.."."..ChosenComponent
        end
    end

    --Determine the center.
    local HouseCenter = CFrame.new(X * 100,0,Y * 100)
    if LeftCellType == "Road" then
        HouseCenter = HouseCenter * CFrame.Angles(0,math.pi * (1/2),0)
    elseif RightCellType == "Road" then
        HouseCenter = HouseCenter * CFrame.Angles(0,math.pi * (3/2),0)
    elseif TopCellType == "Road" then
        HouseCenter = HouseCenter * CFrame.Angles(0,math.pi,0)
    end

    --Assemble the house model.
    local HouseModel = Instance.new("Model")
    HouseModel.Name = "House"
    HouseModel.Parent = self.CellModel
    self.HouseModel = HouseModel

    local BaseLevel = self:AddModel(Components["BaseLevels"],HouseCenter)
    self:AddModel(Components["Fronts"],HouseCenter)
    local SecondLevel
    if Components["SecondLevels"] then
        SecondLevel = self:AddModel(Components["SecondLevels"],BaseLevel:WaitForChild("TopCenter").CFrame)
    end
    self:AddModel(Components["Roofs"],SecondLevel and SecondLevel:WaitForChild("TopCenter").CFrame or BaseLevel:WaitForChild("TopCenter").CFrame)
    if Components["Additions"] then
        self:AddModel(Components["Additions"],HouseCenter)
    end

    --Set the colors.
    local Roof = HouseModel:WaitForChild("Roof")
    for _,Part in pairs(HouseModel:WaitForChild("ColoredWalls"):GetChildren()) do
        if Part:IsA("BasePart") then
            Part.BrickColor = WallColor
        end
    end
    for _,Part in pairs(Roof:GetChildren()) do
        if Part:IsA("BasePart") then
            Part.BrickColor = RoofColor
        end
    end

    --Add leaves to the roof.
    for _,RoofPart in pairs(Roof:GetChildren()) do
        for _ = 1,(RoofPart.Size.X * RoofPart.Size.Z) / 200 do
            local Size = self.RandomNumberGenerator:NextNumber(8,12)
            if RoofPart.Size.X > Size and RoofPart.Size.Z > Size then
                local LeavesPart = Instance.new("Part")
                LeavesPart.Transparency = 1
                LeavesPart.Size = Vector3.new(Size,0.2,Size)
                LeavesPart.CFrame = RoofPart.CFrame * CFrame.new(self.RandomNumberGenerator:NextNumber(-(RoofPart.Size.X - Size)/2,(RoofPart.Size.X - Size)/2),RoofPart.Size.Y/2 - 0.075,self.RandomNumberGenerator:NextNumber(-(RoofPart.Size.Z - Size)/2,(RoofPart.Size.Z - Size)/2)) * CFrame.Angles(0,self.RandomNumberGenerator:NextNumber(-math.pi,math.pi),0)
                LeavesPart.Anchored = true
                LeavesPart.CanCollide = false
                LeavesPart.TopSurface = "Smooth"
                LeavesPart.BottomSurface = "Smooth"
                LeavesPart.Parent = HouseModel
                
                local LeavesDecal = Instance.new("Decal")
                LeavesDecal.Texture = "rbxassetid://134660590"
                LeavesDecal.Face = "Top"
                LeavesDecal.Parent = LeavesPart
            end
        end
    end

    --Add the lawn decorations.
    for i = 1,self.RandomNumberGenerator:NextInteger(1,3) do
        --Determine the center.
        local PoleCenter = HouseCenter * CFrame.new(0,0,-50 + self.RandomNumberGenerator:NextNumber(2,AssemblyData.LawnDepth))
        if self.RandomNumberGenerator:NextNumber() >= 0.5 then
            PoleCenter = PoleCenter * CFrame.new(self.RandomNumberGenerator:NextNumber(-45,-6),0,0)
        else
            PoleCenter = PoleCenter * CFrame.new(self.RandomNumberGenerator:NextNumber(6,45),0,0)
        end
        PoleCenter = PoleCenter * CFrame.Angles(0,self.RandomNumberGenerator:NextNumber(math.rad(-10),math.rad(10)),0)

        --Add a random pole model.
        local PoleModel = PoleItems:GetChildren()[self.RandomNumberGenerator:NextInteger(1,#PoleItems:GetChildren())]:Clone()
        PoleModel.PrimaryPart = PoleModel:WaitForChild("Pole")
        PoleModel:SetPrimaryPartCFrame(PoleCenter * CFrame.new(0,PoleModel.PrimaryPart.Size.X/2,0) * CFrame.Angles(0,0,math.pi/2))
        PoleModel.Parent = HouseModel
    end

    --Add the stair decorations.
    for _,StairPart in pairs({HouseModel:WaitForChild("Stairs"):FindFirstChild("Left"),HouseModel:WaitForChild("Stairs"):FindFirstChild("Right")}) do
        if StairPart then
            for i = 1,self.RandomNumberGenerator:NextInteger(0,1) do
                local Part = StairItems:GetChildren()[self.RandomNumberGenerator:NextInteger(1,#StairItems:GetChildren())]:Clone()
                Part.CFrame = StairPart.CFrame * CFrame.new(self.RandomNumberGenerator:NextNumber(-0.3,0.3),(StairPart.Size.Y/2) + (Part.Size.Y/2),self.RandomNumberGenerator:NextNumber(-0.3,0.3)) * CFrame.Angles(0,self.RandomNumberGenerator:NextNumber(math.rad(-20),math.rad(20)),0)
                Part.Parent = HouseModel
            end
        end
    end
    
    --Set up the door.
    local MainDoorPart = HouseModel:WaitForChild("Door"):WaitForChild("MainDoor")
    self.MainDoorPart = MainDoorPart

    local DoorSound = Instance.new("Sound")
    DoorSound.SoundId = "http://www.roblox.com/asset/?id=130168771"
    DoorSound.Parent = MainDoorPart
    self.DoorSound = DoorSound

    local DoorClickDetector = Instance.new("ClickDetector")
    DoorClickDetector.MaxActivationDistance = 20
    DoorClickDetector.Parent = MainDoorPart
    self.DoorClickDetector = DoorClickDetector

    DoorClickDetector.MouseClick:Connect(function()
        if self.CurrentState == "ACTIVE" then
            StartHouse:FireServer(X,Y)
        end
    end)
    MainDoorPart.Touched:Connect(function(TouchPart)
        if self.CurrentState == "ACTIVE" then
            local Character = Players.LocalPlayer.Character
            if Character and TouchPart:IsDescendantOf(Character) then
                StartHouse:FireServer(X,Y)
            end
        end
    end)

    --Connect the state events.
    self.Events = {}
    local CellId = tostring(X).."_"..tostring(Y)
    table.insert(self.Events,HouseState.ChildAdded:Connect(function(Child)
        if Child.Name == CellId then
            table.insert(self.Events,Child.Changed:Connect(function()
                self:FetchState()
            end))
            self:FetchState()
        end
    end))
    table.insert(self.Events,HouseState.ChildRemoved:Connect(function(Child)
        if Child.Name == CellId then
            self:FetchState()
        end
    end))
    self:FetchState()
end

--[[
Adds a model to the house.
--]]
function HouseCell:AddModel(ModelPath,Center)
    --Get the model.
    local Model = ReplicatedStorageProject:GetResource("Generation.Houses."..ModelPath):Clone()
    Model.PrimaryPart = Model:WaitForChild("Center")
    Model:SetPrimaryPartCFrame(Center)

    --Merge the model.
    for _,Child in pairs(Model:GetChildren()) do
        if Child.Name ~= "Center" and Child.Name ~= "TopCenter" then
            local Parent = self.HouseModel:FindFirstChild(Child.Name)
            if Parent and Child:IsA("Model") then
                for _,SubChild in pairs(Child:GetChildren()) do
                    SubChild.Parent = Parent
                end
            else
                Child.Parent = self.HouseModel
            end
        end
    end

    --Return the model.
    return Model
end

--[[
Updates the state of the house if it changed.
--]]
function HouseCell:UpdateState()
    --Clear the starting animation.
    if self.StartingAnimationModel then
        self.StartingAnimationModel:Destroy()
        self.StartingAnimationModel = nil
    end

    if self.CurrentState == "ACTIVE" then
        --Turn on the lights and allow clicking.
        for _,WindowModel in pairs(self.HouseModel:WaitForChild("Windows"):GetChildren()) do
            local Curtain = WindowModel:WaitForChild("Curtain")
            local Light = Curtain:WaitForChild("Light")
            Curtain.BrickColor = BrickColor.new("Pastel yellow")
            Curtain.Material = "Neon"
            Light.Enabled = true
        end
        self.DoorClickDetector.MaxActivationDistance = 20
    elseif self.CurrentState == "INACTIVE" then
        --Turn off the lights and disable clicking.
        for _,WindowModel in pairs(self.HouseModel:WaitForChild("Windows"):GetChildren()) do
            local Curtain = WindowModel:WaitForChild("Curtain")
            local Light = Curtain:WaitForChild("Light")
            Curtain.BrickColor = BrickColor.new("Black")
            Curtain.Material = "SmoothPlastic"
            Light.Enabled = false
        end
        self.DoorClickDetector.MaxActivationDistance = 0
    elseif self.CurrentState == "STARTING" then
        --Turn on the lights and disable clicking.
        for _,WindowModel in pairs(self.HouseModel:WaitForChild("Windows"):GetChildren()) do
            local Curtain = WindowModel:WaitForChild("Curtain")
            local Light = Curtain:WaitForChild("Light")
            Curtain.BrickColor = BrickColor.new("Pastel yellow")
            Curtain.Material = "Neon"
            Light.Enabled = true
        end
        self.DoorClickDetector.MaxActivationDistance = 0

        --Run the animation.
        coroutine.wrap(function()
            --Create the container and walls.
            local StartingAnimationModel = Instance.new("Model")
            StartingAnimationModel.Name = "StartingAnimationModel"
            StartingAnimationModel.Parent = self.CellModel
            self.StartingAnimationModel = StartingAnimationModel

            local Gradients = {}
            for i = 0,1.5,0.5 do
                local Border = Instance.new("Part")
                Border.Transparency = 1
                Border.CFrame = CFrame.new(self.X * 100,2,self.Y * 100) * CFrame.Angles(0,math.pi * i,0) * CFrame.new(0,0,50)
                Border.Size = Vector3.new(100,4,0.2)
                Border.Anchored = true
                Border.CanCollide = false
                Border.Parent = StartingAnimationModel

                local BorderMesh = Instance.new("SpecialMesh")
                BorderMesh.MeshType = Enum.MeshType.Brick
                BorderMesh.Scale = Vector3.new(1,1,0)
                BorderMesh.Parent = Border

                local FrontGradient = Instance.new("Decal")
                FrontGradient.Color3 = Color3.new(0,170/255,255/255)
                FrontGradient.Transparency = 1
                FrontGradient.Texture = "http://www.roblox.com/asset/?id=154741878"
                FrontGradient.Face = "Front"
                FrontGradient.Parent = Border
                table.insert(Gradients,FrontGradient)

                local BackGradient = Instance.new("Decal")
                BackGradient.Color3 = Color3.new(0,170/255,255/255)
                BackGradient.Transparency = 1
                BackGradient.Texture = "http://www.roblox.com/asset/?id=154741878"
                BackGradient.Face = "Back"
                BackGradient.Parent = Border
                table.insert(Gradients,BackGradient)
            end

            --Create the text.
            local DingPart = Instance.new("Part")
            DingPart.Transparency = 1
            DingPart.Size = Vector3.new(10,5,1)
            DingPart.CFrame = self.MainDoorPart.CFrame * CFrame.Angles(0,0,math.pi/2) * CFrame.new(0,4,-3)
            DingPart.Anchored = true
            DingPart.CanCollide = false
            DingPart.Parent = StartingAnimationModel

            local DingTexture = Instance.new("Decal")
            DingTexture.Texture = "http://www.roblox.com/asset/?id=130170915"
            DingTexture.Transparency = 1
            DingTexture.Parent = DingPart

            local DongPart = Instance.new("Part")
            DongPart.Transparency = 1
            DongPart.Size = Vector3.new(10,5,1)
            DongPart.CFrame = self.MainDoorPart.CFrame * CFrame.Angles(0,0,math.pi/2) * CFrame.new(0,4,-3)
            DongPart.Anchored = true
            DongPart.CanCollide = false
            DongPart.Parent = StartingAnimationModel

            local DongTexture = Instance.new("Decal")
            DongTexture.Texture = "http://www.roblox.com/asset/?id=130169494"
            DongTexture.Transparency = 1
            DongTexture.Parent = DongPart

            --Tween the gradients.
            for _,Gradient in pairs(Gradients) do
                TweenService:Create(Gradient,TweenInfo.new(3),{
                    Transparency = 0,
                }):Play()
            end

            --Play the sound.
            self.DoorSound:Play()

            --Display the text.
            DingTexture.Transparency = 0
            TweenService:Create(DingPart,TweenInfo.new(5.5,Enum.EasingStyle.Quad,Enum.EasingDirection.Out),{
                CFrame = self.MainDoorPart.CFrame * CFrame.Angles(0,0,math.pi/2) * CFrame.new(math.random(-1,1),13,-4),
            }):Play()
            wait(0.15)
            DongTexture.Transparency = 0
            TweenService:Create(DongPart,TweenInfo.new(5.5,Enum.EasingStyle.Quad,Enum.EasingDirection.Out),{
                CFrame = self.MainDoorPart.CFrame * CFrame.Angles(0,0,math.pi/2) * CFrame.new(math.random(-1,1),8,-4),
            }):Play()

            --Hide the text.
            wait(3 - 0.15)
            TweenService:Create(DingTexture,TweenInfo.new(1.5),{
                Transparency = 1,
            }):Play()
            wait(0.15)
            TweenService:Create(DongTexture,TweenInfo.new(1.5),{
                Transparency = 1,
            }):Play()
        end)()
    end
end

--[[
Fetches the replicated state of the house.
--]]
function HouseCell:FetchState()
    --Fetch the state.
    local StateObject = HouseState:FindFirstChild(tostring(self.X).."_"..tostring(self.Y))
    local NewState = (StateObject and StateObject.Value or "ACTIVE")

    --Update the state if it changed.
    if NewState ~= self.CurrentState then
        self.CurrentState = NewState
        self:UpdateState()
    end
end

--[[
Destroys the cell.
--]]
function HouseCell:Destroy()
    self.super:Destroy()
    self.HouseModel:Destroy()
    for _,Event in pairs(self.Events) do
        Event:Disconnect()
    end
    self.Events = {}
end



return HouseCell