[hellfire] Allow continuing Diablo saves in Hellfire and vice versa
This commit is contained in:
parent
2f4b66f844
commit
4ffbb32952
12 changed files with 183 additions and 139 deletions
|
|
@ -2568,7 +2568,7 @@ static void DRLG_L5(int entry)
|
|||
}
|
||||
} else if (entry == ENTRY_MAIN) {
|
||||
if (currlevel < 21) {
|
||||
if (gbIsHellfire) {
|
||||
if (!plr[myplr].pOriginalCathedral) {
|
||||
if (DRLG_PlaceMiniSet(STAIRSUP, 1, 1, 0, 0, TRUE, -1, 0) < 0)
|
||||
doneflag = FALSE;
|
||||
if (DRLG_PlaceMiniSet(STAIRSDOWN, 1, 1, 0, 0, FALSE, -1, 1) < 0)
|
||||
|
|
@ -2594,7 +2594,7 @@ static void DRLG_L5(int entry)
|
|||
}
|
||||
ViewY++;
|
||||
}
|
||||
} else if (gbIsHellfire && entry == ENTRY_PREV) {
|
||||
} else if (!plr[myplr].pOriginalCathedral && entry == ENTRY_PREV) {
|
||||
if (currlevel < 21) {
|
||||
if (DRLG_PlaceMiniSet(STAIRSUP, 1, 1, 0, 0, FALSE, -1, 0) < 0)
|
||||
doneflag = FALSE;
|
||||
|
|
@ -2618,7 +2618,7 @@ static void DRLG_L5(int entry)
|
|||
}
|
||||
} else {
|
||||
if (currlevel < 21) {
|
||||
if (gbIsHellfire) {
|
||||
if (!plr[myplr].pOriginalCathedral) {
|
||||
if (DRLG_PlaceMiniSet(STAIRSUP, 1, 1, 0, 0, FALSE, -1, 0) < 0)
|
||||
doneflag = FALSE;
|
||||
if (DRLG_PlaceMiniSet(STAIRSDOWN, 1, 1, 0, 0, FALSE, -1, 1) < 0)
|
||||
|
|
|
|||
|
|
@ -314,6 +314,7 @@ void ShowProgress(unsigned int uMsg)
|
|||
IncProgress();
|
||||
break;
|
||||
case WM_DIABNEWGAME:
|
||||
plr[myplr].pOriginalCathedral = !gbIsHellfire;
|
||||
IncProgress();
|
||||
FreeGameMem();
|
||||
IncProgress();
|
||||
|
|
|
|||
|
|
@ -16,11 +16,7 @@ ItemDataStruct AllItemsList[] = {
|
|||
/*IDI_WARRSHLD */ { IDROP_NEVER, ICLASS_ARMOR, ILOC_ONEHAND, ICURS_BUCKLER, ITYPE_SHIELD, UITYPE_NONE, "Buckler", NULL, 2, 10, 0, 0, 3, 3, 0, 0, 0, ISPL_NONE, IMISC_NONE, SPL_NULL, FALSE, 50, 50 },
|
||||
/*IDI_WARRCLUB */ { IDROP_NEVER, ICLASS_WEAPON, ILOC_ONEHAND, ICURS_CLUB, ITYPE_MACE, UITYPE_SPIKCLUB, "Club", NULL, 1, 20, 1, 6, 0, 0, 0, 0, 0, ISPL_NONE, IMISC_NONE, SPL_NULL, FALSE, 20, 20 },
|
||||
/*IDI_ROGUE */ { IDROP_NEVER, ICLASS_WEAPON, ILOC_TWOHAND, ICURS_SHORT_BOW, ITYPE_BOW, UITYPE_NONE, "Short Bow", NULL, 1, 30, 1, 4, 0, 0, 0, 0, 0, ISPL_NONE, IMISC_NONE, SPL_NULL, FALSE, 100, 100 },
|
||||
#ifndef HELLFIRE
|
||||
/*IDI_SORCEROR */ { IDROP_NEVER, ICLASS_WEAPON, ILOC_TWOHAND, ICURS_SHORT_STAFF, ITYPE_STAFF, UITYPE_NONE, "Short Staff of Charged Bolt", NULL, 1, 25, 2, 4, 0, 0, 0, 20, 0, ISPL_NONE, IMISC_STAFF, SPL_CBOLT, FALSE, 520, 520 },
|
||||
#else
|
||||
/*IDI_SORCEROR */ { IDROP_NEVER, ICLASS_WEAPON, ILOC_TWOHAND, ICURS_SHORT_STAFF, ITYPE_STAFF, UITYPE_NONE, "Short Staff of Mana", NULL, 1, 25, 2, 4, 0, 0, 0, 20, 0, ISPL_NONE, IMISC_STAFF, SPL_MANA, FALSE, 520, 520 },
|
||||
#endif
|
||||
/*IDI_CLEAVER */ { IDROP_NEVER, ICLASS_WEAPON, ILOC_TWOHAND, ICURS_CLEAVER, ITYPE_AXE, UITYPE_CLEAVER, "Cleaver", NULL, 10, 10, 4, 24, 0, 0, 0, 0, 0, ISPL_NONE, IMISC_UNIQUE, SPL_NULL, FALSE, 2000, 2000 },
|
||||
/*IDI_SKCROWN */ { IDROP_NEVER, ICLASS_ARMOR, ILOC_HELM, ICURS_THE_UNDEAD_CROWN, ITYPE_HELM, UITYPE_SKCROWN, "The Undead Crown", NULL, 0, 50, 0, 0, 15, 15, 0, 0, 0, ISPL_RNDSTEALLIFE, IMISC_UNIQUE, SPL_NULL, FALSE, 10000, 10000 },
|
||||
/*IDI_INFRARING */ { IDROP_NEVER, ICLASS_MISC, ILOC_RING, ICURS_EMPYREAN_BAND, ITYPE_RING, UITYPE_INFRARING, "Empyrean Band", NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, ISPL_NONE, IMISC_UNIQUE, SPL_NULL, FALSE, 8000, 8000 },
|
||||
|
|
@ -37,11 +33,7 @@ ItemDataStruct AllItemsList[] = {
|
|||
/*IDI_FUNGALTM */ { IDROP_NEVER, ICLASS_QUEST, ILOC_UNEQUIPABLE, ICURS_FUNGAL_TOME, ITYPE_MISC, UITYPE_NONE, "Fungal Tome", NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, ISPL_NONE, IMISC_NONE, SPL_NULL, FALSE, 0, 0 },
|
||||
/*IDI_SPECELIX */ { IDROP_NEVER, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_SPECTRAL_ELIXIR, ITYPE_MISC, UITYPE_ELIXIR, "Spectral Elixir", NULL, 15, 0, 0, 0, 0, 0, 0, 0, 0, ISPL_NONE, IMISC_SPECELIX, SPL_NULL, FALSE, 0, 0 },
|
||||
/*IDI_BLDSTONE */ { IDROP_NEVER, ICLASS_QUEST, ILOC_UNEQUIPABLE, ICURS_BLOOD_STONE, ITYPE_MISC, UITYPE_NONE, "Blood Stone", NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, ISPL_NONE, IMISC_NONE, SPL_NULL, FALSE, 0, 0 },
|
||||
#ifndef HELLFIRE
|
||||
/*IDI_MAPOFDOOM */ { IDROP_NEVER, ICLASS_QUEST, ILOC_UNEQUIPABLE, ICURS_MAP_OF_THE_STARS, ITYPE_MISC, UITYPE_MAPOFDOOM, "Map of the Stars", NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, ISPL_NONE, IMISC_MAPOFDOOM, SPL_NULL, TRUE, 0, 0 },
|
||||
#else
|
||||
/*IDI_MAPOFDOOM */ { IDROP_NEVER, ICLASS_QUEST, ILOC_UNEQUIPABLE, ICURS_MAP_OF_THE_STARS, ITYPE_MISC, UITYPE_MAPOFDOOM, "Cathedral Map", NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, ISPL_NONE, IMISC_MAPOFDOOM, SPL_NULL, TRUE, 0, 0 },
|
||||
#endif
|
||||
/*IDI_EAR */ { IDROP_NEVER, ICLASS_QUEST, ILOC_UNEQUIPABLE, ICURS_EAR_SORCEROR, ITYPE_MISC, UITYPE_NONE, "Heart", NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, ISPL_NONE, IMISC_EAR, SPL_NULL, FALSE, 0, 0 },
|
||||
/*IDI_HEAL */ { IDROP_NEVER, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_POTION_OF_HEALING, ITYPE_MISC, UITYPE_NONE, "Potion of Healing", NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, ISPL_NONE, IMISC_HEAL, SPL_NULL, TRUE, 50, 50 },
|
||||
/*IDI_MANA */ { IDROP_NEVER, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_POTION_OF_MANA, ITYPE_MISC, UITYPE_NONE, "Potion of Mana", NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, ISPL_NONE, IMISC_MANA, SPL_NULL, TRUE, 50, 50 },
|
||||
|
|
@ -51,28 +43,9 @@ ItemDataStruct AllItemsList[] = {
|
|||
/*IDI_FULLHEAL */ { IDROP_NEVER, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_POTION_OF_FULL_HEALING, ITYPE_MISC, UITYPE_NONE, "Potion of Full Healing", NULL, 1, 0, 0, 0, 0, 0, 0, 0, 0, ISPL_NONE, IMISC_FULLHEAL, SPL_NULL, TRUE, 150, 150 },
|
||||
/*IDI_FULLMANA */ { IDROP_NEVER, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_POTION_OF_FULL_MANA, ITYPE_MISC, UITYPE_NONE, "Potion of Full Mana", NULL, 1, 0, 0, 0, 0, 0, 0, 0, 0, ISPL_NONE, IMISC_FULLMANA, SPL_NULL, TRUE, 150, 150 },
|
||||
/*IDI_GRISWOLD */ { IDROP_NEVER, ICLASS_WEAPON, ILOC_ONEHAND, ICURS_BROAD_SWORD, ITYPE_SWORD, UITYPE_GRISWOLD, "Griswold's Edge", NULL, 8, 50, 4, 12, 0, 0, 40, 0, 0, ISPL_NONE, IMISC_UNIQUE, SPL_NULL, FALSE, 750, 750 },
|
||||
#ifndef HELLFIRE
|
||||
/*IDI_LGTFORGE */ { IDROP_NEVER, ICLASS_WEAPON, ILOC_ONEHAND, ICURS_MACE, ITYPE_MACE, UITYPE_LGTFORGE, "Lightforge", NULL, 2, 32, 1, 8, 0, 0, 16, 0, 0, ISPL_NONE, IMISC_UNIQUE, SPL_NULL, FALSE, 200, 200 },
|
||||
#else
|
||||
/*IDI_LGTFORGE */ { IDROP_NEVER, ICLASS_ARMOR, ILOC_ARMOR, ICURS_BOVINE, ITYPE_HARMOR, UITYPE_BOVINE, "Bovine Plate", NULL, 0, 40, 0, 0, 0, 0, 50, 0, 0, ISPL_NONE, IMISC_UNIQUE, SPL_NULL, FALSE, 0, 0 },
|
||||
#endif
|
||||
/*IDI_LAZSTAFF */ { IDROP_NEVER, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_STAFF_OF_LAZARUS, ITYPE_MISC, UITYPE_LAZSTAFF, "Staff of Lazarus", NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, ISPL_NONE, IMISC_NONE, SPL_NULL, FALSE, 0, 0 },
|
||||
/*IDI_RESURRECT */ { IDROP_NEVER, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_SCROLL_OF, ITYPE_MISC, UITYPE_NONE, "Scroll of Resurrect", NULL, 1, 0, 0, 0, 0, 0, 0, 0, 0, ISPL_NONE, IMISC_SCROLLT, SPL_RESURRECT, TRUE, 250, 250 },
|
||||
#ifndef HELLFIRE
|
||||
/* */ { IDROP_NEVER, ICLASS_NONE, ILOC_NONE, ICURS_POTION_OF_FULL_MANA, ITYPE_MISC, UITYPE_NONE, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, ISPL_NONE, IMISC_NONE, SPL_NULL, FALSE, 0, 0 },
|
||||
/* */ { IDROP_NEVER, ICLASS_NONE, ILOC_NONE, ICURS_POTION_OF_FULL_MANA, ITYPE_MISC, UITYPE_NONE, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, ISPL_NONE, IMISC_NONE, SPL_NULL, FALSE, 0, 0 },
|
||||
/* */ { IDROP_NEVER, ICLASS_NONE, ILOC_NONE, ICURS_POTION_OF_FULL_MANA, ITYPE_MISC, UITYPE_NONE, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, ISPL_NONE, IMISC_NONE, SPL_NULL, FALSE, 0, 0 },
|
||||
/* */ { IDROP_NEVER, ICLASS_NONE, ILOC_NONE, ICURS_POTION_OF_FULL_MANA, ITYPE_MISC, UITYPE_NONE, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, ISPL_NONE, IMISC_NONE, SPL_NULL, FALSE, 0, 0 },
|
||||
/* */ { IDROP_NEVER, ICLASS_NONE, ILOC_NONE, ICURS_POTION_OF_FULL_MANA, ITYPE_MISC, UITYPE_NONE, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, ISPL_NONE, IMISC_NONE, SPL_NULL, FALSE, 0, 0 },
|
||||
/* */ { IDROP_NEVER, ICLASS_NONE, ILOC_NONE, ICURS_POTION_OF_FULL_MANA, ITYPE_MISC, UITYPE_NONE, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, ISPL_NONE, IMISC_NONE, SPL_NULL, FALSE, 0, 0 },
|
||||
/* */ { IDROP_NEVER, ICLASS_NONE, ILOC_NONE, ICURS_POTION_OF_FULL_MANA, ITYPE_MISC, UITYPE_NONE, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, ISPL_NONE, IMISC_NONE, SPL_NULL, FALSE, 0, 0 },
|
||||
/* */ { IDROP_NEVER, ICLASS_NONE, ILOC_NONE, ICURS_POTION_OF_FULL_MANA, ITYPE_MISC, UITYPE_NONE, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, ISPL_NONE, IMISC_NONE, SPL_NULL, FALSE, 0, 0 },
|
||||
/* */ { IDROP_NEVER, ICLASS_NONE, ILOC_NONE, ICURS_POTION_OF_FULL_MANA, ITYPE_MISC, UITYPE_NONE, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, ISPL_NONE, IMISC_NONE, SPL_NULL, FALSE, 0, 0 },
|
||||
/* */ { IDROP_NEVER, ICLASS_NONE, ILOC_NONE, ICURS_POTION_OF_FULL_MANA, ITYPE_MISC, UITYPE_NONE, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, ISPL_NONE, IMISC_NONE, SPL_NULL, FALSE, 0, 0 },
|
||||
/* */ { IDROP_NEVER, ICLASS_NONE, ILOC_NONE, ICURS_POTION_OF_FULL_MANA, ITYPE_MISC, UITYPE_NONE, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, ISPL_NONE, IMISC_NONE, SPL_NULL, FALSE, 0, 0 },
|
||||
/* */ { IDROP_NEVER, ICLASS_NONE, ILOC_NONE, ICURS_POTION_OF_FULL_MANA, ITYPE_MISC, UITYPE_NONE, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, ISPL_NONE, IMISC_NONE, SPL_NULL, FALSE, 0, 0 },
|
||||
/* */ { IDROP_NEVER, ICLASS_NONE, ILOC_NONE, ICURS_POTION_OF_FULL_MANA, ITYPE_MISC, UITYPE_NONE, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, ISPL_NONE, IMISC_NONE, SPL_NULL, FALSE, 0, 0 },
|
||||
#else
|
||||
/*IDI_OIL */ { IDROP_NEVER, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_OIL, ITYPE_MISC, UITYPE_NONE, "Blacksmith Oil", NULL, 1, 0, 0, 0, 0, 0, 0, 0, 0, ISPL_NONE, IMISC_OILBSMTH, SPL_NULL, TRUE, 100, 100 },
|
||||
/*IDI_SHORTSTAFF */ { IDROP_NEVER, ICLASS_WEAPON, ILOC_TWOHAND, ICURS_SHORT_STAFF, ITYPE_STAFF, UITYPE_NONE, "Short Staff", NULL, 1, 25, 2, 4, 0, 0, 0, 0, 0, ISPL_NONE, IMISC_NONE, SPL_NULL, FALSE, 20, 20 },
|
||||
/*IDI_BARDSWORD */ { IDROP_NEVER, ICLASS_WEAPON, ILOC_ONEHAND, ICURS_SHORT_SWORD, ITYPE_SWORD, UITYPE_NONE, "Sword", NULL, 2, 8, 1, 5, 0, 0, 15, 0, 20, ISPL_NONE, IMISC_NONE, SPL_NULL, FALSE, 20, 20 },
|
||||
|
|
@ -86,7 +59,6 @@ ItemDataStruct AllItemsList[] = {
|
|||
/*IDI_FULLNOTE */ { IDROP_NEVER, ICLASS_QUEST, ILOC_UNEQUIPABLE, ICURS_RECONSTRUCTED_NOTE, ITYPE_MISC, UITYPE_NONE, "Reconstructed Note", NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, ISPL_NONE, IMISC_NOTE, SPL_NULL, TRUE, 0, 0 },
|
||||
/*IDI_BROWNSUIT */ { IDROP_NEVER, ICLASS_QUEST, ILOC_UNEQUIPABLE, ICURS_BROWN_SUIT, ITYPE_MISC, UITYPE_NONE, "Brown Suit", NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, ISPL_NONE, IMISC_NONE, SPL_NULL, FALSE, 0, 0 },
|
||||
/*IDI_GREYSUIT */ { IDROP_NEVER, ICLASS_QUEST, ILOC_UNEQUIPABLE, ICURS_GREY_SUIT, ITYPE_MISC, UITYPE_NONE, "Grey Suit", NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, ISPL_NONE, IMISC_NONE, SPL_NULL, FALSE, 0, 0 },
|
||||
#endif
|
||||
/* */ { IDROP_REGULAR, ICLASS_ARMOR, ILOC_HELM, ICURS_CAP, ITYPE_HELM, UITYPE_NONE, "Cap", "Cap", 1, 15, 0, 0, 1, 3, 0, 0, 0, ISPL_NONE, IMISC_NONE, SPL_NULL, FALSE, 15, 20 },
|
||||
/* */ { IDROP_REGULAR, ICLASS_ARMOR, ILOC_HELM, ICURS_SKULL_CAP, ITYPE_HELM, UITYPE_SKULLCAP, "Skull Cap", "Cap", 4, 20, 0, 0, 2, 4, 0, 0, 0, ISPL_NONE, IMISC_NONE, SPL_NULL, FALSE, 25, 30 },
|
||||
/* */ { IDROP_REGULAR, ICLASS_ARMOR, ILOC_HELM, ICURS_HELM, ITYPE_HELM, UITYPE_HELM, "Helm", "Helm", 8, 30, 0, 0, 4, 6, 25, 0, 0, ISPL_NONE, IMISC_NONE, SPL_NULL, FALSE, 40, 70 },
|
||||
|
|
@ -122,20 +94,16 @@ ItemDataStruct AllItemsList[] = {
|
|||
/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_POTION_OF_FULL_MANA, ITYPE_MISC, UITYPE_NONE, "Potion of Full Mana", NULL, 1, 0, 0, 0, 0, 0, 0, 0, 0, ISPL_NONE, IMISC_FULLMANA, SPL_NULL, TRUE, 150, 150 },
|
||||
/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_POTION_OF_REJUVENATION, ITYPE_MISC, UITYPE_NONE, "Potion of Rejuvenation", NULL, 3, 0, 0, 0, 0, 0, 0, 0, 0, ISPL_NONE, IMISC_REJUV, SPL_NULL, TRUE, 120, 120 },
|
||||
/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_POTION_OF_FULL_REJUVENATION, ITYPE_MISC, UITYPE_NONE, "Potion of Full Rejuvenation", NULL, 7, 0, 0, 0, 0, 0, 0, 0, 0, ISPL_NONE, IMISC_FULLREJUV, SPL_NULL, TRUE, 600, 600 },
|
||||
#ifdef HELLFIRE
|
||||
/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_OIL, ITYPE_MISC, UITYPE_NONE, "Blacksmith Oil", NULL, 1, 0, 0, 0, 0, 0, 0, 0, 0, ISPL_NONE, IMISC_OILBSMTH, SPL_NULL, TRUE, 100, 100 },
|
||||
/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_OIL, ITYPE_MISC, UITYPE_NONE, "Oil of Accuracy", NULL, 1, 0, 0, 0, 0, 0, 0, 0, 0, ISPL_NONE, IMISC_OILACC, SPL_NULL, TRUE, 500, 500 },
|
||||
/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_OIL, ITYPE_MISC, UITYPE_NONE, "Oil of Sharpness", NULL, 1, 0, 0, 0, 0, 0, 0, 0, 0, ISPL_NONE, IMISC_OILSHARP, SPL_NULL, TRUE, 500, 500 },
|
||||
/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_OIL, ITYPE_MISC, UITYPE_NONE, "Oil", NULL, 10, 0, 0, 0, 0, 0, 0, 0, 0, ISPL_NONE, IMISC_OILOF, SPL_NULL, TRUE, 0, 0 },
|
||||
#endif
|
||||
/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_ELIXIR_OF_STRENGTH, ITYPE_MISC, UITYPE_NONE, "Elixir of Strength", NULL, 15, 0, 0, 0, 0, 0, 0, 0, 0, ISPL_NONE, IMISC_ELIXSTR, SPL_NULL, TRUE, 5000, 5000 },
|
||||
/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_ELIXIR_OF_MAGIC, ITYPE_MISC, UITYPE_NONE, "Elixir of Magic", NULL, 15, 0, 0, 0, 0, 0, 0, 0, 0, ISPL_NONE, IMISC_ELIXMAG, SPL_NULL, TRUE, 5000, 5000 },
|
||||
/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_ELIXIR_OF_DEXTERITY, ITYPE_MISC, UITYPE_NONE, "Elixir of Dexterity", NULL, 15, 0, 0, 0, 0, 0, 0, 0, 0, ISPL_NONE, IMISC_ELIXDEX, SPL_NULL, TRUE, 5000, 5000 },
|
||||
/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_ELIXIR_OF_VITALITY, ITYPE_MISC, UITYPE_NONE, "Elixir of Vitality", NULL, 20, 0, 0, 0, 0, 0, 0, 0, 0, ISPL_NONE, IMISC_ELIXVIT, SPL_NULL, TRUE, 5000, 5000 },
|
||||
/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_SCROLL_OF, ITYPE_MISC, UITYPE_NONE, "Scroll of Healing", NULL, 1, 0, 0, 0, 0, 0, 0, 0, 0, ISPL_NONE, IMISC_SCROLL, SPL_HEAL, TRUE, 50, 50 },
|
||||
#ifdef HELLFIRE
|
||||
/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_SCROLL_OF, ITYPE_MISC, UITYPE_NONE, "Scroll of Search", NULL, 1, 0, 0, 0, 0, 0, 0, 0, 0, ISPL_NONE, IMISC_SCROLL, SPL_SEARCH, TRUE, 50, 50 },
|
||||
#endif
|
||||
/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_SCROLL_OF, ITYPE_MISC, UITYPE_NONE, "Scroll of Lightning", NULL, 4, 0, 0, 0, 0, 0, 0, 0, 0, ISPL_NONE, IMISC_SCROLLT, SPL_LIGHTNING, TRUE, 150, 150 },
|
||||
/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_SCROLL_OF, ITYPE_MISC, UITYPE_NONE, "Scroll of Identify", NULL, 1, 0, 0, 0, 0, 0, 0, 0, 0, ISPL_NONE, IMISC_SCROLL, SPL_IDENTIFY, TRUE, 100, 100 },
|
||||
/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_SCROLL_OF, ITYPE_MISC, UITYPE_NONE, "Scroll of Resurrect", NULL, 1, 0, 0, 0, 0, 0, 0, 0, 0, ISPL_NONE, IMISC_SCROLLT, SPL_RESURRECT, TRUE, 250, 250 },
|
||||
|
|
@ -204,13 +172,12 @@ ItemDataStruct AllItemsList[] = {
|
|||
/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_RING, ICURS_RING, ITYPE_RING, UITYPE_RING, "Ring", "Ring", 15, 0, 0, 0, 0, 0, 0, 0, 0, ISPL_NONE, IMISC_RING, SPL_NULL, FALSE, 1000, 1000 },
|
||||
/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_AMULET, ICURS_AMULET, ITYPE_AMULET, UITYPE_AMULET, "Amulet", "Amulet", 8, 0, 0, 0, 0, 0, 0, 0, 0, ISPL_NONE, IMISC_AMULET, SPL_NULL, FALSE, 1200, 1200 },
|
||||
/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_AMULET, ICURS_AMULET, ITYPE_AMULET, UITYPE_AMULET, "Amulet", "Amulet", 16, 0, 0, 0, 0, 0, 0, 0, 0, ISPL_NONE, IMISC_AMULET, SPL_NULL, FALSE, 1200, 1200 },
|
||||
#ifdef HELLFIRE
|
||||
/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_RUNE_OF_FIRE, ITYPE_MISC, UITYPE_NONE, "Rune of Fire", "Rune", 1, 0, 0, 0, 0, 0, 0, 0, 0, ISPL_NONE, IMISC_RUNEF, SPL_NULL, TRUE, 100, 100 },
|
||||
/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_RUNE_OF_LIGHTNING, ITYPE_MISC, UITYPE_NONE, "Rune of Lightning", "Rune", 3, 0, 0, 0, 0, 0, 0, 13, 0, ISPL_NONE, IMISC_RUNEL, SPL_NULL, TRUE, 200, 200 },
|
||||
/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_GREATER_RUNE_OF_FIRE, ITYPE_MISC, UITYPE_NONE, "Greater Rune of Fire", "Rune", 7, 0, 0, 0, 0, 0, 0, 42, 0, ISPL_NONE, IMISC_GR_RUNEF, SPL_NULL, TRUE, 400, 400 },
|
||||
/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_GREATER_RUNE_OF_LIGHTNING, ITYPE_MISC, UITYPE_NONE, "Greater Rune of Lightning", "Rune", 7, 0, 0, 0, 0, 0, 0, 42, 0, ISPL_NONE, IMISC_GR_RUNEL, SPL_NULL, TRUE, 500, 500 },
|
||||
/* */ { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, ICURS_RUNE_OF_STONE, ITYPE_MISC, UITYPE_NONE, "Rune of Stone", "Rune", 7, 0, 0, 0, 0, 0, 0, 25, 0, ISPL_NONE, IMISC_RUNES, SPL_NULL, TRUE, 300, 300 },
|
||||
#endif
|
||||
/*IDI_SORCEROR */ { IDROP_NEVER, ICLASS_WEAPON, ILOC_TWOHAND, ICURS_SHORT_STAFF, ITYPE_STAFF, UITYPE_NONE, "Short Staff of Charged Bolt", NULL, 1, 25, 2, 4, 0, 0, 0, 20, 0, ISPL_NONE, IMISC_STAFF, SPL_CBOLT, FALSE, 520, 520 },
|
||||
/* */ { IDROP_NEVER, ICLASS_NONE, ILOC_INVALID, ICURS_POTION_OF_FULL_MANA, ITYPE_MISC, UITYPE_NONE, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, ISPL_NONE, IMISC_NONE, SPL_NULL, FALSE, 0, 0 },
|
||||
// clang-format on
|
||||
};
|
||||
|
|
@ -314,7 +281,7 @@ const PLStruct PL_Prefix[] = {
|
|||
{ "Bountiful", IPL_CHARGES, 3, 3, 9, PLT_STAFF , GOE_ANY, FALSE, TRUE, 3000, 3000, 3 },
|
||||
{ "Flaming", IPL_FIREDAM, 1, 10, 7, PLT_WEAP | PLT_STAFF , GOE_ANY, FALSE, TRUE, 5000, 5000, 2 },
|
||||
{ "Lightning", IPL_LIGHTDAM, 2, 20, 18, PLT_WEAP | PLT_STAFF , GOE_ANY, FALSE, TRUE, 10000, 10000, 2 },
|
||||
#ifdef HELLFIRE
|
||||
#ifdef HELLFIRE
|
||||
{ "Jester's", IPL_JESTERS, 1, 1, 7, PLT_WEAP , GOE_ANY, FALSE, TRUE, 1200, 1200, 3 },
|
||||
{ "Crystalline", IPL_CRYSTALLINE, 30, 70, 5, PLT_WEAP , GOE_ANY, FALSE, TRUE, 1000, 3000, 3 },
|
||||
{ "Doppelganger's", IPL_DOPPELGANGER, 81, 95, 11, PLT_WEAP | PLT_STAFF , GOE_ANY, FALSE, TRUE, 2000, 2400, 10 },
|
||||
|
|
@ -485,11 +452,7 @@ const UItemStruct UniqueItemList[] = {
|
|||
{ "Veil of Steel", UITYPE_STEELVEIL, 1, 6, 63800, IPL_ALLRES, 50, 50, IPL_LIGHT_CURSE, 2, 2, IPL_ACP, 60, 60, IPL_MANA_CURSE, 30, 30, IPL_STR, 15, 15, IPL_VIT, 15, 15 },
|
||||
{ "Arkaine's Valor", UITYPE_ARMOFVAL, 1, 4, 42000, IPL_SETAC, 25, 25, IPL_VIT, 10, 10, IPL_GETHIT, 3, 3, IPL_FASTRECOVER, 3, 3, IPL_TOHIT, 0, 0, IPL_TOHIT, 0, 0 },
|
||||
{ "Griswold's Edge", UITYPE_GRISWOLD, 1, 6, 42000, IPL_FIREDAM, 1, 10, IPL_TOHIT, 25, 25, IPL_FASTATTACK, 2, 2, IPL_KNOCKBACK, 0, 0, IPL_MANA, 20, 20, IPL_LIFE_CURSE, 20, 20 },
|
||||
#ifdef HELLFIRE
|
||||
{ "Bovine Plate", UITYPE_BOVINE, 1, 6, 400, IPL_SETAC, 150, 150, IPL_INDESTRUCTIBLE, 0, 0, IPL_LIGHT, 5, 5, IPL_ALLRES, 30, 30, IPL_MANA_CURSE, 50, 50, IPL_SPLLVLADD, -2, -2 },
|
||||
#else
|
||||
{ "Lightforge", UITYPE_MACE, 1, 6, 26675, IPL_LIGHT, 4, 4, IPL_DAMP, 150, 150, IPL_TOHIT, 25, 25, IPL_FIREDAM, 10, 20, IPL_INDESTRUCTIBLE, 0, 0, IPL_ATTRIBS, 8, 8 },
|
||||
#endif
|
||||
{ "The Rift Bow", UITYPE_SHORTBOW, 1, 3, 1800, IPL_RNDARROWVEL, 0, 0, IPL_DAMMOD, 2, 2, IPL_DEX_CURSE, 3, 3, IPL_TOHIT, 0, 0, IPL_TOHIT, 0, 0, IPL_TOHIT, 0, 0 },
|
||||
{ "The Needler", UITYPE_SHORTBOW, 2, 4, 8900, IPL_TOHIT, 50, 50, IPL_SETDAM, 1, 3, IPL_FASTATTACK, 2, 2, IPL_INVCURS, 158, 0, IPL_TOHIT, 0, 0, IPL_TOHIT, 0, 0 },
|
||||
{ "The Celestial Bow", UITYPE_LONGBOW, 2, 4, 1200, IPL_NOMINSTR, 0, 0, IPL_DAMMOD, 2, 2, IPL_SETAC, 5, 5, IPL_INVCURS, 133, 0, IPL_TOHIT, 0, 0, IPL_TOHIT, 0, 0 },
|
||||
|
|
@ -570,7 +533,6 @@ const UItemStruct UniqueItemList[] = {
|
|||
{ "The Bleeder", UITYPE_RING, 2, 4, 8500, IPL_MAGICRES, 20, 20, IPL_MANA, 30, 30, IPL_LIFE_CURSE, 10, 10, IPL_INVCURS, 8, 0, IPL_TOHIT, 0, 0, IPL_TOHIT, 0, 0 },
|
||||
{ "Constricting Ring", UITYPE_RING, 5, 3, 62000, IPL_ALLRES, 75, 75, IPL_DRAINLIFE, 0, 0, IPL_INVCURS, 14, 0, IPL_TOHIT, 0, 0, IPL_TOHIT, 0, 0, IPL_TOHIT, 0, 0 },
|
||||
{ "Ring of Engagement", UITYPE_RING, 11, 5, 12476, IPL_GETHIT, 1, 2, IPL_THORNS, 1, 3, IPL_SETAC, 5, 5, IPL_TARGAC, 4, 12, IPL_INVCURS, 13, 0, IPL_TOHIT, 0, 0 },
|
||||
#ifdef HELLFIRE
|
||||
{ "Giant's Knuckle", UITYPE_RING, 8, 3, 8000, IPL_STR, 60, 60, IPL_DEX_CURSE, 30, 30, IPL_INVCURS, 179, 0, IPL_TOHIT, 0, 0, IPL_TOHIT, 0, 0, IPL_TOHIT, 0, 0 },
|
||||
{ "Mercurial Ring", UITYPE_RING, 8, 3, 8000, IPL_DEX, 60, 60, IPL_STR_CURSE, 30, 30, IPL_INVCURS, 176, 0, IPL_TOHIT, 0, 0, IPL_TOHIT, 0, 0, IPL_TOHIT, 0, 0 },
|
||||
{ "Xorine's Ring", UITYPE_RING, 8, 3, 8000, IPL_MAG, 60, 60, IPL_STR_CURSE, 30, 30, IPL_INVCURS, 168, 0, IPL_TOHIT, 0, 0, IPL_TOHIT, 0, 0, IPL_TOHIT, 0, 0 },
|
||||
|
|
@ -591,7 +553,6 @@ const UItemStruct UniqueItemList[] = {
|
|||
{ "Demon Plate Armor", UITYPE_FULLPLATE, 25, 3, 80000, IPL_SETAC, 80, 80, IPL_ACDEMON, 0, 0, IPL_INVCURS, 225, 0, IPL_TOHIT, 0, 0, IPL_TOHIT, 0, 0, IPL_TOHIT, 0, 0 },
|
||||
{ "Acolyte's Amulet", UITYPE_AMULET, 10, 2, 10000, IPL_MANATOLIFE, 50, 50, IPL_INVCURS, 183, 0, IPL_TOHIT, 0, 0, IPL_TOHIT, 0, 0, IPL_TOHIT, 0, 0, IPL_TOHIT, 0, 0 },
|
||||
{ "Gladiator's Ring", UITYPE_RING, 10, 2, 10000, IPL_LIFETOMANA, 40, 40, IPL_INVCURS, 186, 0, IPL_TOHIT, 0, 0, IPL_TOHIT, 0, 0, IPL_TOHIT, 0, 0, IPL_TOHIT, 0, 0 },
|
||||
#endif
|
||||
{ "", UITYPE_INVALID, 0, 0, 0, IPL_TOHIT, 0, 0, IPL_TOHIT, 0, 0, IPL_TOHIT, 0, 0, IPL_TOHIT, 0, 0, IPL_TOHIT, 0, 0, IPL_TOHIT, 0, 0 },
|
||||
// clang-format on
|
||||
};
|
||||
|
|
|
|||
|
|
@ -319,6 +319,18 @@ int premiumLvlAddHellfire[] = {
|
|||
// clang-format on
|
||||
};
|
||||
|
||||
bool ShouldSkipItem(int i)
|
||||
{
|
||||
if (!gbIsHellfire) {
|
||||
return (i >= 35 && i <= 47) // Hellfire exclusive items
|
||||
|| (i >= 83 && i <= 86) // Oils
|
||||
|| i == 92 // Scroll of Search
|
||||
|| (i >= 161 && i <= 165); // Runes
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int get_ring_max_value(int i)
|
||||
{
|
||||
int j, res;
|
||||
|
|
@ -1353,14 +1365,13 @@ void CreatePlrItems(int p)
|
|||
GetPlrHandSeed(&plr[p].InvBody[INVLOC_HAND_RIGHT]);
|
||||
|
||||
#ifdef _DEBUG
|
||||
if (!debug_mode_key_w) {
|
||||
if (!debug_mode_key_w)
|
||||
#endif
|
||||
{
|
||||
SetPlrHandItem(&plr[p].HoldItem, IDI_WARRCLUB);
|
||||
GetPlrHandSeed(&plr[p].HoldItem);
|
||||
AutoPlace(p, 0, 1, 3, TRUE);
|
||||
#ifdef _DEBUG
|
||||
}
|
||||
#endif
|
||||
|
||||
SetPlrHandItem(&plr[p].SpdList[0], IDI_HEAL);
|
||||
GetPlrHandSeed(&plr[p].SpdList[0]);
|
||||
|
|
@ -1379,7 +1390,7 @@ void CreatePlrItems(int p)
|
|||
GetPlrHandSeed(&plr[p].SpdList[1]);
|
||||
break;
|
||||
case PC_SORCERER:
|
||||
SetPlrHandItem(&plr[p].InvBody[INVLOC_HAND_LEFT], IDI_SORCEROR);
|
||||
SetPlrHandItem(&plr[p].InvBody[INVLOC_HAND_LEFT], gbIsHellfire ? IDI_SORCEROR : 166);
|
||||
GetPlrHandSeed(&plr[p].InvBody[INVLOC_HAND_LEFT]);
|
||||
|
||||
SetPlrHandItem(&plr[p].SpdList[0], gbIsHellfire ? IDI_HEAL : IDI_MANA);
|
||||
|
|
@ -2478,6 +2489,9 @@ int RndItem(int m)
|
|||
|
||||
ri = 0;
|
||||
for (i = 0; AllItemsList[i].iLoc != ILOC_INVALID; i++) {
|
||||
if (ShouldSkipItem(i))
|
||||
continue;
|
||||
|
||||
if (AllItemsList[i].iRnd == IDROP_DOUBLE && monster[m].mLevel >= AllItemsList[i].iMinMLvl
|
||||
&& ri < 512) {
|
||||
ril[ri] = i;
|
||||
|
|
@ -2510,6 +2524,9 @@ int RndUItem(int m)
|
|||
int curlv = items_get_currlevel();
|
||||
ri = 0;
|
||||
for (i = 0; AllItemsList[i].iLoc != ILOC_INVALID; i++) {
|
||||
if (ShouldSkipItem(i))
|
||||
continue;
|
||||
|
||||
okflag = TRUE;
|
||||
if (AllItemsList[i].iRnd == IDROP_NEVER)
|
||||
okflag = FALSE;
|
||||
|
|
@ -2552,6 +2569,9 @@ int RndAllItems()
|
|||
int curlv = items_get_currlevel();
|
||||
ri = 0;
|
||||
for (i = 0; AllItemsList[i].iLoc != ILOC_INVALID; i++) {
|
||||
if (ShouldSkipItem(i))
|
||||
continue;
|
||||
|
||||
if (AllItemsList[i].iRnd != IDROP_NEVER && 2 * curlv >= AllItemsList[i].iMinMLvl && ri < 512) {
|
||||
ril[ri] = i;
|
||||
ri++;
|
||||
|
|
@ -2573,6 +2593,9 @@ int RndTypeItems(int itype, int imid, int lvl)
|
|||
|
||||
ri = 0;
|
||||
for (i = 0; AllItemsList[i].iLoc != ILOC_INVALID; i++) {
|
||||
if (ShouldSkipItem(i))
|
||||
continue;
|
||||
|
||||
okflag = TRUE;
|
||||
if (AllItemsList[i].iRnd == IDROP_NEVER)
|
||||
okflag = FALSE;
|
||||
|
|
@ -2602,6 +2625,8 @@ int CheckUnique(int i, int lvl, int uper, BOOL recreate)
|
|||
numu = 0;
|
||||
memset(uok, 0, sizeof(uok));
|
||||
for (j = 0; UniqueItemList[j].UIItemId != UITYPE_INVALID; j++) {
|
||||
if (!gbIsHellfire && j > 89)
|
||||
break;
|
||||
if (UniqueItemList[j].UIItemId == AllItemsList[item[i].IDidx].iItemId
|
||||
&& lvl >= UniqueItemList[j].UIMinLvl
|
||||
&& (recreate || !UniqueItemFlag[j] || gbMaxPlayers != 1)) {
|
||||
|
|
@ -4488,6 +4513,9 @@ int RndSmithItem(int lvl)
|
|||
|
||||
ri = 0;
|
||||
for (i = 1; AllItemsList[i].iLoc != ILOC_INVALID; i++) {
|
||||
if (ShouldSkipItem(i))
|
||||
continue;
|
||||
|
||||
if (AllItemsList[i].iRnd != IDROP_NEVER && SmithItemOk(i) && lvl >= AllItemsList[i].iMinMLvl
|
||||
&& ri < 512) {
|
||||
ril[ri] = i;
|
||||
|
|
@ -4604,6 +4632,9 @@ int RndPremiumItem(int minlvl, int maxlvl)
|
|||
|
||||
ri = 0;
|
||||
for (i = 1; AllItemsList[i].iLoc != ILOC_INVALID; i++) {
|
||||
if (ShouldSkipItem(i))
|
||||
continue;
|
||||
|
||||
if (AllItemsList[i].iRnd != IDROP_NEVER) {
|
||||
if (PremiumItemOk(i)) {
|
||||
if (AllItemsList[i].iMinMLvl >= minlvl && AllItemsList[i].iMinMLvl <= maxlvl && ri < 512) {
|
||||
|
|
@ -4797,6 +4828,9 @@ int RndWitchItem(int lvl)
|
|||
|
||||
ri = 0;
|
||||
for (i = 1; AllItemsList[i].iLoc != ILOC_INVALID; i++) {
|
||||
if (ShouldSkipItem(i))
|
||||
continue;
|
||||
|
||||
if (AllItemsList[i].iRnd != IDROP_NEVER && WitchItemOk(i) && lvl >= AllItemsList[i].iMinMLvl
|
||||
&& ri < 512) {
|
||||
|
||||
|
|
@ -4931,6 +4965,9 @@ int RndBoyItem(int lvl)
|
|||
|
||||
ri = 0;
|
||||
for (i = 1; AllItemsList[i].iLoc != ILOC_INVALID; i++) {
|
||||
if (ShouldSkipItem(i))
|
||||
continue;
|
||||
|
||||
if (AllItemsList[i].iRnd != IDROP_NEVER && PremiumItemOk(i) && lvl >= AllItemsList[i].iMinMLvl
|
||||
&& ri < 512) {
|
||||
ril[ri] = i;
|
||||
|
|
@ -5147,6 +5184,9 @@ int RndHealerItem(int lvl)
|
|||
|
||||
ri = 0;
|
||||
for (i = 1; AllItemsList[i].iLoc != ILOC_INVALID; i++) {
|
||||
if (ShouldSkipItem(i))
|
||||
continue;
|
||||
|
||||
if (AllItemsList[i].iRnd != IDROP_NEVER && HealerItemOk(i) && lvl >= AllItemsList[i].iMinMLvl
|
||||
&& ri < 512) {
|
||||
ril[ri] = i;
|
||||
|
|
|
|||
|
|
@ -19,15 +19,7 @@ static char BLoad()
|
|||
return *tbuff++;
|
||||
}
|
||||
|
||||
static int WLoad()
|
||||
{
|
||||
int rv = *tbuff++ << 24;
|
||||
rv |= *tbuff++ << 16;
|
||||
rv |= *tbuff++ << 8;
|
||||
rv |= *tbuff++;
|
||||
|
||||
return rv;
|
||||
}
|
||||
#define WLoad ILoad
|
||||
|
||||
static int ILoad()
|
||||
{
|
||||
|
|
@ -183,6 +175,9 @@ static void LoadItemData(ItemStruct *pItem)
|
|||
tbuff += 1; // Alignment
|
||||
CopyInt(tbuff, &pItem->_iStatFlag);
|
||||
CopyInt(tbuff, &pItem->IDidx);
|
||||
if (!gbIsHellfireSaveGame) {
|
||||
pItem->IDidx = RemapItemIdxFromDiablo(pItem->IDidx);
|
||||
}
|
||||
CopyInt(tbuff, &pItem->offs016C);
|
||||
if (gbIsHellfireSaveGame)
|
||||
CopyInt(tbuff, &pItem->_iDamAcFlags);
|
||||
|
|
@ -387,7 +382,13 @@ static void LoadPlayer(int i)
|
|||
CopyChar(tbuff, &pPlayer->pBattleNet);
|
||||
}
|
||||
CopyChar(tbuff, &pPlayer->pManaShield);
|
||||
CopyBytes(tbuff, 3, &pPlayer->bReserved);
|
||||
if (gbIsHellfireSaveGame) {
|
||||
CopyChar(tbuff, &pPlayer->pOriginalCathedral);
|
||||
} else {
|
||||
tbuff += 1;
|
||||
pPlayer->pOriginalCathedral = true;
|
||||
}
|
||||
CopyBytes(tbuff, 2, &pPlayer->bReserved);
|
||||
CopyShort(tbuff, &pPlayer->wReflection);
|
||||
CopyShorts(tbuff, 7, &pPlayer->wReserved);
|
||||
|
||||
|
|
@ -687,17 +688,53 @@ static void LoadPortal(int i)
|
|||
CopyInt(tbuff, &pPortal->setlvl);
|
||||
}
|
||||
|
||||
static bool IsHeaderValid(int magicNumber)
|
||||
int RemapItemIdxFromDiablo(int i)
|
||||
{
|
||||
if (i == IDI_SORCEROR) {
|
||||
return 166;
|
||||
}
|
||||
if (i >= 156) {
|
||||
i += 5; // Hellfire exclusive items
|
||||
}
|
||||
if (i >= 88) {
|
||||
i += 1; // Scroll of Search
|
||||
}
|
||||
if (i >= 83) {
|
||||
i += 4; // Oils
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
int RemapItemIdxToDiablo(int i)
|
||||
{
|
||||
if (i == 166) {
|
||||
return IDI_SORCEROR;
|
||||
}
|
||||
if ((i >= 83 && i <= 86) || i == 92 || i >= 161) {
|
||||
return -1; // Hellfire exclusive items
|
||||
}
|
||||
if (i >= 93) {
|
||||
i -= 1; // Scroll of Search
|
||||
}
|
||||
if (i >= 87) {
|
||||
i -= 4; // Oils
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
bool IsHeaderValid(int magicNumber)
|
||||
{
|
||||
gbIsHellfireSaveGame = false;
|
||||
if (magicNumber == 'SHAR') {
|
||||
return true;
|
||||
} else if (gbIsHellfire && magicNumber == 'SHLF') {
|
||||
} else if (magicNumber == 'SHLF') {
|
||||
gbIsHellfireSaveGame = true;
|
||||
return true;
|
||||
} else if (!gbIsSpawn && magicNumber == 'RETL') {
|
||||
return true;
|
||||
} else if (!gbIsSpawn && gbIsHellfire && magicNumber == 'HELF') {
|
||||
} else if (!gbIsSpawn && magicNumber == 'HELF') {
|
||||
gbIsHellfireSaveGame = true;
|
||||
return true;
|
||||
}
|
||||
|
|
@ -713,14 +750,12 @@ void LoadGame(BOOL firstflag)
|
|||
{
|
||||
int i, j;
|
||||
DWORD dwLen;
|
||||
char szName[MAX_PATH];
|
||||
BYTE *LoadBuff;
|
||||
int _ViewX, _ViewY, _nummonsters, _numitems, _nummissiles, _nobjects;
|
||||
|
||||
FreeGameMem();
|
||||
pfile_remove_temp_files();
|
||||
pfile_get_game_name(szName);
|
||||
LoadBuff = pfile_read(szName, &dwLen);
|
||||
LoadBuff = pfile_read("game", &dwLen);
|
||||
tbuff = LoadBuff;
|
||||
|
||||
if (!IsHeaderValid(ILoad()))
|
||||
|
|
@ -927,10 +962,19 @@ static void OSave(BOOL v)
|
|||
|
||||
static void SaveItem(ItemStruct *pItem)
|
||||
{
|
||||
int idx = RemapItemIdxToDiablo(pItem->IDidx);
|
||||
int iType = pItem->_itype;
|
||||
if (idx != -1) {
|
||||
idx = 0;
|
||||
iType = ITYPE_NONE;
|
||||
}
|
||||
|
||||
CopyInt(&pItem->_iSeed, tbuff);
|
||||
CopyShort(&pItem->_iCreateInfo, tbuff);
|
||||
tbuff += 2; // Alignment
|
||||
CopyInt(&pItem->_itype, tbuff);
|
||||
|
||||
CopyInt(&iType, tbuff);
|
||||
|
||||
CopyInt(&pItem->_ix, tbuff);
|
||||
CopyInt(&pItem->_iy, tbuff);
|
||||
CopyInt(&pItem->_iAnimFlag, tbuff);
|
||||
|
|
@ -999,7 +1043,7 @@ static void SaveItem(ItemStruct *pItem)
|
|||
CopyChar(&pItem->_iMinDex, tbuff);
|
||||
tbuff += 1; // Alignment
|
||||
CopyInt(&pItem->_iStatFlag, tbuff);
|
||||
CopyInt(&pItem->IDidx, tbuff);
|
||||
CopyInt(&idx, tbuff);
|
||||
CopyInt(&pItem->offs016C, tbuff);
|
||||
if (gbIsHellfire)
|
||||
CopyInt(&pItem->_iDamAcFlags, tbuff);
|
||||
|
|
@ -1196,7 +1240,7 @@ static void SavePlayer(int i)
|
|||
else
|
||||
CopyChar(&pPlayer->pBattleNet, tbuff);
|
||||
CopyChar(&pPlayer->pManaShield, tbuff);
|
||||
CopyChar(&pPlayer->pDungMsgs2, tbuff);
|
||||
CopyChar(&pPlayer->pOriginalCathedral, tbuff);
|
||||
CopyBytes(&pPlayer->bReserved, 2, tbuff);
|
||||
CopyShort(&pPlayer->wReflection, tbuff);
|
||||
CopyShorts(&pPlayer->wReserved, 7, tbuff);
|
||||
|
|
@ -1496,7 +1540,6 @@ static void SavePortal(int i)
|
|||
void SaveGame()
|
||||
{
|
||||
int i, j;
|
||||
char szName[MAX_PATH];
|
||||
|
||||
DWORD dwLen = codec_get_encoded_len(FILEBUFF);
|
||||
BYTE *SaveBuff = DiabloAllocPtr(dwLen);
|
||||
|
|
@ -1648,9 +1691,8 @@ void SaveGame()
|
|||
|
||||
OSave(automapflag);
|
||||
WSave(AutoMapScale);
|
||||
pfile_get_game_name(szName);
|
||||
dwLen = codec_get_encoded_len(tbuff - SaveBuff);
|
||||
pfile_write_save_file(szName, SaveBuff, tbuff - SaveBuff, dwLen);
|
||||
pfile_write_save_file("game", SaveBuff, tbuff - SaveBuff, dwLen);
|
||||
mem_free_dbg(SaveBuff);
|
||||
gbValidSaveFile = TRUE;
|
||||
pfile_rename_temp_to_perm();
|
||||
|
|
|
|||
|
|
@ -12,8 +12,12 @@ DEVILUTION_BEGIN_NAMESPACE
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern bool gbIsHellfireSaveGame;
|
||||
extern int giNumberOfLevels;
|
||||
|
||||
int RemapItemIdxFromDiablo(int i);
|
||||
int RemapItemIdxToDiablo(int i);
|
||||
bool IsHeaderValid(int magicNumber);
|
||||
void LoadGame(BOOL firstflag);
|
||||
void SaveGame();
|
||||
void SaveLevel();
|
||||
|
|
|
|||
|
|
@ -913,6 +913,7 @@ void recv_plrinfo(int pnum, TCmdPlrInfoHdr *p, BOOL recv)
|
|||
sgwPackPlrOffsetTbl[pnum] = 0;
|
||||
multi_player_left_msg(pnum, 0);
|
||||
plr[pnum]._pGFXLoad = 0;
|
||||
gbIsHellfireSaveGame = gbIsHellfire;
|
||||
UnPackPlayer(&netplr[pnum], pnum, TRUE);
|
||||
|
||||
if (!recv) {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,11 @@ void PackItem(PkItemStruct *id, ItemStruct *is)
|
|||
if (is->_itype == ITYPE_NONE) {
|
||||
id->idx = 0xFFFF;
|
||||
} else {
|
||||
id->idx = SwapLE16(is->IDidx);
|
||||
int idx = is->IDidx;
|
||||
if (!gbIsHellfire) {
|
||||
idx = RemapItemIdxToDiablo(idx);
|
||||
}
|
||||
id->idx = SwapLE16(idx);
|
||||
if (is->IDidx == IDI_EAR) {
|
||||
id->iCreateInfo = is->_iName[8] | (is->_iName[7] << 8);
|
||||
id->iSeed = SwapLE32(is->_iName[12] | ((is->_iName[11] | ((is->_iName[10] | (is->_iName[9] << 8)) << 8)) << 8));
|
||||
|
|
@ -132,6 +136,9 @@ void UnPackItem(PkItemStruct *is, ItemStruct *id)
|
|||
if (idx == 0xFFFF) {
|
||||
id->_itype = ITYPE_NONE;
|
||||
} else {
|
||||
if (!gbIsHellfireSaveGame) {
|
||||
idx = RemapItemIdxFromDiablo(idx);
|
||||
}
|
||||
if (idx == IDI_EAR) {
|
||||
RecreateEar(
|
||||
MAXITEMS,
|
||||
|
|
|
|||
120
Source/pfile.cpp
120
Source/pfile.cpp
|
|
@ -66,18 +66,27 @@ static DWORD pfile_get_save_num_from_name(const char *name)
|
|||
return i;
|
||||
}
|
||||
|
||||
static BOOL pfile_read_hero(HANDLE archive, PkPlayerStruct *pPack)
|
||||
static BYTE *pfile_read_archive(HANDLE archive, const char *pszName, DWORD *pdwLen)
|
||||
{
|
||||
DWORD nread;
|
||||
HANDLE file;
|
||||
DWORD dwlen;
|
||||
BYTE *buf;
|
||||
|
||||
if (!SFileOpenFileEx(archive, "hero", 0, &file)) {
|
||||
return FALSE;
|
||||
} else {
|
||||
buf = NULL;
|
||||
BOOL ret = FALSE;
|
||||
if (!SFileOpenFileEx(archive, pszName, 0, &file))
|
||||
return NULL;
|
||||
|
||||
*pdwLen = SFileGetFileSize(file, NULL);
|
||||
if (*pdwLen == 0)
|
||||
return NULL;
|
||||
|
||||
buf = DiabloAllocPtr(*pdwLen);
|
||||
if (!SFileReadFile(file, buf, *pdwLen, &nread, NULL))
|
||||
return NULL;
|
||||
SFileCloseFile(file);
|
||||
|
||||
{
|
||||
const char *password;
|
||||
DWORD nSize = 16;
|
||||
|
||||
if (gbIsSpawn) {
|
||||
password = PASSWORD_SPAWN_SINGLE;
|
||||
|
|
@ -89,23 +98,30 @@ static BOOL pfile_read_hero(HANDLE archive, PkPlayerStruct *pPack)
|
|||
password = PASSWORD_MULTI;
|
||||
}
|
||||
|
||||
dwlen = SFileGetFileSize(file, NULL);
|
||||
if (dwlen) {
|
||||
DWORD read;
|
||||
buf = DiabloAllocPtr(dwlen);
|
||||
if (SFileReadFile(file, buf, dwlen, &read, NULL)) {
|
||||
read = codec_decode(buf, dwlen, password);
|
||||
if (read == sizeof(*pPack)) {
|
||||
memcpy(pPack, buf, sizeof(*pPack));
|
||||
ret = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (buf)
|
||||
mem_free_dbg(buf);
|
||||
SFileCloseFile(file);
|
||||
return ret;
|
||||
*pdwLen = codec_decode(buf, *pdwLen, password);
|
||||
if (*pdwLen == 0)
|
||||
return NULL;
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
static BOOL pfile_read_hero(HANDLE archive, PkPlayerStruct *pPack)
|
||||
{
|
||||
DWORD read;
|
||||
BYTE *buf;
|
||||
|
||||
buf = pfile_read_archive(archive, "hero", &read);
|
||||
if (buf == NULL)
|
||||
return FALSE;
|
||||
|
||||
BOOL ret = FALSE;
|
||||
if (read == sizeof(*pPack)) {
|
||||
memcpy(pPack, buf, sizeof(*pPack));
|
||||
ret = TRUE;
|
||||
}
|
||||
|
||||
mem_free_dbg(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void pfile_encode_hero(const PkPlayerStruct *pPack)
|
||||
|
|
@ -262,8 +278,9 @@ BOOL pfile_ui_set_hero_infos(BOOL (*ui_add_hero_info)(_uiheroinfo *))
|
|||
if (pfile_read_hero(archive, &pkplr)) {
|
||||
_uiheroinfo uihero;
|
||||
strcpy(hero_names[i], pkplr.pName);
|
||||
bool hasSaveGame = pfile_archive_contains_game(archive, i);
|
||||
UnPackPlayer(&pkplr, 0, FALSE);
|
||||
game_2_ui_player(plr, &uihero, pfile_archive_contains_game(archive, i));
|
||||
game_2_ui_player(plr, &uihero, hasSaveGame);
|
||||
ui_add_hero_info(&uihero);
|
||||
}
|
||||
pfile_SFileCloseArchive(archive);
|
||||
|
|
@ -275,16 +292,18 @@ BOOL pfile_ui_set_hero_infos(BOOL (*ui_add_hero_info)(_uiheroinfo *))
|
|||
|
||||
BOOL pfile_archive_contains_game(HANDLE hsArchive, DWORD save_num)
|
||||
{
|
||||
HANDLE file;
|
||||
|
||||
if (gbMaxPlayers != 1)
|
||||
return FALSE;
|
||||
|
||||
if (!SFileOpenFileEx(hsArchive, "game", 0, &file))
|
||||
DWORD dwLen;
|
||||
BYTE *gameData = pfile_read_archive(hsArchive, "game", &dwLen);
|
||||
if (gameData == NULL)
|
||||
return FALSE;
|
||||
|
||||
SFileCloseFile(file);
|
||||
return TRUE;
|
||||
int hdr = (gameData[0] << 24) | (gameData[1] << 16) | (gameData[2] << 8) | gameData[3];
|
||||
mem_free_dbg(gameData);
|
||||
|
||||
return IsHeaderValid(hdr);
|
||||
}
|
||||
|
||||
void pfile_ui_set_class_stats(unsigned int player_class_nr, _uidefaultstats *class_stats)
|
||||
|
|
@ -374,8 +393,8 @@ void pfile_read_player_from_save()
|
|||
if (!pfile_read_hero(archive, &pkplr))
|
||||
app_fatal("Unable to load character");
|
||||
|
||||
UnPackPlayer(&pkplr, myplr, FALSE);
|
||||
gbValidSaveFile = pfile_archive_contains_game(archive, save_num);
|
||||
UnPackPlayer(&pkplr, myplr, FALSE);
|
||||
pfile_SFileCloseArchive(archive);
|
||||
}
|
||||
|
||||
|
|
@ -407,11 +426,6 @@ void GetPermLevelNames(char *szPerm)
|
|||
}
|
||||
}
|
||||
|
||||
void pfile_get_game_name(char *dst)
|
||||
{
|
||||
strcpy(dst, "game");
|
||||
}
|
||||
|
||||
static BOOL GetPermSaveNames(DWORD dwIndex, char *szPerm)
|
||||
{
|
||||
const char *fmt;
|
||||
|
|
@ -510,8 +524,8 @@ void pfile_write_save_file(const char *pszName, BYTE *pbData, DWORD dwLen, DWORD
|
|||
|
||||
BYTE *pfile_read(const char *pszName, DWORD *pdwLen)
|
||||
{
|
||||
DWORD save_num, nread;
|
||||
HANDLE archive, save;
|
||||
DWORD save_num;
|
||||
HANDLE archive;
|
||||
BYTE *buf;
|
||||
|
||||
save_num = pfile_get_save_num_from_name(plr[myplr]._pName);
|
||||
|
|
@ -519,37 +533,11 @@ BYTE *pfile_read(const char *pszName, DWORD *pdwLen)
|
|||
if (archive == NULL)
|
||||
app_fatal("Unable to open save file archive");
|
||||
|
||||
if (!SFileOpenFileEx(archive, pszName, 0, &save))
|
||||
app_fatal("Unable to open save file");
|
||||
|
||||
*pdwLen = SFileGetFileSize(save, NULL);
|
||||
if (*pdwLen == 0)
|
||||
app_fatal("Invalid save file");
|
||||
|
||||
buf = DiabloAllocPtr(*pdwLen);
|
||||
if (!SFileReadFile(save, buf, *pdwLen, &nread, NULL))
|
||||
app_fatal("Unable to read save file");
|
||||
SFileCloseFile(save);
|
||||
buf = pfile_read_archive(archive, pszName, pdwLen);
|
||||
pfile_SFileCloseArchive(archive);
|
||||
if (buf == NULL)
|
||||
app_fatal("Invalid %s file", pszName);
|
||||
|
||||
{
|
||||
const char *password;
|
||||
DWORD nSize = 16;
|
||||
|
||||
if (gbIsSpawn) {
|
||||
password = PASSWORD_SPAWN_SINGLE;
|
||||
if (gbMaxPlayers > 1)
|
||||
password = PASSWORD_SPAWN_MULTI;
|
||||
} else {
|
||||
password = PASSWORD_SINGLE;
|
||||
if (gbMaxPlayers > 1)
|
||||
password = PASSWORD_MULTI;
|
||||
}
|
||||
|
||||
*pdwLen = codec_decode(buf, *pdwLen, password);
|
||||
if (*pdwLen == 0)
|
||||
app_fatal("Invalid save file");
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@ BOOL pfile_delete_save(_uiheroinfo *hero_info);
|
|||
void pfile_read_player_from_save();
|
||||
void GetTempLevelNames(char *szTemp);
|
||||
void GetPermLevelNames(char *szPerm);
|
||||
void pfile_get_game_name(char *dst);
|
||||
void pfile_remove_temp_files();
|
||||
void pfile_rename_temp_to_perm();
|
||||
void pfile_write_save_file(const char *pszName, BYTE *pbData, DWORD dwLen, DWORD qwLen);
|
||||
|
|
|
|||
|
|
@ -425,7 +425,7 @@ void LoadUiGFX()
|
|||
LoadMaskedArt("ui_art\\focus.pcx", &ArtFocus[FOCUS_MED], 8);
|
||||
LoadMaskedArt("ui_art\\focus42.pcx", &ArtFocus[FOCUS_BIG], 8);
|
||||
LoadMaskedArt("ui_art\\cursor.pcx", &ArtCursor, 1, 0);
|
||||
LoadArt("ui_art\\heros.pcx", &ArtHero, hellfire_mpq ? 6 : 4);
|
||||
LoadArt("ui_art\\heros.pcx", &ArtHero, gbIsHellfire ? 6 : 4);
|
||||
}
|
||||
|
||||
void UiInitialize()
|
||||
|
|
|
|||
|
|
@ -344,6 +344,7 @@ typedef struct PlayerStruct {
|
|||
unsigned char pBattleNet;
|
||||
BOOLEAN pManaShield;
|
||||
unsigned char pDungMsgs2;
|
||||
BOOLEAN pOriginalCathedral;
|
||||
char bReserved[2];
|
||||
short wReflection;
|
||||
short wReserved[7];
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue