]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/mutators/sandbox.qc
Don't srzone message and message2 together, which was causing another bug. Object...
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / mutators / sandbox.qc
index d508727bc06cbf3f1b8f56f85e11640bf3a7a929..ff59b393d4b50a63f82527e9db780e067a120cf6 100644 (file)
@@ -1,6 +1,5 @@
 const float MAX_STORAGE_ATTACHMENTS = 16;
 float object_count;
-.string object_clipboard;
 .entity object_attach;
 .string material;
 
@@ -118,6 +117,7 @@ entity sandbox_ObjectSpawn(float database)
        e.skin = 0;
        e.material = string_null;
        e.touch = sandbox_ObjectFunction_Touch;
+       //e.effects |= EF_SELECTABLE; // don't do this all the time, maybe just when editing objects?
 
        if(!database)
        {
@@ -128,6 +128,11 @@ entity sandbox_ObjectSpawn(float database)
                else
                        print_to(self, "^1SANDBOX - WARNING: ^7You spawned an object, but lack a player UID. ^1Your objects are not secured and can be edited by any player!");
 
+               // set public object information
+               e.netname = strzone(self.netname); // name of the owner
+               e.message = strzone(strftime(TRUE, "%d-%m-%Y %H:%M:%S")); // creation time
+               e.message2 = strzone(strftime(TRUE, "%d-%m-%Y %H:%M:%S")); // last editing time
+
                // set origin and direction based on player position and view angle
                makevectors(self.v_angle);
                WarpZone_TraceLine(self.origin + self.view_ofs, self.origin + self.view_ofs + v_forward * autocvar_g_sandbox_editor_distance_spawn, MOVE_NORMAL, self);
@@ -142,16 +147,12 @@ entity sandbox_ObjectSpawn(float database)
 void sandbox_ObjectRemove(entity e)
 {
        sandbox_ObjectAttach_Remove(e); // detach child objects
-       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.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;        }
+       if(e.message)   {       strunzone(e.message);   e.message = string_null;        }
+       if(e.message2)  {       strunzone(e.message2);  e.message2 = string_null;       }
        remove(e);
        e = world;
 
@@ -216,6 +217,9 @@ string sandbox_ObjectPort_Save(entity e, float 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, "\" ");
                }
        }
 
@@ -281,10 +285,14 @@ entity sandbox_ObjectPort_Load(string s, float 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
-               sandbox_ObjectAttach_Set(e, parent, tagname);
+               if(i)
+                       sandbox_ObjectAttach_Set(e, parent, tagname);
        }
 
        for(i = 0; i <= MAX_STORAGE_ATTACHMENTS; ++i)
