Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
server.qc File Reference
#include "server.qh"
#include "common.qh"
Include dependency graph for server.qc:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define WarpZone_StoreProjectileData(e_)

Functions

 spawnfunc (func_camera)
 spawnfunc (misc_warpzone_position)
 spawnfunc (target_warpzone_reconnect)
 spawnfunc (trigger_warpzone)
 spawnfunc (trigger_warpzone_position)
 spawnfunc (trigger_warpzone_reconnect)
void trigger_warpzone_reconnect_use (entity this, entity actor, entity trigger)
bool visible_to_some_client (entity ent)
bool WarpZone_Camera_Send (entity this, entity to, int sendflags)
void WarpZone_InitStep_ClearTarget (entity this)
void WarpZone_InitStep_FinalizeTransform (entity this)
void WarpZone_InitStep_FindOriginTarget (entity this)
void WarpZone_InitStep_FindTarget (entity this)
void WarpZone_InitStep_UpdateTransform (entity this)
void WarpZone_PlayerPhysics_FixVAngle (entity this)
float WarpZone_Projectile_Touch (entity this, entity toucher)
bool WarpZone_Send (entity this, entity to, int sendflags)
void WarpZone_StartFrame ()
float WarpZone_Teleport (entity wz, entity player, float f0, float f1)
bool WarpZone_Teleported_Send (entity this, entity to, int sf)
void WarpZone_TeleportPlayer (entity teleporter, entity player, vector to, vector to_angles, vector to_velocity)
void WarpZone_Think (entity this)
void WarpZone_Touch (entity this, entity toucher)
void WarpZoneCamera_InitStep_FindTarget (entity this)
void WarpZoneCamera_Think (entity this)
void WarpZonePosition_InitStep_FindTarget (entity this)
void WarpZones_Reconnect ()

Variables

bool autocvar_sv_warpzone_allow_selftarget
entity warpzone_camera_first
float warpzone_initialized
entity warpzone_next
vector warpzone_oldangles
vector warpzone_oldorigin
vector warpzone_oldvelocity
entity warpzone_position_first
float warpzone_reconnecting
vector warpzone_save_angles
vector warpzone_save_eangles
vector warpzone_save_eorigin
vector warpzone_save_origin
float warpzone_teleport_finishtime
float warpzone_teleport_time
entity warpzone_teleport_zone

Macro Definition Documentation

◆ WarpZone_StoreProjectileData

#define WarpZone_StoreProjectileData ( e_)
Value:
MACRO_BEGIN \
entity e = e_; \
e.warpzone_oldorigin = e.origin; \
e.warpzone_oldvelocity = e.velocity; \
e.warpzone_oldangles = e.angles; \
#define MACRO_END
Definition macro.qh:7

Definition at line 38 of file server.qc.

38#define WarpZone_StoreProjectileData(e_) MACRO_BEGIN \
39 entity e = e_; \
40 e.warpzone_oldorigin = e.origin; \
41 e.warpzone_oldvelocity = e.velocity; \
42 e.warpzone_oldangles = e.angles; \
43 MACRO_END

Referenced by WarpZone_StartFrame(), and WarpZone_Teleport().

Function Documentation

◆ spawnfunc() [1/6]

spawnfunc ( func_camera )

Definition at line 713 of file server.qc.

714{
715 if(!this.scale)
716 this.scale = this.modelscale;
717 if(!this.scale)
718 this.scale = 1;
719 if(this.model != "")
720 {
721 precache_model(this.model);
722 _setmodel(this, this.model); // no precision needed
723 }
724 setorigin(this, this.origin);
725 if(this.scale)
726 setsize(this, this.mins * this.scale, this.maxs * this.scale);
727 else
728 setsize(this, this.mins, this.maxs);
729 if(!this.solid)
730 this.solid = SOLID_BSP;
731 else if(this.solid < 0)
732 this.solid = SOLID_NOT;
734 this.SendFlags = 0xFFFFFF;
737}
vector mins
const float SOLID_NOT
vector maxs
vector origin
const float SOLID_BSP
model
Definition ent_cs.qc:139
solid
Definition ent_cs.qc:165
int SendFlags
Definition net.qh:159
float modelscale
Definition models.qh:3
float scale
Definition projectile.qc:14
#define setSendEntity(e, f)
bool WarpZone_Camera_Send(entity this, entity to, int sendflags)
Definition server.qc:284
entity warpzone_camera_first
Definition server.qc:676
entity warpzone_next
Definition server.qc:677

References maxs, mins, model, modelscale, origin, scale, SendFlags, setSendEntity, solid, SOLID_BSP, SOLID_NOT, warpzone_camera_first, WarpZone_Camera_Send(), and warpzone_next.

◆ spawnfunc() [2/6]

spawnfunc ( misc_warpzone_position )

Definition at line 678 of file server.qc.

679{
680 // "target", "angles", "origin"
683}
entity warpzone_position_first
Definition server.qc:675

References warpzone_next, and warpzone_position_first.

◆ spawnfunc() [3/6]

spawnfunc ( target_warpzone_reconnect )

Definition at line 857 of file server.qc.

858{
859 spawnfunc_trigger_warpzone_reconnect(this); // both names make sense here :(
860}

◆ spawnfunc() [4/6]

spawnfunc ( trigger_warpzone )

Definition at line 688 of file server.qc.

689{
690 // warp zone entities must have:
691 // "killtarget" pointing to a target_position with a direction arrow
692 // that points AWAY from the warp zone, and that is inside
693 // the warp zone trigger
694 // "target" pointing to an identical warp zone at another place in
695 // the map, with another killtarget to designate its
696 // orientation
697
698 if(!this.scale)
699 this.scale = this.modelscale;
700 if(!this.scale)
701 this.scale = 1;
702
704
706 this.SendFlags = 0xFFFFFF;
709 warpzone_first = this;
710
711 IL_PUSH(g_warpzones, this);
712}
float effects
const float EF_NODEPTHTEST
ERASEABLE entity IL_PUSH(IntrusiveList this, entity it)
Push to tail.
#define BITSET_ASSIGN(a, b)
Definition common.qh:104
IntrusiveList g_warpzones
Definition common.qh:6
bool WarpZone_Send(entity this, entity to, int sendflags)
Definition server.qc:230
entity warpzone_first
Definition server.qh:4
void WarpZoneLib_ExactTrigger_Init(entity this, bool unsetmodel)

