Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- if not getconnections then return end
- for i,v in next, getconnections(game.Players.LocalPlayer.Idled) do
- v:Disable()
- 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 _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: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()
- wait()
- 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: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 = orderStand:IsGoldOrderStand() and math.random() < 0.05
- 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
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement