From 52fb13ef163bcea7f1409e17fd62509703de9f69 Mon Sep 17 00:00:00 2001 From: Alexander Pickering Date: Thu, 17 Nov 2016 17:11:15 -0500 Subject: Added persistance --- entities/entities/ws_alter/init.lua | 21 +++++++- entities/entities/ws_barrel/init.lua | 35 ++++++++++---- entities/entities/ws_campfire/init.lua | 17 ++++++- entities/entities/ws_grave/init.lua | 21 +++++++- entities/entities/ws_prop/init.lua | 22 ++++++++- entities/entities/ws_researchtable/init.lua | 17 ++++++- gamemode/itemsystem/items/spell_teleport.lua | 8 ++-- gamemode/npcsystem/aidirector.lua | 71 +++++++--------------------- gamemode/npcsystem/loadnpcs.lua | 6 --- gamemode/server/saveworld.lua | 43 +++++++++++++++++ 10 files changed, 180 insertions(+), 81 deletions(-) create mode 100644 gamemode/server/saveworld.lua diff --git a/entities/entities/ws_alter/init.lua b/entities/entities/ws_alter/init.lua index 3830aea..8f2ba64 100644 --- a/entities/entities/ws_alter/init.lua +++ b/entities/entities/ws_alter/init.lua @@ -9,6 +9,23 @@ local ResurrectionTable = { ["Feather"] = 10, } +function ENT:Serialize() + local data = {} + data["Health"] = self:Health() + data["Items"] = self.StoredItems + data["Pos"] = self:GetPos() + data["Ang"] = self:GetAngles() + return util.TableToJSON(data) +end + +function ENT:Deserialize(json) + local data = util.JSONToTable(json) + self:SetHealth(data["Health"]) + self.StoredItems = data["Items"] + self:SetPos(data["Pos"]) + self:SetAngles(data["Ang"]) +end + function ENT:Initialize() self:SetModel("models/props_junk/wood_crate001a.mdl") self:PhysicsInit(SOLID_VPHYSICS) @@ -20,9 +37,9 @@ function ENT:Initialize() phys:EnableMotion(false) phys:Sleep() - self:SetHealth(30) + if self:Health() == 0 then self:SetHealth(30) end - self.StoredItems = {} + self.StoredItems = self.StoredItems or {} end function ENT:Think() diff --git a/entities/entities/ws_barrel/init.lua b/entities/entities/ws_barrel/init.lua index 28d8d20..82f3a9d 100644 --- a/entities/entities/ws_barrel/init.lua +++ b/entities/entities/ws_barrel/init.lua @@ -3,20 +3,37 @@ AddCSLuaFile("shared.lua") include('shared.lua') +function ENT:Serialize() + local data = {} + data["Health"] = self:Health() + data["Items"] = self.StoredItems + data["Pos"] = self:GetPos() + data["Ang"] = self:GetAngles() + return util.TableToJSON(data) +end + +function ENT:Deserialize(json) + local data = util.JSONToTable(json) + self:SetHealth(data["Health"]) + self.StoredItems = data["Items"] + self:SetPos(data["Pos"]) + self:SetAngles(data["Ang"]) +end + function ENT:Initialize() self:SetModel("models/props_c17/oildrum001.mdl") self:PhysicsInit(SOLID_VPHYSICS) self:SetMoveType(MOVETYPE_NONE) self:SetSolid(SOLID_VPHYSICS) self:SetUseType(SIMPLE_USE) - + local phys = self:GetPhysicsObject() phys:EnableMotion(false) phys:Sleep() - - self:SetHealth(30) - - self.StoredItems = {} + + if self:Health() == 0 then self:SetHealth(30) end + + self.StoredItems = self.StoredItems or {} end function ENT:AddItem(item,quantity) @@ -26,7 +43,7 @@ function ENT:AddItem(item,quantity) return end end - + table.insert(self.StoredItems,{Name = item, Quantity = quantity}) end @@ -35,9 +52,9 @@ function ENT:TakeItem(pl,item,quantity) if (v.Name == item) then quantity = math.min(quantity,v.Quantity) v.Quantity = v.Quantity - quantity - + pl:AddItem(item,quantity) - + if (v.Quantity <= 0) then table.remove(self.StoredItems,k) end break end @@ -55,6 +72,6 @@ end function ENT:OnTakeDamage(dmg) self:SetHealth(self:Health()-dmg) - + if (self:Health() <= 0) then self:Remove() end end diff --git a/entities/entities/ws_campfire/init.lua b/entities/entities/ws_campfire/init.lua index a57ccad..e6a3f76 100644 --- a/entities/entities/ws_campfire/init.lua +++ b/entities/entities/ws_campfire/init.lua @@ -3,6 +3,21 @@ AddCSLuaFile( "shared.lua" ) include('shared.lua') +function ENT:Serialize() + local data = {} + data["Items"] = self.StoredItems + data["Pos"] = self:GetPos() + data["Ang"] = self:GetAngles() + return util.TableToJSON(data) +end + +function ENT:Deserialize(json) + local data = util.JSONToTable(json) + self.StoredItems = data["Items"] + self:SetPos(data["Pos"]) + self:SetAngles(data["Ang"]) +end + function ENT:Initialize() self:SetModel("models/props_junk/Rock001a.mdl") self:PhysicsInit( SOLID_VPHYSICS ) @@ -16,7 +31,7 @@ function ENT:Initialize() phys:EnableMotion(false) phys:Sleep() - self.StoredItems = {} + self.StoredItems = self.StoredItems or {} self:Ignite(1000) end diff --git a/entities/entities/ws_grave/init.lua b/entities/entities/ws_grave/init.lua index 814eee7..abd9c8f 100644 --- a/entities/entities/ws_grave/init.lua +++ b/entities/entities/ws_grave/init.lua @@ -3,6 +3,23 @@ AddCSLuaFile("shared.lua") include('shared.lua') +function ENT:Serialize() + local data = {} + data["Health"] = self:Health() + data["Items"] = self.StoredItems + data["Pos"] = self:GetPos() + data["Ang"] = self:GetAngles() + return util.TableToJSON(data) +end + +function ENT:Deserialize(json) + local data = util.JSONToTable(json) + self:SetHealth(data["Health"]) + self.StoredItems = data["Items"] + self:SetPos(data["Pos"]) + self:SetAngles(data["Ang"]) +end + function ENT:Initialize() self:SetModel("models/props_c17/gravestone002a.mdl") self:PhysicsInit(SOLID_VPHYSICS) @@ -14,9 +31,9 @@ function ENT:Initialize() phys:EnableMotion(false) phys:Sleep() - self:SetHealth(30) + if self:Health() == 0 then self:SetHealth(30) end - self.StoredItems = {} + self.StoredItems = self.StoredItems or {} end function ENT:AddItem(item,quantity) diff --git a/entities/entities/ws_prop/init.lua b/entities/entities/ws_prop/init.lua index 51e979f..f757148 100644 --- a/entities/entities/ws_prop/init.lua +++ b/entities/entities/ws_prop/init.lua @@ -3,6 +3,24 @@ AddCSLuaFile("shared.lua") include('shared.lua') +function ENT:Serialize() + local data = {} + data["Health"] = self:Health() + data["Items"] = self.StoredItems + data["Pos"] = self:GetPos() + data["Ang"] = self:GetAngles() + data["HP"] = self.HP + return util.TableToJSON(data) +end + +function ENT:Deserialize(json) + local data = util.JSONToTable(json) + self:SetHealth(data["Health"]) + self:SetPos(data["Pos"]) + self:SetAngles(data["Ang"]) + self.HP = data["HP"] +end + function ENT:Initialize() self:PhysicsInit(SOLID_VPHYSICS) self:SetMoveType(MOVETYPE_NONE) @@ -13,9 +31,9 @@ function ENT:Initialize() phys:EnableMotion(false) phys:Sleep() - self:SetHealth(30) + if self:Health() == 0 then self:SetHealth(30) end - self.HP = 500 + if not self.HP then self.HP = 500 end self.MaxHP = self.HP end diff --git a/entities/entities/ws_researchtable/init.lua b/entities/entities/ws_researchtable/init.lua index 1a3a07b..57d2ffb 100644 --- a/entities/entities/ws_researchtable/init.lua +++ b/entities/entities/ws_researchtable/init.lua @@ -16,6 +16,21 @@ local PossibleRecipies = { {"Vine","Hitting an Antlion hill with a Sickle"}, } +function ENT:Serialize() + local data = {} + data["Health"] = self:Health() + data["Pos"] = self:GetPos() + data["Ang"] = self:GetAngles() + return util.TableToJSON(data) +end + +function ENT:Deserialize(json) + local data = util.JSONToTable(json) + self:SetHealth(data["Health"]) + self:SetPos(data["Pos"]) + self:SetAngles(data["Ang"]) +end + function ENT:Initialize() self:SetModel("models/props_junk/wood_crate002a.mdl") self:PhysicsInit(SOLID_VPHYSICS) @@ -29,7 +44,7 @@ function ENT:Initialize() phys:Sleep() end - self:SetHealth(30) + if self:Health() == 0 then self:SetHealth(30) end end function ENT:Think() diff --git a/gamemode/itemsystem/items/spell_teleport.lua b/gamemode/itemsystem/items/spell_teleport.lua index 686d5d1..9c31f25 100644 --- a/gamemode/itemsystem/items/spell_teleport.lua +++ b/gamemode/itemsystem/items/spell_teleport.lua @@ -26,11 +26,11 @@ ITEM.CD = 0.25 All saved points are stored in a global table where ITEM.savedpoint[player] = ]] -ITEM.savedpoint = {} +local savedpoint = {} function ITEM:DoTeleport(score,pl,self) print("DoTeleport called!") - if ITEM.savedpoint[pl] == nil then return end + if savedpoint[pl] == nil then return end print("Fully successfull teleport callback:") print(pl) local aim = pl:GetAimVector() @@ -39,7 +39,7 @@ function ITEM:DoTeleport(score,pl,self) D:SetPos(pl:GetShootPos() + aim * 200) D:SetOwner(pl) D:SetAngles(aim:Angle()) - D.endpoint = ITEM.savedpoint[pl] + D.endpoint = savedpoint[pl] D:Spawn() D:Activate() pl:EmitSound(Sound("physics/flesh/flesh_impact_hard.wav"),100,math.random(90,110)) @@ -71,7 +71,7 @@ end function ITEM:OnSecondary(pl,tr) print("Endpoint set?") ParticleEffect("firetest",pl:GetPos(),pl:GetAngles(),pl) - ITEM.savedpoint[pl] = pl:GetPos() + savedpoint[pl] = pl:GetPos() end function ITEM:OnPrimary(pl,tr) diff --git a/gamemode/npcsystem/aidirector.lua b/gamemode/npcsystem/aidirector.lua index bda81d7..f5cfc93 100644 --- a/gamemode/npcsystem/aidirector.lua +++ b/gamemode/npcsystem/aidirector.lua @@ -15,9 +15,7 @@ local function spawnnpcfunc(ply,cmd,args) local npc = GetNpcByName(args[1]) if(npc == nil) then print("Not a valid name!") return end - print("attempting to spawn npc...") SpawnNpcByName(args[1],ply:GetPos()) - print("NPC spawned!") end local function spawnnpccomplete(cmd,stringargs) @@ -34,7 +32,7 @@ local function spawnnpccomplete(cmd,stringargs) if(string.find(string.lower(v.Name),stringargs)) then table.insert(tbl,cmd .. " \"" .. v.Name .. "\"") else - print("Could not find " .. stringargs .. " in " .. string.lower(v.Name)) + ErrorNoHalt("Could not find " .. stringargs .. " in " .. string.lower(v.Name)) end end return tbl @@ -46,69 +44,34 @@ else concommand.Add("ws_spawnnpc",spawnnpcfunc, spawnnpccomplete, "Spawns an NPC from winter survival, useage: ws_spawnnpc ") end +local npcfields = { + "Model","Drops","OnDammage","Behave", + "Act","Stats","IdleSequences","Attacks", + "AttackPriority","AwareEnemies","OnSpawn" +} + function SpawnNpcByName(name, position) if(CLIENT) then return end entdata = GetNpcByName(name) if not entdata then - print("Could not find npc data for name " .. name) + ErrorNoHalt("Could not find npc data for name ",name) return end if not position then - print("Invalid position:") - print(position) + ErrorNoHalt("Attempted to spawn an NPC at an invalid location",position) return end ent = ents.Create("ws_npc_ambient") if(not ent) then - print("Could not spawn npc ws_npc_ambient") return end ent:SetPos(position) - print("From server!") - if(entdata.Name) then - ent.Name = entdata.Name - end - if(entdata.Model) then - ent.Model = entdata.Model - end - if(entdata.Drops) then - ent.Drops = entdata.Drops - end - if(entdata.OnDammage) then - ent.OnDammage = entdata.OnDammage - end - if(entdata.Behave) then - ent.Behave = entdata.Behave - end - if(entdata.Act) then - ent.Act = entdata.Act - end - if(entdata.Stats) then - ent.Stats = entdata.Stats - end - if(entdata.IdleSequences) then - ent.IdleSequences = entdata.IdleSequences - end - if(entdata.Attacks) then - ent.Attacks = entdata.Attacks - end - if(entdata.AttackPriority) then - ent.AttackPriority = entdata.AttackPriority - end - if(entdata.AwareEnemies) then - ent.AwareEnemies = entdata.AwareEnemies - end - if(entdata.OnSpawn) then - ent.OnSpawn = entdata.OnSpawn - end - --[[ - if(entdata.BehaveCycle) then - ent.BehaveCycle = entdata.BehaveCycle + for k,v in pairs(npcfields) do + if entdata[v] then + ent[v] = entdata[v] + end end - ]]-- - print("NPC created") ent:Spawn() - print("NPC spawned") end local random = math.random @@ -153,13 +116,13 @@ hook.Add("Tick","SpawnAmbient",function() local C = contents(Pos) if (C != CONTENTS_WATER and C != CONTENTS_WATER+CONTENTS_TRANSLUCENT) then - --print("Appropriate place found, spawning bird)") local randnpcnum = math.Round(math.Rand(0, #ambientnpcs)) local npc = GetNpcByName(ambientnpcs[randnpcnum]) if(npc == nil) then - print("Found npc that getnpcbyname returned nil for") - print(ambientnpcs[randnpcnum]) - continue + ErrorNoHalt(string.format([[ + Tried to spawn an NPC that wasn't registered: %s + ]],ambientnpcs[randnpcnum])) + continue end if(npc:SpawnLocations(Pos)) then SpawnNpcByName(ambientnpcs[randnpcnum],Pos) diff --git a/gamemode/npcsystem/loadnpcs.lua b/gamemode/npcsystem/loadnpcs.lua index 85b3cd6..78e6748 100644 --- a/gamemode/npcsystem/loadnpcs.lua +++ b/gamemode/npcsystem/loadnpcs.lua @@ -2,34 +2,28 @@ local Folder = GM.Folder:gsub("gamemodes/","").."/gamemode/npcsystem/npcs" local insert = table.insert function GM:LoadNPCS() - print("NPC's loaded!!!") local Items = file.Find(Folder.."/*.lua","LUA") local BaseItem = {} GAMEMODE.Npcs = {} NPC = {} - print("Printing something else!") AddCSLuaFile(Folder.."/base.lua") include(Folder.."/base.lua") BaseItem = table.Copy(NPC) - print("Items table was",Items) for k,v in pairs(Items) do - print("Found an npc's file") if (v != "base.lua") then AddCSLuaFile(Folder.."/"..v) include(Folder.."/"..v) insert(GAMEMODE.Npcs,NPC) - print("Inserting ",NPC.Name) NPC = table.Copy(BaseItem) end end - print("Finished loading npc's") end hook.Add("Initialize","Loadnpcs",function() diff --git a/gamemode/server/saveworld.lua b/gamemode/server/saveworld.lua new file mode 100644 index 0000000..25dd048 --- /dev/null +++ b/gamemode/server/saveworld.lua @@ -0,0 +1,43 @@ +--[[ + Saves all player-made items in the world before shutdown +]] + +local savedents = { + "ws_alter","ws_barrel","ws_campfire","ws_grave","ws_infuser","ws_prop","ws_researchtable","ws_rune" +} + +hook.Add("ShutDown","save_playermade_ents",function() + local ppe = {} + for k,v in pairs(savedents) do + ppe[v] = true + end + + --Make sure each entity that should be saved implements a Serialize(self) and Deserialize(self,str) function + local savecontent = {} + for k,v in pairs(ents.GetAll()) do + local class = v:GetClass() + if ppe[class] then + local ssc = #savecontent + savecontent[ssc + 1] = class + savecontent[ssc + 2] = ":" + savecontent[ssc + 3] = v:Serialize() + savecontent[ssc + 4] = "\n" + end + end + + file.Write("ws_save.dat",table.concat(savecontent)) +end) + +hook.Add("InitPostEntity","load_playermade_ents",function() + local filesstr = file.Read("ws_save.dat","DATA") + if filesstr == "" then return end + local lines = string.Explode("\n",filesstr) + local _,ee = lines[1]:find("^.-:") + local entname = lines[1]:sub(1,ee - 1) + local entdata = lines[1]:sub(ee + 1) + print("Loading entity ", entname, "with data",entdata) + local ent = ents.Create(entname) + ent:Spawn() + ent:Deserialize(entdata) + print("ent spawned",ent) +end) -- cgit v1.2.3-70-g09d2