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

Go to the source code of this file.

Macros

#define PORTALS_ARE_NOT_SOLID

Functions

float PlayerEdgeDistance (entity p, vector v)
vector Portal_ApplyTransformToPlayerAngle (vector transform, vector vangle)
void Portal_ClearAll (entity own)
void Portal_ClearAll_PortalsOnly (entity own)
void Portal_ClearAllLater (entity own)
void Portal_ClearAllLater_PortalsOnly (entity own)
void Portal_ClearWithID (entity own, float id)
void Portal_Connect (entity teleporter, entity destination)
bool Portal_Customize (entity this, entity client)
void Portal_Damage (entity this, entity inflictor, entity attacker, float damage, int deathtype,.entity weaponentity, vector hitloc, vector force)
void Portal_Disconnect (entity teleporter, entity destination)
float Portal_FindSafeOrigin (entity portal)
void Portal_MakeBrokenPortal (entity portal)
void Portal_MakeInPortal (entity portal)
void Portal_MakeOutPortal (entity portal)
void Portal_MakeWaitingPortal (entity portal)
void Portal_Remove (entity portal, float killed)
void Portal_RemoveLater (entity portal, float kill)
void Portal_RemoveLater_Think (entity this)
float Portal_SetInPortal (entity own, entity portal)
float Portal_SetOutPortal (entity own, entity portal)
entity Portal_Spawn (entity own, vector org, vector ang)
float Portal_SpawnInPortalAtTrace (entity own, vector dir, float portal_id_val)
float Portal_SpawnOutPortalAtTrace (entity own, vector dir, float portal_id_val)
float Portal_TeleportPlayer (entity teleporter, entity player, entity portal_owner)
void Portal_Think (entity this)
void Portal_Think_TryTeleportPlayer (entity this, entity e, vector g, entity portal_owner)
void Portal_Touch (entity this, entity toucher)
float Portal_WillHitPlane (vector eorg, vector emins, vector emaxs, vector evel, vector porg, vector pnorm, float psize)

Variables

float portal_activatetime
vector portal_safe_origin
vector portal_transform
float portal_wants_to_vanish
vector right_vector
const vector SAFENUDGE = '1 1 1'
const vector SAFERNUDGE = '8 8 8'
float savemodelindex

Macro Definition Documentation

◆ PORTALS_ARE_NOT_SOLID

#define PORTALS_ARE_NOT_SOLID

Definition at line 26 of file portals.qc.

Function Documentation

◆ PlayerEdgeDistance()

float PlayerEdgeDistance ( entity p,
vector v )

Definition at line 37 of file portals.qc.

38{
39 vector vbest = vec3(
40 ((v.x < 0) ? p.mins.x : p.maxs.x),
41 ((v.y < 0) ? p.mins.y : p.maxs.y),
42 ((v.z < 0) ? p.mins.z : p.maxs.z));
43
44 return vbest * v;
45}
vector
Definition self.qh:92
#define vec3(_x, _y, _z)
Definition vector.qh:95

References entity(), vec3, and vector.

Referenced by Portal_TeleportPlayer().

◆ Portal_ApplyTransformToPlayerAngle()

vector Portal_ApplyTransformToPlayerAngle ( vector transform,
vector vangle )

Definition at line 47 of file portals.qc.

48{
49 vector old_forward, old_up;
50 vector old_yawforward;
51 vector new_forward, new_up;
52 vector new_yawforward;
53
54 vector ang = vangle;
55 /*
56 ang_x = bound(-89, mod(-ang_x + 180, 360) - 180, 89);
57 ang = AnglesTransform_ApplyToVAngles(transform, ang);
58 */
59
60 // PLAYERS use different math
61#if !(POSITIVE_PITCH_IS_DOWN)
62 ang.x = -ang.x;
63#endif
64
65 //print("reference: ", vtos(AnglesTransform_ApplyToVAngles(transform, ang)), "\n");
66
68 old_forward = v_forward;
69 old_up = v_up;
70 fixedmakevectors(ang.y * '0 1 0');
71 old_yawforward = v_forward;
72
73 // their aiming directions are portalled...
74 new_forward = AnglesTransform_Apply(transform, old_forward);
75 new_up = AnglesTransform_Apply(transform, old_up);
76 new_yawforward = AnglesTransform_Apply(transform, old_yawforward);
77
78 // but now find a new sense of direction
79 // this is NOT easy!
80 // assume new_forward points straight up.
81 // What is our yaw?
82 //
83 // new_up could now point forward OR backward... which direction to choose?
84
85 if(new_forward.z > 0.7 || new_forward.z < -0.7) // far up; in this case, the "up" vector points backwards
86 {
87 // new_yawforward and new_yawup define the new aiming half-circle
88 // we "just" need to find out whether new_up or -new_up is in that half circle
89 ang = fixedvectoangles(new_forward); // this still gets us a nice pitch value...
90 if(new_up * new_yawforward < 0)
91 new_up = -1 * new_up;
92 ang.y = vectoyaw(new_up); // this vector is the yaw we want
93 //print("UP/DOWN path: ", vtos(ang), "\n");
94 }
95 else
96 {
97 // good angles; here, "forward" suffices
98 ang = fixedvectoangles(new_forward);
99 //print("GOOD path: ", vtos(ang), "\n");
100 }
101
102#if !(POSITIVE_PITCH_IS_DOWN)
103 ang.x = -ang.x;
104#endif
105 ang.z = vangle.z;
106 return ang;
107}
vector AnglesTransform_Apply(vector transform, vector v)
void fixedmakevectors(vector a)
#define fixedvectoangles
vector v_up
vector v_forward
float vectoyaw(vector v)
vector vector ang
Definition self.qh:92

