2 REGISTER_NET_LINKED(ENT_CLIENT_TRIGGER_TELEPORT)
5 void trigger_teleport_use(entity this, entity actor, entity trigger)
8 this.team = actor.team;
10 this.SendFlags |= SF_TRIGGER_UPDATE;
15 bool Teleport_Active(entity this, entity player)
17 if (this.active != ACTIVE_ACTIVE)
21 if (!player.teleportable)
25 if(!player.vehicle.teleportable)
31 if(!IS_PLAYER(player))
39 if(((this.spawnflags & INVERT_TEAMS) == 0) == (DIFF_TEAM(this, player)))
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)
49 void Teleport_Touch(entity this, entity toucher)
51 entity player = toucher;
53 if(!Teleport_Active(this, player))
56 EXACTTRIGGER_TOUCH(this, player);
60 RemoveGrapplingHooks(player);
64 e = Simple_TeleportPlayer(this, player);
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;
71 SUB_UseTargets(e, player, player);
76 void target_teleport_use(entity this, entity actor, entity trigger)
78 entity player = actor;
80 if(!Teleport_Active(this, player))
84 RemoveGrapplingHooks(player);
86 entity e = Simple_TeleportPlayer(this, player);
88 string s = this.target; this.target = string_null;
89 SUB_UseTargets(this, player, player); // TODO: should we be using toucher for trigger too?
95 if(e != this) // only activate the target teleporter if target is different
96 SUB_UseTargets(e, player, player);
101 float trigger_teleport_send(entity this, entity to, float sf)
103 WriteHeader(MSG_ENTITY, ENT_CLIENT_TRIGGER_TELEPORT);
105 WriteByte(MSG_ENTITY, this.team);
106 WriteInt24_t(MSG_ENTITY, this.spawnflags);
107 WriteByte(MSG_ENTITY, this.active);
108 WriteCoord(MSG_ENTITY, this.speed);
110 trigger_common_write(this, true);
115 void trigger_teleport_link(entity this)
117 //trigger_link(this, trigger_teleport_send);
120 spawnfunc(trigger_teleport)
122 this.angles = '0 0 0';
124 this.active = ACTIVE_ACTIVE;
125 //trigger_init(this); // only for predicted triggers?
127 this.use = trigger_teleport_use;
130 FOREACH_WORD(this.noise, true, precache_sound(it));
132 // this must be called to spawn the teleport waypoints for bots
133 InitializeEntity(this, teleport_findtarget, INITPRIO_FINDTARGET);
135 if (!this.target || this.target == "")
137 objerror (this, "Teleporter with no target");
141 IL_PUSH(g_teleporters, this);
144 void target_teleporter_checktarget(entity this)
146 // target_teleporter is used in many strange ways
147 // we must attempt to figure out which way it is being used for in this instance
149 if(!this.target || this.target == "")
151 // this target_teleporter has no target
152 // so it must be either a destination for a teleporter or a teleporter itself
153 bool is_teleporter_target = false;
154 // NOTE: target2, target3, target4 unsupported, this may not be necessary as DeFrag maps have no such targets
155 FOREACH_ENTITY_STRING(target, this.targetname,
157 if(it.classname == "trigger_teleport" || it.classname == "target_teleporter")
159 is_teleporter_target = true;
160 break; // no need to keep looping once a valid target is found
164 if(is_teleporter_target)
166 // there were teleporters found targeting this, so it must be a destination!
167 spawnfunc_info_teleport_destination(this);
171 // set this entity up to be a teleporter, since it can be activated as one
173 this.mangle = this.angles;
174 this.angles = '0 0 0';
177 // seeing as this entity isn't targeted by a teleporter, it must be a teleporter itself
179 this.active = ACTIVE_ACTIVE;
180 this.use = target_teleport_use;
182 if(this.noise && this.noise != "")
183 FOREACH_WORD(this.noise, true, precache_sound(it));
185 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 teleport_findtarget(this);
189 spawnfunc(target_teleporter)
191 InitializeEntity(this, target_teleporter_checktarget, INITPRIO_FINDTARGET);
194 NET_HANDLE(ENT_CLIENT_TRIGGER_TELEPORT, bool isnew)
196 this.classname = "trigger_teleport";
198 IL_PUSH(g_teleporters, this);
199 int mytm = ReadByte();
202 this.team = mytm - 1;
204 this.spawnflags = ReadInt24_t();
205 this.active = ReadByte();
206 this.speed = ReadCoord();
208 trigger_common_read(this, true);
210 this.entremove = trigger_remove_generic;
211 this.solid = SOLID_TRIGGER;
212 //settouch(this, trigger_push_touch);
213 this.move_time = time;
214 defer(this, 0.25, teleport_findtarget);