Jump to content

bone_attach - cannot resume dead coroutine


srslyyyy

Recommended Posts

  • Scripting Moderators

Any idea how to fix this ?

bone_attach/attach_func.lua:117: cannot resume dead coroutine [string "?"]  [DUP x5]
attached_ped = {}
attached_bone = {}
attached_x = {}
attached_y = {}
attached_z = {}
attached_rx = {}
attached_ry = {}
attached_rz = {}

function attachElementToBone(element,ped,bone,x,y,z,rx,ry,rz)
	if not (isElement(element) and isElement(ped)) then return false end
	if getElementType(ped) ~= "ped" and getElementType(ped) ~= "player" then return false end
	bone = tonumber(bone)
	if not bone or bone < 1 or bone > 20 then return false end
	x,y,z,rx,ry,rz = tonumber(x) or 0,tonumber(y) or 0,tonumber(z) or 0,tonumber(rx) or 0,tonumber(ry) or 0,tonumber(rz) or 0
	attached_ped[element] = ped
	attached_bone[element] = bone
	attached_x[element] = x
	attached_y[element] = y
	attached_z[element] = z
	attached_rx[element] = rx
	attached_ry[element] = ry
	attached_rz[element] = rz
	if setElementCollisionsEnabled then
		setElementCollisionsEnabled(element,false)
	end
	if script_serverside then
		triggerClientEvent("boneAttach_attach",root,element,ped,bone,x,y,z,rx,ry,rz)
	end
	return true
end

function detachElementFromBone(element)
	if not element then return false end
	if not attached_ped[element] then return false end
	clearAttachmentData(element)
	if setElementCollisionsEnabled then
		setElementCollisionsEnabled(element,true)
	end
	if script_serverside then
		triggerClientEvent("boneAttach_detach",root,element)
	end
	return true
end

function isElementAttachedToBone(element)
	if not element then return false end
	return isElement(attached_ped[element])
end

function getElementBoneAttachmentDetails(element)
	if not isElementAttachedToBone(element) then return false end
	return attached_ped[element],attached_bone[element],
		attached_x[element],attached_y[element],attached_z[element],
		attached_rx[element],attached_ry[element],attached_rz[element]
end

function setElementBonePositionOffset(element,x,y,z)
	local ped,bone,ox,oy,oz,rx,ry,rz = getElementBoneAttachmentDetails(element)
	if not ped then return false end
	return attachElementToBone(element,ped,bone,x,y,z,rx,ry,rz)
end

function setElementBoneRotationOffset(element,rx,ry,rz)
	local ped,bone,x,y,z,ox,oy,oz = getElementBoneAttachmentDetails(element)
	if not ped then return false end
	return attachElementToBone(element,ped,bone,x,y,z,rx,ry,rz)
end

if not script_serverside then
	function getBonePositionAndRotation(ped,bone)
		bone = tonumber(bone)
		if not bone or bone < 1 or bone > 20 then return false end
		if not isElement(ped) then return false end
		if getElementType(ped) ~= "player" and getElementType(ped) ~= "ped" then return false end
		if not isElementStreamedIn(ped) then return false end
		local x,y,z = getPedBonePosition(ped,bone_0[bone])
		local rx,ry,rz = getEulerAnglesFromMatrix(getBoneMatrix(ped,bone))
		return x,y,z,rx,ry,rz
	end
end

------------------------------------

function clearAttachmentData(element)
	attached_ped[element] = nil
	attached_bone[element] = nil
	attached_x[element] = nil
	attached_y[element] = nil
	attached_z[element] = nil
	attached_rx[element] = nil
	attached_ry[element] = nil
	attached_rz[element] = nil
end

function forgetDestroyedElements()
	if not attached_ped[source] then return end
	clearAttachmentData(source)
end
addEventHandler(script_serverside and "onElementDestroy" or "onClientElementDestroy",root,forgetDestroyedElements)

function forgetNonExistingPeds()
	local checkedcount = 0
	while true do
		for element,ped in pairs(attached_ped) do
			if not isElement(ped) then clearAttachmentData(element) end
			checkedcount = checkedcount+1
			if checkedcount >= 1000 then
				coroutine.yield()
				checkedcount = 0
			end
		end
		coroutine.yield()
	end
end
clearing_nonexisting_peds = coroutine.create(forgetNonExistingPeds)
setTimer(function()	coroutine.resume(clearing_nonexisting_peds) end,1000,0) -- line 117

 