References ang, AnglesTransform_Apply(), fixedmakevectors(), fixedvectoangles, v_forward, v_up, vector, and vectoyaw().

Referenced by Portal_TeleportPlayer().

◆ Portal_ClearAll()

void Portal_ClearAll ( entity own)

Definition at line 586 of file portals.qc.

587{
589 W_Porto_Remove(own);
590}
void Portal_ClearAll_PortalsOnly(entity own)
Definition portals.qc:579
void W_Porto_Remove(entity p)
Definition porto.qc:151

References entity(), Portal_ClearAll_PortalsOnly(), and W_Porto_Remove().

Referenced by checkpoint_passed(), ClientDisconnect(), and PutObserverInServer().

◆ Portal_ClearAll_PortalsOnly()

void Portal_ClearAll_PortalsOnly ( entity own)

Definition at line 579 of file portals.qc.

580{
581 if(own.portal_in)
582 Portal_Remove(own.portal_in, 0);
583 if(own.portal_out)
584 Portal_Remove(own.portal_out, 0);
585}
void Portal_Remove(entity portal, float killed)
Definition portals.qc:408

References entity(), and Portal_Remove().

Referenced by Portal_ClearAll(), and W_Porto_Touch().

◆ Portal_ClearAllLater()

void Portal_ClearAllLater ( entity own)

Definition at line 609 of file portals.qc.

610{
612 W_Porto_Remove(own);
613}
void Portal_ClearAllLater_PortalsOnly(entity own)
Definition portals.qc:602

References entity(), Portal_ClearAllLater_PortalsOnly(), and W_Porto_Remove().

Referenced by PlayerDamage().

◆ Portal_ClearAllLater_PortalsOnly()

void Portal_ClearAllLater_PortalsOnly ( entity own)

Definition at line 602 of file portals.qc.

603{
604 if(own.portal_in)
605 Portal_RemoveLater(own.portal_in, 0);
606 if(own.portal_out)
607 Portal_RemoveLater(own.portal_out, 0);
608}
void Portal_RemoveLater(entity portal, float kill)
Definition portals.qc:595

References entity(), and Portal_RemoveLater().

Referenced by Portal_ClearAllLater().

◆ Portal_ClearWithID()

void Portal_ClearWithID ( entity own,
float id )

Definition at line 614 of file portals.qc.

615{
616 if(own.portal_in)
617 if(own.portal_in.portal_id == id)
618 {
619 if(own.portal_out)
620 Portal_Disconnect(own.portal_in, own.portal_out);
621 Portal_Remove(own.portal_in, 0);
622 }
623 if(own.portal_out)
624 if(own.portal_out.portal_id == id)
625 {
626 if(own.portal_in)
627 Portal_Disconnect(own.portal_in, own.portal_out);
628 Portal_Remove(own.portal_out, 0);
629 }
630}
void Portal_Disconnect(entity teleporter, entity destination)
Definition portals.qc:379

References entity(), Portal_Disconnect(), and Portal_Remove().

Referenced by W_Porto_Fail().

◆ Portal_Connect()

void Portal_Connect ( entity teleporter,
entity destination )

Definition at line 387 of file portals.qc.

388{
389 teleporter.portal_transform = AnglesTransform_RightDivide(AnglesTransform_TurnDirectionFR(destination.mangle), teleporter.mangle);
390
391 teleporter.enemy = destination;
392 destination.enemy = teleporter;
393 Portal_MakeInPortal(teleporter);
394 Portal_MakeOutPortal(destination);
395 teleporter.fade_time = ((autocvar_g_balance_portal_lifetime >= 0) ? time + autocvar_g_balance_portal_lifetime : 0);
396 destination.fade_time = teleporter.fade_time;
397 teleporter.portal_wants_to_vanish = 0;
398 destination.portal_wants_to_vanish = 0;
399 teleporter.teleport_time = time;
400#ifdef PORTALS_ARE_NOT_SOLID
401 teleporter.solid = SOLID_TRIGGER;
402#else
403 teleporter.solid = SOLID_BSP;
404#endif
405 setorigin(teleporter, teleporter.origin); // link it to the area grid
406}
vector AnglesTransform_TurnDirectionFR(vector transform)
vector AnglesTransform_RightDivide(vector to_transform, vector from_transform)
const float SOLID_TRIGGER
float time
const float SOLID_BSP
void Portal_MakeOutPortal(entity portal)
Definition portals.qc:368
void Portal_MakeInPortal(entity portal)
Definition portals.qc:357
float autocvar_g_balance_portal_lifetime
Definition portals.qh:4

References AnglesTransform_RightDivide(), AnglesTransform_TurnDirectionFR(), autocvar_g_balance_portal_lifetime, entity(), Portal_MakeInPortal(), Portal_MakeOutPortal(), SOLID_BSP, SOLID_TRIGGER, and time.

Referenced by Portal_SetInPortal(), and Portal_SetOutPortal().

◆ Portal_Customize()

bool Portal_Customize ( entity this,
entity client )

Definition at line 511 of file portals.qc.

512{
513 if(IS_SPEC(client))
514 client = client.enemy;
515 if(client == this.aiment)
516 {
517 this.modelindex = this.savemodelindex;
518 }
519 else if(IS_INDEPENDENT_PLAYER(client) || IS_INDEPENDENT_PLAYER(this.aiment))
520 {
521 this.modelindex = 0;
522 }
523 else
524 {
525 this.modelindex = this.savemodelindex;
526 }
527 return true;
528}
float modelindex
entity aiment
Definition movetypes.qh:90
float savemodelindex
Definition portals.qc:35
#define IS_INDEPENDENT_PLAYER(e)
Definition client.qh:312
#define IS_SPEC(v)
Definition utils.qh:10

References aiment, entity(), IS_INDEPENDENT_PLAYER, IS_SPEC, modelindex, and savemodelindex.

Referenced by Portal_Spawn().

◆ Portal_Damage()

void Portal_Damage ( entity this,
entity inflictor,
entity attacker,
float damage,
int deathtype,
.entity weaponentity,
vector hitloc,
vector force )

Definition at line 440 of file portals.qc.

441{
442 if(deathtype == DEATH_TELEFRAG.m_id)
443 return;
444 if(attacker != this.aiment)
446 return;
447 TakeResource(this, RES_HEALTH, damage);
448 if(GetResource(this, RES_HEALTH) < 0)
449 Portal_Remove(this, 1);
450}
float GetResource(entity e, Resource res_type)
Returns the current amount of resource the given entity has.
void TakeResource(entity receiver, Resource res_type, float amount)
Takes an entity some resource.

References aiment, entity(), GetResource(), IS_INDEPENDENT_PLAYER, Portal_Remove(), TakeResource(), and vector.

Referenced by Portal_Spawn().

◆ Portal_Disconnect()

void Portal_Disconnect ( entity teleporter,
entity destination )

Definition at line 379 of file portals.qc.

380{
381 teleporter.enemy = NULL;
382 destination.enemy = NULL;
383 Portal_MakeBrokenPortal(teleporter);
384 Portal_MakeBrokenPortal(destination);
385}
void Portal_MakeBrokenPortal(entity portal)
Definition portals.qc:335
#define NULL
Definition post.qh:14

References entity(), NULL, and Portal_MakeBrokenPortal().

Referenced by Portal_ClearWithID(), Portal_Remove(), Portal_SetInPortal(), and Portal_SetOutPortal().

◆ Portal_FindSafeOrigin()

float Portal_FindSafeOrigin ( entity portal)

Definition at line 218 of file portals.qc.

219{
220 vector o = portal.origin;
221 portal.mins = PL_MIN_CONST - SAFERNUDGE;
222 portal.maxs = PL_MAX_CONST + SAFERNUDGE;
223 fixedmakevectors(portal.mangle);
224 portal.origin += 16 * v_forward;
225 if(!move_out_of_solid(portal))
226 {
227#ifdef DEBUG
228 LOG_INFO("NO SAFE ORIGIN");
229#endif
230 return 0;
231 }
232 portal.portal_safe_origin = portal.origin;
233 setorigin(portal, o);
234 return 1;
235}
const vector PL_MIN_CONST
Definition constants.qh:56
const vector PL_MAX_CONST
Definition constants.qh:55
#define move_out_of_solid(e)
Definition common.qh:110
#define LOG_INFO(...)
Definition log.qh:65
const vector SAFERNUDGE
Definition portals.qc:29

References entity(), fixedmakevectors(), LOG_INFO, move_out_of_solid, PL_MAX_CONST, PL_MIN_CONST, SAFERNUDGE, v_forward, and vector.

Referenced by Portal_Spawn().

◆ Portal_MakeBrokenPortal()

void Portal_MakeBrokenPortal ( entity portal)

Definition at line 335 of file portals.qc.

336{
337 portal.skin = 2;
338 portal.solid = SOLID_NOT;
339 settouch(portal, func_null);
340 setthink(portal, func_null);
341 portal.effects = 0;
342 portal.nextthink = 0;
343 portal.takedamage = DAMAGE_NO;
344}
const float SOLID_NOT
var void func_null()
#define setthink(e, f)
#define settouch(e, f)
Definition self.qh:73
const int DAMAGE_NO
Definition subs.qh:79

References DAMAGE_NO, entity(), func_null(), setthink, settouch, and SOLID_NOT.

Referenced by Portal_Disconnect(), Portal_Remove(), and Portal_RemoveLater().

◆ Portal_MakeInPortal()

void Portal_MakeInPortal ( entity portal)

Definition at line 357 of file portals.qc.

358{
359 portal.skin = 0;
360 portal.solid = SOLID_NOT; // this is done when connecting them!
361 settouch(portal, Portal_Touch);
362 setthink(portal, Portal_Think);
363 portal.effects = EF_RED;
364 portal.nextthink = time;
365 portal.takedamage = DAMAGE_NO;
366}
const float EF_RED
void Portal_Think(entity this)
Definition portals.qc:464
void Portal_Touch(entity this, entity toucher)
Definition portals.qc:262

References DAMAGE_NO, EF_RED, entity(), Portal_Think(), Portal_Touch(), setthink, settouch, SOLID_NOT, and time.

