Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Open raw and click Ctrl + A to select the whole script --
- local fpsBoost = fpsBoost or false
- if not getconnections then return end
- for i,v in next, getconnections(game.Players.LocalPlayer.Idled) do
- v:Disable()
- end
- local c = workspace:WaitForChild("__DEBRIS",10)
- c.ChildAdded:Connect(function(ch)
- task.wait()
- if fpsBoost then
- ch:Destroy()
- end
- end)
- local petNet = loadstring(game:HttpGet("https://rawscripts.net/raw/Pet-Simulator-X!-PSX-Safe-Networking-3732"))()
- local Food = petNet:getPath("Food")
- local Entity = petNet:getPath("Entity")
- local Customer = petNet:getPath("Customer")
- local Waiter = petNet:getPath("Waiter")
- local Appliance = petNet:getPath("Appliance")
- local Bakery = petNet:getPath("Bakery")
- local player = game:GetService("Players").LocalPlayer
- local _L = require(game:GetService("ReplicatedStorage"):WaitForChild("Framework",10):WaitForChild("Library",10));
- Food.RandomFoodChoice = function(customerOwnerUID, customerOwnerID, isRichCustomer, isPirateCustomer, isNearTree)
- local spoof = Food.new("45", customerOwnerUID, customerOwnerID, true, true)
- spoof.IsGold = true
- return spoof
- end
- function Entity:FadeTransparency(targetTransparency, finishedCallback)
- local processedCallback = false
- for _, child in ipairs(self.model:GetDescendants()) do
- if child.Name == "HumanoidRootPart" or child.Name == "CenterPart" or not child:IsA("BasePart") then
- continue
- end
- if child.Name == "Head" and self.ID == "25" then
- continue
- end
- _L.Functions.FastTween(
- child,
- {Transparency = targetTransparency},
- {0.0000002, "Quad", "Out"}
- ).Completed:Connect(function()
- -- race condition? god I hope not
- if finishedCallback and not processedCallback then
- processedCallback = true
- finishedCallback()
- end
- end)
- end
- end
- function Entity:WalkThroughWaypoints(voxelpoints, waypoints, startX, startZ)
- self:PlayLoadedAnimation("walking")
- if #voxelpoints == 0 then
- return
- end
- if not self:BelongsToMyBakery() and self.stateData.walkingThroughWaypoints then
- repeat wait() until self.isDeleted or not self.stateData.walkingThroughWaypoints
- if self.isDeleted then
- return
- end
- end
- if not self:BelongsToMyBakery() then
- self.stateData.walkingThroughWaypoints = true
- end
- -- replication fix?
- if not self:BelongsToMyBakery() then
- self.model.HumanoidRootPart.Anchored = false
- end
- for i, v in ipairs(waypoints) do
- self.model.HumanoidRootPart.CFrame = CFrame.new(v)
- --self.humanoid.MoveToFinished:Wait()
- local oldX, oldZ = self.xVoxel, self.zVoxel
- self.xVoxel = voxelpoints[i].x
- self.zVoxel = voxelpoints[i].y
- -- no need for position table updates if it's not my client.
- -- only the owner of the bakery does pathfinding calculations.
- -- if replication occurs, the host client sends the pathfinding
- -- data.... it is not recalculated
- if self:BelongsToMyBakery() then
- self:GetMyFloor():BroadcastNPCPositionChange(self, oldX, oldZ)
- end
- end
- if not self:BelongsToMyBakery() then
- self.stateData.walkingThroughWaypoints = false
- end
- self:StopLoadedAnimation("walking")
- self:PlayLoadedAnimation("idle")
- end
- function Customer:ChangeToWaitForOrderState()
- if self.state ~= "WalkingToSeat" then
- return
- end
- local seatLeaf = self:EntityTable()[self.stateData.seatUID]
- local tableLeaf = self:EntityTable()[self.stateData.tableUID]
- if seatLeaf.isDeleted or tableLeaf.isDeleted then
- self:ForcedToLeave()
- return
- end
- self:SetCustomerState("ThinkingAboutOrder")
- -- make the humanoid sit
- self:SitInSeat(seatLeaf).Completed:Connect(function()
- self.humanoid:SetStateEnabled(Enum.HumanoidStateType.Seated, true)
- -- change voxel position to match the seat
- self.xVoxel = seatLeaf.xVoxel
- self.zVoxel = seatLeaf.zVoxel
- coroutine.wrap(function()
- -- start reading the menu
- self:ReadMenu()
- if self.isDeleted or self.state ~= "ThinkingAboutOrder" then
- return
- end
- -- stop reading the menu
- self:StopReadingMenu()
- -- advance to next state
- self:SetCustomerState("DecidedOnOrder")
- -- only set my entire group to ready to order when everybody has decided on the order
- local myGroup = {self}
- for _, partner in ipairs(self.stateData.queueGroup) do
- if not partner.isDeleted then
- table.insert(myGroup, partner)
- end
- end
- local foundUndecidedMember = false
- for _, groupMember in ipairs(myGroup) do
- if groupMember.state ~= "DecidedOnOrder" then
- foundUndecidedMember = true
- break
- end
- end
- -- if the entire group is ready, then have them say it in sync
- if not foundUndecidedMember then
- for _, groupMember in ipairs(myGroup) do
- groupMember:ReadyToOrder()
- end
- end
- end)()
- end)
- end
- function Customer:ChangeToEatingState()
- coroutine.wrap(function()
- if self.state == "EatingFood" then
- return
- end
- -- first, check for silverware
- local myFloor = self:GetMyFloor()
- table.sort(myFloor.silverwareTrays, function(a, b)
- local aDist = math.abs(self.xVoxel - a.xVoxel) + math.abs(self.zVoxel - a.zVoxel)
- local bDist = math.abs(self.xVoxel - b.xVoxel) + math.abs(self.zVoxel - b.zVoxel)
- return aDist < bDist
- end)
- table.sort(myFloor.goldSilverwareTrays, function(a, b)
- local aDist = math.abs(self.xVoxel - a.xVoxel) + math.abs(self.zVoxel - a.zVoxel)
- local bDist = math.abs(self.xVoxel - b.xVoxel) + math.abs(self.zVoxel - b.zVoxel)
- return aDist < bDist
- end)
- self:SetCustomerState("EatingFood")
- -- if there's a path to me, delete it
- if self.stateData.pathToMe then
- _L.Variables.MyBakery:CleanupAnimatedPath()
- self.stateData.pathToMe = nil
- end
- local didSaladCheck = false
- local function checkForSaladBars(isWalkingFromSilverware, doWalkBackToSeat)
- didSaladCheck = true
- local didWalkToSalad = false
- -- walk to salad bar sometimes
- local isWalkingToSaladBar = false
- for _, saladBar in ipairs(myFloor.saladBars) do
- if math.random() < 0.20 then
- if not isWalkingFromSilverware then
- self:StandUp()
- end
- isWalkingToSaladBar = true
- didWalkToSalad = true
- local sx, sy, sz = self.xVoxel, self.yVoxel, self.zVoxel
- self:WalkToPoint(saladBar.xVoxel, saladBar.yVoxel, saladBar.zVoxel, function()
- if saladBar.isDeleted then
- isWalkingToSaladBar = false
- self:ForcedToLeave()
- return
- end
- self:FaceEntity(saladBar)
- _L.SFX.Play(5708685167, saladBar.model.PrimaryPart)
- _L.Network.Fire("AwardTipWithVerification", self.UID, saladBar.UID, self.stateData.foodOrder.ID, isWalkingFromSilverware)
- if doWalkBackToSeat then
- self:WalkToPoint(sx, sy, sz, function()
- isWalkingToSaladBar = false
- if self.stateData.mySeat.isDeleted then
- self:ForcedToLeave()
- return
- end
- self:SitInSeat(self.stateData.mySeat)
- end)
- else
- isWalkingToSaladBar = false
- end
- end)
- break
- end
- end
- if isWalkingToSaladBar then
- repeat wait() until not isWalkingToSaladBar
- end
- return didWalkToSalad
- end
- local didDessertCheck = false
- local function checkForDessertBars(isWalkingFromSilverware, doWalkBackToSeat)
- didDessertCheck = true
- local didWalkToDessert = false
- -- walk to salad bar sometimes
- local isWalkingToDessertBar = false
- for _, dessertBar in ipairs(myFloor.dessertBars) do
- if math.random() < 0.20 then
- if not isWalkingFromSilverware then
- self:StandUp()
- end
- isWalkingToDessertBar = true
- didWalkToDessert = true
- local sx, sy, sz = self.xVoxel, self.yVoxel, self.zVoxel
- self:WalkToPoint(dessertBar.xVoxel, dessertBar.yVoxel, dessertBar.zVoxel, function()
- if dessertBar.isDeleted then
- isWalkingToDessertBar = false
- self:ForcedToLeave()
- return
- end
- self:FaceEntity(dessertBar)
- _L.SFX.Play(5708685167, dessertBar.model.PrimaryPart)
- _L.Network.Fire("AwardTipWithVerification", self.UID, dessertBar.UID, self.stateData.foodOrder.ID, isWalkingFromSilverware)
- if doWalkBackToSeat then
- self:WalkToPoint(sx, sy, sz, function()
- isWalkingToDessertBar = false
- if self.stateData.mySeat.isDeleted then
- self:ForcedToLeave()
- return
- end
- self:SitInSeat(self.stateData.mySeat)
- end)
- else
- isWalkingToDessertBar = false
- end
- end)
- break
- end
- end
- if isWalkingToDessertBar then
- repeat wait() until not isWalkingToDessertBar
- end
- return didWalkToDessert
- end
- -- create food model for the customer
- if not self.stateData.foodOrder then
- self:ForcedToLeave()
- return
- end
- local myTable = self:EntityTable()[self.stateData.tableUID]
- local mySeat = self:EntityTable()[self.stateData.seatUID]
- if not myTable or not mySeat then
- _L.Print("CRITICAL: COULDN'T FIND CUSTOMERS TABLE WHEN EATING", true)
- return
- end
- local myFloor = myTable:GetMyFloor()
- local worldPos = myFloor:WorldPositionFromVoxel(mySeat:GetFacePosition())
- local tableRoot = myTable.model.PrimaryPart
- local tableTop = Vector3.new(worldPos.X, tableRoot.Position.Y + tableRoot.Size.Y/2, worldPos.Z)
- local foodOffset = (-1.1)*mySeat:GetFaceDirection() + Vector3.new(0, self.stateData.foodOrder.data.model.PrimaryPart.Size.Y/2, 0)
- local foodCF = CFrame.new(tableTop + foodOffset)
- self:CreateMyFoodModel(foodCF)
- local isWalkingToTray = false
- local wasWalkingToTray = false
- local trayUID = false
- local forkModel = nil
- local spoonModel = nil
- local welds = {}
- local function walkToTray(tray)
- isWalkingToTray = true
- wasWalkingToTray = true
- trayUID = tray.UID
- self:StandUp()
- local sx, sy, sz = self.xVoxel, self.yVoxel, self.zVoxel
- self:WalkToPoint(tray.xVoxel, tray.yVoxel, tray.zVoxel, function()
- if tray.isDeleted then
- isWalkingToTray = false
- self:ForcedToLeave()
- return
- end
- local sounds = {5601560377, 5601560515, 5601560641}
- _L.SFX.Play(sounds[math.random(#sounds)], tray.model.PrimaryPart)
- self:FaceEntity(tray)
- if not checkForSaladBars(true, false) then
- checkForDessertBars(true, false)
- end
- self:WalkToPoint(sx, sy, sz, function()
- isWalkingToTray = false
- if self.stateData.mySeat.isDeleted then
- self:ForcedToLeave()
- return
- end
- self:SitInSeat(self.stateData.mySeat)
- -- hold silverware
- local isGold = tray.ID == "25"
- local function weldToHand(part, hand)
- local weld = Instance.new("Weld", part)
- weld.Part0 = part
- weld.Part1 = hand
- weld.C0 = CFrame.Angles(-math.pi/2, 0, 0)
- table.insert(welds, weld)
- end
- if isGold then
- forkModel = game.ReplicatedStorage.Assets.Models["Luxury Fork"]:Clone()
- spoonModel = game.ReplicatedStorage.Assets.Models["Luxury Spoon"]:Clone()
- forkModel.Parent = self.model
- spoonModel.Parent = self.model
- weldToHand(forkModel, self.model.RightHand)
- weldToHand(spoonModel, self.model.LeftHand)
- else
- forkModel = game.ReplicatedStorage.Assets.Models["Default Fork"]:Clone()
- spoonModel = game.ReplicatedStorage.Assets.Models["Default Spoon"]:Clone()
- forkModel.Parent = self.model
- spoonModel.Parent = self.model
- weldToHand(forkModel, self.model.RightHand)
- weldToHand(spoonModel, self.model.LeftHand)
- end
- end)
- end)
- end
- if #myFloor.goldSilverwareTrays > 0 then
- walkToTray(myFloor.goldSilverwareTrays[1])
- elseif #myFloor.silverwareTrays > 0 then
- local goodRoll = false
- for i = 1, #myFloor.silverwareTrays do
- if true then
- goodRoll = true
- end
- end
- if goodRoll then
- walkToTray(myFloor.silverwareTrays[1])
- end
- end
- if isWalkingToTray then
- repeat wait() until not isWalkingToTray
- end
- if not didSaladCheck then
- if not checkForSaladBars(false, true) then
- checkForDessertBars(false, true)
- end
- end
- -- play eating animation
- self:PlayLoadedAnimation("eating")
- -- play served sound
- _L.SFX.Play(5205174537, self.model.PrimaryPart, nil, 0.60)
- -- play eating looped sound
- local pitch = 1 + (math.random() - 0.50)*0.10
- local eatSound = math.random() < 0.50 and 5029600710 or 5029600543
- self.stateData.loopedEatingSound = _L.SFX.Play(eatSound, self.model.PrimaryPart, pitch, 0.85, 35, nil, true)
- coroutine.wrap(function()
- -- eat timing is determined by the server. //no, it's not, -bluwud
- local forceLeaveTip = true
- if not self.isDeleted and self.state == "EatingFood" then
- if self.stateData.loopedEatingSound then
- self.stateData.loopedEatingSound = self.stateData.loopedEatingSound:Destroy()
- end
- self.stateData.foodOrder:ChangeToDirtyDish()
- self:StopLoadedAnimation("eating")
- self:ChangeToReadyToExitState(forceLeaveTip)
- if forkModel then
- forkModel:Destroy()
- spoonModel:Destroy()
- for _, weld in ipairs(welds) do
- weld:Destroy()
- end
- welds = {}
- end
- end
- end)()
- end)()
- end
- function Customer:ChangeToExitingState(wasForcedToLeave, forcedToLeaveTip)
- if self.isDeleted then
- return
- end
- self.leaving = true
- self:SetCustomerState("WalkingToExit")
- -- remove customer from table
- local myTable = self:EntityTable()[self.stateData.tableUID]
- if myTable and not myTable.isDeleted then
- myTable:RemoveCustomerFromTable(self)
- end
- local myFloor = self:GetMyFloor()
- coroutine.wrap(function()
- if wasForcedToLeave then
- self:TimedEmoji("MadEmoji", 2)
- else
- if math.random() < 0.30 or _L.Variables.MyBakery.isTutorial then
- self:TimedEmoji("HappyEmoji", 2.5)
- end
- end
- -- make humanoid stand
- self:StandUp()
- local function goToExitAndLeave()
- self:WalkToNewFloor(_L.Variables.MyBakery.floors[1], function()
- local vx, vy, vz = _L.Variables.MyBakery:GetCustomerStartVoxel(1)
- self:WalkToPoint(vx, vy, vz, function()
- self:FadeTransparency(1, function()
- self:LeaveBakery()
- end)
- end, nil, true)
- end)
- end
- local isLeavingTip = false
- local isGoingForGumball = false
- local isGoingForCandy = false
- local isGoingForArcade = false
- local isGoingForPopcorn = false
- local isGoingForSoda = false
- local isGoingForBowl = false
- -- is there a tip jar on this floor? if so, roll to leave tip
- if not wasForcedToLeave then
- local tipJars = myFloor:GetEntitiesFromClassAndSubClass("Appliance", "Tip Jar")
- if #tipJars > 0 then
- for _, tipJar in ipairs(tipJars) do
- local tipChance = tipJar.ID == "14" and 0.05 or tipJar.ID == "19" and 0.50 or tipJar.ID == "26" and 0.40 or 0
- if true or forcedToLeaveTip or self:IsVIPCustomer() then
- isLeavingTip = true
- self:WalkToPoint(tipJar.xVoxel, tipJar.yVoxel, tipJar.zVoxel, function()
- if tipJar.isDeleted or self.isDeleted or not self.stateData or not self.stateData.foodOrder then
- goToExitAndLeave()
- return
- end
- -- happy emoji at tip jar
- self:TimedEmoji("VeryHappyEmoji", 2.5)
- _L.Network.Fire("AwardTipWithVerification", self.UID, tipJar.UID, self.stateData.foodOrder.ID)
- _L.SFX.Play(5839737230, tipJar.model.PrimaryPart)
- self:FaceEntity(tipJar)
- goToExitAndLeave()
- end)
- break
- end
- end
- end
- end
- if not isLeavingTip then
- local candyBowls = myFloor:GetEntitiesFromClassAndSubClass("Appliance", "CandyBowl")
- if #candyBowls > 0 then
- for _, bowl in ipairs(candyBowls) do
- if true and bowl.level and bowl.level > 0 then
- isGoingForBowl = true
- self:WalkToPoint(bowl.xVoxel, bowl.yVoxel, bowl.zVoxel, function()
- if bowl.isDeleted or not self.stateData or not self.stateData.foodOrder or bowl.level <= 0 then
- goToExitAndLeave()
- return
- end
- -- happy emoji at tip jar
- self:TimedEmoji("VeryHappyEmoji", 2.5)
- _L.Network.Fire("AwardTipWithVerification", self.UID, bowl.UID, self.stateData.foodOrder.ID)
- _L.SFX.Play(5057746151, bowl.model.PrimaryPart)
- self:FaceEntity(bowl)
- goToExitAndLeave()
- end)
- break
- end
- end
- end
- end
- -- only go for gumball if we're not leaving a tip
- if not isLeavingTip and not isGoingForBowl then
- local gumballMachines = myFloor:GetEntitiesFromClassAndSubClass("Appliance", "GumballMachine")
- if #gumballMachines > 0 then
- for _, gumballMachine in ipairs(gumballMachines) do
- if true then
- isGoingForGumball = true
- local fx, fy, fz = gumballMachine:GetFacePosition()
- if not myFloor:IsValidVoxel(fx, fy, fz) then
- fx, fy, fz = gumballMachine.xVoxel, gumballMachine.yVoxel, gumballMachine.zVoxel
- end
- self:WalkToPoint(fx, fy, fz, function()
- if gumballMachine.isDeleted or self.isDeleted then
- goToExitAndLeave()
- return
- end
- -- gumball tip
- if self.stateData.foodOrder then
- _L.Network.Fire("AwardTipWithVerification", self.UID, gumballMachine.UID, self.stateData.foodOrder.ID)
- end
- -- gumball sound
- _L.SFX.Play(5205171179, gumballMachine.model.PrimaryPart.Position)
- -- gumball emoji
- self:TimedEmoji("VeryHappyEmoji", 2.5)
- self:FaceEntity(gumballMachine)
- goToExitAndLeave()
- end)
- break
- end
- end
- end
- end
- if not isLeavingTip and not isGoingForGumball and not isGoingForBowl then
- local candyMachines = myFloor:GetEntitiesFromClassAndSubClass("Appliance", "CandyMachine")
- if #candyMachines > 0 then
- for _, candyMachine in ipairs(candyMachines) do
- if true then
- isGoingForCandy = true
- local fx, fy, fz = candyMachine:GetFacePosition()
- if not myFloor:IsValidVoxel(fx, fy, fz) then
- fx, fy, fz = candyMachine.xVoxel, candyMachine.yVoxel, candyMachine.zVoxel
- end
- self:WalkToPoint(fx, fy, fz, function()
- if candyMachine.isDeleted or self.isDeleted then
- goToExitAndLeave()
- return
- end
- _L.SFX.Play(5601560734, candyMachine.model.PrimaryPart)
- -- gumball tip
- if self.stateData.foodOrder then
- _L.Network.Fire("AwardTipWithVerification", self.UID, candyMachine.UID, self.stateData.foodOrder.ID)
- end
- -- gumball emoji
- self:TimedEmoji("VeryHappyEmoji", 2.5)
- self:FaceEntity(candyMachine)
- goToExitAndLeave()
- end)
- break
- end
- end
- end
- end
- -- check for popcorn machine
- if not isLeavingTip and not isGoingForGumball and not isGoingForCandy and not isGoingForBowl then
- local popcornMachines = myFloor:GetEntitiesFromClassAndSubClass("Appliance", "PopcornMachine")
- if #popcornMachines > 0 then
- for _, popcornMachine in ipairs(popcornMachines) do
- if true then
- isGoingForPopcorn = true
- local fx, fy, fz = popcornMachine:GetFacePosition()
- if not myFloor:IsValidVoxel(fx, fy, fz) then
- fx, fy, fz = popcornMachine.xVoxel, popcornMachine.yVoxel, popcornMachine.zVoxel
- end
- self:WalkToPoint(fx, fy, fz, function()
- if popcornMachine.isDeleted or self.isDeleted then
- goToExitAndLeave()
- return
- end
- _L.SFX.Play(5625433552, popcornMachine.model.PrimaryPart)
- -- popcorn tip
- if self.stateData.foodOrder then
- _L.Network.Fire("AwardTipWithVerification", self.UID, popcornMachine.UID, self.stateData.foodOrder.ID)
- end
- -- gumball emoji
- self:TimedEmoji("VeryHappyEmoji", 2.5)
- self:FaceEntity(popcornMachine)
- goToExitAndLeave()
- end)
- break
- end
- end
- end
- end
- -- check for soda machine
- if not isLeavingTip and not isGoingForGumball and not isGoingForCandy and not isGoingForPopcorn and not wasForcedToLeave and not isGoingForBowl then
- local sodaMachines = myFloor:GetEntitiesFromClassAndSubClass("Appliance", "SodaMachine")
- if #sodaMachines > 0 then
- for _, sodaMachine in ipairs(sodaMachines) do
- if true then
- isGoingForSoda = true
- local fx, fy, fz = sodaMachine:GetFacePosition()
- if not myFloor:IsValidVoxel(fx, fy, fz) then
- fx, fy, fz = sodaMachine.xVoxel, sodaMachine.yVoxel, sodaMachine.zVoxel
- end
- self:WalkToPoint(fx, fy, fz, function()
- if sodaMachine.isDeleted or self.isDeleted then
- goToExitAndLeave()
- return
- end
- _L.SFX.Play(5708685354, sodaMachine.model.PrimaryPart)
- -- soda tip
- if self.stateData.foodOrder then
- _L.Network.Fire("AwardTipWithVerification", self.UID, sodaMachine.UID, self.stateData.foodOrder.ID)
- end
- -- gumball emoji
- self:TimedEmoji("VeryHappyEmoji", 2.5)
- self:FaceEntity(sodaMachine)
- goToExitAndLeave()
- end)
- break
- end
- end
- end
- end
- -- check for arcade machine
- if not isLeavingTip and not isGoingForGumball and not isGoingForCandy and not isGoingForPopcorn and not isGoingForSoda and not wasForcedToLeave and not isGoingForBowl then
- local arcadeMachines = myFloor:GetEntitiesFromClassAndSubClass("Furniture", "ArcadeMachine")
- if #arcadeMachines > 0 then
- local indices = _L.Functions.RandomIndices(arcadeMachines)
- for _, index in ipairs(indices) do
- local arcadeMachine = arcadeMachines[index]
- if arcadeMachine.arcadeState ~= "Highscore" then
- continue
- end
- if arcadeMachine.busy then
- continue
- end
- arcadeMachine.busy = true
- isGoingForArcade = true
- local fx, fy, fz = arcadeMachine:GetFacePosition()
- if not myFloor:IsValidVoxel(fx, fy, fz) then
- fx, fy, fz = arcadeMachine.xVoxel, arcadeMachine.yVoxel, arcadeMachine.zVoxel
- end
- self:WalkToPoint(fx, fy, fz, function()
- if arcadeMachine.isDeleted or self.isDeleted then
- goToExitAndLeave()
- return
- end
- self:FaceEntity(arcadeMachine)
- -- play game (halts thread until done)
- arcadeMachine:PlayGameWithCustomer(self)
- arcadeMachine.busy = false
- goToExitAndLeave()
- end)
- break
- end
- end
- end
- -- check for celebrity customer
- local isGoingForCelebrity = false
- (function()
- if isLeavingTip or isGoingForGumball or isGoingForCandy or isGoingForPopcorn or isGoingForArcade or isGoingForSoda or isGoingForBowl then
- return
- end
- if _L.Variables.MyBakery.nameCounters["Celebrity Customer"] == 0 then
- return
- end
- local celebrity = _L.Variables.MyBakery:SearchForCelebrity()
- if not celebrity or celebrity.isDeleted or celebrity.stateData.celebrityApproachCount >= 3 then
- return
- end
- local function isValidCelebState()
- local validCelebStates = {
- ThinkingAboutOrder = true,
- DecidedOnOrder = true,
- WaitingToOrder = true,
- WaitingForFood = true,
- EatingFood = true
- }
- return not celebrity.isDeleted and validCelebStates[celebrity.state]
- end
- if not isValidCelebState() then
- return
- end
- isGoingForCelebrity = true
- celebrity.stateData.celebrityApproachCount += 1
- self:WalkToNewFloor(celebrity:GetMyFloor(), function()
- if not isValidCelebState() then
- if not celebrity.isDeleted then
- celebrity.stateData.celebrityApproachCount -= 1
- end
- goToExitAndLeave()
- return
- end
- self:WalkToPoint(celebrity.xVoxel, celebrity.yVoxel, celebrity.zVoxel, function()
- if not isValidCelebState() then
- if not celebrity.isDeleted then
- celebrity.stateData.celebrityApproachCount -= 1
- end
- goToExitAndLeave()
- return
- end
- celebrity.stateData.celebrityApproachCount -= 1
- _L.SFX.Play(5278932469, celebrity.model.PrimaryPart.Position)
- self:FaceEntity(celebrity)
- self:TimedEmoji("Starstruck", 2.5)
- self:PlayLoadedAnimation("wave")
- goToExitAndLeave()
- end)
- end)
- end)()
- if not isLeavingTip and not isGoingForGumball and not isGoingForCelebrity and not isGoingForCandy and not isGoingForArcade and not isGoingForPopcorn and not isGoingForBowl then
- goToExitAndLeave()
- end
- end)()
- end
- function Waiter:StartActionLoop()
- coroutine.wrap(function()
- while not self.isDeleted do
- self:PerformAction()
- wait()
- end
- end)()
- end
- function Waiter:CheckForDishPickup()
- local myFloor = self:GetMyFloor()
- local selectedDishChair, selectedDishChairFloor = nil
- -- check other floors for dishes
- local indices = _L.Functions.RandomIndices(_L.Variables.MyBakery.floors)
- --check my floor first
- if true then
- for i, index in ipairs(indices) do
- if index == myFloor.floorLevel then
- table.remove(indices, i)
- table.insert(indices, 1, myFloor.floorLevel)
- break
- end
- end
- end
- for _, index in ipairs(indices) do
- local thisFloor = _L.Variables.MyBakery.floors[index]
- local dishIndices = _L.Functions.RandomIndices(thisFloor.dishChairs)
- for _, dishIndex in ipairs(dishIndices) do
- local dishChair = thisFloor.dishChairs[dishIndex]
- if dishChair.isDeleted or dishChair.stateData.flaggedByWaiterForDishPickup or not dishChair.stateData.dish or dishChair.stateData.dish.isDeleted then
- continue
- end
- selectedDishChair = dishChair
- selectedDishChairFloor = dishChair:GetMyFloor()
- break
- end
- if selectedDishChair then
- break
- end
- end
- if not selectedDishChair then
- return false
- end
- local dishwashers = myFloor:GatherDishwashersOnAnyFloor()
- if #dishwashers == 0 then
- return false
- end
- -- chair that has an attached dish to go to
- local dishChair = selectedDishChair
- dishChair.stateData.flaggedByWaiterForDishPickup = true
- local dishwasher = dishwashers[math.random(#dishwashers)]
- dishwasher.stateData.dishWasherTargetCount += 1
- -- flag the dish with the targeted dishwasher
- dishChair.stateData.dish.flaggedDishwasherUID = dishwasher.UID
- self.state = "WalkingToPickupDish"
- self:WalkToNewFloor(dishChair:GetMyFloor(), function()
- if dishChair.isDeleted or not dishChair.stateData.dish then
- dishwasher.stateData.dishWasherTargetCount -= 1
- self.state = "Idle"
- return
- end
- self:WalkToPoint(dishChair.xVoxel, dishChair.yVoxel, dishChair.zVoxel, function()
- if dishChair.isDeleted or not dishChair.stateData.dish then
- dishwasher.stateData.dishWasherTargetCount -= 1
- self.state = "Idle"
- return
- end
- dishChair.stateData.flaggedByWaiterForDishPickup = false
- if not dishChair.stateData.dish or dishChair.stateData.dish.isDeleted then
- dishwasher.stateData.dishWasherTargetCount -= 1
- self.state = "Idle"
- return
- end
- -- dish is good. delete it and remove
- if dishChair.stateData.dish and dishChair.stateData.dish.model then
- -- remove dishChair from available
- for i, dishChairEntry in ipairs(selectedDishChairFloor.dishChairs) do
- if dishChairEntry == selectedDishChair then
- table.remove(selectedDishChairFloor.dishChairs, i)
- break
- end
- end
- -- stop the interact
- dishChair.stateData.dish:CleanupInteract()
- -- play dish sound
- if dishChair.stateData.dish.model and dishChair.stateData.dish.model.PrimaryPart then
- local dishSounds = {5205173686, 5205173942}
- _L.SFX.Play(dishSounds[math.random(#dishSounds)], dishChair.stateData.dish.model:GetPrimaryPartCFrame().p)
- end
- -- pick up the money and dish (if necessary)
- dishChair.stateData.dish:MoneyPickedUp()
- dishChair.stateData.dish:DestroyModel()
- dishChair.stateData.dish = nil
- -- hold the dish I'm delivering
- self:HoldDirtyDish()
- end
- self:FaceEntity(dishChair)
- if dishwasher.isDeleted then
- self:StopLoadedAnimation("hold")
- if self.stateData.heldDish then
- self.stateData.heldDish = self.stateData.heldDish:Destroy()
- end
- self.state = "Idle"
- return
- end
- -- walk to the dishwasher to deposit
- -- TODO face direction
- self:WalkToNewFloor(dishwasher:GetMyFloor(), function()
- if dishwasher.isDeleted then
- self:StopLoadedAnimation("hold")
- if self.stateData.heldDish then
- self.stateData.heldDish = self.stateData.heldDish:Destroy()
- end
- self.state = "Idle"
- return
- end
- self:WalkToPoint(dishwasher.xVoxel, dishwasher.yVoxel, dishwasher.zVoxel, function()
- -- put down the dish
- self:DropFood()
- if dishwasher.isDeleted then
- self.state = "Idle"
- return
- end
- dishwasher:AddDish()
- self:FaceEntity(dishwasher)
- self:ResetAllStates()
- end)
- end)
- end)
- end)
- return true
- end
- function Waiter:WalkToNewFloor(targetFloor, finishedCallback)
- local currentFloor = self:GetMyFloor()
- if not targetFloor or currentFloor.floorLevel == targetFloor.floorLevel then
- if finishedCallback then finishedCallback() end
- return
- end
- self:TransitionToDifferentFloor(targetFloor)
- if finishedCallback then
- finishedCallback()
- end
- end
- function Waiter:CheckForFoodDelivery()
- -- gather all order stands
- local myFloor = self:GetMyFloor()
- local orderStands = myFloor:GatherOrderStandsWithDeliveryReady()
- if #orderStands == 0 then
- -- if there are no order stands on my floor, search for floors that might need help
- local indices = _L.Functions.RandomIndices(_L.Variables.MyBakery.floors)
- for _, index in ipairs(indices) do
- local floor = _L.Variables.MyBakery.floors[index]
- if floor ~= myFloor then
- if not floor:HasAtLeastOneIdleStateOfClass("Waiter") then
- -- gather order stands on this floor
- orderStands = floor:GatherOrderStandsWithDeliveryReady()
- if #orderStands > 0 then
- break
- end
- end
- end
- end
- -- STILL nothing? abort
- if #orderStands == 0 then
- return false
- end
- end
- -- select a random order stand to deliver from
- local orderStand = orderStands[math.random(#orderStands)]
- if not orderStand then
- return false
- end
- orderStand.stateData.foodReadyTargetCount = orderStand.stateData.foodReadyTargetCount + 1
- self.state = "WalkingToPickupFood"
- -- walk to the order stand
- self:WalkToNewFloor(orderStand:GetMyFloor(), function()
- -- no need to kick out the customer, they've already been removed.
- -- just reset the waiter back to idle
- if orderStand.isDeleted then
- self.state = "Idle"
- return
- end
- self:WalkToPoint(orderStand.xVoxel, orderStand.yVoxel, orderStand.zVoxel, function()
- if orderStand.isDeleted then
- self.state = "Idle"
- return
- end
- orderStand.stateData.foodReadyTargetCount = orderStand.stateData.foodReadyTargetCount - 1
- -- it's possible that the user already cleared the queue...
- if #orderStand.stateData.foodReadyList == 0 then
- self.state = "Idle"
- return
- end
- -- grab some food off of the top of the queue
- local selectedFoodOrder = orderStand.stateData.foodReadyList[1]
- selectedFoodOrder.isGold = true
- table.remove(orderStand.stateData.foodReadyList, 1)
- if selectedFoodOrder.isGold then
- _L.SFX.Play(5370840758, orderStand.model.PrimaryPart)
- end
- -- delete this list item
- selectedFoodOrder:DestroyPopupListItemUI()
- -- the customer that I should deliver to...
- local customerOfOrder = self:EntityTable()[selectedFoodOrder.customerOwnerUID]
- if not customerOfOrder then
- _L.Print("CRITICAL: customer owner of food not found", true)
- self.state = "Idle"
- return false
- end
- -- pause to face the order stand for a little bit
- self:FaceEntity(orderStand)
- -- hold the dish I'm delivering
- self:HoldFood(selectedFoodOrder.ID, selectedFoodOrder.isGold)
- self.state = "WalkingToDeliverFood"
- if customerOfOrder.isDeleted then
- self.state = "Idle"
- self.stateData.heldDish = self.stateData.heldDish:Destroy()
- return
- end
- -- walk to the customer to deliver...
- self:WalkToNewFloor(customerOfOrder:GetMyFloor(), function()
- self:WalkToPoint(customerOfOrder.xVoxel, customerOfOrder.yVoxel, customerOfOrder.zVoxel, function()
- self:DropFood()
- if customerOfOrder.isDeleted then
- _L.Print("CRITICAL: walked to customer, but they were forced to leave. aborting", true)
- self.state = "Idle"
- return
- end
- customerOfOrder:ChangeToEatingState()
- -- face the customer
- self:FaceEntity(customerOfOrder)
- -- award XP for delivering food
- _L.Network.Fire("AwardWaiterExperienceForDeliveringOrderWithVerification", self.UID)
- -- free the waiter back up
- self.state = "Idle"
- end)
- end)
- end)
- end)
- return true
- end
- function Waiter:CheckForCustomerOrder()
- local myFloor = self:GetMyFloor()
- -- find a customer that is waiting to order
- local waitingCustomer = myFloor:GetCustomerWaitingToOrder()
- if not waitingCustomer then
- -- if there's no customer on my current floor, check if other floors need help
- local indices = _L.Functions.RandomIndices(_L.Variables.MyBakery.floors)
- for _, index in ipairs(indices) do
- local floor = _L.Variables.MyBakery.floors[index]
- if floor ~= myFloor then
- if not floor:HasAtLeastOneIdleStateOfClass("Waiter") then
- waitingCustomer = floor:GetCustomerWaitingToOrder()
- if waitingCustomer then
- break
- end
- end
- end
- end
- -- still nothing? abort
- if not waitingCustomer then
- return false
- end
- end
- self.state = "WalkingToTakeOrder"
- -- find the entire customer group
- local customerGroup = {waitingCustomer}
- for _, customerPartner in ipairs(waitingCustomer.stateData.queueGroup) do
- if customerPartner.state == "WaitingToOrder" and not customerPartner.waiterIsAttendingToFoodOrder then
- table.insert(customerGroup, customerPartner)
- end
- end
- -- tag debounce, not allowing other waiters to interfere
- for _, seatedCustomer in ipairs(customerGroup) do
- seatedCustomer.waiterIsAttendingToFoodOrder = true
- end
- local function untagGroup()
- for _, seatedCustomer in ipairs(customerGroup) do
- seatedCustomer.waiterIsAttendingToFoodOrder = false
- end
- end
- -- walk to the seated group
- local firstCustomer = customerGroup[1]
- local groupTable = self:EntityTable()[firstCustomer.stateData.tableUID]
- if not groupTable or groupTable.isDeleted then
- self.state = "Idle"
- return
- end
- local tx, ty, tz = groupTable.xVoxel, groupTable.yVoxel, groupTable.zVoxel
- local customerFloor = firstCustomer:GetMyFloor()
- self:WalkToNewFloor(customerFloor, function()
- if firstCustomer.leaving or firstCustomer.isDeleted then
- self.state = "Idle"
- return
- end
- self:WalkToPoint(tx, ty, tz, function()
- if firstCustomer.isDeleted or firstCustomer.leaving then
- self.state = "Idle"
- return
- end
- -- order stand to deposit the orders in
- local orderStand = customerFloor:FindOrderStandOnAnyFloor()
- if not orderStand then
- _L.Print("CRITICAL: NO ORDER STAND FOUND!", true)
- untagGroup()
- self.state = "Idle"
- self:TimedEmoji("ConcernedEmoji", 2)
- return
- end
- -- stop interacting
- local firstCustomer = customerGroup[1]
- if firstCustomer then
- firstCustomer:StopGroupEmoji()
- firstCustomer:CleanupGroupInteract()
- end
- -- check for customers in the group still waiting to have their
- -- order taken. it's possible that the user took one or
- -- more of their orders
- local groupOrder = {}
- local tookOrdersFrom = {}
- for _, seatedCustomer in ipairs(customerGroup) do
- if seatedCustomer.state == "WaitingToOrder" then
- table.insert(tookOrdersFrom, seatedCustomer)
- groupOrder[seatedCustomer.UID] = _L.Food.RandomFoodChoice(seatedCustomer.UID, seatedCustomer.ID, seatedCustomer:IsRichCustomer(), seatedCustomer:IsPirateCustomer(), seatedCustomer.isNearTree)
- seatedCustomer.state = "WaitingForFood"
- seatedCustomer:StopChat()
- end
- end
- -- if no orders are taken, abort
- if #tookOrdersFrom == 0 then
- self.state = "Idle"
- return
- end
- -- take order animation
- self:PlayLoadedAnimation("write")
- for _, customer in ipairs(customerGroup) do
- self:FaceEntity(customer)
- end
- self:StopLoadedAnimation("write")
- self.state = "WalkingToDropoffOrder"
- self:WalkToNewFloor(orderStand:GetMyFloor(), function()
- if orderStand.isDeleted then
- for _, customer in ipairs(customerGroup) do
- customer:ForcedToLeave()
- end
- self.state = "Idle"
- return
- end
- self:WalkToPoint(orderStand.xVoxel, orderStand.yVoxel, orderStand.zVoxel, function()
- if orderStand.isDeleted then
- for _, customer in ipairs(customerGroup) do
- customer:ForcedToLeave()
- end
- self.state = "Idle"
- return
- end
- -- deposit each of the orders
- for _, orderedCustomer in ipairs(tookOrdersFrom) do
- if orderedCustomer.isDeleted then
- continue
- end
- orderedCustomer:ChangeToWaitingForFoodState(groupOrder[orderedCustomer.UID])
- orderStand:AddFoodToQueue(groupOrder[orderedCustomer.UID])
- end
- -- award XP for taking an order
- _L.Network.Fire("AwardWaiterExperienceForTakingOrderWithVerification", self.UID)
- -- face deposit location
- self:FaceEntity(orderStand)
- -- free up the waiter for more actions
- self.state = "Idle"
- end)
- end)
- end)
- end)
- return true
- end
- function Waiter:CheckForQueuedCustomers()
- if not _L.Variables.MyBakery.isOpen then
- return false
- end
- local myFloor = self:GetMyFloor()
- -- if I'm not on the first floor, only go to help if there is nobody
- -- idle on the first floor
- if myFloor.floorLevel ~= 1 then
- if _L.Variables.MyBakery.floors[1]:HasAtLeastOneIdleStateOfClass("Waiter") then
- return false
- end
- -- only allow myself to go de-queue a customer if there are 5 or less waiters
- -- on the first floor. no need to overdo it.
- if #_L.Variables.MyBakery.floors[1].waiters > 5 then
- return false
- end
- end
- -- search for the top of the queue customer group that is ready
- -- to be seated
- local readyCustomerGroup = nil
- for _, customerGroup in ipairs(_L.Variables.MyBakery.customerQueue) do
- if customerGroup[1].state == "WaitingForSeat" and not customerGroup[1].waiterIsAttendingToInQueue then
- readyCustomerGroup = customerGroup
- break
- end
- end
- if not readyCustomerGroup then
- return false
- end
- -- tag each customer as attended to
- for _, customer in ipairs(readyCustomerGroup) do
- customer.waiterIsAttendingToInQueue = true
- end
- local firstCustomer = readyCustomerGroup[1]
- -- waiter is attending to me but I still haven't been seated? timeout
- coroutine.wrap(function()
- wait()
- if #readyCustomerGroup == 0 then
- return
- end
- if readyCustomerGroup[1].waiterIsAttendingToInQueue and readyCustomerGroup[1].state == "WaitingForSeat" then
- --_L.Print("timeout successful")
- for _, customer in ipairs(readyCustomerGroup) do
- customer.waiterIsAttendingToInQueue = false
- end
- end
- end)()
- self.state = "WalkingToQueuedCustomerGroup"
- -- walk to one of the customers in the queue group
- -- it's possible that the user sends the customers to their
- -- seat before we get there. if so, abort
- if firstCustomer.state ~= "WaitingForSeat" or firstCustomer.stateData.busyWalking then
- -- untag attending
- for _, customer in ipairs(readyCustomerGroup) do
- customer.waiterIsAttendingToInQueue = false
- end
- self:ResetAllStates()
- return
- end
- -- stop user pings
- firstCustomer:CleanupGroupInteract()
- firstCustomer:StopGroupEmoji()
- -- seat the customer group
- _L.Variables.MyBakery:SeatQueuedCustomerGroup(firstCustomer)
- -- update positioning
- _L.Variables.MyBakery:UpdateCustomerQueuePositioning()
- -- face the group
- self:FaceEntity(firstCustomer)
- -- free the waiter up
- self.state = "Idle"
- return true
- end
- local rng = Random.new()
- function Bakery:AddCustomersToQueueIfNecessary(kickCustomerIfNecessary, UIDBatch)
- -- helper function
- local function goToSeat(customer, doNotPlaySound)
- if customer.state ~= "WaitingForSeat" then
- -- error sound
- if not doNotPlaySound then
- _L.Audio.Play(5074110087, player.PlayerGui)
- end
- return
- end
- customer:StopGroupEmoji()
- customer:CleanupGroupInteract()
- self:SeatQueuedCustomerGroup(customer)
- self:UpdateCustomerQueuePositioning()
- -- click sound
- if not doNotPlaySound then
- _L.Audio.Play(5074101610, player.PlayerGui)
- end
- end
- -- max queue size of 4
- if #self.customerQueue >= 4 then
- return 0
- end
- -- every customer is initially on the first floor
- local firstFloor = self.floors[1]
- -- grab all available seats. search floors at random until a seat group is found
- local selectedTable, selectedSeatGroup
- local indices = _L.Functions.RandomIndices(_L.Variables.MyBakery.floors)
- for _, index in ipairs(indices) do
- local floor = self.floors[index]
- selectedTable, selectedSeatGroup = floor:GetAvailableSeatGroupings()
- if selectedTable and selectedSeatGroup then
- break
- end
- end
- if not (selectedTable and selectedSeatGroup) then
- -- if we didn't find a seat and kickCustomerIfNecessary (for VIP customers), then
- -- kick a random customer for the VIP customer
- if kickCustomerIfNecessary then
- local didKickCustomer = false
- for _, floor in ipairs(self.floors) do
- for _, customer in ipairs(floor.customers) do
- if customer.state ~= "ReadyToExit" then
- customer:ForcedToLeave()
- didKickCustomer = true
- break
- end
- end
- if didKickCustomer then
- break
- end
- end
- end
- return 0
- end
- local queueEntry = {}
- local didPlayVIPCustomerSound = false
- -- if a vip is forced (royal set), let the server know
- local vipOverride = {}
- local johnDoeOverride = {}
- local pirateOverride = {}
- local youtuberOverride = {}
- local shadowOverride = {}
- local corruptedVIPOverride = {}
- local santaOverride = {}
- local elfOverride = {}
- local treeTable = {}
- -- create customers to fill this seat grouping
- local containsGhostOrSpecial = false
- for i, seatGroup in pairs(selectedSeatGroup) do
- local seat = seatGroup
- local tabl = selectedTable
- local forceVIPCustomer = false
- local forceShadowCustomer = false
- local forceJohnDoeCustomer = false
- local forcePirateCustomer = false
- local forceYoutuberCustomer = false
- local forceSantaCustomer = false
- local forceElfCustomer = false
- -- look for a nearby christmas tree
- local floor = self.floors[seat.floorLevel]
- for _, entity in ipairs(floor:GetEntitiesFromClassAndSubClass("Furniture", "ChristmasTree")) do
- local dist = math.sqrt(math.pow(entity.xVoxel - seat.xVoxel, 2) + math.pow(entity.zVoxel - seat.zVoxel, 2))
- if dist < 4*math.sqrt(2)+0.1 then
- treeTable[i] = true
- break
- end
- end
- -- royal table logic
- local overrideUID = nil
- if seat.ID == "43" and tabl.ID == "44" then
- forceVIPCustomer = true
- overrideUID = seat.UID
- elseif seat.ID == "43" then
- forceVIPCustomer = true
- overrideUID = seat.UID
- elseif tabl.ID == "44" then
- forceVIPCustomer = true
- overrideUID = tabl.UID
- end
- if forceVIPCustomer then
- UIDBatch[i].ID = "13"
- vipOverride[i] = overrideUID
- end
- -- royal halloween table logic
- if not forceVIPCustomer then
- if seat.ID == "98" and tabl.ID == "99" then
- forceShadowCustomer = true
- overrideUID = seat.UID
- elseif seat.ID == "98" then
- forceShadowCustomer = true
- overrideUID = seat.UID
- elseif tabl.ID == "99" then
- forceShadowCustomer = true
- overrideUID = tabl.UID
- end
- -- 1% chance for haunted customer, otherwise corrupted VIP
- if forceShadowCustomer then
- UIDBatch[i].ID = "26"
- corruptedVIPOverride[i] = overrideUID
- end
- end
- -- John Doe Table Logic
- if not forceVIPCustomer then
- if seat.ID == "216" and tabl.ID == "217" then
- forceJohnDoeCustomer = true
- overrideUID = seat.UID
- elseif seat.ID == "216" then
- forceJohnDoeCustomer = true
- overrideUID = seat.UID
- elseif tabl.ID == "217" then
- forceJohnDoeCustomer = true
- overrideUID = tabl.UID
- end
- --Force John Doe
- if forceJohnDoeCustomer then
- -- if math.random() < 0.005 then
- UIDBatch[i].ID = "29"
- johnDoeOverride[i] = overrideUID
- -- else
- --UIDBatch[i].ID = "26"
- --corruptedVIPOverride[i] = overrideUID
- end
- end
- -- end
- -- pirate table logic
- if not forceVIPCustomer and not forceShadowCustomer then
- if seat.ID == "74" and tabl.ID == "75" then
- forcePirateCustomer = true
- overrideUID = seat.UID
- elseif seat.ID == "74" then
- forcePirateCustomer = true
- overrideUID = seat.UID
- elseif tabl.ID == "75" then
- forcePirateCustomer = true
- overrideUID = tabl.UID
- end
- if forcePirateCustomer then
- UIDBatch[i].ID = "21"
- pirateOverride[i] = overrideUID
- end
- end
- -- gamer table logic
- if not forceVIPCustomer and not forcePirateCustomer and not forceShadowCustomer then
- if seat.ID == "84" and tabl.ID == "85" then
- forceYoutuberCustomer = true
- overrideUID = seat.UID
- elseif seat.ID == "84" then
- forceYoutuberCustomer = true
- overrideUID = seat.UID
- elseif tabl.ID == "85" then
- forceYoutuberCustomer = true
- overrideUID = tabl.UID
- end
- if forceYoutuberCustomer then
- UIDBatch[i].ID = "22"
- youtuberOverride[i] = overrideUID
- end
- end
- -- santa table logic
- if not forceVIPCustomer and not forcePirateCustomer and not forceShadowCustomer and not forceYoutuberCustomer then
- if seat.ID == "108" and true then
- forceSantaCustomer = true
- overrideUID = seat.UID
- UIDBatch[i].ID = "27"
- santaOverride[i] = overrideUID
- end
- end
- -- elf table logic
- if not forceVIPCustomer and not forcePirateCustomer and not forceShadowCustomer and not forceYoutuberCustomer and not forceSantaCustomer then
- if seat.ID == "110" and tabl.ID == "111" then
- forceElfCustomer = true
- overrideUID = seat.UID
- elseif seat.ID == "110" then
- forceElfCustomer = true
- overrideUID = seat.UID
- elseif tabl.ID == "111" then
- forceElfCustomer = true
- overrideUID = tabl.UID
- end
- if forceElfCustomer then
- UIDBatch[i].ID = "28"
- elfOverride[i] = overrideUID
- end
- end
- local sx, sy, sz = self:GetCustomerStartVoxel(i, #selectedSeatGroup)
- local fx, fy, fz = self:GetCustomerQueueVoxel(i, -5, #selectedSeatGroup)
- local createdCustomer = _L.Customer.CreateRandomCustomer(UIDBatch[i], sx, sy, sz)
- local worldStart = firstFloor:WorldPositionFromVoxel(sx, sy, sz)
- local queueFront = firstFloor:WorldPositionFromVoxel(fx, fy, fz)
- createdCustomer.stateData.seatUID = seat.UID
- createdCustomer.stateData.tableUID = tabl.UID
- createdCustomer.stateData.queuePosition = #self.customerQueue + 1
- createdCustomer.isNearTree = treeTable[i] ~= nil
- createdCustomer:SetVoxelPosition(self:GetCustomerStartVoxel(i, #selectedSeatGroup))
- -- center the customer group...... remember that max group size is 4
- if createdCustomer:BelongsToMyBakery() then
- if #selectedSeatGroup % 2 == 0 then
- createdCustomer.model:SetPrimaryPartCFrame(CFrame.new(worldStart + Vector3.new(0, 2, 0), queueFront))
- elseif #selectedSeatGroup == 1 then
- local startCFrame = CFrame.new(worldStart + Vector3.new(0, 2, 0)) * CFrame.Angles(0, self.baseAngle, 0) * CFrame.new(2, 0, 0)
- local faceCFrame = CFrame.new(queueFront) * CFrame.Angles(0, self.baseAngle, 0) * CFrame.new(2, 0, 0)
- createdCustomer.model:SetPrimaryPartCFrame(CFrame.new(startCFrame.p, faceCFrame.p))
- elseif #selectedSeatGroup == 3 then
- local startCFrame = CFrame.new(worldStart + Vector3.new(0, 2, 0)) * CFrame.Angles(0, self.baseAngle, 0) * CFrame.new(-2, 0, 0)
- local faceCFrame = CFrame.new(queueFront) * CFrame.Angles(0, self.baseAngle, 0) * CFrame.new(-2, 0, 0)
- createdCustomer.model:SetPrimaryPartCFrame(CFrame.new(startCFrame.p, faceCFrame.p))
- end
- end
- -- special customer notifications
- if _L.PlayerSettings.GetSetting("Notifications") == "Enabled" then
- -- Haunted Horseman
- if createdCustomer.ID == "25" and not didPlayVIPCustomerSound then
- didPlayVIPCustomerSound = true
- _L.SFX.Play(5839736886, player.PlayerGui, nil, 1)
- _L.Alert.Message("The Headless Horseman has entered your Restaurant!")
- end
- -- Santa
- if createdCustomer.ID == "27" and not didPlayVIPCustomerSound then
- didPlayVIPCustomerSound = true
- _L.SFX.Play("6106142958", player.PlayerGui)
- _L.Alert.Message("Santa has entered your Restaurant!")
- end
- -- VIP customer? play sound for at least one
- if createdCustomer.ID == "13" and not didPlayVIPCustomerSound then
- didPlayVIPCustomerSound = true
- _L.SFX.Play(5174014731, player.PlayerGui)
- _L.Alert.Message("A VIP Customer has entered your Restaurant!")
- end
- -- celebrity customer?
- if createdCustomer.ID == "20" and not didPlayVIPCustomerSound then
- didPlayVIPCustomerSound = true
- _L.SFX.Play(5278932246, player.PlayerGui)
- _L.Alert.Message("A Celebrity Customer has entered your Restaurant!")
- end
- -- pirate customer
- if createdCustomer.ID == "21" and not didPlayVIPCustomerSound then
- didPlayVIPCustomerSound = true
- _L.SFX.Play(5601560215, player.PlayerGui, nil, 0.25)
- _L.Alert.Message("A Pirate Customer has entered your Restaurant!")
- end
- -- youtuber customer
- if createdCustomer.ID == "22" and not didPlayVIPCustomerSound then
- didPlayVIPCustomerSound = true
- _L.SFX.Play(5625433365, player.PlayerGui, nil, 0.25)
- _L.Alert.Message("A Youtuber Customer has entered your Restaurant!")
- end
- -- corrupted VIP
- if createdCustomer.ID == "26" and not didPlayVIPCustomerSound then
- didPlayVIPCustomerSound = true
- _L.SFX.Play(5839737683, player.PlayerGui, nil, 0.25)
- _L.Alert.Message("A Haunted VIP Customer has entered your Restaurant!")
- end
- --John Doe
- if createdCustomer.ID == "29" and not didPlayVIPCustomerSound then
- didPlayVIPCustomerSound = true
- _L.SFX.Play(5839737683, player.PlayerGui, nil, 0.25)
- _L.Alert.Message("John Doe has entered your Restaurant!")
- end
- end
- if createdCustomer.ID == "14" or createdCustomer.ID == "15" then
- containsGhostOrSpecial = true
- end
- -- finally give the customer a parent (prevents weird teleporting from corner thing)
- createdCustomer.model.Parent = createdCustomer.cachedParent
- createdCustomer:FadeTransparency(createdCustomer:GetMyTransparency())
- -- replication event.. customer created
- _L.Replication.SendEvent("CustomerCreated", createdCustomer:ToUIDData())
- -- tutorial table + flag
- if self.isTutorial then
- table.insert(self.tutorial.firstCustomerWave, createdCustomer)
- self.tutorial.hasAllowedFirstWaveOfCustomers = true
- end
- seat:SetIsOccupied(createdCustomer)
- tabl:AddCustomerAtTable(createdCustomer)
- createdCustomer:Emoji("WaitingForSeat", true)
- createdCustomer:Interact(function()
- goToSeat(createdCustomer)
- end)
- -- celebrity customer flag
- if createdCustomer.ID == "20" then
- _L.Variables.MyBakery.activeCelebrity = true
- end
- table.insert(queueEntry, createdCustomer)
- end
- -- initialize each customer's queue group. the customer can NOT be
- -- inside of their own queue group, since cyclic tables are not permitted
- for _, customer0 in ipairs(queueEntry) do
- customer0.stateData.queueGroup = {}
- for _, customer1 in ipairs(queueEntry) do
- if customer0 ~= customer1 then
- table.insert(customer0.stateData.queueGroup, customer1)
- end
- end
- end
- table.insert(self.customerQueue, queueEntry)
- if not containsGhostOrSpecial then
- self:UpdateCustomerQueuePositioning()
- else
- goToSeat(queueEntry[1], true)
- end
- return #selectedSeatGroup, vipOverride, pirateOverride, youtuberOverride, shadowOverride, corruptedVIPOverride, santaOverride, elfOverride, johnDoeOverride, treeTable
- end
- local bakeryData = _L.Variables.UIDData
- if not bakeryData then
- repeat wait() bakeryData = _L.Variables.UIDData until bakeryData
- end
- --"🐈"-bluwu
- local Wells = {"101","49","50"}
- local Slots = {"57"}
- local UNIT_SECOND = 1
- local UNIT_MINUTE = UNIT_SECOND * 60
- local SLOT_REFRESH = UNIT_MINUTE * 10
- local function useWell(wellUID, wellId)
- local event = "RequestWishingWellUsage"
- if wellId == "101" then
- event = "RequestHauntedWishingWellUsage"
- end
- _L.Network.Fire(event,wellUID)
- end
- coroutine.wrap(function()
- while true do
- for i,v in next, bakeryData["Furniture"] do
- local ID = v.ID
- if ID and table.find(Wells,ID) and v.ClassName == "Furniture" then
- task.spawn(function()
- local event = "GetWishingWellRefreshTime"
- if ID == "101" then
- event = "GetHauntedWishingWellRefreshTime"
- end
- local cooldown = _L.Network.Invoke(event,v.UID)
- if not isOnCooldown then
- useWell(v.UID, ID)
- end
- end)
- end
- if ID and table.find(Slots,ID) then
- task.spawn(function()
- local cooldown = _L.Network.Invoke("GetSlotRefreshTime")
- if cooldown == 0 then
- _L.Network.Fire("RequestSlotUsage", v.UID)
- end
- end)
- end
- end
- task.wait(3)
- end
- end)()
- -- script wasnt made by me lol --
Add Comment
Please, Sign In to add comment