Small Problem

Hey guys, I’m using DerpInv and it’s broken.

This is the error I have: [addons\derprp inv\lua\autorun\server\drpinv.lua:95] attempt to index field ‘inv’ (a nil value)

And this is the file that the error points me towards:



AddCSLuaFile("autorun/client/cl_drpinv.lua")
AddCSLuaFile("autorun/drpshared.lua")
AddCSLuaFile("autorun/colchat.lua")

require("glon")

-- CONVARS --

local maxitems = CreateConVar( "drp_maxitems", "10", { FCVAR_REPLICATED, FCVAR_ARCHIVE } )
local maxguns = CreateConVar( "drp_maxguns", "10", { FCVAR_REPLICATED, FCVAR_ARCHIVE } )
local maxshipments = CreateConVar( "drp_maxshipments", "2", { FCVAR_REPLICATED, FCVAR_ARCHIVE } )
local maxfood = CreateConVar( "drp_maxfood", "6", { FCVAR_REPLICATED, FCVAR_ARCHIVE } )

local shouldlog = CreateConVar( "drp_printinfo", "0", { FCVAR_REPLICATED, FCVAR_ARCHIVE } )

-- HOOKS --

function plyjoin(ply)
	local path = "drpinv/" .. ply:UniqueID() .. ".txt"
	if file.Exists(path) then
		ply.inv = glon.decode(file.Read(path))
		ply:ColChat("XtraGaming", Color(0,255,0), "Welcome back " .. ply:Nick() .. "! Your inventory has been loaded.")
	else
		ply.inv = { }
		ply.inv._size = 0 -- hacky, hope no one names an ent _size
		ply.inv.sweps = {}
		ply.inv.ships = {}
		ply.inv.foods = {}
		ply:SaveInv()
		ply:ColChat("XtraGaming", Color(0,255,0), "We have a permanently saving inventory! Press F2 to open it up.")
	end
	if shouldlog:GetBool() then
		print("[DrpInv]: Loaded data for " .. ply:Nick())
	end
	ply:SendInv()
	
	ply.canuse = true --to stop textspam/multiple pickups
	
	--since darkrp ents dont check for uninitialized vars we have to init the max vars incase someone hasnt spawned anythign "legit" yet
	if not ply.maxFoods then
		ply.maxFoods = 0
	end
	
	if not ply.maxDrugs then
		ply.maxDrugs = 0
	end
end
hook.Add("PlayerInitialSpawn","DrpInvSpawn",plyjoin)

local function plydis(ply)
	ply:SaveInv()
	timer.Destroy("canuse" .. ply:UniqueID())
end
hook.Add("PlayerDisconnected","DrpPlyLeave",plydis)

