AddCSLuaFile("cl_init.lua")
AddCSLuaFile("shared.lua")
include("shared.lua")

------------------------------//
function ENT:SpawnFunction(ply, tr)
	if (not tr.Hit) then return end
	local SpawnPos = tr.HitPos + tr.HitNormal * 1
	local ent = ents.Create(self.ClassName)
	local angle = ply:GetAimVector():Angle()
	angle = Angle(0, angle.yaw, 0)
	angle:RotateAroundAxis(angle:Up(), -90)
	ent:SetAngles(angle)
	ent:SetPos(SpawnPos)
	ent:Spawn()
	ent:Activate()
	zrmine.f.SetOwnerID(ent, ply)

	return ent
end

function ENT:Initialize()
	self:SetModel(self.Model)
	self:PhysicsInit(SOLID_VPHYSICS)
	self:SetMoveType(MOVETYPE_VPHYSICS)
	self:SetSolid(SOLID_VPHYSICS)
	self:SetUseType(SIMPLE_USE)
	self:SetCollisionGroup(COLLISION_GROUP_WEAPON)
	local phys = self:GetPhysicsObject()

	if (phys:IsValid()) then
		phys:Wake()
		phys:EnableMotion(true)
		phys:EnableDrag(true)
		phys:SetDragCoefficient(1)
	end

	self.PhysgunDisabled = false
	self:UseClientSideAnimation()
	self:Spawn_OutputGravel()
	self.StoredResource = {}
	self.StoredResource["Coal"] = 0
	self.StoredResource["Iron"] = 0
	self.StoredResource["Bronze"] = 0
	self.StoredResource["Silver"] = 0
	self.StoredResource["Gold"] = 0
	self.Inserter_EndPart = nil
	self.connected_module = nil
	self.connected_Parent = nil
	self.FullInitialized = false

	timer.Simple(0.1, function()
		if (IsValid(self)) then
			self.FullInitialized = true
		end
	end)
end

function ENT:Spawn_OutputGravel()
	self.outputgravel = ents.Create("zrms_gravelanim")
	self.outputgravel:SetAngles(self:GetAngles())
	self.outputgravel:SetPos(self:GetPos())
	self.outputgravel:Spawn()
	self.outputgravel:Activate()
	self.outputgravel:SetModel(self.GravelModel)
	self.outputgravel:SetParent(self)
	self.outputgravel:SetNoDraw(true)
end

function ENT:Use(activator, caller)
	if not IsValid(caller) or not caller:IsPlayer() or not IsValid(self) then return end

	if not zrmine.f.IsOwner(activator, self) then
		zrmine.f.Notify(activator, zrmine.language.Module_DontOwn, 1)

		return
	end

	if (zrmine.f.IsAdmin(activator) == false and self.IsPipeLineEntity) then return end


	if not self:GetHasChild() and not self:GetBuildMode() then
		zrmine.f.CreateEffectTable(nil, "zrmine_sfx_placecrate", self, effectAng, effectPos)

		if (self:Return_StoredAmount() > 0) then
			local effectPos01 = self:GetAttachment(self:LookupAttachment("output")).Pos + self:GetUp() * 5
			local effectAng01 = self:GetAngles()
			effectAng01:RotateAroundAxis(self:GetUp(), -90)
			zrmine.f.CreateEffectTable("zrms_refiner_dirt", "zrmine_sfx_refinerdirt", self, effectAng01, effectPos01)
			self:Clear_Resources()
		end

		self:Detach_Self()
		-- Here we make the normal conveyorbelt too a start module
	elseif (self:GetClass() == "zrms_conveyorbelt_n" and not self:GetHasChild() and self:GetBuildMode()) then
		if (self:ValidPosChecker(self)) then return end
		zrmine.f.CreateEffectTable(nil, "zrmine_sfx_connect_belt", self, effectAng, effectPos)
		self:SetBuildMode(false)
		self.PhysgunDisabled = true
		local sphys = self:GetPhysicsObject()

		if (sphys:IsValid()) then
			sphys:Wake()
			sphys:EnableMotion(false)
		end

		hook.Run("zrms_Verify_Inserter_connection", self)
	end
