]> de.git.xonotic.org Git - xonotic/darkplaces.git/commitdiff
Implement extension DP_QC_FINDBOX
authorbones_was_here <bones_was_here@xonotic.au>
Fri, 24 Feb 2023 18:53:08 +0000 (04:53 +1000)
committerbones_was_here <bones_was_here@xonotic.au>
Fri, 24 Feb 2023 18:53:08 +0000 (04:53 +1000)
Returns a chain of entities that are touching a box (a simpler findradius);
supports DP_QC_FINDCHAIN_TOFIELD

Implements https://gitlab.com/xonotic/darkplaces/-/issues/373

Signed-off-by: bones_was_here <bones_was_here@xonotic.au>
clvm_cmds.c
dpdefs/dpextensions.qc
svvm_cmds.c

index 6778f274208f6eee921907647e062ed530e4030c..c9a0710896116681343bf2370b34dd8c4eacf7b1 100644 (file)
@@ -519,6 +519,42 @@ static void VM_CL_findradius (prvm_prog_t *prog)
        VM_RETURN_EDICT(chain);
 }
 
+// #566 entity(vector mins, vector maxs) findbox
+// #566 entity(vector mins, vector maxs, .entity tofield) findbox_tofield
+static void VM_CL_findbox (prvm_prog_t *prog)
+{
+       prvm_edict_t *chain;
+       int i, numtouchedicts;
+       static prvm_edict_t *touchedicts[MAX_EDICTS];
+       int chainfield;
+
+       VM_SAFEPARMCOUNTRANGE(2, 3, VM_CL_findbox);
+
+       if(prog->argc == 3)
+               chainfield = PRVM_G_INT(OFS_PARM2);
+       else
+               chainfield = prog->fieldoffsets.chain;
+       if(chainfield < 0)
+               prog->error_cmd("VM_CL_findbox: %s doesnt have the specified chain field !", prog->name);
+
+       chain = (prvm_edict_t *)prog->edicts;
+
+       numtouchedicts = World_EntitiesInBox(&cl.world, PRVM_G_VECTOR(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM1), MAX_EDICTS, touchedicts);
+       if (numtouchedicts > MAX_EDICTS)
+       {
+               // this never happens   //[515]: for what then ?
+               Con_Printf("World_EntitiesInBox returned %i edicts, max was %i\n", numtouchedicts, MAX_EDICTS);
+               numtouchedicts = MAX_EDICTS;
+       }
+       for (i = 0; i < numtouchedicts; ++i)
+       {
+               PRVM_EDICTFIELDEDICT(touchedicts[i], chainfield) = PRVM_EDICT_TO_PROG(chain);
+               chain = touchedicts[i];
+       }
+
+       VM_RETURN_EDICT(chain);
+}
+
 // #34 float() droptofloor
 static void VM_CL_droptofloor (prvm_prog_t *prog)
 {
@@ -5508,7 +5544,7 @@ NULL,                                                     // #562
 NULL,                                                  // #563
 NULL,                                                  // #564
 NULL,                                                  // #565
-NULL,                                                  // #566
+VM_CL_findbox,                                 // #566 entity(vector mins, vector maxs) findbox = #566; (DP_QC_FINDBOX)
 NULL,                                                  // #567
 NULL,                                                  // #568
 NULL,                                                  // #569
index 32c5e7c5ab6a145596decc113fc96b0521ae0b7d..504628d37d625a35f65e6ca1b2ff125f1f1425f9 100644 (file)
@@ -2645,4 +2645,13 @@ void(string cmdname) registercommand = #352;
 //Adds a new console command which will take priority over a previous command of the same name (including engine commands) and in CSQC is removed when the VM shuts down. This will call CSQC_ConsoleCommand(string command) or ConsoleCmd(string command) in SVQC.  Return value should be true if QC handled the command, otherwise return false to have the engine handle it.
 
 
+//DP_QC_FINDBOX
+//idea: Mario
+//darkplaces implementation: bones_was_here
+//builtin definitions:
+entity(vector mins, vector maxs) findbox = #566;
+entity(vector mins, vector maxs, .entity tofield) findbox_tofield = #566;
+//description:
+//Returns a chain of entities that are touching a box (a simpler findradius); supports DP_QC_FINDCHAIN_TOFIELD
+
 float(float dividend, float divisor) mod = #245;
index a8ed38364c90edd124866c53106fd9f6ff09ba77..0e19550dc2a7207f81757007cbf0fe15f900cf63 100644 (file)
@@ -229,6 +229,7 @@ const char *vm_sv_extensions[] = {
 "ZQ_PAUSE",
 "DP_RM_CLIPGROUP",
 "DP_QC_FS_SEARCH_PACKFILE",
+"DP_QC_FINDBOX",
 NULL
 //"EXT_CSQC" // not ready yet
 };
@@ -1056,6 +1057,50 @@ static void VM_SV_findradius(prvm_prog_t *prog)
        VM_RETURN_EDICT(chain);
 }
 
+/*
+=================
+VM_SV_findbox
+
+Returns a chain of entities that are touching a box (a simpler findradius); supports DP_QC_FINDCHAIN_TOFIELD
+
+findbox (mins, maxs)
+=================
+*/
+static void VM_SV_findbox(prvm_prog_t *prog)
+{
+       prvm_edict_t *chain;
+       int i, numtouchedicts;
+       static prvm_edict_t *touchedicts[MAX_EDICTS];
+       int chainfield;
+
+       VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_findbox);
+
+       if(prog->argc == 3)
+               chainfield = PRVM_G_INT(OFS_PARM2);
+       else
+               chainfield = prog->fieldoffsets.chain;
+       if (chainfield < 0)
+               prog->error_cmd("VM_SV_findbox: %s doesnt have the specified chain field !", prog->name);
+
+       chain = (prvm_edict_t *)prog->edicts;
+
+       numtouchedicts = SV_EntitiesInBox(PRVM_G_VECTOR(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM1), MAX_EDICTS, touchedicts);
+       if (numtouchedicts > MAX_EDICTS)
+       {
+               // this never happens
+               Con_Printf("SV_EntitiesInBox returned %i edicts, max was %i\n", numtouchedicts, MAX_EDICTS);
+               numtouchedicts = MAX_EDICTS;
+       }
+       for (i = 0; i < numtouchedicts; ++i)
+       {
+               prog->xfunction->builtinsprofile++;
+               PRVM_EDICTFIELDEDICT(touchedicts[i], chainfield) = PRVM_EDICT_TO_PROG(chain);
+               chain = touchedicts[i];
+       }
+
+       VM_RETURN_EDICT(chain);
+}
+
 static void VM_SV_precache_sound(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1, VM_SV_precache_sound);
@@ -3763,7 +3808,7 @@ NULL,                                                     // #562
 NULL,                                                  // #563
 NULL,                                                  // #564
 NULL,                                                  // #565
-NULL,                                                  // #566
+VM_SV_findbox,                                 // #566 entity(vector mins, vector maxs) findbox = #566; (DP_QC_FINDBOX)
 NULL,                                                  // #567
 NULL,                                                  // #568
 NULL,                                                  // #569