function plyuse(ply,cmd,args,ent2)
	local ent = ent2 or ply:GetEyeTrace().Entity

	if  items[ent:GetClass()] then
		if !ply.inv[ent:GetClass()] then
			ply.inv[ent:GetClass()] = 0
		end
		
		local max = items[ent:GetClass()]["max"]
		
		if max > 0 and ply.inv[ent:GetClass()] >= max and !ply:IsVip() then
			ply:ColChat("XtraGaming", Color(0,255,0), "You have reached the maximum amount for that item!")
			ply.canuse = false
			timer.Create("canuse" .. ply:UniqueID(), 1, 1,function() ply.canuse = true end)
			return false
		end
		
		ply.inv._size = ply.inv._size + 1
		ply:AddItem(ent:GetClass(), 1)
		
		ply:EmitSound("items/ammo_pickup.wav", 100, 100)
		
		local vec = ply:GetPos() - ent:GetPos()
		ent:GetPhysicsObject():ApplyForceCenter(Vector(0,0,450))
		ent:SetNotSolid(true)
		
		local ed = EffectData()
		ed:SetEntity(ent)
		util.Effect( "propspawn", ed )	
		
		ent:Remove()
		
		ply.canuse = false
		timer.Create("canuse" .. ply:UniqueID(), 1, 1,function() ply.canuse = true end)
		return false
	end
	-- now handle the stupid special cases
	-- sweps first
	if ent:GetClass() == "spawned_weapon" and weps[ent.weaponclass] then		
		if #table.ClearKeys(ply.inv.sweps) >= maxguns:GetInt() and !ply:IsVip() then
			if cmd == "lawl" then
				ply:Give(weps[ent.weaponclass])
			end
			ply:ColChat("DrpInv", Color(0,255,0), "You have reached the maximum amount of sweps!")
			ply.canuse = false
			timer.Create("canuse" .. ply:UniqueID(), 1, 1,function() ply.canuse = true end)
			return false
		end
		
		local gun = {
			model = ent:GetModel(),
			class = ent.weaponclass
		}
		
		ply.inv._size = ply.inv._size + 1
		ply:AddSwep(gun)

		ply:EmitSound("items/ammo_pickup.wav", 100, 100)
		
		local vec = ply:GetPos() - ent:GetPos()
		ent:GetPhysicsObject():ApplyForceCenter(Vector(0,0,400))
		ent:SetNotSolid(true)
		
		local ed = EffectData()
		ed:SetEntity(ent)
		util.Effect( "propspawn", ed )	
		
		SafeRemoveEntityDelayed(ent, 0.75)
		
		ply.canuse = false
		timer.Create("canuse" .. ply:UniqueID(), 1, 1,function() ply.canuse = true end)
		return false
	end
	-- now food
	if ent:GetClass() == "spawned_food" and foodies[ent:GetModel()] then
		
		if #table.ClearKeys(ply.inv.foods) >= maxfood:GetInt() and !ply:IsVip() then
			ply:ColChat("DrpInv", Color(0,255,0), "You have reached the maximum amount of food!")
			ply.canuse = false
			timer.Create("canuse" .. ply:UniqueID(), 1, 1,function() ply.canuse = true end)
			return false
		end
		
		local food = {
			model = ent:GetModel(),
			amount = ent.FoodEnergy
		}
		
		ply.inv._size = ply.inv._size + 1
		ply:AddFood(food)

		ply:EmitSound("items/ammo_pickup.wav", 100, 100)
		
		local vec = ply:GetPos() - ent:GetPos()
		ent:GetPhysicsObject():ApplyForceCenter(Vector(0,0,800)) -- fatty melons need a bigger kick
		ent:SetNotSolid(true)
		
		local ed = EffectData()
		ed:SetEntity(ent)
		util.Effect( "propspawn", ed )	
		
		SafeRemoveEntityDelayed(ent, 0.75)
		
		ply.canuse = false
		timer.Create("canuse" .. ply:UniqueID(), 1, 1,function() ply.canuse = true end)
		return false
	end
	-- lastly shipments
	if ent:GetClass() == "spawned_shipment" then
		
		if #table.ClearKeys(ply.inv.ships) >= maxshipments:GetInt() and !ply:IsVip() then
			ply:ColChat("DrpInv", Color(0,255,0), "You have reached the maximum amount of shipments!")
			ply.canuse = false
			timer.Create("canuse" .. ply:UniqueID(), 1, 1,function() ply.canuse = true end)
			return false
		end
		
		local ship = {
			cont = ent.dt.contents,
			count = ent.dt.count
		}
		
		ply.inv._size = ply.inv._size + 1
		ply:AddShip(ship)

		ply:EmitSound("items/ammo_pickup.wav", 100, 100)
		
		local vec = ply:GetPos() - ent:GetPos()
		ent:GetPhysicsObject():ApplyForceCenter(Vector(0,0,1500)) -- forget what i said aboot melons...
		ent:SetNotSolid(true)
		
		local ed = EffectData()
		ed:SetEntity(ent)
		util.Effect( "propspawn", ed )	
		
		SafeRemoveEntityDelayed(ent, 0.75)
		
		ply.canuse = false
		timer.Create("canuse" .. ply:UniqueID(), 1, 1,function() ply.canuse = true end)
		return false
	end
	return true
end
concommand.Add("drp_pickupitem",plyuse)

local function plysay(ply, text, tm, death)
    if string.sub(text, 1, 4) == "!inv" then
		ply:ConCommand("drp_showinv")
        return ""
    end

end
hook.Add("PlayerSay","DrpPlySay",plysay)

-- META --
--- inv ---
local meta = FindMetaTable("Player")

function meta:SaveInv()
	file.Write("drpinv/" .. self:UniqueID() .. ".txt", glon.encode(self.inv))
	if shouldlog:GetBool() then
		print("[DrpInv]: Saved data for " .. self:Nick())
	end
end

function meta:SendInv()
	umsg.Start("clearinv", self)
	umsg.End()
	
	for k,v in pairs(self.inv) do
		if type(v) != "table" and k != "_size" then
			umsg.Start("item", self)
				umsg.String(k)
				umsg.Short(v)
			umsg.End()
		end
	end
	
	for k,v in pairs(self.inv.sweps) do
		self:SendSwep(v, k)
	end
	
	for k,v in pairs(self.inv.foods) do
		self:SendFood(v, k)
	end
	
	for k,v in pairs(self.inv.ships) do
		self:SendShip(v, k)
	end
	
	if shouldlog:GetBool() then
		print("[DrpInv]: Sent inventory to " .. self:Nick())
	end
end

--- items ---

function meta:SendItem(str)
	umsg.Start("item", self)
		umsg.String(str)
		umsg.Short(self.inv[str])
	umsg.End()
end

function meta:SetItem(str, amt)
	if items[str] then
		self.inv[str] = amt
	else
		if shouldlog:GetBool() then
			print("[DrpInv]: Tried to add invalid item!")
		end
	end
	self:SaveInv()
	self:SendItem(str)
	if shouldlog:GetBool() then
		print("[DrpInv]: " .. self:Nick() .. " had item " .. str .. " set to " .. amt .. "!")
	end
end

function meta:AddItem(str, amt)
	if items[str] then
		self.inv[str] = self.inv[str] + amt
	else
		if shouldlog:GetBool() then
			print("[DrpInv]: Tried to add invalid item!")
		end
	end
	self:SaveInv()
	self:SendItem(str)
	if shouldlog:GetBool() then
		print("[DrpInv]: " .. self:Nick() .. " added " .. amt .. " to " .. str .. "!")
	end
end

--- sweps ---

function meta:AddSwep(tbl)
	local key = #self.inv.sweps + 1
	self.inv.sweps[key] = tbl
	self:SaveInv()
	self:SendSwep(tbl, key)
	if shouldlog:GetBool() then
		print("[DrpInv]: " .. self:Nick() .. " added swep with class " .. tbl.class .. "!")
	end
end

function meta:RemoveSwep(key)
	self.inv.sweps[key] = nil
	self:SaveInv()
	self:SendSwepRemove(key)
end

function meta:SendSwep(tbl,key)
	umsg.Start("swep", self)
		umsg.Short(key)
		umsg.String(tbl.model)
		umsg.String(tbl.class)
	umsg.End()
end

function meta:SendSwepRemove(key)
	umsg.Start("swepgone", self)
		umsg.Short(key)
	umsg.End()
end

--- food ---

function meta:AddFood(tbl)
	local key = #self.inv.foods + 1
	self.inv.foods[key] = tbl
	self:SaveInv()
	self:SendFood(tbl, key)
	if shouldlog:GetBool() then
		print("[DrpInv]: " .. self:Nick() .. " added food with amt " .. tbl.amount .. "!")
	end
end

function meta:RemoveFood(key)
	self.inv.foods[key] = nil
	self:SaveInv()
	self:SendFoodRemove(key)
end

function meta:SendFood(tbl,key)
	umsg.Start("food", self)
		umsg.Short(key)
		umsg.String(tbl.model)
		umsg.Short(tbl.amount)
	umsg.End()
end

function meta:SendFoodRemove(key)
	umsg.Start("foodgone", self)
		umsg.Short(key)
	umsg.End()
end

--- ships ---

function meta:AddShip(tbl)
	local key = #self.inv.ships + 1
	self.inv.ships[key] = tbl
	self:SaveInv()
	self:SendShip(tbl, key)
	if shouldlog:GetBool() then
		print("[DrpInv]: " .. self:Nick() .. " added shipment " .. tbl.contents .. "!")
	end
end

function meta:RemoveShip(key)
	self.inv.ships[key] = nil
	self:SaveInv()
	self:SendShipRemove(key)
end

function meta:SendShip(tbl,key)
	umsg.Start("ship", self)
		umsg.Short(key)
		umsg.Short(tbl.cont)
		umsg.Short(tbl.count)
	umsg.End()
end

