Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 91 additions & 4 deletions SaveLoadX/data/tables/saveload2-sct.tbm
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,56 @@ function SaveState:CheckList(t, data)

return false

end

function SaveState:GetVariableData(exclusionList)

ba.print("SAVELOAD: Getting mission variables...\n")

local t = {}

for i = 1, #mn.SEXPVariables do
local var = mn.SEXPVariables[i]
if var and var:isValid() then
if var.Persistence == SEXPVAR_NOT_PERSISTENT and not self:CheckList(exclusionList, var.Name) then
local typeStr
if var.Type == SEXPVAR_TYPE_NUMBER then typeStr = "number"
elseif var.Type == SEXPVAR_TYPE_STRING then typeStr = "string" end
if typeStr then
t[var.Name] = { Type = typeStr, Value = var.Value }
ba.print("SAVELOAD: Saved variable " .. var.Name .. " (" .. typeStr .. ") = " .. tostring(var.Value) .. "\n")
end
end
end
end

return t

end

function SaveState:ApplyVariableData(varTable)

if not varTable then return end

ba.print("SAVELOAD: Applying mission variables...\n")

for name, entry in pairs(varTable) do
local var = mn.SEXPVariables[name]
if var and var:isValid() then
local currentType
if var.Type == SEXPVAR_TYPE_NUMBER then currentType = "number"
elseif var.Type == SEXPVAR_TYPE_STRING then currentType = "string" end
if currentType ~= entry.Type then
ba.print("SAVELOAD: Variable " .. name .. " type mismatch (saved " .. tostring(entry.Type) .. ", current " .. tostring(currentType) .. "), skipping\n")
else
var.Value = entry.Value
ba.print("SAVELOAD: Restored variable " .. name .. " = " .. tostring(entry.Value) .. "\n")
end
else
ba.print("SAVELOAD: Variable " .. name .. " no longer exists, skipping\n")
end
end

end

--This is what lua-savestate-save calls
Expand Down Expand Up @@ -407,14 +457,16 @@ function SaveState:SaveAll(index, ...)
end

data.Wings = {}

for i, entry in ipairs(self.WingList) do
if not self:CheckList(exclusionList,entry) then
wingdata,key = self:GetWingData(entry)
data.Wings[key] = wingdata
end
end


data.Variables = self:GetVariableData(exclusionList)

