Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[
- Author: LifeInDevelopment
- Timestamp: 19/April/2018
- Class Diagram:
- Attributes:
- tipBudget
- character
- plot
- order
- type
- owner
- Member Functions:
- Spawn
- Move
- Order
- --]]
- --[[ Services ]]--
- local serverStorage = game:GetService("ServerStorage")
- local pathfindingService = game:GetService("PathfindingService")
- local physicsService = game:GetService("PhysicsService")
- --[[ Components ]]--
- local components = serverStorage:WaitForChild("Components")
- --// Classes //--
- local Order = require(components:WaitForChild("Order"))
- --[[ Data ]]--
- local data = serverStorage:WaitForChild("Data")
- local CustomerData = require(data:WaitForChild("CustomerData"))
- --[[ Assets ]]--
- local assets = serverStorage:WaitForChild("Assets")
- --// Rigs //--
- local rigs = assets:WaitForChild("Rigs")
- --[[ Collision Groups ]]--
- --// Npc Collision Group //--
- local NpcCollisionGroup = physicsService:CreateCollisionGroup("NpcCollisionGroup")
- physicsService:CollisionGroupSetCollidable("NpcCollisionGroup", "NpcCollisionGroup")
- --[[ Private Functions ]]--
- local function FindItemsOfType(character, itemFolder, itemType)
- local itemArray = {}
- -- Append valid items to itemArray
- for _, v in pairs(itemFolder:GetChildren()) do
- if v.ItemData.ItemType == itemType then
- local itemDistance = (character.PrimaryPart.Position - v.ItemModel.PrimaryPart.Position).magnitude
- local element = {item = v, distance = itemDistance}
- end
- end
- -- Sort itemArray
- table.sort(itemArray, function(elementA, elementB)
- return elementA.distance < elementB.distance
- end)
- return itemArray
- end
- local function AddModelToCollisionGroup(model, collisionGroup)
- for _, part in pairs(model:GetChildren()) do
- if part:IsA("BasePart") then
- physicsService:SetPartCollisionGroup(part, collisionGroup)
- end
- end
- end
- --// Class //--
- local Customer = {}
- Customer.__index = Customer
- --// Constructor //--
- function Customer.new(owner, plot, customerType, rig)
- --Variable Initialization.
- local self = setmetatable({}, Customer)
- local customerTemplate = CustomerData.CustomerTemplates[customerType]
- CustomerData.CustomerCount = CustomerData.CustomerCount
- -- Attribute declaration.
- self.type = customerTemplate.Type
- self.tipBudget = customerTemplate.MaxTipBudget
- self.plot = plot
- self.owner = owner
- self.objective = nil
- self.currentState = nil
- self.customerId = CustomerData.CustomerCount
- -- Rig selection.
- self.character = rig and rig:Clone() or (function() local rigs = rigs:GetChildren() return rigs[math.random(#rigs)]:Clone() end)()
- -- Add character to collision group.
- AddModelToCollisionGroup(self.character, "NpcCollisionGroup")
- return self
- end
- --// Methods //--
- function Customer:Spawn()
- -- Move character
- self.character.Parent = self.plot.Customers
- self.character:SetPrimaryPartCFrame(CFrame.new(self.plot.Spawn.Position + Vector3.new(0, 3, 0)))
- end
- function Customer:Move(position) -- Use A* in the future.
- local path = pathfindingService:FindPathAsync(self.character.PrimaryPart.Position, position)
- if path.Status == Enum.PathStatus.NoPath then
- spawn(function()
- repeat
- path = pathfindingService:FindPathAsync(self.character.PrimaryPart.Position, position)
- wait(0.5)
- until path.Status == Enum.PathStatus.Success
- end)
- end
- spawn(function()
- local waypoints = path:GetWaypoints()
- for _, pathWaypoint in pairs(waypoints) do
- self.character.Humanoid:MoveTo(pathWaypoint.Position)
- if pathWaypoint.Action == Enum.PathWaypointAction.Jump then self.charactr.Humanoid.Jump = true end
- self.character.Humanoid.MoveToFinished:Wait()
- end
- end)
- end
- function Customer:SetObjective(objective)
- if not objective then warn("Objective wasn't passed") return end
- self.objective = objective
- if objective == "Order" then
- -- Find the nearest counters.
- local counters = FindItemsOfType(self.character, self.plot.Items, "Counter")
- -- Assign counter to the nearest, free counter, and add the character to the queue.
- local counter = counters[1]
- do
- local index = 1
- while true do
- local counterQueue = counter.Queue:GetChildren()
- if #counterQueue < counter.ItemData.MaxQueue.Value then
- -- Insert character to queue.
- local characterQueueValue = Instance.new("ObjectValue")
- characterQueueValue.Name = #counterQueue + 1
- characterQueueValue.Value = self.character
- characterQueueValue.Parent = counter.Queue
- break
- end
- counter = counters[index + 1]
- wait(0.1)
- end
- end
- -- Move to queue
- do
- -- Set customer state.
- self.currentState = "Queueing"
- -- Move to the end of the queue.
- local queueTargetPosition = CFrame.new(counter.ItemModel.CustomerInteractionPart.CFrame * CFrame.new(Vector3.new(0, 0, -3) * #counter.Queue:GetChildren())).p
- self:Move(queueTargetPosition, true)
- -- Stay & Move up in the queue until the character is first.
- local childRemovedSignal
- childRemovedSignal = counter.Queue.ChildRemoved:Connect(function(child)
- if child.Value == self.character then
- childRemovedSignal:Disconnect()
- return
- end
- -- Increment own character's value obj name.
- local queueValue
- for i, v in pairs(counter.Queue:GetChildren()) do
- if v.Value == self.character then
- queueValue = v
- end
- end
- end)
- repeat wait(0.1) until not (function()
- for i, v in pairs(counter.Queue:GetChildren()) do
- if v.Value == self.character then
- return true
- end
- end
- end)()
- end
- -- Move to the interaction part.
- -- Construct order object.
- self.order = Order.new(self)
- elseif objective == "Sit" then
- elseif objective == "Leave" then
- end
- end
- return Customer
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement