More gracefully handle travelling to a map without matching player starts

- First, don't crash when travelling to a map in a hub that doesn't have
  any player starts that match the position given to Teleport_NewMap (or
  equivalent).
- Seconed, move the player to the location they were at when the left the
  level. At least that way, they shouldn't be in random geometry or off
  the map entirely.
This commit is contained in:
Randy Heit 2016-03-08 21:51:12 -06:00
parent 174e00afe7
commit 76489e7638

View file

@ -1221,32 +1221,48 @@ void G_FinishTravel ()
} }
} }
if (start == NULL) start = G_PickPlayerStart(pnum, 0); if (start == NULL)
{
start = G_PickPlayerStart(pnum, 0);
if (start == NULL)
{
Printf(TEXTCOLOR_RED "No player %d start to travel to!\n", pnum + 1);
// Move to the coordinates this player had when they left the level.
pawn->SetXYZ(pawndup->X(), pawndup->Y(), pawndup->Z());
}
}
oldpawn = pawndup; oldpawn = pawndup;
// The player being spawned here is a short lived dummy and // The player being spawned here is a short lived dummy and
// must not start any ENTER script or big problems will happen. // must not start any ENTER script or big problems will happen.
pawndup = P_SpawnPlayer(start, pnum, SPF_TEMPPLAYER); pawndup = P_SpawnPlayer(start, pnum, SPF_TEMPPLAYER);
if (!(changeflags & CHANGELEVEL_KEEPFACING)) if (pawndup != NULL)
{ {
pawn->angle = pawndup->angle; if (!(changeflags & CHANGELEVEL_KEEPFACING))
pawn->pitch = pawndup->pitch; {
pawn->angle = pawndup->angle;
pawn->pitch = pawndup->pitch;
}
pawn->SetXYZ(pawndup->X(), pawndup->Y(), pawndup->Z());
pawn->velx = pawndup->velx;
pawn->vely = pawndup->vely;
pawn->velz = pawndup->velz;
pawn->Sector = pawndup->Sector;
pawn->floorz = pawndup->floorz;
pawn->ceilingz = pawndup->ceilingz;
pawn->dropoffz = pawndup->dropoffz;
pawn->floorsector = pawndup->floorsector;
pawn->floorpic = pawndup->floorpic;
pawn->floorterrain = pawndup->floorterrain;
pawn->ceilingsector = pawndup->ceilingsector;
pawn->ceilingpic = pawndup->ceilingpic;
pawn->floorclip = pawndup->floorclip;
pawn->waterlevel = pawndup->waterlevel;
}
else
{
P_FindFloorCeiling(pawn);
} }
pawn->SetXYZ(pawndup->X(), pawndup->Y(), pawndup->Z());
pawn->velx = pawndup->velx;
pawn->vely = pawndup->vely;
pawn->velz = pawndup->velz;
pawn->Sector = pawndup->Sector;
pawn->floorz = pawndup->floorz;
pawn->ceilingz = pawndup->ceilingz;
pawn->dropoffz = pawndup->dropoffz;
pawn->floorsector = pawndup->floorsector;
pawn->floorpic = pawndup->floorpic;
pawn->floorterrain = pawndup->floorterrain;
pawn->ceilingsector = pawndup->ceilingsector;
pawn->ceilingpic = pawndup->ceilingpic;
pawn->floorclip = pawndup->floorclip;
pawn->waterlevel = pawndup->waterlevel;
pawn->target = NULL; pawn->target = NULL;
pawn->lastenemy = NULL; pawn->lastenemy = NULL;
pawn->player->mo = pawn; pawn->player->mo = pawn;
@ -1255,7 +1271,10 @@ void G_FinishTravel ()
pawn->flags2 &= ~MF2_BLASTED; pawn->flags2 &= ~MF2_BLASTED;
DObject::StaticPointerSubstitution (oldpawn, pawn); DObject::StaticPointerSubstitution (oldpawn, pawn);
oldpawn->Destroy(); oldpawn->Destroy();
pawndup->Destroy (); if (pawndup != NULL)
{
pawndup->Destroy();
}
pawn->LinkToWorld (); pawn->LinkToWorld ();
pawn->ClearInterpolation(); pawn->ClearInterpolation();
pawn->AddToHash (); pawn->AddToHash ();