References BITSET_ASSIGN, EF_NODEPTHTEST, effects, g_warpzones, IL_PUSH(), modelscale, scale, SendFlags, setSendEntity, warpzone_first, warpzone_next, WarpZone_Send(), and WarpZoneLib_ExactTrigger_Init().

◆ spawnfunc() [5/6]

spawnfunc ( trigger_warpzone_position )

Definition at line 684 of file server.qc.

685{
686 spawnfunc_misc_warpzone_position(this);
687}

◆ spawnfunc() [6/6]

spawnfunc ( trigger_warpzone_reconnect )

Definition at line 852 of file server.qc.

853{
855}
#define use
void trigger_warpzone_reconnect_use(entity this, entity actor, entity trigger)
Definition server.qc:830

References trigger_warpzone_reconnect_use(), and use.

◆ trigger_warpzone_reconnect_use()

void trigger_warpzone_reconnect_use ( entity this,
entity actor,
entity trigger )

Definition at line 830 of file server.qc.

831{
832 // NOTE: this matches for target, not targetname, but of course
833 // targetname must be set too on the other entities
834 for(entity e = warpzone_first; e; e = e.warpzone_next)
835 e.warpzone_reconnecting = ((this.target == "" || e.target == this.target) && !((this.spawnflags & 1) && (visible_to_some_client(e) || visible_to_some_client(e.enemy))));
836 for(entity e = warpzone_camera_first; e; e = e.warpzone_next)
837 e.warpzone_reconnecting = ((this.target == "" || e.target == this.target) && !((this.spawnflags & 1) && visible_to_some_client(e)));
838 for(entity e = warpzone_first; e; e = e.warpzone_next)
839 if(e.warpzone_reconnecting)
841 for(entity e = warpzone_first; e; e = e.warpzone_next)
842 if(e.warpzone_reconnecting)
844 for(entity e = warpzone_camera_first; e; e = e.warpzone_next)
845 if(e.warpzone_reconnecting)
847 for(entity e = warpzone_first; e; e = e.warpzone_next)
848 if(e.warpzone_reconnecting || e.enemy.warpzone_reconnecting)
850}
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
void WarpZoneCamera_InitStep_FindTarget(entity this)
Definition server.qc:501
bool visible_to_some_client(entity ent)
Definition server.qc:822
void WarpZone_InitStep_FindTarget(entity this)
Definition server.qc:620
void WarpZone_InitStep_ClearTarget(entity this)
Definition server.qc:613
void WarpZone_InitStep_FinalizeTransform(entity this)
Definition server.qc:652

References entity(), visible_to_some_client(), warpzone_camera_first, warpzone_first, WarpZone_InitStep_ClearTarget(), WarpZone_InitStep_FinalizeTransform(), WarpZone_InitStep_FindTarget(), and WarpZoneCamera_InitStep_FindTarget().

Referenced by spawnfunc().

◆ visible_to_some_client()

bool visible_to_some_client ( entity ent)

Definition at line 822 of file server.qc.

823{
824 FOREACH_CLIENT(IS_PLAYER(it) && IS_REAL_CLIENT(it) && checkpvs(it.origin + it.view_ofs, ent),
825 {
826 return true;
827 });
828 return false;
829}
#define IS_PLAYER(s)
Definition player.qh:242
float checkpvs(vector viewpos, entity viewee)
#define IS_REAL_CLIENT(v)
Definition utils.qh:17
#define FOREACH_CLIENT(cond, body)
Definition utils.qh:52

References checkpvs(), entity(), FOREACH_CLIENT, IS_PLAYER, and IS_REAL_CLIENT.

Referenced by trigger_warpzone_reconnect_use().

◆ WarpZone_Camera_Send()

bool WarpZone_Camera_Send ( entity this,
entity to,
int sendflags )

Definition at line 284 of file server.qc.

285{
286 int f = 0;
287 WriteHeader(MSG_ENTITY, ENT_CLIENT_WARPZONE_CAMERA);
288
289 if(this.warpzone_fadestart)
290 BITSET_ASSIGN(f, 2);
291 if(this.origin != '0 0 0')
292 BITSET_ASSIGN(f, 4);
294
295 // we need THESE to render the warpzone (and cull properly)...
296 if(f & 4)
297 {
301 }
302
304 WriteCoord(MSG_ENTITY, this.mins.x);
305 WriteCoord(MSG_ENTITY, this.mins.y);
306 WriteCoord(MSG_ENTITY, this.mins.z);
307 WriteCoord(MSG_ENTITY, this.maxs.x);
308 WriteCoord(MSG_ENTITY, this.maxs.y);
309 WriteCoord(MSG_ENTITY, this.maxs.z);
310 WriteByte(MSG_ENTITY, bound(1, this.scale * 16, 255));
311
312 // we need THESE to calculate the proper transform
313 WriteCoord(MSG_ENTITY, this.enemy.origin.x);
314 WriteCoord(MSG_ENTITY, this.enemy.origin.y);
315 WriteCoord(MSG_ENTITY, this.enemy.origin.z);
316 WriteCoord(MSG_ENTITY, this.enemy.angles.x);
317 WriteCoord(MSG_ENTITY, this.enemy.angles.y);
318 WriteCoord(MSG_ENTITY, this.enemy.angles.z);
319
320 if(f & 2)
321 {
324 }
325
326 return true;
327}
float modelindex
const int MSG_ENTITY
Definition net.qh:156
#define WriteHeader(to, id)
Definition net.qh:265
float warpzone_fadestart
Definition common.qh:21
float warpzone_fadeend
Definition common.qh:22
float bound(float min, float value, float max)
void WriteShort(float data, float dest, float desto)
void WriteCoord(float data, float dest, float desto)
void WriteByte(float data, float dest, float desto)
entity enemy
Definition sv_ctf.qh:153

References BITSET_ASSIGN, bound(), enemy, entity(), maxs, mins, modelindex, MSG_ENTITY, origin, scale, warpzone_fadeend, warpzone_fadestart, WriteByte(), WriteCoord(), WriteHeader, and WriteShort().

