Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
teleport.qc
Go to the documentation of this file.
1#include "teleport.qh"
2REGISTER_NET_LINKED(ENT_CLIENT_TRIGGER_TELEPORT)
3
4#ifdef SVQC
5void trigger_teleport_use(entity this, entity actor, entity trigger)
6{
7 if(teamplay)
8 this.team = actor.team;
9#ifdef SVQC
11#endif
12}
13#endif
14
15bool Teleport_Active(entity this, entity player)
16{
17 if (this.active != ACTIVE_ACTIVE)
18 return false;
19
20#ifdef SVQC
21 if (!player.teleportable)
22 return false;
23
24 if(player.vehicle)
25 if(!player.vehicle.teleportable)
26 return false;
27
28 if(IS_TURRET(player))
29 return false;
30#elif defined(CSQC)
31 if(!IS_PLAYER(player))
32 return false;
33#endif
34
35 if(IS_DEAD(player))
36 return false;
37
38 if(this.team)
39 if(((this.spawnflags & INVERT_TEAMS) == 0) == (DIFF_TEAM(this, player)))
40 return false;
41
42 // no need to call IS_OBSERVER(), observers never call use/touch functions which means this is never an observer
43 if(this.classname == "trigger_teleport" && (this.spawnflags & TELEPORT_OBSERVERS_ONLY))
44 return false;
45
46 return true;
47}
48
50{
51 entity player = toucher;
52
53 if(!Teleport_Active(this, player))
54 return;
55
56 EXACTTRIGGER_TOUCH(this, player);
57
58#ifdef SVQC
59 if(IS_PLAYER(player))
61#endif
62
63 noref entity e = Simple_TeleportPlayer(this, player);
64
65#ifdef SVQC
66 string s = this.target; this.target = string_null;
67 SUB_UseTargets(this, player, player); // TODO: should we be using toucher for trigger too?
68 if (!this.target) this.target = s;
69
70 SUB_UseTargets(e, player, player);
71#endif
72}
73
74#ifdef SVQC
75void target_teleport_use(entity this, entity actor, entity trigger)
76{
77 entity player = actor;
78
79 if(!Teleport_Active(this, player))
80 return;
81
82 if(IS_PLAYER(player))
84
85 entity e = Simple_TeleportPlayer(this, player);
86
87 string s = this.target; this.target = string_null;
88 SUB_UseTargets(this, player, player); // TODO: should we be using toucher for trigger too?
89 if (!this.target)
90 {
91 this.target = s;
92 }
93
94 if(e != this) // only activate the target teleporter if target is different
95 SUB_UseTargets(e, player, player);
96}
97#endif
98
99#ifdef SVQC
100float trigger_teleport_send(entity this, entity to, float sf)
101{
102 WriteHeader(MSG_ENTITY, ENT_CLIENT_TRIGGER_TELEPORT);
103
105 WriteInt24_t(MSG_ENTITY, this.spawnflags);
108
109 trigger_common_write(this, true);
110
111 return true;
112}
113
115{
116 //trigger_link(this, trigger_teleport_send);
117}
118
119spawnfunc(trigger_teleport)
120{
121 this.angles = '0 0 0';
122
123 this.active = ACTIVE_ACTIVE;
126
127 if(this.noise != "")
128 FOREACH_WORD(this.noise, true, precache_sound(it));
129
130 // this must be called to spawn the teleport waypoints for bots
132
133 if (!this.target || this.target == "")
134 {
135 objerror (this, "Teleporter with no target");
136 return;
137 }
138
139 IL_PUSH(g_teleporters, this);
140}
141
143{
144 // target_teleporter is used in many strange ways
145 // we must attempt to figure out which way it is being used for in this instance
146
147 if(!this.target || this.target == "")
148 {
149 // this target_teleporter has no target
150 // so it must be either a destination for a teleporter or a teleporter itself
151 bool is_teleporter_target = false;
152 // NOTE: target2, target3, target4 unsupported, this may not be necessary as DeFrag maps have no such targets
154 {
155 if(it.classname == "trigger_teleport" || it.classname == "target_teleporter")
156 {
157 is_teleporter_target = true;
158 break; // no need to keep looping once a valid target is found
159 }
160 });
161
162 if(is_teleporter_target)
163 {
164 // there were teleporters found targeting this, so it must be a destination!
165 spawnfunc_info_teleport_destination(this);
166 return;
167 }
168
169 // set this entity up to be a teleporter, since it can be activated as one
170 this.enemy = this;
171 this.mangle = this.angles;
172 this.angles = '0 0 0';
173 }
174
175 // seeing as this entity isn't targeted by a teleporter, it must be a teleporter itself
176
177 this.active = ACTIVE_ACTIVE;
179
180 if(this.noise && this.noise != "")
181 FOREACH_WORD(this.noise, true, precache_sound(it));
182
183 if(this.target && this.target != "") // no need to find a target on this entity, as it does not have one and .enemy is already set as required
185}
186
191#elif defined(CSQC)
192NET_HANDLE(ENT_CLIENT_TRIGGER_TELEPORT, bool isnew)
193{
194 this.classname = "trigger_teleport";
195 if(isnew)
196 IL_PUSH(g_teleporters, this);
197 int mytm = ReadByte();
198 if(mytm)
199 {
200 this.team = mytm - 1;
201 }
202 this.spawnflags = ReadInt24_t();
203 this.active = ReadByte();
204 this.speed = ReadCoord();
205
206 trigger_common_read(this, true);
207
208 this.entremove = trigger_remove_generic;
209 this.solid = SOLID_TRIGGER;
210 //settouch(this, trigger_push_touch);
211 this.move_time = time;
212 defer(this, 0.25, teleport_findtarget);
213
214 return true;
215}
216
217#endif
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
int team
Definition main.qh:188
int spawnflags
Definition ammo.qh:15
#define IS_DEAD(s)
Definition player.qh:244
#define IS_PLAYER(s)
Definition player.qh:242
const int INITPRIO_FINDTARGET
Definition constants.qh:96
string classname
const float SOLID_TRIGGER
float time
#define use
void defer(entity this, float fdelay, void(entity) func)
Execute func() after time + fdelay.
Definition defer.qh:29
const int INVERT_TEAMS
Definition defs.qh:10
int active
Definition defs.qh:34
const int ACTIVE_ACTIVE
Definition defs.qh:37
const int SF_TRIGGER_UPDATE
Definition defs.qh:23
float speed
Definition dynlight.qc:9
ent angles
Definition ent_cs.qc:121
solid
Definition ent_cs.qc:165
ERASEABLE entity IL_PUSH(IntrusiveList this, entity it)
Push to tail.
#define FOREACH_WORD(words, cond, body)
Definition iter.qh:33
#define FOREACH_ENTITY_STRING(fld, match, body)
Definition iter.qh:184
void SUB_UseTargets(entity this, entity actor, entity trigger)
Definition triggers.qc:344
int SendFlags
Definition net.qh:159
#define NET_HANDLE(id, param)
Definition net.qh:15
const int MSG_ENTITY
Definition net.qh:156
int ReadInt24_t()
Definition net.qh:338
#define WriteHeader(to, id)
Definition net.qh:265
#define REGISTER_NET_LINKED(id)
Definition net.qh:91
int ReadByte()
#define EXACTTRIGGER_TOUCH(e, t)
Definition common.qh:115
#define EXACTTRIGGER_INIT
Definition common.qh:116
string precache_sound(string sample)
void WriteCoord(float data, float dest, float desto)
void WriteByte(float data, float dest, float desto)
float move_time
Definition movetypes.qh:77
string string_null
Definition nil.qh:9
#define objerror
Definition pre.qh:8
entity entity toucher
Definition self.qh:72
void RemoveGrapplingHooks(entity pl)
Definition hook.qc:30
#define spawnfunc(id)
Definition spawnfunc.qh:96
string noise
Definition subs.qh:83
vector mangle
Definition subs.qh:51
entity enemy
Definition sv_ctf.qh:153
bool teamplay
Definition teams.qh:59
#define DIFF_TEAM(a, b)
Definition teams.qh:242
bool Teleport_Active(entity this, entity player)
Definition teleport.qc:15
void trigger_teleport_use(entity this, entity actor, entity trigger)
Definition teleport.qc:5
void target_teleporter_checktarget(entity this)
Definition teleport.qc:142
void Teleport_Touch(entity this, entity toucher)
Definition teleport.qc:49
void trigger_teleport_link(entity this)
Definition teleport.qc:114
float trigger_teleport_send(entity this, entity to, float sf)
Definition teleport.qc:100
void target_teleport_use(entity this, entity actor, entity trigger)
Definition teleport.qc:75
#define TELEPORT_OBSERVERS_ONLY
Definition teleport.qh:7
void teleport_findtarget(entity this)
entity Simple_TeleportPlayer(entity teleporter, entity player)
void trigger_teleport_use(entity this, entity actor, entity trigger)
Definition teleport.qc:5
IntrusiveList g_teleporters
void trigger_common_write(entity this, bool withtarget)
Definition triggers.qc:110
void trigger_remove_generic(entity this)
string targetname
Definition triggers.qh:56
void trigger_common_read(entity this, bool withtarget)
string target
Definition triggers.qh:55
#define IS_TURRET(v)
Definition utils.qh:25
void InitializeEntity(entity e, void(entity this) func, int order)
Definition world.qc:2230