end

-- Here we Receive from our Parent to send resources
function ENT:Receive_Resources(rTable)
	--self:CreateEffect_Table(nil,"zrmine_sfx_addgravel",self,self:GetAngles(),self:GetPos())
	for k, v in pairs(rTable) do
		self.StoredResource[k] = self.StoredResource[k] + v
	end

	self:NET_UpdateResource()
end

-- Here we send resources to our Child
function ENT:Send_Resources(target, rtype)
	local sendTable = {}
	local sendAmount = zrmine.f.Calculate_AmountCap(self.StoredResource[rtype], self.TransportAmount)
	self.StoredResource[rtype] = self.StoredResource[rtype] - sendAmount
	sendTable[rtype] = sendAmount
	target:Receive_Resources(sendTable)
	self:NET_UpdateResource()
end

-- Gives our how many resources we have stored
function ENT:Return_StoredAmount()
	local StoredAmount
	StoredAmount = self.StoredResource["Coal"] + self.StoredResource["Iron"] + self.StoredResource["Bronze"]
	StoredAmount = StoredAmount + self.StoredResource["Silver"] + self.StoredResource["Gold"]

	return StoredAmount
end

-- Updates our net Resource vars
function ENT:NET_UpdateResource()
	self:SetOnBelt_Coal(self.StoredResource["Coal"] or 0)
	self:SetOnBelt_Iron(self.StoredResource["Iron"] or 0)
	self:SetOnBelt_Bronze(self.StoredResource["Bronze"] or 0)
	self:SetOnBelt_Silver(self.StoredResource["Silver"] or 0)
	self:SetOnBelt_Gold(self.StoredResource["Gold"] or 0)
end

-- Clears all stored Resources
function ENT:Clear_Resources()
	zrmine.f.CreateEffectTable(nil, "zrmine_sfx_refinerdirt", self, self:GetAngles(), self:GetPos())
	self.StoredResource = self.StoredResource or {}
	self.StoredResource["Coal"] = 0
	self.StoredResource["Iron"] = 0
	self.StoredResource["Bronze"] = 0
	self.StoredResource["Silver"] = 0
	self.StoredResource["Gold"] = 0
	self:NET_UpdateResource()
end

-- Removes a stored Resource
function ENT:Destroy_Resource(rtype, amount)
	local effectPos02
	local effectAng02

	if (zrmine.config.Inserter_DeleteOnEndPoint) then
		effectPos02 = self:GetAttachment(self:LookupAttachment("output")).Pos + self:GetUp() * 24 + self:GetForward() * 5
		effectAng02 = self:GetAngles()
		zrmine.f.CreateEffectTable("zrms_refiner_dirt02", "zrmine_sfx_refinerdirt", self, effectAng02, effectPos02)
	else
		effectPos02 = self:GetAttachment(self:LookupAttachment("output")).Pos + self:GetUp() * 24 + self:GetForward() * 5
		effectAng02 = self:GetAngles()
		zrmine.f.CreateEffectTable("zrms_refiner_dirt02", "zrmine_sfx_refinerdirt", self, effectAng02, effectPos02)
		local stonePos = self:GetAttachment(self:LookupAttachment("output")).Pos + self:GetUp() * 20
		local yOffset = 2

		if (amount > 0) then
			local junkSize
			stonePos = stonePos + self:GetUp() * yOffset

			if (amount > 10) then
				junkSize = 1
			else
				junkSize = 2
			end

			self:SpawnResource(stonePos, amount, junkSize, rtype)
			yOffset = yOffset + 10
		end
	end

	zrmine.f.CreateEffectTable(nil, "zrmine_sfx_addgravel", self, self:GetAngles(), self:GetPos())
	self.StoredResource = self.StoredResource or {}
	self.StoredResource[rtype] = self.StoredResource[rtype] - amount
	self:NET_UpdateResource()
end

-- This returns the id of a valid resource
function ENT:FindValidResource()
	local validResource = nil

	for k, v in pairs(self.StoredResource) do
		local sendAmount = zrmine.f.Calculate_AmountCap(v, self.TransportAmount)

		if (sendAmount > 0) then
			validResource = k
			break
		end
	end

	return validResource
