diff --git a/Source/monster.cpp b/Source/monster.cpp index fd03624d1..b4a7b4e97 100644 --- a/Source/monster.cpp +++ b/Source/monster.cpp @@ -2689,7 +2689,7 @@ BOOL M_DoRSpAttack(int i) monster[i]._mVar3, 0); #ifdef HELLFIRE - if (Monsters[i].Snds[3][0] != 0) + if (Monsters[i].Snds[3][0] != 0) // BUGFIX `Monsters[i].` should be `monster[i].MType->` #endif PlayEffect(i, 3); } diff --git a/Source/objects.cpp b/Source/objects.cpp index 2341738fa..043624704 100644 --- a/Source/objects.cpp +++ b/Source/objects.cpp @@ -717,14 +717,15 @@ void AddChestTraps() void LoadMapObjects(BYTE *pMap, int startx, int starty, int x1, int y1, int w, int h, int leveridx) { - int rw, rh, i, j, oi; + int rw, rh, i, j, oi, type; BYTE *lm; long mapoff; InitObjFlag = TRUE; - lm = pMap + 2; - rw = pMap[0]; + lm = pMap; + rw = lm[0]; + lm += 2; rh = *lm; mapoff = (rw * rh + 1) * 2; rw <<= 1; @@ -735,7 +736,8 @@ void LoadMapObjects(BYTE *pMap, int startx, int starty, int x1, int y1, int w, i for (j = 0; j < rh; j++) { for (i = 0; i < rw; i++) { if (*lm) { - AddObject(ObjTypeConv[*lm], startx + 16 + i, starty + 16 + j); + type = lm[0]; + AddObject(ObjTypeConv[type], startx + 16 + i, starty + 16 + j); oi = ObjIndex(startx + 16 + i, starty + 16 + j); SetObjMapRange(oi, x1, y1, x1 + w, y1 + h, leveridx); } diff --git a/Source/pack.cpp b/Source/pack.cpp index 89cf0a9c4..344af853b 100644 --- a/Source/pack.cpp +++ b/Source/pack.cpp @@ -70,12 +70,10 @@ void PackPlayer(PkPlayerStruct *pPack, int pnum, BOOL manashield) pPack->pMaxManaBase = SwapLE32(pPlayer->_pMaxManaBase); pPack->pMemSpells = SDL_SwapLE64(pPlayer->_pMemSpells); - for (i = 0; i < 37; i++) // Should be MAX_SPELLS but set to 37 to make save games compatible + for (i = 0; i <= 36; i++) // Should be MAX_SPELLS-1 but set to 36 to make save games compatible pPack->pSplLvl[i] = pPlayer->_pSplLvl[i]; -#ifdef HELLFIRE for (i = 37; i < 47; i++) pPack->pSplLvl2[i - 37] = pPlayer->_pSplLvl[i]; -#endif pki = &pPack->InvBody[0]; pi = &pPlayer->InvBody[0]; @@ -223,16 +221,10 @@ void UnPackPlayer(PkPlayerStruct *pPack, int pnum, BOOL killok) pPlayer->_pManaBase = SwapLE32(pPack->pManaBase); pPlayer->_pMemSpells = SDL_SwapLE64(pPack->pMemSpells); -#ifdef HELLFIRE for (i = 0; i <= 36; i++) // Should be MAX_SPELLS-1 but set to 36 to make save games compatible pPlayer->_pSplLvl[i] = pPack->pSplLvl[i]; - char *p = pPack->pSplLvl2; for (i = 37; i < 47; i++) - pPlayer->_pSplLvl[i] = p[i - 37]; -#else - for (i = 0; i < MAX_SPELLS; i++) - pPlayer->_pSplLvl[i] = pPack->pSplLvl[i]; -#endif + pPlayer->_pSplLvl[i] = pPack->pSplLvl2[i - 37]; pki = &pPack->InvBody[0]; pi = &pPlayer->InvBody[0]; diff --git a/Source/pfile.cpp b/Source/pfile.cpp index 4834fea61..026cac9ee 100644 --- a/Source/pfile.cpp +++ b/Source/pfile.cpp @@ -82,6 +82,7 @@ static BOOL pfile_read_hero(HANDLE archive, PkPlayerStruct *pPack) if (!SFileOpenFileEx(archive, "hero", 0, &file)) { return FALSE; } else { + buf = NULL; BOOL ret = FALSE; const char *password; @@ -106,9 +107,9 @@ static BOOL pfile_read_hero(HANDLE archive, PkPlayerStruct *pPack) ret = TRUE; } } - if (buf) - mem_free_dbg(buf); } + if (buf) + mem_free_dbg(buf); SFileCloseFile(file); return ret; } @@ -325,14 +326,56 @@ BOOL pfile_archive_contains_game(HANDLE hsArchive, DWORD save_num) { HANDLE file; +#ifdef HELLFIRE + DWORD read, size; + BOOL ret = FALSE; + gbLoadGame = FALSE; +#endif + if (gbMaxPlayers != 1) return FALSE; if (!SFileOpenFileEx(hsArchive, "game", 0, &file)) return FALSE; +#ifdef HELLFIRE + DWORD dwlen = SFileGetFileSize(file, NULL); + if (!dwlen) + app_fatal("Invalid save file"); + + BYTE *ptr = DiabloAllocPtr(dwlen + 8); + BYTE *buf = ptr + 4; + + if (SFileReadFile(file, buf, dwlen, &read, NULL)) { + if (read == dwlen) { + const char *password; + password = PASSWORD_SINGLE; + if (gbMaxPlayers > 1) + password = PASSWORD_MULTI; + gbLoadGame = TRUE; + if (codec_decode(buf, dwlen, password)) { + int magic = *buf << 24; + buf++; + magic |= *buf << 16; + buf++; + magic |= *buf << 8; + buf++; + magic |= *buf; + if (magic == 'HELF') { + ret = TRUE; + } + } + } + } + + if (ptr) + mem_free_dbg(ptr); + SFileCloseFile(file); + return ret; +#else SFileCloseFile(file); return TRUE; +#endif } BOOL pfile_ui_set_class_stats(unsigned int player_class_nr, _uidefaultstats *class_stats) @@ -354,12 +397,20 @@ BOOL pfile_ui_save_create(_uiheroinfo *heroinfo) PkPlayerStruct pkplr; save_num = pfile_get_save_num_from_name(heroinfo->name); +#ifdef HELLFIRE + if (save_num >= MAX_CHARACTERS) { +#else if (save_num == MAX_CHARACTERS) { +#endif for (save_num = 0; save_num < MAX_CHARACTERS; save_num++) { if (!hero_names[save_num][0]) break; } +#ifdef HELLFIRE + if (save_num >= MAX_CHARACTERS) +#else if (save_num == MAX_CHARACTERS) +#endif return FALSE; } if (!pfile_open_archive(FALSE, save_num)) @@ -387,14 +438,14 @@ BOOL pfile_get_file_name(DWORD lvl, char *dst) return FALSE; fmt = "hero"; } else { - if (lvl < 17) + if (lvl < NUMLEVELS) fmt = "perml%02d"; - else if (lvl < 34) { - lvl -= 17; + else if (lvl < NUMLEVELS * 2) { + lvl -= NUMLEVELS; fmt = "perms%02d"; - } else if (lvl == 34) + } else if (lvl == NUMLEVELS * 2) fmt = "game"; - else if (lvl == 35) + else if (lvl == NUMLEVELS * 2 + 1) fmt = "hero"; else return FALSE; @@ -561,7 +612,7 @@ void pfile_write_save_file(const char *pszName, BYTE *pbData, DWORD dwLen, DWORD codec_encode(pbData, dwLen, qwLen, password); } if (!pfile_open_archive(FALSE, save_num)) - app_fatal("Unable to write so save file archive"); + app_fatal("Unable to write to save file archive"); mpqapi_write_file(pszName, pbData, qwLen); pfile_flush(TRUE, save_num); } @@ -584,7 +635,7 @@ BYTE *pfile_read(const char *pszName, DWORD *pdwLen) if (*pdwLen == 0) app_fatal("Invalid save file"); - buf = (BYTE *)DiabloAllocPtr(*pdwLen); + buf = DiabloAllocPtr(*pdwLen); if (!SFileReadFile(save, buf, *pdwLen, &nread, NULL)) app_fatal("Unable to read save file"); SFileCloseFile(save); @@ -605,9 +656,8 @@ BYTE *pfile_read(const char *pszName, DWORD *pdwLen) } *pdwLen = codec_decode(buf, *pdwLen, password); - if (*pdwLen == 0) { + if (*pdwLen == 0) app_fatal("Invalid save file"); - } } return buf; }