const float MAX_STORAGE_ATTACHMENTS = 16;
float object_count;
+.float object_flood;
.entity object_attach;
.string material;
void sandbox_ObjectFunction_Think()
{
- if(autocvar_g_sandbox_editor_free < 2 && self.crypto_idfp)
- self.grab = 1;
+ 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;
+ 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;
}
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;
}
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;
}
// ---------------- 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"));
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;
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");