22#ifdef WARPZONELIB_KEEPDEBUG
23#define WARPZONELIB_REMOVEHACK
38#define WarpZone_StoreProjectileData(e_) MACRO_BEGIN \
40 e.warpzone_oldorigin = e.origin; \
41 e.warpzone_oldvelocity = e.velocity; \
42 e.warpzone_oldangles = e.angles; \
48 player.lastteleport_origin = player.origin;
49 player.lastteleporttime =
time;
51 setorigin(player, to);
52 player.angles = to_angles;
54 player.oldorigin = to;
55 player.fixangle =
true;
59 player.v_angle = player.angles;
63 player.velocity = to_velocity;
84 vector o0, a0, v0, o1, a1, v1, o10;
86 o0 = player.origin + player.view_ofs;
97 if(f0 != 0 ||
f1 != 0)
117 o1 = o1 - v1 * (d / dv);
121 tracebox(o1 - player.view_ofs, player.mins, player.maxs, o1 - player.view_ofs,
MOVE_NOMONSTERS, player);
124 setorigin(player, o1 - player.view_ofs);
127 o1 = player.origin + player.view_ofs;
128 setorigin(player, o0 - player.view_ofs);
132 LOG_INFO(
"would have to put player in solid, won't do that");
133 setorigin(player, o0 - player.view_ofs);
142 player.warpzone_teleport_time =
time;
143 player.warpzone_teleport_finishtime =
time;
144 player.warpzone_teleport_zone = wz;
148 float dt = (v1 !=
'0 0 0') ? (o1 - o10) * v1 * (1 / (v1 * v1)) : 0;
153#ifndef WARPZONE_USE_FIXANGLE
156 player = player.owner;
160 player.fixangle =
false;
162 entity ts =
new(warpzone_teleported);
165 ts.SendFlags = 0xFFFFFF;
166 ts.drawonlytoclient = player;
168 ts.nextthink =
time + 1;
172 ts.angles = wz.warpzone_transform;
186 if(
toucher.classname ==
"trigger_warpzone")
242 if(this.
origin !=
'0 0 0')
293 if(this.
origin !=
'0 0 0')
331#ifdef WARPZONELIB_KEEPDEBUG
332float WarpZone_CheckProjectileImpact(
entity player)
336 o0 = player.origin + player.view_ofs;
337 v0 = player.velocity;
340 if(
time <= player.warpzone_teleport_finishtime + 0.1)
349#ifdef WARPZONELIB_REMOVEHACK
350 LOG_INFO(
"impactfilter found something - and it no longer gets handled correctly - please tell divVerent whether anything behaves broken now");
352 LOG_INFO(
"impactfilter found something - and it even gets handled correctly - please tell divVerent that this code apparently gets triggered again");
354 LOG_INFO(
"Entity type: ", player.classname);
358#ifdef WARPZONELIB_REMOVEHACK
362 setorigin(player, player.warpzone_oldorigin);
363 player.velocity = player.warpzone_oldvelocity;
371 setorigin(player, o0 - player.view_ofs);
372 player.velocity = v0;
383 if(
toucher.classname ==
"trigger_warpzone")
396#ifdef WARPZONELIB_KEEPDEBUG
399 float save_dpstartcontents;
400 float save_dphitcontents;
401 float save_dphitq3surfaceflags;
402 string save_dphittexturename;
404 float save_startsolid;
408 float save_plane_dist;
425 float f = WarpZone_CheckProjectileImpact(
this);
426 if (f)
return (f > 0);
459 error(
"Warp zone with nonexisting killtarget");
470 error(
"Warp zone position with no target");
476 error(
"Warp zone position with nonexisting target");
479 if(this.
enemy.aiment)
482 error(
"Warp zone position targeting already oriented warpzone");
485 this.
enemy.aiment =
this;
493 ||
this.warpzone_save_eangles !=
this.enemy.angles)
510 error(
"Camera with no target");
519 error(
"Camera with nonexisting target");
546 norm = point =
'0 0 0';
548 for(i_s = 0; ; ++i_s)
550 tex = getsurfacetexture(
this, i_s);
553 if(tex ==
"textures/common/trigger" || tex ==
"trigger")
555 n_t = getsurfacenumtriangles(
this, i_s);
556 for(i_t = 0; i_t < n_t; ++i_t)
558 tri = getsurfacetriangle(
this, i_s, i_t);
559 a = getsurfacepoint(
this, i_s, tri.x);
560 b = getsurfacepoint(
this, i_s, tri.y);
561 c = getsurfacepoint(
this, i_s, tri.z);
562 n =
cross(c - a, b - a);
563 area = area +
vlen(n);
565 point = point +
vlen(n) * (a + b + c);
570 norm = norm * (1 / area);
571 point = point * (1 / (3 * area));
572 if(
vdist(norm, <, 0.99))
574 LOG_INFO(
"trigger_warpzone near ",
vtos(this.
aiment.origin),
" is nonplanar. BEWARE.");
587 org =
org - ((
org - point) * norm) * norm;
588 vector forward, right, up;
590 if(norm * forward < 0)
592 LOG_INFO(
"Position target of trigger_warpzone near ",
vtos(this.
aiment.origin),
" points into trigger_warpzone. BEWARE.");
595 ang = vectoangles2(norm, up);
597 if(norm * forward < 0.99)
610 error(
"cannot infer origin/angles for this warpzone, please use a killtarget or a trigger_warpzone_position");
640 if(e.classname ==
this.classname)
646 error(
"Warpzone with non-existing target");
659 error(
"Invalid warp zone detected. Killed.");
689 spawnfunc_misc_warpzone_position(
this);
724 precache_model(this.
model);
725 _setmodel(
this, this.
model);
727 setorigin(
this, this.
origin);
729 setsize(
this, this.
mins * this.
scale, this.
maxs * this.scale);
731 setsize(
this, this.
mins, this.
maxs);
734 else if(this.
solid < 0)
758 ||
this.warpzone_save_eangles !=
this.enemy.angles)
840 e.warpzone_reconnecting = ((
this.target ==
"" || e.target ==
this.target) && !((
this.spawnflags & 1) &&
visible_to_some_client(e)));
842 if(e.warpzone_reconnecting)
845 if(e.warpzone_reconnecting)
848 if(e.warpzone_reconnecting)
851 if(e.warpzone_reconnecting || e.enemy.warpzone_reconnecting)
862 spawnfunc_trigger_warpzone_reconnect(
this);
867#ifndef WARPZONE_DONT_FIX_VANGLE
873 this.v_angle_z += 720;
void bot_aim_reset(entity this)
#define BIT(n)
Only ever assign into the first 24 bits in QC (so max is BIT(23)).
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
#define setmodel(this, m)
#define IS_NOT_A_CLIENT(s)
#define PHYS_INPUT_FRAMETIME
#define PHYS_INPUT_ANGLES(s)
const float MOVE_NOMONSTERS
float trace_dphitcontents
const float VF_CL_VIEWANGLES
float trace_dpstartcontents
string trace_dphittexturename
float checkpvs(vector viewpos, entity viewee)
float trace_dphitq3surfaceflags
const float EF_NODEPTHTEST
vector trace_plane_normal
const int EF_TELEPORT_BIT
void SUB_Remove(entity this)
Remove entity.
#define MAKE_VECTORS(angles, forward, right, up)
Same as the makevectors builtin but uses the provided locals instead of the v_* globals.
ERASEABLE entity IL_PUSH(IntrusiveList this, entity it)
Push to tail.
#define IL_EACH(this, cond, body)
#define WriteHeader(to, id)
void WarpZone_Touch(entity this, entity toucher)
void WarpZone_SetUp(entity e, vector my_org, vector my_ang, vector other_org, vector other_ang)
void WarpZone_RefSys_Add(entity me, entity wz)
entity WarpZone_Find(vector mi, vector ma)
bool WarpZoneLib_ExactTrigger_Touch(entity this, entity toucher, bool touchfunc)
float WarpZone_PlaneDist(entity wz, vector v)
void WarpZone_Camera_SetUp(entity e, vector my_org, vector my_ang)
vector WarpZone_TransformVAngles(entity wz, vector ang)
vector WarpZone_TransformVelocity(entity wz, vector v)
vector WarpZone_TransformAngles(entity wz, vector v)
vector WarpZone_TransformOrigin(entity wz, vector v)
float WarpZone_TargetPlaneDist(entity wz, vector v)
int WarpZoneLib_MoveOutOfSolid(entity e)
#define EXACTTRIGGER_TOUCH(e, t)
#define BITSET_ASSIGN(a, b)
float warpzone_cameras_exist
vector warpzone_targetorigin
#define BITCLR_ASSIGN(a, b)
vector warpzone_targetangles
IntrusiveList g_warpzones
float warpzone_warpzones_exist
#define BITXOR_ASSIGN(a, b)
const int MOVETYPE_FOLLOW
#define setSendEntity(e, f)
IntrusiveList g_projectiles
float warpzone_initialized
void WarpZone_Think(entity this)
void WarpZone_InitStep_FindOriginTarget(entity this)
vector warpzone_oldvelocity
vector warpzone_save_eangles
bool WarpZone_Camera_Send(entity this, entity to, int sendflags)
void WarpZone_StartFrame()
bool WarpZone_Teleported_Send(entity this, entity to, int sf)
entity warpzone_teleport_zone
void WarpZone_TeleportPlayer(entity teleporter, entity player, vector to, vector to_angles, vector to_velocity)
float WarpZone_Projectile_Touch(entity this, entity toucher)
vector warpzone_oldangles
entity warpzone_position_first
entity warpzone_camera_first
bool WarpZone_Send(entity this, entity to, int sendflags)
vector warpzone_save_origin
float warpzone_teleport_time
float warpzone_teleport_finishtime
vector warpzone_save_angles
void WarpZoneCamera_InitStep_FindTarget(entity this)
vector warpzone_save_eorigin
void WarpZones_Reconnect()
void WarpZoneCamera_Think(entity this)
bool visible_to_some_client(entity ent)
#define WarpZone_StoreProjectileData(e_)
float warpzone_reconnecting
void WarpZone_InitStep_FindTarget(entity this)
void WarpZone_InitStep_UpdateTransform(entity this)
float WarpZone_Teleport(entity wz, entity player, float f0, float f1)
void WarpZone_InitStep_ClearTarget(entity this)
void WarpZonePosition_InitStep_FindTarget(entity this)
bool autocvar_sv_warpzone_allow_selftarget
void WarpZone_PlayerPhysics_FixVAngle(entity this)
vector warpzone_oldorigin
void WarpZone_InitStep_FinalizeTransform(entity this)
void WarpZone_Touch(entity this, entity toucher)
void trigger_warpzone_reconnect_use(entity this, entity actor, entity trigger)
bool WarpZone_Projectile_Touch_ImpactFilter_Callback(entity this, entity toucher)
void WarpZone_PostInitialize_Callback()
ClientState CS(Client this)
entity Simple_TeleportPlayer(entity teleporter, entity player)
void WarpZone_PostTeleportPlayer_Callback(entity pl)
entity Teleport_Find(vector mi, vector ma)
void SUB_UseTargets_SkipTargets(entity this, entity actor, entity trigger, int skiptargets)
void WarpZoneLib_ExactTrigger_Init(entity this, bool unsetmodel)
#define IS_REAL_CLIENT(v)
#define FOREACH_CLIENT(cond, body)
#define IS_BOT_CLIENT(v)
want: (IS_CLIENT(v) && !IS_REAL_CLIENT(v))
#define vdist(v, cmp, f)
Vector distance comparison, avoids sqrt()