end

-- Construction
function ENT:ConnectModule(amodule)
	local attach = self:GetAttachment(self:LookupAttachment("output"))
	local pos
	if (self:ValidPosChecker(amodule)) then return end

	if (amodule:GetClass() == "zrms_conveyorbelt_n") then
		pos = Vector(attach.Pos.x, attach.Pos.y, self:GetPos().z)
		local ang = self:GetAngles()

		if (self:GetClass() == "zrms_conveyorbelt_c_right") then
			ang:RotateAroundAxis(self:GetUp(), -90)
		elseif (self:GetClass() == "zrms_conveyorbelt_c_left") then
			ang:RotateAroundAxis(self:GetUp(), 90)
		else
			ang:RotateAroundAxis(self:GetUp(), 0)
		end

		amodule:SetAngles(ang)
		amodule:SetPos(pos)
	elseif (amodule:GetClass() == "zrms_conveyorbelt_s") then
		pos = Vector(attach.Pos.x, attach.Pos.y, self:GetPos().z)
		local ang = self:GetAngles()

		if (self:GetClass() == "zrms_conveyorbelt_c_right") then
			ang:RotateAroundAxis(self:GetUp(), -90)
		elseif (self:GetClass() == "zrms_conveyorbelt_c_left") then
			ang:RotateAroundAxis(self:GetUp(), 90)
		else
			ang:RotateAroundAxis(self:GetUp(), 0)
		end

		amodule:SetAngles(ang)
		amodule:SetPos(pos)
	elseif (amodule:GetClass() == "zrms_conveyorbelt_c_right") then
		pos = Vector(attach.Pos.x, attach.Pos.y, self:GetPos().z)
		local ang = self:GetAngles()

		if (self:GetClass() == "zrms_conveyorbelt_c_right") then
			ang:RotateAroundAxis(self:GetUp(), -90)
		elseif (self:GetClass() == "zrms_conveyorbelt_c_left") then
			ang:RotateAroundAxis(self:GetUp(), 90)
		else
			ang:RotateAroundAxis(self:GetUp(), 0)
		end

		amodule:SetAngles(ang)
		amodule:SetPos(pos)
	elseif (amodule:GetClass() == "zrms_conveyorbelt_c_left") then
		pos = Vector(attach.Pos.x, attach.Pos.y, self:GetPos().z)
		local ang = self:GetAngles()

		if (self:GetClass() == "zrms_conveyorbelt_c_right") then
			ang:RotateAroundAxis(self:GetUp(), -90)
		elseif (self:GetClass() == "zrms_conveyorbelt_c_left") then
			ang:RotateAroundAxis(self:GetUp(), 90)
		else
			ang:RotateAroundAxis(self:GetUp(), 0)
		end

		amodule:SetAngles(ang)
		amodule:SetPos(pos)
	elseif (string.sub(amodule:GetClass(), 1, 12) == "zrms_refiner") then
		offset = -40
		local ang = self:GetAngles()

		if (self:GetClass() == "zrms_conveyorbelt_c_right") then
			ang:RotateAroundAxis(self:GetUp(), -90)
		elseif (self:GetClass() == "zrms_conveyorbelt_c_left") then
			ang:RotateAroundAxis(self:GetUp(), 90)
		else
			ang:RotateAroundAxis(self:GetUp(), 0)
		end

		amodule:SetAngles(ang)
		pos = Vector(attach.Pos.x, attach.Pos.y, self:GetPos().z)
		amodule:SetPos(pos)
	elseif (string.sub(amodule:GetClass(), 1, 13) == "zrms_splitter") then
		offset = -40
		local ang = self:GetAngles()

		if (self:GetClass() == "zrms_conveyorbelt_c_right") then
			ang:RotateAroundAxis(self:GetUp(), -180)
		elseif (self:GetClass() == "zrms_conveyorbelt_c_left") then
			ang:RotateAroundAxis(self:GetUp(), 0)
		else
			ang:RotateAroundAxis(self:GetUp(), -90)
		end

		amodule:SetAngles(ang)
		pos = Vector(attach.Pos.x, attach.Pos.y, self:GetPos().z)
		amodule:SetPos(pos)
	elseif (string.sub(amodule:GetClass(), 1, 11) == "zrms_sorter") then
		offset = -15
		local ang = self:GetAngles()

		if (self:GetClass() == "zrms_conveyorbelt_c_right") then
			ang:RotateAroundAxis(self:GetUp(), -180)
		elseif (self:GetClass() == "zrms_conveyorbelt_c_left") then
			ang:RotateAroundAxis(self:GetUp(), 0)
		elseif (self:GetClass() == "zrms_conveyorbelt_s") then
			ang:RotateAroundAxis(self:GetUp(), 180)
			offset = -25
		else
			ang:RotateAroundAxis(self:GetUp(), 180)
		end

		amodule:SetAngles(ang)
		pos = Vector(attach.Pos.x, attach.Pos.y, self:GetPos().z) + self:GetForward() * offset
		amodule:SetPos(pos)
	elseif (string.sub(amodule:GetClass(), 1, 13) == "zrms_inserter") then
		pos = Vector(attach.Pos.x, attach.Pos.y, self:GetPos().z)
		local ang = self:GetAngles()

		if (self:GetClass() == "zrms_conveyorbelt_c_right") then
			ang:RotateAroundAxis(self:GetUp(), -90)
		elseif (self:GetClass() == "zrms_conveyorbelt_c_left") then
			ang:RotateAroundAxis(self:GetUp(), 90)
		else
			ang:RotateAroundAxis(self:GetUp(), 0)
		end

		amodule:SetAngles(ang)
		amodule:SetPos(pos)
	end

	amodule:SetBuildMode(false)
	self.connected_module = amodule
	self.connected_module.connected_Parent = self
	self:SetHasChild(true)
	self.PhysgunDisabled = true
	self.connected_module.PhysgunDisabled = true
	self:SetBuildMode(false)
	local rphys = amodule:GetPhysicsObject()

	if (rphys:IsValid()) then
		rphys:Wake()
		rphys:EnableMotion(false)
	end

	local sphys = self:GetPhysicsObject()

	if (sphys:IsValid()) then
		sphys:Wake()
		sphys:EnableMotion(false)
	end

	if (string.sub(amodule:GetClass(), 1, 12) == "zrms_refiner") then
		zrmine.f.CreateEffectTable(nil, "zrmine_sfx_connect_refinery", self, self:GetAngles(), self:GetPos())
	else
		zrmine.f.CreateEffectTable(nil, "zrmine_sfx_connect_belt", self, self:GetAngles(), self:GetPos())
	end

	if (amodule:GetClass() == "zrms_inserter") then
		timer.Simple(1, function()
			if (IsValid(self) and IsValid(amodule)) then
				amodule:Inserter_SearchEndPart()
			end
		end)
	end

	hook.Run("zrms_Verify_Inserter_connection", self)