Referenced by Portal_Connect().

◆ Portal_MakeOutPortal()

void Portal_MakeOutPortal ( entity portal)

Definition at line 368 of file portals.qc.

369{
370 portal.skin = 1;
371 portal.solid = SOLID_NOT;
372 settouch(portal, func_null);
373 setthink(portal, func_null);
374 portal.effects = EF_STARDUST | EF_BLUE;
375 portal.nextthink = 0;
376 portal.takedamage = DAMAGE_YES;
377}
const float EF_STARDUST
const float EF_BLUE
const int DAMAGE_YES
Definition subs.qh:80

References DAMAGE_YES, EF_BLUE, EF_STARDUST, entity(), func_null(), setthink, settouch, and SOLID_NOT.

Referenced by Portal_Connect().

◆ Portal_MakeWaitingPortal()

void Portal_MakeWaitingPortal ( entity portal)

Definition at line 346 of file portals.qc.

347{
348 portal.skin = 2;
349 portal.solid = SOLID_NOT;
350 settouch(portal, func_null);
351 setthink(portal, func_null);
352 portal.effects = EF_ADDITIVE;
353 portal.nextthink = 0;
354 portal.takedamage = DAMAGE_YES;
355}
const float EF_ADDITIVE

References DAMAGE_YES, EF_ADDITIVE, entity(), func_null(), setthink, settouch, and SOLID_NOT.

Referenced by Portal_Spawn().

◆ Portal_Remove()

void Portal_Remove ( entity portal,
float killed )

Definition at line 408 of file portals.qc.

409{
410 entity e = portal.enemy;
411
412 if(e)
413 {
414 Portal_Disconnect(portal, e);
415 Portal_Remove(e, killed);
416 }
417
418 if(portal == portal.aiment.portal_in)
419 portal.aiment.portal_in = NULL;
420 if(portal == portal.aiment.portal_out)
421 portal.aiment.portal_out = NULL;
422 //portal.aiment = NULL;
423
424 // makes the portal vanish
425 if(killed)
426 {
427 fixedmakevectors(portal.mangle);
428 sound(portal, CH_SHOTS, SND_PORTO_EXPLODE, VOL_BASE, ATTEN_NORM);
429 Send_Effect(EFFECT_ROCKET_EXPLODE, portal.origin + v_forward * 16, v_forward * 1024, 4);
430 delete(portal);
431 }
432 else
433 {
435 sound(portal, CH_SHOTS, SND_PORTO_EXPIRE, VOL_BASE, ATTEN_NORM);
436 SUB_SetFade(portal, time, 0.5);
437 }
438}
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
void Send_Effect(entity eff, vector eff_loc, vector eff_vel, int eff_cnt)
Definition all.qc:120
const float VOL_BASE
Definition sound.qh:36
const int CH_SHOTS
Definition sound.qh:14
const float ATTEN_NORM
Definition sound.qh:30
#define sound(e, c, s, v, a)
Definition sound.qh:52
void SUB_SetFade(entity ent, float vanish_time, float fading_time)
Definition subs.qc:77

References ATTEN_NORM, CH_SHOTS, entity(), fixedmakevectors(), NULL, Portal_Disconnect(), Portal_MakeBrokenPortal(), Portal_Remove(), Send_Effect(), sound, SUB_SetFade(), time, v_forward, and VOL_BASE.

Referenced by Portal_ClearAll_PortalsOnly(), Portal_ClearWithID(), Portal_Damage(), Portal_Remove(), Portal_RemoveLater_Think(), Portal_SetInPortal(), Portal_SetOutPortal(), and Portal_Think().

◆ Portal_RemoveLater()

void Portal_RemoveLater ( entity portal,
float kill )

Definition at line 595 of file portals.qc.

596{
598 portal.cnt = kill;
600 portal.nextthink = time;
601}
void Portal_RemoveLater_Think(entity this)
Definition portals.qc:591

References entity(), Portal_MakeBrokenPortal(), Portal_RemoveLater_Think(), setthink, and time.

Referenced by Portal_ClearAllLater_PortalsOnly().

◆ Portal_RemoveLater_Think()

void Portal_RemoveLater_Think ( entity this)

Definition at line 591 of file portals.qc.

592{
593 Portal_Remove(this, this.cnt);
594}
float cnt
Definition powerups.qc:24

References cnt, entity(), and Portal_Remove().

Referenced by Portal_RemoveLater().

◆ Portal_SetInPortal()

float Portal_SetInPortal ( entity own,
entity portal )

Definition at line 547 of file portals.qc.

548{
549 if(own.portal_in)
550 {
551 if(own.portal_out)
552 Portal_Disconnect(own.portal_in, own.portal_out);
553 Portal_Remove(own.portal_in, 0);
554 }
555 own.portal_in = portal;
556 if(own.portal_out)
557 {
558 own.portal_out.portal_id = portal.portal_id;
559 Portal_Connect(own.portal_in, own.portal_out);
560 }
561 return 2;
562}
void Portal_Connect(entity teleporter, entity destination)
Definition portals.qc:387

References entity(), Portal_Connect(), Portal_Disconnect(), and Portal_Remove().

Referenced by Portal_SpawnInPortalAtTrace().

◆ Portal_SetOutPortal()