function meta:SendShipRemove(key)
	umsg.Start("shipgone", self)
		umsg.Short(key)
	umsg.End()
end

-- CONCOMMANDS --
--- items ---
local function dropitem(ply, cmd, args)
	local item = args[1]
	if !item or ply.inv[item] == nil then
		if shouldlog:GetBool() then
			print("[DrpInv]: " .. ply:Nick() .. " tried to use invalid item " .. item .. "!")
		end
		return
	end
	
	if ply.inv[item] < 1 then
		if shouldlog:GetBool() then
			print("[DrpInv]: " .. ply:Nick() .. " tried to spawn something he had none of!")
		end
		ply:ColChat("DrpInv", Color(0,255,0), "Nice try. You dont have any of that left.")
		return
	end
	
	local pos = ply:EyePos()
	local tracedata = {}
	tracedata.start = pos
	tracedata.endpos = pos+(ply:GetForward()*150)
	tracedata.filter = ply
	local tr = util.TraceLine(tracedata)
	
	local ent = ents.Create(item)
	ent:SetPos(tr.HitPos + tr.HitNormal*10)
	ent.dt.owning_ent = ply
	ent.ShareGravgun = true
	ent.nodupe = true
	ent:Spawn()
	ent:Activate()
	
	if shouldlog:GetBool() then
		print("[DrpInv]: " .. ply:Nick() .. " dropped item " .. item .. "!")
	end
	
	ply.inv._size = ply.inv._size - 1
	ply:AddItem(item, -1)
end
concommand.Add("drp_dropitem", dropitem)

local function useitem(ply, cmd, args)
	local item = args[1]
	if !item or ply.inv[item] == nil then
		if shouldlog:GetBool() then
			print("[DrpInv]: " .. ply:Nick() .. " tried to use invalid item " .. item .. "!")
		end
		return
	end
	
	if ply.inv[item] < 1 then
		if shouldlog:GetBool() then
			print("[DrpInv]: " .. ply:Nick() .. " tried to spawn something he had none of!")
		end
		ply:ColChat("DrpInv", Color(0,255,0), "Nice try. You dont have any of that left.")
		return
	end
	
	local ent = ents.Create(item)
	ent:SetPos(ply:GetPos())
	if ent.dt then
		ent.dt.owning_ent = ply
	end
	ent.ShareGravgun = true
	ent.nodupe = true
	ent:Spawn()
	ent:Activate()
	
	if not ply.maxFoods then
		ply.maxFoods = 0
	end
	
	ent:Use(ply, ply)
	
	if shouldlog:GetBool() then
		print("[DrpInv]: " .. ply:Nick() .. " dropped and used item " .. item .. "!")
	end
	
	ply.inv._size = ply.inv._size - 1
	ply:AddItem(item, -1)
end
concommand.Add("drp_useitem", useitem)

--- sweps ---
local function dropswep(ply, cmd, args)
	local item = tonumber(args[1])
	if !item or ply.inv.sweps[item] == nil then
		if shouldlog:GetBool() then
			print("[DrpInv]: " .. ply:Nick() .. " tried to use invalid swep " .. item .. "!")
		end
		return
	end
	
	local pos = ply:EyePos()
	local tracedata = {}
	tracedata.start = pos
	tracedata.endpos = pos+(ply:GetForward()*150)
	tracedata.filter = ply
	local tr = util.TraceLine(tracedata)
	
	local ent = ents.Create("spawned_weapon")
	ent:SetPos(tr.HitPos + tr.HitNormal*10)
	ent:SetModel(ply.inv.sweps[item].model)
	ent.weaponclass = ply.inv.sweps[item].class
	ent.ShareGravgun = true
	ent.nodupe = true
	ent:Spawn()
	ent:Activate()
	
	if shouldlog:GetBool() then
		print("[DrpInv]: " .. ply:Nick() .. " dropped swep " .. ply.inv.sweps[item].class .. "!")
	end
	
	ply.inv._size = ply.inv._size - 1
	ply:RemoveSwep(item)
end
concommand.Add("drp_dropswep", dropswep)

