From bdd723fea3554c3a391ae854a79b8be705aebdb9 Mon Sep 17 00:00:00 2001 From: bones_was_here Date: Sat, 25 Feb 2023 04:53:08 +1000 Subject: [PATCH] Implement extension DP_QC_FINDBOX 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 --- clvm_cmds.c | 38 +++++++++++++++++++++++++++++++++- dpdefs/dpextensions.qc | 9 ++++++++ svvm_cmds.c | 47 +++++++++++++++++++++++++++++++++++++++++- 3 files changed, 92 insertions(+), 2 deletions(-) diff --git a/clvm_cmds.c b/clvm_cmds.c index 6778f274..c9a07108 100644 --- a/clvm_cmds.c +++ b/clvm_cmds.c @@ -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 diff --git a/dpdefs/dpextensions.qc b/dpdefs/dpextensions.qc index 32c5e7c5..504628d3 100644 --- a/dpdefs/dpextensions.qc +++ b/dpdefs/dpextensions.qc @@ -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; diff --git a/svvm_cmds.c b/svvm_cmds.c index a8ed3836..0e19550d 100644 --- a/svvm_cmds.c +++ b/svvm_cmds.c @@ -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 -- 2.39.2