@@ -373,20 +381,24 @@ MUTATOR_HOOKFUNCTION(sandbox_PlayerCommand)
                {
                        entity e;
                        float i;
+                       string s;
 
                        // ---------------- COMMAND: HELP ----------------
                        case "help":
                                print_to(self, "You can use the following sandbox commands:");
                                print_to(self, "^7\"^2object_spawn ^3models/foo/bar.md3^7\" spawns a new object in front of the player, and gives it the specified model");
                                print_to(self, "^7\"^2object_remove^7\" removes the object the player is looking at. Players can only remove their own objects");
-                               print_to(self, "^7\"^2object_duplicate ^3value^7\" duplicates the object. 'copy' copies the object, 'paste' puts it in front of the player");
+                               print_to(self, "^7\"^2object_duplicate ^3value^7\" duplicates the object, if the player has copying rights over the original");
+                               print_to(self, "^Properties for ^2object_duplicate^7:");
+                               print_to(self, "^3copy value ^7- copies the properties of the object to the specified client cvar");
+                               print_to(self, "^3paste value ^7- spawns an object with the given properties. Properties or cvars must be specified as follows; eg1: \"0 1 2 ...\", eg2: \"$cl_cvar\"");
                                print_to(self, "^7\"^2object_attach ^3property value^7\" attaches one object to another. Players can only attach their own objects");
-                               print_to(self, "^7Attachment properties for ^2object_attach^7:");
+                               print_to(self, "^7Properties for ^2object_attach^7:");
                                print_to(self, "^3get ^7- selects the object you are facing as the object to be attached");
                                print_to(self, "^3set value ^7- attaches the previously selected object to the object you are facing, on the specified bone");
                                print_to(self, "^3remove ^7- detaches all objects from the object you are facing");
                                print_to(self, "^7\"^2object_edit ^3property value^7\" edits the given property of the object. Players can only edit their own objects");
-                               print_to(self, "^7Object properties for ^2object_edit^7:");
+                               print_to(self, "^7Properties for ^2object_edit^7:");
                                print_to(self, "^3skin value ^7- changes the skin of the object");
                                print_to(self, "^3alpha value ^7- sets object transparency");
                                print_to(self, "^3colormod \"value_x value_y value_z\" ^7- main object color");
@@ -445,13 +457,13 @@ MUTATOR_HOOKFUNCTION(sandbox_PlayerCommand)
                                switch(argv(2))
                                {
                                        case "copy":
-                                               // copies customizable properties of the selected object to the clipboard
+                                               // copies customizable properties of the selected object to the clipboard cvar
                                                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;
@@ -460,8 +472,8 @@ MUTATOR_HOOKFUNCTION(sandbox_PlayerCommand)
                                                return TRUE;
 
                                        case "paste":
-                                               // spawns a new object using the properties in the player's clipboard
-                                               if(!self.object_clipboard) // no object in clipboard
+                                               // spawns a new object using the properties in the player's clipboard cvar
+                                               if(!argv(3)) // no object in clipboard
                                                {
                                                        print_to(self, "^1SANDBOX - WARNING: ^7No object in clipboard. You must copy an object before you can paste it");
                                                        return TRUE;
@@ -471,8 +483,7 @@ MUTATOR_HOOKFUNCTION(sandbox_PlayerCommand)
                                                        print_to(self, strcat("^1SANDBOX - WARNING: ^7Cannot spawn any more objects. Up to ^3", ftos(autocvar_g_sandbox_editor_maxobjects), " ^7objects may exist at a time"));
                                                        return TRUE;
                                                }
-
-                                               e = sandbox_ObjectPort_Load(self.object_clipboard, FALSE);
+                                               e = sandbox_ObjectPort_Load(argv(3), FALSE);
 
                                                print_to(self, "^2SANDBOX - INFO: ^7Object pasted successfully");
                                                if(autocvar_g_sandbox_info > 0)
@@ -583,8 +594,7 @@ MUTATOR_HOOKFUNCTION(sandbox_PlayerCommand)
                                                        e.damageforcescale = stof(argv(3));
                                                        break;
                                                case "material":
-                                                       if(e.material)
-                                                               strunzone(e.material);
+                                                       if(e.material)  strunzone(e.material);
                                                        if(argv(3))
                                                        {
                                                                for (i = 1; i <= 5; i++) // precache material sounds, 5 in total
@@ -596,8 +606,13 @@ MUTATOR_HOOKFUNCTION(sandbox_PlayerCommand)
                                                        break;
                                                default:
                                                        print_to(self, "^1SANDBOX - WARNING: ^7Invalid object property. For usage information, type 'sandbox help'");
-                                                       break;
+                                                       return TRUE;
                                        }
+
+                                       // update last editing time
+                                       if(e.message2)  strunzone(e.message2);
+                                       e.message2 = strzone(strftime(TRUE, "%d-%m-%Y %H:%M:%S"));
+
                                        if(autocvar_g_sandbox_info > 1)
                                                print(strcat("^3SANDBOX - SERVER: ^7", self.netname, " edited property ^3", argv(2), " ^7of an object at origin ^3", vtos(e.origin), "\n"));
                                        return TRUE;
@@ -617,15 +632,25 @@ MUTATOR_HOOKFUNCTION(sandbox_PlayerCommand)
                                e = sandbox_ObjectEdit_Get(TRUE);
                                if(e != world)
                                {
+                                       // update the owner's name
+                                       // Do this before checking if you're already the owner and skipping if such, so we
+                                       // also update the player's nickname if he changed it (but has the same player UID)
+                                       if(e.netname != self.netname)
+                                       {
+                                               if(e.netname)   strunzone(e.netname);
+                                               e.netname = strzone(self.netname);
+                                               print_to(self, "^2SANDBOX - INFO: ^7Object owner name updated");
+                                       }
+
                                        if(e.crypto_idfp == self.crypto_idfp)
                                        {
                                                print_to(self, "^2SANDBOX - INFO: ^7Object is already yours, nothing to claim");
                                                return TRUE;
                                        }
 
-                                       if(e.crypto_idfp)
-                                               strunzone(e.crypto_idfp);
-                                       e.crypto_idfp = self.crypto_idfp;
+                                       if(e.crypto_idfp)       strunzone(e.crypto_idfp);
+                                       e.crypto_idfp = strzone(self.crypto_idfp);
+
                                        print_to(self, "^2SANDBOX - INFO: ^7Object claimed successfully");
                                }
                                print_to(self, "^1SANDBOX - WARNING: ^7Object could not be claimed. Make sure you are facing an object that you have edit rights over");
@@ -645,6 +670,9 @@ MUTATOR_HOOKFUNCTION(sandbox_PlayerCommand)
                                                                tags = strcat(tags, "^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: ", tags));
                                                        return TRUE;
+                                               case "object":
+                                                       print_to(self, strcat("^2SANDBOX - INFO: ^7Object is owned by ^7", e.netname, "^7, created ^3", e.message, "^7, last edited ^3", e.message2));
+                                                       return TRUE;
                                        }
                                }
                                print_to(self, "^1SANDBOX - WARNING: ^7No information could not be found. Make sure you are facing an object");
@@ -684,18 +712,6 @@ MUTATOR_HOOKFUNCTION(sandbox_PlayerPreThink)
        return FALSE;
 }
 
-MUTATOR_HOOKFUNCTION(sandbox_ClientDisconnect)
-{
-       // unzone the player's clipboard if it's not empty
-       if(self.object_clipboard)
-       {
-               strunzone(self.object_clipboard);
-               self.object_clipboard = string_null;
-       }
-
-       return FALSE;
-}
-
 float autosave_time;
 MUTATOR_HOOKFUNCTION(sandbox_StartFrame)
 {
@@ -715,7 +731,6 @@ MUTATOR_DEFINITION(sandbox)
        MUTATOR_HOOK(SV_ParseClientCommand, sandbox_PlayerCommand, CBC_ORDER_ANY);
        MUTATOR_HOOK(SV_StartFrame, sandbox_StartFrame, CBC_ORDER_ANY);
        MUTATOR_HOOK(PlayerPreThink, sandbox_PlayerPreThink, CBC_ORDER_ANY);
-       MUTATOR_HOOK(ClientDisconnect, sandbox_ClientDisconnect, CBC_ORDER_ANY);
 
        MUTATOR_ONADD
        {