From 43c9e02033d4b7b2100df527fb8ea5ab8e439e14 Mon Sep 17 00:00:00 2001 From: Mario Date: Wed, 15 Jan 2020 07:53:24 +1000 Subject: [PATCH] Add a function to skip certain target fields when using an entity's targets so they don't need to be manually nullified, fix a potential crash with warpzone targets --- qcsrc/common/mapobjects/triggers.qc | 17 +++++++------ qcsrc/common/mapobjects/triggers.qh | 4 ++++ qcsrc/lib/warpzone/server.qc | 37 ++++++++--------------------- xonotic-server.cfg | 2 ++ 4 files changed, 26 insertions(+), 34 deletions(-) diff --git a/qcsrc/common/mapobjects/triggers.qc b/qcsrc/common/mapobjects/triggers.qc index 9a7181d3a..27ffead9c 100644 --- a/qcsrc/common/mapobjects/triggers.qc +++ b/qcsrc/common/mapobjects/triggers.qc @@ -235,7 +235,7 @@ match (string)this.target and call their .use function ============================== */ -void SUB_UseTargets_Ex(entity this, entity actor, entity trigger, bool preventReuse) +void SUB_UseTargets_Ex(entity this, entity actor, entity trigger, bool preventReuse, int skiptargets) { // // check for a delay @@ -249,10 +249,10 @@ void SUB_UseTargets_Ex(entity this, entity actor, entity trigger, bool preventRe t.enemy = actor; t.message = this.message; t.killtarget = this.killtarget; - t.target = this.target; - t.target2 = this.target2; - t.target3 = this.target3; - t.target4 = this.target4; + if(!(skiptargets & BIT(1))) t.target = this.target; + if(!(skiptargets & BIT(2))) t.target2 = this.target2; + if(!(skiptargets & BIT(3))) t.target3 = this.target3; + if(!(skiptargets & BIT(4))) t.target4 = this.target4; t.antiwall_flag = this.antiwall_flag; return; } @@ -292,6 +292,8 @@ void SUB_UseTargets_Ex(entity this, entity actor, entity trigger, bool preventRe for(int i = 0; i < 4; ++i) { + if(skiptargets & BIT(i + 1)) + continue; switch(i) { default: @@ -329,5 +331,6 @@ void SUB_UseTargets_Ex(entity this, entity actor, entity trigger, bool preventRe } } -void SUB_UseTargets(entity this, entity actor, entity trigger) { SUB_UseTargets_Ex(this, actor, trigger, false); } -void SUB_UseTargets_PreventReuse(entity this, entity actor, entity trigger) { SUB_UseTargets_Ex(this, actor, trigger, true); } +void SUB_UseTargets(entity this, entity actor, entity trigger) { SUB_UseTargets_Ex(this, actor, trigger, false, 0); } +void SUB_UseTargets_PreventReuse(entity this, entity actor, entity trigger) { SUB_UseTargets_Ex(this, actor, trigger, true, 0); } +void SUB_UseTargets_SkipTargets(entity this, entity actor, entity trigger, int skiptargets) { SUB_UseTargets_Ex(this, actor, trigger, false, skiptargets); } diff --git a/qcsrc/common/mapobjects/triggers.qh b/qcsrc/common/mapobjects/triggers.qh index b9baf63f1..797c9767f 100644 --- a/qcsrc/common/mapobjects/triggers.qh +++ b/qcsrc/common/mapobjects/triggers.qh @@ -26,6 +26,10 @@ void SUB_UseTargets(entity this, entity actor, entity trigger); void SUB_UseTargets_PreventReuse(entity this, entity actor, entity trigger); +// allow excluding certain .target* fields without needing to nullify them +// use BIT(1) through BIT(4) +void SUB_UseTargets_SkipTargets(entity this, entity actor, entity trigger, int skiptargets); + void generic_setactive(entity this, int act); // generic methods for netlinked entities void generic_netlinked_reset(entity this); diff --git a/qcsrc/lib/warpzone/server.qc b/qcsrc/lib/warpzone/server.qc index 0244b40a9..66ee6b133 100644 --- a/qcsrc/lib/warpzone/server.qc +++ b/qcsrc/lib/warpzone/server.qc @@ -13,6 +13,10 @@ #include #endif +#ifdef SVQC +bool autocvar_sv_warpzone_allow_selftarget; +#endif + #ifdef WARPZONELIB_KEEPDEBUG #define WARPZONELIB_REMOVEHACK #endif @@ -213,19 +217,8 @@ void WarpZone_Touch(entity this, entity toucher) if(WarpZone_Teleport(this, toucher, f, 0)) { #ifdef SVQC - string save1, save2; - - save1 = this.target; this.target = string_null; - save2 = this.target3; this.target3 = string_null; - SUB_UseTargets(this, toucher, toucher); // use toucher too? - if (!this.target) this.target = save1; - if (!this.target3) this.target3 = save2; - - save1 = this.target; this.target = string_null; - save2 = this.target2; this.target2 = string_null; - SUB_UseTargets(this.enemy, toucher, toucher); // use toucher too? - if (!this.target) this.target = save1; - if (!this.target2) this.target2 = save2; + SUB_UseTargets_SkipTargets(this, toucher, toucher, BIT(1) | BIT(3)); // use toucher too? + SUB_UseTargets_SkipTargets(this.enemy, toucher, toucher, BIT(1) | BIT(2)); // use toucher too? #endif } else @@ -369,19 +362,8 @@ float WarpZone_CheckProjectileImpact(entity player) player.velocity = player.warpzone_oldvelocity; if(WarpZone_Teleport(wz, player, 0, 1)) { - string save1, save2; - - save1 = wz.target; wz.target = string_null; - save2 = wz.target3; wz.target3 = string_null; - SUB_UseTargets(wz, player, player); - if (!wz.target) wz.target = save1; - if (!wz.target3) wz.target3 = save2; - - save1 = wz.enemy.target; wz.enemy.target = string_null; - save2 = wz.enemy.target2; wz.enemy.target2 = string_null; - SUB_UseTargets(wz.enemy, player, player); - if (!wz.enemy.target) wz.enemy.target = save1; - if (!wz.enemy.target2) wz.enemy.target2 = save2; + SUB_UseTargets_SkipTargets(wz, player, player, BIT(1) | BIT(3)); + SUB_UseTargets_SkipTargets(wz.enemy, player, player, BIT(1) | BIT(2)); } else { @@ -648,7 +630,8 @@ void WarpZone_InitStep_FindTarget(entity this) // this way only one of the two ents needs to target if(this.target != "") { - this.enemy = this; // so the if(!e.enemy) check also skips this, saves one IF + if(!autocvar_sv_warpzone_allow_selftarget) + this.enemy = this; // so the if(!e.enemy) check also skips this, saves one IF e2 = NULL; for(e = NULL, i = 0; (e = find(e, targetname, this.target)); ) diff --git a/xonotic-server.cfg b/xonotic-server.cfg index 6e040d5b0..3db80bb33 100644 --- a/xonotic-server.cfg +++ b/xonotic-server.cfg @@ -570,3 +570,5 @@ set sv_damagetext 2 "<= 0: disabled, >= 1: visible to spectators, >= 2: visible set sv_showfps 5 "Show player's FPS counters in the scoreboard. This setting acts as a delay in seconds between updates" set autocvar_sv_doors_always_open 0 "If set to 1 don't close doors which after they were open" + +set sv_warpzone_allow_selftarget 0 "do not touch" -- 2.39.2