Campfire Food Problem

Hi, I’m having a problem with my campfire system, when a food is heating up and runs out of combustion material, I would like to make the food stay in a pending state and if the player adds more combustion material it can finish cooking and not just disappear. How could this be done and implemented in my code?

local CollectionService = game:GetService("CollectionService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local CookingInfo = require(ReplicatedStorage:WaitForChild("CookingTimes"):WaitForChild("CookingData"))

local CookingData = CookingInfo.CookingData
local FuelData = CookingInfo.FuelData

local currentFuelTime = 0
local isBurning = false
local burningEndTime = 0
local isCooking = false -- Nueva variable de estado para verificar si ya hay una comida cocinándose

local proximityPrompt = script.Parent:WaitForChild("ProximityPrompt"):WaitForChild("ProximityPrompt")

local function activateCombustionEffects()
	local particles = script.Parent:FindFirstChild("Particles")
	local sound = particles and particles:FindFirstChild("Sound")
	local fire = particles and particles:FindFirstChild("Fire")
	local smoke = particles and particles:FindFirstChild("Smoke")
	local lights = particles and particles:FindFirstChild("Light")

	if particles then
		local emitter = particles:FindFirstChildOfClass("ParticleEmitter")
		if emitter then
			emitter.Enabled = true
		end
	end

	if sound then
		sound:Play()
	end

	if fire then
		fire.Enabled = true
	end

	if smoke then
		smoke.Enabled = true
	end

	if lights then
		for _, light in pairs(lights:GetChildren()) do
			if light:IsA("Light") then
				light.Enabled = true
			end
		end
	end
end

local function deactivateCombustionEffects()
	local particles = script.Parent:FindFirstChild("Particles")
	local sound = particles and particles:FindFirstChild("Sound")
	local fire = particles and particles:FindFirstChild("Fire")
	local smoke = particles and particles:FindFirstChild("Smoke")
	local lights = particles and particles:FindFirstChild("Light")

	if particles then
		local emitter = particles:FindFirstChildOfClass("ParticleEmitter")
		if emitter then
			emitter.Enabled = false
		end
	end

	if sound then
		sound:Stop()
	end

	if fire then
		fire.Enabled = false
	end

	if smoke then
		smoke.Enabled = false
	end

	if lights then
		for _, light in pairs(lights:GetChildren()) do
			if light:IsA("Light") then
				light.Enabled = false
			end
		end
	end
end

local function addFuel(fuelItem)
	local fuelTime = FuelData[fuelItem.Name]
	if fuelTime then
		fuelItem:Destroy()

		currentFuelTime = fuelTime
		burningEndTime = tick() + currentFuelTime

		if not isBurning then
			isBurning = true
			activateCombustionEffects()
		end

		-- Activar el BillboardGui y actualizar el TextLabel
		local billboardGui = script.Parent:FindFirstChild("Fuego")
		if billboardGui then
			billboardGui.Enabled = true
			local textLabel = billboardGui:FindFirstChild("Frame"):FindFirstChild("TextLabel")

			while tick() < burningEndTime do
				local remainingTime = math.ceil(burningEndTime - tick())
				if textLabel then
					textLabel.Text = tostring(remainingTime)  -- Actualizar el TextLabel con solo el tiempo restante
				end
				wait(1) -- Esperar 1 segundo antes de actualizar el tiempo restante
			end

			-- Deshabilitar el BillboardGui cuando el tiempo se haya agotado
			billboardGui.Enabled = false
		end

		if tick() >= burningEndTime then
			isBurning = false
			deactivateCombustionEffects()
		end
	else
		print("El ítem " .. fuelItem.Name .. " no es un combustible válido")
	end
end

local function startCooking(player, rawFoodName)
	local foodData = CookingData[rawFoodName]
	if not foodData then
		print("No se encontraron datos de cocción para: " .. rawFoodName)
		return
	end

	isCooking = true -- Marcar que la cocción ha comenzado

	local cookingTime = foodData.time
	local cookedItemName = foodData.cookedItem

	print("Iniciando cocción de: " .. rawFoodName .. " Tiempo de cocción: " .. cookingTime)

	local billboardGui = script.Parent:FindFirstChild("BillboardGui")
	if billboardGui then
		billboardGui.Enabled = true
		local progressFrame = billboardGui:FindFirstChild("Frame")
		if progressFrame then
			-- Inicializa el progreso
			local startTime = tick()
			local endTime = startTime + cookingTime

			progressFrame.Size = UDim2.new(0, 0, 1, 0)

			-- La función de actualización del progreso
			local function updateProgress()
				local currentTime = tick()
				local elapsedTime = currentTime - startTime
				local progress = math.clamp(elapsedTime / cookingTime, 0, 1)
				progressFrame.Size = UDim2.new(progress, 0, 1, 0)
			end

			-- Actualiza el progreso suavemente
			while tick() < endTime do
				if tick() > burningEndTime then
					print("Sin combustible. Deteniendo cocción.")
					break
				end

				updateProgress()
				wait(0.001) -- Ajusta la frecuencia de actualización para obtener una transición más suave
			end

			-- Asegúrate de que el progreso esté al 100% al final del tiempo de cocción
			updateProgress()

			billboardGui.Enabled = false
		end
	else
		print("No se encontró BillboardGui en el modelo")
	end


	if tick() <= burningEndTime then
		local cookedFood = ReplicatedStorage:WaitForChild("CookedFoods"):FindFirstChild(cookedItemName)
		if cookedFood then
			local character = player.Character
			if character then
				local newTool = cookedFood:Clone()
				newTool.Parent = player.Backpack
				print("Comida cocida entregada: " .. cookedItemName)
			end
		else
			print("No se encontró comida cocida: " .. cookedItemName)
		end
	end

	isCooking = false -- Marcar que la cocción ha terminado
end

local notifyEvent = ReplicatedStorage:WaitForChild("NotificationEvent")

local function onTriggered(player)
	local character = player.Character
	local tool = character and character:FindFirstChildOfClass("Tool")

	if tool and CollectionService:HasTag(tool, "CanCook") then
		if isCooking then
			-- Enviar una solicitud de notificación al cliente
			notifyEvent:FireClient(player, "Cocina Ocupada", "Ya hay una comida cocinándose. Espera a que termine.")
			return
		end

		local rawFoodName = tool.Name
		if CookingData[rawFoodName] and isBurning then
			tool:Destroy()
			startCooking(player, rawFoodName)
		end
	elseif tool and CollectionService:HasTag(tool, "CanBurn") then
		addFuel(tool)
	end
end

proximityPrompt.Triggered:Connect(onTriggered)

I would try to make 3 states, raw, cooking and cooked, if the food is on the campfire and the combustion material runs out, keep it in the cooking state, and when the campfire starts again wait until it finishes cooking and set the cooking state to cooked.

1 Like

How can I apply it in my code?

1 Like

I can’t write whole scripts for you. But you can implement something like this.

local ProximityPrompt = script.Parent.ProximityPrompt
local state = "raw"
local Cookingtime = 6
local combustionLeft = 5

ProximityPrompt.Triggered:Connect(function()
	
	state = "cooking"
	
	local func = task.spawn(function()
		repeat
			task.wait(1)
			combustionLeft -= 1
			print(combustionLeft)
		until combustionLeft == 0
	end)
	
	task.wait(Cookingtime)
	
	if combustionLeft ~= 0 then
		state = "cooked"
		print(state)
		return
	end
	
	if combustionLeft < Cookingtime then
		state = "isnt cooked through"
		print(state)
		return
	end
end)

its going to set a timer for how long the food should cook, if the combustion isn’t enough to cook it through then it will say, “isn’t cooked through”. But if it is enough then it will print “cooked”. Implement this into your code and it should work.

I tried to implement it but I still can’t get it to work

I don’t know how else to help you, You just have to understand the basic concept of the script and replicate it to your script, that’s usually how it works.

I tried that:

local CollectionService = game:GetService("CollectionService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local CookingInfo = require(ReplicatedStorage:WaitForChild("CookingTimes"):WaitForChild("CookingData"))

local CookingData = CookingInfo.CookingData
local FuelData = CookingInfo.FuelData

local currentFuelTime = 0
local isBurning = false
local burningEndTime = 0
local isCooking = false
local cookingQueue = {}

local proximityPrompt = script.Parent:WaitForChild("ProximityPrompt"):WaitForChild("ProximityPrompt")
local pendienteValue = script.Parent:FindFirstChild("Pendiente")

local function activateCombustionEffects()
	local particles = script.Parent:FindFirstChild("Particles")
	local sound = particles and particles:FindFirstChild("Sound")
	local fire = particles and particles:FindFirstChild("Fire")
	local smoke = particles and particles:FindFirstChild("Smoke")
	local lights = particles and particles:FindFirstChild("Light")

	if particles then
		local emitter = particles:FindFirstChildOfClass("ParticleEmitter")
		if emitter then
			emitter.Enabled = true
		end
	end

	if sound then
		sound:Play()
	end

	if fire then
		fire.Enabled = true
	end

	if smoke then
		smoke.Enabled = true
	end

	if lights then
		for _, light in pairs(lights:GetChildren()) do
			if light:IsA("Light") then
				light.Enabled = true
			end
		end
	end
end

local function deactivateCombustionEffects()
	local particles = script.Parent:FindFirstChild("Particles")
	local sound = particles and particles:FindFirstChild("Sound")
	local fire = particles and particles:FindFirstChild("Fire")
	local smoke = particles and particles:FindFirstChild("Smoke")
	local lights = particles and particles:FindFirstChild("Light")

	if particles then
		local emitter = particles:FindFirstChildOfClass("ParticleEmitter")
		if emitter then
			emitter.Enabled = false
		end
	end

	if sound then
		sound:Stop()
	end

	if fire then
		fire.Enabled = false
	end

	if smoke then
		smoke.Enabled = false
	end

	if lights then
		for _, light in pairs(lights:GetChildren()) do
			if light:IsA("Light") then
				light.Enabled = false
			end
		end
	end
end

local function addFuel(fuelItem)
	local fuelTime = FuelData[fuelItem.Name]
	if fuelTime then
		fuelItem:Destroy()

		currentFuelTime = fuelTime
		burningEndTime = tick() + currentFuelTime

		if not isBurning then
			isBurning = true
			activateCombustionEffects()
		end

		-- Actualiza el BillboardGui para mostrar el tiempo restante del combustible
		local billboardGui = script.Parent:FindFirstChild("Fuego")
		if billboardGui then
			billboardGui.Enabled = true
			local textLabel = billboardGui:FindFirstChild("Frame"):FindFirstChild("TextLabel")

			while tick() < burningEndTime do
				local remainingTime = math.ceil(burningEndTime - tick())
				if textLabel then
					textLabel.Text = tostring(remainingTime)
				end
				wait(1)
			end

			billboardGui.Enabled = false
		end

		if tick() >= burningEndTime then
			isBurning = false
			deactivateCombustionEffects()
		end

		-- Si hay comida pendiente, reanuda la cocción
		if pendienteValue and pendienteValue.Value then
			if resumeCooking then
				resumeCooking()
			else
				print("resumeCooking no está definida")
			end
		end
	else
		print("El ítem " .. fuelItem.Name .. " no es un combustible válido")
	end
end

local function startCooking(player, rawFoodName, initialCookingTime, initialProgress)
	local foodData = CookingData[rawFoodName]
	if not foodData then
		print("No se encontraron datos de cocción para: " .. rawFoodName)
		return
	end

	isCooking = true
	local cookingTime = initialCookingTime or foodData.time
	local cookedItemName = foodData.cookedItem
	local elapsedCookingTime = cookingTime * (initialProgress or 0)

	print("Iniciando cocción de: " .. rawFoodName .. " Tiempo de cocción: " .. (cookingTime - elapsedCookingTime))

	local billboardGui = script.Parent:FindFirstChild("BillboardGui")
	if billboardGui then
		billboardGui.Enabled = true
		local progressFrame = billboardGui:FindFirstChild("Frame")
		if progressFrame then
			local startTime = tick()
			local endTime = startTime + (cookingTime - elapsedCookingTime)

			local function updateProgress()
				local currentTime = tick()
				local elapsedTime = currentTime - startTime
				local progress = math.clamp((elapsedTime / (cookingTime - elapsedCookingTime)) + (initialProgress or 0), 0, 1)
				progressFrame.Size = UDim2.new(progress, 0, 1, 0)
			end

			while tick() < endTime do
				if tick() > burningEndTime then
					print("Sin combustible. Dejando comida pendiente.")
					if pendienteValue then
						pendienteValue.Value = true
					end
					table.insert(cookingQueue, {
						player = player, 
						rawFoodName = rawFoodName, 
						remainingTime = endTime - tick(), 
						progress = progressFrame.Size.X.Scale
					})
					return
				end

				updateProgress()
				wait(0.001)
			end

			updateProgress()

			if tick() <= burningEndTime then
				billboardGui.Enabled = false
				if pendienteValue then
					pendienteValue.Value = false
				end
			end
		end
	else
		print("No se encontró BillboardGui en el modelo")
	end

	if tick() <= burningEndTime then
		local cookedFood = ReplicatedStorage:WaitForChild("CookedFoods"):FindFirstChild(cookedItemName)
		if cookedFood then
			local character = player.Character
			if character then
				local newTool = cookedFood:Clone()
				newTool.Parent = player.Backpack
				print("Comida cocida entregada: " .. cookedItemName)
			end
		else
			print("No se encontró comida cocida: " .. cookedItemName)
		end
	end

	isCooking = false
end

local function resumeCooking()
	print("Reanudando cocción de comida pendiente")
	for _, pending in ipairs(cookingQueue) do
		if isBurning then
			startCooking(pending.player, pending.rawFoodName, pending.remainingTime, pending.progress)
		end
	end
	cookingQueue = {}
end

local notifyEvent = ReplicatedStorage:WaitForChild("NotificationEvent")

local function onTriggered(player)
	local character = player.Character
	local tool = character and character:FindFirstChildOfClass("Tool")

	if tool and CollectionService:HasTag(tool, "CanCook") then
		if isCooking then
			notifyEvent:FireClient(player, "Cocina Ocupada", "Ya hay una comida cocinándose. Espera a que termine.")
			return
		end

		local rawFoodName = tool.Name
		if CookingData[rawFoodName] and isBurning then
			tool:Destroy()
			startCooking(player, rawFoodName)
		end
	elseif tool and CollectionService:HasTag(tool, "CanBurn") then
		addFuel(tool)
	else
		notifyEvent:FireClient(player, "Error", "Este objeto no se puede usar aquí.")
	end
end

proximityPrompt.Triggered:Connect(onTriggered)

-- Check if there's fuel and resume cooking if necessary
if pendienteValue and pendienteValue.Value then
	print("Comprobando pendiente al inicio")
	if resumeCooking then
		resumeCooking()
	else
		print("resumeCooking no está definida")
	end
end

but my resumecooking function is not working, resumeCooking no está definida - Servidor - CookingHandler:127

I don’t speak Spanish, but I think it says resumeCooking isn’t defined. So look into it deeper.

yeah I know it says that, I was trying to figure out why it says that, btw thanks and I’ll see if I can find another solution or someone to help me

Have the cook time be reduced if the campfire is lit instead of just waiting ‘x’ amount of seconds

i’m assuming only one item is allowed to be cooked at once

local cookTime=CookingData[rawFoodName].Time
local lastTick -- leave blank for now

while burning  and cooking do --madeup value, just a value that means the fireplace is cooking something
cookTime=cookTime- (tick()-lastTick or tick()) -- last tick or tick so it doesn't just break when lastick isn't defined

if cookTime<=0 then
cooking=false
 giveFood()
 end

lastTick = tick()
end

Can’t tell you exactly how to change your script to fit this in, didn’t look super in depth, but this approach should work (as long as only one food item is allowed in the campfire)