Skip to content

Commit a4859fa

Browse files
committed
Add persistence system
1 parent fabeef6 commit a4859fa

File tree

3 files changed

+125
-54
lines changed

3 files changed

+125
-54
lines changed

README.md

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ This is a simple but highly customizable crafting and mining system made to work
1818
- Once the entity is mined, it will drop a certain amount of specified entities, and will respawn after a certain amount of time. All of these parameters are defined in the ucs_config.lua file.
1919
## Other Features
2020
- Iron and wood ingredient entities
21+
- Built-in persistence system to save crafting tables and mineable entities to the map, accessible by holding C and right clicking them. (Normal persistence systems won't work due to the nature of the entities.)
22+
- You can also change the type of crafting table or mineable entity through the same menu.
2123
- [Developer functions and hooks](dev.md)
2224

2325
# FAQs
@@ -27,10 +29,5 @@ Press your use key on the table, click the View Recipes button in the menu, and
2729
## How do I create new crafting tables, mineable entities, recipes, ingredients, etc?
2830
Read through the [ucs_config.lua file](lua/autorun/ucs_config.lua). It tells you everything you need to know and gives examples.
2931

30-
## Why do mineable entities spawn invisible after a map change?
31-
This can happen when you save them with a perma prop system that saves their color and other data that tracks whether or not the entity has been mined. You can prevent this by using a more simplistic perma-prop system that doesn't save this data, or by writing a script that spawns the entities at hard-coded coordinates.
32-
33-
It's also possible for this to happen if you set an invalid or corrupted model for the entity.
34-
3532
# Issues & Pull Requests
3633
If you would like to contribute to this repository by creating an issue or pull request, please refer to the [contributing guidelines.](https://lambdagaming.github.io/contributing.html)

lua/autorun/ucs_persist.lua

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
local allowed = {
2+
["ucs_table"] = true,
3+
["ucs_mineable"] = true
4+
}
5+
6+
local function SaveEnts()
7+
local saved = {}
8+
for k,v in ipairs( ents.FindByClass( "ucs_*" ) ) do
9+
if v:GetNWBool( "UCSPersist" ) then
10+
local class = v:GetClass()
11+
local typ = class == "ucs_table" and v:GetTableType() or v:GetMineableType()
12+
table.insert( saved, { class, typ, v:GetPos(), v:GetAngles() } )
13+
end
14+
end
15+
file.CreateDir( "ucs/persist" )
16+
file.Write( "ucs/persist/"..game.GetMap()..".json", util.TableToJSON( saved ) )
17+
end
18+
19+
properties.Add( "ucschangetype", {
20+
MenuLabel = "Change Type",
21+
Order = 1600,
22+
PrependSpacer = true,
23+
MenuIcon = "icon16/brick_edit.png",
24+
Filter = function( self, ent, ply )
25+
return IsValid( ent ) and allowed[ent:GetClass()] and ply:IsAdmin()
26+
end,
27+
MenuOpen = function( self, option, ent, tr )
28+
local sub = option:AddSubMenu()
29+
local tbl = ent:GetClass() == "ucs_table" and CraftingTable or MineableEntity
30+
for k,v in pairs( tbl ) do
31+
sub:AddOption( v.Name or "Invalid Type", function() self:SetType( ent, k ) end )
32+
end
33+
end,
34+
Action = function() end,
35+
SetType = function( self, ent, typ )
36+
self:MsgStart()
37+
net.WriteEntity( ent )
38+
net.WriteString( typ )
39+
self:MsgEnd()
40+
end,
41+
Receive = function( self, len, ply )
42+
if !ply:IsAdmin() then return end
43+
local ent = net.ReadEntity()
44+
local typ = net.ReadString()
45+
local pos = ent:GetPos()
46+
local ang = ent:GetAngles()
47+
local class = ent:GetClass()
48+
ent:Remove()
49+
50+
local e = ents.Create( class )
51+
e:SetPos( pos )
52+
e:SetAngles( ang )
53+
if class == "ucs_table" then
54+
e:SetTableType( typ )
55+
else
56+
e:SetMineableType( typ )
57+
end
58+
e:Spawn()
59+
end
60+
} )
61+
62+
properties.Add( "ucssavetomap", {
63+
MenuLabel = "Save to Map",
64+
Order = 1601,
65+
MenuIcon = "icon16/drive_disk.png",
66+
Filter = function( self, ent, ply )
67+
return IsValid( ent ) and allowed[ent:GetClass()] and ply:IsAdmin() and !ent:GetNWBool( "UCSPersist" )
68+
end,
69+
Action = function( self, ent )
70+
self:MsgStart()
71+
net.WriteEntity( ent )
72+
self:MsgEnd()
73+
end,
74+
Receive = function( self, len, ply )
75+
local ent = net.ReadEntity()
76+
ent:SetNWBool( "UCSPersist", true )
77+
ent:SetMoveType( MOVETYPE_NONE )
78+
SaveEnts()
79+
end
80+
} )
81+
82+
properties.Add( "ucsremovefrommap", {
83+
MenuLabel = "Remove From Map",
84+
Order = 1602,
85+
MenuIcon = "icon16/drive_delete.png",
86+
Filter = function( self, ent, ply )
87+
return IsValid( ent ) and allowed[ent:GetClass()] and ply:IsAdmin() and ent:GetNWBool( "UCSPersist" )
88+
end,
89+
Action = function( self, ent )
90+
self:MsgStart()
91+
net.WriteEntity( ent )
92+
self:MsgEnd()
93+
end,
94+
Receive = function( self, len, ply )
95+
local ent = net.ReadEntity()
96+
ent:SetNWBool( "UCSPersist", false )
97+
ent:SetMoveType( MOVETYPE_VPHYSICS )
98+
SaveEnts()
99+
end
100+
} )
101+
102+
if SERVER then
103+
hook.Add( "InitPostEntity", "UCSLoadSavedEnts", function()
104+
local name = "ucs/persist/"..game.GetMap()..".json"
105+
if file.Exists( name, "DATA" ) then
106+
local tbl = util.JSONToTable( file.Read( name ) )
107+
for k,v in pairs( tbl ) do
108+
local e = ents.Create( v[1] )
109+
if v[1] == "ucs_table" then
110+
e:SetTableType( v[2] )
111+
else
112+
e:SetMineableType( v[2] )
113+
end
114+
e:SetPos( v[3] )
115+
e:SetAngles( v[4] )
116+
e:Spawn()
117+
e:SetNWBool( "UCSPersist", true )
118+
e:SetMoveType( MOVETYPE_NONE )
119+
end
120+
print( "Spawned "..#tbl.." UCS entities." )
121+
end
122+
end )
123+
end

lua/entities/ucs_table/shared.lua

Lines changed: 0 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -20,54 +20,5 @@ function ENT:GetData()
2020
return CraftingTable[typ]
2121
end
2222

23-
properties.Add( "ucschangetype", {
24-
MenuLabel = "Change Type",
25-
Order = 1600,
26-
PrependSpacer = true,
27-
MenuIcon = "icon16/brick_edit.png",
28-
Filter = function( self, ent, ply )
29-
local allowed = {
30-
["ucs_table"] = true,
31-
["ucs_mineable"] = true
32-
}
33-
return IsValid( ent ) and allowed[ent:GetClass()] and ply:IsAdmin()
34-
end,
35-
MenuOpen = function( self, option, ent, tr )
36-
local sub = option:AddSubMenu()
37-
local tbl = ent:GetClass() == "ucs_table" and CraftingTable or MineableEntity
38-
for k,v in pairs( tbl ) do
39-
local opt = sub:AddOption( v.Name or "Invalid Type", function()
40-
self:SetType( ent, k )
41-
end )
42-
end
43-
end,
44-
Action = function() end,
45-
SetType = function( self, ent, typ )
46-
self:MsgStart()
47-
net.WriteEntity( ent )
48-
net.WriteString( typ )
49-
self:MsgEnd()
50-
end,
51-
Receive = function( self, len, ply )
52-
if !ply:IsAdmin() then return end
53-
local ent = net.ReadEntity()
54-
local typ = net.ReadString()
55-
local pos = ent:GetPos()
56-
local ang = ent:GetAngles()
57-
local class = ent:GetClass()
58-
ent:Remove()
59-
60-
local e = ents.Create( class )
61-
e:SetPos( pos )
62-
e:SetAngles( ang )
63-
if class == "ucs_table" then
64-
e:SetTableType( typ )
65-
else
66-
e:SetMineableType( typ )
67-
end
68-
e:Spawn()
69-
end
70-
} )
71-
7223
local version = "2.0"
7324
print( "Universal Crafting System v"..version.." by OPGman successfully loaded.\n" )

0 commit comments

Comments
 (0)