self.LoadedData[index or #self.LoadedData+1] = data

ba.print("SAVELOAD: Writing save data to file " .. self.SaveFilename .. " with save index " .. index .. "\n")
Expand Down Expand Up @@ -443,7 +495,11 @@ function SaveState:LoadAll(index)
ba.print("SAVE STATE: index " .. self.CurrentIndex .. " not found, aborting load data.\n")
return
end


--Restore mission variables before touching ships, so any SEXP evaluation
--triggered by ship-apply code sees the correct variable values.
self:ApplyVariableData(thisloadeddata.Variables)

--Apply saved data to ships that are present

for thisShip in mn.getShipList() do
Expand Down Expand Up @@ -1028,7 +1084,37 @@ function SaveState:ExternalLoad(index, mission, ...)
end

ba.print("SAVELOAD: Finished External Load!\n")


end

function SaveState:ExternalLoadVar(index, mission, ...)

ba.print("SAVELOAD: Beginning External Variable Load!\n")

if mission ~= self.ExternalMission then self:LoadExternalData(mission) end

local data = self.ExternalData

if data and data[index] and data[index].Variables then

local saveData = data[index].Variables
local requested = {}

for i, v in ipairs(arg) do
local varname = v[1].Name
ba.print("SAVELOAD: Requesting external variable " .. varname .. "\n")
if saveData[varname] then
requested[varname] = saveData[varname]
else
ba.print("SAVELOAD: Variable " .. varname .. " not found in external save, skipping\n")
end
end

self:ApplyVariableData(requested)
end

ba.print("SAVELOAD: Finished External Variable Load!\n")

end

function SaveState:LoadExternalData(mission)
Expand Down Expand Up @@ -1150,6 +1236,7 @@ end
mn.LuaSEXPs["lua-savestate-save"].Action = function(index, ...) SaveState:SaveAll(index, ...) end
mn.LuaSEXPs["lua-savestate-load"].Action = function(index) SaveState:LoadAll(index) end
mn.LuaSEXPs["lua-savestate-load-external"].Action = function(index, mission, ...) return SaveState:ExternalLoad(index, mission, ...) end
mn.LuaSEXPs["lua-savestate-load-external-var"].Action = function(index, mission, ...) SaveState:ExternalLoadVar(index, mission, ...) end
mn.LuaSEXPs["lua-savestate-shipstatus"].Action = function(name, index) return SaveState:QueryStatus(name, index) end
mn.LuaSEXPs["lua-savestate-getindex"].Action = function() return SaveState:GetCurrentSaveIndex() end
mn.LuaSEXPs["lua-savestate-check"].Action = function(index, mission) return SaveState:Exists(index, mission) end
Expand Down
27 changes: 22 additions & 5 deletions SaveLoadX/data/tables/saveload2-sexp.tbm
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ $Category: Change
$Subcategory: Scripted
$Minimum Arguments: 1
$Return Type: Nothing
$Description: Saves the state of all ships present in the mission at the time of calling this sexp. Save data can be loaded with lua-savestate-load. Data will be saved in an external JSON file with the filename "[PILOTNAME]_[MISSIONFILENAME].sav". Multiple save states can be saved into one file, use the save state index to decide which index to use. By default all ships are saved, but the list of ships and wings in the optional arguments will be excluded from being saved. (Note for ships in wings, both the ship name and wing name should be put in the exclusion list)
$Description: Saves the state of all ships present in the mission at the time of calling this sexp. Save data can be loaded with lua-savestate-load. Data will be saved in an external JSON file with the filename "[PILOTNAME]_[MISSIONFILENAME].sav". Multiple save states can be saved into one file, use the save state index to decide which index to use. By default all ships are saved, but the list of ships and wings in the optional arguments will be excluded from being saved. (Note for ships in wings, both the ship name and wing name should be put in the exclusion list) All non-persistent mission variables are also saved$semicolon names in the exclusion list also exclude variables of the same name (ship, wing, and variable names share one exclusion namespace). Player-persistent and campaign-persistent variables are always skipped because FSO manages them across missions.
$Parameter:
+Description: Save state index
+Type: number
$Repeat
$Parameter:
+Description: Name of ships and wings to exclude (Note for ships in wings, both the ship name and wing name should be put in the exclusion list)
+Description: Name of ships, wings, or variables to exclude (Note for ships in wings, both the ship name and wing name should be put in the exclusion list)
+Type: string

$Operator: lua-savestate-load
Expand All @@ -20,7 +20,7 @@ $Subcategory: Scripted
$Minimum Arguments: 1
$Maximum Arguments: 1
$Return Type: Nothing
$Description: Loads the save state data into the current mission. Ships not present at start will have save data applied to their parse object data (where the game stores pre-arrival data). Ships present in the save state data but not present on load will automatically have their arrival info changed to warpless arrival, so the FREDder just needs to set up an arrival cue tied to the load data event for them to arrive right away. SPECIAL NOTES: Waypoint orders will be cleared. Wings may not be loaded 100% accurately, especially with waves.
$Description: Loads the save state data into the current mission. Ships not present at start will have save data applied to their parse object data (where the game stores pre-arrival data). Ships present in the save state data but not present on load will automatically have their arrival info changed to warpless arrival, so the FREDder just needs to set up an arrival cue tied to the load data event for them to arrive right away. SPECIAL NOTES: Waypoint orders will be cleared. Wings may not be loaded 100% accurately, especially with waves. Mission variables saved in this slot are also restored$semicolon variables missing from the current mission or with a type that has changed since save are logged and skipped.
$Parameter:
+Description: Save state index
+Type: number
Expand All @@ -30,7 +30,7 @@ $Category: Change
$Subcategory: Scripted
$Minimum Arguments: 3
$Return Type: Nothing
$Description: Loads the save state data from another mission's save state data into the current mission. Position, orientation and order information will not be loaded. This will only work if the ship is already present in the mission!
$Description: Loads the save state data from another mission's save state data into the current mission. Position, orientation and order information will not be loaded. This will only work if the ship is already present in the mission! Mission variables are NOT loaded automatically across missions -- use lua-savestate-load-external-var to pull specific variables from another mission's save.
$Parameter:
+Description: Save state index
+Type: number
Expand All @@ -41,7 +41,24 @@ $Repeat
$Parameter:
+Description: Name of ships to load in
+Type: string


$Operator: lua-savestate-load-external-var
$Category: Change
$Subcategory: Scripted
$Minimum Arguments: 3
$Return Type: Nothing
$Description: Loads specific mission variables from another mission's save state data into the current mission. Each listed variable will be looked up in the external save and assigned to the matching variable in the current mission. Variables missing from the external save, missing from the current mission, or with a type that does not match the saved value are logged and skipped. Persistent variables are not included in save data and cannot be loaded this way.
$Parameter:
+Description: Save state index
+Type: number
$Parameter:
+Description: Mission filename
+Type: string
$Repeat
$Parameter:
+Description: Name of variable to load
+Type: variable

$Operator: lua-savestate-shipstatus
$Category: Status
$Subcategory: Mission
Expand Down