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 716 of file server.qc.

717{
718 if(!this.scale)
719 this.scale = this.modelscale;
720 if(!this.scale)
721 this.scale = 1;
722 if(this.model != "")
723 {
724 precache_model(this.model);
725 _setmodel(this, this.model); // no precision needed
726 }
727 setorigin(this, this.origin);
728 if(this.scale)
729 setsize(this, this.mins * this.scale, this.maxs * this.scale);
730 else
731 setsize(this, this.mins, this.maxs);
732 if(!this.solid)
733 this.solid = SOLID_BSP;
734 else if(this.solid < 0)
735 this.solid = SOLID_NOT;
737 this.SendFlags = 0xFFFFFF;
740}
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:118
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:286
entity warpzone_camera_first
Definition server.qc:679
entity warpzone_next
Definition server.qc:680

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 681 of file server.qc.

682{
683 // "target", "angles", "origin"
686}
entity warpzone_position_first
Definition server.qc:678

References warpzone_next, and warpzone_position_first.

◆ spawnfunc() [3/6]

spawnfunc ( target_warpzone_reconnect )

Definition at line 860 of file server.qc.

861{
862 spawnfunc_trigger_warpzone_reconnect(this); // both names make sense here :(
863}

◆ spawnfunc() [4/6]

spawnfunc ( trigger_warpzone )

Definition at line 691 of file server.qc.

692{
693 // warp zone entities must have:
694 // "killtarget" pointing to a target_position with a direction arrow
695 // that points AWAY from the warp zone, and that is inside
696 // the warp zone trigger
697 // "target" pointing to an identical warp zone at another place in
698 // the map, with another killtarget to designate its
699 // orientation
700
701 if(!this.scale)
702 this.scale = this.modelscale;
703 if(!this.scale)
704 this.scale = 1;
705
707
709 this.SendFlags = 0xFFFFFF;
712 warpzone_first = this;
713
714 IL_PUSH(g_warpzones, this);
715}
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:232
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 687 of file server.qc.

688{
689 spawnfunc_misc_warpzone_position(this);
690}

◆ spawnfunc() [6/6]

spawnfunc ( trigger_warpzone_reconnect )

Definition at line 855 of file server.qc.

856{
858}
#define use
void trigger_warpzone_reconnect_use(entity this, entity actor, entity trigger)
Definition server.qc:833

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 833 of file server.qc.

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

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 825 of file server.qc.

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

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 286 of file server.qc.

287{
288 int f = 0;
289 WriteHeader(MSG_ENTITY, ENT_CLIENT_WARPZONE_CAMERA);
290
291 if(this.warpzone_fadestart)
292 BITSET_ASSIGN(f, 2);
293 if(this.origin != '0 0 0')
294 BITSET_ASSIGN(f, 4);
296
297 // we need THESE to render the warpzone (and cull properly)...
298 if(f & 4)
299 {
303 }
304
306 WriteCoord(MSG_ENTITY, this.mins.x);
307 WriteCoord(MSG_ENTITY, this.mins.y);
308 WriteCoord(MSG_ENTITY, this.mins.z);
309 WriteCoord(MSG_ENTITY, this.maxs.x);
310 WriteCoord(MSG_ENTITY, this.maxs.y);
311 WriteCoord(MSG_ENTITY, this.maxs.z);
312 WriteByte(MSG_ENTITY, bound(1, this.scale * 16, 255));
313
314 // we need THESE to calculate the proper transform
315 WriteCoord(MSG_ENTITY, this.enemy.origin.x);
316 WriteCoord(MSG_ENTITY, this.enemy.origin.y);
317 WriteCoord(MSG_ENTITY, this.enemy.origin.z);
318 WriteCoord(MSG_ENTITY, this.enemy.angles.x);
319 WriteCoord(MSG_ENTITY, this.enemy.angles.y);
320 WriteCoord(MSG_ENTITY, this.enemy.angles.z);
321
322 if(f & 2)
323 {
326 }
327
328 return true;
329}
float modelindex
const int MSG_ENTITY
Definition net.qh:115
#define WriteHeader(to, id)
Definition net.qh:221
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 616 of file server.qc.

