// for all entities
.vector warpzone_oldorigin, warpzone_oldvelocity, warpzone_oldangles;
.float warpzone_teleport_time;
+.float warpzone_teleport_finishtime;
.entity warpzone_teleport_zone;
void WarpZone_StoreProjectileData(entity e)
WarpZone_TeleportPlayer(wz, player, o1 - player.view_ofs, a1, v1); \
WarpZone_StoreProjectileData(player); \
player.warpzone_teleport_time = time; \
+ player.warpzone_teleport_finishtime = time; \
player.warpzone_teleport_zone = wz; \
} \
while(0)
float WarpZone_Teleport(entity wz, entity player, float f0, float f1)
{
- vector o0, a0, v0, o1, a1, v1;
+ vector o0, a0, v0, o1, a1, v1, o10;
o0 = player.origin + player.view_ofs;
v0 = player.velocity;
a0 = player.angles;
- o1 = WarpZone_TransformOrigin(wz, o0);
+ o10 = o1 = WarpZone_TransformOrigin(wz, o0);
v1 = WarpZone_TransformVelocity(wz, v0);
if(clienttype(player) != CLIENTTYPE_NOTACLIENT)
a1 = WarpZone_TransformVAngles(wz, player.v_angle);
}
o1 = trace_endpos + player.view_ofs;
- float d, dv;
+ float d, dv, md;
+ md = max(vlen(player.mins), vlen(player.maxs));
d = WarpZone_TargetPlaneDist(wz, o1);
dv = WarpZone_TargetPlaneDist(wz, v1);
if(d < 0)
WARPZONE_TELEPORT_DOTELEPORT();
+ // prevent further teleports back
+ float dt = (o1 - o10) * v1 * (1 / (v1 * v1));
+ if(dt < sys_frametime)
+ player.warpzone_teleport_finishtime += sys_frametime - dt;
+
#ifndef WARPZONE_USE_FIXANGLE
if(player.classname == "player")
{
if(other.classname == "trigger_warpzone")
return;
- if(other.warpzone_teleport_time == time) // already teleported this frame
+ if(time <= other.warpzone_teleport_finishtime) // already teleported this frame
return;
// FIXME needs a better check to know what is safe to teleport and what not
if(WarpZone_PlaneDist(self, other.origin + other.view_ofs) >= 0) // wrong side of the trigger_warpzone (don't teleport yet)
return;
- if(WarpZone_Teleport(self, other, -1, 0))
+ if(WarpZone_Teleport(self, other, -1000, 0))
{
string save1, save2;
activator = other;
v0 = player.velocity;
// if we teleported shortly before, abort
- if(time < player.warpzone_teleport_time + 0.1)
+ if(time <= player.warpzone_teleport_finishtime + 0.1)
return 0;
// if player hit a warpzone, abort
return TRUE;
// no further impacts if we teleported this frame!
- if(self.warpzone_teleport_time == time)
+ if(time == self.warpzone_teleport_time)
return TRUE;
// this SEEMS to not happen at the moment, but if it did, it would be more reliable
if(WarpZone_Projectile_Touch_ImpactFilter_Callback())
return TRUE;
- if(self.warpzone_teleport_time == time)
- {
- // sequence: hit warpzone, get teleported, hit wall
- // print("2 hits 1 frame\n");
- setorigin(self, self.warpzone_oldorigin);
- self.velocity = self.warpzone_oldvelocity;
- self.angles = self.warpzone_oldangles;
- return TRUE;
- }
return FALSE;
}