I found a year-old code that was given up on.
/*********************************** TODO: Text data? More Powerups? Other player's EXP on screen? More damage? *******************************************/
local EXP_INC = 1 // The experience gained on every shot
local EXP_USENPC = 1 // 0 = Players as exp objects, 1 = NPCs as exp objects, 2 = both
local EXP_DEATHLOSS = 0.03 // The percentage of exp you lose on death (3 percent in this case)
local EXP_STOPATMAX = 1 // Whether or not player's stop gaining exp at the maximum level (1 for they do)
local EXP_USETXT = 0 // Whether or not to use SQL or .txt files to store the data (1 using .txt)
// Let's make the files so we can store the exp
sql.Query("CREATE TABLE IF NOT EXISTS exp_pdata('steam' TEXT NOT NULL, 'exp' INTEGER NOT NULL, 'curlevel' INTEGER NOT NULL, 'nextlevel' INTEGER NOT NULL, 'levelnum' INTEGER NOT NULL, PRIMARY KEY('steam'));")
if not file.Exists("exp_store.txt") and EXP_USETXT == 1 then file.Write("exp_store.txt","") end
// Just a quick function to print things into everyone's chat
local function PrintAll(msg) for _,v in ipairs(player.GetAll()) do v:ChatPrint(msg) end end
// Some writing/reading functions if you're using text files: still a work in progress
local function WriteData(ply)
local lines = string.Explode("\n",file.Read("exp_store.txt"))
local towrite = ""
for k,v in ipairs(lines) do
local values = string.Explode(" ",v)
if values[1] != ply:SteamID() then towrite = towrite..v
else end
end
file.Write("exp_store.txt",
file.Read("exp_store.txt")..ply:SteamID().." "..ply:GetNWInt("Exp").." "..ply:GetNWInt("CurLevel").." "..ply:GetNWInt("NextLevel").." "..ply:GetNWInt("LevelNum").."\n")
end
local function LoadData(ply)
local lines = string.Explode("\n",file.Read("exp_store.txt"))
for _,v in ipairs(lines) do
local values = string.Explode(" ",v)
if values[1] == ply:SteamID() then
ply:SetNWInt("Exp",values[2])
ply:SetNWInt("CurLevel",values[3])
ply:SetNWInt("NextLevel",values[4])
ply:SetNWInt("LevelNum",values[5])
end
end
end
// The markers at which you gain a level (always leave the 0, don't go negative or put something before 0)
levelups = {
0,
50,
100,
250,
500,
1000,
2500,
5000,
10000,
20000,
50000}
/*********************************************************** GAMEMODE HOOKS ****************************************************************/
// Give experience/level up on hit an npc or player
function AddEXP( ply, hitgroup, dmginfo )
local attacker = dmginfo:GetAttacker()
if attacker:IsPlayer() then
if EXP_STOPATMAX == 1 and attacker:GetNWInt("CurLevel") == levelups[table.Count(levelups)] then return end
attacker:SetNWInt("Exp",attacker:GetNWInt("Exp")+EXP_INC)
if table.HasValue(levelups,attacker:GetNWInt("Exp")) then
local leveln = 1
for k,v in ipairs(levelups) do if v == attacker:GetNWInt("Exp") then leveln = k end end
if leveln == table.Count(levelups) then PrintAll(attacker:Name().." has reached the maximum level!")
else PrintAll(attacker:GetName().." has now reached level "..leveln.."!") end
attacker:SetNWInt("NextLevel",levelups[leveln+1])
attacker:SetNWInt("CurLevel",levelups[leveln])
attacker:SetNWInt("LevelNum",leveln)
attacker:SendLua("surface.PlaySound(\"achievements/achievement_earned.mp3\")")
end
end
end
// Check if we want to use NPCs or Players as the object of exp
if EXP_USENPC == 1 then hook.Add("ScaleNPCDamage","NPCExp",AddEXP)
elseif EXP_USENPC == 2 then
hook.Add("ScaleNPCDamage","NPCExp",AddEXP)
hook.Add("ScalePlayerDamage","PlayerExp",AddEXP)
else hook.Add("ScalePlayerDamage","PlayerExp",AddEXP) end
// Take away experience on death
hook.Add("PlayerDeath","DownEXP",function(ply,wep,killer)
local exp = ply:GetNWInt("Exp")
local loss = math.Round(exp-exp*EXP_DEATHLOSS)
if loss < 0 then ply:SetNWInt("Exp",0)
elseif loss < ply:GetNWInt("CurLevel") then ply:SetNWInt("Exp",ply:GetNWInt("CurLevel"))
else ply:SetNWInt("Exp",loss) end
end)
// Save the values in the SQL on disconnect
hook.Add("PlayerDisconnected","UpdateEXP",function(ply)
local exp = ply:GetNWInt("Exp")
local cur = ply:GetNWInt("CurLevel")
local new = ply:GetNWInt("NextLevel")
local lvl = ply:GetNWInt("LevelNum")
if EXP_USETXT == 1 then WriteData(ply)
else
sql.Begin()
sql.Query("UPDATE exp_pdata SET exp = "..exp.." WHERE steam = "..sql.SQLStr(ply:SteamID())..";")
sql.Query("UPDATE exp_pdata SET curlevel = "..cur.." WHERE STEAM = "..sql.SQLStr(ply:SteamID())..";")
sql.Query("UPDATE exp_pdata SET nextlevel = "..new.." WHERE STEAM = "..sql.SQLStr(ply:SteamID())..";")
sql.Query("UPDATE exp_pdata SET levelnum = "..lvl.." WHERE STEAM = "..sql.SQLStr(ply:SteamID())..";")
sql.Commit()
end
end)
// Load or create the player's values on initial connection
hook.Add("PlayerInitialSpawn","RegisterEXP",function(ply)
if not tonumber(sql.QueryValue("SELECT exp FROM exp_pdata WHERE steam = "..sql.SQLStr(ply:SteamID())..";")) then
sql.Query("INSERT INTO exp_pdata VALUES("..sql.SQLStr(ply:SteamID())..",".. 0 ..",".. 0 ..","..levelups[2]..",".. 1 ..");")
ply:SetNWInt("Exp",0)
ply:SetNWInt("CurLevel",0)
ply:SetNWInt("NextLevel",levelups[2])
ply:SetNWInt("LevelNum",1)
else
sql.Begin()
ply:SetNWInt("Exp",tonumber(sql.QueryValue("SELECT exp FROM exp_pdata WHERE steam = "..sql.SQLStr(ply:SteamID())..";")))
ply:SetNWInt("CurLevel",tonumber(sql.QueryValue("SELECT curlevel FROM exp_pdata WHERE steam = "..sql.SQLStr(ply:SteamID())..";")))
ply:SetNWInt("NextLevel",tonumber(sql.QueryValue("SELECT nextlevel FROM exp_pdata WHERE steam = "..sql.SQLStr(ply:SteamID())..";")))
ply:SetNWInt("LevelNum",tonumber(sql.QueryValue("SELECT levelnum FROM exp_pdata WHERE steam = "..sql.SQLStr(ply:SteamID())..";")))
sql.Commit()
end
end)
/********************************************************** CONCOMMANDS **********************************************************************/
local chatcommands = {}
// Allow admins to change the exp level of players
concommand.Add("exp_setlevel",function(ply,cmd,args)
if ply:IsAdmin() then
leveln = tonumber(args[2])
local tar
for _,v in ipairs(player.GetAll()) do if string.match(v:Name(),args[1]) then tar = v end end
if not tar then ply:ChatPrint("Please use a valid target! (format <player name> <level>") return end
if leveln < 1 or leveln > (table.Count(levelups)+1) then ply:ChatPrint("Please select a valid level between 1 - ".. table.Count(levelups) .. ".") return end
tar:SetNWInt("Exp",levelups[leveln])
tar:SetNWInt("CurLevel",levelups[leveln])
if leveln == table.Count(levelups) then tar:SetNWInt("NextLevel",levelups[leveln])
else tar:SetNWInt("NextLevel",levelups[leveln+1]) end
ply:SetNWInt("LevelNum",leveln)
ply:ChatPrint("You set "..tar:Name().."'s level to "..leveln..".")
end
end)
table.insert(chatcommands,{"setlevel","exp_setlevel"})
// Allow admins to change the exp increment per hit via console
concommand.Add("exp_setinc",function(ply,cmd,args)
if ply:IsAdmin() then
local inc = tonumber(args[1])
if inc < 1 then ply:ChatPrint("Please use a positive integer above zero.") return end
EXP_INC = tonumber(args[1])
end
end)
table.insert(chatcommands,{"setinc","exp_setinc"})
// Allow anyone to check their current level
concommand.Add("exp_curlevel",function(ply,cmd,args)
for k,v in ipairs(levelups) do if ply:GetNWInt("CurLevel") == v then ply:ChatPrint("You are on level "..k..".") end end
end)
table.insert(chatcommands,{"curlevel","exp_curlevel"})
// Allow admins to save everyone's data in the SQL
concommand.Add("exp_savedata",function(ply,cmd,args)
if ply:IsAdmin() then
sql.Begin()
for _,v in pairs(player.GetAll()) do
local exp = v:GetNWInt("Exp")
local cur = v:GetNWInt("CurLevel")
local new = v:GetNWInt("NextLevel")
local lvl = v:GetNWInt("LevelNum")
if EXP_USETXT == 1 then WriteData(v)
else
sql.Query("UPDATE exp_pdata SET exp = "..exp.." WHERE steam = "..sql.SQLStr(ply:SteamID())..";")
sql.Query("UPDATE exp_pdata SET curlevel = "..cur.." WHERE STEAM = "..sql.SQLStr(ply:SteamID())..";")
sql.Query("UPDATE exp_pdata SET nextlevel = "..new.." WHERE STEAM = "..sql.SQLStr(ply:SteamID())..";")
sql.Query("UPDATE exp_pdata SET levelnum = "..lvl.." WHERE STEAM = "..sql.SQLStr(ply:SteamID())..";")
end
end
sql.Commit()
ply:ChatPrint("Data saved!")
end
end)
table.insert(chatcommands,{"savedata","exp_savedata"})
// Just in case the SQL fails, let's check why
concommand.Add("exp_debug",function(ply,cmd,args) if sql.LastError() then ply:ChatPrint(sql.LastError()) else ply:ChatPrint("No SQL errors!") end end)
table.insert(chatcommands,{"debug","exp_debug"})
// Get the data from the last save
concommand.Add("exp_printsql",function(ply,cmd,args)
ply:ChatPrint("Data from previous save...")
ply:ChatPrint("Experience: "..tonumber(sql.QueryValue("SELECT exp FROM exp_pdata WHERE steam = "..sql.SQLStr(ply:SteamID())..";")))
ply:ChatPrint("Base Level Experience: "..tonumber(sql.QueryValue("SELECT curlevel FROM exp_pdata WHERE steam = "..sql.SQLStr(ply:SteamID())..";")))
ply:ChatPrint("Next Level: "..tonumber(sql.QueryValue("SELECT nextlevel FROM exp_pdata WHERE steam = "..sql.SQLStr(ply:SteamID())..";")))
ply:ChatPrint("Level Number: "..tonumber(sql.QueryValue("SELECT levelnum FROM exp_pdata WHERE steam = "..sql.SQLStr(ply:SteamID())..";")))
end)
table.insert(chatcommands,{"printsql","exp_printsql"})
// Get the data from right now
concommand.Add("exp_printnw",function(ply,cmd,args)
ply:ChatPrint("Data at this moment...")
ply:ChatPrint("Experience: "..ply:GetNWInt("Exp"))
ply:ChatPrint("Base Level Experience: "..ply:GetNWInt("CurLevel"))
ply:ChatPrint("Next Level: "..ply:GetNWInt("NextLevel"))
ply:ChatPrint("Level Number: "..ply:GetNWInt("LevelNum"))
end)
table.insert(chatcommands,{"printnw","exp_printnw"})
/******************************************************** CHAT COMMANDS **********************************************************************/
// So the chatcommands will work
hook.Add("PlayerSay","EXP_Chat",function(ply,str,toall)
if string.Left(str,2) != "**" then return str end
local cmd = string.Explode(" ",string.sub(str,3,string.len(str)))
local cmdstr = ""
for k,v in ipairs(cmd) do if k != 1 then cmdstr = cmdstr .. " ".. v end end
for _,v in ipairs(chatcommands) do
if cmd[1] == v[1] then ply:ConCommand(v[2].." "..cmdstr) end
end
return ""
end)
include("exp_data.lua")
local UP_RUN = 1 // Increase run speed, set to 0 to disable
local UP_WALK = 1 // Increase walk speed
local UP_JUMP = 1 // Increase jump power
local UP_SWEPS = 1 // Give different weapons
local UP_ARMOR = 1 // Increase armor
local UP_HP = 1 // Increase health
local regweapons = {
"weapon_physgun",
"weapon_physcannon",
"weapon_crowbar",
"gmod_tool",
"gmod_camera",
}
local upweapons = {
{"weapon_crowbar"}, // Level 2
{"weapon_pistol","Pistol"}, // Level 3
{"weapon_crossbow","XBowBolt"}, // Level 4
{"weapon_shotgun","Buckshot"}, // Level 5
{"weapon_smg1","smg1"}, // Level 6
{"weapon_grenade","grenade"}, // Level 7
{"weapon_ar2","ar2"}, // Level 8
{"weapon_357","357"}, // Level 9
{"weapon_rpg","rpg_round"}, // Level 10
}
hook.Add("PlayerSpawn","EXP_PowerupsSpawn",function(ply)
// Get the player's current level
local lvl = 0
for k,v in ipairs(levelups) do if v == ply:GetNWInt("CurLevel") then lvl = k-1 end end
// Enhance their run/walk/jump speed
if UP_RUN == 1 then ply:SetRunSpeed(230+lvl*100) end
if UP_WALK == 1 then ply:SetWalkSpeed(155+lvl*20) end
if UP_JUMP == 1 then ply:SetJumpPower(200+lvl*15) end
if UP_ARMOR == 1 then ply:SetArmor(0+lvl*10) end
if UP_HP == 1 then ply:SetHealth(100+lvl*10) end
end)
hook.Add("PlayerLoadout","EXP_PowerupsLoad",function(ply)
// Get the player's current level
local lvl = 0
for k,v in ipairs(levelups) do if v == ply:GetNWInt("CurLevel") then lvl = k-1 end end
if UP_SWEPS == 1 then
ply:StripWeapons()
for _,v in ipairs(regweapons) do ply:Give(v) end
for k,v in ipairs(upweapons) do
if lvl >= k then
ply:Give(v[1])
if v[2] then ply:GiveAmmo(15*lvl,v[2],false) end
end
end
if lvl >= 7 then
ply:GiveAmmo(lvl-6,"SMG1_Grenade",false)
ply:GiveAmmo(lvl-6,"AR2AltFire",false)
end
end
return true
end)
When you level up, you gain +10 HP and +10 armor, along with specific weapons.