X-Git-Url: https://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=blobdiff_plain;f=qcsrc%2Fcommon%2Fmutators%2Fmutator%2Fsandbox%2Fsandbox.qc;h=bc4cb67752feeac8a1a9ee406446a8f4665b347d;hp=e1decc8a069a093eb3198591153bfd3686317ed9;hb=8ba1f6c672361186033b8bebc3be677ac94bd4da;hpb=317ec3eb27ada1c4668876e9499136125acb7984 diff --git a/qcsrc/common/mutators/mutator/sandbox/sandbox.qc b/qcsrc/common/mutators/mutator/sandbox/sandbox.qc index e1decc8a0..bc4cb6775 100644 --- a/qcsrc/common/mutators/mutator/sandbox/sandbox.qc +++ b/qcsrc/common/mutators/mutator/sandbox/sandbox.qc @@ -25,18 +25,6 @@ REGISTER_MUTATOR(sandbox, cvar("g_sandbox")) if(autocvar_g_sandbox_storage_autoload) sandbox_Database_Load(); } - - MUTATOR_ONROLLBACK_OR_REMOVE - { - // nothing to roll back - } - - MUTATOR_ONREMOVE - { - // nothing to remove - } - - return false; } const float MAX_STORAGE_ATTACHMENTS = 16; @@ -46,19 +34,19 @@ float object_count; .string material; .float touch_timer; -void sandbox_ObjectFunction_Touch() -{SELFPARAM(); +void sandbox_ObjectFunction_Touch(entity this) +{ // apply material impact effects - if(!self.material) + if(!this.material) return; - if(self.touch_timer > time) + if(this.touch_timer > time) return; // don't execute each frame - self.touch_timer = time + 0.1; + this.touch_timer = time + 0.1; // make particle count and sound volume depend on impact speed float intensity; - intensity = vlen(self.velocity) + vlen(other.velocity); + intensity = vlen(this.velocity) + vlen(other.velocity); if(intensity) // avoid divisions by 0 intensity /= 2; // average the two velocities if (!(intensity >= autocvar_g_sandbox_object_material_velocity_min)) @@ -67,59 +55,58 @@ void sandbox_ObjectFunction_Touch() intensity -= autocvar_g_sandbox_object_material_velocity_min; // start from minimum velocity, not actual velocity intensity = bound(0, intensity * autocvar_g_sandbox_object_material_velocity_factor, 1); - _sound(self, CH_TRIGGER, strcat("object/impact_", self.material, "_", ftos(ceil(random() * 5)) , ".wav"), VOL_BASE * intensity, ATTEN_NORM); - Send_Effect_(strcat("impact_", self.material), self.origin, '0 0 0', ceil(intensity * 10)); // allow a count from 1 to 10 + _sound(this, CH_TRIGGER, strcat("object/impact_", this.material, "_", ftos(ceil(random() * 5)) , ".wav"), VOL_BASE * intensity, ATTEN_NORM); + Send_Effect_(strcat("impact_", this.material), this.origin, '0 0 0', ceil(intensity * 10)); // allow a count from 1 to 10 } -void sandbox_ObjectFunction_Think() -{SELFPARAM(); - entity e; - +void sandbox_ObjectFunction_Think(entity this) +{ // 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 + this.grab = 0; // no grabbing + else if(autocvar_g_sandbox_editor_free < 2 && this.crypto_idfp) + this.grab = 1; // owner only else - self.grab = 3; // anyone + this.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) + + // bots can't have objects + FOREACH_CLIENT(IS_PLAYER(it) && IS_REAL_CLIENT(it), LAMBDA( + if(this.crypto_idfp == it.crypto_idfp) { - self.realowner = e; + this.realowner = it; break; } - self.realowner = world; - } + this.realowner = NULL; + )); - self.nextthink = time; + this.nextthink = time; - CSQCMODEL_AUTOUPDATE(self); + CSQCMODEL_AUTOUPDATE(this); } .float old_solid, old_movetype; -entity sandbox_ObjectEdit_Get(float permissions) -{SELFPARAM(); - // Returns the traced entity if the player can edit it, and world if not. +entity sandbox_ObjectEdit_Get(entity this, float permissions) +{ + // Returns the traced entity if the player can edit it, and NULL 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 + crosshair_trace_plusvisibletriggers(this); + if(vdist(this.origin - trace_ent.origin, >, autocvar_g_sandbox_editor_distance_edit)) + return NULL; // out of trace range if(trace_ent.classname != "object") - return world; // entity is not an object + return NULL; // entity is not an object if(!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 (!(trace_ent.realowner != self && autocvar_g_sandbox_editor_free < 2)) + if (!(trace_ent.realowner != this && 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 NULL; } void sandbox_ObjectEdit_Scale(entity e, float f) @@ -156,14 +143,14 @@ void sandbox_ObjectAttach_Remove(entity e) // detaches any object attached to e entity head; - for(head = world; (head = find(head, classname, "object")); ) + for(head = NULL; (head = find(head, classname, "object")); ) { if(head.owner == e) { vector org; org = gettaginfo(head, 0); - setattachment(head, world, ""); - head.owner = world; + setattachment(head, NULL, ""); + head.owner = NULL; // objects change origin and angles when detached, so apply previous position setorigin(head, org); @@ -176,8 +163,8 @@ void sandbox_ObjectAttach_Remove(entity e) } } -entity sandbox_ObjectSpawn(float database) -{SELFPARAM(); +entity sandbox_ObjectSpawn(entity this, float database) +{ // spawn a new object with default properties entity e = new(object); @@ -188,8 +175,8 @@ entity sandbox_ObjectSpawn(float database) e.frame = 0; e.skin = 0; e.material = string_null; - e.touch = sandbox_ObjectFunction_Touch; - e.think = sandbox_ObjectFunction_Think; + settouch(e, sandbox_ObjectFunction_Touch); + setthink(e, sandbox_ObjectFunction_Think); e.nextthink = time; //e.effects |= EF_SELECTABLE; // don't do this all the time, maybe just when editing objects? @@ -197,24 +184,24 @@ entity sandbox_ObjectSpawn(float database) { // set the object's owner via player UID // if the player does not have an UID, the owner cannot be stored and his objects may be edited by anyone - if(self.crypto_idfp != "") - e.crypto_idfp = strzone(self.crypto_idfp); + if(this.crypto_idfp != "") + e.crypto_idfp = strzone(this.crypto_idfp); 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!"); + print_to(this, "^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.netname = strzone(this.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); + makevectors(this.v_angle); + WarpZone_TraceLine(this.origin + this.view_ofs, this.origin + this.view_ofs + v_forward * autocvar_g_sandbox_editor_distance_spawn, MOVE_NORMAL, this); setorigin(e, trace_endpos); - e.angles_y = self.v_angle.y; + e.angles_y = this.v_angle.y; } - WITH(entity, self, e, CSQCMODEL_AUTOINIT(e)); + CSQCMODEL_AUTOINIT(e); object_count += 1; return e; @@ -225,12 +212,7 @@ 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; - } + FOREACH_CLIENT(IS_PLAYER(it) && IS_REAL_CLIENT(it) && it.object_attach == e, LAMBDA(it.object_attach = NULL)); if(e.material) { strunzone(e.material); e.material = string_null; } if(e.crypto_idfp) { strunzone(e.crypto_idfp); e.crypto_idfp = string_null; } @@ -238,7 +220,7 @@ void sandbox_ObjectRemove(entity e) if(e.message) { strunzone(e.message); e.message = string_null; } if(e.message2) { strunzone(e.message2); e.message2 = string_null; } remove(e); - e = world; + e = NULL; object_count -= 1; } @@ -252,7 +234,7 @@ string sandbox_ObjectPort_Save(entity e, float database) string s; entity head; - for(head = world; (head = find(head, classname, "object")); ) + for(head = NULL; (head = find(head, classname, "object")); ) { // the main object needs to be first in the array [0] with attached objects following float slot, physics, solidity; @@ -322,11 +304,11 @@ string sandbox_ObjectPort_Save(entity e, float database) return s; } -entity sandbox_ObjectPort_Load(string s, float database) +entity sandbox_ObjectPort_Load(entity this, string s, float database) { // load object properties, and spawn a new object with them float n, i; - entity e = world, parent = world; + entity e = NULL, parent = NULL; // separate objects between the ; symbols n = tokenizebyseparator(s, "; "); @@ -340,7 +322,7 @@ entity sandbox_ObjectPort_Load(string s, float database) string tagname = string_null; argv_num = 0; tokenize_console(port_string[i]); - e = sandbox_ObjectSpawn(database); + e = sandbox_ObjectSpawn(this, database); // ---------------- OBJECT PROPERTY STORAGE: LOAD ---------------- if(i) @@ -402,10 +384,10 @@ void sandbox_Database_Save() fputs(file_get, strcat("// sandbox storage \"", autocvar_g_sandbox_storage_name, "\" for map \"", GetMapname(), "\" last updated ", strftime(true, "%d-%m-%Y %H:%M:%S"))); fputs(file_get, strcat(" containing ", ftos(object_count), " objects\n")); - for(head = world; (head = find(head, classname, "object")); ) + for(head = NULL; (head = find(head, classname, "object")); ) { // attached objects are persisted separately, ignore them here - if(head.owner != world) + if(head.owner != NULL) continue; // use a line of text for each object, listing all properties @@ -440,7 +422,7 @@ void sandbox_Database_Load() continue; entity e; - e = sandbox_ObjectPort_Load(file_read, true); + e = sandbox_ObjectPort_Load(NULL, file_read, true); if(e.material) { @@ -456,19 +438,24 @@ void sandbox_Database_Load() } MUTATOR_HOOKFUNCTION(sandbox, SV_ParseClientCommand) -{SELFPARAM(); +{ if(MUTATOR_RETURNVALUE) // command was already handled? - return false; + return; + + entity player = M_ARGV(0, entity); + string cmd_name = M_ARGV(1, string); + int cmd_argc = M_ARGV(2, int); + 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"); + print_to(player, "^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, "^2SANDBOX - INFO: ^7Sandbox mode is active. For usage information, type 'sandbox help'"); + print_to(player, "^2SANDBOX - INFO: ^7Sandbox mode is active. For usage information, type 'sandbox help'"); return true; } @@ -480,78 +467,78 @@ MUTATOR_HOOKFUNCTION(sandbox, SV_ParseClientCommand) // ---------------- 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, if the player has copying rights over the original"); - 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, "^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, "^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"); - 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, "^3solidity 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"); - print_to(self, "^7\"^2object_claim^7\" sets the player as the owner of the object, if he has the right to edit it"); - print_to(self, "^7\"^2object_info ^3value^7\" shows public information about the object"); - print_to(self, "^3object ^7- prints general information about the object, such as owner and creation / editing date"); - print_to(self, "^3mesh ^7- prints information about the object's mesh, including skeletal bones"); - print_to(self, "^3attachments ^7- prints information about the object's attachments"); - print_to(self, "^7The ^1drag object ^7key can be used to grab and carry objects. Players can only grab their own objects"); + print_to(player, "You can use the following sandbox commands:"); + print_to(player, "^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(player, "^7\"^2object_remove^7\" removes the object the player is looking at. Players can only remove their own objects"); + print_to(player, "^7\"^2object_duplicate ^3value^7\" duplicates the object, if the player has copying rights over the original"); + print_to(player, "^3copy value ^7- copies the properties of the object to the specified client cvar"); + print_to(player, "^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(player, "^7\"^2object_attach ^3property value^7\" attaches one object to another. Players can only attach their own objects"); + print_to(player, "^3get ^7- selects the object you are facing as the object to be attached"); + print_to(player, "^3set value ^7- attaches the previously selected object to the object you are facing, on the specified bone"); + print_to(player, "^3remove ^7- detaches all objects from the object you are facing"); + print_to(player, "^7\"^2object_edit ^3property value^7\" edits the given property of the object. Players can only edit their own objects"); + print_to(player, "^3skin value ^7- changes the skin of the object"); + print_to(player, "^3alpha value ^7- sets object transparency"); + print_to(player, "^3colormod \"value_x value_y value_z\" ^7- main object color"); + print_to(player, "^3glowmod \"value_x value_y value_z\" ^7- glow object color"); + print_to(player, "^3frame value ^7- object animation frame, for self-animated models"); + print_to(player, "^3scale value ^7- changes object scale. 0.5 is half size and 2 is double size"); + print_to(player, "^3solidity value ^7- object collisions, 0 = non-solid, 1 = solid"); + print_to(player, "^3physics value ^7- object physics, 0 = static, 1 = movable, 2 = physical"); + print_to(player, "^3force value ^7- amount of force applied to objects that are shot"); + print_to(player, "^3material value ^7- sets the material of the object. Default materials are: metal, stone, wood, flesh"); + print_to(player, "^7\"^2object_claim^7\" sets the player as the owner of the object, if he has the right to edit it"); + print_to(player, "^7\"^2object_info ^3value^7\" shows public information about the object"); + print_to(player, "^3object ^7- prints general information about the object, such as owner and creation / editing date"); + print_to(player, "^3mesh ^7- prints information about the object's mesh, including skeletal bones"); + print_to(player, "^3attachments ^7- prints information about the object's attachments"); + print_to(player, "^7The ^1drag object ^7key can be used to grab and carry objects. Players can only grab their own objects"); return true; // ---------------- COMMAND: OBJECT, SPAWN ---------------- case "object_spawn": - if(time < self.object_flood) + if(time < player.object_flood) { - print_to(self, strcat("^1SANDBOX - WARNING: ^7Flood protection active. Please wait ^3", ftos(self.object_flood - time), " ^7seconds beofore spawning another object")); + print_to(player, strcat("^1SANDBOX - WARNING: ^7Flood protection active. Please wait ^3", ftos(player.object_flood - time), " ^7seconds beofore spawning another object")); return true; } - self.object_flood = time + autocvar_g_sandbox_editor_flood; + player.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(player, 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; } if(cmd_argc < 3) { - 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"); + print_to(player, "^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; } if (!(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"); + print_to(player, "^1SANDBOX - WARNING: ^7Attempted to spawn an object with a non-existent model. Make sure the path to your model file is correct"); return true; } - e = sandbox_ObjectSpawn(false); + e = sandbox_ObjectSpawn(player, false); _setmodel(e, argv(2)); if(autocvar_g_sandbox_info > 0) - LOG_INFO(strcat("^3SANDBOX - SERVER: ^7", self.netname, " spawned an object at origin ^3", vtos(e.origin), "\n")); + LOG_INFO(strcat("^3SANDBOX - SERVER: ^7", player.netname, " spawned an object at origin ^3", vtos(e.origin), "\n")); return true; // ---------------- COMMAND: OBJECT, REMOVE ---------------- case "object_remove": - e = sandbox_ObjectEdit_Get(true); - if(e != world) + e = sandbox_ObjectEdit_Get(player, true); + if(e != NULL) { if(autocvar_g_sandbox_info > 0) - LOG_INFO(strcat("^3SANDBOX - SERVER: ^7", self.netname, " removed an object at origin ^3", vtos(e.origin), "\n")); + LOG_INFO(strcat("^3SANDBOX - SERVER: ^7", player.netname, " removed an object at origin ^3", vtos(e.origin), "\n")); sandbox_ObjectRemove(e); return true; } - print_to(self, "^1SANDBOX - WARNING: ^7Object could not be removed. Make sure you are facing an object that you have edit rights over"); + print_to(player, "^1SANDBOX - WARNING: ^7Object could not be removed. Make sure you are facing an object that you have edit rights over"); return true; // ---------------- COMMAND: OBJECT, DUPLICATE ---------------- @@ -560,42 +547,42 @@ MUTATOR_HOOKFUNCTION(sandbox, SV_ParseClientCommand) { case "copy": // 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) + e = sandbox_ObjectEdit_Get(player, autocvar_g_sandbox_editor_free); // can we copy objects we can't edit? + if(e != NULL) { s = sandbox_ObjectPort_Save(e, false); s = strreplace("\"", "\\\"", s); - stuffcmd(self, strcat("set ", argv(3), " \"", s, "\"")); + stuffcmd(player, strcat("set ", argv(3), " \"", s, "\"")); - print_to(self, "^2SANDBOX - INFO: ^7Object copied to clipboard"); + print_to(player, "^2SANDBOX - INFO: ^7Object copied to clipboard"); return true; } - print_to(self, "^1SANDBOX - WARNING: ^7Object could not be copied. Make sure you are facing an object that you have copy rights over"); + print_to(player, "^1SANDBOX - WARNING: ^7Object could not be copied. Make sure you are facing an object that you have copy rights over"); return true; case "paste": // spawns a new object using the properties in the player's clipboard cvar - if(time < self.object_flood) + if(time < player.object_flood) { - print_to(self, strcat("^1SANDBOX - WARNING: ^7Flood protection active. Please wait ^3", ftos(self.object_flood - time), " ^7seconds beofore spawning another object")); + print_to(player, strcat("^1SANDBOX - WARNING: ^7Flood protection active. Please wait ^3", ftos(player.object_flood - time), " ^7seconds beofore spawning another object")); return true; } - self.object_flood = time + autocvar_g_sandbox_editor_flood; + player.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"); + print_to(player, "^1SANDBOX - WARNING: ^7No object in clipboard. You must copy an object before you can paste it"); return true; } 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(player, 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(argv(3), false); + e = sandbox_ObjectPort_Load(player, argv(3), false); - print_to(self, "^2SANDBOX - INFO: ^7Object pasted successfully"); + print_to(player, "^2SANDBOX - INFO: ^7Object pasted successfully"); if(autocvar_g_sandbox_info > 0) - LOG_INFO(strcat("^3SANDBOX - SERVER: ^7", self.netname, " pasted an object at origin ^3", vtos(e.origin), "\n")); + LOG_INFO(strcat("^3SANDBOX - SERVER: ^7", player.netname, " pasted an object at origin ^3", vtos(e.origin), "\n")); return true; } return true; @@ -606,47 +593,47 @@ MUTATOR_HOOKFUNCTION(sandbox, SV_ParseClientCommand) { case "get": // select e as the object as meant to be attached - e = sandbox_ObjectEdit_Get(true); - if(e != world) + e = sandbox_ObjectEdit_Get(player, true); + if(e != NULL) { - self.object_attach = e; - print_to(self, "^2SANDBOX - INFO: ^7Object selected for attachment"); + player.object_attach = e; + print_to(player, "^2SANDBOX - INFO: ^7Object selected for attachment"); return true; } - print_to(self, "^1SANDBOX - WARNING: ^7Object could not be selected for attachment. Make sure you are facing an object that you have edit rights over"); + print_to(player, "^1SANDBOX - WARNING: ^7Object could not be selected for attachment. Make sure you are facing an object that you have edit rights over"); return true; case "set": - if(self.object_attach == world) + if(player.object_attach == NULL) { - print_to(self, "^1SANDBOX - WARNING: ^7No object selected for attachment. Please select an object to be attached first."); + print_to(player, "^1SANDBOX - WARNING: ^7No object selected for attachment. Please select an object to be attached first."); return true; } // attaches the previously selected object to e - e = sandbox_ObjectEdit_Get(true); - if(e != world) + e = sandbox_ObjectEdit_Get(player, true); + if(e != NULL) { - sandbox_ObjectAttach_Set(self.object_attach, e, argv(3)); - self.object_attach = world; // object was attached, no longer keep it scheduled for attachment - print_to(self, "^2SANDBOX - INFO: ^7Object attached successfully"); + sandbox_ObjectAttach_Set(player.object_attach, e, argv(3)); + player.object_attach = NULL; // object was attached, no longer keep it scheduled for attachment + print_to(player, "^2SANDBOX - INFO: ^7Object attached successfully"); if(autocvar_g_sandbox_info > 1) - LOG_INFO(strcat("^3SANDBOX - SERVER: ^7", self.netname, " attached objects at origin ^3", vtos(e.origin), "\n")); + LOG_INFO(strcat("^3SANDBOX - SERVER: ^7", player.netname, " attached objects at origin ^3", vtos(e.origin), "\n")); return true; } - print_to(self, "^1SANDBOX - WARNING: ^7Object could not be attached to the parent. Make sure you are facing an object that you have edit rights over"); + print_to(player, "^1SANDBOX - WARNING: ^7Object could not be attached to the parent. Make sure you are facing an object that you have edit rights over"); return true; case "remove": // removes e if it was attached - e = sandbox_ObjectEdit_Get(true); - if(e != world) + e = sandbox_ObjectEdit_Get(player, true); + if(e != NULL) { sandbox_ObjectAttach_Remove(e); - print_to(self, "^2SANDBOX - INFO: ^7Child objects detached successfully"); + print_to(player, "^2SANDBOX - INFO: ^7Child objects detached successfully"); if(autocvar_g_sandbox_info > 1) - LOG_INFO(strcat("^3SANDBOX - SERVER: ^7", self.netname, " detached objects at origin ^3", vtos(e.origin), "\n")); + LOG_INFO(strcat("^3SANDBOX - SERVER: ^7", player.netname, " detached objects at origin ^3", vtos(e.origin), "\n")); return true; } - print_to(self, "^1SANDBOX - WARNING: ^7Child objects could not be detached. Make sure you are facing an object that you have edit rights over"); + print_to(player, "^1SANDBOX - WARNING: ^7Child objects could not be detached. Make sure you are facing an object that you have edit rights over"); return true; } return true; @@ -655,12 +642,12 @@ MUTATOR_HOOKFUNCTION(sandbox, SV_ParseClientCommand) case "object_edit": if(argv(2) == "") { - print_to(self, "^1SANDBOX - WARNING: ^7Too few parameters. You must specify a property to edit"); + print_to(player, "^1SANDBOX - WARNING: ^7Too few parameters. You must specify a property to edit"); return true; } - e = sandbox_ObjectEdit_Get(true); - if(e != world) + e = sandbox_ObjectEdit_Get(player, true); + if(e != NULL) { switch(argv(2)) { @@ -725,7 +712,7 @@ MUTATOR_HOOKFUNCTION(sandbox, SV_ParseClientCommand) e.material = string_null; // no material break; default: - print_to(self, "^1SANDBOX - WARNING: ^7Invalid object property. For usage information, type 'sandbox help'"); + print_to(player, "^1SANDBOX - WARNING: ^7Invalid object property. For usage information, type 'sandbox help'"); return true; } @@ -734,71 +721,71 @@ MUTATOR_HOOKFUNCTION(sandbox, SV_ParseClientCommand) e.message2 = strzone(strftime(true, "%d-%m-%Y %H:%M:%S")); if(autocvar_g_sandbox_info > 1) - LOG_INFO(strcat("^3SANDBOX - SERVER: ^7", self.netname, " edited property ^3", argv(2), " ^7of an object at origin ^3", vtos(e.origin), "\n")); + LOG_INFO(strcat("^3SANDBOX - SERVER: ^7", player.netname, " edited property ^3", argv(2), " ^7of an object at origin ^3", vtos(e.origin), "\n")); return true; } - print_to(self, "^1SANDBOX - WARNING: ^7Object could not be edited. Make sure you are facing an object that you have edit rights over"); + print_to(player, "^1SANDBOX - WARNING: ^7Object could not be edited. Make sure you are facing an object that you have edit rights over"); return true; // ---------------- COMMAND: OBJECT, CLAIM ---------------- case "object_claim": // if the player can edit an object but is not its owner, this can be used to claim that object - if(self.crypto_idfp == "") + if(player.crypto_idfp == "") { - print_to(self, "^1SANDBOX - WARNING: ^7You do not have a player UID, and cannot claim objects"); + print_to(player, "^1SANDBOX - WARNING: ^7You do not have a player UID, and cannot claim objects"); return true; } - e = sandbox_ObjectEdit_Get(true); - if(e != world) + e = sandbox_ObjectEdit_Get(player, true); + if(e != NULL) { // 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 != player.netname) { if(e.netname) strunzone(e.netname); - e.netname = strzone(self.netname); - print_to(self, "^2SANDBOX - INFO: ^7Object owner name updated"); + e.netname = strzone(player.netname); + print_to(player, "^2SANDBOX - INFO: ^7Object owner name updated"); } - if(e.crypto_idfp == self.crypto_idfp) + if(e.crypto_idfp == player.crypto_idfp) { - print_to(self, "^2SANDBOX - INFO: ^7Object is already yours, nothing to claim"); + print_to(player, "^2SANDBOX - INFO: ^7Object is already yours, nothing to claim"); return true; } if(e.crypto_idfp) strunzone(e.crypto_idfp); - e.crypto_idfp = strzone(self.crypto_idfp); + e.crypto_idfp = strzone(player.crypto_idfp); - print_to(self, "^2SANDBOX - INFO: ^7Object claimed successfully"); + print_to(player, "^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"); + print_to(player, "^1SANDBOX - WARNING: ^7Object could not be claimed. Make sure you are facing an object that you have edit rights over"); return true; // ---------------- COMMAND: OBJECT, INFO ---------------- case "object_info": // prints public information about the object to the player - e = sandbox_ObjectEdit_Get(false); - if(e != world) + e = sandbox_ObjectEdit_Get(player, false); + if(e != NULL) { switch(argv(2)) { 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, "^7\"")); + print_to(player, 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": s = ""; 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)); + print_to(player, strcat("^2SANDBOX - INFO: ^7Object mesh is \"^3", e.model, "^7\" at animation frame ^3", ftos(e.frame), " ^7containing the following tags: ", s)); return true; case "attachments": // this should show the same info as 'mesh' but for attachments s = ""; entity head; i = 0; - for(head = world; (head = find(head, classname, "object")); ) + for(head = NULL; (head = find(head, classname, "object")); ) { if(head.owner == e) { @@ -809,30 +796,29 @@ MUTATOR_HOOKFUNCTION(sandbox, SV_ParseClientCommand) } } if(i) // object contains attachments - print_to(self, strcat("^2SANDBOX - INFO: ^7Object contains the following ^1", ftos(i), "^7 attachment(s): ", s)); + print_to(player, strcat("^2SANDBOX - INFO: ^7Object contains the following ^1", ftos(i), "^7 attachment(s): ", s)); else - print_to(self, "^2SANDBOX - INFO: ^7Object contains no attachments"); + print_to(player, "^2SANDBOX - INFO: ^7Object contains no attachments"); return true; } } - print_to(self, "^1SANDBOX - WARNING: ^7No information could be found. Make sure you are facing an object"); + print_to(player, "^1SANDBOX - WARNING: ^7No information could be found. Make sure you are facing an object"); return true; // ---------------- COMMAND: DEFAULT ---------------- default: - print_to(self, "Invalid command. For usage information, type 'sandbox help'"); + print_to(player, "Invalid command. For usage information, type 'sandbox help'"); return true; } } - return false; } MUTATOR_HOOKFUNCTION(sandbox, SV_StartFrame) { if(!autocvar_g_sandbox_storage_autosave) - return false; + return; if(time < autosave_time) - return false; + return; autosave_time = time + autocvar_g_sandbox_storage_autosave; sandbox_Database_Save();