Add Weapon Saving to YOUR gamemode!

After much work on it, and some help from the people here at Facepunch, I was able to manufacture a bit of code that allows the saving of weapons upon death or disconnect and loading them upon spawn. It took me a while to make and even my seasoned lua mentor was unable to conjure such a code, so i figured it might be helpful to more than just me. So here it is, free to use and edit in what way you will… My weapon saving code! Oh, just give me a tiny bit O’ credit somewhere if you have the chance. Not required but requested.


//Weapon Saving Code
//Made by Salmonman
//For use in making gamemodes
//Stick this code in init.lua


function GM:PlayerLoadout( ply )

		//Give the ammunition. This can be taken out if you want the player to spawn with weps but no ammo.
		ply:RemoveAllAmmo()
		ply:GiveAmmo( 256,	"Pistol", 		true )
		ply:GiveAmmo( 256,	"SMG1", 		true )
		ply:GiveAmmo( 5,	"grenade", 		true )
		ply:GiveAmmo( 64,	"Buckshot", 	true )
		ply:GiveAmmo( 32,	"357", 			true )
		ply:GiveAmmo( 32,	"XBowBolt", 	true )
		ply:GiveAmmo( 6,	"AR2AltFire",   true )
		ply:GiveAmmo( 100,	"AR2", 			true )
		
		//Sets default weapons. These can be atken out if you want the player to start with nothing.
		
		ply:Give("weapon_physgun")
		ply:Give("weapon_physcannon")
		ply:Give("gmod_camera")
		ply:Give("gmod_tool")
		
		//Loads weapons from a file. The folders and filename can be changed, but not the UniqueID part.

	local filename = "wep_data/" .. tostring( ply:UniqueID() ) .. "loadout.txt"

	if ( file.Exists(filename) ) then
		local read = file.Read( filename )
		local loadout = glon.decode( read )
		for k, v in pairs( loadout ) do
			ply:Give( v )
		end 
	end
	
	//Also removable upon your prefference, This code says, if you have a physgun (which you will if you keep the//
	//other code up top), make that the weapon you will have selected on spawn.
	
	if(ply:HasWeapon("weapon_physgun")) then
	ply:SelectWeapon("weapon_physgun")
	end
	
	return true

end

//This your weapons to a file. If you edited the file path above, do the same here.

function SaveWeapons( ply )
	local filename = "wep_data/" .. tostring( ply:UniqueID() ) .. "loadout.txt"
	local wepclasstable = {}
		for d, f in pairs( ply:GetWeapons() ) do
			table.insert( wepclasstable, f:GetClass() )
		end 
	local data = glon.encode( wepclasstable )
	file.Write( filename, data )
end
//These hook adds make it so weapons are saved when the player dies or disconnects. These are the BARE MINIMUM
//if you want it to work %100, but can be removed for any reason, like you want the player to kill themself
//before they leave in order to keep their weapons.
hook.Add( "DoPlayerDeath", "SaveWeapons", SaveWeapons )
hook.Add( "PlayerDisconnected", "SaveWeapons", SaveWeapons )

//Since this saves the players weapons forever, it is important we give the player a way to get rid of
//the ones he doesnt want anymore. When the player says !dropweapon in chat, whatever weapon he is
//currently using will be dropped. !dropweapon can be changed if you want them to say something else, but
//it seems pretty straightforward to me.

function DropWeapons( ply,text,teamonly )
if( not ply:IsPlayer() ) then return end
if( not ply:Alive() ) then return end
if( text=="!dropweapon" ) then
local weapon = ply:GetActiveWeapon()
if( weapon:GetClass()=="weapon_physgun" or weapon:GetClass()=="gmod_camera" 
or weapon:GetClass()=="gmod_tool" or weapon:GetClass()=="weapon_physcannon" ) then return end
ply:DropWeapon(weapon)
ply:SelectWeapon( "weapon_physgun" )
end
end
hook.Add( "PlayerSay","DropWeapons",DropWeapons )

//Sometimes the player may want to get rid of all his weapons (like on a build server where lots of weapons makes
//switching build tools slower by far). So this allows them to revert back to default weapons. It can be removed.

function DropAllWeapons( ply,text,teamonly )
if( not ply:IsPlayer() ) then return end
if( not ply:Alive() ) then return end
if( text=="!dropallweapons" ) then
ply:StripWeapons()
		ply:Give("weapon_physgun")
		ply:Give("weapon_physcannon")
		ply:Give("gmod_camera")
		ply:Give("gmod_tool")
ply:SelectWeapon( "weapon_physgun" )
end
end
hook.Add( "PlayerSay","DropAllWeapons",DropAllWeapons )

