Browse Source

Merge pull request #1333 from AJenbo/spawn

Spawn (Shareware)
pull/202/head^2^2
qndel 7 years ago committed by GitHub
parent
commit
0c461d50c5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      DiabloUI/diabloui.h
  2. 1
      DiabloUI/diabloui_gcc.def
  3. 4
      MakefileVC
  4. 4
      Source/control.cpp
  5. 19
      Source/diablo.cpp
  6. 4
      Source/drlg_l1.cpp
  7. 2
      Source/drlg_l2.cpp
  8. 6
      Source/drlg_l3.cpp
  9. 2
      Source/drlg_l4.cpp
  10. 40
      Source/effects.cpp
  11. 8
      Source/gendung.cpp
  12. 360
      Source/help.cpp
  13. 30
      Source/init.cpp
  14. 105
      Source/inv.cpp
  15. 16
      Source/items.cpp
  16. 8
      Source/mainmenu.cpp
  17. 4
      Source/missiles.cpp
  18. 5
      Source/monstdat.cpp
  19. 34
      Source/monster.cpp
  20. 8
      Source/mpqapi.cpp
  21. 2
      Source/msg.cpp
  22. 12
      Source/multi.cpp
  23. 2
      Source/multi.h
  24. 14
      Source/objects.cpp
  25. 2
      Source/palette.cpp
  26. 26
      Source/pfile.cpp
  27. 28
      Source/player.cpp
  28. 19
      Source/quests.cpp
  29. 2
      Source/setmaps.cpp
  30. 6
      Source/sound.cpp
  31. 8
      Source/stores.cpp
  32. 6
      Source/textdat.cpp
  33. 8
      Source/town.cpp
  34. 13
      Source/towners.cpp
  35. 26
      Source/trigs.cpp
  36. 1
      defs.h
  37. 1772
      enums.h
  38. 2
      structs.h
  39. 2
      types.h

1
DiabloUI/diabloui.h

@ -27,6 +27,7 @@ struct ProfFntStruct {
void __stdcall UiDestroy();
BOOL __stdcall UiTitleDialog(int a1);
void __stdcall UiSetSpawned(BOOL bSpawned);
void __stdcall UiInitialize();
BOOL __stdcall UiCopyProtError(int *pdwResult);
void __stdcall UiAppActivate(BOOL bActive);

1
DiabloUI/diabloui_gcc.def

@ -53,6 +53,7 @@ EXPORTS
UiSelectRegion @28
UiSetBackgroundBitmap @29
UiSetSpawned @30
UiSetSpawned@4 @30 NONAME
UiSetupPlayerInfo @31
UiSetupPlayerInfo@12 @31 NONAME
UiSoundCallback @32

4
MakefileVC

@ -43,6 +43,10 @@ ifeq ($(COPYPROT),1)
CFLAGS += /D "COPYPROT"
endif
ifeq ($(SPAWN),1)
CFLAGS += /D "SPAWN"
endif
ifeq ($(MAKE_BUILD),pdb)
VC_LINK = $(VC6_LINK)
LINKFLAGS += /pdb:"Diablo.pdb" /LIBPATH:$(VC6_LIB_DIR) /debug

4
Source/control.cpp

@ -1173,10 +1173,12 @@ void InitControlPan()
sbookflag = FALSE;
if (plr[myplr]._pClass == PC_WARRIOR) {
SpellPages[0][0] = SPL_REPAIR;
#ifndef SPAWN
} else if (plr[myplr]._pClass == PC_ROGUE) {
SpellPages[0][0] = SPL_DISARM;
} else if (plr[myplr]._pClass == PC_SORCERER) {
SpellPages[0][0] = SPL_RECHARGE;
#endif
}
pQLogCel = LoadFileInMem("Data\\Quest.CEL", NULL);
pGBoxBuff = LoadFileInMem("CtrlPan\\Golddrop.cel", NULL);
@ -1665,10 +1667,12 @@ void DrawChr()
if (plr[myplr]._pClass == PC_WARRIOR) {
ADD_PlrStringXY(168, 32, 299, "Warrior", COL_WHITE);
#ifndef SPAWN
} else if (plr[myplr]._pClass == PC_ROGUE) {
ADD_PlrStringXY(168, 32, 299, "Rogue", COL_WHITE); /* should use ClassStrTbl ? */
} else if (plr[myplr]._pClass == PC_SORCERER) {
ADD_PlrStringXY(168, 32, 299, "Sorceror", COL_WHITE);
#endif
}
sprintf(chrstr, "%i", plr[myplr]._pLevel);

19
Source/diablo.cpp

@ -86,7 +86,7 @@ BOOL StartGame(BOOL bNewGame, BOOL bSinglePlayer)
BOOL fExitProgram;
unsigned int uMsg;
byte_678640 = 1;
gbGameUninitialized = TRUE;
do {
fExitProgram = FALSE;
@ -97,7 +97,7 @@ BOOL StartGame(BOOL bNewGame, BOOL bSinglePlayer)
break;
}
byte_678640 = 0;
gbGameUninitialized = FALSE;
if (bNewGame || !gbValidSaveFile) {
InitLevels();
@ -272,12 +272,16 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
init_create_window(nCmdShow);
sound_init();
UiInitialize();
#ifdef SPAWN
UiSetSpawned(TRUE);
#endif
#ifdef _DEBUG
if (showintrodebug)
#endif
play_movie("gendata\\logo.smk", TRUE);
#ifndef SPAWN
{
char szValueName[] = "Intro";
if (!SRegLoadValue("Diablo", szValueName, 0, &nData))
@ -286,6 +290,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
play_movie("gendata\\diablo1.smk", TRUE);
SRegSaveValue("Diablo", szValueName, 0, 0);
}
#endif
#ifdef _DEBUG
if (showintrodebug) {
@ -1496,6 +1501,7 @@ void LoadLvlGFX()
pLevelPieces = LoadFileInMem("Levels\\L1Data\\L1.MIN", NULL);
pSpecialCels = LoadFileInMem("Levels\\L1Data\\L1S.CEL", NULL);
break;
#ifndef SPAWN
case DTYPE_CATACOMBS:
pDungeonCels = LoadFileInMem("Levels\\L2Data\\L2.CEL", NULL);
pMegaTiles = LoadFileInMem("Levels\\L2Data\\L2.TIL", NULL);
@ -1514,6 +1520,7 @@ void LoadLvlGFX()
pLevelPieces = LoadFileInMem("Levels\\L4Data\\L4.MIN", NULL);
pSpecialCels = LoadFileInMem("Levels\\L2Data\\L2S.CEL", NULL);
break;
#endif
default:
app_fatal("LoadLvlGFX");
break;
@ -1546,6 +1553,7 @@ void CreateLevel(int lvldir)
Freeupstairs();
LoadRndLvlPal(1);
break;
#ifndef SPAWN
case DTYPE_CATACOMBS:
CreateL2Dungeon(glSeedTbl[currlevel], lvldir);
InitL2Triggers();
@ -1564,6 +1572,7 @@ void CreateLevel(int lvldir)
Freeupstairs();
LoadRndLvlPal(4);
break;
#endif
default:
app_fatal("CreateLevel");
break;
@ -1707,6 +1716,7 @@ void LoadGameLevel(BOOL firstflag, int lvldir)
ResyncQuests();
else
ResyncMPQuests();
#ifndef SPAWN
} else {
/// ASSERT: assert(! pSpeedCels);
pSpeedCels = DiabloAllocPtr(0x100000);
@ -1742,6 +1752,7 @@ void LoadGameLevel(BOOL firstflag, int lvldir)
InitMissiles();
IncProgress();
#endif
}
SyncPortals();
@ -1780,8 +1791,10 @@ void LoadGameLevel(BOOL firstflag, int lvldir)
while (!IncProgress())
;
#ifndef SPAWN
if (setlevel && setlvlnum == SL_SKELKING && quests[QTYPE_KING]._qactive == 2)
PlaySFX(USFX_SKING1);
#endif
}
void game_loop(BOOL bStartup)
@ -1876,7 +1889,7 @@ void diablo_color_cyc_logic()
DWORD tc;
tc = GetTickCount();
if (tc - color_cycle_timer >= 0x32) {
if (tc - color_cycle_timer >= 50) {
color_cycle_timer = tc;
if (palette_get_colour_cycling()) {
if (leveltype == DTYPE_HELL) {

4
Source/drlg_l1.cpp

@ -127,6 +127,7 @@ void DRLG_Init_Globals()
memset(dLight, c, sizeof(dLight));
}
#ifndef SPAWN
void LoadL1Dungeon(char *sFileName, int vx, int vy)
{
int i, j, rw, rh;
@ -175,6 +176,7 @@ void LoadL1Dungeon(char *sFileName, int vx, int vy)
SetMapObjects(pLevelMap, 0, 0);
mem_free_dbg(pLevelMap);
}
#endif
void DRLG_L1Floor()
{
@ -323,6 +325,7 @@ void DRLG_InitL1Vals()
}
}
#ifndef SPAWN
void LoadPreL1Dungeon(char *sFileName, int vx, int vy)
{
int i, j, rw, rh;
@ -370,6 +373,7 @@ void LoadPreL1Dungeon(char *sFileName, int vx, int vy)
mem_free_dbg(pLevelMap);
}
#endif
void CreateL5Dungeon(DWORD rseed, int entry)
{

2
Source/drlg_l2.cpp

@ -1,3 +1,4 @@
#ifndef SPAWN
#include "diablo.h"
int nSx1;
@ -2151,3 +2152,4 @@ void DRLG_InitL2Vals()
}
}
}
#endif

6
Source/drlg_l3.cpp

@ -1,3 +1,4 @@
#ifndef SPAWN
#include "diablo.h"
BOOLEAN lavapool;
@ -1020,8 +1021,8 @@ void DRLG_L3River()
}
}
/**
* Flood fills dirt and wall tiles looking for
/**
* Flood fills dirt and wall tiles looking for
* an area of at most 40 tiles and disconnected from the map edge.
* If it finds one, converts it to lava tiles and sets lavapool to TRUE.
*/
@ -1825,3 +1826,4 @@ void LoadPreL3Dungeon(char *sFileName, int vx, int vy)
memcpy(pdungeon, dungeon, sizeof(pdungeon));
mem_free_dbg(pLevelMap);
}
#endif

2
Source/drlg_l4.cpp

@ -8,6 +8,7 @@ int diabquad2x;
int diabquad2y;
int diabquad4x;
int diabquad4y;
#ifndef SPAWN
BOOL hallok[20];
int l4holdx;
int l4holdy;
@ -1988,3 +1989,4 @@ void DRLG_L4Pass3()
yy += 2;
}
}
#endif

40
Source/effects.cpp

