Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
sv_sandbox.qc File Reference
#include "sv_sandbox.qh"
#include <server/intermission.qh>
Include dependency graph for sv_sandbox.qc:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define SANDBOX_GETARG   arg = argv(++argv_num);

Functions

 MUTATOR_HOOKFUNCTION (sandbox, SV_ParseClientCommand)
 MUTATOR_HOOKFUNCTION (sandbox, SV_StartFrame)
void sandbox_Database_Load ()
void sandbox_Database_Save ()
void sandbox_ObjectAttach_Remove (entity e)
void sandbox_ObjectAttach_Set (entity e, entity parent, string s)
entity sandbox_ObjectEdit_Get (entity this, float permissions)
void sandbox_ObjectEdit_Scale (entity e, float f)
void sandbox_ObjectFunction_Think (entity this)
void sandbox_ObjectFunction_Touch (entity this, entity toucher)
entity sandbox_ObjectPort_Load (entity this, string s, float database)
string sandbox_ObjectPort_Save (entity e, bool database)
void sandbox_ObjectRemove (entity e)
entity sandbox_ObjectSpawn (entity this, float database)

Variables

string autocvar_g_sandbox
float autocvar_g_sandbox_editor_distance_edit
float autocvar_g_sandbox_editor_distance_spawn
float autocvar_g_sandbox_editor_flood
int autocvar_g_sandbox_editor_free
int autocvar_g_sandbox_editor_maxobjects
int autocvar_g_sandbox_info
float autocvar_g_sandbox_object_material_velocity_factor
float autocvar_g_sandbox_object_material_velocity_min
float autocvar_g_sandbox_object_scale_max
float autocvar_g_sandbox_object_scale_min
bool autocvar_g_sandbox_readonly
bool autocvar_g_sandbox_storage_autoload
float autocvar_g_sandbox_storage_autosave
string autocvar_g_sandbox_storage_name
float autosave_time
IntrusiveList g_sandbox_objects
string material
entity object_attach
float object_count
float object_flood
float old_movetype
float old_solid
string port_string [MAX_STORAGE_ATTACHMENTS]
float touch_timer

Macro Definition Documentation

◆ SANDBOX_GETARG

#define SANDBOX_GETARG   arg = argv(++argv_num);

Referenced by sandbox_ObjectPort_Load().

Function Documentation

◆ MUTATOR_HOOKFUNCTION() [1/2]

MUTATOR_HOOKFUNCTION ( sandbox ,
SV_ParseClientCommand  )

Definition at line 453 of file sv_sandbox.qc.

