Skip to content

Commit

Permalink
Merge pull request #496 from NataKilar/multitile-saving-fix
Browse files Browse the repository at this point in the history
Multi-tile saving fix
  • Loading branch information
PsyCommando authored Jan 12, 2024
2 parents 51f7abb + 37092a7 commit 1e5cf71
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 38 deletions.
1 change: 1 addition & 0 deletions mods/persistence/_persistence.dme
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@
#include "modules\modular_computers\networking\machines\area_controller.dm"
#include "modules\modular_computers\networking\machines\telecomms.dm"
#include "modules\multiz\level_data.dm"
#include "modules\multiz\stairs.dm"
#include "modules\organs\organs.dm"
#include "modules\organs\external\_external_saving.dm"
#include "modules\organs\external\head.dm"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@

///Runs after deserialize on all the loaded atoms.
/datum/controller/subsystem/persistence/proc/_run_after_deserialize()
//Run after_deserialize on all atoms in the map.
//Run after_deserialize on all datums deserialized.
for(var/id in serializer.reverse_map)
var/datum/T
try
Expand All @@ -156,35 +156,6 @@
catch(var/exception/e)
_handle_recoverable_load_exception(e, "while running after_deserialize() on PID: '[id]'[!isnull(T)? ", '[T]'(\ref[T])([T.type])" : ""]")

//Since datums used as list value and list key are stored in another list, run after_deserialize() on them too
for(var/id in serializer.reverse_list_map)
var/list/_list
try
_list = serializer.reverse_list_map[id]
//#FIXME: If the keys in the list are numbers, this will be even slower than it is right now.
// Since it'll runtime if a number is out of range of the list.
for(var/key in _list)
var/datum/K = key
if(istype(K, /datum))
try
K.after_deserialize()
catch(var/exception/e_list_key)
_handle_recoverable_load_exception(e_list_key, "while running after_deserialize() on key [__PRINT_KEY_DETAIL(K)], of list: [__PRINT_STRING_LIST_DETAIL(id, _list)]")

var/datum/V
try
V = _list[key] //#FIXME: We really need to get rid of this awful way to check list types.
catch
continue
if(istype(V, /datum))
try
V.after_deserialize()
catch(var/exception/e_list_value)
_handle_recoverable_load_exception(e_list_value, "while running after_deserialize() on value [__PRINT_VALUE_DETAIL(V)], for key [__PRINT_KEY_DETAIL(K)], of list: [__PRINT_STRING_LIST_DETAIL(id, _list)]")
catch(var/exception/e_list)
//Catch any sort of bad index error
_handle_recoverable_load_exception(e_list, "while running after_deserialize() on elements of list: [__PRINT_STRING_LIST_DETAIL(id, _list)]")

///Clean up limbo by removing any characters present in the gameworld. This may occur if the server does not save after
///a player enters limbo.
/datum/controller/subsystem/persistence/proc/_update_limbo_state()
Expand Down
24 changes: 24 additions & 0 deletions mods/persistence/game/machinery/doors/double.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/obj/machinery/door/airlock/double/before_save()
. = ..()
if(isturf(loc))
var/turf/T = loc
CUSTOM_SV("primary_loc", "[T.x],[T.y],[T.z]")

/obj/machinery/door/airlock/double/after_deserialize()
var/primary_loc_coords = LOAD_CUSTOM_SV("primary_loc")
var/list/coords = splittext(primary_loc_coords, ",")
if(!islist(coords) || length(coords) < 3)
log_error("\The [src] could not find its primary location on load!")
return ..()

var/adjusted_z = text2num(coords[3])
if(SSpersistence.serializer.z_map[num2text(adjusted_z)])
adjusted_z = SSpersistence.serializer.z_map[num2text(adjusted_z)]

var/turf/primary_loc = locate(text2num(coords[1]), text2num(coords[2]), adjusted_z)

if(isturf(primary_loc))
forceMove(primary_loc)

CLEAR_SV("primary_loc")
return ..()
24 changes: 24 additions & 0 deletions mods/persistence/modules/multiz/stairs.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/obj/structure/stairs/long/before_save()
. = ..()
if(isturf(loc))
var/turf/T = loc
CUSTOM_SV("primary_loc", "[T.x],[T.y],[T.z]")

/obj/structure/stairs/long/after_deserialize()
var/primary_loc_coords = LOAD_CUSTOM_SV("primary_loc")
var/list/coords = splittext(primary_loc_coords, ",")
if(!islist(coords) || length(coords) < 3)
log_error("\The [src] could not find its primary location on load!")
return ..()

var/adjusted_z = text2num(coords[3])
if(SSpersistence.serializer.z_map[num2text(adjusted_z)])
adjusted_z = SSpersistence.serializer.z_map[num2text(adjusted_z)]

var/turf/primary_loc = locate(text2num(coords[1]), text2num(coords[2]), adjusted_z)

if(isturf(primary_loc))
forceMove(primary_loc)

CLEAR_SV("primary_loc")
return ..()
Original file line number Diff line number Diff line change
Expand Up @@ -126,12 +126,6 @@ var/global/list/serialization_time_spent_type
#endif
return existing

//locs check, to make sure we're saving a multi-tile object only on its original turf
if(isturf(object_parent) && ismovable(object))
var/atom/movable/am = object
if(length(am.locs) > 1 && (am.loc != object_parent))
return

var/time_before_serialize = REALTIMEOFDAY
// Thing didn't exist. Create it.
var/p_i = object.persistent_id ? object.persistent_id : PERSISTENT_ID
Expand Down Expand Up @@ -334,7 +328,7 @@ var/global/list/serialization_time_spent_type
KV = flattener.SerializeDatum(KV)
else
KT = SERIALIZER_TYPE_DATUM
KV = SerializeDatum(KV)
KV = SerializeDatum(KV, list_parent)
else
#ifdef SAVE_DEBUG
to_world_log("(SerializeListElem-Skip) Unknown Key. Value: [key]")
Expand Down Expand Up @@ -381,7 +375,7 @@ var/global/list/serialization_time_spent_type
EV = flattener.SerializeDatum(EV)
else
ET = SERIALIZER_TYPE_DATUM
EV = SerializeDatum(EV)
EV = SerializeDatum(EV, list_parent)
else
// Don't know what this is. Skip it.
#ifdef SAVE_DEBUG
Expand Down

0 comments on commit 1e5cf71

Please sign in to comment.