+ for(head = world; (head = find(head, classname, "object")); )
+ {
+ // the main object needs to be first in the array [0] with attached objects following
+ float slot, physics, solidity;
+ if(head == e) // this is the main object, place it first
+ {
+ slot = 0;
+ solidity = head.solid; // applied solidity is normal solidity for children
+ physics = head.movetype; // applied physics are normal physics for parents
+ }
+ else if(head.owner == e) // child object, list them in order
+ {
+ i += 1; // children start from 1
+ slot = i;
+ solidity = head.old_solid; // persisted solidity is normal solidity for children
+ physics = head.old_movetype; // persisted physics are normal physics for children
+ gettaginfo(head.owner, head.tag_index); // get the name of the tag our object is attached to, used further below
+ }
+ else
+ continue;
+
+ // ---------------- OBJECT PROPERTY STORAGE: SAVE ----------------
+ if(slot)
+ {
+ // properties stored only for child objects
+ if(gettaginfo_name) port_string[slot] = strcat(port_string[slot], "\"", gettaginfo_name, "\" "); else port_string[slot] = strcat(port_string[slot], "\"\" "); // none
+ }
+ else
+ {
+ // properties stored only for parent objects
+ if(database)
+ {
+ port_string[slot] = strcat(port_string[slot], sprintf("\"%.9v\"", head.origin), " ");
+ port_string[slot] = strcat(port_string[slot], sprintf("\"%.9v\"", head.angles), " ");
+ }
+ }
+ // properties stored for all objects
+ port_string[slot] = strcat(port_string[slot], "\"", head.model, "\" ");
+ port_string[slot] = strcat(port_string[slot], ftos(head.skin), " ");
+ port_string[slot] = strcat(port_string[slot], ftos(head.alpha), " ");
+ port_string[slot] = strcat(port_string[slot], sprintf("\"%.9v\"", head.colormod), " ");
+ port_string[slot] = strcat(port_string[slot], sprintf("\"%.9v\"", head.glowmod), " ");
+ port_string[slot] = strcat(port_string[slot], ftos(head.frame), " ");
+ port_string[slot] = strcat(port_string[slot], ftos(head.scale), " ");
+ port_string[slot] = strcat(port_string[slot], ftos(solidity), " ");
+ port_string[slot] = strcat(port_string[slot], ftos(physics), " ");
+ port_string[slot] = strcat(port_string[slot], ftos(head.damageforcescale), " ");
+ if(head.material) port_string[slot] = strcat(port_string[slot], "\"", head.material, "\" "); else port_string[slot] = strcat(port_string[slot], "\"\" "); // none
+ if(database)
+ {
+ // properties stored only for the database
+ if(head.crypto_idfp) port_string[slot] = strcat(port_string[slot], "\"", head.crypto_idfp, "\" "); else port_string[slot] = strcat(port_string[slot], "\"\" "); // none
+ port_string[slot] = strcat(port_string[slot], "\"", e.netname, "\" ");
+ port_string[slot] = strcat(port_string[slot], "\"", e.message, "\" ");
+ port_string[slot] = strcat(port_string[slot], "\"", e.message2, "\" ");
+ }
+ }
+
+ // now apply the array to a simple string, with the ; symbol separating objects
+ for(i = 0; i <= MAX_STORAGE_ATTACHMENTS; ++i)
+ {
+ if(port_string[i])
+ s = strcat(s, port_string[i], "; ");
+ port_string[i] = string_null; // fully clear the string
+ }
+
+ return s;
+}
+
+entity sandbox_ObjectPort_Load(string s, float database)
+{
+ // load object properties, and spawn a new object with them
+ float n, i;
+ entity e, parent;
+
+ // separate objects between the ; symbols
+ n = tokenizebyseparator(s, "; ");
+ for(i = 0; i < n; ++i)
+ port_string[i] = argv(i);
+
+ // now separate and apply the properties of each object
+ for(i = 0; i < n; ++i)
+ {
+ float argv_num;
+ string tagname;
+ argv_num = 0;
+ tokenize_console(port_string[i]);
+ e = sandbox_ObjectSpawn(database);
+
+ // ---------------- OBJECT PROPERTY STORAGE: LOAD ----------------
+ if(i)
+ {
+ // properties stored only for child objects
+ if(argv(argv_num) != "") tagname = argv(argv_num); else tagname = string_null; ++argv_num;
+ }
+ else
+ {
+ // properties stored only for parent objects
+ if(database)
+ {
+ setorigin(e, stov(argv(argv_num))); ++argv_num;
+ e.angles = stov(argv(argv_num)); ++argv_num;
+ }
+ parent = e; // mark parent objects as such
+ }
+ // properties stored for all objects
+ setmodel(e, argv(argv_num)); ++argv_num;
+ e.skin = stof(argv(argv_num)); ++argv_num;
+ e.alpha = stof(argv(argv_num)); ++argv_num;
+ e.colormod = stov(argv(argv_num)); ++argv_num;
+ e.glowmod = stov(argv(argv_num)); ++argv_num;
+ e.frame = stof(argv(argv_num)); ++argv_num;
+ sandbox_ObjectEdit_Scale(e, stof(argv(argv_num))); ++argv_num;
+ e.solid = e.old_solid = stof(argv(argv_num)); ++argv_num;
+ e.movetype = e.old_movetype = stof(argv(argv_num)); ++argv_num;
+ e.damageforcescale = stof(argv(argv_num)); ++argv_num;
+ if(e.material) strunzone(e.material); if(argv(argv_num) != "") e.material = strzone(argv(argv_num)); else e.material = string_null; ++argv_num;
+ if(database)
+ {
+ // properties stored only for the database
+ if(e.crypto_idfp) strunzone(e.crypto_idfp); if(argv(argv_num) != "") e.crypto_idfp = strzone(argv(argv_num)); else e.crypto_idfp = string_null; ++argv_num;
+ if(e.netname) strunzone(e.netname); e.netname = strzone(argv(argv_num)); ++argv_num;
+ if(e.message) strunzone(e.message); e.message = strzone(argv(argv_num)); ++argv_num;
+ if(e.message2) strunzone(e.message2); e.message2 = strzone(argv(argv_num)); ++argv_num;
+ }
+
+ // attach last
+ if(i)
+ sandbox_ObjectAttach_Set(e, parent, tagname);
+ }
+
+ for(i = 0; i <= MAX_STORAGE_ATTACHMENTS; ++i)
+ port_string[i] = string_null; // fully clear the string