Link to comment
  • Scripting Moderators
29 minutes ago, SaNoR said:

setTimer(function()
	if coroutine.status (clearing_nonexisting_peds) == "dead" then
		clearing_nonexisting_peds = coroutine.create(forgetNonExistingPeds)
	end
	coroutine.resume(clearing_nonexisting_peds)
end, 1000, 0)

 

 

I'll try it out soon and i give you answer if it works, thank you.

Link to comment
  • 2 weeks later...
  • Scripting Moderators
On 13/12/2018 at 20:39, SaNoR said:

setTimer(function()
	if coroutine.status (clearing_nonexisting_peds) == "dead" then
		clearing_nonexisting_peds = coroutine.create(forgetNonExistingPeds)
	end
	coroutine.resume(clearing_nonexisting_peds)
end, 1000, 0)

 

After:

bone_attach\attach_func.lua:119: bad argument #1 to 'status' (coroutine expected)  [DUP x2]

 

Link to comment

How about

setTimer(
  function()
    if not clearing_nonexisting_peds or coroutine.status (clearing_nonexisting_peds) == "dead" then
      clearing_nonexisting_peds = coroutine.create(forgetNonExistingPeds)
    end
    coroutine.resume(clearing_nonexisting_peds)
  end, 1000, 0
)
Edited by Investor
  • Thanks 1
Link to comment
  • Scripting Moderators
On 22/12/2018 at 21:39, Investor said:

How about


setTimer(
  function()
    if not clearing_nonexisting_peds or coroutine.status (clearing_nonexisting_peds) == "dead" then
      clearing_nonexisting_peds = coroutine.create(forgetNonExistingPeds)
    end
    coroutine.resume(clearing_nonexisting_peds)
  end, 1000, 0
)

I will test it today, later.

Link to comment
  • 2 weeks later...
  • Scripting Moderators
On 22/12/2018 at 21:39, Investor said:

How about


setTimer(
  function()
    if not clearing_nonexisting_peds or coroutine.status (clearing_nonexisting_peds) == "dead" then
      clearing_nonexisting_peds = coroutine.create(forgetNonExistingPeds)
    end
    coroutine.resume(clearing_nonexisting_peds)
  end, 1000, 0
)

 

On 13/12/2018 at 20:39, SaNoR said:

setTimer(function()
	if coroutine.status (clearing_nonexisting_peds) == "dead" then
		clearing_nonexisting_peds = coroutine.create(forgetNonExistingPeds)
	end
	coroutine.resume(clearing_nonexisting_peds)
end, 1000, 0)

 

 

Looks like both of this eliminated error, before it wasn't working due of my mistake. If something will change i will notice. Thank you very much.

Link to comment
  • 2 months later...
  • Scripting Moderators

bump.

attached_ped = {}
attached_bone = {}
attached_x = {}
attached_y = {}
attached_z = {}
attached_rx = {}
attached_ry = {}
attached_rz = {}

function attachElementToBone(element,ped,bone,x,y,z,rx,ry,rz)
	if not (isElement(element) and isElement(ped)) then return false end
	if getElementType(ped) ~= "ped" and getElementType(ped) ~= "player" then return false end
	bone = tonumber(bone)
	if not bone or bone < 1 or bone > 20 then return false end
	x,y,z,rx,ry,rz = tonumber(x) or 0,tonumber(y) or 0,tonumber(z) or 0,tonumber(rx) or 0,tonumber(ry) or 0,tonumber(rz) or 0
	attached_ped[element] = ped
	attached_bone[element] = bone
	attached_x[element] = x
	attached_y[element] = y
	attached_z[element] = z
	attached_rx[element] = rx
	attached_ry[element] = ry
	attached_rz[element] = rz
	if setElementCollisionsEnabled then
		setElementCollisionsEnabled(element,false)
	end
	if script_serverside then
		triggerClientEvent("boneAttach_attach",root,element,ped,bone,x,y,z,rx,ry,rz)
	end
	return true
end

function detachElementFromBone(element)
	if not element then return false end
	if not attached_ped[element] then return false end
	clearAttachmentData(element)
	if setElementCollisionsEnabled then
		setElementCollisionsEnabled(element,true)
	end
	if script_serverside then
		triggerClientEvent("boneAttach_detach",root,element)
	end
	return true
end

function isElementAttachedToBone(element)
	if not element then return false end
	return isElement(attached_ped[element])