end

function ENT:Detach_Self()
	if (IsValid(self.connected_Parent)) then
		if (self.connected_Parent:GetClass() == "zrms_splitter") then
			if (self.splitterPos == 1) then
				self.splitterPos = 0
				self.connected_Parent.connected_module01 = nil
			elseif (self.splitterPos == 2) then
				self.splitterPos = 0
				self.connected_Parent.connected_module02 = nil
			end

			self.connected_Parent:UpdateSplitter()
		elseif (string.sub(self.connected_Parent:GetClass(), 1, 11) == "zrms_sorter") then
			if (self.sorterPos == 1) then
				self.sorterPos = 0
				self.connected_Parent.connected_module01 = nil
			elseif (self.sorterPos == 2) then
				self.sorterPos = 0
				self.connected_Parent.connected_module02 = nil
			end

			self.connected_Parent:UpdateSorter()
		else
			self.connected_Parent:SetHasChild(false)
			self.connected_Parent.connected_module = nil
		end

		self.connected_Parent = nil
		self.PhysgunDisabled = false
		self:SetBuildMode(true)
		local phys = self:GetPhysicsObject()

		if (phys:IsValid()) then
			phys:Wake()
			phys:EnableMotion(true)
		end

		if (self:GetClass() ~= "zrms_inserter") then
			hook.Run("zrms_Verify_Inserter_connection", self)
		end

		self.Inserter_EndPart = nil
		self:SetInserterEndPart(-1)
	else
		self.PhysgunDisabled = false
		self:SetBuildMode(true)
		local phys = self:GetPhysicsObject()

		if (phys:IsValid()) then
			phys:Wake()
			phys:EnableMotion(true)
		end

		if (self:GetClass() ~= "zrms_inserter") then
			hook.Run("zrms_Verify_Inserter_connection", self)
		end
	end