Referenced by spawnfunc().

◆ WarpZone_InitStep_ClearTarget()

void WarpZone_InitStep_ClearTarget ( entity this)

Definition at line 613 of file server.qc.

614{
615 if(this.enemy)
616 this.enemy.enemy = NULL;
617 this.enemy = NULL;
618}
#define NULL
Definition post.qh:14

References enemy, entity(), and NULL.

Referenced by trigger_warpzone_reconnect_use(), and WarpZones_Reconnect().

◆ WarpZone_InitStep_FinalizeTransform()

void WarpZone_InitStep_FinalizeTransform ( entity this)

Definition at line 652 of file server.qc.

653{
654 if(!this.enemy || this.enemy.enemy != this)
655 {
656 error("Invalid warp zone detected. Killed.");
657 return;
658 }
659
661 WarpZone_SetUp(this, this.warpzone_origin, this.warpzone_angles, this.enemy.warpzone_origin, this.enemy.warpzone_angles);
663 this.SendFlags = 0xFFFFFF;
664 if(this.spawnflags & 1)
665 {
667 this.nextthink = time;
668 }
669 else
670 this.nextthink = 0;
671}
int spawnflags
Definition ammo.qh:15
float time
float nextthink
void WarpZone_Touch(entity this, entity toucher)
Definition server.qc:183
void WarpZone_SetUp(entity e, vector my_org, vector my_ang, vector other_org, vector other_ang)
Definition common.qc:64
vector warpzone_origin
Definition common.qh:14
float warpzone_warpzones_exist
Definition common.qh:9
vector warpzone_angles
Definition common.qh:15
#define error
Definition pre.qh:6
#define setthink(e, f)
#define settouch(e, f)
Definition self.qh:73
void WarpZone_Think(entity this)
Definition server.qc:750

References enemy, entity(), error, nextthink, SendFlags, setthink, settouch, spawnflags, time, warpzone_angles, warpzone_origin, WarpZone_SetUp(), WarpZone_Think(), WarpZone_Touch(), and warpzone_warpzones_exist.

Referenced by trigger_warpzone_reconnect_use(), WarpZone_Think(), and WarpZones_Reconnect().

◆ WarpZone_InitStep_FindOriginTarget()

void WarpZone_InitStep_FindOriginTarget ( entity this)

Definition at line 449 of file server.qc.

450{
451 if(this.killtarget != "")
452 {
453 this.aiment = find(NULL, targetname, this.killtarget);
454 if(this.aiment == NULL)
455 {
456 error("Warp zone with nonexisting killtarget");
457 return;
458 }
459 this.killtarget = string_null;
460 }
461}
entity find(entity start,.string field, string match)
entity aiment
Definition movetypes.qh:90
string string_null
Definition nil.qh:9
string killtarget
Definition subs.qh:48
string targetname
Definition triggers.qh:56

References aiment, entity(), error, find(), killtarget, NULL, string_null, and targetname.

Referenced by WarpZone_StartFrame().

◆ WarpZone_InitStep_FindTarget()

void WarpZone_InitStep_FindTarget ( entity this)

Definition at line 620 of file server.qc.

621{
622 float i;
623 entity e, e2;
624
625 if(this.enemy)
626 return;
627
628 // this way only one of the two ents needs to target
629 if(this.target != "")
630 {
632 this.enemy = this; // so the if(!e.enemy) check also skips this, saves one IF
633
634 e2 = NULL;
635 for(e = NULL, i = 0; (e = find(e, targetname, this.target)); )
636 if(!e.enemy)
637 if(e.classname == this.classname) // possibly non-warpzones may use the same targetname!
638 if(random() * ++i < 1)
639 e2 = e;
640 if(!e2)
641 {
642 this.enemy = NULL;
643 error("Warpzone with non-existing target");
644 return;
645 }
646 this.enemy = e2;
647 e2.enemy = this;
648 }
649}
float random(void)
bool autocvar_sv_warpzone_allow_selftarget
Definition server.qc:19
string target
Definition triggers.qh:55

References autocvar_sv_warpzone_allow_selftarget, enemy, entity(), error, find(), NULL, random(), target, and targetname.

Referenced by trigger_warpzone_reconnect_use(), and WarpZones_Reconnect().

◆ WarpZone_InitStep_UpdateTransform()

void WarpZone_InitStep_UpdateTransform ( entity this)

Definition at line 531 of file server.qc.

532{
533 vector org, ang, norm, point;
534 float area;
535 vector tri, a, b, c, n;
536 float i_s, i_t, n_t;
537 string tex;
538
539 org = this.origin;
540 if(org == '0 0 0')
541 org = 0.5 * (this.mins + this.maxs);
542
543 norm = point = '0 0 0';
544 area = 0;
545 for(i_s = 0; ; ++i_s)
546 {
547 tex = getsurfacetexture(this, i_s);
548 if (!tex)
549 break; // this is beyond the last one
550 if(tex == "textures/common/trigger" || tex == "trigger")
551 continue;
552 n_t = getsurfacenumtriangles(this, i_s);
553 for(i_t = 0; i_t < n_t; ++i_t)
554 {
555 tri = getsurfacetriangle(this, i_s, i_t);
556 a = getsurfacepoint(this, i_s, tri.x);
557 b = getsurfacepoint(this, i_s, tri.y);
558 c = getsurfacepoint(this, i_s, tri.z);
559 n = cross(c - a, b - a);
560 area += vlen(n);
561 norm += n;
562 point += vlen(n) * (a + b + c);
563 }
564 }
565 if(area > 0)
566 {
567 norm *= 1 / area;
568 point *= 1 / (3 * area);
569 if(vdist(norm, <, 0.99))
570 {
571 LOG_INFO("trigger_warpzone near ", vtos(this.aiment.origin), " is nonplanar. BEWARE.");
572 area = 0; // no autofixing in this case
573 }
574 norm = normalize(norm);
575 }
576
577 ang = '0 0 0';
578 if(this.aiment)
579 {
580 org = this.aiment.origin;
581 ang = this.aiment.angles;
582 if(area > 0)
583 {
584 org -= ((org - point) * norm) * norm; // project to plane
585 vector forward, right, up;
586 MAKE_VECTORS(ang, forward, right, up);
587 if(norm * forward < 0)
588 {
589 LOG_INFO("Position target of trigger_warpzone near ", vtos(this.aiment.origin), " points into trigger_warpzone. BEWARE.");
590 norm = -1 * norm;
591 }
592 ang = vectoangles2(norm, up); // keep rotation, but turn exactly against plane
593 ang.x = -ang.x;
594 if(norm * forward < 0.99)
595 LOG_INFO("trigger_warpzone near ", vtos(this.aiment.origin), " has been turned to match plane orientation (", vtos(this.aiment.angles), " -> ", vtos(ang));
596 if(vdist(org - this.aiment.origin, >, 0.5))
597 LOG_INFO("trigger_warpzone near ", vtos(this.aiment.origin), " has been moved to match the plane (", vtos(this.aiment.origin), " -> ", vtos(org), ").");
598 }
599 }
600 else if(area > 0)
601 {
602 org = point;
603 ang = vectoangles(norm);
604 ang.x = -ang.x;
605 }
606 else
607 error("cannot infer origin/angles for this warpzone, please use a killtarget or a trigger_warpzone_position");
608
609 this.warpzone_origin = org;
610 this.warpzone_angles = ang;
611}
#define MAKE_VECTORS(angles, forward, right, up)
Same as the makevectors builtin but uses the provided locals instead of the v_* globals.
#define LOG_INFO(...)
Definition log.qh:65
float vlen(vector v)
vector vectoangles(vector v)
string vtos(vector v)
vector normalize(vector v)
vector
Definition self.qh:92
vector org
Definition self.qh:92
vector vector ang
Definition self.qh:92
#define vdist(v, cmp, f)
Vector distance comparison, avoids sqrt()
Definition vector.qh:8
#define cross(a, b)
Definition vector.qh:25