float Portal_SetOutPortal ( entity own,
entity portal )

Definition at line 563 of file portals.qc.

564{
565 if(own.portal_out)
566 {
567 if(own.portal_in)
568 Portal_Disconnect(own.portal_in, own.portal_out);
569 Portal_Remove(own.portal_out, 0);
570 }
571 own.portal_out = portal;
572 if(own.portal_in)
573 {
574 own.portal_in.portal_id = portal.portal_id;
575 Portal_Connect(own.portal_in, own.portal_out);
576 }
577 return 1;
578}

References entity(), Portal_Connect(), Portal_Disconnect(), and Portal_Remove().

Referenced by Portal_SpawnOutPortalAtTrace().

◆ Portal_Spawn()

entity Portal_Spawn ( entity own,
vector org,
vector ang )

Definition at line 632 of file portals.qc.

633{
635 if(!CheckWireframeBox(own, org - 48 * v_right - 48 * v_up + 16 * v_forward, 96 * v_right, 96 * v_up, 96 * v_forward))
636 return NULL;
637
638 entity portal = new(portal);
639 portal.aiment = own;
640 setorigin(portal, org);
641 portal.mangle = ang;
642 portal.angles = ang;
643 portal.angles_x = -portal.angles.x; // is a bmodel
644 setthink(portal, Portal_Think);
645 portal.nextthink = 0;
646 portal.portal_activatetime = time + 0.1;
647 portal.takedamage = DAMAGE_AIM;
648 portal.event_damage = Portal_Damage;
651 setmodel(portal, MDL_PORTAL);
652 portal.savemodelindex = portal.modelindex;
653 setcefc(portal, Portal_Customize);
654
655 if(!Portal_FindSafeOrigin(portal))
656 {
657 delete(portal);
658 return NULL;
659 }
660
661 setsize(portal, '-48 -48 -48', '48 48 48');
663
664 return portal;
665}
bool SetResourceExplicit(entity e, Resource res_type, float amount)
Sets the resource amount of an entity without calling any hooks.
#define setmodel(this, m)
Definition model.qh:26
float CheckWireframeBox(entity forent, vector v0, vector dvx, vector dvy, vector dvz)
Definition util.qc:580
vector v_right
float Portal_FindSafeOrigin(entity portal)
Definition portals.qc:218
void Portal_Damage(entity this, entity inflictor, entity attacker, float damage, int deathtype,.entity weaponentity, vector hitloc, vector force)
Definition portals.qc:440
void Portal_MakeWaitingPortal(entity portal)
Definition portals.qc:346
bool Portal_Customize(entity this, entity client)
Definition portals.qc:511
float autocvar_g_balance_portal_health
Definition portals.qh:3
#define setcefc(e, f)
vector org
Definition self.qh:92
const int DAMAGE_AIM
Definition subs.qh:81

References ang, autocvar_g_balance_portal_health, autocvar_g_balance_portal_lifetime, CheckWireframeBox(), DAMAGE_AIM, entity(), fixedmakevectors(), NULL, org, Portal_Customize(), Portal_Damage(), Portal_FindSafeOrigin(), Portal_MakeWaitingPortal(), Portal_Think(), setcefc, setmodel, SetResourceExplicit(), setthink, time, v_forward, v_right, v_up, and vector.

Referenced by Portal_SpawnInPortalAtTrace(), and Portal_SpawnOutPortalAtTrace().

◆ Portal_SpawnInPortalAtTrace()

float Portal_SpawnInPortalAtTrace ( entity own,
vector dir,
float portal_id_val )

Definition at line 667 of file portals.qc.

668{
672
673 entity portal = Portal_Spawn(own, org, ang);
674 if(!portal)
675 return 0;
676
677 portal.portal_id = portal_id_val;
678 Portal_SetInPortal(own, portal);
679
680 return 1;
681}
#define fixedvectoangles2
vector trace_endpos
vector trace_plane_normal
float Portal_SetInPortal(entity own, entity portal)
Definition portals.qc:547
entity Portal_Spawn(entity own, vector org, vector ang)
Definition portals.qc:632
int dir
Definition impulse.qc:89

References ang, dir, entity(), fixedmakevectors(), fixedvectoangles2, org, Portal_SetInPortal(), Portal_Spawn(), trace_endpos, trace_plane_normal, and vector.

Referenced by W_Porto_Touch().

◆ Portal_SpawnOutPortalAtTrace()

float Portal_SpawnOutPortalAtTrace ( entity own,
vector dir,
float portal_id_val )

Definition at line 683 of file portals.qc.

684{
688
689 entity portal = Portal_Spawn(own, org, ang);
690 if(!portal)
691 return 0;
692
693 portal.portal_id = portal_id_val;
694 Portal_SetOutPortal(own, portal);
695
696 return 1;
697}
float Portal_SetOutPortal(entity own, entity portal)
Definition portals.qc:563

References ang, dir, entity(), fixedmakevectors(), fixedvectoangles2, org, Portal_SetOutPortal(), Portal_Spawn(), trace_endpos, trace_plane_normal, and vector.

Referenced by W_Porto_Touch().

◆ Portal_TeleportPlayer()

float Portal_TeleportPlayer ( entity teleporter,
entity player,
entity portal_owner )

Definition at line 110 of file portals.qc.