local function useswep(ply, cmd, args)
	local item = tonumber(args[1])
	if !item or ply.inv.sweps[item] == nil then
		if shouldlog:GetBool() then
			print("[DrpInv]: " .. ply:Nick() .. " tried to use invalid swep " .. item .. "!")
		end
		return
	end
	
	local ent = ents.Create("spawned_weapon")
	ent:SetPos(ply:GetPos())
	ent:SetModel(ply.inv.sweps[item].model)
	ent.weaponclass = ply.inv.sweps[item].class
	ent.ShareGravgun = true
	ent.nodupe = true
	ent:Spawn()
	ent:Activate()
	
	ent:Use(ply, ply)
	
	if shouldlog:GetBool() then
		print("[DrpInv]: " .. ply:Nick() .. " dropped and used swep " .. item .. "!")
	end
	
	ply.inv._size = ply.inv._size - 1
	ply:RemoveSwep(item)
end
concommand.Add("drp_useswep", useswep)

--- foodies ---
local function dropfood(ply, cmd, args)
	local item = tonumber(args[1])
	if !item or ply.inv.foods[item] == nil then
		if shouldlog:GetBool() then
			print("[DrpInv]: " .. ply:Nick() .. " tried to use invalid food " .. item .. "!")
		end
		return
	end
	
	local pos = ply:EyePos()
	local tracedata = {}
	tracedata.start = pos
	tracedata.endpos = pos+(ply:GetForward()*150)
	tracedata.filter = ply
	local tr = util.TraceLine(tracedata)
	
	local ent = ents.Create("spawned_food")
	ent:SetPos(tr.HitPos + tr.HitNormal*10)
	ent:SetModel(ply.inv.foods[item].model)
	ent.FoodEnergy = ply.inv.foods[item].amount
	ent.ShareGravgun = true
	ent.nodupe = true
	ent:Spawn()
	ent:Activate()
	
	if shouldlog:GetBool() then
		print("[DrpInv]: " .. ply:Nick() .. " dropped food with amount " .. ent.FoodEnergy .. "!")
	end
	
	ply.inv._size = ply.inv._size - 1
	ply:RemoveFood(item)
end
concommand.Add("drp_dropfood", dropfood)

local function usefood(ply, cmd, args)
	local item = tonumber(args[1])
	if !item or ply.inv.foods[item] == nil then
		if shouldlog:GetBool() then
			print("[DrpInv]: " .. ply:Nick() .. " tried to use invalid food " .. item .. "!")
		end
		return
	end
	
	local ent = ents.Create("spawned_food")
	ent:SetPos(ply:GetPos())
	ent:SetModel(ply.inv.foods[item].model)
	ent.FoodEnergy = ply.inv.foods[item].amount
	ent.ShareGravgun = true
	ent.nodupe = true
	ent:Spawn()
	ent:Activate()
	
	ent:Use(ply, ply)
	
	if shouldlog:GetBool() then
		print("[DrpInv]: " .. ply:Nick() .. " dropped and used food with amount " .. ent.FoodEnergy .. "!")
	end
	
	ply.inv._size = ply.inv._size - 1
	ply:RemoveFood(item)
end
concommand.Add("drp_usefood", usefood)

--- ships ---
local function dropship(ply, cmd, args)
	local item = tonumber(args[1])
	if !item or ply.inv.ships[item] == nil then
		if shouldlog:GetBool() then
			print("[DrpInv]: " .. ply:Nick() .. " tried to use invalid shipment " .. item .. "!")
		end
		return
	end
	
	local pos = ply:EyePos()
	local tracedata = {}
	tracedata.start = pos
	tracedata.endpos = pos+(ply:GetForward()*150)
	tracedata.filter = ply
	local tr = util.TraceLine(tracedata)
	
	local ent = ents.Create("spawned_shipment")
	ent:SetPos(tr.HitPos + tr.HitNormal*10)
	ent:SetContents(ply.inv.ships[item].cont, ply.inv.ships[item].count, 10) -- why not.
	ent.nodupe = true
	ent:Spawn()
	ent:Activate()
	
	if shouldlog:GetBool() then
		print("[DrpInv]: " .. ply:Nick() .. " dropped shipment of key " .. ply.inv.ships[item].cont .. "!")
	end
	
	ply.inv._size = ply.inv._size - 1
	ply:RemoveShip(item)
end
concommand.Add("drp_dropship", dropship)


Use [lua] tags please