617{
618 if(this.enemy)
619 this.enemy.enemy = NULL;
620 this.enemy = NULL;
621}
#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 655 of file server.qc.

656{
657 if(!this.enemy || this.enemy.enemy != this)
658 {
659 error("Invalid warp zone detected. Killed.");
660 return;
661 }
662
664 WarpZone_SetUp(this, this.warpzone_origin, this.warpzone_angles, this.enemy.warpzone_origin, this.enemy.warpzone_angles);
666 this.SendFlags = 0xFFFFFF;
667 if(this.spawnflags & 1)
668 {
670 this.nextthink = time;
671 }
672 else
673 this.nextthink = 0;
674}
int spawnflags
Definition ammo.qh:15
float time
float nextthink
void WarpZone_Touch(entity this, entity toucher)
Definition server.qc:184
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:753

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 452 of file server.qc.

453{
454 if(this.killtarget != "")
455 {
456 this.aiment = find(NULL, targetname, this.killtarget);
457 if(this.aiment == NULL)
458 {
459 error("Warp zone with nonexisting killtarget");
460 return;
461 }
462 this.killtarget = string_null;
463 }
464}
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 623 of file server.qc.

624{
625 float i;
626 entity e, e2;
627
628 if(this.enemy)
629 return;
630
631 // this way only one of the two ents needs to target
632 if(this.target != "")
633 {
635 this.enemy = this; // so the if(!e.enemy) check also skips this, saves one IF
636
637 e2 = NULL;
638 for(e = NULL, i = 0; (e = find(e, targetname, this.target)); )
639 if(!e.enemy)
640 if(e.classname == this.classname) // possibly non-warpzones may use the same targetname!
641 if(random() * ++i < 1)
642 e2 = e;
643 if(!e2)
644 {
645 this.enemy = NULL;
646 error("Warpzone with non-existing target");
647 return;
648 }
649 this.enemy = e2;
650 e2.enemy = this;
651 }
652}
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 534 of file server.qc.

535{
536 vector org, ang, norm, point;
537 float area;
538 vector tri, a, b, c, n;
539 float i_s, i_t, n_t;
540 string tex;
541
542 org = this.origin;
543 if(org == '0 0 0')
544 org = 0.5 * (this.mins + this.maxs);
545
546 norm = point = '0 0 0';
547 area = 0;
548 for(i_s = 0; ; ++i_s)
549 {
550 tex = getsurfacetexture(this, i_s);
551 if (!tex)
552 break; // this is beyond the last one
553 if(tex == "textures/common/trigger" || tex == "trigger")
554 continue;
555 n_t = getsurfacenumtriangles(this, i_s);
556 for(i_t = 0; i_t < n_t; ++i_t)
557 {
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);
564 norm = norm + n;
565 point = point + vlen(n) * (a + b + c);
566 }
567 }
568 if(area > 0)
569 {
570 norm = norm * (1 / area);
571 point = point * (1 / (3 * area));
572 if(vdist(norm, <, 0.99))
573 {
574 LOG_INFO("trigger_warpzone near ", vtos(this.aiment.origin), " is nonplanar. BEWARE.");
575 area = 0; // no autofixing in this case
576 }
577 norm = normalize(norm);
578 }
579
580 ang = '0 0 0';
581 if(this.aiment)
582 {
583 org = this.aiment.origin;
584 ang = this.aiment.angles;
585 if(area > 0)
586 {
587 org = org - ((org - point) * norm) * norm; // project to plane
588 vector forward, right, up;
589 MAKE_VECTORS(ang, forward, right, up);
590 if(norm * forward < 0)
591 {
592 LOG_INFO("Position target of trigger_warpzone near ", vtos(this.aiment.origin), " points into trigger_warpzone. BEWARE.");
593 norm = -1 * norm;
594 }
595 ang = vectoangles2(norm, up); // keep rotation, but turn exactly against plane
596 ang.x = -ang.x;
597 if(norm * forward < 0.99)
598 LOG_INFO("trigger_warpzone near ", vtos(this.aiment.origin), " has been turned to match plane orientation (", vtos(this.aiment.angles), " -> ", vtos(ang));
599 if(vdist(org - this.aiment.origin, >, 0.5))
600 LOG_INFO("trigger_warpzone near ", vtos(this.aiment.origin), " has been moved to match the plane (", vtos(this.aiment.origin), " -> ", vtos(org), ").");
601 }
602 }
603 else if(area > 0)
604 {
605 org = point;
606 ang = vectoangles(norm);
607 ang.x = -ang.x;
608 }
609 else
610 error("cannot infer origin/angles for this warpzone, please use a killtarget or a trigger_warpzone_position");
611
612 this.warpzone_origin = org;
613 this.warpzone_angles = ang;
614}
#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 865 of file server.qc.

