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 entity e;
64 e = Simple_TeleportPlayer(this, player);
65
66#ifdef SVQC
67 string s = this.target; this.target = string_null;
68 SUB_UseTargets(this, player, player); // TODO: should we be using toucher for trigger too?
69 if (!this.target) this.target = s;
70
71 SUB_UseTargets(e, player, player);
72#endif
73}
74
75#ifdef SVQC
76void target_teleport_use(entity this, entity actor, entity trigger)
77{
78 entity player = actor;
79
80 if(!Teleport_Active(this, player))
81 return;
82
83 if(IS_PLAYER(player))
85
86 entity e = Simple_TeleportPlayer(this, player);
87
88 string s = this.target; this.target = string_null;
89 SUB_UseTargets(this, player, player); // TODO: should we be using toucher for trigger too?
90 if (!this.target)
91 {
92 this.target = s;
93 }
94
95 if(e != this) // only activate the target teleporter if target is different
96 SUB_UseTargets(e, player, player);
97}
98#endif
99
100#ifdef SVQC
101float trigger_teleport_send(entity this, entity to, float sf)
102{
103 WriteHeader(MSG_ENTITY, ENT_CLIENT_TRIGGER_TELEPORT);
104
106 WriteInt24_t(MSG_ENTITY, this.spawnflags);
109
110 trigger_common_write(this, true);
111
112 return true;
113}
114
116{
117 //trigger_link(this, trigger_teleport_send);
118}
119
120spawnfunc(trigger_teleport)
121{
122 this.angles = '0 0 0';
123
124 this.active = ACTIVE_ACTIVE;
127
128 if(this.noise != "")
129 FOREACH_WORD(this.noise, true, precache_sound(it));
130
131 // this must be called to spawn the teleport waypoints for bots
133
134 if (!this.target || this.target == "")
135 {
136 objerror (this, "Teleporter with no target");
137 return;
138 }
139
140 IL_PUSH(g_teleporters, this);
141}
142
144{
145 // target_teleporter is used in many strange ways
146 // we must attempt to figure out which way it is being used for in this instance
147
148 if(!this.target || this.target == "")
149 {
150 // this target_teleporter has no target
151 // so it must be either a destination for a teleporter or a teleporter itself
152 bool is_teleporter_target = false;
153 // NOTE: target2, target3, target4 unsupported, this may not be necessary as DeFrag maps have no such targets
155 {
156 if(it.classname == "trigger_teleport" || it.classname == "target_teleporter")
157 {
158 is_teleporter_target = true;
159 break; // no need to keep looping once a valid target is found
160 }
161 });
162
163 if(is_teleporter_target)
164 {
165 // there were teleporters found targeting this, so it must be a destination!
166 spawnfunc_info_teleport_destination(this);
167 return;
168 }
169
170 // set this entity up to be a teleporter, since it can be activated as one
171 this.enemy = this;
172 this.mangle = this.angles;
173 this.angles = '0 0 0';
174 }
175
176 // seeing as this entity isn't targeted by a teleporter, it must be a teleporter itself
177
178 this.active = ACTIVE_ACTIVE;
180
181 if(this.noise && this.noise != "")
182 FOREACH_WORD(this.noise, true, precache_sound(it));
183
184 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
186}
187
192#elif defined(CSQC)
193NET_HANDLE(ENT_CLIENT_TRIGGER_TELEPORT, bool isnew)
194{
195 this.classname = "trigger_teleport";
196 if(isnew)
197 IL_PUSH(g_teleporters, this);
198 int mytm = ReadByte();
199 if(mytm)
200 {
201 this.team = mytm - 1;
202 }
203 this.spawnflags = ReadInt24_t();
204 this.active = ReadByte();
205 this.speed = ReadCoord();
206
207 trigger_common_read(this, true);
208
209 this.entremove = trigger_remove_generic;
210 this.solid = SOLID_TRIGGER;
211 //settouch(this, trigger_push_touch);
212 this.move_time = time;
213 defer(this, 0.25, teleport_findtarget);
214
215 return true;
216}
217
218#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:245
#define IS_PLAYER(s)
Definition player.qh:243
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:118
#define NET_HANDLE(id, param)
Definition net.qh:15
const int MSG_ENTITY
Definition net.qh:115
int ReadInt24_t()
Definition net.qh:355
#define WriteHeader(to, id)
Definition net.qh:221
#define REGISTER_NET_LINKED(id)
Definition net.qh:55
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:143
void Teleport_Touch(entity this, entity toucher)
Definition teleport.qc:49
void trigger_teleport_link(entity this)
Definition teleport.qc:115
float trigger_teleport_send(entity this, entity to, float sf)
Definition teleport.qc:101
void target_teleport_use(entity this, entity actor, entity trigger)
Definition teleport.qc:76
#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:23
void InitializeEntity(entity e, void(entity this) func, int order)
Definition world.qc:2209