end

function ENT:OnRemove()
	self:Detach_Self()
end

function ENT:Verify_Inserter_Connection()
	if (IsValid(self.Inserter_EndPart)) then
		if (self.Inserter_EndPart:GetBuildMode() == true) then
			self.Inserter_EndPart = nil
			self:SetInserterEndPart(-1)
		end
	else
		self:Inserter_SearchEndPart()
	end
end

function ENT:Inserter_SearchEndPart()
	local attach = self:GetAttachment(self:LookupAttachment("output"))
	local searchPos = attach.Pos + attach.Ang:Forward() * 7
	local searchSize = 80
	debugoverlay.Sphere(searchPos, searchSize, 3, Color(0, 255, 0, 100), false)
	local validEnts = {}

	for k, v in pairs(ents.FindInSphere(searchPos, searchSize)) do
		--[[&& IsValid(v.connected_Parent)]]
		if (string.sub(v:GetClass(), 1, 17) == "zrms_conveyorbelt" and v ~= self and v:GetBuildMode() == false) then
			table.insert(validEnts, v)
		end
	end

	local nearestEnt = self:Inserter_FindNearestEntity(validEnts, searchPos, searchSize)

	if (IsValid(nearestEnt)) then
		self.Inserter_EndPart = nearestEnt
		self:SetInserterEndPart(nearestEnt:EntIndex())
	end
end

function ENT:Inserter_FindNearestEntity(aents, pos, range)
	local nearestEnt

	for i, entity in ipairs(aents) do
		local distance = pos:Distance(entity:GetPos())

		if (distance <= range) then
			nearestEnt = entity
			range = distance
		end
	end

	return nearestEnt
end

-- Checks if we overlap with a invalid entity
function ENT:ValidPosChecker(tmodule)
	local attach = self:GetAttachment(self:LookupAttachment("output"))
	local pos
	local size

	if (self:GetClass() == "zrms_conveyorbelt_c_left") then
		size = 35
		pos = attach.Pos + attach.Ang:Forward() * 30
	elseif (self:GetClass() == "zrms_conveyorbelt_c_right") then
		size = 35
		pos = attach.Pos + attach.Ang:Forward() * -40
	elseif (self:GetClass() == "zrms_conveyorbelt_s") then
		size = 35
		pos = attach.Pos + attach.Ang:Forward() * -20
	else
		size = 40
		pos = attach.Pos + attach.Ang:Forward() * -30
	end

	if (tmodule:GetClass() == "zrms_inserter" or tmodule:GetClass() == "zrms_conveyorbelt_s") then
		size = size / 1.5
	end

	debugoverlay.Sphere(pos, size, 3, Color(255, 255, 0, 100), false)
	local NotValid = false

	for k, v in pairs(ents.FindInSphere(pos, size)) do
		if (v ~= self and v ~= tmodule and string.sub(v:GetClass(), 1, 17) == "zrms_conveyorbelt" and not v:GetBuildMode()) then
			debugoverlay.Sphere(v:GetPos(), 5, 3, Color(255, 0, 0, 100), true)
			NotValid = true
			zrmine.f.Notify(self:CPPIGetOwner(), zrmine.language.Module_NoSpace, 1)
			break
		end
	end

	return NotValid
end

-- Main function
function ENT:Think()
	if (self.FullInitialized == false) then return end

	if ((self.lastthink or -1) < CurTime()) then
		self.lastthink = CurTime() + 1
		self:ModuleUpdate()
	end
