|
|
|
|
#include "diablo.h"
|
|
|
|
|
|
|
|
|
|
DEVILUTION_BEGIN_NAMESPACE
|
|
|
|
|
|
|
|
|
|
BYTE *tbuff;
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
tbuff = LoadBuff;
|
|
|
|
|
|
|
|
|
|
if (ILoad() != 'RETL')
|
|
|
|
|
app_fatal("Invalid save file");
|
|
|
|
|
|
|
|
|
|
setlevel = OLoad();
|
|
|
|
|
setlvlnum = WLoad();
|
|
|
|
|
currlevel = WLoad();
|
|
|
|
|
leveltype = WLoad();
|
|
|
|
|
_ViewX = WLoad();
|
|
|
|
|
_ViewY = WLoad();
|
|
|
|
|
invflag = OLoad();
|
|
|
|
|
chrflag = OLoad();
|
|
|
|
|
_nummonsters = WLoad();
|
|
|
|
|
_numitems = WLoad();
|
|
|
|
|
_nummissiles = WLoad();
|
|
|
|
|
_nobjects = WLoad();
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < NUMLEVELS; i++) {
|
|
|
|
|
glSeedTbl[i] = ILoad();
|
|
|
|
|
gnLevelTypeTbl[i] = WLoad();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LoadPlayer(myplr);
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < MAXQUESTS; i++)
|
|
|
|
|
LoadQuest(i);
|
|
|
|
|
for (i = 0; i < MAXPORTAL; i++)
|
|
|
|
|
LoadPortal(i);
|
|
|
|
|
|
|
|
|
|
LoadGameLevel(firstflag, 4);
|
|
|
|
|
SyncInitPlr(myplr);
|
|
|
|
|
SyncPlrAnim(myplr);
|
|
|
|
|
|
|
|
|
|
ViewX = _ViewX;
|
|
|
|
|
ViewY = _ViewY;
|
|
|
|
|
nummonsters = _nummonsters;
|
|
|
|
|
numitems = _numitems;
|
|
|
|
|
nummissiles = _nummissiles;
|
|
|
|
|
nobjects = _nobjects;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < MAXMONSTERS; i++)
|
|
|
|
|
monstkills[i] = ILoad();
|
|
|
|
|
|
|
|
|
|
if (leveltype != DTYPE_TOWN) {
|
|
|
|
|
for (i = 0; i < MAXMONSTERS; i++)
|
|
|
|
|
monstactive[i] = WLoad();
|
|
|
|
|
for (i = 0; i < nummonsters; i++)
|
|
|
|
|
LoadMonster(monstactive[i]);
|
|
|
|
|
for (i = 0; i < MAXMISSILES; i++)
|
|
|
|
|
missileactive[i] = BLoad();
|
|
|
|
|
for (i = 0; i < MAXMISSILES; i++)
|
|
|
|
|
missileavail[i] = BLoad();
|
|
|
|
|
for (i = 0; i < nummissiles; i++)
|
|
|
|
|
LoadMissile(missileactive[i]);
|
|
|
|
|
for (i = 0; i < MAXOBJECTS; i++)
|
|
|
|
|
objectactive[i] = BLoad();
|
|
|
|
|
for (i = 0; i < MAXOBJECTS; i++)
|
|
|
|
|
objectavail[i] = BLoad();
|
|
|
|
|
for (i = 0; i < nobjects; i++)
|
|
|
|
|
LoadObject(objectactive[i]);
|
|
|
|
|
for (i = 0; i < nobjects; i++)
|
|
|
|
|
SyncObjectAnim(objectactive[i]);
|
|
|
|
|
|
|
|
|
|
numlights = WLoad();
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < MAXLIGHTS; i++)
|
|
|
|
|
lightactive[i] = BLoad();
|
|
|
|
|
for (i = 0; i < numlights; i++)
|
|
|
|
|
LoadLighting(lightactive[i]);
|
|
|
|
|
|
|
|
|
|
visionid = WLoad();
|
|
|
|
|
numvision = WLoad();
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < numvision; i++)
|
|
|
|
|
LoadVision(i);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < MAXITEMS; i++)
|
|
|
|
|
itemactive[i] = BLoad();
|
|
|
|
|
for (i = 0; i < MAXITEMS; i++)
|
|
|
|
|
itemavail[i] = BLoad();
|
|
|
|
|
for (i = 0; i < numitems; i++)
|
|
|
|
|
LoadItem(itemactive[i]);
|
|
|
|
|
for (i = 0; i < 128; i++)
|
|
|
|
|
UniqueItemFlag[i] = OLoad();
|
|
|
|
|
|
|
|
|
|
for (j = 0; j < MAXDUNY; j++) {
|
|
|
|
|
for (i = 0; i < MAXDUNX; i++)
|
|
|
|
|
dLight[i][j] = BLoad();
|
|
|
|
|
}
|
|
|
|
|
for (j = 0; j < MAXDUNY; j++) {
|
|
|
|
|
for (i = 0; i < MAXDUNX; i++)
|
|
|
|
|
dFlags[i][j] = BLoad();
|
|
|
|
|
}
|
|
|
|
|
for (j = 0; j < MAXDUNY; j++) {
|
|
|
|
|
for (i = 0; i < MAXDUNX; i++)
|
|
|
|
|
dPlayer[i][j] = BLoad();
|
|
|
|
|
}
|
|
|
|
|
for (j = 0; j < MAXDUNY; j++) {
|
|
|
|
|
for (i = 0; i < MAXDUNX; i++)
|
|
|
|
|
dItem[i][j] = BLoad();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (leveltype != DTYPE_TOWN) {
|
|
|
|
|
for (j = 0; j < MAXDUNY; j++) {
|
|
|
|
|
for (i = 0; i < MAXDUNX; i++)
|
|
|
|
|
dMonster[i][j] = WLoad();
|
|
|
|
|
}
|
|
|
|
|
for (j = 0; j < MAXDUNY; j++) {
|
|
|
|
|
for (i = 0; i < MAXDUNX; i++)
|
|
|
|
|
dDead[i][j] = BLoad();
|
|
|
|
|
}
|
|
|
|
|
for (j = 0; j < MAXDUNY; j++) {
|
|
|
|
|
for (i = 0; i < MAXDUNX; i++)
|
|
|
|
|
dObject[i][j] = BLoad();
|
|
|
|
|
}
|
|
|
|
|
for (j = 0; j < MAXDUNY; j++) {
|
|
|
|
|
for (i = 0; i < MAXDUNX; i++)
|
|
|
|
|
dLight[i][j] = BLoad();
|
|
|
|
|
}
|
|
|
|
|
for (j = 0; j < MAXDUNY; j++) {
|
|
|
|
|
for (i = 0; i < MAXDUNX; i++)
|
|
|
|
|
dPreLight[i][j] = BLoad();
|
|
|
|
|
}
|
|
|
|
|
for (j = 0; j < DMAXY; j++) {
|
|
|
|
|
for (i = 0; i < DMAXX; i++)
|
|
|
|
|
automapview[i][j] = OLoad();
|
|
|
|
|
}
|
|
|
|
|
for (j = 0; j < MAXDUNY; j++) {
|
|
|
|
|
for (i = 0; i < MAXDUNX; i++)
|
|
|
|
|
dMissile[i][j] = BLoad();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
numpremium = WLoad();
|
|
|
|
|
premiumlevel = WLoad();
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < 6; i++)
|
|
|
|
|
LoadPremium(i);
|
|
|
|
|
|
|
|
|
|
automapflag = OLoad();
|
|
|
|
|
AutoMapScale = WLoad();
|
|
|
|
|
mem_free_dbg(LoadBuff);
|
|
|
|
|
AutomapZoomReset();
|
|
|
|
|
ResyncQuests();
|
|
|
|
|
|
|
|
|
|
if (leveltype != DTYPE_TOWN)
|
|
|
|
|
ProcessLightList();
|
|
|
|
|
|
|
|
|
|
RedoPlayerVision();
|
|
|
|
|
ProcessVisionList();
|
|
|
|
|
missiles_process_charge();
|
|
|
|
|
ResetPal();
|
|
|
|
|
SetCursor_(CURSOR_HAND);
|
|
|
|
|
gbProcessPlayers = TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Load a byte-size char from the buffer
|
|
|
|
|
char BLoad()
|
|
|
|
|
{
|
|
|
|
|
return *tbuff++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Redundant?
|
|
|
|
|
int WLoad()
|
|
|
|
|
{
|
|
|
|
|
int rv = *tbuff++ << 24;
|
|
|
|
|
rv |= *tbuff++ << 16;
|
|
|
|
|
rv |= *tbuff++ << 8;
|
|
|
|
|
rv |= *tbuff++;
|
|
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Load a 32 bit integer from the buffer
|
|
|
|
|
int ILoad()
|
|
|
|
|
{
|
|
|
|
|
int rv = *tbuff++ << 24;
|
|
|
|
|
rv |= *tbuff++ << 16;
|
|
|
|
|
rv |= *tbuff++ << 8;
|
|
|
|
|
rv |= *tbuff++;
|
|
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOL OLoad()
|
|
|
|
|
{
|
|
|
|
|
if (*tbuff++ == TRUE)
|
|
|
|
|
return TRUE;
|
|
|
|
|
else
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Consume an int from tbuff with memcpy - copies directly, doesn't change byte order
|
|
|
|
|
void CopyInt(int & dst)
|
|
|
|
|
{
|
|
|
|
|
memcpy(&dst, tbuff, 4);
|
|
|
|
|
tbuff += 4;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CopyInt(unsigned int & dst)
|
|
|
|
|
{
|
|
|
|
|
memcpy(&dst, tbuff, 4);
|
|
|
|
|
tbuff += 4;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CopyShort(unsigned short & dst)
|
|
|
|
|
{
|
|
|
|
|
memcpy(&dst, tbuff, 2);
|
|
|
|
|
tbuff += 2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CopyShort(short & dst)
|
|
|
|
|
{
|
|
|
|
|
memcpy(&dst, tbuff, 2);
|
|
|
|
|
tbuff += 2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CopyShorts(const int n, unsigned short * dst)
|
|
|
|
|
{
|
|
|
|
|
memcpy(dst, tbuff, 2 * n);
|
|
|
|
|
tbuff += 2 * n;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Copy an int array of size n
|
|
|
|
|
void CopyInts(const int n, int* dst)
|
|
|
|
|
{
|
|
|
|
|
memcpy(dst, tbuff, 4 * n);
|
|
|
|
|
tbuff += 4 * n;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CopyBytes(const int n, unsigned char *dst)
|
|
|
|
|
{
|
|
|
|
|
memcpy(dst, tbuff, n);
|
|
|
|
|
tbuff += n;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CopyChar(unsigned char & dst)
|
|
|
|
|
{
|
|
|
|
|
memcpy(&dst, tbuff, 1);
|
|
|
|
|
tbuff += 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CopyChar(char & dst)
|
|
|
|
|
{
|
|
|
|
|
memcpy(&dst, tbuff, 1);
|
|
|
|
|
tbuff += 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CopyInt64(long long unsigned int & dst)
|
|
|
|
|
{
|
|
|
|
|
memcpy(&dst, tbuff, 8);
|
|
|
|
|
tbuff += 8;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void LoadPlayer(int i)
|
|
|
|
|
{
|
|
|
|
|
PlayerStruct *pPlayer = &plr[i];
|
|
|
|
|
CopyInt(pPlayer->_pmode);
|
|
|
|
|
CopyBytes(25, pPlayer->walkpath);
|
|
|
|
|
CopyBytes(1, &pPlayer->plractive);
|
|
|
|
|
tbuff += 2; // Some padding here?
|
|
|
|
|
CopyInt(pPlayer->destAction);
|
|
|
|
|
CopyInt(pPlayer->destParam1);
|
|
|
|
|
CopyInt(pPlayer->destParam2);
|
|
|
|
|
CopyInt(pPlayer->destParam3);
|
|
|
|
|
CopyInt(pPlayer->destParam4);
|
|
|
|
|
CopyInt(pPlayer->plrlevel);
|
|
|
|
|
CopyInt(pPlayer->WorldX);
|
|
|
|
|
CopyInt(pPlayer->WorldY);
|
|
|
|
|
CopyInt(pPlayer->_px);
|
|
|
|
|
CopyInt(pPlayer->_py);
|
|
|
|
|
CopyInt(pPlayer->_ptargx);
|
|
|
|
|
CopyInt(pPlayer->_ptargy);
|
|
|
|
|
CopyInt(pPlayer->_pownerx);
|
|
|
|
|
CopyInt(pPlayer->_pownery);
|
|
|
|
|
CopyInt(pPlayer->_poldx);
|
|
|
|
|
CopyInt(pPlayer->_poldy);
|
|
|
|
|
CopyInt(pPlayer->_pxoff);
|
|
|
|
|
CopyInt(pPlayer->_pyoff);
|
|
|
|
|
CopyInt(pPlayer->_pxvel);
|
|
|
|
|
CopyInt(pPlayer->_pyvel);
|
|
|
|
|
CopyInt(pPlayer->_pdir);
|
|
|
|
|
CopyInt(pPlayer->_nextdir);
|
|
|
|
|
CopyInt(pPlayer->_pgfxnum);
|
|
|
|
|
tbuff += 4; // Skip pointers
|
|
|
|
|
CopyInt(pPlayer->_pAnimDelay);
|
|
|
|
|
CopyInt(pPlayer->_pAnimCnt);
|
|
|
|
|
CopyInt(pPlayer->_pAnimLen);
|
|
|
|
|
CopyInt(pPlayer->_pAnimFrame);
|
|
|
|
|
CopyInt(pPlayer->_pAnimWidth);
|
|
|
|
|
CopyInt(pPlayer->_pAnimWidth2);
|
|
|
|
|
CopyInt(pPlayer->_peflag);
|
|
|
|
|
CopyInt(pPlayer->_plid);
|
|
|
|
|
CopyInt(pPlayer->_pvid);
|
|
|
|
|
|
|
|
|
|
CopyInt(pPlayer->_pSpell);
|
|
|
|
|
CopyChar(pPlayer->_pSplType);
|
|
|
|
|
CopyChar(pPlayer->_pSplFrom);
|
|
|
|
|
CopyInt(pPlayer->_pTSpell);
|
|
|
|
|
CopyChar(pPlayer->_pTSplType);
|
|
|
|
|
tbuff += 5;
|
|
|
|
|
CopyInt(pPlayer->_pRSpell);
|
|
|
|
|
CopyChar(pPlayer->_pRSplType);
|
|
|
|
|
tbuff += 3;
|
|
|
|
|
CopyInt(pPlayer->_pSBkSpell);
|
|
|
|
|
CopyChar(pPlayer->_pSBkSplType);
|
|
|
|
|
|
|
|
|
|
CopyBytes(64, pPlayer->_pSplLvl);
|
|
|
|
|
tbuff += 7;
|
|
|
|
|
CopyInt64(pPlayer->_pMemSpells);
|
|
|
|
|
CopyInt64(pPlayer->_pAblSpells);
|
|
|
|
|
CopyInt64(pPlayer->_pScrlSpells);
|
|
|
|
|
CopyChar(pPlayer->_pSpellFlags);
|
|
|
|
|
tbuff += 3;
|
|
|
|
|
CopyInts(4, pPlayer->_pSplHotKey);
|
|
|
|
|
CopyBytes(4, pPlayer->_pSplTHotKey);
|
|
|
|
|
CopyInt(pPlayer->_pwtype);
|
|
|
|
|
CopyChar(pPlayer->_pBlockFlag);
|
|
|
|
|
CopyChar(pPlayer->_pInvincible);
|
|
|
|
|
CopyChar(pPlayer->_pLightRad);
|
|
|
|
|
CopyChar(pPlayer->_pLvlChanging);
|
|
|
|
|
CopyBytes(PLR_NAME_LEN, pPlayer->_pName);
|
|
|
|
|
CopyChar(pPlayer->_pClass);
|
|
|
|
|
tbuff += 3;
|
|
|
|
|
CopyInt(pPlayer->_pStrength);
|
|
|
|
|
CopyInt(pPlayer->_pBaseStr);
|
|
|
|
|
CopyInt(pPlayer->_pMagic);
|
|
|
|
|
CopyInt(pPlayer->_pBaseMag);
|
|
|
|
|
CopyInt(pPlayer->_pDexterity);
|
|
|
|
|
CopyInt(pPlayer->_pBaseDex);
|
|
|
|
|
CopyInt(pPlayer->_pVitality);
|
|
|
|
|
CopyInt(pPlayer->_pBaseVit);
|
|
|
|
|
CopyInt(pPlayer->_pStatPts);
|
|
|
|
|
CopyInt(pPlayer->_pDamageMod);
|
|
|
|
|
CopyInt(pPlayer->_pBaseToBlk);
|
|
|
|
|
CopyInt(pPlayer->_pHPBase);
|
|
|
|
|
CopyInt(pPlayer->_pMaxHPBase);
|
|
|
|
|
CopyInt(pPlayer->_pHitPoints);
|
|
|
|
|
CopyInt(pPlayer->_pMaxHP);
|
|
|
|
|
CopyInt(pPlayer->_pHPPer);
|
|
|
|
|
CopyInt(pPlayer->_pManaBase);
|
|
|
|
|
CopyInt(pPlayer->_pMaxManaBase);
|
|
|
|
|
CopyInt(pPlayer->_pMana);
|
|
|
|
|
CopyInt(pPlayer->_pMaxMana);
|
|
|
|
|
CopyInt(pPlayer->_pManaPer);
|
|
|
|
|
CopyChar(pPlayer->_pLevel);
|
|
|
|
|
CopyChar(pPlayer->_pMaxLvl);
|
|
|
|
|
tbuff += 2;
|
|
|
|
|
CopyInt(pPlayer->_pExperience);
|
|
|
|
|
CopyInt(pPlayer->_pMaxExp);
|
|
|
|
|
CopyInt(pPlayer->_pNextExper);
|
|
|
|
|
CopyChar(pPlayer->_pArmorClass);
|
|
|
|
|
CopyChar(pPlayer->_pMagResist);
|
|
|
|
|
CopyChar(pPlayer->_pFireResist);
|
|
|
|
|
CopyChar(pPlayer->_pLghtResist);
|
|
|
|
|
CopyInt(pPlayer->_pGold);
|
|
|
|
|
CopyInt(pPlayer->_pInfraFlag);
|
|
|
|
|
CopyInt(pPlayer->_pVar1);
|
|
|
|
|
CopyInt(pPlayer->_pVar2);
|
|
|
|
|
CopyInt(pPlayer->_pVar3);
|
|
|
|
|
CopyInt(pPlayer->_pVar4);
|
|
|
|
|
CopyInt(pPlayer->_pVar5);
|
|
|
|
|
CopyInt(pPlayer->_pVar6);
|
|
|
|
|
CopyInt(pPlayer->_pVar7);
|
|
|
|
|
CopyInt(pPlayer->_pVar8);
|
|
|
|
|
CopyBytes(NUMLEVELS, pPlayer->_pLvlVisited);
|
|
|
|
|
CopyBytes(NUMLEVELS, pPlayer->_pSLvlVisited); // only 10 used
|
|
|
|
|
tbuff += 2;
|
|
|
|
|
CopyInt(pPlayer->_pGFXLoad);
|
|
|
|
|
|
|
|
|
|
tbuff += sizeof(__uint32_t) * 8; // Skip 8 pointers
|
|
|
|
|
CopyInt(pPlayer->_pNFrames);
|
|
|
|
|
CopyInt(pPlayer->_pNWidth);
|
|
|
|
|
|
|
|
|
|
tbuff += sizeof(__uint32_t) * 8; // Skip 8 pointers
|
|
|
|
|
|
|
|
|
|
CopyInt(pPlayer->_pWFrames);
|
|
|
|
|
CopyInt(pPlayer->_pWWidth);
|
|
|
|
|
|
|
|
|
|
tbuff += sizeof(__uint32_t) * 8; // Skip 8 pointers
|
|
|
|
|
|
|
|
|
|
CopyInt(pPlayer->_pAFrames);
|
|
|
|
|
CopyInt(pPlayer->_pAWidth);
|
|
|
|
|
CopyInt(pPlayer->_pAFNum);
|
|
|
|
|
|
|
|
|
|
tbuff += sizeof(__uint32_t) * 24; // Skip 24 pointers
|
|
|
|
|
|
|
|
|
|
CopyInt(pPlayer->_pSFrames);
|
|
|
|
|
CopyInt(pPlayer->_pSWidth);
|
|
|
|
|
CopyInt(pPlayer->_pSFNum);
|
|
|
|
|
|
|
|
|
|
tbuff += sizeof(__uint32_t) * 8; // Skip 8 pointers
|
|
|
|
|
|
|
|
|
|
CopyInt(pPlayer->_pHFrames);
|
|
|
|
|
CopyInt(pPlayer->_pHWidth);
|
|
|
|
|
|
|
|
|
|
tbuff += sizeof(__uint32_t) * 8; // Skip 8 pointers
|
|
|
|
|
|
|
|
|
|
CopyInt(pPlayer->_pDFrames);
|
|
|
|
|
CopyInt(pPlayer->_pDWidth);
|
|
|
|
|
|
|
|
|
|
tbuff += sizeof(__uint32_t) * 8; // Skip 8 pointers
|
|
|
|
|
|
|
|
|
|
CopyInt(pPlayer->_pBFrames);
|
|
|
|
|
CopyInt(pPlayer->_pBWidth);
|
|
|
|
|
|
|
|
|
|
CopyItems(NUM_INVLOC, pPlayer->InvBody);
|
|
|
|
|
CopyItems(NUM_INV_GRID_ELEM, pPlayer->InvList);
|
|
|
|
|
|
|
|
|
|
CopyInt(pPlayer->_pNumInv);
|
|
|
|
|
CopyBytes(NUM_INV_GRID_ELEM, pPlayer->InvGrid);
|
|
|
|
|
CopyItems(MAXBELTITEMS, pPlayer->SpdList);
|
|
|
|
|
CopyItem(&pPlayer->HoldItem);
|
|
|
|
|
CopyInt(pPlayer->_pIMinDam);
|
|
|
|
|
CopyInt(pPlayer->_pIMaxDam);
|
|
|
|
|
CopyInt(pPlayer->_pIAC);
|
|
|
|
|
CopyInt(pPlayer->_pIBonusDam);
|
|
|
|
|
CopyInt(pPlayer->_pIBonusToHit);
|
|
|
|
|
CopyInt(pPlayer->_pIBonusAC);
|
|
|
|
|
CopyInt(pPlayer->_pIBonusDamMod);
|
|
|
|
|
tbuff += 4;
|
|
|
|
|
CopyInt64(pPlayer->_pISpells);
|
|
|
|
|
CopyInt(pPlayer->_pIFlags);
|
|
|
|
|
CopyInt(pPlayer->_pIGetHit);
|
|
|
|
|
CopyChar(pPlayer->_pISplLvlAdd);
|
|
|
|
|
CopyChar(pPlayer->_pISplCost);
|
|
|
|
|
tbuff += 2;
|
|
|
|
|
CopyInt(pPlayer->_pISplDur);
|
|
|
|
|
CopyInt(pPlayer->_pIEnAc);
|
|
|
|
|
CopyInt(pPlayer->_pIFMinDam);
|
|
|
|
|
CopyInt(pPlayer->_pIFMaxDam);
|
|
|
|
|
CopyInt(pPlayer->_pILMinDam);
|
|
|
|
|
CopyInt(pPlayer->_pILMaxDam);
|
|
|
|
|
CopyInt(pPlayer->_pOilType);
|
|
|
|
|
CopyChar(pPlayer->pTownWarps);
|
|
|
|
|
CopyChar(pPlayer->pDungMsgs);
|
|
|
|
|
CopyChar(pPlayer->pLvlLoad);
|
|
|
|
|
CopyChar(pPlayer->pBattleNet);
|
|
|
|
|
CopyChar(pPlayer->pManaShield);
|
|
|
|
|
CopyBytes(3, pPlayer->bReserved);
|
|
|
|
|
CopyShorts(8, pPlayer->wReserved);
|
|
|
|
|
CopyInt(pPlayer->pDiabloKillLevel);
|
|
|
|
|
CopyInts(7, pPlayer->dwReserved);
|
|
|
|
|
|
|
|
|
|
// Omit 10 pointers
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void LoadMonster(int i)
|
|
|
|
|
{
|
|
|
|
|
MonsterStruct *pMonster = &monster[i];
|
|
|
|
|
|
|
|
|
|
CopyInt(pMonster->_mMTidx);
|
|
|
|
|
CopyInt(pMonster->_mmode);
|
|
|
|
|
|
|
|
|
|
CopyChar(pMonster->_mgoal);
|
|
|
|
|
tbuff += 3;
|
|
|
|
|
|
|
|
|
|
CopyInt(pMonster->_mgoalvar1);
|
|
|
|
|
CopyInt(pMonster->_mgoalvar2);
|
|
|
|
|
CopyInt(pMonster->_mgoalvar3);
|
|
|
|
|
CopyInt(pMonster->field_18);
|
|
|
|
|
|
|
|
|
|
CopyChar(pMonster->_pathcount);
|
|
|
|
|
tbuff += 3;
|
|
|
|
|
|
|
|
|
|
CopyInt(pMonster->_mx);
|
|
|
|
|
CopyInt(pMonster->_my);
|
|
|
|
|
CopyInt(pMonster->_mfutx);
|
|
|
|
|
CopyInt(pMonster->_mfuty);
|
|
|
|
|
CopyInt(pMonster->_moldx);
|
|
|
|
|
CopyInt(pMonster->_moldy);
|
|
|
|
|
CopyInt(pMonster->_mxoff);
|
|
|
|
|
CopyInt(pMonster->_myoff);
|
|
|
|
|
CopyInt(pMonster->_mxvel);
|
|
|
|
|
CopyInt(pMonster->_myvel);
|
|
|
|
|
CopyInt(pMonster->_mdir);
|
|
|
|
|
CopyInt(pMonster->_menemy);
|
|
|
|
|
|
|
|
|
|
CopyChar(pMonster->_menemyx);
|
|
|
|
|
CopyChar(pMonster->_menemyy);
|
|
|
|
|
CopyShort(pMonster->falign_52);
|
|
|
|
|
|
|
|
|
|
tbuff += 4; // Skip pointer
|
|
|
|
|
CopyInt(pMonster->_mAnimDelay);
|
|
|
|
|
CopyInt(pMonster->_mAnimCnt);
|
|
|
|
|
CopyInt(pMonster->_mAnimLen);
|
|
|
|
|
CopyInt(pMonster->_mAnimFrame);
|
|
|
|
|
CopyInt(pMonster->_meflag);
|
|
|
|
|
CopyInt(pMonster->_mDelFlag);
|
|
|
|
|
CopyInt(pMonster->_mVar1);
|
|
|
|
|
CopyInt(pMonster->_mVar2);
|
|
|
|
|
CopyInt(pMonster->_mVar3);
|
|
|
|
|
CopyInt(pMonster->_mVar4);
|
|
|
|
|
CopyInt(pMonster->_mVar5);
|
|
|
|
|
CopyInt(pMonster->_mVar6);
|
|
|
|
|
CopyInt(pMonster->_mVar7);
|
|
|
|
|
CopyInt(pMonster->_mVar8);
|
|
|
|
|
CopyInt(pMonster->_mmaxhp);
|
|
|
|
|
CopyInt(pMonster->_mhitpoints);
|
|
|
|
|
|
|
|
|
|
CopyChar(pMonster->_mAi);
|
|
|
|
|
CopyChar(pMonster->_mint);
|
|
|
|
|
CopyShort(pMonster->falign_9A);
|
|
|
|
|
|
|
|
|
|
CopyInt(pMonster->_mFlags);
|
|
|
|
|
|
|
|
|
|
CopyChar(pMonster->_msquelch);
|
|
|
|
|
tbuff += 3;
|
|
|
|
|
|
|
|
|
|
CopyInt(pMonster->falign_A4);
|
|
|
|
|
CopyInt(pMonster->_lastx);
|
|
|
|
|
CopyInt(pMonster->_lasty);
|
|
|
|
|
CopyInt(pMonster->_mRndSeed);
|
|
|
|
|
CopyInt(pMonster->_mAISeed);
|
|
|
|
|
CopyInt(pMonster->falign_B8);
|
|
|
|
|
|
|
|
|
|
CopyChar(pMonster->_uniqtype);
|
|
|
|
|
CopyChar(pMonster->_uniqtrans);
|
|
|
|
|
CopyChar(pMonster->_udeadval);
|
|
|
|
|
CopyChar(pMonster->mWhoHit);
|
|
|
|
|
|
|
|
|
|
CopyChar(pMonster->mLevel);
|
|
|
|
|
CopyShort(pMonster->mExp);
|
|
|
|
|
tbuff += 1;
|
|
|
|
|
|
|
|
|
|
CopyChar(pMonster->mHit);
|
|
|
|
|
CopyChar(pMonster->mMinDamage);
|
|
|
|
|
CopyChar(pMonster->mMaxDamage);
|
|
|
|
|
CopyChar(pMonster->mHit2);
|
|
|
|
|
|
|
|
|
|
CopyChar(pMonster->mMinDamage2);
|
|
|
|
|
CopyChar(pMonster->mMaxDamage2);
|
|
|
|
|
CopyChar(pMonster->mArmorClass);
|
|
|
|
|
CopyChar(pMonster->falign_CB);
|
|
|
|
|
|
|
|
|
|
CopyShort(pMonster->mMagicRes);
|
|
|
|
|
tbuff += 2;
|
|
|
|
|
|
|
|
|
|
CopyInt(pMonster->mtalkmsg);
|
|
|
|
|
|
|
|
|
|
CopyChar(pMonster->leader);
|
|
|
|
|
CopyChar(pMonster->leaderflag);
|
|
|
|
|
CopyChar(pMonster->packsize);
|
|
|
|
|
CopyChar(pMonster->mlid);
|
|
|
|
|
|
|
|
|
|
SyncMonsterAnim(i);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void LoadMissile(int i)
|
|
|
|
|
{
|
|
|
|
|
MissileStruct *pMissile = &missile[i];
|
|
|
|
|
|
|
|
|
|
CopyInt(pMissile->_mitype);
|
|
|
|
|
CopyInt(pMissile->_mix);
|
|
|
|
|
CopyInt(pMissile->_miy);
|
|
|
|
|
CopyInt(pMissile->_mixoff);
|
|
|
|
|
CopyInt(pMissile->_miyoff);
|
|
|
|
|
CopyInt(pMissile->_mixvel);
|
|
|
|
|
CopyInt(pMissile->_miyvel);
|
|
|
|
|
CopyInt(pMissile->_misx);
|
|
|
|
|
CopyInt(pMissile->_misy);
|
|
|
|
|
CopyInt(pMissile->_mitxoff);
|
|
|
|
|
CopyInt(pMissile->_mityoff);
|
|
|
|
|
CopyInt(pMissile->_mimfnum);
|
|
|
|
|
CopyInt(pMissile->_mispllvl);
|
|
|
|
|
CopyInt(pMissile->_miDelFlag);
|
|
|
|
|
CopyChar(pMissile->_miAnimType);
|
|
|
|
|
tbuff += 3;
|
|
|
|
|
|
|
|
|
|
CopyInt(pMissile->_miAnimFlags);
|
|
|
|
|
tbuff += 4;
|
|
|
|
|
CopyInt(pMissile->_miAnimDelay);
|
|
|
|
|
CopyInt(pMissile->_miAnimLen);
|
|
|
|
|
CopyInt(pMissile->_miAnimWidth);
|
|
|
|
|
CopyInt(pMissile->_miAnimWidth2);
|
|
|
|
|
CopyInt(pMissile->_miAnimCnt);
|
|
|
|
|
CopyInt(pMissile->_miAnimAdd);
|
|
|
|
|
CopyInt(pMissile->_miAnimFrame);
|
|
|
|
|
CopyInt(pMissile->_miDrawFlag);
|
|
|
|
|
CopyInt(pMissile->_miLightFlag);
|
|
|
|
|
CopyInt(pMissile->_miPreFlag);
|
|
|
|
|
CopyInt(pMissile->_miUniqTrans);
|
|
|
|
|
CopyInt(pMissile->_mirange);
|
|
|
|
|
CopyInt(pMissile->_misource);
|
|
|
|
|
CopyInt(pMissile->_micaster);
|
|
|
|
|
CopyInt(pMissile->_midam);
|
|
|
|
|
CopyInt(pMissile->_miHitFlag);
|
|
|
|
|
CopyInt(pMissile->_midist);
|
|
|
|
|
CopyInt(pMissile->_mlid);
|
|
|
|
|
CopyInt(pMissile->_mirnd);
|
|
|
|
|
CopyInt(pMissile->_miVar1);
|
|
|
|
|
CopyInt(pMissile->_miVar2);
|
|
|
|
|
CopyInt(pMissile->_miVar3);
|
|
|
|
|
CopyInt(pMissile->_miVar4);
|
|
|
|
|
CopyInt(pMissile->_miVar5);
|
|
|
|
|
CopyInt(pMissile->_miVar6);
|
|
|
|
|
CopyInt(pMissile->_miVar7);
|
|
|
|
|
CopyInt(pMissile->_miVar8);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void LoadObject(int i)
|
|
|
|
|
{
|
|
|
|
|
ObjectStruct *pObject = &object[i];
|
|
|
|
|
CopyInt(pObject->_otype);
|
|
|
|
|
CopyInt(pObject->_ox);
|
|
|
|
|
CopyInt(pObject->_oy);
|
|
|
|
|
CopyInt(pObject->_oLight);
|
|
|
|
|
CopyInt(pObject->_oAnimFlag);
|
|
|
|
|
tbuff += 4;
|
|
|
|
|
CopyInt(pObject->_oAnimDelay);
|
|
|
|
|
CopyInt(pObject->_oAnimCnt);
|
|
|
|
|
CopyInt(pObject->_oAnimLen);
|
|
|
|
|
CopyInt(pObject->_oAnimFrame);
|
|
|
|
|
CopyInt(pObject->_oAnimWidth);
|
|
|
|
|
CopyInt(pObject->_oAnimWidth2);
|
|
|
|
|
CopyInt(pObject->_oDelFlag);
|
|
|
|
|
|
|
|
|
|
CopyChar(pObject->_oBreak);
|
|
|
|
|
tbuff += 3;
|
|
|
|
|
|
|
|
|
|
CopyInt(pObject->_oSolidFlag);
|
|
|
|
|
CopyInt(pObject->_oMissFlag);
|
|
|
|
|
|
|
|
|
|
CopyChar(pObject->_oSelFlag);
|
|
|
|
|
tbuff += 3;
|
|
|
|
|
|
|
|
|
|
CopyInt(pObject->_oPreFlag);
|
|
|
|
|
CopyInt(pObject->_oTrapFlag);
|
|
|
|
|
CopyInt(pObject->_oDoorFlag);
|
|
|
|
|
CopyInt(pObject->_olid);
|
|
|
|
|
CopyInt(pObject->_oRndSeed);
|
|
|
|
|
CopyInt(pObject->_oVar1);
|
|
|
|
|
CopyInt(pObject->_oVar2);
|
|
|
|
|
CopyInt(pObject->_oVar3);
|
|
|
|
|
CopyInt(pObject->_oVar4);
|
|
|
|
|
CopyInt(pObject->_oVar5);
|
|
|
|
|
CopyInt(pObject->_oVar6);
|
|
|
|
|
CopyInt(pObject->_oVar7);
|
|
|
|
|
CopyInt(pObject->_oVar8);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void LoadItem(int i)
|
|
|
|
|
{
|
|
|
|
|
CopyItem(&item[i]);
|
|
|
|
|
GetItemFrm(i);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CopyItem(ItemStruct *pItem)
|
|
|
|
|
{
|
|
|
|
|
CopyInt(pItem->_iSeed);
|
|
|
|
|
CopyShort(pItem->_iCreateInfo);
|
|
|
|
|
tbuff += 2;
|
|
|
|
|
CopyInt(pItem->_itype);
|
|
|
|
|
CopyInt(pItem->_ix);
|
|
|
|
|
CopyInt(pItem->_iy);
|
|
|
|
|
CopyInt(pItem->_iAnimFlag);
|
|
|
|
|
tbuff += 4; // Skip pointer _iAnimData
|
|
|
|
|
CopyInt(pItem->_iAnimLen);
|
|
|
|
|
CopyInt(pItem->_iAnimFrame);
|
|
|
|
|
CopyInt(pItem->_iAnimWidth);
|
|
|
|
|
CopyInt(pItem->_iAnimWidth2); // width 2?
|
|
|
|
|
CopyInt(pItem->_isin); // set when item is flagged for deletion, deprecated in 1.02
|
|
|
|
|
CopyChar(pItem->_iSelFlag);
|
|
|
|
|
tbuff += 3;
|
|
|
|
|
CopyInt(pItem->_iPostDraw);
|
|
|
|
|
CopyInt(pItem->_iIdentified);
|
|
|
|
|
CopyChar(pItem->_iMagical);
|
|
|
|
|
CopyBytes(64, pItem->_iName);
|
|
|
|
|
CopyBytes(64, pItem->_iIName);
|
|
|
|
|
CopyChar(pItem->_iLoc);
|
|
|
|
|
CopyChar(pItem->_iClass);
|
|
|
|
|
tbuff += 1;
|
|
|
|
|
CopyInt(pItem->_iCurs);
|
|
|
|
|
CopyInt(pItem->_ivalue);
|
|
|
|
|
CopyInt(pItem->_iIvalue);
|
|
|
|
|
CopyInt(pItem->_iMinDam);
|
|
|
|
|
CopyInt(pItem->_iMaxDam);
|
|
|
|
|
CopyInt(pItem->_iAC);
|
|
|
|
|
CopyInt(pItem->_iFlags);
|
|
|
|
|
CopyInt(pItem->_iMiscId);
|
|
|
|
|
CopyInt(pItem->_iSpell);
|
|
|
|
|
CopyInt(pItem->_iCharges);
|
|
|
|
|
CopyInt(pItem->_iMaxCharges);
|
|
|
|
|
CopyInt(pItem->_iDurability);
|
|
|
|
|
CopyInt(pItem->_iMaxDur);
|
|
|
|
|
CopyInt(pItem->_iPLDam);
|
|
|
|
|
CopyInt(pItem->_iPLToHit);
|
|
|
|
|
CopyInt(pItem->_iPLAC);
|
|
|
|
|
CopyInt(pItem->_iPLStr);
|
|
|
|
|
CopyInt(pItem->_iPLMag);
|
|
|
|
|
CopyInt(pItem->_iPLDex);
|
|
|
|
|
CopyInt(pItem->_iPLVit);
|
|
|
|
|
CopyInt(pItem->_iPLFR);
|
|
|
|
|
CopyInt(pItem->_iPLLR);
|
|
|
|
|
CopyInt(pItem->_iPLMR);
|
|
|
|
|
CopyInt(pItem->_iPLMana);
|
|
|
|
|
CopyInt(pItem->_iPLHP);
|
|
|
|
|
CopyInt(pItem->_iPLDamMod);
|
|
|
|
|
CopyInt(pItem->_iPLGetHit);
|
|
|
|
|
CopyInt(pItem->_iPLLight);
|
|
|
|
|
CopyChar(pItem->_iSplLvlAdd);
|
|
|
|
|
CopyChar(pItem->_iRequest);
|
|
|
|
|
tbuff += 2;
|
|
|
|
|
CopyInt(pItem->_iUid);
|
|
|
|
|
CopyInt(pItem->_iFMinDam);
|
|
|
|
|
CopyInt(pItem->_iFMaxDam);
|
|
|
|
|
CopyInt(pItem->_iLMinDam);
|
|
|
|
|
CopyInt(pItem->_iLMaxDam);
|
|
|
|
|
CopyInt(pItem->_iPLEnAc);
|
|
|
|
|
CopyChar(pItem->_iPrePower);
|
|
|
|
|
CopyChar(pItem->_iSufPower);
|
|
|
|
|
tbuff += 2;
|
|
|
|
|
CopyInt(pItem->_iVAdd1);
|
|
|
|
|
CopyInt(pItem->_iVMult1);
|
|
|
|
|
CopyInt(pItem->_iVAdd2);
|
|
|
|
|
CopyInt(pItem->_iVMult2);
|
|
|
|
|
CopyChar(pItem->_iMinStr);
|
|
|
|
|
CopyChar(pItem->_iMinMag);
|
|
|
|
|
CopyChar(pItem->_iMinDex);
|
|
|
|
|
tbuff += 1;
|
|
|
|
|
CopyInt(pItem->_iStatFlag);
|
|
|
|
|
CopyInt(pItem->IDidx);
|
|
|
|
|
CopyInt(pItem->offs016C);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CopyItems(const int n, ItemStruct *pItem)
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < n; i++)
|
|
|
|
|
{
|
|
|
|
|
CopyItem(&pItem[i]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void LoadPremium(int i)
|
|
|
|
|
{
|
|
|
|
|
memcpy(&premiumitem[i], tbuff, sizeof(*premiumitem));
|
|
|
|
|
tbuff += sizeof(*premiumitem);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void LoadQuest(int i)
|
|
|
|
|
{
|
|
|
|
|
memcpy(&quests[i], tbuff, sizeof(*quests));
|
|
|
|
|
tbuff += sizeof(*quests);
|
|
|
|
|
ReturnLvlX = WLoad();
|
|
|
|
|
ReturnLvlY = WLoad();
|
|
|
|
|
ReturnLvl = WLoad();
|
|
|
|
|
ReturnLvlT = WLoad();
|
|
|
|
|
DoomQuestState = WLoad();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void LoadLighting(int i)
|
|
|
|
|
{
|
|
|
|
|
memcpy(&LightList[i], tbuff, sizeof(*LightList));
|
|
|
|
|
tbuff += sizeof(*LightList);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void LoadVision(int i)
|
|
|
|
|
{
|
|
|
|
|
memcpy(&VisionList[i], tbuff, sizeof(*VisionList));
|
|
|
|
|
tbuff += sizeof(*VisionList);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void LoadPortal(int i)
|
|
|
|
|
{
|
|
|
|
|
memcpy(&portal[i], tbuff, sizeof(*portal));
|
|
|
|
|
tbuff += sizeof(*portal);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SaveGame()
|
|
|
|
|
{
|
|
|
|
|
int i, j;
|
|
|
|
|
char szName[MAX_PATH];
|
|
|
|
|
|
|
|
|
|
DWORD dwLen = codec_get_encoded_len(FILEBUFF);
|
|
|
|
|
BYTE *SaveBuff = DiabloAllocPtr(dwLen);
|
|
|
|
|
tbuff = SaveBuff;
|
|
|
|
|
|
|
|
|
|
ISave('RETL');
|
|
|
|
|
OSave((unsigned char)setlevel);
|
|
|
|
|
WSave(setlvlnum);
|
|
|
|
|
WSave(currlevel);
|
|
|
|
|
WSave((unsigned char)leveltype);
|
|
|
|
|
WSave(ViewX);
|
|
|
|
|
WSave(ViewY);
|
|
|
|
|
OSave(invflag);
|
|
|
|
|
OSave(chrflag);
|
|
|
|
|
WSave(nummonsters);
|
|
|
|
|
WSave(numitems);
|
|
|
|
|
WSave(nummissiles);
|
|
|
|
|
WSave(nobjects);
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < NUMLEVELS; i++) {
|
|
|
|
|
ISave(glSeedTbl[i]);
|
|
|
|
|
WSave(gnLevelTypeTbl[i]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SavePlayer(myplr);
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < MAXQUESTS; i++)
|
|
|
|
|
SaveQuest(i);
|
|
|
|
|
for (i = 0; i < MAXPORTAL; i++)
|
|
|
|
|
SavePortal(i);
|
|
|
|
|
for (i = 0; i < MAXMONSTERS; i++)
|
|
|
|
|
ISave(monstkills[i]);
|
|
|
|
|
|
|
|
|
|
if (leveltype != DTYPE_TOWN) {
|
|
|
|
|
for (i = 0; i < MAXMONSTERS; i++)
|
|
|
|
|
WSave(monstactive[i]);
|
|
|
|
|
for (i = 0; i < nummonsters; i++)
|
|
|
|
|
SaveMonster(monstactive[i]);
|
|
|
|
|
for (i = 0; i < MAXMISSILES; i++)
|
|
|
|
|
BSave(missileactive[i]);
|
|
|
|
|
for (i = 0; i < MAXMISSILES; i++)
|
|
|
|
|
BSave(missileavail[i]);
|
|
|
|
|
for (i = 0; i < nummissiles; i++)
|
|
|
|
|
SaveMissile(missileactive[i]);
|
|
|
|
|
for (i = 0; i < MAXOBJECTS; i++)
|
|
|
|
|
BSave(objectactive[i]);
|
|
|
|
|
for (i = 0; i < MAXOBJECTS; i++)
|
|
|
|
|
BSave(objectavail[i]);
|
|
|
|
|
for (i = 0; i < nobjects; i++)
|
|
|
|
|
SaveObject(objectactive[i]);
|
|
|
|
|
|
|
|
|
|
WSave(numlights);
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < MAXLIGHTS; i++)
|
|
|
|
|
BSave(lightactive[i]);
|
|
|
|
|
for (i = 0; i < numlights; i++)
|
|
|
|
|
SaveLighting(lightactive[i]);
|
|
|
|
|
|
|
|
|
|
WSave(visionid);
|
|
|
|
|
WSave(numvision);
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < numvision; i++)
|
|
|
|
|
SaveVision(i);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < MAXITEMS; i++)
|
|
|
|
|
BSave(itemactive[i]);
|
|
|
|
|
for (i = 0; i < MAXITEMS; i++)
|
|
|
|
|
BSave(itemavail[i]);
|
|
|
|
|
for (i = 0; i < numitems; i++)
|
|
|
|
|
SaveItem(itemactive[i]);
|
|
|
|
|
for (i = 0; i < 128; i++)
|
|
|
|
|
OSave(UniqueItemFlag[i]);
|
|
|
|
|
|
|
|
|
|
for (j = 0; j < MAXDUNY; j++) {
|
|
|
|
|
for (i = 0; i < MAXDUNX; i++)
|
|
|
|
|
BSave(dLight[i][j]);
|
|
|
|
|
}
|
|
|
|
|
for (j = 0; j < MAXDUNY; j++) {
|
|
|
|
|
for (i = 0; i < MAXDUNX; i++)
|
|
|
|
|
BSave(dFlags[i][j] & ~(BFLAG_MISSILE | BFLAG_VISIBLE | BFLAG_DEAD_PLAYER));
|
|
|
|
|
}
|
|
|
|
|
for (j = 0; j < MAXDUNY; j++) {
|
|
|
|
|
for (i = 0; i < MAXDUNX; i++)
|
|
|
|
|
BSave(dPlayer[i][j]);
|
|
|
|
|
}
|
|
|
|
|
for (j = 0; j < MAXDUNY; j++) {
|
|
|
|
|
for (i = 0; i < MAXDUNX; i++)
|
|
|
|
|
BSave(dItem[i][j]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (leveltype != DTYPE_TOWN) {
|
|
|
|
|
for (j = 0; j < MAXDUNY; j++) {
|
|
|
|
|
for (i = 0; i < MAXDUNX; i++)
|
|
|
|
|
WSave(dMonster[i][j]);
|
|
|
|
|
}
|
|
|
|
|
for (j = 0; j < MAXDUNY; j++) {
|
|
|
|
|
for (i = 0; i < MAXDUNX; i++)
|
|
|
|
|
BSave(dDead[i][j]);
|
|
|
|
|
}
|
|
|
|
|
for (j = 0; j < MAXDUNY; j++) {
|
|
|
|
|
for (i = 0; i < MAXDUNX; i++)
|
|
|
|
|
BSave(dObject[i][j]);
|
|
|
|
|
}
|
|
|
|
|
for (j = 0; j < MAXDUNY; j++) {
|
|
|
|
|
for (i = 0; i < MAXDUNX; i++)
|
|
|
|
|
BSave(dLight[i][j]);
|
|
|
|
|
}
|
|
|
|
|
for (j = 0; j < MAXDUNY; j++) {
|
|
|
|
|
for (i = 0; i < MAXDUNX; i++)
|
|
|
|
|
BSave(dPreLight[i][j]);
|
|
|
|
|
}
|
|
|
|
|
for (j = 0; j < DMAXY; j++) {
|
|
|
|
|
for (i = 0; i < DMAXX; i++)
|
|
|
|
|
OSave(automapview[i][j]);
|
|
|
|
|
}
|
|
|
|
|
for (j = 0; j < MAXDUNY; j++) {
|
|
|
|
|
for (i = 0; i < MAXDUNX; i++)
|
|
|
|
|
BSave(dMissile[i][j]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
WSave(numpremium);
|
|
|
|
|
WSave(premiumlevel);
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < 6; i++)
|
|
|
|
|
SavePremium(i);
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
mem_free_dbg(SaveBuff);
|
|
|
|
|
gbValidSaveFile = TRUE;
|
|
|
|
|
pfile_rename_temp_to_perm();
|
|
|
|
|
pfile_write_hero();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BSave(char v)
|
|
|
|
|
{
|
|
|
|
|
*tbuff++ = v;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void WSave(int v)
|
|
|
|
|
{
|
|
|
|
|
*tbuff++ = v >> 24;
|
|
|
|
|
*tbuff++ = v >> 16;
|
|
|
|
|
*tbuff++ = v >> 8;
|
|
|
|
|
*tbuff++ = v;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ISave(int v)
|
|
|
|
|
{
|
|
|
|
|
*tbuff++ = v >> 24;
|
|
|
|
|
*tbuff++ = v >> 16;
|
|
|
|
|
*tbuff++ = v >> 8;
|
|
|
|
|
*tbuff++ = v;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void OSave(BOOL v)
|
|
|
|
|
{
|
|
|
|
|
if (v != FALSE)
|
|
|
|
|
*tbuff++ = TRUE;
|
|
|
|
|
else
|
|
|
|
|
*tbuff++ = FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SavePlayer(int i)
|
|
|
|
|
{
|
|
|
|
|
memcpy(tbuff, &plr[i], sizeof(*plr) - (10 * sizeof(void *)));
|
|
|
|
|
tbuff += sizeof(*plr) - (10 * sizeof(void *)); // omit last 10 pointers
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SaveMonster(int i)
|
|
|
|
|
{
|
|
|
|
|
memcpy(tbuff, &monster[i], sizeof(*monster) - (3 * sizeof(void *)));
|
|
|
|
|
tbuff += sizeof(*monster) - (3 * sizeof(void *)); // omit last 3 pointers
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SaveMissile(int i)
|
|
|
|
|
{
|
|
|
|
|
memcpy(tbuff, &missile[i], sizeof(*missile));
|
|
|
|
|
tbuff += sizeof(*missile);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SaveObject(int i)
|
|
|
|
|
{
|
|
|
|
|
memcpy(tbuff, &object[i], sizeof(*object));
|
|
|
|
|
tbuff += sizeof(*object);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SaveItem(int i)
|
|
|
|
|
{
|
|
|
|
|
memcpy(tbuff, &item[i], sizeof(*item));
|
|
|
|
|
tbuff += sizeof(*item);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SavePremium(int i)
|
|
|
|
|
{
|
|
|
|
|
memcpy(tbuff, &premiumitem[i], sizeof(*premiumitem));
|
|
|
|
|
tbuff += sizeof(*premiumitem);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SaveQuest(int i)
|
|
|
|
|
{
|
|
|
|
|
memcpy(tbuff, &quests[i], sizeof(*quests));
|
|
|
|
|
tbuff += sizeof(*quests);
|
|
|
|
|
WSave(ReturnLvlX);
|
|
|
|
|
WSave(ReturnLvlY);
|
|
|
|
|
WSave(ReturnLvl);
|
|
|
|
|
WSave(ReturnLvlT);
|
|
|
|
|
WSave(DoomQuestState);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SaveLighting(int i)
|
|
|
|
|
{
|
|
|
|
|
memcpy(tbuff, &LightList[i], sizeof(*LightList));
|
|
|
|
|
tbuff += sizeof(*LightList);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SaveVision(int i)
|
|
|
|
|
{
|
|
|
|
|
memcpy(tbuff, &VisionList[i], sizeof(*VisionList));
|
|
|
|
|
tbuff += sizeof(*VisionList);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SavePortal(int i)
|
|
|
|
|
{
|
|
|
|
|
memcpy(tbuff, &portal[i], sizeof(*portal));
|
|
|
|
|
tbuff += sizeof(*portal);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SaveLevel()
|
|
|
|
|
{
|
|
|
|
|
int i, j;
|
|
|
|
|
char szName[MAX_PATH];
|
|
|
|
|
int dwLen;
|
|
|
|
|
unsigned char *SaveBuff;
|
|
|
|
|
|
|
|
|
|
if (!currlevel)
|
|
|
|
|
glSeedTbl[0] = GetRndSeed();
|
|
|
|
|
|
|
|
|
|
dwLen = codec_get_encoded_len(FILEBUFF);
|
|
|
|
|
SaveBuff = DiabloAllocPtr(dwLen);
|
|
|
|
|
tbuff = SaveBuff;
|
|
|
|
|
|
|
|
|
|
if (leveltype != DTYPE_TOWN) {
|
|
|
|
|
for (j = 0; j < MAXDUNY; j++) {
|
|
|
|
|
for (i = 0; i < MAXDUNX; i++)
|
|
|
|
|
BSave(dDead[i][j]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
WSave(nummonsters);
|
|
|
|
|
WSave(numitems);
|
|
|
|
|
WSave(nobjects);
|
|
|
|
|
|
|
|
|
|
if (leveltype != DTYPE_TOWN) {
|
|
|
|
|
for (i = 0; i < MAXMONSTERS; i++)
|
|
|
|
|
WSave(monstactive[i]);
|
|
|
|
|
for (i = 0; i < nummonsters; i++)
|
|
|
|
|
SaveMonster(monstactive[i]);
|
|
|
|
|
for (i = 0; i < MAXOBJECTS; i++)
|
|
|
|
|
BSave(objectactive[i]);
|
|
|
|
|
for (i = 0; i < MAXOBJECTS; i++)
|
|
|
|
|
BSave(objectavail[i]);
|
|
|
|
|
for (i = 0; i < nobjects; i++)
|
|
|
|
|
SaveObject(objectactive[i]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < MAXITEMS; i++)
|
|
|
|
|
BSave(itemactive[i]);
|
|
|
|
|
for (i = 0; i < MAXITEMS; i++)
|
|
|
|
|
BSave(itemavail[i]);
|
|
|
|
|
for (i = 0; i < numitems; i++)
|
|
|
|
|
SaveItem(itemactive[i]);
|
|
|
|
|
|
|
|
|
|
for (j = 0; j < MAXDUNY; j++) {
|
|
|
|
|
for (i = 0; i < MAXDUNX; i++)
|
|
|
|
|
BSave(dFlags[i][j] & ~(BFLAG_MISSILE | BFLAG_VISIBLE | BFLAG_DEAD_PLAYER));
|
|
|
|
|
}
|
|
|
|
|
for (j = 0; j < MAXDUNY; j++) {
|
|
|
|
|
for (i = 0; i < MAXDUNX; i++)
|
|
|
|
|
BSave(dItem[i][j]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (leveltype != DTYPE_TOWN) {
|
|
|
|
|
for (j = 0; j < MAXDUNY; j++) {
|
|
|
|
|
for (i = 0; i < MAXDUNX; i++)
|
|
|
|
|
WSave(dMonster[i][j]);
|
|
|
|
|
}
|
|
|
|
|
for (j = 0; j < MAXDUNY; j++) {
|
|
|
|
|
for (i = 0; i < MAXDUNX; i++)
|
|
|
|
|
BSave(dObject[i][j]);
|
|
|
|
|
}
|
|
|
|
|
for (j = 0; j < MAXDUNY; j++) {
|
|
|
|
|
for (i = 0; i < MAXDUNX; i++)
|
|
|
|
|
BSave(dLight[i][j]);
|
|
|
|
|
}
|
|
|
|
|
for (j = 0; j < MAXDUNY; j++) {
|
|
|
|
|
for (i = 0; i < MAXDUNX; i++)
|
|
|
|
|
BSave(dPreLight[i][j]);
|
|
|
|
|
}
|
|
|
|
|
for (j = 0; j < DMAXY; j++) {
|
|
|
|
|
for (i = 0; i < DMAXX; i++)
|
|
|
|
|
OSave(automapview[i][j]);
|
|
|
|
|
}
|
|
|
|
|
for (j = 0; j < MAXDUNY; j++) {
|
|
|
|
|
for (i = 0; i < MAXDUNX; i++)
|
|
|
|
|
BSave(dMissile[i][j]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GetTempLevelNames(szName);
|
|
|
|
|
dwLen = codec_get_encoded_len(tbuff - SaveBuff);
|
|
|
|
|
pfile_write_save_file(szName, SaveBuff, tbuff - SaveBuff, dwLen);
|
|
|
|
|
mem_free_dbg(SaveBuff);
|
|
|
|
|
|
|
|
|
|
if (setlevel == 0)
|
|
|
|
|
plr[myplr]._pLvlVisited[currlevel] = 1;
|
|
|
|
|
else
|
|
|
|
|
plr[myplr]._pSLvlVisited[setlvlnum] = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void LoadLevel()
|
|
|
|
|
{
|
|
|
|
|
int i, j;
|
|
|
|
|
DWORD dwLen;
|
|
|
|
|
char szName[MAX_PATH];
|
|
|
|
|
BYTE *LoadBuff;
|
|
|
|
|
|
|
|
|
|
GetPermLevelNames(szName);
|
|
|
|
|
LoadBuff = pfile_read(szName, &dwLen);
|
|
|
|
|
tbuff = LoadBuff;
|
|
|
|
|
|
|
|
|
|
if (leveltype != DTYPE_TOWN) {
|
|
|
|
|
for (j = 0; j < MAXDUNY; j++) {
|
|
|
|
|
for (i = 0; i < MAXDUNX; i++)
|
|
|
|
|
dDead[i][j] = BLoad();
|
|
|
|
|
}
|
|
|
|
|
SetDead();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nummonsters = WLoad();
|
|
|
|
|
numitems = WLoad();
|
|
|
|
|
nobjects = WLoad();
|
|
|
|
|
|
|
|
|
|
if (leveltype != DTYPE_TOWN) {
|
|
|
|
|
for (i = 0; i < MAXMONSTERS; i++)
|
|
|
|
|
monstactive[i] = WLoad();
|
|
|
|
|
for (i = 0; i < nummonsters; i++)
|
|
|
|
|
LoadMonster(monstactive[i]);
|
|
|
|
|
for (i = 0; i < MAXOBJECTS; i++)
|
|
|
|
|
objectactive[i] = BLoad();
|
|
|
|
|
for (i = 0; i < MAXOBJECTS; i++)
|
|
|
|
|
objectavail[i] = BLoad();
|
|
|
|
|
for (i = 0; i < nobjects; i++)
|
|
|
|
|
LoadObject(objectactive[i]);
|
|
|
|
|
for (i = 0; i < nobjects; i++)
|
|
|
|
|
SyncObjectAnim(objectactive[i]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < MAXITEMS; i++)
|
|
|
|
|
itemactive[i] = BLoad();
|
|
|
|
|
for (i = 0; i < MAXITEMS; i++)
|
|
|
|
|
itemavail[i] = BLoad();
|
|
|
|
|
for (i = 0; i < numitems; i++)
|
|
|
|
|
LoadItem(itemactive[i]);
|
|
|
|
|
|
|
|
|
|
for (j = 0; j < MAXDUNY; j++) {
|
|
|
|
|
for (i = 0; i < MAXDUNX; i++)
|
|
|
|
|
dFlags[i][j] = BLoad();
|
|
|
|
|
}
|
|
|
|
|
for (j = 0; j < MAXDUNY; j++) {
|
|
|
|
|
for (i = 0; i < MAXDUNX; i++)
|
|
|
|
|
dItem[i][j] = BLoad();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (leveltype != DTYPE_TOWN) {
|
|
|
|
|
for (j = 0; j < MAXDUNY; j++) {
|
|
|
|
|
for (i = 0; i < MAXDUNX; i++)
|
|
|
|
|
dMonster[i][j] = WLoad();
|
|
|
|
|
}
|
|
|
|
|
for (j = 0; j < MAXDUNY; j++) {
|
|
|
|
|
for (i = 0; i < MAXDUNX; i++)
|
|
|
|
|
dObject[i][j] = BLoad();
|
|
|
|
|
}
|
|
|
|
|
for (j = 0; j < MAXDUNY; j++) {
|
|
|
|
|
for (i = 0; i < MAXDUNX; i++)
|
|
|
|
|
dLight[i][j] = BLoad();
|
|
|
|
|
}
|
|
|
|
|
for (j = 0; j < MAXDUNY; j++) {
|
|
|
|
|
for (i = 0; i < MAXDUNX; i++)
|
|
|
|
|
dPreLight[i][j] = BLoad();
|
|
|
|
|
}
|
|
|
|
|
for (j = 0; j < DMAXY; j++) {
|
|
|
|
|
for (i = 0; i < DMAXX; i++)
|
|
|
|
|
automapview[i][j] = OLoad();
|
|
|
|
|
}
|
|
|
|
|
for (j = 0; j < MAXDUNY; j++) {
|
|
|
|
|
for (i = 0; i < MAXDUNX; i++)
|
|
|
|
|
dMissile[i][j] = 0; /// BUGFIX: supposed to load saved missiles with "BLoad()"?
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
AutomapZoomReset();
|
|
|
|
|
ResyncQuests();
|
|
|
|
|
SyncPortals();
|
|
|
|
|
dolighting = 1;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < MAX_PLRS; i++) {
|
|
|
|
|
if (plr[i].plractive && currlevel == plr[i].plrlevel)
|
|
|
|
|
LightList[plr[i]._plid]._lunflag = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mem_free_dbg(LoadBuff);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DEVILUTION_END_NAMESPACE
|