X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=blobdiff_plain;f=qcsrc%2Fserver%2Fmutators%2Fsandbox.qc;h=264aa83a7d9e62c9a827431e9e47f4fcfe556716;hp=2a38941d2eaaedde0a660a89d1ba1d32d194c3b6;hb=a0b81c8a4bac14f23744b8fa2d3e0fd3ecd0730d;hpb=d891ad284c7f42356b2f6a220990ed5a6885893d diff --git a/qcsrc/server/mutators/sandbox.qc b/qcsrc/server/mutators/sandbox.qc index 2a38941d2e..264aa83a7d 100644 --- a/qcsrc/server/mutators/sandbox.qc +++ b/qcsrc/server/mutators/sandbox.qc @@ -1,5 +1,6 @@ const float MAX_STORAGE_ATTACHMENTS = 16; float object_count; +.float object_flood; .entity object_attach; .string material; @@ -29,6 +30,34 @@ void sandbox_ObjectFunction_Touch() pointparticles(particleeffectnum(strcat("impact_", self.material)), self.origin, '0 0 0', ceil(intensity * 10)); // allow a count from 1 to 10 } +void sandbox_ObjectFunction_Think() +{ + entity e; + + // decide if and how this object can be grabbed + if(autocvar_g_sandbox_readonly) + self.grab = 0; // no grabbing + else if(autocvar_g_sandbox_editor_free < 2 && self.crypto_idfp) + self.grab = 1; // owner only + else + self.grab = 3; // anyone + + // Object owner is stored via player UID, but we also need the owner as an entity (if the player is available on the server). + // Therefore, scan for all players, and update the owner as long as the player is present. We must always do this, + // since if the owning player disconnects, the object's owner should also be reset. + FOR_EACH_REALPLAYER(e) // bots can't have objects + { + if(self.crypto_idfp == e.crypto_idfp) + { + self.realowner = e; + break; + } + self.realowner = world; + } + + self.nextthink = time; +} + entity sandbox_ObjectEdit_Get(float permissions) { // returns the traced entity if the player can edit it, and world if not @@ -44,7 +73,7 @@ entity sandbox_ObjectEdit_Get(float permissions) return trace_ent; // don't check permissions, anyone can edit this object if(!trace_ent.crypto_idfp) return trace_ent; // the player who spawned this object did not have an UID, so anyone can edit it - if not(trace_ent.crypto_idfp != self.crypto_idfp && autocvar_g_sandbox_editor_free < 2) + if not(trace_ent.realowner != self && autocvar_g_sandbox_editor_free < 2) return trace_ent; // object does not belong to the player, and players can only edit their own objects on this server return world; } @@ -117,6 +146,8 @@ entity sandbox_ObjectSpawn(float database) e.skin = 0; e.material = string_null; e.touch = sandbox_ObjectFunction_Touch; + e.think = sandbox_ObjectFunction_Think; + e.nextthink = time; //e.effects |= EF_SELECTABLE; // don't do this all the time, maybe just when editing objects? if(!database) @@ -371,9 +402,14 @@ MUTATOR_HOOKFUNCTION(sandbox_PlayerCommand) return FALSE; if(cmd_name == "g_sandbox") { + if(autocvar_g_sandbox_readonly) + { + print_to(self, "^2SANDBOX - INFO: ^7Sandbox mode is active, but in read-only mode. Sandbox commands cannot be used"); + return TRUE; + } if(cmd_argc < 2) { - print_to(self, "Sandbox mode is active. For usage information, type 'sandbox help'"); + print_to(self, "^2SANDBOX - INFO: ^7Sandbox mode is active. For usage information, type 'sandbox help'"); return TRUE; } @@ -415,6 +451,12 @@ MUTATOR_HOOKFUNCTION(sandbox_PlayerCommand) // ---------------- COMMAND: OBJECT, SPAWN ---------------- case "object_spawn": + if(time < self.object_flood) + { + print_to(self, strcat("^1SANDBOX - WARNING: ^7Flood protection active. Please wait ^3", ftos(self.object_flood - time), " ^7seconds beofore spawning another object")); + return TRUE; + } + self.object_flood = time + autocvar_g_sandbox_editor_flood; if(object_count >= autocvar_g_sandbox_editor_maxobjects) { 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")); @@ -425,7 +467,7 @@ MUTATOR_HOOKFUNCTION(sandbox_PlayerCommand) print_to(self, "^1SANDBOX - WARNING: ^7Attempted to spawn an object without specifying a model. Please specify the path to your model file after the 'object_spawn' command"); return TRUE; } - else if not(fexists(argv(2))) + if not(fexists(argv(2))) { print_to(self, "^1SANDBOX - WARNING: ^7Attempted to spawn an object with a non-existent model. Make sure the path to your model file is correct"); return TRUE; @@ -473,6 +515,12 @@ MUTATOR_HOOKFUNCTION(sandbox_PlayerCommand) case "paste": // spawns a new object using the properties in the player's clipboard cvar + if(time < self.object_flood) + { + print_to(self, strcat("^1SANDBOX - WARNING: ^7Flood protection active. Please wait ^3", ftos(self.object_flood - time), " ^7seconds beofore spawning another object")); + return TRUE; + } + self.object_flood = time + autocvar_g_sandbox_editor_flood; 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"); @@ -704,31 +752,6 @@ MUTATOR_HOOKFUNCTION(sandbox_PlayerCommand) return FALSE; } -MUTATOR_HOOKFUNCTION(sandbox_PlayerPreThink) -{ - // if the player is close enough to their object, they can drag it - - if(autocvar_sv_cheats) - return FALSE; // cheat dragging is used instead - - // grab is TRUE if the object can be picked up. While an object is being carried, the Drag() function - // must execute for it either way, otherwise it would cause bugs if it went out of the player's trace. - // This also makes sure that an object can only pe picked up if in range, but does not get dropped if - // it goes out of range while slinging it around. - - entity e; - float grab; - - e = sandbox_ObjectEdit_Get(TRUE); - if(e != world && vlen(e.origin - self.origin) <= autocvar_g_sandbox_editor_distance_edit) - grab = TRUE; - - if(Drag(e, grab)) // execute dragging - return TRUE; - - return FALSE; -} - float autosave_time; MUTATOR_HOOKFUNCTION(sandbox_StartFrame) { @@ -747,7 +770,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_ONADD {