111{
112 vector from, to, safe, step, transform, ang, newvel;
113 float planeshift, s, t;
114
115 if (!teleporter.enemy)
116 {
117 backtrace("Portal_TeleportPlayer called without other portal being set. Stop.");
118 return 0;
119 }
120
121 from = teleporter.origin;
122 transform = teleporter.portal_transform;
123
124 to = teleporter.enemy.origin;
125 to += AnglesTransform_Apply(teleporter.portal_transform, player.origin - from);
126 newvel = AnglesTransform_Apply(transform, player.velocity);
127 // this now is INSIDE the plane... can't use that
128
129 // shift it out
130 fixedmakevectors(teleporter.enemy.mangle);
131
132 // first shift it ON the plane if needed
133 planeshift = ((teleporter.enemy.origin - to) * v_forward) + PlayerEdgeDistance(player, v_forward) + 1;
134 /*
135 if(planeshift > 0 && (newvel * v_forward) > vlen(newvel) * 0.01)
136 // if we can't, let us not do the planeshift and do somewhat incorrect transformation in the end
137 to += newvel * (planeshift / (newvel * v_forward));
138 else
139 */
140 to += v_forward * planeshift;
141
142 s = (to - teleporter.enemy.origin) * v_right;
143 t = (to - teleporter.enemy.origin) * v_up;
144 s = bound(-48, s, 48);
145 t = bound(-48, t, 48);
146 to = teleporter.enemy.origin
147 + ((to - teleporter.enemy.origin) * v_forward) * v_forward
148 + s * v_right
149 + t * v_up;
150
151 safe = teleporter.enemy.portal_safe_origin; // a valid player origin
152 step = to + ((safe - to) * v_forward) * v_forward;
153 tracebox(safe, player.mins - SAFENUDGE, player.maxs + SAFENUDGE, step, MOVE_NOMONSTERS, player);
155 {
156 LOG_INFO("'safe' teleport location is not safe!");
157 // FAIL TODO why does this happen?
158 return 0;
159 }
160 safe = trace_endpos + normalize(safe - trace_endpos) * 0;
161 tracebox(safe, player.mins - SAFENUDGE, player.maxs + SAFENUDGE, to, MOVE_NOMONSTERS, player);
163 {
164 LOG_INFO("trace_endpos in solid, this can't be!");
165 // FAIL TODO why does this happen? (reported by MrBougo)
166 return 0;
167 }
168 to = trace_endpos + normalize(safe - trace_endpos) * 0;
169 //print(vtos(to), "\n");
170
171 // ang_x stuff works around weird quake angles
172 if(IS_PLAYER(player))
173 ang = Portal_ApplyTransformToPlayerAngle(transform, player.v_angle);
174 else
175 ang = AnglesTransform_ApplyToAngles(transform, player.angles);
176
177 // factor -1 allows chaining portals, but may be weird
178 player.right_vector = -1 * AnglesTransform_Apply(transform, player.right_vector);
179
180 MUTATOR_CALLHOOK(PortalTeleport, player);
181
182 if (!teleporter.enemy)
183 {
184 backtrace("Portal_TeleportPlayer ended up without other portal being set BEFORE TeleportPlayer. Stop.");
185 return 0;
186 }
187
188 tdeath_hit = 0;
189 TeleportPlayer(teleporter, player, to, ang, newvel, teleporter.enemy.absmin, teleporter.enemy.absmax, TELEPORT_FLAGS_PORTAL);
190 if(tdeath_hit)
191 {
192 // telefrag within 1 second of portal creation = amazing
193 if(time < teleporter.teleport_time + 1)
194 Send_Notification(NOTIF_ONE, player, MSG_ANNCE, ANNCE_ACHIEVEMENT_AMAZING);
195 }
196 else if(player != portal_owner && IS_PLAYER(portal_owner) && IS_PLAYER(player))
197 {
198 player.pusher = portal_owner;
199 player.pushltime = time + autocvar_g_maxpushtime;
200 player.istypefrag = PHYS_INPUT_BUTTON_CHAT(player);
201 }
202
203 if (!teleporter.enemy)
204 {
205 backtrace("Portal_TeleportPlayer ended up without other portal being set AFTER TeleportPlayer. Stop.");
206 return 0;
207 }
208
209 // reset fade counter
210 teleporter.portal_wants_to_vanish = 0;
211 teleporter.fade_time = ((autocvar_g_balance_portal_lifetime >= 0) ? time + autocvar_g_balance_portal_lifetime : 0);
213 SetResourceExplicit(teleporter.enemy, RES_HEALTH, autocvar_g_balance_portal_health);
214
215 return 1;
216}
vector AnglesTransform_ApplyToAngles(vector transform, vector v)
#define MUTATOR_CALLHOOK(id,...)
Definition base.qh:143
#define PHYS_INPUT_BUTTON_CHAT(s)
Definition player.qh:161
#define IS_PLAYER(s)
Definition player.qh:242
const float MOVE_NOMONSTERS
float trace_startsolid
float autocvar_g_maxpushtime
Definition damage.qh:17
#define backtrace(msg)
Definition log.qh:99
float bound(float min, float value, float max)
vector normalize(vector v)
void Send_Notification(NOTIF broadcast, entity client, MSG net_type, Notification net_name,...count)
Definition all.qc:1573
vector Portal_ApplyTransformToPlayerAngle(vector transform, vector vangle)
Definition portals.qc:47
float PlayerEdgeDistance(entity p, vector v)
Definition portals.qc:37
const vector SAFENUDGE
Definition portals.qc:28
void TeleportPlayer(entity teleporter, entity player, vector to, vector to_angles, vector to_velocity, vector telefragmin, vector telefragmax, float tflags)
#define TELEPORT_FLAGS_PORTAL
float tdeath_hit