454{
455 if(MUTATOR_RETURNVALUE) // command was already handled?
456 return;
457
458 entity player = M_ARGV(0, entity);
459 string cmd_name = M_ARGV(1, string);
460 int cmd_argc = M_ARGV(2, int);
461
462 if(cmd_name == "g_sandbox")
463 {
464 if(autocvar_g_sandbox_readonly || MUTATOR_CALLHOOK(Sandbox_EditAllowed, player))
465 {
466 print_to(player, "^2SANDBOX - INFO: ^7Sandbox mode is active, but in read-only mode. Sandbox commands cannot be used");
467 return true;
468 }
469 if(cmd_argc < 2)
470 {
471 print_to(player, "^2SANDBOX - INFO: ^7Sandbox mode is active. For usage information, type 'sandbox help'");
472 return true;
473 }
474
475 switch(argv(1))
476 {
477 entity e;
478 int j;
479 string s;
480
481 // ---------------- COMMAND: HELP ----------------
482 case "help":
483 print_to(player, "You can use the following sandbox commands:");
484 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");
485 print_to(player, "^7\"^2object_remove^7\" removes the object the player is looking at. Players can only remove their own objects");
486 print_to(player, "^7\"^2object_duplicate ^3value^7\" duplicates the object, if the player has copying rights over the original");
487 print_to(player, "^3copy value ^7- copies the properties of the object to the specified client cvar");
488 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\"");
489 print_to(player, "^7\"^2object_attach ^3property value^7\" attaches one object to another. Players can only attach their own objects");
490 print_to(player, "^3get ^7- selects the object you are facing as the object to be attached");
491 print_to(player, "^3set value ^7- attaches the previously selected object to the object you are facing, on the specified bone");
492 print_to(player, "^3remove ^7- detaches all objects from the object you are facing");
493 print_to(player, "^7\"^2object_edit ^3property value^7\" edits the given property of the object. Players can only edit their own objects");
494 print_to(player, "^3skin value ^7- changes the skin of the object");
495 print_to(player, "^3alpha value ^7- sets object transparency");
496 print_to(player, "^3colormod \"value_x value_y value_z\" ^7- main object color");
497 print_to(player, "^3glowmod \"value_x value_y value_z\" ^7- glow object color");
498 print_to(player, "^3frame value ^7- object animation frame, for self-animated models");
499 print_to(player, "^3scale value ^7- changes object scale. 0.5 is half size and 2 is double size");
500 print_to(player, "^3solidity value ^7- object collisions, 0 = non-solid, 1 = solid");
501 print_to(player, "^3physics value ^7- object physics, 0 = static, 1 = movable, 2 = physical");
502 print_to(player, "^3force value ^7- amount of force applied to objects that are shot");
503 print_to(player, "^3material value ^7- sets the material of the object. Default materials are: metal, stone, wood, flesh");
504 print_to(player, "^7\"^2object_claim^7\" sets the player as the owner of the object, if they have the right to edit it");
505 print_to(player, "^7\"^2object_info ^3value^7\" shows public information about the object");
506 print_to(player, "^3object ^7- prints general information about the object, such as owner and creation / editing date");
507 print_to(player, "^3mesh ^7- prints information about the object's mesh, including skeletal bones");
508 print_to(player, "^3attachments ^7- prints information about the object's attachments");
509 print_to(player, "^7The ^1drag object ^7key can be used to grab and carry objects. Players can only grab their own objects");
510 return true;
511
512 // ---------------- COMMAND: OBJECT, SPAWN ----------------
513 case "object_spawn":
514 if(time < player.object_flood)
515 {
516 print_to(player, strcat("^1SANDBOX - WARNING: ^7Flood protection active. Please wait ^3", ftos(player.object_flood - time), " ^7seconds beofore spawning another object"));
517 return true;
518 }
519 player.object_flood = time + autocvar_g_sandbox_editor_flood;
521 {
522 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"));
523 return true;
524 }
525 if(cmd_argc < 3)
526 {
527 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");
528 return true;
529 }
530 if (!(fexists(argv(2))))
531 {
532 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");
533 return true;
534 }
535
536 e = sandbox_ObjectSpawn(player, false);
537 precache_model(argv(2));
538 _setmodel(e, argv(2));
539
541 LOG_INFO("^3SANDBOX - SERVER: ^7", player.netname, " spawned an object at origin ^3", vtos(e.origin));
542 return true;
543
544 // ---------------- COMMAND: OBJECT, REMOVE ----------------
545 case "object_remove":
546 e = sandbox_ObjectEdit_Get(player, true);
547 if(e != NULL)
548 {
550 LOG_INFO("^3SANDBOX - SERVER: ^7", player.netname, " removed an object at origin ^3", vtos(e.origin));
552 return true;
553 }
554
555 print_to(player, "^1SANDBOX - WARNING: ^7Object could not be removed. Make sure you are facing an object that you have edit rights over");
556 return true;
557
558 // ---------------- COMMAND: OBJECT, DUPLICATE ----------------
559 case "object_duplicate":
560 switch(argv(2))
561 {
562 case "copy":
563 // copies customizable properties of the selected object to the clipboard cvar
564 e = sandbox_ObjectEdit_Get(player, autocvar_g_sandbox_editor_free); // can we copy objects we can't edit?
565 if(e != NULL)
566 {
567 s = sandbox_ObjectPort_Save(e, false);
568 s = strreplace("\"", "\\\"", s);
569 stuffcmd(player, strcat("set ", argv(3), " \"", s, "\""));
570
571 print_to(player, "^2SANDBOX - INFO: ^7Object copied to clipboard");
572 return true;
573 }
574 print_to(player, "^1SANDBOX - WARNING: ^7Object could not be copied. Make sure you are facing an object that you have copy rights over");
575 return true;
576
577 case "paste":
578 // spawns a new object using the properties in the player's clipboard cvar
579 if(time < player.object_flood)
580 {
581 print_to(player, strcat("^1SANDBOX - WARNING: ^7Flood protection active. Please wait ^3", ftos(player.object_flood - time), " ^7seconds beofore spawning another object"));
582 return true;
583 }
584 player.object_flood = time + autocvar_g_sandbox_editor_flood;
585 if(argv(3) == "") // no object in clipboard
586 {
587 print_to(player, "^1SANDBOX - WARNING: ^7No object in clipboard. You must copy an object before you can paste it");
588 return true;
589 }
591 {
592 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"));
593 return true;
594 }
595 e = sandbox_ObjectPort_Load(player, argv(3), false);
596
597 print_to(player, "^2SANDBOX - INFO: ^7Object pasted successfully");
599 LOG_INFO("^3SANDBOX - SERVER: ^7", player.netname, " pasted an object at origin ^3", vtos(e.origin));
600 return true;
601 }
602 return true;
603
604 // ---------------- COMMAND: OBJECT, ATTACH ----------------
605 case "object_attach":
606 switch(argv(2))
607 {
608 case "get":
609 // select e as the object as meant to be attached
610 e = sandbox_ObjectEdit_Get(player, true);
611 if(e != NULL)
612 {
613 player.object_attach = e;
614 print_to(player, "^2SANDBOX - INFO: ^7Object selected for attachment");
615 return true;
616 }
617 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");
618 return true;
619 case "set":
620 if(player.object_attach == NULL)
621 {
622 print_to(player, "^1SANDBOX - WARNING: ^7No object selected for attachment. Please select an object to be attached first.");
623 return true;
624 }
625
626 // attaches the previously selected object to e
627 e = sandbox_ObjectEdit_Get(player, true);
628 if(e != NULL)
629 {
630 sandbox_ObjectAttach_Set(player.object_attach, e, argv(3));
631 player.object_attach = NULL; // object was attached, no longer keep it scheduled for attachment
632 print_to(player, "^2SANDBOX - INFO: ^7Object attached successfully");
634 LOG_INFO("^3SANDBOX - SERVER: ^7", player.netname, " attached objects at origin ^3", vtos(e.origin));
635 return true;
636 }
637 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");
638 return true;
639 case "remove":
640 // removes e if it was attached
641 e = sandbox_ObjectEdit_Get(player, true);
642 if(e != NULL)
643 {
645 print_to(player, "^2SANDBOX - INFO: ^7Child objects detached successfully");
647 LOG_INFO("^3SANDBOX - SERVER: ^7", player.netname, " detached objects at origin ^3", vtos(e.origin));
648 return true;
649 }
650 print_to(player, "^1SANDBOX - WARNING: ^7Child objects could not be detached. Make sure you are facing an object that you have edit rights over");
651 return true;
652 }
653 return true;
654
655 // ---------------- COMMAND: OBJECT, EDIT ----------------
656 case "object_edit":
657 if(argv(2) == "")
658 {
659 print_to(player, "^1SANDBOX - WARNING: ^7Too few parameters. You must specify a property to edit");
660 return true;
661 }
662
663 e = sandbox_ObjectEdit_Get(player, true);
664 if(e != NULL)
665 {
666 switch(argv(2))
667 {
668 case "skin":
669 e.skin = stof(argv(3));
670 break;
671 case "alpha":
672 e.alpha = stof(argv(3));
673 break;
674 case "color_main":
675 e.colormod = stov(argv(3));
676 break;
677 case "color_glow":
678 e.glowmod = stov(argv(3));
679 break;
680 case "frame":
681 e.frame = stof(argv(3));
682 break;
683 case "scale":
685 break;
686 case "solidity":
687 switch(argv(3))
688 {
689 case "0": // non-solid
690 e.solid = SOLID_TRIGGER;
691 break;
692 case "1": // solid
693 e.solid = SOLID_BBOX;
694 break;
695 default:
696 break;
697 }
698 case "physics":
699 switch(argv(3))
700 {
701 case "0": // static
703 break;
704 case "1": // movable
706 break;
707 case "2": // physical
709 break;
710 default:
711 break;
712 }
713 break;
714 case "force":
715 e.damageforcescale = stof(argv(3));
716 break;
717 case "material":
718 strfree(e.material);
719 if(argv(3))
720 {
721 for (j = 1; j <= 5; ++j) // precache material sounds, 5 in total
722 precache_sound(strcat("object/impact_", argv(3), "_", ftos(j), ".wav"));
723 e.material = strzone(argv(3));
724 }
725 else
726 e.material = string_null; // no material
727 break;
728 default:
729 print_to(player, "^1SANDBOX - WARNING: ^7Invalid object property. For usage information, type 'sandbox help'");
730 return true;
731 }
732
733 // update last editing time
734 strcpy(e.message2, strftime(true, "%d-%m-%Y %H:%M:%S"));
735
737 LOG_INFO("^3SANDBOX - SERVER: ^7", player.netname, " edited property ^3", argv(2), " ^7of an object at origin ^3", vtos(e.origin));
738 return true;
739 }
740
741 print_to(player, "^1SANDBOX - WARNING: ^7Object could not be edited. Make sure you are facing an object that you have edit rights over");
742 return true;
743
744 // ---------------- COMMAND: OBJECT, CLAIM ----------------
745 case "object_claim":
746 // if the player can edit an object but is not its owner, this can be used to claim that object
747 if(player.crypto_idfp == "")
748 {
749 print_to(player, "^1SANDBOX - WARNING: ^7You do not have a player UID, and cannot claim objects");
750 return true;
751 }
752 e = sandbox_ObjectEdit_Get(player, true);
753 if(e != NULL)
754 {
755 // update the owner's name
756 // Do this before checking if you're already the owner and skipping if such, so we
757 // also update the player's nickname if they changed it (but has the same player UID)
758 if(e.netname != player.netname)
759 {
760 strcpy(e.netname, player.netname);
761 print_to(player, "^2SANDBOX - INFO: ^7Object owner name updated");
762 }
763
764 if(e.crypto_idfp == player.crypto_idfp)
765 {
766 print_to(player, "^2SANDBOX - INFO: ^7Object is already yours, nothing to claim");
767 return true;
768 }
769
770 strcpy(e.crypto_idfp, player.crypto_idfp);
771
772 print_to(player, "^2SANDBOX - INFO: ^7Object claimed successfully");
773 }
774 print_to(player, "^1SANDBOX - WARNING: ^7Object could not be claimed. Make sure you are facing an object that you have edit rights over");
775 return true;
776
777 // ---------------- COMMAND: OBJECT, INFO ----------------
778 case "object_info":
779 // prints public information about the object to the player
780 e = sandbox_ObjectEdit_Get(player, false);
781 if(e != NULL)
782 {
783 switch(argv(2))
784 {
785 case "object":
786 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\""));
787 return true;
788 case "mesh":
789 s = "";
790 FOR_EACH_TAG(e)
791 s = strcat(s, "^7\"^5", gettaginfo_name, "^7\", ");
792 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));
793 return true;
794 case "attachments":
795 // this should show the same info as 'mesh' but for attachments
796 s = "";
797 j = 0;
798 IL_EACH(g_sandbox_objects, it.owner == e,
799 {
800 ++j; // start from 1
801 gettaginfo(e, it.tag_index);
802 s = strcat(s, "^1attachment ", ftos(j), "^7 has mesh \"^3", it.model, "^7\" at animation frame ^3", ftos(it.frame));
803 s = strcat(s, "^7 and is attached to bone \"^5", gettaginfo_name, "^7\", ");
804 });
805 if(j) // object contains attachments
806 print_to(player, strcat("^2SANDBOX - INFO: ^7Object contains the following ^1", ftos(j), "^7 attachment(s): ", s));
807 else
808 print_to(player, "^2SANDBOX - INFO: ^7Object contains no attachments");
809 return true;
810 }
811 }
812 print_to(player, "^1SANDBOX - WARNING: ^7No information could be found. Make sure you are facing an object");
813 return true;
814
815 // ---------------- COMMAND: DEFAULT ----------------
816 default:
817 print_to(player, "Invalid command. For usage information, type 'sandbox help'");
818 return true;
819 }
820 }
821}
#define MUTATOR_CALLHOOK(id,...)
Definition base.qh:143
#define MUTATOR_RETURNVALUE
Definition base.qh:328
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
#define M_ARGV(x, type)
Definition events.qh:17
#define FOR_EACH_TAG(v)
Definition util.qh:218
const float SOLID_TRIGGER
const float SOLID_BBOX
string gettaginfo_name
float time
ERASEABLE bool fexists(string f)
Definition file.qh:4
#define IL_EACH(this, cond, body)
#define LOG_INFO(...)
Definition log.qh:62
string cmd_name
Definition events.qh:12
int cmd_argc
Definition events.qh:13
float stof(string val,...)
vector stov(string s)
string precache_sound(string sample)
string vtos(vector v)
string ftos(float f)
string strzone(string s)
string argv(float n)
void set_movetype(entity this, int mt)
Definition movetypes.qc:4
const int MOVETYPE_NONE
Definition movetypes.qh:133
const int MOVETYPE_PHYSICS
Definition movetypes.qh:146
const int MOVETYPE_TOSS
Definition movetypes.qh:139
string string_null
Definition nil.qh:9
strcat(_("^F4Countdown stopped!"), "\n^BG", _("Teams are too unbalanced."))
#define NULL
Definition post.qh:14
#define stuffcmd(cl,...)
Definition progsdefs.qh:23
void print_to(entity to, string input)
Definition common.qc:171
#define strfree(this)
Definition string.qh:57
#define strcpy(this, s)
Definition string.qh:51
void sandbox_ObjectRemove(entity e)
bool autocvar_g_sandbox_readonly
Definition sv_sandbox.qc:7
entity sandbox_ObjectSpawn(entity this, float database)
float autocvar_g_sandbox_editor_flood
Definition sv_sandbox.qc:11
entity sandbox_ObjectEdit_Get(entity this, float permissions)
Definition sv_sandbox.qc:97
string sandbox_ObjectPort_Save(entity e, bool database)
void sandbox_ObjectAttach_Remove(entity e)
void sandbox_ObjectEdit_Scale(entity e, float f)
float object_count
Definition sv_sandbox.qc:37
IntrusiveList g_sandbox_objects
Definition sv_sandbox.qc:21
entity sandbox_ObjectPort_Load(entity this, string s, float database)
int autocvar_g_sandbox_info
Definition sv_sandbox.qc:6
int autocvar_g_sandbox_editor_maxobjects
Definition sv_sandbox.qc:12
int autocvar_g_sandbox_editor_free
Definition sv_sandbox.qc:13
void sandbox_ObjectAttach_Set(entity e, entity parent, string s)