end

function ENT:ModuleUpdate()
	if (self:GetCurrentState() == "WAITING_FOR_ORDER" and self:Return_StoredAmount() > 0) then
		local cm = self.connected_module

		if (IsValid(cm) and cm:Return_StoredAmount() < cm.HoldAmount) then
			if (cm:GetClass() == "zrms_splitter") then
				if (cm:Return_StoredAmount() < zrmine.config.SplitterBelt_Capacity) then
					self:Transport()
				end
			else
				self:Transport()
			end
		elseif (self:GetClass() == "zrms_inserter") then
			if (IsValid(self.Inserter_EndPart)) then
				if (self.Inserter_EndPart:Return_StoredAmount() < self.Inserter_EndPart.HoldAmount) then
					self:Transport()
				end
			else
				self:Transport()
			end
		else
			self:CreateAnim_Table("idle", 1)
		end
	end
end

function ENT:Transport()
	-- Sets the current state to busy
	self:SetCurrentState("TRANSPORTING")
	local SendResource = self:FindValidResource()
	-- Plays the Transport gravel animation
	local gravel_animTime = (1 / self.TransportSpeed) * self.GravelAnimTime
	self:Play_GravelGive_anim(gravel_animTime, self.TransportSpeed, SendResource)
	self:CreateAnim_Table("output", 0.25)

	-- Sends the gravel to the connected module if not a inserter
	if (self:GetClass() == "zrms_inserter") then
		timer.Simple(self.TransportSpeed - 1.8, function()
			if (IsValid(self)) then
				-- Here we send the resources or show the discard gravel effect
				if (IsValid(self.Inserter_EndPart)) then
					self:Send_Resources(self.Inserter_EndPart, SendResource)
					zrmine.f.CreateInsertEffect(self.Inserter_EndPart, SendResource)
					local effectPos03 = self:GetAttachment(self:LookupAttachment("output")).Pos + self:GetUp() * 24 + self:GetForward() * 5
					local effectAng03 = self:GetAngles()
					zrmine.f.CreateEffectTable("zrms_refiner_dirt02", "zrmine_sfx_refinerdirt", self, effectAng03, effectPos03)
				else
					local sendAmount = zrmine.f.Calculate_AmountCap(self.StoredResource[SendResource], self.TransportAmount)
					self:Destroy_Resource(SendResource, sendAmount)
				end
			end
		end)

		timer.Simple(self.TransportSpeed + 0.3, function()
			if (IsValid(self)) then
				self:SetCurrentState("WAITING_FOR_ORDER")

				if (self:Return_StoredAmount() <= 0) then
					self:CreateAnim_Table("idle", 1)
				end
			end
		end)
	else
		timer.Simple(self.TransportSpeed, function()
			if (IsValid(self)) then
				-- Here we send the resources or show the discard gravel effect
				local cm = self.connected_module

				if IsValid(cm) then
					if (string.sub(cm:GetClass(), 1, 17) == "zrms_conveyorbelt") then
						if (cm:Return_StoredAmount() < cm.HoldAmount) then
							self:Send_Resources(cm, SendResource)
							zrmine.f.CreateInsertEffect(cm, SendResource)
						end
					elseif (string.sub(cm:GetClass(), 1, 12) == "zrms_refiner") then
						if (cm:Return_StoredAmount() < cm.HoldAmount) then
							self:Send_Resources(cm, SendResource)
						end
					elseif (string.sub(cm:GetClass(), 1, 13) == "zrms_splitter") then
						if (cm:Return_StoredAmount() < zrmine.config.SplitterBelt_Capacity) then
							self:Send_Resources(cm, SendResource)
							zrmine.f.CreateInsertEffect(cm, SendResource)
						end
					elseif (string.sub(cm:GetClass(), 1, 11) == "zrms_sorter") then
						if (cm:Return_StoredAmount() < cm.HoldAmount) then
							self:Send_Resources(cm, SendResource)
							zrmine.f.CreateInsertEffect(cm, SendResource)
						end
					elseif (string.sub(cm:GetClass(), 1, 13) == "zrms_inserter") then
						if (cm:Return_StoredAmount() < cm.HoldAmount) then
							self:Send_Resources(cm, SendResource)
							zrmine.f.CreateInsertEffect(cm, SendResource)
						end
					end
				else
					local sendAmount = zrmine.f.Calculate_AmountCap(self.StoredResource[SendResource], self.TransportAmount)
					self:Destroy_Resource(SendResource, sendAmount)
				end

			end
		end)
		timer.Simple(self.TransportSpeed + 0.1, function()
			if (IsValid(self)) then
				self:SetCurrentState("WAITING_FOR_ORDER")

				if (self:Return_StoredAmount() <= 0) then
					zrmine.f.CreateAnimTable(self, "idle", 1)
				end
			end
		end)
	end