@ -10,7 +10,7 @@ const char monster_action_sounds[] = { 'a', 'h', 'd', 's' };
/* data */
TSFX sgSFX[NUM_SFX] = {
TSFX sgSFX[] = {
// clang-format off
// bFlags, pszName, pSnd
{ SFX_MISC, "Sfx\\Misc\\Walk1.wav", NULL },
@ -153,6 +153,7 @@ TSFX sgSFX[NUM_SFX] = {
{ SFX_MISC, "Sfx\\Misc\\Vtheft.wav", NULL },
{ SFX_MISC, "Sfx\\Misc\\Wallloop.wav", NULL },
{ SFX_MISC, "Sfx\\Misc\\Wallstrt.wav", NULL },
#ifndef SPAWN
{ SFX_STREAM, "Sfx\\Towners\\Bmaid01.wav", NULL },
{ SFX_STREAM, "Sfx\\Towners\\Bmaid02.wav", NULL },
{ SFX_STREAM, "Sfx\\Towners\\Bmaid03.wav", NULL },
@ -183,7 +184,9 @@ TSFX sgSFX[NUM_SFX] = {
{ SFX_STREAM, "Sfx\\Towners\\Bmaid28.wav", NULL },
{ SFX_STREAM, "Sfx\\Towners\\Bmaid29.wav", NULL },
{ SFX_STREAM, "Sfx\\Towners\\Bmaid30.wav", NULL },
#endif
{ SFX_STREAM, "Sfx\\Towners\\Bmaid31.wav", NULL },
#ifndef SPAWN
{ SFX_STREAM, "Sfx\\Towners\\Bmaid32.wav", NULL },
{ SFX_STREAM, "Sfx\\Towners\\Bmaid33.wav", NULL },
{ SFX_STREAM, "Sfx\\Towners\\Bmaid34.wav", NULL },
@ -236,7 +239,9 @@ TSFX sgSFX[NUM_SFX] = {
{ SFX_STREAM, "Sfx\\Towners\\Bsmith41.wav", NULL },
{ SFX_STREAM, "Sfx\\Towners\\Bsmith42.wav", NULL },
{ SFX_STREAM, "Sfx\\Towners\\Bsmith43.wav", NULL },
#endif
{ SFX_STREAM, "Sfx\\Towners\\Bsmith44.wav", NULL },
#ifndef SPAWN
{ SFX_STREAM, "Sfx\\Towners\\Bsmith45.wav", NULL },
{ SFX_STREAM, "Sfx\\Towners\\Bsmith46.wav", NULL },
{ SFX_STREAM, "Sfx\\Towners\\Bsmith47.wav", NULL },
@ -249,8 +254,10 @@ TSFX sgSFX[NUM_SFX] = {
{ SFX_STREAM, "Sfx\\Towners\\Bsmith54.wav", NULL },
{ SFX_STREAM, "Sfx\\Towners\\Bsmith55.wav", NULL },
{ SFX_STREAM, "Sfx\\Towners\\Bsmith56.wav", NULL },
#endif
{ 0, "Sfx\\Towners\\Cow1.wav", NULL },
{ 0, "Sfx\\Towners\\Cow2.wav", NULL },
#ifndef SPAWN
{ SFX_STREAM, "Sfx\\Towners\\Deadguy2.wav", NULL },
{ SFX_STREAM, "Sfx\\Towners\\Drunk01.wav", NULL },
{ SFX_STREAM, "Sfx\\Towners\\Drunk02.wav", NULL },
@ -278,7 +285,9 @@ TSFX sgSFX[NUM_SFX] = {
{ SFX_STREAM, "Sfx\\Towners\\Drunk24.wav", NULL },
{ SFX_STREAM, "Sfx\\Towners\\Drunk25.wav", NULL },
{ SFX_STREAM, "Sfx\\Towners\\Drunk26.wav", NULL },
#endif
{ SFX_STREAM, "Sfx\\Towners\\Drunk27.wav", NULL },
#ifndef SPAWN
{ SFX_STREAM, "Sfx\\Towners\\Drunk28.wav", NULL },
{ SFX_STREAM, "Sfx\\Towners\\Drunk29.wav", NULL },
{ SFX_STREAM, "Sfx\\Towners\\Drunk30.wav", NULL },
@ -323,7 +332,9 @@ TSFX sgSFX[NUM_SFX] = {
{ SFX_STREAM, "Sfx\\Towners\\Healer34.wav", NULL },
{ SFX_STREAM, "Sfx\\Towners\\Healer35.wav", NULL },
{ SFX_STREAM, "Sfx\\Towners\\Healer36.wav", NULL },
#endif
{ SFX_STREAM, "Sfx\\Towners\\Healer37.wav", NULL },
#ifndef SPAWN
{ SFX_STREAM, "Sfx\\Towners\\Healer38.wav", NULL },
{ SFX_STREAM, "Sfx\\Towners\\Healer39.wav", NULL },
{ SFX_STREAM, "Sfx\\Towners\\Healer40.wav", NULL },
@ -365,7 +376,9 @@ TSFX sgSFX[NUM_SFX] = {
{ SFX_STREAM, "Sfx\\Towners\\Pegboy29.wav", NULL },
{ SFX_STREAM, "Sfx\\Towners\\Pegboy30.wav", NULL },
{ SFX_STREAM, "Sfx\\Towners\\Pegboy31.wav", NULL },
#endif
{ SFX_STREAM, "Sfx\\Towners\\Pegboy32.wav", NULL },
#ifndef SPAWN
{ SFX_STREAM, "Sfx\\Towners\\Pegboy33.wav", NULL },
{ SFX_STREAM, "Sfx\\Towners\\Pegboy34.wav", NULL },
{ SFX_STREAM, "Sfx\\Towners\\Pegboy35.wav", NULL },
@ -410,7 +423,9 @@ TSFX sgSFX[NUM_SFX] = {
{ SFX_STREAM, "Sfx\\Towners\\Storyt22.wav", NULL },
{ SFX_STREAM, "Sfx\\Towners\\Storyt23.wav", NULL },
{ SFX_STREAM, "Sfx\\Towners\\Storyt24.wav", NULL },
#endif
{ SFX_STREAM, "Sfx\\Towners\\Storyt25.wav", NULL },
#ifndef SPAWN
{ SFX_STREAM, "Sfx\\Towners\\Storyt26.wav", NULL },
{ SFX_STREAM, "Sfx\\Towners\\Storyt27.wav", NULL },
{ SFX_STREAM, "Sfx\\Towners\\Storyt28.wav", NULL },
@ -424,7 +439,9 @@ TSFX sgSFX[NUM_SFX] = {
{ SFX_STREAM, "Sfx\\Towners\\Storyt36.wav", NULL },
{ SFX_STREAM, "Sfx\\Towners\\Storyt37.wav", NULL },
{ SFX_STREAM, "Sfx\\Towners\\Storyt38.wav", NULL },
#endif
{ SFX_STREAM, "Sfx\\Towners\\Tavown00.wav", NULL },
#ifndef SPAWN
{ SFX_STREAM, "Sfx\\Towners\\Tavown01.wav", NULL },
{ SFX_STREAM, "Sfx\\Towners\\Tavown02.wav", NULL },
{ SFX_STREAM, "Sfx\\Towners\\Tavown03.wav", NULL },
@ -460,7 +477,9 @@ TSFX sgSFX[NUM_SFX] = {
{ SFX_STREAM, "Sfx\\Towners\\Tavown33.wav", NULL },
{ SFX_STREAM, "Sfx\\Towners\\Tavown34.wav", NULL },
{ SFX_STREAM, "Sfx\\Towners\\Tavown35.wav", NULL },
#endif
{ SFX_STREAM, "Sfx\\Towners\\Tavown36.wav", NULL },
#ifndef SPAWN
{ SFX_STREAM, "Sfx\\Towners\\Tavown37.wav", NULL },
{ SFX_STREAM, "Sfx\\Towners\\Tavown38.wav", NULL },
{ SFX_STREAM, "Sfx\\Towners\\Tavown39.wav", NULL },
@ -507,7 +526,9 @@ TSFX sgSFX[NUM_SFX] = {
{ SFX_STREAM, "Sfx\\Towners\\Witch35.wav", NULL },
{ SFX_STREAM, "Sfx\\Towners\\Witch36.wav", NULL },
{ SFX_STREAM, "Sfx\\Towners\\Witch37.wav", NULL },
#endif
{ SFX_STREAM, "Sfx\\Towners\\Witch38.wav", NULL },
#ifndef SPAWN
{ SFX_STREAM, "Sfx\\Towners\\Witch39.wav", NULL },
{ SFX_STREAM, "Sfx\\Towners\\Witch40.wav", NULL },
{ SFX_STREAM, "Sfx\\Towners\\Witch41.wav", NULL },
@ -739,6 +760,7 @@ TSFX sgSFX[NUM_SFX] = {
{ SFX_STREAM | SFX_WARRIOR, "Sfx\\Warrior\\Warior10.wav", NULL },
{ SFX_STREAM | SFX_WARRIOR, "Sfx\\Warrior\\Warior11.wav", NULL },
{ SFX_STREAM | SFX_WARRIOR, "Sfx\\Warrior\\Warior12.wav", NULL },
#endif
{ SFX_WARRIOR, "Sfx\\Warrior\\Warior13.wav", NULL },
{ SFX_WARRIOR, "Sfx\\Warrior\\Warior14.wav", NULL },
{ SFX_WARRIOR, "Sfx\\Warrior\\Wario14b.wav", NULL },
@ -813,6 +835,7 @@ TSFX sgSFX[NUM_SFX] = {
{ SFX_WARRIOR, "Sfx\\Warrior\\Warior77.wav", NULL },
{ SFX_WARRIOR, "Sfx\\Warrior\\Warior78.wav", NULL },
{ SFX_WARRIOR, "Sfx\\Warrior\\Warior79.wav", NULL },
#ifndef SPAWN
{ SFX_STREAM | SFX_WARRIOR, "Sfx\\Warrior\\Warior80.wav", NULL },
{ SFX_STREAM | SFX_WARRIOR, "Sfx\\Warrior\\Warior81.wav", NULL },
{ SFX_STREAM | SFX_WARRIOR, "Sfx\\Warrior\\Warior82.wav", NULL },
@ -834,10 +857,12 @@ TSFX sgSFX[NUM_SFX] = {
{ SFX_STREAM | SFX_WARRIOR, "Sfx\\Warrior\\Wario95d.wav", NULL },
{ SFX_STREAM | SFX_WARRIOR, "Sfx\\Warrior\\Wario95e.wav", NULL },
{ SFX_STREAM | SFX_WARRIOR, "Sfx\\Warrior\\Wario95f.wav", NULL },
#endif
{ SFX_STREAM | SFX_WARRIOR, "Sfx\\Warrior\\Wario96b.wav", NULL },
{ SFX_STREAM | SFX_WARRIOR, "Sfx\\Warrior\\Wario97.wav", NULL },
{ SFX_STREAM | SFX_WARRIOR, "Sfx\\Warrior\\Wario98.wav", NULL },
{ SFX_STREAM | SFX_WARRIOR, "Sfx\\Warrior\\Warior99.wav", NULL },
#ifndef SPAWN
{ SFX_STREAM | SFX_WARRIOR, "Sfx\\Warrior\\Wario100.wav", NULL },
{ SFX_STREAM | SFX_WARRIOR, "Sfx\\Warrior\\Wario101.wav", NULL },
{ SFX_STREAM | SFX_WARRIOR, "Sfx\\Warrior\\Wario102.wav", NULL },
@ -871,6 +896,7 @@ TSFX sgSFX[NUM_SFX] = {
{ SFX_STREAM, "Sfx\\Monsters\\Zhar01.wav", NULL },
{ SFX_STREAM, "Sfx\\Monsters\\Zhar02.wav", NULL },
{ SFX_STREAM, "Sfx\\Monsters\\DiabloD.wav", NULL }
#endif
// clang-format on
};
@ -1077,10 +1103,12 @@ int RndSFX(int psfx)
nRand = 3;
else if (psfx == PS_WARR16)
nRand = 3;
#ifndef SPAWN
else if (psfx == PS_MAGE69)
nRand = 2;
else if (psfx == PS_ROGUE69)
nRand = 2;
#endif
else if (psfx == PS_SWING)
nRand = 2;
else if (psfx == LS_ACID)
@ -1091,8 +1119,10 @@ int RndSFX(int psfx)
nRand = 2;
else if (psfx == IS_BHIT)
nRand = 2;
#ifndef SPAWN
else if (psfx == PS_WARR2)
nRand = 3;
#endif
else
return psfx;
return psfx + random(165, nRand);
@ -1136,7 +1166,7 @@ void sound_stop()
TSFX *snd;
snd = &sgSFX[0];
for (i = 0; i < NUM_SFX; i++) {
for (i = 0; i < sizeof(sgSFX) / sizeof(TSFX); i++) {
if (snd->pSnd)
snd_stop_snd(snd->pSnd);
snd++;
@ -1168,7 +1198,7 @@ void effects_cleanup_sfx()
FreeMonsterSnd();
for (i = 0; i < NUM_SFX; i++) {
for (i = 0; i < sizeof(sgSFX) / sizeof(TSFX); i++) {
if (sgSFX[i].pSnd) {
sound_file_cleanup(sgSFX[i].pSnd);
sgSFX[i].pSnd = NULL;
@ -1206,7 +1236,7 @@ void priv_sound_init(BYTE bLoadMask)
pc = bLoadMask & (SFX_ROGUE | SFX_WARRIOR | SFX_SORCEROR);
bLoadMask ^= pc;
for (i = 0; i < NUM_SFX; i++) {
for (i = 0; i < sizeof(sgSFX) / sizeof(TSFX); i++) {
if (sgSFX[i].pSnd) {
continue;
}
@ -1241,7 +1271,7 @@ void __stdcall effects_play_sound(char *snd_file)
return;
}
for (i = 0; i < NUM_SFX; i++) {
for (i = 0; i < sizeof(sgSFX) / sizeof(TSFX); i++) {
if (!_strcmpi(sgSFX[i].pszName, snd_file) && sgSFX[i].pSnd) {
if (!snd_playing(sgSFX[i].pSnd))
snd_play_snd(sgSFX[i].pSnd, 0, 0);

8
Source/gendung.cpp

@ -594,6 +594,7 @@ void DRLG_CopyTrans(int sx, int sy, int dx, int dy)
dTransVal[dx][dy] = dTransVal[sx][sy];
}
#ifndef SPAWN
void DRLG_ListTrans(int num, BYTE *List)
{
int i;
@ -619,10 +620,11 @@ void DRLG_AreaTrans(int num, BYTE *List)
x2 = *List++;
y2 = *List++;
DRLG_RectTrans(x1, y1, x2, y2);
--TransVal;
TransVal--;
}
++TransVal;
TransVal++;
}
#endif
void DRLG_InitSetPC()
{
@ -648,6 +650,7 @@ void DRLG_SetPC()
}
}
#ifndef SPAWN
void Make_SetPC(int x, int y, int w, int h)
{
int i, j, dx, dy, dh, dw;
@ -913,6 +916,7 @@ void DRLG_PlaceThemeRooms(int minSize, int maxSize, int floor, int freq, int rnd
}
}
}
#endif
void DRLG_HoldThemeRooms()
{

360
Source/help.cpp

@ -7,6 +7,365 @@ int displayinghelp[22]; /* check, does nothing? */
int HelpTop;
const char gszHelpText[] = {
#ifdef SPAWN
"Shareware Diablo Help|"
"|"
"$Keyboard Shortcuts:|"
"Diablo can be played exclusively by using the mouse controls. "
"There are times, however, when you may want to use shortcuts to some "
"commands by using the keyboard. These shortcuts are listed below:|"
"|"
"F1: Open the Help Screen|"
"Esc: Displays the main menu|"
"Tab: Displays the Auto-map|"
"Space: Removes any pop-up menus or maps from the play area|"
"S: Open Speedbook|"
"B: Open Spellbook|"
"I: Opens the Inventory screen|"
"C: Opens the Character screen|"
"Z: Zooms the game screen in and out|"
"F: Reduces the brightness of the screen|"
"G: Increases the brightness of the screen|"
"Q: Opens the Quest log (non-functional in the Shareware version)|"
"1 - 8: Use that item from your Belt|"
"F5, F6, F7, F8: Sets a hot key for a selected skill or spell|"
"Shift + Left Click: Use any weapon without moving|"
"|"
"|"
"$Movement:|"
"Movement is controlled by the mouse. The gauntlet on the screen is "
"your cursor. Use this to indicate the destination of your character "
"and then left-click to move to that area. "
"If you hold the mouse button down while moving, the character "
"will continue to move in that direction.|"
"|"
"$Selecting Items:|"
"What you can interact with within the game is easily identifiable. "
"Move the cursor over any object or creature. If the object can be "
"picked up, attacked, activated or used in any way, it will be "
"immediately outlined. A description of the highlighted object appears "
"in the text area on the control panel.|"
"|"
"Example: If you select a door and then left-click the character will "
"walk to the door and open it. If you left-click on a highlighted "
"weapon, the character will walk over to it and put it in his "
"inventory. If you left-click on a highlighted creature...|"
"|"
"$Combat:|"
"Combat is initiated by left-clicking on a creature that has been "
"highlighted. If your character is equipped with a melee weapon "
"(Sword, Mace, Ax, etc.) your character will move to range and attack. "
"If your character is equipped with a bow, left-clicking will fire an "
"arrow at the highlighted creature. "
"Holding down the shift key and then left-clicking allows the "
"character to attack without moving.|"
"|"
"$Picking up Objects:|"
"If you left-click on an item - such as a weapon, shield, armor or "
"book - your character will move to that item and add it to his "
"inventory automatically.|"
"|"
"Useable items that are small in size - such as a potion or "
"scroll - are automatically placed in your 'belt', located at the "
"top of the Interface bar . When an item is placed in the belt, "
"a small number appears in that box. Items may be used by either "
"right-clicking on the item or pressing the corresponding number on "
"the keyboard.|"
"|"
"If you do not have enough room in your inventory or belt for an item "
"that you try to pick up, it will fall from your grasp. Open your "
"inventory screen and try re-arranging or removing items to carry "
"what you really want or need.|"
"|"
"$Inventory:|"
"You can toggle the Inventory screen on and off by clicking the "
"INV> button on the control panel. Items may be moved around in "
"your inventory by selecting them and then left-clicking to pick "
"them up. When you pick up an item while in the inventory screen, "
"your cursor changes into the item. You can then place this item into "
"empty spaces in your inventory, swap them with other items in your "
"inventory or equip them.|"
"|"
"If you have an item that you no longer wish to carry, simply "
"grab the item from your inventory and then left-click in the "
"play area to drop it.|"
"|"
"$Equipping Items:|"
"To equip an item, open the inventory screen and pick up the desired "
"item, either from play or from your inventory, placing it in the "
"appropriate box on the figure in the inventory screen. Weapons and "
"shields go into the large spaces to the right or left of the figure. "
"Two-handed weapons such as bows and axes preclude the use of a "
"shield and will take up both of these large spaces.|"
"|"
"Cloaks, robes, capes and all other armor must go in the central "
"torso slot of the figure. |"
"|"
"Helmets and caps go in the box over the head of the character.|"
"|"
"Rings go into the small boxes at the hands of the figure.|"
"|"
"Amulets go into the small box at the next to the neck of the figure.|"
"|"
"To change items that your character has equipped, pick up a new "
"item and place it on top of the item you wish to remove. Your "
"character will automatically swap the items and the cursor will "
"now change into the item that was in that box.|"
"|"
"$Usable Items:|"
"Potions, elixirs and books are classified as usable items. These "
"items can be used by right-clicking on them in the inventory screen. "
"Books are too large to be placed in the belt, but any potions or "
"scrolls that are put there can also be used by pressing the "
"corresponding number on the keyboard.|"
"|"
"$Gold:|"
"You can select a specific amount of gold to drop by right "
"clicking on a pile of gold in your inventory. "
"A dialog will appear that allows you to select a specific amount of "
"gold to take. When you have entered that number, your cursor will "
"change into that amount of gold.|"
"|"
"$Item Information:|"
"Many items in Diablo share certain common attributes. These are "
"damage, durability, charges and minimum requirements..|"
"|"
"Damage: This is represented by a range that indicates the minimum "
"and maximum damage that item can inflict. A short sword has a (2-6) "
"after its name, meaning it inflicts a minimum of two damage and a "
"maximum of six when it hits. Damage can be modified by the quality "
"of the weapon, the character's strength and magical effects.|"
"|"
"Durability: This is the amount of damage that an item can take "
"before it is rendered useless. Durability is represented by a "
"ratio of current durability to maximum durability. A shield that "
"has a durability of 15/20 would still have 15 points of damage it "
"could take from use before it was rendered useless. Maximum "
"durability can be affected by the quality of the item, enchantments "
"or repairs made upon the item. The minimum durability can be raised "
"by repairing an item.|"
"|"
"Charges: Some items have charges associated with them. Charges "
"indicate how many times that item can be used to cast the spell or "
"affect indicated in its description. Charges are represented by "
"a ratio of charges left to maximum charges. A staff that has charges "
"listed as 2/5 could be used to cast 2 more spells before it was "
"rendered powerless. It could still be used to attack with as a "
"physical weapon, however. Maximum charges can be affected by the "
"magic or recharges cast upon the item. Minimum charges can be "
"raised by recharging the item.|"
"|"
"Minimum Requirements: These are the minimum requirements that a "
"character must meet to wield the item. The more powerful an item is, "
"the higher the minimum requirements will be. If a character "
"does not meet these requirements, he will be unable to equip the "
"item and its name and information will be displayed in red. "
"The item artwork will also have a red tint in the Inventory screen.|"
"|"
"$Items Classes:|"
"There are three classes of items in Diablo - Mundane, "
"Magic and Unique:|"
"|"
"Mundane items have no special attributes. Their information is "
"displayed in white text.|"
"|"
"Magic Items are represented by blue names and text descriptions. "
"Use the Identify spell or speak to Cain in town to determine their "
"exact properties and attributes.|"
"|"
"Unique items are represented by gold names and text descriptions. "
"Use the Identify spell or speak to Cain in town to determine their "
"exact properties and attributes.|"
"|"
"$Skills & Spells:|"
"You can access your list of skills and spells by left-clicking on "
"the SPELLS button in the interface bar. This 'Spellbook' contains all "
"of the skills and spells that your character knows. Spells "
"available through staffs are also listed here. Left-clicking on "
"the Icon of the spell you wish to ready will place it in the "
"'select current spell' icon/area and set it as the current "
"readied spell. A readied spell "
"may be cast by simply right-clicking in the play area.|"
"|"
"Left-clicking on the 'select current spell' button will also "
"open a 'Speedbook' menu that also allows you to ready a skill "
"or spell for use. To use a readied skill or spell, simply "
"right-click in the main play area.|"
"|"
"Skills are the innate abilities of your character. These skills "
"are different depending on what class you choose and require no "
"mana to use.|"
"|"
"Warrior:|"
"The Warrior has the skill of Repair Items. This allows him to fix "
"an item that has been worn by use or is damaged in combat. "
"To accomplish this, select the Repair Skill through the "
"Spellbook or Speedbook and right-click the mouse as if you were "
"casting a spell. Your cursor will change into a Hammer Icon "
"that you will use to select the item to be repaired. "
"Although Repairing an item in this way will decrease the "
"maximum durability of that item, it can be done without leaving "
"the labyrinth.|"
"|"
"The Blacksmith can also repair items for a price. When the "
"Blacksmith performs this service, it does decrease the maximum "
"durability of the item.|"
"|"
"Rogue:|"
"The Rogue has the skill of Disarm Traps. This allows her to not only "
"remove traps, but also acts as a 'sixth sense' that warns her of "
"where these trapped items are located. To accomplish this, select "
"the Disarm Trap skill through the Spellbook or Speedbook and "
"right-click the mouse as if you were casting a spell. "
"Your cursor will change into a Targeting Cursor that you will "
"use to select the item to be disarmed. The success of this "
"attempt is based on the level of the Rogue and the expertise of "
"whomever set the trap.|"
"|"
"Sorcerer:|"
"The Sorcerer has the skill of Recharge Staffs. This allows him to "
"focus his mana into an staff that has been drained of its magical "
"energies. To accomplish this, select the Recharge Staffs skill "
"through the Spellbook or Speedbook and right-click the mouse as "
"if you were casting a spell. Your cursor will change into a "
"Staff Icon that you will use to select the item to be recharged. "
"Although Recharging a staff in this way will decrease its maximum "
"charges, it can be done without leaving the labyrinth.|"
"|"
"The Witch can also recharge staffs for a price. When the Witch "
"performs this service, it does decrease the maximum charges of the "
"item.|"
"|"
"Spells are magical effects that can be cast from a scroll, "
"a staff or memorized from a book. Spells may or may not require "
"mana to use and are available to all classes.|"
"|"
"Spells cast from a scroll cost no mana to use, but are limited "
"to only one charge. Casting a spell from a scroll is accomplished "
"by either right clicking on the scroll or, if it is located in "
"our belt, pressing the corresponding number on the keyboard. "
"Scrolls can also be readied in the Speedbook and are represented "
"by a red icon/button in the 'select current spell' area.|"
"|"
"Spells cast from staffs cost no mana to use, but are limited by "
"the number of charges available. To cast spells from a staff, "
"it must first be equipped. The 'select current spell' icon/button "
"will change to indicate that the spell on the staff is currently "
"ready to cast. Scrolls can also be readied in the Spellbook or "
"Speedbook and are represented by an orange icon/button in the "
"'select current spell' area.|"
"|"
"Spells that are memorized cost mana to cast, but they can be used "
"as long as the character has mana to power them. The Warrior "
"and Rogue start the game with no memorized spells while "
"the sorcerer begins with Firebolt. If the character finds a book "
"in the labyrinth, he can memorize the spell written in that book "
"by opening the Inventory screen and right-clicking on the book. "
"This will make that spell always available to the character for "
"casting. Memorized spells can be readied through either the "
"Spellbook or Speedbook and are represented by a blue icon/button "
"in the 'select current spell' area.|"
"|"
"$Important note on books:|"
"Reading more than one book increases your knowledge of that spell "
"and gives you the spell at a higher level. The higher the level "
"of a spell the more effective it is.|"
"|"
"While some spells affect the caster, other spells require a target. "
"These targeted spells are cast in the direction that you indicate "
"with your cursor on the play area. If you highlight a creature, "
"you will cast that spell at that creature. Not all items within "
"the labyrinth can be targeted.|"
"|"
"Example: A fireball spell will travel at the creature or to the "
"location you right-click on. A Healing spell will simply add "
"health to your character while diminishing his available mana "
"and requires no targeting.|"
"|"
"You can also set a spell or scroll as a Hot Key position for "
"instant selection. Start by opening the pop-up menu as described "
"in the skill section above. Assign Hot Keys by hitting the "
"F5, F6, F7 or F8 keys on your keyboard after scrolling through "
"the available spells and highlighting the one you wish to assign. |"
"|"
"$Health and Mana:|"
"The two orbs in the Information Bar display your life and mana. "
"The red sphere of fluid on the left side of the control panel "
"represents the overall health of your character. When the fluid "
"is gone - your character is dead.|"
"|"
"The blue fluid on the right side of the control panel represents "
"your character's available mana. Mana is the magical force used by "
"your character to cast spells. When the liquid in the sphere is "
"low or depleted, you may be unable to cast some (or all) of your "
"spells.|"
"|"
"$Information Bar:|"
"The Information Bar is where you receive detailed information in "
"Diablo and interact with much of your surroundings. Here is a "
"quick run-down of the control panel areas and their use:|"
"|"
"CHAR: This button is used to access your Character Statistics screen|"
"INV: This button is used to access your Inventory screen|"
"Quest: This button displays your Quest Log (inactive in "
"Shareware version)|"
"Automap: This button activates the mapping overlay|"
"Menu: This button activates the game menu screen|"
"Spells: This button is used to access your Spellbook|"
"Current Spell: This is the spell that has been readied for "
"immediate casting|"
"Life Orb: This is the amount of health your character currently has|"
"Mana Orb: This is the amount of mana your character currently has|"
"Multiplayer Message: This activates the Message Area|"
"Description Area: This is where any important information about "
"creatures or items you can interact with is displayed. "
"This is also where you will enter the text you wish to send when "
"sending multiplayer messages.|"
"|"
"$Character Info:|"
"Toggle the Character Statistics Screen on and off by clicking the "
"<CHAR button on the Information Bar. This screen shows the "
"'nuts and bolts' of your character. There are four major attributes "
"that dictate how your character progresses in the game.|"
"|"
"STRENGTH: This is how physically powerful your character is. This "
"statistic plays a large part in determining how much damage you "
"can do when attacking creatures.|"
"|"
"MAGIC: This is how attuned your character is with the arcane powers "
"of the world. This statistic plays a large part in determining how "
"much mana you have available for casting spells.|"
"|"
"DEXTERITY: This is how quick of foot and hand your character is. "
"This statistic plays a large part in determining the chance you "
"have to hit creatures in combat.|"
"|"
"VITALITY: This is how physically fit your character is. This "
"statistic plays a large part in determining how much health your "
"character has when he is undamaged.|"
"|"
"$In Game Menu:|"
"To activate the Game Menu, click the MENU button on the Information "
"Bar. You have three options in this menu:|"
"|"
"New Game: This exits you from your current game and returns you to "
"the Main Menu.|"
"|"
"Options: This opens the options menu that allows you to "
"adjust your music and sound effects settings as well as "
"the gamma level of the screen.|"
"|"
"Quit Diablo: This exits the program. Please note that this "
"automatically saves your character.|"
"|"
"$Auto-map:|"
"Your character automatically maps where he has been in the "
"labyrinth. To access the auto-map, click the MAP button on the "
"Information Bar. You can also press TAB on your keyboard to activate "
"the auto-map. Zooming in and out of the map is done with the + and - "
"keys while scrolling the map uses the arrow keys.|"
"&"
#else
"$Keyboard Shortcuts:|"
"F1: Open Help Screen|"
"Esc: Display Main Menu|"
@ -73,6 +432,7 @@ const char gszHelpText[] = {
"Reading more than one book increases your knowledge of that "
"spell, allowing you to cast the spell more effectively.|"
"&"
#endif
};
void InitHelp()

30
Source/init.cpp

@ -231,7 +231,15 @@ void init_archives()
#ifdef COPYPROT
while (1) {
#endif
#ifdef SPAWN
diabdat_mpq = init_test_access(diabdat_mpq_path, "\\spawn.mpq", "DiabloSpawn", 1000, FS_PC);
#else
#ifdef COPYPROT
diabdat_mpq = init_test_access(diabdat_mpq_path, "\\diabdat.mpq", "DiabloCD", 1000, FS_CD);
#else
diabdat_mpq = init_test_access(diabdat_mpq_path, "\\diabdat.mpq", "DiabloCD", 1000, FS_PC);
#endif
#endif
#ifdef COPYPROT
if (diabdat_mpq)
break;
@ -241,9 +249,17 @@ void init_archives()
}
#endif
if (!WOpenFile("ui_art\\title.pcx", &fh, TRUE))
#ifdef SPAWN
FileErrDlg("Main program archive: spawn.mpq");
#else
FileErrDlg("Main program archive: diabdat.mpq");
#endif
WCloseFile(fh);
#ifdef SPAWN
patch_rt_mpq = init_test_access(patch_rt_mpq_path, "\\patch_sh.mpq", "DiabloSpawn", 2000, FS_PC);
#else
patch_rt_mpq = init_test_access(patch_rt_mpq_path, "\\patch_rt.mpq", "DiabloInstall", 2000, FS_PC);
#endif
}
HANDLE init_test_access(char *mpq_path, char *mpq_name, char *reg_loc, int flags, int fs)
@ -267,20 +283,12 @@ HANDLE init_test_access(char *mpq_path, char *mpq_name, char *reg_loc, int flags
init_strip_trailing_slash(Filename);
strcpy(mpq_path, Buffer);
strcat(mpq_path, mpq_name);
#ifdef COPYPROT
if (SFileOpenArchive(mpq_path, flags, fs, &archive))
#else
if (SFileOpenArchive(mpq_path, flags, FS_PC, &archive))
#endif
return archive;
if (strcmp(Filename, Buffer)) {
strcpy(mpq_path, Filename);
strcat(mpq_path, mpq_name);
#ifdef COPYPROT
if (SFileOpenArchive(mpq_path, flags, fs, &archive))
#else
if (SFileOpenArchive(mpq_path, flags, FS_PC, &archive))
#endif
return archive;
}
archive_path[0] = '\0';
@ -289,11 +297,7 @@ HANDLE init_test_access(char *mpq_path, char *mpq_name, char *reg_loc, int flags
init_strip_trailing_slash(archive_path);
strcpy(mpq_path, archive_path);
strcat(mpq_path, mpq_name);
#ifdef COPYPROT
if (SFileOpenArchive(mpq_path, flags, fs, &archive))
#else
if (SFileOpenArchive(mpq_path, flags, FS_PC, &archive))
#endif
return archive;
}
}
@ -398,7 +402,7 @@ LRESULT __stdcall MainWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
break;
#ifdef _DEBUG
case WM_SYSKEYUP:
if(wParam == VK_RETURN) {
if (wParam == VK_RETURN) {
fullscreen = !fullscreen;
dx_reinit();
return 0;

105
Source/inv.cpp

@ -97,10 +97,12 @@ void InitInv()
{
if (plr[myplr]._pClass == PC_WARRIOR) {
pInvCels = LoadFileInMem("Data\\Inv\\Inv.CEL", NULL);
#ifndef SPAWN
} else if (plr[myplr]._pClass == PC_ROGUE) {
pInvCels = LoadFileInMem("Data\\Inv\\Inv_rog.CEL", NULL);
} else if (plr[myplr]._pClass == PC_SORCERER) {
pInvCels = LoadFileInMem("Data\\Inv\\Inv_Sor.CEL", NULL);
#endif
}
invflag = 0;
@ -797,10 +799,12 @@ void CheckInvPaste(int pnum, int mx, int my)
done = FALSE;
if (plr[pnum]._pClass == PC_WARRIOR)
PlaySFX(PS_WARR13);
#ifndef SPAWN
else if (plr[pnum]._pClass == PC_ROGUE)
PlaySFX(PS_ROGUE13);
else if (plr[pnum]._pClass == PC_SORCERER)
PlaySFX(PS_MAGE13);
#endif
}
if (!done)
@ -1394,6 +1398,7 @@ void CheckQuestItem(int pnum)
if (plr[pnum].HoldItem.IDidx == IDI_OPTAMULET)
quests[QTYPE_BLIND]._qactive = 3;
if (plr[pnum].HoldItem.IDidx == IDI_MUSHROOM && quests[QTYPE_BLKM]._qactive == 2 && quests[QTYPE_BLKM]._qvar1 == QS_MUSHSPAWNED) {
#ifndef SPAWN
sfxdelay = 10;
if (plr[pnum]._pClass == PC_WARRIOR) { // BUGFIX: Voice for this quest might be wrong in MP
sfxdnum = PS_WARR95;
@ -1402,6 +1407,7 @@ void CheckQuestItem(int pnum)
} else if (plr[pnum]._pClass == PC_SORCERER) {
sfxdnum = PS_MAGE95;
}
#endif
quests[QTYPE_BLKM]._qvar1 = QS_MUSHPICKED;
}
if (plr[pnum].HoldItem.IDidx == IDI_ANVIL) {
@ -1409,6 +1415,7 @@ void CheckQuestItem(int pnum)
quests[QTYPE_ANVIL]._qactive = 2;
quests[QTYPE_ANVIL]._qvar1 = 1;
}
#ifndef SPAWN
if (quests[QTYPE_ANVIL]._qlog == 1) {
sfxdelay = 10;
if (plr[myplr]._pClass == PC_WARRIOR) {
@ -1419,7 +1426,9 @@ void CheckQuestItem(int pnum)
sfxdnum = PS_MAGE89;
}
}
#endif
}
#ifndef SPAWN
if (plr[pnum].HoldItem.IDidx == IDI_GLDNELIX) {
sfxdelay = 30;
if (plr[myplr]._pClass == PC_WARRIOR) {
@ -1430,11 +1439,13 @@ void CheckQuestItem(int pnum)
sfxdnum = PS_MAGE88;
}
}
#endif
if (plr[pnum].HoldItem.IDidx == IDI_ROCK) {
if (quests[QTYPE_INFRA]._qactive == 1) {
quests[QTYPE_INFRA]._qactive = 2;
quests[QTYPE_INFRA]._qvar1 = 1;
}
#ifndef SPAWN
if (quests[QTYPE_INFRA]._qlog == 1) {
sfxdelay = 10;
if (plr[myplr]._pClass == PC_WARRIOR) {
@ -1445,9 +1456,11 @@ void CheckQuestItem(int pnum)
sfxdnum = PS_MAGE87;
}
}
#endif
}
if (plr[pnum].HoldItem.IDidx == IDI_ARMOFVAL) {
quests[QTYPE_BLOOD]._qactive = 3;
#ifndef SPAWN
sfxdelay = 20;
if (plr[myplr]._pClass == PC_WARRIOR) {
sfxdnum = PS_WARR91;
@ -1456,6 +1469,7 @@ void CheckQuestItem(int pnum)
} else if (plr[myplr]._pClass == PC_SORCERER) {
sfxdnum = PS_MAGE91;
}
#endif
}
}
@ -1608,10 +1622,12 @@ void AutoGetItem(int pnum, int ii)
if (pnum == myplr) {
if (plr[pnum]._pClass == PC_WARRIOR) {
PlaySFX(random(0, 3) + PS_WARR14);
#ifndef SPAWN
} else if (plr[pnum]._pClass == PC_ROGUE) {
PlaySFX(random(0, 3) + PS_ROGUE14);
} else if (plr[pnum]._pClass == PC_SORCERER) {
PlaySFX(random(0, 3) + PS_MAGE14);
#endif
}
}
plr[pnum].HoldItem = item[ii];
@ -2080,10 +2096,10 @@ BOOL UseInvItem(int pnum, int cii)
if (plr[pnum]._pInvincible && !plr[pnum]._pHitPoints && pnum == myplr)
return TRUE;
if (pcurs != 1 || stextflag)
if (pcurs != 1)
return TRUE;
if (stextflag)
return TRUE;
if (cii <= 5)
return FALSE;
@ -2102,6 +2118,7 @@ BOOL UseInvItem(int pnum, int cii)
switch (Item->IDidx) {
case 17:
sfxdelay = 10;
#ifndef SPAWN
if (plr[pnum]._pClass == PC_WARRIOR) {
sfxdnum = PS_WARR95;
} else if (plr[pnum]._pClass == PC_ROGUE) {
@ -2109,62 +2126,68 @@ BOOL UseInvItem(int pnum, int cii)
} else if (plr[pnum]._pClass == PC_SORCERER) {
sfxdnum = PS_MAGE95;
}
break;
#endif
return TRUE;
case 19:
PlaySFX(IS_IBOOK);
sfxdelay = 10;
if (plr[pnum]._pClass == PC_WARRIOR) {
sfxdnum = PS_WARR29;
#ifndef SPAWN
} else if (plr[pnum]._pClass == PC_ROGUE) {
sfxdnum = PS_ROGUE29;
} else if (plr[pnum]._pClass == PC_SORCERER) {
sfxdnum = PS_MAGE29;
#endif
}
break;
default:
if (!AllItemsList[Item->IDidx].iUsable)
return FALSE;
return TRUE;
}
if (!Item->_iStatFlag) {
if (plr[pnum]._pClass == PC_WARRIOR) {
PlaySFX(PS_WARR13);
} else if (plr[pnum]._pClass == PC_ROGUE) {
PlaySFX(PS_ROGUE13);
} else if (plr[pnum]._pClass == PC_SORCERER) {
PlaySFX(PS_MAGE13);
}
return TRUE;
}
if (!AllItemsList[Item->IDidx].iUsable)
return FALSE;
if (Item->_iMiscId == IMISC_NONE && Item->_itype == ITYPE_GOLD) {
StartGoldDrop();
return TRUE;
if (!Item->_iStatFlag) {
if (plr[pnum]._pClass == PC_WARRIOR) {
PlaySFX(PS_WARR13);
#ifndef SPAWN
} else if (plr[pnum]._pClass == PC_ROGUE) {
PlaySFX(PS_ROGUE13);
} else if (plr[pnum]._pClass == PC_SORCERER) {
PlaySFX(PS_MAGE13);
#endif
}
return TRUE;
}
if (dropGoldFlag) {
dropGoldFlag = FALSE;
dropGoldValue = 0;
}
if (Item->_iMiscId == IMISC_NONE && Item->_itype == ITYPE_GOLD) {
StartGoldDrop();
return TRUE;
}
if ((Item->_iMiscId == IMISC_SCROLL && currlevel == 0 && !spelldata[Item->_iSpell].sTownSpell)
|| (Item->_iMiscId == IMISC_SCROLLT && currlevel == 0 && !spelldata[Item->_iSpell].sTownSpell)) {
return TRUE;
}
if (dropGoldFlag) {
dropGoldFlag = FALSE;
dropGoldValue = 0;
}
idata = ItemCAnimTbl[Item->_iCurs];
if (Item->_iMiscId == IMISC_BOOK)
PlaySFX(IS_RBOOK);
else if (pnum == myplr)
PlaySFX(ItemInvSnds[idata]);
if (Item->_iMiscId == IMISC_SCROLL && currlevel == 0 && !spelldata[Item->_iSpell].sTownSpell) {
return TRUE;
}
if (Item->_iMiscId == IMISC_SCROLLT && currlevel == 0 && !spelldata[Item->_iSpell].sTownSpell) {
return TRUE;
}
idata = ItemCAnimTbl[Item->_iCurs];
if (Item->_iMiscId == IMISC_BOOK)
PlaySFX(IS_RBOOK);
else if (pnum == myplr)
PlaySFX(ItemInvSnds[idata]);
UseItem(pnum, Item->_iMiscId, Item->_iSpell);
UseItem(pnum, Item->_iMiscId, Item->_iSpell);
if (speedlist) {
RemoveSpdBarItem(pnum, c);
} else if (plr[pnum].InvList[c]._iMiscId != IMISC_MAPOFDOOM) {
RemoveInvItem(pnum, c);
}
break;
if (speedlist) {
RemoveSpdBarItem(pnum, c);
} else if (plr[pnum].InvList[c]._iMiscId != IMISC_MAPOFDOOM) {
RemoveInvItem(pnum, c);
}
return TRUE;

16
Source/items.cpp

@ -560,12 +560,14 @@ void CalcPlrItemVals(int p, BOOL Loadgfx)
g++;
}
#ifndef SPAWN
if (plr[p].InvBody[INVLOC_CHEST]._itype == ITYPE_MARMOR && plr[p].InvBody[INVLOC_CHEST]._iStatFlag) {
g += ANIM_ID_MEDIUM_ARMOR;
}
if (plr[p].InvBody[INVLOC_CHEST]._itype == ITYPE_HARMOR && plr[p].InvBody[INVLOC_CHEST]._iStatFlag) {
g += ANIM_ID_HEAVY_ARMOR;
}
#endif
if (plr[p]._pgfxnum != g && Loadgfx) {
plr[p]._pgfxnum = g;
@ -897,6 +899,7 @@ void CreatePlrItems(int p)
SetPlrHandItem(&plr[p].SpdList[1], IDI_HEAL);
GetPlrHandSeed(&plr[p].SpdList[1]);
break;
#ifndef SPAWN
case PC_ROGUE:
SetPlrHandItem(&plr[p].InvBody[INVLOC_HAND_LEFT], IDI_ROGUE);
GetPlrHandSeed(&plr[p].InvBody[INVLOC_HAND_LEFT]);
@ -917,6 +920,7 @@ void CreatePlrItems(int p)
SetPlrHandItem(&plr[p].SpdList[1], IDI_MANA);
GetPlrHandSeed(&plr[p].SpdList[1]);
break;
#endif
}
SetPlrHandItem(&plr[p].HoldItem, IDI_GOLD);
@ -1100,9 +1104,13 @@ void GetBookSpell(int i, int lvl)
{
int rv, s, bs;
if (!lvl)
if (lvl == 0)
lvl = 1;
rv = random(14, MAX_SPELLS) + 1;
#ifdef SPAWN
if (lvl > 5)
lvl = 5;
#endif
s = 1;
while (rv > 0) {
if (spelldata[s].sBookLvl != -1 && lvl >= spelldata[s].sBookLvl) {
@ -1197,9 +1205,13 @@ void GetStaffSpell(int i, int lvl, BOOL onlygood)
GetItemPower(i, lvl >> 1, lvl, 256, onlygood);
} else {
l = lvl >> 1;
if (!l)
if (l == 0)
l = 1;
rv = random(18, MAX_SPELLS) + 1;
#ifdef SPAWN
if (lvl > 10)
lvl = 10;
#endif
s = 1;
while (rv > 0) {
if (spelldata[s].sStaffLvl != -1 && l >= spelldata[s].sStaffLvl) {

8
Source/mainmenu.cpp

@ -11,11 +11,13 @@ int menu_music_track_id = 5;
void mainmenu_refresh_music()
{
music_start(menu_music_track_id);
#ifndef SPAWN
do {
menu_music_track_id++;
if (menu_music_track_id == 6)
menu_music_track_id = 0;
} while (!menu_music_track_id || menu_music_track_id == 1);
#endif
}
void __stdcall mainmenu_change_name(int arg1, int arg2, int arg3, int arg4, char *name_1, char *name_2)
@ -104,8 +106,12 @@ void mainmenu_loop()
break;
case MAINMENU_REPLAY_INTRO:
case MAINMENU_ATTRACT_MODE:
#ifdef SPAWN
done = FALSE;
#else
if (gbActive)
mainmenu_play_intro();
#endif
break;
case MAINMENU_SHOW_CREDITS:
UiCreditsDialog(16);
@ -147,9 +153,11 @@ BOOL mainmenu_multi_player()
return mainmenu_init_menu(SELHERO_CONNECT);
}
#ifndef SPAWN
void mainmenu_play_intro()
{
music_stop();
play_movie("gendata\\diablo1.smk", 1);
mainmenu_refresh_music();
}
#endif

4
Source/missiles.cpp

@ -805,10 +805,12 @@ BOOL PlayerMHit(int pnum, int m, int dist, int mind, int maxd, int mtype, BOOLEA
} else {
if (plr[pnum]._pClass == PC_WARRIOR) {
PlaySfxLoc(PS_WARR69, plr[pnum].WorldX, plr[pnum].WorldY);
#ifndef SPAWN
} else if (plr[pnum]._pClass == PC_ROGUE) {
PlaySfxLoc(PS_ROGUE69, plr[pnum].WorldX, plr[pnum].WorldY);
} else if (plr[pnum]._pClass == PC_SORCERER) {
PlaySfxLoc(PS_MAGE69, plr[pnum].WorldX, plr[pnum].WorldY);
#endif
}
drawhpflag = TRUE;
}
@ -930,10 +932,12 @@ BOOL Plr2PlrMHit(int pnum, int p, int mindam, int maxdam, int dist, int mtype, B
NetSendCmdDamage(TRUE, p, dam - resper * dam / 100);
if (plr[pnum]._pClass == PC_WARRIOR) {
tac = PS_WARR69;
#ifndef SPAWN
} else if (plr[pnum]._pClass == PC_ROGUE) {
tac = PS_ROGUE69;
} else if (plr[pnum]._pClass == PC_SORCERER) {
tac = PS_MAGE69;
#endif
} else {
return TRUE;
}

5
Source/monstdat.cpp

@ -134,6 +134,11 @@ char MonstConvTbl[128] = {
0, 0, 0, 0, 0, 0, 80, 111
};
/**
* 0 = Never avalible
* 1 = Avalible in retail and shareware
* 2 = avalible in retail only
*/
BYTE MonstAvailTbl[112] = {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,

34
Source/monster.cpp

@ -183,7 +183,11 @@ void GetLevelMTypes()
int nt; // number of types
#ifdef SPAWN
mamask = 1; // monster availability mask
#else
mamask = 3; // monster availability mask
#endif
AddMonsterType(MT_GOLEM, 2);
if (currlevel == 16) {
@ -553,6 +557,7 @@ void PlaceMonster(int i, int mtype, int x, int y)
InitMonster(i, rd, mtype, x, y);
}
#ifndef SPAWN
void PlaceUniqueMonst(int uniqindex, int miniontype, int unpackfilesize)
{
int xp, yp, x, y, i;
@ -827,6 +832,7 @@ void PlaceQuestMonsters()
PlaceUniqueMonst(UMT_SKELKING, 0, 0);
}
}
#endif
void PlaceGroup(int mtype, int num, int leaderf, int leader)
{
@ -908,6 +914,7 @@ void PlaceGroup(int mtype, int num, int leaderf, int leader)
}
}
#ifndef SPAWN
void LoadDiabMonsts()
{
BYTE *lpSetPiece;
@ -925,6 +932,7 @@ void LoadDiabMonsts()
SetMapMonsters(lpSetPiece, 2 * diabquad4x, 2 * diabquad4y);
mem_free_dbg(lpSetPiece);
}
#endif
void InitMonsters()
{
@ -943,8 +951,10 @@ void InitMonsters()
AddMonster(1, 0, 0, 0, FALSE);
AddMonster(1, 0, 0, 0, FALSE);
AddMonster(1, 0, 0, 0, FALSE);
#ifndef SPAWN
if (!setlevel && currlevel == 16)
LoadDiabMonsts();
#endif
}
nt = numtrigs;
if (currlevel == 15)
@ -955,9 +965,13 @@ void InitMonsters()
DoVision(s + trigs[i]._tx, t + trigs[i]._ty, 15, FALSE, FALSE);
}
}
#ifndef SPAWN
PlaceQuestMonsters();
#endif
if (!setlevel) {
#ifndef SPAWN
PlaceUniques();
#endif
na = 0;
for (s = 16; s < 96; s++)
for (t = 16; t < 96; t++)
@ -994,6 +1008,7 @@ void InitMonsters()
}
}
#ifndef SPAWN
void PlaceUniques()
{
int u, mt;
@ -1063,6 +1078,7 @@ void SetMapMonsters(BYTE *pMap, int startx, int starty)
}
}
}
#endif
void DeleteMonster(int i)
{
@ -1533,7 +1549,9 @@ void M_DiabloDeath(int i, BOOL sendmsg)
int _moldx, _moldy;
Monst = monster + i;
#ifndef SPAWN
PlaySFX(USFX_DIABLOD);
#endif
quests[QTYPE_MOD]._qactive = 3;
if (sendmsg)
NetSendCmdQuest(TRUE, QTYPE_MOD);
@ -2526,6 +2544,7 @@ void DoEnding()
Sleep(1000);
}
#ifndef SPAWN
if (plr[myplr]._pClass == PC_WARRIOR) {
play_movie("gendata\\DiabVic2.smk", 0);
} else if (plr[myplr]._pClass == PC_SORCERER) {
@ -2549,6 +2568,7 @@ void DoEnding()
sound_get_or_set_music_volume(musicVolume);
gbMusicOn = bMusicOn;
#endif
}
void PrepDoEnding()
@ -4194,6 +4214,7 @@ void MAI_Garbud(int i)
}
if (dFlags[_mx][_my] & BFLAG_VISIBLE) {
#ifndef SPAWN
if (Monst->mtalkmsg == QUEST_GARBUD4) {
if (!effect_is_playing(USFX_GARBUD4) && Monst->_mgoal == MGOAL_TALKING) {
Monst->_mgoal = MGOAL_NORMAL;
@ -4201,6 +4222,7 @@ void MAI_Garbud(int i)
Monst->mtalkmsg = 0;
}
}
#endif
}
if (Monst->_mgoal == MGOAL_NORMAL || Monst->_mgoal == MGOAL_MOVE)
@ -4240,6 +4262,7 @@ void MAI_Zhar(int i)
abs(_mx);
else
abs(_my);
#ifndef SPAWN
if (Monst->mtalkmsg == QUEST_ZHAR2) {
if (!effect_is_playing(USFX_ZHAR2) && Monst->_mgoal == MGOAL_TALKING) {
Monst->_msquelch = UCHAR_MAX;
@ -4247,6 +4270,7 @@ void MAI_Zhar(int i)
Monst->_mgoal = MGOAL_NORMAL;
}
}
#endif
}
if (Monst->_mgoal == MGOAL_NORMAL || Monst->_mgoal == MGOAL_RETREAT || Monst->_mgoal == MGOAL_MOVE)
@ -4286,6 +4310,7 @@ void MAI_SnotSpil(int i)
}
if (dFlags[mx][my] & BFLAG_VISIBLE) {
#ifndef SPAWN
if (Monst->mtalkmsg == QUEST_BANNER12) {
if (!effect_is_playing(USFX_SNOT3) && Monst->_mgoal == MGOAL_TALKING) {
ObjChangeMap(setpc_x, setpc_y, setpc_x + setpc_w + 1, setpc_y + setpc_h + 1);
@ -4296,6 +4321,7 @@ void MAI_SnotSpil(int i)
Monst->_mgoal = MGOAL_NORMAL;
}
}
#endif
if (quests[QTYPE_BOL]._qvar1 == 3) {
if (Monst->_mgoal == MGOAL_NORMAL || Monst->_mgoal == MGOAL_SHOOT)
MAI_Fallen(i);
@ -4332,6 +4358,7 @@ void MAI_Lazurus(int i)
quests[QTYPE_VB]._qvar1 = 5;
}
#ifndef SPAWN
if (Monst->mtalkmsg == QUEST_VILE13 && !effect_is_playing(USFX_LAZ1) && Monst->_mgoal == MGOAL_TALKING) {
ObjChangeMapResync(1, 18, 20, 24);
RedoPlayerVision();
@ -4340,6 +4367,7 @@ void MAI_Lazurus(int i)
quests[QTYPE_VB]._qvar1 = 6;
Monst->_mgoal = MGOAL_NORMAL;
}
#endif
}
if (gbMaxPlayers != 1 && Monst->mtalkmsg == QUEST_VILE13 && Monst->_mgoal == MGOAL_INQUIRING && quests[QTYPE_VB]._qvar1 <= 3) {
@ -4408,6 +4436,7 @@ void MAI_Lachdanan(int i)
_mx = Monst->_mx;
_my = Monst->_my;
md = M_GetDir(i);
#ifndef SPAWN
if (Monst->mtalkmsg == QUEST_VEIL9 && !(dFlags[_mx][_my] & BFLAG_VISIBLE) && monster[i]._mgoal == MGOAL_TALKING) {
Monst->mtalkmsg = QUEST_VEIL10;
monster[i]._mgoal = MGOAL_INQUIRING;
@ -4422,6 +4451,7 @@ void MAI_Lachdanan(int i)
}
}
}
#endif
Monst->_mdir = md;
@ -4448,11 +4478,13 @@ void MAI_Warlord(int i)
if (dFlags[mx][my] & BFLAG_VISIBLE) {
if (Monst->mtalkmsg == QUEST_WARLRD9 && Monst->_mgoal == MGOAL_INQUIRING)
Monst->_mmode = MM_TALK;
#ifndef SPAWN
if (Monst->mtalkmsg == QUEST_WARLRD9 && !effect_is_playing(USFX_WARLRD1) && Monst->_mgoal == MGOAL_TALKING) {
Monst->_msquelch = UCHAR_MAX;
Monst->mtalkmsg = 0;
Monst->_mgoal = MGOAL_NORMAL;
}
#endif
}
if (Monst->_mgoal == MGOAL_NORMAL)
@ -4516,9 +4548,11 @@ void ProcessMonsters()
}
mx = Monst->_mx;
my = Monst->_my;
#ifndef SPAWN
if (dFlags[mx][my] & BFLAG_VISIBLE && Monst->_msquelch == 0 && Monst->MType->mtype == MT_CLEAVER) {
PlaySFX(USFX_CLEAVER);
}
#endif
if (Monst->_mFlags & MFLAG_TARGETS_MONSTER) {
_menemy = Monst->_menemy;
if ((DWORD)_menemy >= MAXMONSTERS) {

8
Source/mpqapi.cpp

@ -54,7 +54,11 @@ BOOL mpqapi_reg_load_modification_time(char *dst, int size)
pszDst = dst;
memset(dst, 0, size);
#ifdef SPAWN
if (!SRegLoadData("Diablo", "Audio Playback ", 0, (BYTE *)pszDst, size, &nbytes_read)) {
#else
if (!SRegLoadData("Diablo", "Video Player ", 0, (BYTE *)pszDst, size, &nbytes_read)) {
#endif
return FALSE;
}
@ -120,7 +124,11 @@ BOOLEAN mpqapi_reg_store_modification_time(char *pbData, DWORD dwLen)
} while (i);
}
#ifdef SPAWN
return SRegSaveData("Diablo", "Audio Playback ", 0, (BYTE *)pbData, dwLen);
#else
return SRegSaveData("Diablo", "Video Player ", 0, (BYTE *)pbData, dwLen);
#endif
}
void mpqapi_remove_hash_entry(const char *pszName)

2
Source/msg.cpp

@ -122,7 +122,7 @@ int msg_wait_for_turns()
}
multi_process_network_packets();
nthread_send_and_recv_turn(0, 0);
if (nthread_has_500ms_passed(0))
if (nthread_has_500ms_passed(FALSE))
nthread_recv_turns(&received);
if (gbGameDestroyed)

12
Source/multi.cpp

@ -18,7 +18,7 @@ BYTE gbActivePlayers;
BOOLEAN gbGameDestroyed;
BOOLEAN sgbSendDeltaTbl[MAX_PLRS];
_gamedata sgGameInitInfo;
char byte_678640;
BOOLEAN gbGameUninitialized;
int sglTimeoutStart;
int sgdwPlayerLeftReasonTbl[MAX_PLRS];
TBuffer sgLoPriBuf;
@ -651,7 +651,11 @@ BOOL NetInit(BOOL bSinglePlayer, BOOL *pfExitProgram)
sgGameInitInfo.bDiff = gnDifficulty;
memset(&ProgramData, 0, sizeof(ProgramData));
ProgramData.size = sizeof(ProgramData);
#ifdef SPAWN
ProgramData.programname = "Diablo Shareware";
#else
ProgramData.programname = "Diablo Retail";
#endif
ProgramData.programdescription = gszVersionNumber;
ProgramData.programid = 'DRTL';
ProgramData.versionid = 42;
@ -720,7 +724,7 @@ BOOL NetInit(BOOL bSinglePlayer, BOOL *pfExitProgram)
if (sgbPlayerTurnBitTbl[myplr] == 0 || msg_wait_resync())
break;
NetClose();
byte_678640 = 0;
gbGameUninitialized = FALSE;
}
gnDifficulty = sgGameInitInfo.bDiff;
SetRndSeed(sgGameInitInfo.dwSeed);
@ -825,7 +829,7 @@ BOOL multi_init_multi(_SNETPROGRAMDATA *client_info, _SNETPLAYERDATA *user_info,
for (first = TRUE;; first = FALSE) {
type = 0x00;
if (byte_678640) {
if (gbGameUninitialized) {
if (!UiSelectProvider(0, client_info, user_info, ui_info, &fileinfo, &type)
&& (!first || SErrGetLastError() != STORM_ERROR_REQUIRES_UPGRADE || !multi_upgrade(pfExitProgram))) {
return FALSE;
@ -838,7 +842,7 @@ BOOL multi_init_multi(_SNETPROGRAMDATA *client_info, _SNETPLAYERDATA *user_info,
if (UiSelectGame(1, client_info, user_info, ui_info, &fileinfo, &playerId))
break;
byte_678640 = 1;
gbGameUninitialized = TRUE;
}
if ((DWORD)playerId >= MAX_PLRS) {

2
Source/multi.h

@ -9,7 +9,7 @@ extern PkPlayerStruct netplr[MAX_PLRS];
extern BOOL gbShouldValidatePackage;
extern BYTE gbActivePlayers;
extern BOOLEAN gbGameDestroyed;
extern char byte_678640;
extern BOOLEAN gbGameUninitialized;
extern BYTE gbMaxPlayers;
extern char szPlayerName[128];
extern BYTE gbDeltaSender;

14
Source/objects.cpp

@ -837,6 +837,7 @@ void InitObjects()
}
}
#ifndef SPAWN
void SetMapObjects(BYTE *pMap, int startx, int starty)
{
int rw, rh;
@ -896,6 +897,7 @@ void SetMapObjects(BYTE *pMap, int startx, int starty)
}
InitObjFlag = FALSE;
}
#endif
void DeleteObject_(int oi, int i)
{
@ -1705,10 +1707,12 @@ void Obj_BCrossDamage(int i)
} else {
if (plr[myplr]._pClass == PC_WARRIOR) {
PlaySfxLoc(PS_WARR68, plr[myplr].WorldX, plr[myplr].WorldY);
#ifndef SPAWN
} else if (plr[myplr]._pClass == PC_ROGUE) {
PlaySfxLoc(PS_ROGUE68, plr[myplr].WorldX, plr[myplr].WorldY);
} else if (plr[myplr]._pClass == PC_SORCERER) {
PlaySfxLoc(PS_MAGE68, plr[myplr].WorldX, plr[myplr].WorldY);
#endif
}
}
drawhpflag = TRUE;
@ -2621,10 +2625,12 @@ void OperateMushPatch(int pnum, int i)
if (!deltaload && pnum == myplr) {
if (plr[myplr]._pClass == PC_WARRIOR) {
PlaySFX(PS_WARR13);
#ifndef SPAWN
} else if (plr[myplr]._pClass == PC_ROGUE) {
PlaySFX(PS_ROGUE13);
} else if (plr[myplr]._pClass == PC_SORCERER) {
PlaySFX(PS_MAGE13);
#endif
}
}
} else {
@ -2650,10 +2656,12 @@ void OperateInnSignChest(int pnum, int i)
if (!deltaload && pnum == myplr) {
if (plr[myplr]._pClass == PC_WARRIOR) {
PlaySFX(PS_WARR24);
#ifndef SPAWN
} else if (plr[myplr]._pClass == PC_ROGUE) {
PlaySFX(PS_ROGUE24);
} else if (plr[myplr]._pClass == PC_SORCERER) {
PlaySFX(PS_MAGE24);
#endif
}
}
} else {
@ -2677,13 +2685,19 @@ void OperateSlainHero(int pnum, int i, BOOL sendmsg)
if (!deltaload) {
if (plr[pnum]._pClass == PC_WARRIOR) {
CreateMagicArmor(object[i]._ox, object[i]._oy, 9, ICURS_BREAST_PLATE, 0, 1);
#ifndef SPAWN
PlaySfxLoc(PS_WARR9, plr[myplr].WorldX, plr[myplr].WorldY);
#endif
} else if (plr[pnum]._pClass == PC_ROGUE) {
CreateMagicWeapon(object[i]._ox, object[i]._oy, 3, ICURS_LONG_WAR_BOW, 0, 1);
#ifndef SPAWN
PlaySfxLoc(PS_ROGUE9, plr[myplr].WorldX, plr[myplr].WorldY);
#endif
} else if (plr[pnum]._pClass == PC_SORCERER) {
CreateSpellBook(object[i]._ox, object[i]._oy, 3, 0, 1);
#ifndef SPAWN
PlaySfxLoc(PS_MAGE9, plr[myplr].WorldX, plr[myplr].WorldY);
#endif
}
if (pnum == myplr)
NetSendCmdParam1(FALSE, CMD_OPERATEOBJ, i);

2
Source/palette.cpp

@ -269,6 +269,7 @@ void palette_update_caves()
palette_update();
}
#ifndef SPAWN
void palette_update_quest_palette(int n)
{
int i;
@ -279,6 +280,7 @@ void palette_update_quest_palette(int n)
ApplyGamma(system_palette, logical_palette, 32);
palette_update();
}
#endif
BOOL palette_get_colour_cycling()
{

26
Source/pfile.cpp

@ -2,8 +2,13 @@
#include "../3rdParty/Storm/Source/storm.h"
#include "../DiabloUI/diabloui.h"
#ifdef SPAWN
#define PASSWORD_SINGLE "adslhfb1"
#define PASSWORD_MULTI "lshbkfg1"
#else
#define PASSWORD_SINGLE "xrgyrkj1"
#define PASSWORD_MULTI "szqnlsk1"
#endif
static char hero_names[MAX_CHARACTERS][PLR_NAME_LEN];
BOOL gbValidSaveFile;
@ -113,10 +118,17 @@ void pfile_get_save_path(char *pszBuf, DWORD dwBufSize, DWORD save_num)
DWORD plen;
char *s;
char path[MAX_PATH];
#ifdef SPAWN
const char *fmt = "\\share_%d.sv";
if (gbMaxPlayers <= 1)
fmt = "\\spawn%d.sv";
#else
const char *fmt = "\\multi_%d.sv";
if (gbMaxPlayers <= 1)
fmt = "\\single_%d.sv";
#endif
// BUGFIX: ignores dwBufSize and uses MAX_PATH instead
plen = GetModuleFileName(ghInst, pszBuf, MAX_PATH);
@ -209,7 +221,11 @@ void game_2_ui_player(const PlayerStruct *p, _uiheroinfo *heroinfo, BOOL bHasSav
heroinfo->gold = p->_pGold;
heroinfo->hassaved = bHasSaveFile;
heroinfo->herorank = p->pDiabloKillLevel;
heroinfo->spawned = 0;
#ifdef SPAWN
heroinfo->spawned = TRUE;
#else
heroinfo->spawned = FALSE;
#endif
}
BYTE game_2_ui_class(const PlayerStruct *p)
@ -291,11 +307,19 @@ char *GetSaveDirectory(char *dst, int dst_size, DWORD save_num)
// BUGFIX: ignores dst_size and uses MAX_PATH instead
if (gbMaxPlayers > 1) {
#ifdef SPAWN
savename = "\\slinfo_%d.drv";
#else
savename = "\\dlinfo_%d.drv";
#endif
dirLen = GetWindowsDirectory(dst, MAX_PATH);
} else {
char *s;
#ifdef SPAWN
savename = "\\spawn_%d.sv";
#else
savename = "\\single_%d.sv";
#endif
dirLen = GetModuleFileName(ghInst, dst, MAX_PATH);
s = strrchr(dst, '\\');
if (s)

28
Source/player.cpp

@ -445,6 +445,7 @@ void SetPlrAnims(int pnum)
plr[pnum]._pAFrames = 16;
plr[pnum]._pAFNum = 11;
}
#ifndef SPAWN
} else if (pc == PC_ROGUE) {
if (gn == ANIM_ID_AXE) {
plr[pnum]._pAFrames = 22;
@ -469,6 +470,7 @@ void SetPlrAnims(int pnum)
plr[pnum]._pAFrames = 24;
plr[pnum]._pAFNum = 16;
}
#endif
}
}
@ -594,10 +596,12 @@ void CreatePlayer(int pnum, char c)
if (c == PC_WARRIOR) {
plr[pnum]._pAblSpells = (__int64)1 << (SPL_REPAIR - 1);
#ifndef SPAWN
} else if (c == PC_ROGUE) {
plr[pnum]._pAblSpells = (__int64)1 << (SPL_DISARM - 1);
} else if (c == PC_SORCERER) {
plr[pnum]._pAblSpells = (__int64)1 << (SPL_RECHARGE - 1);
#endif
}
if (c == PC_SORCERER) {
@ -624,10 +628,12 @@ void CreatePlayer(int pnum, char c)
if (c == PC_WARRIOR) {
plr[pnum]._pgfxnum = ANIM_ID_SWORD_SHIELD;
#ifndef SPAWN
} else if (c == PC_ROGUE) {
plr[pnum]._pgfxnum = ANIM_ID_BOW;
} else if (c == PC_SORCERER) {
plr[pnum]._pgfxnum = ANIM_ID_STAFF;
#endif
}
for (i = 0; i < NUMLEVELS; i++) {
@ -878,10 +884,12 @@ void InitPlayer(int pnum, BOOL FirstTime)
if (plr[pnum]._pClass == PC_WARRIOR) {
plr[pnum]._pAblSpells = 1 << (SPL_REPAIR - 1);
#ifndef SPAWN
} else if (plr[pnum]._pClass == PC_ROGUE) {
plr[pnum]._pAblSpells = 1 << (SPL_DISARM - 1);
} else if (plr[pnum]._pClass == PC_SORCERER) {
plr[pnum]._pAblSpells = 1 << (SPL_RECHARGE - 1);
#endif
}
#ifdef _DEBUG
@ -1587,10 +1595,12 @@ void StartPlrHit(int pnum, int dam, BOOL forcehit)
if (plr[pnum]._pClass == PC_WARRIOR) {
PlaySfxLoc(PS_WARR69, plr[pnum].WorldX, plr[pnum].WorldY);
#ifndef SPAWN
} else if (plr[pnum]._pClass == PC_ROGUE) {
PlaySfxLoc(PS_ROGUE69, plr[pnum].WorldX, plr[pnum].WorldY);
} else if (plr[pnum]._pClass == PC_SORCERER) {
PlaySfxLoc(PS_MAGE69, plr[pnum].WorldX, plr[pnum].WorldY);
#endif
}
drawhpflag = TRUE;
@ -1660,10 +1670,12 @@ void StartPlayerKill(int pnum, int earflag)
if (plr[pnum]._pClass == PC_WARRIOR) {
PlaySfxLoc(PS_DEAD, plr[pnum].WorldX, plr[pnum].WorldY); // BUGFIX: should use `PS_WARR71` like other classes
#ifndef SPAWN
} else if (plr[pnum]._pClass == PC_ROGUE) {
PlaySfxLoc(PS_ROGUE71, plr[pnum].WorldX, plr[pnum].WorldY);
} else if (plr[pnum]._pClass == PC_SORCERER) {
PlaySfxLoc(PS_MAGE71, plr[pnum].WorldX, plr[pnum].WorldY);
#endif
}
if (plr[pnum]._pgfxnum) {
@ -3602,10 +3614,12 @@ void CheckPlrSpell()
if (rspell == SPL_INVALID) {
if (plr[myplr]._pClass == PC_WARRIOR) {
PlaySFX(PS_WARR34);
#ifndef SPAWN
} else if (plr[myplr]._pClass == PC_ROGUE) {
PlaySFX(PS_ROGUE34);
} else if (plr[myplr]._pClass == PC_SORCERER) {
PlaySFX(PS_MAGE34);
#endif
}
return;
}
@ -3613,10 +3627,12 @@ void CheckPlrSpell()
if (leveltype == DTYPE_TOWN && !spelldata[rspell].sTownSpell) {
if (plr[myplr]._pClass == PC_WARRIOR) {
PlaySFX(PS_WARR27);
#ifndef SPAWN
} else if (plr[myplr]._pClass == PC_ROGUE) {
PlaySFX(PS_ROGUE27);
} else if (plr[myplr]._pClass == PC_SORCERER) {
PlaySFX(PS_MAGE27);
#endif
}
return;
}
@ -3667,10 +3683,12 @@ void CheckPlrSpell()
if (plr[myplr]._pRSplType == RSPLTYPE_SPELL) {
if (plr[myplr]._pClass == PC_WARRIOR) {
PlaySFX(PS_WARR35);
#ifndef SPAWN
} else if (plr[myplr]._pClass == PC_ROGUE) {
PlaySFX(PS_ROGUE35);
} else if (plr[myplr]._pClass == PC_SORCERER) {
PlaySFX(PS_MAGE35);
#endif
}
}
}
@ -4074,47 +4092,57 @@ void PlayDungMsgs()
sfxdelay = 40;
if (plr[myplr]._pClass == PC_WARRIOR) {
sfxdnum = PS_WARR97;
#ifndef SPAWN
} else if (plr[myplr]._pClass == PC_ROGUE) {
sfxdnum = PS_ROGUE97;
} else if (plr[myplr]._pClass == PC_SORCERER) {
sfxdnum = PS_MAGE97;
#endif
}
plr[myplr].pDungMsgs = plr[myplr].pDungMsgs | DMSG_CATHEDRAL;
} else if (currlevel == 5 && !plr[myplr]._pLvlVisited[5] && gbMaxPlayers == 1 && !(plr[myplr].pDungMsgs & DMSG_CATACOMBS)) {
sfxdelay = 40;
if (plr[myplr]._pClass == PC_WARRIOR) {
sfxdnum = PS_WARR96B;
#ifndef SPAWN
} else if (plr[myplr]._pClass == PC_ROGUE) {
sfxdnum = PS_ROGUE96;
} else if (plr[myplr]._pClass == PC_SORCERER) {
sfxdnum = PS_MAGE96;
#endif
}
plr[myplr].pDungMsgs |= DMSG_CATACOMBS;
} else if (currlevel == 9 && !plr[myplr]._pLvlVisited[9] && gbMaxPlayers == 1 && !(plr[myplr].pDungMsgs & DMSG_CAVES)) {
sfxdelay = 40;
if (plr[myplr]._pClass == PC_WARRIOR) {
sfxdnum = PS_WARR98;
#ifndef SPAWN
} else if (plr[myplr]._pClass == PC_ROGUE) {
sfxdnum = PS_ROGUE98;
} else if (plr[myplr]._pClass == PC_SORCERER) {
sfxdnum = PS_MAGE98;
#endif
}
plr[myplr].pDungMsgs |= DMSG_CAVES;
} else if (currlevel == 13 && !plr[myplr]._pLvlVisited[13] && gbMaxPlayers == 1 && !(plr[myplr].pDungMsgs & DMSG_HELL)) {
sfxdelay = 40;
if (plr[myplr]._pClass == PC_WARRIOR) {
sfxdnum = PS_WARR99;
#ifndef SPAWN
} else if (plr[myplr]._pClass == PC_ROGUE) {
sfxdnum = PS_ROGUE99;
} else if (plr[myplr]._pClass == PC_SORCERER) {
sfxdnum = PS_MAGE99;
#endif
}
plr[myplr].pDungMsgs |= DMSG_HELL;
} else if (currlevel == 16 && !plr[myplr]._pLvlVisited[15] && gbMaxPlayers == 1 && !(plr[myplr].pDungMsgs & DMSG_DIABLO)) { // BUGFIX: _pLvlVisited should check 16 or this message will never play
sfxdelay = 40;
#ifndef SPAWN
if (plr[myplr]._pClass == PC_WARRIOR || plr[myplr]._pClass == PC_ROGUE || plr[myplr]._pClass == PC_SORCERER) {
sfxdnum = PS_DIABLVLINT;
}
#endif
plr[myplr].pDungMsgs |= DMSG_DIABLO;
} else {
sfxdelay = 0;

19
Source/quests.cpp

@ -115,6 +115,13 @@ void InitQuests()
if (questdebug != -1)
quests[questdebug]._qactive = 2;
#endif
#ifdef SPAWN
for (z = 0; z < MAXQUESTS; z++) {
quests[z]._qactive = 0;
}
#endif
if (!quests[QTYPE_KING]._qactive)
quests[QTYPE_KING]._qvar2 = 2;
if (!quests[QTYPE_INFRA]._qactive)
@ -126,6 +133,7 @@ void InitQuests()
void CheckQuests()
{
#ifndef SPAWN
int i, rportx, rporty;
if (QuestStatus(QTYPE_VB) && gbMaxPlayers != 1 && quests[QTYPE_VB]._qvar1 == 2) {
@ -193,10 +201,12 @@ void CheckQuests()
}
}
}
#endif
}
BOOL ForceQuests()
{
#ifndef SPAWN
int i, j, qx, qy, ql;
if (gbMaxPlayers != 1) {
@ -220,6 +230,7 @@ BOOL ForceQuests()
}
}
}
#endif
return FALSE;
}
@ -239,6 +250,7 @@ BOOL QuestStatus(int i)
void CheckQuestKill(int m, BOOL sendmsg)
{
#ifndef SPAWN
int i, j;
if (monster[m].MType->mtype == MT_SKING) {
@ -339,6 +351,7 @@ void CheckQuestKill(int m, BOOL sendmsg)
sfxdnum = PS_MAGE94;
}
}
#endif
}
void DrawButcher()
@ -574,6 +587,7 @@ void GetReturnLvlPos()
void ResyncMPQuests()
{
#ifndef SPAWN
if (quests[QTYPE_KING]._qactive == 1
&& currlevel >= quests[QTYPE_KING]._qlevel - 1
&& currlevel <= quests[QTYPE_KING]._qlevel + 1) {
@ -592,10 +606,12 @@ void ResyncMPQuests()
}
if (QuestStatus(QTYPE_VB))
AddObject(OBJ_ALTBOY, 2 * setpc_x + 20, 2 * setpc_y + 22);
#endif
}
void ResyncQuests()
{
#ifndef SPAWN
int i, tren, x, y;
if (setlevel && setlvlnum == quests[QTYPE_PW]._qslvl && quests[QTYPE_PW]._qactive != 1 && leveltype == quests[QTYPE_PW]._qlvltype) {
@ -677,6 +693,7 @@ void ResyncQuests()
&& (quests[QTYPE_VB]._qactive == 2 || quests[QTYPE_VB]._qactive == 3)) {
quests[QTYPE_VB]._qvar2 = 2;
}
#endif
}
void PrintQLString(int x, int y, BOOL cjustflag, char *str, int col)
@ -807,6 +824,7 @@ void QuestlogESC()
void SetMultiQuest(int q, int s, int l, int v1)
{
#ifndef SPAWN
if (quests[q]._qactive != 3) {
if (s > quests[q]._qactive)
quests[q]._qactive = s;
@ -814,4 +832,5 @@ void SetMultiQuest(int q, int s, int l, int v1)
if (v1 > quests[q]._qvar1)
quests[q]._qvar1 = v1;
}
#endif
}

2
Source/setmaps.cpp

@ -77,6 +77,7 @@ int ObjIndex(int x, int y)
return -1;
}
#ifndef SPAWN
void AddSKingObjs()
{
SetObjMapRange(ObjIndex(64, 34), 20, 7, 23, 10, 1);
@ -188,3 +189,4 @@ void LoadSetMap()
break;
}
}
#endif

6
Source/sound.cpp

@ -17,12 +17,18 @@ BOOLEAN gbSoundOn = TRUE;
BOOLEAN gbDupSounds = TRUE;
int sgnMusicTrack = 6;
char *sgszMusicTracks[NUM_MUSIC] = {
#ifdef SPAWN
"Music\\sTowne.wav",
"Music\\sLvlA.wav",
"Music\\sintro.wav"
#else
"Music\\DTowne.wav",
"Music\\DLvlA.wav",
"Music\\DLvlB.wav",
"Music\\DLvlC.wav",
"Music\\DLvlD.wav",
"Music\\Dintro.wav"
#endif
};
char unk_volume[4][2] = {
{ 15, -16 },

8
Source/stores.cpp

@ -1363,6 +1363,13 @@ void S_StartTalk()
sprintf(tempstr, "Talk to %s", talkname[talker]);
AddSText(0, 2, 1, tempstr, COL_GOLD, 0);
AddSLine(5);
#ifdef SPAWN
sprintf(tempstr, "Talking to %s", talkname[talker]);
AddSText(0, 10, 1, tempstr, COL_WHITE, 0);
AddSText(0, 12, 1, "is not available", COL_WHITE, 0);
AddSText(0, 14, 1, "in the shareware", COL_WHITE, 0);
AddSText(0, 16, 1, "version", COL_WHITE, 0);
#else
sn = 0;
for (i = 0; i < 16; i++) {
if (quests[i]._qlevel == 2 && ((DWORD *)&Qtalklist[talker])[i] != -1 && quests[i]._qlog)
@ -1386,6 +1393,7 @@ void S_StartTalk()
}
}
AddSText(0, sn2, 1, "Gossip", COL_BLUE, 1);
#endif
AddSText(0, 22, 1, "Back", COL_WHITE, 1);
}

6
Source/textdat.cpp

@ -2,7 +2,10 @@
/* todo: move text out of struct */
const TextDataStruct alltext[259] = {
const TextDataStruct alltext[] = {
#ifdef SPAWN
{ "Nice try... ", 0, 5, TSFX_TAVERN36 },
#else
{ " Ahh, the story of our King, is it? The tragic fall of Leoric was a harsh blow to this land. The people always loved the King, and now they live in mortal fear of him. The question that I keep asking myself is how he could have fallen so far from the Light, as Leoric had always been the holiest of men. Only the vilest powers of Hell could so utterly destroy a man from within... |",
1, 5, TSFX_STORY1 },
{ "The village needs your help, good master! Some months ago King Leoric's son, Prince Albrecht, was kidnapped. The King went into a rage and scoured the village for his missing child. With each passing day, Leoric seemed to slip deeper into madness. He sought to blame innocent townsfolk for the boy's disappearance and had them brutally executed. Less than half of us survived his insanity...\n \nThe King's Knights and Priests tried to placate him, but he turned against them and sadly, they were forced to kill him. With his dying breath the King called down a terrible curse upon his former followers. He vowed that they would serve him in darkness forever...\n \nThis is where things take an even darker twist than I thought possible! Our former King has risen from his eternal sleep and now commands a legion of undead minions within the Labyrinth. His body was buried in a tomb three levels beneath the Cathedral. Please, good master, put his soul at ease by destroying his now cursed form... |",
@ -505,5 +508,6 @@ const TextDataStruct alltext[259] = {
1, 3, PS_NAR9 },
{ "Thank goodness you've returned!\nMuch has changed since you lived here, my friend. All was peaceful until the dark riders came and destroyed our village. Many were cut down where they stood, and those who took up arms were slain or dragged away to become slaves - or worse. The church at the edge of town has been desecrated and is being used for dark rituals. The screams that echo in the night are inhuman, but some of our townsfolk may yet survive. Follow the path that lies between my tavern and the blacksmith shop to find the church and save who you can. \n \nPerhaps I can tell you more if we speak again. Good luck.|",
1, 5, TSFX_TAVERN0 }
#endif
};
const DWORD gdwAllTextEntries = 259; /* unused */

8
Source/town.cpp

@ -1448,20 +1448,28 @@ void T_Pass3()
T_FillSector(P3Tiles, pSector, 0, 0, 23, 23);
mem_free_dbg(pSector);
#ifndef SPAWN
if (gbMaxPlayers == 1) {
if (!(plr[myplr].pTownWarps & 1)) {
#endif
T_FillTile(P3Tiles, 48, 20, 320);
#ifndef SPAWN
}
if (!(plr[myplr].pTownWarps & 2)) {
#endif
T_FillTile(P3Tiles, 16, 68, 332);
T_FillTile(P3Tiles, 16, 70, 331);
#ifndef SPAWN
}
if (!(plr[myplr].pTownWarps & 4)) {
#endif
for (x = 36; x < 46; x++) {
T_FillTile(P3Tiles, x, 78, random(0, 4) + 1);
}
#ifndef SPAWN
}
}
#endif
if (quests[13]._qactive != 3 && quests[13]._qactive) {
T_FillTile(P3Tiles, 60, 70, 342);

13
Source/towners.cpp

@ -9,11 +9,13 @@ BOOL boyloadflag;
BYTE *pCowCels;
TownerStruct towner[16];
#ifndef SPAWN
const int snSFX[3][3] = {
{ PS_WARR52, PS_ROGUE52, PS_MAGE52 },
{ PS_WARR49, PS_ROGUE49, PS_MAGE49 },
{ PS_WARR50, PS_ROGUE50, PS_MAGE50 }
};
#endif
/* data */
@ -686,6 +688,7 @@ void TalkToTowner(int p, int t)
towner[t]._tbtcnt = 150;
towner[t]._tVar1 = p;
quests[QTYPE_BUTCH]._qvar1 = 1;
#ifndef SPAWN
if (plr[p]._pClass == 0 && !effect_is_playing(PS_WARR8)) {
PlaySFX(PS_WARR8);
} else if (plr[p]._pClass == 1 && !effect_is_playing(PS_ROGUE8)) {
@ -693,6 +696,7 @@ void TalkToTowner(int p, int t)
} else if (plr[p]._pClass == 2 && !effect_is_playing(PS_MAGE8)) {
PlaySFX(PS_MAGE8);
}
#endif
towner[t]._tMsgSaid = TRUE;
} else if (quests[QTYPE_BUTCH]._qactive == 3 && quests[QTYPE_BUTCH]._qvar1 == 1) {
quests[QTYPE_BUTCH]._qvar1 = 1;
@ -937,6 +941,14 @@ void CowSFX(int pnum)
{
if (CowPlaying == -1 || !effect_is_playing(CowPlaying)) {
sgdwCowClicks++;
#ifdef SPAWN
if (sgdwCowClicks == 4) {
sgdwCowClicks = 0;
CowPlaying = TSFX_COW2;
} else {
CowPlaying = TSFX_COW1;
}
#else
if (sgdwCowClicks >= 8) {
PlaySfxLoc(TSFX_COW1, plr[pnum].WorldX, plr[pnum].WorldY + 5);
sgdwCowClicks = 4;
@ -947,6 +959,7 @@ void CowSFX(int pnum)
} else {
CowPlaying = sgdwCowClicks == 4 ? TSFX_COW2 : TSFX_COW1;
}
#endif
PlaySfxLoc(CowPlaying, plr[pnum].WorldX, plr[pnum].WorldY);
}
}

26
Source/trigs.cpp

@ -85,11 +85,13 @@ int L4PentaList[33] = {
-1
};
#ifndef SPAWN
void InitNoTriggers()
{
numtrigs = 0;
trigflag = 0;
}
#endif
void InitTownTriggers()
{
@ -101,6 +103,7 @@ void InitTownTriggers()
numtrigs = 1;
#ifndef SPAWN
if (gbMaxPlayers == MAX_PLRS) {
for (i = 0; i < sizeof(townwarps) / sizeof(townwarps[0]); i++) {
townwarps[i] = TRUE;
@ -119,9 +122,11 @@ void InitTownTriggers()
trigs[3]._tlvl = 13;
numtrigs = 4;
} else {
#endif
for (i = 0; i < 3; i++) {
townwarps[i] = FALSE;
}
#ifndef SPAWN
if (plr[myplr].pTownWarps & 1) {
trigs[1]._tx = 49;
trigs[1]._ty = 21;
@ -147,6 +152,7 @@ void InitTownTriggers()
numtrigs++;
}
}
#endif
trigflag = FALSE;
}
@ -175,6 +181,7 @@ void InitL1Triggers()
trigflag = 0;
}
#ifndef SPAWN
void InitL2Triggers()
{
int i, j;
@ -319,6 +326,7 @@ void InitVPTriggers()
trigs[0]._ty = 32;
trigs[0]._tmsg = WM_DIABRTNLVL;
}
#endif
BOOL ForceTownTrig()
{
@ -711,9 +719,19 @@ void CheckTriggers()
switch (trigs[i]._tmsg) {
case WM_DIABNEXTLVL:
if (pcurs >= CURSOR_FIRSTITEM && DropItemBeforeTrig())
return;
StartNewLvl(myplr, trigs[i]._tmsg, currlevel + 1);
#ifdef SPAWN
if (currlevel >= 2) {
NetSendCmdLoc(TRUE, CMD_WALKXY, plr[myplr].WorldX, plr[myplr].WorldY + 1);
PlaySFX(PS_WARR18);
InitDiabloMsg(EMSG_NOT_IN_SHAREWARE);
} else {
#endif
if (pcurs >= CURSOR_FIRSTITEM && DropItemBeforeTrig())
return;
StartNewLvl(myplr, trigs[i]._tmsg, currlevel + 1);
#ifdef SPAWN
}
#endif
break;
case WM_DIABPREVLVL:
if (pcurs >= CURSOR_FIRSTITEM && DropItemBeforeTrig())
@ -751,10 +769,12 @@ void CheckTriggers()
if (abort) {
if (plr[myplr]._pClass == PC_WARRIOR) {
PlaySFX(PS_WARR43);
#ifndef SPAWN
} else if (plr[myplr]._pClass == PC_ROGUE) {
PlaySFX(PS_ROGUE43);
} else if (plr[myplr]._pClass == PC_SORCERER) {
PlaySFX(PS_MAGE43);
#endif
}
InitDiabloMsg(abortflag);

1
defs.h

@ -48,7 +48,6 @@
#define VOLUME_MAX 0
// todo: enums
#define NUM_SFX 858
#define NUMLEVELS 17
// from diablo 2 beta

1772
enums.h

File diff suppressed because it is too large Load Diff

2
structs.h

@ -1232,7 +1232,7 @@ typedef struct _uiheroinfo {
WORD vitality;
int gold;
int hassaved;
int spawned;
BOOL spawned;
} _uiheroinfo;
// TPDEF PTR FCN UCHAR ENUMHEROPROC

2
types.h

@ -48,7 +48,7 @@
#endif
// If defined, use copy protection [Default -> Defined]
#ifndef _DEBUG
#if !defined(_DEBUG) && !defined(SPAWN)
#define COPYPROT
#endif

Loading…
Cancel
Save