866{
867#ifndef WARPZONE_DONT_FIX_VANGLE
868 if(IS_REAL_CLIENT(this))
869 if(this.v_angle.z <= 360) // if not already adjusted
870 if(time - CS(this).ping * 0.001 < this.warpzone_teleport_time)
871 {
873 this.v_angle_z += 720; // mark as adjusted
874 }
875#endif
876}
float ping
Definition main.qh:169
vector v_angle
Definition player.qh:237
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 381 of file server.qc.

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

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 232 of file server.qc.

233{
234 WriteHeader(MSG_ENTITY, ENT_CLIENT_WARPZONE);
235
236 // we must send this flag for clientside to match properly too
237 int f = 0;
238 if(this.warpzone_isboxy)
239 BITSET_ASSIGN(f, 1);
240 if(this.warpzone_fadestart)
241 BITSET_ASSIGN(f, 2);
242 if(this.origin != '0 0 0')
243 BITSET_ASSIGN(f, 4);
245
246 // we need THESE to render the warpzone (and cull properly)...
247 if(f & 4)
248 {
252 }
253
255 WriteCoord(MSG_ENTITY, this.mins.x);
256 WriteCoord(MSG_ENTITY, this.mins.y);
257 WriteCoord(MSG_ENTITY, this.mins.z);
258 WriteCoord(MSG_ENTITY, this.maxs.x);
259 WriteCoord(MSG_ENTITY, this.maxs.y);
260 WriteCoord(MSG_ENTITY, this.maxs.z);
261 WriteByte(MSG_ENTITY, bound(1, this.scale * 16, 255));
262
263 // we need THESE to calculate the proper transform
276
277 if(f & 2)
278 {
281 }
282
283 return true;
284}
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 772 of file server.qc.