end

function ENT:Play_GravelGive_anim(speed, resettime, rtype)
	zrmine.f.CreateAnimTable(self.outputgravel, "output", speed)

	if (rtype == "Iron") then
		self.outputgravel:SetSkin(1)
	elseif (rtype == "Bronze") then
		self.outputgravel:SetSkin(2)
	elseif (rtype == "Silver") then
		self.outputgravel:SetSkin(3)
	elseif (rtype == "Gold") then
		self.outputgravel:SetSkin(4)
	elseif (rtype == "Coal") then
		self.outputgravel:SetSkin(5)
	else
		self.outputgravel:SetSkin(0)
	end

	timer.Simple(0.1, function()
		if (IsValid(self)) then
			self.outputgravel:SetNoDraw(false)
		end
	end)

	timer.Simple(resettime, function()
		if (IsValid(self)) then
			self.outputgravel:SetNoDraw(true)
		end
	end)
end

-- Spawns ore
function ENT:SpawnResource(pos, oreamount, bg, rType)
	local ent = ents.Create("zrms_resource")
	ent:SetAngles(Angle(math.random(0, 360), math.random(0, 360), math.random(0, 360)))
	ent:SetPos(pos)
	ent:Spawn()
	ent:Activate()
	ent:SetBodygroup(0, bg)

	if (rType == "Iron") then
		ent:SetSkin(0)
	elseif (rType == "Bronze") then
		ent:SetSkin(1)
	elseif (rType == "Silver") then
		ent:SetSkin(2)
	elseif (rType == "Gold") then
		ent:SetSkin(3)
	elseif (rType == "Coal") then
		ent:SetSkin(4)
	end

	ent:SetResourceType(tostring(rType))
	ent:SetResourceAmount(oreamount)

	return ent
end

-- Damage Stuff
function ENT:OnTakeDamage(dmg)
	self:TakePhysicsDamage(dmg)
	local damage = dmg:GetDamage()
	local entHealth = zrmine.config.Damageable["Conveyorbelt"].EntityHealth

	if (entHealth > 0) then
		self.CurrentHealth = (self.CurrentHealth or entHealth) - damage

		if (self.CurrentHealth <= 0) then
			self:Destruct()
			self:Remove()
		end
	end
end

function ENT:Destruct()
	local vPoint = self:GetPos()
	local effectdata = EffectData()
	effectdata:SetStart(vPoint)
	effectdata:SetOrigin(vPoint)
	effectdata:SetScale(1)
	util.Effect("Explosion", effectdata)
end

-- Animation
function ENT:CreateAnim_Table(anim, speed)
	if (self:LookupSequence(anim) ~= self:GetSequence()) then
		zrmine.f.CreateAnimTable(self, anim, speed)
	end
end

-- Custom Hook
hook.Add("zrms_Verify_Inserter_connection", "Update our Inserter connection", function(caller)
	if (IsValid(caller)) then
		for k, v in pairs(ents.FindByClass("zrms_inserter")) do
			if (zrmine.config.SharedOwnership and v:GetBuildMode() == false) then
				v:Verify_Inserter_Connection()
			else
				local pl = zrmine.f.GetOwner(caller)

				if (pl and IsValid(pl) and zrmine.f.IsOwner(pl, v) and v:GetBuildMode() == false) then
					v:Verify_Inserter_Connection()
				end
			end
		end
	end
end)