References aiment, ang, cross, entity(), error, LOG_INFO, MAKE_VECTORS, maxs, mins, normalize(), org, origin, vdist, vectoangles(), vector, vlen(), vtos(), warpzone_angles, and warpzone_origin.

Referenced by WarpZone_StartFrame(), and WarpZone_Think().

◆ WarpZone_PlayerPhysics_FixVAngle()

void WarpZone_PlayerPhysics_FixVAngle ( entity this)

Definition at line 862 of file server.qc.

863{
864#ifndef WARPZONE_DONT_FIX_VANGLE
865 if(IS_REAL_CLIENT(this))
866 if(this.v_angle.z <= 360) // if not already adjusted
867 if(time - CS(this).ping * 0.001 < this.warpzone_teleport_time)
868 {
870 this.v_angle_z += 720; // mark as adjusted
871 }
872#endif
873}
float ping
Definition main.qh:169
vector v_angle
Definition player.qh:236
vector WarpZone_TransformVAngles(entity wz, vector ang)
Definition common.qc:524
entity warpzone_teleport_zone
Definition server.qc:36
float warpzone_teleport_time
Definition server.qc:34
ClientState CS(Client this)
Definition state.qh:47

References CS(), entity(), IS_REAL_CLIENT, ping, time, v_angle, warpzone_teleport_time, warpzone_teleport_zone, and WarpZone_TransformVAngles().

Referenced by PlayerPreThink(), and sys_phys_fix().

◆ WarpZone_Projectile_Touch()

float WarpZone_Projectile_Touch ( entity this,
entity toucher )

Definition at line 378 of file server.qc.

379{
380 if(toucher.classname == "trigger_warpzone")
381 return true;
382
383 // no further impacts if we teleported this frame!
384 // this is because even if we did teleport, the engine still may raise
385 // touch events for the previous location
386 // engine now aborts moves on teleport, so this SHOULD not happen any more
387 // but if this is called from TouchAreaGrid of the projectile moving,
388 // then this won't do
389 if(time == this.warpzone_teleport_time)
390 return true;
391
392#ifdef SVQC
393#ifdef WARPZONELIB_KEEPDEBUG
394 // this SEEMS to not happen at the moment, but if it did, it would be more reliable
395 {
396 float save_dpstartcontents;
397 float save_dphitcontents;
398 float save_dphitq3surfaceflags;
399 string save_dphittexturename;
400 float save_allsolid;
401 float save_startsolid;
402 float save_fraction;
403 vector save_endpos;
404 vector save_plane_normal;
405 float save_plane_dist;
406 entity save_ent;
407 float save_inopen;
408 float save_inwater;
409 save_dpstartcontents = trace_dpstartcontents;
410 save_dphitcontents = trace_dphitcontents;
411 save_dphitq3surfaceflags = trace_dphitq3surfaceflags;
412 save_dphittexturename = trace_dphittexturename;
413 save_allsolid = trace_allsolid;
414 save_startsolid = trace_startsolid;
415 save_fraction = trace_fraction;
416 save_endpos = trace_endpos;
417 save_plane_normal = trace_plane_normal;
418 save_plane_dist = trace_plane_dist;
419 save_ent = trace_ent;
420 save_inopen = trace_inopen;
421 save_inwater = trace_inwater;
422 float f = WarpZone_CheckProjectileImpact(this);
423 if (f) return (f > 0);
424 trace_dpstartcontents = save_dpstartcontents;
425 trace_dphitcontents = save_dphitcontents;
426 trace_dphitq3surfaceflags = save_dphitq3surfaceflags;
427 trace_dphittexturename = save_dphittexturename;
428 trace_allsolid = save_allsolid;
429 trace_startsolid = save_startsolid;
430 trace_fraction = save_fraction;
431 trace_endpos = save_endpos;
432 trace_plane_normal = save_plane_normal;
433 trace_plane_dist = save_plane_dist;
434 trace_ent = save_ent;
435 trace_inopen = save_inopen;
436 trace_inwater = save_inwater;
437 }
438#endif
439
441 return true;
442#endif
443
444 return false;
445}
float trace_dphitcontents
entity trace_ent
float trace_dpstartcontents
string trace_dphittexturename
vector trace_endpos
float trace_startsolid
float trace_inopen
float trace_dphitq3surfaceflags
float trace_fraction
float trace_allsolid
vector trace_plane_normal
float trace_plane_dist
float trace_inwater
entity entity toucher
Definition self.qh:72
bool WarpZone_Projectile_Touch_ImpactFilter_Callback(entity this, entity toucher)
Definition common.qc:150