References argv(), autocvar_g_sandbox_editor_flood, autocvar_g_sandbox_editor_free, autocvar_g_sandbox_editor_maxobjects, autocvar_g_sandbox_info, autocvar_g_sandbox_readonly, cmd_argc, cmd_name, entity(), fexists(), FOR_EACH_TAG, ftos(), g_sandbox_objects, gettaginfo_name, IL_EACH, LOG_INFO, M_ARGV, MOVETYPE_NONE, MOVETYPE_PHYSICS, MOVETYPE_TOSS, MUTATOR_CALLHOOK, MUTATOR_RETURNVALUE, NULL, object_count, precache_sound(), print_to(), sandbox_ObjectAttach_Remove(), sandbox_ObjectAttach_Set(), sandbox_ObjectEdit_Get(), sandbox_ObjectEdit_Scale(), sandbox_ObjectPort_Load(), sandbox_ObjectPort_Save(), sandbox_ObjectRemove(), sandbox_ObjectSpawn(), set_movetype(), SOLID_BBOX, SOLID_TRIGGER, stof(), stov(), strcat(), strcpy, strfree, string_null, strzone(), stuffcmd, SV_ParseClientCommand, time, and vtos().

◆ MUTATOR_HOOKFUNCTION() [2/2]

MUTATOR_HOOKFUNCTION ( sandbox ,
SV_StartFrame  )

