local function GeneratePersistentTable()
	local ret = {}
	ret.bodycount = BonkerBox_FWEnvi.GetDefaultBodyCount()
	
	local acc = BonkerBox_FWEnvi.GetAltColourCount()
	
	for i=1,acc
		ret[BonkerBox_FWEnvi.GetAltColourName(i)] = SKINCOLOR_NONE
	end
	
	ret.bodycolspeed = 0
	ret.bodycolreversespeed=false
	ret.bodycolmapping = BonkerBox_FWEnvi.GetMappingModeEnumByName(BonkerBox_FWEnvi.GetMappingModeEnumByIndex(1,false),false)//it will literally just result in the magic number passed to GetMappingModeEnumByIndex() but this way i get error reports if the magic number in question is fucked up
	return ret
end

local function GetPlayerPosAsTable(player)
	if(BonkerBox_G.PlayerPhysicallyExists(player)~=true)
		return
	end
	
	local ret = {}
	ret.x  = player.mo.x
	ret.y = player.mo.y
	ret.z = player.mo.z
	return ret
end

local function CalculateMag(player,maxdrivingspeed)
	local ret = {}

	if(BonkerBox_G.PlayerPhysicallyExists(player)~=true)
		return ret
	end
	
	if(BonkerBox_G.IsTable(player[BonkerBox_FWEnvi.GetSkinName()])~=true)
		return ret
	end
	
	if(BonkerBox_G.IsTable(player[BonkerBox_FWEnvi.GetSkinName()].lastPlayerPos)~=true)
		player[BonkerBox_FWEnvi.GetSkinName()].lastPlayerPos = {}
	end

	if(BonkerBox_G.IsNumber(player[BonkerBox_FWEnvi.GetSkinName()].lastPlayerPos.x)~=true)
		player[BonkerBox_FWEnvi.GetSkinName()].lastPlayerPos.x = player.mo.x
	end
	
	if(BonkerBox_G.IsNumber(player[BonkerBox_FWEnvi.GetSkinName()].lastPlayerPos.y)~=true)
		player[BonkerBox_FWEnvi.GetSkinName()].lastPlayerPos.y = player.mo.y
	end
	
	if(BonkerBox_G.IsNumber(player[BonkerBox_FWEnvi.GetSkinName()].lastPlayerPos.z)~=true)
		player[BonkerBox_FWEnvi.GetSkinName()].lastPlayerPos.z = player.mo.z
	end
	
	local movemag = abs(P_AproxDistance(abs(player.mo.x-player[BonkerBox_FWEnvi.GetSkinName()].lastPlayerPos.x),abs(player.mo.y-player[BonkerBox_FWEnvi.GetSkinName()].lastPlayerPos.y))) //abs-ing this because huge distances overflow to negatives
	ret.movemagnormalized = BonkerBox_G.Clamp(BonkerBox_G.FixedInverseLerp(movemag,0,FixedMul(max(maxdrivingspeed,0),abs(player.mo.scale))),0,FRACUNIT)
	ret.movemagzsigned = player.mo.z-player[BonkerBox_FWEnvi.GetSkinName()].lastPlayerPos.z
	return ret
end

local function GetAllMobjs(player)
	local ret = {}
	local writeIndex = 1
	
	if(BonkerBox_G.IsPlayer(player)~=true)
		return ret
	end
	
	if(BonkerBox_G.IsTable(player[BonkerBox_FWEnvi.GetSkinName()])~=true)
		return ret
	end
	
	if(BonkerBox_G.IsMobj(player[BonkerBox_FWEnvi.GetSkinName()].headmobj)==true)
		ret[writeIndex] = player[BonkerBox_FWEnvi.GetSkinName()].headmobj
		writeIndex = writeIndex+1
	end
	
	if(BonkerBox_G.IsTable(player[BonkerBox_FWEnvi.GetSkinName()].bodymobjs)==true)
		for i,v in ipairs(player[BonkerBox_FWEnvi.GetSkinName()].bodymobjs)
			if(BonkerBox_G.IsMobj(v)~=true)
				continue
			end
			
			ret[writeIndex] = v
			writeIndex = writeIndex+1
		end
	end
	
	return ret
end

local bbfwf = {}
bbfwf.CalculateMag = CalculateMag
bbfwf.GetAllMobjs = GetAllMobjs
bbfwf.GetPlayerPosAsTable = GetPlayerPosAsTable
bbfwf.GeneratePersistentTable = GeneratePersistentTable

rawset(_G,"BonkerBox_FWFunc",bbfwf)