References entity(), time, toucher, trace_allsolid, trace_dphitcontents, trace_dphitq3surfaceflags, trace_dphittexturename, trace_dpstartcontents, trace_endpos, trace_ent, trace_fraction, trace_inopen, trace_inwater, trace_plane_dist, trace_plane_normal, trace_startsolid, vector, WarpZone_Projectile_Touch_ImpactFilter_Callback(), and warpzone_teleport_time.

Referenced by W_Devastator_Touch(), and W_OverkillRocketPropelledChainsaw_Touch().

◆ WarpZone_Send()

bool WarpZone_Send ( entity this,
entity to,
int sendflags )

Definition at line 230 of file server.qc.

231{
232 WriteHeader(MSG_ENTITY, ENT_CLIENT_WARPZONE);
233
234 // we must send this flag for clientside to match properly too
235 int f = 0;
236 if(this.warpzone_isboxy)
237 BITSET_ASSIGN(f, 1);
238 if(this.warpzone_fadestart)
239 BITSET_ASSIGN(f, 2);
240 if(this.origin != '0 0 0')
241 BITSET_ASSIGN(f, 4);
243
244 // we need THESE to render the warpzone (and cull properly)...
245 if(f & 4)
246 {
250 }
251
253 WriteCoord(MSG_ENTITY, this.mins.x);
254 WriteCoord(MSG_ENTITY, this.mins.y);
255 WriteCoord(MSG_ENTITY, this.mins.z);
256 WriteCoord(MSG_ENTITY, this.maxs.x);
257 WriteCoord(MSG_ENTITY, this.maxs.y);
258 WriteCoord(MSG_ENTITY, this.maxs.z);
259 WriteByte(MSG_ENTITY, bound(1, this.scale * 16, 255));
260
261 // we need THESE to calculate the proper transform
274
275 if(f & 2)
276 {
279 }
280
281 return true;
282}
vector warpzone_targetorigin
Definition common.qh:17
float warpzone_isboxy
Definition common.qh:12
vector warpzone_targetangles
Definition common.qh:18

References BITSET_ASSIGN, bound(), entity(), maxs, mins, modelindex, MSG_ENTITY, origin, scale, warpzone_angles, warpzone_fadeend, warpzone_fadestart, warpzone_isboxy, warpzone_origin, warpzone_targetangles, warpzone_targetorigin, WriteByte(), WriteCoord(), WriteHeader, and WriteShort().

Referenced by spawnfunc().

◆ WarpZone_StartFrame()

void WarpZone_StartFrame ( )

Definition at line 769 of file server.qc.

770{
772 {
774 for(entity e = warpzone_first; e; e = e.warpzone_next)
776 for(entity e = warpzone_position_first; e; e = e.warpzone_next)
778 for(entity e = warpzone_first; e; e = e.warpzone_next)
782 }
783
785 {
787 {
789 });
790 }
791
792
793 FOREACH_CLIENT(true,
794 {
796 WarpZone_StoreProjectileData(it); // TODO: not actually needed
797
798 if((IS_OBSERVER(it) || it.solid == SOLID_NOT))
799 {
800 // warpzones
802 entity e = WarpZone_Find(it.origin + it.mins, it.origin + it.maxs);
803 if (e)
804 if (WarpZoneLib_ExactTrigger_Touch(e, it, false))
805 if (WarpZone_PlaneDist(e, it.origin + it.view_ofs) <= 0)
806 WarpZone_Teleport(e, it, -1, 0); // NOT triggering targets by this!
807 }
808
809 // teleporters
810 if(it.teleportable)
811 {
812 entity ent = Teleport_Find(it.origin + it.mins, it.origin + it.maxs);
813 if (ent)
814 if (WarpZoneLib_ExactTrigger_Touch(ent, it, false))
815 Simple_TeleportPlayer(ent, it); // NOT triggering targets by this!
816 }
817 }
818 });
819}
#define IL_EACH(this, cond, body)
entity WarpZone_Find(vector mi, vector ma)
Definition common.qc:167
bool WarpZoneLib_ExactTrigger_Touch(entity this, entity toucher, bool touchfunc)
Definition common.qc:813
float WarpZone_PlaneDist(entity wz, vector v)
Definition common.qc:499
IntrusiveList g_projectiles
Definition common.qh:58
float warpzone_initialized
Definition server.qc:673
void WarpZone_InitStep_FindOriginTarget(entity this)
Definition server.qc:449
void WarpZones_Reconnect()
Definition server.qc:738
#define WarpZone_StoreProjectileData(e_)
Definition server.qc:38
void WarpZone_InitStep_UpdateTransform(entity this)
Definition server.qc:531
float WarpZone_Teleport(entity wz, entity player, float f0, float f1)
Definition server.qc:82
void WarpZonePosition_InitStep_FindTarget(entity this)
Definition server.qc:463
void WarpZone_PostInitialize_Callback()
Definition main.qc:518
entity Simple_TeleportPlayer(entity teleporter, entity player)
entity Teleport_Find(vector mi, vector ma)
#define IS_OBSERVER(v)
Definition utils.qh:11

References entity(), FOREACH_CLIENT, g_projectiles, IL_EACH, IS_OBSERVER, Simple_TeleportPlayer(), SOLID_NOT, Teleport_Find(), WarpZone_Find(), warpzone_first, warpzone_initialized, WarpZone_InitStep_FindOriginTarget(), WarpZone_InitStep_UpdateTransform(), WarpZone_PlaneDist(), warpzone_position_first, WarpZone_PostInitialize_Callback(), WarpZone_StoreProjectileData, WarpZone_Teleport(), warpzone_warpzones_exist, WarpZoneLib_ExactTrigger_Touch(), WarpZonePosition_InitStep_FindTarget(), and WarpZones_Reconnect().

Referenced by StartFrame().

◆ WarpZone_Teleport()

float WarpZone_Teleport ( entity wz,
entity player,
float f0,
float f1 )

Definition at line 82 of file server.qc.

