]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/mutators/sandbox.qc
Merge branch 'master' into mirceakitsune/sandbox
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / mutators / sandbox.qc
index 6514dccba7d312a90647e9b4e1909b30c7bcd210..142ac199dc09b0de0c0d04098b6840e076ed337f 100644 (file)
@@ -58,14 +58,27 @@ void sandbox_ObjectFunction_Think()
        self.nextthink = time;
 }
 
+.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;
+       }
 
        if(trace_ent.classname != "object")
                return world; // entity is not an object
@@ -89,7 +102,6 @@ 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)
 {
@@ -98,6 +110,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_solid = e.solid; // persist solidity
        e.old_movetype = e.movetype; // persist physics
        e.movetype = MOVETYPE_FOLLOW;
        e.solid = SOLID_NOT;
@@ -117,8 +130,8 @@ 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.solid = SOLID_BBOX;
                        head.takedamage = DAMAGE_AIM;
 
                        org = gettaginfo(head, 0);
@@ -203,16 +216,18 @@ 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, physics;
+               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
                }
@@ -242,6 +257,7 @@ 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(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
@@ -310,6 +326,7 @@ entity sandbox_ObjectPort_Load(string s, float database)
                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;
@@ -440,6 +457,7 @@ MUTATOR_HOOKFUNCTION(sandbox_PlayerCommand)
                                print_to(self, "^3glowmod \"value_x value_y value_z\" ^7- glow object color");
                                print_to(self, "^3frame value ^7- object animation frame, for self-animated models");
                                print_to(self, "^3scale value ^7- changes object scale. 0.5 is half size and 2 is double size");
+                               print_to(self, "^3solid value ^7- object collisions, 0 = non-solid, 1 = solid");
                                print_to(self, "^3physics value ^7- object physics, 0 = static, 1 = movable, 2 = physical");
                                print_to(self, "^3force value ^7- amount of force applied to objects that are shot");
                                print_to(self, "^3material value ^7- sets the material of the object. Default materials are: metal, stone, wood, flesh");
@@ -624,6 +642,18 @@ MUTATOR_HOOKFUNCTION(sandbox_PlayerCommand)
                                                case "scale":
                                                        sandbox_ObjectEdit_Scale(e, stof(argv(3)));
                                                        break;
+                                               case "solid":
+                                                       switch(argv(3))
+                                                       {
+                                                               case "0": // non-solid
+                                                                       e.solid = SOLID_NOT;
+                                                                       break;
+                                                               case "1": // solid
+                                                                       e.solid = SOLID_BBOX;
+                                                                       break;
+                                                               default:
+                                                                       break;
+                                                       }
                                                case "physics":
                                                        switch(argv(3))
                                                        {