end

function getElementBoneAttachmentDetails(element)
	if not isElementAttachedToBone(element) then return false end
	return attached_ped[element],attached_bone[element],
		attached_x[element],attached_y[element],attached_z[element],
		attached_rx[element],attached_ry[element],attached_rz[element]
end

function setElementBonePositionOffset(element,x,y,z)
	local ped,bone,ox,oy,oz,rx,ry,rz = getElementBoneAttachmentDetails(element)
	if not ped then return false end
	return attachElementToBone(element,ped,bone,x,y,z,rx,ry,rz)
end

function setElementBoneRotationOffset(element,rx,ry,rz)
	local ped,bone,x,y,z,ox,oy,oz = getElementBoneAttachmentDetails(element)
	if not ped then return false end
	return attachElementToBone(element,ped,bone,x,y,z,rx,ry,rz)
end

if not script_serverside then
	function getBonePositionAndRotation(ped,bone)
		bone = tonumber(bone)
		if not bone or bone < 1 or bone > 20 then return false end
		if not isElement(ped) then return false end
		if getElementType(ped) ~= "player" and getElementType(ped) ~= "ped" then return false end
		if not isElementStreamedIn(ped) then return false end
		local x,y,z = getPedBonePosition(ped,bone_0[bone])
		local rx,ry,rz = getEulerAnglesFromMatrix(getBoneMatrix(ped,bone))
		return x,y,z,rx,ry,rz
	end
end

------------------------------------

function clearAttachmentData(element)
	attached_ped[element] = nil
	attached_bone[element] = nil
	attached_x[element] = nil
	attached_y[element] = nil
	attached_z[element] = nil
	attached_rx[element] = nil
	attached_ry[element] = nil
	attached_rz[element] = nil
end

function forgetDestroyedElements()
	if not attached_ped[source] then return end
	clearAttachmentData(source)
end
addEventHandler(script_serverside and "onElementDestroy" or "onClientElementDestroy",root,forgetDestroyedElements)

function forgetNonExistingPeds()
	local checkedcount = 0
	while true do
		for element,ped in pairs(attached_ped) do
			if not isElement(ped) then clearAttachmentData(element) end
			checkedcount = checkedcount+1
			if checkedcount >= 1000 then
				coroutine.yield()
				checkedcount = 0
			end
		end
		coroutine.yield()
	end
end
clearing_nonexisting_peds = coroutine.create(forgetNonExistingPeds)
--setTimer(function()	coroutine.resume(clearing_nonexisting_peds) end,1000,0)
--[[setTimer(function()
    if not clearing_nonexisting_peds or coroutine.status(clearing_nonexisting_peds) == "dead" then
      clearing_nonexisting_peds = coroutine.create(forgetNonExistingPeds)
    end
    coroutine.resume(clearing_nonexisting_peds)
  end, 1000, 0)]]

setTimer(function()
	if coroutine.status (clearing_nonexisting_peds) == "dead" then
		clearing_nonexisting_peds = coroutine.create(forgetNonExistingPeds)
	end
	coroutine.resume(clearing_nonexisting_peds)
end, 10000, 0)

 

attach_func.lua:105: invalid key to 'next' [string "?"]

 

Link to comment
  • Moderators

According this topic:

http://www.computercraft.info/forums2/index.php?/topic/11043-invalid-key-to-next/

It says that the table has been changed while the process has been yield. Not sure is that is true or not.

 

If we would reproduce that:

 

We have for example this table:

local thisTable = {[element] = ped, [element] = ped, [element] = ped, [element] = ped, [element] = ped,[element] = ped }

 

We start looping:

local thisTable = {

[element] = ped,

[element] = ped,

[element] = ped,

-- yield

[element] = ped,

[element] = ped,

[element] = ped

}

 

 

Now a different part of the code removes:

local thisTable = {

[element] = ped,

[element] = ped,

[element] = ped,

-- yield

[element] = ped, -- < deleted

[element] = ped,

[element] = ped

}

 

And we resume.

 

That is when it is suppose to be happening according to this information.

 


 

Solution without changing the table structure?

 

pcall might be to catch the error and if there is an error, recreate the coroutine.

local status, err = pcall(coroutine.resume, clearing_nonexisting_peds)
if not status then
	clearing_nonexisting_peds = coroutine.create(forgetNonExistingPeds)
end

 

 

 

 

  • Like 1
Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...