773{
775 {
777 for(entity e = warpzone_first; e; e = e.warpzone_next)
779 for(entity e = warpzone_position_first; e; e = e.warpzone_next)
781 for(entity e = warpzone_first; e; e = e.warpzone_next)
785 }
786
788 {
790 {
792 });
793 }
794
795
796 FOREACH_CLIENT(true,
797 {
799 WarpZone_StoreProjectileData(it); // TODO: not actually needed
800
801 if((IS_OBSERVER(it) || it.solid == SOLID_NOT))
802 {
803 // warpzones
805 entity e = WarpZone_Find(it.origin + it.mins, it.origin + it.maxs);
806 if (e)
807 if (WarpZoneLib_ExactTrigger_Touch(e, it, false))
808 if (WarpZone_PlaneDist(e, it.origin + it.view_ofs) <= 0)
809 WarpZone_Teleport(e, it, -1, 0); // NOT triggering targets by this!
810 }
811
812 // teleporters
813 if(it.teleportable)
814 {
815 entity ent = Teleport_Find(it.origin + it.mins, it.origin + it.maxs);
816 if (ent)
817 if (WarpZoneLib_ExactTrigger_Touch(ent, it, false))
818 Simple_TeleportPlayer(ent, it); // NOT triggering targets by this!
819 }
820 }
821 });
822}
#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:815
float WarpZone_PlaneDist(entity wz, vector v)
Definition common.qc:499
IntrusiveList g_projectiles
Definition common.qh:58
float warpzone_initialized
Definition server.qc:676
void WarpZone_InitStep_FindOriginTarget(entity this)
Definition server.qc:452
void WarpZones_Reconnect()
Definition server.qc:741
#define WarpZone_StoreProjectileData(e_)
Definition server.qc:38
void WarpZone_InitStep_UpdateTransform(entity this)
Definition server.qc:534
float WarpZone_Teleport(entity wz, entity player, float f0, float f1)
Definition server.qc:82
void WarpZonePosition_InitStep_FindTarget(entity this)
Definition server.qc:466
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;
105 own = player.owner;
106 player.owner = NULL;
107 tracebox(trace_endpos, player.mins, player.maxs, o1 - player.view_ofs + v1 * frametime * f1, MOVE_NORMAL, player); // this should get us through the warpzone
108 player.owner = own;
109 }
110 o1 = trace_endpos + player.view_ofs;
111
112 float d, dv, md;
113 md = max(vlen(player.mins), vlen(player.maxs));
114 d = WarpZone_TargetPlaneDist(wz, o1);
115 dv = WarpZone_TargetPlaneDist(wz, v1);
116 if(d < 0)
117 o1 = o1 - v1 * (d / dv);
118 }
119
120 // put them out of solid
121 tracebox(o1 - player.view_ofs, player.mins, player.maxs, o1 - player.view_ofs, MOVE_NOMONSTERS, player);
123 {
124 setorigin(player, o1 - player.view_ofs);
126 {
127 o1 = player.origin + player.view_ofs;
128 setorigin(player, o0 - player.view_ofs);
129 }
130 else
131 {
132 LOG_INFO("would have to put player in solid, won't do that");
133 setorigin(player, o0 - player.view_ofs);
134 return 0;
135 }
136 }
137
138 // do the teleport
139 WarpZone_RefSys_Add(player, wz);
140 WarpZone_TeleportPlayer(wz, player, o1 - player.view_ofs, a1, v1);
142 player.warpzone_teleport_time = time;
143 player.warpzone_teleport_finishtime = time;
144 player.warpzone_teleport_zone = wz;
145
146#ifdef SVQC
147 // prevent further teleports back
148 float dt = (v1 != '0 0 0') ? (o1 - o10) * v1 * (1 / (v1 * v1)) : 0;
149 if(dt < PHYS_INPUT_FRAMETIME)
150 player.warpzone_teleport_finishtime += PHYS_INPUT_FRAMETIME - dt;
151#endif
152
153#ifndef WARPZONE_USE_FIXANGLE
154 #ifdef SVQC
155 if(IS_VEHICLE(player) && player.owner)
156 player = player.owner; // hax
157 if(IS_PLAYER(player))
158 {
159 // instead of fixangle, send the transform to the client for smoother operation
160 player.fixangle = false;
161
162 entity ts = new(warpzone_teleported);
163 setmodel(ts, MDL_Null);
165 ts.SendFlags = 0xFFFFFF;
166 ts.drawonlytoclient = player;
167 setthink(ts, SUB_Remove);
168 ts.nextthink = time + 1;
169 ts.owner = player;
170 ts.enemy = wz;
171 ts.effects = EF_NODEPTHTEST;
172 ts.angles = wz.warpzone_transform;
173 }
174 #elif defined(CSQC)
175 setproperty(VF_CL_VIEWANGLES, WarpZone_TransformVAngles(wz, getpropertyvec(VF_CL_VIEWANGLES)));
176 //if(checkextension("DP_CSQC_ROTATEMOVES"))
177 //CL_RotateMoves(wz.warpzone_transform);
178 #endif
179#endif
180
181 return 1;
182}
#define setmodel(this, m)
Definition model.qh:26
#define IS_NOT_A_CLIENT(s)
Definition player.qh:244
#define PHYS_INPUT_FRAMETIME
Definition player.qh:255
#define PHYS_INPUT_ANGLES(s)
Definition player.qh:250
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:731
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:848
float max(float f,...)
f1
Definition all.inc:561
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:22

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 753 of file server.qc.

