void WarpZone_TeleportPlayer(entity teleporter, entity player, vector to, vector to_angles, vector to_velocity)
{
+#ifdef SVQC
player.lastteleport_origin = player.origin;
player.lastteleporttime = time;
+#endif
setorigin(player, to); // NOTE: this also aborts the move, when this is called by touch
#ifdef SVQC
player.oldorigin = to; // for DP's unsticking
{
// make sure jumppad is really hit, don't rely on distance based checks
// as they may report a touch even if it didn't really happen
- if(this.lastteleporttime > 0
- && time - this.lastteleporttime < ((this.goalcurrent.wpflags & WAYPOINTFLAG_PERSONAL) ? 2 : 0.15))
+ if(this.lastteleporttime > 0 && TELEPORT_USED(this, this.goalcurrent))
{
- if (!boxesoverlap(this.goalcurrent.absmin, this.goalcurrent.absmax,
- this.lastteleport_origin + STAT(PL_MIN, this), this.lastteleport_origin + STAT(PL_MAX, this)))
- {
- return removed_goals;
- }
-
if(this.aistatus & AI_STATUS_WAYPOINT_PERSONAL_GOING)
if(this.goalcurrent.wpflags & WAYPOINTFLAG_PERSONAL && this.goalcurrent.owner==this)
{
else
return removed_goals;
}
+ else if (this.lastteleporttime > 0)
+ {
+ // sometimes bot is pushed so hard (by a jumppad or a shot) that ends up touching the next
+ // teleport / jumppad / warpzone present in its path skipping check of one or more goals
+ // if so immediately fix bot path by removing skipped goals
+ entity tele_ent = NULL;
+ if (this.goalstack01 && (this.goalstack01.wpflags & WAYPOINTFLAG_TELEPORT))
+ tele_ent = this.goalstack01;
+ else if (this.goalstack02 && (this.goalstack02.wpflags & WAYPOINTFLAG_TELEPORT))
+ tele_ent = this.goalstack02;
+ else if (this.goalstack03 && (this.goalstack03.wpflags & WAYPOINTFLAG_TELEPORT))
+ tele_ent = this.goalstack03;
+ if (tele_ent && TELEPORT_USED(this, tele_ent))
+ {
+ if (this.aistatus & AI_STATUS_WAYPOINT_PERSONAL_GOING)
+ if (tele_ent.wpflags & WAYPOINTFLAG_PERSONAL && tele_ent.owner == this)
+ {
+ this.aistatus &= ~AI_STATUS_WAYPOINT_PERSONAL_GOING;
+ this.aistatus |= AI_STATUS_WAYPOINT_PERSONAL_REACHED;
+ }
+ while (this.goalcurrent != tele_ent)
+ {
+ navigation_poproute(this);
+ ++removed_goals;
+ }
+ navigation_poproute(this);
+ this.lastteleporttime = 0;
+ ++removed_goals;
+ return removed_goals;
+ }
+ }
// Loose goal touching check when running
if(this.aistatus & AI_STATUS_RUNNING)
#define navigation_item_addlink(from_wp, to_item) \
waypoint_addlink_customcost(to_item, from_wp, waypoint_getlinkcost(from_wp, to_item))
+#define TELEPORT_USED(pl, tele_wp) \
+ (time - pl.lastteleporttime < ((tele_wp.wpflags & WAYPOINTFLAG_PERSONAL) ? 2 : 0.15) \
+ && boxesoverlap(tele_wp.absmin, tele_wp.absmax, pl.lastteleport_origin + STAT(PL_MIN, pl), pl.lastteleport_origin + STAT(PL_MAX, pl)))
+
vector tracewalk_dest;
float tracewalk_dest_height;