]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/mutators/sandbox.qc
And now for something a little different: No longer use a string for the clipboard...
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / mutators / sandbox.qc
index 9047f66846a5cde2cf0f8eabe4828e1365a89ecf..e49fbd21885a285d4155424bc6724abe0d3e17da 100644 (file)
@@ -60,6 +60,7 @@ void sandbox_ObjectEdit_Scale(entity e, float f)
        }
 }
 
+.float old_movetype;
 void sandbox_ObjectAttach_Remove(entity e);
 void sandbox_ObjectAttach_Set(entity e, entity parent, string s)
 {
@@ -68,6 +69,7 @@ void sandbox_ObjectAttach_Set(entity e, entity parent, string s)
        // we can't attach to an attachment, for obvious reasons
        sandbox_ObjectAttach_Remove(e);
 
+       e.old_movetype = e.movetype; // persist physics
        e.movetype = MOVETYPE_FOLLOW;
        e.solid = SOLID_NOT;
        e.takedamage = DAMAGE_NO;
@@ -86,7 +88,7 @@ void sandbox_ObjectAttach_Remove(entity e)
                if(head.owner == e)
                {
                        vector org;
-                       head.movetype = MOVETYPE_TOSS; // default
+                       head.movetype = head.old_movetype; // restore persisted physics
                        head.solid = SOLID_BBOX;
                        head.takedamage = DAMAGE_AIM;
 
@@ -168,25 +170,38 @@ string sandbox_ObjectPort_Save(entity e, float database)
        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;
-               string tagindex;
+               float slot, physics;
                if(head == e) // this is the main object, place it first
                {
                        slot = 0;
-                       tagindex = string_null;
+                       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;
-
-                       // get the name of the tag our object is attached to
-                       gettaginfo(head.owner, head.tag_index);
-                       tagindex = gettaginfo_name;
+                       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), " ");
@@ -194,15 +209,13 @@ string sandbox_ObjectPort_Save(entity e, float database)
                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(head.movetype), " ");
+               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(tagindex)    port_string[slot] = strcat(port_string[slot], "\"", tagindex, "\" ");   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], sprintf("\"%.9v\"", head.origin), " ");
-                       port_string[slot] = strcat(port_string[slot], sprintf("\"%.9v\"", head.angles), " ");
                }
        }
 
@@ -231,32 +244,48 @@ entity sandbox_ObjectPort_Load(string s, float database)
        // now separate and apply the properties of each object
        for(i = 0; i < n; ++i)
        {
-               string taginfo;
+               float argv_num;
+               string tagname;
+               argv_num = 0;
                tokenize_console(port_string[i]);
                e = sandbox_ObjectSpawn(database);
 
-               setmodel(e, argv(0));
-               e.skin = stof(argv(1));
-               e.alpha = stof(argv(2));
-               e.colormod = stov(argv(3));
-               e.glowmod = stov(argv(4));
-               e.frame = stof(argv(5));
-               sandbox_ObjectEdit_Scale(e, stof(argv(6)));
-               e.movetype = stof(argv(7));
-               e.damageforcescale = stof(argv(8));
-               if(e.material)  strunzone(e.material);  if(argv(9) != "-")      e.material = strzone(argv(9));  else    e.material = string_null;
-               if(argv(10) != "-")     taginfo = argv(10);     else    taginfo = string_null;
+               // ---------------- 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.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)
                {
-                       if(e.crypto_idfp)       strunzone(e.crypto_idfp);       if(argv(11) != "-")     e.crypto_idfp = strzone(argv(11));      else    e.crypto_idfp = string_null;
-                       setorigin(e, stov(argv(12)));
-                       e.angles = stov(argv(13));
+                       // 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(!i) // parent object, set it as such and leave it be
-                       parent = e;
-               else // child object, attach it to the parent
-                       sandbox_ObjectAttach_Set(e, parent, taginfo);
+               // attach last
+               if(i)
+                       sandbox_ObjectAttach_Set(e, parent, tagname);
        }
 
        for(i = 0; i <= MAX_STORAGE_ATTACHMENTS; ++i)
@@ -345,6 +374,7 @@ MUTATOR_HOOKFUNCTION(sandbox_PlayerCommand)
                {
                        entity e;
                        float i;
+                       string s;
 
                        // ---------------- COMMAND: HELP ----------------
                        case "help":
@@ -421,9 +451,9 @@ MUTATOR_HOOKFUNCTION(sandbox_PlayerCommand)
                                                e = sandbox_ObjectEdit_Get(autocvar_g_sandbox_editor_free); // can we copy objects we can't edit?
                                                if(e != world)
                                                {
-                                                       if(self.object_clipboard)
-                                                               strunzone(self.object_clipboard);
-                                                       self.object_clipboard = strzone(sandbox_ObjectPort_Save(e, FALSE));
+                                                       s = sandbox_ObjectPort_Save(e, FALSE);
+                                                       s = strreplace("\"", "\\\"", s);
+                                                       stuffcmd(self, strcat("set ", argv(3), " \"", s, "\""));
 
                                                        print_to(self, "^2SANDBOX - INFO: ^7Object copied to clipboard");
                                                        return TRUE;