#include <common/constants.qh>
#include <common/net_linked.qh>
#include <common/mapobjects/subs.qh>
+ #include <common/mapobjects/teleporters.qh>
#include <common/util.qh>
- #include <server/constants.qh>
- #include <server/defs.qh>
+ #include <common/weapons/_all.qh>
+ #include <common/stats.qh>
#include <server/utils.qh>
+ #include <server/weapons/common.qh>
+#endif
+
+#ifdef SVQC
+bool autocvar_sv_warpzone_allow_selftarget;
#endif
#ifdef WARPZONELIB_KEEPDEBUG
o1 = o1 - v1 * (d / dv);
}
- // put him out of solid
+ // put them out of solid
tracebox(o1 - player.view_ofs, player.mins, player.maxs, o1 - player.view_ofs, MOVE_NOMONSTERS, player);
if(trace_startsolid)
{
if(toucher.move_movetype == MOVETYPE_NONE || toucher.move_movetype == MOVETYPE_FOLLOW || toucher.tag_entity)
return;
- if(WarpZoneLib_ExactTrigger_Touch(this, toucher))
- return;
-
if(WarpZone_PlaneDist(this, toucher.origin + toucher.view_ofs) >= 0) // wrong side of the trigger_warpzone (don't teleport yet)
return;
+ EXACTTRIGGER_TOUCH(this, toucher);
+
float f;
// number of frames we need to go back:
// dist = 16*sqrt(2) qu
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
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
{
if(area > 0)
{
org = org - ((org - point) * norm) * norm; // project to plane
- makevectors(ang);
- if(norm * v_forward < 0)
+ vector forward, right, up;
+ MAKE_VECTORS(ang, forward, right, up);
+ if(norm * forward < 0)
{
LOG_INFO("Position target of trigger_warpzone near ", vtos(this.aiment.origin), " points into trigger_warpzone. BEWARE.");
norm = -1 * norm;
}
- ang = vectoangles2(norm, v_up); // keep rotation, but turn exactly against plane
+ ang = vectoangles2(norm, up); // keep rotation, but turn exactly against plane
ang.x = -ang.x;
- if(norm * v_forward < 0.99)
+ if(norm * forward < 0.99)
LOG_INFO("trigger_warpzone near ", vtos(this.aiment.origin), " has been turned to match plane orientation (", vtos(this.aiment.angles), " -> ", vtos(ang));
if(vdist(org - this.aiment.origin, >, 0.5))
LOG_INFO("trigger_warpzone near ", vtos(this.aiment.origin), " has been moved to match the plane (", vtos(this.aiment.origin), " -> ", vtos(org), ").");
// 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)); )
this.scale = this.modelscale;
if(!this.scale)
this.scale = 1;
- string m;
- m = this.model;
- WarpZoneLib_ExactTrigger_Init(this);
- if(m != "")
- {
- precache_model(m);
- _setmodel(this, m); // no precision needed
- }
- setorigin(this, this.origin);
- if(this.scale)
- setsize(this, this.mins * this.scale, this.maxs * this.scale);
- else
- setsize(this, this.mins, this.maxs);
+
+ WarpZoneLib_ExactTrigger_Init(this, false);
+
setSendEntity(this, WarpZone_Send);
this.SendFlags = 0xFFFFFF;
BITSET_ASSIGN(this.effects, EF_NODEPTHTEST);
if(warpzone_warpzones_exist)
WarpZone_StoreProjectileData(it); // TODO: not actually needed
- if(IS_OBSERVER(it) || it.solid == SOLID_NOT)
- if(IS_CLIENT(it)) // we don't care about it being a bot
+ if((IS_OBSERVER(it) || it.solid == SOLID_NOT))
{
// warpzones
if (warpzone_warpzones_exist) {
entity e = WarpZone_Find(it.origin + it.mins, it.origin + it.maxs);
if (e)
- if (!WarpZoneLib_ExactTrigger_Touch(e, it))
+ if (WarpZoneLib_ExactTrigger_Touch(e, it, false))
if (WarpZone_PlaneDist(e, it.origin + it.view_ofs) <= 0)
WarpZone_Teleport(e, it, -1, 0); // NOT triggering targets by this!
}
{
entity ent = Teleport_Find(it.origin + it.mins, it.origin + it.maxs);
if (ent)
- if (!WarpZoneLib_ExactTrigger_Touch(ent, it))
+ if (WarpZoneLib_ExactTrigger_Touch(ent, it, false))
Simple_TeleportPlayer(ent, it); // NOT triggering targets by this!
}
}