Definition at line 823 of file sv_sandbox.qc.

824{
826 return;
827 if(time < autosave_time)
828 return;
830
832
833 return true;
834}
void sandbox_Database_Save()
float autocvar_g_sandbox_storage_autosave
Definition sv_sandbox.qc:9
float autosave_time
Definition sv_sandbox.qc:22

References autocvar_g_sandbox_storage_autosave, autosave_time, sandbox_Database_Save(), and time.

◆ sandbox_Database_Load()

void sandbox_Database_Load ( )

Definition at line 412 of file sv_sandbox.qc.

413{
414 // loads all objects from the database file
415 string file_read, file_name;
416 float file_get, i;
417
418 file_name = strcat("sandbox/storage_", autocvar_g_sandbox_storage_name, "_", GetMapname(), ".txt");
419 file_get = fopen(file_name, FILE_READ);
420 if(file_get < 0)
421 {
423 LOG_INFO("^3SANDBOX - SERVER: ^7could not find storage file ^3", file_name, "^7, no objects were loaded");
424 return;
425 }
426 else
427 {
428 for (;;)
429 {
430 file_read = fgets(file_get);
431 if(file_read == "")
432 break;
433 if(substring(file_read, 0, 2) == "//")
434 continue;
435 if(substring(file_read, 0, 1) == "#")
436 continue;
437
438 entity e = sandbox_ObjectPort_Load(NULL, file_read, true);
439
440 if(e.material)
441 {
442 // since objects are being loaded for the first time, precache material sounds for each
443 for (i = 1; i <= 5; ++i) // 5 sounds in total
444 precache_sound(strcat("object/impact_", e.material, "_", ftos(i), ".wav"));
445 }
446 }
448 LOG_INFO("^3SANDBOX - SERVER: ^7successfully loaded storage file ^3", file_name);
449 }
450 fclose(file_get);
451}
const float FILE_READ
string GetMapname()
string fgets(float fhandle)
void fclose(float fhandle)
string substring(string s, float start, float length)
float fopen(string filename, float mode)
string autocvar_g_sandbox_storage_name
Definition sv_sandbox.qc:8

References autocvar_g_sandbox_info, autocvar_g_sandbox_storage_name, entity(), fclose(), fgets(), FILE_READ, fopen(), ftos(), GetMapname(), LOG_INFO, NULL, precache_sound(), sandbox_ObjectPort_Load(), strcat(), and substring().

◆ sandbox_Database_Save()

void sandbox_Database_Save ( )

Definition at line 390 of file sv_sandbox.qc.

391{
392 if(MUTATOR_CALLHOOK(Sandbox_SaveAllowed))
393 return;
394
395 // saves all objects to the database file
396 string file_name;
397 float file_get;
398
399 file_name = strcat("sandbox/storage_", autocvar_g_sandbox_storage_name, "_", GetMapname(), ".txt");
400 file_get = fopen(file_name, FILE_WRITE);
401 fputs(file_get, strcat("// sandbox storage \"", autocvar_g_sandbox_storage_name, "\" for map \"", GetMapname(), "\" last updated ", strftime(true, "%d-%m-%Y %H:%M:%S")));
402 fputs(file_get, strcat(" containing ", ftos(object_count), " objects\n"));
403
404 IL_EACH(g_sandbox_objects, !it.owner, // attached objects are persisted separately, ignore them here
405 {
406 // use a line of text for each object, listing all properties
407 fputs(file_get, strcat(sandbox_ObjectPort_Save(it, true), "\n"));
408 });
409 fclose(file_get);
410}
const float FILE_WRITE
void fputs(float fhandle, string s)

References autocvar_g_sandbox_storage_name, fclose(), FILE_WRITE, fopen(), fputs(), ftos(), g_sandbox_objects, GetMapname(), IL_EACH, MUTATOR_CALLHOOK, object_count, and strcat().

Referenced by MUTATOR_HOOKFUNCTION().

◆ sandbox_ObjectAttach_Remove()

void sandbox_ObjectAttach_Remove ( entity e)

Definition at line 147 of file sv_sandbox.qc.

148{
149 // detaches any object attached to e
150
151 IL_EACH(g_sandbox_objects, it.owner == e,
152 {
153 vector org = gettaginfo(it, 0);
154 setattachment(it, NULL, "");
155 it.owner = NULL;
156
157 // objects change origin and angles when detached, so apply previous position
158 setorigin(it, org);
159 it.angles = e.angles; // don't allow detached objects to spin or roll
160
161 it.solid = it.old_solid; // restore persisted solidity
162 set_movetype(it, it.old_movetype); // restore persisted physics
163 it.takedamage = DAMAGE_AIM;
164 });
165}

