diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index 65940c568..df6e0700e 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -4461,6 +4461,21 @@ static inline pslope_t *LoadSlope(UINT32 slopeid) return NULL; } +static mobjtype_t g_doomednum_to_mobjtype[UINT16_MAX]; + +static void CalculateDoomednumToMobjtype(void) +{ + memset(g_doomednum_to_mobjtype, MT_NULL, sizeof(g_doomednum_to_mobjtype)); + + for (size_t i = MT_NULL+1; i < NUMMOBJTYPES; i++) + { + if (mobjinfo[i].doomednum > 0 && mobjinfo[i].doomednum <= UINT16_MAX) + { + g_doomednum_to_mobjtype[ mobjinfo[i].doomednum ] = static_cast(i); + } + } +} + static thinker_t* LoadMobjThinker(savebuffer_t *save, actionf_p1 thinker) { mobj_t *mobj; @@ -4532,20 +4547,26 @@ static thinker_t* LoadMobjThinker(savebuffer_t *save, actionf_p1 thinker) mobj->type = (mobjtype_t)READUINT32(save->p); else { - for (i = 0; i < NUMMOBJTYPES; i++) - if (mobj->spawnpoint && mobj->spawnpoint->type == mobjinfo[i].doomednum) - break; - if (i == NUMMOBJTYPES) + mobjtype_t new_type = MT_NULL; + if (mobj->spawnpoint) + { + new_type = g_doomednum_to_mobjtype[mobj->spawnpoint->type]; + } + + if (new_type <= MT_NULL || new_type >= NUMMOBJTYPES) { if (mobj->spawnpoint) - CONS_Alert(CONS_ERROR, "Found mobj with unknown map thing type %d\n", mobj->spawnpoint->type); + CONS_Alert(CONS_ERROR, "Found mobj with unknown map thing doomednum %d\n", mobj->spawnpoint->type); else - CONS_Alert(CONS_ERROR, "Found mobj with unknown map thing type NULL\n"); + CONS_Alert(CONS_ERROR, "Found mobj with unknown map thing doomednum NULL\n"); + I_Error("Netsave corrupted"); } - mobj->type = (mobjtype_t)i; + + mobj->type = new_type; } mobj->info = &mobjinfo[mobj->type]; + if (diff & MD_POS) { mobj->x = mobj->old_x = READFIXED(save->p); @@ -5506,6 +5527,10 @@ static void P_NetUnArchiveThinkers(savebuffer_t *save) if (READUINT32(save->p) != ARCHIVEBLOCK_THINKERS) I_Error("Bad $$$.sav at archive block Thinkers"); + // Pre-calculate this lookup, because it was wasting + // a shit ton of time loading mobj thinkers. + CalculateDoomednumToMobjtype(); + // remove all the current thinkers for (i = 0; i < NUM_THINKERLISTS; i++) {