83{
84 vector o0, a0, v0, o1, a1, v1, o10;
85
86 o0 = player.origin + player.view_ofs;
87 v0 = player.velocity;
88 a0 = player.angles;
89
90 o10 = o1 = WarpZone_TransformOrigin(wz, o0);
91 v1 = WarpZone_TransformVelocity(wz, v0);
92 if (!IS_NOT_A_CLIENT(player))
94 else
95 a1 = WarpZone_TransformAngles(wz, a0);
96
97 if(f0 != 0 || f1 != 0)
98 {
99 // retry last move but behind the warpzone!
100 // we must first go back as far as we can, then forward again, to not cause double touch events!
101
102 tracebox(o1 - player.view_ofs + v1 * frametime * f1, player.mins, player.maxs, o1 - player.view_ofs + v1 * frametime * f0, MOVE_WORLDONLY, player);
103 {
104 entity own = player.owner;
105 player.owner = NULL;
106 tracebox(trace_endpos, player.mins, player.maxs, o1 - player.view_ofs + v1 * frametime * f1, MOVE_NORMAL, player); // this should get us through the warpzone
107 player.owner = own;
108 }
109 o1 = trace_endpos + player.view_ofs;
110
111 float d, dv, md;
112 md = max(vlen(player.mins), vlen(player.maxs));
113 d = WarpZone_TargetPlaneDist(wz, o1);
114 dv = WarpZone_TargetPlaneDist(wz, v1);
115 if(d < 0)
116 o1 -= v1 * (d / dv);
117 }
118
119 // put them out of solid
120 tracebox(o1 - player.view_ofs, player.mins, player.maxs, o1 - player.view_ofs, MOVE_NOMONSTERS, player);
122 {
123 setorigin(player, o1 - player.view_ofs);
125 {
126 o1 = player.origin + player.view_ofs;
127 setorigin(player, o0 - player.view_ofs);
128 }
129 else
130 {
131 LOG_INFO("would have to put player in solid, won't do that");
132 setorigin(player, o0 - player.view_ofs);
133 return 0;
134 }
135 }
136
137 // do the teleport
138 WarpZone_RefSys_Add(player, wz);
139 WarpZone_TeleportPlayer(wz, player, o1 - player.view_ofs, a1, v1);
141 player.warpzone_teleport_time = time;
142 player.warpzone_teleport_finishtime = time;
143 player.warpzone_teleport_zone = wz;
144
145#ifdef SVQC
146 // prevent further teleports back
147 float dt = (v1 != '0 0 0') ? (o1 - o10) * v1 * (1 / (v1 * v1)) : 0;
148 if(dt < PHYS_INPUT_FRAMETIME)
149 player.warpzone_teleport_finishtime += PHYS_INPUT_FRAMETIME - dt;
150#endif
151
152#ifndef WARPZONE_USE_FIXANGLE
153 #ifdef SVQC
154 if(IS_VEHICLE(player) && player.owner)
155 player = player.owner; // hax
156 if(IS_PLAYER(player))
157 {
158 // instead of fixangle, send the transform to the client for smoother operation
159 player.fixangle = false;
160
161 entity ts = new(warpzone_teleported);
162 setmodel(ts, MDL_Null);
164 ts.SendFlags = 0xFFFFFF;
165 ts.drawonlytoclient = player;
166 setthink(ts, SUB_Remove);
167 ts.nextthink = time + 1;
168 ts.owner = player;
169 ts.enemy = wz;
170 ts.effects = EF_NODEPTHTEST;
171 ts.angles = wz.warpzone_transform;
172 }
173 #elif defined(CSQC)
174 setproperty(VF_CL_VIEWANGLES, WarpZone_TransformVAngles(wz, getpropertyvec(VF_CL_VIEWANGLES)));
175 //if(checkextension("DP_CSQC_ROTATEMOVES"))
176 //CL_RotateMoves(wz.warpzone_transform);
177 #endif
178#endif
179
180 return 1;
181}
#define setmodel(this, m)
Definition model.qh:26
#define IS_NOT_A_CLIENT(s)
Definition player.qh:243
#define PHYS_INPUT_FRAMETIME
Definition player.qh:254
#define PHYS_INPUT_ANGLES(s)
Definition player.qh:249
const float MOVE_NOMONSTERS
const float VF_CL_VIEWANGLES
float frametime
const float MOVE_NORMAL
float MOVE_WORLDONLY
void SUB_Remove(entity this)
Remove entity.
Definition defer.qh:13
void WarpZone_RefSys_Add(entity me, entity wz)
Definition common.qc:729
vector WarpZone_TransformVelocity(entity wz, vector v)
Definition common.qc:514
vector WarpZone_TransformAngles(entity wz, vector v)
Definition common.qc:519
vector WarpZone_TransformOrigin(entity wz, vector v)
Definition common.qc:509
float WarpZone_TargetPlaneDist(entity wz, vector v)
Definition common.qc:504
int WarpZoneLib_MoveOutOfSolid(entity e)
Definition common.qc:846
float max(float f,...)
f1
Definition all.inc:563
bool WarpZone_Teleported_Send(entity this, entity to, int sf)
Definition server.qc:74
void WarpZone_TeleportPlayer(entity teleporter, entity player, vector to, vector to_angles, vector to_velocity)
Definition server.qc:45
#define IS_VEHICLE(v)
Definition utils.qh:24

References EF_NODEPTHTEST, entity(), f1, frametime, IS_NOT_A_CLIENT, IS_PLAYER, IS_VEHICLE, LOG_INFO, max(), MOVE_NOMONSTERS, MOVE_NORMAL, MOVE_WORLDONLY, NULL, PHYS_INPUT_ANGLES, PHYS_INPUT_FRAMETIME, setmodel, setSendEntity, setthink, SUB_Remove(), time, trace_endpos, trace_startsolid, vector, VF_CL_VIEWANGLES, vlen(), WarpZone_RefSys_Add(), WarpZone_StoreProjectileData, WarpZone_TargetPlaneDist(), WarpZone_Teleported_Send(), WarpZone_TeleportPlayer(), WarpZone_TransformAngles(), WarpZone_TransformOrigin(), WarpZone_TransformVAngles(), WarpZone_TransformVelocity(), and WarpZoneLib_MoveOutOfSolid().

Referenced by WarpZone_StartFrame(), and WarpZone_Touch().