References entity(), g_sandbox_objects, and IL_EACH.

Referenced by MUTATOR_HOOKFUNCTION(), sandbox_ObjectAttach_Set(), and sandbox_ObjectRemove().

◆ sandbox_ObjectAttach_Set()

void sandbox_ObjectAttach_Set ( entity e,
entity parent,
string s )

Definition at line 130 of file sv_sandbox.qc.

131{
132 // attaches e to parent on string s
133
134 // we can't attach to an attachment, for obvious reasons
136
137 e.old_solid = e.solid; // persist solidity
138 e.old_movetype = e.move_movetype; // persist physics
140 e.solid = SOLID_NOT;
141 e.takedamage = DAMAGE_NO;
142
143 setattachment(e, parent, s);
144 e.owner = parent;
145}
entity parent
Definition animhost.qc:7
const float SOLID_NOT
const int MOVETYPE_FOLLOW
Definition movetypes.qh:145
const int DAMAGE_NO
Definition subs.qh:79

References DAMAGE_NO, entity(), MOVETYPE_FOLLOW, parent, sandbox_ObjectAttach_Remove(), set_movetype(), and SOLID_NOT.

Referenced by MUTATOR_HOOKFUNCTION(), and sandbox_ObjectPort_Load().

◆ sandbox_ObjectEdit_Get()

entity sandbox_ObjectEdit_Get ( entity this,
float permissions )

Definition at line 97 of file sv_sandbox.qc.

98{
99 // Returns the traced entity if the player can edit it, and NULL if not.
100 // If permissions if false, the object is returned regardless of editing rights.
101 // Attached objects are SOLID_NOT and do not get traced.
102
105 return NULL; // out of trace range
106 if(trace_ent.classname != "object")
107 return NULL; // entity is not an object
108 if(!permissions)
109 return trace_ent; // don't check permissions, anyone can edit this object
110 if(trace_ent.crypto_idfp == "")
111 return trace_ent; // the player who spawned this object did not have an UID, so anyone can edit it
112 if (!(trace_ent.realowner != this && autocvar_g_sandbox_editor_free < 2))
113 return trace_ent; // object does not belong to the player, and players can only edit their own objects on this server
114 return NULL;
115}
entity trace_ent
vector origin
vector WarpZone_UnTransformOrigin(entity wz, vector org)
Transforms origin org backwards through warpzone wz, as the inverse of WarpZone_TransformOrigin.
Definition common.qc:526
entity WarpZone_trace_transform
Transform accumulator during a trace.
Definition common.qh:40
float autocvar_g_sandbox_editor_distance_edit
Definition sv_sandbox.qc:15
void WarpZone_crosshair_trace_plusvisibletriggers(entity pl)
Definition tracing.qc:576
#define vdist(v, cmp, f)
Vector distance comparison, avoids sqrt().
Definition vector.qh:8

References autocvar_g_sandbox_editor_distance_edit, autocvar_g_sandbox_editor_free, entity(), NULL, origin, trace_ent, vdist, WarpZone_crosshair_trace_plusvisibletriggers(), WarpZone_trace_transform, and WarpZone_UnTransformOrigin().

Referenced by MUTATOR_HOOKFUNCTION().

◆ sandbox_ObjectEdit_Scale()

void sandbox_ObjectEdit_Scale ( entity e,
float f )

Definition at line 117 of file sv_sandbox.qc.

118{
119 e.scale = f;
120 if(e.scale)
121 {
123 _setmodel(e, e.model); // reset mins and maxs based on mesh
124 // apply object scaling and prevent any float precision issues like #2742
125 setsize(e, RoundPerfectVector(e.mins * e.scale), RoundPerfectVector(e.maxs * e.scale));
126 }
127}
float bound(float min, float value, float max)
float autocvar_g_sandbox_object_scale_max
Definition sv_sandbox.qc:17
float autocvar_g_sandbox_object_scale_min
Definition sv_sandbox.qc:16
ERASEABLE vector RoundPerfectVector(vector v)
Definition vector.qh:215

References autocvar_g_sandbox_object_scale_max, autocvar_g_sandbox_object_scale_min, bound(), entity(), and RoundPerfectVector().

Referenced by MUTATOR_HOOKFUNCTION(), and sandbox_ObjectPort_Load().

◆ sandbox_ObjectFunction_Think()

void sandbox_ObjectFunction_Think ( entity this)

Definition at line 67 of file sv_sandbox.qc.

68{
69 // decide if and how this object can be grabbed
70 if(autocvar_g_sandbox_readonly || MUTATOR_CALLHOOK(Sandbox_DragAllowed, this))
71 this.grab = 0; // no grabbing
73 this.grab = 1; // owner only
74 else
75 this.grab = 3; // anyone
76
77 // Object owner is stored via player UID, but we also need the owner as an entity (if the player is available on the server).
78 // Therefore, scan for all players, and update the owner as long as the player is present. We must always do this,
79 // since if the owning player disconnects, the object's owner should also be reset.
80
81 // bots can't have objects
83 if(this.crypto_idfp == it.crypto_idfp)
84 {
85 this.realowner = it;
86 break;
87 }
88 this.realowner = NULL;
89 });
90
91 this.nextthink = time;
92
94}
int grab
Definition cheats.qh:26
#define IS_PLAYER(s)
Definition player.qh:242
float nextthink
#define CSQCMODEL_AUTOUPDATE(e)
string crypto_idfp
entity realowner
#define IS_REAL_CLIENT(v)
Definition utils.qh:17
#define FOREACH_CLIENT(cond, body)
Definition utils.qh:52

References autocvar_g_sandbox_editor_free, autocvar_g_sandbox_readonly, crypto_idfp, CSQCMODEL_AUTOUPDATE, entity(), FOREACH_CLIENT, grab, IS_PLAYER, IS_REAL_CLIENT, MUTATOR_CALLHOOK, nextthink, NULL, realowner, and time.

Referenced by sandbox_ObjectSpawn().

◆ sandbox_ObjectFunction_Touch()

void sandbox_ObjectFunction_Touch ( entity this,
entity toucher )

Definition at line 43 of file sv_sandbox.qc.

