/
gmsave.lua
115 lines (78 loc) · 2.94 KB
/
gmsave.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
gmsave = {}
if ( CLIENT ) then return end
include( "gmsave/entity_filters.lua" )
include( "gmsave/player.lua" )
local g_WavSound = 1
function gmsave.LoadMap( strMapContents, ply, callback )
-- TODO: Do this in engine before sending it to this function.
-- Strip off any crap before the start char..
local startchar = string.find( strMapContents, '' )
if ( startchar != nil ) then
strMapContents = string.sub( strMapContents, startchar )
end
-- Strip off any crap after the end char..
strMapContents = strMapContents:reverse()
local startchar = string.find( strMapContents, '' )
if ( startchar != nil ) then
strMapContents = string.sub( strMapContents, startchar )
end
strMapContents = strMapContents:reverse()
-- END TODO
local tab = util.JSONToTable( strMapContents )
if ( !istable( tab ) ) then
-- Error loading save!
MsgN( "gm_load: Couldn't decode from json!" )
return false
end
-- Existing addons are forcing us to do this
-- The issue is that some addons overwrite game.CleanUpMap
-- Making the 3rd argument not exist
hook.Add( "PostCleanupMap", "GMod_Load_Save", function()
hook.Remove( "PostCleanupMap", "GMod_Load_Save" )
if ( IsValid( ply ) ) then
ply:SendLua( "hook.Run( \"OnSpawnMenuClose\" )" )
g_WavSound = g_WavSound + 1
if ( g_WavSound > 4 ) then g_WavSound = 1 end
ply:SendLua( string.format( "surface.PlaySound( \"garrysmod/save_load%d.wav\" )", g_WavSound ) )
gmsave.PlayerLoad( ply, tab.Player )
end
timer.Simple( 0.1, function()
DisablePropCreateEffect = true
duplicator.RemoveMapCreatedEntities()
duplicator.Paste( ply, tab.Entities, tab.Constraints )
DisablePropCreateEffect = nil
if ( IsValid( ply ) ) then
gmsave.PlayerLoad( ply, tab.Player )
end
-- Since this save system is inferior to Source's, we gotta make sure this entity is disabled on load of a save
-- On maps like Portal's testchmb_a_00.bsp this entity takes away player control and will not restore it
-- if the player is not in a very specific place.
timer.Simple( 1, function()
for id, ent in ipairs( ents.FindByClass( "point_viewcontrol" ) ) do
ent:Fire( "Disable" )
end
end )
if ( callback ) then callback() end
end )
end )
game.CleanUpMap( false, nil, function() end )
end
function gmsave.SaveMap( ply )
local Ents = ents.GetAll()
for k, v in ipairs( Ents ) do
if ( !gmsave.ShouldSaveEntity( v, v:GetSaveTable() ) || v:IsConstraint() ) then
Ents[ k ] = nil
end
end
-- This is to copy the constraints that are applied to the world only (ropes, etc)
-- It will not actually save and then try to restore the world entity, as that would cause issues
table.insert( Ents, game.GetWorld() )
local tab = duplicator.CopyEnts( Ents )
if ( !tab ) then return end
tab.Player = gmsave.PlayerSave( ply )
--
-- Try to figure out if any of the models/materials/etc came from some addon
--
duplicator.FigureOutRequiredAddons( tab )
return util.TableToJSON( tab )
end