diff --git a/src/b_game.cpp b/src/b_game.cpp index 5f852d043..44545f73d 100644 --- a/src/b_game.cpp +++ b/src/b_game.cpp @@ -369,14 +369,6 @@ bool FCajunMaster::DoAddBot (BYTE *info, botskill_t skill) D_ReadUserInfoStrings (bnum, &info, false); - if (!deathmatch && playerstarts[bnum].type == 0) - { - Printf ("%s tried to join, but there was no player %d start\n", - players[bnum].userinfo.GetName(), bnum+1); - ClearPlayer (bnum, false); // Make the bot inactive again - return false; - } - multiplayer = true; //Prevents cheating and so on; emulates real netgame (almost). players[bnum].Bot = new DBot; players[bnum].Bot->player = &players[bnum]; diff --git a/src/g_game.cpp b/src/g_game.cpp index c97ea2198..7ca8b2b35 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -1422,6 +1422,8 @@ bool G_CheckSpot (int playernum, FPlayerStart *mthing) fixed_t z, oldz; int i; + if (mthing->type == 0) return false; + x = mthing->x; y = mthing->y; z = mthing->z; @@ -1573,6 +1575,11 @@ void G_DeathMatchSpawnPlayer (int playernum) // FPlayerStart *G_PickPlayerStart(int playernum, int flags) { + if (AllPlayerStarts.Size() == 0) // No starts to pick + { + return NULL; + } + if ((level.flags2 & LEVEL2_RANDOMPLAYERSTARTS) || (flags & PPS_FORCERANDOM) || playerstarts[playernum].type == 0) { diff --git a/src/g_level.cpp b/src/g_level.cpp index 43a07a475..d799cc893 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -1195,74 +1195,83 @@ void G_FinishTravel () TThinkerIterator it (STAT_TRAVELLING); APlayerPawn *pawn, *pawndup, *oldpawn, *next; AInventory *inv; + FPlayerStart *start; + int pnum; next = it.Next (); while ( (pawn = next) != NULL) { next = it.Next (); + pnum = (pawn->player - players); pawn->ChangeStatNum (STAT_PLAYER); pawndup = pawn->player->mo; + start = NULL; assert (pawn != pawndup); if (pawndup == NULL) { // Oh no! there was no start for this player! - pawn->flags |= MF_NOSECTOR|MF_NOBLOCKMAP; - pawn->Destroy (); + start = G_PickPlayerStart(pnum, PPS_FORCERANDOM); + if (start != NULL) pawndup = P_SpawnPlayer(start, pnum, (level.flags2 & LEVEL2_PRERAISEWEAPON) ? SPF_WEAPONFULLYUP : 0); + if (pawndup == NULL) + { + pawn->flags |= MF_NOSECTOR | MF_NOBLOCKMAP; + pawn->Destroy(); + continue; + } } - else + + if (start == NULL) start = G_PickPlayerStart(pnum, 0); + oldpawn = pawndup; + + // The player being spawned here is a short lived dummy and + // must not start any ENTER script or big problems will happen. + pawndup = P_SpawnPlayer(start, pnum, SPF_TEMPPLAYER); + if (!(changeflags & CHANGELEVEL_KEEPFACING)) { - oldpawn = pawndup; + 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; + pawn->target = NULL; + pawn->lastenemy = NULL; + pawn->player->mo = pawn; + pawn->player->camera = pawn; + pawn->player->viewheight = pawn->ViewHeight; + pawn->flags2 &= ~MF2_BLASTED; + DObject::StaticPointerSubstitution (oldpawn, pawn); + oldpawn->Destroy(); + pawndup->Destroy (); + pawn->LinkToWorld (); + pawn->AddToHash (); + pawn->SetState(pawn->SpawnState); + pawn->player->SendPitchLimits(); - // The player being spawned here is a short lived dummy and - // must not start any ENTER script or big problems will happen. - pawndup = P_SpawnPlayer (&playerstarts[pawn->player - players], int(pawn->player - players), SPF_TEMPPLAYER); - if (!(changeflags & CHANGELEVEL_KEEPFACING)) - { - 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; - pawn->target = NULL; - pawn->lastenemy = NULL; - pawn->player->mo = pawn; - pawn->player->camera = pawn; - pawn->player->viewheight = pawn->ViewHeight; - pawn->flags2 &= ~MF2_BLASTED; - DObject::StaticPointerSubstitution (oldpawn, pawn); - oldpawn->Destroy(); - pawndup->Destroy (); - pawn->LinkToWorld (); - pawn->AddToHash (); - pawn->SetState(pawn->SpawnState); - pawn->player->SendPitchLimits(); - - for (inv = pawn->Inventory; inv != NULL; inv = inv->Inventory) - { - inv->ChangeStatNum (STAT_INVENTORY); - inv->LinkToWorld (); - inv->Travelled (); - } - if (ib_compatflags & BCOMPATF_RESETPLAYERSPEED) - { - pawn->Speed = pawn->GetDefault()->Speed; - } - if (level.FromSnapshot) - { - FBehavior::StaticStartTypedScripts (SCRIPT_Return, pawn, true); - } + for (inv = pawn->Inventory; inv != NULL; inv = inv->Inventory) + { + inv->ChangeStatNum (STAT_INVENTORY); + inv->LinkToWorld (); + inv->Travelled (); + } + if (ib_compatflags & BCOMPATF_RESETPLAYERSPEED) + { + pawn->Speed = pawn->GetDefault()->Speed; + } + if (level.FromSnapshot) + { + FBehavior::StaticStartTypedScripts (SCRIPT_Return, pawn, true); } }