//The function below allows players to save their weapons manually by saying !saveweapons in chat. This can be
//changed or removed upon prefference. Of course if you changed the weapon saving path or filename above, you
//must do so here as well.

function SaveAllWeapons( ply,text,teamonly )
if( not ply:IsPlayer() ) then return end
if( not ply:Alive() ) then return end
	if( text=="!saveweapons" ) then
	local filename = "wep_data/" .. tostring( ply:UniqueID() ) .. "loadout.txt"
	local wepclasstable = {}
		for d, f in pairs( ply:GetWeapons() ) do
			table.insert( wepclasstable, f:GetClass() )
		end 
	local data = glon.encode( wepclasstable )
	file.Write( filename, data )
	end
end
hook.Add( "PlayerSay","SaveAllWeapons",SaveAllWeapons )

I know its not a finished product, but it is the lua releases forum and I AM releasing a lua.

Funny a couple of minutes ago I was thinking of this and look I found it Thank you VERY much!

YES! Someone has gotten use from something i made!

The disconnect part can be put to good use, but I don’t really like the death part. Thanks!
Have a lua king. :v:

Quite a handy snippet. A quick suggestion is you could make it save ammo as well, instead of adding unlimited ammo.

Also hook to “Shutdown” so when the map changes it’ll save.

it is nice for game modes like ehm, Surf but not on deathrun etc … garryware team based its not that good on :stuck_out_tongue: BUT I LOVE YOU FOR POSTING THIS (L) ITS AWSOME TY IM USING IT ON MY SURF :heart:

This is awesome! Cookie for you (and a Lua King!)
I have a few questions/requests tough, if I may.

Assuming that I may, here we go:
-Are the weapons also saved when somebody times out or disconnects with an error? (such as Reliable Snapshot Overflow).
-Would it be possible that it saves like every 5 minutes and/or eacht time you’ve picked up a weapon, so when the server unfortunately crashes for some reason, you still have your weapons, and something to come back for?

Thanks in advance!

To save every 5 mins do:

[lua]timer.Simple(300, function() for _, ply in pairs(player.GetAll()) do SavePlayer(ply) end end)[/lua]

And my other questions…?

This saves me some thought and time, only thing it is missing is ammo saving. :stuck_out_tongue:

Timing out still calls PlayerDisconnect.

Would be a nice addition indeed!

Thanks

If client crashed, server crash and your fucked

Im not sure, as i am but a novice lua coder, but this might work to save ammo counts.



ammos = {"Pistol","SMG1","grenade","Buckshot","357","XBowBolt","AR2AltFire","Ar2"}
	
function LoadAmmo( ply )


	ply:RemoveAllAmmo()
	local filename = "wep_data/" .. tostring( ply:UniqueID() ) .. "ammo.txt"

	if ( file.Exists(filename) ) then
		local read = file.Read( filename )
		local loadout = glon.decode( read )
		local Lnumber = 1
		for k, v in pairs( loadout ) do
			ply:GiveAmmo( v,ammos[Lnumber],true )
			Lnumber += 1
		end 
	end
	
	end
hook.Add("PlayerLoadout","LoadAmmo",LoadAmmo)
	
function SaveAmmo( ply )
	
	local filename = "wep_data/" .. tostring( ply:UniqueID() ) .. "ammo.txt"
	local ammotable = {}
	local Snumber = 1
		for d, f in pairs( ply:GetWeapons() ) do
			table.insert( ammotable, ply:GetAmmoCount(ammos[Snumber]) )
			Snumber += 1
		end 
	local data = glon.encode( ammotable )
	file.Write( filename, data )
	
	end
hook.Add( "DoPlayerDeath", "SaveAmmo", SaveAmmo )
hook.Add( "PlayerDisconnected", "SaveAmmo", SaveAmmo )


Might need some debugging.

I’m assuming this goes under lua/autorun/
Also great job, I’m going to test it now, along with the ammunition saving too?

the ammo saving will not work, lua doesnt have a += operator, and theres other niggles with the code

The PlayerDisconnect hook is not always working on timeouts/crashes etc. autosaving is the best way to make it work…

Well, i said it might need some debugging. And it does have a += operator, just not in the place you might expect.

I guess you could put it in autorun if you wanted, i intended it to be used in the development of gamemodes, but if you want it alone, then go ahead. I dont know anything about putting code in autorun, so i cant really answer that question.

This looks brilliant only problem is that the PlayerLoadout overwrites DarkRP job loadout in sv_gamemode_functions so if you could find a little fix for that it would be perfect. :smiley:

Just to point it out, Temparh, the last post before yours were more than 1 year ago.