754{
755 if(this.warpzone_save_origin != this.origin
756 || this.warpzone_save_angles != this.angles
757 || this.warpzone_save_eorigin != this.enemy.origin
758 || this.warpzone_save_eangles != this.enemy.angles)
759 {
764 this.warpzone_save_origin = this.origin;
765 this.warpzone_save_angles = this.angles;
766 this.warpzone_save_eorigin = this.enemy.origin;
767 this.warpzone_save_eangles = this.enemy.angles;
768 }
769 this.nextthink = time;
770}
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 184 of file server.qc.

185{
186 if(toucher.classname == "trigger_warpzone")
187 return;
188
189 if(time <= toucher.warpzone_teleport_finishtime) // already teleported this frame
190 return;
191
192 // FIXME needs a better check to know what is safe to teleport and what not
193 if(toucher.move_movetype == MOVETYPE_NONE || toucher.move_movetype == MOVETYPE_FOLLOW || toucher.tag_entity)
194 return;
195
196 if(WarpZone_PlaneDist(this, toucher.origin + toucher.view_ofs) >= 0) // wrong side of the trigger_warpzone (don't teleport yet)
197 return;
198
200
201 float f;
202 // number of frames we need to go back:
203 // dist = 16*sqrt(2) qu
204 // dist ~ 24 qu
205 // 24 qu = v*t
206 // 24 qu = v*frametime*n
207 // n = 24 qu/(v*frametime)
208 // for clients go only one frame though, may be too irritating otherwise
209 // but max 0.25 sec = 0.25/frametime frames
210 // 24/(0.25/frametime)
211 // 96*frametime
212 float d;
213 d = 24 + max(vlen(toucher.mins), vlen(toucher.maxs));
215 f = -d / bound(frametime * d * 1, frametime * vlen(toucher.velocity), d);
216 else
217 f = -1;
218 if(WarpZone_Teleport(this, toucher, f, 0))
219 {
220#ifdef SVQC
221 SUB_UseTargets_SkipTargets(this, toucher, toucher, BIT(1) | BIT(3)); // use toucher too?
222 SUB_UseTargets_SkipTargets(this.enemy, toucher, toucher, BIT(1) | BIT(2)); // use toucher too?
223#endif
224 }
225 else
226 {
227 LOG_TRACE("WARPZONE FAIL AHAHAHAHAH))");
228 }
229}
#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 504 of file server.qc.

505{
506 entity e;
507 float i;
508 if(this.target == "")
509 {
510 error("Camera with no target");
511 return;
512 }
513 this.enemy = NULL;
514 for(e = NULL, i = 0; (e = find(e, targetname, this.target)); )
515 if(random() * ++i < 1)
516 this.enemy = e;
517 if(this.enemy == NULL)
518 {
519 error("Camera with nonexisting target");
520 return;
521 }
523 WarpZone_Camera_SetUp(this, this.enemy.origin, this.enemy.angles);
524 this.SendFlags = 0xFFFFFF;
525 if(this.spawnflags & 1)
526 {
528 this.nextthink = time;
529 }
530 else
531 this.nextthink = 0;
532}
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:488

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 488 of file server.qc.

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

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 466 of file server.qc.

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

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 679 of file server.qc.

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

◆ warpzone_initialized

float warpzone_initialized

Definition at line 676 of file server.qc.

Referenced by WarpZone_StartFrame().

◆ warpzone_next

entity warpzone_next

Definition at line 680 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 678 of file server.qc.

Referenced by spawnfunc(), and WarpZone_StartFrame().

◆ warpzone_reconnecting

float warpzone_reconnecting

Definition at line 824 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().