diff --git a/src/d_player.h b/src/d_player.h index 4da0e9d10..f50db97b1 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -434,6 +434,7 @@ public: TObjPtr PremorphWeapon; // ready weapon before morphing int chickenPeck; // chicken peck countdown int jumpTics; // delay the next jump for a moment + bool onground; // Identifies if this player is on the ground or other object int respawn_time; // [RH] delay respawning until this tic TObjPtr camera; // [RH] Whose eyes this player sees through diff --git a/src/g_level.cpp b/src/g_level.cpp index 0b07ae2b5..65bde08d8 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -387,7 +387,7 @@ void G_InitNew (const char *mapname, bool bTitleLevel) StatusBar->NewGame (); setsizeneeded = true; - if (gameinfo.gametype == GAME_Strife || (SBarInfoScript != NULL && SBarInfoScript[SCRIPT_CUSTOM]->GetGameType() == GAME_Strife)) + if (gameinfo.gametype == GAME_Strife || (SBarInfoScript[SCRIPT_CUSTOM] != NULL && SBarInfoScript[SCRIPT_CUSTOM]->GetGameType() == GAME_Strife)) { // Set the initial quest log text for Strife. for (i = 0; i < MAXPLAYERS; ++i) @@ -1084,6 +1084,7 @@ void G_StartTravel () { AActor *pawn = players[i].mo; AInventory *inv; + players[i].camera = NULL; // Only living players travel. Dead ones get a new body on the new level. if (players[i].health > 0) diff --git a/src/p_glnodes.cpp b/src/p_glnodes.cpp index b07d50aed..a8fa04c34 100644 --- a/src/p_glnodes.cpp +++ b/src/p_glnodes.cpp @@ -724,9 +724,10 @@ static bool DoLoadGLNodes(FileReader ** lumps) static bool MatchHeader(const char * label, const char * hdata) { - if (!memcmp(hdata, "LEVEL=", 6) == 0) + if (memcmp(hdata, "LEVEL=", 6) == 0) { size_t labellen = strlen(label); + labellen = MIN(size_t(8), labellen); if (strnicmp(hdata+6, label, labellen)==0 && (hdata[6+labellen]==0xa || hdata[6+labellen]==0xd)) @@ -771,7 +772,7 @@ static int FindGLNodesInWAD(int labellump) if (Wads.GetLumpFile(lump)==wadfile) { FMemLump mem = Wads.ReadLump(lump); - if (MatchHeader(Wads.GetLumpFullName(labellump), (const char *)mem.GetMem())) return true; + if (MatchHeader(Wads.GetLumpFullName(labellump), (const char *)mem.GetMem())) return lump; } } } @@ -781,7 +782,7 @@ static int FindGLNodesInWAD(int labellump) //=========================================================================== // -// FindGLNodesInWAD +// FindGLNodesInFile // // Looks for GL nodes in the same WAD as the level itself // Function returns the lump number within the file. Returns -1 if the input @@ -929,13 +930,13 @@ bool P_LoadGLNodes(MapData * map) result=true; for(unsigned i=0; i<4;i++) { - if (strnicmp(f_gwa->GetLump(i)->Name, check[i], 8)) + if (strnicmp(f_gwa->GetLump(i+1)->Name, check[i], 8)) { result=false; break; } else - gwalumps[i] = f_gwa->GetLump(i)->NewReader(); + gwalumps[i] = f_gwa->GetLump(i+1)->NewReader(); } if (result) result = DoLoadGLNodes(gwalumps); } diff --git a/src/p_map.cpp b/src/p_map.cpp index d900c2a46..45eb0d95c 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -914,34 +914,34 @@ bool PIT_CheckThing (AActor *thing, FCheckPosition &tm) } } - // touchy object is alive, toucher is solid - if (thing->flags6 & MF6_TOUCHY && tm.thing->flags & MF_SOLID && thing->health > 0 && - // Thing is an armed mine or a sentient thing - (thing->flags6 & MF6_ARMED || thing->IsSentient()) && - // either different classes or players - (thing->player || thing->GetClass() != tm.thing->GetClass()) && - // or different species if DONTHARMSPECIES - (!(thing->flags6 & MF6_DONTHARMSPECIES) || thing->GetSpecies() != tm.thing->GetSpecies()) && - // touches vertically - thing->z + thing->height >= tm.thing->z && tm.thing->z + tm.thing->height >= thing->z && - // prevents lost souls from exploding when fired by pain elementals - (thing->master != tm.thing && tm.thing->master != thing)) - // Difference with MBF: MBF hardcodes the LS/PE check and lets actors of the same species - // but different classes trigger the touchiness, but that seems less straightforwards. + if (tm.thing->player == NULL || !(tm.thing->player->cheats & CF_PREDICTING)) { - thing->flags6 &= ~MF6_ARMED; // Disarm - P_DamageMobj (thing, NULL, NULL, thing->health, NAME_None, DMG_FORCED); // kill object - return true; - } + // touchy object is alive, toucher is solid + if (thing->flags6 & MF6_TOUCHY && tm.thing->flags & MF_SOLID && thing->health > 0 && + // Thing is an armed mine or a sentient thing + (thing->flags6 & MF6_ARMED || thing->IsSentient()) && + // either different classes or players + (thing->player || thing->GetClass() != tm.thing->GetClass()) && + // or different species if DONTHARMSPECIES + (!(thing->flags6 & MF6_DONTHARMSPECIES) || thing->GetSpecies() != tm.thing->GetSpecies()) && + // touches vertically + thing->z + thing->height >= tm.thing->z && tm.thing->z + tm.thing->height >= thing->z && + // prevents lost souls from exploding when fired by pain elementals + (thing->master != tm.thing && tm.thing->master != thing)) + // Difference with MBF: MBF hardcodes the LS/PE check and lets actors of the same species + // but different classes trigger the touchiness, but that seems less straightforwards. + { + thing->flags6 &= ~MF6_ARMED; // Disarm + P_DamageMobj(thing, NULL, NULL, thing->health, NAME_None, DMG_FORCED); // kill object + return true; + } - // Check for MF6_BUMPSPECIAL - // By default, only players can activate things by bumping into them - if ((thing->flags6 & MF6_BUMPSPECIAL) && ((tm.thing->player != NULL) - || ((thing->activationtype & THINGSPEC_MonsterTrigger) && (tm.thing->flags3 & MF3_ISMONSTER)) - || ((thing->activationtype & THINGSPEC_MissileTrigger) && (tm.thing->flags & MF_MISSILE)) - ) && (level.maptime > thing->lastbump)) // Leave the bumper enough time to go away - { - if (tm.thing->player == NULL || !(tm.thing->player->cheats & CF_PREDICTING)) + // Check for MF6_BUMPSPECIAL + // By default, only players can activate things by bumping into them + if ((thing->flags6 & MF6_BUMPSPECIAL) && ((tm.thing->player != NULL) + || ((thing->activationtype & THINGSPEC_MonsterTrigger) && (tm.thing->flags3 & MF3_ISMONSTER)) + || ((thing->activationtype & THINGSPEC_MissileTrigger) && (tm.thing->flags & MF_MISSILE)) + ) && (level.maptime > thing->lastbump)) // Leave the bumper enough time to go away { if (P_ActivateThingSpecial(thing, tm.thing)) thing->lastbump = level.maptime + TICRATE; @@ -955,6 +955,17 @@ bool PIT_CheckThing (AActor *thing, FCheckPosition &tm) tm.thing->BlockingMobj = NULL; return res; } + + // [ED850] Player Prediction ends here. There is nothing else they could/should do. + if (tm.thing->player != NULL && (tm.thing->player->cheats & CF_PREDICTING)) + { + solid = (thing->flags & MF_SOLID) && + !(thing->flags & MF_NOCLIP) && + ((tm.thing->flags & MF_SOLID) || (tm.thing->flags6 & MF6_BLOCKEDBYSOLIDACTORS)); + + return !solid || unblocking; + } + // Check for blasted thing running into another if ((tm.thing->flags2 & MF2_BLASTED) && (thing->flags & MF_SHOOTABLE)) { @@ -1203,8 +1214,7 @@ bool PIT_CheckThing (AActor *thing, FCheckPosition &tm) } return false; // don't traverse any more } - if (thing->flags2 & MF2_PUSHABLE && !(tm.thing->flags2 & MF2_CANNOTPUSH) && - (tm.thing->player == NULL || !(tm.thing->player->cheats & CF_PREDICTING))) + if (thing->flags2 & MF2_PUSHABLE && !(tm.thing->flags2 & MF2_CANNOTPUSH)) { // Push thing if (thing->lastpush != tm.PushTime) { diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 7dc8a3f46..168d686fe 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -2726,16 +2726,15 @@ int P_FindUniqueTID(int start_tid, int limit) if (start_tid != 0) { // Do a linear search. - int end_tid = start_tid; - if (start_tid > 0 && limit > INT_MAX - start_tid + 1) - { // If 'limit+start_tid-1' overflows, clamp 'end_tid' to INT_MAX - end_tid = INT_MAX; + if (start_tid > INT_MAX-limit+1) + { // If 'limit+start_tid-1' overflows, clamp 'limit' to INT_MAX + limit = INT_MAX; } else { - end_tid += limit-1; + limit += start_tid-1; } - for (tid = start_tid; tid <= end_tid; ++tid) + for (tid = start_tid; tid <= limit; ++tid) { if (tid != 0 && !P_IsTIDUsed(tid)) { diff --git a/src/p_user.cpp b/src/p_user.cpp index e1b0210ef..90d0dd6cf 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -210,8 +210,6 @@ CCMD (playerclasses) // 16 pixels of bob #define MAXBOB 0x100000 -bool onground; - FArchive &operator<< (FArchive &arc, player_t *&p) { return arc.SerializePointer (players, (BYTE **)&p, sizeof(*players)); @@ -268,6 +266,7 @@ player_t::player_t() PremorphWeapon(0), chickenPeck(0), jumpTics(0), + onground(0), respawn_time(0), camera(0), air_finished(0), @@ -375,6 +374,7 @@ player_t &player_t::operator=(const player_t &p) PremorphWeapon = p.PremorphWeapon; chickenPeck = p.chickenPeck; jumpTics = p.jumpTics; + onground = p.onground; respawn_time = p.respawn_time; camera = p.camera; air_finished = p.air_finished; @@ -1747,7 +1747,7 @@ void P_CalcHeight (player_t *player) { player->bob = 0; } - else if ((player->mo->flags & MF_NOGRAVITY) && !onground) + else if ((player->mo->flags & MF_NOGRAVITY) && !player->onground) { player->bob = FRACUNIT / 2; } @@ -1872,7 +1872,7 @@ void P_MovePlayer (player_t *player) mo->angle += cmd->ucmd.yaw << 16; } - onground = (mo->z <= mo->floorz) || (mo->flags2 & MF2_ONMOBJ) || (mo->BounceFlags & BOUNCE_MBF) || (player->cheats & CF_NOCLIP2); + player->onground = (mo->z <= mo->floorz) || (mo->flags2 & MF2_ONMOBJ) || (mo->BounceFlags & BOUNCE_MBF) || (player->cheats & CF_NOCLIP2); // killough 10/98: // @@ -1890,7 +1890,7 @@ void P_MovePlayer (player_t *player) movefactor = P_GetMoveFactor (mo, &friction); bobfactor = friction < ORIG_FRICTION ? movefactor : ORIG_FRICTION_FACTOR; - if (!onground && !(player->mo->flags & MF_NOGRAVITY) && !player->mo->waterlevel) + if (!player->onground && !(player->mo->flags & MF_NOGRAVITY) && !player->mo->waterlevel) { // [RH] allow very limited movement if not on ground. movefactor = FixedMul (movefactor, level.aircontrol); @@ -2061,12 +2061,12 @@ void P_DeathThink (player_t *player) P_MovePsprites (player); - onground = (player->mo->z <= player->mo->floorz); + player->onground = (player->mo->z <= player->mo->floorz); if (player->mo->IsKindOf (RUNTIME_CLASS(APlayerChunk))) { // Flying bloody skull or flying ice chunk player->viewheight = 6 * FRACUNIT; player->deltaviewheight = 0; - if (onground) + if (player->onground) { if (player->mo->pitch > -(int)ANGLE_1*19) { @@ -2365,7 +2365,7 @@ void P_PlayerThink (player_t *player) if (player->jumpTics != 0) { player->jumpTics--; - if (onground && player->jumpTics < -18) + if (player->onground && player->jumpTics < -18) { player->jumpTics = 0; } @@ -2465,7 +2465,7 @@ void P_PlayerThink (player_t *player) { player->mo->velz = 3*FRACUNIT; } - else if (level.IsJumpingAllowed() && onground && player->jumpTics == 0) + else if (level.IsJumpingAllowed() && player->onground && player->jumpTics == 0) { fixed_t jumpvelz = player->mo->JumpZ * 35 / TICRATE; @@ -2877,6 +2877,14 @@ void player_t::Serialize (FArchive &arc) { settings_controller = (this - players == Net_Arbitrator); } + if (SaveVersion >= 4505) + { + arc << onground; + } + else + { + onground = (mo->z <= mo->floorz) || (mo->flags2 & MF2_ONMOBJ) || (mo->BounceFlags & BOUNCE_MBF) || (cheats & CF_NOCLIP2); + } if (isbot) { diff --git a/src/v_font.cpp b/src/v_font.cpp index d34b08be5..abd7f494c 100644 --- a/src/v_font.cpp +++ b/src/v_font.cpp @@ -2009,26 +2009,20 @@ void FSpecialFont::LoadTranslations() } // exclude the non-translated colors from the translation calculation - if (notranslate != NULL) - { - for (i = 0; i < 256; i++) - if (notranslate[i]) - usedcolors[i] = false; - } + for (i = 0; i < 256; i++) + if (notranslate[i]) + usedcolors[i] = false; TotalColors = ActiveColors = SimpleTranslation (usedcolors, PatchRemap, identity, &luminosity); // Map all untranslated colors into the table of used colors - if (notranslate != NULL) + for (i = 0; i < 256; i++) { - for (i = 0; i < 256; i++) + if (notranslate[i]) { - if (notranslate[i]) - { - PatchRemap[i] = TotalColors; - identity[TotalColors] = i; - TotalColors++; - } + PatchRemap[i] = TotalColors; + identity[TotalColors] = i; + TotalColors++; } } diff --git a/src/version.h b/src/version.h index f70591b99..4a43d3b4d 100644 --- a/src/version.h +++ b/src/version.h @@ -76,7 +76,7 @@ const char *GetVersionString(); // Use 4500 as the base git save version, since it's higher than the // SVN revision ever got. -#define SAVEVER 4504 +#define SAVEVER 4505 #define SAVEVERSTRINGIFY2(x) #x #define SAVEVERSTRINGIFY(x) SAVEVERSTRINGIFY2(x)