Basic task system & fetch task

Tasks.lua

local Fetch = require(script.Parent.Type.Fetch)

return {
	
	-- Task Types
	["Fetch"] = Fetch,
	
	-- Premade Tasks
	["task_fetch_sample"] = function(itemToFetch: string?, returnPosition: Vector3?)
		return Fetch.new("Fetch Sample", "Fetch a sample in Sector C.", function(players: {Player}) end, itemToFetch or "Sample", returnPosition or Vector3.new())
	end,
}

Task.lua

-- Task.lua
-- Galicate | 9/28/2024 | 7:17 AM

local Task = {}

function Task.new(name: string, description: string, rewardFunc: ({Player}) -> ())
	local self = setmetatable({}, Task)

	self.Name = name or "Task Name"
	self.Description = description or "Task Description"
	self.RewardFunction = rewardFunc or 0

	self.Players = {}
	self.Completed = false

	return self
end

function Task:GetName(): string
	return self.Name
end

function Task:GetDescription(): string
	return self.Description
end

function Task:AddPlayer(player: Player)
	self.Players[player] = player
end

function Task:RemovePlayer(player: Player)
	self.Players[player] = nil
end

function Task:GetPlayers(): {Player}
	return self.Players
end

function Task:Complete()
	assert(not self.Completed, "This task is already completed")
	self.Completed = true
	self.RewardFunction(self:GetPlayers())
	self:Destroy()
end

function Task:Destroy()
	self = nil
end

Task.__index = Task
return Task

Fetch.lua

-- Fetch.lua
-- Galicate | 9/28/2024 | 7:06 AM

local Task = require(script.Parent.Task)

local Fetch = {}
Fetch.__index = Fetch
setmetatable(Fetch, Task)

local function isPlayerNearReturnPosition(players: {Player}, returnPosition: Vector3)
	
end

local function doesPlayerHaveItemToFetch(player: Player, itemToFetch: string)
	local backpack = player:FindFirstChild("Backpack")
	return backpack:FindFirstChild(itemToFetch) ~= nil
end

function Fetch.new(name: string, description: string, rewardFunc: ({Player}) -> (), itemToFetch: string, returnPosition: Vector3)
	local self = setmetatable(Task.new(name, description, rewardFunc), Fetch)
	
	self.ItemToFetch = itemToFetch or ""
	self.ReturnPosition = returnPosition or Vector3.new()
	
	self:Start()
	
	return self
end

function Fetch:GetItemToFetch(): string
	return self.ItemToFetch
end

function Fetch:GetReturnPosition(): Vector3
	return self.ReturnPosition
end

function Fetch:Start()
	while task.wait(1) and self do
		local playerNearReturnPosition = isPlayerNearReturnPosition(self:GetPlayers(), self:GetReturnPosition())
		if playerNearReturnPosition and doesPlayerHaveItemToFetch(playerNearReturnPosition, self:GetItemToFetch()) then
			self:Complete()
			break
		end
	end
end

return Fetch

Execution

local Tasks = require(game.ReplicatedStorage.Task.Tasks)
local newTask = Tasks.task_fetch_sample()
newTask:AddPlayer(game.Players.Galicate)

Organization

image

1 Like