44{
45 // apply material impact effects
46
47 if(!this.material)
48 return;
49 if(this.touch_timer > time)
50 return; // don't execute each frame
51 this.touch_timer = time + 0.1;
52
53 // make particle count and sound volume depend on impact speed
54 float intensity = vlen(this.velocity) + vlen(toucher.velocity);
55 if(intensity) // avoid divisions by 0
56 intensity /= 2; // average the two velocities
58 return; // impact not strong enough to do anything
59 // now offset intensity and apply it to the effects
60 intensity -= autocvar_g_sandbox_object_material_velocity_min; // start from minimum velocity, not actual velocity
61 intensity = bound(0, intensity * autocvar_g_sandbox_object_material_velocity_factor, 1);
62
63 _sound(this, CH_TRIGGER, strcat("object/impact_", this.material, "_", ftos(ceil(random() * 5)) , ".wav"), VOL_BASE * intensity, ATTEN_NORM);
64 Send_Effect_(strcat("impact_", this.material), this.origin, '0 0 0', ceil(intensity * 10)); // allow a count from 1 to 10
65}
vector velocity
void Send_Effect_(string eff_name, vector eff_loc, vector eff_vel, int eff_cnt)
Definition all.qc:160
float ceil(float f)
float random(void)
float vlen(vector v)
entity entity toucher
Definition self.qh:76
const int CH_TRIGGER
Definition sound.qh:12
const float VOL_BASE
Definition sound.qh:36
#define _sound(e, c, s, v, a)
Definition sound.qh:43
const float ATTEN_NORM
Definition sound.qh:30
float touch_timer
Definition sv_sandbox.qc:42
float autocvar_g_sandbox_object_material_velocity_min
Definition sv_sandbox.qc:18
string material
Definition sv_sandbox.qc:40
float autocvar_g_sandbox_object_material_velocity_factor
Definition sv_sandbox.qc:19

References _sound, ATTEN_NORM, autocvar_g_sandbox_object_material_velocity_factor, autocvar_g_sandbox_object_material_velocity_min, bound(), ceil(), CH_TRIGGER, entity(), ftos(), material, origin, random(), Send_Effect_(), strcat(), time, touch_timer, toucher, velocity, vlen(), and VOL_BASE.

Referenced by sandbox_ObjectSpawn().

◆ sandbox_ObjectPort_Load()

entity sandbox_ObjectPort_Load ( entity this,
string s,
float database )

Definition at line 317 of file sv_sandbox.qc.

318{
319 // load object properties, and spawn a new object with them
320 int n, i;
321 entity e = NULL, parent = NULL;
322 string arg = string_null;
323
324 // separate objects between the ; symbols
325 n = tokenizebyseparator(s, "; ");
326 for(i = 0; i < n; ++i)
327 port_string[i] = argv(i);
328
329 // now separate and apply the properties of each object
330 for(i = 0; i < n; ++i)
331 {
332 #define SANDBOX_GETARG arg = argv(++argv_num);
333 int argv_num = -1; // starts at -1 so I don't need postincrement
334
335 string tagname = string_null;
337 e = sandbox_ObjectSpawn(this, database);
338
339 // ---------------- OBJECT PROPERTY STORAGE: LOAD ----------------
340 if(i)
341 {
342 // properties stored only for child objects
343 SANDBOX_GETARG; tagname = (arg != "") ? arg : string_null;
344 }
345 else
346 {
347 // properties stored only for parent objects
348 if(database)
349 {
350 SANDBOX_GETARG; setorigin(e, stov(arg));
351 SANDBOX_GETARG; e.angles = stov(arg);
352 }
353 parent = e; // mark parent objects as such
354 }
355 // properties stored for all objects
356 SANDBOX_GETARG; precache_model(arg); _setmodel(e, arg);
357 SANDBOX_GETARG; e.skin = stof(arg);
358 SANDBOX_GETARG; e.alpha = stof(arg);
359 SANDBOX_GETARG; e.colormod = stov(arg);
360 SANDBOX_GETARG; e.glowmod = stov(arg);
361 SANDBOX_GETARG; e.frame = stof(arg);
363 SANDBOX_GETARG; e.solid = e.old_solid = stof(arg);
364 SANDBOX_GETARG; e.old_movetype = stof(arg);
365 set_movetype(e, e.old_movetype);
366 SANDBOX_GETARG; e.damageforcescale = stof(arg);
367 strfree(e.material);
368 SANDBOX_GETARG; e.material = (arg != "") ? strzone(arg) : string_null;
369 if(database)
370 {
371 // properties stored only for the database
372 strfree(e.crypto_idfp);
373 SANDBOX_GETARG; e.crypto_idfp = (arg != "") ? strzone(arg) : string_null;
374 SANDBOX_GETARG; strcpy(e.netname, arg);
375 SANDBOX_GETARG; strcpy(e.message, arg);
376 SANDBOX_GETARG; strcpy(e.message2, arg);
377 }
378
379 // attach last
380 if(i)
381 sandbox_ObjectAttach_Set(e, parent, tagname);
382 }
383
384 for(i = 0; i <= MAX_STORAGE_ATTACHMENTS; ++i)
385 port_string[i] = string_null; // fully clear the string
386
387 return e;
388}
#define tokenize_console
#define tokenizebyseparator
#define SANDBOX_GETARG
string port_string[MAX_STORAGE_ATTACHMENTS]

References argv(), entity(), NULL, parent, port_string, SANDBOX_GETARG, sandbox_ObjectAttach_Set(), sandbox_ObjectEdit_Scale(), sandbox_ObjectSpawn(), set_movetype(), stof(), stov(), strcpy, strfree, string_null, strzone(), tokenize_console, and tokenizebyseparator.

Referenced by MUTATOR_HOOKFUNCTION(), and sandbox_Database_Load().

◆ sandbox_ObjectPort_Save()

string sandbox_ObjectPort_Save ( entity e,
bool database )

Definition at line 233 of file sv_sandbox.qc.