References ang, AnglesTransform_Apply(), AnglesTransform_ApplyToAngles(), autocvar_g_balance_portal_health, autocvar_g_balance_portal_lifetime, autocvar_g_maxpushtime, backtrace, bound(), entity(), fixedmakevectors(), IS_PLAYER, LOG_INFO, MOVE_NOMONSTERS, MUTATOR_CALLHOOK, normalize(), PHYS_INPUT_BUTTON_CHAT, PlayerEdgeDistance(), Portal_ApplyTransformToPlayerAngle(), SAFENUDGE, Send_Notification(), SetResourceExplicit(), tdeath_hit, TELEPORT_FLAGS_PORTAL, TeleportPlayer(), time, trace_endpos, trace_startsolid, v_forward, v_right, v_up, and vector.

Referenced by Portal_Think_TryTeleportPlayer(), and Portal_Touch().

◆ Portal_Think()

void Portal_Think ( entity this)

Definition at line 464 of file portals.qc.

465{
466 entity o;
467 vector g;
468
469#ifdef PORTALS_ARE_NOT_SOLID
470 // portal is being removed?
471 if(this.solid != SOLID_TRIGGER)
472 return; // possibly engine bug
473
474 if(!this.enemy)
475 error("Portal_Think called for a broken portal\n");
476
477 o = this.aiment;
478 this.solid = SOLID_BBOX;
479 this.aiment = NULL;
480
482
484 {
485 if(it != o)
487 continue; // cannot go through someone else's portal
488
489 g = frametime * '0 0 -1' * PHYS_GRAVITY(it);
490
491 if(it != o || time >= this.portal_activatetime)
492 Portal_Think_TryTeleportPlayer(this, it, g, o);
493
494 for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
495 {
496 .entity weaponentity = weaponentities[slot];
497 if(it.(weaponentity).hook)
498 Portal_Think_TryTeleportPlayer(this, it.(weaponentity).hook, g, o);
499 }
500 });
501 this.solid = SOLID_TRIGGER;
502 this.aiment = o;
503#endif
504
505 this.nextthink = time;
506
507 if(this.fade_time && time > this.fade_time)
508 Portal_Remove(this, 0);
509}
float frametime
const float SOLID_BBOX
float nextthink
solid
Definition ent_cs.qc:165
#define PHYS_GRAVITY(s)
Definition movetypes.qh:53
void Portal_Think_TryTeleportPlayer(entity this, entity e, vector g, entity portal_owner)
Definition portals.qc:452
float portal_activatetime
Definition portals.qc:34
#define error
Definition pre.qh:6
float fade_time
Definition common.qh:23
vector mangle
Definition subs.qh:51
entity enemy
Definition sv_ctf.qh:153
#define FOREACH_CLIENT(cond, body)
Definition utils.qh:52
const int MAX_WEAPONSLOTS
Definition weapon.qh:16
entity weaponentities[MAX_WEAPONSLOTS]
Definition weapon.qh:17

References aiment, enemy, entity(), error, fade_time, fixedmakevectors(), FOREACH_CLIENT, frametime, IS_INDEPENDENT_PLAYER, IS_PLAYER, mangle, MAX_WEAPONSLOTS, nextthink, NULL, PHYS_GRAVITY, portal_activatetime, Portal_Remove(), Portal_Think_TryTeleportPlayer(), solid, SOLID_BBOX, SOLID_TRIGGER, time, vector, and weaponentities.

Referenced by Portal_MakeInPortal(), and Portal_Spawn().

◆ Portal_Think_TryTeleportPlayer()

void Portal_Think_TryTeleportPlayer ( entity this,
entity e,
vector g,
entity portal_owner )

Definition at line 452 of file portals.qc.

453{
454 if(!Portal_WillHitPlane(e.origin, e.mins, e.maxs, e.velocity + g, this.origin, v_forward, this.maxs.x))
455 return;
456
457 // if e would hit the portal in a frame...
458 // already teleport him
459 tracebox(e.origin, e.mins, e.maxs, e.origin + e.velocity * 2 * frametime, MOVE_NORMAL, e);
460 if(trace_ent == this)
461 Portal_TeleportPlayer(this, e, portal_owner);
462}
entity trace_ent
const float MOVE_NORMAL
float Portal_WillHitPlane(vector eorg, vector emins, vector emaxs, vector evel, vector porg, vector pnorm, float psize)
Definition portals.qc:237
float Portal_TeleportPlayer(entity teleporter, entity player, entity portal_owner)
Definition portals.qc:110

References entity(), frametime, MOVE_NORMAL, Portal_TeleportPlayer(), Portal_WillHitPlane(), trace_ent, v_forward, and vector.

Referenced by Portal_Think().

◆ Portal_Touch()

void Portal_Touch ( entity this,
entity toucher )

Definition at line 262 of file portals.qc.

