ID:147702

I am using a regular map with turfs on areas and objects in those turfs. I would like a portion of the map defined by an area (area/savezone) to be saved. Here is what I got so far:
 area/savezoneatom/var saved_x saved_y saved_zworld/Del() var/i=1 var/savefile/F = new("data/areas.sav") var/area/Area = locate(/area/savezone) for(var/turf/T in Area.contents) for(var/obj/O in T.contents) if(istype(O,/mob/)) break O.saved_x = O.x O.saved_y = O.y O.saved_z = O.z F["[i]"] << O i++ F["count"] << i ..()world/New() if(fexists("data/areas.sav")) var/area/R = locate(/area/savezone) for(var/turf/T in R) for(var/obj/O in T) del(O) var/savefile/F = new("data/areas.sav") var/count F["count"] >> count for(var/i=1, i < count, i--) var/obj/O F["[i]"] >> O O.loc = locate(O.saved_x, O.saved_y, O.saved_z) ..() 

It 'works' (as in no runtime or compile-time errors) BUT references are not preserved. When the map loads some of the objects(especially objects that run on strings of references [see note 1]) lose their references. I heard that when you save a reference the object being referenced is saved as well. The circle like action (that occurs VERY often) may be what is causing the problems.

Note 1: Objects such as wires that have 2 variables. Each one of those variables points to another wire which in turn points to another wire which in turn... There is a chance that these form a circle of references aka
Obj1.ref = Obj2, Obj2.ref = Obj3, Obj3.ref = Obj1.
 #1 Jan 18 2004, 1:24 pm It's very possible they -are- being saved, but what's being loaded is a new instance of the object that was referenced, absent any information or instructions re: location. What I do when I need saved objects to "link" back up with each other is have the references converted to tags during saving, and then locate(the tag) a moment after loading.
 #2 Jan 18 2004, 2:13 pm In response to Hedgemistress (#1) Which procedure do you think would do the job better? New() or Read()
 #3 Jan 18 2004, 3:02 pm In response to Exadv1 (#2) You could do it either way, in world/New() as part of the loading proc, or in Read()... my inclination would be Read(), though... keep the stuff specific to a given object within that object's code.
 #4 Jan 18 2004, 4:13 pm In response to Hedgemistress (#1) even nicer is... That \ref[src] will give me a tag!
 #5 Jan 18 2004, 4:22 pm In response to Exadv1 (#4) You realize if you're not assigning a tag prior to generating the reference, the next time the game is loaded, another object may be created with that same ID before the objects are finished loading, which (if both objects are things that need to be saved and re-referenced)could lead to funky conflicts? Depending on what you're doing, this conflict could be anywhere between likely or impossible... but I'd still recommend, as a good habit, generating your own unique ID numbers.
In response to Hedgemistress (#5)
Here is hwat I developed for a simple 1 line input device (but all the others are really the same anyway)
 var/s_tag Write(savefile/F) F << "object\ref[src]" //s_tag F << ((line1)?("object\ref[line1]"):null) line1 = null ..() Read(savefile/F) F >> s_tag F >> line1 ..() tag = "[s_tag]" spawn(50) line1 = locate("[line1]") 

Sadly when I start using the 'precise' same code as last time it gave a runtime error (cannot modify null.loc referring to line O.loc = locate(...) )
and when I prefixed with if(O) (which shouldn't have to be done!) it just crashed :/