]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/mutators/sandbox.qc
Merge branch 'master' of git://de.git.xonotic.org/xonotic/xonotic-data.pk3dir
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / mutators / sandbox.qc
index 8b3a9596d384073563fa1adbfed89793a17dee42..e7f51aa887f7931445f0006452db6110a7e8928f 100644 (file)
@@ -61,25 +61,13 @@ void sandbox_ObjectFunction_Think()
 .float old_solid, old_movetype;
 entity sandbox_ObjectEdit_Get(float permissions)
 {
-       // returns the traced entity if the player can edit it, and world if not
-       // if permissions if FALSE, the object is returned regardless of editing rights
-       // attached objects are SOLID_NOT and don't risk getting traced
-       entity head;
-
-       // Tracing does not work for entities that use SOLID_NOT or SOLID_TRIGGER. Therefore, make all
-       // objects temporarily solid while doing the trace, then revert them to their initial solidity.
-       for(head = world; (head = find(head, classname, "object")); )
-       {
-               head.old_solid = head.solid;
-               head.solid = SOLID_BBOX;
-       }
-       makevectors(self.v_angle);
-       WarpZone_TraceLine(self.origin + self.view_ofs, self.origin + self.view_ofs + v_forward * autocvar_g_sandbox_editor_distance_edit, MOVE_NORMAL, self);
-       for(head = world; (head = find(head, classname, "object")); )
-       {
-               head.solid = head.old_solid;
-       }
+       // Returns the traced entity if the player can edit it, and world if not.
+       // If permissions if FALSE, the object is returned regardless of editing rights.
+       // Attached objects are SOLID_NOT and do not get traced.
 
+       crosshair_trace_plusvisibletriggers(self);
+       if(vlen(self.origin - trace_ent.origin) > autocvar_g_sandbox_editor_distance_edit)
+               return world; // out of trace range
        if(trace_ent.classname != "object")
                return world; // entity is not an object
        if(!permissions)
@@ -130,10 +118,6 @@ void sandbox_ObjectAttach_Remove(entity e)
                if(head.owner == e)
                {
                        vector org;
-                       head.solid = head.old_solid; // restore persisted solidity
-                       head.movetype = head.old_movetype; // restore persisted physics
-                       head.takedamage = DAMAGE_AIM;
-
                        org = gettaginfo(head, 0);
                        setattachment(head, world, "");
                        head.owner = world;
@@ -141,6 +125,10 @@ void sandbox_ObjectAttach_Remove(entity e)
                        // objects change origin and angles when detached, so apply previous position
                        setorigin(head, org);
                        head.angles = e.angles; // don't allow detached objects to spin or roll
+
+                       head.solid = head.old_solid; // restore persisted solidity
+                       head.movetype = head.old_movetype; // restore persisted physics
+                       head.takedamage = DAMAGE_AIM;
                }
        }
 }
@@ -193,6 +181,14 @@ void sandbox_ObjectRemove(entity e)
 {
        sandbox_ObjectAttach_Remove(e); // detach child objects
 
+       // if the object being removed has been selected for attachment by a player, unset it
+       entity head;
+       FOR_EACH_REALPLAYER(head) // bots can't have objects
+       {
+               if(head.object_attach == e)
+                       head.object_attach = world;
+       }
+
        if(e.material)  {       strunzone(e.material);  e.material = string_null;       }
        if(e.crypto_idfp)       {       strunzone(e.crypto_idfp);       e.crypto_idfp = string_null;    }
        if(e.netname)   {       strunzone(e.netname);   e.netname = string_null;        }
@@ -238,7 +234,7 @@ string sandbox_ObjectPort_Save(entity e, float database)
                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
+                       if(gettaginfo_name)     port_string[slot] = strcat(port_string[slot], "\"", gettaginfo_name, "\" ");    else    port_string[slot] = strcat(port_string[slot], "\"\" "); // none
                }
                else
                {
@@ -260,11 +256,11 @@ string sandbox_ObjectPort_Save(entity e, float database)
                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(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
+                       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, "\" ");
@@ -306,7 +302,7 @@ entity sandbox_ObjectPort_Load(string s, float database)
                if(i)
                {
                        // properties stored only for child objects
-                       if(argv(argv_num) != "-")       tagname = argv(argv_num);       else tagname = string_null;     ++argv_num;
+                       if(argv(argv_num) != "")        tagname = argv(argv_num);       else tagname = string_null;     ++argv_num;
                }
                else
                {
@@ -329,11 +325,11 @@ entity sandbox_ObjectPort_Load(string s, float database)
                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(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.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;
@@ -646,7 +642,7 @@ MUTATOR_HOOKFUNCTION(sandbox_PlayerCommand)
                                                        switch(argv(3))
                                                        {
                                                                case "0": // non-solid
-                                                                       e.solid = SOLID_NOT;
+                                                                       e.solid = SOLID_TRIGGER;
                                                                        break;
                                                                case "1": // solid
                                                                        e.solid = SOLID_BBOX;
@@ -748,7 +744,7 @@ MUTATOR_HOOKFUNCTION(sandbox_PlayerCommand)
                                                        print_to(self, strcat("^2SANDBOX - INFO: ^7Object is owned by \"^7", e.netname, "^7\", created \"^3", e.message, "^7\", last edited \"^3", e.message2, "^7\""));
                                                        return TRUE;
                                                case "mesh":
-                                                       for(i = 1; gettaginfo(e, i); i++)
+                                                       FOR_EACH_TAG(e)
                                                                s = strcat(s, "^7\"^5", gettaginfo_name, "^7\", ");
                                                        print_to(self, strcat("^2SANDBOX - INFO: ^7Object mesh is \"^3", e.model, "^7\" at animation frame ^3", ftos(e.frame), " ^7containing the following tags: ", s));
                                                        return TRUE;