234{
235 // save object properties, and return them as a string
236 int o = 0;
237
238 // order doesn't really matter, as we're writing the file fresh
239 IL_EACH(g_sandbox_objects, it == e || it.owner == e, LAMBDA(
240 // the main object needs to be first in the array [0] with attached objects following
241 int slot, physics, solidity;
242 if(it == e) // this is the main object, place it first
243 {
244 slot = 0;
245 solidity = it.solid; // applied solidity is normal solidity for children
246 physics = it.move_movetype; // applied physics are normal physics for parents
247 }
248 else if(it.owner == e) // child object, list them in order
249 {
250 ++o; // children start from 1
251 slot = o;
252 solidity = it.old_solid; // persisted solidity is normal solidity for children
253 physics = it.old_movetype; // persisted physics are normal physics for children
254 gettaginfo(it.owner, it.tag_index); // get the name of the tag our object is attached to, used further below
255 }
256 else
257 continue;
258
259 // ---------------- OBJECT PROPERTY STORAGE: SAVE ----------------
260 if(slot)
261 {
262 // properties stored only for child objects
263 if(gettaginfo_name)
264 port_string[slot] = strcat(port_string[slot], "\"", gettaginfo_name, "\" ");
265 else
266 port_string[slot] = strcat(port_string[slot], "\"\" "); // none
267 }
268 else
269 {
270 // properties stored only for parent objects
271 if(database)
272 {
273 port_string[slot] = strcat(port_string[slot], sprintf("\"%.9v\"", it.origin), " ");
274 port_string[slot] = strcat(port_string[slot], sprintf("\"%.9v\"", it.angles), " ");
275 }
276 }
277 // properties stored for all objects
278 port_string[slot] = strcat(port_string[slot], "\"", it.model, "\" ");
279 port_string[slot] = strcat(port_string[slot], ftos(it.skin), " ");
280 port_string[slot] = strcat(port_string[slot], ftos(it.alpha), " ");
281 port_string[slot] = strcat(port_string[slot], sprintf("\"%.9v\"", it.colormod), " ");
282 port_string[slot] = strcat(port_string[slot], sprintf("\"%.9v\"", it.glowmod), " ");
283 port_string[slot] = strcat(port_string[slot], ftos(it.frame), " ");
284 port_string[slot] = strcat(port_string[slot], ftos(it.scale), " ");
285 port_string[slot] = strcat(port_string[slot], ftos(solidity), " ");
286 port_string[slot] = strcat(port_string[slot], ftos(physics), " ");
287 port_string[slot] = strcat(port_string[slot], ftos(it.damageforcescale), " ");
288 if(it.material)
289 port_string[slot] = strcat(port_string[slot], "\"", it.material, "\" ");
290 else
291 port_string[slot] = strcat(port_string[slot], "\"\" "); // none
292 if(database)
293 {
294 // properties stored only for the database
295 if(it.crypto_idfp)
296 port_string[slot] = strcat(port_string[slot], "\"", it.crypto_idfp, "\" ");
297 else
298 port_string[slot] = strcat(port_string[slot], "\"\" "); // none
299 port_string[slot] = strcat(port_string[slot], "\"", e.netname, "\" ");
300 port_string[slot] = strcat(port_string[slot], "\"", e.message, "\" ");
301 port_string[slot] = strcat(port_string[slot], "\"", e.message2, "\" ");
302 }
303 ));
304
305 // now apply the array to a simple string, with the ; symbol separating objects
306 string s = "";
307 for(int j = 0; j <= MAX_STORAGE_ATTACHMENTS; ++j)
308 {
309 if(port_string[j])
310 s = strcat(s, port_string[j], "; ");
311 port_string[j] = string_null; // fully clear the string
312 }
313
314 return s;
315}
#define LAMBDA(...)
Definition misc.qh:34

References entity(), g_sandbox_objects, IL_EACH, and LAMBDA.

Referenced by MUTATOR_HOOKFUNCTION().

◆ sandbox_ObjectRemove()

void sandbox_ObjectRemove ( entity e)

Definition at line 213 of file sv_sandbox.qc.

214{
215 sandbox_ObjectAttach_Remove(e); // detach child objects
216
217 // if the object being removed has been selected for attachment by a player, unset it
218 FOREACH_CLIENT(IS_PLAYER(it) && IS_REAL_CLIENT(it) && it.object_attach == e, { it.object_attach = NULL; });
219
220 strfree(e.material);
221 strfree(e.crypto_idfp);
222 strfree(e.netname);
223 strfree(e.message);
224 strfree(e.message2);
225 delete(e);
226 e = NULL;
227
228 --object_count;
229}

References entity(), FOREACH_CLIENT, IS_PLAYER, IS_REAL_CLIENT, NULL, object_count, sandbox_ObjectAttach_Remove(), and strfree.

Referenced by MUTATOR_HOOKFUNCTION().

◆ sandbox_ObjectSpawn()

entity sandbox_ObjectSpawn ( entity this,
float database )

Definition at line 167 of file sv_sandbox.qc.

168{
169 // spawn a new object with default properties
170
171 entity e = new(object);
173 e.takedamage = DAMAGE_AIM;
174 e.damageforcescale = 1;
175 e.solid = SOLID_BBOX; // SOLID_BSP would be best, but can lag the server badly
177 e.frame = 0;
178 e.skin = 0;
179 e.material = string_null;
182 e.nextthink = time;
183 //e.effects |= EF_SELECTABLE; // don't do this all the time, maybe just when editing objects?
184
185 if(!database)
186 {
187 // set the object's owner via player UID
188 // if the player does not have an UID, the owner cannot be stored and their objects may be edited by anyone
189 if(this.crypto_idfp != "")
190 e.crypto_idfp = strzone(this.crypto_idfp);
191 else
192 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!");
193
194 // set public object information
195 e.netname = strzone(this.netname); // name of the owner
196 e.message = strzone(strftime(true, "%d-%m-%Y %H:%M:%S")); // creation time
197 e.message2 = strzone(strftime(true, "%d-%m-%Y %H:%M:%S")); // last editing time
198
199 // set origin and direction based on player position and view angle
200 makevectors(this.v_angle);
201 vector view_org = this.origin + this.view_ofs;
203 setorigin(e, trace_endpos);
205 }
206
208
209 ++object_count;
210 return e;
211}
string netname
Definition powerups.qc:20
vector v_angle
Definition player.qh:236
const float MOVE_NORMAL
vector trace_endpos
vector v_forward
#define CSQCMODEL_AUTOINIT(e)
ERASEABLE entity IL_PUSH(IntrusiveList this, entity it)
Push to tail.
vector WarpZone_TransformVAngles(entity wz, vector ang)
Transforms v_angle ang across warpzone wz.
Definition common.qc:505
#define WarpZone_TraceLine(org, end, nomonsters, forent)
Definition common.qh:51
#define makevectors
Definition post.qh:21
vector view_ofs
Definition progsdefs.qc:151
#define setthink(e, f)
vector
Definition self.qh:96
#define settouch(e, f)
Definition self.qh:77
const int DAMAGE_AIM
Definition subs.qh:81
void sandbox_ObjectFunction_Think(entity this)
Definition sv_sandbox.qc:67
float autocvar_g_sandbox_editor_distance_spawn
Definition sv_sandbox.qc:14
void sandbox_ObjectFunction_Touch(entity this, entity toucher)
Definition sv_sandbox.qc:43

