Browse Source

Move local symbols to anonymous namespace

pull/2368/head
Anders Jenbo 5 years ago
parent
commit
4bf4e42230
  1. 65
      Source/lighting.cpp
  2. 6
      Source/lighting.h
  3. 845
      Source/loadsave.cpp
  4. 4
      Source/mainmenu.cpp
  5. 1309
      Source/missiles.cpp
  6. 1
      Source/missiles.h
  7. 5478
      Source/monster.cpp
  8. 54
      Source/monster.h

65
Source/lighting.cpp

@ -13,18 +13,15 @@
namespace devilution {
LightStruct VisionList[MAXVISION];
uint8_t ActiveLights[MAXLIGHTS];
int VisionCount;
int VisionId;
LightStruct Lights[MAXLIGHTS];
uint8_t ActiveLights[MAXLIGHTS];
int ActiveLightCount;
uint8_t lightradius[16][128];
bool dovision;
int VisionCount;
char LightsMax;
bool UpdateLighting;
uint8_t lightblock[64][16][16];
int VisionId;
std::array<uint8_t, LIGHTSIZE> LightTables;
bool DisableLighting;
bool UpdateLighting;
/**
* CrawlTable specifies X- and Y-coordinate deltas from a missile target coordinate.
@ -49,7 +46,7 @@ bool DisableLighting;
* | 526
* +-------> x
*/
const char CrawlTable[2749] = {
const int8_t CrawlTable[2749] = {
// clang-format off
1, // Table 0, offset 0
0, 0,
@ -447,6 +444,12 @@ const uint8_t VisionCrawlTable[23][30] = {
// clang-format on
};
namespace {
uint8_t lightradius[16][128];
bool dovision;
uint8_t lightblock[64][16][16];
/** RadiusAdj maps from VisionCrawlTable index to lighting vision radius adjustment. */
const BYTE RadiusAdj[23] = { 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 4, 3, 2, 2, 2, 1, 1, 1, 0, 0, 0, 0 };
@ -491,6 +494,30 @@ char GetLight(Point position)
return dLight[position.x][position.y];
}
void DoUnLight(int nXPos, int nYPos, int nRadius)
{
nRadius++;
int minX = nXPos - nRadius;
int maxX = nXPos + nRadius;
int minY = nYPos - nRadius;
int maxY = nYPos + nRadius;
minX = std::max(minX, 0);
maxX = std::max(maxX, MAXDUNX);
minY = std::max(minY, 0);
maxY = std::max(maxY, MAXDUNY);
for (int y = minY; y < maxY; y++) {
for (int x = minX; x < maxX; x++) {
if (x >= 0 && x < MAXDUNX && y >= 0 && y < MAXDUNY)
dLight[x][y] = dPreLight[x][y];
}
}
}
} // namespace
void DoLighting(Point position, int nRadius, int lnum)
{
int xoff = 0;
@ -598,28 +625,6 @@ void DoLighting(Point position, int nRadius, int lnum)
}
}
void DoUnLight(int nXPos, int nYPos, int nRadius)
{
nRadius++;
int minX = nXPos - nRadius;
int maxX = nXPos + nRadius;
int minY = nYPos - nRadius;
int maxY = nYPos + nRadius;
minX = std::max(minX, 0);
maxX = std::max(maxX, MAXDUNX);
minY = std::max(minY, 0);
maxY = std::max(maxY, MAXDUNY);
for (int y = minY; y < maxY; y++) {
for (int x = minX; x < maxX; x++) {
if (x >= 0 && x < MAXDUNX && y >= 0 && y < MAXDUNY)
dLight[x][y] = dPreLight[x][y];
}
}
}
void DoUnVision(Point position, int nRadius)
{
nRadius++;

6
Source/lighting.h

@ -43,7 +43,7 @@ extern LightStruct Lights[MAXLIGHTS];
extern uint8_t ActiveLights[MAXLIGHTS];
extern int ActiveLightCount;
extern char LightsMax;
extern std::array<BYTE, LIGHTSIZE> LightTables;
extern std::array<uint8_t, LIGHTSIZE> LightTables;
extern bool DisableLighting;
extern bool UpdateLighting;
@ -73,7 +73,7 @@ void lighting_color_cycling();
/* rdata */
extern const char CrawlTable[2749];
extern const BYTE VisionCrawlTable[23][30];
extern const int8_t CrawlTable[2749];
extern const uint8_t VisionCrawlTable[23][30];
} // namespace devilution

845
Source/loadsave.cpp

@ -33,11 +33,12 @@ namespace devilution {
bool gbIsHellfireSaveGame;
uint8_t giNumberOfLevels;
uint8_t giNumberQuests;
uint8_t giNumberOfSmithPremiumItems;
namespace {
uint8_t giNumberQuests;
uint8_t giNumberOfSmithPremiumItems;
template <class T>
T SwapLE(T in)
{
@ -206,25 +207,6 @@ public:
}
};
} // namespace
void RemoveInvalidItem(ItemStruct *pItem)
{
bool isInvalid = !IsItemAvailable(pItem->IDidx) || !IsUniqueAvailable(pItem->_iUid);
if (!gbIsHellfire) {
isInvalid = isInvalid || (pItem->_itype == ITYPE_STAFF && GetSpellStaffLevel(pItem->_iSpell) == -1);
isInvalid = isInvalid || (pItem->_iMiscId == IMISC_BOOK && GetSpellBookLevel(pItem->_iSpell) == -1);
isInvalid = isInvalid || pItem->_iDamAcFlags != 0;
isInvalid = isInvalid || pItem->_iPrePower > IDI_LASTDIABLO;
isInvalid = isInvalid || pItem->_iSufPower > IDI_LASTDIABLO;
}
if (isInvalid) {
pItem->_itype = ITYPE_NONE;
}
}
static void LoadItemData(LoadHelper *file, ItemStruct *pItem)
{
pItem->_iSeed = file->NextLE<int32_t>();
@ -817,133 +799,6 @@ static void LoadPortal(LoadHelper *file, int i)
pPortal->setlvl = file->NextBool32();
}
_item_indexes RemapItemIdxFromDiablo(_item_indexes i)
{
constexpr auto GetItemIdValue = [](int i) -> int {
if (i == IDI_SORCERER) {
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;
};
return static_cast<_item_indexes>(GetItemIdValue(i));
}
_item_indexes RemapItemIdxToDiablo(_item_indexes i)
{
constexpr auto GetItemIdValue = [](int i) -> int {
if (i == 166) {
return IDI_SORCERER;
}
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;
};
return static_cast<_item_indexes>(GetItemIdValue(i));
}
_item_indexes RemapItemIdxFromSpawn(_item_indexes i)
{
constexpr auto GetItemIdValue = [](int i) {
if (i >= 62) {
i += 9; // Medium and heavy armors
}
if (i >= 96) {
i += 1; // Scroll of Stone Curse
}
if (i >= 98) {
i += 1; // Scroll of Guardian
}
if (i >= 99) {
i += 1; // Scroll of ...
}
if (i >= 101) {
i += 1; // Scroll of Golem
}
if (i >= 102) {
i += 1; // Scroll of None
}
if (i >= 104) {
i += 1; // Scroll of Apocalypse
}
return i;
};
return static_cast<_item_indexes>(GetItemIdValue(i));
}
_item_indexes RemapItemIdxToSpawn(_item_indexes i)
{
constexpr auto GetItemIdValue = [](int i) {
if (i >= 104) {
i -= 1; // Scroll of Apocalypse
}
if (i >= 102) {
i -= 1; // Scroll of None
}
if (i >= 101) {
i -= 1; // Scroll of Golem
}
if (i >= 99) {
i -= 1; // Scroll of ...
}
if (i >= 98) {
i -= 1; // Scroll of Guardian
}
if (i >= 96) {
i -= 1; // Scroll of Stone Curse
}
if (i >= 71) {
i -= 9; // Medium and heavy armors
}
return i;
};
return static_cast<_item_indexes>(GetItemIdValue(i));
}
bool IsHeaderValid(uint32_t magicNumber)
{
gbIsHellfireSaveGame = false;
if (magicNumber == LoadLE32("SHAR")) {
return true;
}
if (magicNumber == LoadLE32("SHLF")) {
gbIsHellfireSaveGame = true;
return true;
}
if (!gbIsSpawn && magicNumber == LoadLE32("RETL")) {
return true;
}
if (!gbIsSpawn && magicNumber == LoadLE32("HELF")) {
gbIsHellfireSaveGame = true;
return true;
}
return false;
}
static void ConvertLevels()
{
// Backup current level state
@ -994,43 +849,6 @@ static void ConvertLevels()
leveltype = tmpLeveltype;
}
void LoadHotkeys()
{
LoadHelper file("hotkeys");
if (!file.IsValid())
return;
auto &myPlayer = Players[MyPlayerId];
for (auto &spellId : myPlayer._pSplHotKey) {
spellId = static_cast<spell_id>(file.NextLE<int32_t>());
}
for (auto &spellType : myPlayer._pSplTHotKey) {
spellType = static_cast<spell_type>(file.NextLE<int8_t>());
}
myPlayer._pRSpell = static_cast<spell_id>(file.NextLE<int32_t>());
myPlayer._pRSplType = static_cast<spell_type>(file.NextLE<int8_t>());
}
void SaveHotkeys()
{
auto &myPlayer = Players[MyPlayerId];
const size_t nHotkeyTypes = sizeof(myPlayer._pSplHotKey) / sizeof(myPlayer._pSplHotKey[0]);
const size_t nHotkeySpells = sizeof(myPlayer._pSplTHotKey) / sizeof(myPlayer._pSplTHotKey[0]);
SaveHelper file("hotkeys", (nHotkeyTypes * 4) + nHotkeySpells + 4 + 1);
for (auto &spellId : myPlayer._pSplHotKey) {
file.WriteLE<int32_t>(spellId);
}
for (auto &spellType : myPlayer._pSplTHotKey) {
file.WriteLE<uint8_t>(spellType);
}
file.WriteLE<int32_t>(myPlayer._pRSpell);
file.WriteLE<uint8_t>(myPlayer._pRSplType);
}
static void LoadMatchingItems(LoadHelper *file, const int n, ItemStruct *pItem)
{
ItemStruct tempItem;
@ -1045,31 +863,6 @@ static void LoadMatchingItems(LoadHelper *file, const int n, ItemStruct *pItem)
}
}
void LoadHeroItems(PlayerStruct &player)
{
LoadHelper file("heroitems");
if (!file.IsValid())
return;
gbIsHellfireSaveGame = file.NextBool8();
LoadMatchingItems(&file, NUM_INVLOC, player.InvBody);
LoadMatchingItems(&file, NUM_INV_GRID_ELEM, player.InvList);
LoadMatchingItems(&file, MAXBELTITEMS, player.SpdList);
gbIsHellfireSaveGame = gbIsHellfire;
}
void RemoveEmptyInventory(PlayerStruct &player)
{
for (int i = NUM_INV_GRID_ELEM; i > 0; i--) {
int idx = player.InvGrid[i - 1];
if (idx > 0 && player.InvList[idx - 1].isEmpty()) {
player.RemoveInvItem(idx - 1);
}
}
}
void RemoveEmptyLevelItems()
{
for (int i = ActiveItemCount; i > 0; i--) {
@ -1081,219 +874,17 @@ void RemoveEmptyLevelItems()
}
}
/**
* @brief Load game state
* @param firstflag Can be set to false if we are simply reloading the current game
*/
void LoadGame(bool firstflag)
static void SaveItem(SaveHelper *file, ItemStruct *pItem)
{
FreeGameMem();
pfile_remove_temp_files();
LoadHelper file("game");
if (!file.IsValid())
app_fatal("%s", _("Unable to open save file archive"));
if (!IsHeaderValid(file.NextLE<uint32_t>()))
app_fatal("%s", _("Invalid save file"));
if (gbIsHellfireSaveGame) {
giNumberOfLevels = 25;
giNumberQuests = 24;
giNumberOfSmithPremiumItems = 15;
} else {
// Todo initialize additional levels and quests if we are running Hellfire
giNumberOfLevels = 17;
giNumberQuests = 16;
giNumberOfSmithPremiumItems = 6;
}
setlevel = file.NextBool8();
setlvlnum = static_cast<_setlevels>(file.NextBE<uint32_t>());
currlevel = file.NextBE<uint32_t>();
leveltype = static_cast<dungeon_type>(file.NextBE<uint32_t>());
if (!setlevel)
leveltype = gnLevelTypeTbl[currlevel];
int viewX = file.NextBE<int32_t>();
int viewY = file.NextBE<int32_t>();
invflag = file.NextBool8();
chrflag = file.NextBool8();
int tmpNummonsters = file.NextBE<int32_t>();
int tmpNumitems = file.NextBE<int32_t>();
int tmpNummissiles = file.NextBE<int32_t>();
int tmpNobjects = file.NextBE<int32_t>();
if (!gbIsHellfire && currlevel > 17)
app_fatal("%s", _("Player is on a Hellfire only level"));
for (uint8_t i = 0; i < giNumberOfLevels; i++) {
glSeedTbl[i] = file.NextBE<uint32_t>();
file.Skip(4); // Skip loading gnLevelTypeTbl
}
LoadPlayer(&file, MyPlayerId);
sgGameInitInfo.nDifficulty = Players[MyPlayerId].pDifficulty;
if (sgGameInitInfo.nDifficulty < DIFF_NORMAL || sgGameInitInfo.nDifficulty > DIFF_HELL)
sgGameInitInfo.nDifficulty = DIFF_NORMAL;
for (int i = 0; i < giNumberQuests; i++)
LoadQuest(&file, i);
for (int i = 0; i < MAXPORTAL; i++)
LoadPortal(&file, i);
if (gbIsHellfireSaveGame != gbIsHellfire) {
ConvertLevels();
RemoveEmptyInventory(Players[MyPlayerId]);
}
LoadGameLevel(firstflag, ENTRY_LOAD);
SyncInitPlr(MyPlayerId);
SyncPlrAnim(MyPlayerId);
ViewX = viewX;
ViewY = viewY;
ActiveMonsterCount = tmpNummonsters;
ActiveItemCount = tmpNumitems;
ActiveMissileCount = tmpNummissiles;
ActiveObjectCount = tmpNobjects;
for (int &monstkill : MonsterKillCounts)
monstkill = file.NextBE<int32_t>();
if (leveltype != DTYPE_TOWN) {
for (int &monsterId : ActiveMonsters)
monsterId = file.NextBE<int32_t>();
for (int i = 0; i < ActiveMonsterCount; i++)
LoadMonster(&file, ActiveMonsters[i]);
for (int &missileId : ActiveMissiles)
missileId = file.NextLE<int8_t>();
for (int &missileId : AvailableMissiles)
missileId = file.NextLE<int8_t>();
for (int i = 0; i < ActiveMissileCount; i++)
LoadMissile(&file, ActiveMissiles[i]);
for (int &objectId : ActiveObjects)
objectId = file.NextLE<int8_t>();
for (int &objectId : AvailableObjects)
objectId = file.NextLE<int8_t>();
for (int i = 0; i < ActiveObjectCount; i++)
LoadObject(&file, ActiveObjects[i]);
for (int i = 0; i < ActiveObjectCount; i++)
SyncObjectAnim(Objects[ActiveObjects[i]]);
ActiveLightCount = file.NextBE<int32_t>();
for (uint8_t &lightId : ActiveLights)
lightId = file.NextLE<uint8_t>();
for (int i = 0; i < ActiveLightCount; i++)
LoadLighting(&file, &Lights[ActiveLights[i]]);
VisionId = file.NextBE<int32_t>();
VisionCount = file.NextBE<int32_t>();
for (int i = 0; i < VisionCount; i++)
LoadLighting(&file, &VisionList[i]);
}
for (int &itemId : ActiveItems)
itemId = file.NextLE<int8_t>();
for (int &itemId : AvailableItems)
itemId = file.NextLE<int8_t>();
for (int i = 0; i < ActiveItemCount; i++)
LoadItem(&file, ActiveItems[i]);
for (bool &uniqueItemFlag : UniqueItemFlags)
uniqueItemFlag = file.NextBool8();
for (int j = 0; j < MAXDUNY; j++) {
for (int i = 0; i < MAXDUNX; i++) // NOLINT(modernize-loop-convert)
dLight[i][j] = file.NextLE<int8_t>();
}
for (int j = 0; j < MAXDUNY; j++) {
for (int i = 0; i < MAXDUNX; i++) // NOLINT(modernize-loop-convert)
dFlags[i][j] = file.NextLE<int8_t>();
}
for (int j = 0; j < MAXDUNY; j++) {
for (int i = 0; i < MAXDUNX; i++) // NOLINT(modernize-loop-convert)
dPlayer[i][j] = file.NextLE<int8_t>();
}
for (int j = 0; j < MAXDUNY; j++) {
for (int i = 0; i < MAXDUNX; i++) // NOLINT(modernize-loop-convert)
dItem[i][j] = file.NextLE<int8_t>();
}
if (leveltype != DTYPE_TOWN) {
for (int j = 0; j < MAXDUNY; j++) {
for (int i = 0; i < MAXDUNX; i++) // NOLINT(modernize-loop-convert)
dMonster[i][j] = file.NextBE<int32_t>();
}
for (int j = 0; j < MAXDUNY; j++) {
for (int i = 0; i < MAXDUNX; i++) // NOLINT(modernize-loop-convert)
dDead[i][j] = file.NextLE<int8_t>();
}
for (int j = 0; j < MAXDUNY; j++) {
for (int i = 0; i < MAXDUNX; i++) // NOLINT(modernize-loop-convert)
dObject[i][j] = file.NextLE<int8_t>();
}
for (int j = 0; j < MAXDUNY; j++) {
for (int i = 0; i < MAXDUNX; i++) // NOLINT(modernize-loop-convert)
dLight[i][j] = file.NextLE<int8_t>();
}
for (int j = 0; j < MAXDUNY; j++) {
for (int i = 0; i < MAXDUNX; i++) // NOLINT(modernize-loop-convert)
dPreLight[i][j] = file.NextLE<int8_t>();
}
for (int j = 0; j < DMAXY; j++) {
for (int i = 0; i < DMAXX; i++) // NOLINT(modernize-loop-convert)
AutomapView[i][j] = file.NextBool8();
}
for (int j = 0; j < MAXDUNY; j++) {
for (int i = 0; i < MAXDUNX; i++) // NOLINT(modernize-loop-convert)
dMissile[i][j] = file.NextLE<int8_t>();
}
}
numpremium = file.NextBE<int32_t>();
premiumlevel = file.NextBE<int32_t>();
for (int i = 0; i < giNumberOfSmithPremiumItems; i++)
LoadPremium(&file, i);
if (gbIsHellfire && !gbIsHellfireSaveGame)
SpawnPremium(MyPlayerId);
AutomapActive = file.NextBool8();
AutoMapScale = file.NextBE<int32_t>();
AutomapZoomReset();
ResyncQuests();
if (leveltype != DTYPE_TOWN)
ProcessLightList();
RedoPlayerVision();
ProcessVisionList();
missiles_process_charge();
ResetPal();
NewCursor(CURSOR_HAND);
gbProcessPlayers = true;
if (gbIsHellfireSaveGame != gbIsHellfire) {
RemoveEmptyLevelItems();
SaveGame();
}
gbIsHellfireSaveGame = gbIsHellfire;
}
static void SaveItem(SaveHelper *file, ItemStruct *pItem)
{
auto idx = pItem->IDidx;
if (!gbIsHellfire)
idx = RemapItemIdxToDiablo(idx);
if (gbIsSpawn)
idx = RemapItemIdxToSpawn(idx);
int iType = pItem->_itype;
if (idx == -1) {
idx = _item_indexes::IDI_GOLD;
iType = ITYPE_NONE;
auto idx = pItem->IDidx;
if (!gbIsHellfire)
idx = RemapItemIdxToDiablo(idx);
if (gbIsSpawn)
idx = RemapItemIdxToSpawn(idx);
int iType = pItem->_itype;
if (idx == -1) {
idx = _item_indexes::IDI_GOLD;
iType = ITYPE_NONE;
}
file->WriteLE<int32_t>(pItem->_iSeed);
@ -1856,6 +1447,416 @@ static void SavePortal(SaveHelper *file, int i)
const int DiabloItemSaveSize = 368;
const int HellfireItemSaveSize = 372;
} // namespace
void RemoveInvalidItem(ItemStruct *pItem)
{
bool isInvalid = !IsItemAvailable(pItem->IDidx) || !IsUniqueAvailable(pItem->_iUid);
if (!gbIsHellfire) {
isInvalid = isInvalid || (pItem->_itype == ITYPE_STAFF && GetSpellStaffLevel(pItem->_iSpell) == -1);
isInvalid = isInvalid || (pItem->_iMiscId == IMISC_BOOK && GetSpellBookLevel(pItem->_iSpell) == -1);
isInvalid = isInvalid || pItem->_iDamAcFlags != 0;
isInvalid = isInvalid || pItem->_iPrePower > IDI_LASTDIABLO;
isInvalid = isInvalid || pItem->_iSufPower > IDI_LASTDIABLO;
}
if (isInvalid) {
pItem->_itype = ITYPE_NONE;
}
}
_item_indexes RemapItemIdxFromDiablo(_item_indexes i)
{
constexpr auto GetItemIdValue = [](int i) -> int {
if (i == IDI_SORCERER) {
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;
};
return static_cast<_item_indexes>(GetItemIdValue(i));
}
_item_indexes RemapItemIdxToDiablo(_item_indexes i)
{
constexpr auto GetItemIdValue = [](int i) -> int {
if (i == 166) {
return IDI_SORCERER;
}
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;
};
return static_cast<_item_indexes>(GetItemIdValue(i));
}
_item_indexes RemapItemIdxFromSpawn(_item_indexes i)
{
constexpr auto GetItemIdValue = [](int i) {
if (i >= 62) {
i += 9; // Medium and heavy armors
}
if (i >= 96) {
i += 1; // Scroll of Stone Curse
}
if (i >= 98) {
i += 1; // Scroll of Guardian
}
if (i >= 99) {
i += 1; // Scroll of ...
}
if (i >= 101) {
i += 1; // Scroll of Golem
}
if (i >= 102) {
i += 1; // Scroll of None
}
if (i >= 104) {
i += 1; // Scroll of Apocalypse
}
return i;
};
return static_cast<_item_indexes>(GetItemIdValue(i));
}
_item_indexes RemapItemIdxToSpawn(_item_indexes i)
{
constexpr auto GetItemIdValue = [](int i) {
if (i >= 104) {
i -= 1; // Scroll of Apocalypse
}
if (i >= 102) {
i -= 1; // Scroll of None
}
if (i >= 101) {
i -= 1; // Scroll of Golem
}
if (i >= 99) {
i -= 1; // Scroll of ...
}
if (i >= 98) {
i -= 1; // Scroll of Guardian
}
if (i >= 96) {
i -= 1; // Scroll of Stone Curse
}
if (i >= 71) {
i -= 9; // Medium and heavy armors
}
return i;
};
return static_cast<_item_indexes>(GetItemIdValue(i));
}
bool IsHeaderValid(uint32_t magicNumber)
{
gbIsHellfireSaveGame = false;
if (magicNumber == LoadLE32("SHAR")) {
return true;
}
if (magicNumber == LoadLE32("SHLF")) {
gbIsHellfireSaveGame = true;
return true;
}
if (!gbIsSpawn && magicNumber == LoadLE32("RETL")) {
return true;
}
if (!gbIsSpawn && magicNumber == LoadLE32("HELF")) {
gbIsHellfireSaveGame = true;
return true;
}
return false;
}
void LoadHotkeys()
{
LoadHelper file("hotkeys");
if (!file.IsValid())
return;
auto &myPlayer = Players[MyPlayerId];
for (auto &spellId : myPlayer._pSplHotKey) {
spellId = static_cast<spell_id>(file.NextLE<int32_t>());
}
for (auto &spellType : myPlayer._pSplTHotKey) {
spellType = static_cast<spell_type>(file.NextLE<int8_t>());
}
myPlayer._pRSpell = static_cast<spell_id>(file.NextLE<int32_t>());
myPlayer._pRSplType = static_cast<spell_type>(file.NextLE<int8_t>());
}
void SaveHotkeys()
{
auto &myPlayer = Players[MyPlayerId];
const size_t nHotkeyTypes = sizeof(myPlayer._pSplHotKey) / sizeof(myPlayer._pSplHotKey[0]);
const size_t nHotkeySpells = sizeof(myPlayer._pSplTHotKey) / sizeof(myPlayer._pSplTHotKey[0]);
SaveHelper file("hotkeys", (nHotkeyTypes * 4) + nHotkeySpells + 4 + 1);
for (auto &spellId : myPlayer._pSplHotKey) {
file.WriteLE<int32_t>(spellId);
}
for (auto &spellType : myPlayer._pSplTHotKey) {
file.WriteLE<uint8_t>(spellType);
}
file.WriteLE<int32_t>(myPlayer._pRSpell);
file.WriteLE<uint8_t>(myPlayer._pRSplType);
}
void LoadHeroItems(PlayerStruct &player)
{
LoadHelper file("heroitems");
if (!file.IsValid())
return;
gbIsHellfireSaveGame = file.NextBool8();
LoadMatchingItems(&file, NUM_INVLOC, player.InvBody);
LoadMatchingItems(&file, NUM_INV_GRID_ELEM, player.InvList);
LoadMatchingItems(&file, MAXBELTITEMS, player.SpdList);
gbIsHellfireSaveGame = gbIsHellfire;
}
void RemoveEmptyInventory(PlayerStruct &player)
{
for (int i = NUM_INV_GRID_ELEM; i > 0; i--) {
int idx = player.InvGrid[i - 1];
if (idx > 0 && player.InvList[idx - 1].isEmpty()) {
player.RemoveInvItem(idx - 1);
}
}
}
/**
* @brief Load game state
* @param firstflag Can be set to false if we are simply reloading the current game
*/
void LoadGame(bool firstflag)
{
FreeGameMem();
pfile_remove_temp_files();
LoadHelper file("game");
if (!file.IsValid())
app_fatal("%s", _("Unable to open save file archive"));
if (!IsHeaderValid(file.NextLE<uint32_t>()))
app_fatal("%s", _("Invalid save file"));
if (gbIsHellfireSaveGame) {
giNumberOfLevels = 25;
giNumberQuests = 24;
giNumberOfSmithPremiumItems = 15;
} else {
// Todo initialize additional levels and quests if we are running Hellfire
giNumberOfLevels = 17;
giNumberQuests = 16;
giNumberOfSmithPremiumItems = 6;
}
setlevel = file.NextBool8();
setlvlnum = static_cast<_setlevels>(file.NextBE<uint32_t>());
currlevel = file.NextBE<uint32_t>();
leveltype = static_cast<dungeon_type>(file.NextBE<uint32_t>());
if (!setlevel)
leveltype = gnLevelTypeTbl[currlevel];
int viewX = file.NextBE<int32_t>();
int viewY = file.NextBE<int32_t>();
invflag = file.NextBool8();
chrflag = file.NextBool8();
int tmpNummonsters = file.NextBE<int32_t>();
int tmpNumitems = file.NextBE<int32_t>();
int tmpNummissiles = file.NextBE<int32_t>();
int tmpNobjects = file.NextBE<int32_t>();
if (!gbIsHellfire && currlevel > 17)
app_fatal("%s", _("Player is on a Hellfire only level"));
for (uint8_t i = 0; i < giNumberOfLevels; i++) {
glSeedTbl[i] = file.NextBE<uint32_t>();
file.Skip(4); // Skip loading gnLevelTypeTbl
}
LoadPlayer(&file, MyPlayerId);
sgGameInitInfo.nDifficulty = Players[MyPlayerId].pDifficulty;
if (sgGameInitInfo.nDifficulty < DIFF_NORMAL || sgGameInitInfo.nDifficulty > DIFF_HELL)
sgGameInitInfo.nDifficulty = DIFF_NORMAL;
for (int i = 0; i < giNumberQuests; i++)
LoadQuest(&file, i);
for (int i = 0; i < MAXPORTAL; i++)
LoadPortal(&file, i);
if (gbIsHellfireSaveGame != gbIsHellfire) {
ConvertLevels();
RemoveEmptyInventory(Players[MyPlayerId]);
}
LoadGameLevel(firstflag, ENTRY_LOAD);
SyncInitPlr(MyPlayerId);
SyncPlrAnim(MyPlayerId);
ViewX = viewX;
ViewY = viewY;
ActiveMonsterCount = tmpNummonsters;
ActiveItemCount = tmpNumitems;
ActiveMissileCount = tmpNummissiles;
ActiveObjectCount = tmpNobjects;
for (int &monstkill : MonsterKillCounts)
monstkill = file.NextBE<int32_t>();
if (leveltype != DTYPE_TOWN) {
for (int &monsterId : ActiveMonsters)
monsterId = file.NextBE<int32_t>();
for (int i = 0; i < ActiveMonsterCount; i++)
LoadMonster(&file, ActiveMonsters[i]);
for (int &missileId : ActiveMissiles)
missileId = file.NextLE<int8_t>();
for (int &missileId : AvailableMissiles)
missileId = file.NextLE<int8_t>();
for (int i = 0; i < ActiveMissileCount; i++)
LoadMissile(&file, ActiveMissiles[i]);
for (int &objectId : ActiveObjects)
objectId = file.NextLE<int8_t>();
for (int &objectId : AvailableObjects)
objectId = file.NextLE<int8_t>();
for (int i = 0; i < ActiveObjectCount; i++)
LoadObject(&file, ActiveObjects[i]);
for (int i = 0; i < ActiveObjectCount; i++)
SyncObjectAnim(Objects[ActiveObjects[i]]);
ActiveLightCount = file.NextBE<int32_t>();
for (uint8_t &lightId : ActiveLights)
lightId = file.NextLE<uint8_t>();
for (int i = 0; i < ActiveLightCount; i++)
LoadLighting(&file, &Lights[ActiveLights[i]]);
VisionId = file.NextBE<int32_t>();
VisionCount = file.NextBE<int32_t>();
for (int i = 0; i < VisionCount; i++)
LoadLighting(&file, &VisionList[i]);
}
for (int &itemId : ActiveItems)
itemId = file.NextLE<int8_t>();
for (int &itemId : AvailableItems)
itemId = file.NextLE<int8_t>();
for (int i = 0; i < ActiveItemCount; i++)
LoadItem(&file, ActiveItems[i]);
for (bool &uniqueItemFlag : UniqueItemFlags)
uniqueItemFlag = file.NextBool8();
for (int j = 0; j < MAXDUNY; j++) {
for (int i = 0; i < MAXDUNX; i++) // NOLINT(modernize-loop-convert)
dLight[i][j] = file.NextLE<int8_t>();
}
for (int j = 0; j < MAXDUNY; j++) {
for (int i = 0; i < MAXDUNX; i++) // NOLINT(modernize-loop-convert)
dFlags[i][j] = file.NextLE<int8_t>();
}
for (int j = 0; j < MAXDUNY; j++) {
for (int i = 0; i < MAXDUNX; i++) // NOLINT(modernize-loop-convert)
dPlayer[i][j] = file.NextLE<int8_t>();
}
for (int j = 0; j < MAXDUNY; j++) {
for (int i = 0; i < MAXDUNX; i++) // NOLINT(modernize-loop-convert)
dItem[i][j] = file.NextLE<int8_t>();
}
if (leveltype != DTYPE_TOWN) {
for (int j = 0; j < MAXDUNY; j++) {
for (int i = 0; i < MAXDUNX; i++) // NOLINT(modernize-loop-convert)
dMonster[i][j] = file.NextBE<int32_t>();
}
for (int j = 0; j < MAXDUNY; j++) {
for (int i = 0; i < MAXDUNX; i++) // NOLINT(modernize-loop-convert)
dDead[i][j] = file.NextLE<int8_t>();
}
for (int j = 0; j < MAXDUNY; j++) {
for (int i = 0; i < MAXDUNX; i++) // NOLINT(modernize-loop-convert)
dObject[i][j] = file.NextLE<int8_t>();
}
for (int j = 0; j < MAXDUNY; j++) {
for (int i = 0; i < MAXDUNX; i++) // NOLINT(modernize-loop-convert)
dLight[i][j] = file.NextLE<int8_t>();
}
for (int j = 0; j < MAXDUNY; j++) {
for (int i = 0; i < MAXDUNX; i++) // NOLINT(modernize-loop-convert)
dPreLight[i][j] = file.NextLE<int8_t>();
}
for (int j = 0; j < DMAXY; j++) {
for (int i = 0; i < DMAXX; i++) // NOLINT(modernize-loop-convert)
AutomapView[i][j] = file.NextBool8();
}
for (int j = 0; j < MAXDUNY; j++) {
for (int i = 0; i < MAXDUNX; i++) // NOLINT(modernize-loop-convert)
dMissile[i][j] = file.NextLE<int8_t>();
}
}
numpremium = file.NextBE<int32_t>();
premiumlevel = file.NextBE<int32_t>();
for (int i = 0; i < giNumberOfSmithPremiumItems; i++)
LoadPremium(&file, i);
if (gbIsHellfire && !gbIsHellfireSaveGame)
SpawnPremium(MyPlayerId);
AutomapActive = file.NextBool8();
AutoMapScale = file.NextBE<int32_t>();
AutomapZoomReset();
ResyncQuests();
if (leveltype != DTYPE_TOWN)
ProcessLightList();
RedoPlayerVision();
ProcessVisionList();
missiles_process_charge();
ResetPal();
NewCursor(CURSOR_HAND);
gbProcessPlayers = true;
if (gbIsHellfireSaveGame != gbIsHellfire) {
RemoveEmptyLevelItems();
SaveGame();
}
gbIsHellfireSaveGame = gbIsHellfire;
}
void SaveHeroItems(PlayerStruct &player)
{
size_t itemCount = NUM_INVLOC + NUM_INV_GRID_ELEM + MAXBELTITEMS;

4
Source/mainmenu.cpp

@ -16,7 +16,7 @@ namespace devilution {
char gszHero[16];
/* data */
namespace {
/** The active music track id for the main menu. */
uint8_t menu_music_track_id = TMUSIC_INTRO;
@ -76,6 +76,8 @@ static void MainmenuPlayIntro()
mainmenu_refresh_music();
}
} // namespace
bool mainmenu_select_hero_dialog(GameData *gameData)
{
_selhero_selections dlgresult = SELHERO_NEW_DUNGEON;

1309
Source/missiles.cpp

File diff suppressed because it is too large Load Diff

1
Source/missiles.h

@ -129,7 +129,6 @@ Direction16 GetDirection16(Point p1, Point p2);
void DeleteMissile(int mi, int i);
bool MonsterTrapHit(int m, int mindam, int maxdam, int dist, int t, bool shift);
bool PlayerMHit(int pnum, int m, int dist, int mind, int maxd, int mtype, bool shift, int earflag, bool *blocked);
void SetMissAnim(int mi, int animtype);
void SetMissDir(int mi, int dir);
void LoadMissileGFX(BYTE mi);
void InitMissileGFX();

5478
Source/monster.cpp

File diff suppressed because it is too large Load Diff

54
Source/monster.h

@ -228,13 +228,9 @@ extern bool sgbSaveSoundOn;
void InitLevelMonsters();
void GetLevelMTypes();
void InitMonsterGFX(int monst);
void InitMonster(int i, Direction rd, int mtype, Point position);
void ClrAllMonsters();
void monster_some_crypt();
void PlaceGroup(int mtype, int num, int leaderf, int leader);
void InitMonsters();
void SetMapMonsters(const uint16_t *dunData, Point startPosition);
void DeleteMonster(int i);
int AddMonster(Point position, Direction dir, int mtype, bool InMap);
void AddDoppelganger(MonsterStruct &monster);
bool M_Talker(int i);
@ -244,60 +240,16 @@ void M_GetKnockback(int i);
void M_StartHit(int i, int pnum, int dam);
void M_StartKill(int i, int pnum);
void M_SyncStartKill(int i, Point position, int pnum);
void M_Teleport(int i);
void M_UpdateLeader(int i);
void DoEnding();
void PrepDoEnding();
void M_WalkDir(int i, Direction md);
void MAI_Zombie(int i);
void MAI_SkelSd(int i);
void MAI_Snake(int i);
void MAI_Bat(int i);
void MAI_SkelBow(int i);
void MAI_Fat(int i);
void MAI_Sneak(int i);
void MAI_Fireman(int i);
void MAI_Fallen(int i);
void MAI_Cleaver(int i);
void MAI_Round(int i, bool special);
void MAI_GoatMc(int i);
void MAI_Ranged(int i, missile_id missileType, bool special);
void MAI_GoatBow(int i);
void MAI_Succ(int i);
void MAI_Lich(int i);
void MAI_ArchLich(int i);
void MAI_Psychorb(int i);
void MAI_Necromorb(int i);
void MAI_AcidUniq(int i);
void MAI_Firebat(int i);
void MAI_Torchant(int i);
void MAI_Scav(int i);
void MAI_Garg(int i);
void MAI_RoundRanged(int i, missile_id missileType, bool checkdoors, int dam, int lessmissiles);
void MAI_Magma(int i);
void MAI_Storm(int i);
void MAI_BoneDemon(int i);
void MAI_Acid(int i);
void MAI_Diablo(int i);
void MAI_Mega(int i);
void MAI_Golum(int i);
void MAI_SkelKing(int i);
void MAI_Rhino(int i);
void MAI_HorkDemon(int i);
void MAI_Counselor(int i);
void MAI_Garbud(int i);
void MAI_Zhar(int i);
void MAI_SnotSpil(int i);
void MAI_Lazurus(int i);
void MAI_Lazhelp(int i);
void MAI_Lachdanan(int i);
void MAI_Warlord(int i);
void DeleteMonsterList();
void ProcessMonsters();
void FreeMonsters();
bool DirOK(int i, Direction mdir);
bool PosOkMissile(int entity, Point position);
bool LineClearSolid(Point startPoint, Point endPoint);
bool LineClearMissile(Point startPoint, Point endPoint);
bool LineClear(bool (*Clear)(int, Point), int entity, Point startPoint, Point endPoint);
void SyncMonsterAnim(int i);
@ -306,12 +258,8 @@ void PrintMonstHistory(int mt);
void PrintUniqueHistory();
void MissToMonst(int i, Point position);
bool PosOkMonst(int i, Point position);
bool monster_posok(int i, Point position);
bool PosOkMonst2(int i, Point position);
bool PosOkMonst3(int i, Point position);
bool IsSkel(int mt);
bool IsGoat(int mt);
int M_SpawnSkel(Point position, Direction dir);
bool SpawnSkeleton(int ii, Point position);
int PreSpawnSkeleton();
void TalktoMonster(int i);
@ -321,8 +269,6 @@ bool CheckMonsterHit(int m, bool *ret);
int encode_enemy(int m);
void decode_enemy(int m, int enemy);
/* data */
extern Direction left[8];
extern Direction right[8];
extern Direction opposite[8];

Loading…
Cancel
Save