◆ WarpZone_Teleported_Send()

bool WarpZone_Teleported_Send ( entity this,
entity to,
int sf )

Definition at line 74 of file server.qc.

75{
76 WriteHeader(MSG_ENTITY, ENT_CLIENT_WARPZONE_TELEPORTED);
77 WriteVector(MSG_ENTITY, this.angles);
78 return true;
79}
ent angles
Definition ent_cs.qc:121

References angles, entity(), MSG_ENTITY, and WriteHeader.

Referenced by WarpZone_Teleport().

◆ WarpZone_TeleportPlayer()

void WarpZone_TeleportPlayer ( entity teleporter,
entity player,
vector to,
vector to_angles,
vector to_velocity )

Definition at line 45 of file server.qc.

46{
47#ifdef SVQC
48 player.lastteleport_origin = player.origin;
49 player.lastteleporttime = time;
50#endif
51 setorigin(player, to); // NOTE: this also aborts the move, when this is called by touch
52 player.angles = to_angles;
53#ifdef SVQC
54 player.oldorigin = to; // for DP's unsticking
55 player.fixangle = true;
56 if (IS_BOT_CLIENT(player))
57 {
58 // FIXME find a way to smooth view's angles change for bots too
59 player.v_angle = player.angles;
60 bot_aim_reset(player);
61 }
62#endif
63 player.velocity = to_velocity;
64
65 BITXOR_ASSIGN(player.effects, EF_TELEPORT_BIT);
66
67 if(IS_PLAYER(player))
68 BITCLR_ASSIGN(player.flags, FL_ONGROUND);
69
71}
void bot_aim_reset(entity this)
Definition aim.qc:134
const int FL_ONGROUND
Definition constants.qh:78
const int EF_TELEPORT_BIT
#define BITCLR_ASSIGN(a, b)
Definition common.qh:101
#define BITXOR_ASSIGN(a, b)
Definition common.qh:107
void WarpZone_PostTeleportPlayer_Callback(entity pl)
#define IS_BOT_CLIENT(v)
want: (IS_CLIENT(v) && !IS_REAL_CLIENT(v))
Definition utils.qh:15

References BITCLR_ASSIGN, BITXOR_ASSIGN, bot_aim_reset(), EF_TELEPORT_BIT, entity(), FL_ONGROUND, IS_BOT_CLIENT, IS_PLAYER, time, vector, and WarpZone_PostTeleportPlayer_Callback().

Referenced by WarpZone_Teleport().

◆ WarpZone_Think()

void WarpZone_Think ( entity this)

Definition at line 750 of file server.qc.

751{
752 if(this.warpzone_save_origin != this.origin
753 || this.warpzone_save_angles != this.angles
754 || this.warpzone_save_eorigin != this.enemy.origin
755 || this.warpzone_save_eangles != this.enemy.angles)
756 {
761 this.warpzone_save_origin = this.origin;
762 this.warpzone_save_angles = this.angles;
763 this.warpzone_save_eorigin = this.enemy.origin;
764 this.warpzone_save_eangles = this.enemy.angles;
765 }
766 this.nextthink = time;
767}
vector warpzone_save_eangles
Definition server.qc:30
vector warpzone_save_origin
Definition server.qc:27
vector warpzone_save_angles
Definition server.qc:28
vector warpzone_save_eorigin
Definition server.qc:29

References angles, enemy, entity(), nextthink, origin, time, WarpZone_InitStep_FinalizeTransform(), WarpZone_InitStep_UpdateTransform(), warpzone_save_angles, warpzone_save_eangles, warpzone_save_eorigin, and warpzone_save_origin.

Referenced by WarpZone_InitStep_FinalizeTransform().

◆ WarpZone_Touch()

void WarpZone_Touch ( entity this,
entity toucher )

Definition at line 183 of file server.qc.

184{
185 if(toucher.classname == "trigger_warpzone")
186 return;
187
188 if(time <= toucher.warpzone_teleport_finishtime) // already teleported this frame
189 return;
190
191 // FIXME needs a better check to know what is safe to teleport and what not
192 if(toucher.move_movetype == MOVETYPE_NONE || toucher.move_movetype == MOVETYPE_FOLLOW || toucher.tag_entity)
193 return;
194
195 if(WarpZone_PlaneDist(this, toucher.origin + toucher.view_ofs) >= 0) // wrong side of the trigger_warpzone (don't teleport yet)
196 return;
197
199
200 float f;
201 // number of frames we need to go back:
202 // dist = 16*sqrt(2) qu
203 // dist ~ 24 qu
204 // 24 qu = v*t
205 // 24 qu = v*frametime*n
206 // n = 24 qu/(v*frametime)
207 // for clients go only one frame though, may be too irritating otherwise
208 // but max 0.25 sec = 0.25/frametime frames
209 // 24/(0.25/frametime)
210 // 96*frametime
211 float d = 24 + max(vlen(toucher.mins), vlen(toucher.maxs));
213 f = -d / bound(frametime * d * 1, frametime * vlen(toucher.velocity), d);
214 else
215 f = -1;
216 if(WarpZone_Teleport(this, toucher, f, 0))
217 {
218#ifdef SVQC
219 SUB_UseTargets_SkipTargets(this, toucher, toucher, BIT(1) | BIT(3)); // use toucher too?
220 SUB_UseTargets_SkipTargets(this.enemy, toucher, toucher, BIT(1) | BIT(2)); // use toucher too?
221#endif
222 }
223 else
224 {
225 LOG_TRACE("WARPZONE FAIL AHAHAHAHAH))");
226 }
227}
#define BIT(n)
Only ever assign into the first 24 bits in QC (so max is BIT(23)).
Definition bits.qh:8
#define EXACTTRIGGER_TOUCH(e, t)
Definition common.qh:115
#define LOG_TRACE(...)
Definition log.qh:76
const int MOVETYPE_NONE
Definition movetypes.qh:129
const int MOVETYPE_FOLLOW
Definition movetypes.qh:141
void SUB_UseTargets_SkipTargets(entity this, entity actor, entity trigger, int skiptargets)
Definition triggers.qc:346

References BIT, bound(), enemy, entity(), EXACTTRIGGER_TOUCH, frametime, IS_NOT_A_CLIENT, LOG_TRACE, max(), MOVETYPE_FOLLOW, MOVETYPE_NONE, SUB_UseTargets_SkipTargets(), time, toucher, vlen(), WarpZone_PlaneDist(), and WarpZone_Teleport().

Referenced by WarpZone_InitStep_FinalizeTransform().

◆ WarpZoneCamera_InitStep_FindTarget()

void WarpZoneCamera_InitStep_FindTarget ( entity this)

Definition at line 501 of file server.qc.

502{
503 entity e;
504 float i;
505 if(this.target == "")
506 {
507 error("Camera with no target");
508 return;
509 }
510 this.enemy = NULL;
511 for(e = NULL, i = 0; (e = find(e, targetname, this.target)); )
512 if(random() * ++i < 1)
513 this.enemy = e;
514 if(this.enemy == NULL)
515 {
516 error("Camera with nonexisting target");
517 return;
518 }
520 WarpZone_Camera_SetUp(this, this.enemy.origin, this.enemy.angles);
521 this.SendFlags = 0xFFFFFF;
522 if(this.spawnflags & 1)
523 {
525 this.nextthink = time;
526 }
527 else
528 this.nextthink = 0;
529}
void WarpZone_Camera_SetUp(entity e, vector my_org, vector my_ang)
Definition common.qc:93
float warpzone_cameras_exist
Definition common.qh:10
void WarpZoneCamera_Think(entity this)
Definition server.qc:485

References enemy, entity(), error, find(), nextthink, NULL, random(), SendFlags, setthink, spawnflags, target, targetname, time, WarpZone_Camera_SetUp(), warpzone_cameras_exist, and WarpZoneCamera_Think().

Referenced by trigger_warpzone_reconnect_use(), and WarpZones_Reconnect().

◆ WarpZoneCamera_Think()

void WarpZoneCamera_Think ( entity this)

Definition at line 485 of file server.qc.

486{
487 if(this.warpzone_save_origin != this.origin
488 || this.warpzone_save_angles != this.angles
489 || this.warpzone_save_eorigin != this.enemy.origin
490 || this.warpzone_save_eangles != this.enemy.angles)
491 {
492 WarpZone_Camera_SetUp(this, this.enemy.origin, this.enemy.angles);
493 this.warpzone_save_origin = this.origin;
494 this.warpzone_save_angles = this.angles;
495 this.warpzone_save_eorigin = this.enemy.origin;
496 this.warpzone_save_eangles = this.enemy.angles;
497 }
498 this.nextthink = time;
499}

References angles, enemy, entity(), nextthink, origin, time, WarpZone_Camera_SetUp(), warpzone_save_angles, warpzone_save_eangles, warpzone_save_eorigin, and warpzone_save_origin.

Referenced by WarpZoneCamera_InitStep_FindTarget().

◆ WarpZonePosition_InitStep_FindTarget()

void WarpZonePosition_InitStep_FindTarget ( entity this)

Definition at line 463 of file server.qc.

464{
465 if(this.target == "")
466 {
467 error("Warp zone position with no target");
468 return;
469 }
470 this.enemy = find(NULL, targetname, this.target);
471 if(this.enemy == NULL)
472 {
473 error("Warp zone position with nonexisting target");
474 return;
475 }
476 if(this.enemy.aiment)
477 {
478 // already is positioned
479 error("Warp zone position targeting already oriented warpzone");
480 return;
481 }
482 this.enemy.aiment = this;
483}

References enemy, entity(), error, find(), NULL, target, and targetname.

Referenced by WarpZone_StartFrame().

◆ WarpZones_Reconnect()

void WarpZones_Reconnect ( )

Variable Documentation

◆ autocvar_sv_warpzone_allow_selftarget

bool autocvar_sv_warpzone_allow_selftarget

Definition at line 19 of file server.qc.

Referenced by WarpZone_InitStep_FindTarget().

◆ warpzone_camera_first

entity warpzone_camera_first

Definition at line 676 of file server.qc.

Referenced by spawnfunc(), trigger_warpzone_reconnect_use(), and WarpZones_Reconnect().

◆ warpzone_initialized

float warpzone_initialized

Definition at line 673 of file server.qc.

Referenced by WarpZone_StartFrame().

◆ warpzone_next

entity warpzone_next

Definition at line 677 of file server.qc.

Referenced by spawnfunc(), spawnfunc(), and spawnfunc().

◆ warpzone_oldangles

vector warpzone_oldangles

Definition at line 33 of file server.qc.

◆ warpzone_oldorigin

vector warpzone_oldorigin

Definition at line 33 of file server.qc.

◆ warpzone_oldvelocity

vector warpzone_oldvelocity

Definition at line 33 of file server.qc.

◆ warpzone_position_first

entity warpzone_position_first

Definition at line 675 of file server.qc.

Referenced by spawnfunc(), and WarpZone_StartFrame().

◆ warpzone_reconnecting

float warpzone_reconnecting

Definition at line 821 of file server.qc.

◆ warpzone_save_angles

vector warpzone_save_angles

Definition at line 28 of file server.qc.

Referenced by WarpZone_Think(), and WarpZoneCamera_Think().

◆ warpzone_save_eangles

vector warpzone_save_eangles

Definition at line 30 of file server.qc.

Referenced by WarpZone_Think(), and WarpZoneCamera_Think().

◆ warpzone_save_eorigin

vector warpzone_save_eorigin

Definition at line 29 of file server.qc.

Referenced by WarpZone_Think(), and WarpZoneCamera_Think().

◆ warpzone_save_origin

vector warpzone_save_origin

Definition at line 27 of file server.qc.

Referenced by WarpZone_Think(), and WarpZoneCamera_Think().

◆ warpzone_teleport_finishtime

float warpzone_teleport_finishtime

Definition at line 35 of file server.qc.

◆ warpzone_teleport_time

float warpzone_teleport_time

Definition at line 34 of file server.qc.

Referenced by WarpZone_PlayerPhysics_FixVAngle(), and WarpZone_Projectile_Touch().

◆ warpzone_teleport_zone

entity warpzone_teleport_zone

Definition at line 36 of file server.qc.

Referenced by WarpZone_PlayerPhysics_FixVAngle().