263{
264 vector g;
265
266#ifdef PORTALS_ARE_NOT_SOLID
267 // portal is being removed?
268 if(this.solid != SOLID_TRIGGER)
269 return; // possibly engine bug
270
271 if(IS_PLAYER(toucher))
272 return; // handled by think
273#endif
274
275 if(toucher.classname == "item_flag_team")
276 return; // never portal these
277
278 if(toucher.classname == "grapplinghook")
279 return; // handled by think
280
283 return; // no teleporting vehicles?
284
285 if(!this.enemy)
286 error("Portal_Touch called for a broken portal\n");
287
288#ifdef PORTALS_ARE_NOT_SOLID
289 if(trace_fraction < 1)
290 return; // only handle TouchAreaGrid ones (only these can teleport)
291#else
292 if(trace_fraction >= 1)
293 return; // only handle impacts
294#endif
295
296 if(toucher.classname == "porto")
297 {
298 if(toucher.portal_id == this.portal_id)
299 return;
300 }
301 if(time < this.portal_activatetime)
302 if(toucher == this.aiment)
303 {
304 this.portal_activatetime = time + 0.1;
305 return;
306 }
307 if(toucher != this.aiment)
308 if(IS_PLAYER(toucher))
310 return; // cannot go through someone else's portal
311 if(toucher.aiment != this.aiment)
312 if(IS_PLAYER(toucher.aiment))
314 return; // cannot go through someone else's portal
316 g = frametime * '0 0 -1' * PHYS_GRAVITY(toucher);
317 if(!Portal_WillHitPlane(toucher.origin, toucher.mins, toucher.maxs, toucher.velocity + g, this.origin, v_forward, this.maxs.x))
318 return;
319
320 /*
321 if(toucher.mins_x < PL_MIN.x || toucher.mins_y < PL_MIN.y || toucher.mins_z < PL_MIN.z
322 || toucher.maxs_x > PL_MAX.x || toucher.maxs_y > PL_MAX.y || toucher.maxs_z > PL_MAX.z)
323 {
324 // can't teleport this
325 return;
326 }
327 */
328
329 if(Portal_TeleportPlayer(this, toucher, this.aiment))
330 if(toucher.classname == "porto")
331 if(toucher.effects & EF_RED)
332 toucher.effects = (toucher.effects & ~EF_RED) | EF_BLUE;
333}
float trace_fraction
entity entity toucher
Definition self.qh:72
float autocvar_g_vehicles_teleportable
#define IS_VEHICLE(v)
Definition utils.qh:24

References aiment, autocvar_g_vehicles_teleportable, EF_BLUE, EF_RED, enemy, entity(), error, fixedmakevectors(), frametime, IS_INDEPENDENT_PLAYER, IS_PLAYER, IS_VEHICLE, mangle, PHYS_GRAVITY, portal_activatetime, Portal_TeleportPlayer(), Portal_WillHitPlane(), solid, SOLID_TRIGGER, time, toucher, trace_fraction, v_forward, and vector.

Referenced by Portal_MakeInPortal().

◆ Portal_WillHitPlane()

float Portal_WillHitPlane ( vector eorg,
vector emins,
vector emaxs,
vector evel,
vector porg,
vector pnorm,
float psize )

Definition at line 237 of file portals.qc.

238{
239 float dist, distpersec, delta;
240 vector v;
241
242 dist = (eorg - porg) * pnorm;
243 dist += min(emins.x * pnorm.x, emaxs.x * pnorm.x);
244 dist += min(emins.y * pnorm.y, emaxs.y * pnorm.y);
245 dist += min(emins.z * pnorm.z, emaxs.z * pnorm.z);
246 if(dist < -1) // other side?
247 return 0;
248#ifdef PORTALS_ARE_NOT_SOLID
249 distpersec = evel * pnorm;
250 if(distpersec >= 0) // going away from the portal?
251 return 0;
252 // we don't need this check with solid portals, them being SOLID_BSP should suffice
253 delta = dist / distpersec;
254 v = eorg - evel * delta - porg;
255 v -= pnorm * (pnorm * v);
256 return vlen(v) < psize;
257#else
258 return 1;
259#endif
260}
float vlen(vector v)
float min(float f,...)

References min(), vector, and vlen().

Referenced by Portal_Think_TryTeleportPlayer(), and Portal_Touch().

Variable Documentation

◆ portal_activatetime

float portal_activatetime

Definition at line 34 of file portals.qc.

Referenced by Portal_Think(), and Portal_Touch().

◆ portal_safe_origin

vector portal_safe_origin

Definition at line 32 of file portals.qc.

◆ portal_transform

vector portal_transform

Definition at line 31 of file portals.qc.

◆ portal_wants_to_vanish

float portal_wants_to_vanish

Definition at line 33 of file portals.qc.

◆ right_vector

vector right_vector

Definition at line 109 of file portals.qc.

◆ SAFENUDGE

const vector SAFENUDGE = '1 1 1'

Definition at line 28 of file portals.qc.

Referenced by Portal_TeleportPlayer().

◆ SAFERNUDGE

const vector SAFERNUDGE = '8 8 8'

Definition at line 29 of file portals.qc.

Referenced by Portal_FindSafeOrigin().

◆ savemodelindex

float savemodelindex

Definition at line 35 of file portals.qc.

Referenced by Portal_Customize().