References autocvar_g_sandbox_editor_distance_spawn, crypto_idfp, CSQCMODEL_AUTOINIT, DAMAGE_AIM, entity(), g_sandbox_objects, IL_PUSH(), makevectors, MOVE_NORMAL, MOVETYPE_TOSS, netname, object_count, origin, print_to(), sandbox_ObjectFunction_Think(), sandbox_ObjectFunction_Touch(), set_movetype(), setthink, settouch, SOLID_BBOX, string_null, strzone(), time, trace_endpos, v_angle, v_forward, vector, view_ofs, WarpZone_trace_transform, WarpZone_TraceLine, and WarpZone_TransformVAngles().

Referenced by MUTATOR_HOOKFUNCTION(), and sandbox_ObjectPort_Load().

Variable Documentation

◆ autocvar_g_sandbox

string autocvar_g_sandbox

Definition at line 5 of file sv_sandbox.qc.

◆ autocvar_g_sandbox_editor_distance_edit

float autocvar_g_sandbox_editor_distance_edit

Definition at line 15 of file sv_sandbox.qc.

Referenced by sandbox_ObjectEdit_Get().

◆ autocvar_g_sandbox_editor_distance_spawn

float autocvar_g_sandbox_editor_distance_spawn

Definition at line 14 of file sv_sandbox.qc.

Referenced by sandbox_ObjectSpawn().

◆ autocvar_g_sandbox_editor_flood

float autocvar_g_sandbox_editor_flood

Definition at line 11 of file sv_sandbox.qc.

Referenced by MUTATOR_HOOKFUNCTION().

◆ autocvar_g_sandbox_editor_free

int autocvar_g_sandbox_editor_free

◆ autocvar_g_sandbox_editor_maxobjects

int autocvar_g_sandbox_editor_maxobjects

Definition at line 12 of file sv_sandbox.qc.

Referenced by MUTATOR_HOOKFUNCTION().

◆ autocvar_g_sandbox_info

int autocvar_g_sandbox_info

Definition at line 6 of file sv_sandbox.qc.

Referenced by MUTATOR_HOOKFUNCTION(), and sandbox_Database_Load().

◆ autocvar_g_sandbox_object_material_velocity_factor

float autocvar_g_sandbox_object_material_velocity_factor

Definition at line 19 of file sv_sandbox.qc.

Referenced by sandbox_ObjectFunction_Touch().

◆ autocvar_g_sandbox_object_material_velocity_min

float autocvar_g_sandbox_object_material_velocity_min

Definition at line 18 of file sv_sandbox.qc.

Referenced by sandbox_ObjectFunction_Touch().

◆ autocvar_g_sandbox_object_scale_max

float autocvar_g_sandbox_object_scale_max

Definition at line 17 of file sv_sandbox.qc.

Referenced by sandbox_ObjectEdit_Scale().

◆ autocvar_g_sandbox_object_scale_min

float autocvar_g_sandbox_object_scale_min

Definition at line 16 of file sv_sandbox.qc.

Referenced by sandbox_ObjectEdit_Scale().

◆ autocvar_g_sandbox_readonly

bool autocvar_g_sandbox_readonly

Definition at line 7 of file sv_sandbox.qc.

Referenced by MUTATOR_HOOKFUNCTION(), and sandbox_ObjectFunction_Think().

◆ autocvar_g_sandbox_storage_autoload

bool autocvar_g_sandbox_storage_autoload

Definition at line 10 of file sv_sandbox.qc.

◆ autocvar_g_sandbox_storage_autosave

float autocvar_g_sandbox_storage_autosave

Definition at line 9 of file sv_sandbox.qc.

Referenced by MUTATOR_HOOKFUNCTION().

◆ autocvar_g_sandbox_storage_name

string autocvar_g_sandbox_storage_name

Definition at line 8 of file sv_sandbox.qc.

Referenced by sandbox_Database_Load(), and sandbox_Database_Save().

◆ autosave_time

float autosave_time

Definition at line 22 of file sv_sandbox.qc.

Referenced by MUTATOR_HOOKFUNCTION().

◆ g_sandbox_objects

◆ material

string material

Definition at line 40 of file sv_sandbox.qc.

Referenced by sandbox_ObjectFunction_Touch().

◆ object_attach

entity object_attach

Definition at line 39 of file sv_sandbox.qc.

◆ object_count

float object_count
Initial value:
{
{
}
}
const float MAX_STORAGE_ATTACHMENTS = 16
#define MUTATOR_ONADD
Definition base.qh:309
#define IL_NEW()
void sandbox_Database_Load()
bool autocvar_g_sandbox_storage_autoload
Definition sv_sandbox.qc:10

Definition at line 37 of file sv_sandbox.qc.

Referenced by MUTATOR_HOOKFUNCTION(), sandbox_Database_Save(), sandbox_ObjectRemove(), and sandbox_ObjectSpawn().

◆ object_flood

float object_flood

Definition at line 38 of file sv_sandbox.qc.

◆ old_movetype

float old_movetype

Definition at line 96 of file sv_sandbox.qc.

◆ old_solid

float old_solid

Definition at line 96 of file sv_sandbox.qc.

◆ port_string

string port_string[MAX_STORAGE_ATTACHMENTS]

Definition at line 231 of file sv_sandbox.qc.

Referenced by sandbox_ObjectPort_Load().

◆ touch_timer

float touch_timer

Definition at line 42 of file sv_sandbox.qc.

Referenced by sandbox_ObjectFunction_Touch().